[
  {
    "path": ".all-contributorsrc",
    "content": "{\n  \"projectName\": \"formily\",\n  \"projectOwner\": \"alibaba\",\n  \"repoType\": \"github\",\n  \"repoHost\": \"https://github.com\",\n  \"files\": [\n    \"README.md\"\n  ],\n  \"imageSize\": 100,\n  \"commit\": false,\n  \"contributors\": [\n    {\n      \"login\": \"janryWang\",\n      \"name\": \"Janry\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/4060976?v=4\",\n      \"profile\": \"https://github.com/janryWang\",\n      \"contributions\": [\n        \"design\"\n      ]\n    },\n    {\n      \"login\": \"cnt1992\",\n      \"name\": \"SkyCai\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/3118988?v=4\",\n      \"profile\": \"http://cnt1992.github.io\",\n      \"contributions\": [\n        \"design\"\n      ]\n    },\n    {\n      \"login\": \"yujiangshui\",\n      \"name\": \"Harry Yu\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/2942913?v=4\",\n      \"profile\": \"https://www.linkedin.com/in/harry-yu-0a931a69/\",\n      \"contributions\": [\n        \"doc\",\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"zsirfs\",\n      \"name\": \"zsir\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/22249411?v=4\",\n      \"profile\": \"https://www.luoyangfu.com\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"monkindey\",\n      \"name\": \"Kiho · Cham\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/6913898?v=4\",\n      \"profile\": \"http://www.monkindey.xyz/\",\n      \"contributions\": [\n        \"code\",\n        \"doc\"\n      ]\n    },\n    {\n      \"login\": \"whj1995\",\n      \"name\": \"Hongjiang Wu\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/22634735?v=4\",\n      \"profile\": \"http://whj1995.xyz\",\n      \"contributions\": [\n        \"doc\"\n      ]\n    },\n    {\n      \"login\": \"anyuxuan\",\n      \"name\": \"合木\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/24931869?v=4\",\n      \"profile\": \"https://github.com/anyuxuan\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"Azath0th\",\n      \"name\": \"Chen YuBen\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/18497361?v=4\",\n      \"profile\": \"https://github.com/Azath0th\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"HarrisFeng\",\n      \"name\": \"Harris Feng\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/7928957?v=4\",\n      \"profile\": \"https://github.com/HarrisFeng\",\n      \"contributions\": [\n        \"code\"\n      ]\n    }\n  ],\n  \"contributorsPerLine\": 7\n}\n"
  },
  {
    "path": ".codecov.yml",
    "content": "coverage:\n  status:\n    project:\n      default:\n        threshold: 0.1%\n    patch:\n      default:\n        threshold: 0.1%\n        target: 95%\n"
  },
  {
    "path": ".editorconfig",
    "content": "# EditorConfig is awesome: http://EditorConfig.org\n\n# top-most EditorConfig file\nroot = true\n\n# Unix-style newlines with a newline ending every file\n[*]\nend_of_line = lf\ninsert_final_newline = true\nindent_style = space\nindent_size = 2\n\n[*.gradle]\nindent_size = 4"
  },
  {
    "path": ".eslintignore",
    "content": "node_modules\nlib\ndist\nbuild\ncoverage\nexpected\nwebsite\ngh-pages\nweex\nbuild.ts\npackages/vue\npackages/element\nesm\ndoc-site\npublic\npackage"
  },
  {
    "path": ".eslintrc",
    "content": "{\n  \"env\": {\n    \"node\": true\n  },\n  \"extends\": [\n    \"plugin:react/recommended\",\n    \"plugin:@typescript-eslint/recommended\",\n    \"prettier/@typescript-eslint\"\n  ],\n  \"globals\": {\n    \"sleep\": true,\n    \"prettyFormat\": true\n  },\n  \"parserOptions\": {\n    \"ecmaVersion\": 10,\n    \"sourceType\": \"module\",\n    \"ecmaFeatures\": {\n      \"jsx\": true\n    }\n  },\n  \"parser\": \"@typescript-eslint/parser\",\n  \"plugins\": [\"@typescript-eslint\", \"react\", \"prettier\", \"markdown\"],\n  \"settings\": {\n    \"react\": {\n      \"version\": \"detect\"\n    }\n  },\n  \"rules\": {\n    \"@typescript-eslint/explicit-module-boundary-types\": \"off\",\n    \"@typescript-eslint/no-var-requires\": \"off\",\n    \"@typescript-eslint/no-explicit-any\": \"off\",\n    \"@typescript-eslint/no-unused-vars\": \"error\",\n    \"@typescript-eslint/ban-ts-comment\": \"off\",\n    \"react/no-unescaped-entities\": \"off\",\n    \"react/prop-types\": \"off\"\n  },\n  \"overrides\": [\n    {\n      \"files\": [\"**/*.md\"],\n      \"processor\": \"markdown/markdown\"\n    },\n    {\n      \"files\": [\"**/*.md/*.{jsx,tsx}\"],\n      \"rules\": {\n        \"@typescript-eslint/no-unused-vars\": \"error\",\n        \"no-unused-vars\": \"error\",\n        \"no-console\": \"off\",\n        \"react/display-name\": \"off\",\n        \"react/prop-types\": \"off\"\n      }\n    },\n    {\n      \"files\": [\"**/*.md/*.{js,ts}\"],\n      \"rules\": {\n        \"@typescript-eslint/no-unused-vars\": \"off\",\n        \"no-unused-vars\": \"off\",\n        \"no-console\": \"off\",\n        \"react/display-name\": \"off\",\n        \"react/prop-types\": \"off\"\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "content": "# Contributing Guide\n\nHi! I’m really excited that you are interested in contributing to Formily. Before submitting your contribution though, please make sure to take a moment and read through the following guidelines.\n\n- [Contributing Guide](#contributing-guide)\n  - [Issue Reporting Guidelines](#issue-reporting-guidelines)\n  - [Pull Request Guidelines](#pull-request-guidelines)\n  - [Git Commit Specific](#git-commit-specific)\n\n## Issue Reporting Guidelines\n\n- The issue list of this repo is **exclusively** for bug reports and feature requests. Non-conforming issues will be closed immediately.\n\n  - For simple beginner questions, you can get quick answers from\n\n  - For more complicated questions, you can use Google or StackOverflow. Make sure to provide enough information when asking your questions - this makes it easier for others to help you!\n\n- Try to search for your issue, it may have already been answered or even fixed in the development branch.\n\n- Check if the issue is reproducible with the latest stable version of Formily. If you are using a pre-release, please indicate the specific version you are using.\n\n- It is **required** that you clearly describe the steps necessary to reproduce the issue you are running into. Issues with no clear repro steps will not be triaged. If an issue labeled \"need repro\" receives no further input from the issue author for more than 5 days, it will be closed.\n\n- For bugs that involves build setups, you can create a reproduction repository with steps in the README.\n\n- If your issue is resolved but still open, don’t hesitate to close it. In case you found a solution by yourself, it could be helpful to explain how you fixed it.\n\n## Pull Request Guidelines\n\n- Only code that's ready for release should be committed to the master branch. All development should be done in dedicated branches.\n- Checkout a **new** topic branch from master branch, and merge back against master branch.\n- Work in the `src` folder and **DO NOT** checkin `dist` in the commits.\n- Make sure `npm test` passes.\n- If adding new feature:\n  - Add accompanying test case.\n  - Provide convincing reason to add this feature. Ideally you should open a suggestion issue first and have it greenlighted before working on it.\n- If fixing a bug:\n  - If you are resolving a special issue, add `(fix #xxxx[,#xxx])` (#xxxx is the issue id) in your PR title for a better release log, e.g. `update entities encoding/decoding (fix #3899)`.\n  - Provide detailed description of the bug in the PR. Live demo preferred.\n  - Add appropriate test coverage if applicable.\n\n## Git Commit Specific\n\n- Your commits message must follow our [git commit specific](https://github.com/alibaba/formily/blob/master/.github/GIT_COMMIT_SPECIFIC.md).\n- We will check your commit message, if it does not conform to the specification, the commit will be automatically refused, make sure you have read the specification above.\n- You could use `git cz` with a CLI interface to replace `git commit` command, it will help you to build a proper commit-message, see [commitizen](https://github.com/commitizen/cz-cli).\n- It's OK to have multiple small commits as you work on your branch - we will let GitHub automatically squash it before merging.\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]\npatreon: # Replace with a single Patreon username\nopen_collective: formily # Replace with a single Open Collective username\nko_fi: # Replace with a single Ko-fi username\ntidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel\ncommunity_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry\nliberapay: # Replace with a single Liberapay username\nissuehunt: # Replace with a single IssueHunt username\notechie: # Replace with a single Otechie username\ncustom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: true\ncontact_links:\n  - name: Create new issue\n    url: https://formilyjs.org/guide/issue-helper\n    about: The issue which is not created via https://formilyjs.org/guide/issue-helper will be closed immediately.\n  - name: ✨ Question Answer / Idea\n    url: https://github.com/alibaba/formily/discussions/new\n    about: All questions can be solved here. At the same time you can provide all your ideas here.\n  - name: 📖 View documentation\n    url: https://formilyjs.org\n    about: Official Formily documentation\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "_Before_ submitting a pull request, please make sure the following is done...\n\n- [ ] Ensure the pull request title and commit message follow the [Commit Specific](https://formilyjs.org/guide/contribution#pr-specification) in **English**.\n- [ ] Fork the repo and create your branch from `master` or `formily_next`.\n- [ ] If you've added code that should be tested, add tests!\n- [ ] If you've changed APIs, update the documentation.\n- [ ] Ensure the test suite passes (`npm test`).\n- [ ] Make sure your code lints (`npm run lint`) - we've done our best to make sure these rules match our internal linting guidelines.\n\n**Please do not delete the above content**\n\n---\n\n## What have you changed?\n"
  },
  {
    "path": ".github/workflows/check-pr-title.yml",
    "content": "name: Check PR title\non:\n  pull_request_target:\n    types:\n      - opened\n      - reopened\n      - edited\n      - synchronize\n\njobs:\n  lint:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: aslafy-z/conventional-pr-title-action@v2.4.0\n        with:\n          preset: conventional-changelog-angular@^5.0.6\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: Node CI\n\non:\n  push:\n    branches:\n      - formily_next\n  pull_request:\n    branches:\n      - formily_next\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    if: contains(github.event.head_commit.message, 'chore(versions)') == false\n    steps:\n      - uses: actions/checkout@v1\n      - name: Use Node.js\n        uses: actions/setup-node@v1\n        with:\n          node-version: 16\n\n      - run: yarn -v\n      - run: yarn --ignore-engines\n      - name: ESlint\n        uses: reviewdog/action-eslint@v1\n        with:\n          reporter: github-check\n          eslint_flags: '.'\n      - run: yarn build\n      - run: yarn test:prod\n        env:\n          CI: true\n          HEADLESS: false\n          PROGRESS: none\n          NODE_ENV: test\n          NODE_OPTIONS: --max_old_space_size=4096\n"
  },
  {
    "path": ".github/workflows/commitlint.yml",
    "content": "# This is a basic workflow to help you get started with Actions\n\nname: Check Commit spec\n\n# Controls when the action will run.\non:\n  # Triggers the workflow on push or pull request events but only for the formily_next branch\n  push:\n    branches: [formily_next]\n  pull_request:\n    branches: [formily_next]\n\n  # Allows you to run this workflow manually from the Actions tab\n  workflow_dispatch:\n\n# A workflow run is made up of one or more jobs that can run sequentially or in parallel\njobs:\n  # This workflow contains a single job called \"build\"\n  commitlint:\n    # The type of runner that the job will run on\n    runs-on: ubuntu-latest\n\n    # Steps represent a sequence of tasks that will be executed as part of the job\n    steps:\n      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it\n      - uses: actions/checkout@v2\n        with:\n          fetch-depth: 0=\n      - uses: wagoid/commitlint-github-action@v3\n"
  },
  {
    "path": ".github/workflows/issue-open-check.yml",
    "content": "name: Issue Open Check\n\non:\n  issues:\n    types: [opened]\n\njobs:\n  check-issue:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions-cool/check-user-permission@v1.0.0\n        id: checkUser\n        with:\n          require: 'write'\n\n      - name: check invalid\n        if: (contains(github.event.issue.body, 'formily-issue-helper') == false) && (steps.checkUser.outputs.result == 'false')\n        uses: actions-cool/issues-helper@v1.2\n        with:\n          actions: 'create-comment,add-labels,close-issue'\n          issue-number: ${{ github.event.issue.number }}\n          labels: 'Invalid'\n          body: |\n            Hello @${{ github.event.issue.user.login }}, your issue has been closed because it does not conform to our issue requirements. Please use the [Issue Helper](https://formilyjs.org/guide/issue-helper) to create an issue, thank you!\n            你好 @${{ github.event.issue.user.login }}，为了能够进行高效沟通，我们对 issue 有一定的格式要求，你的 issue 因为不符合要求而被自动关闭。你可以通过 [issue 助手](https://formilyjs.org/guide/issue-helper) 来创建 issue 以方便我们定位错误。谢谢配合！\n"
  },
  {
    "path": ".github/workflows/package-size.yml",
    "content": "name: Compressed Size\n\non: [pull_request]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v3\n      - uses: actions/setup-node@v3\n        with:\n          node-version: 16\n      - uses: preactjs/compressed-size-action@v2\n        with:\n          repo-token: '${{ secrets.GITHUB_TOKEN }}'\n"
  },
  {
    "path": ".github/workflows/pr-welcome.yml",
    "content": "name: PR Welcome\n\non:\n  pull_request_target:\n    types: [opened]\n\njobs:\n  welcome:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions-cool/pr-welcome@v1.1.2\n        with:\n          pr-emoji: '+1, heart'\n"
  },
  {
    "path": ".gitignore",
    "content": "*~\n*.swp\n.DS_Store\n.tea\nnpm-debug.log\nlerna-debug.log\nnpm-debug.log*\npackage-lock.json\nlib/\nesm/\ntemp_esm/\ndist/\ntype-artefacts/\nbuild/\ncoverage/\nnode_modules/\nexamples/test\n.idea/\nTODO.md\ntsconfig.tsbuildinfo\npackage/\npackage.zip\n.umi\n.umi-production\n.cjsescache\ndoc-site\n.lerna-changelog\n.history\n.lint-report.log\n"
  },
  {
    "path": ".prettierrc.js",
    "content": "module.exports = {\n  semi: false,\n  tabWidth: 2,\n  singleQuote: true,\n}"
  },
  {
    "path": ".umirc.js",
    "content": "export default {\n  mode: 'site',\n  logo: '//img.alicdn.com/imgextra/i2/O1CN01Kq3OHU1fph6LGqjIz_!!6000000004056-55-tps-1141-150.svg',\n  title: 'Formily',\n  hash: true,\n  favicon:\n    '//img.alicdn.com/imgextra/i3/O1CN01XtT3Tv1Wd1b5hNVKy_!!6000000002810-55-tps-360-360.svg',\n  outputPath: './doc-site',\n  locales: [\n    ['en-US', 'English'],\n    ['zh-CN', '中文'],\n  ],\n  navs: {\n    'en-US': [\n      {\n        title: 'Guide',\n        path: '/guide',\n      },\n      {\n        title: 'Basic Core Library',\n        children: [\n          {\n            title: '@formily/reactive',\n            path: 'https://reactive.formilyjs.org',\n          },\n          {\n            title: '@formily/core',\n            path: 'https://core.formilyjs.org',\n          },\n          {\n            title: '@formily/react',\n            path: 'https://react.formilyjs.org',\n          },\n          {\n            title: '@formily/vue',\n            path: 'https://vue.formilyjs.org',\n          },\n        ],\n      },\n      {\n        title: 'Component Ecology',\n        children: [\n          {\n            title: '@formily/antd',\n            path: 'https://antd.formilyjs.org',\n          },\n          {\n            title: '@formily/antd-v5',\n            path: 'https://antd5.formilyjs.org',\n          },\n          {\n            title: '@formily/antd-mobile',\n            path: 'https://antd-mobile.formilyjs.org',\n          },\n          {\n            title: '@formily/next',\n            path: 'https://fusion.formilyjs.org',\n          },\n          {\n            title: '@formily/element',\n            path: 'https://element.formilyjs.org',\n          },\n          {\n            title: '@formily/element-plus',\n            path: 'https://element-plus.formilyjs.org',\n          },\n          {\n            title: '@formily/antdv',\n            path: 'https://antdv.formilyjs.org',\n          },\n          {\n            title: '@formily/antdv-x3',\n            path: 'https://antdv-x3.formilyjs.org',\n          },\n          {\n            title: '@formily/vant',\n            path: 'https://vant.formilyjs.org',\n          },\n          {\n            title: '@formily/semi',\n            path: 'https://semi.formilyjs.org',\n          },\n          {\n            title: '@formily/tdesign-react',\n            path: 'https://tdesign-react.formilyjs.org/',\n          },\n          {\n            title: 'aliyun teamix',\n            path: 'https://formily.dg.aliyun-inc.com/',\n          },\n          {\n            title: 'antd-formily-boost',\n            path: 'https://github.com/fishedee/antd-formily-boost',\n          },\n        ],\n      },\n      {\n        title: 'Tools',\n        children: [\n          {\n            title: 'Formily Designer',\n            path: 'https://designable-antd.formilyjs.org/',\n          },\n          {\n            title: 'Designable',\n            path: 'https://github.com/alibaba/designable',\n          },\n          {\n            title: 'Chrome Extension',\n            path: 'https://chrome.google.com/webstore/detail/formily-devtools/kkocalmbfnplecdmbadaapgapdioecfm?hl=zh-CN',\n          },\n        ],\n      },\n      {\n        title: 'Community',\n        children: [\n          {\n            title: 'Forum',\n            path: 'https://github.com/alibaba/formily/discussions',\n          },\n          { title: 'Zhihu', path: 'https://www.zhihu.com/column/uform' },\n        ],\n      },\n      {\n        title: 'Document@1.x',\n        path: 'https://v1.formilyjs.org',\n      },\n      {\n        title: 'GITHUB',\n        path: 'https://github.com/alibaba/formily',\n      },\n    ],\n    'zh-CN': [\n      {\n        title: '指南',\n        path: '/zh-CN/guide',\n      },\n      {\n        title: '基础核心库',\n        children: [\n          {\n            title: '@formily/reactive',\n            path: 'https://reactive.formilyjs.org/zh-CN',\n          },\n          {\n            title: '@formily/core',\n            path: 'https://core.formilyjs.org/zh-CN',\n          },\n          {\n            title: '@formily/react',\n            path: 'https://react.formilyjs.org/zh-CN',\n          },\n          {\n            title: '@formily/vue',\n            path: 'https://vue.formilyjs.org',\n          },\n        ],\n      },\n      {\n        title: '组件生态',\n        children: [\n          {\n            title: '@formily/antd',\n            path: 'https://antd.formilyjs.org/zh-CN',\n          },\n          {\n            title: '@formily/antd-v5',\n            path: 'https://antd5.formilyjs.org/zh-CN',\n          },\n          {\n            title: '@formily/antd-mobile',\n            path: 'https://antd-mobile.formilyjs.org/zh-CN',\n          },\n          {\n            title: '@formily/next',\n            path: 'https://fusion.formilyjs.org/zh-CN',\n          },\n          {\n            title: '@formily/element',\n            path: 'https://element.formilyjs.org',\n          },\n          {\n            title: '@formily/element-plus',\n            path: 'https://element-plus.formilyjs.org',\n          },\n          {\n            title: '@formily/antdv',\n            path: 'https://antdv.formilyjs.org',\n          },\n          {\n            title: '@formily/vant',\n            path: 'https://vant.formilyjs.org',\n          },\n          {\n            title: '@formily/semi',\n            path: 'https://semi.formilyjs.org',\n          },\n          {\n            title: '@formily/tdesign-react',\n            path: 'https://tdesign-react.formilyjs.org',\n          },\n          {\n            title: 'aliyun teamix',\n            path: 'https://formily.dg.aliyun-inc.com',\n          },\n          {\n            title: 'antd-formily-boost',\n            path: 'https://github.com/fishedee/antd-formily-boost',\n          },\n        ],\n      },\n      {\n        title: '工具',\n        children: [\n          {\n            title: 'Formily 设计器',\n            path: 'https://designable-antd.formilyjs.org/',\n          },\n          {\n            title: '通用搭建引擎',\n            path: 'https://github.com/alibaba/designable',\n          },\n          {\n            title: 'Chrome扩展',\n            path: 'https://chrome.google.com/webstore/detail/formily-devtools/kkocalmbfnplecdmbadaapgapdioecfm?hl=zh-CN',\n          },\n        ],\n      },\n      {\n        title: '社区',\n        children: [\n          {\n            title: '论坛',\n            path: 'https://github.com/alibaba/formily/discussions',\n          },\n          { title: '知乎专栏', path: 'https://www.zhihu.com/column/uform' },\n        ],\n      },\n      {\n        title: '1.x文档',\n        path: 'https://v1.formilyjs.org',\n      },\n      {\n        title: 'GITHUB',\n        path: 'https://github.com/alibaba/formily',\n      },\n    ],\n  },\n  headScripts: [\n    `\n    function loadAd(){\n      var header = document.querySelector('.__dumi-default-layout-content .markdown h1')\n      if(header && !header.querySelector('#_carbonads_js')){\n        var script = document.createElement('script')\n        script.src = '//cdn.carbonads.com/carbon.js?serve=CEAICK3M&placement=formilyjsorg'\n        script.id = '_carbonads_js'\n        script.classList.add('head-ad')\n        header.appendChild(script)\n      }\n    }\n    var request = null\n    var observer = new MutationObserver(function(){\n      cancelIdleCallback(request)\n      request = requestIdleCallback(loadAd)\n    })\n    document.addEventListener('DOMContentLoaded',function(){\n      loadAd()\n      observer.observe(\n        document.body,\n        {\n          childList:true,\n          subtree:true\n        }\n      )\n    })\n    `,\n  ],\n  links: [\n    {\n      rel: 'stylesheet',\n      href: 'https://esm.sh/antd@4.x/dist/antd.css',\n    },\n  ],\n  styles: [\n    `.__dumi-default-navbar-logo{\n      height: 60px !important;\n      width: 150px !important;\n      padding-left:0 !important;\n      color: transparent !important;\n    }\n    .__dumi-default-navbar{\n      padding: 0 28px !important;\n    }\n    .__dumi-default-layout-hero{\n      background-image: url(//img.alicdn.com/imgextra/i4/O1CN01ZcvS4e26XMsdsCkf9_!!6000000007671-2-tps-6001-4001.png);\n      background-size: cover;\n      background-repeat: no-repeat;\n      padding: 120px 0 !important;\n    }\n    .__dumi-default-layout-hero h1{\n      color:#45124e !important;\n      font-size:80px !important;\n      padding-bottom: 30px !important;\n    }\n    .__dumi-default-dark-switch {\n      display:none\n    }\n    nav a{\n      text-decoration: none !important;\n    }\n    #carbonads * {\n      margin: initial;\n      padding: initial;\n    }\n    #carbonads {\n      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,\n        Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Helvetica, Arial,\n        sans-serif;\n    }\n    #carbonads {\n      display: flex;\n      max-width: 330px;\n      background-color: hsl(0, 0%, 98%);\n      box-shadow: 0 1px 4px 1px hsla(0, 0%, 0%, 0.1);\n      z-index: 100;\n      float:right;\n    }\n    #carbonads a {\n      color: inherit;\n      text-decoration: none;\n    }\n    #carbonads a:hover {\n      color: inherit;\n    }\n    #carbonads span {\n      position: relative;\n      display: block;\n      overflow: hidden;\n    }\n    #carbonads .carbon-wrap {\n      display: flex;\n    }\n    #carbonads .carbon-img {\n      display: block;\n      margin: 0;\n      line-height: 1;\n    }\n    #carbonads .carbon-img img {\n      display: block;\n    }\n    #carbonads .carbon-text {\n      font-size: 13px;\n      padding: 10px;\n      margin-bottom: 16px;\n      line-height: 1.5;\n      text-align: left;\n    }\n    #carbonads .carbon-poweredby {\n      display: block;\n      padding: 6px 8px;\n      background: #f1f1f2;\n      text-align: center;\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n      font-weight: 600;\n      font-size: 8px;\n      line-height: 1;\n      border-top-left-radius: 3px;\n      position: absolute;\n      bottom: 0;\n      right: 0;\n    }\n    `,\n  ],\n  menus: {\n    '/guide': [\n      {\n        title: 'Introduction',\n        path: '/guide',\n      },\n      {\n        title: 'How to learn Formily',\n        path: '/guide/learn-formily',\n      },\n      {\n        title: 'Quick start',\n        path: '/guide/quick-start',\n      },\n      {\n        title: 'V2 Upgrade Guide',\n        path: '/guide/upgrade',\n      },\n      {\n        title: 'Contribution Guide',\n        path: '/guide/contribution',\n      },\n      {\n        title: 'Form Builder Guide',\n        path: '/guide/form-builder',\n      },\n      {\n        title: 'Issue Helper',\n        path: '/guide/issue-helper',\n      },\n      {\n        title: 'Scenes',\n        children: [\n          {\n            title: 'Login&Signup',\n            path: '/guide/scenes/login-register',\n          },\n          {\n            title: 'Query List',\n            path: '/guide/scenes/query-list',\n          },\n          {\n            title: 'Edit&Details',\n            path: '/guide/scenes/edit-detail',\n          },\n          {\n            title: 'Dialog&Drawer',\n            path: '/guide/scenes/dialog-drawer',\n          },\n          {\n            title: 'Step Form',\n            path: '/guide/scenes/step-form',\n          },\n          {\n            title: 'Tab Form',\n            path: '/guide/scenes/tab-form',\n          },\n          {\n            title: 'More Scenes',\n            path: '/guide/scenes/more',\n          },\n        ],\n      },\n      {\n        title: 'Advanced Guide',\n        children: [\n          {\n            title: 'Form Validation',\n            path: '/guide/advanced/validate',\n          },\n          {\n            title: 'Form Layout',\n            path: '/guide/advanced/layout',\n          },\n          {\n            title: 'Asynchronous Data Sources',\n            path: '/guide/advanced/async',\n          },\n          {\n            title: 'Form Controlled',\n            path: '/guide/advanced/controlled',\n          },\n          {\n            title: 'Linkage Logic',\n            path: '/guide/advanced/linkages',\n          },\n          {\n            title: 'Calculator',\n            path: '/guide/advanced/calculator',\n          },\n          {\n            title: 'Custom Components',\n            path: '/guide/advanced/custom',\n          },\n          {\n            title: 'Front-end and back-end data compatibility solution',\n            path: '/guide/advanced/destructor',\n          },\n          {\n            title: 'Manage Business Logic',\n            path: '/guide/advanced/business-logic',\n          },\n          {\n            title: 'Pack on demand',\n            path: '/guide/advanced/build',\n          },\n        ],\n      },\n    ],\n\n    '/zh-CN/guide': [\n      {\n        title: '介绍',\n        path: '/zh-CN/guide',\n      },\n      {\n        title: '如何学习Formily',\n        path: '/zh-CN/guide/learn-formily',\n      },\n      {\n        title: '快速开始',\n        path: '/zh-CN/guide/quick-start',\n      },\n      {\n        title: 'V2升级指南',\n        path: '/zh-CN/guide/upgrade',\n      },\n      {\n        title: '贡献指南',\n        path: '/zh-CN/guide/contribution',\n      },\n      {\n        title: '表单设计器开发指南',\n        path: '/zh-CN/guide/form-builder',\n      },\n      {\n        title: '问题反馈',\n        path: '/zh-CN/guide/issue-helper',\n      },\n      {\n        title: '场景案例',\n        children: [\n          {\n            title: '登录注册',\n            path: '/zh-CN/guide/scenes/login-register',\n          },\n          {\n            title: '查询列表',\n            path: '/zh-CN/guide/scenes/query-list',\n          },\n          {\n            title: '编辑详情',\n            path: '/zh-CN/guide/scenes/edit-detail',\n          },\n          {\n            title: '弹窗与抽屉',\n            path: '/zh-CN/guide/scenes/dialog-drawer',\n          },\n          {\n            title: '分步表单',\n            path: '/zh-CN/guide/scenes/step-form',\n          },\n          {\n            title: '选项卡/手风琴表单',\n            path: '/zh-CN/guide/scenes/tab-form',\n          },\n          {\n            title: '更多场景',\n            path: '/zh-CN/guide/scenes/more',\n          },\n        ],\n      },\n      {\n        title: '进阶指南',\n        children: [\n          {\n            title: '实现表单校验',\n            path: '/zh-CN/guide/advanced/validate',\n          },\n          {\n            title: '实现表单布局',\n            path: '/zh-CN/guide/advanced/layout',\n          },\n          {\n            title: '实现异步数据源',\n            path: '/zh-CN/guide/advanced/async',\n          },\n          {\n            title: '实现表单受控',\n            path: '/zh-CN/guide/advanced/controlled',\n          },\n          {\n            title: '实现联动逻辑',\n            path: '/zh-CN/guide/advanced/linkages',\n          },\n          {\n            title: '实现联动计算器',\n            path: '/zh-CN/guide/advanced/calculator',\n          },\n          {\n            title: '实现自定义组件',\n            path: '/zh-CN/guide/advanced/custom',\n          },\n          {\n            title: '前后端数据差异兼容方案',\n            path: '/zh-CN/guide/advanced/destructor',\n          },\n          {\n            title: '管理业务逻辑',\n            path: '/zh-CN/guide/advanced/business-logic',\n          },\n          {\n            title: '按需打包',\n            path: '/zh-CN/guide/advanced/build',\n          },\n        ],\n      },\n    ],\n  },\n}\n"
  },
  {
    "path": ".vscode/cspell.json",
    "content": "{\n  \"version\": \"0.1\",\n  \"language\": \"en\",\n  \"ignoreWords\": [\n    \"autorun\",\n    \"mutators\",\n    \"Formily\",\n    \"formily\",\n    \"untrack\",\n    \"untracker\",\n    \"untracked\",\n    \"Untracking\",\n    \"Unmount\",\n    \"octokit\",\n    \"repos\",\n    \"alibaba\",\n    \"Lifecycles\",\n    \"antd\",\n    \"Antd\",\n    \"alifd\",\n    \"Mixins\",\n    \"builtins\",\n    \"cascader\",\n    \"Cascader\",\n    \"middlewares\"\n  ]\n}\n"
  },
  {
    "path": ".yarnrc",
    "content": "registry \"https://registry.yarnpkg.com\""
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\n## v2.3.6(2025-05-15)\n\n### No Change Log\n\n## v2.3.5(2025-05-15)\n\n### No Change Log\n\n## v2.3.4(2025-05-14)\n\n### :tada: Enhancements\n\n1. [feat(core): 支持用户配置 validate 在哪些 pattern & display 下生效](https://github.com/alibaba/formily/commit/cea638cd) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n### :bug: Bug Fixes\n\n1. [fix(formily grid): add requestAnimationFrame to smooth grid digest (#4281)](https://github.com/alibaba/formily/commit/70475f77) :point_right: ( [CHEN GUODONG](https://github.com/CHEN GUODONG) )\n\n1. [fix: fix doc cdn link](https://github.com/alibaba/formily/commit/cabecfea) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n### :blush: Other Changes\n\n1. [chore: upgrade devtools](https://github.com/alibaba/formily/commit/29bbcf5d) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n## v2.3.3(2025-03-31)\n\n### :tada: Enhancements\n\n1. [feat: slot (#4259)](https://github.com/alibaba/formily/commit/123d536b) :point_right: ( [NiceTooo](https://github.com/NiceTooo) )\n\n1. [feat(core): 支持用户配置 validate 在哪些 pattern & display 下生效 (#4211)](https://github.com/alibaba/formily/commit/39fdb681) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n### :bug: Bug Fixes\n\n1. [fix(antd): fix antd/next render error at React 19 (#4262)](https://github.com/alibaba/formily/commit/a0f3169a) :point_right: ( [ChaoGPT](https://github.com/ChaoGPT) )\n\n1. [fix: array-table/main.scss mixed-decls Deprecation warning on sass@1.77.7 + (#4195)](https://github.com/alibaba/formily/commit/d60f12db) :point_right: ( [Godpu](https://github.com/Godpu) )\n\n## v2.3.2(2024-07-18)\n\n### :tada: Enhancements\n\n1. [feat(shared): support BigNumber (#4182)](https://github.com/alibaba/formily/commit/b46b9b72) :point_right: ( [飝猫](https://github.com/飝猫) )\n\n1. [feat(vue): add default value for createSchemaField (#4123)](https://github.com/alibaba/formily/commit/0eeeb0c8) :point_right: ( [Din](https://github.com/Din) )\n\n1. [feat(antd): add form-item tooltip props support (#4144)](https://github.com/alibaba/formily/commit/b4524135) :point_right: ( [阿四](https://github.com/阿四) )\n\n1. [feat(json-schema): x-compile-omitted supports x-validator (#4072)](https://github.com/alibaba/formily/commit/4dc50bce) :point_right: ( [hyl](https://github.com/hyl) )\n\n1. [feat: improve checkers generics (#4075)](https://github.com/alibaba/formily/commit/d11080a4) :point_right: ( [幽閒](https://github.com/幽閒) )\n\n### :bug: Bug Fixes\n\n1. [fix(chrome devtool): graph has symbol value, but devtool dont show (#4113)](https://github.com/alibaba/formily/commit/37d437d6) :point_right: ( [zhangxiaofan](https://github.com/zhangxiaofan) )\n\n1. [fix: wrong RadioGroup optionType value (#4083)](https://github.com/alibaba/formily/commit/9bb53573) :point_right: ( [shenshen](https://github.com/shenshen) )\n\n1. [fix(element): fix form-item extra bugs (#4125)](https://github.com/alibaba/formily/commit/6d55283a) :point_right: ( [James Smith](https://github.com/James Smith) )\n\n1. [fix(vue): fix vue-demi's dependencies version (#4085)](https://github.com/alibaba/formily/commit/cecf56d0) :point_right: ( [严浩](https://github.com/严浩) )\n\n### :memo: Documents Changes\n\n1. [docs: fix deps (#4096)](https://github.com/alibaba/formily/commit/0932a11b) :point_right: ( [tkgkn](https://github.com/tkgkn) )\n\n1. [docs: update validate.md (#4156)](https://github.com/alibaba/formily/commit/9001580e) :point_right: ( [唯心](https://github.com/唯心) )\n\n1. [docs(react): fix typo (#4065)](https://github.com/alibaba/formily/commit/3fa68e69) :point_right: ( [stefango](https://github.com/stefango) )\n\n### :hammer_and_wrench: Update Workflow Scripts\n\n1. [build(deps): bump axios from 0.18.1 to 1.7.2 (#4185)](https://github.com/alibaba/formily/commit/7d43e923) :point_right: ( [dependabot[bot]](https://github.com/dependabot[bot]) )\n\n### :blush: Other Changes\n\n1. [chore: update ci.yml](https://github.com/alibaba/formily/commit/bf292edf) :point_right: ( [Janry](https://github.com/Janry) )\n\n## v2.3.1(2023-12-18)\n\n### :tada: Enhancements\n\n1. [feat: export getLocaleByPath (#4006)](https://github.com/alibaba/formily/commit/15d51bc9) :point_right: ( [uxuip](https://github.com/uxuip) )\n\n1. [feat: props recursion test case added (#4001)](https://github.com/alibaba/formily/commit/d8716ea9) :point_right: ( [Nice](https://github.com/Nice) )\n\n1. [feat(antd): support disable default behavior of built-in operations in ArrayBase (#3998)](https://github.com/alibaba/formily/commit/c90b1df1) :point_right: ( [whincwu](https://github.com/whincwu) )\n\n### :bug: Bug Fixes\n\n1. [fix: fix vue2 array reactive bug (#4042)](https://github.com/alibaba/formily/commit/c94da3fe) :point_right: ( [yiyunwan](https://github.com/yiyunwan) )\n\n1. [fix: fix docs throw error](https://github.com/alibaba/formily/commit/588e5e52) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix: #3986 (#4003)](https://github.com/alibaba/formily/commit/39d64318) :point_right: ( [Lumdzeehol](https://github.com/Lumdzeehol) )\n\n### :hammer_and_wrench: Update Workflow Scripts\n\n1. [build(deps-dev): bump axios from 0.23.0 to 1.6.0 (#4023)](https://github.com/alibaba/formily/commit/d6f827c1) :point_right: ( [dependabot[bot]](https://github.com/dependabot[bot]) )\n\n1. [build(deps): bump browserify-sign from 4.2.1 to 4.2.2 (#4010)](https://github.com/alibaba/formily/commit/e38de2a3) :point_right: ( [dependabot[bot]](https://github.com/dependabot[bot]) )\n\n### :blush: Other Changes\n\n1. [chore: dumi updated for node 18+ (#4018)](https://github.com/alibaba/formily/commit/48c9968b) :point_right: ( [bob](https://github.com/bob) )\n\n## v2.3.0(2023-10-20)\n\n### :tada: Enhancements\n\n1. [feat: recursion field props recursion (#3966)](https://github.com/alibaba/formily/commit/72d533f6) :point_right: ( [Nice](https://github.com/Nice) )\n\n## v2.2.30(2023-10-18)\n\n### :tada: Enhancements\n\n1. [feat: Support labelFor props in <FormItem/> (#3974)](https://github.com/alibaba/formily/commit/eeac65c2) :point_right: ( [小四](https://github.com/小四) )\n\n### :bug: Bug Fixes\n\n1. [fix: remove unexpect label tag (#3996)](https://github.com/alibaba/formily/commit/e8707e9e) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(react): fix field unmounted but can not update right model (#3994)](https://github.com/alibaba/formily/commit/5207021f) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(core): @types/node pollution (#3944)](https://github.com/alibaba/formily/commit/bf0ab1c2) :point_right: ( [Dmitrii Kartashev](https://github.com/Dmitrii Kartashev) )\n\n1. [fix: close dialog should remove dom (#3963)](https://github.com/alibaba/formily/commit/97e7544d) :point_right: ( [Summer](https://github.com/Summer) )\n\n1. [fix: cancel button props (#3964)](https://github.com/alibaba/formily/commit/ac76b62f) :point_right: ( [Summer](https://github.com/Summer) )\n\n### :memo: Documents Changes\n\n1. [docs: fix TS signature for dependencies field of SchemaReactions (#3938)](https://github.com/alibaba/formily/commit/9598d971) :point_right: ( [Andy](https://github.com/Andy) )\n\n### :rocket: Improve Performance\n\n1. [perf(path): simplified code (#3933)](https://github.com/alibaba/formily/commit/8861ef58) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n### :hammer_and_wrench: Update Workflow Scripts\n\n1. [build(deps): bump @babel/traverse from 7.17.10 to 7.23.2 (#3993)](https://github.com/alibaba/formily/commit/421073e7) :point_right: ( [dependabot[bot]](https://github.com/dependabot[bot]) )\n\n1. [build(rollup): add externals with vue-demi (#3975)](https://github.com/alibaba/formily/commit/373dfed3) :point_right: ( [ttsimon](https://github.com/ttsimon) )\n\n1. [build(deps-dev): bump postcss from 7.0.39 to 8.4.31 (#3984)](https://github.com/alibaba/formily/commit/d51b4f28) :point_right: ( [dependabot[bot]](https://github.com/dependabot[bot]) )\n\n### :construction: Add/Update Test Cases\n\n1. [test(core): test case for query field error issue and pr (#3995)](https://github.com/alibaba/formily/commit/31d2c8e3) :point_right: ( [ChaoGPT](https://github.com/ChaoGPT) )\n\n### :blush: Other Changes\n\n1. [chore(grid): add support for peer dependencies of typescript@5.x (#3988)](https://github.com/alibaba/formily/commit/2fc23dd9) :point_right: ( [Sam Liu](https://github.com/Sam Liu) )\n\n## v2.2.29(2023-08-08)\n\n### :bug: Bug Fixes\n\n1. [fix(antd): componentProps lose responsiveness (#3917)](https://github.com/alibaba/formily/commit/6f8ec7dd) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n1. [fix: money format regex (#3913)](https://github.com/alibaba/formily/commit/d37bce83) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n1. [fix: reduce judgment (#3916)](https://github.com/alibaba/formily/commit/da52e7c1) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n1. [fix: 🐛 antd array-table sortable infinite loop and cursor style (#3911)](https://github.com/alibaba/formily/commit/f254b399) :point_right: ( [ChaoGPT](https://github.com/ChaoGPT) )\n\n### :hammer_and_wrench: Update Workflow Scripts\n\n1. [build(deps): bump word-wrap from 1.2.3 to 1.2.4 (#3908)](https://github.com/alibaba/formily/commit/bc90d7b2) :point_right: ( [dependabot[bot]](https://github.com/dependabot[bot]) )\n\n### :construction: Add/Update Test Cases\n\n1. [test: remove unneed code (#3921)](https://github.com/alibaba/formily/commit/8508358d) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n1. [test: add more test cases (#3922)](https://github.com/alibaba/formily/commit/f4223e8d) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n## v2.2.27(2023-07-11)\n\n### :tada: Enhancements\n\n1. [feat(antd): support for hidden pagination of component array table (#3875)](https://github.com/alibaba/formily/commit/1e62b24e) :point_right: ( [xudihui](https://github.com/xudihui) )\n\n1. [feat: 🎸 antd sortable impl by dnd, replace react-sort-hoc (#3855)](https://github.com/alibaba/formily/commit/b3e270fc) :point_right: ( [ChaoGPT](https://github.com/ChaoGPT) )\n\n### :bug: Bug Fixes\n\n1. [fix(vue): decorator event props not work in vue2 (#3884)](https://github.com/alibaba/formily/commit/8528067b) :point_right: ( [MeetzhDing](https://github.com/MeetzhDing) )\n\n1. [fix: ts type (#3888)](https://github.com/alibaba/formily/commit/2e59dc52) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n### :memo: Documents Changes\n\n1. [docs(schema): supplementary scope variable (#3869)](https://github.com/alibaba/formily/commit/061ad213) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n### :rocket: Improve Performance\n\n1. [perf: ⚡️ core array move method optimize, move to shared (#3863)](https://github.com/alibaba/formily/commit/3349815f) :point_right: ( [ChaoGPT](https://github.com/ChaoGPT) )\n\n1. [perf(schema): parse pattern only when needed (#3871)](https://github.com/alibaba/formily/commit/7f6fed07) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n### :hammer_and_wrench: Update Workflow Scripts\n\n1. [build(deps-dev): bump semver from 7.3.7 to 7.5.2 (#3868)](https://github.com/alibaba/formily/commit/f5128343) :point_right: ( [dependabot[bot]](https://github.com/dependabot[bot]) )\n\n### :construction: Add/Update Test Cases\n\n1. [test: add message scope (#3886)](https://github.com/alibaba/formily/commit/0ac09f91) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n1. [test: remove duplicate use cases (#3882)](https://github.com/alibaba/formily/commit/b9ab5097) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n1. [test: rename (#3885)](https://github.com/alibaba/formily/commit/c8661b1c) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n### :blush: Other Changes\n\n1. [style: simplify get value (#3887)](https://github.com/alibaba/formily/commit/287fdadc) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n## v2.2.26(2023-06-21)\n\n### :bug: Bug Fixes\n\n1. [fix(core): onInput not ignore when currentTarget is undefined (#3862)](https://github.com/alibaba/formily/commit/1e490616) :point_right: ( [frehkxu](https://github.com/frehkxu) )\n\n### :construction: Add/Update Test Cases\n\n1. [test(core): improve array test case (#3861)](https://github.com/alibaba/formily/commit/44f08106) :point_right: ( [{ Chao }](https://github.com/{ Chao }) )\n\n## v2.2.25(2023-06-16)\n\n### :tada: Enhancements\n\n1. [feat(json-schema): add IScopeContext easy to expand scope types (#3821)](https://github.com/alibaba/formily/commit/cc6a5fdf) :point_right: ( [yiyunwan](https://github.com/yiyunwan) )\n\n### :bug: Bug Fixes\n\n1. [fix(core): onInput ignore HTMLInputEvent propagation (#3856)](https://github.com/alibaba/formily/commit/b3edf2d1) :point_right: ( [frehkxu](https://github.com/frehkxu) )\n\n1. [fix(doc): fix url langue (#3844)](https://github.com/alibaba/formily/commit/77d7e586) :point_right: ( [微笑](https://github.com/微笑) )\n\n1. [fix: fix array items sortable (#3836)](https://github.com/alibaba/formily/commit/7477e86a) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(json-schema): use `string & {}` instead of string to keep Literal Type for ISchema (#3835)](https://github.com/alibaba/formily/commit/798fde79) :point_right: ( [yiyunwan](https://github.com/yiyunwan) )\n\n1. [fix: fix react typings (#3831)](https://github.com/alibaba/formily/commit/2c41e3ef) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix: change mapProps consistent with react (#3819)](https://github.com/alibaba/formily/commit/6a3fe6b1) :point_right: ( [yiyunwan](https://github.com/yiyunwan) )\n\n### :memo: Documents Changes\n\n1. [doc: fix typo (#3826)](https://github.com/alibaba/formily/commit/84740029) :point_right: ( [godf](https://github.com/godf) )\n\n## v2.2.24(2023-05-15)\n\n### :bug: Bug Fixes\n\n1. [fix: require react dom #3704 (#3818)](https://github.com/alibaba/formily/commit/c3d028d6) :point_right: ( [gwsbhqt](https://github.com/gwsbhqt) )\n\n### :blush: Other Changes\n\n1. [chore: update json-schema's peerDependencies (#3817)](https://github.com/alibaba/formily/commit/4050621f) :point_right: ( [严浩](https://github.com/严浩) )\n\n## v2.2.23(2023-05-05)\n\n### :bug: Bug Fixes\n\n1. [fix: fix requiredMark hidden (#3796)](https://github.com/alibaba/formily/commit/0d187111) :point_right: ( [Alex](https://github.com/Alex) )\n\n1. [fix(antd/next): fix array-collapse onAdd function nullable issue (#3795)](https://github.com/alibaba/formily/commit/39fac2b5) :point_right: ( [戣蓦](https://github.com/戣蓦) )\n\n## v2.2.22(2023-04-12)\n\n### :bug: Bug Fixes\n\n1. [fix(antd): add helperContainer to antd array-items (#3780)](https://github.com/alibaba/formily/commit/757b466d) :point_right: ( [linxianxi](https://github.com/linxianxi) )\n\n1. [fix: field hidden with null value (#3783)](https://github.com/alibaba/formily/commit/f8c2040f) :point_right: ( [gwsbhqt](https://github.com/gwsbhqt) )\n\n1. [fix(core): add types to form submit (#3775)](https://github.com/alibaba/formily/commit/b458efdb) :point_right: ( [Dmitrii Kartashev](https://github.com/Dmitrii Kartashev) )\n\n## v2.2.21(2023-03-21)\n\n### :tada: Enhancements\n\n1. [feat(antd): support ReactNode of ArrayCollapse header](https://github.com/alibaba/formily/commit/1450f60d) :point_right: ( [coder_curry](https://github.com/coder_curry) )\n\n1. [feat(antd): support array-base operator title display (#3646)](https://github.com/alibaba/formily/commit/3ba48209) :point_right: ( [Jehu](https://github.com/Jehu) )\n\n### :bug: Bug Fixes\n\n1. [fix(core): fix patchFieldStates update problem (#3763)](https://github.com/alibaba/formily/commit/eca5a7e5) :point_right: ( [zeqing](https://github.com/zeqing) )\n\n## v2.2.20(2023-02-28)\n\n### :tada: Enhancements\n\n1. [feat(antd): FormItem adds more attribute configuration (#3727)](https://github.com/alibaba/formily/commit/71be0a57) :point_right: ( [Alex](https://github.com/Alex) )\n\n### :bug: Bug Fixes\n\n1. [fix(antd): fix locale import path](https://github.com/alibaba/formily/commit/06a64935) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n### :memo: Documents Changes\n\n1. [docs: add antd5 links (#3728)](https://github.com/alibaba/formily/commit/7e34079d) :point_right: ( [yiyunwan](https://github.com/yiyunwan) )\n\n### :blush: Other Changes\n\n1. [chore(antd/next): fix getObjectParent issue in arrayTable component (#3741)](https://github.com/alibaba/formily/commit/21cff368) :point_right: ( [zeqing](https://github.com/zeqing) )\n\n1. [chore: fixed build ci node version as 16 (#3732)](https://github.com/alibaba/formily/commit/cfca08d5) :point_right: ( [gwsbhqt](https://github.com/gwsbhqt) )\n\n## v2.2.19(2023-02-17)\n\n### :tada: Enhancements\n\n1. [feat(core): support record api (#3711)](https://github.com/alibaba/formily/commit/d4bb96c4) :point_right: ( [Janry](https://github.com/Janry) )\n\n### :bug: Bug Fixes\n\n1. [fix(antd/next): remove RecordScope (#3726)](https://github.com/alibaba/formily/commit/29c347a0) :point_right: ( [zeqing](https://github.com/zeqing) )\n\n### :memo: Documents Changes\n\n1. [docs(linkage): change the controlled is display when initialized & dynamic controlled field (#3717)](https://github.com/alibaba/formily/commit/75d36d29) :point_right: ( [xbsheng](https://github.com/xbsheng) )\n\n1. [docs(core): change the default value of the hidden parameter of createForm function (#3707)](https://github.com/alibaba/formily/commit/5f95cdf1) :point_right: ( [xbsheng](https://github.com/xbsheng) )\n\n## v2.2.18(2023-02-07)\n\n### :bug: Bug Fixes\n\n1. [fix(next): fix ArrayCards and ArrayTable props (#3701)](https://github.com/alibaba/formily/commit/0367c51b) :point_right: ( [常泽清](https://github.com/常泽清) )\n\n1. [fix(element): fix opened name writing error (#3695)](https://github.com/alibaba/formily/commit/c616bf15) :point_right: ( [LiangZhiLin](https://github.com/LiangZhiLin) )\n\n### :hammer_and_wrench: Update Workflow Scripts\n\n1. [build(deps): bump ua-parser-js from 0.7.31 to 0.7.33 (#3682)](https://github.com/alibaba/formily/commit/9fe0520b) :point_right: ( [dependabot[bot]](https://github.com/dependabot[bot]) )\n\n## v2.2.17(2023-01-18)\n\n### :bug: Bug Fixes\n\n1. [fix(vue): fix view may not update when states change. (#3680)](https://github.com/alibaba/formily/commit/b221d3e0) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [fix: fix a compatible problem when using ios10.x (#3677)](https://github.com/alibaba/formily/commit/2fce092c) :point_right: ( [ZSQCola](https://github.com/ZSQCola) )\n\n1. [fix(reactive-react): fix reactive useForceUpdate uncounted strategy (#3668)](https://github.com/alibaba/formily/commit/0bf551eb) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(element): fix Checkbox.Group's change event failure (#3667)](https://github.com/alibaba/formily/commit/2bfa40c1) :point_right: ( [LiangZhiLin](https://github.com/LiangZhiLin) )\n\n### :construction: Add/Update Test Cases\n\n1. [test: adding test case (#3652)](https://github.com/alibaba/formily/commit/f54ccfbc) :point_right: ( [Lumdzeehol](https://github.com/Lumdzeehol) )\n\n## v2.2.16(2022-12-29)\n\n### :bug: Bug Fixes\n\n1. [fix(vue): fix default slot invalid bug when not pass decorator (#3638)](https://github.com/alibaba/formily/commit/29b799c3) :point_right: ( [frehkxu](https://github.com/frehkxu) )\n\n### :rose: Improve code quality\n\n1. [refactor(core): revert initial values check logic (#3642)](https://github.com/alibaba/formily/commit/42be1937) :point_right: ( [Janry](https://github.com/Janry) )\n\n## v2.2.15(2022-12-16)\n\n### :bug: Bug Fixes\n\n1. [fix(antd): fix array tabs waring (#3629)](https://github.com/alibaba/formily/commit/a7e80893) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(vue): keep origin SlotProps pass in ReactiveField (#3623)](https://github.com/alibaba/formily/commit/200af68e) :point_right: ( [frehkxu](https://github.com/frehkxu) )\n\n1. [fix(vue): fix view may not update when states change. (#3619)](https://github.com/alibaba/formily/commit/82ca678d) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n### :hammer_and_wrench: Update Workflow Scripts\n\n1. [build(deps): bump decode-uri-component from 0.2.0 to 0.2.2 (#3607)](https://github.com/alibaba/formily/commit/e075e4e3) :point_right: ( [dependabot[bot]](https://github.com/dependabot[bot]) )\n\n## v2.2.14(2022-12-05)\n\n### :bug: Bug Fixes\n\n1. [fix(react): fix react-dom deps (#3591)](https://github.com/alibaba/formily/commit/75b1e8b9) :point_right: ( [常泽清](https://github.com/常泽清) )\n\n1. [fix(core): fix initValues when values is empty Array or Object (#3583)](https://github.com/alibaba/formily/commit/c538d0d2) :point_right: ( [yiyunwan](https://github.com/yiyunwan) )\n\n1. [fix(antd/next): fix checkbox and radio can not trigger user onChange (#3585)](https://github.com/alibaba/formily/commit/e6454be2) :point_right: ( [Janry](https://github.com/Janry) )\n\n### :construction: Add/Update Test Cases\n\n1. [test: improve antd coverage (#3586)](https://github.com/alibaba/formily/commit/8602fe2b) :point_right: ( [Lumdzeehol](https://github.com/Lumdzeehol) )\n\n### :blush: Other Changes\n\n1. [chore: update benchmark template static js url](https://github.com/alibaba/formily/commit/836d1ce3) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n## v2.2.13(2022-11-28)\n\n### :bug: Bug Fixes\n\n1. [fix(core): take result is possible to be undefined (#3562)](https://github.com/alibaba/formily/commit/cda62b90) :point_right: ( [戣蓦](https://github.com/戣蓦) )\n\n1. [fix(path): fix typo of readIgnoreString (#3545)](https://github.com/alibaba/formily/commit/34964f26) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n### :memo: Documents Changes\n\n1. [doc: typo in architecture.zh-CN.md (#3569)](https://github.com/alibaba/formily/commit/d1ee69b2) :point_right: ( [yeehone](https://github.com/yeehone) )\n\n1. [docs(core): correct properties spelling (#3555)](https://github.com/alibaba/formily/commit/b0206023) :point_right: ( [Lumdzeehol](https://github.com/Lumdzeehol) )\n\n1. [docs(reactive): correct typos (#3532)](https://github.com/alibaba/formily/commit/41d1720b) :point_right: ( [liuwei1025](https://github.com/liuwei1025) )\n\n### :rocket: Improve Performance\n\n1. [perf: improve performance of ArrayTable (#3574)](https://github.com/alibaba/formily/commit/0c0c3b06) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [perf: parentLTok should not after dbStartTok (#3534)](https://github.com/alibaba/formily/commit/48fd1842) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n### :blush: Other Changes\n\n1. [chore: update antd.css version](https://github.com/alibaba/formily/commit/324986c2) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [style: rename to camelCase (#3533)](https://github.com/alibaba/formily/commit/a7c4627d) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n## v2.2.12(2022-11-11)\n\n### :bug: Bug Fixes\n\n1. [fix(core): fix setValues/setInitialValues will change ref (#3529)](https://github.com/alibaba/formily/commit/886144fa) :point_right: ( [Janry](https://github.com/Janry) )\n\n### :memo: Documents Changes\n\n1. [docs: add formily-antd-mobile doc link (#3527)](https://github.com/alibaba/formily/commit/c658cb91) :point_right: ( [Dark](https://github.com/Dark) )\n\n## v2.2.11(2022-11-07)\n\n### :bug: Bug Fixes\n\n1. [fix(element): remove Space gap when child is hidden and attrs pass children (#3526)](https://github.com/alibaba/formily/commit/8bcd51fe) :point_right: ( [frehkxu](https://github.com/frehkxu) )\n\n1. [fix(reactive-react): fix reactive track failed in suspense mode (#3525)](https://github.com/alibaba/formily/commit/5ab10b48) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(core): fix field destructor name will cause stack overflow (#3524)](https://github.com/alibaba/formily/commit/7306677b) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix: ts error in test (#3516)](https://github.com/alibaba/formily/commit/f35e5dfa) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n1. [fix: callback will not be executed until it is a function (#3511)](https://github.com/alibaba/formily/commit/0c969140) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n1. [fix(element): fix vue resolve (#3496)](https://github.com/alibaba/formily/commit/f347a7c0) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n### :rocket: Improve Performance\n\n1. [perf(path): judge lastToken when needed (#3522)](https://github.com/alibaba/formily/commit/0ef61df0) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n1. [perf: lowerCase when necessary (#3492)](https://github.com/alibaba/formily/commit/4379ad0b) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n### :construction: Add/Update Test Cases\n\n1. [test: add setTimeout default value (#3514)](https://github.com/alibaba/formily/commit/618307b9) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n### :blush: Other Changes\n\n1. [chore(core): improve allowAssignDefaultValue (#3523)](https://github.com/alibaba/formily/commit/666b867a) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n1. [style: simplify code (#3506)](https://github.com/alibaba/formily/commit/d6a894f0) :point_right: ( [huangcheng](https://github.com/huangcheng) )\n\n## v2.2.10(2022-10-26)\n\n### :bug: Bug Fixes\n\n1. [fix(react): fix throw react-dom error in react-native (#3491)](https://github.com/alibaba/formily/commit/00141fe7) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(core): fix value filtered from none-hidden #3477 (#3481)](https://github.com/alibaba/formily/commit/617717cb) :point_right: ( [Lumdzeehol](https://github.com/Lumdzeehol) )\n\n### :memo: Documents Changes\n\n1. [docs: update readme](https://github.com/alibaba/formily/commit/e1539bbf) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n### :blush: Other Changes\n\n1. [chore(docs): remove linkage of adjacent in initiative scene (#3488)](https://github.com/alibaba/formily/commit/3033416c) :point_right: ( [kesiyuan](https://github.com/kesiyuan) )\n\n## v2.2.9(2022-10-19)\n\n### :bug: Bug Fixes\n\n1. [fix(core): fix initial value is filtered when the field is hidden (#3471)](https://github.com/alibaba/formily/commit/47ee4786) :point_right: ( [Janry](https://github.com/Janry) )\n\n## v2.2.8(2022-10-18)\n\n### :tada: Enhancements\n\n1. [feat(core): support auto clean field value with visible false (#3452)](https://github.com/alibaba/formily/commit/2c9b332f) :point_right: ( [Janry](https://github.com/Janry) )\n\n### :bug: Bug Fixes\n\n1. [fix(element): remove useless code in demo's guide (#3463)](https://github.com/alibaba/formily/commit/3a3db058) :point_right: ( [guaqiu](https://github.com/guaqiu) )\n\n1. [fix(antd): fix ArrayTable WrapperComp deps missing (#3457)](https://github.com/alibaba/formily/commit/a382a18e) :point_right: ( [Lumdzeehol](https://github.com/Lumdzeehol) )\n\n### :hammer_and_wrench: Update Workflow Scripts\n\n1. [build: fix duplicate packaging with @formily/json-schema (#3467)](https://github.com/alibaba/formily/commit/6d768b0a) :point_right: ( [Grapedge](https://github.com/Grapedge) )\n\n### :blush: Other Changes\n\n1. [chore(docs): improve the translation and example of the login and registration case (#3455)](https://github.com/alibaba/formily/commit/95c295b5) :point_right: ( [WD](https://github.com/WD) )\n\n1. [chore(devtools): change dependencies version (#3448)](https://github.com/alibaba/formily/commit/9809637b) :point_right: ( [fuzi](https://github.com/fuzi) )\n\n## v2.2.7(2022-10-11)\n\n### :bug: Bug Fixes\n\n1. [fix(next): fix cascader preview text can not shown data (#3447)](https://github.com/alibaba/formily/commit/67125bd6) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(docs): fix links in chinese documentation (#3438)](https://github.com/alibaba/formily/commit/382cd177) :point_right: ( [WD](https://github.com/WD) )\n\n1. [fix(core): indexes need exclude incomplete number (#3437)](https://github.com/alibaba/formily/commit/d328bb3a) :point_right: ( [frehkxu](https://github.com/frehkxu) )\n\n## v2.2.6(2022-09-30)\n\n### :bug: Bug Fixes\n\n1. [fix(next/antd): chore formatMomentValue (#3432)](https://github.com/alibaba/formily/commit/ed386f4d) :point_right: ( [danyue](https://github.com/danyue) )\n\n1. [fix(core): fix clearFormGraph unexpect behaviors with action annotation (#3431)](https://github.com/alibaba/formily/commit/e077e6c9) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(core): fix void field child field reactions not work in some cases (#3415)](https://github.com/alibaba/formily/commit/f05cb6b3) :point_right: ( [coolbob](https://github.com/coolbob) )\n\n1. [fix(next/antd): fix SelectTable Template literals invalid && fix FormItem classname error (#3413)](https://github.com/alibaba/formily/commit/b3d3eb7b) :point_right: ( [Lyca](https://github.com/Lyca) )\n\n### :rocket: Improve Performance\n\n1. [perf(reactive): improve reactive performance (#3430)](https://github.com/alibaba/formily/commit/5196f452) :point_right: ( [Janry](https://github.com/Janry) )\n\n## v2.2.5(2022-09-20)\n\n### :bug: Bug Fixes\n\n1. [fix(next/antd): fix moment timestamp (#3395)](https://github.com/alibaba/formily/commit/2054c10f) :point_right: ( [danyue](https://github.com/danyue) )\n\n### :memo: Documents Changes\n\n1. [docs(antd): correct the usage type of the password component (#3406)](https://github.com/alibaba/formily/commit/03719d12) :point_right: ( [WD](https://github.com/WD) )\n\n## v2.2.4(2022-09-12)\n\n### :tada: Enhancements\n\n1. [feat(core): support field inject/invoke actions api (#3389)](https://github.com/alibaba/formily/commit/07593760) :point_right: ( [Janry](https://github.com/Janry) )\n\n### :bug: Bug Fixes\n\n1. [fix(antd): fix ArrayTabs warning after antd4.23.0 (#3387)](https://github.com/alibaba/formily/commit/f6347cc4) :point_right: ( [Lumdzeehol](https://github.com/Lumdzeehol) )\n\n1. [fix(antd/next): onChange does not work when no formTab instance is passed (#3388)](https://github.com/alibaba/formily/commit/e4ba3ea1) :point_right: ( [Dark](https://github.com/Dark) )\n\n1. [fix(antd/next): fix array base use record null error (#3380)](https://github.com/alibaba/formily/commit/053e0f0c) :point_right: ( [{ Chao }](https://github.com/{ Chao }) )\n\n## v2.2.3(2022-09-07)\n\n### :tada: Enhancements\n\n1. [feat(docs): add antdv-x3 doc link (#3361)](https://github.com/alibaba/formily/commit/af1484e3) :point_right: ( [zhouxinyong](https://github.com/zhouxinyong) )\n\n### :bug: Bug Fixes\n\n1. [fix(vue): fix useFormEffects not reactive when form change (#3371)](https://github.com/alibaba/formily/commit/b8b4c510) :point_right: ( [frehkxu](https://github.com/frehkxu) )\n\n1. [fix(element): update type of IFormDialog (#3360)](https://github.com/alibaba/formily/commit/9233d5ec) :point_right: ( [椿楸冥灵](https://github.com/椿楸冥灵) )\n\n## v2.2.2(2022-08-30)\n\n### :bug: Bug Fixes\n\n1. [fix(antd/next): fix array base record ref data is not newest in expression (#3358)](https://github.com/alibaba/formily/commit/35cd1431) :point_right: ( [Janry](https://github.com/Janry) )\n\n## v2.2.1(2022-08-22)\n\n### :tada: Enhancements\n\n1. [feat(element): compat vue2.7 (#3350)](https://github.com/alibaba/formily/commit/da94164e) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n### :bug: Bug Fixes\n\n1. [fix(devtools): Does not render correctly when title is an object (#3340)](https://github.com/alibaba/formily/commit/4fb83052) :point_right: ( [Dark](https://github.com/Dark) )\n\n## v2.2.0(2022-08-11)\n\n### :tada: Enhancements\n\n1. [feat(core): lock setValue/setInitialValue behavior to untrack (#3331)](https://github.com/alibaba/formily/commit/ff1d403a) :point_right: ( [Janry](https://github.com/Janry) )\n\n## v2.1.13(2022-08-11)\n\n### :tada: Enhancements\n\n1. [feat(vue): support vue2.7](https://github.com/alibaba/formily/commit/6af972d1) :point_right: ( [MisicDemone](https://github.com/MisicDemone) )\n\n### :bug: Bug Fixes\n\n1. [fix(next): fix time format moment (#3330)](https://github.com/alibaba/formily/commit/8b7bbd28) :point_right: ( [danyue](https://github.com/danyue) )\n\n1. [fix(core): fix form initialValues not work after array field removed elements (#3324)](https://github.com/alibaba/formily/commit/f7e1b7d8) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(antd/next/element): fix ArrayCards-like component errors with inline component (#3321)](https://github.com/alibaba/formily/commit/aa8ed99e) :point_right: ( [Lumdzeehol](https://github.com/Lumdzeehol) )\n\n1. [fix(antd/next): fix array base not work with pure jsx (#3317)](https://github.com/alibaba/formily/commit/acd6533d) :point_right: ( [Janry](https://github.com/Janry) )\n\n### :memo: Documents Changes\n\n1. [docs(antd): add close command demo (#3312)](https://github.com/alibaba/formily/commit/e718f2b2) :point_right: ( [moon](https://github.com/moon) )\n\n## v2.1.12(2022-08-04)\n\n### :bug: Bug Fixes\n\n1. [fix(path): fix getIn unexpect value with null (#3305)](https://github.com/alibaba/formily/commit/140aa524) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(react): update type of IRecursionFieldProps (#3291)](https://github.com/alibaba/formily/commit/42fcc28e) :point_right: ( [Elinia](https://github.com/Elinia) )\n\n1. [fix(vue): fix reactions not work correctly in schema field (#3287)](https://github.com/alibaba/formily/commit/551ad0f2) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n### :blush: Other Changes\n\n1. [chore(deps): bump terser from 4.8.0 to 4.8.1 (#3290)](https://github.com/alibaba/formily/commit/1314087a) :point_right: ( [dependabot[bot]](https://github.com/dependabot[bot]) )\n\n## v2.1.11(2022-07-19)\n\n### :tada: Enhancements\n\n1. [feat(antd/next): improve copy action ui (#3263)](https://github.com/alibaba/formily/commit/fd7b5f53) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(antd/next): add NumberPicker PreviewText (#3237)](https://github.com/alibaba/formily/commit/bfef03a6) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(antd): drawer support extra (#3213)](https://github.com/alibaba/formily/commit/ef218b9c) :point_right: ( [shaaaaaaaa](https://github.com/shaaaaaaaa) )\n\n1. [feat(element): add element style import description (#3188)](https://github.com/alibaba/formily/commit/4bca1108) :point_right: ( [KKandLL-Forever](https://github.com/KKandLL-Forever) )\n\n1. [feat(react): adjust component recognition priority (#3180)](https://github.com/alibaba/formily/commit/bf4e035c) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(json-schema): support x-compile-omitted attribute (#3145)](https://github.com/alibaba/formily/commit/c8485c0e) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(react): support dynamic scope (#3143)](https://github.com/alibaba/formily/commit/92945b0b) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(antd/next): react-sticky-box upgraded to 1.x (#3125)](https://github.com/alibaba/formily/commit/78479704) :point_right: ( [蜘蛛侠](https://github.com/蜘蛛侠) )\n\n1. [feat(core): support disable forceClear to clearFormGraph (#3122)](https://github.com/alibaba/formily/commit/d24168bb) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(core): improve readPretty restrict (#3105)](https://github.com/alibaba/formily/commit/67a555c3) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(docs): add element-plus doc link (#3086)](https://github.com/alibaba/formily/commit/4f13df32) :point_right: ( [Stephen Woo](https://github.com/Stephen Woo) )\n\n1. [feat(next): add TimPicker2 component (#3082)](https://github.com/alibaba/formily/commit/657fc298) :point_right: ( [yiye](https://github.com/yiye) )\n\n1. [feat(next/antd): fix SelectTable optionAsValue and add disabled props in ArrayBase icon button (#3072)](https://github.com/alibaba/formily/commit/43d0faa9) :point_right: ( [Lyca](https://github.com/Lyca) )\n\n1. [feat(antd/next): add style generator (#3053)](https://github.com/alibaba/formily/commit/fddd591a) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(next/antd): fix selected bug3 by search in SelectTable (#2927)](https://github.com/alibaba/formily/commit/bc943de3) :point_right: ( [Lyca](https://github.com/Lyca) )\n\n1. [feat(vue): improve performance of mapProps (#2909)](https://github.com/alibaba/formily/commit/5ca0456a) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [feat(vue): support x-slot (#2892)](https://github.com/alibaba/formily/commit/9e268aa8) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [feat(vue): improve expression scope (#2875)](https://github.com/alibaba/formily/commit/22a3d2bf) :point_right: ( [frehkxu](https://github.com/frehkxu) )\n\n1. [feat(antd/next): use full text matcha for SelectTable nd remove filterOptionProp](https://github.com/alibaba/formily/commit/127e0c7f) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(next): support checkStrictly props in SelectTable (#2824)](https://github.com/alibaba/formily/commit/feba6375) :point_right: ( [Lyca](https://github.com/Lyca) )\n\n1. [feat(antd/next): support 16427form scope with Form](https://github.com/alibaba/formily/commit/09a597f7) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(core): support index/indexes properties (#2769)](https://github.com/alibaba/formily/commit/36143ef0) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(next/antd/vue): add useResponsiveFormLayout fault tolerance and FormItem useOverflow update (#2707)](https://github.com/alibaba/formily/commit/98a544ac) :point_right: ( [Lyca](https://github.com/Lyca) )\n\n1. [feat(devtools): support select node to bind $vm with console (#2682)](https://github.com/alibaba/formily/commit/80ef0792) :point_right: ( [fuzi](https://github.com/fuzi) )\n\n1. [feat(reactive-vue): add observer option scheduler (#2672)](https://github.com/alibaba/formily/commit/ca55e484) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [feat(antd-component): provide `getPopupContainer` prop for `FormItem` when use popover feedback (#2619)](https://github.com/alibaba/formily/commit/69ff01cb) :point_right: ( [小翼](https://github.com/小翼) )\n\n1. [feat(element): support createFormGrid api (#2510)](https://github.com/alibaba/formily/commit/cadd63b3) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [feat(core): add setData & setContent of field models (#2478)](https://github.com/alibaba/formily/commit/f6d31032) :point_right: ( [DivX.Hu](https://github.com/DivX.Hu) )\n\n1. [feat(vue): add injectionCleaner to FormProvider (#2449)](https://github.com/alibaba/formily/commit/56c36468) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [feat(grid): support onDigest](https://github.com/alibaba/formily/commit/3c857a24) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(element): add ArrayTable/ArrayCollapse/ArrayTabs event (#2365)](https://github.com/alibaba/formily/commit/d54cdb8b) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [feat(next/antd): support breakpoints for FormLayout (#2336)](https://github.com/alibaba/formily/commit/c894adc8) :point_right: ( [Lyca](https://github.com/Lyca) )\n\n1. [feat(element): support useRecord for ArrayBase (#2313)](https://github.com/alibaba/formily/commit/74594663) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [feat(next): fix FormDialog footerActions/okProps/cancelProps (#2312)](https://github.com/alibaba/formily/commit/e2fe6734) :point_right: ( [Lyca](https://github.com/Lyca) )\n\n1. [feat(json-schema): support extend schema property (#2284)](https://github.com/alibaba/formily/commit/67ca5e58) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(react): fix schema x-component-props children invalid (#2160)](https://github.com/alibaba/formily/commit/7dc9d9ff) :point_right: ( [Lyca](https://github.com/Lyca) )\n\n1. [feat(reactive): support skip toJS with markRaw](https://github.com/alibaba/formily/commit/5d245511) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(element): radio/checkbox add optionType prop (#2114)](https://github.com/alibaba/formily/commit/54072a67) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [feat(next/antd): add tooltipIcon props to FormLayout & FormItem (#2085)](https://github.com/alibaba/formily/commit/1a817918) :point_right: ( [Lyca](https://github.com/Lyca) )\n\n1. [feat(designable): add icons for drag source](https://github.com/alibaba/formily/commit/8c14fa6e) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(designable): support componentsIcon/componentsSourceIcon](https://github.com/alibaba/formily/commit/5255e0da) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(core): support field destroy method (#1895)](https://github.com/alibaba/formily/commit/52457e10) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(antd/next): improve FormDialog/FormDrawer typings and api (#1886)](https://github.com/alibaba/formily/commit/e3d7d264) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(setters): add ValidatorSetter (#1885)](https://github.com/alibaba/formily/commit/4e2203e7) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(element): update array-table component & doc (#1862)](https://github.com/alibaba/formily/commit/f98129a9) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [feat(shared): add middleware function (#1858)](https://github.com/alibaba/formily/commit/e54525da) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(packages): add react 18 test cases (#1834)](https://github.com/alibaba/formily/commit/aa792203) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(reactive): support autorun.memo/autorun.effect (#1819)](https://github.com/alibaba/formily/commit/e43dda6a) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(project): support bundle dts (#1796)](https://github.com/alibaba/formily/commit/5f8c1879) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(form-dialog): add form dialog and form drawer oncancel return value (#1791)](https://github.com/alibaba/formily/commit/f08de0dc) :point_right: ( [张威](https://github.com/张威) )\n\n1. [feat(gitignore): support ignore .history directory (#1792)](https://github.com/alibaba/formily/commit/0035e61c) :point_right: ( [张威](https://github.com/张威) )\n\n1. [feat(antd): transfer compat label/value](https://github.com/alibaba/formily/commit/2be3a10d) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(core): skip validate when parent.visible is equal hidden/none (#1712)](https://github.com/alibaba/formily/commit/0076ef7d) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(designable-antd): support markup schema view](https://github.com/alibaba/formily/commit/2acb1033) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(vue): add components prop for schema-field (#1686)](https://github.com/alibaba/formily/commit/e9dec48f) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [feat(antd): improve Submit API (#1640)](https://github.com/alibaba/formily/commit/6b33ec9c) :point_right: ( [后浪](https://github.com/后浪) )\n\n1. [feat(reactive-react): support Observer Component like vue slot](https://github.com/alibaba/formily/commit/a49ee263) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(antd/next): add Form and Submit components submitFailed callback events (#1597)](https://github.com/alibaba/formily/commit/2517f807) :point_right: ( [后浪](https://github.com/后浪) )\n\n1. [feat(antd/next): add tree-shaking support for antd/next (#1544)](https://github.com/alibaba/formily/commit/6835f6d2) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [feat(core): support more types for dataSource](https://github.com/alibaba/formily/commit/6715555e) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(next): support form drawer get context from fusion (#1511)](https://github.com/alibaba/formily/commit/7fce306c) :point_right: ( [王大白](https://github.com/王大白) )\n\n1. [feat(next): add fusion multiple lang of validator (#1504)](https://github.com/alibaba/formily/commit/2ca07e7a) :point_right: ( [王大白](https://github.com/王大白) )\n\n1. [feat(antd): support defaultOpenPanelCount for ArrayCollapse (#1505)](https://github.com/alibaba/formily/commit/e9e3f74e) :point_right: ( [Lind](https://github.com/Lind) )\n\n1. [feat(next): add stopPropagation to array-base events](https://github.com/alibaba/formily/commit/276a5fbb) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(core): remove property of form values with undefined value (#1495)](https://github.com/alibaba/formily/commit/296eae47) :point_right: ( [小黄黄](https://github.com/小黄黄) )\n\n1. [feat(core): support value change trigger validate](https://github.com/alibaba/formily/commit/0473017a) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(core): add extra strategy for merge form value (#1448)](https://github.com/alibaba/formily/commit/0b5606d1) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [feat(vue): improve typings and docs(#1433)](https://github.com/alibaba/formily/commit/fc5d6650) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [feat(.md): Form => FormLayout (#1427)](https://github.com/alibaba/formily/commit/2501e72f) :point_right: ( [Lyca](https://github.com/Lyca) )\n\n1. [feat(next): improve styles](https://github.com/alibaba/formily/commit/bce90958) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat: url regexp support /?a=1 and ?a=1 (#1374)](https://github.com/alibaba/formily/commit/4fed6246) :point_right: ( [No.96](https://github.com/No.96) )\n\n1. [feat(shared): remove isValidElement types dependency](https://github.com/alibaba/formily/commit/b649228f) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(antd/next): export FormGrid props interface (#1327)](https://github.com/alibaba/formily/commit/733f7c26) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [feat(json-schema): add registerPolyfills/enablePolyfills api](https://github.com/alibaba/formily/commit/fd5eac5f) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(json-schema): add error when x-component can not found](https://github.com/alibaba/formily/commit/8bc884b3) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(json-schema): support alias style for x-reactions.dependencies](https://github.com/alibaba/formily/commit/b84a6244) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(form-item): support string format for labelWidth/wrapperWidth](https://github.com/alibaba/formily/commit/228e259c) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(effects): normoalize onFieldInit](https://github.com/alibaba/formily/commit/98922c8a) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat: add build style (#1201)](https://github.com/alibaba/formily/commit/3ceedb11) :point_right: ( [atzcl](https://github.com/atzcl) )\n\n1. [feat(project): rename fullfill=>fulfill](https://github.com/alibaba/formily/commit/0b794f11) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(reactive): recover batch.scope](https://github.com/alibaba/formily/commit/aeeb9f94) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(antd/next): update extract css name](https://github.com/alibaba/formily/commit/ea3d5194) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat: applicable less and scss to vite (#1187)](https://github.com/alibaba/formily/commit/fb011768) :point_right: ( [atzcl](https://github.com/atzcl) )\n\n1. [feat: add logic-diagram to Next and AntD (TBD) (#1158)](https://github.com/alibaba/formily/commit/5626d97d) :point_right: ( [soulwu](https://github.com/soulwu) )\n\n1. [feat: update antd message style](https://github.com/alibaba/formily/commit/b6d87da6) :point_right: ( [quirkyshop](https://github.com/quirkyshop) )\n\n1. [feat(react): update mapProps](https://github.com/alibaba/formily/commit/7940cab8) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat: move param-case to shared (#1152)](https://github.com/alibaba/formily/commit/6106257b) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [feat: add feedback layout](https://github.com/alibaba/formily/commit/df56cded) :point_right: ( [quirkyshop](https://github.com/quirkyshop) )\n\n1. [feat: update 'feedbackText'](https://github.com/alibaba/formily/commit/9e71f0c9) :point_right: ( [quirkyshop](https://github.com/quirkyshop) )\n\n1. [feat: add formitem demo](https://github.com/alibaba/formily/commit/5a263e68) :point_right: ( [guishu.zc](https://github.com/guishu.zc) )\n\n1. [feat(next): add FormGrid](https://github.com/alibaba/formily/commit/1805d8da) :point_right: ( [ZirkleTsing](https://github.com/ZirkleTsing) )\n\n1. [feat(vue): add vue3 compatibly (#1138)](https://github.com/alibaba/formily/commit/ac3783df) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [feat(react): connect add hoistNonReactStatics](https://github.com/alibaba/formily/commit/9b68f1ef) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(core): add more effects](https://github.com/alibaba/formily/commit/5b42226d) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat: update alignment (#1060)](https://github.com/alibaba/formily/commit/fadb3f7d) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [feat(core): support enableUnmountRemoveNode/disableUnmountRemoveNode API](https://github.com/alibaba/formily/commit/8f99e5b3) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat: add registerPreviewTextComponent (#1041)](https://github.com/alibaba/formily/commit/4b0f9768) :point_right: ( [soulwu](https://github.com/soulwu) )\n\n1. [feat: Add ja validation language (#1028) (#1029)](https://github.com/alibaba/formily/commit/6b65fbb9) :point_right: ( [Yaodong Li](https://github.com/Yaodong Li) )\n\n1. [feat(layout/docs): update docs and fix layout (#1003)](https://github.com/alibaba/formily/commit/16be58cc) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [feat(schema): add nested form polyfill (#972)](https://github.com/alibaba/formily/commit/6deb86d9) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [feat(components): add FormMegaLayout className (#935)](https://github.com/alibaba/formily/commit/7a2ad9e2) :point_right: ( [changfuguo](https://github.com/changfuguo) )\n\n1. [feat: add span to array-card dot for custom style (#922)](https://github.com/alibaba/formily/commit/4b2833d5) :point_right: ( [slientcloud](https://github.com/slientcloud) )\n\n1. [feat(layout): support responsive gri layout for older browsers (#916)](https://github.com/alibaba/formily/commit/f87e70dc) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [feat: add ie compat mode of grid(ie) (#912)](https://github.com/alibaba/formily/commit/b7313976) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [feat(layout): add ts type desc of MegaLayout and fix array-inc doc (#905)](https://github.com/alibaba/formily/commit/f37a0934) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [feat(layout): add inset mode for mega layout (#900)](https://github.com/alibaba/formily/commit/6f173317) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [feat: update snapshot and layout test for nested grid (#894)](https://github.com/alibaba/formily/commit/72619eca) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [feat: compile expression for array-table column title (#868)](https://github.com/alibaba/formily/commit/48fbcf0f) :point_right: ( [soulwu](https://github.com/soulwu) )\n\n1. [feat(docs): add antd TimePicker.RangePicker demo. (#811)](https://github.com/alibaba/formily/commit/fab22309) :point_right: ( [ShiCheng](https://github.com/ShiCheng) )\n\n1. [feat(antd-components): add default export (#810)](https://github.com/alibaba/formily/commit/0b4e64da) :point_right: ( [kenve](https://github.com/kenve) )\n\n1. [feat: add formily-meet documents (#797)](https://github.com/alibaba/formily/commit/03bbd0b7) :point_right: ( [DarK-AleX-alibaba](https://github.com/DarK-AleX-alibaba) )\n\n1. [feat(core): remove initializeLazySyncState](https://github.com/alibaba/formily/commit/70094beb) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat(schema-renderer): support relative target path (#779)](https://github.com/alibaba/formily/commit/f5fe4061) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(docs): add service worker cache (#745)](https://github.com/alibaba/formily/commit/a5879b72) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat: add recursive-render doc and fix some bugs (#736)](https://github.com/alibaba/formily/commit/d7199d82) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(hooks): add onSubmit hook and docs (#727)](https://github.com/alibaba/formily/commit/b99be566) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [feat(core): support pass FormPathPattern to createMutators, and fix some typings (#728)](https://github.com/alibaba/formily/commit/c0798c6d) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(core): change visible behavior to fix array list delete auto assign value not work (#725)](https://github.com/alibaba/formily/commit/366047e6) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(prject): access unified log module (#723)](https://github.com/alibaba/formily/commit/750ef0af) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(shared): support BigData (#708)](https://github.com/alibaba/formily/commit/7343b960) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat: add wiki (#705)](https://github.com/alibaba/formily/commit/9b2126c9) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat: url type support rtmp (#686)](https://github.com/alibaba/formily/commit/084cbc03) :point_right: ( [Desen Meng](https://github.com/Desen Meng) )\n\n1. [feat: add components and hooks (#670)](https://github.com/alibaba/formily/commit/ef9bc68e) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [feat(@uform/devtools): update lerna config (#635)](https://github.com/alibaba/formily/commit/7ca92451) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(@uform/core): reset add clearInitialValue (#627)](https://github.com/alibaba/formily/commit/02e715ce) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat: update formitem props (#614)](https://github.com/alibaba/formily/commit/1ff5f8bc) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [feat: use react-drag-listview instead of ReactDnD and support antd draggable table (#609)](https://github.com/alibaba/formily/commit/88ce573b) :point_right: ( [soulwu](https://github.com/soulwu) )\n\n1. [feat(@uform/core)support visible cache values and intialValues sync action (#588)](https://github.com/alibaba/formily/commit/7bceed76) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat: support change fieldKey](https://github.com/alibaba/formily/commit/ffc8f6a7) :point_right: ( [ziyi.hzy](https://github.com/ziyi.hzy) )\n\n1. [feat: add dragable to @uform/next table field (#561)](https://github.com/alibaba/formily/commit/4c947306) :point_right: ( [soulwu](https://github.com/soulwu) )\n\n1. [featfix(@uform/react-schema-renderer/antd/next) doc and depreacate x-render (#557)](https://github.com/alibaba/formily/commit/2bd1503b) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [feat: FieldEditor UI 优化](https://github.com/alibaba/formily/commit/071058e4) :point_right: ( [秋逢](https://github.com/秋逢) )\n\n1. [feat: update unitest and document (#476)](https://github.com/alibaba/formily/commit/8c49ca9a) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [feat: json to basic schema (#450)](https://github.com/alibaba/formily/commit/785a760d) :point_right: ( [大康](https://github.com/大康) )\n\n1. [feat: 表达式 value](https://github.com/alibaba/formily/commit/73c90914) :point_right: ( [秋逢](https://github.com/秋逢) )\n\n1. [feat: fix bug](https://github.com/alibaba/formily/commit/bfd76328) :point_right: ( [ascoders](https://github.com/ascoders) )\n\n1. [feat(@uform/next): update next features (#439)](https://github.com/alibaba/formily/commit/15b6b43e) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(@uform/react): actions support clearErrors (#434)](https://github.com/alibaba/formily/commit/551d74c1) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat: 规则](https://github.com/alibaba/formily/commit/fa6215dc) :point_right: ( [秋逢](https://github.com/秋逢) )\n\n1. [feat(@uform/react): remove raf and fix unittest (#422)](https://github.com/alibaba/formily/commit/670fadbe) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [feat(@uform/core): support pass visible/display of register method (#421)](https://github.com/alibaba/formily/commit/908882a2) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat: support useFormEffects (#403)](https://github.com/alibaba/formily/commit/dff959c8) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat: 临时交互对焦](https://github.com/alibaba/formily/commit/bed060ff) :point_right: ( [秋逢](https://github.com/秋逢) )\n\n1. [feat: add docs and some test cases (#395)](https://github.com/alibaba/formily/commit/ecff8eff) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat: add react/actions tests](https://github.com/alibaba/formily/commit/21ee40b1) :point_right: ( [anyuxuan](https://github.com/anyuxuan) )\n\n1. [feat: 添加 next components schema](https://github.com/alibaba/formily/commit/1b184a6c) :point_right: ( [秋逢](https://github.com/秋逢) )\n\n1. [feat: add silent option (#377)](https://github.com/alibaba/formily/commit/43771809) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [feat(shared): add unit test (#374)](https://github.com/alibaba/formily/commit/9cd72725) :point_right: ( [s0ngyee](https://github.com/s0ngyee) )\n\n1. [feat(docs): support deconstruction (#179)](https://github.com/alibaba/formily/commit/b114c9e7) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(@uform/core): Improve noValidate reset logic](https://github.com/alibaba/formily/commit/efaa75a8) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [feat: update the api docs using typescript (#149)](https://github.com/alibaba/formily/commit/5a9ea5a2) :point_right: ( [Kevin Tan](https://github.com/Kevin Tan) )\n\n1. [feat: make scheduler optional (#141)](https://github.com/alibaba/formily/commit/ed52e4a7) :point_right: ( [Kevin Tan](https://github.com/Kevin Tan) )\n\n1. [feat(@uform/antd/next): Optimize the description of the word count calculation rules and docs #117](https://github.com/alibaba/formily/commit/65c449e0) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(@uform/antd): support form layout properties #116](https://github.com/alibaba/formily/commit/e9cc882d) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [feat(refactor): perfect test suites and add builder demo in docs (#100)](https://github.com/alibaba/formily/commit/ada8ba9f) :point_right: ( [SkyCai](https://github.com/SkyCai) )\n\n1. [feat(@uform/types): update validator type description](https://github.com/alibaba/formily/commit/6763583a) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [feat(@uform/utils): support ts, but build scripts is not work](https://github.com/alibaba/formily/commit/8e452149) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [feat(@uform/next): add disabled when loading](https://github.com/alibaba/formily/commit/1b1d70db) :point_right: ( [monkindey](https://github.com/monkindey) )\n\n1. [feat(@uform/react): Optimize package size and fixing onFieldChange initialization trigger twice](https://github.com/alibaba/formily/commit/a98c247b) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [feat(packages): some the antd component and the react component](https://github.com/alibaba/formily/commit/c663abc0) :point_right: ( [zsirfs](https://github.com/zsirfs) )\n\n1. [feat(fix): add builder-next package and fix builder bugs. fix(docs): update playground link and fix some bugs](https://github.com/alibaba/formily/commit/71e6af8a) :point_right: ( [cnt1992](https://github.com/cnt1992) )\n\n1. [feat(@uform/next/antd): support mapTextComponent and mapStyledProps](https://github.com/alibaba/formily/commit/b0f7134d) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [feat(utils): export path destruct string parse methods.](https://github.com/alibaba/formily/commit/1bded6c3) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [feat(fix): fix style](https://github.com/alibaba/formily/commit/7841970d) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n### :bug: Bug Fixes\n\n1. [fix(react): fix useAttach not work with react18 strict mode (#3284)](https://github.com/alibaba/formily/commit/9df806b5) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix: doc (#3280)](https://github.com/alibaba/formily/commit/8569c0fe) :point_right: ( [Creabine](https://github.com/Creabine) )\n\n1. [fix(antd): use Select fieldNames (#3275)](https://github.com/alibaba/formily/commit/edf7a9f9) :point_right: ( [yiyunwan](https://github.com/yiyunwan) )\n\n1. [fix(antd/next): fix array components lose reactive (#3266)](https://github.com/alibaba/formily/commit/9107e86c) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(antd/next): fix Cascader in form readPretty mode display error #3250 (#3253)](https://github.com/alibaba/formily/commit/d5719100) :point_right: ( [风](https://github.com/风) )\n\n1. [fix(core): fix memo leak of onFieldReact/onFieldChange (#3231)](https://github.com/alibaba/formily/commit/d1c44513) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(antd/next): react 18 createRoot warning (#3226)](https://github.com/alibaba/formily/commit/cc1f5d48) :point_right: ( [csc-bo](https://github.com/csc-bo) )\n\n1. [fix(reactive-react): fix useLayoutEffect warning in server render (#3228)](https://github.com/alibaba/formily/commit/8c9ab06b) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix: vue3 slots.default do not always exist (#3192)](https://github.com/alibaba/formily/commit/91d64889) :point_right: ( [qq1037305420](https://github.com/qq1037305420) )\n\n1. [fix(core): fix set initialValue no cache value when display none (#3182)](https://github.com/alibaba/formily/commit/66ffeb6c) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(react): fix field wrong mounted state (#3181)](https://github.com/alibaba/formily/commit/d705f56d) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix: typo (#3169)](https://github.com/alibaba/formily/commit/0cb920d2) :point_right: ( [Adel](https://github.com/Adel) )\n\n1. [fix(antd): fix array table lose focus (#3160)](https://github.com/alibaba/formily/commit/8ee5ba51) :point_right: ( [Grapedge](https://github.com/Grapedge) )\n\n1. [fix(next): fix space item empty style (#3149)](https://github.com/alibaba/formily/commit/18700a90) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix: add Component Ecology: semi for zhCN (#3146)](https://github.com/alibaba/formily/commit/4eee3574) :point_right: ( [programmerwy](https://github.com/programmerwy) )\n\n1. [fix(antd): remove radio button border right color compat codes (#3144)](https://github.com/alibaba/formily/commit/abefbeac) :point_right: ( [蜘蛛侠](https://github.com/蜘蛛侠) )\n\n1. [fix(core): fix onInput should not filter value with target (#3140)](https://github.com/alibaba/formily/commit/e1a2a65e) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix: fix ArrayTable skipping validation of new page (#3117)](https://github.com/alibaba/formily/commit/99f669a8) :point_right: ( [maurice](https://github.com/maurice) )\n\n1. [fix: compat FormItem styles for chrome88 (#3121)](https://github.com/alibaba/formily/commit/9eb73067) :point_right: ( [陈为响](https://github.com/陈为响) )\n\n1. [fix(core): fix field destroyed still can be assigned value (#3115)](https://github.com/alibaba/formily/commit/5dd9acce) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(core): fix errors filter (#3113)](https://github.com/alibaba/formily/commit/7d731af5) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(next): fix ArrayCollapse extra (#3106)](https://github.com/alibaba/formily/commit/39e26a83) :point_right: ( [oldchicken](https://github.com/oldchicken) )\n\n1. [fix(next/antd): fix form-collapse pass defaultActiveKey (#3107)](https://github.com/alibaba/formily/commit/793cae98) :point_right: ( [Jehu](https://github.com/Jehu) )\n\n1. [fix(react): update react peerDependencies (#3096)](https://github.com/alibaba/formily/commit/6e939d82) :point_right: ( [蜘蛛侠](https://github.com/蜘蛛侠) )\n\n1. [fix: fix rollup.base.js externals antd name (#3084)](https://github.com/alibaba/formily/commit/a4029fbe) :point_right: ( [ickeep](https://github.com/ickeep) )\n\n1. [fix(next): fix FormDrawer demo error (#3080)](https://github.com/alibaba/formily/commit/79d94774) :point_right: ( [Lyca](https://github.com/Lyca) )\n\n1. [fix(reactive-vue): stop tracking if watcher is destroyed #3074 (#3075)](https://github.com/alibaba/formily/commit/c2b7ba91) :point_right: ( [lcch](https://github.com/lcch) )\n\n1. [fix(core): fix field validateFirst not working (#3071)](https://github.com/alibaba/formily/commit/82af5e16) :point_right: ( [ryuurock](https://github.com/ryuurock) )\n\n1. [fix(vue): fix render loop cause by functional component in mapProps (#3070)](https://github.com/alibaba/formily/commit/0d15fe96) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [fix(vue): fix unexpected dep collection during $mount() #3015 (#3065)](https://github.com/alibaba/formily/commit/b2128aeb) :point_right: ( [lcch](https://github.com/lcch) )\n\n1. [fix(antd): fix the problem that when optionAsValue, the value is lost when searched or paged (#3064)](https://github.com/alibaba/formily/commit/43fbf031) :point_right: ( [Ray](https://github.com/Ray) )\n\n1. [fix(path): fix range all match is not expect (#3067)](https://github.com/alibaba/formily/commit/04e753f5) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(core): fix array child reactions invalid with remove (#3063)](https://github.com/alibaba/formily/commit/34e9420b) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(next): fix date time picker value format (#3044)](https://github.com/alibaba/formily/commit/cee97228) :point_right: ( [Eric Zhang](https://github.com/Eric Zhang) )\n\n1. [fix(antd/next): form step setCurrent bug (#3039)](https://github.com/alibaba/formily/commit/7aba4847) :point_right: ( [戣蓦](https://github.com/戣蓦) )\n\n1. [fix(antd/next): valueType should not be required attribute since it has default value (#3036)](https://github.com/alibaba/formily/commit/7b8669ba) :point_right: ( [戣蓦](https://github.com/戣蓦) )\n\n1. [fix(antd/next): fix form tab type check issue (#3025)](https://github.com/alibaba/formily/commit/f0511355) :point_right: ( [戣蓦](https://github.com/戣蓦) )\n\n1. [fix(antd): fix error, can't read 'length' of undefined (#3020) (#3021)](https://github.com/alibaba/formily/commit/10503b83) :point_right: ( [melodyYang](https://github.com/melodyYang) )\n\n1. [fix(antd/next): fix cascader preview text exception errors (#3000)](https://github.com/alibaba/formily/commit/a48252b6) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(antd/next): fix array string field addition logic (#2998)](https://github.com/alibaba/formily/commit/888dc47e) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(next/antd): fix array base type (#2994)](https://github.com/alibaba/formily/commit/b202c0d5) :point_right: ( [Jehu](https://github.com/Jehu) )\n\n1. [fix(reactive-vue): fix the exception of multiple update nodes in vue3 case (#2991)](https://github.com/alibaba/formily/commit/90486ecb) :point_right: ( [e_the](https://github.com/e_the) )\n\n1. [fix: fix destroy can not remove value/initialValues and FormStep reactive strategy (#2988)](https://github.com/alibaba/formily/commit/4d18c9e7) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(antd): StepPane & createFormStep should not be optional property (#2979)](https://github.com/alibaba/formily/commit/1c6970c5) :point_right: ( [戣蓦](https://github.com/戣蓦) )\n\n1. [fix(antd): fix ConfigProvider.ConfigContext error in antd@4.6.3- (#2956)](https://github.com/alibaba/formily/commit/3bdfe2f2) :point_right: ( [Lyca](https://github.com/Lyca) )\n\n1. [fix(antd/next): fix null in dataSource error in SelectTable (#2952)](https://github.com/alibaba/formily/commit/2d428941) :point_right: ( [Lyca](https://github.com/Lyca) )\n\n1. [fix(next/antd): fix single value invalid in PreviewText.Cascader (#2940)](https://github.com/alibaba/formily/commit/33a54e7a) :point_right: ( [Lyca](https://github.com/Lyca) )\n\n1. [fix(grid): fix grid mutation observer infinite loop (#2925)](https://github.com/alibaba/formily/commit/72534b43) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(validator): fix unexpect validate with empty format (#2926)](https://github.com/alibaba/formily/commit/7da26285) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(vue): fix error when designable is true (#2908)](https://github.com/alibaba/formily/commit/398fac96) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [fix(core): fix empty string or number can not rewrite default value (#2906)](https://github.com/alibaba/formily/commit/b6c3e311) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(reactive-vue): fix vue3 render dependency collection broken (#2904)](https://github.com/alibaba/formily/commit/b226760e) :point_right: ( [e_the](https://github.com/e_the) )\n\n1. [fix(element-components): fix formitem feedback msg (#2899)](https://github.com/alibaba/formily/commit/8d201778) :point_right: ( [skyfore](https://github.com/skyfore) )\n\n1. [fix(antd/next): remove host element after unmount in portal (#2900)](https://github.com/alibaba/formily/commit/a2af5c94) :point_right: ( [zhouxinyong](https://github.com/zhouxinyong) )\n\n1. [fix(antd/next): fix ArrayItems sortItem style (#2893)](https://github.com/alibaba/formily/commit/1ef47b0a) :point_right: ( [zhouxinyong](https://github.com/zhouxinyong) )\n\n1. [fix(antd/next): disable label/wrapper col when vertical layout](https://github.com/alibaba/formily/commit/119fd389) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(vue): fix FormConsumer not update correctly (#2888)](https://github.com/alibaba/formily/commit/4e39c082) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [fix(antd): fix use treeData props for PreviewText.TreeSelect (#2867)](https://github.com/alibaba/formily/commit/edcc9544) :point_right: ( [Dark](https://github.com/Dark) )\n\n1. [fix(core): fix relative match can not skip void field (#2850)](https://github.com/alibaba/formily/commit/e7c99843) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(shared): fix merge empty object is not work (#2841)](https://github.com/alibaba/formily/commit/28a58530) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(vue): add component name in connect (#2810)](https://github.com/alibaba/formily/commit/5a695c06) :point_right: ( [zhouxinyong](https://github.com/zhouxinyong) )\n\n1. [fix(core): fix reset can not clear value in array list (#2775)](https://github.com/alibaba/formily/commit/064e13aa) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(antd): fix ArrayTabs auto switch activeKey (#2774)](https://github.com/alibaba/formily/commit/72e0bdbd) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix: correct indian rupee regexp (#2714)](https://github.com/alibaba/formily/commit/b2269019) :point_right: ( [catch on me](https://github.com/catch on me) )\n\n1. [fix(element): fix ArrayTable style error (#2760)](https://github.com/alibaba/formily/commit/3b24f7f7) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [fix(antd/next): fix Editable component can not set default editable](https://github.com/alibaba/formily/commit/88915bc5) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(antd/next): fix tool methods and provide simple unit tests (#2694)](https://github.com/alibaba/formily/commit/475d10e9) :point_right: ( [小翼](https://github.com/小翼) )\n\n1. [fix(vue): fix postinstall error (#2684)](https://github.com/alibaba/formily/commit/d4b9133f) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [fix(core): fix void array items node need skip (#2683)](https://github.com/alibaba/formily/commit/a67ab3a4) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(path): update README.md (#2677)](https://github.com/alibaba/formily/commit/589e74bf) :point_right: ( [AlexStacker](https://github.com/AlexStacker) )\n\n1. [fix(element): fix usePlaceholder not update error (#2646)](https://github.com/alibaba/formily/commit/550d0a6a) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [fix(grid): add resize-observer-polyfill (#2630)](https://github.com/alibaba/formily/commit/8c234a8a) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(vue): fix format vue3 h function props (#2609)](https://github.com/alibaba/formily/commit/e2dfc0bc) :point_right: ( [zhaowei-plus](https://github.com/zhaowei-plus) )\n\n1. [fix(antd/next): fix FormItem.label can not shown in void field](https://github.com/alibaba/formily/commit/f2bd220c) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(json-schema): fix reactions isolate effect (#2590)](https://github.com/alibaba/formily/commit/f04deb13) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(react): fix doc link (#2584)](https://github.com/alibaba/formily/commit/4faa406d) :point_right: ( [燃冰](https://github.com/燃冰) )\n\n1. [fix(next): fix missing ExclamationCircleOutlined Icon (#2564)](https://github.com/alibaba/formily/commit/33d8d278) :point_right: ( [Lyca](https://github.com/Lyca) )\n\n1. [fix(reactive): fix unexpect effect in reactions (#2563)](https://github.com/alibaba/formily/commit/8f8db67a) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(vue): fix void field children is not undefined (#2551)](https://github.com/alibaba/formily/commit/f5a1d1bb) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(next): fix Space align is not work (#2531)](https://github.com/alibaba/formily/commit/3f4afef1) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(element): add optinal chain to FormItem useOverflow hook (#2519)](https://github.com/alibaba/formily/commit/da189834) :point_right: ( [qq1037305420](https://github.com/qq1037305420) )\n\n1. [fix(next): fix the antd-icons is not removed cleanly](https://github.com/alibaba/formily/commit/4e7a4626) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(core): fix required validate with wrong order (#2508)](https://github.com/alibaba/formily/commit/f0ac9918) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(core): fix validator will trigger multi times with duplicate triggerTypes (#2495)](https://github.com/alibaba/formily/commit/88d6f83b) :point_right: ( [nexx](https://github.com/nexx) )\n\n1. [fix(grid): fix calc origin columns (#2468)](https://github.com/alibaba/formily/commit/1a9e37b4) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix: fix validator notify error message of Antd Upload Item (#2433)](https://github.com/alibaba/formily/commit/8e4a6a98) :point_right: ( [jazzjia](https://github.com/jazzjia) )\n\n1. [fix(grid): fix build by removing build:global (#2417)](https://github.com/alibaba/formily/commit/0d78006d) :point_right: ( [Deng Ruoqi](https://github.com/Deng Ruoqi) )\n\n1. [fix(grid): fix grid calculate failed when container was hidden (#2400)](https://github.com/alibaba/formily/commit/18a09d42) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(core): fix reset should clear field caches (#2401)](https://github.com/alibaba/formily/commit/6b1162ad) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(reactive): fix computed value can not get real value (#2389)](https://github.com/alibaba/formily/commit/eb34b2de) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(core): fix default is not work when name is length (#2387)](https://github.com/alibaba/formily/commit/0adf07ab) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix: fix decorator attrs is not passed down correctly (#2369)](https://github.com/alibaba/formily/commit/fee4af03) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [fix(vue): view should updated when schema changed (#2354)](https://github.com/alibaba/formily/commit/4b3d092d) :point_right: ( [Amorites](https://github.com/Amorites) )\n\n1. [fix(core): make exchangeArrayState be right when move (#2357)](https://github.com/alibaba/formily/commit/a2189465) :point_right: ( [折木](https://github.com/折木) )\n\n1. [fix(react): fix incorrect dts in useFieldSchema (#2350)](https://github.com/alibaba/formily/commit/e8781032) :point_right: ( [Jingkun Hua](https://github.com/Jingkun Hua) )\n\n1. [fix(core): fix initialValues merge with no fields (#2339)](https://github.com/alibaba/formily/commit/9c2ebc36) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(schema): fix setValidateRule will throw error when use void field (#2281)](https://github.com/alibaba/formily/commit/d752b221) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(core): fix validate lifecycle wrong trigger in skip digest (#2279)](https://github.com/alibaba/formily/commit/1ac87fb4) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(validator): getValidatorLocale Maximum call stack size exceeded (#2273)](https://github.com/alibaba/formily/commit/200253e0) :point_right: ( [Suel](https://github.com/Suel) )\n\n1. [fix(reactive): fix batch api can not throw error (#2268)](https://github.com/alibaba/formily/commit/07227ad2) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(vue): fix the problem that the component class name will be overwritten rather than merged (#2260)](https://github.com/alibaba/formily/commit/73053737) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [fix(element): fix form props pass bug (#2253)](https://github.com/alibaba/formily/commit/71859771) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [fix(vue): fix vue2 scopedSlot and slot pass problem (#2221)](https://github.com/alibaba/formily/commit/2489182c) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [fix(antd/next): fix props.prefix is not work for FormGrid/FormLayout (#2151)](https://github.com/alibaba/formily/commit/bcdac582) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(core): fix array unshift with incomplete elements (#2150)](https://github.com/alibaba/formily/commit/64633714) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(path): fix path match destructor (#2148)](https://github.com/alibaba/formily/commit/f621d989) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(next/antd/vue): fix Switch type & add classname to ArrayItems.Index (#2093)](https://github.com/alibaba/formily/commit/9f875692) :point_right: ( [Lyca](https://github.com/Lyca) )\n\n1. [fix(designable): fix Uncaught SyntaxError (#1997) (#2089)](https://github.com/alibaba/formily/commit/b56b5b28) :point_right: ( [youshao](https://github.com/youshao) )\n\n1. [fix(core): fix add effects memo leak in form umount (#2050)](https://github.com/alibaba/formily/commit/f753ba12) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(element): remove Formily namepsace usecase](https://github.com/alibaba/formily/commit/0cc90672) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(vue): fix 'x-content' render named slot not work (#2046)](https://github.com/alibaba/formily/commit/71fb9814) :point_right: ( [jiezi19971225](https://github.com/jiezi19971225) )\n\n1. [fix(designable-antd): fix locales](https://github.com/alibaba/formily/commit/27be2651) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(designable): fix can not drag object to array cards in initialization](https://github.com/alibaba/formily/commit/99b46a3e) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(next): fix usePrefixCls tag undefined (#2042)](https://github.com/alibaba/formily/commit/9af2dda7) :point_right: ( [hellohy](https://github.com/hellohy) )\n\n1. [fix(next): fix fullness icon width (#2020)](https://github.com/alibaba/formily/commit/8c4651fb) :point_right: ( [Lyca](https://github.com/Lyca) )\n\n1. [fix(antd): fix form size=large bug (#1998) (#2008)](https://github.com/alibaba/formily/commit/3edd6e89) :point_right: ( [Grapedge](https://github.com/Grapedge) )\n\n1. [fix(designable-next): fix style and support history (#2007)](https://github.com/alibaba/formily/commit/7e9c9cbd) :point_right: ( [Grapedge](https://github.com/Grapedge) )\n\n1. [fix(next): fix range and transfer styles in FormItem](https://github.com/alibaba/formily/commit/cd9c2159) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(next): fix config provider prefix bug (#2000) (#2002)](https://github.com/alibaba/formily/commit/32746f77) :point_right: ( [Grapedge](https://github.com/Grapedge) )\n\n1. [fix(vue): prop \"scope\" of SchemaField not work with x-reactions (#1976)](https://github.com/alibaba/formily/commit/05e14cea) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [fix(next): fix mapStatus takeState](https://github.com/alibaba/formily/commit/576c9b56) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(antd): fix dark label color](https://github.com/alibaba/formily/commit/c1e5b0f4) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(shared): fix applyMiddleware can not catch error (#1952)](https://github.com/alibaba/formily/commit/22f0379a) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(next): fix FormTab activeKey bug (#1945)](https://github.com/alibaba/formily/commit/29024475) :point_right: ( [Grapedge](https://github.com/Grapedge) )\n\n1. [fix(next): add the default language when the language is undefined (#1939)](https://github.com/alibaba/formily/commit/c74e7f91) :point_right: ( [Grapedge](https://github.com/Grapedge) )\n\n1. [fix(next/designable-antd): fix Select bug && designable-antd spelling error (#1934)](https://github.com/alibaba/formily/commit/739e8c18) :point_right: ( [Grapedge](https://github.com/Grapedge) )\n\n1. [fix(next): fix size style in FormItem/main.scss && set default fullness true (#1908)](https://github.com/alibaba/formily/commit/c0e2c126) :point_right: ( [Lyca](https://github.com/Lyca) )\n\n1. [fix(element): fix protal destroy (#1898)](https://github.com/alibaba/formily/commit/1036440c) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [fix(designable-antd): remove switch optionType: 'button' (#1891)](https://github.com/alibaba/formily/commit/c136e349) :point_right: ( [aloha](https://github.com/aloha) )\n\n1. [fix(react): fix select type validate error #1838 (#1844)](https://github.com/alibaba/formily/commit/b7975baf) :point_right: ( [张威](https://github.com/张威) )\n\n1. [fix(antd): fix sideEffects mismatch when use babel-plugin-import (#1843)](https://github.com/alibaba/formily/commit/eaccb72a) :point_right: ( [KM.Seven](https://github.com/KM.Seven) )\n\n1. [fix(core): fix object field's children auto clean but they are not additionalProperty (#1840)](https://github.com/alibaba/formily/commit/dd313646) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(core): fix ArrayField operation will trigger memo leak (#1831)](https://github.com/alibaba/formily/commit/021c155a) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(path): fix segments match (#1826)](https://github.com/alibaba/formily/commit/6e541dcb) :point_right: ( [砂糖梨子](https://github.com/砂糖梨子) )\n\n1. [fix(antd/next): form-grid and layout props optional with default value (#1809)](https://github.com/alibaba/formily/commit/2738e418) :point_right: ( [gwsbhqt](https://github.com/gwsbhqt) )\n\n1. [fix(vue): fix field doesnt update correctly in designable mode (#1799)](https://github.com/alibaba/formily/commit/837cfc0b) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [fix(element): fix vuepress doc not identify fetch (#1769)](https://github.com/alibaba/formily/commit/bc4348e3) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [fix(element): add rollup external to fix element package size (#1766)](https://github.com/alibaba/formily/commit/8104dbfb) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [fix(vue): fix vue typing (#1730)](https://github.com/alibaba/formily/commit/b51a2198) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [fix(react): fix x-content is not work with array type (#1719)](https://github.com/alibaba/formily/commit/2cd60d32) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(reactive): fix Tracker memo leak in StrictMode (#1715)](https://github.com/alibaba/formily/commit/e9f23c39) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(json-schema): fix typo about transformer](https://github.com/alibaba/formily/commit/498d3119) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(core): fix lifecycle not working after call form.setXXX (#1699)](https://github.com/alibaba/formily/commit/01c5fb89) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [fix(shared): fix defaults merge with null will get unexpect results #1644](https://github.com/alibaba/formily/commit/d39c426f) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(json-schema): fix findComponent return unexpected result (#1625)](https://github.com/alibaba/formily/commit/3453c69d) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [fix(antd/next): remove FormButtonGroup.FormItem colon #1623](https://github.com/alibaba/formily/commit/48137547) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(antd): fix DatePicker week formatting errors (#1614)](https://github.com/alibaba/formily/commit/dbdd1984) :point_right: ( [sun](https://github.com/sun) )\n\n1. [fix(vue): fix unmount a field in a wrong lifecycle function.(#1609) (#1611)](https://github.com/alibaba/formily/commit/26896482) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [fix(types): fix global.d.ts](https://github.com/alibaba/formily/commit/df8561d6) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(project): fix typings](https://github.com/alibaba/formily/commit/c8aff09b) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(vue): add deep copy to decorator props (#1587)](https://github.com/alibaba/formily/commit/710f5e1b) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [fix(core): fix createForm memory leak](https://github.com/alibaba/formily/commit/5f11459b) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(antd/next): fix arrayCollapse will throw error in accordion mode](https://github.com/alibaba/formily/commit/4c88ca7f) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(next): fix style missing due to wrong sideEffects (#1564)](https://github.com/alibaba/formily/commit/9fb8b93e) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [fix(antd/next): fix dumi lost style due to treeshaking (#1549)](https://github.com/alibaba/formily/commit/20d6b4f2) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [fix(core): fix array path calculation #1533](https://github.com/alibaba/formily/commit/29249000) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(react): fix useFormEffects not support StrictMode #1491](https://github.com/alibaba/formily/commit/0198b0c4) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(core): fix field value restored incorrectly when hidden toggled (#1529)](https://github.com/alibaba/formily/commit/047c98af) :point_right: ( [JustDs](https://github.com/JustDs) )\n\n1. [fix(vue): remove empty default slots of fields (#1517)](https://github.com/alibaba/formily/commit/00a80b4b) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [fix(react): fix ReactComponentPropsByPathValue type return error result (#1507)](https://github.com/alibaba/formily/commit/fb7654eb) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [fix(core): fix reactive query #1494](https://github.com/alibaba/formily/commit/a0ca5b2b) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(validator): fix typo](https://github.com/alibaba/formily/commit/b1a83d2b) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(path): fix realative path for sibling in array (#1492)](https://github.com/alibaba/formily/commit/860264d6) :point_right: ( [JustDs](https://github.com/JustDs) )\n\n1. [fix(json-schema): remove array patch state logic](https://github.com/alibaba/formily/commit/73bd9a47) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(antd/next): fix gridSpan calculate algorithm (#1440)](https://github.com/alibaba/formily/commit/3b1f1cfa) :point_right: ( [Nokecy](https://github.com/Nokecy) )\n\n1. [fix(antd): fix btn is too big in small mode (#1455)](https://github.com/alibaba/formily/commit/c33df277) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [fix(vue): fix a type error in ISchemaMarkupFieldProps (#1454)](https://github.com/alibaba/formily/commit/43abadc5) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [fix(core): fix the effects of IFormProps losing generic type (#1418)](https://github.com/alibaba/formily/commit/ee8d118d) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [fix Form.submit miss return values (#1382)](https://github.com/alibaba/formily/commit/57c2c1b3) :point_right: ( [林法鑫](https://github.com/林法鑫) )\n\n1. [fix(doc): fix next doc (#1385)](https://github.com/alibaba/formily/commit/77e2c486) :point_right: ( [Lind](https://github.com/Lind) )\n\n1. [fix(antd/next): fix the feedbackLayout type definition error of the form-layout (#1372)](https://github.com/alibaba/formily/commit/3c5f6f7c) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [fix json-schema SchemaReaction type error (#1367)](https://github.com/alibaba/formily/commit/adae3da5) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [fix(reactive-react): fix browser crash in strict-mode async linkages scence](https://github.com/alibaba/formily/commit/feb64875) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(next): fix scss variables](https://github.com/alibaba/formily/commit/c99a380e) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(vue): mapProps、mapReadPretty listeners bug](https://github.com/alibaba/formily/commit/b5f39ce0) :point_right: ( [p(^-^q)](<https://github.com/p(^-^q)>) )\n\n1. [fix(array-table): give toFieldProps an options](https://github.com/alibaba/formily/commit/edf3cab2) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(antd): fix validated form-item box-shadow styles (#1265)](https://github.com/alibaba/formily/commit/589b9b8b) :point_right: ( [Fog3211](https://github.com/Fog3211) )\n\n1. [fix(react/vue): fix onChange can not pass to voidField's component props. (#1264)](https://github.com/alibaba/formily/commit/1764f6ee) :point_right: ( [林法鑫](https://github.com/林法鑫) )\n\n1. [fix(core): fix reset logic for ArrayField/ObjectField](https://github.com/alibaba/formily/commit/909c5907) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(reactive): fix tojs recursive dependence stack overflow (#1245)](https://github.com/alibaba/formily/commit/675df0ce) :point_right: ( [gwsbhqt](https://github.com/gwsbhqt) )\n\n1. [fix(core): rollback onFieldInit behavior](https://github.com/alibaba/formily/commit/15f9a56d) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(antd): Prevent native events bubbles](https://github.com/alibaba/formily/commit/11e14a39) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(core): Fix the problem of onChange event catching exception](https://github.com/alibaba/formily/commit/8d6e1c2b) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(path): fix accessor](https://github.com/alibaba/formily/commit/4fde9ca0) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(antd): fix multiple select small/large styles](https://github.com/alibaba/formily/commit/7b628cef) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix antd styles (#1181)](https://github.com/alibaba/formily/commit/2083b01e) :point_right: ( [Dark](https://github.com/Dark) )\n\n1. [fix(core): untracked update values](https://github.com/alibaba/formily/commit/4b54d376) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix: use form.setValuesIn instead of field.removeProperty (#1160)](https://github.com/alibaba/formily/commit/f5fc7e61) :point_right: ( [soulwu](https://github.com/soulwu) )\n\n1. [fix(form-grid): improve performace](https://github.com/alibaba/formily/commit/f1b7afd2) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(core): fix observable componentProps](https://github.com/alibaba/formily/commit/dfe2e213) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(devtools): fix serialize function](https://github.com/alibaba/formily/commit/36aef5b8) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(core): Fix the problem that the initialValues cannot be synchronized to values repeatedly](https://github.com/alibaba/formily/commit/09e0f70b) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(next): fix month picker (#1115)](https://github.com/alibaba/formily/commit/f77b2ca2) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(vue): fix connect](https://github.com/alibaba/formily/commit/727169ba) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix: fix form help validate status error (#1071)](https://github.com/alibaba/formily/commit/82d50df4) :point_right: ( [Yohox](https://github.com/Yohox) )\n\n1. [fix(next): fix children not rendered](https://github.com/alibaba/formily/commit/52ece397) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(react): fix form render dirty check (#1056)](https://github.com/alibaba/formily/commit/5aeed554) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(core): fix input change trigger order](https://github.com/alibaba/formily/commit/1cebca66) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(next-components): Replace ArrayList.Item with Table.Column. Fix #1034 (#1045)](https://github.com/alibaba/formily/commit/e116838a) :point_right: ( [soulwu](https://github.com/soulwu) )\n\n1. [fix(core): fix hasChanged return type (#1036)](https://github.com/alibaba/formily/commit/d0eb66b6) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix Upload preview image (#1031)](https://github.com/alibaba/formily/commit/e2bfcce9) :point_right: ( [liunian](https://github.com/liunian) )\n\n1. [fix(antd-components): missing 'key' prop warning when table draggable (#1011)](https://github.com/alibaba/formily/commit/a69cdad1) :point_right: ( [daief](https://github.com/daief) )\n\n1. [fix: compat legal props (#1007)](https://github.com/alibaba/formily/commit/5dde72ae) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [fix(schema-renderer): fix schema field lazy state (#999)](https://github.com/alibaba/formily/commit/8faab444) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(shared): update cool-path version, ensure bug to be fixed (#988)](https://github.com/alibaba/formily/commit/5ae37fe0) :point_right: ( [soulwu](https://github.com/soulwu) )\n\n1. [fix(schema-renderer): Fix expression complie perf bug (#986)](https://github.com/alibaba/formily/commit/0e8383ee) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix: compat ie10-11 for antd3 (#985)](https://github.com/alibaba/formily/commit/74fa86c9) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [fix: 回滚 mutators.move 行为 (#984)](https://github.com/alibaba/formily/commit/010e1495) :point_right: ( [soulwu](https://github.com/soulwu) )\n\n1. [fix: mutator insert (#977)](https://github.com/alibaba/formily/commit/f3356321) :point_right: ( [xiaowanzi](https://github.com/xiaowanzi) )\n\n1. [fix(core): fix field default sync exception (#970)](https://github.com/alibaba/formily/commit/d0872817) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(layout): type typo (#962)](https://github.com/alibaba/formily/commit/9b9f052f) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [fix(core): fix move down throw errors and fix null assign merge throw errors (#961)](https://github.com/alibaba/formily/commit/854feec2) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(core): use form batch to sync errors in array state exchanging](https://github.com/alibaba/formily/commit/0e4880fb) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(editor): remove import lodash/fp](https://github.com/alibaba/formily/commit/a105cff3) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(core): fix form ref values (#952)](https://github.com/alibaba/formily/commit/777596b7) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(schema): compat eva expression actions (#951)](https://github.com/alibaba/formily/commit/aed0369b) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [fix(core): fix antd table get row key (#946)](https://github.com/alibaba/formily/commit/6bda3296) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(@formily/core): fix unmountClearStates flags is not right (#944)](https://github.com/alibaba/formily/commit/754a55f4) :point_right: ( [soulwu](https://github.com/soulwu) )\n\n1. [fix(antd,next): fix ie.tsx ssr bug (#936)](https://github.com/alibaba/formily/commit/0d3c3810) :point_right: ( [Markey](https://github.com/Markey) )\n\n1. [fix: issue 853 and 860 (#928)](https://github.com/alibaba/formily/commit/c1774308) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [bugfix (#920)](https://github.com/alibaba/formily/commit/4f41b564) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(core): sync form state (#906)](https://github.com/alibaba/formily/commit/de32802a) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(react): fix ArrayTable index and FormSpy (#904)](https://github.com/alibaba/formily/commit/944891f7) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(layout): inset mode comflict with labelAlign top (#903)](https://github.com/alibaba/formily/commit/9906a0ce) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [fix(core): fix array list mutators (#888)](https://github.com/alibaba/formily/commit/50f4e9e5) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(next/components): incorrect size #884 (#885)](https://github.com/alibaba/formily/commit/c930e27d) :point_right: ( [锦此](https://github.com/锦此) )\n\n1. [fix(components): fix datepicker format and checkbox editable style (#881)](https://github.com/alibaba/formily/commit/99ad146f) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(schema-renderer): fixed connect onBlur/onFocus throw errors (#874)](https://github.com/alibaba/formily/commit/54012b46) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix: megalayout columns (#871)](https://github.com/alibaba/formily/commit/9bff1f29) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [fix(schema-renderer): fix virtual box can not receive visible ant display (#869)](https://github.com/alibaba/formily/commit/1d7d94e6) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix: remove warning of addon before (#863)](https://github.com/alibaba/formily/commit/110238c6) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [fix(react): fix useField/useVirtualField props assign (#858)](https://github.com/alibaba/formily/commit/e71e527a) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(schema-editor): fix dependencies (#857)](https://github.com/alibaba/formily/commit/78f02c38) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(antd/next): fix button-group typings (#855)](https://github.com/alibaba/formily/commit/08077729) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(react): fix formSpy conflict with parent SchemaForm (#854)](https://github.com/alibaba/formily/commit/e122c9d9) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(antd/next): fix FormTextBox doesnot support className (#851)](https://github.com/alibaba/formily/commit/e40bdf2b) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(antd): fix labelCol/wrapperCol can not be overwriten (#850)](https://github.com/alibaba/formily/commit/4f87465c) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(core): fix unmounteRemoveValue property is not work #827 (#847)](https://github.com/alibaba/formily/commit/f53d02ae) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(react-schema-renderer): fix x-linkages typings (#823)](https://github.com/alibaba/formily/commit/06c1a310) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(array-table): remove min-width style property (#820)](https://github.com/alibaba/formily/commit/22d03df2) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(core): fix immer autoFreeze and reset Native Object (#816)](https://github.com/alibaba/formily/commit/aff23189) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix: arrayTable style (#813)](https://github.com/alibaba/formily/commit/fe913dd9) :point_right: ( [xiaowanzi](https://github.com/xiaowanzi) )\n\n1. [fix: FormTab components parseDefaultActiveKey (#802)](https://github.com/alibaba/formily/commit/2fb128b0) :point_right: ( [xiaowanzi](https://github.com/xiaowanzi) )\n\n1. [fix: Add default export for the antd (#787)](https://github.com/alibaba/formily/commit/5f5d4190) :point_right: ( [Rex Guo](https://github.com/Rex Guo) )\n\n1. [fix(react-schema-editor): improve SchemaEditor types (#786)](https://github.com/alibaba/formily/commit/944b6f7a) :point_right: ( [kenve](https://github.com/kenve) )\n\n1. [fix: readme typo (#785)](https://github.com/alibaba/formily/commit/56ef8829) :point_right: ( [WanTong](https://github.com/WanTong) )\n\n1. [fix(antd): fix FormItem type definition (#784)](https://github.com/alibaba/formily/commit/a53b46a7) :point_right: ( [kenve](https://github.com/kenve) )\n\n1. [fix(next): add onPageSizeChange (#777)](https://github.com/alibaba/formily/commit/b2df2d40) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(core): add lifecycle buffer gc (#773)](https://github.com/alibaba/formily/commit/360c2110) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(share): fix toArr if param is a proxy (#760)](https://github.com/alibaba/formily/commit/fca3890e) :point_right: ( [林法鑫](https://github.com/林法鑫) )\n\n1. [fix(antd): fix error auto scroll is not work for antd4 (#750)](https://github.com/alibaba/formily/commit/9d0f2196) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix x-index order algorithm (#724)](https://github.com/alibaba/formily/commit/17ae9ddb) :point_right: ( [JerryLyu](https://github.com/JerryLyu) )\n\n1. [fix(printer): fix print schema (#710)](https://github.com/alibaba/formily/commit/eb4b4e37) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix: doc typo of antd (#699)](https://github.com/alibaba/formily/commit/a10efdf9) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [fix(antd-components): fix password component bugs (#672)](https://github.com/alibaba/formily/commit/bf6128eb) :point_right: ( [JerryLyu](https://github.com/JerryLyu) )\n\n1. [fix(project): compat uform (#666)](https://github.com/alibaba/formily/commit/74008983) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(meet): fix ci (#660)](https://github.com/alibaba/formily/commit/0aba4483) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(@formily/meet): fix pacakge config (#659)](https://github.com/alibaba/formily/commit/06837f9e) :point_right: ( [DarK-AleX-alibaba](https://github.com/DarK-AleX-alibaba) )\n\n1. [fix: upload children (#631)](https://github.com/alibaba/formily/commit/9c0095c1) :point_right: ( [JeromeYangtao](https://github.com/JeromeYangtao) )\n\n1. [fix: fix type lint (#628)](https://github.com/alibaba/formily/commit/8215d7f4) :point_right: ( [soulwu](https://github.com/soulwu) )\n\n1. [fix(antd/next): fix antd/next table arr[0] path (#624)](https://github.com/alibaba/formily/commit/fb64eae7) :point_right: ( [WingGao](https://github.com/WingGao) )\n\n1. [fix: 616 (#622)](https://github.com/alibaba/formily/commit/23ff1447) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [fix(@uform/core/react): fix #613 #615 (#618)](https://github.com/alibaba/formily/commit/8dc609f9) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(@uform/shared): fix isValid (#604)](https://github.com/alibaba/formily/commit/4136691d) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(@uform/core): fix submit catch error (#603)](https://github.com/alibaba/formily/commit/406f9fb9) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(uform/core): recover field visible/display state after parent changed (#567)](https://github.com/alibaba/formily/commit/d270ef78) :point_right: ( [小黄黄](https://github.com/小黄黄) )\n\n1. [fix: issue#540 (#549)](https://github.com/alibaba/formily/commit/4ae1759d) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [fix: build on windows (#539)](https://github.com/alibaba/formily/commit/8ad99322) :point_right: ( [WingGao](https://github.com/WingGao) )\n\n1. [bugfix: add config files and fix the build error messages](https://github.com/alibaba/formily/commit/2da0edae) :point_right: ( [云数](https://github.com/云数) )\n\n1. [fix(@uform/core): add onFormReset hook](https://github.com/alibaba/formily/commit/8633ae5f) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(@uform/core): add values to submit resolve callback params (#508)](https://github.com/alibaba/formily/commit/06c4f631) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix: form effect demo (#499)](https://github.com/alibaba/formily/commit/93f87ad2) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [fix schema property `minItems ` (#493)](https://github.com/alibaba/formily/commit/26e12aa1) :point_right: ( [李力](https://github.com/李力) )\n\n1. [fix: use omit to elegant &](https://github.com/alibaba/formily/commit/72e51a61) :point_right: ( [quirkyshop](https://github.com/quirkyshop) )\n\n1. [fix: types merge error](https://github.com/alibaba/formily/commit/950a1930) :point_right: ( [quirkyshop](https://github.com/quirkyshop) )\n\n1. [fix(@uform/antd): Warning Received `true` for a non-boolean attribute `inline` (#494)](https://github.com/alibaba/formily/commit/46fbcb44) :point_right: ( [GODI13](https://github.com/GODI13) )\n\n1. [fix(@uform/core): fix init visible can not remove value (#492)](https://github.com/alibaba/formily/commit/a6dcc18d) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix: merge uform master](https://github.com/alibaba/formily/commit/84d2bf17) :point_right: ( [秋逢](https://github.com/秋逢) )\n\n1. [fix: printer get api and add get form schema to doc (#482)](https://github.com/alibaba/formily/commit/f01988ff) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [fix(@uform/antd/next/react): doc (#471)](https://github.com/alibaba/formily/commit/6d73c6cd) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [fix(@uform/validator): fix maximum rule get message logic (#468)](https://github.com/alibaba/formily/commit/752c09e3) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix: Not in the browser](https://github.com/alibaba/formily/commit/676ff5f5) :point_right: ( [jinc.cjc](https://github.com/jinc.cjc) )\n\n1. [fix: in miniapp, globalSelf is existing](https://github.com/alibaba/formily/commit/4b6a9c08) :point_right: ( [jinc.cjc](https://github.com/jinc.cjc) )\n\n1. [fix: in miniapp (worker runtime) , globalThis is not a function](https://github.com/alibaba/formily/commit/745a0d9f) :point_right: ( [jinc.cjc](https://github.com/jinc.cjc) )\n\n1. [fix(@uform/next): formitem compatibility (#440)](https://github.com/alibaba/formily/commit/3bfe515b) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [fix: 引入 next 样式](https://github.com/alibaba/formily/commit/9d12b489) :point_right: ( [秋逢](https://github.com/秋逢) )\n\n1. [fix(antd): return null while time field get falsy value (#372)](https://github.com/alibaba/formily/commit/269a1706) :point_right: ( [腰花](https://github.com/腰花) )\n\n1. [fix: [onFieldChange] types](https://github.com/alibaba/formily/commit/dc4fa80c) :point_right: ( [jinc.cjc](https://github.com/jinc.cjc) )\n\n1. [fix window is not defined (#312)](https://github.com/alibaba/formily/commit/a089fa89) :point_right: ( [Neil](https://github.com/Neil) )\n\n1. [fix(globalThis): fix ReferenceError (#309)](https://github.com/alibaba/formily/commit/9efc90a6) :point_right: ( [Neil](https://github.com/Neil) )\n\n1. [fix: ButtonGroup missing the definition of align prop (#297)](https://github.com/alibaba/formily/commit/a989364f) :point_right: ( [atzcl](https://github.com/atzcl) )\n\n1. [fix(core): Increase lastValidateValue value processing during initialization (#276)](https://github.com/alibaba/formily/commit/045f6fea) :point_right: ( [atzcl](https://github.com/atzcl) )\n\n1. [fix: getSchema returning undefined doesn't break setIn (#269)](https://github.com/alibaba/formily/commit/da1f7a21) :point_right: ( [Kiho · Cham](https://github.com/Kiho · Cham) )\n\n1. [fix: remove react unstable concurrent (#270)](https://github.com/alibaba/formily/commit/0f7edab9) :point_right: ( [Kiho · Cham](https://github.com/Kiho · Cham) )\n\n1. [fix(antd): improve week type moment parse regex (#254)](https://github.com/alibaba/formily/commit/88654b80) :point_right: ( [Wayne Zhu](https://github.com/Wayne Zhu) )\n\n1. [fix(examples): remove the onChange of next/Detail (#257)](https://github.com/alibaba/formily/commit/62ae0cbb) :point_right: ( [atzcl](https://github.com/atzcl) )\n\n1. [fix(@uform/antd): add typings entry file (#250)](https://github.com/alibaba/formily/commit/a9063a2e) :point_right: ( [atzcl](https://github.com/atzcl) )\n\n1. [fix(@uform/core): add scheduler backward compat (#251)](https://github.com/alibaba/formily/commit/ed948348) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix FormTextBox margin value (#237)](https://github.com/alibaba/formily/commit/6148e332) :point_right: ( [合木](https://github.com/合木) )\n\n1. [fix validator of id card to support tail x (#227)](https://github.com/alibaba/formily/commit/33291e3e) :point_right: ( [合木](https://github.com/合木) )\n\n1. [fix(@uform/react): invariant initialValues will not be changed when form rerender (#214)](https://github.com/alibaba/formily/commit/b9efa4ca) :point_right: ( [Kiho · Cham](https://github.com/Kiho · Cham) )\n\n1. [fix(@uform/antd): Fix Antd Input loading state automatically loses focus (#207)](https://github.com/alibaba/formily/commit/3824942b) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(@uform/antd): support password add size props and use Input.Password in antd(#192)](https://github.com/alibaba/formily/commit/633dd302) :point_right: ( [atzcl](https://github.com/atzcl) )\n\n1. [fix(@uform/core): fix field props transformer is not work](https://github.com/alibaba/formily/commit/8686c7c8) :point_right: ( [合木](https://github.com/合木) )\n\n1. [fix(typings): correction FormLayout、Submit typings (#182)](https://github.com/alibaba/formily/commit/11dde612) :point_right: ( [atzcl](https://github.com/atzcl) )\n\n1. [fix(utils): adjust the order of getting self (#178)](https://github.com/alibaba/formily/commit/4ef2e1ca) :point_right: ( [Kiho · Cham](https://github.com/Kiho · Cham) )\n\n1. [fix(@uform/core): Fix the parameters of changeEditable api which have been defined in interface IField. (#180)](https://github.com/alibaba/formily/commit/54daf28d) :point_right: ( [Rain](https://github.com/Rain) )\n\n1. [fix(docs): fix docs without display property description (#176)](https://github.com/alibaba/formily/commit/24d12be5) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(typescript): fix typescript config](https://github.com/alibaba/formily/commit/546d9f01) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix(typescript): fix ts build can not transplie jsx](https://github.com/alibaba/formily/commit/0dfcba7c) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [fix: move string-length into utils (#154)](https://github.com/alibaba/formily/commit/b84803b4) :point_right: ( [Kevin Tan](https://github.com/Kevin Tan) )\n\n1. [fix(@uform/utils): fix setIn with number key can not auto create array](https://github.com/alibaba/formily/commit/48aa6d57) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [fix(@uform/utils): Fix the exception of setIn when undefiend value is assigned undefined property](https://github.com/alibaba/formily/commit/7cb63161) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [fix(@uform/core): Fix value synchronization of field state](https://github.com/alibaba/formily/commit/38dc0aa6) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [fix: antd select should not have max-width by default (#112)](https://github.com/alibaba/formily/commit/b4a494a1) :point_right: ( [Kevin Tan](https://github.com/Kevin Tan) )\n\n1. [fix(@uform/core): Fixed the value was not cached when the field was hidden #113](https://github.com/alibaba/formily/commit/402daff2) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [fix array table will show labels wrapped by form card](https://github.com/alibaba/formily/commit/60e0917b) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(@uform/utils): fix bug of every and some (#88)](https://github.com/alibaba/formily/commit/36ab9da0) :point_right: ( [Chen YuBen](https://github.com/Chen YuBen) )\n\n1. [fix(next-ts): fix ts lint errors](https://github.com/alibaba/formily/commit/759f4f24) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [fix(@uform/core): Fix the issue of the onFieldChange event after the Field is removed (#72)](https://github.com/alibaba/formily/commit/30cd1e56) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [fix(@uform/core): Optimize the 'errors' information structure](https://github.com/alibaba/formily/commit/be680e02) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [fix(project): Fix known issues. 1. Improve the Button API Description 2. Improve the Field API Description 3. Fix showLoading Submit Component is not work 4. Fix x-index is not work with array table 5. Improve Field Subtree Parsing Performance](https://github.com/alibaba/formily/commit/826ebce1) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [fix(@uform/react): Fixing index.d.ts can not found registerFormField. #29](https://github.com/alibaba/formily/commit/6c287413) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [fix(@uform/react): Fix Form List error in JSON Schema driver usecase #22](https://github.com/alibaba/formily/commit/6d11c4bd) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [fix(@uform/antd): fix upload field is not work when uploading some files #18](https://github.com/alibaba/formily/commit/fbc22e74) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [fix(@uform/core): fix setFormState Promise resolve is not wait rerender completed.](https://github.com/alibaba/formily/commit/d9a24d44) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [fix(@uform/react): fix field dynamic hidden will effect other field. When the virtual box without name is hidden in the dynamic display, it will affect the dynamic hiding of the adjacent virtual box.](https://github.com/alibaba/formily/commit/97bb44d9) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [fix(@uform/nexxt): fix time picker click will throw error](https://github.com/alibaba/formily/commit/e9659ac3) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [fix(docs): improve Form Schema](https://github.com/alibaba/formily/commit/83a3137f) :point_right: ( [harryyu](https://github.com/harryyu) )\n\n1. [fix(docs): fix docs can not scroll in ios](https://github.com/alibaba/formily/commit/a6e53c2e) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [fix(@uform/utils): fix isEmpty'result is not correct when ['','']](https://github.com/alibaba/formily/commit/091c2f17) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [fix(@uform/core): fix bug - fix bug that async schema default property is not work - fix bug that visible property is not work by setFieldState when FormInit](https://github.com/alibaba/formily/commit/8864ba99) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [fix(@uform/next/antd): fix FormButtonGroup will throw error when root component rerendering](https://github.com/alibaba/formily/commit/ccd93349) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [fix: 修改版本号](https://github.com/alibaba/formily/commit/a26a5013) :point_right: ( [cnt1992](https://github.com/cnt1992) )\n\n1. [fix(next): replace fusion next package name](https://github.com/alibaba/formily/commit/db2061e8) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [fix(pkg): add access=public to allow lerna to publish scoped package](https://github.com/alibaba/formily/commit/b41d1fab) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n### :memo: Documents Changes\n\n1. [docs: add @formily/tdesign-react links (#3265)](https://github.com/alibaba/formily/commit/57510b42) :point_right: ( [zFitness](https://github.com/zFitness) )\n\n1. [docs: fix typo (#3247)](https://github.com/alibaba/formily/commit/ac807c13) :point_right: ( [Weiqi Wu](https://github.com/Weiqi Wu) )\n\n1. [docs(reactive): add assignment statement (#3210)](https://github.com/alibaba/formily/commit/297532f8) :point_right: ( [zhangrenyang](https://github.com/zhangrenyang) )\n\n1. [docs: fix contribution.zh-CN error (doc -> docs) (#3202)](https://github.com/alibaba/formily/commit/a4974d23) :point_right: ( [Akong](https://github.com/Akong) )\n\n1. [docs(antd): fix Select component docs error (#3199)](https://github.com/alibaba/formily/commit/ee70cde1) :point_right: ( [微笑](https://github.com/微笑) )\n\n1. [docs: delete useless code (#3198)](https://github.com/alibaba/formily/commit/8ef12b43) :point_right: ( [zhangrenyang](https://github.com/zhangrenyang) )\n\n1. [docs: fix demo error (#3173)](https://github.com/alibaba/formily/commit/91e44698) :point_right: ( [PlutoCA](https://github.com/PlutoCA) )\n\n1. [docs: update codesandbox templates that use the latest formily (#2980)](https://github.com/alibaba/formily/commit/7bb26f98) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [docs: add vant link (#2851)](https://github.com/alibaba/formily/commit/de85f9f7) :point_right: ( [摇了摇头 oO](https://github.com/摇了摇头oO) )\n\n1. [docs: update issue-helper api](https://github.com/alibaba/formily/commit/ea4b1009) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs: fix a typo in Field.zh-CN.md (#2825)](https://github.com/alibaba/formily/commit/248ba3b0) :point_right: ( [stefango](https://github.com/stefango) )\n\n1. [docs(core): update setValidationLanguage to setValidateLanguage (#2674)](https://github.com/alibaba/formily/commit/31bc258d) :point_right: ( [JuFeng Zhang](https://github.com/JuFeng Zhang) )\n\n1. [docs(core): update form-path doc path](https://github.com/alibaba/formily/commit/7f901de7) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs: update qrcode](https://github.com/alibaba/formily/commit/fe10bfdb) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs(core): improve docs (#2636)](https://github.com/alibaba/formily/commit/436dedbe) :point_right: ( [Hencky](https://github.com/Hencky) )\n\n1. [docs(element): update element brandName & codesandbox (#2608)](https://github.com/alibaba/formily/commit/26861a8f) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [docs(react): update field document urls (#2585)](https://github.com/alibaba/formily/commit/98628470) :point_right: ( [燃冰](https://github.com/燃冰) )\n\n1. [docs: improve site show brandName (#2574)](https://github.com/alibaba/formily/commit/483f79f1) :point_right: ( [Dark](https://github.com/Dark) )\n\n1. [docs(react): fix the typo on ISchemaFieldProps (#2528)](https://github.com/alibaba/formily/commit/0c5c6f1e) :point_right: ( [B2D1](https://github.com/B2D1) )\n\n1. [docs: update Chinese guide 1.x link (#2515)](https://github.com/alibaba/formily/commit/bf0d9b8b) :point_right: ( [csrigogogo](https://github.com/csrigogogo) )\n\n1. [docs: update structure image](https://github.com/alibaba/formily/commit/ad485978) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs: update QueryList docs (#2475)](https://github.com/alibaba/formily/commit/f84703b5) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [docs(core): update links in Form model Chinese doc (#2414)](https://github.com/alibaba/formily/commit/d6cdf71a) :point_right: ( [haloworld](https://github.com/haloworld) )\n\n1. [docs: fix scenes url (#2384)](https://github.com/alibaba/formily/commit/3538b171) :point_right: ( [PlutoCA](https://github.com/PlutoCA) )\n\n1. [docs: add issues-helper badge (#2359)](https://github.com/alibaba/formily/commit/a99feb43) :point_right: ( [xrkffgg](https://github.com/xrkffgg) )\n\n1. [docs(reactive): update reactive docs](https://github.com/alibaba/formily/commit/db4c35ff) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs: update errors to use selfErrors](https://github.com/alibaba/formily/commit/731ddc02) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs(vue): add more scopedSlot content tests and readme (#2226)](https://github.com/alibaba/formily/commit/ff7e790f) :point_right: ( [lirui](https://github.com/lirui) )\n\n1. [docs(project): update login-register.md](https://github.com/alibaba/formily/commit/79f948b3) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [doc: fix typo for Ant Design in docs/guide/quick-start.md (#2201)](https://github.com/alibaba/formily/commit/151f6845) :point_right: ( [vagusX](https://github.com/vagusX) )\n\n1. [docs: add notice for onFormValuesChange (#2146)](https://github.com/alibaba/formily/commit/c8176e53) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [docs(site): update Pack on Demand doc (#2086)](https://github.com/alibaba/formily/commit/c0c50ace) :point_right: ( [vimvinter](https://github.com/vimvinter) )\n\n1. [docs(designable): add designable form docs](https://github.com/alibaba/formily/commit/fef3600d) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs(site): improve home site contributors ui](https://github.com/alibaba/formily/commit/7592bafe) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs(site): add serverless functions](https://github.com/alibaba/formily/commit/d872ea4c) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs(site): update fragment linkage case](https://github.com/alibaba/formily/commit/7e5e2625) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs(main): add schema fragment controlled case (#1852)](https://github.com/alibaba/formily/commit/2212486b) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [docs(project): add translated docs (#1822)](https://github.com/alibaba/formily/commit/79ab341f) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [docs(react): improve ObjectField demo code (#1727)](https://github.com/alibaba/formily/commit/ccfba03a) :point_right: ( [砂糖梨子](https://github.com/砂糖梨子) )\n\n1. [docs(core): fix HTML Anchor jump link (#1639)](https://github.com/alibaba/formily/commit/3feaf906) :point_right: ( [后浪](https://github.com/后浪) )\n\n1. [docs: issue helper add codesandbox template (#1623)](https://github.com/alibaba/formily/commit/a7d2726c) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [docs(core): fix Type declaration errors in the document and code of setFieldState method (#1605)](https://github.com/alibaba/formily/commit/bb4f175f) :point_right: ( [后浪](https://github.com/后浪) )\n\n1. [docs(core): add Type number and integer for ValidatorFormats (#1599)](https://github.com/alibaba/formily/commit/03591144) :point_right: ( [codetyphon](https://github.com/codetyphon) )\n\n1. [docs(json-schema): add definitions and doc](https://github.com/alibaba/formily/commit/e729e007) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs(readme): add download stats](https://github.com/alibaba/formily/commit/09ec8e52) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs(all): add inject global styles](https://github.com/alibaba/formily/commit/70852e91) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs(issue-helper): improve issue-helper](https://github.com/alibaba/formily/commit/e4d10d13) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs(react): improve schema static declarations document (#1310)](https://github.com/alibaba/formily/commit/02aee29f) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [docs(antd): fix antd time picker ref (#1282)](https://github.com/alibaba/formily/commit/affa40c4) :point_right: ( [Pandazki](https://github.com/Pandazki) )\n\n1. [docs(antd/next): add useIndex api](https://github.com/alibaba/formily/commit/b36efe4a) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs(vue): update vue schema docs](https://github.com/alibaba/formily/commit/a54cf82b) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs(site): add english doc](https://github.com/alibaba/formily/commit/fd75b1ec) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs(main): fix main site docs](https://github.com/alibaba/formily/commit/cd6a3474) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs(fusion): update fusion docs](https://github.com/alibaba/formily/commit/1256a385) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs: JOSN -> JSON (#1196)](https://github.com/alibaba/formily/commit/87837801) :point_right: ( [zkylearner](https://github.com/zkylearner) )\n\n1. [docs(all): fix lint](https://github.com/alibaba/formily/commit/5c7a77fb) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs(formily): add quick-start doc](https://github.com/alibaba/formily/commit/e29857ee) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs(antd): add form-layout doc](https://github.com/alibaba/formily/commit/f167a750) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs(project): add contribution.md](https://github.com/alibaba/formily/commit/a6748df8) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [doc:improve validate documents (#1000)](https://github.com/alibaba/formily/commit/3a145304) :point_right: ( [wangmingxu](https://github.com/wangmingxu) )\n\n1. [docs(antd): mardown special symbol escape (#882)](https://github.com/alibaba/formily/commit/9c969cc9) :point_right: ( [kromalee](https://github.com/kromalee) )\n\n1. [docs: add type definition of x-linkages and x-mega-props (#876)](https://github.com/alibaba/formily/commit/c93b5171) :point_right: ( [Empireo](https://github.com/Empireo) )\n\n1. [docs(antd): fix registerVirtualBox demo (#834)](https://github.com/alibaba/formily/commit/02fcd0d4) :point_right: ( [kenve](https://github.com/kenve) )\n\n1. [docs(antd/component): fix labelAlign type and remove labelTextAlign (#817)](https://github.com/alibaba/formily/commit/3704873c) :point_right: ( [kenve](https://github.com/kenve) )\n\n1. [docs: fix spelling (#791)](https://github.com/alibaba/formily/commit/f27a66ba) :point_right: ( [kenve](https://github.com/kenve) )\n\n1. [docs: formatted with prettier (#768)](https://github.com/alibaba/formily/commit/cb7f095d) :point_right: ( [kenve](https://github.com/kenve) )\n\n1. [docs(antd-components): update import package name (#758)](https://github.com/alibaba/formily/commit/c038dbdd) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [docs: add introduction and support FormTab and support FieldState. unmountRemoveValue (#752)](https://github.com/alibaba/formily/commit/bfaa3ed7) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [doc(next/antd): array item docs optimization (#749)](https://github.com/alibaba/formily/commit/b12bce24) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [docs : add complex-field-component.md (#737)](https://github.com/alibaba/formily/commit/1235a11a) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [doc: add form and formitem (#700)](https://github.com/alibaba/formily/commit/aaa4742a) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [docs(@formily/react-schema-renderer): fix docs example (#681)](https://github.com/alibaba/formily/commit/a546e6a2) :point_right: ( [朱建](https://github.com/朱建) )\n\n1. [docs: update next/antd (#661)](https://github.com/alibaba/formily/commit/611125c7) :point_right: ( [quirkyvar](https://github.com/quirkyvar) )\n\n1. [docs(project): fix docs codesandbox config](https://github.com/alibaba/formily/commit/0c65601d) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [docs(examples): fix FormStep examples (#593)](https://github.com/alibaba/formily/commit/27018c6c) :point_right: ( [常泽清](https://github.com/常泽清) )\n\n1. [doc: add questions(customize action) (#289)](https://github.com/alibaba/formily/commit/baecbaab) :point_right: ( [xiaowanzi](https://github.com/xiaowanzi) )\n\n1. [docs(Submit): fix table style (#203)](https://github.com/alibaba/formily/commit/d59436b3) :point_right: ( [atzcl](https://github.com/atzcl) )\n\n1. [docs: add detail of createForm (#156)](https://github.com/alibaba/formily/commit/ae8bb439) :point_right: ( [Kevin Tan](https://github.com/Kevin Tan) )\n\n1. [docs: optimize demo of form detail in docs (#150)](https://github.com/alibaba/formily/commit/b04d4135) :point_right: ( [合木](https://github.com/合木) )\n\n1. [docs(antd-relations): fix MM visible toggle is not work](https://github.com/alibaba/formily/commit/a930f78c) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [docs(Field_React): fix rule description](https://github.com/alibaba/formily/commit/827cb26a) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [docs(questions): add Q/A](https://github.com/alibaba/formily/commit/b98c0565) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [docs(api): fix form text box docs](https://github.com/alibaba/formily/commit/69b3c5a9) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [docs(docs): remove statis](https://github.com/alibaba/formily/commit/3203efbe) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [docs: add HarrisFeng as a contributor (#93)](https://github.com/alibaba/formily/commit/255d153e) :point_right: ( [allcontributors[bot]](https://github.com/allcontributors[bot]) )\n\n1. [docs: improve the English version (#3)](https://github.com/alibaba/formily/commit/d592cbf9) :point_right: ( [Harry Yu](https://github.com/Harry Yu) )\n\n1. [docs(api): update SchemaForm API links](https://github.com/alibaba/formily/commit/0573af76) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [docs(site): move github pages==>netlify](https://github.com/alibaba/formily/commit/dc9abdfa) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [docs(all): sort api table](https://github.com/alibaba/formily/commit/930ce7aa) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [docs(API): Fix jump link can't jump in doc site. #59](https://github.com/alibaba/formily/commit/724affdb) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [docs: remove useless column in field api table (#61)](https://github.com/alibaba/formily/commit/49be9871) :point_right: ( [Kiho · Cham](https://github.com/Kiho · Cham) )\n\n1. [docs(@uform/docs): Optimize package bundle size](https://github.com/alibaba/formily/commit/c42ea06a) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [docs(examples): add international docs #25](https://github.com/alibaba/formily/commit/aaa22278) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [docs(site_pages): add gitter.im sidebar](https://github.com/alibaba/formily/commit/5809a987) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [docs(next/antd): add createAsyncFormActions docs](https://github.com/alibaba/formily/commit/4ab122e1) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [docs: add README.md](https://github.com/alibaba/formily/commit/52fc2c2d) :point_right: ( [cnt1992](https://github.com/cnt1992) )\n\n### :rose: Improve code quality\n\n1. [refactor(vue): change Field component type to functional (#2773)](https://github.com/alibaba/formily/commit/ffbaba25) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [refactor(vue): switch type files for vue2/vue3 in postinstall (#2640)](https://github.com/alibaba/formily/commit/6015b7c8) :point_right: ( [月落音阑](https://github.com/月落音阑) )\n\n1. [refactor(grid): use data-grid-span for base grid span](https://github.com/alibaba/formily/commit/712aba94) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [refactor(core): revert field unmount to skip validate (#2379)](https://github.com/alibaba/formily/commit/8a016794) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [refactor(element): redesign form-grid and improve form-layout (#2337)](https://github.com/alibaba/formily/commit/9e468fae) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [refactor(antd/next/element): adjust the read priority of Form context](https://github.com/alibaba/formily/commit/f0c29bbc) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [refactor(react): silent useForm for child form sence (#2302)](https://github.com/alibaba/formily/commit/c2c2e305) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [refactor(core): reduce core package size (#2261)](https://github.com/alibaba/formily/commit/84f3fc1b) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [refactor(element): refactor element slot pass way (#2236)](https://github.com/alibaba/formily/commit/da28fe7e) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [refactor(project): support more features for page description (#2099)](https://github.com/alibaba/formily/commit/6162ad5d) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [refactor(json-schema): use with statement for compiler](https://github.com/alibaba/formily/commit/f913b35b) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [refactor(reactive): change model default batch annotation to action annotation](https://github.com/alibaba/formily/commit/6162639b) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [refactor(element): refactor FormDialog/FormDrawer & refactor component export type (#1892)](https://github.com/alibaba/formily/commit/cc3cb360) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [refactor(project): remove Formily.\\* use cases (#1820)](https://github.com/alibaba/formily/commit/72a2958c) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [refactor(designable-ant): expose upload component's textContent property in setting form (#1818)](https://github.com/alibaba/formily/commit/15344449) :point_right: ( [nekic](https://github.com/nekic) )\n\n1. [refactor(reactive): fix #1598 and support #1586 and super performance optimization](https://github.com/alibaba/formily/commit/a1e72006) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [refactor(designable-antd): refactor and add DesignableArrayTable](https://github.com/alibaba/formily/commit/97c78dbd) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [refactor(antd/next): improve docs and support x-component/x-decorator ReactComponent style](https://github.com/alibaba/formily/commit/65bfef1e) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [refactor(core): controlled ==> designable](https://github.com/alibaba/formily/commit/ac79c196) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [refactor(reactive-react): refactor observer function (#1523)](https://github.com/alibaba/formily/commit/55b93420) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [refactor(antd/next): rewrite PreviewText to JSXComponent (#1509)](https://github.com/alibaba/formily/commit/3f6c34d2) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [refactor(json-schema): refactor stringify type to fix literal type is erased (#1508)](https://github.com/alibaba/formily/commit/43e79a61) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [refactor(core): modify IFormState type (#1434)](https://github.com/alibaba/formily/commit/57a7ea37) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [refactor(reactive): add benchmark scripts](https://github.com/alibaba/formily/commit/6954a1fb) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [refactor(project): update deps declaration](https://github.com/alibaba/formily/commit/0b846317) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [refactor: adjust the umd compilation process of the ui library (#1206)](https://github.com/alibaba/formily/commit/e3fc6ade) :point_right: ( [atzcl](https://github.com/atzcl) )\n\n1. [refactor: update rollup config (#1193)](https://github.com/alibaba/formily/commit/a8d119c0) :point_right: ( [Dark](https://github.com/Dark) )\n\n1. [refactor(antd): fine adjustment (#1188)](https://github.com/alibaba/formily/commit/ea022745) :point_right: ( [atzcl](https://github.com/atzcl) )\n\n1. [refactor: remove disabled, update props name, update NodeTypes enum(#1155)](https://github.com/alibaba/formily/commit/43972bae) :point_right: ( [soulwu](https://github.com/soulwu) )\n\n1. [refactor(project): remove react-shared-components](https://github.com/alibaba/formily/commit/6f6dbed4) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [refactor(devtools): update npm scripts](https://github.com/alibaba/formily/commit/c449fbbf) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [refactor(react): improve form-spy (#824)](https://github.com/alibaba/formily/commit/c4dc2144) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [refactor(@uform/react-schema-editor): update (#606)](https://github.com/alibaba/formily/commit/179cd62a) :point_right: ( [Andy](https://github.com/Andy) )\n\n1. [refactor:code and style refactor (#522)](https://github.com/alibaba/formily/commit/24b3503e) :point_right: ( [Andy](https://github.com/Andy) )\n\n1. [refactor(antd): adjust the handling of importing components on demand (#485)](https://github.com/alibaba/formily/commit/2fb41e9a) :point_right: ( [atzcl](https://github.com/atzcl) )\n\n1. [refactor(typings): update FormStep、dispatch、notify typings](https://github.com/alibaba/formily/commit/929ef2c6) :point_right: ( [atzcl](https://github.com/atzcl) )\n\n1. [refactor: 代码优化](https://github.com/alibaba/formily/commit/e9f2c04e) :point_right: ( [秋逢](https://github.com/秋逢) )\n\n1. [refactor: improve test case (#375)](https://github.com/alibaba/formily/commit/dfec008a) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [refactor(@uform/core): remove processing test case](https://github.com/alibaba/formily/commit/56835f9e) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [refactor(build): add build docs flow in CI and remove dynamic style inject](https://github.com/alibaba/formily/commit/1fb5cc07) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [refactor: next in TypeScript (#206)](https://github.com/alibaba/formily/commit/33e4bfb8) :point_right: ( [Kiho · Cham](https://github.com/Kiho · Cham) )\n\n1. [refactor: use isEqual instead of isEmpty](https://github.com/alibaba/formily/commit/41aa26e8) :point_right: ( [monkindey](https://github.com/monkindey) )\n\n1. [refactor(pkg): update eslint-plugin-react version](https://github.com/alibaba/formily/commit/a9f0c7ce) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [refactor(test): update react-test-library==>@test-library/react](https://github.com/alibaba/formily/commit/a97ffa0b) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [refactor(project): merge alibaba/uform master](https://github.com/alibaba/formily/commit/b050eeaa) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [refactor(pkg): add ts deps](https://github.com/alibaba/formily/commit/bfdfb822) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [refactor(project): move @alifd/next and antd dependencies to peerDependencies](https://github.com/alibaba/formily/commit/201a53d2) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [refactor(docs): rebuild docs](https://github.com/alibaba/formily/commit/18388943) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [refactor(ci): update .travis.yml](https://github.com/alibaba/formily/commit/9396e9d6) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [refactor(docs): move \\_config.yml to root dir](https://github.com/alibaba/formily/commit/1670178a) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [refactor: monaco editor amd](https://github.com/alibaba/formily/commit/4535cbe0) :point_right: ( [cnt1992](https://github.com/cnt1992) )\n\n1. [refactor: split next version](https://github.com/alibaba/formily/commit/b77cedb1) :point_right: ( [cnt1992](https://github.com/cnt1992) )\n\n1. [refactor(builder): delete package-lock.json and config/jest](https://github.com/alibaba/formily/commit/d35820c4) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [refactor(gitignore): remove lib](https://github.com/alibaba/formily/commit/8677e38d) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [refactor(project): LESENCE.md ==> LICENSE.md](https://github.com/alibaba/formily/commit/1968d1f3) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [refactor(project): add test scripts It’s almost done](https://github.com/alibaba/formily/commit/e8a90213) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n### :rocket: Improve Performance\n\n1. [perf(core): improve form change trigger performance (#3236)](https://github.com/alibaba/formily/commit/8e8a661e) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [perf(antd/next): improve ArrayTable performance](https://github.com/alibaba/formily/commit/2c982289) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [perf: improve total performance 20% (#2589)](https://github.com/alibaba/formily/commit/2d981385) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [perf(path): use Map replace LRUMap](https://github.com/alibaba/formily/commit/1141e580) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [perf(reactive-react): improve performace with immediate](https://github.com/alibaba/formily/commit/6d6a18f4) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [perf(core): improve validate perf (#755)](https://github.com/alibaba/formily/commit/3ea64169) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [perf(core): fix nested path update performance (#722)](https://github.com/alibaba/formily/commit/130feeae) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [perf(array): shorten the code (#678)](https://github.com/alibaba/formily/commit/f8706760) :point_right: ( [Neil](https://github.com/Neil) )\n\n### :hammer_and_wrench: Update Workflow Scripts\n\n1. [build: add peerDependenciesMeta (#3026)](https://github.com/alibaba/formily/commit/bbc2a51b) :point_right: ( [うまる](https://github.com/うまる) )\n\n1. [build(sourcemap): add \"sourcesContent\" to the output source map (#2399)](https://github.com/alibaba/formily/commit/3305cf80) :point_right: ( [zengguirong](https://github.com/zengguirong) )\n\n1. [build: fix build global may be failed (#1744)](https://github.com/alibaba/formily/commit/818aa132) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [build: fix git message sort incorrect (#1708)](https://github.com/alibaba/formily/commit/617ce88c) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [build: add sourcemap support (#1687)](https://github.com/alibaba/formily/commit/7bb433bb) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [build(shared): external path package](https://github.com/alibaba/formily/commit/be3ae401) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [build(project): buld project](https://github.com/alibaba/formily/commit/fc455da7) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n### :construction: Add/Update Test Cases\n\n1. [test(json-schema): add test of transformer in json-schema (#2975)](https://github.com/alibaba/formily/commit/c3228191) :point_right: ( [Zardddddd60](https://github.com/Zardddddd60) )\n\n1. [test(code): optimize test case of core/lifecycle (#2874)](https://github.com/alibaba/formily/commit/f1766ecc) :point_right: ( [Zardddddd60](https://github.com/Zardddddd60) )\n\n1. [test(reactive): adding missing tests and correcting existing tests (#2525)](https://github.com/alibaba/formily/commit/432f6204) :point_right: ( [Yiliang Wang](https://github.com/Yiliang Wang) )\n\n1. [test: update package.json](https://github.com/alibaba/formily/commit/288a8777) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [test(core): add designable tests (#1972)](https://github.com/alibaba/formily/commit/6a437c8b) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [test(core): nested reaction should recall the tracker (#1696)](https://github.com/alibaba/formily/commit/a6b81042) :point_right: ( [小黄黄](https://github.com/小黄黄) )\n\n1. [test: update jest config (#1634)](https://github.com/alibaba/formily/commit/f228a405) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [test(reactive): add mark tests and fix docs typo](https://github.com/alibaba/formily/commit/b3b2679e) :point_right: ( [gwsbhqt](https://github.com/gwsbhqt) )\n\n1. [test(project): update mobx => @formily/reactive](https://github.com/alibaba/formily/commit/7ae0a923) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [test(json-schema): update snapshot](https://github.com/alibaba/formily/commit/0c5947a8) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [test(validator): add some core tests](https://github.com/alibaba/formily/commit/c5236042) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [test(@uform/react): improve field and virtualField test cases (#438)](https://github.com/alibaba/formily/commit/853e051f) :point_right: ( [dahuang](https://github.com/dahuang) )\n\n1. [test(@uform/utils): add setIn testcase](https://github.com/alibaba/formily/commit/67a82e67) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [test(effects): remove unnecessary button tags](https://github.com/alibaba/formily/commit/7d25ac4c) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [test(project): add large test cases](https://github.com/alibaba/formily/commit/68fd2e1c) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n### :blush: Other Changes\n\n1. [chore(deps): bump moment from 2.29.3 to 2.29.4 (#3267)](https://github.com/alibaba/formily/commit/88df0daa) :point_right: ( [dependabot[bot]](https://github.com/dependabot[bot]) )\n\n1. [chore: remove getValueByValue](https://github.com/alibaba/formily/commit/2ca7aaf5) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(deps): bump parse-url from 6.0.0 to 6.0.2 (#3255)](https://github.com/alibaba/formily/commit/679fbb74) :point_right: ( [dependabot[bot]](https://github.com/dependabot[bot]) )\n\n1. [chore(reactive): improve strict mode update strategy](https://github.com/alibaba/formily/commit/c3002bde) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(deps-dev): bump semver-regex from 3.1.3 to 3.1.4 (#3166)](https://github.com/alibaba/formily/commit/ca97cae3) :point_right: ( [dependabot[bot]](https://github.com/dependabot[bot]) )\n\n1. [chore(reactive): revert batch tracker (#3112)](https://github.com/alibaba/formily/commit/604d74ac) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [chore: add carbon ad tag](https://github.com/alibaba/formily/commit/679efc54) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(antd/next): replace useForm to useParentForm in Form component](https://github.com/alibaba/formily/commit/43a3d6b8) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(antd/next): revert editable](https://github.com/alibaba/formily/commit/16a376d3) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(json-schema): improve typings](https://github.com/alibaba/formily/commit/d116d272) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore: change pr template and commit message specific link (#2742)](https://github.com/alibaba/formily/commit/129cd693) :point_right: ( [zhouxinyong](https://github.com/zhouxinyong) )\n\n1. [chore(grid): improve strictAutoFit](https://github.com/alibaba/formily/commit/d485a49e) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(next): export ExtendTableProps](https://github.com/alibaba/formily/commit/ad82905b) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore: improve code style (#2579)](https://github.com/alibaba/formily/commit/4a083bad) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [chore: add dingtalk notification for release](https://github.com/alibaba/formily/commit/35a18c48) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(element): update ts-import-plugin version (#2518)](https://github.com/alibaba/formily/commit/4f27990d) :point_right: ( [Muyao](https://github.com/Muyao) )\n\n1. [chore: add ESNext and DOM lib to TS compiler options (#2507)](https://github.com/alibaba/formily/commit/a51d1898) :point_right: ( [Yiliang Wang](https://github.com/Yiliang Wang) )\n\n1. [chore: fix yarn.lock](https://github.com/alibaba/formily/commit/8305c18f) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(antd/next): compat antd@4.17 and remove antd-icons from fusion package (#2492)](https://github.com/alibaba/formily/commit/cc325699) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [chore: change site domain v2.formilyjs.org -> formilyjs.org](https://github.com/alibaba/formily/commit/342493a0) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore: remove build global scripts (#2474)](https://github.com/alibaba/formily/commit/4cb7e9f9) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [chore: update workflow](https://github.com/alibaba/formily/commit/e84a4769) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(grid): update readme](https://github.com/alibaba/formily/commit/9738292c) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(desingbale): move designable-antd/next to designable repo](https://github.com/alibaba/formily/commit/84327d2d) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(workflow): fix actions](https://github.com/alibaba/formily/commit/12dacdcc) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [chore(designable): lock version](https://github.com/alibaba/formily/commit/b61ad907) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(react): compat ReactNative with SchemaField only json-schema mode](https://github.com/alibaba/formily/commit/77dd47e4) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(docs): add antd-formily-boost link](https://github.com/alibaba/formily/commit/4fb9ff8d) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(ts): map @formily/\\* to src folder during development (#1917)](https://github.com/alibaba/formily/commit/65259a06) :point_right: ( [JuFeng Zhang](https://github.com/JuFeng Zhang) )\n\n1. [chore(validator): improve validator (#1918)](https://github.com/alibaba/formily/commit/b1681bff) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [chore(flow): add release.yml](https://github.com/alibaba/formily/commit/301a89c1) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(setters): improve DataSourceSetter ui](https://github.com/alibaba/formily/commit/1c12f543) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(core): improve display model (#1713)](https://github.com/alibaba/formily/commit/bad483da) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [chore(designable-antd): improve playgroun ui](https://github.com/alibaba/formily/commit/2d07630c) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(path): add benchmark case](https://github.com/alibaba/formily/commit/9533e049) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore: replace 'disgusting' with 'sophisticated' (#1574)](https://github.com/alibaba/formily/commit/d14c042e) :point_right: ( [Riting LIU](https://github.com/Riting LIU) )\n\n1. [chore(pkg): add workspaces](https://github.com/alibaba/formily/commit/d8af530e) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(github): update pr template](https://github.com/alibaba/formily/commit/b3149307) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(dumi): update next css link](https://github.com/alibaba/formily/commit/6843d946) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(pkg): update lint-staged scripts](https://github.com/alibaba/formily/commit/ddd8fc9a) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(project): prettier all code and change style behavior](https://github.com/alibaba/formily/commit/3792c221) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(scripts): remove mapCoverage.js](https://github.com/alibaba/formily/commit/3b3c3134) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(workflow): Update check-pr-title.yml (#1490)](https://github.com/alibaba/formily/commit/9243908d) :point_right: ( [xrkffgg](https://github.com/xrkffgg) )\n\n1. [chore(workflow): rename main.yml ==>commitlint.yml](https://github.com/alibaba/formily/commit/45734661) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [chore(actions): update commit checker action](https://github.com/alibaba/formily/commit/573b60fe) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [chore(pkg): add preversion/version lerna scripts hook](https://github.com/alibaba/formily/commit/d933f1fe) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(pkg): change the execution timing of the changelog generator](https://github.com/alibaba/formily/commit/0ff511f6) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore(scripts): slice changelog counts](https://github.com/alibaba/formily/commit/fead7843) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore: improve github pull request template (#1328)](https://github.com/alibaba/formily/commit/353e87a7) :point_right: ( [liuwei](https://github.com/liuwei) )\n\n1. [ci(core): fix tests](https://github.com/alibaba/formily/commit/faaceba0) :point_right: ( [janrywang](https://github.com/janrywang) )\n\n1. [chore: unify ts dependencies (#296)](https://github.com/alibaba/formily/commit/5268ce80) :point_right: ( [Kevin Tan](https://github.com/Kevin Tan) )\n\n1. [chore(travis): Guaranteed dependency peering (#288)](https://github.com/alibaba/formily/commit/97885c2c) :point_right: ( [atzcl](https://github.com/atzcl) )\n\n1. [chore(docs): UFrom --> UForm (#228)](https://github.com/alibaba/formily/commit/e55d8400) :point_right: ( [Kiho · Cham](https://github.com/Kiho · Cham) )\n\n1. [chore(docs): remove unused file and correct antd multiple example (#184)](https://github.com/alibaba/formily/commit/eee944f5) :point_right: ( [Kiho · Cham](https://github.com/Kiho · Cham) )\n\n1. [chore: fix tsc build errors (#174)](https://github.com/alibaba/formily/commit/c43397c1) :point_right: ( [Kevin Tan](https://github.com/Kevin Tan) )\n\n1. [chore: resolve the conflict](https://github.com/alibaba/formily/commit/22a7c32f) :point_right: ( [monkindey](https://github.com/monkindey) )\n\n1. [chore: remove tslint and use typescript-eslint (#159)](https://github.com/alibaba/formily/commit/97caa9cd) :point_right: ( [Kevin Tan](https://github.com/Kevin Tan) )\n\n1. [chore(project): release v0.1.15 (#94)](https://github.com/alibaba/formily/commit/bc3125d2) :point_right: ( [Janry](https://github.com/Janry) )\n\n1. [chore(scripts): correct git commit specific url)](https://github.com/alibaba/formily/commit/341b2ffb) :point_right: ( [monkindey](https://github.com/monkindey) )\n\n1. [chore(alpha): change version to v0.1.0-beta.20](https://github.com/alibaba/formily/commit/5bead131) :point_right: ( [janryWang](https://github.com/janryWang) )\n\n1. [chore: merge](https://github.com/alibaba/formily/commit/4b7aacb9) :point_right: ( [cnt1992](https://github.com/cnt1992) )\n\n1. [chore: delete no use files](https://github.com/alibaba/formily/commit/49deb94f) :point_right: ( [cnt1992](https://github.com/cnt1992) )\n\n1. [chore: rebuild](https://github.com/alibaba/formily/commit/2b95a387) :point_right: ( [cnt1992](https://github.com/cnt1992) )\n\n1. [chore: add react & react-dom in package.json](https://github.com/alibaba/formily/commit/3b814059) :point_right: ( [cnt1992](https://github.com/cnt1992) )\n\n1. [chore: upgrade webpack-dev-server](https://github.com/alibaba/formily/commit/2dfa848c) :point_right: ( [cnt1992](https://github.com/cnt1992) )\n"
  },
  {
    "path": "LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-present, Alibaba Group Holding Limited. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "README.md",
    "content": "English | [简体中文](./README.zh-cn.md)\n\n<p align=\"center\">\n<img src=\"https://img.alicdn.com/tfs/TB1fHhZu4D1gK0jSZFyXXciOVXa-2500-1200.png\">\n<img src=\"https://img.shields.io/npm/dt/@formily/core\"/>\n<img src=\"https://img.shields.io/npm/dm/@formily/core\"/>\n<a href=\"https://www.npmjs.com/package/@formily/core\"><img src=\"https://img.shields.io/npm/v/@formily/core.svg\"></a>\n<a href=\"https://codecov.io/gh/alibaba/formily\">\n  <img src=\"https://codecov.io/gh/alibaba/formily/branch/formily_next/graph/badge.svg?token=3V9RU8Wh9d\"/>\n</a>\n<img alt=\"PRs Welcome\" src=\"https://img.shields.io/badge/PRs-welcome-brightgreen.svg\"/>\n<a href=\"https://github.com/actions-cool/issues-helper\">\n  <img src=\"https://img.shields.io/badge/using-issues--helper-blueviolet\"/>\n</a>\n<a href=\"https://app.netlify.com/sites/formily/deploys\"><img src=\"https://api.netlify.com/api/v1/badges/7145918b-9cb5-47f8-8a42-111969e232ef/deploy-status\"/></a>\n</p>\n\n---\n\n## Background\n\nIn React, the whole tree rendering performance problem of the form is very obvious in the controlled mode. Especially for the scene of data linkage, it is easy to cause the page to be stuck. To solve this problem, we have distributed the management of the state of each form field, which significantly improves the performance of the form operations. At the same time, we deeply integrate the JSON Schema protocol to help you solve the problem of back-end driven form rendering quickly.\n\n## Features\n\n- 🖼 Designable, You can quickly develop forms at low cost through [Form Builder](https://designable-antd.formilyjs.org/).\n- 🚀 High performance, fields managed independently, rather rerender the whole tree.\n- 💡 Integrated Alibaba Fusion and Ant Design components are guaranteed to work out of the box.\n- 🎨 JSON Schema applied for BackEnd. JSchema applied for FrontEnd. Two paradigms can be converted to each other.\n- 🏅 Side effects are managed independently, making form data linkages easier than ever before.\n- 🌯 Override most complicated form layout use cases.\n\n## Form Builder\n\n![https://designable-antd.formilyjs.org/](https://img.alicdn.com/imgextra/i3/O1CN01xAJj1y1wcGzXYc1Uq_!!6000000006328-2-tps-2980-1740.png)\n\n## WebSite\n\n2.0\n\nhttps://formilyjs.org\n\n1.0\n\nhttps://v1.formilyjs.org\n\n## Community\n\n- [formilyjs](https://github.com/formilyjs)\n- [designable](https://github.com/alibaba/designable)\n- [icejs](https://github.com/alibaba/ice)\n\n## How to contribute?\n\n- [Contribute document](https://formilyjs.org/zh-CN/guide/contribution)\n\n## Contributors\n\nThis project exists thanks to all the people who contribute.\n<a href=\"https://github.com/alibaba/formily/graphs/contributors\"><img src=\"https://contrib.rocks/image?repo=alibaba/formily\" /></a>\n\n## LICENSE\n\nFormily is open source software licensed as\n[MIT](https://github.com/alibaba/formily/blob/master/LICENSE.md).\n"
  },
  {
    "path": "README.zh-cn.md",
    "content": "[English](./README.md) | 简体中文\n\n<p align=\"center\">\n<img src=\"https://img.alicdn.com/tfs/TB1fHhZu4D1gK0jSZFyXXciOVXa-2500-1200.png\">\n<img src=\"https://img.shields.io/npm/dt/@formily/core\"/>\n<img src=\"https://img.shields.io/npm/dm/@formily/core\"/>\n<a href=\"https://www.npmjs.com/package/@formily/core\"><img src=\"https://img.shields.io/npm/v/@formily/core.svg\"></a>\n<a href=\"https://codecov.io/gh/alibaba/formily\">\n  <img src=\"https://codecov.io/gh/alibaba/formily/branch/formily_next/graph/badge.svg?token=3V9RU8Wh9d\"/>\n</a>\n<img alt=\"PRs Welcome\" src=\"https://img.shields.io/badge/PRs-welcome-brightgreen.svg\"/>\n<a href=\"https://github.com/actions-cool/issues-helper\">\n  <img src=\"https://img.shields.io/badge/using-issues--helper-blueviolet\"/>\n</a>\n<a href=\"https://app.netlify.com/sites/formily/deploys\"><img src=\"https://api.netlify.com/api/v1/badges/7145918b-9cb5-47f8-8a42-111969e232ef/deploy-status\"/></a>\n</p>\n\n---\n\n## 背景\n\n在 React 中，在受控模式下，表单的整树渲染问题非常明显。特别是对于数据联动的场景，很容易导致页面卡顿，为了解决这个问题，我们将每个表单字段的状态做了分布式管理，从而大大提升了表单操作性能。同时，我们深度整合了 JSON Schema 协议，可以帮助您快速解决后端驱动表单渲染的问题。\n\n## 特性\n\n- 🖼 可设计，借助 Form Builder 可以快速搭建表单\n- 🚀 高性能，字段分布式渲染，大大减轻 React 渲染压力\n- 💡 支持 Ant Design/Fusion Next 组件体系\n- 🎨 JSX 标签化写法/JSON Schema 数据驱动方案无缝迁移过渡\n- 🏅 副作用逻辑独立管理，涵盖各种复杂联动校验逻辑\n- 🌯 支持各种表单复杂布局方案\n\n## Form Builder\n\n![https://designable-antd.formilyjs.org/](https://img.alicdn.com/imgextra/i3/O1CN01xAJj1y1wcGzXYc1Uq_!!6000000006328-2-tps-2980-1740.png)\n\n## 官网\n\n2.0\n\nhttps://formilyjs.org\n\n1.0\n\nhttps://v1.formilyjs.org\n\n## 生态产品\n\n- [formilyjs](https://github.com/formilyjs)\n- [designable](https://github.com/alibaba/designable)\n- [icejs](https://github.com/alibaba/ice)\n\n## 如何贡献\n\n- [贡献指南](https://formilyjs.org/zh-CN/guide/contribution)\n\n## 贡献者\n\nThis project exists thanks to all the people who contribute.\n<a href=\"https://github.com/alibaba/formily/graphs/contributors\"><img src=\"https://contrib.rocks/image?repo=alibaba/formily\" /></a>\n\n## LICENSE\n\nFormily is open source software licensed as\n[MIT.](https://github.com/alibaba/formily/blob/master/LICENSE.md)\n"
  },
  {
    "path": "commitlint.config.js",
    "content": "module.exports = { extends: ['@commitlint/config-conventional'] }\n"
  },
  {
    "path": "devtools/.eslintrc",
    "content": "{\n  \"parser\": \"@typescript-eslint/parser\",\n  \"extends\": [\n    \"plugin:react/recommended\",\n    \"plugin:@typescript-eslint/recommended\",\n    \"prettier/@typescript-eslint\"\n  ],\n  \"env\": {\n    \"node\": true\n  },\n  \"plugins\": [\"@typescript-eslint\", \"react\", \"prettier\", \"markdown\"],\n  \"parserOptions\": {\n    \"sourceType\": \"module\",\n    \"ecmaVersion\": 10,\n    \"ecmaFeatures\": {\n      \"jsx\": true\n    }\n  },\n  \"settings\": {\n    \"react\": {\n      \"version\": \"detect\"\n    }\n  },\n  \"rules\": {\n    \"prettier/prettier\": 0,\n    // don't force es6 functions to include space before paren\n    \"space-before-function-paren\": 0,\n    \"react/prop-types\": 0,\n    \"react/no-find-dom-node\": 0,\n    \"react/display-name\": 0,\n    // allow specifying true explicitly for boolean props\n    \"react/jsx-boolean-value\": 0,\n    \"react/no-did-update-set-state\": 0,\n    // maybe we should no-public\n    \"@typescript-eslint/explicit-member-accessibility\": 0,\n    \"@typescript-eslint/interface-name-prefix\": 0,\n    \"@typescript-eslint/no-explicit-any\": 0,\n    \"@typescript-eslint/explicit-function-return-type\": 0,\n    \"@typescript-eslint/no-parameter-properties\": 0,\n    \"@typescript-eslint/array-type\": 0,\n    \"@typescript-eslint/no-object-literal-type-assertion\": 0,\n    \"@typescript-eslint/no-use-before-define\": 0,\n    \"@typescript-eslint/no-unused-vars\": 1,\n    \"@typescript-eslint/no-namespace\": 0,\n    \"@typescript-eslint/ban-types\": 0,\n    \"@typescript-eslint/adjacent-overload-signatures\": 0,\n    \"@typescript-eslint/explicit-module-boundary-types\": 0,\n    \"@typescript-eslint/triple-slash-reference\": 0,\n    \"@typescript-eslint/no-empty-function\": 0,\n    \"no-console\": [\n      \"error\",\n      {\n        \"allow\": [\"warn\", \"error\", \"info\"]\n      }\n    ],\n    \"prefer-const\": 0,\n    \"no-var\": 1,\n    \"prefer-rest-params\": 0\n  },\n  \"overrides\": [\n    {\n      \"files\": [\"**/*.md.{jsx,tsx}\"],\n      \"processor\": \"markdown/markdown\"\n    },\n    {\n      \"files\": [\"**/*.md/*.{jsx,tsx}\"],\n      \"rules\": {\n        \"@typescript-eslint/no-unused-vars\": \"error\",\n        \"no-unused-vars\": \"error\",\n        \"no-console\": \"off\",\n        \"react/display-name\": \"off\",\n        \"react/prop-types\": \"off\"\n      }\n    },\n    {\n      \"files\": [\"**/*.md/*.{js,ts}\"],\n      \"rules\": {\n        \"@typescript-eslint/no-unused-vars\": \"off\",\n        \"no-unused-vars\": \"off\",\n        \"no-console\": \"off\",\n        \"react/display-name\": \"off\",\n        \"react/prop-types\": \"off\"\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "devtools/chrome-extension/.npmignore",
    "content": "node_modules\n*.log\nbuild\ndocs\ndoc-site\n__tests__\n.eslintrc\njest.config.js\ntsconfig.json\n.umi\nsrc"
  },
  {
    "path": "devtools/chrome-extension/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-present, Alibaba Group Holding Limited. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "devtools/chrome-extension/config/webpack.base.ts",
    "content": "import path from 'path'\nimport fs from 'fs-extra'\n\nconst getEntry = (src) => {\n  return [path.resolve(__dirname, '../src/extension/', src)]\n}\n\n// 先确保删除package目录，再创建新的\nconst packageDir = path.resolve(__dirname, '../package')\nif (fs.existsSync(packageDir)) {\n  fs.removeSync(packageDir)\n}\nfs.ensureDirSync(packageDir)\n\nfs.copy(path.resolve(__dirname, '../assets'), packageDir)\n\nfs.copy(\n  path.resolve(__dirname, '../src/extension/manifest.json'),\n  path.resolve(__dirname, '../package/manifest.json')\n)\n\nexport default {\n  mode: 'development',\n  devtool: 'inline-source-map', // 嵌入到源文件中\n  entry: {\n    popup: getEntry('./popup.tsx'),\n    devtools: getEntry('./devtools.tsx'),\n    devpanel: getEntry('./devpanel.tsx'),\n    content: getEntry('./content.ts'),\n    backend: getEntry('./backend.ts'),\n    demo: getEntry('../app/demo.tsx'),\n    inject: getEntry('./inject.ts'),\n    background: getEntry('./background.ts'),\n  },\n  output: {\n    path: path.resolve(__dirname, '../package'),\n    filename: 'js/[name].bundle.js',\n  },\n  resolve: {\n    modules: ['node_modules'],\n    extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],\n  },\n  module: {\n    rules: [\n      {\n        test: /\\.tsx?$/,\n        use: [\n          {\n            loader: require.resolve('ts-loader'),\n            options: {\n              transpileOnly: true,\n            },\n          },\n        ],\n      },\n      {\n        test: /\\.css$/,\n        use: [\n          {\n            loader: require.resolve('style-loader'),\n            options: {\n              singleton: true,\n            },\n          },\n          require.resolve('css-loader'),\n        ],\n      },\n      {\n        test: /\\.html?$/,\n        loader: require.resolve('file-loader'),\n        options: {\n          name: '[name].[ext]',\n        },\n      },\n    ],\n  },\n}\n"
  },
  {
    "path": "devtools/chrome-extension/config/webpack.dev.ts",
    "content": "import baseConfig from './webpack.base'\nimport HtmlWebpackPlugin from 'html-webpack-plugin'\nimport webpack from 'webpack'\nimport path from 'path'\n\nconst PORT = 3000\n\nconst createPages = (pages) => {\n  return pages.map(({ filename, template, chunk }) => {\n    return new HtmlWebpackPlugin({\n      filename,\n      template,\n      inject: 'body',\n      chunks: [chunk],\n    })\n  })\n}\n\nfor (let key in baseConfig.entry) {\n  if (Array.isArray(baseConfig.entry[key])) {\n    baseConfig.entry[key].push(\n      require.resolve('webpack/hot/dev-server'),\n      `${require.resolve('webpack-dev-server/client')}?http://localhost:${PORT}`\n    )\n  }\n}\n\nmodule.exports = {\n  ...baseConfig,\n  plugins: [\n    ...createPages([\n      {\n        filename: 'index.html',\n        template: path.resolve(\n          __dirname,\n          '../src/extension/views/devtools.ejs'\n        ),\n        chunk: 'demo',\n      },\n    ]),\n    new webpack.HotModuleReplacementPlugin(),\n  ],\n  devServer: {\n    open: true,\n    port: PORT,\n  },\n}\n"
  },
  {
    "path": "devtools/chrome-extension/config/webpack.prod.ts",
    "content": "import baseConfig from './webpack.base'\nimport HtmlWebpackPlugin from 'html-webpack-plugin'\nimport path from 'path'\n\nconst createPages = (pages) => {\n  return pages.map(({ filename, template, chunk }) => {\n    return new HtmlWebpackPlugin({\n      filename,\n      template,\n      inject: 'body',\n      chunks: [chunk],\n    })\n  })\n}\n\nmodule.exports = {\n  ...baseConfig,\n  mode: 'production',\n  plugins: [\n    ...createPages([\n      {\n        filename: 'popup.html',\n        template: path.resolve(__dirname, '../src/extension/views/popup.ejs'),\n        chunk: 'popup',\n      },\n      {\n        filename: 'devtools.html',\n        template: path.resolve(\n          __dirname,\n          '../src/extension/views/devtools.ejs'\n        ),\n        chunk: 'devtools',\n      },\n      {\n        filename: 'devpanel.html',\n        template: path.resolve(\n          __dirname,\n          '../src/extension/views/devpanel.ejs'\n        ),\n        chunk: 'devpanel',\n      },\n    ]),\n  ],\n}\n"
  },
  {
    "path": "devtools/chrome-extension/package.json",
    "content": "{\n  \"name\": \"@formily/chrome-extension\",\n  \"version\": \"2.3.7\",\n  \"private\": true,\n  \"license\": \"MIT\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/alibaba/formily.git\"\n  },\n  \"types\": \"esm/index.d.ts\",\n  \"bugs\": {\n    \"url\": \"https://github.com/alibaba/formily/issues\"\n  },\n  \"homepage\": \"https://github.com/alibaba/formily#readme\",\n  \"engines\": {\n    \"npm\": \">=3.0.0\"\n  },\n  \"scripts\": {\n    \"build:devtools\": \"cross-env NODE_OPTIONS=--openssl-legacy-provider webpack-cli --config config/webpack.prod.ts\",\n    \"build:zip\": \"rimraf package.zip && zip -r package.zip package\",\n    \"start\": \"cross-env NODE_OPTIONS=--openssl-legacy-provider webpack-dev-server --config config/webpack.dev.ts\"\n  },\n  \"dependencies\": {\n    \"@formily/core\": \"2.3.7\",\n    \"@formily/shared\": \"2.3.7\",\n    \"react\": \"^18.0.0\",\n    \"react-dom\": \"^18.0.0\",\n    \"react-json-view\": \"^1.19.1\",\n    \"react-treebeard\": \"^3.2.4\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"gitHead\": \"2c44ae410a73f02735c63c6430e021a50e21f3ec\"\n}\n"
  },
  {
    "path": "devtools/chrome-extension/src/app/components/FieldTree.tsx",
    "content": "import React, { useState, useEffect, useRef } from 'react'\nimport styled from 'styled-components'\nimport { FormPath, isObj } from '@formily/shared'\nimport { Treebeard, decorators } from 'react-treebeard'\nimport * as filters from './filter'\nimport SearchBox from './SearchBox'\n\nconst createTree = (dataSource: any, cursor?: any) => {\n  const tree: any = {}\n  const getParentPath = (key: string) => {\n    let parentPath: FormPath = FormPath.parse(key)\n    let i = 0\n    while (true) {\n      parentPath = parentPath.parent()\n      if (dataSource[parentPath.toString()]) {\n        return parentPath\n      }\n      if (i > parentPath.segments.length) return parentPath\n      i++\n    }\n  }\n  const findParent = (key: string): any => {\n    const parentPath = getParentPath(key)\n    const _findParent = (node: any) => {\n      if (FormPath.parse(node.path).match(parentPath)) {\n        return node\n      } else {\n        for (let i = 0; i < node?.children?.length; i++) {\n          const parent = _findParent(node.children[i])\n          if (parent) {\n            return parent\n          }\n        }\n      }\n    }\n    return _findParent(tree)\n  }\n  Object.keys(dataSource || {}).forEach((key) => {\n    if (key == '') {\n      tree.name = 'Form'\n      tree.path = key\n      tree.toggled = true\n      tree.data = dataSource[key]\n      if (cursor && cursor.current && cursor.current.path === key) {\n        tree.active = true\n        cursor.current = tree\n      }\n    } else {\n      const node: any = {\n        name: key,\n        path: key,\n        toggled: true,\n        data: dataSource[key],\n      }\n      if (cursor && cursor.current && cursor.current.path === key) {\n        node.active = true\n        cursor.current = node\n      }\n      const parent = findParent(key)\n      if (parent) {\n        node.name = (node.path || '').slice(\n          parent && parent.path ? parent.path.length + 1 : 0\n        )\n        parent.children = parent.children || []\n        parent.children.push(node)\n      }\n    }\n  })\n  return tree\n}\n\nconst theme = {\n  tree: {\n    base: {\n      listStyle: 'none',\n      margin: 0,\n      padding: 0,\n      color: '#9DA5AB',\n      fontFamily: 'lucida grande ,tahoma,verdana,arial,sans-serif',\n      fontSize: '8px',\n      background: 'none',\n      marginBottom: '50px',\n    },\n    node: {\n      base: {\n        position: 'relative',\n        background: 'none',\n      },\n      link: {\n        cursor: 'pointer',\n        position: 'relative',\n        padding: '0px 5px',\n        display: 'block',\n      },\n      activeLink: {\n        background: '#3D424A',\n      },\n      toggle: {\n        base: {\n          position: 'relative',\n          display: 'inline-block',\n          verticalAlign: 'top',\n          marginLeft: '-5px',\n          height: '22px',\n          width: '20px',\n          zIndex: 2,\n        },\n        wrapper: {\n          position: 'absolute',\n          top: '50%',\n          left: '50%',\n          transform: 'translate(-50%,-50%)',\n          width: 4,\n          height: 6,\n          display: 'flex',\n          alignItems: 'center',\n          justifyContent: 'center',\n        },\n        height: 6,\n        width: 4,\n        arrow: {\n          fill: '#9DA5AB',\n          strokeWidth: 0,\n        },\n      },\n      header: {\n        base: {\n          display: 'inline-block',\n          verticalAlign: 'top',\n          color: '#9DA5AB',\n        },\n        connector: {\n          width: '2px',\n          height: '12px',\n          borderLeft: 'solid 2px black',\n          borderBottom: 'solid 2px black',\n          position: 'absolute',\n          top: '0px',\n          left: '-21px',\n        },\n        title: {\n          lineHeight: '24px',\n          verticalAlign: 'middle',\n        },\n      },\n      subtree: {\n        listStyle: 'none',\n        paddingLeft: '19px',\n      },\n      loading: {\n        color: '#E2C089',\n      },\n    },\n  },\n}\n\nconst Header = (props) => {\n  const { node, style, customStyles } = props\n  const title = node.data?.title ? node.data.title : ''\n  return (\n    <div\n      className=\"node-header\"\n      style={style.base}\n      onClick={() => {\n        node.toggled = false\n      }}\n    >\n      <div\n        style={\n          node.selected\n            ? { ...style.title, ...customStyles.header.title }\n            : style.title\n        }\n      >\n        <span\n          style={{\n            zIndex: 1,\n            position: 'relative',\n            fontSize: 12,\n          }}\n        >\n          {node.name}\n        </span>\n        <span style={{ zIndex: 1, position: 'absolute', right: 12 }}>\n           {isObj(title) ? ((title as any).title ?? '') : title}\n        </span>\n        <div\n          className={`highlight ${node.active ? 'active' : ''}`}\n          style={{ transition: '.15s all ease-in' }}\n        ></div>\n      </div>\n    </div>\n  )\n}\n\nconst ToolBar = styled.div`\n  border-bottom: 1px solid #3d424a;\n  height: 20px;\n  padding: 10px 10px;\n  padding: 5px;\n  overflow: auto;\n  position: sticky;\n  top: 0;\n  background: #282c34;\n  z-index: 100;\n`\n\nexport const FieldTree = styled(({ className, dataSource, onSelect }) => {\n  const allDataRef = useRef(createTree(dataSource))\n  const cursor = useRef(allDataRef.current)\n  const [keyword, setKeyword] = useState('')\n  const searchTimer = useRef(null)\n  const [data, setData] = useState(allDataRef.current)\n\n  const filterData = () => {\n    if (!keyword) return data\n    const finded = filters.filterTree(data, keyword)\n    return filters.expandFilteredNodes(finded, keyword)\n  }\n\n  const onToggle = (node: any, toggled: boolean) => {\n    cursor.current.active = false\n    node.active = true\n    if (node.children && node.children.length) {\n      node.toggled = toggled\n    }\n    cursor.current = node\n    setData(data)\n    if (onSelect) {\n      onSelect(node)\n    }\n  }\n\n  const onSearch = ({ target: { value } }) => {\n    clearTimeout(searchTimer.current)\n    searchTimer.current = setTimeout(() => {\n      setKeyword(value.trim())\n    }, 100)\n  }\n\n  useEffect(() => {\n    allDataRef.current = createTree(dataSource, cursor)\n    setData(allDataRef.current)\n  }, [dataSource])\n\n  return (\n    <div className={className}>\n      <ToolBar>\n        <SearchBox onSearch={onSearch} />\n      </ToolBar>\n\n      <Treebeard\n        data={filterData()}\n        onToggle={onToggle}\n        decorators={{\n          ...decorators,\n          Header,\n        }}\n        style={theme}\n      />\n    </div>\n  )\n})`\n  position: relative;\n  overflow: auto;\n  height: calc(100% - 40px);\n  user-select: none;\n  .highlight {\n    position: absolute;\n    top: 0;\n    right: 0;\n    left: -100%;\n    height: 100%;\n    z-index: 0;\n    &.active {\n      background: #3d424a;\n    }\n  }\n  .node-header:hover .highlight {\n    background: #3d424a;\n  }\n`\n"
  },
  {
    "path": "devtools/chrome-extension/src/app/components/LeftPanel.tsx",
    "content": "import React, { useState } from 'react'\nimport { Tabs } from './Tabs'\nimport { FieldTree } from './FieldTree'\nimport styled from 'styled-components'\n\nexport const LeftPanel = styled(({ className, dataSource, onSelect }) => {\n  const [current, setCurrent] = useState(0)\n  return (\n    <div className={className}>\n      <Tabs\n        dataSource={dataSource}\n        current={current}\n        onChange={(index) => {\n          setCurrent(index)\n          onSelect({\n            current: index,\n            key: '',\n          })\n        }}\n      />\n      <FieldTree\n        dataSource={dataSource[current]}\n        onSelect={(node) => {\n          if (onSelect) {\n            onSelect({\n              current,\n              key: node.path,\n            })\n          }\n        }}\n      />\n    </div>\n  )\n})`\n  width: 50%;\n  min-width: 50%;\n`\n"
  },
  {
    "path": "devtools/chrome-extension/src/app/components/RightPanel.tsx",
    "content": "import React from 'react'\nimport styled from 'styled-components'\nimport ReactJson from 'react-json-view'\n\nexport const RightPanel = styled(({ className, dataSource }) => {\n  return (\n    <div className={className}>\n      <ReactJson\n        src={dataSource}\n        name={dataSource && dataSource.displayName}\n        theme=\"hopscotch\"\n        displayDataTypes={false}\n        enableClipboard={false}\n        sortKeys={true}\n        onEdit={false}\n        onAdd={false}\n        onDelete={false}\n        iconStyle=\"square\"\n      />\n    </div>\n  )\n})`\n  border-left: 1px solid #3d424a;\n  flex-grow: 2;\n  overflow: auto;\n  padding: 10px;\n  .react-json-view {\n    background: none !important;\n    font-size: 12px !important;\n  }\n`\n"
  },
  {
    "path": "devtools/chrome-extension/src/app/components/SearchBox.tsx",
    "content": "import React from 'react'\nimport styled from 'styled-components'\n\nconst SerachBox = styled.div`\n  display: flex;\n  align-items: center;\n  height: 100%;\n  .input-addon {\n    padding: 0 5px;\n  }\n  .form-control {\n    width: 50%;\n    border: none;\n    background: transparent;\n    color: white;\n    outline: none;\n  }\n`\n\nconst SearchIcon = () => {\n  return (\n    <svg\n      t=\"1592193216787\"\n      className=\"icon\"\n      viewBox=\"0 0 1024 1024\"\n      version=\"1.1\"\n      p-id=\"3365\"\n      width=\"12\"\n      height=\"12\"\n    >\n      <defs>\n        <style type=\"text/css\"></style>\n      </defs>\n      <path\n        d=\"M976.738462 892.061538L712.861538 630.153846c53.169231-74.830769 80.738462-169.353846 66.953847-269.784615-23.630769-169.353846-161.476923-303.261538-332.8-319.015385C214.646154 17.723077 17.723077 214.646154 41.353846 448.984615c15.753846 169.353846 149.661538 309.169231 319.015385 332.8 100.430769 13.784615 194.953846-13.784615 269.784615-66.953846l261.907692 261.907693c11.815385 11.815385 29.538462 11.815385 41.353847 0l41.353846-41.353847c11.815385-11.815385 11.815385-31.507692 1.969231-43.323077zM157.538462 411.569231C157.538462 271.753846 271.753846 157.538462 411.569231 157.538462s254.030769 114.215385 254.030769 254.030769S551.384615 665.6 411.569231 665.6 157.538462 553.353846 157.538462 411.569231z\"\n        p-id=\"3366\"\n        fill=\"#9da5ab\"\n      ></path>\n    </svg>\n  )\n}\n\nexport default ({ onSearch }) => {\n  return (\n    <SerachBox>\n      <div className=\"input-addon\">\n        <SearchIcon />\n      </div>\n      <input\n        className=\"form-control\"\n        onChange={onSearch}\n        placeholder=\"Search the field...\"\n        type=\"text\"\n      />\n    </SerachBox>\n  )\n}\n"
  },
  {
    "path": "devtools/chrome-extension/src/app/components/Tabs.tsx",
    "content": "import React from 'react'\nimport styled from 'styled-components'\nimport { toArr } from '@formily/shared'\n\nexport const Tabs = styled(({ className, dataSource, current, onChange }) => {\n  current = current || 0\n  return (\n    <div className={className}>\n      {toArr(dataSource).map((item, index) => {\n        return (\n          <div\n            className={`tab-item ${current == index ? 'active' : ''}`}\n            key={index}\n            onClick={() => {\n              if (onChange) {\n                onChange(index)\n              }\n            }}\n          >\n            <span>Form#{index + 1}</span>\n          </div>\n        )\n      })}\n    </div>\n  )\n})`\n  height: 36px;\n  border-bottom: 1px solid #3d424a;\n  display: flex;\n  line-height: 36px;\n  width: 100%;\n  overflow: scroll;\n  &::-webkit-scrollbar {\n    display: none;\n  }\n  .tab-item {\n    cursor: pointer;\n    transition: 0.15s all ease-in-out;\n    border-right: 1px solid #3d424a;\n    padding: 0 10px;\n    font-size: 12px;\n    &:hover {\n      background: #1d1f25;\n    }\n    &.active {\n      background: #1d1f25;\n    }\n  }\n`\n"
  },
  {
    "path": "devtools/chrome-extension/src/app/components/filter.ts",
    "content": "// Helper functions for filtering\nexport const defaultMatcher = (filterText, node) => {\n  return node.name.toLowerCase().indexOf(filterText.toLowerCase()) !== -1\n}\n\nexport const findNode = (node, filter, matcher) => {\n  return (\n    matcher(filter, node) || // i match\n    (node.children && // or i have decendents and one of them match\n      node.children.length &&\n      !!node.children.find((child) => findNode(child, filter, matcher)))\n  )\n}\n\nexport const filterTree = (node, filter, matcher = defaultMatcher) => {\n  // If im an exact match then all my children get to stay\n  if (matcher(filter, node) || !node.children) {\n    return node\n  }\n  // If not then only keep the ones that match or have matching descendants\n  const filtered = node.children\n    .filter((child) => findNode(child, filter, matcher))\n    .map((child) => filterTree(child, filter, matcher))\n  return Object.assign({}, node, { children: filtered })\n}\n\nexport const expandFilteredNodes = (node, filter, matcher = defaultMatcher) => {\n  let children = node.children\n  if (!children || children.length === 0) {\n    return Object.assign({}, node, { toggled: false })\n  }\n  const childrenWithMatches = node.children.filter((child) =>\n    findNode(child, filter, matcher)\n  )\n  const shouldExpand = childrenWithMatches.length > 0\n  // If im going to expand, go through all the matches and see if thier children need to expand\n  if (shouldExpand) {\n    children = childrenWithMatches.map((child) => {\n      return expandFilteredNodes(child, filter, matcher)\n    })\n  }\n  return Object.assign({}, node, {\n    children: children,\n    toggled: shouldExpand,\n  })\n}\n"
  },
  {
    "path": "devtools/chrome-extension/src/app/demo.tsx",
    "content": "import React from 'react'\nimport ReactDOM from 'react-dom'\nimport App from './index'\nconst dataSource = [\n  {\n    '': {\n      pristine: false,\n      valid: true,\n      invalid: false,\n      loading: false,\n      validating: false,\n      initialized: true,\n      submitting: false,\n      errors: [],\n      warnings: [],\n      values: {\n        aa: true,\n        cc: true,\n        gg: 'aaaa',\n      },\n      initialValues: {\n        aa: true,\n        cc: true,\n      },\n      mounted: true,\n      unmounted: false,\n      props: {},\n      displayName: 'FormState',\n    },\n    block: {\n      name: 'block',\n      path: 'block',\n      initialized: true,\n      visible: true,\n      display: true,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'block',\n        type: 'object',\n        name: 'block',\n        'x-component': 'block',\n        'x-props': {\n          title: 'Block1',\n        },\n        'x-component-props': {\n          title: 'Block1',\n        },\n      },\n      displayName: 'VirtualFieldState',\n    },\n    'block.aa': {\n      name: 'aa',\n      path: 'block.aa',\n      dataType: 'boolean',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [true],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      value: true,\n      initialValue: true,\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'aa',\n        name: 'aa',\n        type: 'boolean',\n        'x-component': 'radio',\n        default: true,\n        enum: [\n          {\n            label: '是',\n            value: true,\n          },\n          {\n            label: '否',\n            value: false,\n          },\n        ],\n        title: '是否隐藏AA',\n      },\n      displayName: 'FieldState',\n    },\n    'block.bb': {\n      name: 'bb',\n      path: 'block.bb',\n      dataType: 'string',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: false,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [null],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'bb',\n        name: 'bb',\n        type: 'string',\n        title: 'AA',\n      },\n      displayName: 'FieldState',\n    },\n    'block.cc': {\n      name: 'cc',\n      path: 'block.cc',\n      dataType: 'boolean',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [true],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      value: true,\n      initialValue: true,\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'cc',\n        name: 'cc',\n        type: 'boolean',\n        title: '是否隐藏DD',\n        default: true,\n        'x-component': 'radio',\n        enum: [\n          {\n            label: '是',\n            value: true,\n          },\n          {\n            label: '否',\n            value: false,\n          },\n        ],\n      },\n      displayName: 'FieldState',\n    },\n    dd: {\n      name: 'dd',\n      path: 'dd',\n      initialized: true,\n      visible: false,\n      display: true,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'dd',\n        type: 'object',\n        name: 'dd',\n        'x-component': 'block',\n        'x-props': {\n          title: 'Block2',\n        },\n        'x-component-props': {\n          title: 'Block2',\n        },\n      },\n      displayName: 'VirtualFieldState',\n    },\n    kk: {\n      name: 'kk',\n      path: 'kk',\n      initialized: true,\n      visible: true,\n      display: true,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'kk',\n        type: 'object',\n        name: 'kk',\n        'x-component': 'block',\n        'x-props': {\n          title: 'Block3',\n        },\n        'x-component-props': {\n          title: 'Block3',\n        },\n      },\n      displayName: 'VirtualFieldState',\n    },\n    'kk.gg': {\n      name: 'gg',\n      path: 'kk.gg',\n      dataType: 'string',\n      initialized: true,\n      pristine: false,\n      valid: true,\n      modified: true,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: ['aaaa'],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      value: 'aaaa',\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'gg',\n        name: 'gg',\n        type: 'string',\n        title: 'GG',\n        'x-props': {\n          showSearch: true,\n          filterLocal: false,\n          style: {\n            width: 200,\n          },\n        },\n        enum: [\n          {\n            label: 'aaaa',\n            value: 'aaaa',\n            extra: ['x1', 'x2', 'x3'],\n          },\n          {\n            label: 'bbbb',\n            value: 'bbbb',\n            extra: ['x4', 'x5', 'x6'],\n          },\n          {\n            label: 'cccc',\n            value: 'cccc',\n            extra: ['x7', 'x8', 'x9'],\n          },\n        ],\n      },\n      displayName: 'FieldState',\n    },\n    'kk.hh': {\n      name: 'hh',\n      path: 'kk.hh',\n      dataType: 'string',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: false,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [null],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'hh',\n        name: 'hh',\n        type: 'string',\n        title: 'HH',\n        enum: [],\n        'x-props': {\n          style: {\n            width: 200,\n          },\n        },\n      },\n      displayName: 'FieldState',\n    },\n  },\n  {\n    '': {\n      pristine: true,\n      valid: true,\n      invalid: false,\n      loading: false,\n      validating: false,\n      initialized: true,\n      submitting: false,\n      errors: [],\n      warnings: [],\n      values: {},\n      initialValues: {},\n      mounted: true,\n      unmounted: false,\n      props: {},\n      displayName: 'FormState',\n    },\n    total: {\n      name: 'total',\n      path: 'total',\n      dataType: 'number',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [null],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      rules: [\n        {\n          required: true,\n        },\n      ],\n      required: true,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'total',\n        name: 'total',\n        type: 'number',\n        required: true,\n        title: '总价',\n      },\n      displayName: 'FieldState',\n    },\n    count: {\n      name: 'count',\n      path: 'count',\n      dataType: 'number',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [null],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      rules: [\n        {\n          required: true,\n        },\n      ],\n      required: true,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'count',\n        name: 'count',\n        type: 'number',\n        required: true,\n        title: '数量',\n      },\n      displayName: 'FieldState',\n    },\n    price: {\n      name: 'price',\n      path: 'price',\n      dataType: 'number',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [null],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      rules: [\n        {\n          required: true,\n        },\n      ],\n      required: true,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'price',\n        name: 'price',\n        type: 'number',\n        required: true,\n        title: '单价',\n      },\n      displayName: 'FieldState',\n    },\n  },\n  {\n    '': {\n      pristine: true,\n      valid: true,\n      invalid: false,\n      loading: false,\n      validating: false,\n      initialized: true,\n      submitting: false,\n      errors: [],\n      warnings: [],\n      values: {},\n      initialValues: {},\n      mounted: true,\n      unmounted: false,\n      props: {},\n      displayName: 'FormState',\n    },\n    NO_NAME_FIELD_$0: {\n      name: 'NO_NAME_FIELD_$0',\n      path: 'NO_NAME_FIELD_$0',\n      initialized: true,\n      visible: true,\n      display: true,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'NO_NAME_FIELD_$0',\n        type: 'object',\n        name: 'NO_NAME_FIELD_$0',\n        'x-component': 'block',\n        'x-props': {\n          title: 'Block1',\n        },\n        'x-component-props': {\n          title: 'Block1',\n        },\n      },\n      displayName: 'VirtualFieldState',\n    },\n    'NO_NAME_FIELD_$0.aa': {\n      name: 'aa',\n      path: 'NO_NAME_FIELD_$0.aa',\n      dataType: 'string',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [null],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'aa',\n        name: 'aa',\n        type: 'string',\n        enum: ['aaaaa', 'bbbbb', 'ccccc', 'ddddd', 'eeeee'],\n        title: 'AA',\n      },\n      displayName: 'FieldState',\n    },\n    'NO_NAME_FIELD_$0.bb': {\n      name: 'bb',\n      path: 'NO_NAME_FIELD_$0.bb',\n      dataType: 'string',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: false,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [null],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'bb',\n        type: 'string',\n        name: 'bb',\n        title: 'BB',\n        enum: [],\n      },\n      displayName: 'FieldState',\n    },\n    'NO_NAME_FIELD_$0.cc': {\n      name: 'cc',\n      path: 'NO_NAME_FIELD_$0.cc',\n      dataType: 'string',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [null],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'cc',\n        type: 'string',\n        name: 'cc',\n        title: 'CC',\n      },\n      displayName: 'FieldState',\n    },\n  },\n  {\n    '': {\n      pristine: true,\n      valid: true,\n      invalid: false,\n      loading: false,\n      validating: false,\n      initialized: true,\n      submitting: false,\n      errors: [],\n      warnings: [],\n      values: {},\n      initialValues: {},\n      mounted: true,\n      unmounted: false,\n      props: {},\n      displayName: 'FormState',\n    },\n    aa: {\n      name: 'aa',\n      path: 'aa',\n      dataType: 'string',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [null],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      rules: [\n        {\n          required: true,\n        },\n      ],\n      required: true,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'aa',\n        name: 'aa',\n        type: 'string',\n        required: true,\n        title: 'AA',\n      },\n      displayName: 'FieldState',\n    },\n    bb: {\n      name: 'bb',\n      path: 'bb',\n      dataType: 'string',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [null],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'bb',\n        type: 'string',\n        name: 'bb',\n        title: 'BB',\n        enum: ['111', '222'],\n      },\n      displayName: 'FieldState',\n    },\n  },\n  {\n    '': {\n      pristine: false,\n      valid: true,\n      invalid: false,\n      loading: false,\n      validating: false,\n      initialized: true,\n      submitting: false,\n      errors: [],\n      warnings: [],\n      values: {\n        aa: [\n          {\n            bb: 'aaaaa',\n            dd: [\n              {\n                ff: '是',\n                ee: '是',\n              },\n            ],\n            cc: '1111',\n          },\n          {\n            bb: 'ccccc',\n            dd: [\n              {\n                ff: '是',\n                ee: '否',\n              },\n            ],\n            cc: '1111',\n          },\n        ],\n      },\n      initialValues: {\n        aa: [\n          {\n            bb: 'aaaaa',\n            dd: [\n              {\n                ee: '是',\n                ff: '是',\n              },\n            ],\n          },\n          {\n            bb: 'ccccc',\n            dd: [\n              {\n                ee: '否',\n                ff: '是',\n              },\n            ],\n          },\n        ],\n      },\n      mounted: true,\n      unmounted: false,\n      props: {},\n      displayName: 'FormState',\n    },\n    NO_NAME_FIELD_$0: {\n      name: 'NO_NAME_FIELD_$0',\n      path: 'NO_NAME_FIELD_$0',\n      initialized: true,\n      visible: true,\n      display: true,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'NO_NAME_FIELD_$0',\n        type: 'object',\n        name: 'NO_NAME_FIELD_$0',\n        'x-component': 'block',\n        'x-props': {\n          title: 'Block1',\n        },\n        'x-component-props': {\n          title: 'Block1',\n        },\n      },\n      displayName: 'VirtualFieldState',\n    },\n    'NO_NAME_FIELD_$0.aa': {\n      name: 'aa',\n      path: 'NO_NAME_FIELD_$0.aa',\n      dataType: 'array',\n      initialized: true,\n      pristine: false,\n      valid: true,\n      modified: true,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [\n        [\n          {\n            bb: 'aaaaa',\n            dd: [\n              {\n                ff: '是',\n                ee: '是',\n              },\n            ],\n            cc: '1111',\n          },\n          {\n            bb: 'ccccc',\n            dd: [\n              {\n                ff: '是',\n                ee: '否',\n              },\n            ],\n            cc: '1111',\n          },\n        ],\n      ],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      value: [\n        {\n          bb: 'aaaaa',\n          dd: [\n            {\n              ff: '是',\n              ee: '是',\n            },\n          ],\n          cc: '1111',\n        },\n        {\n          bb: 'ccccc',\n          dd: [\n            {\n              ff: '是',\n              ee: '否',\n            },\n          ],\n          cc: '1111',\n        },\n      ],\n      initialValue: [\n        {\n          bb: 'aaaaa',\n          dd: [\n            {\n              ee: '是',\n              ff: '是',\n            },\n          ],\n        },\n        {\n          bb: 'ccccc',\n          dd: [\n            {\n              ee: '否',\n              ff: '是',\n            },\n          ],\n        },\n      ],\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'aa',\n        type: 'array',\n        name: 'aa',\n      },\n      displayName: 'FieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.0': {\n      name: 'aa.0',\n      path: 'NO_NAME_FIELD_$0.aa.0',\n      dataType: 'object',\n      initialized: true,\n      pristine: false,\n      valid: true,\n      modified: true,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [\n        {\n          bb: 'aaaaa',\n          dd: [\n            {\n              ff: '是',\n              ee: '是',\n            },\n          ],\n          cc: '1111',\n        },\n      ],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      value: {\n        bb: 'aaaaa',\n        dd: [\n          {\n            ff: '是',\n            ee: '是',\n          },\n        ],\n        cc: '1111',\n      },\n      initialValue: {\n        bb: 'aaaaa',\n        dd: [\n          {\n            ee: '是',\n            ff: '是',\n          },\n        ],\n      },\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        type: 'object',\n      },\n      displayName: 'FieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$1': {\n      name: 'aa.0.NO_NAME_FIELD_$1',\n      path: 'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$1',\n      initialized: true,\n      visible: true,\n      display: true,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'NO_NAME_FIELD_$1',\n        type: 'object',\n        name: 'NO_NAME_FIELD_$1',\n        'x-component': 'block',\n        'x-props': {\n          title: '基本信息',\n        },\n        'x-component-props': {\n          title: '基本信息',\n        },\n      },\n      displayName: 'VirtualFieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$1.NO_NAME_FIELD_$2': {\n      name: 'aa.0.NO_NAME_FIELD_$2',\n      path: 'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$1.NO_NAME_FIELD_$2',\n      initialized: true,\n      visible: true,\n      display: true,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'NO_NAME_FIELD_$2',\n        type: 'object',\n        name: 'NO_NAME_FIELD_$2',\n        'x-component': 'layout',\n        'x-props': {\n          inline: true,\n        },\n        'x-component-props': {\n          inline: true,\n        },\n      },\n      displayName: 'VirtualFieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$1.NO_NAME_FIELD_$2.bb': {\n      name: 'aa.0.bb',\n      path: 'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$1.NO_NAME_FIELD_$2.bb',\n      dataType: 'string',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: ['aaaaa'],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      value: 'aaaaa',\n      initialValue: 'aaaaa',\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'bb',\n        type: 'string',\n        name: 'bb',\n        enum: ['aaaaa', 'bbbbb', 'ccccc', 'ddddd', 'eeeee'],\n        title: 'BB',\n      },\n      displayName: 'FieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$1.NO_NAME_FIELD_$2.cc': {\n      name: 'aa.0.cc',\n      path: 'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$1.NO_NAME_FIELD_$2.cc',\n      dataType: 'string',\n      initialized: true,\n      pristine: false,\n      valid: true,\n      modified: true,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: ['1111'],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      value: '1111',\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'cc',\n        type: 'string',\n        name: 'cc',\n        enum: ['1111', '2222'],\n        title: 'CC',\n      },\n      displayName: 'FieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$1.NO_NAME_FIELD_$2.gg': {\n      name: 'aa.0.gg',\n      path: 'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$1.NO_NAME_FIELD_$2.gg',\n      dataType: 'string',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [null],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'gg',\n        type: 'string',\n        name: 'gg',\n        title: 'GG',\n        'x-props': {\n          style: {\n            width: 200,\n          },\n        },\n      },\n      displayName: 'FieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$3': {\n      name: 'aa.0.NO_NAME_FIELD_$3',\n      path: 'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$3',\n      initialized: true,\n      visible: true,\n      display: true,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'NO_NAME_FIELD_$3',\n        type: 'object',\n        name: 'NO_NAME_FIELD_$3',\n        'x-component': 'block',\n        'x-props': {\n          title: '嵌套Array',\n        },\n        'x-component-props': {\n          title: '嵌套Array',\n        },\n      },\n      displayName: 'VirtualFieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$3.dd': {\n      name: 'aa.0.dd',\n      path: 'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$3.dd',\n      dataType: 'array',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [\n        [\n          {\n            ee: '是',\n            ff: '是',\n          },\n        ],\n      ],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      value: [\n        {\n          ee: '是',\n          ff: '是',\n        },\n      ],\n      initialValue: [\n        {\n          ee: '是',\n          ff: '是',\n        },\n      ],\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'dd',\n        type: 'array',\n        name: 'dd',\n      },\n      displayName: 'FieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$3.dd.0': {\n      name: 'aa.0.dd.0',\n      path: 'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$3.dd.0',\n      dataType: 'object',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [\n        {\n          ee: '是',\n          ff: '是',\n        },\n      ],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      value: {\n        ee: '是',\n        ff: '是',\n      },\n      initialValue: {\n        ee: '是',\n        ff: '是',\n      },\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        type: 'object',\n      },\n      displayName: 'FieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$3.dd.0.NO_NAME_FIELD_$4': {\n      name: 'aa.0.dd.0.NO_NAME_FIELD_$4',\n      path: 'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$3.dd.0.NO_NAME_FIELD_$4',\n      initialized: true,\n      visible: true,\n      display: true,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'NO_NAME_FIELD_$4',\n        type: 'object',\n        name: 'NO_NAME_FIELD_$4',\n        'x-component': 'layout',\n        'x-props': {\n          inline: true,\n          style: {\n            marginLeft: 20,\n          },\n        },\n        'x-component-props': {\n          inline: true,\n          style: {\n            marginLeft: 20,\n          },\n        },\n      },\n      displayName: 'VirtualFieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$3.dd.0.NO_NAME_FIELD_$4.ee': {\n      name: 'aa.0.dd.0.ee',\n      path: 'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$3.dd.0.NO_NAME_FIELD_$4.ee',\n      dataType: 'string',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: ['是'],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      value: '是',\n      initialValue: '是',\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'ee',\n        type: 'string',\n        name: 'ee',\n        enum: ['是', '否'],\n        title: 'EE',\n        description: '是否显示GG',\n      },\n      displayName: 'FieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$3.dd.0.NO_NAME_FIELD_$4.ff': {\n      name: 'aa.0.dd.0.ff',\n      path: 'NO_NAME_FIELD_$0.aa.0.NO_NAME_FIELD_$3.dd.0.NO_NAME_FIELD_$4.ff',\n      dataType: 'string',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: ['是'],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      value: '是',\n      initialValue: '是',\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'ff',\n        type: 'string',\n        name: 'ff',\n        default: '是',\n        enum: ['是', '否'],\n        title: 'FF',\n        description: '是否显示EE',\n      },\n      displayName: 'FieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.1': {\n      name: 'aa.1',\n      path: 'NO_NAME_FIELD_$0.aa.1',\n      dataType: 'object',\n      initialized: true,\n      pristine: false,\n      valid: true,\n      modified: true,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [\n        {\n          bb: 'ccccc',\n          dd: [\n            {\n              ff: '是',\n              ee: '否',\n            },\n          ],\n          cc: '1111',\n        },\n      ],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      value: {\n        bb: 'ccccc',\n        dd: [\n          {\n            ff: '是',\n            ee: '否',\n          },\n        ],\n        cc: '1111',\n      },\n      initialValue: {\n        bb: 'ccccc',\n        dd: [\n          {\n            ee: '否',\n            ff: '是',\n          },\n        ],\n      },\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        type: 'object',\n      },\n      displayName: 'FieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$1': {\n      name: 'aa.1.NO_NAME_FIELD_$1',\n      path: 'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$1',\n      initialized: true,\n      visible: true,\n      display: true,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'NO_NAME_FIELD_$1',\n        type: 'object',\n        name: 'NO_NAME_FIELD_$1',\n        'x-component': 'block',\n        'x-props': {\n          title: '基本信息',\n        },\n        'x-component-props': {\n          title: '基本信息',\n        },\n      },\n      displayName: 'VirtualFieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$1.NO_NAME_FIELD_$2': {\n      name: 'aa.1.NO_NAME_FIELD_$2',\n      path: 'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$1.NO_NAME_FIELD_$2',\n      initialized: true,\n      visible: true,\n      display: true,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'NO_NAME_FIELD_$2',\n        type: 'object',\n        name: 'NO_NAME_FIELD_$2',\n        'x-component': 'layout',\n        'x-props': {\n          inline: true,\n        },\n        'x-component-props': {\n          inline: true,\n        },\n      },\n      displayName: 'VirtualFieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$1.NO_NAME_FIELD_$2.bb': {\n      name: 'aa.1.bb',\n      path: 'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$1.NO_NAME_FIELD_$2.bb',\n      dataType: 'string',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: ['ccccc'],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      value: 'ccccc',\n      initialValue: 'ccccc',\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'bb',\n        type: 'string',\n        name: 'bb',\n        enum: ['aaaaa', 'bbbbb', 'ccccc', 'ddddd', 'eeeee'],\n        title: 'BB',\n      },\n      displayName: 'FieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$1.NO_NAME_FIELD_$2.cc': {\n      name: 'aa.1.cc',\n      path: 'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$1.NO_NAME_FIELD_$2.cc',\n      dataType: 'string',\n      initialized: true,\n      pristine: false,\n      valid: true,\n      modified: true,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: ['1111'],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      value: '1111',\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'cc',\n        type: 'string',\n        name: 'cc',\n        enum: ['1111', '2222'],\n        title: 'CC',\n      },\n      displayName: 'FieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$1.NO_NAME_FIELD_$2.gg': {\n      name: 'aa.1.gg',\n      path: 'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$1.NO_NAME_FIELD_$2.gg',\n      dataType: 'string',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: false,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [null],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'gg',\n        type: 'string',\n        name: 'gg',\n        title: 'GG',\n        'x-props': {\n          style: {\n            width: 200,\n          },\n        },\n      },\n      displayName: 'FieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$3': {\n      name: 'aa.1.NO_NAME_FIELD_$3',\n      path: 'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$3',\n      initialized: true,\n      visible: true,\n      display: true,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'NO_NAME_FIELD_$3',\n        type: 'object',\n        name: 'NO_NAME_FIELD_$3',\n        'x-component': 'block',\n        'x-props': {\n          title: '嵌套Array',\n        },\n        'x-component-props': {\n          title: '嵌套Array',\n        },\n      },\n      displayName: 'VirtualFieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$3.dd': {\n      name: 'aa.1.dd',\n      path: 'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$3.dd',\n      dataType: 'array',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [\n        [\n          {\n            ee: '否',\n            ff: '是',\n          },\n        ],\n      ],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      value: [\n        {\n          ee: '否',\n          ff: '是',\n        },\n      ],\n      initialValue: [\n        {\n          ee: '否',\n          ff: '是',\n        },\n      ],\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'dd',\n        type: 'array',\n        name: 'dd',\n      },\n      displayName: 'FieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$3.dd.0': {\n      name: 'aa.1.dd.0',\n      path: 'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$3.dd.0',\n      dataType: 'object',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: [\n        {\n          ee: '否',\n          ff: '是',\n        },\n      ],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      value: {\n        ee: '否',\n        ff: '是',\n      },\n      initialValue: {\n        ee: '否',\n        ff: '是',\n      },\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        type: 'object',\n      },\n      displayName: 'FieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$3.dd.0.NO_NAME_FIELD_$4': {\n      name: 'aa.1.dd.0.NO_NAME_FIELD_$4',\n      path: 'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$3.dd.0.NO_NAME_FIELD_$4',\n      initialized: true,\n      visible: true,\n      display: true,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'NO_NAME_FIELD_$4',\n        type: 'object',\n        name: 'NO_NAME_FIELD_$4',\n        'x-component': 'layout',\n        'x-props': {\n          inline: true,\n          style: {\n            marginLeft: 20,\n          },\n        },\n        'x-component-props': {\n          inline: true,\n          style: {\n            marginLeft: 20,\n          },\n        },\n      },\n      displayName: 'VirtualFieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$3.dd.0.NO_NAME_FIELD_$4.ee': {\n      name: 'aa.1.dd.0.ee',\n      path: 'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$3.dd.0.NO_NAME_FIELD_$4.ee',\n      dataType: 'string',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: ['否'],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      value: '否',\n      initialValue: '否',\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'ee',\n        type: 'string',\n        name: 'ee',\n        enum: ['是', '否'],\n        title: 'EE',\n        description: '是否显示GG',\n      },\n      displayName: 'FieldState',\n    },\n    'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$3.dd.0.NO_NAME_FIELD_$4.ff': {\n      name: 'aa.1.dd.0.ff',\n      path: 'NO_NAME_FIELD_$0.aa.1.NO_NAME_FIELD_$3.dd.0.NO_NAME_FIELD_$4.ff',\n      dataType: 'string',\n      initialized: true,\n      pristine: true,\n      valid: true,\n      modified: false,\n      touched: false,\n      active: false,\n      visited: false,\n      invalid: false,\n      visible: true,\n      display: true,\n      loading: false,\n      validating: false,\n      errors: [],\n      values: ['是'],\n      ruleErrors: [],\n      ruleWarnings: [],\n      effectErrors: [],\n      warnings: [],\n      effectWarnings: [],\n      editable: true,\n      value: '是',\n      initialValue: '是',\n      rules: [],\n      required: false,\n      mounted: true,\n      unmounted: false,\n      props: {\n        key: 'ff',\n        type: 'string',\n        name: 'ff',\n        default: '是',\n        enum: ['是', '否'],\n        title: 'FF',\n        description: '是否显示EE',\n      },\n      displayName: 'FieldState',\n    },\n  },\n]\n\nReactDOM.render(\n  <App dataSource={dataSource} />,\n  document.getElementById('root')\n)\n"
  },
  {
    "path": "devtools/chrome-extension/src/app/index.tsx",
    "content": "import React, { useState } from 'react'\nimport { LeftPanel } from './components/LeftPanel'\nimport { RightPanel } from './components/RightPanel'\nimport styled from 'styled-components'\n\nexport default styled(({ className, dataSource }) => {\n  const [selected, select] = useState({\n    current: 0,\n    key: '',\n  })\n  return (\n    <div className={className}>\n      <LeftPanel\n        dataSource={dataSource}\n        onSelect={(info) => {\n          select(info)\n          if (chrome && chrome.devtools && chrome.devtools.inspectedWindow) {\n            chrome.devtools.inspectedWindow.eval(\n              `window.__FORMILY_DEV_TOOLS_HOOK__.setVm(\"${info.key}\",\"${\n                dataSource[info.current][''].id\n              }\")`\n            )\n          }\n        }}\n      />\n      <RightPanel\n        dataSource={\n          selected\n            ? (dataSource &&\n                dataSource[selected.current] &&\n                dataSource[selected.current][selected.key]) ||\n              {}\n            : {}\n        }\n      />\n    </div>\n  )\n})`\n  display: flex;\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  right: 0;\n  overflow: hidden;\n  color: #36d4c7;\n  background: #282c34;\n`\n"
  },
  {
    "path": "devtools/chrome-extension/src/extension/backend.ts",
    "content": "//inject content script\n\nconst serializeObject = (obj: any) => {\n  const seens = new WeakMap()\n  const serialize = (obj: any) => {\n    if (Array.isArray(obj)) {\n      return obj.map(serialize)\n    } else if (typeof obj === 'function') {\n      return `f ${obj.displayName || obj.name}(){ }`\n    } else if (typeof obj === 'object') {\n      if (seens.get(obj)) return '#CircularReference'\n      if (!obj) return obj\n      if ('$$typeof' in obj && '_owner' in obj) {\n        seens.set(obj, true)\n        return '#ReactNode'\n      } else if (obj.toJS) {\n        seens.set(obj, true)\n        return obj.toJS()\n      } else if (obj.toJSON) {\n        seens.set(obj, true)\n        return obj.toJSON()\n      } else {\n        seens.set(obj, true)\n        const result = {}\n        for (let key in obj) {\n          result[key] = serialize(obj[key])\n        }\n        seens.set(obj, false)\n        return result\n      }\n    }\n    return obj\n  }\n  return serialize(obj)\n}\n\nconst send = ({\n  type,\n  id,\n  form,\n}: {\n  type: string\n  id?: string | number\n  form?: any\n}) => {\n  const graph = serializeObject(form?.getFormGraph())\n  window.postMessage(\n    {\n      source: '@formily-devtools-inject-script',\n      type,\n      id,\n      graph:\n        form &&\n        JSON.stringify(graph, (key, value) => {\n          if (typeof value === 'symbol') {\n            return value.toString()\n          }\n          return value\n        }),\n    },\n    '*'\n  )\n}\n\nsend({\n  type: 'init',\n})\n\ninterface IIdleDeadline {\n  didTimeout: boolean\n  timeRemaining: () => DOMHighResTimeStamp\n}\n\nconst HOOK = {\n  hasFormilyInstance: false,\n  hasOpenDevtools: false,\n  store: {},\n  openDevtools() {\n    this.hasOpenDevtools = true\n  },\n  closeDevtools() {\n    this.hasOpenDevtools = false\n  },\n  setVm(fieldId: string, formId: string) {\n    if (fieldId) {\n      globalThis.$vm = this.store[formId].fields[fieldId]\n    } else {\n      globalThis.$vm = this.store[formId]\n    }\n  },\n  inject(id: number, form: any) {\n    this.hasFormilyInstance = true\n    this.store[id] = form\n    send({\n      type: 'install',\n      id,\n      form,\n    })\n    let timer = null\n    const task = () => {\n      globalThis.requestIdleCallback((deadline: IIdleDeadline) => {\n        if (this.store[id]) {\n          if (deadline.timeRemaining() < 16) {\n            task()\n          } else {\n            send({\n              type: 'update',\n              id,\n              form,\n            })\n          }\n        }\n      })\n    }\n    form.subscribe(() => {\n      if (!this.hasOpenDevtools) return\n      clearTimeout(timer)\n      timer = setTimeout(task, 300)\n    })\n  },\n  update() {\n    const keys = Object.keys(this.store || {})\n    keys.forEach((id) => {\n      send({\n        type: 'update',\n        id,\n        form: this.store[id],\n      })\n    })\n  },\n  unmount(id: number) {\n    delete this.store[id]\n    send({\n      type: 'uninstall',\n      id,\n    })\n  },\n}\n\nglobalThis.__FORMILY_DEV_TOOLS_HOOK__ = HOOK\nglobalThis.__UFORM_DEV_TOOLS_HOOK__ = HOOK\n"
  },
  {
    "path": "devtools/chrome-extension/src/extension/background.ts",
    "content": "// background.ts - Manifest V3版本\nconst connections = {}\n\n// 处理扩展程序的连接请求\nchrome.runtime.onConnect.addListener(function (port) {\n  if (port.name === '@formily-devtools-panel-script') {\n    const extensionListener = function (message) {\n      // 原始的连接事件不包含开发者工具网页的标签页标识符，\n      // 所以我们需要显式发送它。\n      if (message.name == 'init') {\n        connections[message.tabId] = port\n        return\n      }\n      // 其他消息的处理\n    }\n\n    // 监听开发者工具网页发来的消息\n    port.onMessage.addListener(extensionListener)\n\n    port.onDisconnect.addListener(function (disconnectedPort) {\n      port.onMessage.removeListener(extensionListener)\n      const tabs = Object.keys(connections)\n      for (let i = 0, len = tabs.length; i < len; i++) {\n        if (connections[tabs[i]] == port) {\n          delete connections[tabs[i]]\n          break\n        }\n      }\n    })\n  }\n})\n\n// 从内容脚本接收消息，并转发至当前标签页对应的开发者工具网页\nchrome.runtime.onMessage.addListener(function (request, sender) {\n  // 来自内容脚本的消息应该已经设置 sender.tab\n  if (sender.tab) {\n    const tabId = sender.tab.id\n    if (tabId && tabId in connections) {\n      connections[tabId].postMessage(request)\n    }\n  }\n  return true\n})\n"
  },
  {
    "path": "devtools/chrome-extension/src/extension/content.ts",
    "content": "window.addEventListener(\n  'message',\n  (event) => {\n    const { source, ...payload } = event.data\n    if (source === '@formily-devtools-inject-script') {\n      chrome.runtime.sendMessage({\n        source,\n        ...payload,\n      })\n    }\n  },\n  false\n)\n"
  },
  {
    "path": "devtools/chrome-extension/src/extension/devpanel.tsx",
    "content": "import React, { useEffect, useState } from 'react'\nimport ReactDOM from 'react-dom'\nimport App from '../app'\n\nconst backgroundPageConnection = chrome.runtime.connect({\n  name: '@formily-devtools-panel-script',\n})\n\nbackgroundPageConnection.postMessage({\n  name: 'init',\n  tabId: chrome.devtools.inspectedWindow.tabId,\n})\n\nchrome.devtools.inspectedWindow.eval(\n  'window.__FORMILY_DEV_TOOLS_HOOK__.openDevtools()'\n)\n\nconst Devtools = () => {\n  const [state, setState] = useState([])\n  useEffect(() => {\n    let store = {}\n    const update = () => {\n      setState(\n        Object.keys(store).map((key) => {\n          return store[key]\n        })\n      )\n    }\n    chrome.devtools.inspectedWindow.eval(\n      'window.__FORMILY_DEV_TOOLS_HOOK__.update()'\n    )\n    backgroundPageConnection.onMessage.addListener(({ type, id, graph }) => {\n      if (type === 'init') {\n        store = {}\n        chrome.devtools.inspectedWindow.eval(\n          'window.__FORMILY_DEV_TOOLS_HOOK__.openDevtools()'\n        )\n      } else if (type !== 'uninstall') {\n        store[id] = JSON.parse(graph)\n      } else {\n        delete store[id]\n      }\n      update()\n    })\n  }, [])\n  return <App dataSource={state} />\n}\n\nReactDOM.render(<Devtools />, document.getElementById('root'))\n"
  },
  {
    "path": "devtools/chrome-extension/src/extension/devtools.tsx",
    "content": "declare let chrome: any\n\nlet created = false\n\nconst createPanel = () => {\n  if (created) {\n    return\n  }\n\n  chrome.devtools.inspectedWindow.eval(\n    'window.__FORMILY_DEV_TOOLS_HOOK__ && window.__FORMILY_DEV_TOOLS_HOOK__.hasFormilyInstance',\n    (hasFormily: boolean) => {\n      if (!hasFormily) return\n      created = true\n      clearInterval(loadCheckInterval)\n      chrome.devtools.panels.create(\n        'Formily',\n        'img/logo/scalable.png',\n        './devpanel.html',\n        function () {}\n      )\n    }\n  )\n}\n\nconst loadCheckInterval = setInterval(function () {\n  createPanel()\n}, 1000)\n\ncreatePanel()\n"
  },
  {
    "path": "devtools/chrome-extension/src/extension/inject.ts",
    "content": "import backend from 'raw-loader!./backend'\nfunction nullthrows(x: any, message?: string) {\n  if (x != null) {\n    return x\n  }\n  const error: any = new Error(\n    message !== undefined ? message : 'Got unexpected ' + x\n  )\n  error.framesToPop = 1 // Skip nullthrows's own stack frame.\n  throw error\n}\n\nfunction injectCode(code) {\n  const script = document.createElement('script')\n  script.textContent = code\n\n  // This script runs before the <head> element is created,\n  // so we add the script to <html> instead.\n  nullthrows(document.documentElement).appendChild(script)\n  nullthrows(script.parentNode).removeChild(script)\n}\n\ninjectCode(`;(function(){\n  var exports = {};\n  ${backend}\n})()`)\n"
  },
  {
    "path": "devtools/chrome-extension/src/extension/manifest.json",
    "content": "{\n  \"version\": \"0.1.14\",\n  \"name\": \"Formily DevTools\",\n  \"short_name\": \"Formily DevTools\",\n  \"description\": \"Formily DevTools for debugging application's state changes.\",\n  \"homepage_url\": \"https://github.com/alibaba/formily\",\n  \"manifest_version\": 3,\n  \"action\": {\n    \"default_icon\": \"img/logo/scalable.png\",\n    \"default_title\": \"Formily DevTools\",\n    \"default_popup\": \"popup.html\"\n  },\n  \"commands\": {\n    \"devtools-left\": {\n      \"description\": \"DevTools window to left\"\n    },\n    \"devtools-right\": {\n      \"description\": \"DevTools window to right\"\n    },\n    \"devtools-bottom\": {\n      \"description\": \"DevTools window to bottom\"\n    },\n    \"devtools-remote\": {\n      \"description\": \"Remote DevTools\"\n    },\n    \"_execute_action\": {\n      \"suggested_key\": {\n        \"default\": \"Ctrl+Shift+E\"\n      }\n    }\n  },\n  \"icons\": {\n    \"16\": \"img/logo/16x16.png\",\n    \"48\": \"img/logo/48x48.png\",\n    \"128\": \"img/logo/128x128.png\"\n  },\n  \"background\": {\n    \"service_worker\": \"js/background.bundle.js\",\n    \"type\": \"module\"\n  },\n  \"content_scripts\": [\n    {\n      \"matches\": [\"<all_urls>\"],\n      \"exclude_matches\": [\"*://www.google.com/*\"],\n      \"js\": [\"js/content.bundle.js\", \"js/inject.bundle.js\"],\n      \"run_at\": \"document_start\",\n      \"all_frames\": true\n    }\n  ],\n  \"devtools_page\": \"devtools.html\",\n  \"web_accessible_resources\": [\n    {\n      \"resources\": [\"js/backend.bundle.js\"],\n      \"matches\": [\"<all_urls>\"]\n    }\n  ],\n  \"externally_connectable\": {\n    \"ids\": [\"*\"]\n  },\n  \"host_permissions\": [\"file://*/*\", \"http://*/*\", \"https://*/*\"],\n  \"content_security_policy\": {\n    \"extension_pages\": \"script-src 'self'; object-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;\"\n  },\n  \"update_url\": \"https://clients2.google.com/service/update2/crx\"\n}\n"
  },
  {
    "path": "devtools/chrome-extension/src/extension/popup.tsx",
    "content": "import React from 'react'\nimport ReactDOM from 'react-dom'\n\nReactDOM.render(<div>hello world</div>, document.getElementById('root'))\n"
  },
  {
    "path": "devtools/chrome-extension/src/extension/views/devpanel.ejs",
    "content": "<!DOCTYPE html>\n\n<head>\n  <title>\n    Formily Devtools\n  </title>\n  <style type=\"text/css\">\n    ::-webkit-scrollbar {\n      width: 5px;\n      height: 5px;\n    }\n\n    ::-webkit-scrollbar-thumb {\n      background: #101114;\n      border-radius: 10px;\n    }\n\n    ::-webkit-scrollbar-thumb:hover {\n      background: #494e5f;\n    }\n\n    ::-webkit-scrollbar-track {\n      background: transparent;\n      border-radius: 10px;\n    }\n  </style>\n</head>\n\n<body>\n  <div id=\"root\">\n  </div>\n</body>"
  },
  {
    "path": "devtools/chrome-extension/src/extension/views/devtools.ejs",
    "content": "<!DOCTYPE html>\n<head>\n  <title>\n    Formily Devtools\n  </title>\n</head>\n<body>\n  <div id=\"root\">\n  </div>\n</body>"
  },
  {
    "path": "devtools/chrome-extension/src/extension/views/popup.ejs",
    "content": "<!DOCTYPE html>\n<head>\n  <title>\n    Formily Devtools\n  </title>\n</head>\n<body>\n  <div id=\"root\">\n  </div>\n</body>"
  },
  {
    "path": "devtools/chrome-extension/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*\", \"devtools/*\"]\n    },\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "devtools/chrome-extension/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"include\": [\"./src/**/*.ts\", \"./src/**/*.tsx\"],\n  \"exclude\": [\"./src/__tests__/*\", \"./esm/*\", \"./lib/*\"]\n}\n"
  },
  {
    "path": "docs/functions/contributors.ts",
    "content": "import { Handler } from '@netlify/functions'\nimport { Octokit } from '@octokit/rest'\n\nconst octokit = new Octokit({\n  baseUrl: 'https://api.github.com',\n  auth: process.env.GITHUB_TOKEN,\n})\n\nconst headers = {\n  'Access-Control-Allow-Origin': '*',\n  'Access-Control-Allow-Headers': 'Content-Type',\n  'Access-Control-Allow-Methods': 'GET',\n}\n\nexport const handler: Handler = async (event) => {\n  if (event.httpMethod !== 'GET') {\n    return { statusCode: 405, body: 'Method Not Allowed' }\n  }\n  return {\n    statusCode: 200,\n    headers,\n    body: JSON.stringify(\n      await octokit.repos.listContributors({\n        owner: 'alibaba',\n        repo: 'formily',\n        per_page: 1000,\n        page: 1,\n      })\n    ),\n  }\n}\n"
  },
  {
    "path": "docs/functions/npm-search.ts",
    "content": "import { Handler } from '@netlify/functions'\nimport qs from 'querystring'\nimport axios from 'axios'\n\nconst headers = {\n  'Access-Control-Allow-Origin': '*',\n  'Access-Control-Allow-Headers': 'Content-Type',\n  'Access-Control-Allow-Methods': 'GET',\n}\n\nexport const handler: Handler = async (event) => {\n  if (event.httpMethod !== 'GET') {\n    return { statusCode: 405, body: 'Method Not Allowed' }\n  }\n  const params = qs.parse(event.rawQuery)\n  const results = await axios.get(\n    `https://www.npmjs.com/search/suggestions?q=${params.q}&size=100`\n  )\n  return {\n    statusCode: 200,\n    headers,\n    body: JSON.stringify(results.data),\n  }\n}\n"
  },
  {
    "path": "docs/guide/advanced/async.md",
    "content": "# Asynchronous Data Sources\n\nAsynchronous data source management, the core is reflected in the dataSource property of the [Field](https://core.formilyjs.org/api/models/field) model. We can modify the dataSource of the Field in effects, or modify the dataSource property in reactions.\n\nIf the field component (such as Select) has a consumer dataSource property, when the dataSource changes, the corresponding component will automatically re-render.\n\n<Alert>\nNote: If it is a business custom component, please manually map the dataSource to the custom component, you can use  <a href=\"https://react.formilyjs.org/api/shared/connect\">connect</a> or <a href=\"https://react.formilyjs.org/api/shared/observer\">observer</a> + <a href=\"https://react.formilyjs.org/api/hooks/use-field\">useField</a>\n</Alert>\n\nSpecific cases can refer to:\n\n- [Select](https://antd.formilyjs.org/components/select)\n- [TreeSelect](https://antd.formilyjs.org/components/tree-select)\n- [Cascader](https://antd.formilyjs.org/components/cascader)\n"
  },
  {
    "path": "docs/guide/advanced/async.zh-CN.md",
    "content": "# 实现异步数据源\n\n异步数据源管理，核心体现在[Field](https://core.formilyjs.org/zh-CN/api/models/field)模型中的 dataSource 属性，我们可以在 effects 中修改 Field 的 dataSource，也可以在 reactions 中修改 dataSource 属性。\n\n如果字段组件内部(比如 Select)有消费 dataSource 属性，当 dataSource 发生变化时，对应组件会自动重渲染。\n\n<Alert>\n注意：如果是业务自定义组件，请手动映射dataSource到自定义组件中，可以使用 <a href=\"https://react.formilyjs.org/zh-CN/api/shared/connect\">connect</a>，也可以使用 <a href=\"https://react.formilyjs.org/zh-CN/api/shared/observer\">observer</a> + <a href=\"https://react.formilyjs.org/zh-CN/api/hooks/use-field\">useField</a>\n</Alert>\n\n具体案例可以参考：\n\n- [Select](https://antd.formilyjs.org/zh-CN/components/select)\n- [TreeSelect](https://antd.formilyjs.org/zh-CN/components/tree-select)\n- [Cascader](https://antd.formilyjs.org/zh-CN/components/cascader)\n"
  },
  {
    "path": "docs/guide/advanced/build.md",
    "content": "# Pack on Demand\n\n## Based on Umi Development\n\n#### Install `babel-plugin-import`\n\n```shell\nnpm install babel-plugin-import --save-dev\n```\n\nor\n\n```shell\nyarn add babel-plugin-import --dev\n```\n\n#### Plugin Configuration\n\nModify `.umirc.js` or `.umirc.ts`\n\n```js\nexport default {\n  extraBabelPlugins: [\n    [\n      'babel-plugin-import',\n      { libraryName: 'antd', libraryDirectory: 'es', style: true },\n      'antd',\n    ],\n    [\n      'babel-plugin-import',\n      { libraryName: '@formily/antd', libraryDirectory: 'esm', style: true },\n      '@formily/antd',\n    ],\n  ],\n}\n```\n\n## Based on Create-react-app Development\n\nFirst, we need to customize the default configuration of `create-react-app`, here we use [react-app-rewired](https://github.com/timarney/react-app-rewired) （A community solution for custom configuration of `create-react-app`)\nIntroduce `react-app-rewired` and modify the startup configuration in `package.json`. Due to the new [react-app-rewired@2.x](https://github.com/timarney/react-app-rewired#alternatives) version, you also need to install [customize-cra](https://github.com/arackaf/customize-cra).\n\n```shell\n$ npm install react-app-rewired customize-cra  --save-dev\n```\n\nor\n\n```shell\n$ yarn add react-app-rewired customize-cra --dev\n```\n\nmodify `package.json`\n\n```diff\n\"scripts\": {\n-   \"start\": \"react-scripts start\",\n+   \"start\": \"react-app-rewired start\",\n-   \"build\": \"react-scripts build\",\n+   \"build\": \"react-app-rewired build\",\n-   \"test\": \"react-scripts test\",\n+   \"test\": \"react-app-rewired test\",\n}\n```\n\nThen create a `config-overrides.js` in the project root directory to modify the default configuration.\n\n```js\nmodule.exports = function override(config, env) {\n  // do stuff with the webpack config...\n  return config\n}\n```\n\n#### Install babel-plugin-import\n\n```shell\nnpm install babel-plugin-import --save-dev\n```\n\nor\n\n```shell\nyarn add babel-plugin-import --dev\n```\n\nmodify `config-overrides.js`\n\n```diff\n+ const { override, fixBabelImports } = require('customize-cra');\n\n- module.exports = function override(config, env) {\n-   // do stuff with the webpack config...\n-   return config;\n- };\n+ module.exports = override(\n+   fixBabelImports('antd', {\n+     libraryName: 'antd',\n+     libraryDirectory: 'es',\n+     style: true\n+   }),\n+   fixBabelImports('@formily/antd', {\n+     libraryName: '@formily/antd',\n+     libraryDirectory: 'esm',\n+     style: true\n+   }),\n+ );\n```\n\n## Use in Webpack\n\n#### Install babel-plugin-import\n\n```shell\nnpm install babel-plugin-import --save-dev\n```\n\nor\n\n```shell\nyarn add babel-plugin-import --dev\n```\n\nModify `.babelrc` or babel-loader\n\n```json\n{\n  \"plugins\": [\n    [\n      \"import\",\n      {\n        \"libraryName\": \"antd\",\n        \"libraryDirectory\": \"es\",\n        \"style\": true\n      },\n      \"antd\"\n    ],\n    [\n      \"import\",\n      {\n        \"libraryName\": \"@formily/antd\",\n        \"libraryDirectory\": \"esm\",\n        \"style\": true\n      },\n      \"@formily/antd\"\n    ]\n  ]\n}\n```\n\nFor more configuration, please refer to [babel-plugin-import](https://github.com/ant-design/babel-plugin-import)\n"
  },
  {
    "path": "docs/guide/advanced/build.zh-CN.md",
    "content": "# 按需打包\n\n## 基于 Umi 开发\n\n#### 安装 `babel-plugin-import`\n\n```shell\nnpm install babel-plugin-import --save-dev\n```\n\n或者\n\n```shell\nyarn add babel-plugin-import --dev\n```\n\n#### 插件配置\n\n修改 `.umirc.js`或 `.umirc.ts`\n\n```js\nexport default {\n  extraBabelPlugins: [\n    [\n      'babel-plugin-import',\n      { libraryName: 'antd', libraryDirectory: 'es', style: true },\n      'antd',\n    ],\n    [\n      'babel-plugin-import',\n      { libraryName: '@formily/antd', libraryDirectory: 'esm', style: true },\n      '@formily/antd',\n    ],\n  ],\n}\n```\n\n## 基于 create-react-app 开发\n\n首先我们需要对`create-react-app`的默认配置进行自定义，这里我们使用 [react-app-rewired](https://github.com/timarney/react-app-rewired) （一个对 `create-react-app` 进行自定义配置的社区解决方案）。\n引入 `react-app-rewired` 并修改 `package.json` 里的启动配置。由于新的 [react-app-rewired@2.x](https://github.com/timarney/react-app-rewired#alternatives) 版本的关系，你还需要安装 [customize-cra](https://github.com/arackaf/customize-cra)。\n\n```shell\n$ npm install react-app-rewired customize-cra  --save-dev\n```\n\n或者\n\n```shell\n$ yarn add react-app-rewired customize-cra --dev\n```\n\n修改 `package.json`\n\n```diff\n\"scripts\": {\n-   \"start\": \"react-scripts start\",\n+   \"start\": \"react-app-rewired start\",\n-   \"build\": \"react-scripts build\",\n+   \"build\": \"react-app-rewired build\",\n-   \"test\": \"react-scripts test\",\n+   \"test\": \"react-app-rewired test\",\n}\n```\n\n然后在项目根目录创建一个 `config-overrides.js` 用于修改默认配置。\n\n```js\nmodule.exports = function override(config, env) {\n  // do stuff with the webpack config...\n  return config\n}\n```\n\n#### 安装 babel-plugin-import\n\n```shell\nnpm install babel-plugin-import --save-dev\n```\n\n或者\n\n```shell\nyarn add babel-plugin-import --dev\n```\n\n修改`config-overrides.js`\n\n```diff\n+ const { override, fixBabelImports } = require('customize-cra');\n\n- module.exports = function override(config, env) {\n-   // do stuff with the webpack config...\n-   return config;\n- };\n+ module.exports = override(\n+   fixBabelImports('antd', {\n+     libraryName: 'antd',\n+     libraryDirectory: 'es',\n+     style: true\n+   }),\n+   fixBabelImports('@formily/antd', {\n+     libraryName: '@formily/antd',\n+     libraryDirectory: 'esm',\n+     style: true\n+   }),\n+ );\n```\n\n## 在 Webpack 中使用\n\n#### 安装 babel-plugin-import\n\n```shell\nnpm install babel-plugin-import --save-dev\n```\n\n或者\n\n```shell\nyarn add babel-plugin-import --dev\n```\n\n修改 `.babelrc` 或者 babel-loader\n\n```json\n{\n  \"plugins\": [\n    [\n      \"import\",\n      {\n        \"libraryName\": \"antd\",\n        \"libraryDirectory\": \"es\",\n        \"style\": true\n      },\n      \"antd\"\n    ],\n    [\n      \"import\",\n      {\n        \"libraryName\": \"@formily/antd\",\n        \"libraryDirectory\": \"esm\",\n        \"style\": true\n      },\n      \"@formily/antd\"\n    ]\n  ]\n}\n```\n\n更多配置请参考 [babel-plugin-import](https://github.com/ant-design/babel-plugin-import)\n"
  },
  {
    "path": "docs/guide/advanced/business-logic.md",
    "content": "# Manage Business Logic\n\nIn the previous document, we can actually find that Formily has provided the ability to describe the logic locally, that is, the x-reactions/reactions property of the field component. And in Schema, x-reactions can pass both functions and a structured object. Of course, there are also effects inherited from Formily 1.x, So to summarize, the ways to describe logic in Formily 2.x are:\n\n- Effects or reactions property in pure JSX mode\n- Effects or structured x-reactions property in Schema mode\n- Effects or functional x-reactions property in Schema mode\n\nWith so many ways of describing logic, how should we choose? What scenarios are best practices? First, we need to understand the positioning of effects and reactions.\n\nFirst of all, reactions are responders used on specific field properties. They will be executed repeatedly based on the data changes that the function depends on. Its biggest advantage is that it is simple, straightforward and easy to understand, such as:\n\n```tsx pure\n/* eslint-disable */\n<Field\n  name=\"A\"\n  reactions={(field) => {\n    /**specific logic implementation**/\n  }}\n/>\n```\n\nThen, effects are used to implement the side-effect isolation logic management model. Its biggest advantage is that it can make the view code easier to maintain in a scenario with a large number of fields. At the same time, it also has the ability to process fields in batches. For example, we declare x-reactions in the field properties of A, B, C. If the x-reactions logic of these three fields are exactly the same, then we only need to write this in effects:\n\n```ts\nonFieldReact('*(A,B,C)', (field) => {\n  //...logic\n})\n```\n\nAnother advantage of using effects is that a series of reusable logic plug-ins can be implemented, which can be very convenient logic pluggable, and at the same time can do some things like global monitoring.\n\nIn this way, do we not need to define the logic locally?\n\nNo, the premise of the above writing is that for a large number of fields, if the view layer is full of reactions, it looks uncomfortable, so it is a better strategy to consider extracting logic from unified maintenance.\nOn the contrary, if the number of fields is small and the logic is relatively simple, it is also good to write reactions directly on the field attributes, which is clear.\n\nAt the same time, because JSON Schema can be consumed by the configuration system, we need to logically configure a specific field on the configuration interface. So we still need to support local definition logic capabilities, and also need to support structured description logic, such as:\n\n```json\n{\n  \"x-reactions\": {\n    \"dependencies\": [\"aa\"],\n    \"fulfill\": {\n      \"state\": {\n        \"visible\": \"{{$deps[0] == '123'}}\"\n      }\n    }\n  }\n}\n```\n\nThis can well solve the linkage requirements of most configuration scenarios. However, there is another scenario, that is, our linkage process is asynchronous, the logic is very complicated, or there is a large amount of data processing, then we can only consider open up the ability to describe functional states, such as:\n\n```json\n{\n  \"x-reactions\": \"{{(field)=>{/**specific logic implementation**/}}}\"\n}\n```\n\nThis is very similar to a low-code configuration. Of course, we can also register a series of general logic functions in the context scope:\n\n```json\n{\n  \"x-reactions\": \"{{customFunction}}\"\n}\n```\n\nIn conclusion, the way we manage business logic has the following priorities:\n\n- Pure source mode\n  - The number of fields is huge and the logic is complex, and the logic defined in effects is preferred.\n  - The number of fields is small, the logic is simple, and the logic defined in reactions is preferred\n- Schema mode\n  - There is no asynchronous logic, structured reactions are preferred to define logic.\n  - There is asynchronous logic, or a large number of calculations, the functional state reactions are preferred to define logic.\n\nFor how to play with effects in effects, we mainly look at the [@formily/core](https://core.formilyjs.org) document.\n"
  },
  {
    "path": "docs/guide/advanced/business-logic.zh-CN.md",
    "content": "# 管理业务逻辑\n\n在前面的文档中，我们其实可以发现 Formily 已经提供了局部描述逻辑的能力，也就是字段组件的 x-reactions/reactions 属性，而且在 Schema 中，x-reactions 既能传函数，也能传一个结构化对象，当然，还有 Formily1.x 继承下来的 effects，那么总结一下，在 Formily2.x 中描述逻辑的方式有：\n\n- 纯 JSX 模式下的 effects 或 reactions 属性\n- Schema 模式下的 effects 或结构化 x-reactions 属性\n- Schema 模式下的 effects 或函数态 x-reactions 属性\n\n这么多描述逻辑的方式，我们该如何选择？什么场景下是最佳实践呢？首先，我们要理解清楚 effects 和 reactions 的定位。\n\n首先，reactions 是用在具体字段属性上的响应器，它会基于函数内依赖的数据变化而重复执行，它最大的优点就是简单直接，容易理解，比如：\n\n```tsx pure\n/* eslint-disable */\n<Field\n  name=\"A\"\n  reactions={(field) => {\n    /**具体逻辑实现**/\n  }}\n/>\n```\n\n然后，effects 是用于实现副作用隔离逻辑管理模型，它最大的优点就是在字段数量超多的场景下，可以让视图代码变得更易维护，同时它还有一个能力，就是可以批量化的对字段做处理。比如我们在 A,B,C 字段属性显示声明 x-reactions，如果这 3 个字段的 x-reactions 逻辑都是一模一样的，那我们在 effects 中只需这么写即可：\n\n```ts\nonFieldReact('*(A,B,C)', (field) => {\n  //...逻辑\n})\n```\n\n使用 effects 还有一个好处就是可以实现一系列的可复用逻辑插件，可以做到很方便的逻辑可拔插，同时还能做一些全局监控之类的事情。\n\n这样看来，是不是我们就不需要局部定义逻辑了？\n\n并不是，上面的写法的前提是对于字段数量很多，如果视图层满屏的 reactions，看着是很难受的，所以考虑将逻辑抽离统一维护则是一个比较好的策略。相反，如果字段数量很少，逻辑相对简单的，直接在字段属性上写 reactions 也是不错的，清晰明了。\n\n同时，因为 JSON Schema 是可以给配置化系统消费的，我们需要在配置界面上对具体某个字段做逻辑配置。所以我们还是需要支持局部定义逻辑能力，同时还需要支持结构化描述逻辑，比如：\n\n```json\n{\n  \"x-reactions\": {\n    \"dependencies\": [\"aa\"],\n    \"fulfill\": {\n      \"state\": {\n        \"visible\": \"{{$deps[0] == '123'}}\"\n      }\n    }\n  }\n}\n```\n\n这样可以很好的解决大部分配置场景的联动需求了，但是，还有一种场景，就是我们的联动过程是存在异步的，逻辑非常复杂的，或者存在大量数据处理的，那我们就只能考虑开放函数态描述的能力了，比如：\n\n```json\n{\n  \"x-reactions\": \"{{(field)=>{/**具体逻辑实现**/}}}\"\n}\n```\n\n这种就很像是低代码配置了，当然，我们也可以在上下文作用域中注册一系列的通用逻辑函数：\n\n```json\n{\n  \"x-reactions\": \"{{customFunction}}\"\n}\n```\n\n最终总结下来，我们管理业务逻辑的方式，有以下优先级：\n\n- 纯源码模式\n  - 字段数量庞大，逻辑复杂，优先选择 effects 中定义逻辑\n  - 字段数量少，逻辑简单，优先选择 reactions 中定义逻辑\n- Schema 模式\n  - 不存在异步逻辑，优先选择结构化 reactions 定义逻辑\n  - 存在异步逻辑，或者大量计算，优先选择函数态 reactions 定义逻辑\n\n对于 effects 中如何玩出花来，我们主要看[@formily/core](https://core.formilyjs.org/zh-CN)文档即可\n"
  },
  {
    "path": "docs/guide/advanced/calculator.md",
    "content": "# Calculator\n\nLinkage calculator is mainly used for evaluation and summarization in the process of filling in the form. In Formily 1.x, the cost of realizing this kind of demand is very high. In 2.x, we can easily implement it with the help of reactions.\n\n## Markup Schema Case\n\n```tsx\nimport React from 'react'\nimport {\n  Form,\n  FormItem,\n  NumberPicker,\n  ArrayTable,\n  Editable,\n  Input,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Editable,\n    Input,\n    NumberPicker,\n    ArrayTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <Form form={form} layout=\"vertical\">\n      <SchemaField>\n        <SchemaField.Array\n          name=\"projects\"\n          title=\"Projects\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayTable\"\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ width: 50, title: 'Sort', align: 'center' }}\n            >\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayTable.SortHandle\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ width: 80, title: 'Index', align: 'center' }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayTable.Index\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'Price' }}\n            >\n              <SchemaField.Number\n                name=\"price\"\n                x-decorator=\"Editable\"\n                required\n                x-component=\"NumberPicker\"\n                x-component-props={{\n                  addonAfter: '$',\n                }}\n                default={0}\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'Count' }}\n            >\n              <SchemaField.Number\n                name=\"count\"\n                x-decorator=\"Editable\"\n                required\n                x-component=\"NumberPicker\"\n                default={0}\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'Total' }}\n            >\n              <SchemaField.Number\n                x-decorator=\"FormItem\"\n                name=\"total\"\n                x-component=\"NumberPicker\"\n                x-pattern=\"readPretty\"\n                x-component-props={{\n                  addonAfter: '$',\n                }}\n                x-reactions={{\n                  dependencies: ['.price', '.count'],\n                  when: '{{$deps[0] && $deps[1]}}',\n                  fulfill: {\n                    state: {\n                      value: '{{$deps[0] * $deps[1]}}',\n                    },\n                  },\n                }}\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{\n                title: 'Operations',\n                dataIndex: 'operations',\n                width: 200,\n                fixed: 'right',\n              }}\n            >\n              <SchemaField.Void x-component=\"FormItem\">\n                <SchemaField.Void x-component=\"ArrayTable.Remove\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveDown\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveUp\" />\n              </SchemaField.Void>\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void x-component=\"ArrayTable.Addition\" title=\"Add\" />\n        </SchemaField.Array>\n        <SchemaField.Number\n          name=\"total\"\n          title=\"Total\"\n          x-decorator=\"FormItem\"\n          x-component=\"NumberPicker\"\n          x-component-props={{\n            addonAfter: '$',\n          }}\n          x-pattern=\"readPretty\"\n          x-reactions={{\n            dependencies: ['.projects'],\n            when: '{{$deps[0].length > 0}}',\n            fulfill: {\n              state: {\n                value:\n                  '{{$deps[0].reduce((total,item)=>item.total ? total+item.total : total,0)}}',\n              },\n            },\n          }}\n        />\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </Form>\n  )\n}\n```\n\n## JSON Schema Case\n\n```tsx\nimport React from 'react'\nimport {\n  Form,\n  FormItem,\n  NumberPicker,\n  ArrayTable,\n  Editable,\n  Input,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Editable,\n    Input,\n    NumberPicker,\n    ArrayTable,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    projects: {\n      type: 'array',\n      title: 'Projects',\n      'x-decorator': 'FormItem',\n      'x-component': 'ArrayTable',\n      items: {\n        type: 'object',\n        properties: {\n          column_1: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              width: 50,\n              title: 'Sort',\n              align: 'center',\n            },\n            properties: {\n              sortable: {\n                type: 'void',\n                'x-component': 'ArrayTable.SortHandle',\n              },\n            },\n          },\n          column_2: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              width: 50,\n              title: 'Index',\n              align: 'center',\n            },\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayTable.Index',\n              },\n            },\n          },\n          column_3: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              title: 'Price',\n            },\n            properties: {\n              price: {\n                type: 'number',\n                default: 0,\n                'x-decorator': 'Editable',\n                'x-component': 'NumberPicker',\n                'x-component-props': {\n                  addonAfter: '$',\n                },\n              },\n            },\n          },\n          column_4: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              title: 'Count',\n            },\n            properties: {\n              count: {\n                type: 'number',\n                default: 0,\n                'x-decorator': 'Editable',\n                'x-component': 'NumberPicker',\n                'x-component-props': {\n                  addonAfter: '$',\n                },\n              },\n            },\n          },\n          column_5: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              title: 'Total',\n            },\n            properties: {\n              total: {\n                type: 'number',\n                'x-read-pretty': true,\n                'x-decorator': 'FormItem',\n                'x-component': 'NumberPicker',\n                'x-component-props': {\n                  addonAfter: '$',\n                },\n                'x-reactions': {\n                  dependencies: ['.price', '.count'],\n                  when: '{{$deps[0] && $deps[1]}}',\n                  fulfill: {\n                    state: {\n                      value: '{{$deps[0] * $deps[1]}}',\n                    },\n                  },\n                },\n              },\n            },\n          },\n          column_6: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              title: 'Operations',\n            },\n            properties: {\n              item: {\n                type: 'void',\n                'x-component': 'FormItem',\n                properties: {\n                  remove: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.Remove',\n                  },\n                  moveDown: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveDown',\n                  },\n                  moveUp: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveUp',\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          title: 'Add',\n          'x-component': 'ArrayTable.Addition',\n        },\n      },\n    },\n    total: {\n      type: 'number',\n      title: 'Total',\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n      'x-component-props': {\n        addonAfter: '$',\n      },\n      'x-pattern': 'readPretty',\n      'x-reactions': {\n        dependencies: ['.projects'],\n        when: '{{$deps[0].length > 0}}',\n        fulfill: {\n          state: {\n            value:\n              '{{$deps[0].reduce((total,item)=>item.total ? total+item.total : total,0)}}',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <Form form={form} layout=\"vertical\">\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>submit</Submit>\n      </FormButtonGroup>\n    </Form>\n  )\n}\n```\n"
  },
  {
    "path": "docs/guide/advanced/calculator.zh-CN.md",
    "content": "# 实现联动计算器\n\n联动计算器，主要用于在填写表单的过程中做求值汇总，在 Formily1.x 中实现这类需求的成本非常非常高，在 2.x 中，我们可以借助 reactions 轻松实现\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Form,\n  FormItem,\n  NumberPicker,\n  ArrayTable,\n  Editable,\n  Input,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Editable,\n    Input,\n    NumberPicker,\n    ArrayTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <Form form={form} layout=\"vertical\">\n      <SchemaField>\n        <SchemaField.Array\n          name=\"projects\"\n          title=\"Projects\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayTable\"\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ width: 50, title: 'Sort', align: 'center' }}\n            >\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayTable.SortHandle\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ width: 80, title: 'Index', align: 'center' }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayTable.Index\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'Price' }}\n            >\n              <SchemaField.Number\n                name=\"price\"\n                x-decorator=\"Editable\"\n                required\n                x-component=\"NumberPicker\"\n                x-component-props={{\n                  addonAfter: '$',\n                }}\n                default={0}\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'Count' }}\n            >\n              <SchemaField.Number\n                name=\"count\"\n                x-decorator=\"Editable\"\n                required\n                x-component=\"NumberPicker\"\n                default={0}\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'Total' }}\n            >\n              <SchemaField.Number\n                x-decorator=\"FormItem\"\n                name=\"total\"\n                x-component=\"NumberPicker\"\n                x-pattern=\"readPretty\"\n                x-component-props={{\n                  addonAfter: '$',\n                }}\n                x-reactions={{\n                  dependencies: ['.price', '.count'],\n                  when: '{{$deps[0] && $deps[1]}}',\n                  fulfill: {\n                    state: {\n                      value: '{{$deps[0] * $deps[1]}}',\n                    },\n                  },\n                }}\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{\n                title: 'Operations',\n                dataIndex: 'operations',\n                width: 200,\n                fixed: 'right',\n              }}\n            >\n              <SchemaField.Void x-component=\"FormItem\">\n                <SchemaField.Void x-component=\"ArrayTable.Remove\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveDown\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveUp\" />\n              </SchemaField.Void>\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void x-component=\"ArrayTable.Addition\" title=\"Add\" />\n        </SchemaField.Array>\n        <SchemaField.Number\n          name=\"total\"\n          title=\"Total\"\n          x-decorator=\"FormItem\"\n          x-component=\"NumberPicker\"\n          x-component-props={{\n            addonAfter: '$',\n          }}\n          x-pattern=\"readPretty\"\n          x-reactions={{\n            dependencies: ['.projects'],\n            when: '{{$deps[0].length > 0}}',\n            fulfill: {\n              state: {\n                value:\n                  '{{$deps[0].reduce((total,item)=>item.total ? total+item.total : total,0)}}',\n              },\n            },\n          }}\n        />\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </Form>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Form,\n  FormItem,\n  NumberPicker,\n  ArrayTable,\n  Editable,\n  Input,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Editable,\n    Input,\n    NumberPicker,\n    ArrayTable,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    projects: {\n      type: 'array',\n      title: 'Projects',\n      'x-decorator': 'FormItem',\n      'x-component': 'ArrayTable',\n      items: {\n        type: 'object',\n        properties: {\n          column_1: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              width: 50,\n              title: 'Sort',\n              align: 'center',\n            },\n            properties: {\n              sortable: {\n                type: 'void',\n                'x-component': 'ArrayTable.SortHandle',\n              },\n            },\n          },\n          column_2: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              width: 50,\n              title: 'Index',\n              align: 'center',\n            },\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayTable.Index',\n              },\n            },\n          },\n          column_3: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              title: 'Price',\n            },\n            properties: {\n              price: {\n                type: 'number',\n                default: 0,\n                'x-decorator': 'Editable',\n                'x-component': 'NumberPicker',\n                'x-component-props': {\n                  addonAfter: '$',\n                },\n              },\n            },\n          },\n          column_4: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              title: 'Count',\n            },\n            properties: {\n              count: {\n                type: 'number',\n                default: 0,\n                'x-decorator': 'Editable',\n                'x-component': 'NumberPicker',\n                'x-component-props': {\n                  addonAfter: '$',\n                },\n              },\n            },\n          },\n          column_5: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              title: 'Total',\n            },\n            properties: {\n              total: {\n                type: 'number',\n                'x-read-pretty': true,\n                'x-decorator': 'FormItem',\n                'x-component': 'NumberPicker',\n                'x-component-props': {\n                  addonAfter: '$',\n                },\n                'x-reactions': {\n                  dependencies: ['.price', '.count'],\n                  when: '{{$deps[0] && $deps[1]}}',\n                  fulfill: {\n                    state: {\n                      value: '{{$deps[0] * $deps[1]}}',\n                    },\n                  },\n                },\n              },\n            },\n          },\n          column_6: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              title: 'Operations',\n            },\n            properties: {\n              item: {\n                type: 'void',\n                'x-component': 'FormItem',\n                properties: {\n                  remove: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.Remove',\n                  },\n                  moveDown: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveDown',\n                  },\n                  moveUp: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveUp',\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          title: 'Add',\n          'x-component': 'ArrayTable.Addition',\n        },\n      },\n    },\n    total: {\n      type: 'number',\n      title: 'Total',\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n      'x-component-props': {\n        addonAfter: '$',\n      },\n      'x-pattern': 'readPretty',\n      'x-reactions': {\n        dependencies: ['.projects'],\n        when: '{{$deps[0].length > 0}}',\n        fulfill: {\n          state: {\n            value:\n              '{{$deps[0].reduce((total,item)=>item.total ? total+item.total : total,0)}}',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <Form form={form} layout=\"vertical\">\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </Form>\n  )\n}\n```\n"
  },
  {
    "path": "docs/guide/advanced/controlled.md",
    "content": "# Form Controlled\n\nFormily 2.x has given up supporting controlled mode for form components and field components. Because the internal management state mode of the form itself is not a controlled mode, there will be many boundary problems in the process of changing the controlled mode to the uncontrolled mode. At the same time, the controlled mode will have a large number of dirty inspection processes, and the performance is very poor. Instead, the controlled mode itself can solve most of the problems.\n\nSo Formily no longer supports the controlled mode, but if we insist on implementing ordinary React controlled, we can still support it. It can only achieve value control, not field-level control, which is the Field component we use. The properties will only take effect during the first rendering. Any changes to the properties in the future will not be automatically updated. If you want to update automatically, unless you recreate the Form instance (obviously this will lose all the previously maintained state).\n\nTherefore, we more recommend using [@formily/reactive](https://reactive.formilyjs.org) to achieve responsive control, which can achieve both value control and field-level control.\n\n## Value Controlled\n\nOrdinary controlled mode, which will rely heavily on dirty checking to achieve data synchronization, and the number of component renderings will be very high.\n\n```tsx\nimport React, { useMemo, useState, useEffect, useRef } from 'react'\nimport { createForm, onFormValuesChange } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst MyForm = (props) => {\n  const form = useMemo(\n    () =>\n      createForm({\n        values: props.values,\n        effects: () => {\n          onFormValuesChange((form) => {\n            props.onChange(form.values)\n          })\n        },\n      }),\n    []\n  )\n  const count = useRef(1)\n\n  useEffect(() => {\n    form.setValues(props.values, 'overwrite')\n  }, [JSON.stringify(props.values)])\n\n  return (\n    <Form form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"input\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-component-props={{ placeholder: 'controlled target' }}\n        />\n      </SchemaField>\n      Form component rendering times：{count.current++}\n    </Form>\n  )\n}\n\nexport default () => {\n  const [values, setValues] = useState({ input: '' })\n  const count = useRef(1)\n  return (\n    <>\n      <FormItem>\n        <Input\n          value={values.input}\n          placeholder=\"controller\"\n          onChange={(event) => {\n            setValues({ ...values, input: event.target.value })\n          }}\n        />\n      </FormItem>\n      <MyForm\n        values={values}\n        onChange={(values) => {\n          setValues({ ...values })\n        }}\n      />\n      root component rendering times: {count.current++}\n    </>\n  )\n}\n```\n\n## Responsive Value Controlled\n\nResponsive control is mainly to use [@formily/reactive](https://reactive.formilyjs.org) to achieve responsive updates, we can easily achieve two-way binding, while the performance is full of normal controlled updates.\n\n```tsx\nimport React, { useMemo, useRef } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\nimport { observable } from '@formily/reactive'\nimport { observer } from '@formily/reactive-react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst MyForm = (props) => {\n  const count = useRef(1)\n  const form = useMemo(\n    () =>\n      createForm({\n        values: props.values,\n      }),\n    []\n  )\n\n  return (\n    <Form form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"input\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-component-props={{ placeholder: 'controlled target' }}\n        />\n      </SchemaField>\n      Form component rendering times：{count.current++}\n    </Form>\n  )\n}\n\nconst Controller = observer((props) => {\n  const count = useRef(1)\n  return (\n    <FormItem>\n      <Input\n        value={props.values.input}\n        placeholder=\"controller\"\n        onChange={(event) => {\n          props.values.input = event.target.value\n        }}\n      />\n      Controller component rendering times：{count.current++}\n    </FormItem>\n  )\n})\n\nexport default () => {\n  const count = useRef(1)\n  const values = useMemo(() =>\n    observable({\n      input: '',\n    })\n  )\n  return (\n    <>\n      <Controller values={values} />\n      <MyForm values={values} />\n      root component rendering times：{count.current++}\n    </>\n  )\n}\n```\n\n## Schema Controlled\n\nThere will be a requirement for the form configuration scenario. The Schema of the form will change frequently. In fact, it is equivalent to frequently creating new forms. The state of the previous operation should be discarded.\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\nimport { Button, Space } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    Select,\n  },\n})\n\nexport default () => {\n  const [current, setCurrent] = useState({})\n  const form = useMemo(() => createForm(), [current])\n  return (\n    <Form form={form} layout=\"vertical\">\n      <Space style={{ marginBottom: 20 }}>\n        <Button\n          onClick={() => {\n            setCurrent({\n              type: 'object',\n              properties: {\n                aa: {\n                  type: 'string',\n                  title: 'AA',\n                  'x-decorator': 'FormItem',\n                  'x-component': 'Input',\n                  'x-component-props': {\n                    placeholder: 'Input',\n                  },\n                },\n              },\n            })\n          }}\n        >\n          Schema1\n        </Button>\n        <Button\n          onClick={() => {\n            setCurrent({\n              type: 'object',\n              properties: {\n                aa: {\n                  type: 'string',\n                  title: 'AA',\n                  'x-decorator': 'FormItem',\n                  enum: [\n                    {\n                      label: '111',\n                      value: '111',\n                    },\n                    { label: '222', value: '222' },\n                  ],\n                  'x-component': 'Select',\n                  'x-component-props': {\n                    placeholder: 'Select',\n                  },\n                },\n                bb: {\n                  type: 'string',\n                  title: 'BB',\n                  'x-decorator': 'FormItem',\n                  'x-component': 'Input',\n                },\n              },\n            })\n          }}\n        >\n          Schema2\n        </Button>\n      </Space>\n      <SchemaField schema={current} />\n    </Form>\n  )\n}\n```\n\n## Schema fragment linkage (top level control)\n\nThe most important thing for fragment linkage is to manually clean up the field model, otherwise the UI cannot be synchronized\n\n```tsx\nimport React, { useMemo, useRef } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, observer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    Select,\n  },\n})\n\nconst DYNAMIC_INJECT_SCHEMA = {\n  type_1: {\n    type: 'void',\n    properties: {\n      aa: {\n        type: 'string',\n        title: 'AA',\n        'x-decorator': 'FormItem',\n        'x-component': 'Input',\n        'x-component-props': {\n          placeholder: 'Input',\n        },\n      },\n    },\n  },\n  type_2: {\n    type: 'void',\n    properties: {\n      aa: {\n        type: 'string',\n        title: 'AA',\n        'x-decorator': 'FormItem',\n        enum: [\n          {\n            label: '111',\n            value: '111',\n          },\n          { label: '222', value: '222' },\n        ],\n        'x-component': 'Select',\n        'x-component-props': {\n          placeholder: 'Select',\n        },\n      },\n      bb: {\n        type: 'string',\n        title: 'BB',\n        'x-decorator': 'FormItem',\n        'x-component': 'Input',\n      },\n    },\n  },\n}\n\nconst App = observer(() => {\n  const oldTypeRef = useRef()\n  const form = useMemo(() => createForm(), [])\n  const currentType = form.values.type\n  const schema = {\n    type: 'object',\n    properties: {\n      type: {\n        type: 'string',\n        title: 'Type',\n        enum: [\n          { label: 'type 1', value: 'type_1' },\n          { label: 'type 2', value: 'type_2' },\n        ],\n        'x-decorator': 'FormItem',\n        'x-component': 'Select',\n      },\n      container: DYNAMIC_INJECT_SCHEMA[currentType],\n    },\n  }\n\n  if (oldTypeRef.current !== currentType) {\n    form.clearFormGraph('container.*') //Recycle field model\n  }\n\n  oldTypeRef.current = currentType\n\n  return (\n    <Form form={form} layout=\"vertical\">\n      <SchemaField schema={schema} />\n    </Form>\n  )\n})\n\nexport default App\n```\n\n## Schema fragment linkage (custom component)\n\n```tsx\nimport React, { useMemo, useState, useEffect } from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  createSchemaField,\n  RecursionField,\n  useForm,\n  useField,\n  observer,\n} from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst Custom = observer(() => {\n  const field = useField()\n  const form = useForm()\n  const [schema, setSchema] = useState({})\n\n  useEffect(() => {\n    form.clearFormGraph(`${field.address}.*`) //Recycle field model\n    //Can be obtained asynchronously\n    setSchema(DYNAMIC_INJECT_SCHEMA[form.values.type])\n  }, [form.values.type])\n\n  return (\n    <RecursionField\n      basePath={field.address}\n      schema={schema}\n      onlyRenderProperties\n    />\n  )\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    Select,\n    Custom,\n  },\n})\n\nconst DYNAMIC_INJECT_SCHEMA = {\n  type_1: {\n    type: 'void',\n    properties: {\n      aa: {\n        type: 'string',\n        title: 'AA',\n        'x-decorator': 'FormItem',\n        'x-component': 'Input',\n        'x-component-props': {\n          placeholder: 'Input',\n        },\n      },\n    },\n  },\n  type_2: {\n    type: 'void',\n    properties: {\n      aa: {\n        type: 'string',\n        title: 'AA',\n        'x-decorator': 'FormItem',\n        enum: [\n          {\n            label: '111',\n            value: '111',\n          },\n          { label: '222', value: '222' },\n        ],\n        'x-component': 'Select',\n        'x-component-props': {\n          placeholder: 'Select',\n        },\n      },\n      bb: {\n        type: 'string',\n        title: 'BB',\n        'x-decorator': 'FormItem',\n        'x-component': 'Input',\n      },\n    },\n  },\n}\n\nconst App = observer(() => {\n  const form = useMemo(() => createForm(), [])\n  const schema = {\n    type: 'object',\n    properties: {\n      type: {\n        type: 'string',\n        title: 'Type',\n        enum: [\n          { label: 'type 1', value: 'type_1' },\n          { label: 'type 2', value: 'type_2' },\n        ],\n        'x-decorator': 'FormItem',\n        'x-component': 'Select',\n      },\n      container: {\n        type: 'object',\n        'x-component': 'Custom',\n      },\n    },\n  }\n\n  return (\n    <Form form={form} layout=\"vertical\">\n      <SchemaField schema={schema} />\n    </Form>\n  )\n})\n\nexport default App\n```\n\n## Field Level Control\n\n### Best Practices\n\nIt is recommended to use [@formily/reactive](https://reactive.formilyjs.org) to achieve responsive control.\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\nimport { observable } from '@formily/reactive'\nimport { observer } from '@formily/reactive-react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst obs = observable({\n  input: '',\n})\n\nconst Controller = observer(() => {\n  return (\n    <FormItem>\n      <Input\n        value={obs.input}\n        placeholder=\"controller\"\n        onChange={(event) => {\n          obs.input = event.target.value\n        }}\n      />\n    </FormItem>\n  )\n})\n\nexport default () => {\n  return (\n    <>\n      <Controller />\n      <Form form={form}>\n        <SchemaField>\n          <SchemaField.String\n            name=\"input\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            x-component-props={{ placeholder: 'controlled target' }}\n            x-reactions={(field) => {\n              field.component[1].placeholder = obs.input || 'controlled target'\n            }}\n          />\n        </SchemaField>\n      </Form>\n    </>\n  )\n}\n```\n\n### Anti-pattern\n\nIt is not possible to update automatically when using traditional controlled mode.\n\n```tsx\nimport React, { useState } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  const [value, setValue] = useState('')\n  return (\n    <>\n      <FormItem>\n        <Input\n          value={value}\n          placeholder=\"controller\"\n          onChange={(event) => {\n            setValue(event.target.value)\n          }}\n        />\n      </FormItem>\n      <Form form={form}>\n        <SchemaField>\n          <SchemaField.String\n            name=\"input\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            x-component-props={{ placeholder: value || 'controlled target' }}\n          />\n        </SchemaField>\n      </Form>\n    </>\n  )\n}\n```\n"
  },
  {
    "path": "docs/guide/advanced/controlled.zh-CN.md",
    "content": "# 实现表单受控\n\nFormily2.x 已经放弃了给表单组件和字段组件支持受控模式，因为表单内部管理状态模式本身就不是受控模式，在将受控模式转为非受控模式的过程中会有很多边界问题，同时受控模式会存在大量的脏检查过程，性能很不好，反而非受控模式本身就可以解决大部分问题了。\n\n所以 Formily 就不再支持受控模式了，但是如果我们硬要实现普通 React 受控，还是可以支持的，只不过只能实现值受控，不能实现字段级受控，也就是我们使用的 Field 组件，属性只会在初次渲染时生效，未来属性发生任何变化都不会自动更新，想要自动更新，除非重新创建 Form 实例(显然这样会丢失所有之前维护好的状态)。\n\n所以，我们更加推荐的是使用[@formily/reactive](https://reactive.formilyjs.org/zh-CN) 实现响应式受控，既能实现值受控，也能实现字段级受控\n\n## 值受控\n\n普通受控模式，会强依赖脏检查实现数据同步，同时组件渲染次数会非常高\n\n```tsx\nimport React, { useMemo, useState, useEffect, useRef } from 'react'\nimport { createForm, onFormValuesChange } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst MyForm = (props) => {\n  const form = useMemo(\n    () =>\n      createForm({\n        values: props.values,\n        effects: () => {\n          onFormValuesChange((form) => {\n            props.onChange(form.values)\n          })\n        },\n      }),\n    []\n  )\n  const count = useRef(1)\n\n  useEffect(() => {\n    form.setValues(props.values, 'overwrite')\n  }, [JSON.stringify(props.values)])\n\n  return (\n    <Form form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"input\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-component-props={{ placeholder: '受控者' }}\n        />\n      </SchemaField>\n      Form组件渲染次数：{count.current++}\n    </Form>\n  )\n}\n\nexport default () => {\n  const [values, setValues] = useState({ input: '' })\n  const count = useRef(1)\n  return (\n    <>\n      <FormItem>\n        <Input\n          value={values.input}\n          placeholder=\"控制者\"\n          onChange={(event) => {\n            setValues({ ...values, input: event.target.value })\n          }}\n        />\n      </FormItem>\n      <MyForm\n        values={values}\n        onChange={(values) => {\n          setValues({ ...values })\n        }}\n      />\n      根组件渲染次数：{count.current++}\n    </>\n  )\n}\n```\n\n## 响应式值受控\n\n响应式受控主要是使用[@formily/reactive](https://reactive.formilyjs.org/zh-CN)实现响应式更新，我们可以轻松实现双向绑定，同时性能完爆普通受控更新\n\n```tsx\nimport React, { useMemo, useRef } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\nimport { observable } from '@formily/reactive'\nimport { observer } from '@formily/reactive-react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst MyForm = (props) => {\n  const count = useRef(1)\n  const form = useMemo(\n    () =>\n      createForm({\n        values: props.values,\n      }),\n    []\n  )\n\n  return (\n    <Form form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"input\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-component-props={{ placeholder: '受控者' }}\n        />\n      </SchemaField>\n      Form组件渲染次数：{count.current++}\n    </Form>\n  )\n}\n\nconst Controller = observer((props) => {\n  const count = useRef(1)\n  return (\n    <FormItem>\n      <Input\n        value={props.values.input}\n        placeholder=\"控制者\"\n        onChange={(event) => {\n          props.values.input = event.target.value\n        }}\n      />\n      Controller组件渲染次数：{count.current++}\n    </FormItem>\n  )\n})\n\nexport default () => {\n  const count = useRef(1)\n  const values = useMemo(() =>\n    observable({\n      input: '',\n    })\n  )\n  return (\n    <>\n      <Controller values={values} />\n      <MyForm values={values} />\n      根组件渲染次数：{count.current++}\n    </>\n  )\n}\n```\n\n## Schema 受控\n\n对于表单配置化场景会有一个需求，表单的 Schema 会发生频繁改变，其实就相当于频繁创建新表单了，之前操作的状态就应该丢弃了\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\nimport { Button, Space } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    Select,\n  },\n})\n\nexport default () => {\n  const [current, setCurrent] = useState({})\n  const form = useMemo(() => createForm(), [current])\n  return (\n    <Form form={form} layout=\"vertical\">\n      <Space style={{ marginBottom: 20 }}>\n        <Button\n          onClick={() => {\n            setCurrent({\n              type: 'object',\n              properties: {\n                aa: {\n                  type: 'string',\n                  title: 'AA',\n                  'x-decorator': 'FormItem',\n                  'x-component': 'Input',\n                  'x-component-props': {\n                    placeholder: 'Input',\n                  },\n                },\n              },\n            })\n          }}\n        >\n          Schema1\n        </Button>\n        <Button\n          onClick={() => {\n            setCurrent({\n              type: 'object',\n              properties: {\n                aa: {\n                  type: 'string',\n                  title: 'AA',\n                  'x-decorator': 'FormItem',\n                  enum: [\n                    {\n                      label: '111',\n                      value: '111',\n                    },\n                    { label: '222', value: '222' },\n                  ],\n                  'x-component': 'Select',\n                  'x-component-props': {\n                    placeholder: 'Select',\n                  },\n                },\n                bb: {\n                  type: 'string',\n                  title: 'BB',\n                  'x-decorator': 'FormItem',\n                  'x-component': 'Input',\n                },\n              },\n            })\n          }}\n        >\n          Schema2\n        </Button>\n      </Space>\n      <SchemaField schema={current} />\n    </Form>\n  )\n}\n```\n\n## Schema 片段联动(顶层控制)\n\n片段联动最重要的是需要手动清理字段模型，否则无法做到 UI 同步\n\n```tsx\nimport React, { useMemo, useRef } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, observer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    Select,\n  },\n})\n\nconst DYNAMIC_INJECT_SCHEMA = {\n  type_1: {\n    type: 'void',\n    properties: {\n      aa: {\n        type: 'string',\n        title: 'AA',\n        'x-decorator': 'FormItem',\n        'x-component': 'Input',\n        'x-component-props': {\n          placeholder: 'Input',\n        },\n      },\n    },\n  },\n  type_2: {\n    type: 'void',\n    properties: {\n      aa: {\n        type: 'string',\n        title: 'AA',\n        'x-decorator': 'FormItem',\n        enum: [\n          {\n            label: '111',\n            value: '111',\n          },\n          { label: '222', value: '222' },\n        ],\n        'x-component': 'Select',\n        'x-component-props': {\n          placeholder: 'Select',\n        },\n      },\n      bb: {\n        type: 'string',\n        title: 'BB',\n        'x-decorator': 'FormItem',\n        'x-component': 'Input',\n      },\n    },\n  },\n}\n\nconst App = observer(() => {\n  const oldTypeRef = useRef()\n  const form = useMemo(() => createForm(), [])\n  const currentType = form.values.type\n  const schema = {\n    type: 'object',\n    properties: {\n      type: {\n        type: 'string',\n        title: '类型',\n        enum: [\n          { label: '类型1', value: 'type_1' },\n          { label: '类型2', value: 'type_2' },\n        ],\n        'x-decorator': 'FormItem',\n        'x-component': 'Select',\n      },\n      container: DYNAMIC_INJECT_SCHEMA[currentType],\n    },\n  }\n\n  if (oldTypeRef.current !== currentType) {\n    form.clearFormGraph('container.*') //回收字段模型\n  }\n\n  oldTypeRef.current = currentType\n\n  return (\n    <Form form={form} layout=\"vertical\">\n      <SchemaField schema={schema} />\n    </Form>\n  )\n})\n\nexport default App\n```\n\n## Schema 片段联动(自定义组件)\n\n```tsx\nimport React, { useMemo, useState, useEffect } from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  createSchemaField,\n  RecursionField,\n  useForm,\n  useField,\n  observer,\n} from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst Custom = observer(() => {\n  const field = useField()\n  const form = useForm()\n  const [schema, setSchema] = useState({})\n\n  useEffect(() => {\n    form.clearFormGraph(`${field.address}.*`) //回收字段模型\n    //可以异步获取\n    setSchema(DYNAMIC_INJECT_SCHEMA[form.values.type])\n  }, [form.values.type])\n\n  return (\n    <RecursionField\n      basePath={field.address}\n      schema={schema}\n      onlyRenderProperties\n    />\n  )\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    Select,\n    Custom,\n  },\n})\n\nconst DYNAMIC_INJECT_SCHEMA = {\n  type_1: {\n    type: 'void',\n    properties: {\n      aa: {\n        type: 'string',\n        title: 'AA',\n        'x-decorator': 'FormItem',\n        'x-component': 'Input',\n        'x-component-props': {\n          placeholder: 'Input',\n        },\n      },\n    },\n  },\n  type_2: {\n    type: 'void',\n    properties: {\n      aa: {\n        type: 'string',\n        title: 'AA',\n        'x-decorator': 'FormItem',\n        enum: [\n          {\n            label: '111',\n            value: '111',\n          },\n          { label: '222', value: '222' },\n        ],\n        'x-component': 'Select',\n        'x-component-props': {\n          placeholder: 'Select',\n        },\n      },\n      bb: {\n        type: 'string',\n        title: 'BB',\n        'x-decorator': 'FormItem',\n        'x-component': 'Input',\n      },\n    },\n  },\n}\n\nconst App = observer(() => {\n  const form = useMemo(() => createForm(), [])\n  const schema = {\n    type: 'object',\n    properties: {\n      type: {\n        type: 'string',\n        title: '类型',\n        enum: [\n          { label: '类型1', value: 'type_1' },\n          { label: '类型2', value: 'type_2' },\n        ],\n        'x-decorator': 'FormItem',\n        'x-component': 'Select',\n      },\n      container: {\n        type: 'object',\n        'x-component': 'Custom',\n      },\n    },\n  }\n\n  return (\n    <Form form={form} layout=\"vertical\">\n      <SchemaField schema={schema} />\n    </Form>\n  )\n})\n\nexport default App\n```\n\n## 字段级受控\n\n### 最佳实践\n\n推荐使用[@formily/reactive](https://reactive.formilyjs.org/zh-CN) 实现响应式受控\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\nimport { observable } from '@formily/reactive'\nimport { observer } from '@formily/reactive-react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst obs = observable({\n  input: '',\n})\n\nconst Controller = observer(() => {\n  return (\n    <FormItem>\n      <Input\n        value={obs.input}\n        placeholder=\"控制者\"\n        onChange={(event) => {\n          obs.input = event.target.value\n        }}\n      />\n    </FormItem>\n  )\n})\n\nexport default () => {\n  return (\n    <>\n      <Controller />\n      <Form form={form}>\n        <SchemaField>\n          <SchemaField.String\n            name=\"input\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            x-component-props={{ placeholder: '受控者' }}\n            x-reactions={(field) => {\n              field.component[1].placeholder = obs.input || '受控者'\n            }}\n          />\n        </SchemaField>\n      </Form>\n    </>\n  )\n}\n```\n\n### 反模式\n\n使用传统受控模式是无法自动更新的\n\n```tsx\nimport React, { useState } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  const [value, setValue] = useState('')\n  return (\n    <>\n      <FormItem>\n        <Input\n          value={value}\n          placeholder=\"控制者\"\n          onChange={(event) => {\n            setValue(event.target.value)\n          }}\n        />\n      </FormItem>\n      <Form form={form}>\n        <SchemaField>\n          <SchemaField.String\n            name=\"input\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            x-component-props={{ placeholder: value || '受控者' }}\n          />\n        </SchemaField>\n      </Form>\n    </>\n  )\n}\n```\n"
  },
  {
    "path": "docs/guide/advanced/custom.md",
    "content": "# Custom Components\n\nThe realization of business custom components mainly uses the Hooks API and observer API in [@formily/react](https://react.formilyjs.org) or [@formily/vue](https://vue.formilyjs.org).\n\nTo access the ready-made component library, we mainly use connect/mapProps/mapReadPretty API.\n\nIf you want to implement some more complex custom components, we strongly recommend looking directly at the source code of [@formily/antd](https://github.com/alibaba/formily/tree/formily_next/packages/antd/src) or [@formily/next](https://github.com/alibaba/formily/tree/formily_next/packages/next/src).\n"
  },
  {
    "path": "docs/guide/advanced/custom.zh-CN.md",
    "content": "# 实现自定义组件\n\n实现业务自定义组件主要是使用[@formily/react](https://react.formilyjs.org/zh-CN) 或[@formily/vue](https://vue.formilyjs.org)中的 Hooks API 与 observer API\n\n接入现成组件库的话，我们主要使用 connect/mapProps/mapReadPretty API\n\n如果想要实现一些更复杂的自定义组件，我们强烈推荐直接看[@formily/antd](https://github.com/alibaba/formily/tree/formily_next/packages/antd/src)或 [@formily/next](https://github.com/alibaba/formily/tree/formily_next/packages/next/src)的源码\n"
  },
  {
    "path": "docs/guide/advanced/destructor.md",
    "content": "# Compatible solution for front-end and back-end data differences\n\nMany times, we always encounter scenarios where the front-end data structure does not match the back-end data structure. The seemingly simple problem is actually very uncomfortable to solve. The most common problems are:\n\nThe output of the front-end date range component is an array structure, but the format required by the back-end is to split a flat data structure. This problem is largely limited by the back-end domain model. Because from the perspective of back-end model design, splitting the flat structure is the best solution;\n\nBut from the perspective of front-end componentization, the array structure is the best;\n\nSo each side has its truth, but unfortunately, it can only cancel such an unequal treaty at the front end every time. However, with Formily, you don’t need to feel uncomfortable for such an embarrassing situation. **Formily provides the ability to deconstruct the path, which can help users quickly solve such problems.** Let's take a look at an example\n\n## Markup Schema Case\n\n```tsx\nimport React from 'react'\nimport {\n  Form,\n  FormItem,\n  DatePicker,\n  FormButtonGroup,\n  Radio,\n  Submit,\n} from '@formily/antd'\nimport { createForm, onFieldValueChange } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    DatePicker,\n    Radio,\n  },\n})\n\nconst form = createForm({\n  effects() {\n    onFieldValueChange('visible_destructor', (field) => {\n      form.setFieldState('[startDate,endDate]', (state) => {\n        state.visible = !!field.value\n      })\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <Form form={form} layout=\"vertical\">\n      <SchemaField>\n        <SchemaField.Boolean\n          name=\"visible_destructor\"\n          title=\"Whether to display deconstructed fields\"\n          default={true}\n          enum={[\n            { label: 'yes', value: true },\n            { label: 'no', value: false },\n          ]}\n          x-decorator=\"FormItem\"\n          x-component=\"Radio.Group\"\n        />\n        <SchemaField.String\n          name=\"undestructor\"\n          title=\"before deconstruction\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker.RangePicker\"\n        />\n        <SchemaField.String\n          name=\"[startDate,endDate]\"\n          title=\"after deconstruction\"\n          default={['2020-11-20', '2021-12-30']}\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker.RangePicker\"\n        />\n      </SchemaField>\n      <code>\n        <pre>\n          <FormConsumer>\n            {(form) => JSON.stringify(form.values, null, 2)}\n          </FormConsumer>\n        </pre>\n      </code>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>submit</Submit>\n      </FormButtonGroup>\n    </Form>\n  )\n}\n```\n\n## JSON Schema Cases\n\n```tsx\nimport React from 'react'\nimport {\n  Form,\n  FormItem,\n  DatePicker,\n  FormButtonGroup,\n  Radio,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    DatePicker,\n    Radio,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    visible_destructor: {\n      type: 'boolean',\n      title: 'Whether to display deconstructed fields',\n      default: true,\n      enum: [\n        { label: 'yes', value: true },\n        { label: 'no', value: false },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Radio.Group',\n    },\n    undestructor: {\n      type: 'string',\n      title: 'before deconstruction',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n    },\n    '[startDate,endDate]': {\n      type: 'string',\n      title: 'after deconstruction',\n      default: ['2020-11-20', '2021-12-30'],\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n      'x-reactions': {\n        dependencies: ['visible_destructor'],\n        fulfill: {\n          state: {\n            visible: '{{!!$deps[0]}}',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <Form form={form} layout=\"vertical\">\n      <SchemaField schema={schema} />\n      <code>\n        <pre>\n          <FormConsumer>\n            {(form) => JSON.stringify(form.values, null, 2)}\n          </FormConsumer>\n        </pre>\n      </code>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>submit</Submit>\n      </FormButtonGroup>\n    </Form>\n  )\n}\n```\n\n## Pure JSX Case\n\n```tsx\nimport React from 'react'\nimport {\n  Form,\n  FormItem,\n  DatePicker,\n  FormButtonGroup,\n  Radio,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { Field, FormConsumer } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <Form form={form} layout=\"vertical\">\n      <Field\n        name=\"visible_destructor\"\n        title=\"Whether to display deconstructed fields\"\n        initialValue={true}\n        dataSource={[\n          { label: 'yes', value: true },\n          { label: 'no', value: false },\n        ]}\n        decorator={[FormItem]}\n        component={[Radio.Group]}\n      />\n      <Field\n        name=\"undestructor\"\n        title=\"before deconstruction\"\n        decorator={[FormItem]}\n        component={[DatePicker.RangePicker]}\n      />\n      <Field\n        name=\"[startDate,endDate]\"\n        title=\"after deconstruction\"\n        initialValue={['2020-11-20', '2021-12-30']}\n        decorator={[FormItem]}\n        component={[DatePicker.RangePicker]}\n        reactions={(field) => {\n          field.visible = !!field.query('visible_destructor').value()\n        }}\n      />\n      <code>\n        <pre>\n          <FormConsumer>\n            {(form) => JSON.stringify(form.values, null, 2)}\n          </FormConsumer>\n        </pre>\n      </code>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>submit</Submit>\n      </FormButtonGroup>\n    </Form>\n  )\n}\n```\n"
  },
  {
    "path": "docs/guide/advanced/destructor.zh-CN.md",
    "content": "# 前后端数据差异兼容方案\n\n很多时候，我们总会遇到前端数据结构与后端数据结构不匹配的场景，看似很简单的问题，其实解决起来非常的让人难受，最常见的问题就是：\n\n前端日期范围组件输出的是数组结构，但是后端要求的格式是拆分扁平数据结构，这种问题很大程度是受后端领域模型所限制，因为从后端模型设计的角度来看，拆分扁平结构是最佳方案；\n\n但从前端组件化角度来看，数组结构又是最佳的；\n\n所以哪一边都有其道理，可惜的是，每次都只能前端去消化这样一个不平等条约，不过，有了 Formily，你就完全不需要为这样一个尴尬局面而难受了，**Formily 提供了解构路径的能力，可以帮助用户快速解决这类问题。**，下面可以看看例子\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Form,\n  FormItem,\n  DatePicker,\n  FormButtonGroup,\n  Radio,\n  Submit,\n} from '@formily/antd'\nimport { createForm, onFieldValueChange } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    DatePicker,\n    Radio,\n  },\n})\n\nconst form = createForm({\n  effects() {\n    onFieldValueChange('visible_destructor', (field) => {\n      form.setFieldState('[startDate,endDate]', (state) => {\n        state.visible = !!field.value\n      })\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <Form form={form} layout=\"vertical\">\n      <SchemaField>\n        <SchemaField.Boolean\n          name=\"visible_destructor\"\n          title=\"是否显示解构字段\"\n          default={true}\n          enum={[\n            { label: '是', value: true },\n            { label: '否', value: false },\n          ]}\n          x-decorator=\"FormItem\"\n          x-component=\"Radio.Group\"\n        />\n        <SchemaField.String\n          name=\"undestructor\"\n          title=\"解构前\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker.RangePicker\"\n        />\n        <SchemaField.String\n          name=\"[startDate,endDate]\"\n          title=\"解构后\"\n          default={['2020-11-20', '2021-12-30']}\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker.RangePicker\"\n        />\n      </SchemaField>\n      <code>\n        <pre>\n          <FormConsumer>\n            {(form) => JSON.stringify(form.values, null, 2)}\n          </FormConsumer>\n        </pre>\n      </code>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </Form>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Form,\n  FormItem,\n  DatePicker,\n  FormButtonGroup,\n  Radio,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    DatePicker,\n    Radio,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    visible_destructor: {\n      type: 'boolean',\n      title: '是否显示解构字段',\n      default: true,\n      enum: [\n        { label: '是', value: true },\n        { label: '否', value: false },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Radio.Group',\n    },\n    undestructor: {\n      type: 'string',\n      title: '解构前',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n    },\n    '[startDate,endDate]': {\n      type: 'string',\n      title: '解构后',\n      default: ['2020-11-20', '2021-12-30'],\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n      'x-reactions': {\n        dependencies: ['visible_destructor'],\n        fulfill: {\n          state: {\n            visible: '{{!!$deps[0]}}',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <Form form={form} layout=\"vertical\">\n      <SchemaField schema={schema} />\n      <code>\n        <pre>\n          <FormConsumer>\n            {(form) => JSON.stringify(form.values, null, 2)}\n          </FormConsumer>\n        </pre>\n      </code>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </Form>\n  )\n}\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Form,\n  FormItem,\n  DatePicker,\n  FormButtonGroup,\n  Radio,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { Field, FormConsumer } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <Form form={form} layout=\"vertical\">\n      <Field\n        name=\"visible_destructor\"\n        title=\"是否显示解构字段\"\n        initialValue={true}\n        dataSource={[\n          { label: '是', value: true },\n          { label: '否', value: false },\n        ]}\n        decorator={[FormItem]}\n        component={[Radio.Group]}\n      />\n      <Field\n        name=\"undestructor\"\n        title=\"解构前\"\n        decorator={[FormItem]}\n        component={[DatePicker.RangePicker]}\n      />\n      <Field\n        name=\"[startDate,endDate]\"\n        title=\"解构后\"\n        initialValue={['2020-11-20', '2021-12-30']}\n        decorator={[FormItem]}\n        component={[DatePicker.RangePicker]}\n        reactions={(field) => {\n          field.visible = !!field.query('visible_destructor').value()\n        }}\n      />\n      <code>\n        <pre>\n          <FormConsumer>\n            {(form) => JSON.stringify(form.values, null, 2)}\n          </FormConsumer>\n        </pre>\n      </code>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </Form>\n  )\n}\n```\n"
  },
  {
    "path": "docs/guide/advanced/input.less",
    "content": "input {\n  background-color: transparent !important;\n}\n"
  },
  {
    "path": "docs/guide/advanced/layout.md",
    "content": "# Form Layout\n\nThe form layout mainly uses [@formily/antd](https://antd.formilyjs.org) or [@formily/next](https://fusion.formilyjs.org):\n\n- [FormLayout](http://antd.formilyjs.org/components/form-layout) Component\n- [FormItem](http://antd.formilyjs.org/components/form-item) Component\n- [FormGrid](http://antd.formilyjs.org/components/form-grid) Component\n- [Space](http://antd.formilyjs.org/components/space) Component\n\nThese 4 components can basically solve all complex form layout scenarios, we only need to flexibly combine these components.\n"
  },
  {
    "path": "docs/guide/advanced/layout.zh-CN.md",
    "content": "# 实现表单布局\n\n表单布局主要是使用[@formily/antd](https://antd.formilyjs.org/zh-CN) 或 [@formily/next](https://fusion.formilyjs.org/zh-CN) 中的：\n\n- [FormLayout](https://antd.formilyjs.org/zh-CN/components/form-layout) 组件\n- [FormItem](https://antd.formilyjs.org/zh-CN/components/form-item) 组件\n- [FormGrid](https://antd.formilyjs.org/zh-CN/components/form-grid) 组件\n- [Space](https://antd.formilyjs.org/zh-CN/components/space) 组件\n\n这 4 个组件基本上能解决所有复杂表单布局场景，我们只需要灵活的组合使用这几个组件即可。\n"
  },
  {
    "path": "docs/guide/advanced/linkages.md",
    "content": "# Linkage Logic\n\nThere is only one mode to realize linkage logic in Formily 1.x, that is, active mode. It is necessary to monitor the event changes of one or more fields to control the state of another or more fields.\nThis is very convenient for one-to-many linkage scenarios, but it is very troublesome for many-to-one scenarios. It is necessary to monitor the changes of multiple fields to control the state of a field. Therefore, Formily 2.x provides a responsive mechanism that allows the linkage to support passive linkage. You only need to pay attention to the field that a field depends on. When the dependent field changes, the dependent field can be automatically linked.\n\n## Active Mode\n\nThe core of active linkage is based on\n\n- [FormEffectHooks](https://core.formilyjs.org/api/entry/form-effect-hooks)\n- [FieldEffectHooks](https://core.formilyjs.org/api/entry/field-effect-hooks)\n- [setFormState](https://core.formilyjs.org/api/models/form#setformstate)\n- [setFieldState](https://core.formilyjs.org/api/models/form#setfieldstate)\n- [SchemaReactions](https://react.formilyjs.org/api/shared/schema#schemareactions)\n\nRealize active linkage, the advantage is that it is very convenient to realize one-to-many linkage.\n\n### One-to-One Linkage\n\n#### Effects Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldValueChange } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldValueChange('select', (field) => {\n      form.setFieldState('input', (state) => {\n        //For the initial linkage, if the field cannot be found, setFieldState will push the update into the update queue until the field appears before performing the operation\n        state.display = field.value\n      })\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"controller\"\n        default=\"visible\"\n        enum={[\n          { label: 'display', value: 'visible' },\n          { label: 'hide', value: 'none' },\n          { label: 'Hidden-reserved value', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"controlled target\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"controller\"\n        default=\"visible\"\n        enum={[\n          { label: 'display', value: 'visible' },\n          { label: 'hide', value: 'none' },\n          { label: 'Hidden-reserved value', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          target: 'input',\n          fulfill: {\n            state: {\n              display: '{{$self.value}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"controlled target\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### One-to-Many Linkage\n\n#### Effects Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldValueChange } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldValueChange('select', (field) => {\n      form.setFieldState('*(input1,input2)', (state) => {\n        //For the initial linkage, if the field cannot be found, setFieldState will push the update into the update queue until the field appears before performing the operation\n        state.display = field.value\n      })\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"controller\"\n        default=\"visible\"\n        enum={[\n          { label: 'display', value: 'visible' },\n          { label: 'hide', value: 'none' },\n          { label: 'Hidden-reserved value', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input1\"\n        title=\"controlled target\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"controlled target\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"controller\"\n        default=\"visible\"\n        enum={[\n          { label: 'display', value: 'visible' },\n          { label: 'hide', value: 'none' },\n          { label: 'Hidden-reserved value', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          target: '*(input1,input2)',\n          fulfill: {\n            state: {\n              display: '{{$self.value}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"input1\"\n        title=\"controller\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"controller\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### Rely on Linkage\n\n#### Effects Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldValueChange } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldValueChange('dim_1', (field) => {\n      const dim1 = field.value\n      const dim2 = field.query('dim_2').value()\n      form.setFieldState('result', (state) => {\n        state.value = dim1 * dim2\n      })\n    })\n    onFieldValueChange('dim_2', (field) => {\n      const dim1 = field.query('dim_1').value()\n      const dim2 = field.value || 0\n      form.setFieldState('result', (state) => {\n        state.value = dim1 * dim2\n      })\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    NumberPicker,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"dim_1\"\n        title=\"controller\"\n        default={0}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"dim_2\"\n        title=\"controller\"\n        default={0}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"result\"\n        title=\"controlled target\"\n        x-pattern=\"readPretty\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    NumberPicker,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"dim_1\"\n        title=\"controller\"\n        default={0}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['dim_2'],\n          target: 'result',\n          fulfill: {\n            state: {\n              value: '{{$self.value * $deps[0]}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.Number\n        name=\"dim_2\"\n        title=\"controller\"\n        default={0}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['dim_1'],\n          target: 'result',\n          fulfill: {\n            state: {\n              value: '{{$self.value * $deps[0]}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.Number\n        name=\"result\"\n        title=\"controller\"\n        x-pattern=\"readPretty\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### Chain Linkage\n\n#### Effects Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldValueChange } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldValueChange('select', (field) => {\n      form.setFieldState('input1', (state) => {\n        //For the initial linkage, if the field cannot be found, setFieldState will push the update into the update queue until the field appears before performing the operation\n        state.visible = !!field.value\n      })\n    })\n    onFieldValueChange('input1', (field) => {\n      form.setFieldState('input2', (state) => {\n        //For the initial linkage, if the field cannot be found, setFieldState will push the update into the update queue until the field appears before performing the operation\n        state.visible = !!field.value\n      })\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"controller\"\n        default={false}\n        enum={[\n          { label: 'display', value: true },\n          { label: 'hide', value: false },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input1\"\n        title=\"controlled target\"\n        default={true}\n        enum={[\n          { label: 'display', value: true },\n          { label: 'hide', value: false },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"controlled target\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"controller\"\n        default={false}\n        enum={[\n          { label: 'display', value: true },\n          { label: 'hide', value: false },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          target: 'input1',\n          fulfill: {\n            state: {\n              visible: '{{!!$self.value}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"input1\"\n        title=\"controlled target\"\n        default={true}\n        enum={[\n          { label: 'display', value: true },\n          { label: 'hide', value: false },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          target: 'input2',\n          fulfill: {\n            state: {\n              visible: '{{!!$self.value}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"controlled target\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### Loop Linkage\n\n#### Effects Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldInputValueChange } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, NumberPicker } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldInputValueChange('total', (field) => {\n      if (field.value === undefined) return\n      form.setFieldState('count', (state) => {\n        const price = form.values.price\n        if (!price) return\n        state.value = field.value / price\n      })\n      form.setFieldState('price', (state) => {\n        const count = form.values.count\n        if (!count) return\n        state.value = field.value / count\n      })\n    })\n    onFieldInputValueChange('price', (field) => {\n      form.setFieldState('total', (state) => {\n        const count = form.values.count\n        if (count === undefined) return\n        state.value = field.value * count\n      })\n    })\n    onFieldInputValueChange('count', (field) => {\n      form.setFieldState('total', (state) => {\n        const price = form.values.price\n        if (price === undefined) return\n        state.value = field.value * price\n      })\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    NumberPicker,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"total\"\n        title=\"total price\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"count\"\n        title=\"quantity\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"price\"\n        title=\"unit price\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, NumberPicker } from '@formily/antd'\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    NumberPicker,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"total\"\n        title=\"total price\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n        x-reactions={[\n          {\n            target: 'count',\n            effects: ['onFieldInputValueChange'],\n            dependencies: ['price'],\n            fulfill: {\n              state: {\n                value: '{{$deps[0] ? $self.value / $deps[0] : $target.value}}',\n              },\n            },\n          },\n          {\n            target: 'price',\n            effects: ['onFieldInputValueChange'],\n            dependencies: ['count'],\n            fulfill: {\n              state: {\n                value: '{{$deps[0] ? $self.value / $deps[0] : $target.value}}',\n              },\n            },\n          },\n        ]}\n      />\n      <SchemaField.Number\n        name=\"count\"\n        title=\"quantity\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          target: 'total',\n          effects: ['onFieldInputValueChange'],\n          dependencies: ['price'],\n          fulfill: {\n            state: {\n              value:\n                '{{$deps[0] !== undefined ? $self.value * $deps[0] : $target.value}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.Number\n        name=\"price\"\n        title=\"unit price\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          target: 'total',\n          effects: ['onFieldInputValueChange'],\n          dependencies: ['count'],\n          fulfill: {\n            state: {\n              value:\n                '{{$deps[0] !== undefined ? $self.value * $deps[0] : $target.value}}',\n            },\n          },\n        }}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### Self Linkage\n\n#### Effects Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldValueChange } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\nimport './input.less'\n\nconst form = createForm({\n  effects() {\n    onFieldValueChange('color', (field) => {\n      field.setComponentProps({\n        style: {\n          backgroundColor: field.value,\n        },\n      })\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"color\"\n        default=\"#FFFFFF\"\n        title=\"color\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\nimport './input.less'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"color\"\n        default=\"#FFFFFF\"\n        title=\"color\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          target: 'color',\n          fulfill: {\n            state: {\n              'component[1].style.backgroundColor': '{{$self.value}}',\n            },\n            //The following usage is also possible\n            // schema: {\n            //   'x-component-props.style.backgroundColor': '{{$self.value}}',\n            // },\n          },\n        }}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### Asynchronous Linkage\n\n#### Effects Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldValueChange } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldValueChange('select', (field) => {\n      field.loading = true\n      setTimeout(() => {\n        field.loading = false\n        form.setFieldState('input', (state) => {\n          //For the initial linkage, if the field cannot be found, setFieldState will push the update into the update queue until the field appears before performing the operation\n          state.display = field.value\n        })\n      }, 1000)\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"controller\"\n        default=\"visible\"\n        enum={[\n          { label: 'display', value: 'visible' },\n          { label: 'hide', value: 'none' },\n          { label: 'Hidden-reserved value', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"controlled target\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-visible={false}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n  scope: {\n    asyncVisible(field, target) {\n      field.loading = true\n      setTimeout(() => {\n        field.loading = false\n        form.setFieldState(target, (state) => {\n          //For the initial linkage, if the field cannot be found, setFieldState will push the update into the update queue until the field appears before performing the operation\n          state.display = field.value\n        })\n      }, 1000)\n    },\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"controller\"\n        default=\"visible\"\n        enum={[\n          { label: 'display', value: 'visible' },\n          { label: 'hide', value: 'none' },\n          { label: 'Hidden-reserved value', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          target: 'input',\n          effects: ['onFieldInit', 'onFieldValueChange'],\n          fulfill: {\n            run: 'asyncVisible($self,$target)',\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"controlled target\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-visible={false}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n## Passive Mode\n\nThe core of the passive mode is based on\n\n- [onFieldReact](https://core.formilyjs.org/api/entry/field-effect-hooks#onfieldreact) Implement global reactive logic\n- [FieldReaction](https://core.formilyjs.org/api/models/field#fieldreaction) Implement partial responsive logic\n- [SchemaReactions](https://react.formilyjs.org/api/shared/schema#schemareactions) Implement the structured logical description in the Schema protocol (the internal implementation is based on FieldReaction)\n\n### One-to-One Linkage\n\n#### Effects Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldReact('input', (field) => {\n      field.display = field.query('select').value()\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"controller\"\n        default=\"visible\"\n        enum={[\n          { label: 'display', value: 'visible' },\n          { label: 'hide', value: 'none' },\n          { label: 'Hidden-reserved value', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"controlled target\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"controller\"\n        default=\"visible\"\n        enum={[\n          { label: 'display', value: 'visible' },\n          { label: 'hide', value: 'none' },\n          { label: 'Hidden-reserved value', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"controlled target\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['select'],\n          fulfill: {\n            state: {\n              display: '{{$deps[0]}}',\n            },\n          },\n        }}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### One-to-Many Linkage\n\n#### Effects Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldReact('*(input1,input2)', (field) => {\n      field.display = field.query('select').value()\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"controller\"\n        default=\"visible\"\n        enum={[\n          { label: 'display', value: 'visible' },\n          { label: 'hide', value: 'none' },\n          { label: 'Hidden-reserved value', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input1\"\n        title=\"controlled target\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"controlled target\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"controller\"\n        default=\"visible\"\n        enum={[\n          { label: 'display', value: 'visible' },\n          { label: 'hide', value: 'none' },\n          { label: 'Hidden-reserved value', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input1\"\n        title=\"controlled target\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['select'],\n          fulfill: {\n            state: {\n              display: '{{$deps[0]}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"controlled target\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['select'],\n          fulfill: {\n            state: {\n              display: '{{$deps[0]}}',\n            },\n          },\n        }}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### Rely on Linkage\n\n#### Effects Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldReact('result', (field) => {\n      field.value = field.query('dim_1').value() * field.query('dim_2').value()\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    NumberPicker,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"dim_1\"\n        title=\"controller\"\n        default={0}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"dim_2\"\n        title=\"controller\"\n        default={0}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"result\"\n        title=\"controlled target\"\n        x-pattern=\"readPretty\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    NumberPicker,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"dim_1\"\n        title=\"controller\"\n        default={0}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"dim_2\"\n        title=\"controller\"\n        default={0}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"result\"\n        title=\"controlled target\"\n        x-pattern=\"readPretty\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['dim_1', 'dim_2'],\n          fulfill: {\n            state: {\n              value: '{{$deps[0] * $deps[1]}}',\n            },\n          },\n        }}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### Chain Linkage\n\n#### Effects Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldReact('input1', (field) => {\n      field.visible = !!field.query('select').value()\n    })\n    onFieldReact('input2', (field) => {\n      field.visible = !!field.query('input1').value()\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"controller\"\n        default={false}\n        enum={[\n          { label: 'display', value: true },\n          { label: 'hide', value: false },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input1\"\n        title=\"controlled target\"\n        default={true}\n        enum={[\n          { label: 'display', value: true },\n          { label: 'hide', value: false },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"controlled target\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"controller\"\n        default={false}\n        enum={[\n          { label: 'display', value: true },\n          { label: 'hide', value: false },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input1\"\n        title=\"controlled target\"\n        default={true}\n        enum={[\n          { label: 'display', value: true },\n          { label: 'hide', value: false },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['select'],\n          fulfill: {\n            state: {\n              visible: '{{!!$deps[0]}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"controlled target\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['input1'],\n          fulfill: {\n            state: {\n              visible: '{{!!$deps[0]}}',\n            },\n          },\n        }}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### Loop Linkage\n\n#### Effects Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, NumberPicker } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldReact('total', (field) => {\n      const count = field.query('count').value()\n      const price = field.query('price').value()\n      if (count !== undefined && price !== undefined) {\n        field.value = count * price\n      }\n    })\n    onFieldReact('price', (field) => {\n      const total = field.query('total').value()\n      const count = field.query('count').value()\n      if (total !== undefined && count > 0) {\n        field.value = total / count\n      }\n    })\n    onFieldReact('count', (field) => {\n      const total = field.query('total').value()\n      const price = field.query('price').value()\n      if (total !== undefined && price > 0) {\n        field.value = total / price\n      }\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    NumberPicker,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"total\"\n        title=\"总价\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"count\"\n        title=\"数量\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"price\"\n        title=\"单价\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    NumberPicker,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"total\"\n        title=\"总价\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['.count', '.price'],\n          fulfill: {\n            state: {\n              value:\n                '{{$deps[0] !== undefined && $deps[1] !== undefined ? $deps[0] * $deps[1] : $self.value}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.Number\n        name=\"count\"\n        title=\"数量\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['.total', '.price'],\n          fulfill: {\n            state: {\n              value: '{{ $deps[1] > 0 ? $deps[0] / $deps[1] : $self.value}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.Number\n        name=\"price\"\n        title=\"单价\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['.total', '.count'],\n          fulfill: {\n            state: {\n              value: '{{ $deps[1] > 0 ? $deps[0] / $deps[1] : $self.value}}',\n            },\n          },\n        }}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### Self Linkage\n\n#### Effects Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\nimport './input.less'\n\nconst form = createForm({\n  effects() {\n    onFieldReact('color', (field) => {\n      field.setComponentProps({\n        style: {\n          backgroundColor: field.value,\n        },\n      })\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"color\"\n        default=\"#FFFFFF\"\n        title=\"color\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\nimport './input.less'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"color\"\n        default=\"#FFFFFF\"\n        title=\"color\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          fulfill: {\n            state: {\n              'component[1].style.backgroundColor': '{{$self.value}}',\n            },\n            //The following usage is also possible\n            // schema: {\n            //   'x-component-props.style.backgroundColor': '{{$self.value}}',\n            // },\n          },\n        }}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### Asynchronous Linkage\n\n#### Effects Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldReact('input', (field) => {\n      const select = field.query('select').take()\n      if (!select) return\n      const selectValue = select.value\n      select.loading = true\n      if (selectValue) {\n        setTimeout(() => {\n          select.loading = false\n          field.display = selectValue\n        }, 1000)\n      }\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"controller\"\n        default=\"visible\"\n        enum={[\n          { label: 'display', value: 'visible' },\n          { label: 'hide', value: 'none' },\n          { label: 'Hidden-reserved value', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"controlled target\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-visible={false}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n  scope: {\n    asyncVisible(field) {\n      const select = field.query('select').take()\n      if (!select) return\n      const selectValue = select.value\n      select.loading = true\n      if (selectValue) {\n        setTimeout(() => {\n          select.loading = false\n          field.display = selectValue\n        }, 1000)\n      }\n    },\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"controller\"\n        default=\"visible\"\n        enum={[\n          { label: 'display', value: 'visible' },\n          { label: 'hide', value: 'none' },\n          { label: 'Hidden-reserved value', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"controlled target\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-visible={false}\n        x-reactions=\"{{asyncVisible}}\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n"
  },
  {
    "path": "docs/guide/advanced/linkages.zh-CN.md",
    "content": "# 实现联动逻辑\n\nFormily1.x 中实现联动逻辑只有一种模式，也就是主动模式，必须要监听一个或多个字段的事件变化去控制另一个或者多个字段的状态，这样对于一对多联动场景很方便，但是对于多对一场景就很麻烦了，需要监听多个字段的变化去控制一个字段状态，所以 Formily2.x 提供了响应式机制，可以让联动支持被动式联动，只需要关注某个字段所依赖的字段即可，依赖字段变化了，被依赖的字段即可自动联动。\n\n## 主动模式\n\n主动联动核心是基于\n\n- [FormEffectHooks](https://core.formilyjs.org/zh-CN/api/entry/form-effect-hooks)\n- [FieldEffectHooks](https://core.formilyjs.org/zh-CN/api/entry/field-effect-hooks)\n- [setFormState](https://core.formilyjs.org/zh-CN/api/models/form#setformstate)\n- [setFieldState](https://core.formilyjs.org/zh-CN/api/models/form#setfieldstate)\n- [SchemaReactions](https://react.formilyjs.org/zh-CN/api/shared/schema#schemareactions)\n\n实现主动联动，优点是实现一对多联动时非常方便\n\n### 一对一联动\n\n#### Effects 用例\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldValueChange } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldValueChange('select', (field) => {\n      form.setFieldState('input', (state) => {\n        //对于初始联动，如果字段找不到，setFieldState会将更新推入更新队列，直到字段出现再执行操作\n        state.display = field.value\n      })\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"控制者\"\n        default=\"visible\"\n        enum={[\n          { label: '显示', value: 'visible' },\n          { label: '隐藏', value: 'none' },\n          { label: '隐藏-保留值', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"控制者\"\n        default=\"visible\"\n        enum={[\n          { label: '显示', value: 'visible' },\n          { label: '隐藏', value: 'none' },\n          { label: '隐藏-保留值', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          target: 'input',\n          fulfill: {\n            state: {\n              display: '{{$self.value}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### 一对多联动\n\n#### Effects 用例\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldValueChange } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldValueChange('select', (field) => {\n      form.setFieldState('*(input1,input2)', (state) => {\n        //对于初始联动，如果字段找不到，setFieldState会将更新推入更新队列，直到字段出现再执行操作\n        state.display = field.value\n      })\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"控制者\"\n        default=\"visible\"\n        enum={[\n          { label: '显示', value: 'visible' },\n          { label: '隐藏', value: 'none' },\n          { label: '隐藏-保留值', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input1\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"控制者\"\n        default=\"visible\"\n        enum={[\n          { label: '显示', value: 'visible' },\n          { label: '隐藏', value: 'none' },\n          { label: '隐藏-保留值', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          target: '*(input1,input2)',\n          fulfill: {\n            state: {\n              display: '{{$self.value}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"input1\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### 依赖联动\n\n#### Effects 用例\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldValueChange } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldValueChange('dim_1', (field) => {\n      const dim1 = field.value\n      const dim2 = field.query('dim_2').value()\n      form.setFieldState('result', (state) => {\n        state.value = dim1 * dim2\n      })\n    })\n    onFieldValueChange('dim_2', (field) => {\n      const dim1 = field.query('dim_1').value()\n      const dim2 = field.value || 0\n      form.setFieldState('result', (state) => {\n        state.value = dim1 * dim2\n      })\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    NumberPicker,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"dim_1\"\n        title=\"控制者\"\n        default={0}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"dim_2\"\n        title=\"控制者\"\n        default={0}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"result\"\n        title=\"受控者\"\n        x-pattern=\"readPretty\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    NumberPicker,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"dim_1\"\n        title=\"控制者\"\n        default={0}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['dim_2'],\n          target: 'result',\n          fulfill: {\n            state: {\n              value: '{{$self.value * $deps[0]}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.Number\n        name=\"dim_2\"\n        title=\"控制者\"\n        default={0}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['dim_1'],\n          target: 'result',\n          fulfill: {\n            state: {\n              value: '{{$self.value * $deps[0]}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.Number\n        name=\"result\"\n        title=\"受控者\"\n        x-pattern=\"readPretty\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### 链式联动\n\n#### Effects 用例\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldValueChange } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldValueChange('select', (field) => {\n      form.setFieldState('input1', (state) => {\n        //对于初始联动，如果字段找不到，setFieldState会将更新推入更新队列，直到字段出现再执行操作\n        state.visible = !!field.value\n      })\n    })\n    onFieldValueChange('input1', (field) => {\n      form.setFieldState('input2', (state) => {\n        //对于初始联动，如果字段找不到，setFieldState会将更新推入更新队列，直到字段出现再执行操作\n        state.visible = !!field.value\n      })\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"控制者\"\n        default={false}\n        enum={[\n          { label: '显示', value: true },\n          { label: '隐藏', value: false },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input1\"\n        title=\"受控者\"\n        default={true}\n        enum={[\n          { label: '显示', value: true },\n          { label: '隐藏', value: false },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"控制者\"\n        default={false}\n        enum={[\n          { label: '显示', value: true },\n          { label: '隐藏', value: false },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          target: 'input1',\n          fulfill: {\n            state: {\n              visible: '{{!!$self.value}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"input1\"\n        title=\"受控者\"\n        default={true}\n        enum={[\n          { label: '显示', value: true },\n          { label: '隐藏', value: false },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          target: 'input2',\n          fulfill: {\n            state: {\n              visible: '{{!!$self.value}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### 循环联动\n\n#### Effects 用例\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldInputValueChange } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, NumberPicker } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldInputValueChange('total', (field) => {\n      if (field.value === undefined) return\n      form.setFieldState('count', (state) => {\n        const price = form.values.price\n        if (!price) return\n        state.value = field.value / price\n      })\n      form.setFieldState('price', (state) => {\n        const count = form.values.count\n        if (!count) return\n        state.value = field.value / count\n      })\n    })\n    onFieldInputValueChange('price', (field) => {\n      form.setFieldState('total', (state) => {\n        const count = form.values.count\n        if (count === undefined) return\n        state.value = field.value * count\n      })\n    })\n    onFieldInputValueChange('count', (field) => {\n      form.setFieldState('total', (state) => {\n        const price = form.values.price\n        if (price === undefined) return\n        state.value = field.value * price\n      })\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    NumberPicker,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"total\"\n        title=\"总价\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"count\"\n        title=\"数量\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"price\"\n        title=\"单价\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, NumberPicker } from '@formily/antd'\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    NumberPicker,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"total\"\n        title=\"总价\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n        x-reactions={[\n          {\n            target: 'count',\n            effects: ['onFieldInputValueChange'],\n            dependencies: ['price'],\n            fulfill: {\n              state: {\n                value: '{{$deps[0] ? $self.value / $deps[0] : $target.value}}',\n              },\n            },\n          },\n          {\n            target: 'price',\n            effects: ['onFieldInputValueChange'],\n            dependencies: ['count'],\n            fulfill: {\n              state: {\n                value: '{{$deps[0] ? $self.value / $deps[0] : $target.value}}',\n              },\n            },\n          },\n        ]}\n      />\n      <SchemaField.Number\n        name=\"count\"\n        title=\"数量\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          target: 'total',\n          effects: ['onFieldInputValueChange'],\n          dependencies: ['price'],\n          fulfill: {\n            state: {\n              value:\n                '{{$deps[0] !== undefined ? $self.value * $deps[0] : $target.value}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.Number\n        name=\"price\"\n        title=\"单价\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          target: 'total',\n          effects: ['onFieldInputValueChange'],\n          dependencies: ['count'],\n          fulfill: {\n            state: {\n              value:\n                '{{$deps[0] !== undefined ? $self.value * $deps[0] : $target.value}}',\n            },\n          },\n        }}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### 自身联动\n\n#### Effects 用例\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldValueChange } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\nimport './input.less'\n\nconst form = createForm({\n  effects() {\n    onFieldValueChange('color', (field) => {\n      field.setComponentProps({\n        style: {\n          backgroundColor: field.value,\n        },\n      })\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"color\"\n        default=\"#FFFFFF\"\n        title=\"颜色\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\nimport './input.less'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"color\"\n        default=\"#FFFFFF\"\n        title=\"颜色\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          target: 'color',\n          fulfill: {\n            state: {\n              'component[1].style.backgroundColor': '{{$self.value}}',\n            },\n            //以下用法也可以\n            // schema: {\n            //   'x-component-props.style.backgroundColor': '{{$self.value}}',\n            // },\n          },\n        }}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### 异步联动\n\n#### Effects 用例\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldValueChange } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldValueChange('select', (field) => {\n      field.loading = true\n      setTimeout(() => {\n        field.loading = false\n        form.setFieldState('input', (state) => {\n          //对于初始联动，如果字段找不到，setFieldState会将更新推入更新队列，直到字段出现再执行操作\n          state.display = field.value\n        })\n      }, 1000)\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"控制者\"\n        default=\"visible\"\n        enum={[\n          { label: '显示', value: 'visible' },\n          { label: '隐藏', value: 'none' },\n          { label: '隐藏-保留值', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-visible={false}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n  scope: {\n    asyncVisible(field, target) {\n      field.loading = true\n      setTimeout(() => {\n        field.loading = false\n        form.setFieldState(target, (state) => {\n          //对于初始联动，如果字段找不到，setFieldState会将更新推入更新队列，直到字段出现再执行操作\n          state.display = field.value\n        })\n      }, 1000)\n    },\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"控制者\"\n        default=\"visible\"\n        enum={[\n          { label: '显示', value: 'visible' },\n          { label: '隐藏', value: 'none' },\n          { label: '隐藏-保留值', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          target: 'input',\n          effects: ['onFieldInit', 'onFieldValueChange'],\n          fulfill: {\n            run: 'asyncVisible($self,$target)',\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-visible={false}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n## 被动模式\n\n被动模式的核心是基于\n\n- [onFieldReact](https://core.formilyjs.org/zh-CN/api/entry/field-effect-hooks#onfieldreact)实现全局响应式逻辑\n- [FieldReaction](https://core.formilyjs.org/zh-CN/api/models/field#fieldreaction)实现局部响应式逻辑\n- [SchemaReactions](https://react.formilyjs.org/zh-CN/api/shared/schema#schemareactions)实现 Schema 协议中的结构化逻辑描述(内部是基于 FieldReaction 来实现的)\n\n### 一对一联动\n\n#### Effects 用例\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldReact('input', (field) => {\n      field.display = field.query('select').value()\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"控制者\"\n        default=\"visible\"\n        enum={[\n          { label: '显示', value: 'visible' },\n          { label: '隐藏', value: 'none' },\n          { label: '隐藏-保留值', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"控制者\"\n        default=\"visible\"\n        enum={[\n          { label: '显示', value: 'visible' },\n          { label: '隐藏', value: 'none' },\n          { label: '隐藏-保留值', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['select'],\n          fulfill: {\n            state: {\n              display: '{{$deps[0]}}',\n            },\n          },\n        }}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### 一对多联动\n\n#### Effects 用例\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldReact('*(input1,input2)', (field) => {\n      field.display = field.query('select').value()\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"控制者\"\n        default=\"visible\"\n        enum={[\n          { label: '显示', value: 'visible' },\n          { label: '隐藏', value: 'none' },\n          { label: '隐藏-保留值', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input1\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"控制者\"\n        default=\"visible\"\n        enum={[\n          { label: '显示', value: 'visible' },\n          { label: '隐藏', value: 'none' },\n          { label: '隐藏-保留值', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input1\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['select'],\n          fulfill: {\n            state: {\n              display: '{{$deps[0]}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['select'],\n          fulfill: {\n            state: {\n              display: '{{$deps[0]}}',\n            },\n          },\n        }}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### 依赖联动\n\n#### Effects 用例\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldReact('result', (field) => {\n      field.value = field.query('dim_1').value() * field.query('dim_2').value()\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    NumberPicker,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"dim_1\"\n        title=\"控制者\"\n        default={0}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"dim_2\"\n        title=\"控制者\"\n        default={0}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"result\"\n        title=\"受控者\"\n        x-pattern=\"readPretty\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    NumberPicker,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"dim_1\"\n        title=\"控制者\"\n        default={0}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"dim_2\"\n        title=\"控制者\"\n        default={0}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"result\"\n        title=\"受控者\"\n        x-pattern=\"readPretty\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['dim_1', 'dim_2'],\n          fulfill: {\n            state: {\n              value: '{{$deps[0] * $deps[1]}}',\n            },\n          },\n        }}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### 链式联动\n\n#### Effects 用例\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldReact('input1', (field) => {\n      field.visible = !!field.query('select').value()\n    })\n    onFieldReact('input2', (field) => {\n      field.visible = !!field.query('input1').value()\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"控制者\"\n        default={false}\n        enum={[\n          { label: '显示', value: true },\n          { label: '隐藏', value: false },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input1\"\n        title=\"受控者\"\n        default={true}\n        enum={[\n          { label: '显示', value: true },\n          { label: '隐藏', value: false },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"控制者\"\n        default={false}\n        enum={[\n          { label: '显示', value: true },\n          { label: '隐藏', value: false },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input1\"\n        title=\"受控者\"\n        default={true}\n        enum={[\n          { label: '显示', value: true },\n          { label: '隐藏', value: false },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['select'],\n          fulfill: {\n            state: {\n              visible: '{{!!$deps[0]}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['input1'],\n          fulfill: {\n            state: {\n              visible: '{{!!$deps[0]}}',\n            },\n          },\n        }}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### 循环联动\n\n#### Effects 用例\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, NumberPicker } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldReact('total', (field) => {\n      const count = field.query('count').value()\n      const price = field.query('price').value()\n      if (count !== undefined && price !== undefined) {\n        field.value = count * price\n      }\n    })\n    onFieldReact('price', (field) => {\n      const total = field.query('total').value()\n      const count = field.query('count').value()\n      if (total !== undefined && count > 0) {\n        field.value = total / count\n      }\n    })\n    onFieldReact('count', (field) => {\n      const total = field.query('total').value()\n      const price = field.query('price').value()\n      if (total !== undefined && price > 0) {\n        field.value = total / price\n      }\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    NumberPicker,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"total\"\n        title=\"总价\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"count\"\n        title=\"数量\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"price\"\n        title=\"单价\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    NumberPicker,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"total\"\n        title=\"总价\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['.count', '.price'],\n          fulfill: {\n            state: {\n              value:\n                '{{$deps[0] !== undefined && $deps[1] !== undefined ? $deps[0] * $deps[1] : $self.value}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.Number\n        name=\"count\"\n        title=\"数量\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['.total', '.price'],\n          fulfill: {\n            state: {\n              value: '{{ $deps[1] > 0 ? $deps[0] / $deps[1] : $self.value}}',\n            },\n          },\n        }}\n      />\n      <SchemaField.Number\n        name=\"price\"\n        title=\"单价\"\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          dependencies: ['.total', '.count'],\n          fulfill: {\n            state: {\n              value: '{{ $deps[1] > 0 ? $deps[0] / $deps[1] : $self.value}}',\n            },\n          },\n        }}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### 自身联动\n\n#### Effects 用例\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\nimport './input.less'\n\nconst form = createForm({\n  effects() {\n    onFieldReact('color', (field) => {\n      field.setComponentProps({\n        style: {\n          backgroundColor: field.value,\n        },\n      })\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"color\"\n        default=\"#FFFFFF\"\n        title=\"颜色\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\nimport './input.less'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"color\"\n        default=\"#FFFFFF\"\n        title=\"颜色\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-reactions={{\n          fulfill: {\n            state: {\n              'component[1].style.backgroundColor': '{{$self.value}}',\n            },\n            //以下用法也可以\n            // schema: {\n            //   'x-component-props.style.backgroundColor': '{{$self.value}}',\n            // },\n          },\n        }}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n### 异步联动\n\n#### Effects 用例\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm({\n  effects() {\n    onFieldReact('input', (field) => {\n      const select = field.query('select').take()\n      if (!select) return\n      const selectValue = select.value\n      select.loading = true\n      if (selectValue) {\n        setTimeout(() => {\n          select.loading = false\n          field.display = selectValue\n        }, 1000)\n      }\n    })\n  },\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"控制者\"\n        default=\"visible\"\n        enum={[\n          { label: '显示', value: 'visible' },\n          { label: '隐藏', value: 'none' },\n          { label: '隐藏-保留值', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-visible={false}\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n\n#### SchemaReactions 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormConsumer } from '@formily/react'\nimport { Form, FormItem, Input, Select } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n  },\n  scope: {\n    asyncVisible(field) {\n      const select = field.query('select').take()\n      if (!select) return\n      const selectValue = select.value\n      select.loading = true\n      if (selectValue) {\n        setTimeout(() => {\n          select.loading = false\n          field.display = selectValue\n        }, 1000)\n      }\n    },\n  },\n})\n\nexport default () => (\n  <Form form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"控制者\"\n        default=\"visible\"\n        enum={[\n          { label: '显示', value: 'visible' },\n          { label: '隐藏', value: 'none' },\n          { label: '隐藏-保留值', value: 'hidden' },\n        ]}\n        x-component=\"Select\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"受控者\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n        x-visible={false}\n        x-reactions=\"{{asyncVisible}}\"\n      />\n    </SchemaField>\n    <FormConsumer>\n      {() => (\n        <code>\n          <pre>{JSON.stringify(form.values, null, 2)}</pre>\n        </code>\n      )}\n    </FormConsumer>\n  </Form>\n)\n```\n"
  },
  {
    "path": "docs/guide/advanced/validate.md",
    "content": "# Form Validation\n\nFormily's form validation uses the extremely powerful and flexible @formily/validator validation engine. There are two main scenarios for validation:\n\n- Markup(JSON) Schema scene protocol verification property verification, using JSON Schema's own verification property and x-validator property to achieve verification\n- Pure JSX scene verification properties, use validator property to achieve verification\n\nAt the same time, we can also implement linkage verification in effects or x-reactions/reactions\n\nSpecific rule verification document reference [FieldValidator](https://core.formilyjs.org/api/models/field#fieldvalidator)\n\nForm validation is an important part of optimizing user experience and ensuring data accuracy in forms. Formily provides various validation methods, including built-in rule validation, built-in format validation, and custom rule validation. In the following sections, we will introduce these validation methods one by one.\n\n## Built-in rule check\n\nBuilt-in rule validation refers to the common validation rules provided by Formily, such as required, max, min, len, enum, const, multipleOf, etc. These rules can be described using JSON Schema properties or the x-validator property. Formily supports multiple ways of writing built-in rules and it is recommended for teams to establish internal conventions based on their usage habits.\n\n#### Markup Schema Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    NumberPicker,\n  },\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"required_1\"\n        title=\"Required\"\n        required\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"required_2\"\n        title=\"Required\"\n        x-validator={{ required: true }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"required_3\"\n        title=\"Required\"\n        x-validator={[{ required: true }]}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"max_1\"\n        title=\"Maximum value (>5 error)\"\n        maximum={5}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"max_2\"\n        title=\"Maximum value (>5 error)\"\n        x-validator={{ maximum: 5 }}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"max_3\"\n        title=\"Maximum value (>5 error)\"\n        x-validator={[{ maximum: 5 }]}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"max_4\"\n        title=\"Maximum value (>=5 error)\"\n        exclusiveMaximum={5}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"max_5\"\n        title=\"Maximum value (>=5 error)\"\n        x-validator={{ exclusiveMaximum: 5 }}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"max_6\"\n        title=\"Maximum value (>=5 error)\"\n        x-validator={[{ exclusiveMaximum: 5 }]}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.Number\n        name=\"min_1\"\n        title=\"Minimum value (<5 error)\"\n        minimum={5}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"min_2\"\n        title=\"Minimum value (<5 error)\"\n        x-validator={{ minimum: 5 }}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"min_3\"\n        title=\"Minimum value (<5 error)\"\n        x-validator={[{ minimum: 5 }]}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"min_4\"\n        title=\"Minimum value (<=5 error)\"\n        exclusiveMinimum={5}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"min_5\"\n        title=\"Minimum value (<=5 error)\"\n        x-validator={{ exclusiveMinimum: 5 }}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"min_6\"\n        title=\"Minimum value (<=5 error)\"\n        x-validator={[{ exclusiveMinimum: 5 }]}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.String\n        name=\"length_1\"\n        title=\"Length is 5\"\n        x-validator={{ len: 5 }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"length_2\"\n        title=\"Length is 5\"\n        x-validator={[{ len: 5 }]}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.String\n        name=\"maxlength_1\"\n        title=\"Maximum length is 5\"\n        maxLength={5}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"maxlength_2\"\n        title=\"Maximum length is 5\"\n        x-validator={{ max: 5 }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"maxlength_3\"\n        title=\"Maximum length is 5\"\n        x-validator={[{ max: 5 }]}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.String\n        name=\"maxlength_4\"\n        title=\"Minimum length is 5\"\n        minLength={5}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"maxlength_5\"\n        title=\"Minimum length is 5\"\n        x-validator={{ min: 5 }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"maxlength_6\"\n        title=\"Minimum length is 5\"\n        x-validator={[{ min: 5 }]}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.String\n        name=\"whitespace\"\n        title=\"Exclude pure whitespace characters\"\n        x-validator={[{ whitespace: true }]}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.String\n        name=\"enum\"\n        title=\"Enumeration match\"\n        x-validator={[{ enum: ['1', '2', '3'] }]}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.String\n        name=\"const\"\n        title=\"Constant match\"\n        const=\"123\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.String\n        name=\"multipleOf\"\n        title=\"Divisible match\"\n        multipleOf={2}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n  </Form>\n)\n```\n\n#### JSON Schema Use Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    NumberPicker,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    required_1: {\n      name: 'required_1',\n      title: 'Required',\n      type: 'string',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    required_2: {\n      name: 'required_2',\n      title: 'Required',\n      type: 'string',\n      'x-validator': {\n        required: true,\n      },\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    required_3: {\n      name: 'required_3',\n      title: 'Required',\n      type: 'string',\n      'x-validator': [\n        {\n          required: true,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    max_1: {\n      name: 'max_1',\n      title: 'Maximum value (>5 error)',\n      type: 'number',\n      maximum: 5,\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    max_2: {\n      name: 'max_2',\n      title: 'Maximum value (>5 error)',\n      type: 'number',\n      'x-validator': {\n        maximum: 5,\n      },\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    max_3: {\n      name: 'max_3',\n      title: 'Maximum value (>5 error)',\n      type: 'number',\n      'x-validator': [\n        {\n          maximum: 5,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    max_4: {\n      name: 'max_4',\n      title: 'Maximum value (>=5 error))',\n      type: 'number',\n      exclusiveMaximum: 5,\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    max_5: {\n      name: 'max_5',\n      title: 'Maximum value (>=5 error))',\n      type: 'number',\n      'x-validator': {\n        exclusiveMaximum: 5,\n      },\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    max_6: {\n      name: 'max_6',\n      title: 'Maximum value (>=5 error))',\n      type: 'number',\n      'x-validator': [\n        {\n          exclusiveMaximum: 5,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    min_1: {\n      name: 'min_1',\n      title: 'Minimum value (<5 error))',\n      type: 'number',\n      minimum: 5,\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    min_2: {\n      name: 'min_2',\n      title: 'Minimum value (<5 error))',\n      type: 'number',\n      'x-validator': {\n        minimum: 5,\n      },\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    min_3: {\n      name: 'min_3',\n      title: 'Minimum value (<5 error))',\n      type: 'string',\n      'x-validator': [\n        {\n          minimum: 5,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    min_4: {\n      name: 'min_4',\n      title: 'Minimum value (<=5 error))',\n      type: 'number',\n      exclusiveMinimum: 5,\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    min_5: {\n      name: 'min_5',\n      title: 'Minimum value (<=5 error))',\n      type: 'number',\n      'x-validator': {\n        exclusiveMinimum: 5,\n      },\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    min_6: {\n      name: 'min_6',\n      title: 'Minimum value (<=5 error))',\n      type: 'number',\n      'x-validator': [\n        {\n          exclusiveMinimum: 5,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    length_1: {\n      name: 'length_1',\n      title: 'Length is 5',\n      type: 'string',\n      'x-validator': {\n        len: 5,\n      },\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    length_2: {\n      name: 'length_2',\n      title: 'Length is 5',\n      type: 'string',\n      'x-validator': [\n        {\n          len: 5,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    maxlength_1: {\n      name: 'maxlength_1',\n      title: 'Maximum length is 5',\n      type: 'string',\n      maxLength: 5,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    maxlength_2: {\n      name: 'maxlength_2',\n      title: 'Maximum length is 5',\n      type: 'string',\n      'x-validator': {\n        max: 5,\n      },\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    maxlength_3: {\n      name: 'maxlength_3',\n      title: 'Maximum length is 5',\n      type: 'string',\n      'x-validator': [\n        {\n          max: 5,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    minlength_1: {\n      name: 'minlength_1',\n      title: 'Minimum length is 5',\n      type: 'string',\n      minLength: 5,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    minlength_2: {\n      name: 'minlength_2',\n      title: 'Minimum length is 5',\n      type: 'string',\n      'x-validator': {\n        min: 5,\n      },\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    minlength_3: {\n      name: 'minlength_3',\n      title: 'Minimum length is 5',\n      type: 'string',\n      'x-validator': [\n        {\n          min: 5,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    whitespace: {\n      name: 'whitespace',\n      title: 'Exclude pure whitespace characters',\n      type: 'string',\n      'x-validator': [\n        {\n          whitespace: true,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    enum: {\n      name: 'enum',\n      title: 'Enumeration match',\n      type: 'string',\n      'x-validator': [\n        {\n          enum: ['1', '2', '3'],\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    const: {\n      name: 'const',\n      title: 'Constant match',\n      type: 'string',\n      const: '123',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    multipleOf: {\n      name: 'multipleOf',\n      title: 'Divisible match',\n      type: 'string',\n      multipleOf: 2,\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n  },\n}\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField schema={schema} />\n  </Form>\n)\n```\n\n#### Pure JSX Case\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <Field\n      name=\"required_1\"\n      title=\"Required\"\n      required\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"required_2\"\n      title=\"Required\"\n      validator={{ required: true }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"required_3\"\n      title=\"Required\"\n      validator={[{ required: true }]}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"max_1\"\n      title=\"Maximum value (>5 error)\"\n      validator={{ maximum: 5 }}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"max_2\"\n      title=\"Maximum value (>5 error)\"\n      validator={[{ maximum: 5 }]}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"max_3\"\n      title=\"Maximum value (>=5 error)\"\n      validator={{ exclusiveMaximum: 5 }}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"max_4\"\n      title=\"Maximum value (>=5 error)\"\n      validator={[{ exclusiveMaximum: 5 }]}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"min_1\"\n      title=\"Minimum value (<5 error)\"\n      validator={{ minimum: 5 }}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"min_2\"\n      title=\"Minimum value (<5 error)\"\n      validator={[{ minimum: 5 }]}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"min_3\"\n      title=\"Minimum value (<=5 error)\"\n      validator={{ exclusiveMinimum: 5 }}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"min_4\"\n      title=\"Minimum value (<=5 error)\"\n      validator={[{ exclusiveMinimum: 5 }]}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n\n    <Field\n      name=\"length_1\"\n      title=\"Length is 5\"\n      validator={{ len: 5 }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"length_2\"\n      title=\"Length is 5\"\n      validator={[{ len: 5 }]}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"maxlength_1\"\n      title=\"Maximum length is 5\"\n      validator={{ max: 5 }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"maxlength_2\"\n      title=\"Maximum length is 5\"\n      validator={[{ max: 5 }]}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"minlength_1\"\n      title=\"Minimum length is 5\"\n      validator={{ min: 5 }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"minlength_2\"\n      title=\"Minimum length is 5\"\n      validator={[{ min: 5 }]}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n\n    <Field\n      name=\"whitespace\"\n      title=\"Exclude pure whitespace characters\"\n      validator={[{ whitespace: true }]}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n  </Form>\n)\n```\n\n## Built-in Format Verification\n\n#### Markup Schema Cases\n\n```tsx\nimport React, { Fragment } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst renderFormat = (format: string, key: number) => {\n  return (\n    <Fragment key={key}>\n      <SchemaField.String\n        name={`${format}_1`}\n        title={`${format} format`}\n        format={format}\n        required\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name={`${format}_2`}\n        title={`${format} format`}\n        required\n        x-validator={format}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name={`${format}_3`}\n        title={`${format} format`}\n        required\n        x-validator={{ format }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name={`${format}_4`}\n        title={`${format} format`}\n        required\n        x-validator={[format]}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name={`${format}_5`}\n        title={`${format} format`}\n        required\n        x-validator={[{ format }]}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </Fragment>\n  )\n}\n\nconst FORMATS = [\n  'url',\n  'email',\n  'phone',\n  'ipv6',\n  'ipv4',\n  'number',\n  'integer',\n  'qq',\n  'idcard',\n  'money',\n  'zh',\n  'date',\n  'zip',\n]\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField>{FORMATS.map(renderFormat)}</SchemaField>\n  </Form>\n)\n```\n\n#### JSON Schema Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {},\n}\n\nconst FORMATS = [\n  'url',\n  'email',\n  'phone',\n  'ipv6',\n  'ipv4',\n  'number',\n  'integer',\n  'qq',\n  'idcard',\n  'money',\n  'zh',\n  'date',\n  'zip',\n]\n\nFORMATS.forEach((key) => {\n  Object.assign(schema.properties, {\n    [`${key}_1`]: {\n      title: `${key} format`,\n      type: 'string',\n      required: true,\n      format: key,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    [`${key}_2`]: {\n      title: `${key} format`,\n      type: 'string',\n      required: true,\n      'x-validator': key,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    [`${key}_3`]: {\n      title: `${key} format`,\n      type: 'string',\n      required: true,\n      'x-validator': {\n        format: key,\n      },\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    [`${key}_4`]: {\n      title: `${key} format`,\n      type: 'string',\n      required: true,\n      'x-validator': [key],\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n\n    [`${key}_5`]: {\n      title: `${key} format`,\n      type: 'string',\n      required: true,\n      'x-validator': [\n        {\n          format: key,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n  })\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField schema={schema} />\n  </Form>\n)\n```\n\n#### Pure JSX Cases\n\n```tsx\nimport React, { Fragment } from 'react'\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nconst renderFormat = (format: string, key: number) => {\n  return (\n    <Fragment key={key}>\n      <Field\n        name={`${format}_1`}\n        title={`${format} format`}\n        required\n        validator={format}\n        component={[Input]}\n        decorator={[FormItem]}\n      />\n      <Field\n        name={`${format}_2`}\n        title={`${format} format`}\n        required\n        validator={{ format }}\n        component={[Input]}\n        decorator={[FormItem]}\n      />\n      <Field\n        name={`${format}_3`}\n        title={`${format} format`}\n        required\n        validator={[format]}\n        component={[Input]}\n        decorator={[FormItem]}\n      />\n      <Field\n        name={`${format}_4`}\n        title={`${format} format`}\n        required\n        validator={[{ format }]}\n        component={[Input]}\n        decorator={[FormItem]}\n      />\n    </Fragment>\n  )\n}\n\nconst FORMATS = [\n  'url',\n  'email',\n  'phone',\n  'ipv6',\n  'ipv4',\n  'number',\n  'integer',\n  'qq',\n  'idcard',\n  'money',\n  'zh',\n  'date',\n  'zip',\n]\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    {FORMATS.map(renderFormat)}\n  </Form>\n)\n```\n\n## Custom Rule Verification\n\n#### Markup Schema Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, registerValidateRules } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    NumberPicker,\n  },\n})\n\nregisterValidateRules({\n  global_1(value) {\n    if (!value) return ''\n    return value !== '123' ? 'error❎' : ''\n  },\n  global_2(value, rule) {\n    if (!value) return ''\n    return value !== '123' ? rule.message : ''\n  },\n  global_3(value) {\n    if (!value) return ''\n    return value === '123'\n  },\n  global_4(value) {\n    if (!value) return ''\n    if (value < 10) {\n      return {\n        type: 'error',\n        message: 'The value cannot be less than 10',\n      }\n    } else if (value < 100) {\n      return {\n        type: 'warning',\n        message: 'The value is within 100',\n      }\n    } else if (value < 1000) {\n      return {\n        type: 'success',\n        message: 'The value is greater than 100 and less than 1000',\n      }\n    }\n  },\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"global_style_1\"\n        title=\"Global registration style\"\n        required\n        x-validator={{\n          global_1: true,\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"global_style_2\"\n        title=\"Global registration style\"\n        required\n        x-validator={{\n          global_2: true,\n          message: 'error❎',\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"global_style_3\"\n        title=\"Global registration style\"\n        required\n        x-validator={{\n          global_3: true,\n          message: 'error❎',\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"global_style_4\"\n        title=\"Global registration style\"\n        required\n        x-validator={{\n          global_4: true,\n        }}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.String\n        name=\"validator_style_1\"\n        title=\"Locally defined style\"\n        required\n        x-validator={(value) => {\n          if (!value) return ''\n          return value !== '123' ? 'error❎' : ''\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"validator_style_2\"\n        title=\"Locally defined style\"\n        required\n        x-validator={{\n          validator(value, rule) {\n            if (!value) return ''\n            return value !== '123' ? rule.message : ''\n          },\n          message: 'error❎',\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"validator_style_3\"\n        title=\"Locally defined style\"\n        required\n        x-validator={{\n          validator(value) {\n            if (!value) return ''\n            return value === '123'\n          },\n          message: 'error❎',\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"validator_style_4\"\n        title=\"Locally defined style\"\n        required\n        x-validator={(value) => {\n          if (!value) return ''\n          if (value < 10) {\n            return {\n              type: 'error',\n              message: 'The value cannot be less than 10',\n            }\n          } else if (value < 100) {\n            return {\n              type: 'warning',\n              message: 'The value is within 100',\n            }\n          } else if (value < 1000) {\n            return {\n              type: 'success',\n              message: 'The value is greater than 100 and less than 1000',\n            }\n          }\n        }}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n  </Form>\n)\n```\n\n#### JSON Schema Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, registerValidateRules } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    NumberPicker,\n  },\n})\n\nregisterValidateRules({\n  global_1(value) {\n    if (!value) return ''\n    return value !== '123' ? 'error❎' : ''\n  },\n  global_2(value, rule) {\n    if (!value) return ''\n    return value !== '123' ? rule.message : ''\n  },\n  global_3(value) {\n    if (!value) return ''\n    return value === '123'\n  },\n  global_4(value) {\n    if (!value) return ''\n    if (value < 10) {\n      return {\n        type: 'error',\n        message: 'The value cannot be less than 10',\n      }\n    } else if (value < 100) {\n      return {\n        type: 'warning',\n        message: 'The value is within 100',\n      }\n    } else if (value < 1000) {\n      return {\n        type: 'success',\n        message: 'The value is greater than 100 and less than 1000',\n      }\n    }\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    global_style_1: {\n      title: 'Global registration style',\n      required: true,\n      'x-validator': {\n        global_1: true,\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    global_style_2: {\n      title: 'Global registration style',\n      required: true,\n      'x-validator': {\n        global_2: true,\n        message: 'error❎',\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    global_style_3: {\n      title: 'Global registration style',\n      required: true,\n      'x-validator': {\n        global_3: true,\n        message: 'error❎',\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    global_style_4: {\n      title: 'Global registration style',\n      required: true,\n      'x-validator': {\n        global_4: true,\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n\n    validator_style_1: {\n      title: 'Locally defined style',\n      required: true,\n      'x-validator': `{{(value)=> {\n            if (!value) return ''\n            return value !== '123' ? 'error❎' : ''\n          }}}`,\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    validator_style_2: {\n      title: 'Locally defined style',\n      required: true,\n      'x-validator': {\n        validator: `{{(value, rule)=> {\n            if (!value) return ''\n            return value !== '123' ? rule.message : ''\n          }}}`,\n        message: 'error❎',\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    validator_style_3: {\n      title: 'Locally defined style',\n      required: true,\n      'x-validator': {\n        validator: `{{(value, rule)=> {\n          if (!value) return ''\n          return value === '123'\n        }}}`,\n        message: 'error❎',\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    validator_style_4: {\n      title: 'Locally defined style',\n      required: true,\n      'x-validator': `{{(value, rule)=> {\n          if (!value) return ''\n          if (value < 10) {\n            return {\n              type: 'error',\n              message: 'The value cannot be less than 10',\n            }\n          } else if (value < 100) {\n            return {\n              type: 'warning',\n              message: 'The value is within 100',\n            }\n          } else if (value < 1000) {\n            return {\n              type: 'success',\n              message: 'The value is greater than 100 and less than 1000',\n            }\n          }\n        }}}`,\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n  },\n}\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField schema={schema} />\n  </Form>\n)\n```\n\n#### Pure JSX Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, registerValidateRules } from '@formily/core'\nimport { Field } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nregisterValidateRules({\n  global_1(value) {\n    if (!value) return ''\n    return value !== '123' ? 'error❎' : ''\n  },\n  global_2(value, rule) {\n    if (!value) return ''\n    return value !== '123' ? rule.message : ''\n  },\n  global_3(value) {\n    if (!value) return ''\n    return value === '123'\n  },\n  global_4(value) {\n    if (!value) return ''\n    if (value < 10) {\n      return {\n        type: 'error',\n        message: 'The value cannot be less than 10',\n      }\n    } else if (value < 100) {\n      return {\n        type: 'warning',\n        message: 'The value is within 100',\n      }\n    } else if (value < 1000) {\n      return {\n        type: 'success',\n        message: 'The value is greater than 100 and less than 1000',\n      }\n    }\n  },\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <Field\n      name=\"global_style_1\"\n      title=\"Global registration style\"\n      required\n      validator={{\n        global_1: true,\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"global_style_2\"\n      title=\"Global registration style\"\n      required\n      validator={{\n        global_2: true,\n        message: 'error❎',\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"global_style_3\"\n      title=\"Global registration style\"\n      required\n      validator={{\n        global_3: true,\n        message: 'error❎',\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"global_style_4\"\n      title=\"Global registration style\"\n      required\n      validator={{\n        global_4: true,\n      }}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n\n    <Field\n      name=\"validator_style_1\"\n      title=\"Locally defined style\"\n      required\n      validator={(value) => {\n        if (!value) return ''\n        return value !== '123' ? 'error❎' : ''\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"validator_style_2\"\n      title=\"Locally defined style\"\n      required\n      validator={{\n        validator(value, rule) {\n          if (!value) return ''\n          return value !== '123' ? rule.message : ''\n        },\n        message: 'error❎',\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"validator_style_3\"\n      title=\"Locally defined style\"\n      required\n      validator={{\n        validator(value) {\n          if (!value) return ''\n          return value === '123'\n        },\n        message: 'error❎',\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"validator_style_4\"\n      title=\"Locally defined style\"\n      required\n      validator={(value) => {\n        if (!value) return ''\n        if (value < 10) {\n          return {\n            type: 'error',\n            message: 'The value cannot be less than 10',\n          }\n        } else if (value < 100) {\n          return {\n            type: 'warning',\n            message: 'The value is within 100',\n          }\n        } else if (value < 1000) {\n          return {\n            type: 'success',\n            message: 'The value is greater than 100 and less than 1000',\n          }\n        }\n      }}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n  </Form>\n)\n```\n\n## Using Third-Party Validation Libraries\n\nWith the powerful validation engine of Formily, it is extremely convenient to adapt to third-party validation libraries such as yup. Here is an example of how to use it:\n\n#### JSON Schema Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, registerValidateRules } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\nimport { string } from 'yup'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    NumberPicker,\n  },\n})\n\nregisterValidateRules({\n  yup: async (value, rule) => {\n    try {\n      await rule.yup().validate(value)\n      return '' // Return an empty string when validation is successful\n    } catch (err) {\n      return err.errors.join(',') // Return the error message when validation fails\n    }\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    global_style_1: {\n      title: 'Maximum length is 2',\n      'x-validator': [\n        {\n          triggerType: 'onBlur',\n          yup: () => string().required('required'),\n        },\n        {\n          triggerType: 'onBlur',\n          yup: () => string().max(2, 'Maximum length is 2'),\n        },\n      ],\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    global_style_2: {\n      title: 'email',\n      required: true,\n      'x-validator': {\n        triggerType: 'onBlur',\n        yup: () => string().email(),\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n  },\n}\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField schema={schema} />\n  </Form>\n)\n```\n\n#### Pure JSX Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, registerValidateRules } from '@formily/core'\nimport { Field } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\nimport { string, number } from 'yup'\n\nconst form = createForm()\n\nregisterValidateRules({\n  yup: async (value, rule) => {\n    try {\n      await rule.yup().validate(value)\n      return '' // Return an empty string when validation is successful\n    } catch (err) {\n      return err.errors.join(',') // Return the error message when validation fails\n    }\n  },\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <Field\n      name=\"global_style_1\"\n      title=\"email\"\n      required\n      validator={{\n        yup: () => string().email(),\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"global_style_2\"\n      title=\"max 30\"\n      required\n      validator={{\n        yup: () => number().max(30),\n      }}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"global_style_3\"\n      title=\"email\"\n      required\n      validator={{\n        yup: () => string().email(),\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n  </Form>\n)\n```\n\n## Custom Format Verification\n\n#### Markup Schema Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, registerValidateFormats } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nregisterValidateFormats({\n  custom_format: /123/,\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"global_style_1\"\n        title=\"Global registration style\"\n        required\n        x-validator={{\n          format: 'custom_format',\n          message: 'error❎',\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"global_style_2\"\n        title=\"Global registration style\"\n        required\n        x-validator={'custom_format'}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"global_style_3\"\n        title=\"Global registration style\"\n        required\n        x-validator={['custom_format']}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"global_style_4\"\n        title=\"Global registration style\"\n        required\n        x-validator={{\n          format: 'custom_format',\n          message: 'error❎',\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.String\n        name=\"validator_style_1\"\n        title=\"Locally defined style\"\n        required\n        pattern={/123/}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"validator_style_2\"\n        title=\"Locally defined style\"\n        required\n        pattern=\"123\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"validator_style_3\"\n        title=\"Locally defined style\"\n        required\n        x-validator={{\n          pattern: /123/,\n          message: 'error❎',\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"validator_style_4\"\n        title=\"Locally defined style\"\n        required\n        x-validator={{\n          pattern: '123',\n          message: 'error❎',\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n  </Form>\n)\n```\n\n#### JSON Schema Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, registerValidateFormats } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nregisterValidateFormats({\n  custom_format: /123/,\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    global_style_1: {\n      title: 'Global registration style',\n      required: true,\n      'x-validator': {\n        format: 'custom_format',\n        message: 'error❎',\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    global_style_2: {\n      title: 'Global registration style',\n      required: true,\n      'x-validator': 'custom_format',\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    global_style_3: {\n      title: 'Global registration style',\n      required: true,\n      'x-validator': ['custom_format'],\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    global_style_4: {\n      title: 'Global registration style',\n      required: true,\n      'x-validator': {\n        format: 'custom_format',\n        message: 'error❎',\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    validator_style_1: {\n      title: 'Locally defined style',\n      required: true,\n      pattern: /123/,\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    validator_style_2: {\n      title: 'Locally defined style',\n      required: true,\n      pattern: '123',\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    validator_style_3: {\n      title: 'Locally defined style',\n      required: true,\n      'x-validator': {\n        pattern: /123/,\n        message: 'error❎',\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    validator_style_4: {\n      title: 'Locally defined style',\n      required: true,\n      'x-validator': {\n        pattern: '123',\n        message: 'error❎',\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n  },\n}\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField schema={schema} />\n  </Form>\n)\n```\n\n#### Pure JSX Cases\n\n```tsx\nimport React from 'react'\nimport { createForm, registerValidateFormats } from '@formily/core'\nimport { Field } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nregisterValidateFormats({\n  custom_format: /123/,\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <Field\n      name=\"global_style_1\"\n      title=\"Global registration style\"\n      required\n      validator={{\n        format: 'custom_format',\n        message: 'error❎',\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"global_style_2\"\n      title=\"Global registration style\"\n      required\n      validator={'custom_format'}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"global_style_3\"\n      title=\"Global registration style\"\n      required\n      validator={['custom_format']}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"global_style_4\"\n      title=\"Global registration style\"\n      required\n      validator={{\n        format: 'custom_format',\n        message: 'error❎',\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"validator_style_1\"\n      title=\"Locally defined style\"\n      required\n      validator={{\n        pattern: /123/,\n        message: 'error❎',\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"validator_style_2\"\n      title=\"Locally defined style\"\n      required\n      validator={{\n        pattern: '123',\n        message: 'error❎',\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n  </Form>\n)\n```\n\n## Asynchronous Verification\n\n#### Markup Schema Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"async_validate\"\n        title=\"Asynchronous verification\"\n        required\n        x-validator={(value) => {\n          return new Promise((resolve) => {\n            setTimeout(() => {\n              if (!value) {\n                resolve('')\n              }\n              if (value === '123') {\n                resolve('')\n              } else {\n                resolve('error❎')\n              }\n            }, 1000)\n          })\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"async_validate_2\"\n        title=\"Asynchronous verification (onBlur trigger)\"\n        required\n        x-validator={{\n          triggerType: 'onBlur',\n          validator: (value) => {\n            return new Promise((resolve) => {\n              setTimeout(() => {\n                if (!value) {\n                  resolve('')\n                }\n                if (value === '123') {\n                  resolve('')\n                } else {\n                  resolve('error❎')\n                }\n              }, 1000)\n            })\n          },\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n  </Form>\n)\n```\n\n#### JSON Schema Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    async_validate: {\n      title: 'Asynchronous verification',\n      required: true,\n      'x-validator': `{{(value) => {\n        return new Promise((resolve) => {\n          setTimeout(() => {\n            if (!value) {\n              resolve('')\n            }\n            if (value === '123') {\n              resolve('')\n            } else {\n              resolve('error❎')\n            }\n          }, 1000)\n        })\n      }}}`,\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    async_validate_2: {\n      title: 'Asynchronous verification (onBlur trigger)',\n      required: true,\n      'x-validator': {\n        triggerType: 'onBlur',\n        validator: `{{(value) => {\n        return new Promise((resolve) => {\n          setTimeout(() => {\n            if (!value) {\n              resolve('')\n            }\n            if (value === '123') {\n              resolve('')\n            } else {\n              resolve('错误❎')\n            }\n          }, 1000)\n        })\n      }}}`,\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n  },\n}\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField schema={schema} />\n  </Form>\n)\n```\n\n#### Pure JSX Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <Field\n      name=\"async_validate\"\n      title=\"Asynchronous verification\"\n      required\n      validator={(value) => {\n        return new Promise((resolve) => {\n          setTimeout(() => {\n            if (!value) {\n              resolve('')\n            }\n            if (value === '123') {\n              resolve('')\n            } else {\n              resolve('error❎')\n            }\n          }, 1000)\n        })\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"async_validate_2\"\n      title=\"Asynchronous verification (onBlur trigger)\"\n      required\n      validator={{\n        triggerType: 'onBlur',\n        validator: (value) => {\n          return new Promise((resolve) => {\n            setTimeout(() => {\n              if (!value) {\n                resolve('')\n              }\n              if (value === '123') {\n                resolve('')\n              } else {\n                resolve('error ❎')\n              }\n            }, 1000)\n          })\n        },\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n  </Form>\n)\n```\n\n## Linkage Verification\n\n#### Markup Schema Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    NumberPicker,\n    FormItem,\n  },\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"aa\"\n        title=\"AA\"\n        required\n        x-reactions={(field) => {\n          field.selfErrors =\n            field.query('bb').value() >= field.value\n              ? 'AA must be greater than BB'\n              : ''\n        }}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"bb\"\n        title=\"BB\"\n        required\n        x-reactions={(field) => {\n          field.selfErrors =\n            field.query('aa').value() <= field.value\n              ? 'AA must be greater than BB'\n              : ''\n        }}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n  </Form>\n)\n```\n\n#### JSON Schema Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    NumberPicker,\n    FormItem,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    aa: {\n      title: 'AA',\n      required: true,\n      'x-reactions': `{{(field) => {\n          field.selfErrors =\n            field.query('bb').value() >= field.value ? 'AA must be greater than BB' : ''\n      }}}`,\n      'x-component': 'NumberPicker',\n      'x-decorator': 'FormItem',\n    },\n    bb: {\n      title: 'BB',\n      required: true,\n      'x-reactions': {\n        dependencies: ['aa'],\n        fulfill: {\n          state: {\n            selfErrors:\n              \"{{$deps[0] <= $self.value ? 'AA must be greater than BB' : ''}}\",\n          },\n        },\n      },\n      'x-component': 'NumberPicker',\n      'x-decorator': 'FormItem',\n    },\n  },\n}\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField schema={schema} />\n  </Form>\n)\n```\n\n#### Pure JSX Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/react'\nimport { Form, FormItem, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <Field\n      name=\"aa\"\n      title=\"AA\"\n      required\n      reactions={(field) => {\n        field.selfErrors =\n          field.query('bb').value() >= field.value\n            ? 'AA must be greater than BB'\n            : ''\n      }}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"bb\"\n      title=\"BB\"\n      required\n      reactions={(field) => {\n        field.selfErrors =\n          field.query('aa').value() <= field.value\n            ? 'AA must be greater than BB'\n            : ''\n      }}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n  </Form>\n)\n```\n\n## Custom Verification Messages\n\nMainly through [registerValidateLocale](https://core.formilyjs.org/api/entry/form-validator-registry#registervalidatelocale) to customize the built-in verification messages\n\n```tsx\nimport React from 'react'\nimport {\n  createForm,\n  registerValidateLocale,\n  setValidateLanguage,\n} from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nsetValidateLanguage('en-US')\n\nregisterValidateLocale({\n  'en-US': {\n    required: 'Custom required verification message',\n  },\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"aa\"\n        title=\"AA\"\n        required\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n  </Form>\n)\n```\n"
  },
  {
    "path": "docs/guide/advanced/validate.zh-CN.md",
    "content": "# 表单校验\n\nFormily 的表单校验使用了极其强大且灵活的@formily/validator 校验引擎，校验主要分两种场景：\n\n- Markup(JSON) Schema 场景协议校验属性校验，使用 JSON Schema 本身的校验属性与 x-validator 属性实现校验\n- 纯 JSX 场景校验属性，使用 validator 属性实现校验\n\n同时我们还能在 effects 或者 x-reactions/reactions 中实现联动校验\n\n具体规则校验文档参考 [FieldValidator](https://core.formilyjs.org/zh-CN/api/models/field#fieldvalidator)\n\n表单校验是表单中优化用户体验和保证数据准确性的重要一环，Formily 提供了多种校验方式，包括内置规则校验、内置格式校验、自定义规则校验等，下面我们将逐一介绍这些校验方式。\n\n## 内置规则校验\n\n内置规则校验是指 Formily 提供的一些常用校验规则，比如必填、最大值、最小值、长度、枚举、常量、整除等，实现了最简单和最通用的校验，这些规则可以通过 JSON Schema 的属性描述，也可以通过 x-validator 属性描述。Formily 支持多种形式的内置规则书写方式，建议团队内部根据使用习惯制定团队规范。\n\n#### Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    NumberPicker,\n  },\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"required_1\"\n        title=\"必填\"\n        required\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"required_2\"\n        title=\"必填\"\n        x-validator={{ required: true }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"required_3\"\n        title=\"必填\"\n        x-validator={[{ required: true }]}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"max_1\"\n        title=\"最大值(>5报错)\"\n        maximum={5}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"max_2\"\n        title=\"最大值(>5报错)\"\n        x-validator={{ maximum: 5 }}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"max_3\"\n        title=\"最大值(>5报错)\"\n        x-validator={[{ maximum: 5 }]}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"max_4\"\n        title=\"最大值(>=5报错)\"\n        exclusiveMaximum={5}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"max_5\"\n        title=\"最大值(>=5报错)\"\n        x-validator={{ exclusiveMaximum: 5 }}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"max_6\"\n        title=\"最大值(>=5报错)\"\n        x-validator={[{ exclusiveMaximum: 5 }]}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.Number\n        name=\"min_1\"\n        title=\"最小值(<5报错)\"\n        minimum={5}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"min_2\"\n        title=\"最小值(<5报错)\"\n        x-validator={{ minimum: 5 }}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"min_3\"\n        title=\"最小值(<5报错)\"\n        x-validator={[{ minimum: 5 }]}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"min_4\"\n        title=\"最小值(<=5报错)\"\n        exclusiveMinimum={5}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"min_5\"\n        title=\"最小值(<=5报错)\"\n        x-validator={{ exclusiveMinimum: 5 }}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"min_6\"\n        title=\"最小值(<=5报错)\"\n        x-validator={[{ exclusiveMinimum: 5 }]}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.String\n        name=\"length_1\"\n        title=\"长度为5\"\n        x-validator={{ len: 5 }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"length_2\"\n        title=\"长度为5\"\n        x-validator={[{ len: 5 }]}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.String\n        name=\"maxlength_1\"\n        title=\"最大长度为5\"\n        maxLength={5}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"maxlength_2\"\n        title=\"最大长度为5\"\n        x-validator={{ max: 5 }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"maxlength_3\"\n        title=\"最大长度为5\"\n        x-validator={[{ max: 5 }]}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.String\n        name=\"maxlength_4\"\n        title=\"最小长度为5\"\n        minLength={5}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"maxlength_5\"\n        title=\"最小长度为5\"\n        x-validator={{ min: 5 }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"maxlength_6\"\n        title=\"最小长度为5\"\n        x-validator={[{ min: 5 }]}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.String\n        name=\"whitespace\"\n        title=\"排除纯空白字符\"\n        x-validator={[{ whitespace: true }]}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.String\n        name=\"enum\"\n        title=\"枚举匹配\"\n        x-validator={[{ enum: ['1', '2', '3'] }]}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.String\n        name=\"const\"\n        title=\"常量匹配\"\n        const=\"123\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.String\n        name=\"multipleOf\"\n        title=\"整除匹配\"\n        multipleOf={2}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n  </Form>\n)\n```\n\n#### JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    NumberPicker,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    required_1: {\n      name: 'required_1',\n      title: '必填',\n      type: 'string',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    required_2: {\n      name: 'required_2',\n      title: '必填',\n      type: 'string',\n      'x-validator': {\n        required: true,\n      },\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    required_3: {\n      name: 'required_3',\n      title: '必填',\n      type: 'string',\n      'x-validator': [\n        {\n          required: true,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    max_1: {\n      name: 'max_1',\n      title: '最大值(>5报错)',\n      type: 'number',\n      maximum: 5,\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    max_2: {\n      name: 'max_2',\n      title: '最大值(>5报错)',\n      type: 'number',\n      'x-validator': {\n        maximum: 5,\n      },\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    max_3: {\n      name: 'max_3',\n      title: '最大值(>5报错)',\n      type: 'number',\n      'x-validator': [\n        {\n          maximum: 5,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    max_4: {\n      name: 'max_4',\n      title: '最大值(>=5报错)',\n      type: 'number',\n      exclusiveMaximum: 5,\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    max_5: {\n      name: 'max_5',\n      title: '最大值(>=5报错)',\n      type: 'number',\n      'x-validator': {\n        exclusiveMaximum: 5,\n      },\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    max_6: {\n      name: 'max_6',\n      title: '最大值(>=5报错)',\n      type: 'number',\n      'x-validator': [\n        {\n          exclusiveMaximum: 5,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    min_1: {\n      name: 'min_1',\n      title: '最小值(<5报错)',\n      type: 'number',\n      minimum: 5,\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    min_2: {\n      name: 'min_2',\n      title: '最小值(<5报错)',\n      type: 'number',\n      'x-validator': {\n        minimum: 5,\n      },\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    min_3: {\n      name: 'min_3',\n      title: '最小值(<5报错)',\n      type: 'string',\n      'x-validator': [\n        {\n          minimum: 5,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    min_4: {\n      name: 'min_4',\n      title: '最小值(<=5报错)',\n      type: 'number',\n      exclusiveMinimum: 5,\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    min_5: {\n      name: 'min_5',\n      title: '最小值(<=5报错)',\n      type: 'number',\n      'x-validator': {\n        exclusiveMinimum: 5,\n      },\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    min_6: {\n      name: 'min_6',\n      title: '最小值(<=5报错)',\n      type: 'number',\n      'x-validator': [\n        {\n          exclusiveMinimum: 5,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n    length_1: {\n      name: 'length_1',\n      title: '长度为5',\n      type: 'string',\n      'x-validator': {\n        len: 5,\n      },\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    length_2: {\n      name: 'length_2',\n      title: '长度为5',\n      type: 'string',\n      'x-validator': [\n        {\n          len: 5,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    maxlength_1: {\n      name: 'maxlength_1',\n      title: '最大长度为5',\n      type: 'string',\n      maxLength: 5,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    maxlength_2: {\n      name: 'maxlength_2',\n      title: '最大长度为5',\n      type: 'string',\n      'x-validator': {\n        max: 5,\n      },\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    maxlength_3: {\n      name: 'maxlength_3',\n      title: '最大长度为5',\n      type: 'string',\n      'x-validator': [\n        {\n          max: 5,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    minlength_1: {\n      name: 'minlength_1',\n      title: '最小长度为5',\n      type: 'string',\n      minLength: 5,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    minlength_2: {\n      name: 'minlength_2',\n      title: '最小长度为5',\n      type: 'string',\n      'x-validator': {\n        min: 5,\n      },\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    minlength_3: {\n      name: 'minlength_3',\n      title: '最小长度为5',\n      type: 'string',\n      'x-validator': [\n        {\n          min: 5,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    whitespace: {\n      name: 'whitespace',\n      title: '排除纯空白字符',\n      type: 'string',\n      'x-validator': [\n        {\n          whitespace: true,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    enum: {\n      name: 'enum',\n      title: '枚举匹配',\n      type: 'string',\n      'x-validator': [\n        {\n          enum: ['1', '2', '3'],\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    const: {\n      name: 'const',\n      title: '常量匹配',\n      type: 'string',\n      const: '123',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    multipleOf: {\n      name: 'multipleOf',\n      title: '整除匹配',\n      type: 'string',\n      multipleOf: 2,\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n    },\n  },\n}\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField schema={schema} />\n  </Form>\n)\n```\n\n#### 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <Field\n      name=\"required_1\"\n      title=\"必填\"\n      required\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"required_2\"\n      title=\"必填\"\n      validator={{ required: true }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"required_3\"\n      title=\"必填\"\n      validator={[{ required: true }]}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"max_1\"\n      title=\"最大值(>5报错)\"\n      validator={{ maximum: 5 }}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"max_2\"\n      title=\"最大值(>5报错)\"\n      validator={[{ maximum: 5 }]}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"max_3\"\n      title=\"最大值(>=5报错)\"\n      validator={{ exclusiveMaximum: 5 }}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"max_4\"\n      title=\"最大值(>=5报错)\"\n      validator={[{ exclusiveMaximum: 5 }]}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"min_1\"\n      title=\"最小值(<5报错)\"\n      validator={{ minimum: 5 }}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"min_2\"\n      title=\"最小值(<5报错)\"\n      validator={[{ minimum: 5 }]}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"min_3\"\n      title=\"最小值(<=5报错)\"\n      validator={{ exclusiveMinimum: 5 }}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"min_4\"\n      title=\"最小值(<=5报错)\"\n      validator={[{ exclusiveMinimum: 5 }]}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n\n    <Field\n      name=\"length_1\"\n      title=\"长度为5\"\n      validator={{ len: 5 }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"length_2\"\n      title=\"长度为5\"\n      validator={[{ len: 5 }]}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"maxlength_1\"\n      title=\"最大长度为5\"\n      validator={{ max: 5 }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"maxlength_2\"\n      title=\"最大长度为5\"\n      validator={[{ max: 5 }]}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"minlength_1\"\n      title=\"最小长度为5\"\n      validator={{ min: 5 }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"minlength_2\"\n      title=\"最小长度为5\"\n      validator={[{ min: 5 }]}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n\n    <Field\n      name=\"whitespace\"\n      title=\"排除纯空白字符\"\n      validator={[{ whitespace: true }]}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n  </Form>\n)\n```\n\n## 内置格式校验\n\n#### Markup Schema 案例\n\n```tsx\nimport React, { Fragment } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst renderFormat = (format: string, key: number) => {\n  return (\n    <Fragment key={key}>\n      <SchemaField.String\n        name={`${format}_1`}\n        title={`${format}格式`}\n        format={format}\n        required\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name={`${format}_2`}\n        title={`${format}格式`}\n        required\n        x-validator={format}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name={`${format}_3`}\n        title={`${format}格式`}\n        required\n        x-validator={{ format }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name={`${format}_4`}\n        title={`${format}格式`}\n        required\n        x-validator={[format]}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name={`${format}_5`}\n        title={`${format}格式`}\n        required\n        x-validator={[{ format }]}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </Fragment>\n  )\n}\n\nconst FORMATS = [\n  'url',\n  'email',\n  'phone',\n  'ipv6',\n  'ipv4',\n  'number',\n  'integer',\n  'qq',\n  'idcard',\n  'money',\n  'zh',\n  'date',\n  'zip',\n]\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField>{FORMATS.map(renderFormat)}</SchemaField>\n  </Form>\n)\n```\n\n#### JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {},\n}\n\nconst FORMATS = [\n  'url',\n  'email',\n  'phone',\n  'ipv6',\n  'ipv4',\n  'number',\n  'integer',\n  'qq',\n  'idcard',\n  'money',\n  'zh',\n  'date',\n  'zip',\n]\n\nFORMATS.forEach((key) => {\n  Object.assign(schema.properties, {\n    [`${key}_1`]: {\n      title: `${key}格式`,\n      type: 'string',\n      required: true,\n      format: key,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    [`${key}_2`]: {\n      title: `${key}格式`,\n      type: 'string',\n      required: true,\n      'x-validator': key,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    [`${key}_3`]: {\n      title: `${key}格式`,\n      type: 'string',\n      required: true,\n      'x-validator': {\n        format: key,\n      },\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    [`${key}_4`]: {\n      title: `${key}格式`,\n      type: 'string',\n      required: true,\n      'x-validator': [key],\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n\n    [`${key}_5`]: {\n      title: `${key}格式`,\n      type: 'string',\n      required: true,\n      'x-validator': [\n        {\n          format: key,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n  })\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField schema={schema} />\n  </Form>\n)\n```\n\n#### 纯 JSX 案例\n\n```tsx\nimport React, { Fragment } from 'react'\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nconst renderFormat = (format: string, key: number) => {\n  return (\n    <Fragment key={key}>\n      <Field\n        name={`${format}_1`}\n        title={`${format}格式`}\n        required\n        validator={format}\n        component={[Input]}\n        decorator={[FormItem]}\n      />\n      <Field\n        name={`${format}_2`}\n        title={`${format}格式`}\n        required\n        validator={{ format }}\n        component={[Input]}\n        decorator={[FormItem]}\n      />\n      <Field\n        name={`${format}_3`}\n        title={`${format}格式`}\n        required\n        validator={[format]}\n        component={[Input]}\n        decorator={[FormItem]}\n      />\n      <Field\n        name={`${format}_4`}\n        title={`${format}格式`}\n        required\n        validator={[{ format }]}\n        component={[Input]}\n        decorator={[FormItem]}\n      />\n    </Fragment>\n  )\n}\n\nconst FORMATS = [\n  'url',\n  'email',\n  'phone',\n  'ipv6',\n  'ipv4',\n  'number',\n  'integer',\n  'qq',\n  'idcard',\n  'money',\n  'zh',\n  'date',\n  'zip',\n]\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    {FORMATS.map(renderFormat)}\n  </Form>\n)\n```\n\n## 自定义规则校验\n\n#### Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { createForm, registerValidateRules } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    NumberPicker,\n  },\n})\n\nregisterValidateRules({\n  global_1(value) {\n    if (!value) return ''\n    return value !== '123' ? '错误了❎' : ''\n  },\n  global_2(value, rule) {\n    if (!value) return ''\n    return value !== '123' ? rule.message : ''\n  },\n  global_3(value) {\n    if (!value) return ''\n    return value === '123'\n  },\n  global_4(value) {\n    if (!value) return ''\n    if (value < 10) {\n      return {\n        type: 'error',\n        message: '数值不能小于10',\n      }\n    } else if (value < 100) {\n      return {\n        type: 'warning',\n        message: '数值在100以内',\n      }\n    } else if (value < 1000) {\n      return {\n        type: 'success',\n        message: '数值大于100小于1000',\n      }\n    }\n  },\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"global_style_1\"\n        title=\"全局注册风格\"\n        required\n        x-validator={{\n          global_1: true,\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"global_style_2\"\n        title=\"全局注册风格\"\n        required\n        x-validator={{\n          global_2: true,\n          message: '错误了❎',\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"global_style_3\"\n        title=\"全局注册风格\"\n        required\n        x-validator={{\n          global_3: true,\n          message: '错误了❎',\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"global_style_4\"\n        title=\"全局注册风格\"\n        required\n        x-validator={{\n          global_4: true,\n        }}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.String\n        name=\"validator_style_1\"\n        title=\"局部定义风格\"\n        required\n        x-validator={(value) => {\n          if (!value) return ''\n          return value !== '123' ? '错误了❎' : ''\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"validator_style_2\"\n        title=\"局部定义风格\"\n        required\n        x-validator={{\n          validator(value, rule) {\n            if (!value) return ''\n            return value !== '123' ? rule.message : ''\n          },\n          message: '错误了❎',\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"validator_style_3\"\n        title=\"局部定义风格\"\n        required\n        x-validator={{\n          validator(value) {\n            if (!value) return ''\n            return value === '123'\n          },\n          message: '错误了❎',\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"validator_style_4\"\n        title=\"局部定义风格\"\n        required\n        x-validator={(value) => {\n          if (!value) return ''\n          if (value < 10) {\n            return {\n              type: 'error',\n              message: '数值不能小于10',\n            }\n          } else if (value < 100) {\n            return {\n              type: 'warning',\n              message: '数值在100以内',\n            }\n          } else if (value < 1000) {\n            return {\n              type: 'success',\n              message: '数值大于100小于1000',\n            }\n          }\n        }}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n  </Form>\n)\n```\n\n#### JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { createForm, registerValidateRules } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    NumberPicker,\n  },\n})\n\nregisterValidateRules({\n  global_1(value) {\n    if (!value) return ''\n    return value !== '123' ? '错误了❎' : ''\n  },\n  global_2(value, rule) {\n    if (!value) return ''\n    return value !== '123' ? rule.message : ''\n  },\n  global_3(value) {\n    if (!value) return ''\n    return value === '123'\n  },\n  global_4(value) {\n    if (!value) return ''\n    if (value < 10) {\n      return {\n        type: 'error',\n        message: '数值不能小于10',\n      }\n    } else if (value < 100) {\n      return {\n        type: 'warning',\n        message: '数值在100以内',\n      }\n    } else if (value < 1000) {\n      return {\n        type: 'success',\n        message: '数值大于100小于1000',\n      }\n    }\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    global_style_1: {\n      title: '全局注册风格',\n      required: true,\n      'x-validator': {\n        global_1: true,\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    global_style_2: {\n      title: '全局注册风格',\n      required: true,\n      'x-validator': {\n        global_2: true,\n        message: '错误了❎',\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    global_style_3: {\n      title: '全局注册风格',\n      required: true,\n      'x-validator': {\n        global_3: true,\n        message: '错误了❎',\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    global_style_4: {\n      title: '全局注册风格',\n      required: true,\n      'x-validator': {\n        global_4: true,\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n\n    validator_style_1: {\n      title: '局部定义风格',\n      required: true,\n      'x-validator': `{{(value)=> {\n            if (!value) return ''\n            return value !== '123' ? '错误了❎' : ''\n          }}}`,\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    validator_style_2: {\n      title: '局部定义风格',\n      required: true,\n      'x-validator': {\n        validator: `{{(value, rule)=> {\n            if (!value) return ''\n            return value !== '123' ? rule.message : ''\n          }}}`,\n        message: '错误了❎',\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    validator_style_3: {\n      title: '局部定义风格',\n      required: true,\n      'x-validator': {\n        validator: `{{(value, rule)=> {\n          if (!value) return ''\n          return value === '123'\n        }}}`,\n        message: '错误了❎',\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    validator_style_4: {\n      title: '局部定义风格',\n      required: true,\n      'x-validator': `{{(value, rule)=> {\n          if (!value) return ''\n          if (value < 10) {\n            return {\n              type: 'error',\n              message: '数值不能小于10',\n            }\n          } else if (value < 100) {\n            return {\n              type: 'warning',\n              message: '数值在100以内',\n            }\n          } else if (value < 1000) {\n            return {\n              type: 'success',\n              message: '数值大于100小于1000',\n            }\n          }\n        }}}`,\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n  },\n}\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField schema={schema} />\n  </Form>\n)\n```\n\n#### 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { createForm, registerValidateRules } from '@formily/core'\nimport { Field } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nregisterValidateRules({\n  global_1(value) {\n    if (!value) return ''\n    return value !== '123' ? '错误了❎' : ''\n  },\n  global_2(value, rule) {\n    if (!value) return ''\n    return value !== '123' ? rule.message : ''\n  },\n  global_3(value) {\n    if (!value) return ''\n    return value === '123'\n  },\n  global_4(value) {\n    if (!value) return ''\n    if (value < 10) {\n      return {\n        type: 'error',\n        message: '数值不能小于10',\n      }\n    } else if (value < 100) {\n      return {\n        type: 'warning',\n        message: '数值在100以内',\n      }\n    } else if (value < 1000) {\n      return {\n        type: 'success',\n        message: '数值大于100小于1000',\n      }\n    }\n  },\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <Field\n      name=\"global_style_1\"\n      title=\"全局注册风格\"\n      required\n      validator={{\n        global_1: true,\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"global_style_2\"\n      title=\"全局注册风格\"\n      required\n      validator={{\n        global_2: true,\n        message: '错误了❎',\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"global_style_3\"\n      title=\"全局注册风格\"\n      required\n      validator={{\n        global_3: true,\n        message: '错误了❎',\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"global_style_4\"\n      title=\"全局注册风格\"\n      required\n      validator={{\n        global_4: true,\n      }}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n\n    <Field\n      name=\"validator_style_1\"\n      title=\"局部定义风格\"\n      required\n      validator={(value) => {\n        if (!value) return ''\n        return value !== '123' ? '错误了❎' : ''\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"validator_style_2\"\n      title=\"局部定义风格\"\n      required\n      validator={{\n        validator(value, rule) {\n          if (!value) return ''\n          return value !== '123' ? rule.message : ''\n        },\n        message: '错误了❎',\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"validator_style_3\"\n      title=\"局部定义风格\"\n      required\n      validator={{\n        validator(value) {\n          if (!value) return ''\n          return value === '123'\n        },\n        message: '错误了❎',\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"validator_style_4\"\n      title=\"局部定义风格\"\n      required\n      validator={(value) => {\n        if (!value) return ''\n        if (value < 10) {\n          return {\n            type: 'error',\n            message: '数值不能小于10',\n          }\n        } else if (value < 100) {\n          return {\n            type: 'warning',\n            message: '数值在100以内',\n          }\n        } else if (value < 1000) {\n          return {\n            type: 'success',\n            message: '数值大于100小于1000',\n          }\n        }\n      }}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n  </Form>\n)\n```\n\n## 使用第三方校验库\n\n凭借 Formily 极为强大的校验引擎，能够极为便捷地适配诸如 yup 等第三方校验库。其使用示例如下：\n\n#### JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { createForm, registerValidateRules } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\nimport { string } from 'yup'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    NumberPicker,\n  },\n})\n\nregisterValidateRules({\n  yup: async (value, rule) => {\n    try {\n      await rule.yup().validate(value)\n      return '' // 验证成功时返回空字符串\n    } catch (err) {\n      return err.errors.join(',') // 验证失败时返回错误信息\n    }\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    global_style_1: {\n      title: '最大长度为 2',\n      'x-validator': [\n        {\n          triggerType: 'onBlur',\n          yup: () => string().required('必填'),\n        },\n        {\n          triggerType: 'onBlur',\n          yup: () => string().max(2, '最大长度为 2'),\n        },\n      ],\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    global_style_2: {\n      title: 'email',\n      required: true,\n      'x-validator': {\n        triggerType: 'onBlur',\n        yup: () => string().email(),\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n  },\n}\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField schema={schema} />\n  </Form>\n)\n```\n\n#### 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { createForm, registerValidateRules } from '@formily/core'\nimport { Field } from '@formily/react'\nimport { Form, FormItem, Input, NumberPicker } from '@formily/antd'\nimport { string, number } from 'yup'\n\nconst form = createForm()\n\nregisterValidateRules({\n  yup: async (value, rule) => {\n    try {\n      await rule.yup().validate(value)\n      return '' // 验证成功时返回空字符串\n    } catch (err) {\n      return err.errors.join(',') // 验证失败时返回错误信息\n    }\n  },\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <Field\n      name=\"global_style_1\"\n      title=\"email\"\n      required\n      validator={{\n        yup: () => string().email(),\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"global_style_2\"\n      title=\"最大值 30\"\n      required\n      validator={{\n        yup: () => number().max(30),\n      }}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"global_style_3\"\n      title=\"email\"\n      required\n      validator={{\n        yup: () => string().email(),\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n  </Form>\n)\n```\n\n## 自定义格式校验\n\n#### Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { createForm, registerValidateFormats } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nregisterValidateFormats({\n  custom_format: /123/,\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"global_style_1\"\n        title=\"全局注册风格\"\n        required\n        x-validator={{\n          format: 'custom_format',\n          message: '错误❎',\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"global_style_2\"\n        title=\"全局注册风格\"\n        required\n        x-validator={'custom_format'}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"global_style_3\"\n        title=\"全局注册风格\"\n        required\n        x-validator={['custom_format']}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.Number\n        name=\"global_style_4\"\n        title=\"全局注册风格\"\n        required\n        x-validator={{\n          format: 'custom_format',\n          message: '错误❎',\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n\n      <SchemaField.String\n        name=\"validator_style_1\"\n        title=\"局部定义风格\"\n        required\n        pattern={/123/}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"validator_style_2\"\n        title=\"局部定义风格\"\n        required\n        pattern=\"123\"\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"validator_style_3\"\n        title=\"局部定义风格\"\n        required\n        x-validator={{\n          pattern: /123/,\n          message: '错误了❎',\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"validator_style_4\"\n        title=\"局部定义风格\"\n        required\n        x-validator={{\n          pattern: '123',\n          message: '错误了❎',\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n  </Form>\n)\n```\n\n#### JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { createForm, registerValidateFormats } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nregisterValidateFormats({\n  custom_format: /123/,\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    global_style_1: {\n      title: '全局注册风格',\n      required: true,\n      'x-validator': {\n        format: 'custom_format',\n        message: '错误❎',\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    global_style_2: {\n      title: '全局注册风格',\n      required: true,\n      'x-validator': 'custom_format',\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    global_style_3: {\n      title: '全局注册风格',\n      required: true,\n      'x-validator': ['custom_format'],\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    global_style_4: {\n      title: '全局注册风格',\n      required: true,\n      'x-validator': {\n        format: 'custom_format',\n        message: '错误❎',\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    validator_style_1: {\n      title: '局部定义风格',\n      required: true,\n      pattern: /123/,\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    validator_style_2: {\n      title: '局部定义风格',\n      required: true,\n      pattern: '123',\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    validator_style_3: {\n      title: '局部定义风格',\n      required: true,\n      'x-validator': {\n        pattern: /123/,\n        message: '错误了❎',\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    validator_style_4: {\n      title: '局部定义风格',\n      required: true,\n      'x-validator': {\n        pattern: '123',\n        message: '错误了❎',\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n  },\n}\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField schema={schema} />\n  </Form>\n)\n```\n\n#### 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { createForm, registerValidateFormats } from '@formily/core'\nimport { Field } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nregisterValidateFormats({\n  custom_format: /123/,\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <Field\n      name=\"global_style_1\"\n      title=\"全局注册风格\"\n      required\n      validator={{\n        format: 'custom_format',\n        message: '错误❎',\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"global_style_2\"\n      title=\"全局注册风格\"\n      required\n      validator={'custom_format'}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"global_style_3\"\n      title=\"全局注册风格\"\n      required\n      validator={['custom_format']}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"global_style_4\"\n      title=\"全局注册风格\"\n      required\n      validator={{\n        format: 'custom_format',\n        message: '错误❎',\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"validator_style_1\"\n      title=\"局部定义风格\"\n      required\n      validator={{\n        pattern: /123/,\n        message: '错误了❎',\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"validator_style_2\"\n      title=\"局部定义风格\"\n      required\n      validator={{\n        pattern: '123',\n        message: '错误了❎',\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n  </Form>\n)\n```\n\n## 异步校验\n\n#### Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"async_validate\"\n        title=\"异步校验\"\n        required\n        x-validator={(value) => {\n          return new Promise((resolve) => {\n            setTimeout(() => {\n              if (!value) {\n                resolve('')\n              }\n              if (value === '123') {\n                resolve('')\n              } else {\n                resolve('错误❎')\n              }\n            }, 1000)\n          })\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"async_validate_2\"\n        title=\"异步校验(onBlur触发)\"\n        required\n        x-validator={{\n          triggerType: 'onBlur',\n          validator: (value) => {\n            return new Promise((resolve) => {\n              setTimeout(() => {\n                if (!value) {\n                  resolve('')\n                }\n                if (value === '123') {\n                  resolve('')\n                } else {\n                  resolve('错误❎')\n                }\n              }, 1000)\n            })\n          },\n        }}\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n  </Form>\n)\n```\n\n#### JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    async_validate: {\n      title: '异步校验',\n      required: true,\n      'x-validator': `{{(value) => {\n        return new Promise((resolve) => {\n          setTimeout(() => {\n            if (!value) {\n              resolve('')\n            }\n            if (value === '123') {\n              resolve('')\n            } else {\n              resolve('错误❎')\n            }\n          }, 1000)\n        })\n      }}}`,\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n    async_validate_2: {\n      title: '异步校验(onBlur触发)',\n      required: true,\n      'x-validator': {\n        triggerType: 'onBlur',\n        validator: `{{(value) => {\n        return new Promise((resolve) => {\n          setTimeout(() => {\n            if (!value) {\n              resolve('')\n            }\n            if (value === '123') {\n              resolve('')\n            } else {\n              resolve('错误❎')\n            }\n          }, 1000)\n        })\n      }}}`,\n      },\n      'x-component': 'Input',\n      'x-decorator': 'FormItem',\n    },\n  },\n}\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField schema={schema} />\n  </Form>\n)\n```\n\n#### 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <Field\n      name=\"async_validate\"\n      title=\"异步校验\"\n      required\n      validator={(value) => {\n        return new Promise((resolve) => {\n          setTimeout(() => {\n            if (!value) {\n              resolve('')\n            }\n            if (value === '123') {\n              resolve('')\n            } else {\n              resolve('错误❎')\n            }\n          }, 1000)\n        })\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"async_validate_2\"\n      title=\"异步校验(onBlur触发)\"\n      required\n      validator={{\n        triggerType: 'onBlur',\n        validator: (value) => {\n          return new Promise((resolve) => {\n            setTimeout(() => {\n              if (!value) {\n                resolve('')\n              }\n              if (value === '123') {\n                resolve('')\n              } else {\n                resolve('错误❎')\n              }\n            }, 1000)\n          })\n        },\n      }}\n      component={[Input]}\n      decorator={[FormItem]}\n    />\n  </Form>\n)\n```\n\n## 联动校验\n\n#### Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    NumberPicker,\n    FormItem,\n  },\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"aa\"\n        title=\"AA\"\n        required\n        x-reactions={(field) => {\n          field.selfErrors =\n            field.query('bb').value() >= field.value ? 'AA必须大于BB' : ''\n        }}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n      <SchemaField.String\n        name=\"bb\"\n        title=\"BB\"\n        required\n        x-reactions={(field) => {\n          field.selfErrors =\n            field.query('aa').value() <= field.value ? 'AA必须大于BB' : ''\n        }}\n        x-component=\"NumberPicker\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n  </Form>\n)\n```\n\n#### JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    NumberPicker,\n    FormItem,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    aa: {\n      title: 'AA',\n      required: true,\n      'x-reactions': `{{(field) => {\n          field.selfErrors =\n            field.query('bb').value() >= field.value ? 'AA必须大于BB' : ''\n      }}}`,\n      'x-component': 'NumberPicker',\n      'x-decorator': 'FormItem',\n    },\n    bb: {\n      title: 'BB',\n      required: true,\n      'x-reactions': {\n        dependencies: ['aa'],\n        fulfill: {\n          state: {\n            selfErrors: \"{{$deps[0] <= $self.value ? 'AA必须大于BB' : ''}}\",\n          },\n        },\n      },\n      'x-component': 'NumberPicker',\n      'x-decorator': 'FormItem',\n    },\n  },\n}\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField schema={schema} />\n  </Form>\n)\n```\n\n#### 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/react'\nimport { Form, FormItem, NumberPicker } from '@formily/antd'\n\nconst form = createForm()\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <Field\n      name=\"aa\"\n      title=\"AA\"\n      required\n      reactions={(field) => {\n        field.selfErrors =\n          field.query('bb').value() >= field.value ? 'AA必须大于BB' : ''\n      }}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n    <Field\n      name=\"bb\"\n      title=\"BB\"\n      required\n      reactions={(field) => {\n        field.selfErrors =\n          field.query('aa').value() <= field.value ? 'AA必须大于BB' : ''\n      }}\n      component={[NumberPicker]}\n      decorator={[FormItem]}\n    />\n  </Form>\n)\n```\n\n## 定制校验文案\n\n主要通过[registerValidateLocale](https://core.formilyjs.org/zh-CN/api/entry/form-validator-registry#registervalidatelocale)来定制内置校验文案\n\n```tsx\nimport React from 'react'\nimport {\n  createForm,\n  registerValidateLocale,\n  setValidateLanguage,\n} from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input } from '@formily/antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nsetValidateLanguage('zh-CN')\n\nregisterValidateLocale({\n  'zh-CN': {\n    required: '定制的必填校验文案',\n  },\n})\n\nexport default () => (\n  <Form form={form} labelCol={6} wrapperCol={10}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"aa\"\n        title=\"AA\"\n        required\n        x-component=\"Input\"\n        x-decorator=\"FormItem\"\n      />\n    </SchemaField>\n  </Form>\n)\n```\n"
  },
  {
    "path": "docs/guide/contribution.md",
    "content": "# Contribution Guide\n\n## Why become a contributor?\n\nWelcome to our community!**Formily** It is the only official open-source form framework announced by Alibaba. Its functions and quality are guaranteed. It has a large number of community users. Participating in contributions can make **Formily** stronger and allow more developers to enjoy a better experience of developing forms. we are very grateful to any people who initiated **Pull Request** for this project.\n\n## What can I contribute?\n\n- Add&Update features\n- Add/Update unit test cases\n- Fix the existing issue\n- Documentation improvements\n- Other\n\n## How to contribute?\n\n#### Pull Repository\n\n- Original repository: https://github.com/alibaba/formily\n- Target repository: fork to your own github ![img](https://img.alicdn.com/tfs/TB1NLrjxXY7gK0jSZKzXXaikpXa-2206-490.png)\n\n#### Pull Branch\n\nThe original branch is alibaba/formily master, The branch after pulling should be quirkyshop/formily master\n\n> Note: The recommended branch name is [feat]-[name], [feat] is the type of this branch. Featdoc[other] is optional, and [name] is the name, just customize it. eg. unittest-core (meaning: add single test to the core)\n\n#### Submit Code\n\nThe code style follows 2 spaces and no semicolons. Please do not include any console-related methods and debuggers in the code unless it is explained. After the development is completed, submit a pull request to the repository you forked.![img](https://img.alicdn.com/tfs/TB1HSvqxkT2gK0jSZFkXXcIQFXa-2050-898.png)![img](https://img.alicdn.com/tfs/TB1O.6mxbr1gK0jSZR0XXbP8XXa-1696-254.png)\n\n> Note the target repository on the left here(base repository is alibaba/formily master) . And then the doc-wiki of the current branch own repository on the right.\n\n#### PR Specification\n\nReference documents: https://github.com/alibaba/formily/blob/master/.github/GIT_COMMIT_SPECIFIC.md\n\n- PR name: format: `<type>(<scope>): <subject>` For example: `feat(core): add unit test`\n- PR content: List the content of this change\n- PR requirements: the added feat content, as far as possible, make clear comments. And the corresponding single test coverage should be covered as much 关注梁帅抽大奖 possible.\n- BUGFIX requirements: If the modified issue is related to issues, please include the relevant issueID in the content.\n\n#### Review&Merge\n\nThe review phase will enter a multi-review process,`@janryWang` is responsible for reviewing whether this change is merged, and other people will also participate in the discussion. The discussion will be stored in the PR of github, and the DingTalk group will also receive corresponding notifications.\n\nWhen you see that the status in the Pull requests list changes to Closed, the merge is successful. ![img](https://img.alicdn.com/tfs/TB1HUnjxXY7gK0jSZKzXXaikpXa-964-104.png)\n\n#### Synchronize source repository changes to repository after fork\n\n```\n# First, add \"upstream\" to your branch, that is, the source repository\n$ git remote add upstream https://github.com/alibaba/formily.git\n# Get the latest changes to the source repository\n$ git fetch upstream\n# Synchronize the changes of the source repository to the local branch\n$ git pull upstream master [The current local target branch, if not filled in, the current branch will be]\n```\n\n#### Project Development\n\n```bash\n$ cd formily\n$ yarn install # Install overall project dependencies\n$ yarn build # Build all projects\n$ yarn test # Perform unit tests\n```\n\n#### Development Document\n\nMain project document\n\n```bash\n$ yarn start\n```\n\nCore project documentation\n\n```bash\n$ yarn workspace @formily/core start\n```\n\nReact project documentation\n\n```bash\n$ yarn workspace @formily/react start\n```\n\nVue project documentation\n\n```bash\n$ yarn workspace @formily/vue start\n```\n\nAntd project documentation\n\n```bash\n$ yarn workspace @formily/antd start\n```\n\nFusion project documentation\n\n```bash\n$ yarn workspace @formily/next start\n```\n\nReactive project documentation\n\n```bash\n$ yarn workspace @formily/reactive start\n```\n"
  },
  {
    "path": "docs/guide/contribution.zh-CN.md",
    "content": "# 贡献指南\n\n## 为什么要成为贡献者？\n\n欢迎您来到我们的社区！**Formily** 是阿里巴巴唯一官方向外公布的开源表单框架，功能和质量都有一定保证，拥有众多的社区使用者，参与贡献可以使 **Formily** 变得强大，也会让更多开发者能够享受到更好的开发表单的体验，我们非常感谢任何对本项目发起 **Pull Request** 的同学。\n\n## 我可以贡献什么？\n\n- features 新增/修改功能特性\n- unitest 新增/修改单测\n- bugfix 修复现有 issue 的问题\n- doc 文档改进\n- other 其他\n\n## 如何贡献？\n\n#### 拉取仓库\n\n- 原始仓库：https://github.com/alibaba/formily\n- 目标仓库：fork 到自己的 github 上 ![img](https://img.alicdn.com/tfs/TB1NLrjxXY7gK0jSZKzXXaikpXa-2206-490.png)\n\n#### 拉取分支\n\n原始分支是 alibaba/formily master，拉取后的分支应该是 quirkyshop/formily master\n\n> 注意：建议分支名为[feat]-[name]，[feat]是这个分支的类型，可选的有[feat][unitest][docs][bugfix][other]，[name]则是名字，自定义就好了。eg. unittest-core(意为：对核心补充单测)\n\n#### 提交代码\n\n代码风格遵循 2 空格，无分号，非说明请不要在代码中附带任何 console 相关的方法及 debugger。 开发完成后，到自己 fork 出来的仓库提交 pull request ![img](https://img.alicdn.com/tfs/TB1HSvqxkT2gK0jSZFkXXcIQFXa-2050-898.png)![img](https://img.alicdn.com/tfs/TB1O.6mxbr1gK0jSZR0XXbP8XXa-1696-254.png)\n\n> 注意这里的左边目标仓库(base repository 是 alibaba/formily master) ，然后右边当前分支自己仓库的 doc-wiki\n\n#### PR 规范\n\n参考文档：https://github.com/alibaba/formily/blob/master/.github/GIT_COMMIT_SPECIFIC.md\n\n- PR 名称：格式：`<type>(<scope>): <subject>` 举例：`feat(core): add unit test`\n- PR 内容：列举本次改动的内容\n- PR 要求：增加的 feat 内容，尽量做到注释清晰，相应的单测覆盖要尽可能覆盖\n- BUGFIX 要求：如果修改的问题和 issues 相关，请在内容中附上相关的 issueID。\n\n#### 审核与合并\n\n审核阶段会进入多 review 的流程，`@janryWang` 负责审核这个改动是否合并，其他同学也会参与讨论，讨论的经过都会留存在 github 的 PR 里，钉钉群也会收到相应的通知。\n\n当看到 Pull requests 列表中的状态变为 Closed 即为合并成功。 ![img](https://img.alicdn.com/tfs/TB1HUnjxXY7gK0jSZKzXXaikpXa-964-104.png)\n\n#### 同步源仓库变更到 fork 后的仓库\n\n```\n# 首先在自己的分支增加一个 upstream，即原仓库\n$ git remote add upstream https://github.com/alibaba/formily.git\n# 获取原仓库最新的变更\n$ git fetch upstream\n# 同步原仓库的改动到本地分支\n$ git pull upstream master [当前本地目标分支，不填默认就是当前分支]\n```\n\n#### 项目开发\n\n```bash\n$ cd formily\n$ yarn install # 安装整体项目依赖\n$ yarn build # 构建所有项目\n$ yarn test # 执行单元测试\n```\n\n#### 开发文档\n\n主项目文档\n\n```bash\n$ yarn start\n```\n\n内核项目文档\n\n```bash\n$ yarn workspace @formily/core start\n```\n\nReact 项目文档\n\n```bash\n$ yarn workspace @formily/react start\n```\n\nVue 项目文档\n\n```bash\n$ yarn workspace @formily/vue start\n```\n\nAntd 项目文档\n\n```bash\n$ yarn workspace @formily/antd start\n```\n\nFusion 项目文档\n\n```bash\n$ yarn workspace @formily/next start\n```\n\nReactive 项目文档\n\n```bash\n$ yarn workspace @formily/reactive start\n```\n"
  },
  {
    "path": "docs/guide/form-builder.md",
    "content": "# Form designer development guide\n\n## Introduction\n\n![](http://img.alicdn.com/imgextra/i2/O1CN01eI9FLz22tZek2jv7E_!!6000000007178-2-tps-3683-2272.png)\n\nFormily Form Designer is an extension package based on [designable](https://github.com/alibaba/designable). It inherits the basic capabilities of designable, and provides Formily basic form building and configuration capabilities.\n\n## Core Concept\n\nThe core concept of Designable is to turn the designer into a modular combination, everything can be replaced, Designable itself provides a series of out-of-the-box components for users to use, but if users are not satisfied with the components, they can directly replace the components. To achieve maximum flexible customization, that is, Designable itself does not provide any plug-in related APIs\n\n## Install\n\nAnt Design users\n\n```bash\nnpm install --save @designable/formily-antd\n```\n\nAlibaba Fusion users\n\n```bash\nnpm install --save @designable/formily-next\n```\n\n## Get started quickly\n\n[Example Source Code](https://github.com/alibaba/designable/tree/main/formily/antd/playground)\n\n```tsx pure\nimport 'antd/dist/antd.less'\nimport React, { useMemo } from 'react'\nimport ReactDOM from 'react-dom'\nimport {\n  Designer, //Designer root component, mainly used to deliver context\n  DesignerToolsWidget, //Drawing board tool pendant\n  ViewToolsWidget, //View switching tool pendant\n  Workspace, //Workspace components, core components, used to manage drag and drop behavior in the workspace, tree node data, etc...\n  OutlineTreeWidget, //Outline tree component, it will automatically identify the current workspace and display the tree nodes in the workspace\n  ResourceWidget, //Drag and drop the source widget\n  HistoryWidget, //History widget\n  StudioPanel, //Main layout panel\n  CompositePanel, //Left combined layout panel\n  WorkspacePanel, //Workspace layout panel\n  ToolbarPanel, //Toolbar layout panel\n  ViewportPanel, //Viewport layout panel\n  ViewPanel, //View layout panel\n  SettingsPanel, //Configure the form layout panel on the right\n  ComponentTreeWidget, //Component tree renderer\n} from '@designable/react'\nimport { SettingsForm } from '@designable/react-settings-form'\nimport {\n  createDesigner,\n  GlobalRegistry,\n  Shortcut,\n  KeyCode,\n} from '@designable/core'\nimport {\n  LogoWidget,\n  ActionsWidget,\n  PreviewWidget,\n  SchemaEditorWidget,\n  MarkupSchemaWidget,\n} from './widgets'\nimport { saveSchema } from './service'\nimport {\n  Form,\n  Field,\n  Input,\n  Select,\n  TreeSelect,\n  Cascader,\n  Radio,\n  Checkbox,\n  Slider,\n  Rate,\n  NumberPicker,\n  Transfer,\n  Password,\n  DatePicker,\n  TimePicker,\n  Upload,\n  Switch,\n  Text,\n  Card,\n  ArrayCards,\n  ObjectContainer,\n  ArrayTable,\n  Space,\n  FormTab,\n  FormCollapse,\n  FormLayout,\n  FormGrid,\n} from '../src'\n\nGlobalRegistry.registerDesignerLocales({\n  'zh-CN': {\n    sources: {\n      Inputs: 'Input controls',\n      Layouts: 'Layout components',\n      Arrays: 'Self-incrementing components',\n      Displays: 'Display components',\n    },\n  },\n  'en-US': {\n    sources: {\n      Inputs: 'Inputs',\n      Layouts: 'Layouts',\n      Arrays: 'Arrays',\n      Displays: 'Displays',\n    },\n  },\n})\n\nconst App = () => {\n  const engine = useMemo(\n    () =>\n      createDesigner({\n        shortcuts: [\n          new Shortcut({\n            codes: [\n              [KeyCode.Meta, KeyCode.S],\n              [KeyCode.Control, KeyCode.S],\n            ],\n            handler(ctx) {\n              saveSchema(ctx.engine)\n            },\n          }),\n        ],\n        rootComponentName: 'Form',\n      }),\n    []\n  )\n  return (\n    <Designer engine={engine}>\n      <StudioPanel logo={<LogoWidget />} actions={<ActionsWidget />}>\n        <CompositePanel>\n          <CompositePanel.Item title=\"panels.Component\" icon=\"Component\">\n            <ResourceWidget\n              title=\"sources.Inputs\"\n              sources={[\n                Input,\n                Password,\n                NumberPicker,\n                Rate,\n                Slider,\n                Select,\n                TreeSelect,\n                Cascader,\n                Transfer,\n                Checkbox,\n                Radio,\n                DatePicker,\n                TimePicker,\n                Upload,\n                Switch,\n                ObjectContainer,\n              ]}\n            />\n            <ResourceWidget\n              title=\"sources.Layouts\"\n              sources={[\n                Card,\n                FormGrid,\n                FormTab,\n                FormLayout,\n                FormCollapse,\n                Space,\n              ]}\n            />\n            <ResourceWidget\n              title=\"sources.Arrays\"\n              sources={[ArrayCards, ArrayTable]}\n            />\n            <ResourceWidget title=\"sources.Displays\" sources={[Text]} />\n          </CompositePanel.Item>\n          <CompositePanel.Item title=\"panels.OutlinedTree\" icon=\"Outline\">\n            <OutlineTreeWidget />\n          </CompositePanel.Item>\n          <CompositePanel.Item title=\"panels.History\" icon=\"History\">\n            <HistoryWidget />\n          </CompositePanel.Item>\n        </CompositePanel>\n        <Workspace id=\"form\">\n          <WorkspacePanel>\n            <ToolbarPanel>\n              <DesignerToolsWidget />\n              <ViewToolsWidget\n                use={['DESIGNABLE', 'JSONTREE', 'MARKUP', 'PREVIEW']}\n              />\n            </ToolbarPanel>\n            <ViewportPanel>\n              <ViewPanel type=\"DESIGNABLE\">\n                {() => (\n                  <ComponentTreeWidget\n                    components={{\n                      Form,\n                      Field,\n                      Input,\n                      Select,\n                      TreeSelect,\n                      Cascader,\n                      Radio,\n                      Checkbox,\n                      Slider,\n                      Rate,\n                      NumberPicker,\n                      Transfer,\n                      Password,\n                      DatePicker,\n                      TimePicker,\n                      Upload,\n                      Switch,\n                      Text,\n                      Card,\n                      ArrayCards,\n                      ArrayTable,\n                      Space,\n                      FormTab,\n                      FormCollapse,\n                      FormGrid,\n                      FormLayout,\n                      ObjectContainer,\n                    }}\n                  />\n                )}\n              </ViewPanel>\n              <ViewPanel type=\"JSONTREE\" scrollable={false}>\n                {(tree, onChange) => (\n                  <SchemaEditorWidget tree={tree} onChange={onChange} />\n                )}\n              </ViewPanel>\n              <ViewPanel type=\"MARKUP\" scrollable={false}>\n                {(tree) => <MarkupSchemaWidget tree={tree} />}\n              </ViewPanel>\n              <ViewPanel type=\"PREVIEW\">\n                {(tree) => <PreviewWidget tree={tree} />}\n              </ViewPanel>\n            </ViewportPanel>\n          </WorkspacePanel>\n        </Workspace>\n        <SettingsPanel title=\"panels.PropertySettings\">\n          <SettingsForm uploadAction=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\" />\n        </SettingsPanel>\n      </StudioPanel>\n    </Designer>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById('root'))\n```\n"
  },
  {
    "path": "docs/guide/form-builder.zh-CN.md",
    "content": "# 表单设计器开发指南\n\n## 介绍\n\n![](http://img.alicdn.com/imgextra/i2/O1CN01eI9FLz22tZek2jv7E_!!6000000007178-2-tps-3683-2272.png)\n\nFormily 表单设计器是基于[designable](https://github.com/alibaba/designable)而扩展出来的扩展包，它在继承了 designable 的基础能力上，提供了 Formily 基础表单的搭建和配置能力。\n\n## 核心理念\n\nDesignable 的核心理念是将设计器搭建变成模块化组合，一切可替换，Designable 本身提供了一系列开箱即用的组件给用户使用，但是如果用户对组件不满意，是可以直接替换组件，从而实现最大化灵活定制，也就是 Designable 本身是不会提供任何插槽 Plugin 相关的 API\n\n## 安装\n\nAnt Design 用户\n\n```bash\nnpm install --save @designable/formily-antd\n```\n\nAlibaba Fusion 用户\n\n```bash\nnpm install --save @designable/formily-next\n```\n\n## 快速上手\n\n[示例源代码](https://github.com/alibaba/designable/tree/main/formily/antd/playground)\n\n```tsx pure\nimport 'antd/dist/antd.less'\nimport React, { useMemo } from 'react'\nimport ReactDOM from 'react-dom'\nimport {\n  Designer, //设计器根组件，主要用于下发上下文\n  DesignerToolsWidget, //画板工具挂件\n  ViewToolsWidget, //视图切换工具挂件\n  Workspace, //工作区组件，核心组件，用于管理工作区内的拖拽行为，树节点数据等等...\n  OutlineTreeWidget, //大纲树组件，它会自动识别当前工作区，展示出工作区内树节点\n  ResourceWidget, //拖拽源挂件\n  HistoryWidget, //历史记录挂件\n  StudioPanel, //主布局面板\n  CompositePanel, //左侧组合布局面板\n  WorkspacePanel, //工作区布局面板\n  ToolbarPanel, //工具栏布局面板\n  ViewportPanel, //视口布局面板\n  ViewPanel, //视图布局面板\n  SettingsPanel, //右侧配置表单布局面板\n  ComponentTreeWidget, //组件树渲染器\n} from '@designable/react'\nimport { SettingsForm } from '@designable/react-settings-form'\nimport {\n  createDesigner,\n  GlobalRegistry,\n  Shortcut,\n  KeyCode,\n} from '@designable/core'\nimport {\n  LogoWidget,\n  ActionsWidget,\n  PreviewWidget,\n  SchemaEditorWidget,\n  MarkupSchemaWidget,\n} from './widgets'\nimport { saveSchema } from './service'\nimport {\n  Form,\n  Field,\n  Input,\n  Select,\n  TreeSelect,\n  Cascader,\n  Radio,\n  Checkbox,\n  Slider,\n  Rate,\n  NumberPicker,\n  Transfer,\n  Password,\n  DatePicker,\n  TimePicker,\n  Upload,\n  Switch,\n  Text,\n  Card,\n  ArrayCards,\n  ObjectContainer,\n  ArrayTable,\n  Space,\n  FormTab,\n  FormCollapse,\n  FormLayout,\n  FormGrid,\n} from '../src'\n\nGlobalRegistry.registerDesignerLocales({\n  'zh-CN': {\n    sources: {\n      Inputs: '输入控件',\n      Layouts: '布局组件',\n      Arrays: '自增组件',\n      Displays: '展示组件',\n    },\n  },\n  'en-US': {\n    sources: {\n      Inputs: 'Inputs',\n      Layouts: 'Layouts',\n      Arrays: 'Arrays',\n      Displays: 'Displays',\n    },\n  },\n})\n\nconst App = () => {\n  const engine = useMemo(\n    () =>\n      createDesigner({\n        shortcuts: [\n          new Shortcut({\n            codes: [\n              [KeyCode.Meta, KeyCode.S],\n              [KeyCode.Control, KeyCode.S],\n            ],\n            handler(ctx) {\n              saveSchema(ctx.engine)\n            },\n          }),\n        ],\n        rootComponentName: 'Form',\n      }),\n    []\n  )\n  return (\n    <Designer engine={engine}>\n      <StudioPanel logo={<LogoWidget />} actions={<ActionsWidget />}>\n        <CompositePanel>\n          <CompositePanel.Item title=\"panels.Component\" icon=\"Component\">\n            <ResourceWidget\n              title=\"sources.Inputs\"\n              sources={[\n                Input,\n                Password,\n                NumberPicker,\n                Rate,\n                Slider,\n                Select,\n                TreeSelect,\n                Cascader,\n                Transfer,\n                Checkbox,\n                Radio,\n                DatePicker,\n                TimePicker,\n                Upload,\n                Switch,\n                ObjectContainer,\n              ]}\n            />\n            <ResourceWidget\n              title=\"sources.Layouts\"\n              sources={[\n                Card,\n                FormGrid,\n                FormTab,\n                FormLayout,\n                FormCollapse,\n                Space,\n              ]}\n            />\n            <ResourceWidget\n              title=\"sources.Arrays\"\n              sources={[ArrayCards, ArrayTable]}\n            />\n            <ResourceWidget title=\"sources.Displays\" sources={[Text]} />\n          </CompositePanel.Item>\n          <CompositePanel.Item title=\"panels.OutlinedTree\" icon=\"Outline\">\n            <OutlineTreeWidget />\n          </CompositePanel.Item>\n          <CompositePanel.Item title=\"panels.History\" icon=\"History\">\n            <HistoryWidget />\n          </CompositePanel.Item>\n        </CompositePanel>\n        <Workspace id=\"form\">\n          <WorkspacePanel>\n            <ToolbarPanel>\n              <DesignerToolsWidget />\n              <ViewToolsWidget\n                use={['DESIGNABLE', 'JSONTREE', 'MARKUP', 'PREVIEW']}\n              />\n            </ToolbarPanel>\n            <ViewportPanel>\n              <ViewPanel type=\"DESIGNABLE\">\n                {() => (\n                  <ComponentTreeWidget\n                    components={{\n                      Form,\n                      Field,\n                      Input,\n                      Select,\n                      TreeSelect,\n                      Cascader,\n                      Radio,\n                      Checkbox,\n                      Slider,\n                      Rate,\n                      NumberPicker,\n                      Transfer,\n                      Password,\n                      DatePicker,\n                      TimePicker,\n                      Upload,\n                      Switch,\n                      Text,\n                      Card,\n                      ArrayCards,\n                      ArrayTable,\n                      Space,\n                      FormTab,\n                      FormCollapse,\n                      FormGrid,\n                      FormLayout,\n                      ObjectContainer,\n                    }}\n                  />\n                )}\n              </ViewPanel>\n              <ViewPanel type=\"JSONTREE\" scrollable={false}>\n                {(tree, onChange) => (\n                  <SchemaEditorWidget tree={tree} onChange={onChange} />\n                )}\n              </ViewPanel>\n              <ViewPanel type=\"MARKUP\" scrollable={false}>\n                {(tree) => <MarkupSchemaWidget tree={tree} />}\n              </ViewPanel>\n              <ViewPanel type=\"PREVIEW\">\n                {(tree) => <PreviewWidget tree={tree} />}\n              </ViewPanel>\n            </ViewportPanel>\n          </WorkspacePanel>\n        </Workspace>\n        <SettingsPanel title=\"panels.PropertySettings\">\n          <SettingsForm uploadAction=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\" />\n        </SettingsPanel>\n      </StudioPanel>\n    </Designer>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById('root'))\n```\n"
  },
  {
    "path": "docs/guide/index.md",
    "content": "# Introduction\n\n## Problem\n\nAs we all know, the form scene has always been the most complex scene in the front-end and back-end fields. What is the main complexity of it?\n\n- There are a lot of fields, how can the performance not deteriorate with the increase of the number of fields?\n- Field association logic is complex, how to implement complex linkage logic more simply? How to ensure that the form performance is not affected when the field is associated with the field?\n\n  - One-to-Many (asynchronous)\n  - Many-to-One (asynchronous)\n  - Many-to-Many (asynchronous)\n\n- Complex form data management\n  - Form value conversion logic is complex (front and back formats are inconsistent)\n  - The logic of merging synchronous and asynchronous default values is complicated\n  - Cross-form data communication, how to keep the performance from deteriorating with the increase in the number of fields?\n- Complex form state management\n  - Focusing on the self-incrementing list scenario, how to make the array data move, and the field status can follow the move during the deletion process?\n- Scene reuse of forms\n  - Query list\n  - Dialog/Drawer form\n  - Step form\n  - Tab form\n- Dynamic rendering requirements are very strong\n  - Field configuration allows non-professional front-ends to quickly build complex forms\n  - Cross-terminal rendering, a JSON Schema, multi-terminal adaptation\n  - How to describe the layout in the form protocol?\n    - Vertical layout\n    - Horizontal layout\n    - Grid layout\n    - Flexible layout\n    - Free layout\n  - How to describe the logic in the form protocol?\n\nSo many problems, how to solve them, think about it, But we still have to find a solution，Not only to solve but also to solve elegantly, The Alibaba digital supply chain team, after experiencing a lot of middle and back-office practice and exploration, finally precipitated **Formily form solution**. All the problems mentioned above, after going through UForm to Formily1.x, until Formily2.x finally achieved the degree of **elegant solution**. So how does Formily 2.x solve these problems?\n\n## Solution\n\nIn order to solve the above problems, we can further refine the problem and come up with a breakthrough direction.\n\n### Accurate Rendering\n\nIn the React scenario, to realize a form requirement, most of them use setState to realize field data collection. because form data needs to be collected and some linkage requirements are realized.This implementation is very simple and the mental cost is very low, but it also introduces performance problems, because each input will cause all fields to be rendered in full. Although there is diff at the DOM update level, diff also has a computational cost, which wastes a lot of computational resources. In terms of time complexity, the initial rendering of the form is O(n), and the field input is also O(n), which is obviously unreasonable.\n\nHistorical experience is always helpful to mankind. Decades ago, humans created the MVVM design pattern. The core of this design pattern is to abstract the view model and consume it at the DSL template layer.SL uses a certain dependency collection mechanism, and then uniformly schedules in the view model to ensure that each input is accurately rendered. This is the industrial-grade GUI form!\n\nIt just so happened that the github community abstracted a state management solution called Mobx for such MVVM models. The core capabilities of [Mobx](https://github.com/mobxjs/mobx) are its dependency tracking mechanism and the abstraction capabilities of responsive models.\n\nTherefore, with the help of Mobx, the O(n) problem in the form field input process can be completely solved, and it can be solved very elegantly. However, during the implementation of Formily 2.x, it was discovered that Mobx still has some problems that are not compatible with Formily's core ideas. In the end, we only can reinvent one wheel,[@formily/reactive](https://reactive.formilyjs.org) which continues the core idea of Mobx.\n\nMention here [react-hook-form](https://github.com/react-hook-form/react-hook-form) , Very popular, known as the industry’s top performance form solution, let’s take a look at its simplest case:\n\n```tsx pure\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport { useForm } from 'react-hook-form'\n\nfunction App() {\n  const { register, handleSubmit, errors } = useForm() // initialize the hook\n  const onSubmit = (data) => {\n    console.log(data)\n  }\n\n  return (\n    <form onSubmit={handleSubmit(onSubmit)}>\n      <input name=\"firstname\" ref={register} /> {/* register an input */}\n      <input name=\"lastname\" ref={register({ required: true })} />\n      {errors.lastname && 'Last name is required.'}\n      <input name=\"age\" ref={register({ pattern: /\\d+/ })} />\n      {errors.age && 'Please enter number for age.'}\n      <input type=\"submit\" />\n    </form>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById('root'))\n```\n\nAlthough the value management achieves accurate rendering, when the verification is triggered, the form will still be rendered in full. Because of the update of the errors state, the overall controlled rendering is necessary to achieve synchronization. This is only the full rendering of the verification meeting. In fact, there is linkage. To achieve linkage with react-hook-form, it also requires overall controlled rendering to achieve linkage. Therefore, if you want to truly achieve accurate rendering, it must be Reactive!\n\n### Domain Model\n\nAs mentioned in the previous question, the linkage of forms is very complicated, including various relationships between fields. Let’s imagine that most form linkages are basically linkages triggered based on the values of certain fields. However, actual business requirements may be sophisticated. It is not only necessary to trigger linkage based on certain field values, but also based on other side-effect values, such as application status, server data status, page URL, internal data of a UI component of a field, and current Other data status of the field itself, some special asynchronous events, etc. Use a picture to describe:\n\n![image-20210202081316031](//img.alicdn.com/imgextra/i3/O1CN01LWjBSt251w5BtGHW2_!!6000000007467-55-tps-1100-432.svg)\n\nAs you can see from the above figure, in order to achieve a linkage relationship, the core is to associate certain state attributes of the field with certain data. Some data here can be external data or own data. For example, the display/hide of a field is associated with certain data, the value of a field is associated with certain data, and the disabling/editing of a field is associated with certain data. Here are three examples. We have actually abstracted it. One of the simplest Field model:\n\n```typescript\ninterface Field {\n  value: any\n  visible: boolean\n  disabled: boolean\n}\n```\n\nOf course, does the Field model only have these 3 attributes? Definitely not, if we want to express a field, then the path of the field must have, Because we want to describe the entire form tree structure, at the same time, we also need to manage the properties of the field corresponding to the UI component. For example, Input and Select have their properties. For example, the placeholder of Input is associated with some data, or the drop-down option of Select is associated with some data, so you can understand it. So, our Field model can look like this:\n\n```typescript\ninterface Field {\n  path: string[]\n  value: any\n  visible: boolean\n  disabled: boolean\n  component: [Component, ComponentProps]\n}\n```\n\nWe have added the component attribute, which represents the UI component and UI component attribute corresponding to the field, so that the ability to associate certain data with the field component attribute, or even the field component, is realized. Are there any more? Of course, there are also, such as the outer package container of the field, usually we call it FormItem, which is mainly responsible for the interactive style of the field, such as the field title, the style of error prompts, etc., If we want to include more linkage, such as the linkage between certain data and FormItem, then we have to add the outer package container. There are many other attributes, which are not listed here.\n\nFrom the above ideas, we can see that in order to solve the linkage problem, no matter how abstract we are, the field model will eventually be abstracted. It contains all the states related to the field. As long as these states are manipulated, linkage can be triggered.\n\nRegarding accurate rendering, we have determined that we can choose a Reactive solution similar to Mobx. Although it is a reinvention of a wheel, the Reactive model is still very suitable for abstract responsive models. So based on the ability of Reactive, Formily, after constant trial and error and correction, finally designed a truly elegant form model. Such a form model solves the problem of the form domain, so it is also called a domain model. With such a domain model, we can make the linkage of the form enumerable and predictable, which also lays a solid foundation for the linkage of the protocol description to be discussed later.\n\n### Path System\n\nThe field model in the form domain model was mentioned earlier. If the design is more complete, it is not only a field model, but also a form model as the top-level model. The top-level model manages all the field models, and each field has its own Path. How to find these fields? The linkage relationship mentioned earlier is more of a passive dependency, but in some scenarios, we just need to modify the state of a field based on an asynchronous event action. Here is how to find a field elegantly. The same It has also undergone a lot of trial and error and correction. Formily's original path system @formily/path solves this problem very well. It not only makes the field lookup elegant, but it can also deal with the disgusting problem of inconsistent front-end and back-end data structures through destructuring expressions.\n\n### Life Cycle\n\nWith the help of Mobx and the path system, we have created a relatively complete form scheme, but after this abstraction, our scheme is like a black box, and the outside world cannot perceive the internal state flow process of the scheme. If you want to implement some logic in a certain process stage, you cannot achieve it. So, here we need another concept, the life cycle. As long as we expose the entire form life cycle as an event hook to the outside world, we can achieve an abstract but flexible form solution.\n\n### Protocol Driven\n\nIf you want to implement a dynamically configurable form, you must make the form structure serializable.\nThere are many ways to serialize, which can be a UI description protocol based on the UI, or a data description protocol based on the data. Because the form itself is to maintain a copy of data, it is natural that for the form scenario, the data protocol is the most suitable. To describe the data structure, [JSON-Schema](https://json-schema.org/) is now the most popular in the industry. Because the JSON Schema protocol itself has many verification-related attributes, this is naturally associated with form verification. Is the UI description protocol really not suitable for describing forms? No, the UI description protocol is suitable for more general UI expressions. Of course, the description form is not a problem, but it will be more front-end protocol. On the contrary, JSON-Schema is expressible at the back-end model layer, and is more versatile in describing data. Therefore, the two protocols have their own strengths, but in the field of pure forms, JSON-Schema will be more domain-oriented.\n\nSo, if we choose JSON-Schema, how do we describe the UI and how do we describe the logic? It is not realistic to simply describe the data and output the form pages available for actual business.\n\nThe solution of [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form) is that data is data and UI is UI. The advantage of this is that each protocol is a very pure protocol, but it brings a large maintenance cost and understanding cost.\nTo develop a form, users need to constantly switch between the two protocols mentally. Therefore, if you look at such a split from a technical perspective, it is very reasonable, but from a product perspective, the split is to throw the cost to the user. Therefore, Formily's form protocol will be more inclined to expand on JSON-Schema.\n\nSo, how to expand? In order not to pollute the standard JSON-Schema attributes, we uniformly express the extended attributes in the x-\\* format:\n\n```json\n{\n  \"type\": \"string\",\n  \"title\": \"String\",\n  \"description\": \"This is a string\",\n  \"x-component\": \"Input\",\n  \"x-component-props\": {\n    \"placeholder\": \"please enter\"\n  }\n}\n```\n\nIn this way, the UI protocol and the data protocol are mixed together. As long as there is a unified extension agreement, the responsibilities of the two protocols can still be guaranteed to be single.\n\nThen, what if you want to wrap a UI container on certain fields? Here, Formily defines a new schema type called `void`. No stranger to void, there is also void element in W3C specification, and void keyword in js. The former represents virtual elements, and the latter represents virtual pointers. Therefore, in JSON Schema, void is introduced to represent a virtual data node, which means that the node does not occupy the actual data structure. So, we can do this:\n\n```json\n{\n  \"type\": \"void\",\n  \"title\": \"card\",\n  \"description\": \"This is a card\",\n  \"x-component\": \"Card\",\n  \"properties\": {\n    \"string\": {\n      \"type\": \"string\",\n      \"title\": \"String\",\n      \"description\": \"This is a string\",\n      \"x-component\": \"Input\",\n      \"x-component-props\": {\n        \"placeholder\": \"please enter\"\n      }\n    }\n  }\n}\n```\n\nIn this way, a UI container can be described. Because the UI container can be described, we can easily encapsulate a scene-based component, such as FormStep. So how do we describe the linkage between fields? For example, one field needs to control the display and hide of another field. We can do this:\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"title\": \"Source\",\n      \"x-component\": \"Input\",\n      \"x-component-props\": {\n        \"placeholder\": \"please enter\"\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"title\": \"Target\",\n      \"x-component\": \"Input\",\n      \"x-component-props\": {\n        \"placeholder\": \"please enter\"\n      },\n      \"x-reactions\": [\n        {\n          \"dependencies\": [\"source\"],\n          \"when\": \"{{$deps[0] == '123'}}\",\n          \"fulfill\": {\n            \"state\": {\n              \"visible\": true\n            }\n          },\n          \"otherwise\": {\n            \"state\": {\n              \"visible\": false\n            }\n          }\n        }\n      ]\n    }\n  }\n}\n```\n\nThe target field is described with the help of `x-reactions`, which depends on the value of the source field. If the value is `'123'`, the target field is displayed, otherwise it is hidden. This linkage method is a passive linkage. What if we want to achieve active linkage ? It can be like this:\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"title\": \"Source\",\n      \"x-component\": \"Input\",\n      \"x-component-props\": {\n        \"placeholder\": \"please enter\"\n      },\n      \"x-reactions\": [\n        {\n          \"when\": \"{{$self.value == '123'}}\",\n          \"target\": \"target\",\n          \"fulfill\": {\n            \"state\": {\n              \"visible\": true\n            }\n          },\n          \"otherwise\": {\n            \"state\": {\n              \"visible\": false\n            }\n          }\n        }\n      ]\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"title\": \"Target\",\n      \"x-component\": \"Input\",\n      \"x-component-props\": {\n        \"placeholder\": \"please enter\"\n      }\n    }\n  }\n}\n```\n\nJust change the location of `x-reactions`, put it on the source field, and then specify a target.\n\nIt can be seen that our linkage is actually based on:\n\n- condition\n- Condition-satisfied action\n- Unsatisfied action\n\nTo achieve. Because the internal state management uses the [@formily/reactive](https://reactive.formilyjs.org) solution similar to Mobx, Formily easily realizes passive and active linkage scenarios, covering most business needs.\n\nTherefore, our form can be described by protocol, and it can be configurable no matter how complicated the layout is or the linkage is very complicated.\n\n### Layered Architecture\n\nI talked about the solutions to various problems at the beginning, so how do we design now to make Formily more self-consistent and elegant?\n\n![](https://img.alicdn.com/imgextra/i4/O1CN019qbf1b1ChnTfT9x3X_!!6000000000113-55-tps-1939-1199.svg)\n\nThis picture mainly divides Formily into the kernel layer, UI bridge layer, extended component layer, and configuration application layer.\n\nThe kernel layer is UI-independent. It ensures that the logic and state of user management are not coupled to any framework. This has several advantages:\n\n- Logic and UI framework are decoupled, and framework-level migration will be done in the future, without extensive refactoring of business code.\n- The learning cost is uniform. If the user uses @formily/react, the business will be migrated to @formily/vue in the future, and the user does not need to learn again.\n\nJSON Schema exists independently and is consumed by the UI bridging layer, ensuring the absolute consistency of protocol drivers under different UI frameworks, and there is no need to repeatedly implement protocol parsing logic.\n\nExtend the component layer to provide a series of form scene components to ensure that users can use it out of the box. No need to spend a lot of time for secondary development.\n\n## Competitive Product Comparison\n\n```tsx\n/**\n * inline: true\n */\nimport React from 'react'\nimport { Table, Tooltip } from 'antd'\nimport { QuestionCircleOutlined } from '@ant-design/icons'\n\nconst text = (content, tooltips) => {\n  if (tooltips) {\n    return (\n      <div>\n        {content}\n        <Tooltip title={tooltips}>\n          <QuestionCircleOutlined style={{ marginLeft: 3 }} />\n        </Tooltip>\n      </div>\n    )\n  }\n  return content\n}\n\nconst dataSource = [\n  {\n    feature: 'Custom component access cost',\n    antd: '4.x low access cost',\n    fusion: 'high',\n    formik: 'low',\n    finalForm: 'low',\n    schemaForm: text('high', 'Because of coupling bootstrap'),\n    hookForm: text('high', 'Because of coupling React Ref'),\n    'formily1.x': 'low',\n    'formily2.x': 'low',\n  },\n  {\n    feature: 'performance',\n    antd: text(\n      '4.x performance is better',\n      'Only solved the value synchronization and accurate rendering'\n    ),\n    fusion: 'bad',\n    formik: 'bad',\n    finalForm: text(\n      'better',\n      'But only solved the value synchronization and accurate rendering'\n    ),\n    schemaForm: 'bad',\n    hookForm: text(\n      'good',\n      'But only solved the value synchronization and accurate rendering'\n    ),\n    'formily1.x': text(\n      'excellent',\n      'Can solve the precise rendering in the linkage process'\n    ),\n    'formily2.x': text(\n      'excellent',\n      'Can solve the precise rendering in the linkage process'\n    ),\n  },\n  {\n    feature: 'Whether to support dynamic rendering',\n    antd: 'no',\n    fusion: 'no',\n    formik: 'no',\n    finalForm: 'no',\n    schemaForm: 'yes',\n    hookForm: 'no',\n    'formily1.x': 'yes',\n    'formily2.x': 'yes',\n  },\n  {\n    feature: 'Whether to use out of the box',\n    antd: 'yes',\n    fusion: 'yes',\n    formik: 'no',\n    finalForm: 'no',\n    schemaForm: 'yes',\n    hookForm: 'no',\n    'formily1.x': 'yes',\n    'formily2.x': 'yes',\n  },\n  {\n    feature: 'Whether to support cross-terminal',\n    antd: 'no',\n    fusion: 'no',\n    formik: 'no',\n    finalForm: 'no',\n    schemaForm: 'no',\n    hookForm: 'no',\n    'formily1.x': 'yes',\n    'formily2.x': 'yes',\n  },\n  {\n    feature: 'Development efficiency',\n    antd: 'general',\n    fusion: 'generalv',\n    formik: 'general',\n    finalForm: 'general',\n    schemaForm: text(\n      'low',\n      'Source code development requires manual maintenance of JSON'\n    ),\n    hookForm: 'general',\n    'formily1.x': 'high',\n    'formily2.x': 'high',\n  },\n  {\n    feature: 'Learning cost',\n    antd: 'easy',\n    fusion: 'easy',\n    formik: 'easy',\n    finalForm: 'hard',\n    schemaForm: 'hard',\n    hookForm: 'easy',\n    'formily1.x': 'very hard',\n    'formily2.x': text('hard', 'The concept is drastically reduced'),\n  },\n  {\n    feature: 'View code maintainability',\n    antd: text('bad', 'Lots of conditional expressions'),\n    fusion: text('bad', 'Lots of conditional expressions'),\n    formik: text('bad', 'Lots of conditional expressions'),\n    finalForm: text('bad', 'Lots of conditional expressions'),\n    schemaForm: 'good',\n    hookForm: text('bad', 'Lots of conditional expressions'),\n    'formily1.x': 'good',\n    'formily2.x': 'good',\n  },\n  {\n    feature: 'Scenario-based packaging capabilities',\n    antd: 'no',\n    fusion: 'no',\n    formik: 'no',\n    finalForm: 'no',\n    schemaForm: 'yes',\n    hookForm: 'no',\n    'formily1.x': 'yes',\n    'formily2.x': 'yes',\n  },\n  {\n    feature: 'Whether to support form preview',\n    antd: 'no',\n    fusion: 'yes',\n    formik: 'no',\n    finalForm: 'no',\n    schemaForm: 'no',\n    hookForm: 'no',\n    'formily1.x': 'yes',\n    'formily2.x': 'yes',\n  },\n]\n\nexport default () => {\n  return (\n    <Table\n      dataSource={dataSource}\n      pagination={false}\n      bordered\n      scroll={{ x: 1600 }}\n      size=\"small\"\n    >\n      <Table.Column title=\"ability\" dataIndex=\"feature\" width={160} />\n      <Table.Column title=\"Ant Design Form\" dataIndex=\"antd\" width={160} />\n      <Table.Column title=\"Fusion Form\" dataIndex=\"fusion\" width={160} />\n      <Table.Column title=\"Formik\" dataIndex=\"formik\" width={160} />\n      <Table.Column\n        title=\"React Final Form\"\n        dataIndex=\"finalForm\"\n        width={160}\n      />\n      <Table.Column\n        title=\"React Schema Form\"\n        dataIndex=\"schemaForm\"\n        width={160}\n      />\n      <Table.Column title=\"React Hook Form\" dataIndex=\"hookForm\" width={160} />\n      <Table.Column title=\"Formily1.x\" dataIndex=\"formily1.x\" width={160} />\n      <Table.Column title=\"Formily2.x\" dataIndex=\"formily2.x\" width={160} />\n    </Table>\n  )\n}\n```\n\n## Core Advantages\n\n- high performance\n- Out of the box\n- Linkage logic to achieve high efficiencyv\n- Cross-terminal capability, logic can be cross-frame, cross-terminal reuse\n- Dynamic rendering capability\n\n## Core Disadvantage\n\n- The learning cost is relatively high. Although 2.x has already converged a large number of concepts, there is still a certain learning cost.\n\n## Who is using it?\n\n- Alibaba\n- Tencent\n- ByteDance\n\n## Q/A\n\nQ: Now that I have Vue, why do I still need to provide @formily/vue?\n\nAnswer: Vue is a UI framework. The problem it solves is a wider range of UI problems. Although its reactive ability is outstanding in form scenarios, at least it is more convenient than native React to write forms, but if it is in more complex form scenarios , We still need to do a lot of abstraction and encapsulation, so @formily/vue is to help you do these abstract encapsulation things, really let you develop super-complex form applications efficiently and conveniently.\n\nQ: What is the biggest advantage of Formily2.x compared to 1.x?\n\nAnswer: The cost of learning, yes, the core is to allow users to understand Formily more quickly. We have tried our best to avoid all kinds of obscure logic and boundary problems during the 2.x design process.\n\nQ: What is the browser compatibility of Formily 2.x?\n\nAnswer: IE is not supported, because the implementation of Reactive strongly relies on Proxy.\n"
  },
  {
    "path": "docs/guide/index.zh-CN.md",
    "content": "# 介绍\n\n## 问题\n\n众所周知，表单场景一直都是前端中后台领域最复杂的场景，它的复杂度主要在哪里呢？\n\n- 字段数量多，如何让性能不随字段数量增加而变差？\n- 字段关联逻辑复杂，如何更简单的实现复杂的联动逻辑？字段与字段关联时，如何保证不影响表单性能？\n\n  - 一对多(异步)\n  - 多对一(异步)\n  - 多对多(异步)\n\n- 表单数据管理复杂\n  - 表单值转换逻辑复杂(前后端格式不一致)\n  - 同步默认值与异步默认值合并逻辑复杂\n  - 跨表单数据通信，如何让性能不随字段数量增加而变差？\n- 表单状态管理复杂\n  - 着重提自增列表场景，如何让数组数据在移动，删除过程中，字段状态能够做到跟随移动？\n- 表单的场景化复用\n  - 查询列表\n  - 弹窗/抽屉表单\n  - 分步表单\n  - 选项卡表单\n- 动态渲染诉求很强烈\n  - 字段配置化，让非专业前端也能快速搭建复杂表单\n  - 跨端渲染，一份 JSON Schema，多端适配\n  - 如何在表单协议中描述布局？\n    - 纵向布局\n    - 横向布局\n    - 网格布局\n    - 弹性布局\n    - 自由布局\n  - 如何在表单协议中描述逻辑？\n\n这么多问题，怎么解决，想想就头大，但是我们还是得想办法解决，不仅要解决，还要优雅的解决，阿里数字供应链团队，在经历了大量的中后台实践和探索之后，总算沉淀出了 **Formily 表单解决方案** ，以上提到的所有问题，在经历了 UForm 到 Formily1.x，直到 Formily2.x 总算做到了 **优雅解决** 的程度。那 Formily2.x 是如何解决这些问题的呢？\n\n## 解法\n\n为了解决以上问题，我们可以对问题做进一步提炼，得出可突破的方向。\n\n### 精确渲染\n\n在 React 场景下实现一个表单需求，因为要收集表单数据，实现一些联动需求，大多数都是通过 setState 来实现字段数据收集，这样实现非常简单，心智成本非常低，但是却又引入了性能问题，因为每次输入都会导致所有字段全量渲染，虽然在 DOM 更新层面是有 diff，但是 diff 也是有计算成本的，浪费了很多计算资源，如果用时间复杂度来看的话，初次渲染表单是 O(n)，字段输入时也是 O(n)，这样明显是不合理的。\n\n历史的经验总是对人类有帮助的，几十年前，人类创造出了 MVVM 设计模式。这样的设计模式核心是将视图模型抽象出来，然后在 DSL 模板层消费，DSL 借助某种依赖收集机制，然后在视图模型中统一调度，保证每次输入都是精确渲染的，这就是工业级的 GUI 形态！\n\n刚好，github 社区为这样的 MVVM 模型抽象出了一个叫 [Mobx](https://github.com/mobxjs/mobx) 的状态管理解决方案，Mobx 最核心的能力就是它的依赖追踪机制和响应式模型的抽象能力。\n\n所以，借助 Mobx，完全可以解决表单字段输入过程中的 O(n)问题，而且是可以很优雅的解决，但是 Formily2.x 在实现的过程中发现 Mobx 还是存在一些不兼容 Formily 核心思想的问题，最终，只能重新造了一个轮子，延续 Mobx 的核心思想的 [@formily/reactive](https://reactive.formilyjs.org/zh-CN)\n\n这里提一下 [react-hook-form](https://github.com/react-hook-form/react-hook-form) ，非常流行，号称业界性能第一的表单方案，我们看看它最简单的案例：\n\n```tsx pure\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport { useForm } from 'react-hook-form'\n\nfunction App() {\n  const { register, handleSubmit, errors } = useForm() // initialize the hook\n  const onSubmit = (data) => {\n    console.log(data)\n  }\n\n  return (\n    <form onSubmit={handleSubmit(onSubmit)}>\n      <input name=\"firstname\" ref={register} /> {/* register an input */}\n      <input name=\"lastname\" ref={register({ required: true })} />\n      {errors.lastname && 'Last name is required.'}\n      <input name=\"age\" ref={register({ pattern: /\\d+/ })} />\n      {errors.age && 'Please enter number for age.'}\n      <input type=\"submit\" />\n    </form>\n  )\n}\n\nReactDOM.render(<App />, document.getElementById('root'))\n```\n\n虽然值管理做到了精确渲染，但是在触发校验的时候，还是会导致表单全量渲染，因为 errors 状态的更新，是必须要整体受控渲染才能实现同步，这仅仅只是校验会全量渲染，其实还有联动，react-hook-form 要实现联动，同样是需要整体受控渲染才能实现联动。所以，如果要真正实现精确渲染，非 Reactive 不可！\n\n### 领域模型\n\n前面问题中有提到表单的联动是非常复杂的，包含了字段间的各种关系，我们想象一下，大多数表单联动，基本上都是基于某些字段的值引发的联动，但是，实际业务需求可能会比较恶心，不仅要基于某些字段值引发联动，还会基于其他副作用值引发联动，比如应用状态，服务端数据状态，页面 URL，某个字段 UI 组件内部数据，当前字段自身的其他数据状态，某些特殊异步事件等等。用张图来描述：\n\n![image-20210202081316031](//img.alicdn.com/imgextra/i3/O1CN01LWjBSt251w5BtGHW2_!!6000000007467-55-tps-1100-432.svg)\n\n从上图可以看到，想要达成一个联动关系，核心是将字段的某些状态属性与某些数据关联起来，这里的某些数据可以是外界数据，也可以是自身数据，比如字段的显示/隐藏与某些数据的关联，又比如字段的值与某些数据关联，还比如字段的禁用/编辑与某些数据关联，就举了 3 个例子，我们其实已经抽象出了一个最简单的 Field 模型：\n\n```typescript\ninterface Field {\n  value: any\n  visible: boolean\n  disabled: boolean\n}\n```\n\n当然，Field 模型仅仅只有这 3 个属性吗？肯定不是，如果我们要表达一个字段，那么字段的路径一定要有，因为要描述整个表单树结构，同时，我们还要管理起字段对应 UI 组件的属性，比如 Input 和 Select 都有它的属性，举个例子，Input 的 placeholder 与某些数据关联，或者 Select 的下拉选项与某些数据关联，这样就能理解了吧。所以，我们的 Field 模型可以是这样：\n\n```\ninterface Field {\n   path:string[],\n   value:any,\n   visible:boolean,\n   disabled:boolean,\n   component:[Component,ComponentProps]\n}\n```\n\n我们加了 component 属性，它代表了字段所对应的 UI 组件和 UI 组件属性，这样就实现了某些数据与字段组件属性关联，甚至是与字段组件关联的能力。还有吗？当然还有，比如字段的外包裹容器，通常我们都叫 FormItem，它主要负责字段的外围的交互样式，比如字段标题，错误提示的样式等等，如果我们想要囊括更多联动，比如某些数据与 FormItem 的联动，那就得把外包裹容器也加进去。还有很多很多属性，这里没法一一列举。\n\n从上面的思路中我们可以看到，为了解决联动问题，不管我们怎么抽象，最终还是会抽象出字段模型，它包含了字段相关的所有状态，只要去操作这些状态就能引发联动。\n\n关于精确渲染，我们已经确定可以选用类似 Mobx 的 Reactive 方案，虽然是重新造了一个轮子，但是，Reactive 这种模式始终还是很适合抽象响应式模型，所以基于 Reactive 的能力，Formily 经过不断试错与纠正，总算设计出了真正优雅的表单模型。这样的表单模型，解决的是表单领域问题，所以也称之为领域模型，有了这样的领域模型，我们就能让表单的联动变得可枚举可预测，这样也为后面要说的协议描述联动打下了坚实基础。\n\n### 路径系统\n\n前面提到了表单领域模型中的字段模型，如果设计的更完备的话，其实不止是字段模型，必须还要有一个表单模型作为顶层模型，顶层模型管理着所有字段模型，每个字段都有着自己的路径，那如何查找这些字段呢？前面说到的联动关系，更多的是被动依赖关系，但是有些场景，我们就是要基于某个异步事件动作，去修改某个字段的状态，这里就涉及到如何优雅的查找某个字段，同样也是经过了大量的试错与纠正，Formily 独创的路径系统 @formily/path 很好的解决了这个问题，不仅仅是让字段查找变得优雅，它还能通过解构表达式去处理前后端数据结构不一致的恶心问题。\n\n### 生命周期\n\n借助 Mobx 和路径系统，我们已经打造了一个较为完备的表单方案了，但是这样抽象了之后，我们的方案就像个黑盒，外界无法感知到方案内部状态流转过程，想要在某个过程阶段内实现一些逻辑则无法实现，所以，这里我们就需要另外一个概念了，生命周期，只要我们将整个表单生命周期作为事件钩子暴露给外界，这样就能做到了既有抽象，但又灵活的表单方案。\n\n### 协议驱动\n\n如果想要实现动态可配置表单，那必然是需要将表单结构变得可序列化，序列化的方式有很多种，可以是以 UI 为思路的 UI 描述协议，也可以是以数据为思路的数据描述协议，因为表单本身就是为了维护一份数据，那自然而然，对于表单场景而言，数据协议最适合不过，想要描述数据结构，现在业界最流行的就是 [JSON-Schema](https://json-schema.org/) 了，因为 JSON Schema 协议上本身就有很多校验相关的属性，这就天然和表单校验关联上了。那 UI 描述协议就真的不适合描述表单吗？No，UI 描述协议适合更通用的 UI 表达，描述表单当然不在话下，只是它会更偏前端协议，相反，JSON-Schema，在后端模型层，都是可表达的，在描述数据上更通用，所以两种协议，各有所长，只是在单纯表单领域，JSON-Schema 会更偏领域化一些。\n\n那么，如果选用 JSON-Schema，我们怎么描述 UI，怎么描述逻辑呢？单纯的描述数据，想要输出实际业务可用的表单页面，不太现实。\n\n[react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form)的解法是，数据是数据，UI 是 UI，这样的好处是，各个协议都是非常纯净的协议，但是却带来了较大的维护成本和理解成本，用户要开发一个表单，需要不断的在两种协议心智上做切换，所以，如果从技术视角来看这样的拆分，其实是非常合理的，但是从产品视角来看的话，拆分则是把成本抛给了用户，所以，Formily 的表单协议会更加倾向于在 JSON-Schema 上做扩展。\n\n那么，如何扩展呢？为了不污染标准 JSON-Schema 属性，我们统一以`x-*`格式来表达扩展属性：\n\n```json\n{\n  \"type\": \"string\",\n  \"title\": \"字符串\",\n  \"description\": \"这是一个字符串\",\n  \"x-component\": \"Input\",\n  \"x-component-props\": {\n    \"placeholder\": \"请输入\"\n  }\n}\n```\n\n这样看来，UI 协议与数据协议混合在一起，只要有一个统一的扩展约定，也还是能保证两种协议职责单一。\n\n然后，如果想要在某些字段上包裹一个 UI 容器怎么办呢？这里，Formily 定义了一个新的 schema type，叫`void`。void 不陌生，W3C 规范里也有 void element，js 里也有 void 关键字，前者代表虚元素，后者代表虚指针，所以，在 JSON Schema 中，引入 void，代表一个虚数据节点，表示该节点并不占用实际数据结构。所以，我们可以这样：\n\n```json\n{\n  \"type\": \"void\",\n  \"title\": \"卡片\",\n  \"description\": \"这是一个卡片\",\n  \"x-component\": \"Card\",\n  \"properties\": {\n    \"string\": {\n      \"type\": \"string\",\n      \"title\": \"字符串\",\n      \"description\": \"这是一个字符串\",\n      \"x-component\": \"Input\",\n      \"x-component-props\": {\n        \"placeholder\": \"请输入\"\n      }\n    }\n  }\n}\n```\n\n这样就可以描述了一个 UI 容器了，因为可以描述 UI 容器，我们就能轻易封装一个场景化的组件了，比如 FormStep，那么我们怎么描述字段间联动呢？比如一个字段要控制另一个字段的显示隐藏。我们可以这样：\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"title\": \"Source\",\n      \"x-component\": \"Input\",\n      \"x-component-props\": {\n        \"placeholder\": \"请输入\"\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"title\": \"Target\",\n      \"x-component\": \"Input\",\n      \"x-component-props\": {\n        \"placeholder\": \"请输入\"\n      },\n      \"x-reactions\": [\n        {\n          \"dependencies\": [\"source\"],\n          \"when\": \"{{$deps[0] == '123'}}\",\n          \"fulfill\": {\n            \"state\": {\n              \"visible\": true\n            }\n          },\n          \"otherwise\": {\n            \"state\": {\n              \"visible\": false\n            }\n          }\n        }\n      ]\n    }\n  }\n}\n```\n\n借助`x-reactions`描述了 target 字段，依赖了 source 字段的值，如果值为`'123'`的时候则显示 target 字段，否则隐藏，这种联动方式是一种被动联动，那如果我们希望实现主动联动呢？可以这样：\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"title\": \"Source\",\n      \"x-component\": \"Input\",\n      \"x-component-props\": {\n        \"placeholder\": \"请输入\"\n      },\n      \"x-reactions\": [\n        {\n          \"when\": \"{{$self.value == '123'}}\",\n          \"target\": \"target\",\n          \"fulfill\": {\n            \"state\": {\n              \"visible\": true\n            }\n          },\n          \"otherwise\": {\n            \"state\": {\n              \"visible\": false\n            }\n          }\n        }\n      ]\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"title\": \"Target\",\n      \"x-component\": \"Input\",\n      \"x-component-props\": {\n        \"placeholder\": \"请输入\"\n      }\n    }\n  }\n}\n```\n\n只需要将`x-reactions`换个位置，放到 source 字段上，然后再指定一个 target 即可。\n\n可以看到，我们的联动，其实核心是基于：\n\n- 条件\n- 条件满足的动作\n- 条件不满足的动作\n\n来实现的，因为内部状态管理借助了 类似 Mobx 的[@formily/reactive](https://reactive.formilyjs.org/zh-CN)方案，所以，Formily 很轻松的就实现了被动和主动联动场景，覆盖了绝大多数业务需求。\n\n所以，我们的表单完全可以使用协议来描述了，不管是再复杂的布局，还是很复杂的联动，都能做到可配置。\n\n### 分层架构\n\n前面讲了对于一开始的各种问题的解法，那么现在我们如何设计才能让 Formily 更加自洽且优雅呢？\n\n![](https://img.alicdn.com/imgextra/i3/O1CN01iEwHrP1NUw84xTded_!!6000000001574-55-tps-1939-1199.svg)\n\n这张图主要将 Formily 分为了内核层，UI 桥接层，扩展组件层，和配置应用层。\n\n内核层是 UI 无关的，它保证了用户管理的逻辑和状态是不耦合任何一个框架，这样有几个好处：\n\n- 逻辑与 UI 框架解耦，未来做框架级别的迁移，业务代码无需大范围重构\n- 学习成本统一，如果用户使用了@formily/react，以后业务迁移@formily/vue，用户不需要重新学习\n\nJSON Schema 独立存在，给 UI 桥接层消费，保证了协议驱动在不同 UI 框架下的绝对一致性，不需要重复实现协议解析逻辑。\n\n扩展组件层，提供一系列表单场景化组件，保证用户开箱即用。无需花大量时间做二次开发。\n\n## 竞品对比\n\n```tsx\n/**\n * inline: true\n */\nimport React from 'react'\nimport { Table, Tooltip } from 'antd'\nimport { QuestionCircleOutlined } from '@ant-design/icons'\n\nconst text = (content, tooltips) => {\n  if (tooltips) {\n    return (\n      <div>\n        {content}\n        <Tooltip title={tooltips}>\n          <QuestionCircleOutlined style={{ marginLeft: 3 }} />\n        </Tooltip>\n      </div>\n    )\n  }\n  return content\n}\n\nconst dataSource = [\n  {\n    feature: '自定义组件接入成本',\n    antd: '4.x接入成本低',\n    fusion: '高',\n    formik: '低',\n    finalForm: '低',\n    schemaForm: text('高', '因为耦合bootstrap'),\n    hookForm: text('高', '因为耦合React Ref'),\n    'formily1.x': '低',\n    'formily2.x': '低',\n  },\n  {\n    feature: '性能',\n    antd: text('4.x性能较好', '只解决了值同步精确渲染'),\n    fusion: '差',\n    formik: '差',\n    finalForm: text('较好', '但只解决了值同步精确渲染'),\n    schemaForm: '差',\n    hookForm: text('好', '但只解决了值同步精确渲染'),\n    'formily1.x': text('非常好', '能解决联动过程中的精确渲染'),\n    'formily2.x': text('非常好', '能解决联动过程中的精确渲染'),\n  },\n  {\n    feature: '是否支持动态渲染',\n    antd: '否',\n    fusion: '否',\n    formik: '否',\n    finalForm: '否',\n    schemaForm: '是',\n    hookForm: '否',\n    'formily1.x': '是',\n    'formily2.x': '是',\n  },\n  {\n    feature: '是否开箱即用',\n    antd: '是',\n    fusion: '是',\n    formik: '否',\n    finalForm: '否',\n    schemaForm: '是',\n    hookForm: '否',\n    'formily1.x': '是',\n    'formily2.x': '是',\n  },\n  {\n    feature: '是否支持跨端',\n    antd: '否',\n    fusion: '否',\n    formik: '否',\n    finalForm: '否',\n    schemaForm: '否',\n    hookForm: '否',\n    'formily1.x': '是',\n    'formily2.x': '是',\n  },\n  {\n    feature: '开发效率',\n    antd: '一般',\n    fusion: '一般',\n    formik: '一般',\n    finalForm: '一般',\n    schemaForm: text('低', '源码开发需要手工维护JSON'),\n    hookForm: '一般',\n    'formily1.x': '高',\n    'formily2.x': '高',\n  },\n  {\n    feature: '学习成本',\n    antd: '低',\n    fusion: '低',\n    formik: '低',\n    finalForm: '高',\n    schemaForm: '高',\n    hookForm: '低',\n    'formily1.x': '很高',\n    'formily2.x': text('高', '概念大量减少'),\n  },\n  {\n    feature: '视图代码可维护性',\n    antd: text('低', '大量条件表达式'),\n    fusion: text('低', '大量条件表达式'),\n    formik: text('低', '大量条件表达式'),\n    finalForm: text('低', '大量条件表达式'),\n    schemaForm: '高',\n    hookForm: text('低', '大量条件表达式'),\n    'formily1.x': '高',\n    'formily2.x': '高',\n  },\n  {\n    feature: '场景化封装能力',\n    antd: '无',\n    fusion: '无',\n    formik: '无',\n    finalForm: '无',\n    schemaForm: '有',\n    hookForm: '无',\n    'formily1.x': '有',\n    'formily2.x': '有',\n  },\n  {\n    feature: '是否支持表单预览态',\n    antd: '否',\n    fusion: '是',\n    formik: '否',\n    finalForm: '否',\n    schemaForm: '否',\n    hookForm: '否',\n    'formily1.x': '是',\n    'formily2.x': '是',\n  },\n]\n\nexport default () => {\n  return (\n    <Table\n      dataSource={dataSource}\n      pagination={false}\n      bordered\n      scroll={{ x: 1600 }}\n      size=\"small\"\n    >\n      <Table.Column title=\"能力\" dataIndex=\"feature\" width={160} />\n      <Table.Column title=\"Ant Design Form\" dataIndex=\"antd\" width={160} />\n      <Table.Column title=\"Fusion Form\" dataIndex=\"fusion\" width={160} />\n      <Table.Column title=\"Formik\" dataIndex=\"formik\" width={160} />\n      <Table.Column\n        title=\"React Final Form\"\n        dataIndex=\"finalForm\"\n        width={160}\n      />\n      <Table.Column\n        title=\"React Schema Form\"\n        dataIndex=\"schemaForm\"\n        width={160}\n      />\n      <Table.Column title=\"React Hook Form\" dataIndex=\"hookForm\" width={160} />\n      <Table.Column title=\"Formily1.x\" dataIndex=\"formily1.x\" width={160} />\n      <Table.Column title=\"Formily2.x\" dataIndex=\"formily2.x\" width={160} />\n    </Table>\n  )\n}\n```\n\n## 核心优势\n\n- 高性能\n- 开箱即用\n- 联动逻辑实现高效\n- 跨端能力，逻辑可跨框架，跨终端复用\n- 动态渲染能力\n\n## 核心劣势\n\n- 学习成本较高，虽然 2.x 已经在大量收敛概念，但还是存在一定的学习成本。\n\n## 谁在使用？\n\n- 阿里巴巴\n  - 数字供应链事业部\n  - 淘系技术部\n  - 飞猪\n  - 阿里云\n  - 蚂蚁\n  - 政务平台\n  - 大文娱\n  - 盒马\n  - 阿里妈妈\n  - 数据平台\n  - ICBU\n  - 口碑\n  - 钉钉\n  - 天猫超市、天猫国际、阿里健康、农村淘宝、淘宝心选\n- 腾讯\n- 字节跳动\n\n## Q/A\n\n问：有了 Vue 了，为什么还需要提供@formily/vue？\n\n答：Vue 是一个 UI 框架，它解决的问题是更大范围的 UI 问题，虽然它的 reactive 能力在表单场景上表现出众，至少比原生 React 写表单要方便，但是如果在更复杂的表单场景上，我们还是需要做很多抽象和封装，所以@formily/vue 就是为了帮您做这些抽象封装的事情，真正让您高效便捷的开发出超复杂表单应用。\n\n问：Formily2.x 相比于 1.x 最大的优势是什么？\n\n答：学习成本的大大降低，对，核心是为了让用户更快速的理解 Formily，我们在 2.x 设计的过程中极力的避免出现各种隐晦逻辑，边界问题，同时因为移除了 rxjs/styled-components 的依赖，整体体积大大降低\n\n问：Formily2.x 的浏览器兼容性如何？\n\n答：不支持 IE，因为 Reactive 的实现强依赖 Proxy\n"
  },
  {
    "path": "docs/guide/issue-helper.md",
    "content": "# Issue Helper\n\n## Before You Start...\n\nThe issue list is reserved exclusively for bug reports and feature requests. That means we do not accept usage questions. If you open an issue that does not conform to the requirements, it will be closed immediately.\n\nFor usage questions, please use the following resources:\n\n- Read the introduce and components documentation\n- Make sure you have search your question in FAQ and changelog\n- Look for / ask questions on [Discussions](https://github.com/alibaba/formily/discussions)\n\nAlso try to search for your issue\n\nit may have already been answered or even fixed in the development branch. However, if you find that an old, closed issue still persists in the latest version, you should open a new issue using the form below instead of commenting on the old issue.\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldMount, onFieldReact } from '@formily/core'\nimport { Field, VoidField } from '@formily/react'\nimport {\n  Form,\n  Input,\n  Select,\n  Radio,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport semver from 'semver'\nimport ReactMde from 'react-mde'\nimport * as Showdown from 'showdown'\nimport 'react-mde/lib/styles/css/react-mde-all.css'\n\nconst converter = new Showdown.Converter({\n  tables: true,\n  simplifiedAutoLink: true,\n  strikethrough: true,\n  tasklists: true,\n})\n\nconst MdInput = ({ value, onChange }) => {\n  const [selectedTab, setSelectedTab] = React.useState('write')\n  return (\n    <div style={{ fontSize: 12, lineHeight: 1 }}>\n      <ReactMde\n        value={value}\n        onChange={onChange}\n        selectedTab={selectedTab}\n        onTabChange={setSelectedTab}\n        generateMarkdownPreview={(markdown) =>\n          Promise.resolve(\n            `<div class=\"markdown\" style=\"margin:0 20px;\">${\n              converter.makeHtml(markdown) || ''\n            }</div>`\n          )\n        }\n      />\n    </div>\n  )\n}\n\nconst form = createForm({\n  validateFirst: true,\n  effects() {\n    onFieldMount('version', async (field) => {\n      const { versions: unsort } = await fetch(\n        'https://registry.npmmirror.com/@formily/core'\n      ).then((res) => res.json())\n\n      const versions = Object.keys(unsort).sort((v1, v2) =>\n        semver.gte(v1, v2) ? -1 : 1\n      )\n      field.dataSource = versions.map((version) => ({\n        label: version,\n        value: version,\n      }))\n    })\n    onFieldMount('package', async (field) => {\n      const packages = await fetch(\n        'https://formilyjs.org/.netlify/functions/npm-search?q=@formily'\n      ).then((res) => res.json())\n      field.dataSource = packages.map(({ name }) => {\n        return {\n          label: name,\n          value: name,\n        }\n      })\n    })\n    onFieldReact('bug-desc', (field) => {\n      field.visible = field.query('type').value() === 'Bug Report'\n    })\n    onFieldReact('feature-desc', (field) => {\n      field.visible = field.query('type').value() === 'Feature Request'\n    })\n  },\n})\n\nconst createIssueURL = ({\n  type,\n  title,\n  version,\n  package: pkg,\n  reproduceLink,\n  reproduceStep,\n  expected,\n  actually,\n  comment,\n  feature,\n  api,\n}) => {\n  const url = new URL('https://github.com/alibaba/formily/issues/new')\n\n  const bugInfo = `\n- [ ] I have searched the [issues](https://github.com/alibaba/formily/issues) of this repository and believe that this is not a duplicate.\n\n### Reproduction link\n[![Edit on CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](${\n    reproduceLink || ''\n  })\n\n### Steps to reproduce\n${reproduceStep || ''}\n\n### What is expected?\n${expected || ''}\n\n### What is actually happening?\n${actually || ''}\n\n### Package\n${pkg}@${version}\n\n---\n\n${comment || ''}\n\n<!-- generated by formily-issue-helper. DO NOT REMOVE -->\n`\n\n  const prInfo = `\n- [ ] I have searched the [issues](https://github.com/alibaba/formily/issues) of this repository and believe that this is not a duplicate.\n\n### What problem does this feature solve?\n${feature || ''}\n\n### What does the proposed API look like?\n${api || ''}\n\n\n<!-- generated by formily-issue-helper. DO NOT REMOVE -->\n`\n\n  url.searchParams.set('title', `[${type}] ${title}`)\n  url.searchParams.set('body', type === 'Bug Report' ? bugInfo : prInfo)\n\n  return url.href\n}\n\nexport default () => {\n  return (\n    <Form form={form} layout=\"vertical\" size=\"large\">\n      <Field\n        title=\"This is a\"\n        name=\"type\"\n        required\n        initialValue=\"Bug Report\"\n        decorator={[FormItem]}\n        component={[Radio.Group, { optionType: 'button' }]}\n        dataSource={[\n          { label: 'Bug Report', value: 'Bug Report' },\n          { label: 'Feature Request', value: 'Feature Request' },\n        ]}\n      />\n      <Field\n        title=\"Title\"\n        name=\"title\"\n        required\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <VoidField name=\"bug-desc\">\n        <Field\n          title=\"Package\"\n          name=\"package\"\n          required\n          decorator={[FormItem]}\n          component={[Select, { showSearch: true }]}\n        />\n        <Field\n          title=\"Version\"\n          description=\"Check if the issue is reproducible with the latest stable version.\"\n          name=\"version\"\n          required\n          decorator={[FormItem]}\n          component={[Select, { showSearch: true }]}\n        />\n\n        <Field\n          title=\"Link to minimal reproduction\"\n          name=\"reproduceLink\"\n          decorator={[FormItem]}\n          component={[Input]}\n          required\n          validator={[\n            'url',\n            (value) => {\n              return /\\/\\/(codesandbox\\.io|github)/.test(value)\n                ? ''\n                : 'Must Be Codesandbox Link or Github Repo'\n            },\n          ]}\n          description={\n            <div>\n              This is Codesandbox templates.If you are:\n              <ul>\n                <li>\n                  React + Antd User:\n                  <ul>\n                    <li>\n                      <a\n                        href=\"https://codesandbox.io/s/formily-react-antd-pure-jsx-omncis\"\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                      >\n                        Pure JSX\n                      </a>\n                    </li>\n                    <li>\n                      <a\n                        href=\"https://codesandbox.io/s/formily-react-antd-markup-schema-fvpevx\"\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                      >\n                        Markup Schema\n                      </a>\n                    </li>\n                    <li>\n                      <a\n                        href=\"https://codesandbox.io/s/formily-react-antd-json-schema-28p0fh\"\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                      >\n                        JSON Schema\n                      </a>\n                    </li>\n                  </ul>\n                </li>\n                <li>\n                  React + Fusion User:\n                  <ul>\n                    <li>\n                      <a\n                        href=\"https://codesandbox.io/s/formily-react-next-pure-jsx-ji9iiu\"\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                      >\n                        Pure JSX\n                      </a>\n                    </li>\n                    <li>\n                      <a\n                        href=\"https://codesandbox.io/s/formily-react-next-markup-schema-i7dm17\"\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                      >\n                        Markup Schema\n                      </a>\n                    </li>\n                    <li>\n                      <a\n                        href=\"https://codesandbox.io/s/formily-react-next-json-schema-1lm35h\"\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                      >\n                        JSON Schema\n                      </a>\n                    </li>\n                  </ul>\n                </li>\n                <li>\n                  Vue3 + ant-design-vue User:\n                  <ul>\n                    <li>\n                      <a\n                        href=\"https://codesandbox.io/s/formily-antd-vue-pure-jsx-pp3gvv\"\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                      >\n                        Pure JSX\n                      </a>\n                    </li>\n                    <li>\n                      <a\n                        href=\"https://codesandbox.io/s/formily-vue-ant-design-vue-markup-schema-donivp\"\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                      >\n                        Markup Schema\n                      </a>\n                    </li>\n                    <li>\n                      <a\n                        href=\"https://codesandbox.io/s/formily-vue-ant-design-vue-json-schema-25g4z1\"\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                      >\n                        JSON Schema\n                      </a>\n                    </li>\n                  </ul>\n                </li>\n              </ul>\n            </div>\n          }\n        />\n        <Field\n          title=\"Step to reproduce\"\n          description=\"Clear and concise reproduction instructions are important for us to be able to triage your issue in a timely manner. Note that you can use Markdown to format lists and code.\"\n          name=\"reproduceStep\"\n          decorator={[FormItem]}\n          component={[MdInput]}\n          required\n        />\n        <Field\n          title=\"What is expected?\"\n          name=\"expected\"\n          decorator={[FormItem]}\n          component={[MdInput]}\n          required\n        />\n        <Field\n          title=\"What is actually happening?\"\n          name=\"actually\"\n          decorator={[FormItem]}\n          component={[MdInput]}\n          required\n        />\n        <Field\n          title=\"Any additional comments? (optional)\"\n          name=\"comment\"\n          decorator={[FormItem]}\n          component={[MdInput]}\n        />\n      </VoidField>\n      <VoidField name=\"feature-desc\">\n        <Field\n          title=\"What problem does this feature solve?\"\n          description={\n            <div>\n              <p>\n                Explain your use case, context, and rationale behind this\n                feature request. More importantly, what is the end user\n                experience you are trying to build that led to the need for this\n                feature?\n              </p>\n              <p>\n                An important design goal of Formily is keeping the API surface\n                small and straightforward. In general, we only consider adding\n                new features that solve a problem that cannot be easily dealt\n                with using existing APIs (i.e. not just an alternative way of\n                doing things that can already be done). The problem should also\n                be common enough to justify the addition.\n              </p>\n            </div>\n          }\n          name=\"feature\"\n          required\n          decorator={[FormItem]}\n          component={[MdInput]}\n        />\n\n        <Field\n          title=\"What does the proposed API look like?\"\n          description=\"Describe how you propose to solve the problem and provide code samples of how the API would work once implemented.\"\n          name=\"api\"\n          required\n          decorator={[FormItem]}\n          component={[MdInput]}\n        />\n      </VoidField>\n      <FormButtonGroup.Sticky align=\"center\">\n        <Submit\n          size=\"large\"\n          onSubmit={(values) => {\n            window.open(createIssueURL(values))\n          }}\n        >\n          Submit\n        </Submit>\n      </FormButtonGroup.Sticky>\n    </Form>\n  )\n}\n```\n"
  },
  {
    "path": "docs/guide/issue-helper.zh-CN.md",
    "content": "# 问题反馈\n\n## 在你开始之前...\n\nIssue List 专用于跟踪错误报告和功能请求。 这意味着我们不接受使用相关的问题。 如果您创建了不符合要求的 Issue，它将立即被关闭。\n\n如果您面临的是使用相关的问题，您可以这样：\n\n- 先阅读介绍和组件文档\n- 确保您已在 FAQ 和 changelog 中搜索了您的问题\n- 在[Discussions](https://github.com/alibaba/formily/discussions)中查找/询问问题\n\n试着先尝试搜索您的问题\n\n它可能已经在开发分支中得到了解决，甚至已经解决。 但是，如果发现旧的，已关闭的问题仍保留在最新版本中，则应使用下面的表单打开一个新的问题，而不是对旧问题进行评论。\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldMount, onFieldReact } from '@formily/core'\nimport { Field, VoidField } from '@formily/react'\nimport {\n  Form,\n  Input,\n  Select,\n  Radio,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport semver from 'semver'\nimport ReactMde from 'react-mde'\nimport * as Showdown from 'showdown'\nimport 'react-mde/lib/styles/css/react-mde-all.css'\n\nconst converter = new Showdown.Converter({\n  tables: true,\n  simplifiedAutoLink: true,\n  strikethrough: true,\n  tasklists: true,\n})\n\nconst MdInput = ({ value, onChange }) => {\n  const [selectedTab, setSelectedTab] = React.useState('write')\n  return (\n    <div style={{ fontSize: 12, lineHeight: 1 }}>\n      <ReactMde\n        value={value}\n        onChange={onChange}\n        selectedTab={selectedTab}\n        onTabChange={setSelectedTab}\n        generateMarkdownPreview={(markdown) =>\n          Promise.resolve(\n            `<div class=\"markdown\" style=\"margin:0 20px;\">${\n              converter.makeHtml(markdown) || ''\n            }</div>`\n          )\n        }\n      />\n    </div>\n  )\n}\n\nconst form = createForm({\n  validateFirst: true,\n  effects() {\n    onFieldMount('version', async (field) => {\n      const { versions: unsort } = await fetch(\n        'https://registry.npmmirror.com/@formily/core'\n      ).then((res) => res.json())\n\n      const versions = Object.keys(unsort).sort((v1, v2) =>\n        semver.gte(v1, v2) ? -1 : 1\n      )\n      field.dataSource = versions.map((version) => ({\n        label: version,\n        value: version,\n      }))\n    })\n    onFieldMount('package', async (field) => {\n      const packages = await fetch(\n        'https://formilyjs.org/.netlify/functions/npm-search?q=@formily'\n      ).then((res) => res.json())\n      field.dataSource = packages.map(({ name }) => {\n        return {\n          label: name,\n          value: name,\n        }\n      })\n    })\n    onFieldReact('bug-desc', (field) => {\n      field.visible = field.query('type').value() === 'Bug Report'\n    })\n    onFieldReact('feature-desc', (field) => {\n      field.visible = field.query('type').value() === 'Feature Request'\n    })\n  },\n})\n\nconst createIssueURL = ({\n  type,\n  title,\n  version,\n  package: pkg,\n  reproduceLink,\n  reproduceStep,\n  expected,\n  actually,\n  comment,\n  feature,\n  api,\n}) => {\n  const url = new URL('https://github.com/alibaba/formily/issues/new')\n\n  const bugInfo = `\n- [ ] I have searched the [issues](https://github.com/alibaba/formily/issues) of this repository and believe that this is not a duplicate.\n\n### Reproduction link\n[![Edit on CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](${\n    reproduceLink || ''\n  })\n\n### Steps to reproduce\n${reproduceStep || ''}\n\n### What is expected?\n${expected || ''}\n\n### What is actually happening?\n${actually || ''}\n\n### Package\n${pkg}@${version}\n\n---\n\n${comment || ''}\n\n<!-- generated by formily-issue-helper. DO NOT REMOVE -->\n`\n\n  const prInfo = `\n- [ ] I have searched the [issues](https://github.com/alibaba/formily/issues) of this repository and believe that this is not a duplicate.\n\n### What problem does this feature solve?\n${feature || ''}\n\n### What does the proposed API look like?\n${api || ''}\n\n\n<!-- generated by formily-issue-helper. DO NOT REMOVE -->\n`\n\n  url.searchParams.set('title', `[${type}] ${title}`)\n  url.searchParams.set('body', type === 'Bug Report' ? bugInfo : prInfo)\n\n  return url.href\n}\n\nexport default () => {\n  return (\n    <Form form={form} layout=\"vertical\" size=\"large\">\n      <Field\n        title=\"这是一个\"\n        name=\"type\"\n        required\n        initialValue=\"Bug Report\"\n        decorator={[FormItem]}\n        component={[Radio.Group, { optionType: 'button' }]}\n        dataSource={[\n          { label: '错误报告', value: 'Bug Report' },\n          { label: '功能要求', value: 'Feature Request' },\n        ]}\n      />\n      <Field\n        title=\"标题\"\n        name=\"title\"\n        required\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <VoidField name=\"bug-desc\">\n        <Field\n          title=\"所在包\"\n          name=\"package\"\n          required\n          decorator={[FormItem]}\n          component={[Select, { showSearch: true }]}\n        />\n        <Field\n          title=\"包版本\"\n          description=\"请检查问题是否存在于最新版本中。\"\n          name=\"version\"\n          required\n          decorator={[FormItem]}\n          component={[Select, { showSearch: true }]}\n        />\n        <Field\n          title=\"重现链接\"\n          name=\"reproduceLink\"\n          decorator={[FormItem]}\n          component={[Input]}\n          required\n          validator={[\n            'url',\n            (value) => {\n              return /\\/\\/(codesandbox\\.io|github)/.test(value)\n                ? ''\n                : '必须是 Codesandbox 链接或者 Github 仓库地址'\n            },\n          ]}\n          description={\n            <div>\n              This is Codesandbox templates.If you are:\n              <ul>\n                <li>\n                  React + Antd User:\n                  <ul>\n                    <li>\n                      <a\n                        href=\"https://codesandbox.io/s/formily-react-antd-pure-jsx-omncis\"\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                      >\n                        Pure JSX\n                      </a>\n                    </li>\n                    <li>\n                      <a\n                        href=\"https://codesandbox.io/s/formily-react-antd-markup-schema-fvpevx\"\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                      >\n                        Markup Schema\n                      </a>\n                    </li>\n                    <li>\n                      <a\n                        href=\"https://codesandbox.io/s/formily-react-antd-json-schema-28p0fh\"\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                      >\n                        JSON Schema\n                      </a>\n                    </li>\n                  </ul>\n                </li>\n                <li>\n                  React + Fusion User:\n                  <ul>\n                    <li>\n                      <a\n                        href=\"https://codesandbox.io/s/formily-react-next-pure-jsx-ji9iiu\"\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                      >\n                        Pure JSX\n                      </a>\n                    </li>\n                    <li>\n                      <a\n                        href=\"https://codesandbox.io/s/formily-react-next-markup-schema-i7dm17\"\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                      >\n                        Markup Schema\n                      </a>\n                    </li>\n                    <li>\n                      <a\n                        href=\"hhttps://codesandbox.io/s/formily-react-next-json-schema-1lm35h\"\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                      >\n                        JSON Schema\n                      </a>\n                    </li>\n                  </ul>\n                </li>\n                <li>\n                  Vue3 + ant-design-vue User:\n                  <ul>\n                    <li>\n                      <a\n                        href=\"https://codesandbox.io/s/formily-antd-vue-pure-jsx-pp3gvv\"\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                      >\n                        Pure JSX\n                      </a>\n                    </li>\n                    <li>\n                      <a\n                        href=\"https://codesandbox.io/s/formily-vue-ant-design-vue-markup-schema-donivp\"\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                      >\n                        Markup Schema\n                      </a>\n                    </li>\n                    <li>\n                      <a\n                        href=\"https://codesandbox.io/s/formily-vue-ant-design-vue-json-schema-25g4z1\"\n                        target=\"_blank\"\n                        rel=\"noreferrer\"\n                      >\n                        JSON Schema\n                      </a>\n                    </li>\n                  </ul>\n                </li>\n              </ul>\n            </div>\n          }\n        />\n        <Field\n          title=\"重现步骤\"\n          description=\"简洁清晰的重现步骤能够帮助我们更迅速地定位问题所在。\"\n          name=\"reproduceStep\"\n          decorator={[FormItem]}\n          component={[MdInput]}\n          required\n        />\n        <Field\n          title=\"期望的结果是什么？\"\n          name=\"expected\"\n          decorator={[FormItem]}\n          component={[MdInput]}\n          required\n        />\n        <Field\n          title=\"实际的结果是什么？\"\n          name=\"actually\"\n          decorator={[FormItem]}\n          component={[MdInput]}\n          required\n        />\n        <Field\n          title=\"补充说明（可选）\"\n          name=\"comment\"\n          decorator={[FormItem]}\n          component={[MdInput]}\n        />\n      </VoidField>\n      <VoidField name=\"feature-desc\">\n        <Field\n          title=\"这个功能解决了什么问题？\"\n          description={\n            <div>\n              <p>\n                请尽可能详尽地说明这个需求的用例和场景。最重要的是：解释清楚是怎样的用户体验需求催生了这个功能上的需求。\n              </p>\n              <p>\n                Formily 的一个重要设计原则是保持 API\n                的简洁和直接。通常来说，我们只考虑添加在现有的 API\n                下无法轻松实现的功能。新功能的用例也应当足够常见。\n              </p>\n            </div>\n          }\n          name=\"feature\"\n          required\n          decorator={[FormItem]}\n          component={[MdInput]}\n        />\n\n        <Field\n          title=\"你期望的 API 是怎样的？\"\n          description=\"描述一下你期望这个新功能的 API 是如何使用的，并提供一些代码示例\"\n          name=\"api\"\n          required\n          decorator={[FormItem]}\n          component={[MdInput]}\n        />\n      </VoidField>\n      <FormButtonGroup.Sticky align=\"center\">\n        <Submit\n          size=\"large\"\n          onSubmit={(values) => {\n            window.open(createIssueURL(values))\n          }}\n        >\n          提交\n        </Submit>\n      </FormButtonGroup.Sticky>\n    </Form>\n  )\n}\n```\n"
  },
  {
    "path": "docs/guide/learn-formily.md",
    "content": "# How to learn Formily\n\n## Study Suggestion\n\nTo describe Formily in one sentence, it is an MVVM form solution that abstracts the form domain model. Therefore, if you want to use Formily in depth, you must learn and understand what Formily's domain model is like and what problems does it solve. After understanding the domain model, it is actually how to consume the view layer of this domain model. This layer only needs to look at the documentation of the specific components.\n\n## About the documentation\n\nBecause Formily’s learning costs are still relatively high, if you want to quickly understand the full picture of Formily, the most important thing is to read the documentation. It's just how to look at the document and where it will be more important. Below we give different document learning routes for different users.\n\n### Entry-level user\n\n- Introduction, because you need to understand Formily's core ideas and whether it is suitable for your business scenario.\n- Quick start, learn how to use Formily in practice from the simplest example.\n- Component documentation/core library documentation, because Formily has already encapsulated most of the out-of-the-box components for you. If you encounter component-related problems, you can just check the component documentation just like looking up a dictionary.\n- Scenario case, starting from the specific scenario, see what is the best practice in this scenario.\n\n### Advanced users\n\n- Digest the core concepts carefully and have a deeper understanding of Formily.\n- Advanced guide, mainly to learn more advanced usage methods, such as custom components, from simple custom components to super complex custom components.\n- Read component documents/core library documents at any time to deepen memory\n- For the details and best practices of custom component development, it is recommended to look directly at the source code of @formily/antd or @formily/next, because this is the boilerplate code and is closely related to the actual business scenario.\n\n### Source code co-builder\n\n- Contribution guide, understand the most basic contribution posture.\n- Read the document, if you find that the document is defective, you can submit a PR to fix it.\n- Read the unit test to understand the implementation details corresponding to each test case. If you find that there are missing test cases, you can submit a PR.\n- Read the source code, if you find a bug in the source code, you can raise a PR.\n\n<Alert type=\"error\">\nPay attention to modify the source code, you must bring unit tests\n</Alert>\n\n## About the question\n\nIf you encounter problems during the development process, it is recommended to use the search function at the top of the document to quickly search for the content of the document and solve it quickly. If you can’t find it, I recommend you to ask questions in the [forum](https://github.com/alibaba/formily/discussions). It is convenient to record. If you encounter a very urgent problem, you can help solve it in the Dingding group @白玄. **It is not recommended to ask various basic questions directly without reading the document, which is very inefficient**\n\n## About the bug\n\nIf you find behaviors that do not meet expectations during the development process and can be reproduced in the smallest case, you can submit an [issue](https://github.com/alibaba/formily/issues) to Formily\nIt is strongly not recommended to record the problem in the issue, which will disrupt the information flow of Issue. At the same time, **be sure to bring the smallest reproducible link address when mentioning Issue**, so that developers can quickly locate the problem and fix it quickly, instead of Find bugs in a bunch of codes.\n\n## About Feature Request\n\nIf during the development process you find that some of Formily's designs are not good, or can be improved better, you can submit your own ideas in the [forum](https://github.com/alibaba/formily/discussions)\n"
  },
  {
    "path": "docs/guide/learn-formily.zh-CN.md",
    "content": "# 如何学习 Formily\n\n## 学习建议\n\nFormily 用一句话来描述，它就是一个抽象了表单领域模型的 MVVM 表单解决方案，所以，如果你想深入使用 Formily，那必须学习并了解 Formily 的领域模型到底是咋样的，它到底解决了哪些问题，了解完领域模型之后，其实就是如何消费这个领域模型的视图层了，这一层就只需要看具体组件的文档即可了。\n\n## 关于文档\n\n因为 Formily 的学习成本还是比较高的，想要快速了解 Formily 的全貌，最重要的还是看文档，只是文档怎么看，从哪里看会比较重要，下面我们针对不同用户给出了不同的文档学习路线。\n\n### 入门级用户\n\n- 引言介绍，因为你要了解 Formily 的核心思路，是否适合你的业务场景。\n- 快速开始，从最简单的例子学习实际 Formily 使用都是怎么使用的。\n- 组件文档/核心库文档，因为 Formily 为你已经封装好了大多数开箱即用的组件，遇到组件相关的问题，就像查字典一样的去查看组件文档即可。\n- 场景案例，从具体的场景出发，看看什么才是这个场景下的最佳实践。\n\n### 进阶级用户\n\n- 仔细消化核心概念，更深入的理解 Formily\n- 进阶指南，主要学习更高级的使用方式，比如自定义组件，从简单自定义组件到超复杂自定义组件\n- 随时查阅组件文档/核心库文档，加深记忆\n- 对于自定义组件开发上的细节问题，最佳实践，推荐直接看@formily/antd 或者@formily/next 的源码，因为这就是样板代码，跟实际业务场景息息相关。\n\n### 源码共建者\n\n- 贡献指南，了解最基本的贡献姿势\n- 阅读文档，如果发现文档有缺陷，可以提 PR 修复\n- 阅读单元测试，了解每个测试用例所对应的实现细节，如果发现有遗漏测试用例，可以提 PR\n- 阅读源码，如果发现源码有 Bug，可以提 PR\n\n<Alert type=\"error\">\n注意修改源码，必须要带上单元测试\n</Alert>\n\n## 关于提问\n\n如果在开发的过程中遇到问题，推荐使用文档上方的搜索功能快速搜索文档内容，快速解决，如果搜索不到的，推荐到 [论坛](https://github.com/alibaba/formily/discussions) 中提问，这里方便记录，如果遇到非常紧急的问题，可以在钉钉群里 @白玄 帮忙解决。**非常不推荐文档都不看，就直接问各种基础问题，这样很低效**\n\n## 关于 Bug\n\n如果在开发过程中发现不符合预期的行为，并能够以最小案例复现的，可以给 Formily 提[Issue](https://github.com/alibaba/formily/issues) ，非常不推荐将问题记录在 issue 里，会打乱 Issue 的信息流，同时一定注意，**提 Issue 的时候要带上最小可复现的链接地址**，方便开发者快速定位问题，快速修复，而不是在一堆代码里找 Bug。\n\n## 关于 Feature Request\n\n如果在开发过程中发现 Formily 的某些设计很不好，或者可以改进的更好的，则可以在 [论坛](https://github.com/alibaba/formily/discussions) 中提交自己的想法。\n"
  },
  {
    "path": "docs/guide/quick-start.md",
    "content": "# Quick Start\n\n## Install Dependencies\n\n### Install the Core Library\n\nTo use Formily, you must use [@formily/core](https://core.formilyjs.org), which is responsible for managing the status of the form, form verification, linkage, and so on.\n\n```bash\n$ npm install --save @formily/core\n```\n\n### Install UI Bridge Library\n\nThe kernel alone is not enough. We also need a UI library to access kernel data to achieve the final form interaction effect. For users of different frameworks, we have different bridge libraries.\n\n**React users**\n\n```bash\n$ npm install --save @formily/react\n```\n\n**Vue users**\n\n```bash\n$ npm install --save @formily/vue\n```\n\n### Install component library\n\nTo quickly implement beautiful forms, we usually need to use industry-leading component libraries, such as [Ant Design](https://ant.design) and [Alibaba Fusion](https://fusion.design). However, these excellent component libraries are not fully covered in some scenes of the form. For example, the detailed preview state is not supported by Ant Design, and some scene-based components are not supported, so Formily is in On top of this, @formily/antd and @formily/next are encapsulated to ensure that users can use it out of the box.\n\n**Ant Design users**\n\n```bash\n$ npm install --save antd moment @formily/antd\n```\n\n**Alibaba Fusion users**\n\n```bash\n$ npm install --save @alifd/next moment @formily/next\n```\n\n## Import Dependencies\n\nUse ES Module import syntax to import dependencies\n\n```ts\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { FormItem, Input } from '@formily/antd'\n```\n\n## Example\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, Field } from '@formily/react'\nimport {\n  FormItem,\n  FormLayout,\n  Input,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout layout=\"vertical\">\n        <Field\n          name=\"input\"\n          title=\"Input box\"\n          required\n          initialValue=\"Hello world\"\n          decorator={[FormItem]}\n          component={[Input]}\n        />\n      </FormLayout>\n      <FormConsumer>\n        {() => (\n          <div\n            style={{\n              marginBottom: 20,\n              padding: 5,\n              border: '1px dashed #666',\n            }}\n          >\n            Real-time response：{form.values.input}\n          </div>\n        )}\n      </FormConsumer>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\nFrom the above examples, we can learn a lot:\n\n- [createForm](https://core.formilyjs.org/api/entry/create-form) is used to create the core domain model of the form, which is the standard ViewModel as the [MVVM](https://core.formilyjs.org/guide/mvvm) design pattern.\n- The [FormProvider](https://react.formilyjs.org/api/components/form-provider) component is used as the entrance to the view layer bridge form model. It has only one parameter, which is to receive the Form instance created by createForm and pass the Form instance to the child component in the form of context.\n- The [FormLayout](https://antd.formilyjs.org/components/form-layout) component is a component used to control the style of [FormItem](https://antd.formilyjs.org/components/form-item) in batches. Here we specify the layout as top and bottom layout, that is, the label is on the top and the component is on the bottom.\n- The [Field](https://react.formilyjs.org/api/components/field) component is a component used to undertake common fields.\n  - The name attribute identifies the path of the field in the final submitted data of the form.\n  - Title attribute, which identifies the title of the field\n    - If the decorator is specified as FormItem, then the title attribute will be received as the label by default in the FormItem component.\n    - If specified as a custom component, the consumer of the title will be taken over by the custom component.\n    - If decorator is not specified, then the title will not be displayed on the UI.\n  - Required attribute, a shorthand for required verification, which identifies that the field is required\n    - If the decorator is specified as FormItem, then an asterisk prompt will automatically appear, and there will be corresponding status feedback if the verification fails. These are the default processing done inside the FormItem.\n    - If the decorator is specified as a custom component, the corresponding UI style needs to be implemented by the custom component implementer.\n    - If decorator is not specified, then required will just block submission, and there will be no UI feedback for verification failure.\n  - InitialValue property, which represents the default value of the field\n  - Decorator attribute, representing the UI decorator of the field, usually we will specify it as FormItem\n    - Note that the decorator attribute is passed in the form of an array, the first parameter represents the specified component type, and the second parameter represents the specified component attribute.\n  - The component attribute, which represents the input control of the field, can be Input or Select, etc.\n    - Note that the component property is passed in the form of an array, the first parameter represents the specified component type, and the second parameter represents the specified component property.\n- The [FormConsumer](https://react.formilyjs.org/api/components/form-consumer) component exists as a responder of a responsive model. Its core is a render props mode. In the callback function as children, all dependencies are automatically collected. If the dependencies change, it will be re-rendered. With the help of FormConsumer, we can Conveniently realize the needs of various calculations and summaries.\n- The [FormButtonGroup](https://antd.formilyjs.org/components/form-button-group) component exists as a form button group container and is mainly responsible for the layout of the buttons.\n- The [Submit](https://antd.formilyjs.org/components/submit) component exists as an action trigger for form submission. In fact, we can also directly use the form.submit method to submit. But the advantage of using Submit is that there is no need to write the onClick event handler on the Button component every time, and it also handles the loading state of the Form. If the onSubmit method returns a Promise and the Promise is pending, the button will automatically enter the loading state.\n"
  },
  {
    "path": "docs/guide/quick-start.zh-CN.md",
    "content": "# 快速开始\n\n## 安装依赖\n\n### 安装内核库\n\n使用 Formily 必须要用到[@formily/core](https://core.formilyjs.org/zh-CN)，它负责管理表单的状态，表单校验，联动等等。\n\n```bash\n$ npm install --save @formily/core\n```\n\n### 安装 UI 桥接库\n\n单纯有了内核还不够，我们还需要一个 UI 库来接入内核数据，用来实现最终的表单交互效果，对于不同框架的用户，我们有不同的桥接库。\n\n**React 用户**\n\n```bash\n$ npm install --save @formily/react\n```\n\n**Vue 用户**\n\n```bash\n$ npm install --save @formily/vue\n```\n\n### 安装组件库\n\n想要快速实现漂亮的表单，通常我们都是需要使用业界优秀的组件库的，比如[Ant Design ](https://ant.design)和 [Alibaba Fusion](https://fusion.design)，但是这些优秀的组件库，在表单的某些场景上覆盖的还是不够全面，比如详情预览态的支持，Ant Design 是不支持的，还有一些场景化的组件它也是不支持的，所以 Formily 在此之上又封装了@formily/antd 和@formily/next，保证用户开箱即用。\n\n**Ant Design 用户**\n\n```bash\n$ npm install --save antd moment @formily/antd\n```\n\n**Alibaba Fusion 用户**\n\n```bash\n$ npm install --save @alifd/next moment @formily/next\n```\n\n## 导入依赖\n\n使用 ES Module import 语法导入依赖即可\n\n```ts\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { FormItem, Input } from '@formily/antd'\n```\n\n## 具体用例\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, Field } from '@formily/react'\nimport {\n  FormItem,\n  FormLayout,\n  Input,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout layout=\"vertical\">\n        <Field\n          name=\"input\"\n          title=\"输入框\"\n          required\n          initialValue=\"Hello world\"\n          decorator={[FormItem]}\n          component={[Input]}\n        />\n      </FormLayout>\n      <FormConsumer>\n        {() => (\n          <div\n            style={{\n              marginBottom: 20,\n              padding: 5,\n              border: '1px dashed #666',\n            }}\n          >\n            实时响应：{form.values.input}\n          </div>\n        )}\n      </FormConsumer>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n从以上例子中，我们可以学到很多东西：\n\n- [createForm](https://core.formilyjs.org/zh-CN/api/entry/create-form)用来创建表单核心领域模型，它是作为[MVVM](https://core.formilyjs.org/guide/mvvm)设计模式的标准 ViewModel\n- [FormProvider](https://react.formilyjs.org/zh-CN/api/components/form-provider)组件是作为视图层桥接表单模型的入口，它只有一个参数，就是接收 createForm 创建出来的 Form 实例，并将 Form 实例以上下文形式传递到子组件中\n- [FormLayout](https://antd.formilyjs.org/zh-CN/components/form-layout)组件是用来批量控制[FormItem](https://antd.formilyjs.org/zh-CN/components/form-item)样式的组件，这里我们指定布局为上下布局，也就是标签在上，组件在下\n- [Field](https://react.formilyjs.org/zh-CN/api/components/field)组件是用来承接普通字段的组件\n  - name 属性，标识字段在表单最终提交数据中的路径\n  - title 属性，标识字段的标题\n    - 如果 decorator 指定为 FormItem，那么在 FormItem 组件中会默认以接收 title 属性作为标签\n    - 如果指定为某个自定义组件，那么 title 的消费方则由自定义组件来承接\n    - 如果不指定 decorator，那么 title 则不会显示在 UI 上\n  - required 属性，必填校验的极简写法，标识该字段必填\n    - 如果 decorator 指定为 FormItem，那么会自动出现星号提示，同时校验失败也会有对应的状态反馈，这些都是 FormItem 内部做的默认处理\n    - 如果 decorator 指定为自定义组件，那么对应的 UI 样式则需要自定义组件实现方自己实现\n    - 如果不指定 decorator，那么 required 只是会阻塞提交，校验失败不会有任何 UI 反馈。\n  - initialValue 属性，代表字段的默认值\n  - decorator 属性，代表字段的 UI 装饰器，通常我们都会指定为 FormItem\n    - 注意 decorator 属性传递的是数组形式，第一个参数代表指定组件类型，第二个参数代表指定组件属性\n  - component 属性，代表字段的输入控件，可以是 Input，也可以是 Select，等等\n    - 注意 component 属性传递的是数组形式，第一个参数代表指定组件类型，第二个参数代表指定组件属性\n- [FormConsumer](https://react.formilyjs.org/zh-CN/api/components/form-consumer)组件是作为响应式模型的响应器而存在，它核心是一个 render props 模式，在作为 children 的回调函数中，会自动收集所有依赖，如果依赖发生变化，则会重新渲染，借助 FormConsumer 我们可以很方便的实现各种计算汇总的需求\n- [FormButtonGroup](https://antd.formilyjs.org/zh-CN/components/form-button-group)组件作为表单按钮组容器而存在，主要负责按钮的布局\n- [Submit](https://antd.formilyjs.org/zh-CN/components/submit)组件作为表单提交的动作触发器而存在，其实我们也可以直接使用 form.submit 方法进行提交，但是使用 Submit 的好处是不需要每次都在 Button 组件上写 onClick 事件处理器，同时它还处理了 Form 的 loading 状态，如果 onSubmit 方法返回一个 Promise，且 Promise 正在 pending 状态，那么按钮会自动进入 loading 状态\n"
  },
  {
    "path": "docs/guide/scenes/VerifyCode.tsx",
    "content": "import React, { useState } from 'react'\nimport { Input, Button } from 'antd'\n\ninterface IVerifyCodeProps {\n  value?: any\n  onChange?: (value: any) => void\n  readyPost?: boolean\n  phoneNumber?: number\n  style?: React.CSSProperties\n}\n\nexport const VerifyCode: React.FC<React.PropsWithChildren<IVerifyCodeProps>> =\n  ({ value, onChange, readyPost, phoneNumber, ...props }) => {\n    const [lastTime, setLastTime] = useState(0)\n\n    const counting = (time = 20) => {\n      if (time < 0) return\n      setLastTime(time)\n      setTimeout(() => {\n        counting(time - 1)\n      }, 1000)\n    }\n\n    return (\n      <div\n        style={{ display: 'inline-flex', width: '100%', alignItems: 'center' }}\n      >\n        <Input\n          {...props}\n          style={{ marginRight: 5, ...props.style }}\n          value={value}\n          onChange={onChange}\n        />\n        <div\n          style={{\n            flexShrink: 0,\n            color: '#999',\n            width: 100,\n            height: 35,\n            display: 'flex',\n            alignItems: 'center',\n            justifyContent: 'center',\n          }}\n        >\n          {lastTime === 0 && (\n            <Button\n              disabled={!readyPost}\n              block\n              onClick={() => {\n                if (phoneNumber) {\n                  console.log(`post code by phone number ${phoneNumber}`)\n                }\n                counting()\n              }}\n            >\n              发送验证码\n            </Button>\n          )}\n          {lastTime > 0 && <span>剩余{lastTime}秒</span>}\n        </div>\n      </div>\n    )\n  }\n"
  },
  {
    "path": "docs/guide/scenes/dialog-drawer.md",
    "content": "# Dialog and Drawers\n\nMainly use the [FormDialog](https://antd.formilyjs.org/components/form-dialog) function and [FormDrawer]() function in [@formily/antd](https://antd.formilyjs.org) or [@formily/next](https://fusion.formilyjs.org)\n"
  },
  {
    "path": "docs/guide/scenes/dialog-drawer.zh-CN.md",
    "content": "# 弹窗与抽屉\n\n主要使用[@formily/antd](https://antd.formilyjs.org/zh-CN) 或 [@formily/next](https://fusion.formilyjs.org/zh-CN) 中的[FormDialog](https://antd.formilyjs.org/zh-CN/components/form-dialog)函数 和 [FormDrawer](https://antd.formilyjs.org/zh-CN/components/form-drawer)函数\n"
  },
  {
    "path": "docs/guide/scenes/edit-detail.md",
    "content": "# Edit Details\n\n## Edit\n\n#### Markup Schema Cases\n\n```tsx\nimport React, { useState, useEffect } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  FormLayout,\n  Input,\n  Select,\n  Cascader,\n  DatePicker,\n  Submit,\n  FormGrid,\n  Upload,\n  ArrayItems,\n  Editable,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { action } from '@formily/reactive'\nimport { Card, Button, Spin } from 'antd'\nimport { UploadOutlined } from '@ant-design/icons'\n\nconst form = createForm({\n  validateFirst: true,\n})\n\nconst IDUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button icon={<UploadOutlined />}>Upload a copy</Button>\n    </Upload>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormGrid,\n    FormLayout,\n    Input,\n    DatePicker,\n    Cascader,\n    Select,\n    IDUpload,\n    ArrayItems,\n    Editable,\n  },\n  scope: {\n    fetchAddress: (field) => {\n      const transform = (data = {}) => {\n        return Object.entries(data).reduce((buf, [key, value]) => {\n          if (typeof value === 'string')\n            return buf.concat({\n              label: value,\n              value: key,\n            })\n          const { name, code, cities, districts } = value\n          const _cities = transform(cities)\n          const _districts = transform(districts)\n          return buf.concat({\n            label: name,\n            value: code,\n            children: _cities.length\n              ? _cities\n              : _districts.length\n              ? _districts\n              : undefined,\n          })\n        }, [])\n      }\n\n      field.loading = true\n      fetch('//unpkg.com/china-location/dist/location.json')\n        .then((res) => res.json())\n        .then(\n          action.bound((data) => {\n            field.dataSource = transform(data)\n            field.loading = false\n          })\n        )\n    },\n  },\n})\n\nexport default () => {\n  const [loading, setLoading] = useState(true)\n  useEffect(() => {\n    setTimeout(() => {\n      form.setInitialValues({\n        username: 'Aston Martin',\n        firstName: 'Aston',\n        lastName: 'Martin',\n        email: 'aston_martin@aston.com',\n        gender: 1,\n        birthday: '1836-01-03',\n        address: ['110000', '110000', '110101'],\n        idCard: [\n          {\n            name: 'this is image',\n            thumbUrl:\n              'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n            uid: 'rc-upload-1615825692847-2',\n            url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n          },\n        ],\n        contacts: [\n          {\n            name: 'Zhang San',\n            phone: '13245633378',\n            email: 'zhangsan@gmail.com',\n          },\n          { name: 'Li Si', phone: '16873452678', email: 'lisi@gmail.com' },\n        ],\n      })\n      setLoading(false)\n    }, 2000)\n  }, [])\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card title=\"Edit User\" style={{ width: 620 }}>\n        <Spin spinning={loading}>\n          <Form\n            form={form}\n            labelCol={5}\n            wrapperCol={16}\n            onAutoSubmit={console.log}\n          >\n            <SchemaField>\n              <SchemaField.String\n                name=\"username\"\n                title=\"Username\"\n                required\n                x-decorator=\"FormItem\"\n                x-component=\"Input\"\n              />\n              <SchemaField.Void\n                title=\"Name\"\n                x-decorator=\"FormItem\"\n                x-decorator-props={{\n                  asterisk: true,\n                  feedbackLayout: 'none',\n                }}\n                x-component=\"FormGrid\"\n              >\n                <SchemaField.String\n                  name=\"firstName\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                  x-component-props={{\n                    placeholder: 'firstName',\n                  }}\n                  required\n                />\n                <SchemaField.String\n                  name=\"lastName\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                  x-component-props={{\n                    placeholder: 'lastname',\n                  }}\n                  required\n                />\n              </SchemaField.Void>\n              <SchemaField.String\n                name=\"email\"\n                title=\"Email\"\n                required\n                x-validator=\"email\"\n                x-decorator=\"FormItem\"\n                x-component=\"Input\"\n              />\n              <SchemaField.String\n                name=\"gender\"\n                title=\"Gender\"\n                x-decorator=\"FormItem\"\n                x-component=\"Select\"\n                enum={[\n                  {\n                    label: 'male',\n                    value: 1,\n                  },\n                  {\n                    label: 'female',\n                    value: 2,\n                  },\n                  {\n                    label: 'third gender',\n                    value: 3,\n                  },\n                ]}\n                required\n              />\n              <SchemaField.String\n                name=\"birthday\"\n                title=\"Birthday\"\n                required\n                x-decorator=\"FormItem\"\n                x-component=\"DatePicker\"\n              />\n              <SchemaField.String\n                name=\"address\"\n                title=\"Address\"\n                required\n                x-decorator=\"FormItem\"\n                x-component=\"Cascader\"\n                x-reactions=\"{{fetchAddress}}\"\n              />\n              <SchemaField.String\n                name=\"idCard\"\n                title=\"ID\"\n                required\n                x-decorator=\"FormItem\"\n                x-component=\"IDUpload\"\n              />\n              <SchemaField.Array\n                name=\"contacts\"\n                title=\"Contacts\"\n                required\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems\"\n              >\n                <SchemaField.Object x-component=\"ArrayItems.Item\">\n                  <SchemaField.Void\n                    x-decorator=\"FormItem\"\n                    x-component=\"ArrayItems.SortHandle\"\n                  />\n                  <SchemaField.Void\n                    name=\"popover\"\n                    title=\"Contact Informations\"\n                    x-decorator=\"Editable.Popover\"\n                    x-component=\"FormLayout\"\n                    x-component-props={{\n                      layout: 'vertical',\n                    }}\n                    x-reactions={[\n                      {\n                        fulfill: {\n                          schema: {\n                            title: '{{$self.query(\".name\").value() }}',\n                          },\n                        },\n                      },\n                    ]}\n                  >\n                    <SchemaField.String\n                      name=\"name\"\n                      required\n                      title=\"Name\"\n                      x-decorator=\"FormItem\"\n                      x-component=\"Input\"\n                      x-component-props={{\n                        style: {\n                          width: 300,\n                        },\n                      }}\n                    />\n                    <SchemaField.String\n                      name=\"email\"\n                      title=\"Email\"\n                      x-validator={[{ required: true }, 'email']}\n                      x-decorator=\"FormItem\"\n                      x-component=\"Input\"\n                      x-component-props={{\n                        style: {\n                          width: 300,\n                        },\n                      }}\n                    />\n                    <SchemaField.String\n                      name=\"phone\"\n                      required\n                      title=\"Phone Number\"\n                      x-validator=\"phone\"\n                      x-decorator=\"FormItem\"\n                      x-component=\"Input\"\n                      x-component-props={{\n                        style: {\n                          width: 300,\n                        },\n                      }}\n                    />\n                  </SchemaField.Void>\n                  <SchemaField.Void\n                    x-decorator=\"FormItem\"\n                    x-component=\"ArrayItems.Remove\"\n                  />\n                </SchemaField.Object>\n                <SchemaField.Void\n                  x-component=\"ArrayItems.Addition\"\n                  title=\"Add Contact\"\n                />\n              </SchemaField.Array>\n            </SchemaField>\n            <FormButtonGroup.FormItem>\n              <Submit block size=\"large\">\n                Submit\n              </Submit>\n            </FormButtonGroup.FormItem>\n          </Form>\n        </Spin>\n      </Card>\n    </div>\n  )\n}\n```\n\n#### JSON Schema Cases\n\n```tsx\nimport React, { useState, useEffect } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  FormLayout,\n  Input,\n  Select,\n  Cascader,\n  DatePicker,\n  Submit,\n  FormGrid,\n  Upload,\n  ArrayItems,\n  Editable,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { action } from '@formily/reactive'\nimport { Card, Button, Spin } from 'antd'\nimport { UploadOutlined } from '@ant-design/icons'\n\nconst form = createForm({\n  validateFirst: true,\n})\n\nconst IDUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button icon={<UploadOutlined />}>Upload a copy</Button>\n    </Upload>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormGrid,\n    FormLayout,\n    Input,\n    DatePicker,\n    Cascader,\n    Select,\n    IDUpload,\n    ArrayItems,\n    Editable,\n  },\n  scope: {\n    fetchAddress: (field) => {\n      const transform = (data = {}) => {\n        return Object.entries(data).reduce((buf, [key, value]) => {\n          if (typeof value === 'string')\n            return buf.concat({\n              label: value,\n              value: key,\n            })\n          const { name, code, cities, districts } = value\n          const _cities = transform(cities)\n          const _districts = transform(districts)\n          return buf.concat({\n            label: name,\n            value: code,\n            children: _cities.length\n              ? _cities\n              : _districts.length\n              ? _districts\n              : undefined,\n          })\n        }, [])\n      }\n\n      field.loading = true\n      fetch('//unpkg.com/china-location/dist/location.json')\n        .then((res) => res.json())\n        .then(\n          action.bound((data) => {\n            field.dataSource = transform(data)\n            field.loading = false\n          })\n        )\n    },\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    username: {\n      type: 'string',\n      title: 'Username',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    name: {\n      type: 'void',\n      title: 'Name',\n      'x-decorator': 'FormItem',\n      'x-decorator-props': {\n        asterisk: true,\n        feedbackLayout: 'none',\n      },\n      'x-component': 'FormGrid',\n      properties: {\n        firstName: {\n          type: 'string',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          'x-component-props': {\n            placeholder: 'firstName',\n          },\n        },\n        lastName: {\n          type: 'string',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          'x-component-props': {\n            placeholder: 'lastname',\n          },\n        },\n      },\n    },\n    email: {\n      type: 'string',\n      title: 'Email',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-validator': 'email',\n    },\n    gender: {\n      type: 'string',\n      title: 'Gender',\n      enum: [\n        {\n          label: 'male',\n          value: 1,\n        },\n        {\n          label: 'female',\n          value: 2,\n        },\n        {\n          label: 'third gender',\n          value: 3,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n    },\n    birthday: {\n      type: 'string',\n      required: true,\n      title: 'Birthday',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n    },\n    address: {\n      type: 'string',\n      required: true,\n      title: 'Address',\n      'x-decorator': 'FormItem',\n      'x-component': 'Cascader',\n      'x-reactions': '{{fetchAddress}}',\n    },\n    idCard: {\n      type: 'string',\n      required: true,\n      title: 'ID',\n      'x-decorator': 'FormItem',\n      'x-component': 'IDUpload',\n    },\n    contacts: {\n      type: 'array',\n      required: true,\n      title: 'Contacts',\n      'x-decorator': 'FormItem',\n      'x-component': 'ArrayItems',\n      items: {\n        type: 'object',\n        'x-component': 'ArrayItems.Item',\n        properties: {\n          sort: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.SortHandle',\n          },\n          popover: {\n            type: 'void',\n            title: 'Contact Informations',\n            'x-decorator': 'Editable.Popover',\n            'x-component': 'FormLayout',\n            'x-component-props': {\n              layout: 'vertical',\n            },\n            'x-reactions': [\n              {\n                fulfill: {\n                  schema: {\n                    title: '{{$self.query(\".name\").value() }}',\n                  },\n                },\n              },\n            ],\n            properties: {\n              name: {\n                type: 'string',\n                title: 'Name',\n                required: true,\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-component-props': {\n                  style: {\n                    width: 300,\n                  },\n                },\n              },\n              email: {\n                type: 'string',\n                title: 'Email',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-validator': [{ required: true }, 'email'],\n                'x-component-props': {\n                  style: {\n                    width: 300,\n                  },\n                },\n              },\n              phone: {\n                type: 'string',\n                title: 'Phone Number',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-validator': [{ required: true }, 'phone'],\n                'x-component-props': {\n                  style: {\n                    width: 300,\n                  },\n                },\n              },\n            },\n          },\n          remove: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.Remove',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add Contact',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  const [loading, setLoading] = useState(true)\n  useEffect(() => {\n    setTimeout(() => {\n      form.setInitialValues({\n        username: 'Aston Martin',\n        firstName: 'Aston',\n        lastName: 'Martin',\n        email: 'aston_martin@aston.com',\n        gender: 1,\n        birthday: '1836-01-03',\n        address: ['110000', '110000', '110101'],\n        idCard: [\n          {\n            name: 'this is image',\n            thumbUrl:\n              'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n            uid: 'rc-upload-1615825692847-2',\n            url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n          },\n        ],\n        contacts: [\n          {\n            name: 'Zhang San',\n            phone: '13245633378',\n            email: 'zhangsan@gmail.com',\n          },\n          { name: 'Li Si', phone: '16873452678', email: 'lisi@gmail.com' },\n        ],\n      })\n      setLoading(false)\n    }, 2000)\n  }, [])\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card title=\"Edit User\" style={{ width: 620 }}>\n        <Spin spinning={loading}>\n          <Form\n            form={form}\n            labelCol={5}\n            wrapperCol={16}\n            onAutoSubmit={console.log}\n          >\n            <SchemaField schema={schema} />\n            <FormButtonGroup.FormItem>\n              <Submit block size=\"large\">\n                Submit\n              </Submit>\n            </FormButtonGroup.FormItem>\n          </Form>\n        </Spin>\n      </Card>\n    </div>\n  )\n}\n```\n\n#### Pure JSX Cases\n\n```tsx\nimport React, { useState, useEffect } from 'react'\nimport { createForm } from '@formily/core'\nimport { Field, VoidField, ArrayField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  FormLayout,\n  Input,\n  Select,\n  Cascader,\n  DatePicker,\n  Submit,\n  FormGrid,\n  Upload,\n  ArrayBase,\n  Editable,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { action } from '@formily/reactive'\nimport { Card, Button, Spin } from 'antd'\nimport { UploadOutlined } from '@ant-design/icons'\nimport './index.less'\n\nconst form = createForm({\n  validateFirst: true,\n})\n\nconst IDUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button icon={<UploadOutlined />}>Upload a copy</Button>\n    </Upload>\n  )\n}\n\nconst fetchAddress = (field) => {\n  const transform = (data = {}) => {\n    return Object.entries(data).reduce((buf, [key, value]) => {\n      if (typeof value === 'string')\n        return buf.concat({\n          label: value,\n          value: key,\n        })\n      const { name, code, cities, districts } = value\n      const _cities = transform(cities)\n      const _districts = transform(districts)\n      return buf.concat({\n        label: name,\n        value: code,\n        children: _cities.length\n          ? _cities\n          : _districts.length\n          ? _districts\n          : undefined,\n      })\n    }, [])\n  }\n\n  field.loading = true\n  fetch('//unpkg.com/china-location/dist/location.json')\n    .then((res) => res.json())\n    .then(\n      action.bound((data) => {\n        field.dataSource = transform(data)\n        field.loading = false\n      })\n    )\n}\n\nexport default () => {\n  const [loading, setLoading] = useState(true)\n  useEffect(() => {\n    setTimeout(() => {\n      form.setInitialValues({\n        username: 'Aston Martin',\n        firstName: 'Aston',\n        lastName: 'Martin',\n        email: 'aston_martin@aston.com',\n        gender: 1,\n        birthday: '1836-01-03',\n        address: ['110000', '110000', '110101'],\n        idCard: [\n          {\n            name: 'this is image',\n            thumbUrl:\n              'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n            uid: 'rc-upload-1615825692847-2',\n            url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n          },\n        ],\n        contacts: [\n          {\n            name: 'Zhang San',\n            phone: '13245633378',\n            email: 'zhangsan@gmail.com',\n          },\n          { name: 'Li Si', phone: '16873452678', email: 'lisi@gmail.com' },\n        ],\n      })\n      setLoading(false)\n    }, 2000)\n  }, [])\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card title=\"Edit User\" style={{ width: 620 }}>\n        <Spin spinning={loading}>\n          <Form\n            form={form}\n            labelCol={5}\n            wrapperCol={16}\n            onAutoSubmit={console.log}\n          >\n            <Field\n              name=\"username\"\n              title=\"Username\"\n              required\n              decorator={[FormItem]}\n              component={[Input]}\n            />\n            <VoidField\n              name=\"name\"\n              title=\"Name\"\n              decorator={[\n                FormItem,\n                {\n                  asterisk: true,\n                  feedbackLayout: 'none',\n                },\n              ]}\n              component={[FormGrid]}\n            >\n              <Field\n                name=\"firstName\"\n                decorator={[FormItem]}\n                component={[\n                  Input,\n                  {\n                    placeholder: 'firstName',\n                  },\n                ]}\n                required\n              />\n              <Field\n                name=\"lastName\"\n                decorator={[FormItem]}\n                component={[\n                  Input,\n                  {\n                    placeholder: 'lastname',\n                  },\n                ]}\n                required\n              />\n            </VoidField>\n            <Field\n              name=\"email\"\n              title=\"Email\"\n              required\n              validator=\"email\"\n              decorator={[FormItem]}\n              component={[Input]}\n            />\n            <Field\n              name=\"gender\"\n              title=\"Gender\"\n              decorator={[FormItem]}\n              component={[Select]}\n              dataSource={[\n                {\n                  label: 'male',\n                  value: 1,\n                },\n                {\n                  label: 'female',\n                  value: 2,\n                },\n                {\n                  label: 'third gender',\n                  value: 3,\n                },\n              ]}\n              required\n            />\n            <Field\n              name=\"birthday\"\n              title=\"Birthday\"\n              required\n              decorator={[FormItem]}\n              component={[DatePicker]}\n            />\n            <Field\n              name=\"address\"\n              title=\"Address\"\n              required\n              decorator={[FormItem]}\n              component={[Cascader]}\n              reactions={fetchAddress}\n            />\n            <Field\n              name=\"idCard\"\n              title=\"ID\"\n              required\n              decorator={[FormItem]}\n              component={[IDUpload]}\n            />\n            <ArrayField name=\"contacts\" title=\"Contacts\" decorator={[FormItem]}>\n              {(field) => (\n                <ArrayBase>\n                  {field.value?.map((item, index) => (\n                    <div key={index} className=\"array-items-item\">\n                      <Field\n                        name={`${index}`}\n                        title=\"Contact Informations\"\n                        component={[Editable.Popover]}\n                        reactions={(field) => {\n                          field.title =\n                            field.query('.[].name').value() || field.title\n                        }}\n                      >\n                        <VoidField\n                          name=\"layout\"\n                          component={[FormLayout, { layout: 'vertical' }]}\n                        >\n                          <Field\n                            name=\"name\"\n                            title=\"Name\"\n                            required\n                            decorator={[FormItem]}\n                            component={[\n                              Input,\n                              {\n                                style: {\n                                  width: 300,\n                                },\n                              },\n                            ]}\n                          />\n                          <Field\n                            name=\"email\"\n                            title=\"Email\"\n                            required\n                            validator=\"email\"\n                            decorator={[FormItem]}\n                            component={[\n                              Input,\n                              {\n                                style: {\n                                  width: 300,\n                                },\n                              },\n                            ]}\n                          />\n                          <Field\n                            name=\"phone\"\n                            title=\"Phone Number\"\n                            required\n                            validator=\"phone\"\n                            decorator={[FormItem]}\n                            component={[\n                              Input,\n                              {\n                                style: {\n                                  width: 300,\n                                },\n                              },\n                            ]}\n                          />\n                        </VoidField>\n                      </Field>\n                      <FormItem.BaseItem>\n                        <ArrayBase.Remove index={index} />\n                        <ArrayBase.MoveDown index={index} />\n                        <ArrayBase.MoveUp index={index} />\n                      </FormItem.BaseItem>\n                    </div>\n                  ))}\n                  <ArrayBase.Addition title=\"Add Contact\" />\n                </ArrayBase>\n              )}\n            </ArrayField>\n            <FormButtonGroup.FormItem>\n              <Submit block size=\"large\">\n                Submit\n              </Submit>\n            </FormButtonGroup.FormItem>\n          </Form>\n        </Spin>\n      </Card>\n    </div>\n  )\n}\n```\n\n## Details\n\n#### Markup Schema Cases\n\n```tsx\nimport React, { useState, useEffect } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, useField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  FormLayout,\n  Input,\n  Select,\n  Cascader,\n  DatePicker,\n  FormGrid,\n  Upload,\n  ArrayItems,\n  Editable,\n  PreviewText,\n} from '@formily/antd'\nimport { action } from '@formily/reactive'\nimport { Card, Button, Spin } from 'antd'\nimport { UploadOutlined } from '@ant-design/icons'\n\nconst form = createForm({\n  readPretty: true,\n  validateFirst: true,\n})\n\nconst IDUpload = (props) => {\n  const field = useField()\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      {field.editable && (\n        <Button icon={<UploadOutlined />}>Upload a copy</Button>\n      )}\n    </Upload>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormGrid,\n    FormLayout,\n    Input,\n    DatePicker,\n    Cascader,\n    Select,\n    IDUpload,\n    ArrayItems,\n    Editable,\n  },\n  scope: {\n    fetchAddress: (field) => {\n      const transform = (data = {}) => {\n        return Object.entries(data).reduce((buf, [key, value]) => {\n          if (typeof value === 'string')\n            return buf.concat({\n              label: value,\n              value: key,\n            })\n          const { name, code, cities, districts } = value\n          const _cities = transform(cities)\n          const _districts = transform(districts)\n          return buf.concat({\n            label: name,\n            value: code,\n            children: _cities.length\n              ? _cities\n              : _districts.length\n              ? _districts\n              : undefined,\n          })\n        }, [])\n      }\n\n      field.loading = true\n      fetch('//unpkg.com/china-location/dist/location.json')\n        .then((res) => res.json())\n        .then(\n          action.bound((data) => {\n            field.dataSource = transform(data)\n            field.loading = false\n          })\n        )\n    },\n  },\n})\n\nexport default () => {\n  const [loading, setLoading] = useState(true)\n  useEffect(() => {\n    setTimeout(() => {\n      form.setInitialValues({\n        username: 'Aston Martin',\n        firstName: 'Aston',\n        lastName: 'Martin',\n        email: 'aston_martin@aston.com',\n        gender: 1,\n        birthday: '1836-01-03',\n        address: ['110000', '110000', '110101'],\n        idCard: [\n          {\n            name: 'this is image',\n            thumbUrl:\n              'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n            uid: 'rc-upload-1615825692847-2',\n            url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n          },\n        ],\n        contacts: [\n          {\n            name: 'Zhang San',\n            phone: '13245633378',\n            email: 'zhangsan@gmail.com',\n          },\n          { name: 'Li Si', phone: '16873452678', email: 'lisi@gmail.com' },\n        ],\n      })\n      setLoading(false)\n    }, 2000)\n  }, [])\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <PreviewText.Placeholder value=\"-\">\n        <Card title=\"User Details\" style={{ width: 620 }}>\n          <Spin spinning={loading}>\n            <Form\n              form={form}\n              labelCol={5}\n              wrapperCol={16}\n              onAutoSubmit={console.log}\n            >\n              <SchemaField>\n                <SchemaField.String\n                  name=\"username\"\n                  title=\"Username\"\n                  required\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.Void\n                  title=\"Name\"\n                  x-decorator=\"FormItem\"\n                  x-decorator-props={{\n                    feedbackLayout: 'none',\n                  }}\n                  x-component=\"FormGrid\"\n                >\n                  <SchemaField.String\n                    name=\"firstName\"\n                    x-decorator=\"FormItem\"\n                    x-component=\"Input\"\n                    x-component-props={{\n                      placeholder: 'firstName',\n                    }}\n                    required\n                  />\n                  <SchemaField.String\n                    name=\"lastName\"\n                    x-decorator=\"FormItem\"\n                    x-component=\"Input\"\n                    x-component-props={{\n                      placeholder: 'lastname',\n                    }}\n                    required\n                  />\n                </SchemaField.Void>\n                <SchemaField.String\n                  name=\"email\"\n                  title=\"Email\"\n                  required\n                  x-validator=\"email\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"gender\"\n                  title=\"Gender\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Select\"\n                  enum={[\n                    {\n                      label: 'male',\n                      value: 1,\n                    },\n                    {\n                      label: 'female',\n                      value: 2,\n                    },\n                    {\n                      label: 'third gender',\n                      value: 3,\n                    },\n                  ]}\n                  required\n                />\n                <SchemaField.String\n                  name=\"birthday\"\n                  title=\"Birthday\"\n                  required\n                  x-decorator=\"FormItem\"\n                  x-component=\"DatePicker\"\n                />\n                <SchemaField.String\n                  name=\"address\"\n                  title=\"Address\"\n                  required\n                  x-decorator=\"FormItem\"\n                  x-component=\"Cascader\"\n                  x-reactions=\"{{fetchAddress}}\"\n                />\n                <SchemaField.String\n                  name=\"idCard\"\n                  title=\"ID\"\n                  required\n                  x-decorator=\"FormItem\"\n                  x-component=\"IDUpload\"\n                />\n                <SchemaField.Array\n                  name=\"contacts\"\n                  title=\"Contacts\"\n                  required\n                  x-decorator=\"FormItem\"\n                  x-component=\"ArrayItems\"\n                >\n                  <SchemaField.Object x-component=\"ArrayItems.Item\">\n                    <SchemaField.Void\n                      x-decorator=\"FormItem\"\n                      x-component=\"ArrayItems.SortHandle\"\n                    />\n                    <SchemaField.Void\n                      name=\"popover\"\n                      title=\"Contact Informations\"\n                      x-decorator=\"Editable.Popover\"\n                      x-component=\"FormLayout\"\n                      x-component-props={{\n                        layout: 'vertical',\n                      }}\n                      x-reactions={[\n                        {\n                          fulfill: {\n                            schema: {\n                              title: '{{$self.query(\".name\").value() }}',\n                            },\n                          },\n                        },\n                      ]}\n                    >\n                      <SchemaField.String\n                        name=\"name\"\n                        required\n                        title=\"Name\"\n                        x-decorator=\"FormItem\"\n                        x-component=\"Input\"\n                        x-component-props={{\n                          style: {\n                            width: 300,\n                          },\n                        }}\n                      />\n                      <SchemaField.String\n                        name=\"email\"\n                        title=\"Email\"\n                        x-validator={[{ required: true }, 'email']}\n                        x-decorator=\"FormItem\"\n                        x-component=\"Input\"\n                        x-component-props={{\n                          style: {\n                            width: 300,\n                          },\n                        }}\n                      />\n                      <SchemaField.String\n                        name=\"phone\"\n                        required\n                        title=\"Phone Number\"\n                        x-validator=\"phone\"\n                        x-decorator=\"FormItem\"\n                        x-component=\"Input\"\n                        x-component-props={{\n                          style: {\n                            width: 300,\n                          },\n                        }}\n                      />\n                    </SchemaField.Void>\n                    <SchemaField.Void\n                      x-decorator=\"FormItem\"\n                      x-component=\"ArrayItems.Remove\"\n                    />\n                  </SchemaField.Object>\n                  <SchemaField.Void\n                    x-component=\"ArrayItems.Addition\"\n                    title=\"Add Contact\"\n                  />\n                </SchemaField.Array>\n              </SchemaField>\n            </Form>\n          </Spin>\n        </Card>\n      </PreviewText.Placeholder>\n    </div>\n  )\n}\n```\n\n#### JSON Schema Cases\n\n```tsx\nimport React, { useState, useEffect } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, useField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  FormLayout,\n  Input,\n  Select,\n  Cascader,\n  DatePicker,\n  FormGrid,\n  Upload,\n  ArrayItems,\n  Editable,\n  PreviewText,\n} from '@formily/antd'\nimport { action } from '@formily/reactive'\nimport { Card, Button, Spin } from 'antd'\nimport { UploadOutlined } from '@ant-design/icons'\n\nconst form = createForm({\n  readPretty: true,\n  validateFirst: true,\n})\n\nconst IDUpload = (props) => {\n  const field = useField()\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      {field.editable && (\n        <Button icon={<UploadOutlined />}>Upload a copy</Button>\n      )}\n    </Upload>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormGrid,\n    FormLayout,\n    Input,\n    DatePicker,\n    Cascader,\n    Select,\n    IDUpload,\n    ArrayItems,\n    Editable,\n  },\n  scope: {\n    fetchAddress: (field) => {\n      const transform = (data = {}) => {\n        return Object.entries(data).reduce((buf, [key, value]) => {\n          if (typeof value === 'string')\n            return buf.concat({\n              label: value,\n              value: key,\n            })\n          const { name, code, cities, districts } = value\n          const _cities = transform(cities)\n          const _districts = transform(districts)\n          return buf.concat({\n            label: name,\n            value: code,\n            children: _cities.length\n              ? _cities\n              : _districts.length\n              ? _districts\n              : undefined,\n          })\n        }, [])\n      }\n\n      field.loading = true\n      fetch('//unpkg.com/china-location/dist/location.json')\n        .then((res) => res.json())\n        .then(\n          action.bound((data) => {\n            field.dataSource = transform(data)\n            field.loading = false\n          })\n        )\n    },\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    username: {\n      type: 'string',\n      title: 'Username',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    name: {\n      type: 'void',\n      title: 'Name',\n      'x-decorator': 'FormItem',\n      'x-decorator-props': {\n        asterisk: true,\n        feedbackLayout: 'none',\n      },\n      'x-component': 'FormGrid',\n      properties: {\n        firstName: {\n          type: 'string',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          'x-component-props': {\n            placeholder: 'firstName',\n          },\n        },\n        lastName: {\n          type: 'string',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          'x-component-props': {\n            placeholder: 'lastname',\n          },\n        },\n      },\n    },\n    email: {\n      type: 'string',\n      title: 'Email',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-validator': 'email',\n    },\n    gender: {\n      type: 'string',\n      title: 'Gender',\n      enum: [\n        {\n          label: 'male',\n          value: 1,\n        },\n        {\n          label: 'female',\n          value: 2,\n        },\n        {\n          label: 'third gender',\n          value: 3,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n    },\n    birthday: {\n      type: 'string',\n      required: true,\n      title: 'Birthday',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n    },\n    address: {\n      type: 'string',\n      required: true,\n      title: 'Address',\n      'x-decorator': 'FormItem',\n      'x-component': 'Cascader',\n      'x-reactions': '{{fetchAddress}}',\n    },\n    idCard: {\n      type: 'string',\n      required: true,\n      title: 'ID',\n      'x-decorator': 'FormItem',\n      'x-component': 'IDUpload',\n    },\n    contacts: {\n      type: 'array',\n      required: true,\n      title: 'Contacts',\n      'x-decorator': 'FormItem',\n      'x-component': 'ArrayItems',\n      items: {\n        type: 'object',\n        'x-component': 'ArrayItems.Item',\n        properties: {\n          sort: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.SortHandle',\n          },\n          popover: {\n            type: 'void',\n            title: 'Contact Informations',\n            'x-decorator': 'Editable.Popover',\n            'x-component': 'FormLayout',\n            'x-component-props': {\n              layout: 'vertical',\n            },\n            'x-reactions': [\n              {\n                fulfill: {\n                  schema: {\n                    title: '{{$self.query(\".name\").value() }}',\n                  },\n                },\n              },\n            ],\n            properties: {\n              name: {\n                type: 'string',\n                title: 'Name',\n                required: true,\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-component-props': {\n                  style: {\n                    width: 300,\n                  },\n                },\n              },\n              email: {\n                type: 'string',\n                title: 'Email',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-validator': [{ required: true }, 'email'],\n                'x-component-props': {\n                  style: {\n                    width: 300,\n                  },\n                },\n              },\n              phone: {\n                type: 'string',\n                title: 'Phone Number',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-validator': [{ required: true }, 'phone'],\n                'x-component-props': {\n                  style: {\n                    width: 300,\n                  },\n                },\n              },\n            },\n          },\n          remove: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.Remove',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add Contact',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  const [loading, setLoading] = useState(true)\n  useEffect(() => {\n    setTimeout(() => {\n      form.setInitialValues({\n        username: 'Aston Martin',\n        firstName: 'Aston',\n        lastName: 'Martin',\n        email: 'aston_martin@aston.com',\n        gender: 1,\n        birthday: '1836-01-03',\n        address: ['110000', '110000', '110101'],\n        idCard: [\n          {\n            name: 'this is image',\n            thumbUrl:\n              'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n            uid: 'rc-upload-1615825692847-2',\n            url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n          },\n        ],\n        contacts: [\n          {\n            name: 'Zhang San',\n            phone: '13245633378',\n            email: 'zhangsan@gmail.com',\n          },\n          { name: 'Li Si', phone: '16873452678', email: 'lisi@gmail.com' },\n        ],\n      })\n      setLoading(false)\n    }, 2000)\n  }, [])\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <PreviewText.Placeholder value=\"-\">\n        <Card title=\"User Details\" style={{ width: 620 }}>\n          <Spin spinning={loading}>\n            <Form\n              form={form}\n              labelCol={5}\n              wrapperCol={16}\n              onAutoSubmit={console.log}\n            >\n              <SchemaField schema={schema} />\n            </Form>\n          </Spin>\n        </Card>\n      </PreviewText.Placeholder>\n    </div>\n  )\n}\n```\n\n#### Pure JSX Cases\n\n```tsx\nimport React, { useState, useEffect } from 'react'\nimport { createForm } from '@formily/core'\nimport { Field, VoidField, ArrayField, useField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  FormLayout,\n  Input,\n  Select,\n  Cascader,\n  DatePicker,\n  FormGrid,\n  ArrayBase,\n  Upload,\n  PreviewText,\n  Editable,\n} from '@formily/antd'\nimport { action } from '@formily/reactive'\nimport { Card, Button, Spin } from 'antd'\nimport { UploadOutlined } from '@ant-design/icons'\nimport './index.less'\n\nconst form = createForm({\n  validateFirst: true,\n  readPretty: true,\n})\n\nconst IDUpload = (props) => {\n  const field = useField()\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      {field.editable && (\n        <Button icon={<UploadOutlined />}>Upload a copy</Button>\n      )}\n    </Upload>\n  )\n}\n\nconst fetchAddress = (field) => {\n  const transform = (data = {}) => {\n    return Object.entries(data).reduce((buf, [key, value]) => {\n      if (typeof value === 'string')\n        return buf.concat({\n          label: value,\n          value: key,\n        })\n      const { name, code, cities, districts } = value\n      const _cities = transform(cities)\n      const _districts = transform(districts)\n      return buf.concat({\n        label: name,\n        value: code,\n        children: _cities.length\n          ? _cities\n          : _districts.length\n          ? _districts\n          : undefined,\n      })\n    }, [])\n  }\n\n  field.loading = true\n  fetch('//unpkg.com/china-location/dist/location.json')\n    .then((res) => res.json())\n    .then(\n      action.bound((data) => {\n        field.dataSource = transform(data)\n        field.loading = false\n      })\n    )\n}\n\nexport default () => {\n  const [loading, setLoading] = useState(true)\n  useEffect(() => {\n    setTimeout(() => {\n      form.setInitialValues({\n        username: 'Aston Martin',\n        firstName: 'Aston',\n        lastName: 'Martin',\n        email: 'aston_martin@aston.com',\n        gender: 1,\n        birthday: '1836-01-03',\n        address: ['110000', '110000', '110101'],\n        idCard: [\n          {\n            name: 'this is image',\n            thumbUrl:\n              'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n            uid: 'rc-upload-1615825692847-2',\n            url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n          },\n        ],\n        contacts: [\n          {\n            name: 'Zhang San',\n            phone: '13245633378',\n            email: 'zhangsan@gmail.com',\n          },\n          { name: 'Li Si', phone: '16873452678', email: 'lisi@gmail.com' },\n        ],\n      })\n      setLoading(false)\n    }, 2000)\n  }, [])\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <PreviewText.Placeholder value=\"-\">\n        <Card title=\"Edit User\" style={{ width: 620 }}>\n          <Spin spinning={loading}>\n            <Form\n              form={form}\n              labelCol={5}\n              wrapperCol={16}\n              onAutoSubmit={console.log}\n            >\n              <Field\n                name=\"username\"\n                title=\"Username\"\n                required\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <VoidField\n                name=\"name\"\n                title=\"Name\"\n                decorator={[\n                  FormItem,\n                  {\n                    feedbackLayout: 'none',\n                  },\n                ]}\n                component={[FormGrid]}\n              >\n                <Field\n                  name=\"firstName\"\n                  decorator={[FormItem]}\n                  component={[\n                    Input,\n                    {\n                      placeholder: 'firstName',\n                    },\n                  ]}\n                  required\n                />\n                <Field\n                  name=\"lastName\"\n                  decorator={[FormItem]}\n                  component={[\n                    Input,\n                    {\n                      placeholder: 'lastname',\n                    },\n                  ]}\n                  required\n                />\n              </VoidField>\n              <Field\n                name=\"email\"\n                title=\"Email\"\n                required\n                validator=\"email\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"gender\"\n                title=\"Gender\"\n                decorator={[FormItem]}\n                component={[Select]}\n                dataSource={[\n                  {\n                    label: 'male',\n                    value: 1,\n                  },\n                  {\n                    label: 'female',\n                    value: 2,\n                  },\n                  {\n                    label: 'third gender',\n                    value: 3,\n                  },\n                ]}\n                required\n              />\n              <Field\n                name=\"birthday\"\n                title=\"Birthday\"\n                required\n                decorator={[FormItem]}\n                component={[DatePicker]}\n              />\n              <Field\n                name=\"address\"\n                title=\"Address\"\n                required\n                decorator={[FormItem]}\n                component={[Cascader]}\n                reactions={fetchAddress}\n              />\n              <Field\n                name=\"idCard\"\n                title=\"ID\"\n                required\n                decorator={[FormItem]}\n                component={[IDUpload]}\n              />\n              <ArrayField\n                name=\"contacts\"\n                title=\"Contacts\"\n                decorator={[FormItem]}\n              >\n                {(field) => (\n                  <ArrayBase>\n                    {field.value?.map((item, index) => (\n                      <div key={index} className=\"array-items-item\">\n                        <Field\n                          name={`${index}`}\n                          title=\"Contact Informations\"\n                          component={[Editable.Popover]}\n                          reactions={(field) => {\n                            field.title =\n                              field.query('.[].name').value() || field.title\n                          }}\n                        >\n                          <VoidField\n                            name=\"layout\"\n                            component={[FormLayout, { layout: 'vertical' }]}\n                          >\n                            <Field\n                              name=\"name\"\n                              title=\"Name\"\n                              required\n                              decorator={[FormItem]}\n                              component={[\n                                Input,\n                                {\n                                  style: {\n                                    width: 300,\n                                  },\n                                },\n                              ]}\n                            />\n                            <Field\n                              name=\"email\"\n                              title=\"Email\"\n                              required\n                              validator=\"email\"\n                              decorator={[FormItem]}\n                              component={[\n                                Input,\n                                {\n                                  style: {\n                                    width: 300,\n                                  },\n                                },\n                              ]}\n                            />\n                            <Field\n                              name=\"phone\"\n                              title=\"Phone Number\"\n                              required\n                              validator=\"phone\"\n                              decorator={[FormItem]}\n                              component={[\n                                Input,\n                                {\n                                  style: {\n                                    width: 300,\n                                  },\n                                },\n                              ]}\n                            />\n                          </VoidField>\n                        </Field>\n                      </div>\n                    ))}\n                    <ArrayBase.Addition title=\"Add Contact\" />\n                  </ArrayBase>\n                )}\n              </ArrayField>\n            </Form>\n          </Spin>\n        </Card>\n      </PreviewText.Placeholder>\n    </div>\n  )\n}\n```\n"
  },
  {
    "path": "docs/guide/scenes/edit-detail.zh-CN.md",
    "content": "# 编辑详情\n\n## 编辑\n\n#### Markup Schema 案例\n\n```tsx\nimport React, { useState, useEffect } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  FormLayout,\n  Input,\n  Select,\n  Cascader,\n  DatePicker,\n  Submit,\n  FormGrid,\n  Upload,\n  ArrayItems,\n  Editable,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { action } from '@formily/reactive'\nimport { Card, Button, Spin } from 'antd'\nimport { UploadOutlined } from '@ant-design/icons'\n\nconst form = createForm({\n  validateFirst: true,\n})\n\nconst IDUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button icon={<UploadOutlined />}>上传复印件</Button>\n    </Upload>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormGrid,\n    FormLayout,\n    Input,\n    DatePicker,\n    Cascader,\n    Select,\n    IDUpload,\n    ArrayItems,\n    Editable,\n  },\n  scope: {\n    fetchAddress: (field) => {\n      const transform = (data = {}) => {\n        return Object.entries(data).reduce((buf, [key, value]) => {\n          if (typeof value === 'string')\n            return buf.concat({\n              label: value,\n              value: key,\n            })\n          const { name, code, cities, districts } = value\n          const _cities = transform(cities)\n          const _districts = transform(districts)\n          return buf.concat({\n            label: name,\n            value: code,\n            children: _cities.length\n              ? _cities\n              : _districts.length\n              ? _districts\n              : undefined,\n          })\n        }, [])\n      }\n\n      field.loading = true\n      fetch('//unpkg.com/china-location/dist/location.json')\n        .then((res) => res.json())\n        .then(\n          action.bound((data) => {\n            field.dataSource = transform(data)\n            field.loading = false\n          })\n        )\n    },\n  },\n})\n\nexport default () => {\n  const [loading, setLoading] = useState(true)\n  useEffect(() => {\n    setTimeout(() => {\n      form.setInitialValues({\n        username: 'Aston Martin',\n        firstName: 'Aston',\n        lastName: 'Martin',\n        email: 'aston_martin@aston.com',\n        gender: 1,\n        birthday: '1836-01-03',\n        address: ['110000', '110000', '110101'],\n        idCard: [\n          {\n            name: 'this is image',\n            thumbUrl:\n              'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n            uid: 'rc-upload-1615825692847-2',\n            url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n          },\n        ],\n        contacts: [\n          { name: '张三', phone: '13245633378', email: 'zhangsan@gmail.com' },\n          { name: '李四', phone: '16873452678', email: 'lisi@gmail.com' },\n        ],\n      })\n      setLoading(false)\n    }, 2000)\n  }, [])\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card title=\"编辑用户\" style={{ width: 620 }}>\n        <Spin spinning={loading}>\n          <Form\n            form={form}\n            labelCol={5}\n            wrapperCol={16}\n            onAutoSubmit={console.log}\n          >\n            <SchemaField>\n              <SchemaField.String\n                name=\"username\"\n                title=\"用户名\"\n                required\n                x-decorator=\"FormItem\"\n                x-component=\"Input\"\n              />\n              <SchemaField.Void\n                title=\"姓名\"\n                x-decorator=\"FormItem\"\n                x-decorator-props={{\n                  asterisk: true,\n                  feedbackLayout: 'none',\n                }}\n                x-component=\"FormGrid\"\n              >\n                <SchemaField.String\n                  name=\"firstName\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                  x-component-props={{\n                    placeholder: '姓',\n                  }}\n                  required\n                />\n                <SchemaField.String\n                  name=\"lastName\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                  x-component-props={{\n                    placeholder: '名',\n                  }}\n                  required\n                />\n              </SchemaField.Void>\n              <SchemaField.String\n                name=\"email\"\n                title=\"邮箱\"\n                required\n                x-validator=\"email\"\n                x-decorator=\"FormItem\"\n                x-component=\"Input\"\n              />\n              <SchemaField.String\n                name=\"gender\"\n                title=\"性别\"\n                x-decorator=\"FormItem\"\n                x-component=\"Select\"\n                enum={[\n                  {\n                    label: '男',\n                    value: 1,\n                  },\n                  {\n                    label: '女',\n                    value: 2,\n                  },\n                  {\n                    label: '第三性别',\n                    value: 3,\n                  },\n                ]}\n                required\n              />\n              <SchemaField.String\n                name=\"birthday\"\n                title=\"生日\"\n                required\n                x-decorator=\"FormItem\"\n                x-component=\"DatePicker\"\n              />\n              <SchemaField.String\n                name=\"address\"\n                title=\"地址\"\n                required\n                x-decorator=\"FormItem\"\n                x-component=\"Cascader\"\n                x-reactions=\"{{fetchAddress}}\"\n              />\n              <SchemaField.String\n                name=\"idCard\"\n                title=\"身份证复印件\"\n                required\n                x-decorator=\"FormItem\"\n                x-component=\"IDUpload\"\n              />\n              <SchemaField.Array\n                name=\"contacts\"\n                title=\"联系人信息\"\n                required\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems\"\n              >\n                <SchemaField.Object x-component=\"ArrayItems.Item\">\n                  <SchemaField.Void\n                    x-decorator=\"FormItem\"\n                    x-component=\"ArrayItems.SortHandle\"\n                  />\n                  <SchemaField.Void\n                    name=\"popover\"\n                    title=\"维护联系人信息\"\n                    x-decorator=\"Editable.Popover\"\n                    x-component=\"FormLayout\"\n                    x-component-props={{\n                      layout: 'vertical',\n                    }}\n                    x-reactions={[\n                      {\n                        fulfill: {\n                          schema: {\n                            title: '{{$self.query(\".name\").value() }}',\n                          },\n                        },\n                      },\n                    ]}\n                  >\n                    <SchemaField.String\n                      name=\"name\"\n                      required\n                      title=\"姓名\"\n                      x-decorator=\"FormItem\"\n                      x-component=\"Input\"\n                      x-component-props={{\n                        style: {\n                          width: 300,\n                        },\n                      }}\n                    />\n                    <SchemaField.String\n                      name=\"email\"\n                      title=\"邮箱\"\n                      x-validator={[{ required: true }, 'email']}\n                      x-decorator=\"FormItem\"\n                      x-component=\"Input\"\n                      x-component-props={{\n                        style: {\n                          width: 300,\n                        },\n                      }}\n                    />\n                    <SchemaField.String\n                      name=\"phone\"\n                      required\n                      title=\"手机号\"\n                      x-validator=\"phone\"\n                      x-decorator=\"FormItem\"\n                      x-component=\"Input\"\n                      x-component-props={{\n                        style: {\n                          width: 300,\n                        },\n                      }}\n                    />\n                  </SchemaField.Void>\n                  <SchemaField.Void\n                    x-decorator=\"FormItem\"\n                    x-component=\"ArrayItems.Remove\"\n                  />\n                </SchemaField.Object>\n                <SchemaField.Void\n                  x-component=\"ArrayItems.Addition\"\n                  title=\"新增联系人\"\n                />\n              </SchemaField.Array>\n            </SchemaField>\n            <FormButtonGroup.FormItem>\n              <Submit block size=\"large\">\n                提交\n              </Submit>\n            </FormButtonGroup.FormItem>\n          </Form>\n        </Spin>\n      </Card>\n    </div>\n  )\n}\n```\n\n#### JSON Schema 案例\n\n```tsx\nimport React, { useState, useEffect } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  FormLayout,\n  Input,\n  Select,\n  Cascader,\n  DatePicker,\n  Submit,\n  FormGrid,\n  Upload,\n  ArrayItems,\n  Editable,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { action } from '@formily/reactive'\nimport { Card, Button, Spin } from 'antd'\nimport { UploadOutlined } from '@ant-design/icons'\n\nconst form = createForm({\n  validateFirst: true,\n})\n\nconst IDUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button icon={<UploadOutlined />}>上传复印件</Button>\n    </Upload>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormGrid,\n    FormLayout,\n    Input,\n    DatePicker,\n    Cascader,\n    Select,\n    IDUpload,\n    ArrayItems,\n    Editable,\n  },\n  scope: {\n    fetchAddress: (field) => {\n      const transform = (data = {}) => {\n        return Object.entries(data).reduce((buf, [key, value]) => {\n          if (typeof value === 'string')\n            return buf.concat({\n              label: value,\n              value: key,\n            })\n          const { name, code, cities, districts } = value\n          const _cities = transform(cities)\n          const _districts = transform(districts)\n          return buf.concat({\n            label: name,\n            value: code,\n            children: _cities.length\n              ? _cities\n              : _districts.length\n              ? _districts\n              : undefined,\n          })\n        }, [])\n      }\n\n      field.loading = true\n      fetch('//unpkg.com/china-location/dist/location.json')\n        .then((res) => res.json())\n        .then(\n          action.bound((data) => {\n            field.dataSource = transform(data)\n            field.loading = false\n          })\n        )\n    },\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    username: {\n      type: 'string',\n      title: '用户名',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    name: {\n      type: 'void',\n      title: '姓名',\n      'x-decorator': 'FormItem',\n      'x-decorator-props': {\n        asterisk: true,\n        feedbackLayout: 'none',\n      },\n      'x-component': 'FormGrid',\n      properties: {\n        firstName: {\n          type: 'string',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          'x-component-props': {\n            placeholder: '姓',\n          },\n        },\n        lastName: {\n          type: 'string',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          'x-component-props': {\n            placeholder: '名',\n          },\n        },\n      },\n    },\n    email: {\n      type: 'string',\n      title: '邮箱',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-validator': 'email',\n    },\n    gender: {\n      type: 'string',\n      title: '性别',\n      enum: [\n        {\n          label: '男',\n          value: 1,\n        },\n        {\n          label: '女',\n          value: 2,\n        },\n        {\n          label: '第三性别',\n          value: 3,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n    },\n    birthday: {\n      type: 'string',\n      required: true,\n      title: '生日',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n    },\n    address: {\n      type: 'string',\n      required: true,\n      title: '地址',\n      'x-decorator': 'FormItem',\n      'x-component': 'Cascader',\n      'x-reactions': '{{fetchAddress}}',\n    },\n    idCard: {\n      type: 'string',\n      required: true,\n      title: '身份证复印件',\n      'x-decorator': 'FormItem',\n      'x-component': 'IDUpload',\n    },\n    contacts: {\n      type: 'array',\n      required: true,\n      title: '联系人信息',\n      'x-decorator': 'FormItem',\n      'x-component': 'ArrayItems',\n      items: {\n        type: 'object',\n        'x-component': 'ArrayItems.Item',\n        properties: {\n          sort: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.SortHandle',\n          },\n          popover: {\n            type: 'void',\n            title: '完善联系人信息',\n            'x-decorator': 'Editable.Popover',\n            'x-component': 'FormLayout',\n            'x-component-props': {\n              layout: 'vertical',\n            },\n            'x-reactions': [\n              {\n                fulfill: {\n                  schema: {\n                    title: '{{$self.query(\".name\").value() }}',\n                  },\n                },\n              },\n            ],\n            properties: {\n              name: {\n                type: 'string',\n                title: '姓名',\n                required: true,\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-component-props': {\n                  style: {\n                    width: 300,\n                  },\n                },\n              },\n              email: {\n                type: 'string',\n                title: '邮箱',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-validator': [{ required: true }, 'email'],\n                'x-component-props': {\n                  style: {\n                    width: 300,\n                  },\n                },\n              },\n              phone: {\n                type: 'string',\n                title: '手机号',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-validator': [{ required: true }, 'phone'],\n                'x-component-props': {\n                  style: {\n                    width: 300,\n                  },\n                },\n              },\n            },\n          },\n          remove: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.Remove',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '新增联系人',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  const [loading, setLoading] = useState(true)\n  useEffect(() => {\n    setTimeout(() => {\n      form.setInitialValues({\n        username: 'Aston Martin',\n        firstName: 'Aston',\n        lastName: 'Martin',\n        email: 'aston_martin@aston.com',\n        gender: 1,\n        birthday: '1836-01-03',\n        address: ['110000', '110000', '110101'],\n        idCard: [\n          {\n            name: 'this is image',\n            thumbUrl:\n              'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n            uid: 'rc-upload-1615825692847-2',\n            url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n          },\n        ],\n        contacts: [\n          { name: '张三', phone: '13245633378', email: 'zhangsan@gmail.com' },\n          { name: '李四', phone: '16873452678', email: 'lisi@gmail.com' },\n        ],\n      })\n      setLoading(false)\n    }, 2000)\n  }, [])\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card title=\"编辑用户\" style={{ width: 620 }}>\n        <Spin spinning={loading}>\n          <Form\n            form={form}\n            labelCol={5}\n            wrapperCol={16}\n            onAutoSubmit={console.log}\n          >\n            <SchemaField schema={schema} />\n            <FormButtonGroup.FormItem>\n              <Submit block size=\"large\">\n                提交\n              </Submit>\n            </FormButtonGroup.FormItem>\n          </Form>\n        </Spin>\n      </Card>\n    </div>\n  )\n}\n```\n\n#### 纯 JSX 案例\n\n```tsx\nimport React, { useState, useEffect } from 'react'\nimport { createForm } from '@formily/core'\nimport { Field, VoidField, ArrayField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  FormLayout,\n  Input,\n  Select,\n  Cascader,\n  DatePicker,\n  Submit,\n  FormGrid,\n  Upload,\n  ArrayBase,\n  Editable,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { action } from '@formily/reactive'\nimport { Card, Button, Spin } from 'antd'\nimport { UploadOutlined } from '@ant-design/icons'\nimport './index.less'\n\nconst form = createForm({\n  validateFirst: true,\n})\n\nconst IDUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button icon={<UploadOutlined />}>上传复印件</Button>\n    </Upload>\n  )\n}\n\nconst fetchAddress = (field) => {\n  const transform = (data = {}) => {\n    return Object.entries(data).reduce((buf, [key, value]) => {\n      if (typeof value === 'string')\n        return buf.concat({\n          label: value,\n          value: key,\n        })\n      const { name, code, cities, districts } = value\n      const _cities = transform(cities)\n      const _districts = transform(districts)\n      return buf.concat({\n        label: name,\n        value: code,\n        children: _cities.length\n          ? _cities\n          : _districts.length\n          ? _districts\n          : undefined,\n      })\n    }, [])\n  }\n\n  field.loading = true\n  fetch('//unpkg.com/china-location/dist/location.json')\n    .then((res) => res.json())\n    .then(\n      action.bound((data) => {\n        field.dataSource = transform(data)\n        field.loading = false\n      })\n    )\n}\n\nexport default () => {\n  const [loading, setLoading] = useState(true)\n  useEffect(() => {\n    setTimeout(() => {\n      form.setInitialValues({\n        username: 'Aston Martin',\n        firstName: 'Aston',\n        lastName: 'Martin',\n        email: 'aston_martin@aston.com',\n        gender: 1,\n        birthday: '1836-01-03',\n        address: ['110000', '110000', '110101'],\n        idCard: [\n          {\n            name: 'this is image',\n            thumbUrl:\n              'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n            uid: 'rc-upload-1615825692847-2',\n            url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n          },\n        ],\n        contacts: [\n          { name: '张三', phone: '13245633378', email: 'zhangsan@gmail.com' },\n          { name: '李四', phone: '16873452678', email: 'lisi@gmail.com' },\n        ],\n      })\n      setLoading(false)\n    }, 2000)\n  }, [])\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card title=\"编辑用户\" style={{ width: 620 }}>\n        <Spin spinning={loading}>\n          <Form\n            form={form}\n            labelCol={5}\n            wrapperCol={16}\n            onAutoSubmit={console.log}\n          >\n            <Field\n              name=\"username\"\n              title=\"用户名\"\n              required\n              decorator={[FormItem]}\n              component={[Input]}\n            />\n            <VoidField\n              name=\"name\"\n              title=\"姓名\"\n              decorator={[\n                FormItem,\n                {\n                  asterisk: true,\n                  feedbackLayout: 'none',\n                },\n              ]}\n              component={[FormGrid]}\n            >\n              <Field\n                name=\"firstName\"\n                decorator={[FormItem]}\n                component={[\n                  Input,\n                  {\n                    placeholder: '姓',\n                  },\n                ]}\n                required\n              />\n              <Field\n                name=\"lastName\"\n                decorator={[FormItem]}\n                component={[\n                  Input,\n                  {\n                    placeholder: '名',\n                  },\n                ]}\n                required\n              />\n            </VoidField>\n            <Field\n              name=\"email\"\n              title=\"邮箱\"\n              required\n              validator=\"email\"\n              decorator={[FormItem]}\n              component={[Input]}\n            />\n            <Field\n              name=\"gender\"\n              title=\"性别\"\n              decorator={[FormItem]}\n              component={[Select]}\n              dataSource={[\n                {\n                  label: '男',\n                  value: 1,\n                },\n                {\n                  label: '女',\n                  value: 2,\n                },\n                {\n                  label: '第三性别',\n                  value: 3,\n                },\n              ]}\n              required\n            />\n            <Field\n              name=\"birthday\"\n              title=\"生日\"\n              required\n              decorator={[FormItem]}\n              component={[DatePicker]}\n            />\n            <Field\n              name=\"address\"\n              title=\"地址\"\n              required\n              decorator={[FormItem]}\n              component={[Cascader]}\n              reactions={fetchAddress}\n            />\n            <Field\n              name=\"idCard\"\n              title=\"身份证复印件\"\n              required\n              decorator={[FormItem]}\n              component={[IDUpload]}\n            />\n            <ArrayField\n              name=\"contacts\"\n              title=\"联系人信息\"\n              decorator={[FormItem]}\n            >\n              {(field) => (\n                <ArrayBase>\n                  {field.value?.map((item, index) => (\n                    <div key={index} className=\"array-items-item\">\n                      <Field\n                        name={`${index}`}\n                        title=\"完善联系人信息\"\n                        component={[Editable.Popover]}\n                        reactions={(field) => {\n                          field.title =\n                            field.query('.[].name').value() || field.title\n                        }}\n                      >\n                        <VoidField\n                          name=\"layout\"\n                          component={[FormLayout, { layout: 'vertical' }]}\n                        >\n                          <Field\n                            name=\"name\"\n                            title=\"姓名\"\n                            required\n                            decorator={[FormItem]}\n                            component={[\n                              Input,\n                              {\n                                style: {\n                                  width: 300,\n                                },\n                              },\n                            ]}\n                          />\n                          <Field\n                            name=\"email\"\n                            title=\"邮箱\"\n                            required\n                            validator=\"email\"\n                            decorator={[FormItem]}\n                            component={[\n                              Input,\n                              {\n                                style: {\n                                  width: 300,\n                                },\n                              },\n                            ]}\n                          />\n                          <Field\n                            name=\"phone\"\n                            title=\"手机号\"\n                            required\n                            validator=\"phone\"\n                            decorator={[FormItem]}\n                            component={[\n                              Input,\n                              {\n                                style: {\n                                  width: 300,\n                                },\n                              },\n                            ]}\n                          />\n                        </VoidField>\n                      </Field>\n                      <FormItem.BaseItem>\n                        <ArrayBase.Remove index={index} />\n                        <ArrayBase.MoveDown index={index} />\n                        <ArrayBase.MoveUp index={index} />\n                      </FormItem.BaseItem>\n                    </div>\n                  ))}\n                  <ArrayBase.Addition title=\"新增联系人\" />\n                </ArrayBase>\n              )}\n            </ArrayField>\n            <FormButtonGroup.FormItem>\n              <Submit block size=\"large\">\n                提交\n              </Submit>\n            </FormButtonGroup.FormItem>\n          </Form>\n        </Spin>\n      </Card>\n    </div>\n  )\n}\n```\n\n## 详情\n\n#### Markup Schema 案例\n\n```tsx\nimport React, { useState, useEffect } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, useField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  FormLayout,\n  Input,\n  Select,\n  Cascader,\n  DatePicker,\n  FormGrid,\n  Upload,\n  ArrayItems,\n  Editable,\n  PreviewText,\n} from '@formily/antd'\nimport { action } from '@formily/reactive'\nimport { Card, Button, Spin } from 'antd'\nimport { UploadOutlined } from '@ant-design/icons'\n\nconst form = createForm({\n  readPretty: true,\n  validateFirst: true,\n})\n\nconst IDUpload = (props) => {\n  const field = useField()\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      {field.editable && <Button icon={<UploadOutlined />}>上传复印件</Button>}\n    </Upload>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormGrid,\n    FormLayout,\n    Input,\n    DatePicker,\n    Cascader,\n    Select,\n    IDUpload,\n    ArrayItems,\n    Editable,\n  },\n  scope: {\n    fetchAddress: (field) => {\n      const transform = (data = {}) => {\n        return Object.entries(data).reduce((buf, [key, value]) => {\n          if (typeof value === 'string')\n            return buf.concat({\n              label: value,\n              value: key,\n            })\n          const { name, code, cities, districts } = value\n          const _cities = transform(cities)\n          const _districts = transform(districts)\n          return buf.concat({\n            label: name,\n            value: code,\n            children: _cities.length\n              ? _cities\n              : _districts.length\n              ? _districts\n              : undefined,\n          })\n        }, [])\n      }\n\n      field.loading = true\n      fetch('//unpkg.com/china-location/dist/location.json')\n        .then((res) => res.json())\n        .then(\n          action.bound((data) => {\n            field.dataSource = transform(data)\n            field.loading = false\n          })\n        )\n    },\n  },\n})\n\nexport default () => {\n  const [loading, setLoading] = useState(true)\n  useEffect(() => {\n    setTimeout(() => {\n      form.setInitialValues({\n        username: 'Aston Martin',\n        firstName: 'Aston',\n        lastName: 'Martin',\n        email: 'aston_martin@aston.com',\n        gender: 1,\n        birthday: '1836-01-03',\n        address: ['110000', '110000', '110101'],\n        idCard: [\n          {\n            name: 'this is image',\n            thumbUrl:\n              'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n            uid: 'rc-upload-1615825692847-2',\n            url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n          },\n        ],\n        contacts: [\n          { name: '张三', phone: '13245633378', email: 'zhangsan@gmail.com' },\n          { name: '李四', phone: '16873452678', email: 'lisi@gmail.com' },\n        ],\n      })\n      setLoading(false)\n    }, 2000)\n  }, [])\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <PreviewText.Placeholder value=\"-\">\n        <Card title=\"用户详情\" style={{ width: 620 }}>\n          <Spin spinning={loading}>\n            <Form\n              form={form}\n              labelCol={5}\n              wrapperCol={16}\n              onAutoSubmit={console.log}\n            >\n              <SchemaField>\n                <SchemaField.String\n                  name=\"username\"\n                  title=\"用户名\"\n                  required\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.Void\n                  title=\"姓名\"\n                  x-decorator=\"FormItem\"\n                  x-decorator-props={{\n                    feedbackLayout: 'none',\n                  }}\n                  x-component=\"FormGrid\"\n                >\n                  <SchemaField.String\n                    name=\"firstName\"\n                    x-decorator=\"FormItem\"\n                    x-component=\"Input\"\n                    x-component-props={{\n                      placeholder: '姓',\n                    }}\n                    required\n                  />\n                  <SchemaField.String\n                    name=\"lastName\"\n                    x-decorator=\"FormItem\"\n                    x-component=\"Input\"\n                    x-component-props={{\n                      placeholder: '名',\n                    }}\n                    required\n                  />\n                </SchemaField.Void>\n                <SchemaField.String\n                  name=\"email\"\n                  title=\"邮箱\"\n                  required\n                  x-validator=\"email\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"gender\"\n                  title=\"性别\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Select\"\n                  enum={[\n                    {\n                      label: '男',\n                      value: 1,\n                    },\n                    {\n                      label: '女',\n                      value: 2,\n                    },\n                    {\n                      label: '第三性别',\n                      value: 3,\n                    },\n                  ]}\n                  required\n                />\n                <SchemaField.String\n                  name=\"birthday\"\n                  title=\"生日\"\n                  required\n                  x-decorator=\"FormItem\"\n                  x-component=\"DatePicker\"\n                />\n                <SchemaField.String\n                  name=\"address\"\n                  title=\"地址\"\n                  required\n                  x-decorator=\"FormItem\"\n                  x-component=\"Cascader\"\n                  x-reactions=\"{{fetchAddress}}\"\n                />\n                <SchemaField.String\n                  name=\"idCard\"\n                  title=\"身份证复印件\"\n                  required\n                  x-decorator=\"FormItem\"\n                  x-component=\"IDUpload\"\n                />\n                <SchemaField.Array\n                  name=\"contacts\"\n                  title=\"联系人信息\"\n                  required\n                  x-decorator=\"FormItem\"\n                  x-component=\"ArrayItems\"\n                >\n                  <SchemaField.Object x-component=\"ArrayItems.Item\">\n                    <SchemaField.Void\n                      x-decorator=\"FormItem\"\n                      x-component=\"ArrayItems.SortHandle\"\n                    />\n                    <SchemaField.Void\n                      name=\"popover\"\n                      title=\"维护联系人信息\"\n                      x-decorator=\"Editable.Popover\"\n                      x-component=\"FormLayout\"\n                      x-component-props={{\n                        layout: 'vertical',\n                      }}\n                      x-reactions={[\n                        {\n                          fulfill: {\n                            schema: {\n                              title: '{{$self.query(\".name\").value() }}',\n                            },\n                          },\n                        },\n                      ]}\n                    >\n                      <SchemaField.String\n                        name=\"name\"\n                        required\n                        title=\"姓名\"\n                        x-decorator=\"FormItem\"\n                        x-component=\"Input\"\n                        x-component-props={{\n                          style: {\n                            width: 300,\n                          },\n                        }}\n                      />\n                      <SchemaField.String\n                        name=\"email\"\n                        title=\"邮箱\"\n                        x-validator={[{ required: true }, 'email']}\n                        x-decorator=\"FormItem\"\n                        x-component=\"Input\"\n                        x-component-props={{\n                          style: {\n                            width: 300,\n                          },\n                        }}\n                      />\n                      <SchemaField.String\n                        name=\"phone\"\n                        required\n                        title=\"手机号\"\n                        x-validator=\"phone\"\n                        x-decorator=\"FormItem\"\n                        x-component=\"Input\"\n                        x-component-props={{\n                          style: {\n                            width: 300,\n                          },\n                        }}\n                      />\n                    </SchemaField.Void>\n                    <SchemaField.Void\n                      x-decorator=\"FormItem\"\n                      x-component=\"ArrayItems.Remove\"\n                    />\n                  </SchemaField.Object>\n                  <SchemaField.Void\n                    x-component=\"ArrayItems.Addition\"\n                    title=\"新增联系人\"\n                  />\n                </SchemaField.Array>\n              </SchemaField>\n            </Form>\n          </Spin>\n        </Card>\n      </PreviewText.Placeholder>\n    </div>\n  )\n}\n```\n\n#### JSON Schema 案例\n\n```tsx\nimport React, { useState, useEffect } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, useField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  FormLayout,\n  Input,\n  Select,\n  Cascader,\n  DatePicker,\n  FormGrid,\n  Upload,\n  ArrayItems,\n  Editable,\n  PreviewText,\n} from '@formily/antd'\nimport { action } from '@formily/reactive'\nimport { Card, Button, Spin } from 'antd'\nimport { UploadOutlined } from '@ant-design/icons'\n\nconst form = createForm({\n  readPretty: true,\n  validateFirst: true,\n})\n\nconst IDUpload = (props) => {\n  const field = useField()\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      {field.editable && <Button icon={<UploadOutlined />}>上传复印件</Button>}\n    </Upload>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormGrid,\n    FormLayout,\n    Input,\n    DatePicker,\n    Cascader,\n    Select,\n    IDUpload,\n    ArrayItems,\n    Editable,\n  },\n  scope: {\n    fetchAddress: (field) => {\n      const transform = (data = {}) => {\n        return Object.entries(data).reduce((buf, [key, value]) => {\n          if (typeof value === 'string')\n            return buf.concat({\n              label: value,\n              value: key,\n            })\n          const { name, code, cities, districts } = value\n          const _cities = transform(cities)\n          const _districts = transform(districts)\n          return buf.concat({\n            label: name,\n            value: code,\n            children: _cities.length\n              ? _cities\n              : _districts.length\n              ? _districts\n              : undefined,\n          })\n        }, [])\n      }\n\n      field.loading = true\n      fetch('//unpkg.com/china-location/dist/location.json')\n        .then((res) => res.json())\n        .then(\n          action.bound((data) => {\n            field.dataSource = transform(data)\n            field.loading = false\n          })\n        )\n    },\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    username: {\n      type: 'string',\n      title: '用户名',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    name: {\n      type: 'void',\n      title: '姓名',\n      'x-decorator': 'FormItem',\n      'x-decorator-props': {\n        asterisk: true,\n        feedbackLayout: 'none',\n      },\n      'x-component': 'FormGrid',\n      properties: {\n        firstName: {\n          type: 'string',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          'x-component-props': {\n            placeholder: '姓',\n          },\n        },\n        lastName: {\n          type: 'string',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          'x-component-props': {\n            placeholder: '名',\n          },\n        },\n      },\n    },\n    email: {\n      type: 'string',\n      title: '邮箱',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-validator': 'email',\n    },\n    gender: {\n      type: 'string',\n      title: '性别',\n      enum: [\n        {\n          label: '男',\n          value: 1,\n        },\n        {\n          label: '女',\n          value: 2,\n        },\n        {\n          label: '第三性别',\n          value: 3,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n    },\n    birthday: {\n      type: 'string',\n      required: true,\n      title: '生日',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n    },\n    address: {\n      type: 'string',\n      required: true,\n      title: '地址',\n      'x-decorator': 'FormItem',\n      'x-component': 'Cascader',\n      'x-reactions': '{{fetchAddress}}',\n    },\n    idCard: {\n      type: 'string',\n      required: true,\n      title: '身份证复印件',\n      'x-decorator': 'FormItem',\n      'x-component': 'IDUpload',\n    },\n    contacts: {\n      type: 'array',\n      required: true,\n      title: '联系人信息',\n      'x-decorator': 'FormItem',\n      'x-component': 'ArrayItems',\n      items: {\n        type: 'object',\n        'x-component': 'ArrayItems.Item',\n        properties: {\n          sort: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.SortHandle',\n          },\n          popover: {\n            type: 'void',\n            title: '完善联系人信息',\n            'x-decorator': 'Editable.Popover',\n            'x-component': 'FormLayout',\n            'x-component-props': {\n              layout: 'vertical',\n            },\n            'x-reactions': [\n              {\n                fulfill: {\n                  schema: {\n                    title: '{{$self.query(\".name\").value() }}',\n                  },\n                },\n              },\n            ],\n            properties: {\n              name: {\n                type: 'string',\n                title: '姓名',\n                required: true,\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-component-props': {\n                  style: {\n                    width: 300,\n                  },\n                },\n              },\n              email: {\n                type: 'string',\n                title: '邮箱',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-validator': [{ required: true }, 'email'],\n                'x-component-props': {\n                  style: {\n                    width: 300,\n                  },\n                },\n              },\n              phone: {\n                type: 'string',\n                title: '手机号',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-validator': [{ required: true }, 'phone'],\n                'x-component-props': {\n                  style: {\n                    width: 300,\n                  },\n                },\n              },\n            },\n          },\n          remove: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.Remove',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '新增联系人',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  const [loading, setLoading] = useState(true)\n  useEffect(() => {\n    setTimeout(() => {\n      form.setInitialValues({\n        username: 'Aston Martin',\n        firstName: 'Aston',\n        lastName: 'Martin',\n        email: 'aston_martin@aston.com',\n        gender: 1,\n        birthday: '1836-01-03',\n        address: ['110000', '110000', '110101'],\n        idCard: [\n          {\n            name: 'this is image',\n            thumbUrl:\n              'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n            uid: 'rc-upload-1615825692847-2',\n            url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n          },\n        ],\n        contacts: [\n          { name: '张三', phone: '13245633378', email: 'zhangsan@gmail.com' },\n          { name: '李四', phone: '16873452678', email: 'lisi@gmail.com' },\n        ],\n      })\n      setLoading(false)\n    }, 2000)\n  }, [])\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <PreviewText.Placeholder value=\"-\">\n        <Card title=\"用户详情\" style={{ width: 620 }}>\n          <Spin spinning={loading}>\n            <Form\n              form={form}\n              labelCol={5}\n              wrapperCol={16}\n              onAutoSubmit={console.log}\n            >\n              <SchemaField schema={schema} />\n            </Form>\n          </Spin>\n        </Card>\n      </PreviewText.Placeholder>\n    </div>\n  )\n}\n```\n\n#### 纯 JSX 案例\n\n```tsx\nimport React, { useState, useEffect } from 'react'\nimport { createForm } from '@formily/core'\nimport { Field, VoidField, ArrayField, useField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  FormLayout,\n  Input,\n  Select,\n  Cascader,\n  DatePicker,\n  FormGrid,\n  ArrayBase,\n  Upload,\n  PreviewText,\n  Editable,\n} from '@formily/antd'\nimport { action } from '@formily/reactive'\nimport { Card, Button, Spin } from 'antd'\nimport { UploadOutlined } from '@ant-design/icons'\nimport './index.less'\n\nconst form = createForm({\n  validateFirst: true,\n  readPretty: true,\n})\n\nconst IDUpload = (props) => {\n  const field = useField()\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      {field.editable && <Button icon={<UploadOutlined />}>上传复印件</Button>}\n    </Upload>\n  )\n}\n\nconst fetchAddress = (field) => {\n  const transform = (data = {}) => {\n    return Object.entries(data).reduce((buf, [key, value]) => {\n      if (typeof value === 'string')\n        return buf.concat({\n          label: value,\n          value: key,\n        })\n      const { name, code, cities, districts } = value\n      const _cities = transform(cities)\n      const _districts = transform(districts)\n      return buf.concat({\n        label: name,\n        value: code,\n        children: _cities.length\n          ? _cities\n          : _districts.length\n          ? _districts\n          : undefined,\n      })\n    }, [])\n  }\n\n  field.loading = true\n  fetch('//unpkg.com/china-location/dist/location.json')\n    .then((res) => res.json())\n    .then(\n      action.bound((data) => {\n        field.dataSource = transform(data)\n        field.loading = false\n      })\n    )\n}\n\nexport default () => {\n  const [loading, setLoading] = useState(true)\n  useEffect(() => {\n    setTimeout(() => {\n      form.setInitialValues({\n        username: 'Aston Martin',\n        firstName: 'Aston',\n        lastName: 'Martin',\n        email: 'aston_martin@aston.com',\n        gender: 1,\n        birthday: '1836-01-03',\n        address: ['110000', '110000', '110101'],\n        idCard: [\n          {\n            name: 'this is image',\n            thumbUrl:\n              'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n            uid: 'rc-upload-1615825692847-2',\n            url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',\n          },\n        ],\n        contacts: [\n          { name: '张三', phone: '13245633378', email: 'zhangsan@gmail.com' },\n          { name: '李四', phone: '16873452678', email: 'lisi@gmail.com' },\n        ],\n      })\n      setLoading(false)\n    }, 2000)\n  }, [])\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <PreviewText.Placeholder value=\"-\">\n        <Card title=\"编辑用户\" style={{ width: 620 }}>\n          <Spin spinning={loading}>\n            <Form\n              form={form}\n              labelCol={5}\n              wrapperCol={16}\n              onAutoSubmit={console.log}\n            >\n              <Field\n                name=\"username\"\n                title=\"用户名\"\n                required\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <VoidField\n                name=\"name\"\n                title=\"姓名\"\n                decorator={[\n                  FormItem,\n                  {\n                    feedbackLayout: 'none',\n                  },\n                ]}\n                component={[FormGrid]}\n              >\n                <Field\n                  name=\"firstName\"\n                  decorator={[FormItem]}\n                  component={[\n                    Input,\n                    {\n                      placeholder: '姓',\n                    },\n                  ]}\n                  required\n                />\n                <Field\n                  name=\"lastName\"\n                  decorator={[FormItem]}\n                  component={[\n                    Input,\n                    {\n                      placeholder: '名',\n                    },\n                  ]}\n                  required\n                />\n              </VoidField>\n              <Field\n                name=\"email\"\n                title=\"邮箱\"\n                required\n                validator=\"email\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"gender\"\n                title=\"性别\"\n                decorator={[FormItem]}\n                component={[Select]}\n                dataSource={[\n                  {\n                    label: '男',\n                    value: 1,\n                  },\n                  {\n                    label: '女',\n                    value: 2,\n                  },\n                  {\n                    label: '第三性别',\n                    value: 3,\n                  },\n                ]}\n                required\n              />\n              <Field\n                name=\"birthday\"\n                title=\"生日\"\n                required\n                decorator={[FormItem]}\n                component={[DatePicker]}\n              />\n              <Field\n                name=\"address\"\n                title=\"地址\"\n                required\n                decorator={[FormItem]}\n                component={[Cascader]}\n                reactions={fetchAddress}\n              />\n              <Field\n                name=\"idCard\"\n                title=\"身份证复印件\"\n                required\n                decorator={[FormItem]}\n                component={[IDUpload]}\n              />\n              <ArrayField\n                name=\"contacts\"\n                title=\"联系人信息\"\n                decorator={[FormItem]}\n              >\n                {(field) => (\n                  <ArrayBase>\n                    {field.value?.map((item, index) => (\n                      <div key={index} className=\"array-items-item\">\n                        <Field\n                          name={`${index}`}\n                          title=\"完善联系人信息\"\n                          component={[Editable.Popover]}\n                          reactions={(field) => {\n                            field.title =\n                              field.query('.[].name').value() || field.title\n                          }}\n                        >\n                          <VoidField\n                            name=\"layout\"\n                            component={[FormLayout, { layout: 'vertical' }]}\n                          >\n                            <Field\n                              name=\"name\"\n                              title=\"姓名\"\n                              required\n                              decorator={[FormItem]}\n                              component={[\n                                Input,\n                                {\n                                  style: {\n                                    width: 300,\n                                  },\n                                },\n                              ]}\n                            />\n                            <Field\n                              name=\"email\"\n                              title=\"邮箱\"\n                              required\n                              validator=\"email\"\n                              decorator={[FormItem]}\n                              component={[\n                                Input,\n                                {\n                                  style: {\n                                    width: 300,\n                                  },\n                                },\n                              ]}\n                            />\n                            <Field\n                              name=\"phone\"\n                              title=\"手机号\"\n                              required\n                              validator=\"phone\"\n                              decorator={[FormItem]}\n                              component={[\n                                Input,\n                                {\n                                  style: {\n                                    width: 300,\n                                  },\n                                },\n                              ]}\n                            />\n                          </VoidField>\n                        </Field>\n                      </div>\n                    ))}\n                    <ArrayBase.Addition title=\"新增联系人\" />\n                  </ArrayBase>\n                )}\n              </ArrayField>\n            </Form>\n          </Spin>\n        </Card>\n      </PreviewText.Placeholder>\n    </div>\n  )\n}\n```\n"
  },
  {
    "path": "docs/guide/scenes/index.less",
    "content": ".array-items-item {\n  border: 1px solid rgb(238, 238, 238);\n  margin-bottom: 10px;\n  padding: 3px 6px;\n  display: flex;\n  justify-content: space-around;\n  transition: all 0.25s;\n  .ant-formily-item {\n    margin-bottom: 0 !important;\n  }\n\n  &:hover {\n    border: 1px solid rgb(170, 170, 170);\n  }\n}\n"
  },
  {
    "path": "docs/guide/scenes/login-register.md",
    "content": "# Log in&Sign up\n\n## Log in\n\n#### Markup Schema Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input, Password, Submit } from '@formily/antd'\nimport { Tabs, Card } from 'antd'\nimport * as ICONS from '@ant-design/icons'\nimport { VerifyCode } from './VerifyCode'\n\nconst normalForm = createForm({\n  validateFirst: true,\n})\n\nconst phoneForm = createForm({\n  validateFirst: true,\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Password,\n    VerifyCode,\n  },\n  scope: {\n    icon(name) {\n      return React.createElement(ICONS[name])\n    },\n  },\n})\n\nexport default () => {\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card style={{ width: 400 }}>\n        <Tabs style={{ overflow: 'visible', marginTop: -10 }}>\n          <Tabs.TabPane key=\"1\" tab=\"Password Login\">\n            <Form\n              form={normalForm}\n              layout=\"vertical\"\n              size=\"large\"\n              onAutoSubmit={console.log}\n            >\n              <SchemaField>\n                <SchemaField.String\n                  name=\"username\"\n                  title=\"Username\"\n                  required\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                  x-validator={{\n                    required: true,\n                  }}\n                  x-component-props={{\n                    prefix: \"{{icon('UserOutlined')}}\",\n                  }}\n                />\n                <SchemaField.String\n                  name=\"password\"\n                  title=\"Password\"\n                  required\n                  x-decorator=\"FormItem\"\n                  x-component=\"Password\"\n                  x-component-props={{\n                    prefix: \"{{icon('LockOutlined')}}\",\n                  }}\n                />\n              </SchemaField>\n              <Submit block size=\"large\">\n                Log in\n              </Submit>\n            </Form>\n          </Tabs.TabPane>\n          <Tabs.TabPane key=\"2\" tab=\"Mobile Login\">\n            <Form\n              form={phoneForm}\n              layout=\"vertical\"\n              size=\"large\"\n              onAutoSubmit={console.log}\n            >\n              <SchemaField>\n                <SchemaField.String\n                  name=\"phone\"\n                  title=\"Phone Number\"\n                  required\n                  x-validator=\"phone\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                  x-component-props={{\n                    prefix: \"{{icon('PhoneOutlined')}}\",\n                  }}\n                />\n                <SchemaField.String\n                  name=\"verifyCode\"\n                  title=\"Verification Code\"\n                  required\n                  x-decorator=\"FormItem\"\n                  x-component=\"VerifyCode\"\n                  x-component-props={{\n                    prefix: \"{{icon('LockOutlined')}}\",\n                  }}\n                  x-reactions={[\n                    {\n                      dependencies: ['.phone#value', '.phone#valid'],\n                      fulfill: {\n                        state: {\n                          'component[1].readyPost': '{{$deps[0] && $deps[1]}}',\n                          'component[1].phoneNumber': '{{$deps[0]}}',\n                        },\n                      },\n                    },\n                  ]}\n                />\n              </SchemaField>\n              <Submit block size=\"large\">\n                Log in\n              </Submit>\n            </Form>\n          </Tabs.TabPane>\n        </Tabs>\n        <div\n          style={{\n            display: 'flex',\n            justifyContent: 'space-between',\n          }}\n        >\n          <a href=\"#Sign up\">Sign up</a>\n          <a href=\"#Forgot password\">Forgot password?</a>\n        </div>\n      </Card>\n    </div>\n  )\n}\n```\n\n#### JSON Schema Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input, Password, Submit } from '@formily/antd'\nimport { Tabs, Card } from 'antd'\nimport * as ICONS from '@ant-design/icons'\nimport { VerifyCode } from './VerifyCode'\n\nconst normalForm = createForm({\n  validateFirst: true,\n})\n\nconst phoneForm = createForm({\n  validateFirst: true,\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Password,\n    VerifyCode,\n  },\n  scope: {\n    icon(name) {\n      return React.createElement(ICONS[name])\n    },\n  },\n})\n\nconst normalSchema = {\n  type: 'object',\n  properties: {\n    username: {\n      type: 'string',\n      title: 'Username',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-component-props': {\n        prefix: \"{{icon('UserOutlined')}}\",\n      },\n    },\n    password: {\n      type: 'string',\n      title: 'Password',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Password',\n      'x-component-props': {\n        prefix: \"{{icon('LockOutlined')}}\",\n      },\n    },\n  },\n}\n\nconst phoneSchema = {\n  type: 'object',\n  properties: {\n    phone: {\n      type: 'string',\n      title: 'Phone Number',\n      required: true,\n      'x-validator': 'phone',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-component-props': {\n        prefix: \"{{icon('PhoneOutlined')}}\",\n      },\n    },\n    verifyCode: {\n      type: 'string',\n      title: 'Verification Code',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'VerifyCode',\n      'x-component-props': {\n        prefix: \"{{icon('LockOutlined')}}\",\n      },\n      'x-reactions': [\n        {\n          dependencies: ['.phone#value', '.phone#valid'],\n          fulfill: {\n            state: {\n              'component[1].readyPost': '{{$deps[0] && $deps[1]}}',\n              'component[1].phoneNumber': '{{$deps[0]}}',\n            },\n          },\n        },\n      ],\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card style={{ width: 400 }}>\n        <Tabs style={{ overflow: 'visible', marginTop: -10 }}>\n          <Tabs.TabPane key=\"1\" tab=\"Password Login\">\n            <Form\n              form={normalForm}\n              layout=\"vertical\"\n              size=\"large\"\n              onAutoSubmit={console.log}\n            >\n              <SchemaField schema={normalSchema} />\n              <Submit block size=\"large\">\n                Log in\n              </Submit>\n            </Form>\n          </Tabs.TabPane>\n          <Tabs.TabPane key=\"2\" tab=\"Mobile Login\">\n            <Form\n              form={phoneForm}\n              layout=\"vertical\"\n              size=\"large\"\n              onAutoSubmit={console.log}\n            >\n              <SchemaField schema={phoneSchema} />\n              <Submit block size=\"large\">\n                Log in\n              </Submit>\n            </Form>\n          </Tabs.TabPane>\n        </Tabs>\n        <div\n          style={{\n            display: 'flex',\n            justifyContent: 'space-between',\n          }}\n        >\n          <a href=\"#Sign up\">Sign up</a>\n          <a href=\"#Forgot password\">Forgot password?</a>\n        </div>\n      </Card>\n    </div>\n  )\n}\n```\n\n#### Pure JSX Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/react'\nimport { Form, FormItem, Input, Password, Submit } from '@formily/antd'\nimport { Tabs, Card } from 'antd'\nimport { UserOutlined, LockOutlined, PhoneOutlined } from '@ant-design/icons'\nimport { VerifyCode } from './VerifyCode'\n\nconst normalForm = createForm({\n  validateFirst: true,\n})\n\nconst phoneForm = createForm({\n  validateFirst: true,\n})\n\nexport default () => {\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card style={{ width: 400 }}>\n        <Tabs style={{ overflow: 'visible', marginTop: -10 }}>\n          <Tabs.TabPane key=\"1\" tab=\"Password Login\">\n            <Form\n              form={normalForm}\n              layout=\"vertical\"\n              size=\"large\"\n              onAutoSubmit={console.log}\n            >\n              <Field\n                name=\"username\"\n                title=\"Username\"\n                required\n                decorator={[FormItem]}\n                component={[\n                  Input,\n                  {\n                    prefix: <UserOutlined />,\n                  },\n                ]}\n              />\n              <Field\n                name=\"password\"\n                title=\"Password\"\n                required\n                decorator={[FormItem]}\n                component={[\n                  Password,\n                  {\n                    prefix: <LockOutlined />,\n                  },\n                ]}\n              />\n              <Submit block size=\"large\">\n                Log in\n              </Submit>\n            </Form>\n          </Tabs.TabPane>\n          <Tabs.TabPane key=\"2\" tab=\"Mobile Login\">\n            <Form\n              form={phoneForm}\n              layout=\"vertical\"\n              size=\"large\"\n              onAutoSubmit={console.log}\n            >\n              <Field\n                name=\"phone\"\n                title=\"Phone Number\"\n                required\n                validator=\"phone\"\n                decorator={[FormItem]}\n                component={[\n                  Input,\n                  {\n                    prefix: <PhoneOutlined />,\n                  },\n                ]}\n              />\n              <Field\n                name=\"verifyCode\"\n                title=\"Verification Code\"\n                required\n                reactions={(field) => {\n                  const phone = field.query('.phone')\n                  field.setComponentProps({\n                    readyPost: phone.get('valid') && phone.get('value'),\n                    phoneNumber: phone.get('value'),\n                  })\n                }}\n                decorator={[FormItem]}\n                component={[\n                  VerifyCode,\n                  {\n                    prefix: <LockOutlined />,\n                  },\n                ]}\n              />\n              <Submit block size=\"large\">\n                Log in\n              </Submit>\n            </Form>\n          </Tabs.TabPane>\n        </Tabs>\n        <div\n          style={{\n            display: 'flex',\n            justifyContent: 'space-between',\n          }}\n        >\n          <a href=\"#Sign up\">Sign up</a>\n          <a href=\"#Forgot password\">Forgot password?</a>\n        </div>\n      </Card>\n    </div>\n  )\n}\n```\n\n## Sign up\n\n#### Markup Schema Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  FormLayout,\n  Input,\n  Select,\n  Password,\n  Cascader,\n  DatePicker,\n  Submit,\n  Space,\n  FormGrid,\n  Upload,\n  ArrayItems,\n  Editable,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { action } from '@formily/reactive'\nimport { Card, Button } from 'antd'\nimport { UploadOutlined } from '@ant-design/icons'\n\nconst form = createForm({\n  validateFirst: true,\n})\n\nconst IDUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button icon={<UploadOutlined />}>Upload a copy</Button>\n    </Upload>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormGrid,\n    FormLayout,\n    Input,\n    DatePicker,\n    Cascader,\n    Select,\n    Password,\n    IDUpload,\n    Space,\n    ArrayItems,\n    Editable,\n  },\n  scope: {\n    fetchAddress: (field) => {\n      const transform = (data = {}) => {\n        return Object.entries(data).reduce((buf, [key, value]) => {\n          if (typeof value === 'string')\n            return buf.concat({\n              label: value,\n              value: key,\n            })\n          const { name, code, cities, districts } = value\n          const _cities = transform(cities)\n          const _districts = transform(districts)\n          return buf.concat({\n            label: name,\n            value: code,\n            children: _cities.length\n              ? _cities\n              : _districts.length\n              ? _districts\n              : undefined,\n          })\n        }, [])\n      }\n\n      field.loading = true\n      fetch('//unpkg.com/china-location/dist/location.json')\n        .then((res) => res.json())\n        .then(\n          action.bound((data) => {\n            field.dataSource = transform(data)\n            field.loading = false\n          })\n        )\n    },\n  },\n})\n\nexport default () => {\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card title=\"Sign up\" style={{ width: 620 }}>\n        <Form\n          form={form}\n          labelCol={5}\n          wrapperCol={16}\n          onAutoSubmit={console.log}\n        >\n          <SchemaField>\n            <SchemaField.String\n              name=\"username\"\n              title=\"Username\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"password\"\n              title=\"Password\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Password\"\n              x-component-props={{\n                checkStrength: true,\n              }}\n              x-reactions={[\n                {\n                  dependencies: ['.confirm_password'],\n                  fulfill: {\n                    state: {\n                      selfErrors:\n                        '{{$deps[0] && $self.value && $self.value !== $deps[0] ? \"Confirm that the password does not match\" : \"\"}}',\n                    },\n                  },\n                },\n              ]}\n            />\n            <SchemaField.String\n              name=\"confirm_password\"\n              title=\"Confirm Password\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Password\"\n              x-component-props={{\n                checkStrength: true,\n              }}\n              x-reactions={[\n                {\n                  dependencies: ['.password'],\n                  fulfill: {\n                    state: {\n                      selfErrors:\n                        '{{$deps[0] && $self.value && $self.value !== $deps[0] ? \"Confirm that the password does not match\" : \"\"}}',\n                    },\n                  },\n                },\n              ]}\n            />\n            <SchemaField.Void\n              title=\"name\"\n              x-decorator=\"FormItem\"\n              x-decorator-props={{\n                asterisk: true,\n                feedbackLayout: 'none',\n              }}\n              x-component=\"FormGrid\"\n            >\n              <SchemaField.String\n                name=\"firstName\"\n                x-decorator=\"FormItem\"\n                x-component=\"Input\"\n                x-component-props={{\n                  placeholder: 'firstname',\n                }}\n                required\n              />\n              <SchemaField.String\n                name=\"lastName\"\n                x-decorator=\"FormItem\"\n                x-component=\"Input\"\n                x-component-props={{\n                  placeholder: 'lastname',\n                }}\n                required\n              />\n            </SchemaField.Void>\n            <SchemaField.String\n              name=\"email\"\n              title=\"Email\"\n              required\n              x-validator=\"email\"\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"gender\"\n              title=\"Gender\"\n              x-decorator=\"FormItem\"\n              x-component=\"Select\"\n              enum={[\n                {\n                  label: 'male',\n                  value: 1,\n                },\n                {\n                  label: 'female',\n                  value: 2,\n                },\n                {\n                  label: 'third gender',\n                  value: 3,\n                },\n              ]}\n              required\n            />\n            <SchemaField.String\n              name=\"birthday\"\n              title=\"Birthday\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"DatePicker\"\n            />\n            <SchemaField.String\n              name=\"address\"\n              title=\"Address\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Cascader\"\n              x-reactions=\"{{fetchAddress}}\"\n            />\n            <SchemaField.String\n              name=\"idCard\"\n              title=\"ID\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"IDUpload\"\n            />\n            <SchemaField.Array\n              name=\"contacts\"\n              title=\"Contacts\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems\"\n            >\n              <SchemaField.Object x-component=\"ArrayItems.Item\">\n                <SchemaField.Void\n                  x-decorator=\"FormItem\"\n                  x-component=\"ArrayItems.SortHandle\"\n                />\n                <SchemaField.Void\n                  name=\"popover\"\n                  title=\"Contact Information\"\n                  x-decorator=\"Editable.Popover\"\n                  x-component=\"FormLayout\"\n                  x-component-props={{\n                    layout: 'vertical',\n                  }}\n                  x-reactions={[\n                    {\n                      dependencies: ['.popover.name'],\n                      fulfill: {\n                        schema: {\n                          title: '{{$deps[0]}}',\n                        },\n                      },\n                    },\n                  ]}\n                >\n                  <SchemaField.String\n                    name=\"name\"\n                    required\n                    title=\"Name\"\n                    x-decorator=\"FormItem\"\n                    x-component=\"Input\"\n                    x-component-props={{\n                      style: {\n                        width: 300,\n                      },\n                    }}\n                  />\n                  <SchemaField.String\n                    name=\"email\"\n                    title=\"Email\"\n                    x-validator={[{ required: true }, 'email']}\n                    x-decorator=\"FormItem\"\n                    x-component=\"Input\"\n                    x-component-props={{\n                      style: {\n                        width: 300,\n                      },\n                    }}\n                  />\n                  <SchemaField.String\n                    name=\"phone\"\n                    required\n                    title=\"Phone Number\"\n                    x-validator=\"phone\"\n                    x-decorator=\"FormItem\"\n                    x-component=\"Input\"\n                    x-component-props={{\n                      style: {\n                        width: 300,\n                      },\n                    }}\n                  />\n                </SchemaField.Void>\n                <SchemaField.Void\n                  x-decorator=\"FormItem\"\n                  x-component=\"ArrayItems.Remove\"\n                />\n              </SchemaField.Object>\n              <SchemaField.Void\n                x-component=\"ArrayItems.Addition\"\n                title=\"Add Contact\"\n              />\n            </SchemaField.Array>\n          </SchemaField>\n          <FormButtonGroup.FormItem>\n            <Submit block size=\"large\">\n              Sign up\n            </Submit>\n          </FormButtonGroup.FormItem>\n        </Form>\n      </Card>\n    </div>\n  )\n}\n```\n\n#### JSON Schema Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  FormLayout,\n  Input,\n  Select,\n  Password,\n  Cascader,\n  DatePicker,\n  Submit,\n  Space,\n  FormGrid,\n  Upload,\n  ArrayItems,\n  Editable,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { action } from '@formily/reactive'\nimport { Card, Button } from 'antd'\nimport { UploadOutlined } from '@ant-design/icons'\n\nconst form = createForm({\n  validateFirst: true,\n})\n\nconst IDUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button icon={<UploadOutlined />}>Upload a copy</Button>\n    </Upload>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormGrid,\n    FormLayout,\n    Input,\n    DatePicker,\n    Cascader,\n    Select,\n    Password,\n    IDUpload,\n    Space,\n    ArrayItems,\n    Editable,\n  },\n  scope: {\n    fetchAddress: (field) => {\n      const transform = (data = {}) => {\n        return Object.entries(data).reduce((buf, [key, value]) => {\n          if (typeof value === 'string')\n            return buf.concat({\n              label: value,\n              value: key,\n            })\n          const { name, code, cities, districts } = value\n          const _cities = transform(cities)\n          const _districts = transform(districts)\n          return buf.concat({\n            label: name,\n            value: code,\n            children: _cities.length\n              ? _cities\n              : _districts.length\n              ? _districts\n              : undefined,\n          })\n        }, [])\n      }\n\n      field.loading = true\n      fetch('//unpkg.com/china-location/dist/location.json')\n        .then((res) => res.json())\n        .then(\n          action.bound((data) => {\n            field.dataSource = transform(data)\n            field.loading = false\n          })\n        )\n    },\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    username: {\n      type: 'string',\n      title: 'Username',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    password: {\n      type: 'string',\n      title: 'Password',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Password',\n      'x-component-props': {\n        checkStrength: true,\n      },\n      'x-reactions': [\n        {\n          dependencies: ['.confirm_password'],\n          fulfill: {\n            state: {\n              selfErrors:\n                '{{$deps[0] && $self.value && $self.value !== $deps[0] ? \"确认password不匹配\" : \"\"}}',\n            },\n          },\n        },\n      ],\n    },\n    confirm_password: {\n      type: 'string',\n      title: 'Confirm Password',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Password',\n      'x-component-props': {\n        checkStrength: true,\n      },\n      'x-reactions': [\n        {\n          dependencies: ['.password'],\n          fulfill: {\n            state: {\n              selfErrors:\n                '{{$deps[0] && $self.value && $self.value !== $deps[0] ? \"Confirm that the password does not match\" : \"\"}}',\n            },\n          },\n        },\n      ],\n    },\n    name: {\n      type: 'void',\n      title: 'name',\n      'x-decorator': 'FormItem',\n      'x-decorator-props': {\n        asterisk: true,\n        feedbackLayout: 'none',\n      },\n      'x-component': 'FormGrid',\n      properties: {\n        firstName: {\n          type: 'string',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          'x-component-props': {\n            placeholder: 'firstname',\n          },\n        },\n        lastName: {\n          type: 'string',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          'x-component-props': {\n            placeholder: 'lastname',\n          },\n        },\n      },\n    },\n    email: {\n      type: 'string',\n      title: 'Email',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-validator': 'email',\n    },\n    gender: {\n      type: 'string',\n      title: 'Gender',\n      enum: [\n        {\n          label: 'male',\n          value: 1,\n        },\n        {\n          label: 'female',\n          value: 2,\n        },\n        {\n          label: 'third gender',\n          value: 3,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n    },\n    birthday: {\n      type: 'string',\n      required: true,\n      title: 'Birthday',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n    },\n    address: {\n      type: 'string',\n      required: true,\n      title: 'Address',\n      'x-decorator': 'FormItem',\n      'x-component': 'Cascader',\n      'x-reactions': '{{fetchAddress}}',\n    },\n    idCard: {\n      type: 'string',\n      required: true,\n      title: 'ID',\n      'x-decorator': 'FormItem',\n      'x-component': 'IDUpload',\n    },\n    contacts: {\n      type: 'array',\n      required: true,\n      title: 'Contacts',\n      'x-decorator': 'FormItem',\n      'x-component': 'ArrayItems',\n      items: {\n        type: 'object',\n        'x-component': 'ArrayItems.Item',\n        properties: {\n          sort: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.SortHandle',\n          },\n          popover: {\n            type: 'void',\n            title: 'improve contact information',\n            'x-decorator': 'Editable.Popover',\n            'x-component': 'FormLayout',\n            'x-component-props': {\n              layout: 'vertical',\n            },\n            'x-reactions': [\n              {\n                dependencies: ['.popover.name'],\n                fulfill: {\n                  schema: {\n                    title: '{{$deps[0]}}',\n                  },\n                },\n              },\n            ],\n            properties: {\n              name: {\n                type: 'string',\n                title: 'Name',\n                required: true,\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-component-props': {\n                  style: {\n                    width: 300,\n                  },\n                },\n              },\n              email: {\n                type: 'string',\n                title: 'Email',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-validator': [{ required: true }, 'email'],\n                'x-component-props': {\n                  style: {\n                    width: 300,\n                  },\n                },\n              },\n              phone: {\n                type: 'string',\n                title: 'Phone Number',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-validator': [{ required: true }, 'phone'],\n                'x-component-props': {\n                  style: {\n                    width: 300,\n                  },\n                },\n              },\n            },\n          },\n          remove: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.Remove',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add Contact',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card title=\"Sign up\" style={{ width: 620 }}>\n        <Form\n          form={form}\n          labelCol={5}\n          wrapperCol={16}\n          onAutoSubmit={console.log}\n        >\n          <SchemaField schema={schema} />\n          <FormButtonGroup.FormItem>\n            <Submit block size=\"large\">\n              Sign up\n            </Submit>\n          </FormButtonGroup.FormItem>\n        </Form>\n      </Card>\n    </div>\n  )\n}\n```\n\n#### Pure JSX Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { Field, VoidField, ArrayField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  Input,\n  Select,\n  Password,\n  Cascader,\n  DatePicker,\n  Submit,\n  FormGrid,\n  Upload,\n  FormButtonGroup,\n  ArrayBase,\n  Editable,\n  FormLayout,\n} from '@formily/antd'\nimport { action } from '@formily/reactive'\nimport { Card, Button } from 'antd'\nimport { UploadOutlined } from '@ant-design/icons'\n\nconst form = createForm({\n  validateFirst: true,\n})\n\nconst IDUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button icon={<UploadOutlined />}>Upload a copy</Button>\n    </Upload>\n  )\n}\n\nexport default () => {\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card title=\"Sign up\" style={{ width: 620 }}>\n        <Form\n          form={form}\n          labelCol={5}\n          wrapperCol={16}\n          onAutoSubmit={console.log}\n        >\n          <Field\n            name=\"username\"\n            title=\"Username\"\n            required\n            decorator={[FormItem]}\n            component={[Input]}\n          />\n          <Field\n            name=\"password\"\n            title=\"Password\"\n            required\n            decorator={[FormItem]}\n            component={[\n              Password,\n              {\n                checkStrength: true,\n              },\n            ]}\n            reactions={(field) => {\n              const confirm = field.query('.confirm_password')\n              field.selfErrors =\n                confirm.get('value') &&\n                field.value &&\n                field.value !== confirm.get('value')\n                  ? 'Confirm that the password does not match'\n                  : ''\n            }}\n          />\n          <Field\n            name=\"confirm_password\"\n            title=\"Confirm Password\"\n            required\n            decorator={[FormItem]}\n            component={[\n              Password,\n              {\n                checkStrength: true,\n              },\n            ]}\n            reactions={(field) => {\n              const password = field.query('.password')\n              field.selfErrors =\n                password.get('value') &&\n                field.value &&\n                field.value !== password.get('value')\n                  ? 'Confirm that the password does not match'\n                  : ''\n            }}\n          />\n          <VoidField\n            name=\"name\"\n            title=\"Name\"\n            decorator={[\n              FormItem,\n              {\n                asterisk: true,\n                feedbackLayout: 'none',\n              },\n            ]}\n            component={[FormGrid]}\n          >\n            <Field\n              name=\"firstName\"\n              decorator={[FormItem]}\n              component={[\n                Input,\n                {\n                  placeholder: 'firstname',\n                },\n              ]}\n              required\n            />\n            <Field\n              name=\"lastName\"\n              decorator={[FormItem]}\n              component={[\n                Input,\n                {\n                  placeholder: 'lastname',\n                },\n              ]}\n              required\n            />\n          </VoidField>\n          <Field\n            name=\"email\"\n            title=\"Email\"\n            required\n            validator=\"email\"\n            decorator={[FormItem]}\n            component={[Input]}\n          />\n          <Field\n            name=\"gender\"\n            title=\"Gender\"\n            decorator={[FormItem]}\n            component={[Select]}\n            dataSource={[\n              {\n                label: 'male',\n                value: 1,\n              },\n              {\n                label: 'female',\n                value: 2,\n              },\n              {\n                label: 'third gender',\n                value: 3,\n              },\n            ]}\n            required\n          />\n          <Field\n            name=\"birthday\"\n            title=\"Birthday\"\n            required\n            decorator={[FormItem]}\n            component={[DatePicker]}\n          />\n          <Field\n            name=\"address\"\n            title=\"Address\"\n            required\n            decorator={[FormItem]}\n            component={[Cascader]}\n            reactions={(field) => {\n              const transform = (data = {}) => {\n                return Object.entries(data).reduce((buf, [key, value]) => {\n                  if (typeof value === 'string')\n                    return buf.concat({\n                      label: value,\n                      value: key,\n                    })\n                  const { name, code, cities, districts } = value\n                  const _cities = transform(cities)\n                  const _districts = transform(districts)\n                  return buf.concat({\n                    label: name,\n                    value: code,\n                    children: _cities.length\n                      ? _cities\n                      : _districts.length\n                      ? _districts\n                      : undefined,\n                  })\n                }, [])\n              }\n\n              field.loading = true\n              fetch('//unpkg.com/china-location/dist/location.json')\n                .then((res) => res.json())\n                .then(\n                  action.bound((data) => {\n                    field.dataSource = transform(data)\n                    field.loading = false\n                  })\n                )\n            }}\n          />\n          <Field\n            name=\"idCard\"\n            title=\"ID\"\n            required\n            decorator={[FormItem]}\n            component={[IDUpload]}\n          />\n          <ArrayField name=\"contacts\" title=\"Contacts\" decorator={[FormItem]}>\n            {(field) => (\n              <ArrayBase>\n                {field.value?.map((item, index) => (\n                  <div key={index} className=\"array-items-item\">\n                    <Field\n                      name={`${index}`}\n                      title=\"Contact Informations\"\n                      component={[Editable.Popover]}\n                      reactions={(field) => {\n                        field.title =\n                          field.query('.[].name').value() || field.title\n                      }}\n                    >\n                      <VoidField\n                        name=\"layout\"\n                        component={[FormLayout, { layout: 'vertical' }]}\n                      >\n                        <Field\n                          name=\"name\"\n                          title=\"Name\"\n                          required\n                          decorator={[FormItem]}\n                          component={[\n                            Input,\n                            {\n                              style: {\n                                width: 300,\n                              },\n                            },\n                          ]}\n                        />\n                        <Field\n                          name=\"email\"\n                          title=\"Email\"\n                          required\n                          validator=\"email\"\n                          decorator={[FormItem]}\n                          component={[\n                            Input,\n                            {\n                              style: {\n                                width: 300,\n                              },\n                            },\n                          ]}\n                        />\n                        <Field\n                          name=\"phone\"\n                          title=\"Phone Number\"\n                          required\n                          validator=\"phone\"\n                          decorator={[FormItem]}\n                          component={[\n                            Input,\n                            {\n                              style: {\n                                width: 300,\n                              },\n                            },\n                          ]}\n                        />\n                      </VoidField>\n                    </Field>\n                    <FormItem.BaseItem>\n                      <ArrayBase.Remove index={index} />\n                      <ArrayBase.MoveDown index={index} />\n                      <ArrayBase.MoveUp index={index} />\n                    </FormItem.BaseItem>\n                  </div>\n                ))}\n                <ArrayBase.Addition title=\"Add Contact\" />\n              </ArrayBase>\n            )}\n          </ArrayField>\n          <FormButtonGroup.FormItem>\n            <Submit block size=\"large\">\n              Sign up\n            </Submit>\n          </FormButtonGroup.FormItem>\n        </Form>\n      </Card>\n    </div>\n  )\n}\n```\n\n## Forgot password\n\n#### Markup Schema Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  Input,\n  Password,\n  Submit,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { Card } from 'antd'\n\nconst form = createForm({\n  validateFirst: true,\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Password,\n  },\n})\n\nexport default () => {\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card title=\"change password\" style={{ width: 620 }}>\n        <Form\n          form={form}\n          labelCol={5}\n          wrapperCol={16}\n          onAutoSubmit={console.log}\n        >\n          <SchemaField>\n            <SchemaField.String\n              name=\"username\"\n              title=\"Username\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"email\"\n              title=\"Email\"\n              required\n              x-validator=\"email\"\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"old_password\"\n              title=\"Old Password\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Password\"\n            />\n            <SchemaField.String\n              name=\"password\"\n              title=\"New Password\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Password\"\n              x-component-props={{\n                checkStrength: true,\n              }}\n              x-reactions={[\n                {\n                  dependencies: ['.confirm_password'],\n                  fulfill: {\n                    state: {\n                      selfErrors:\n                        '{{$deps[0] && $self.value && $self.value !== $deps[0] ? \"Confirm that the password does not match\" : \"\"}}',\n                    },\n                  },\n                },\n              ]}\n            />\n            <SchemaField.String\n              name=\"confirm_password\"\n              title=\"Confirm Password\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Password\"\n              x-component-props={{\n                checkStrength: true,\n              }}\n              x-reactions={[\n                {\n                  dependencies: ['.password'],\n                  fulfill: {\n                    state: {\n                      selfErrors:\n                        '{{$deps[0] && $self.value && $self.value !== $deps[0] ? \"Confirm that the password does not match\" : \"\"}}',\n                    },\n                  },\n                },\n              ]}\n            />\n          </SchemaField>\n          <FormButtonGroup.FormItem>\n            <Submit block size=\"large\">\n              Confirm\n            </Submit>\n          </FormButtonGroup.FormItem>\n        </Form>\n      </Card>\n    </div>\n  )\n}\n```\n\n#### JSON Schema Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  Input,\n  Password,\n  Submit,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { Card } from 'antd'\n\nconst form = createForm({\n  validateFirst: true,\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Password,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    username: {\n      type: 'string',\n      title: 'Username',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    email: {\n      type: 'string',\n      title: 'Email',\n      required: true,\n      'x-validator': 'email',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    oldPassword: {\n      type: 'string',\n      title: 'Old Password',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Password',\n    },\n    password: {\n      type: 'string',\n      title: 'New Password',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Password',\n      'x-component-props': {\n        checkStrength: true,\n      },\n      'x-reactions': [\n        {\n          dependencies: ['.confirm_password'],\n          fulfill: {\n            state: {\n              selfErrors:\n                '{{$deps[0] && $self.value && $self.value !== $deps[0] ? \"Confirm that the password does not match\" : \"\"}}',\n            },\n          },\n        },\n      ],\n    },\n    confirm_password: {\n      type: 'string',\n      title: 'Confirm Password',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Password',\n      'x-component-props': {\n        checkStrength: true,\n      },\n      'x-reactions': [\n        {\n          dependencies: ['.password'],\n          fulfill: {\n            state: {\n              selfErrors:\n                '{{$deps[0] && $self.value && $self.value !== $deps[0] ? \"Confirm that the password does not match\" : \"\"}}',\n            },\n          },\n        },\n      ],\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card title=\"change password\" style={{ width: 620 }}>\n        <Form\n          form={form}\n          labelCol={5}\n          wrapperCol={16}\n          onAutoSubmit={console.log}\n        >\n          <SchemaField schema={schema} />\n          <FormButtonGroup.FormItem>\n            <Submit block size=\"large\">\n              Confirm\n            </Submit>\n          </FormButtonGroup.FormItem>\n        </Form>\n      </Card>\n    </div>\n  )\n}\n```\n\n#### Pure JSX Cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  Input,\n  Password,\n  Submit,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { Card } from 'antd'\n\nconst form = createForm({\n  validateFirst: true,\n})\n\nexport default () => {\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card title=\"change password\" style={{ width: 620 }}>\n        <Form\n          form={form}\n          labelCol={5}\n          wrapperCol={16}\n          onAutoSubmit={console.log}\n        >\n          <Field\n            name=\"username\"\n            title=\"Username\"\n            required\n            decorator={[FormItem]}\n            component={[Input]}\n          />\n          <Field\n            name=\"email\"\n            title=\"Email\"\n            required\n            validator=\"email\"\n            decorator={[FormItem]}\n            component={[Input]}\n          />\n          <Field\n            name=\"old_password\"\n            title=\"Old Password\"\n            required\n            decorator={[FormItem]}\n            component={[Password]}\n          />\n          <Field\n            name=\"password\"\n            title=\"New Password\"\n            required\n            decorator={[FormItem]}\n            component={[\n              Password,\n              {\n                checkStrength: true,\n              },\n            ]}\n            reactions={(field) => {\n              const confirm = field.query('.confirm_password')\n              field.selfErrors =\n                confirm.get('value') &&\n                field.value &&\n                field.value !== confirm.get('value')\n                  ? 'Confirm that the password does not match'\n                  : ''\n            }}\n          />\n          <Field\n            name=\"confirm_password\"\n            title=\"Confirm Password\"\n            required\n            decorator={[FormItem]}\n            component={[\n              Password,\n              {\n                checkStrength: true,\n              },\n            ]}\n            reactions={(field) => {\n              const confirm = field.query('.password')\n              field.selfErrors =\n                confirm.get('value') &&\n                field.value &&\n                field.value !== confirm.get('value')\n                  ? 'Confirm that the password does not match'\n                  : ''\n            }}\n          />\n          <FormButtonGroup.FormItem>\n            <Submit block size=\"large\">\n              Confirm change\n            </Submit>\n          </FormButtonGroup.FormItem>\n        </Form>\n      </Card>\n    </div>\n  )\n}\n```\n"
  },
  {
    "path": "docs/guide/scenes/login-register.zh-CN.md",
    "content": "# 登录注册\n\n## 登录\n\n#### Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input, Password, Submit } from '@formily/antd'\nimport { Tabs, Card } from 'antd'\nimport * as ICONS from '@ant-design/icons'\nimport { VerifyCode } from './VerifyCode'\n\nconst normalForm = createForm({\n  validateFirst: true,\n})\n\nconst phoneForm = createForm({\n  validateFirst: true,\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Password,\n    VerifyCode,\n  },\n  scope: {\n    icon(name) {\n      return React.createElement(ICONS[name])\n    },\n  },\n})\n\nexport default () => {\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card style={{ width: 400 }}>\n        <Tabs style={{ overflow: 'visible', marginTop: -10 }}>\n          <Tabs.TabPane key=\"1\" tab=\"账密登录\">\n            <Form\n              form={normalForm}\n              layout=\"vertical\"\n              size=\"large\"\n              onAutoSubmit={console.log}\n            >\n              <SchemaField>\n                <SchemaField.String\n                  name=\"username\"\n                  title=\"用户名\"\n                  required\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                  x-validator={{\n                    required: true,\n                  }}\n                  x-component-props={{\n                    prefix: \"{{icon('UserOutlined')}}\",\n                  }}\n                />\n                <SchemaField.String\n                  name=\"password\"\n                  title=\"密码\"\n                  required\n                  x-decorator=\"FormItem\"\n                  x-component=\"Password\"\n                  x-component-props={{\n                    prefix: \"{{icon('LockOutlined')}}\",\n                  }}\n                />\n              </SchemaField>\n              <Submit block size=\"large\">\n                登录\n              </Submit>\n            </Form>\n          </Tabs.TabPane>\n          <Tabs.TabPane key=\"2\" tab=\"手机登录\">\n            <Form\n              form={phoneForm}\n              layout=\"vertical\"\n              size=\"large\"\n              onAutoSubmit={console.log}\n            >\n              <SchemaField>\n                <SchemaField.String\n                  name=\"phone\"\n                  title=\"手机号\"\n                  required\n                  x-validator=\"phone\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                  x-component-props={{\n                    prefix: \"{{icon('PhoneOutlined')}}\",\n                  }}\n                />\n                <SchemaField.String\n                  name=\"verifyCode\"\n                  title=\"验证码\"\n                  required\n                  x-decorator=\"FormItem\"\n                  x-component=\"VerifyCode\"\n                  x-component-props={{\n                    prefix: \"{{icon('LockOutlined')}}\",\n                  }}\n                  x-reactions={[\n                    {\n                      dependencies: ['.phone#value', '.phone#valid'],\n                      fulfill: {\n                        state: {\n                          'component[1].readyPost': '{{$deps[0] && $deps[1]}}',\n                          'component[1].phoneNumber': '{{$deps[0]}}',\n                        },\n                      },\n                    },\n                  ]}\n                />\n              </SchemaField>\n              <Submit block size=\"large\">\n                登录\n              </Submit>\n            </Form>\n          </Tabs.TabPane>\n        </Tabs>\n        <div\n          style={{\n            display: 'flex',\n            justifyContent: 'space-between',\n          }}\n        >\n          <a href=\"#新用户注册\">新用户注册</a>\n          <a href=\"#忘记密码\">忘记密码?</a>\n        </div>\n      </Card>\n    </div>\n  )\n}\n```\n\n#### JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport { Form, FormItem, Input, Password, Submit } from '@formily/antd'\nimport { Tabs, Card } from 'antd'\nimport * as ICONS from '@ant-design/icons'\nimport { VerifyCode } from './VerifyCode'\n\nconst normalForm = createForm({\n  validateFirst: true,\n})\n\nconst phoneForm = createForm({\n  validateFirst: true,\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Password,\n    VerifyCode,\n  },\n  scope: {\n    icon(name) {\n      return React.createElement(ICONS[name])\n    },\n  },\n})\n\nconst normalSchema = {\n  type: 'object',\n  properties: {\n    username: {\n      type: 'string',\n      title: '用户名',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-component-props': {\n        prefix: \"{{icon('UserOutlined')}}\",\n      },\n    },\n    password: {\n      type: 'string',\n      title: '密码',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Password',\n      'x-component-props': {\n        prefix: \"{{icon('LockOutlined')}}\",\n      },\n    },\n  },\n}\n\nconst phoneSchema = {\n  type: 'object',\n  properties: {\n    phone: {\n      type: 'string',\n      title: '手机号',\n      required: true,\n      'x-validator': 'phone',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-component-props': {\n        prefix: \"{{icon('PhoneOutlined')}}\",\n      },\n    },\n    verifyCode: {\n      type: 'string',\n      title: '验证码',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'VerifyCode',\n      'x-component-props': {\n        prefix: \"{{icon('LockOutlined')}}\",\n      },\n      'x-reactions': [\n        {\n          dependencies: ['.phone#value', '.phone#valid'],\n          fulfill: {\n            state: {\n              'component[1].readyPost': '{{$deps[0] && $deps[1]}}',\n              'component[1].phoneNumber': '{{$deps[0]}}',\n            },\n          },\n        },\n      ],\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card style={{ width: 400 }}>\n        <Tabs style={{ overflow: 'visible', marginTop: -10 }}>\n          <Tabs.TabPane key=\"1\" tab=\"账密登录\">\n            <Form\n              form={normalForm}\n              layout=\"vertical\"\n              size=\"large\"\n              onAutoSubmit={console.log}\n            >\n              <SchemaField schema={normalSchema} />\n              <Submit block size=\"large\">\n                登录\n              </Submit>\n            </Form>\n          </Tabs.TabPane>\n          <Tabs.TabPane key=\"2\" tab=\"手机登录\">\n            <Form\n              form={phoneForm}\n              layout=\"vertical\"\n              size=\"large\"\n              onAutoSubmit={console.log}\n            >\n              <SchemaField schema={phoneSchema} />\n              <Submit block size=\"large\">\n                登录\n              </Submit>\n            </Form>\n          </Tabs.TabPane>\n        </Tabs>\n        <div\n          style={{\n            display: 'flex',\n            justifyContent: 'space-between',\n          }}\n        >\n          <a href=\"#新用户注册\">新用户注册</a>\n          <a href=\"#忘记密码\">忘记密码?</a>\n        </div>\n      </Card>\n    </div>\n  )\n}\n```\n\n#### 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/react'\nimport { Form, FormItem, Input, Password, Submit } from '@formily/antd'\nimport { Tabs, Card } from 'antd'\nimport { UserOutlined, LockOutlined, PhoneOutlined } from '@ant-design/icons'\nimport { VerifyCode } from './VerifyCode'\n\nconst normalForm = createForm({\n  validateFirst: true,\n})\n\nconst phoneForm = createForm({\n  validateFirst: true,\n})\n\nexport default () => {\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card style={{ width: 400 }}>\n        <Tabs style={{ overflow: 'visible', marginTop: -10 }}>\n          <Tabs.TabPane key=\"1\" tab=\"账密登录\">\n            <Form\n              form={normalForm}\n              layout=\"vertical\"\n              size=\"large\"\n              onAutoSubmit={console.log}\n            >\n              <Field\n                name=\"username\"\n                title=\"用户名\"\n                required\n                decorator={[FormItem]}\n                component={[\n                  Input,\n                  {\n                    prefix: <UserOutlined />,\n                  },\n                ]}\n              />\n              <Field\n                name=\"password\"\n                title=\"密码\"\n                required\n                decorator={[FormItem]}\n                component={[\n                  Password,\n                  {\n                    prefix: <LockOutlined />,\n                  },\n                ]}\n              />\n              <Submit block size=\"large\">\n                登录\n              </Submit>\n            </Form>\n          </Tabs.TabPane>\n          <Tabs.TabPane key=\"2\" tab=\"手机登录\">\n            <Form\n              form={phoneForm}\n              layout=\"vertical\"\n              size=\"large\"\n              onAutoSubmit={console.log}\n            >\n              <Field\n                name=\"phone\"\n                title=\"手机号\"\n                required\n                validator=\"phone\"\n                decorator={[FormItem]}\n                component={[\n                  Input,\n                  {\n                    prefix: <PhoneOutlined />,\n                  },\n                ]}\n              />\n              <Field\n                name=\"verifyCode\"\n                title=\"验证码\"\n                required\n                reactions={(field) => {\n                  const phone = field.query('.phone')\n                  field.setComponentProps({\n                    readyPost: phone.get('valid') && phone.get('value'),\n                    phoneNumber: phone.get('value'),\n                  })\n                }}\n                decorator={[FormItem]}\n                component={[\n                  VerifyCode,\n                  {\n                    prefix: <LockOutlined />,\n                  },\n                ]}\n              />\n              <Submit block size=\"large\">\n                登录\n              </Submit>\n            </Form>\n          </Tabs.TabPane>\n        </Tabs>\n        <div\n          style={{\n            display: 'flex',\n            justifyContent: 'space-between',\n          }}\n        >\n          <a href=\"#新用户注册\">新用户注册</a>\n          <a href=\"#忘记密码\">忘记密码?</a>\n        </div>\n      </Card>\n    </div>\n  )\n}\n```\n\n## 新用户注册\n\n#### Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  FormLayout,\n  Input,\n  Select,\n  Password,\n  Cascader,\n  DatePicker,\n  Submit,\n  Space,\n  FormGrid,\n  Upload,\n  ArrayItems,\n  Editable,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { action } from '@formily/reactive'\nimport { Card, Button } from 'antd'\nimport { UploadOutlined } from '@ant-design/icons'\n\nconst form = createForm({\n  validateFirst: true,\n})\n\nconst IDUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button icon={<UploadOutlined />}>上传复印件</Button>\n    </Upload>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormGrid,\n    FormLayout,\n    Input,\n    DatePicker,\n    Cascader,\n    Select,\n    Password,\n    IDUpload,\n    Space,\n    ArrayItems,\n    Editable,\n  },\n  scope: {\n    fetchAddress: (field) => {\n      const transform = (data = {}) => {\n        return Object.entries(data).reduce((buf, [key, value]) => {\n          if (typeof value === 'string')\n            return buf.concat({\n              label: value,\n              value: key,\n            })\n          const { name, code, cities, districts } = value\n          const _cities = transform(cities)\n          const _districts = transform(districts)\n          return buf.concat({\n            label: name,\n            value: code,\n            children: _cities.length\n              ? _cities\n              : _districts.length\n              ? _districts\n              : undefined,\n          })\n        }, [])\n      }\n\n      field.loading = true\n      fetch('//unpkg.com/china-location/dist/location.json')\n        .then((res) => res.json())\n        .then(\n          action.bound((data) => {\n            field.dataSource = transform(data)\n            field.loading = false\n          })\n        )\n    },\n  },\n})\n\nexport default () => {\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card title=\"新用户注册\" style={{ width: 620 }}>\n        <Form\n          form={form}\n          labelCol={5}\n          wrapperCol={16}\n          onAutoSubmit={console.log}\n        >\n          <SchemaField>\n            <SchemaField.String\n              name=\"username\"\n              title=\"用户名\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"password\"\n              title=\"密码\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Password\"\n              x-component-props={{\n                checkStrength: true,\n              }}\n              x-reactions={[\n                {\n                  dependencies: ['.confirm_password'],\n                  fulfill: {\n                    state: {\n                      selfErrors:\n                        '{{$deps[0] && $self.value && $self.value !== $deps[0] ? \"确认密码不匹配\" : \"\"}}',\n                    },\n                  },\n                },\n              ]}\n            />\n            <SchemaField.String\n              name=\"confirm_password\"\n              title=\"确认密码\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Password\"\n              x-component-props={{\n                checkStrength: true,\n              }}\n              x-reactions={[\n                {\n                  dependencies: ['.password'],\n                  fulfill: {\n                    state: {\n                      selfErrors:\n                        '{{$deps[0] && $self.value && $self.value !== $deps[0] ? \"确认密码不匹配\" : \"\"}}',\n                    },\n                  },\n                },\n              ]}\n            />\n            <SchemaField.Void\n              title=\"姓名\"\n              x-decorator=\"FormItem\"\n              x-decorator-props={{\n                asterisk: true,\n                feedbackLayout: 'none',\n              }}\n              x-component=\"FormGrid\"\n            >\n              <SchemaField.String\n                name=\"firstName\"\n                x-decorator=\"FormItem\"\n                x-component=\"Input\"\n                x-component-props={{\n                  placeholder: '姓',\n                }}\n                required\n              />\n              <SchemaField.String\n                name=\"lastName\"\n                x-decorator=\"FormItem\"\n                x-component=\"Input\"\n                x-component-props={{\n                  placeholder: '名',\n                }}\n                required\n              />\n            </SchemaField.Void>\n            <SchemaField.String\n              name=\"email\"\n              title=\"邮箱\"\n              required\n              x-validator=\"email\"\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"gender\"\n              title=\"性别\"\n              x-decorator=\"FormItem\"\n              x-component=\"Select\"\n              enum={[\n                {\n                  label: '男',\n                  value: 1,\n                },\n                {\n                  label: '女',\n                  value: 2,\n                },\n                {\n                  label: '第三性别',\n                  value: 3,\n                },\n              ]}\n              required\n            />\n            <SchemaField.String\n              name=\"birthday\"\n              title=\"生日\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"DatePicker\"\n            />\n            <SchemaField.String\n              name=\"address\"\n              title=\"地址\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Cascader\"\n              x-reactions=\"{{fetchAddress}}\"\n            />\n            <SchemaField.String\n              name=\"idCard\"\n              title=\"身份证复印件\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"IDUpload\"\n            />\n            <SchemaField.Array\n              name=\"contacts\"\n              title=\"联系人信息\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems\"\n            >\n              <SchemaField.Object x-component=\"ArrayItems.Item\">\n                <SchemaField.Void\n                  x-decorator=\"FormItem\"\n                  x-component=\"ArrayItems.SortHandle\"\n                />\n                <SchemaField.Void\n                  name=\"popover\"\n                  title=\"维护联系人信息\"\n                  x-decorator=\"Editable.Popover\"\n                  x-component=\"FormLayout\"\n                  x-component-props={{\n                    layout: 'vertical',\n                  }}\n                  x-reactions={[\n                    {\n                      dependencies: ['.popover.name'],\n                      fulfill: {\n                        schema: {\n                          title: '{{$deps[0]}}',\n                        },\n                      },\n                    },\n                  ]}\n                >\n                  <SchemaField.String\n                    name=\"name\"\n                    required\n                    title=\"姓名\"\n                    x-decorator=\"FormItem\"\n                    x-component=\"Input\"\n                    x-component-props={{\n                      style: {\n                        width: 300,\n                      },\n                    }}\n                  />\n                  <SchemaField.String\n                    name=\"email\"\n                    title=\"邮箱\"\n                    x-validator={[{ required: true }, 'email']}\n                    x-decorator=\"FormItem\"\n                    x-component=\"Input\"\n                    x-component-props={{\n                      style: {\n                        width: 300,\n                      },\n                    }}\n                  />\n                  <SchemaField.String\n                    name=\"phone\"\n                    required\n                    title=\"手机号\"\n                    x-validator=\"phone\"\n                    x-decorator=\"FormItem\"\n                    x-component=\"Input\"\n                    x-component-props={{\n                      style: {\n                        width: 300,\n                      },\n                    }}\n                  />\n                </SchemaField.Void>\n                <SchemaField.Void\n                  x-decorator=\"FormItem\"\n                  x-component=\"ArrayItems.Remove\"\n                />\n              </SchemaField.Object>\n              <SchemaField.Void\n                x-component=\"ArrayItems.Addition\"\n                title=\"新增联系人\"\n              />\n            </SchemaField.Array>\n          </SchemaField>\n          <FormButtonGroup.FormItem>\n            <Submit block size=\"large\">\n              注册\n            </Submit>\n          </FormButtonGroup.FormItem>\n        </Form>\n      </Card>\n    </div>\n  )\n}\n```\n\n#### JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  FormLayout,\n  Input,\n  Select,\n  Password,\n  Cascader,\n  DatePicker,\n  Submit,\n  Space,\n  FormGrid,\n  Upload,\n  ArrayItems,\n  Editable,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { action } from '@formily/reactive'\nimport { Card, Button } from 'antd'\nimport { UploadOutlined } from '@ant-design/icons'\n\nconst form = createForm({\n  validateFirst: true,\n})\n\nconst IDUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button icon={<UploadOutlined />}>上传复印件</Button>\n    </Upload>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormGrid,\n    FormLayout,\n    Input,\n    DatePicker,\n    Cascader,\n    Select,\n    Password,\n    IDUpload,\n    Space,\n    ArrayItems,\n    Editable,\n  },\n  scope: {\n    fetchAddress: (field) => {\n      const transform = (data = {}) => {\n        return Object.entries(data).reduce((buf, [key, value]) => {\n          if (typeof value === 'string')\n            return buf.concat({\n              label: value,\n              value: key,\n            })\n          const { name, code, cities, districts } = value\n          const _cities = transform(cities)\n          const _districts = transform(districts)\n          return buf.concat({\n            label: name,\n            value: code,\n            children: _cities.length\n              ? _cities\n              : _districts.length\n              ? _districts\n              : undefined,\n          })\n        }, [])\n      }\n\n      field.loading = true\n      fetch('//unpkg.com/china-location/dist/location.json')\n        .then((res) => res.json())\n        .then(\n          action.bound((data) => {\n            field.dataSource = transform(data)\n            field.loading = false\n          })\n        )\n    },\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    username: {\n      type: 'string',\n      title: '用户名',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    password: {\n      type: 'string',\n      title: '密码',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Password',\n      'x-component-props': {\n        checkStrength: true,\n      },\n      'x-reactions': [\n        {\n          dependencies: ['.confirm_password'],\n          fulfill: {\n            state: {\n              selfErrors:\n                '{{$deps[0] && $self.value && $self.value !== $deps[0] ? \"确认密码不匹配\" : \"\"}}',\n            },\n          },\n        },\n      ],\n    },\n    confirm_password: {\n      type: 'string',\n      title: '确认密码',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Password',\n      'x-component-props': {\n        checkStrength: true,\n      },\n      'x-reactions': [\n        {\n          dependencies: ['.password'],\n          fulfill: {\n            state: {\n              selfErrors:\n                '{{$deps[0] && $self.value && $self.value !== $deps[0] ? \"确认密码不匹配\" : \"\"}}',\n            },\n          },\n        },\n      ],\n    },\n    name: {\n      type: 'void',\n      title: '姓名',\n      'x-decorator': 'FormItem',\n      'x-decorator-props': {\n        asterisk: true,\n        feedbackLayout: 'none',\n      },\n      'x-component': 'FormGrid',\n      properties: {\n        firstName: {\n          type: 'string',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          'x-component-props': {\n            placeholder: '姓',\n          },\n        },\n        lastName: {\n          type: 'string',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          'x-component-props': {\n            placeholder: '名',\n          },\n        },\n      },\n    },\n    email: {\n      type: 'string',\n      title: '邮箱',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-validator': 'email',\n    },\n    gender: {\n      type: 'string',\n      title: '性别',\n      enum: [\n        {\n          label: '男',\n          value: 1,\n        },\n        {\n          label: '女',\n          value: 2,\n        },\n        {\n          label: '第三性别',\n          value: 3,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n    },\n    birthday: {\n      type: 'string',\n      required: true,\n      title: '生日',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n    },\n    address: {\n      type: 'string',\n      required: true,\n      title: '地址',\n      'x-decorator': 'FormItem',\n      'x-component': 'Cascader',\n      'x-reactions': '{{fetchAddress}}',\n    },\n    idCard: {\n      type: 'string',\n      required: true,\n      title: '身份证复印件',\n      'x-decorator': 'FormItem',\n      'x-component': 'IDUpload',\n    },\n    contacts: {\n      type: 'array',\n      required: true,\n      title: '联系人信息',\n      'x-decorator': 'FormItem',\n      'x-component': 'ArrayItems',\n      items: {\n        type: 'object',\n        'x-component': 'ArrayItems.Item',\n        properties: {\n          sort: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.SortHandle',\n          },\n          popover: {\n            type: 'void',\n            title: '完善联系人信息',\n            'x-decorator': 'Editable.Popover',\n            'x-component': 'FormLayout',\n            'x-component-props': {\n              layout: 'vertical',\n            },\n            'x-reactions': [\n              {\n                dependencies: ['.popover.name'],\n                fulfill: {\n                  schema: {\n                    title: '{{$deps[0]}}',\n                  },\n                },\n              },\n            ],\n            properties: {\n              name: {\n                type: 'string',\n                title: '姓名',\n                required: true,\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-component-props': {\n                  style: {\n                    width: 300,\n                  },\n                },\n              },\n              email: {\n                type: 'string',\n                title: '邮箱',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-validator': [{ required: true }, 'email'],\n                'x-component-props': {\n                  style: {\n                    width: 300,\n                  },\n                },\n              },\n              phone: {\n                type: 'string',\n                title: '手机号',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-validator': [{ required: true }, 'phone'],\n                'x-component-props': {\n                  style: {\n                    width: 300,\n                  },\n                },\n              },\n            },\n          },\n          remove: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.Remove',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '新增联系人',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card title=\"新用户注册\" style={{ width: 620 }}>\n        <Form\n          form={form}\n          labelCol={5}\n          wrapperCol={16}\n          onAutoSubmit={console.log}\n        >\n          <SchemaField schema={schema} />\n          <FormButtonGroup.FormItem>\n            <Submit block size=\"large\">\n              注册\n            </Submit>\n          </FormButtonGroup.FormItem>\n        </Form>\n      </Card>\n    </div>\n  )\n}\n```\n\n#### 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { Field, VoidField, ArrayField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  Input,\n  Select,\n  Password,\n  Cascader,\n  DatePicker,\n  Submit,\n  FormGrid,\n  Upload,\n  FormButtonGroup,\n  ArrayBase,\n  Editable,\n  FormLayout,\n} from '@formily/antd'\nimport { action } from '@formily/reactive'\nimport { Card, Button } from 'antd'\nimport { UploadOutlined } from '@ant-design/icons'\n\nconst form = createForm({\n  validateFirst: true,\n})\n\nconst IDUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button icon={<UploadOutlined />}>上传复印件</Button>\n    </Upload>\n  )\n}\n\nexport default () => {\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card title=\"新用户注册\" style={{ width: 620 }}>\n        <Form\n          form={form}\n          labelCol={5}\n          wrapperCol={16}\n          onAutoSubmit={console.log}\n        >\n          <Field\n            name=\"username\"\n            title=\"用户名\"\n            required\n            decorator={[FormItem]}\n            component={[Input]}\n          />\n          <Field\n            name=\"password\"\n            title=\"密码\"\n            required\n            decorator={[FormItem]}\n            component={[\n              Password,\n              {\n                checkStrength: true,\n              },\n            ]}\n            reactions={(field) => {\n              const confirm = field.query('.confirm_password')\n              field.selfErrors =\n                confirm.get('value') &&\n                field.value &&\n                field.value !== confirm.get('value')\n                  ? '确认密码不匹配'\n                  : ''\n            }}\n          />\n          <Field\n            name=\"confirm_password\"\n            title=\"确认密码\"\n            required\n            decorator={[FormItem]}\n            component={[\n              Password,\n              {\n                checkStrength: true,\n              },\n            ]}\n            reactions={(field) => {\n              const password = field.query('.password')\n              field.selfErrors =\n                password.get('value') &&\n                field.value &&\n                field.value !== password.get('value')\n                  ? '确认密码不匹配'\n                  : ''\n            }}\n          />\n          <VoidField\n            name=\"name\"\n            title=\"姓名\"\n            decorator={[\n              FormItem,\n              {\n                asterisk: true,\n                feedbackLayout: 'none',\n              },\n            ]}\n            component={[FormGrid]}\n          >\n            <Field\n              name=\"firstName\"\n              decorator={[FormItem]}\n              component={[\n                Input,\n                {\n                  placeholder: '姓',\n                },\n              ]}\n              required\n            />\n            <Field\n              name=\"lastName\"\n              decorator={[FormItem]}\n              component={[\n                Input,\n                {\n                  placeholder: '名',\n                },\n              ]}\n              required\n            />\n          </VoidField>\n          <Field\n            name=\"email\"\n            title=\"邮箱\"\n            required\n            validator=\"email\"\n            decorator={[FormItem]}\n            component={[Input]}\n          />\n          <Field\n            name=\"gender\"\n            title=\"性别\"\n            decorator={[FormItem]}\n            component={[Select]}\n            dataSource={[\n              {\n                label: '男',\n                value: 1,\n              },\n              {\n                label: '女',\n                value: 2,\n              },\n              {\n                label: '第三性别',\n                value: 3,\n              },\n            ]}\n            required\n          />\n          <Field\n            name=\"birthday\"\n            title=\"生日\"\n            required\n            decorator={[FormItem]}\n            component={[DatePicker]}\n          />\n          <Field\n            name=\"address\"\n            title=\"地址\"\n            required\n            decorator={[FormItem]}\n            component={[Cascader]}\n            reactions={(field) => {\n              const transform = (data = {}) => {\n                return Object.entries(data).reduce((buf, [key, value]) => {\n                  if (typeof value === 'string')\n                    return buf.concat({\n                      label: value,\n                      value: key,\n                    })\n                  const { name, code, cities, districts } = value\n                  const _cities = transform(cities)\n                  const _districts = transform(districts)\n                  return buf.concat({\n                    label: name,\n                    value: code,\n                    children: _cities.length\n                      ? _cities\n                      : _districts.length\n                      ? _districts\n                      : undefined,\n                  })\n                }, [])\n              }\n\n              field.loading = true\n              fetch('//unpkg.com/china-location/dist/location.json')\n                .then((res) => res.json())\n                .then(\n                  action.bound((data) => {\n                    field.dataSource = transform(data)\n                    field.loading = false\n                  })\n                )\n            }}\n          />\n          <Field\n            name=\"idCard\"\n            title=\"身份证复印件\"\n            required\n            decorator={[FormItem]}\n            component={[IDUpload]}\n          />\n          <ArrayField name=\"contacts\" title=\"联系人信息\" decorator={[FormItem]}>\n            {(field) => (\n              <ArrayBase>\n                {field.value?.map((item, index) => (\n                  <div key={index} className=\"array-items-item\">\n                    <Field\n                      name={`${index}`}\n                      title=\"完善联系人信息\"\n                      component={[Editable.Popover]}\n                      reactions={(field) => {\n                        field.title =\n                          field.query('.[].name').value() || field.title\n                      }}\n                    >\n                      <VoidField\n                        name=\"layout\"\n                        component={[FormLayout, { layout: 'vertical' }]}\n                      >\n                        <Field\n                          name=\"name\"\n                          title=\"姓名\"\n                          required\n                          decorator={[FormItem]}\n                          component={[\n                            Input,\n                            {\n                              style: {\n                                width: 300,\n                              },\n                            },\n                          ]}\n                        />\n                        <Field\n                          name=\"email\"\n                          title=\"邮箱\"\n                          required\n                          validator=\"email\"\n                          decorator={[FormItem]}\n                          component={[\n                            Input,\n                            {\n                              style: {\n                                width: 300,\n                              },\n                            },\n                          ]}\n                        />\n                        <Field\n                          name=\"phone\"\n                          title=\"手机号\"\n                          required\n                          validator=\"phone\"\n                          decorator={[FormItem]}\n                          component={[\n                            Input,\n                            {\n                              style: {\n                                width: 300,\n                              },\n                            },\n                          ]}\n                        />\n                      </VoidField>\n                    </Field>\n                    <FormItem.BaseItem>\n                      <ArrayBase.Remove index={index} />\n                      <ArrayBase.MoveDown index={index} />\n                      <ArrayBase.MoveUp index={index} />\n                    </FormItem.BaseItem>\n                  </div>\n                ))}\n                <ArrayBase.Addition title=\"新增联系人\" />\n              </ArrayBase>\n            )}\n          </ArrayField>\n          <FormButtonGroup.FormItem>\n            <Submit block size=\"large\">\n              注册\n            </Submit>\n          </FormButtonGroup.FormItem>\n        </Form>\n      </Card>\n    </div>\n  )\n}\n```\n\n## 忘记密码\n\n#### Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  Input,\n  Password,\n  Submit,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { Card } from 'antd'\n\nconst form = createForm({\n  validateFirst: true,\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Password,\n  },\n})\n\nexport default () => {\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card title=\"变更密码\" style={{ width: 620 }}>\n        <Form\n          form={form}\n          labelCol={5}\n          wrapperCol={16}\n          onAutoSubmit={console.log}\n        >\n          <SchemaField>\n            <SchemaField.String\n              name=\"username\"\n              title=\"用户名\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"email\"\n              title=\"邮箱\"\n              required\n              x-validator=\"email\"\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"old_password\"\n              title=\"原始密码\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Password\"\n            />\n            <SchemaField.String\n              name=\"password\"\n              title=\"新密码\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Password\"\n              x-component-props={{\n                checkStrength: true,\n              }}\n              x-reactions={[\n                {\n                  dependencies: ['.confirm_password'],\n                  fulfill: {\n                    state: {\n                      selfErrors:\n                        '{{$deps[0] && $self.value && $self.value !== $deps[0] ? \"确认密码不匹配\" : \"\"}}',\n                    },\n                  },\n                },\n              ]}\n            />\n            <SchemaField.String\n              name=\"confirm_password\"\n              title=\"确认密码\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Password\"\n              x-component-props={{\n                checkStrength: true,\n              }}\n              x-reactions={[\n                {\n                  dependencies: ['.password'],\n                  fulfill: {\n                    state: {\n                      selfErrors:\n                        '{{$deps[0] && $self.value && $self.value !== $deps[0] ? \"确认密码不匹配\" : \"\"}}',\n                    },\n                  },\n                },\n              ]}\n            />\n          </SchemaField>\n          <FormButtonGroup.FormItem>\n            <Submit block size=\"large\">\n              确认变更\n            </Submit>\n          </FormButtonGroup.FormItem>\n        </Form>\n      </Card>\n    </div>\n  )\n}\n```\n\n#### JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  Input,\n  Password,\n  Submit,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { Card } from 'antd'\n\nconst form = createForm({\n  validateFirst: true,\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Password,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    username: {\n      type: 'string',\n      title: '用户名',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    email: {\n      type: 'string',\n      title: '邮箱',\n      required: true,\n      'x-validator': 'email',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    oldPassword: {\n      type: 'string',\n      title: '原始密码',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Password',\n    },\n    password: {\n      type: 'string',\n      title: '新密码',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Password',\n      'x-component-props': {\n        checkStrength: true,\n      },\n      'x-reactions': [\n        {\n          dependencies: ['.confirm_password'],\n          fulfill: {\n            state: {\n              selfErrors:\n                '{{$deps[0] && $self.value && $self.value !== $deps[0] ? \"确认密码不匹配\" : \"\"}}',\n            },\n          },\n        },\n      ],\n    },\n    confirm_password: {\n      type: 'string',\n      title: '确认密码',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Password',\n      'x-component-props': {\n        checkStrength: true,\n      },\n      'x-reactions': [\n        {\n          dependencies: ['.password'],\n          fulfill: {\n            state: {\n              selfErrors:\n                '{{$deps[0] && $self.value && $self.value !== $deps[0] ? \"确认密码不匹配\" : \"\"}}',\n            },\n          },\n        },\n      ],\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card title=\"变更密码\" style={{ width: 620 }}>\n        <Form\n          form={form}\n          labelCol={5}\n          wrapperCol={16}\n          onAutoSubmit={console.log}\n        >\n          <SchemaField schema={schema} />\n          <FormButtonGroup.FormItem>\n            <Submit block size=\"large\">\n              确认变更\n            </Submit>\n          </FormButtonGroup.FormItem>\n        </Form>\n      </Card>\n    </div>\n  )\n}\n```\n\n#### 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/react'\nimport {\n  Form,\n  FormItem,\n  Input,\n  Password,\n  Submit,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { Card } from 'antd'\n\nconst form = createForm({\n  validateFirst: true,\n})\n\nexport default () => {\n  return (\n    <div\n      style={{\n        display: 'flex',\n        justifyContent: 'center',\n        background: '#eee',\n        padding: '40px 0',\n      }}\n    >\n      <Card title=\"变更密码\" style={{ width: 620 }}>\n        <Form\n          form={form}\n          labelCol={5}\n          wrapperCol={16}\n          onAutoSubmit={console.log}\n        >\n          <Field\n            name=\"username\"\n            title=\"用户名\"\n            required\n            decorator={[FormItem]}\n            component={[Input]}\n          />\n          <Field\n            name=\"email\"\n            title=\"邮箱\"\n            required\n            validator=\"email\"\n            decorator={[FormItem]}\n            component={[Input]}\n          />\n          <Field\n            name=\"old_password\"\n            title=\"原始密码\"\n            required\n            decorator={[FormItem]}\n            component={[Password]}\n          />\n          <Field\n            name=\"password\"\n            title=\"新密码\"\n            required\n            decorator={[FormItem]}\n            component={[\n              Password,\n              {\n                checkStrength: true,\n              },\n            ]}\n            reactions={(field) => {\n              const confirm = field.query('.confirm_password')\n              field.selfErrors =\n                confirm.get('value') &&\n                field.value &&\n                field.value !== confirm.get('value')\n                  ? '确认密码不匹配'\n                  : ''\n            }}\n          />\n          <Field\n            name=\"confirm_password\"\n            title=\"确认密码\"\n            required\n            decorator={[FormItem]}\n            component={[\n              Password,\n              {\n                checkStrength: true,\n              },\n            ]}\n            reactions={(field) => {\n              const confirm = field.query('.password')\n              field.selfErrors =\n                confirm.get('value') &&\n                field.value &&\n                field.value !== confirm.get('value')\n                  ? '确认密码不匹配'\n                  : ''\n            }}\n          />\n          <FormButtonGroup.FormItem>\n            <Submit block size=\"large\">\n              确认变更\n            </Submit>\n          </FormButtonGroup.FormItem>\n        </Form>\n      </Card>\n    </div>\n  )\n}\n```\n"
  },
  {
    "path": "docs/guide/scenes/more.md",
    "content": "# More Scenes\n\nBecause Formily is a very complete solution at the form level, and it is also very flexible. It supports a lot of scenarios, but we can't list them all.\n\nTherefore, I still hope that the community can help Formily improve more scenarios! We would be very grateful!😀\n"
  },
  {
    "path": "docs/guide/scenes/more.zh-CN.md",
    "content": "# 更多场景\n\n因为 Formily 在表单层面上是一个非常完备的方案，而且还很灵活，支持的场景非常多，但是场景案例，我们无法一一列举。\n\n所以，还是希望社区能帮助 Formily 完善更多场景案例！我们会不胜感激！😀\n"
  },
  {
    "path": "docs/guide/scenes/query-list.md",
    "content": "# Query list\n\nBecause Formily Schema can completely describe the UI, we can simply abstract out the QueryList/QueryForm/QueryTable components to combine to implement the query list component. The following is only the pseudo code, because the query list scenario usually involves a lot of business packaging. At present, Formily hasn't figured out how to consider both versatility and quick start of business, so it will not open up specific components for the time being.\n\nBut you can take a look at the pseudo-code first. If these components are officially implemented, the usage will definitely be like this:\n\n```tsx pure\nimport React from 'react'\nimport { Void, Object, Array, String } from './MySchemaField'\nexport default () => (\n  <Void\n    x-component=\"QueryList\"\n    x-component-props={{\n      service: (params) => fetchRecords(params),\n    }}\n  >\n    <Object name=\"query\" x-component=\"QueryForm\">\n      <String name=\"name\" x-component=\"Input\" />\n      <String name=\"id\" x-component=\"Input\" />\n    </Object>\n    <Void name=\"toolbar\" x-component=\"QueryToolbar\"></Void>\n    <Array name=\"list\" x-component=\"QueryTable\">\n      <Object>\n        <Void x-component=\"QueryTable.Column\">\n          <String name=\"name\" x-component=\"PreviewText\" />\n        </Void>\n        <Void x-component=\"QueryTable.Column\">\n          <String name=\"id\" x-component=\"PreviewText\" />\n        </Void>\n      </Object>\n    </Array>\n  </Void>\n)\n```\n\n## Ideas\n\n- QueryList\n  - Mainly responsible for sending requests at the top level, and issuing query methods to QueryForm and QueryTable for consumption through React Context\n  - Query parameters need to call `form.query('query')` to find the field of QueryForm, and then take out the value of the field to send the request\n  - When you have finished querying the data, you need to call `form.query('list')` to find the QueryTable field, and then fill in the table data for the value of the field model\n- QueryTable\n  - The idea is very similar to that of ArrayTable. The main thing is to parse the Schema subtree and assemble the Columns data needed by the Table by yourself. If you want to support column merging and row merging, you need to parse more complex data\n  - Based on props.value for rendering Table structure\n  - Rely on RecursionField to render the internal data of the Table Column\n  - Rely on the query method passed down from the context to achieve paging query\n- QueryForm\n  - There is no special logic, the main thing is to combine Form+FormGrid to realize a query form layout\n  - Realize query form query by relying on the query method passed down from the context\n"
  },
  {
    "path": "docs/guide/scenes/query-list.zh-CN.md",
    "content": "# 查询列表\n\n因为 Formily Schema 是可以完全描述 UI 的，所以我们可以简单的抽象出 QueryList/QueryForm/QueryTable 几个组件来组合实现查询列表组件,以下只是给出伪代码，因为查询列表场景通常都会涉及大量业务封装，目前 Formily 还没想好怎么既考虑通用性又能考虑业务快速上手，所以暂时不开放出具体组件。\n\n不过可以先看看伪代码，如果官方实现这几个组件，那使用方式肯定会是这样：\n\n```tsx pure\nimport React from 'react'\nimport { Void, Object, Array, String } from './MySchemaField'\nexport default () => (\n  <Void\n    x-component=\"QueryList\"\n    x-component-props={{\n      service: (params) => fetchRecords(params),\n    }}\n  >\n    <Object name=\"query\" x-component=\"QueryForm\">\n      <String name=\"name\" x-component=\"Input\" />\n      <String name=\"id\" x-component=\"Input\" />\n    </Object>\n    <Void name=\"toolbar\" x-component=\"QueryToolbar\"></Void>\n    <Array name=\"list\" x-component=\"QueryTable\">\n      <Object>\n        <Void x-component=\"QueryTable.Column\">\n          <String name=\"name\" x-component=\"PreviewText\" />\n        </Void>\n        <Void x-component=\"QueryTable.Column\">\n          <String name=\"id\" x-component=\"PreviewText\" />\n        </Void>\n      </Object>\n    </Array>\n  </Void>\n)\n```\n\n## 思路\n\n- QueryList\n  - 主要负责在顶层发请求，通过 React Context 下发 query 方法给 QueryForm 和 QueryTable 消费\n  - 查询参数需要调用`form.query('query')`找到 QueryForm 的字段，然后取出字段的 value，用于发请求\n  - 当查询完数据了，需要调用`form.query('list')`找到 QueryTable 的字段，然后给字段模型的 value 填 table 数据\n- QueryTable\n  - 思路跟 ArrayTable 非常相似，主要就是解析 Schema 子树，自己拼装出 Table 需要的 Columns 数据，如果想支持列合并，行合并，就需要解析更复杂的数据\n  - 基于 props.value 用于渲染 Table 结构\n  - 依赖 RecursionField 用于渲染 Table Column 内部数据\n  - 依赖上下文传下来的 query 方法实现分页查询\n- QueryForm\n  - 没什么特殊逻辑，主要就是组合 Form+FormGrid 实现一个查询表单布局\n  - 依赖上下文传下来的 query 方法实现查询表单查询\n"
  },
  {
    "path": "docs/guide/scenes/step-form.md",
    "content": "# Step-by-Step Form\n\nMainly use the [FormStep](https://antd.formilyjs.org/components/form-step) component in [@formily/antd](https://antd.formilyjs.org) or [@formily/next](ttps://next.formilyjs.org)\n"
  },
  {
    "path": "docs/guide/scenes/step-form.zh-CN.md",
    "content": "# 分步表单\n\n主要使用[@formily/antd](https://antd.formilyjs.org/zh-CN) 或 [@formily/next](https://fusion.formilyjs.org/zh-CN) 中的[FormStep](https://antd.formilyjs.org/zh-CN/components/form-step)组件\n"
  },
  {
    "path": "docs/guide/scenes/tab-form.md",
    "content": "# Tab/Accordion Form\n\nMainly use the [FormTab](https://antd.formilyjs.org/components/form-tab) component and [FormCollapse](https://antd.formilyjs.org/components/form-collapse) component in [@formily/antd](https://antd.formilyjs.org) or [@formily/next](https://fusion.formilyjs.org)\n"
  },
  {
    "path": "docs/guide/scenes/tab-form.zh-CN.md",
    "content": "# 选项卡/手风琴表单\n\n主要使用[@formily/antd](https://antd.formilyjs.org/zh-CN) 或 [@formily/next](https://fusion.formilyjs.org/zh-CN) 中的[FormTab](https://antd.formilyjs.org/zh-CN/components/form-tab)组件 与 [FormCollapse](https://antd.formilyjs.org/zh-CN/components/form-collapse)组件\n"
  },
  {
    "path": "docs/guide/upgrade.md",
    "content": "# V2 Upgrade Guide\n\nIt is important to mention here that Formily2 is very different from Formily1.x, and there are a lot of Break Changes.\n\nTherefore, for old users, they basically need to learn again, and V1 and V2 cannot be upgraded smoothly.\n\nBut the original intention of the Formily2 project is to reduce everyone's learning costs, because the old users themselves have a certain understanding of Formily's core ideas. In order to help old users learn Formily2 more quickly, this article will list the core differences between V1 and V2. , and will not list the new capabilities.\n\n## Kernel Difference\n\n> This mainly refers to the difference between @formily/core\n\nBecause Formily1.x users mainly use setFieldState/setFormState and getFieldState/getFormState when using the core APIs, these APIs are retained in V2, but the internal model properties are semantically different. The differences are as follows:\n\n**modified**\n\n- V1: Represent whether the field has been changed, in fact, it is of no use, because the initialization of the field means that it has been changed.\n- V2: Indicates whether the field is manually modified, that is, it will be set to true when the component triggers the onChange event.\n\n**inputed**\n\n- V1: Represent Whether the field has been manually modified\n- V2: Remove, use modified uniformly\n\n**pristine**\n\n- V1:Represent whether the field value is equal to initialValue\n- V2: Remove, user manual judgment, this attribute will cause a lot of dirty checks\n\n**display**\n\n- V1: Represent whether the field is displayed, if it is false, the field value will not be removed\n- V2: Represent the field display mode, the value is `\"none\" | \"visible\" | \"hidden\"`\n\n**touched**\n\n- V1: Redundant field\n- V2: Remove\n\n**validating**\n\n- V1: Whether the representative field is being verified\n- V2: Remove, use validateStatus uniformly\n\n**effectErrors/effectWarnings**\n\n- V1: Errors and warnings that represent the manual operation of the user\n- V2: Remove, use feedbacks uniformly\n\n**ruleErrors/ruleWarnings**\n\n- V1: Errors and warnings representing the verification operation of the validator\n- V2: Remove, use feedbacks uniformly\n\n**values**\n\n- V1: Represent all the parameters returned by the onChange event\n- V2: Remove, use inputValues uniformly\n\n**rules**\n\n- V1: Represent verification rules\n- V2: Remove, use validator uniformly, because rules literally means rules, but the meaning of rules is very big, not limited to verification rules\n\n**props**\n\n- V1: Represent the extended attributes of the component, and the positioning is very unclear. In the pure JSX scenario, it represents the collection of component attributes and FormItem attributes. In the Schema scenario, it represents the attributes of the Schema field.\n- V2: Remove, use decorator and component uniformly\n\n**VirtualField**\n\n- V1: Represents a virtual field\n- V2: Renamed and use [VoidField](https://core.formilyjs.org/api/models/void-field) uniformly\n\n## Bridge layer differences\n\n> This mainly refers to the difference between @formily/react and @formily/react-schema-renderer.\n\n**createFormActions/createAsyncFormActions**\n\n- V1 Create a Form operator, you can call the setFieldState/setFormState method.\n- V2 is removed, and the operation status of the Form instance created by [createForm](https://core.formilyjs.org/api/entry/create-form) in @formily/core is used uniformly.\n\n**Form**\n\n- V1 will create a Form instance inside, which can control the transfer of values/initialValues attributes, etc.\n- V2 removed, unified use of [FormProvider](https://react.formilyjs.org/api/components/form-provider)\n\n**SchemaForm**\n\n- V1 will parse the json-schema protocol internally, create a Form instance, support controlled mode, and render it.\n- V2 is removed, the SchemaField component created by [createSchemaField](https://react.formilyjs.org/api/components/schema-field) is used uniformly, and the controlled mode is not supported.\n\n**Field**\n\n- V1 supports controlled mode, which requires the use of render props for component state mapping.\n- V2 does not support controlled mode, you can quickly implement state mapping by passing in the decorator/component property.\n\n**VirtualField**\n\n- V1 supports controlled mode, which requires the use of render props for component state mapping.\n- V2 does not support controlled mode, renamed [VoidField](https://react.formilyjs.org/api/components/void-field), and passed in the decorator/component property to quickly implement state mapping.\n\n**FieldList**\n\n- V1 Represent auto-incremented field control component\n- V2 Renamed to [ArrayField](https://react.formilyjs.org/api/components/array-field)\n\n**FormSpy**\n\n- V1 Monitor all life cycle triggers and re-render\n- V2 Remove and use [FormConsumer](https://react.formilyjs.org/api/components/form-consumer)\n\n**SchemaMarkupField**\n\n- V1 Stands for Schema description label component\n- V2 Remove, unified use the description label component created by the [createSchemaField](https://react.formilyjs.org/api/components/schema-field)\n\n**useFormQuery**\n\n- V1 Fast Hook for realizing form query, supporting middleware mechanism\n- V2 Temporarily remove\n\n**useForm**\n\n- V1 Represents the creation of a Form instance\n- V2 Represents the Form instance in the consumption context, if you want to create it, please use [createForm](https://react.formilyjs.org/api/entry/create-form)\n\n**useField**\n\n- V1 Represents the creation of a Field instance\n- V2 Represents the Field instance in the consumption context, if you want to create it, please call [form.createField](https://core.formilyjs.org/api/models/form#createfield)\n\n**useVirtualField**\n\n- V1 Represents the creation of a VirtualField instance\n- V2 Remove, if you want to create, please call [form.createVoidField](https://core.formilyjs.org/api/models/form#createvoidfield)\n\n**useFormState**\n\n- V1 Form state in consumption context\n- V2 Remove, use [useForm](https://react.formilyjs.org/api/hooks/use-form) uniformly\n\n**useFieldState**\n\n- V1 consume Field status in context\n- V2 Remove, use [useField](https://react.formilyjs.org/api/hooks/use-field)\n\n**useFormSpy**\n\n- V1 Create a lifecycle listener and trigger a re-render\n- V2 Remove\n\n**useSchemaProps**\n\n- V1Cconsume rops of SchemaField in context\n- V2 Remove, use [useFieldSchema](https://react.formilyjs.org/api/hooks/use-field-schema) uniformly\n\n**connect**\n\n- V1 Standard HOC\n- V2 The higher-order function is changed to 1st order, and the properties have changed dramatically. See the [connect document](https://react.formilyjs.org/api/shared/connect) for details\n\n**registerFormField/registerVirtaulBox/registerFormComponent/registerFormItemComponent**\n\n- V1 Globally registered components\n- V2 Remove, global registration is no longer supported\n\n**FormEffectHooks**\n\n- V1 RxJS lifecycle hook\n- V2 Remove, export from @formily/core uniformly, and will not return RxJS Observable object\n\n**effects**\n\n- V1 Support callback function`$` selector\n- V2 Remove`$`selector\n\n## Protocol layer differences\n\n> This mainly refers to the difference in the JSON Schema protocol\n\n**editable**\n\n- V1 is directly in the Schema description, indicating whether the field can be edited\n- V2 Renamed x-editable\n\n**visible**\n\n- V1 Indicates whether the field is displayed\n- V2 Renamed x-visible\n\n**display**\n\n- V1 Represent whether the field is displayed or not, if it is false, it represents the hidden behavior without deleting the value\n- V2 Renamed x-display, which represents the field display mode, and the value is`\"none\" | \"visible\" | \"hidden\"`\n\n**triggerType**\n\n- V1 Represent the field verification timing\n- V2 Remove, please use`x-validator:[{triggerType:\"onBlur\",validator:()=>...}]`\n\n**x-props**\n\n- V1 Represents the FormItem property\n- V2 Remove, please use x-decorator-props\n\n**x-rules**\n\n- V1 Represent field verification rules\n- V2 Renamed x-validator\n\n**x-linkages**\n\n- V1 Represent field linkage\n- V2 Remove, use x-reactions uniformly\n\n**x-mega-props**\n\n- V1 Represent the sub-component properties of the MegaLayout component\n- V2 Remove\n\n## Component library differences\n\nIn Formily 1.x, we mainly use @formily/antd and @formily/antd-components, or @formily/next and @formily/next-components.\n\nIn V2, we have the following changes:\n\n- @formily/antd and @formily/antd-components were merged into @formily/antd, and the directory structure was changed to that of a pure component library.\n\n- The internal API of @formily/react @formily/core will no longer be exported.\n- Almost all components have been rewritten and cannot be smoothly upgraded.\n- Remove styled-components.\n"
  },
  {
    "path": "docs/guide/upgrade.zh-CN.md",
    "content": "# V2 升级指南\n\n这里着重提一下，Formily2 相比于 Formily1.x，差别非常大，存在大量 Break Change。\n\n所以对老用户而言，基本上是需要重新学习的，V1 和 V2 是无法做到平滑升级的。\n\n但是 Formily2 的项目初衷就是为了降低大家的学习成本，因为老用户本身已经对 Formily 的核心思想有过一定的了解，为了帮助老用户更快速的学习 Formily2，本文会列举出 V1 和 V2 的核心差异点，并不会列举新增的能力。\n\n## 内核差异\n\n> 这里主要指@formily/core 的差异\n\n因为 Formily1.x 用户在使用内核 API 的时候，主要是使用 setFieldState/setFormState 与 getFieldState/getFormState，在 V2 中保留了这些 API，但是内部的模型属性是有语义上的差别的，差别如下：\n\n**modified**\n\n- V1: 代表字段是否已改动，其实并没有任何用处，因为字段初始化就代表已改动\n- V2: 代表字段是否被手动修改，也就是组件触发 onChange 事件的时候才会设置为 true\n\n**inputed**\n\n- V1: 代表字段是否被手动修改\n- V2: 移除，统一使用 modified\n\n**pristine**\n\n- V1: 代表字段 value 是否等于 initialValue\n- V2: 移除，用户手动判断，该属性会导致大量脏检查\n\n**display**\n\n- V1: 代表字段是否显示，如果为 false，不会移除字段值\n- V2: 代表字段展示模式，值为`\"none\" | \"visible\" | \"hidden\"`\n\n**touched**\n\n- V1: 冗余字段\n- V2: 移除\n\n**validating**\n\n- V1: 代表字段是否正在校验\n- V2: 移除，统一使用 validateStatus\n\n**effectErrors/effectWarnings**\n\n- V1: 代表用户手动操作的 errors 和 warnings\n- V2: 移除，统一使用 feedbacks\n\n**ruleErrors/ruleWarnings**\n\n- V1: 代表校验器校验操作的 errors 与 warnings\n- V2: 移除，统一使用 feedbacks\n\n**values**\n\n- V1: 代表 onChange 事件返回的所有参数\n- V2: 移除，统一使用 inputValues\n\n**rules**\n\n- V1:代表校验规则\n- V2:移除，统一使用 validator，因为 rules 的字面意思是规则，但是规则的含义很大，不局限于校验规则\n\n**props**\n\n- V1:代表组件的扩展属性，定位很不清晰，在纯 JSX 场景是代表组件属性与 FormItem 属性的集合，在 Schema 场景又是代表 Schema 字段的属性\n- V2: 移除，统一使用 decorator 和 component\n\n**VirtualField**\n\n- V1: 代表虚拟字段\n- V2: 改名，统一使用[VoidField](https://core.formilyjs.org/zh-CN/api/models/void-field)\n\n**unmount 行为**\n\n- V1: 字段 unmount，字段值默认会被删除\n- V2: 移除，这个默认行为太隐晦，如果要删值，可以直接修改 value，同时自动删值的行为只有字段 display 为 none 时才会自动删值\n\n## 桥接层差异\n\n> 这里主要指@formily/react 和@formily/react-schema-renderer 的差异\n\n**createFormActions/createAsyncFormActions**\n\n- V1 创建一个 Form 操作器，可以调用 setFieldState/setFormState 方法\n- V2 移除，统一使用@formily/core 中的[createForm](https://core.formilyjs.org/zh-CN/api/entry/create-form)创建出来的 Form 实例操作状态\n\n**Form**\n\n- V1 内部会创建 Form 实例，可以受控传递 values/initialValues 属性等\n- V2 移除，统一使用[FormProvider](https://react.formilyjs.org/zh-CN/api/components/form-provider)\n\n**SchemaForm**\n\n- V1 内部会解析 json-schema 协议，同时会创建 Form 实例，支持受控模式，并渲染\n- V2 移除，统一使用[createSchemaField](https://react.formilyjs.org/zh-CN/api/components/schema-field)创建出来的 SchemaField 组件，且不支持受控模式\n\n**Field**\n\n- V1 支持受控模式，需要使用 render props 进行组件状态映射\n- V2 不支持受控模式，传入 decorator/component 属性即可快速实现状态映射\n\n**VirtualField**\n\n- V1 支持受控模式，需要使用 render props 进行组件状态映射\n- V2 不支持受控模式，改名[VoidField](https://react.formilyjs.org/zh-CN/api/components/void-field)，传入 decorator/component 属性即可快速实现状态映射\n\n**FieldList**\n\n- V1 代表自增字段控制组件\n- V2 改名为[ArrayField](https://react.formilyjs.org/zh-CN/api/components/array-field)\n\n**FormSpy**\n\n- V1 监听所有生命周期触发，并重新渲染\n- V2 移除，统一使用[FormConsumer](https://react.formilyjs.org/zh-CN/api/components/form-consumer)\n\n**SchemaMarkupField**\n\n- V1 代表 Schema 描述标签组件\n- V2 移除，统一使用[createSchemaField](https://react.formilyjs.org/zh-CN/api/components/schema-field)工厂函数创建出来的描述标签组件\n\n**useFormQuery**\n\n- V1 用于实现表单查询的快捷 Hook，支持中间件机制\n- V2 暂时移除\n\n**useForm**\n\n- V1 代表创建 Form 实例\n- V2 代表消费上下文中的 Form 实例，如果要创建，请使用[createForm](https://core.formilyjs.org/zh-CN/api/entry/create-form)\n\n**useField**\n\n- V1 代表创建 Field 实例\n- V2 代表消费上下文中的 Field 实例，如果要创建，请调用[form.createField](https://core.formilyjs.org/zh-CN/api/models/form#createfield)\n\n**useVirtualField**\n\n- V1 代表创建 VirtualField 实例\n- V2 移除，如果要创建，请调用[form.createVoidField](https://core.formilyjs.org/zh-CN/api/models/form#createvoidfield)\n\n**useFormState**\n\n- V1 消费上下文中的 Form 状态\n- V2 移除，统一使用[useForm](https://react.formilyjs.org/zh-CN/api/hooks/use-form)\n\n**useFieldState**\n\n- V1 消费上下文中的 Field 状态\n- V2 移除，统一使用[useField](https://react.formilyjs.org/zh-CN/api/hooks/use-field)\n\n**useFormSpy**\n\n- V1 创建生命周期监听器，并触发重新渲染\n- V2 移除\n\n**useSchemaProps**\n\n- V1 消费上下文中的 SchemaField 的 Props\n- V2 移除，统一使用[useFieldSchema](https://react.formilyjs.org/zh-CN/api/hooks/use-field-schema)\n\n**connect**\n\n- V1 标准 HOC\n- V2 高阶函数改为 1 阶，属性有巨大变化，具体看[connect 文档](https://react.formilyjs.org/zh-CN/api/shared/connect)\n\n**registerFormField/registerVirtaulBox/registerFormComponent/registerFormItemComponent**\n\n- V1 全局注册组件\n- V2 移除，不再支持全局注册\n\n**FormEffectHooks**\n\n- V1 RxJS 生命周期钩子\n- V2 移除，统一从@formily/core 中导出，且不会返回 RxJS Observable 对象\n\n**effects**\n\n- V1 支持回调函数`$`选择器\n- V2 移除`$`选择器\n\n## 协议层差异\n\n> 这里主要指 JSON Schema 协议上的差异\n\n**editable**\n\n- V1 直接在 Schema 描述中，代表字段是否可编辑\n- V2 改名 x-editable\n\n**visible**\n\n- V1 代表字段是否显示\n- V2 改名 x-visible\n\n**display**\n\n- V1 代表字段是否显示，如果为 false，代表不删值的隐藏行为\n- V2 改名 x-display，代表字段展示模式，值为`\"none\" | \"visible\" | \"hidden\"`\n\n**triggerType**\n\n- V1 代表字段校验时机\n- V2 移除，请使用`x-validator:[{triggerType:\"onBlur\",validator:()=>...}]`\n\n**x-props**\n\n- V1 代表 FormItem 属性\n- V2 移除，请使用 x-decorator-props\n\n**x-rules**\n\n- V1 代表字段校验规则\n- V2 改名 x-validator\n\n**x-linkages**\n\n- V1 代表字段联动\n- V2 移除，统一使用 x-reactions\n\n**x-mega-props**\n\n- V1 代表 MegaLayout 组件的子组件属性\n- V2 移除\n\n## 组件库差异\n\n在 Formily1.x 中，我们主要使用@formily/antd 和@formily/antd-components，或者@formily/next 和@formily/next-components，\n\n在 V2 中，我们有以下几个改变：\n\n- @formily/antd 与@formily/antd-components 合并成@formily/antd，同时目录结构全部改成纯组件库的目录结构了。\n\n- 不会再导出@formily/react @formily/core 的内部 API\n- 所有组件几乎都做了重写，无法平滑升级\n- 移除 styled-components\n"
  },
  {
    "path": "docs/index.md",
    "content": "---\ntitle: Formily - Alibaba unified front-end form solution\norder: 10\nhero:\n  title: Alibaba Formily\n  desc: Alibaba Unified Front-end Form Solution\n  actions:\n    - text: Introduction\n      link: /guide\n    - text: Quick start\n      link: /guide/quick-start\nfeatures:\n  - icon: https://img.alicdn.com/imgextra/i2/O1CN016i72sH1c5wh1kyy9U_!!6000000003550-55-tps-800-800.svg\n    title: Easier to Use\n    desc: Out of the box, rich cases\n  - icon: https://img.alicdn.com/imgextra/i1/O1CN01bHdrZJ1rEOESvXEi5_!!6000000005599-55-tps-800-800.svg\n    title: More Efficient\n    desc: Fool writing, ultra-high performance\n  - icon: https://img.alicdn.com/imgextra/i3/O1CN01xlETZk1G0WSQT6Xii_!!6000000000560-55-tps-800-800.svg\n    title: More Professional\n    desc: Complete, flexible and elegant\nfooter: Open-source MIT Licensed | Copyright © 2019-present<br />Powered by self\n---\n\n```tsx\n/**\n * inline: true\n */\nimport React from 'react'\nimport { Section } from './site/Section'\nimport './site/styles.less'\n\nexport default () => (\n  <Section\n    title=\"Fool Writing, Ultra-high Performance\"\n    style={{ marginTop: 40 }}\n    titleStyle={{ paddingBottom: 100, fontWeight: 'bold' }}\n  >\n    <iframe\n      className=\"codesandbox\"\n      src=\"https://codesandbox.io/embed/formilyyaliceshi-vbu4w?fontsize=12&module=%2FApp.tsx&theme=dark\"\n      allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\n      sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\"\n    ></iframe>\n  </Section>\n)\n```\n\n```tsx\n/**\n * inline: true\n */\nimport React from 'react'\nimport { Section } from './site/Section'\nimport './site/styles.less'\n\nexport default () => (\n  <Section\n    title=\"Form Builder,Efficient Development\"\n    style={{ marginTop: 140, fontWeight: 'bold' }}\n    titleStyle={{ paddingBottom: 140 }}\n    scale={1.2}\n  >\n    <a href=\"//designable-antd.formilyjs.org\" target=\"_blank\" rel=\"noreferrer\">\n      <img src=\"//img.alicdn.com/imgextra/i2/O1CN01eI9FLz22tZek2jv7E_!!6000000007178-2-tps-3683-2272.png\" />\n    </a>\n  </Section>\n)\n```\n\n```tsx\n/**\n * inline: true\n */\nimport React from 'react'\nimport { Section } from './site/Section'\nimport './site/styles.less'\n\nexport default () => (\n  <Section\n    title=\"Pure Core, More Extensibility\"\n    style={{ marginTop: 140 }}\n    titleStyle={{ paddingBottom: 100, fontWeight: 'bold' }}\n  >\n    <a href=\"//core.formilyjs.org\" target=\"_blank\" rel=\"noreferrer\">\n      <img src=\"//img.alicdn.com/imgextra/i4/O1CN019qbf1b1ChnTfT9x3X_!!6000000000113-55-tps-1939-1199.svg\" />\n    </a>\n  </Section>\n)\n```\n\n```tsx\n/**\n * inline: true\n */\nimport React from 'react'\nimport { Section } from './site/Section'\nimport { Contributors } from './site/Contributors'\nimport './site/styles.less'\n\nexport default () => (\n  <Section\n    title=\"Active Community & Genius People\"\n    style={{ marginTop: 100 }}\n    titleStyle={{ paddingBottom: 140, fontWeight: 'bold' }}\n  >\n    <Contributors />\n  </Section>\n)\n```\n\n```tsx\n/**\n * inline: true\n */\nimport React from 'react'\nimport { Section } from './site/Section'\nimport { QrCode, QrCodeGroup } from './site/QrCode'\nimport './site/styles.less'\n\nexport default () => (\n  <Section\n    title=\"High-Quality Community Group\"\n    style={{ marginTop: 140 }}\n    titleStyle={{ paddingBottom: 20, fontWeight: 'bold' }}\n  >\n    <QrCodeGroup>\n      <QrCode link=\"//img.alicdn.com/imgextra/i1/O1CN011zlc5b1uu1BDUpNg1_!!6000000006096-2-tps-978-1380.png\" />\n    </QrCodeGroup>\n  </Section>\n)\n```\n"
  },
  {
    "path": "docs/index.zh-CN.md",
    "content": "---\ntitle: Formily - 阿里巴巴统一前端表单解决方案\norder: 10\nhero:\n  title: Alibaba Formily\n  desc: 阿里巴巴统一前端表单解决方案\n  actions:\n    - text: 查看文档\n      link: /zh-CN/guide\n    - text: 快速开始\n      link: /zh-CN/guide/quick-start\nfeatures:\n  - icon: https://img.alicdn.com/imgextra/i2/O1CN016i72sH1c5wh1kyy9U_!!6000000003550-55-tps-800-800.svg\n    title: 更易用\n    desc: 开箱即用，案例丰富\n  - icon: https://img.alicdn.com/imgextra/i1/O1CN01bHdrZJ1rEOESvXEi5_!!6000000005599-55-tps-800-800.svg\n    title: 更高效\n    desc: 傻瓜写法，超高性能\n  - icon: https://img.alicdn.com/imgextra/i3/O1CN01xlETZk1G0WSQT6Xii_!!6000000000560-55-tps-800-800.svg\n    title: 更专业\n    desc: 完备，灵活，优雅\nfooter: Open-source MIT Licensed | Copyright © 2019-present<br />Powered by self\n---\n\n```tsx\n/**\n * inline: true\n */\nimport React from 'react'\nimport { Section } from './site/Section'\nimport './site/styles.less'\n\nexport default () => (\n  <Section\n    title=\"傻瓜写法，超高性能\"\n    style={{ marginTop: 40 }}\n    titleStyle={{ paddingBottom: 100 }}\n  >\n    <iframe\n      className=\"codesandbox\"\n      src=\"https://codesandbox.io/embed/formilyyaliceshi-vbu4w?fontsize=12&module=%2FApp.tsx&theme=dark\"\n      allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\n      sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\"\n    ></iframe>\n  </Section>\n)\n```\n\n```tsx\n/**\n * inline: true\n */\nimport React from 'react'\nimport { Section } from './site/Section'\nimport './site/styles.less'\n\nexport default () => (\n  <Section\n    title=\"拖拽搭建，高效开发\"\n    style={{ marginTop: 140 }}\n    titleStyle={{ paddingBottom: 140 }}\n    scale={1.2}\n  >\n    <a href=\"//designable-antd.formilyjs.org\" target=\"_blank\" rel=\"noreferrer\">\n      <img src=\"//img.alicdn.com/imgextra/i2/O1CN01eI9FLz22tZek2jv7E_!!6000000007178-2-tps-3683-2272.png\" />\n    </a>\n  </Section>\n)\n```\n\n```tsx\n/**\n * inline: true\n */\nimport React from 'react'\nimport { Section } from './site/Section'\nimport './site/styles.less'\n\nexport default () => (\n  <Section\n    title=\"纯净内核，更易扩展\"\n    style={{ marginTop: 140 }}\n    titleStyle={{ paddingBottom: 100 }}\n  >\n    <a href=\"//core.formilyjs.org\" target=\"_blank\" rel=\"noreferrer\">\n      <img src=\"//img.alicdn.com/imgextra/i3/O1CN01iEwHrP1NUw84xTded_!!6000000001574-55-tps-1939-1199.svg\" />\n    </a>\n  </Section>\n)\n```\n\n```tsx\n/**\n * inline: true\n */\nimport React from 'react'\nimport { Section } from './site/Section'\nimport { Contributors } from './site/Contributors'\nimport './site/styles.less'\n\nexport default () => (\n  <Section\n    title=\"社区活跃，能者众多\"\n    style={{ marginTop: 100 }}\n    titleStyle={{ paddingBottom: 140 }}\n  >\n    <Contributors />\n  </Section>\n)\n```\n\n```tsx\n/**\n * inline: true\n */\nimport React from 'react'\nimport { Section } from './site/Section'\nimport { QrCode, QrCodeGroup } from './site/QrCode'\nimport './site/styles.less'\n\nexport default () => (\n  <Section\n    title=\"全球互助共建答疑大群\"\n    style={{ marginTop: 140 }}\n    titleStyle={{ paddingBottom: 20, fontWeight: 'bold' }}\n  >\n    <QrCodeGroup>\n      <QrCode link=\"//img.alicdn.com/imgextra/i1/O1CN011zlc5b1uu1BDUpNg1_!!6000000006096-2-tps-978-1380.png\" />\n    </QrCodeGroup>\n  </Section>\n)\n```\n"
  },
  {
    "path": "docs/site/Contributors.less",
    "content": ".contri-list {\n  display: flex;\n  flex-wrap: wrap;\n\n  .contri-user {\n    display: flex;\n    flex-direction: column;\n    width: 120px;\n    height: 120px;\n    align-items: center;\n    justify-content: center;\n\n    &-avatar {\n      display: block;\n      width: 60px;\n      height: 60px;\n      border-radius: 60px;\n      overflow: hidden;\n      transition: all 0.15s ease-in-out;\n\n      &:hover {\n        opacity: 0.8;\n      }\n    }\n\n    &-info {\n      text-align: center;\n    }\n  }\n}\n"
  },
  {
    "path": "docs/site/Contributors.tsx",
    "content": "import React, { useEffect, useState } from 'react'\nimport './Contributors.less'\n\nexport const Contributors: React.FC = () => {\n  const [contributors, setContributors] = useState([])\n  useEffect(() => {\n    fetch('//formilyjs.org/.netlify/functions/contributors')\n      .then((res) => res.json())\n      .then(({ data }) => {\n        setContributors(data)\n      })\n  }, [])\n  return (\n    <div className=\"contri-list\">\n      {contributors.map((user, key) => (\n        <div className=\"contri-user\" key={key}>\n          <a\n            className=\"contri-user-avatar\"\n            href={user.html_url}\n            target=\"_blank\"\n            rel=\"noreferrer\"\n          >\n            <img src={user.avatar_url} />\n          </a>\n          <div className=\"contri-user-info\">\n            <a href={user.html_url} target=\"_blank\" rel=\"noreferrer\">\n              <div className=\"contri-user-name\">{user.login}</div>\n            </a>\n          </div>\n        </div>\n      ))}\n    </div>\n  )\n}\n"
  },
  {
    "path": "docs/site/QrCode.less",
    "content": ".qrcode-group {\n  display: flex;\n  justify-content: center;\n  .qrcode {\n    width: 400px;\n    margin: 20px;\n    display: flex;\n    flex-direction: column;\n    justify-content: center;\n    align-items: center;\n\n    &-title {\n      font-size: 20px;\n      position: relative;\n\n      &-content {\n        position: absolute;\n        left: 50%;\n        bottom: 0;\n        white-space: nowrap;\n        transform: translateX(-50%);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "docs/site/QrCode.tsx",
    "content": "import React from 'react'\nimport './QrCode.less'\n\nexport interface IQrCodeProps {\n  title?: React.ReactNode\n  link?: string\n}\n\nexport const QrCode: React.FC<React.PropsWithChildren<IQrCodeProps>> = (\n  props\n) => {\n  return (\n    <div className=\"qrcode\">\n      <div className=\"qrcode-title\">\n        <div className=\"qrcode-title-content\">{props.title}</div>\n      </div>\n      <div className=\"qrcode-content\">\n        <img src={props.link} />\n      </div>\n    </div>\n  )\n}\n\nexport const QrCodeGroup: React.FC = (props) => (\n  <div className=\"qrcode-group\">{props.children}</div>\n)\n"
  },
  {
    "path": "docs/site/Section.less",
    "content": ".site-section {\n  &-title {\n    font-size: 50px;\n    text-align: center;\n    padding-bottom: 200px;\n    position: relative;\n    color: #45124e;\n\n    @media (max-width: 480px) {\n      font-size: 30px;\n    }\n  }\n}\n"
  },
  {
    "path": "docs/site/Section.tsx",
    "content": "import React from 'react'\nimport './Section.less'\n\nexport interface ISectionProps {\n  title?: React.ReactNode\n  style?: React.CSSProperties\n  titleStyle?: React.CSSProperties\n  scale?: number\n}\n\nexport const Section: React.FC<React.PropsWithChildren<ISectionProps>> = (\n  props\n) => {\n  return (\n    <section className=\"site-section\" style={props.style}>\n      <div className=\"site-section-title\" style={props.titleStyle}>\n        {props.title}\n      </div>\n      <div\n        className=\"site-section-body\"\n        style={{ transform: `scale(${props.scale || 1})` }}\n      >\n        {props.children}\n      </div>\n    </section>\n  )\n}\n"
  },
  {
    "path": "docs/site/styles.less",
    "content": ".site-section {\n  .codesandbox {\n    width: 100%;\n    height: 500px;\n    border: 0;\n    border-radius: 4px;\n    overflow: hidden;\n    box-shadow: 0 10px 30px #555;\n  }\n\n  img {\n    width: 100%;\n    border-radius: 4px;\n  }\n}\n\n#root {\n  overflow: hidden;\n}\n"
  },
  {
    "path": "global.config.ts",
    "content": "import prettyFormat from 'pretty-format'\n\nglobal['prettyFormat'] = prettyFormat\n\nglobal['sleep'] = (time: number) => {\n  return new Promise((resolve) => setTimeout(resolve, time))\n}\n\nglobal['requestAnimationFrame'] = (fn: () => void) => setTimeout(fn, 0)\n\nglobal['document'].documentElement.style['grid-column-gap'] = true\n"
  },
  {
    "path": "jest.config.js",
    "content": "module.exports = {\n  collectCoverage: true,\n  verbose: true,\n  testEnvironment: 'jsdom',\n  preset: 'ts-jest',\n  testMatch: ['**/__tests__/**/*.spec.[jt]s?(x)'],\n  setupFilesAfterEnv: [\n    require.resolve('jest-dom/extend-expect'),\n    './global.config.ts',\n  ],\n  // moduleNameMapper: process.env.TEST_ENV === 'production' ? undefined : alias,\n  globals: {\n    'ts-jest': {\n      babelConfig: false,\n      tsconfig: './tsconfig.jest.json',\n      diagnostics: false,\n    },\n  },\n  coveragePathIgnorePatterns: [\n    '/node_modules/',\n    '/__tests__/',\n    '/esm/',\n    '/lib/',\n    'package.json',\n    '/demo/',\n    '/packages/builder/src/__tests__/',\n    '/packages/builder/src/components/',\n    '/packages/builder/src/configs/',\n    'package-lock.json',\n  ],\n}\n"
  },
  {
    "path": "lerna.json",
    "content": "{\n  \"version\": \"2.3.7\",\n  \"npmClient\": \"yarn\",\n  \"useWorkspaces\": true,\n  \"npmClientArgs\": [\n    \"--ignore-engines\"\n  ],\n  \"command\": {\n    \"version\": {\n      \"forcePublish\": true,\n      \"exact\": true,\n      \"message\": \"chore(release): 😊 publish %s\"\n    }\n  }\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"root\",\n  \"private\": true,\n  \"devEngines\": {\n    \"node\": \"8.x || 9.x || 10.x || 11.x\"\n  },\n  \"workspaces\": [\n    \"packages/*\",\n    \"devtools/*\"\n  ],\n  \"scripts\": {\n    \"build\": \"rimraf -rf packages/*/{lib,dist,esm} && lerna run build\",\n    \"build:docs\": \"dumi build\",\n    \"start\": \"dumi dev\",\n    \"test\": \"jest --coverage\",\n    \"test:reactive\": \"jest packages/reactive/\",\n    \"test:validator\": \"jest packages/validator/\",\n    \"test:core\": \"jest packages/core/\",\n    \"test:core:watch\": \"npm run test:core --- --watch\",\n    \"test:schema\": \"jest packages/json-schema/\",\n    \"test:schema:watch\": \"npm run test:schema --- --watch\",\n    \"test:react\": \"jest packages/react/\",\n    \"test:shared\": \"jest packages/shared/\",\n    \"test:path\": \"jest packages/path/\",\n    \"test:react:watch\": \"npm run test:react --- --watch\",\n    \"test:vue\": \"jest packages/vue/\",\n    \"test:vue:watch\": \"npm run test:vue --- --watch\",\n    \"test:reactive-vue\": \"jest packages/reactive-vue/\",\n    \"test:reactive-vue:watch\": \"npm run test:reactive-vue --- --watch\",\n    \"test:antd\": \"jest packages/antd/\",\n    \"test:next\": \"jest packages/next/\",\n    \"test:watch\": \"jest --watch\",\n    \"test:prod\": \"jest --coverage --silent\",\n    \"preversion\": \"yarn install --ignore-engines && git add -A && npm run build && npm run lint && npm run test\",\n    \"version:alpha\": \"lerna version prerelease --preid alpha\",\n    \"version:beta\": \"lerna version prerelease --preid beta\",\n    \"version:rc\": \"lerna version prerelease --preid rc\",\n    \"version:patch\": \"lerna version patch\",\n    \"version:minor\": \"lerna version minor\",\n    \"version:preminor\": \"lerna version preminor --preid beta\",\n    \"version:major\": \"lerna version major\",\n    \"release:force\": \"lerna publish from-package --yes\",\n    \"lint\": \"eslint .\"\n  },\n  \"resolutions\": {\n    \"@types/react\": \"^18.0.0\",\n    \"@types/react-dom\": \"^18.0.0\",\n    \"@mapbox/hast-util-to-jsx\": \"~1.0.0\",\n    \"yargs\": \"^16.x\",\n    \"commander\": \"^6.x\",\n    \"ttypescript\": \"1.5.15\"\n  },\n  \"devDependencies\": {\n    \"@alifd/next\": \"^1.19.1\",\n    \"@commitlint/cli\": \"^14.1.0\",\n    \"@commitlint/config-conventional\": \"^14.1.0\",\n    \"@commitlint/prompt-cli\": \"^14.1.0\",\n    \"@netlify/functions\": \"^0.7.2\",\n    \"@rollup/plugin-commonjs\": \"^17.0.0\",\n    \"@testing-library/jest-dom\": \"^5.0.0\",\n    \"@testing-library/react\": \"^11.2.3\",\n    \"@testing-library/vue\": \"^5.6.2\",\n    \"@types/fs-extra\": \"^8.1.0\",\n    \"@types/hoist-non-react-statics\": \"^3.3.1\",\n    \"@types/jest\": \"^24.0.18\",\n    \"@types/node\": \"^12.6.8\",\n    \"@types/react\": \"^18.0.0\",\n    \"@types/react-dom\": \"^18.0.0\",\n    \"@types/react-is\": \"^18.3.0\",\n    \"@typescript-eslint/eslint-plugin\": \"^4.9.1\",\n    \"@typescript-eslint/parser\": \"^4.8.2\",\n    \"@umijs/plugin-sass\": \"^1.1.1\",\n    \"@vue/test-utils\": \"1.0.0-beta.22\",\n    \"antd\": \"^4.0.0\",\n    \"axios\": \"^1.6.0\",\n    \"chalk\": \"^2.4.2\",\n    \"chokidar\": \"^2.1.2\",\n    \"concurrently\": \"^4.1.0\",\n    \"conventional-commit-types\": \"^2.2.0\",\n    \"cool-path\": \"^1.0.6\",\n    \"cross-env\": \"^5.2.1\",\n    \"css-loader\": \"^5.0.0\",\n    \"cz-conventional-changelog\": \"^2.1.0\",\n    \"dumi\": \"^1.1.53\",\n    \"escape-string-regexp\": \"^4.0.0\",\n    \"eslint\": \"^7.14.0\",\n    \"eslint-config-prettier\": \"^7.0.0\",\n    \"eslint-plugin-import\": \"^2.13.0\",\n    \"eslint-plugin-markdown\": \"^2.0.1\",\n    \"eslint-plugin-node\": \"^11.1.0\",\n    \"eslint-plugin-prettier\": \"^3.1.0\",\n    \"eslint-plugin-promise\": \"^4.0.0\",\n    \"eslint-plugin-react\": \"^7.14.2\",\n    \"eslint-plugin-react-hooks\": \"^4.2.0\",\n    \"eslint-plugin-vue\": \"^7.0.1\",\n    \"execa\": \"^5.0.0\",\n    \"file-loader\": \"^5.0.2\",\n    \"findup\": \"^0.1.5\",\n    \"fs-extra\": \"^7.0.1\",\n    \"ghooks\": \"^2.0.4\",\n    \"glob\": \"^7.1.3\",\n    \"html-webpack-plugin\": \"^3.2.0\",\n    \"immutable\": \"^4.0.0-rc.12\",\n    \"istanbul-api\": \"^2.1.1\",\n    \"istanbul-lib-coverage\": \"^2.0.3\",\n    \"jest\": \"^26.0.0\",\n    \"jest-codemods\": \"^0.19.1\",\n    \"jest-dom\": \"^3.1.2\",\n    \"jest-localstorage-mock\": \"^2.3.0\",\n    \"jest-styled-components\": \"6.3.3\",\n    \"jest-watch-lerna-packages\": \"^1.1.0\",\n    \"lerna\": \"^4.0.0\",\n    \"less\": \"^4.1.1\",\n    \"less-loader\": \"^5.0.0\",\n    \"less-plugin-npm-import\": \"^2.1.0\",\n    \"lint-staged\": \"^8.2.1\",\n    \"mfetch\": \"^0.2.27\",\n    \"mobx\": \"^6.0.4\",\n    \"mobx-react-lite\": \"^3.1.6\",\n    \"onchange\": \"^5.2.0\",\n    \"opencollective\": \"^1.0.3\",\n    \"opencollective-postinstall\": \"^2.0.2\",\n    \"param-case\": \"^3.0.4\",\n    \"postcss\": \"^8.0.0\",\n    \"prettier\": \"^2.2.1\",\n    \"pretty-format\": \"^24.0.0\",\n    \"pretty-quick\": \"^3.1.0\",\n    \"querystring\": \"^0.2.1\",\n    \"raw-loader\": \"^4.0.0\",\n    \"react\": \"^18.0.0\",\n    \"react-dom\": \"^18.0.0\",\n    \"react-mde\": \"^11.5.0\",\n    \"react-test-renderer\": \"^16.11.0\",\n    \"rimraf\": \"^3.0.0\",\n    \"rollup\": \"^2.37.1\",\n    \"rollup-plugin-dts\": \"^2.0.0\",\n    \"rollup-plugin-external-globals\": \"^0.6.1\",\n    \"rollup-plugin-inject-process-env\": \"^1.3.1\",\n    \"rollup-plugin-node-resolve\": \"^5.2.0\",\n    \"rollup-plugin-postcss\": \"^4.0.0\",\n    \"rollup-plugin-terser\": \"^7.0.2\",\n    \"rollup-plugin-typescript2\": \"^0.35.0\",\n    \"semver\": \"^7.3.5\",\n    \"semver-regex\": \"^3.1.3\",\n    \"showdown\": \"^1.9.1\",\n    \"staged-git-files\": \"^1.1.2\",\n    \"string-similarity\": \"^4.0.4\",\n    \"style-loader\": \"^1.1.3\",\n    \"styled-components\": \"^5.0.0\",\n    \"ts-import-plugin\": \"1.6.1\",\n    \"ts-jest\": \"^26.0.0\",\n    \"ts-loader\": \"^7.0.4\",\n    \"ts-node\": \"^9.1.1\",\n    \"typescript\": \"^4.1.5\",\n    \"vue-eslint-parser\": \"^7.1.1\",\n    \"webpack\": \"^4.41.5\",\n    \"webpack-cli\": \"^3.3.10\",\n    \"webpack-dev-server\": \"^3.10.1\",\n    \"yup\": \"^1.4.0\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/alibaba/formily.git\"\n  },\n  \"config\": {\n    \"ghooks\": {\n      \"pre-commit\": \"lint-staged\",\n      \"commit-msg\": \"commitlint --edit\"\n    }\n  },\n  \"lint-staged\": {\n    \"*.{ts,tsx,js}\": [\n      \"eslint --ext .ts,.tsx,.js\",\n      \"pretty-quick --staged\",\n      \"git add\"\n    ],\n    \"*.md\": [\n      \"pretty-quick --staged\",\n      \"git add\"\n    ]\n  },\n  \"collective\": {\n    \"type\": \"opencollective\",\n    \"url\": \"https://opencollective.com/formily\"\n  },\n  \"dependencies\": {\n    \"@ant-design/icons\": \"^4.0.2\"\n  },\n  \"packageManager\": \"yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e\"\n}\n"
  },
  {
    "path": "packages/.eslintrc",
    "content": "{\n  \"parser\": \"@typescript-eslint/parser\",\n  \"extends\": [\n    \"plugin:react/recommended\",\n    \"plugin:@typescript-eslint/recommended\",\n    \"prettier/@typescript-eslint\"\n  ],\n  \"env\": {\n    \"node\": true\n  },\n  \"plugins\": [\"@typescript-eslint\", \"react\", \"prettier\", \"markdown\"],\n  \"parserOptions\": {\n    \"sourceType\": \"module\",\n    \"ecmaVersion\": 10,\n    \"ecmaFeatures\": {\n      \"jsx\": true\n    }\n  },\n  \"settings\": {\n    \"react\": {\n      \"version\": \"detect\"\n    }\n  },\n  \"rules\": {\n    \"prettier/prettier\": 0,\n    // don't force es6 functions to include space before paren\n    \"space-before-function-paren\": 0,\n    \"react/prop-types\": 0,\n    \"react/no-find-dom-node\": 0,\n    \"react/display-name\": 0,\n    // allow specifying true explicitly for boolean props\n    \"react/jsx-boolean-value\": 0,\n    \"react/no-did-update-set-state\": 0,\n    \"react/no-unescaped-entities\": \"off\",\n    // maybe we should no-public\n    \"@typescript-eslint/explicit-member-accessibility\": 0,\n    \"@typescript-eslint/interface-name-prefix\": 0,\n    \"@typescript-eslint/no-explicit-any\": 0,\n    \"@typescript-eslint/explicit-function-return-type\": 0,\n    \"@typescript-eslint/no-parameter-properties\": 0,\n    \"@typescript-eslint/array-type\": 0,\n    \"@typescript-eslint/no-object-literal-type-assertion\": 0,\n    \"@typescript-eslint/no-use-before-define\": 0,\n    \"@typescript-eslint/no-unused-vars\": 1,\n    \"@typescript-eslint/no-namespace\": 0,\n    \"@typescript-eslint/ban-ts-comment\": 0,\n    \"@typescript-eslint/ban-types\": 0,\n    \"@typescript-eslint/adjacent-overload-signatures\": 0,\n    \"@typescript-eslint/explicit-module-boundary-types\": 0,\n    \"@typescript-eslint/triple-slash-reference\": 0,\n    \"@typescript-eslint/no-empty-function\": 0,\n    \"no-console\": [\n      \"error\",\n      {\n        \"allow\": [\"warn\", \"error\", \"info\"]\n      }\n    ],\n    \"prefer-const\": 0,\n    \"no-var\": 1,\n    \"prefer-rest-params\": 0\n  },\n  \"overrides\": [\n    {\n      \"files\": [\"**/*.md.{jsx,tsx}\"],\n      \"processor\": \"markdown/markdown\"\n    },\n    {\n      \"files\": [\"**/*.md/*.{jsx,tsx}\"],\n      \"rules\": {\n        \"@typescript-eslint/no-unused-vars\": \"error\",\n        \"no-unused-vars\": \"error\",\n        \"no-console\": \"off\",\n        \"react/display-name\": \"off\",\n        \"react/prop-types\": \"off\"\n      }\n    },\n    {\n      \"files\": [\"**/*.md/*.{js,ts}\"],\n      \"rules\": {\n        \"@typescript-eslint/no-unused-vars\": \"off\",\n        \"no-unused-vars\": \"off\",\n        \"no-console\": \"off\",\n        \"react/display-name\": \"off\",\n        \"react/prop-types\": \"off\"\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "packages/antd/.npmignore",
    "content": "node_modules\n*.log\nbuild\ndocs\ndoc-site\n__tests__\n.eslintrc\njest.config.js\ntsconfig.json\n.umi\nsrc"
  },
  {
    "path": "packages/antd/.umirc.js",
    "content": "import { resolve } from 'path'\nexport default {\n  mode: 'site',\n  logo: '//img.alicdn.com/imgextra/i2/O1CN01Kq3OHU1fph6LGqjIz_!!6000000004056-55-tps-1141-150.svg',\n  title: 'Ant Design',\n  hash: true,\n  favicon:\n    '//img.alicdn.com/imgextra/i3/O1CN01XtT3Tv1Wd1b5hNVKy_!!6000000002810-55-tps-360-360.svg',\n  outputPath: './doc-site',\n  locales: [\n    ['en-US', 'English'],\n    ['zh-CN', '中文'],\n  ],\n  navs: {\n    'zh-CN': [\n      {\n        title: 'Ant Design',\n        path: '/zh-CN/components',\n      },\n      {\n        title: '主站',\n        path: 'https://formilyjs.org',\n      },\n      {\n        title: 'GITHUB',\n        path: 'https://github.com/alibaba/formily',\n      },\n    ],\n    'en-US': [\n      {\n        title: 'Ant Design',\n        path: '/components',\n      },\n      {\n        title: 'Home Site',\n        path: 'https://formilyjs.org',\n      },\n      {\n        title: 'GITHUB',\n        path: 'https://github.com/alibaba/formily',\n      },\n    ],\n  },\n  links: [\n    {\n      rel: 'stylesheet',\n      href: 'https://esm.sh/antd@4.x/dist/antd.css',\n    },\n  ],\n  headScripts: [\n    `\n    function loadAd(){\n      var header = document.querySelector('.__dumi-default-layout-content .markdown h1')\n      if(header && !header.querySelector('#_carbonads_js')){\n        var script = document.createElement('script')\n        script.src = '//cdn.carbonads.com/carbon.js?serve=CEAICK3M&placement=formilyjsorg'\n        script.id = '_carbonads_js'\n        script.classList.add('head-ad')\n        header.appendChild(script)\n      }\n    }\n    var request = null\n    var observer = new MutationObserver(function(){\n      cancelIdleCallback(request)\n      request = requestIdleCallback(loadAd)\n    })\n    document.addEventListener('DOMContentLoaded',function(){\n      loadAd()\n      observer.observe(\n        document.body,\n        {\n          childList:true,\n          subtree:true\n        }\n      )\n    })\n    `,\n  ],\n  styles: [\n    `.__dumi-default-navbar-logo{\n      height: 60px !important;\n      width: 150px !important;\n      padding-left:0 !important;\n      color: transparent !important;\n    }\n    .__dumi-default-navbar{\n      padding: 0 28px !important;\n    }\n    .__dumi-default-layout-hero{\n      background-image: url(//img.alicdn.com/imgextra/i4/O1CN01ZcvS4e26XMsdsCkf9_!!6000000007671-2-tps-6001-4001.png);\n      background-size: cover;\n      background-repeat: no-repeat;\n      padding: 120px 0 !important;\n    }\n    .__dumi-default-layout-hero h1{\n      color:#45124e !important;\n      font-size:80px !important;\n      padding-bottom: 30px !important;\n    }\n    .__dumi-default-dark-switch {\n      display:none\n    }\n    nav a{\n      text-decoration: none !important;\n    }\n    #carbonads * {\n      margin: initial;\n      padding: initial;\n    }\n    #carbonads {\n      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,\n        Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Helvetica, Arial,\n        sans-serif;\n    }\n    #carbonads {\n      display: flex;\n      max-width: 330px;\n      background-color: hsl(0, 0%, 98%);\n      box-shadow: 0 1px 4px 1px hsla(0, 0%, 0%, 0.1);\n      z-index: 100;\n      float:right;\n    }\n    #carbonads a {\n      color: inherit;\n      text-decoration: none;\n    }\n    #carbonads a:hover {\n      color: inherit;\n    }\n    #carbonads span {\n      position: relative;\n      display: block;\n      overflow: hidden;\n    }\n    #carbonads .carbon-wrap {\n      display: flex;\n    }\n    #carbonads .carbon-img {\n      display: block;\n      margin: 0;\n      line-height: 1;\n    }\n    #carbonads .carbon-img img {\n      display: block;\n    }\n    #carbonads .carbon-text {\n      font-size: 13px;\n      padding: 10px;\n      margin-bottom: 16px;\n      line-height: 1.5;\n      text-align: left;\n    }\n    #carbonads .carbon-poweredby {\n      display: block;\n      padding: 6px 8px;\n      background: #f1f1f2;\n      text-align: center;\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n      font-weight: 600;\n      font-size: 8px;\n      line-height: 1;\n      border-top-left-radius: 3px;\n      position: absolute;\n      bottom: 0;\n      right: 0;\n    }\n    `,\n  ],\n}\n"
  },
  {
    "path": "packages/antd/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-present, Alibaba Group Holding Limited. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "packages/antd/README.md",
    "content": "# @formily/antd\n\n### Install\n\n```bash\nnpm install --save @formily/antd\n```\n"
  },
  {
    "path": "packages/antd/__tests__/moment.spec.ts",
    "content": "import moment from 'moment'\nimport { formatMomentValue, momentable } from '../src/__builtins__/moment'\n\ntest('momentable is usable', () => {\n  expect(moment.isMoment(momentable('2021-09-08'))).toBe(true)\n  expect(\n    momentable(['2021-09-08', '2021-12-29']).every((item) =>\n      moment.isMoment(item)\n    )\n  ).toBe(true)\n  expect(momentable(0)).toBe(0)\n})\n\ntest('formatMomentValue is usable', () => {\n  expect(formatMomentValue('', 'YYYY-MM-DD', '~')).toBe('~')\n  expect(formatMomentValue('2021-12-21 15:47:00', 'YYYY-MM-DD')).toBe(\n    '2021-12-21'\n  )\n  expect(formatMomentValue('2021-12-21 15:47:00', undefined)).toBe(\n    '2021-12-21 15:47:00'\n  )\n  expect(formatMomentValue('2021-12-21 15:47:00', (date: string) => date)).toBe(\n    '2021-12-21 15:47:00'\n  )\n  expect(formatMomentValue('12:11', 'HH:mm')).toBe('12:11')\n  expect(formatMomentValue('12:11:11', 'HH:mm:ss')).toBe('12:11:11')\n  expect(formatMomentValue(['12:11'], ['HH:mm'])).toEqual(['12:11'])\n  expect(formatMomentValue(['12:11:11'], ['HH:mm:ss'])).toEqual(['12:11:11'])\n  expect(formatMomentValue(1663155911097, 'YYYY-MM-DD HH:mm:ss')).toBe(\n    moment(1663155911097).format('YYYY-MM-DD HH:mm:ss')\n  )\n  expect(formatMomentValue([1663155911097], ['YYYY-MM-DD HH:mm:ss'])).toEqual([\n    moment(1663155911097).format('YYYY-MM-DD HH:mm:ss'),\n  ])\n  expect(\n    formatMomentValue('2022-09-15T09:56:26.000Z', 'YYYY-MM-DD HH:mm:ss')\n  ).toBe(moment('2022-09-15T09:56:26.000Z').format('YYYY-MM-DD HH:mm:ss'))\n  expect(\n    formatMomentValue(['2022-09-15T09:56:26.000Z'], ['YYYY-MM-DD HH:mm:ss'])\n  ).toEqual([moment('2022-09-15T09:56:26.000Z').format('YYYY-MM-DD HH:mm:ss')])\n  expect(formatMomentValue('2022-09-15 09:56:26', 'HH:mm:ss')).toBe('09:56:26')\n  expect(formatMomentValue(['2022-09-15 09:56:26'], ['HH:mm:ss'])).toEqual([\n    '09:56:26',\n  ])\n  expect(\n    formatMomentValue(\n      ['2021-12-21 15:47:00', '2021-12-29 15:47:00'],\n      'YYYY-MM-DD'\n    )\n  ).toEqual(['2021-12-21', '2021-12-29'])\n  expect(\n    formatMomentValue(\n      ['2021-12-21 16:47:00', '2021-12-29 18:47:00'],\n      (date: string) => date\n    )\n  ).toEqual(['2021-12-21 16:47:00', '2021-12-29 18:47:00'])\n  expect(\n    formatMomentValue(\n      ['2021-12-21 16:47:00', '2021-12-29 18:47:00'],\n      ['YYYY-MM-DD', (date: string) => date]\n    )\n  ).toEqual(['2021-12-21', '2021-12-29 18:47:00'])\n  expect(\n    formatMomentValue(\n      ['2021-12-21 16:47:00', '2021-12-29 18:47:00'],\n      ['YYYY-MM-DD', undefined]\n    )\n  ).toEqual(['2021-12-21', '2021-12-29 18:47:00'])\n  expect(formatMomentValue([undefined], 'YYYY-MM-DD', 'placeholder')).toEqual([\n    'placeholder',\n  ])\n})\n"
  },
  {
    "path": "packages/antd/__tests__/sideEffects.spec.ts",
    "content": "import SideEffectsFlagPlugin from 'webpack/lib/optimize/SideEffectsFlagPlugin'\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { sideEffects, name: baseName } = require('../package.json')\n\ntest('sideEffects should be controlled manually', () => {\n  // if config in pkg.json changed, please ensure it is covered by jest.\n  expect(sideEffects).toStrictEqual([\n    'dist/*',\n    'esm/*.js',\n    'lib/*.js',\n    'src/*.ts',\n    '*.less',\n    '**/*/style.js',\n  ])\n})\n\ntest('dist/*', () => {\n  // eg. import \"@formily/antd/dist/antd.css\"\n  expect(\n    SideEffectsFlagPlugin.moduleHasSideEffects('dist/antd.css', 'dist/*')\n  ).toBeTruthy()\n  expect(\n    SideEffectsFlagPlugin.moduleHasSideEffects(\n      'dist/formily.antd.umd.development.js',\n      'dist/*'\n    )\n  ).toBeTruthy()\n  expect(\n    SideEffectsFlagPlugin.moduleHasSideEffects(\n      'dist/formily.antd.umd.production.js',\n      'dist/*'\n    )\n  ).toBeTruthy()\n})\n\ntest('esm/*.js & lib/*.js', () => {\n  // expected to be truthy\n  // eg. import FormilyAntd from \"@formily/antd/esm/index\"\n  expect(\n    SideEffectsFlagPlugin.moduleHasSideEffects('esm/index.js', 'esm/*.js')\n  ).toBeTruthy()\n  expect(\n    SideEffectsFlagPlugin.moduleHasSideEffects('lib/index.js', 'lib/*.js')\n  ).toBeTruthy()\n\n  // expected to be falsy\n  // eg. import Input from \"@formily/antd/esm/input/index\" => will be compiled to __webpack_require__(\"./node_modules/@formily/antd/esm/input/index.js\")\n  // It should be removed by webpack if not used after imported.\n  expect(\n    SideEffectsFlagPlugin.moduleHasSideEffects('esm/input/index.js', 'esm/*.js')\n  ).toBeFalsy()\n  expect(\n    SideEffectsFlagPlugin.moduleHasSideEffects(\n      'esm/array-base/index.js',\n      'esm/*.js'\n    )\n  ).toBeFalsy()\n  expect(\n    SideEffectsFlagPlugin.moduleHasSideEffects('lib/input/index.js', 'lib/*.js')\n  ).toBeFalsy()\n})\n\ntest('*.less', () => {\n  //  eg. import \"@formily/antd/lib/input/style.less\"\n  expect(\n    SideEffectsFlagPlugin.moduleHasSideEffects(\n      `${baseName}/lib/input/style.less`,\n      '*.less'\n    )\n  ).toBeTruthy()\n})\n\ntest('**/*/style.js', () => {\n  // eg. import \"@formily/antd/lib/input/style\" will be compiled to  __webpack_require__(\"./node_modules/@formily/antd/lib/input/style.js\")\n  // so we can match the `*style.js` only, not `**/*/style*` may be cause someting mismatch like `@formily/antd/lib/xxx-style/index.js`\n  const modulePathArr = [\n    'lib/input/style.js',\n    `${baseName}/lib/input/style.js`,\n    `./node_modules/${baseName}/style.js`,\n  ]\n\n  modulePathArr.forEach((modulePath) => {\n    const hasSideEffects = SideEffectsFlagPlugin.moduleHasSideEffects(\n      modulePath,\n      '**/*/style.js'\n    )\n    expect(hasSideEffects).toBeTruthy()\n  })\n})\n"
  },
  {
    "path": "packages/antd/build-style.ts",
    "content": "import { build } from '../../scripts/build-style'\n\nbuild({\n  esStr: 'antd/es/',\n  libStr: 'antd/lib/',\n  allStylesOutputFile: 'dist/antd.css',\n})\n"
  },
  {
    "path": "packages/antd/create-style.ts",
    "content": "import glob from 'glob'\nimport path from 'path'\nimport fs from 'fs-extra'\n\nglob(\n  './*/style.less',\n  { cwd: path.resolve(__dirname, './src') },\n  (err, files) => {\n    if (err) return console.error(err)\n    fs.writeFile(\n      path.resolve(__dirname, './src/style.ts'),\n      `// auto generated code\n${files\n  .map((path) => {\n    return `import '${path}'\\n`\n  })\n  .join('')}`,\n      'utf8'\n    )\n    fs.writeFile(\n      path.resolve(__dirname, './src/style.less'),\n      `// auto generated code\n${files\n  .map((path) => {\n    return `@import '${path}';\\n`\n  })\n  .join('')}`,\n      'utf8'\n    )\n  }\n)\n"
  },
  {
    "path": "packages/antd/docs/components/ArrayCards.md",
    "content": "# ArrayCards\n\n> Card list, it is more suitable to use ArrayCards for scenarios with a large number of fields in each row and more linkages\n>\n> Note: This component is only applicable to Schema scenarios\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCards,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"string_array\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCards\"\n          x-component-props={{\n            title: 'String array',\n          }}\n        >\n          <SchemaField.Void>\n            <SchemaField.Void x-component=\"ArrayCards.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCards.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCards.Copy\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveDown\" />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"ArrayCards.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"array\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCards\"\n          x-component-props={{\n            title: 'Object array',\n          }}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void x-component=\"ArrayCards.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCards.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveDown\" />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayCards.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCards,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    string_array: {\n      type: 'array',\n      'x-component': 'ArrayCards',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      'x-component-props': {\n        title: 'String array',\n      },\n      items: {\n        type: 'void',\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCards.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCards.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayCards.Addition',\n        },\n      },\n    },\n    array: {\n      type: 'array',\n      'x-component': 'ArrayCards',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      'x-component-props': {\n        title: 'Object array',\n      },\n      items: {\n        type: 'object',\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCards.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCards.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayCards.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## Effects linkage case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCards,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nconst form = createForm({\n  effects: () => {\n    //Active linkage mode\n    onFieldChange('array.*.aa', ['value'], (field, form) => {\n      form.setFieldState(field.query('.bb'), (state) => {\n        state.visible = field.value != '123'\n      })\n    })\n    //Passive linkage mode\n    onFieldReact('array.*.dd', (field) => {\n      field.visible = field.query('.cc').get('value') != '123'\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"array\"\n          maxItems={3}\n          x-component=\"ArrayCards\"\n          x-decorator=\"FormItem\"\n          x-component-props={{\n            title: 'Object array',\n          }}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void x-component=\"ArrayCards.Index\" />\n            <SchemaField.String\n              name=\"aa\"\n              x-decorator=\"FormItem\"\n              title=\"AA\"\n              required\n              description=\"AA hide BB when entering 123\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"bb\"\n              x-decorator=\"FormItem\"\n              title=\"BB\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"cc\"\n              x-decorator=\"FormItem\"\n              title=\"CC\"\n              required\n              description=\"Hide DD when CC enters 123\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"dd\"\n              x-decorator=\"FormItem\"\n              title=\"DD\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCards.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveDown\" />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayCards.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema linkage case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCards,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    array: {\n      type: 'array',\n      'x-component': 'ArrayCards',\n      maxItems: 3,\n      title: 'Object array',\n      items: {\n        type: 'object',\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCards.Index',\n          },\n          aa: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'AA',\n            required: true,\n            'x-component': 'Input',\n            description: 'Enter 123',\n          },\n          bb: {\n            type: 'string',\n            title: 'BB',\n            required: true,\n            'x-decorator': 'FormItem',\n            'x-component': 'Input',\n            'x-reactions': [\n              {\n                dependencies: ['.aa'],\n                when: \"{{$deps[0] != '123'}}\",\n                fulfill: {\n                  schema: {\n                    title: 'BB',\n                    'x-disabled': true,\n                  },\n                },\n                otherwise: {\n                  schema: {\n                    title: 'Changed',\n                    'x-disabled': false,\n                  },\n                },\n              },\n            ],\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCards.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayCards.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### ArrayCards\n\nExtended attributes\n\n| Property name | Type                      | Description     | Default value |\n| ------------- | ------------------------- | --------------- | ------------- |\n| onAdd         | `(index: number) => void` | add method      |               |\n| onRemove      | `(index: number) => void` | remove method   |               |\n| onCopy        | `(index: number) => void` | copy method     |               |\n| onMoveUp      | `(index: number) => void` | moveUp method   |               |\n| onMoveDown    | `(index: number) => void` | moveDown method |               |\n\nOther Reference https://ant.design/components/card-cn/\n\n### ArrayCards.Addition\n\n> Add button\n\nExtended attributes\n\n| Property name | Type                 | Description   | Default value |\n| ------------- | -------------------- | ------------- | ------------- |\n| title         | ReactText            | Copywriting   |               |\n| method        | `'push' \\|'unshift'` | add method    | `'push'`      |\n| defaultValue  | `any`                | Default value |               |\n\nOther references https://ant.design/components/button-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayCards.Copy\n\n> Copy button\n\nExtended attributes\n\n| Property name | Type                 | Description | Default value |\n| ------------- | -------------------- | ----------- | ------------- |\n| title         | ReactText            | Copywriting |               |\n| method        | `'push' \\|'unshift'` | Copy method | `'push'`      |\n\nOther references https://ant.design/components/button-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayCards.Remove\n\n> Delete button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayCards.MoveDown\n\n> Move down button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayCards.MoveUp\n\n> Move up button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayCards.Index\n\n> Index Renderer\n\nNo attributes\n\n### ArrayCards.useIndex\n\n> Read the React Hook of the current rendering row index\n\n### ArrayCards.useRecord\n\n> Read the React Hook of the current rendering row\n"
  },
  {
    "path": "packages/antd/docs/components/ArrayCards.zh-CN.md",
    "content": "# ArrayCards\n\n> 卡片列表，对于每行字段数量较多，联动较多的场景比较适合使用 ArrayCards\n>\n> 注意：该组件只适用于 Schema 场景\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCards,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"string_array\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCards\"\n          x-component-props={{\n            title: '字符串数组',\n          }}\n        >\n          <SchemaField.Void>\n            <SchemaField.Void x-component=\"ArrayCards.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCards.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCards.Copy\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveDown\" />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"ArrayCards.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"array\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCards\"\n          x-component-props={{\n            title: '对象数组',\n          }}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void x-component=\"ArrayCards.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCards.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveDown\" />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayCards.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCards,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    string_array: {\n      type: 'array',\n      'x-component': 'ArrayCards',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      'x-component-props': {\n        title: '字符串数组',\n      },\n      items: {\n        type: 'void',\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCards.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCards.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayCards.Addition',\n        },\n      },\n    },\n    array: {\n      type: 'array',\n      'x-component': 'ArrayCards',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      'x-component-props': {\n        title: '对象数组',\n      },\n      items: {\n        type: 'object',\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCards.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCards.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayCards.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## Effects 联动案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCards,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nconst form = createForm({\n  effects: () => {\n    //主动联动模式\n    onFieldChange('array.*.aa', ['value'], (field, form) => {\n      form.setFieldState(field.query('.bb'), (state) => {\n        state.visible = field.value != '123'\n      })\n    })\n    //被动联动模式\n    onFieldReact('array.*.dd', (field) => {\n      field.visible = field.query('.cc').get('value') != '123'\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"array\"\n          maxItems={3}\n          x-component=\"ArrayCards\"\n          x-decorator=\"FormItem\"\n          x-component-props={{\n            title: '对象数组',\n          }}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void x-component=\"ArrayCards.Index\" />\n            <SchemaField.String\n              name=\"aa\"\n              x-decorator=\"FormItem\"\n              title=\"AA\"\n              required\n              description=\"AA输入123时隐藏BB\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"bb\"\n              x-decorator=\"FormItem\"\n              title=\"BB\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"cc\"\n              x-decorator=\"FormItem\"\n              title=\"CC\"\n              required\n              description=\"CC输入123时隐藏DD\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"dd\"\n              x-decorator=\"FormItem\"\n              title=\"DD\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCards.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveDown\" />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayCards.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 联动案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCards,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    array: {\n      type: 'array',\n      'x-component': 'ArrayCards',\n      maxItems: 3,\n      title: '对象数组',\n      items: {\n        type: 'object',\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCards.Index',\n          },\n          aa: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'AA',\n            required: true,\n            'x-component': 'Input',\n            description: '输入123',\n          },\n          bb: {\n            type: 'string',\n            title: 'BB',\n            required: true,\n            'x-decorator': 'FormItem',\n            'x-component': 'Input',\n            'x-reactions': [\n              {\n                dependencies: ['.aa'],\n                when: \"{{$deps[0] != '123'}}\",\n                fulfill: {\n                  schema: {\n                    title: 'BB',\n                    'x-disabled': true,\n                  },\n                },\n                otherwise: {\n                  schema: {\n                    title: 'Changed',\n                    'x-disabled': false,\n                  },\n                },\n              },\n            ],\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCards.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayCards.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### ArrayCards\n\n扩展属性\n\n| 属性名     | 类型                      | 描述         | 默认值 |\n| ---------- | ------------------------- | ------------ | ------ |\n| onAdd      | `(index: number) => void` | 增加方法     |        |\n| onRemove   | `(index: number) => void` | 删除方法     |        |\n| onCopy     | `(index: number) => void` | 复制方法     |        |\n| onMoveUp   | `(index: number) => void` | 向上移动方法 |        |\n| onMoveDown | `(index: number) => void` | 向下移动方法 |        |\n\n其余参考 https://ant.design/components/card-cn/\n\n### ArrayCards.Addition\n\n> 添加按钮\n\n扩展属性\n\n| 属性名       | 类型                  | 描述     | 默认值   |\n| ------------ | --------------------- | -------- | -------- |\n| title        | ReactText             | 文案     |          |\n| method       | `'push' \\| 'unshift'` | 添加方式 | `'push'` |\n| defaultValue | `any`                 | 默认值   |          |\n\n其余参考 https://ant.design/components/button-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayCards.Copy\n\n> 复制按钮\n\n扩展属性\n\n| 属性名 | 类型                  | 描述     | 默认值   |\n| ------ | --------------------- | -------- | -------- |\n| title  | ReactText             | 文案     |          |\n| method | `'push' \\| 'unshift'` | 添加方式 | `'push'` |\n\n其余参考 https://ant.design/components/button-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayCards.Remove\n\n> 删除按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayCards.MoveDown\n\n> 下移按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayCards.MoveUp\n\n> 上移按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayCards.Index\n\n> 索引渲染器\n\n无属性\n\n### ArrayCards.useIndex\n\n> 读取当前渲染行索引的 React Hook\n\n### ArrayCards.useRecord\n\n> 读取当前渲染记录的 React Hook\n"
  },
  {
    "path": "packages/antd/docs/components/ArrayCollapse.md",
    "content": "# ArrayCollapse\n\n> Folding panel, it is more suitable to use ArrayCollapse for scenes with more fields in each row and more linkage\n>\n> Note: This component is only applicable to Schema scenarios\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCollapse,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"string_array\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCollapse\"\n          x-component-props={{\n            accordion: true,\n            defaultOpenPanelCount: 3,\n          }}\n        >\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.CollapsePanel\"\n            x-component-props={{\n              header: 'String array',\n            }}\n          >\n            <SchemaField.Void x-component=\"ArrayCollapse.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCollapse.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveDown\" />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"array\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCollapse\"\n        >\n          <SchemaField.Object\n            x-component=\"ArrayCollapse.CollapsePanel\"\n            x-component-props={{\n              header: 'Object array',\n            }}\n          >\n            <SchemaField.Void x-component=\"ArrayCollapse.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCollapse.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveDown\" />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"string_array_unshift\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCollapse\"\n          x-component-props={{\n            defaultOpenPanelCount: 8,\n          }}\n        >\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.CollapsePanel\"\n            x-component-props={{\n              header: 'String array',\n            }}\n          >\n            <SchemaField.Void x-component=\"ArrayCollapse.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCollapse.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveDown\" />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.Addition\"\n            title=\"Add entry (unshift)\"\n            x-component-props={{\n              method: 'unshift',\n            }}\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Button\n          onClick={() => {\n            form.setInitialValues({\n              array: Array.from({ length: 10 }).map(() => ({\n                input: 'default value',\n              })),\n              string_array: Array.from({ length: 10 }).map(\n                () => 'default value'\n              ),\n              string_array_unshift: Array.from({ length: 10 }).map(\n                () => 'default value'\n              ),\n            })\n          }}\n        >\n          Load default data\n        </Button>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCollapse,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    string_array: {\n      type: 'array',\n      'x-component': 'ArrayCollapse',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      items: {\n        type: 'void',\n        'x-component': 'ArrayCollapse.CollapsePanel',\n        'x-component-props': {\n          header: 'String array',\n        },\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayCollapse.Addition',\n        },\n      },\n    },\n    array: {\n      type: 'array',\n      'x-component': 'ArrayCollapse',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      items: {\n        type: 'object',\n        'x-component': 'ArrayCollapse.CollapsePanel',\n        'x-component-props': {\n          header: 'Object array',\n        },\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayCollapse.Addition',\n        },\n      },\n    },\n    array_unshift: {\n      type: 'array',\n      'x-component': 'ArrayCollapse',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      items: {\n        type: 'object',\n        'x-component': 'ArrayCollapse.CollapsePanel',\n        'x-component-props': {\n          header: 'Object array',\n        },\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add entry (unshift)',\n          'x-component': 'ArrayCollapse.Addition',\n          'x-component-props': {\n            method: 'unshift',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## Effects linkage case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCollapse,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nconst form = createForm({\n  effects: () => {\n    //Active linkage mode\n    onFieldChange('array.*.aa', ['value'], (field, form) => {\n      form.setFieldState(field.query('.bb'), (state) => {\n        state.visible = field.value != '123'\n      })\n    })\n    //Passive linkage mode\n    onFieldReact('array.*.dd', (field) => {\n      field.visible = field.query('.cc').get('value') != '123'\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"array\"\n          maxItems={3}\n          x-component=\"ArrayCollapse\"\n          x-decorator=\"FormItem\"\n          x-component-props={{\n            title: 'Object array',\n          }}\n        >\n          <SchemaField.Object\n            x-component=\"ArrayCollapse.CollapsePanel\"\n            x-component-props={{\n              header: 'Object array',\n            }}\n          >\n            <SchemaField.Void x-component=\"ArrayCollapse.Index\" />\n            <SchemaField.String\n              name=\"aa\"\n              x-decorator=\"FormItem\"\n              title=\"AA\"\n              required\n              description=\"AA hide BB when entering 123\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"bb\"\n              x-decorator=\"FormItem\"\n              title=\"BB\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"cc\"\n              x-decorator=\"FormItem\"\n              title=\"CC\"\n              required\n              description=\"Hide DD when CC enters 123\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"dd\"\n              x-decorator=\"FormItem\"\n              title=\"DD\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCollapse.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveDown\" />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema linkage case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCollapse,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    array: {\n      type: 'array',\n      'x-component': 'ArrayCollapse',\n      maxItems: 3,\n      title: 'Object array',\n      items: {\n        type: 'object',\n        'x-component': 'ArrayCollapse.CollapsePanel',\n        'x-component-props': {\n          header: 'Object array',\n        },\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Index',\n          },\n          aa: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'AA',\n            required: true,\n            'x-component': 'Input',\n            description: 'Enter 123',\n          },\n          bb: {\n            type: 'string',\n            title: 'BB',\n            required: true,\n            'x-decorator': 'FormItem',\n            'x-component': 'Input',\n            'x-reactions': [\n              {\n                dependencies: ['.aa'],\n                when: \"{{$deps[0] != '123'}}\",\n                fulfill: {\n                  schema: {\n                    title: 'BB',\n                    'x-disabled': true,\n                  },\n                },\n                otherwise: {\n                  schema: {\n                    title: 'Changed',\n                    'x-disabled': false,\n                  },\n                },\n              },\n            ],\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayCollapse.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### ArrayCollapse\n\nReference https://ant.design/components/collapse-cn/\n\n### ArrayCollapse.CollapsePanel\n\nReference https://ant.design/components/collapse-cn/\n\n### ArrayCollapse.Addition\n\n> Add button\n\nExtended attributes\n\n| Property name | Type                 | Description   | Default value |\n| ------------- | -------------------- | ------------- | ------------- |\n| title         | ReactText            | Copywriting   |               |\n| method        | `'push' \\|'unshift'` | add method    | `'push'`      |\n| defaultValue  | `any`                | Default value |               |\n\nOther references https://ant.design/components/button-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayCollapse.Remove\n\n> Delete button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayCollapse.MoveDown\n\n> Move down button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayCollapse.MoveUp\n\n> Move up button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayCollapse.Index\n\n> Index Renderer\n\nNo attributes\n\n### ArrayCollapse.useIndex\n\n> Read the React Hook of the current rendering row index\n\n### ArrayCollapse.useRecord\n\n> Read the React Hook of the current rendering row\n"
  },
  {
    "path": "packages/antd/docs/components/ArrayCollapse.zh-CN.md",
    "content": "# ArrayCollapse\n\n> 折叠面板，对于每行字段数量较多，联动较多的场景比较适合使用 ArrayCollapse\n>\n> 注意：该组件只适用于 Schema 场景\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCollapse,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"string_array\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCollapse\"\n          x-component-props={{\n            accordion: true,\n            defaultOpenPanelCount: 3,\n          }}\n        >\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.CollapsePanel\"\n            x-component-props={{\n              header: '字符串数组',\n            }}\n          >\n            <SchemaField.Void x-component=\"ArrayCollapse.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCollapse.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveDown\" />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"array\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCollapse\"\n        >\n          <SchemaField.Object\n            x-component=\"ArrayCollapse.CollapsePanel\"\n            x-component-props={{\n              header: '对象数组',\n            }}\n          >\n            <SchemaField.Void x-component=\"ArrayCollapse.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCollapse.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveDown\" />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"string_array_unshift\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCollapse\"\n          x-component-props={{\n            defaultOpenPanelCount: 8,\n          }}\n        >\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.CollapsePanel\"\n            x-component-props={{\n              header: '字符串数组',\n            }}\n          >\n            <SchemaField.Void x-component=\"ArrayCollapse.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCollapse.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveDown\" />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.Addition\"\n            title=\"添加条目（unshift）\"\n            x-component-props={{\n              method: 'unshift',\n            }}\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Button\n          onClick={() => {\n            form.setInitialValues({\n              array: Array.from({ length: 10 }).map(() => ({\n                input: 'default value',\n              })),\n              string_array: Array.from({ length: 10 }).map(\n                () => 'default value'\n              ),\n              string_array_unshift: Array.from({ length: 10 }).map(\n                () => 'default value'\n              ),\n            })\n          }}\n        >\n          加载默认数据\n        </Button>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCollapse,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    string_array: {\n      type: 'array',\n      'x-component': 'ArrayCollapse',\n      'x-component-props': {\n        onAdd: (index: number) => {\n          console.log('Adding ' + index + ' item')\n        },\n      },\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      items: {\n        type: 'void',\n        'x-component': 'ArrayCollapse.CollapsePanel',\n        'x-component-props': {\n          header: '字符串数组',\n        },\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayCollapse.Addition',\n        },\n      },\n    },\n    array: {\n      type: 'array',\n      'x-component': 'ArrayCollapse',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      items: {\n        type: 'object',\n        'x-component': 'ArrayCollapse.CollapsePanel',\n        'x-component-props': {\n          header: '对象数组',\n        },\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayCollapse.Addition',\n        },\n      },\n    },\n    array_unshift: {\n      type: 'array',\n      'x-component': 'ArrayCollapse',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      items: {\n        type: 'object',\n        'x-component': 'ArrayCollapse.CollapsePanel',\n        'x-component-props': {\n          header: '对象数组',\n        },\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '添加条目(unshift)',\n          'x-component': 'ArrayCollapse.Addition',\n          'x-component-props': {\n            method: 'unshift',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## Effects 联动案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCollapse,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nconst form = createForm({\n  effects: () => {\n    //主动联动模式\n    onFieldChange('array.*.aa', ['value'], (field, form) => {\n      form.setFieldState(field.query('.bb'), (state) => {\n        state.visible = field.value != '123'\n      })\n    })\n    //被动联动模式\n    onFieldReact('array.*.dd', (field) => {\n      field.visible = field.query('.cc').get('value') != '123'\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"array\"\n          maxItems={3}\n          x-component=\"ArrayCollapse\"\n          x-decorator=\"FormItem\"\n          x-component-props={{\n            title: '对象数组',\n          }}\n        >\n          <SchemaField.Object\n            x-component=\"ArrayCollapse.CollapsePanel\"\n            x-component-props={{\n              header: '对象数组',\n            }}\n          >\n            <SchemaField.Void x-component=\"ArrayCollapse.Index\" />\n            <SchemaField.String\n              name=\"aa\"\n              x-decorator=\"FormItem\"\n              title=\"AA\"\n              required\n              description=\"AA输入123时隐藏BB\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"bb\"\n              x-decorator=\"FormItem\"\n              title=\"BB\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"cc\"\n              x-decorator=\"FormItem\"\n              title=\"CC\"\n              required\n              description=\"CC输入123时隐藏DD\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"dd\"\n              x-decorator=\"FormItem\"\n              title=\"DD\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCollapse.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveDown\" />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 联动案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCollapse,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    array: {\n      type: 'array',\n      'x-component': 'ArrayCollapse',\n      maxItems: 3,\n      title: '对象数组',\n      items: {\n        type: 'object',\n        'x-component': 'ArrayCollapse.CollapsePanel',\n        'x-component-props': {\n          header: '对象数组',\n        },\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Index',\n          },\n          aa: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'AA',\n            required: true,\n            'x-component': 'Input',\n            description: '输入123',\n          },\n          bb: {\n            type: 'string',\n            title: 'BB',\n            required: true,\n            'x-decorator': 'FormItem',\n            'x-component': 'Input',\n            'x-reactions': [\n              {\n                dependencies: ['.aa'],\n                when: \"{{$deps[0] != '123'}}\",\n                fulfill: {\n                  schema: {\n                    title: 'BB',\n                    'x-disabled': true,\n                  },\n                },\n                otherwise: {\n                  schema: {\n                    title: 'Changed',\n                    'x-disabled': false,\n                  },\n                },\n              },\n            ],\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayCollapse.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### ArrayCollapse\n\n参考 https://ant.design/components/collapse-cn/\n\n### ArrayCollapse.CollapsePanel\n\n参考 https://ant.design/components/collapse-cn/\n\n### ArrayCollapse.Addition\n\n> 添加按钮\n\n扩展属性\n\n| 属性名       | 类型                  | 描述     | 默认值   |\n| ------------ | --------------------- | -------- | -------- |\n| title        | ReactText             | 文案     |          |\n| method       | `'push' \\| 'unshift'` | 添加方式 | `'push'` |\n| defaultValue | `any`                 | 默认值   |          |\n\n其余参考 https://ant.design/components/button-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayCollapse.Remove\n\n> 删除按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayCollapse.MoveDown\n\n> 下移按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayCollapse.MoveUp\n\n> 上移按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayCollapse.Index\n\n> 索引渲染器\n\n无属性\n\n### ArrayCollapse.useIndex\n\n> 读取当前渲染行索引的 React Hook\n\n### ArrayCollapse.useRecord\n\n> 读取当前渲染记录的 React Hook\n"
  },
  {
    "path": "packages/antd/docs/components/ArrayItems.md",
    "content": "# ArrayItems\n\n> Self-increment list, suitable for simple self-increment editing scenes, or for scenes with high space requirements\n>\n> Note: This component is only applicable to Schema scenarios\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  Editable,\n  Select,\n  DatePicker,\n  ArrayItems,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    DatePicker,\n    Editable,\n    Space,\n    Input,\n    Select,\n    ArrayItems,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"string_array\"\n          title=\"string array\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayItems\"\n        >\n          <SchemaField.Void x-component=\"Space\">\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.SortHandle\"\n            />\n            <SchemaField.String\n              x-decorator=\"FormItem\"\n              required\n              name=\"input\"\n              x-component=\"Input\"\n            />\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.Remove\"\n            />\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.Copy\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"ArrayItems.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"array\"\n          title=\"Object array\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayItems\"\n        >\n          <SchemaField.Object>\n            <SchemaField.Void x-component=\"Space\">\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.SortHandle\"\n              />\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"date\"\n                name=\"date\"\n                x-component=\"DatePicker.RangePicker\"\n                x-component-props={{\n                  style: {\n                    width: 160,\n                  },\n                }}\n              />\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"input box\"\n                name=\"input\"\n                x-component=\"Input\"\n              />\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"select box\"\n                name=\"select\"\n                enum={[\n                  { label: 'Option 1', value: 1 },\n                  { label: 'Option 2', value: 2 },\n                ]}\n                x-component=\"Select\"\n                x-component-props={{\n                  style: {\n                    width: 160,\n                  },\n                }}\n              />\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.Remove\"\n              />\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayItems.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"array2\"\n          title=\"Object array\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayItems\"\n          x-component-props={{ style: { width: 300 } }}\n        >\n          <SchemaField.Object x-decorator=\"ArrayItems.Item\">\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.SortHandle\"\n            />\n            <SchemaField.String\n              x-decorator=\"Editable\"\n              title=\"input box\"\n              name=\"input\"\n              x-component=\"Input\"\n              x-component-props={{ bordered: false }}\n            />\n            <SchemaField.Object\n              name=\"config\"\n              x-component=\"Editable.Popover\"\n              required\n              title=\"Configure complex data\"\n              x-reactions={(field) => {\n                field.title = field.value?.input || field.title\n              }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"date\"\n                name=\"date\"\n                x-component=\"DatePicker.RangePicker\"\n                x-component-props={{ style: { width: '100%' } }}\n              />\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"input box\"\n                name=\"input\"\n                x-component=\"Input\"\n              />\n            </SchemaField.Object>\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.Remove\"\n            />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayItems.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Editable,\n  Input,\n  Select,\n  Radio,\n  DatePicker,\n  ArrayItems,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Editable,\n    DatePicker,\n    Space,\n    Radio,\n    Input,\n    Select,\n    ArrayItems,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    string_array: {\n      type: 'array',\n      'x-component': 'ArrayItems',\n      'x-decorator': 'FormItem',\n      title: 'String array',\n      items: {\n        type: 'void',\n        'x-component': 'Space',\n        properties: {\n          sort: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.SortHandle',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.Remove',\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n    array: {\n      type: 'array',\n      'x-component': 'ArrayItems',\n      'x-decorator': 'FormItem',\n      title: 'Object array',\n      items: {\n        type: 'object',\n        properties: {\n          space: {\n            type: 'void',\n            'x-component': 'Space',\n            properties: {\n              sort: {\n                type: 'void',\n                'x-decorator': 'FormItem',\n                'x-component': 'ArrayItems.SortHandle',\n              },\n              date: {\n                type: 'string',\n                title: 'Date',\n                'x-decorator': 'FormItem',\n                'x-component': 'DatePicker.RangePicker',\n                'x-component-props': {\n                  style: {\n                    width: 160,\n                  },\n                },\n              },\n              input: {\n                type: 'string',\n                title: 'input box',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n              select: {\n                type: 'string',\n                title: 'drop-down box',\n                enum: [\n                  { label: 'Option 1', value: 1 },\n                  { label: 'Option 2', value: 2 },\n                ],\n                'x-decorator': 'FormItem',\n                'x-component': 'Select',\n                'x-component-props': {\n                  style: {\n                    width: 160,\n                  },\n                },\n              },\n              remove: {\n                type: 'void',\n                'x-decorator': 'FormItem',\n                'x-component': 'ArrayItems.Remove',\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n    array2: {\n      type: 'array',\n      'x-component': 'ArrayItems',\n      'x-decorator': 'FormItem',\n      'x-component-props': { style: { width: 300 } },\n      title: 'Object array',\n      items: {\n        type: 'object',\n        'x-decorator': 'ArrayItems.Item',\n        properties: {\n          sort: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.SortHandle',\n          },\n\n          input: {\n            type: 'string',\n            title: 'input box',\n            'x-decorator': 'Editable',\n            'x-component': 'Input',\n            'x-component-props': {\n              bordered: false,\n            },\n          },\n          config: {\n            type: 'object',\n            title: 'Configure complex data',\n            'x-component': 'Editable.Popover',\n            'x-reactions':\n              '{{(field)=>field.title = field.value && field.value.input || field.title}}',\n            properties: {\n              date: {\n                type: 'string',\n                title: 'Date',\n                'x-decorator': 'FormItem',\n                'x-component': 'DatePicker.RangePicker',\n                'x-component-props': {\n                  style: {\n                    width: 160,\n                  },\n                },\n              },\n              input: {\n                type: 'string',\n                title: 'input box',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n              select: {\n                type: 'string',\n                title: 'drop-down box',\n                enum: [\n                  { label: 'Option 1', value: 1 },\n                  { label: 'Option 2', value: 2 },\n                ],\n                'x-decorator': 'FormItem',\n                'x-component': 'Select',\n                'x-component-props': {\n                  style: {\n                    width: 160,\n                  },\n                },\n              },\n            },\n          },\n          remove: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.Remove',\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## Effects linkage case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayItems,\n  Editable,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/antd'\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Space,\n    Editable,\n    FormItem,\n    Input,\n    ArrayItems,\n  },\n})\n\nconst form = createForm({\n  effects: () => {\n    //Active linkage mode\n    onFieldChange('array.*.aa', ['value'], (field, form) => {\n      form.setFieldState(field.query('.bb'), (state) => {\n        state.visible = field.value != '123'\n      })\n    })\n    //Passive linkage mode\n    onFieldReact('array.*.dd', (field) => {\n      field.visible = field.query('.cc').get('value') != '123'\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"array\"\n          title=\"Object array\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayItems\"\n          x-component-props={{\n            style: {\n              width: 300,\n            },\n          }}\n        >\n          <SchemaField.Object x-decorator=\"ArrayItems.Item\">\n            <SchemaField.Void x-component=\"Space\">\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.SortHandle\"\n              />\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.Index\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"Editable.Popover\"\n              title=\"Configuration data\"\n            >\n              <SchemaField.String\n                name=\"aa\"\n                x-decorator=\"FormItem\"\n                title=\"AA\"\n                required\n                description=\"AA hide BB when entering 123\"\n                x-component=\"Input\"\n              />\n              <SchemaField.String\n                name=\"bb\"\n                x-decorator=\"FormItem\"\n                title=\"BB\"\n                required\n                x-component=\"Input\"\n              />\n              <SchemaField.String\n                name=\"cc\"\n                x-decorator=\"FormItem\"\n                title=\"CC\"\n                required\n                description=\"Hide DD when CC enters 123\"\n                x-component=\"Input\"\n              />\n              <SchemaField.String\n                name=\"dd\"\n                x-decorator=\"FormItem\"\n                title=\"DD\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void x-component=\"Space\">\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.Remove\"\n              />\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.MoveUp\"\n              />\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.MoveDown\"\n              />\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayItems.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema linkage case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayItems,\n  Editable,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Space,\n    Editable,\n    FormItem,\n    Input,\n    ArrayItems,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    array: {\n      type: 'array',\n      'x-component': 'ArrayItems',\n      'x-decorator': 'FormItem',\n      maxItems: 3,\n      title: 'Object array',\n      'x-component-props': { style: { width: 300 } },\n      items: {\n        type: 'object',\n        'x-decorator': 'ArrayItems.Item',\n        properties: {\n          left: {\n            type: 'void',\n            'x-component': 'Space',\n            properties: {\n              sort: {\n                type: 'void',\n                'x-decorator': 'FormItem',\n                'x-component': 'ArrayItems.SortHandle',\n              },\n              index: {\n                type: 'void',\n                'x-decorator': 'FormItem',\n                'x-component': 'ArrayItems.Index',\n              },\n            },\n          },\n          edit: {\n            type: 'void',\n            'x-component': 'Editable.Popover',\n            title: 'Configuration data',\n            properties: {\n              aa: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                title: 'AA',\n                required: true,\n                'x-component': 'Input',\n                description: 'Enter 123',\n              },\n              bb: {\n                type: 'string',\n                title: 'BB',\n                required: true,\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-reactions': [\n                  {\n                    dependencies: ['.aa'],\n                    when: \"{{$deps[0] != '123'}}\",\n                    fulfill: {\n                      schema: {\n                        title: 'BB',\n                        'x-disabled': true,\n                      },\n                    },\n                    otherwise: {\n                      schema: {\n                        title: 'Changed',\n                        'x-disabled': false,\n                      },\n                    },\n                  },\n                ],\n              },\n            },\n          },\n          right: {\n            type: 'void',\n            'x-component': 'Space',\n            properties: {\n              remove: {\n                type: 'void',\n                'x-component': 'ArrayItems.Remove',\n              },\n              moveUp: {\n                type: 'void',\n                'x-component': 'ArrayItems.MoveUp',\n              },\n              moveDown: {\n                type: 'void',\n                'x-component': 'ArrayItems.MoveDown',\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### ArrayItems\n\nExtended attributes\n\n| Property name | Type                      | Description     | Default value |\n| ------------- | ------------------------- | --------------- | ------------- |\n| onAdd         | `(index: number) => void` | add method      |               |\n| onRemove      | `(index: number) => void` | remove method   |               |\n| onCopy        | `(index: number) => void` | copy method     |               |\n| onMoveUp      | `(index: number) => void` | moveUp method   |               |\n| onMoveDown    | `(index: number) => void` | moveDown method |               |\n\nOther Inherit HTMLDivElement Props\n\n### ArrayItems.Item\n\n> List block\n\nInherit HTMLDivElement Props\n\nExtended attributes\n\n| Property name | Type                | Description           | Default value |\n| ------------- | ------------------- | --------------------- | ------------- |\n| type          | `'card' \\|'divide'` | card or dividing line |               |\n\n### ArrayItems.SortHandle\n\n> Drag handle\n\nReference https://ant.design/components/icon-cn/\n\n### ArrayItems.Addition\n\n> Add button\n\nExtended attributes\n\n| Property name | Type                 | Description   | Default value |\n| ------------- | -------------------- | ------------- | ------------- |\n| title         | ReactText            | Copywriting   |               |\n| method        | `'push' \\|'unshift'` | add method    | `'push'`      |\n| defaultValue  | `any`                | Default value |               |\n\nOther references https://ant.design/components/button-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayItems.Copy\n\n> Copy button\n\nExtended attributes\n\n| Property name | Type                 | Description | Default value |\n| ------------- | -------------------- | ----------- | ------------- |\n| title         | ReactText            | Copywriting |               |\n| method        | `'push' \\|'unshift'` | Copy method | `'push'`      |\n\nOther references https://ant.design/components/button-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayItems.Remove\n\n> Delete button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayItems.MoveDown\n\n> Move down button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayItems.MoveUp\n\n> Move up button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayItems.Index\n\n> Index Renderer\n\nNo attributes\n\n### ArrayItems.useIndex\n\n> Read the React Hook of the current rendering row index\n\n### ArrayItems.useRecord\n\n> Read the React Hook of the current rendering row\n"
  },
  {
    "path": "packages/antd/docs/components/ArrayItems.zh-CN.md",
    "content": "# ArrayItems\n\n> 自增列表，对于简单的自增编辑场景比较适合，或者对于空间要求高的场景比较适合\n>\n> 注意：该组件只适用于 Schema 场景\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  Editable,\n  Select,\n  DatePicker,\n  ArrayItems,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    DatePicker,\n    Editable,\n    Space,\n    Input,\n    Select,\n    ArrayItems,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"string_array\"\n          title=\"字符串数组\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayItems\"\n        >\n          <SchemaField.Void x-component=\"Space\">\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.SortHandle\"\n            />\n            <SchemaField.String\n              x-decorator=\"FormItem\"\n              required\n              name=\"input\"\n              x-component=\"Input\"\n            />\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.Remove\"\n            />\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.Copy\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"ArrayItems.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"array\"\n          title=\"对象数组\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayItems\"\n        >\n          <SchemaField.Object>\n            <SchemaField.Void x-component=\"Space\">\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.SortHandle\"\n              />\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"日期\"\n                name=\"date\"\n                x-component=\"DatePicker.RangePicker\"\n                x-component-props={{\n                  style: {\n                    width: 160,\n                  },\n                }}\n              />\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"输入框\"\n                name=\"input\"\n                x-component=\"Input\"\n              />\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"选择框\"\n                name=\"select\"\n                enum={[\n                  { label: '选项1', value: 1 },\n                  { label: '选项2', value: 2 },\n                ]}\n                x-component=\"Select\"\n                x-component-props={{\n                  style: {\n                    width: 160,\n                  },\n                }}\n              />\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.Remove\"\n              />\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.Copy\"\n              />\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayItems.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"array2\"\n          title=\"对象数组\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayItems\"\n          x-component-props={{ style: { width: 300 } }}\n        >\n          <SchemaField.Object x-decorator=\"ArrayItems.Item\">\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.SortHandle\"\n            />\n            <SchemaField.String\n              x-decorator=\"Editable\"\n              title=\"输入框\"\n              name=\"input\"\n              x-component=\"Input\"\n              x-component-props={{ bordered: false }}\n            />\n            <SchemaField.Object\n              name=\"config\"\n              x-component=\"Editable.Popover\"\n              required\n              title=\"配置复杂数据\"\n              x-reactions={(field) => {\n                field.title = field.value?.input || field.title\n              }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"日期\"\n                name=\"date\"\n                x-component=\"DatePicker.RangePicker\"\n                x-component-props={{ style: { width: '100%' } }}\n              />\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"输入框\"\n                name=\"input\"\n                x-component=\"Input\"\n              />\n            </SchemaField.Object>\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.Remove\"\n            />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayItems.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Editable,\n  Input,\n  Select,\n  Radio,\n  DatePicker,\n  ArrayItems,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Editable,\n    DatePicker,\n    Space,\n    Radio,\n    Input,\n    Select,\n    ArrayItems,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    string_array: {\n      type: 'array',\n      'x-component': 'ArrayItems',\n      'x-decorator': 'FormItem',\n      title: '字符串数组',\n      items: {\n        type: 'void',\n        'x-component': 'Space',\n        properties: {\n          sort: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.SortHandle',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.Remove',\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n    array: {\n      type: 'array',\n      'x-component': 'ArrayItems',\n      'x-decorator': 'FormItem',\n      title: '对象数组',\n      items: {\n        type: 'object',\n        properties: {\n          space: {\n            type: 'void',\n            'x-component': 'Space',\n            properties: {\n              sort: {\n                type: 'void',\n                'x-decorator': 'FormItem',\n                'x-component': 'ArrayItems.SortHandle',\n              },\n              date: {\n                type: 'string',\n                title: '日期',\n                'x-decorator': 'FormItem',\n                'x-component': 'DatePicker.RangePicker',\n                'x-component-props': {\n                  style: {\n                    width: 160,\n                  },\n                },\n              },\n              input: {\n                type: 'string',\n                title: '输入框',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n              select: {\n                type: 'string',\n                title: '下拉框',\n                enum: [\n                  { label: '选项1', value: 1 },\n                  { label: '选项2', value: 2 },\n                ],\n                'x-decorator': 'FormItem',\n                'x-component': 'Select',\n                'x-component-props': {\n                  style: {\n                    width: 160,\n                  },\n                },\n              },\n              remove: {\n                type: 'void',\n                'x-decorator': 'FormItem',\n                'x-component': 'ArrayItems.Remove',\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n    array2: {\n      type: 'array',\n      'x-component': 'ArrayItems',\n      'x-decorator': 'FormItem',\n      'x-component-props': { style: { width: 300 } },\n      title: '对象数组',\n      items: {\n        type: 'object',\n        'x-decorator': 'ArrayItems.Item',\n        properties: {\n          sort: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.SortHandle',\n          },\n\n          input: {\n            type: 'string',\n            title: '输入框',\n            'x-decorator': 'Editable',\n            'x-component': 'Input',\n            'x-component-props': {\n              bordered: false,\n            },\n          },\n          config: {\n            type: 'object',\n            title: '配置复杂数据',\n            'x-component': 'Editable.Popover',\n            'x-reactions':\n              '{{(field)=>field.title = field.value && field.value.input || field.title}}',\n            properties: {\n              date: {\n                type: 'string',\n                title: '日期',\n                'x-decorator': 'FormItem',\n                'x-component': 'DatePicker.RangePicker',\n                'x-component-props': {\n                  style: {\n                    width: 160,\n                  },\n                },\n              },\n              input: {\n                type: 'string',\n                title: '输入框',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n              select: {\n                type: 'string',\n                title: '下拉框',\n                enum: [\n                  { label: '选项1', value: 1 },\n                  { label: '选项2', value: 2 },\n                ],\n                'x-decorator': 'FormItem',\n                'x-component': 'Select',\n                'x-component-props': {\n                  style: {\n                    width: 160,\n                  },\n                },\n              },\n            },\n          },\n          remove: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.Remove',\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## Effects 联动案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayItems,\n  Editable,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/antd'\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Space,\n    Editable,\n    FormItem,\n    Input,\n    ArrayItems,\n  },\n})\n\nconst form = createForm({\n  effects: () => {\n    //主动联动模式\n    onFieldChange('array.*.aa', ['value'], (field, form) => {\n      form.setFieldState(field.query('.bb'), (state) => {\n        state.visible = field.value != '123'\n      })\n    })\n    //被动联动模式\n    onFieldReact('array.*.dd', (field) => {\n      field.visible = field.query('.cc').get('value') != '123'\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"array\"\n          title=\"对象数组\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayItems\"\n          x-component-props={{\n            style: {\n              width: 300,\n            },\n          }}\n        >\n          <SchemaField.Object x-decorator=\"ArrayItems.Item\">\n            <SchemaField.Void x-component=\"Space\">\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.SortHandle\"\n              />\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.Index\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void x-component=\"Editable.Popover\" title=\"配置数据\">\n              <SchemaField.String\n                name=\"aa\"\n                x-decorator=\"FormItem\"\n                title=\"AA\"\n                required\n                description=\"AA输入123时隐藏BB\"\n                x-component=\"Input\"\n              />\n              <SchemaField.String\n                name=\"bb\"\n                x-decorator=\"FormItem\"\n                title=\"BB\"\n                required\n                x-component=\"Input\"\n              />\n              <SchemaField.String\n                name=\"cc\"\n                x-decorator=\"FormItem\"\n                title=\"CC\"\n                required\n                description=\"CC输入123时隐藏DD\"\n                x-component=\"Input\"\n              />\n              <SchemaField.String\n                name=\"dd\"\n                x-decorator=\"FormItem\"\n                title=\"DD\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void x-component=\"Space\">\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.Remove\"\n              />\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.MoveUp\"\n              />\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.MoveDown\"\n              />\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayItems.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 联动案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayItems,\n  Editable,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Space,\n    Editable,\n    FormItem,\n    Input,\n    ArrayItems,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    array: {\n      type: 'array',\n      'x-component': 'ArrayItems',\n      'x-decorator': 'FormItem',\n      maxItems: 3,\n      title: '对象数组',\n      'x-component-props': { style: { width: 300 } },\n      items: {\n        type: 'object',\n        'x-decorator': 'ArrayItems.Item',\n        properties: {\n          left: {\n            type: 'void',\n            'x-component': 'Space',\n            properties: {\n              sort: {\n                type: 'void',\n                'x-decorator': 'FormItem',\n                'x-component': 'ArrayItems.SortHandle',\n              },\n              index: {\n                type: 'void',\n                'x-decorator': 'FormItem',\n                'x-component': 'ArrayItems.Index',\n              },\n            },\n          },\n          edit: {\n            type: 'void',\n            'x-component': 'Editable.Popover',\n            title: '配置数据',\n            properties: {\n              aa: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                title: 'AA',\n                required: true,\n                'x-component': 'Input',\n                description: '输入123',\n              },\n              bb: {\n                type: 'string',\n                title: 'BB',\n                required: true,\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-reactions': [\n                  {\n                    dependencies: ['.aa'],\n                    when: \"{{$deps[0] != '123'}}\",\n                    fulfill: {\n                      schema: {\n                        title: 'BB',\n                        'x-disabled': true,\n                      },\n                    },\n                    otherwise: {\n                      schema: {\n                        title: 'Changed',\n                        'x-disabled': false,\n                      },\n                    },\n                  },\n                ],\n              },\n            },\n          },\n          right: {\n            type: 'void',\n            'x-component': 'Space',\n            properties: {\n              remove: {\n                type: 'void',\n                'x-component': 'ArrayItems.Remove',\n              },\n              moveUp: {\n                type: 'void',\n                'x-component': 'ArrayItems.MoveUp',\n              },\n              moveDown: {\n                type: 'void',\n                'x-component': 'ArrayItems.MoveDown',\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### ArrayItems\n\n扩展属性\n\n| 属性名     | 类型                      | 描述         | 默认值 |\n| ---------- | ------------------------- | ------------ | ------ |\n| onAdd      | `(index: number) => void` | 增加方法     |        |\n| onRemove   | `(index: number) => void` | 删除方法     |        |\n| onCopy     | `(index: number) => void` | 复制方法     |        |\n| onMoveUp   | `(index: number) => void` | 向上移动方法 |        |\n| onMoveDown | `(index: number) => void` | 向下移动方法 |        |\n\n其余继承 HTMLDivElement Props\n\n### ArrayItems.Item\n\n> 列表区块\n\n继承 HTMLDivElement Props\n\n扩展属性\n\n| 属性名 | 类型                 | 描述           | 默认值 |\n| ------ | -------------------- | -------------- | ------ |\n| type   | `'card' \\| 'divide'` | 卡片或者分割线 |        |\n\n### ArrayItems.SortHandle\n\n> 拖拽手柄\n\n参考 https://ant.design/components/icon-cn/\n\n### ArrayItems.Addition\n\n> 添加按钮\n\n扩展属性\n\n| 属性名       | 类型                  | 描述     | 默认值   |\n| ------------ | --------------------- | -------- | -------- |\n| title        | ReactText             | 文案     |          |\n| method       | `'push' \\| 'unshift'` | 添加方式 | `'push'` |\n| defaultValue | `any`                 | 默认值   |          |\n\n其余参考 https://ant.design/components/button-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayItems.Copy\n\n> 复制按钮\n\n扩展属性\n\n| 属性名 | 类型                  | 描述     | 默认值   |\n| ------ | --------------------- | -------- | -------- |\n| title  | ReactText             | 文案     |          |\n| method | `'push' \\| 'unshift'` | 添加方式 | `'push'` |\n\n其余参考 https://ant.design/components/button-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayItems.Remove\n\n> 删除按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayItems.MoveDown\n\n> 下移按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayItems.MoveUp\n\n> 上移按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayItems.Index\n\n> 索引渲染器\n\n无属性\n\n### ArrayItems.useIndex\n\n> 读取当前渲染行索引的 React Hook\n\n### ArrayItems.useRecord\n\n> 读取当前渲染记录的 React Hook\n"
  },
  {
    "path": "packages/antd/docs/components/ArrayTable.md",
    "content": "# ArrayTable\n\n> Self-increasing table, it is more suitable to use this component for scenes with a large amount of data. Although the amount of data is large to a certain extent, it will be a little bit stuck, but it will not affect the basic operation\n>\n> Note: This component is only applicable to Schema scenarios and can only be an array of objects\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  Editable,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button, Alert } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Editable,\n    Input,\n    ArrayTable,\n  },\n})\n\nconst form = createForm()\n\nconst range = (count: number) =>\n  Array.from(new Array(count)).map((_, key) => ({\n    aaa: key,\n  }))\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"array\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayTable\"\n          x-component-props={{\n            pagination: { pageSize: 10 },\n            scroll: { x: '100%' },\n          }}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ width: 50, title: 'Sort', align: 'center' }}\n            >\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"ArrayTable.SortHandle\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ width: 80, title: 'Index', align: 'center' }}\n            >\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"ArrayTable.Index\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'A1', dataIndex: 'a1', width: 200 }}\n            >\n              <SchemaField.String\n                name=\"a1\"\n                x-decorator=\"Editable\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'A2', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a2\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'A3', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a3\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{\n                title: 'Operations',\n                dataIndex: 'operations',\n                width: 200,\n                fixed: 'right',\n              }}\n            >\n              <SchemaField.Void x-component=\"FormItem\">\n                <SchemaField.Void x-component=\"ArrayTable.Remove\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveDown\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveUp\" />\n              </SchemaField.Void>\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayTable.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n        <Button\n          block\n          onClick={() => {\n            form.setInitialValues({\n              array: range(100000),\n            })\n          }}\n        >\n          Load 10W pieces of large data\n        </Button>\n      </FormButtonGroup>\n      <Alert\n        style={{ marginTop: 10 }}\n        message=\"Note: Open the formily plug-in page, because there is data communication in the background, which will occupy the browser's computing power, it is best to test in the incognito mode (no formily plug-in)\"\n        type=\"warning\"\n      />\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  Editable,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Editable,\n    Input,\n    ArrayTable,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    array: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'ArrayTable',\n      'x-component-props': {\n        pagination: { pageSize: 10 },\n        scroll: { x: '100%' },\n      },\n      items: {\n        type: 'object',\n        properties: {\n          column1: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 50, title: 'Sort', align: 'center' },\n            properties: {\n              sort: {\n                type: 'void',\n                'x-component': 'ArrayTable.SortHandle',\n              },\n            },\n          },\n          column2: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 80, title: 'Index', align: 'center' },\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayTable.Index',\n              },\n            },\n          },\n          column3: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A1' },\n            properties: {\n              a1: {\n                type: 'string',\n                'x-decorator': 'Editable',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column4: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A2' },\n            properties: {\n              a2: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column5: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A3' },\n            properties: {\n              a3: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column6: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              title: 'Operations',\n              dataIndex: 'operations',\n              width: 200,\n              fixed: 'right',\n            },\n            properties: {\n              item: {\n                type: 'void',\n                'x-component': 'FormItem',\n                properties: {\n                  remove: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.Remove',\n                  },\n                  moveDown: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveDown',\n                  },\n                  moveUp: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveUp',\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          'x-component': 'ArrayTable.Addition',\n          title: 'Add entry',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## Effects linkage case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  Switch,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Switch,\n    Input,\n    Button,\n    ArrayTable,\n  },\n})\n\nconst form = createForm({\n  effects: () => {\n    //Active linkage mode\n    onFieldChange('hideFirstColumn', ['value'], (field) => {\n      field.query('array.column4').take((target) => {\n        target.visible = !field.value\n      })\n      field.query('array.*.a2').take((target) => {\n        target.visible = !field.value\n      })\n    })\n    //Passive linkage mode\n    onFieldReact('array.*.a2', (field) => {\n      field.visible = !field.query('.a1').get('value')\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Boolean\n          name=\"hideFirstColumn\"\n          x-decorator=\"FormItem\"\n          x-component=\"Switch\"\n          title=\"Hide A2\"\n        />\n        <SchemaField.Array\n          name=\"array\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayTable\"\n          x-component-props={{\n            pagination: { pageSize: 10 },\n            scroll: { x: '100%' },\n          }}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column1\"\n              x-component-props={{ width: 50, title: 'Sort', align: 'center' }}\n            >\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"ArrayTable.SortHandle\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column2\"\n              x-component-props={{ width: 80, title: 'Index', align: 'center' }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"ArrayTable.Index\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column3\"\n              x-component-props={{\n                title: 'Explicitly hidden->A2',\n                dataIndex: 'a1',\n                width: 100,\n              }}\n            >\n              <SchemaField.Boolean\n                name=\"a1\"\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"Switch\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column4\"\n              x-component-props={{ title: 'A2', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a2\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column5\"\n              x-component-props={{ title: 'A3', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a3\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column6\"\n              x-component-props={{\n                title: 'Operations',\n                dataIndex: 'operations',\n                width: 200,\n                fixed: 'right',\n              }}\n            >\n              <SchemaField.Void x-component=\"FormItem\">\n                <SchemaField.Void x-component=\"ArrayTable.Remove\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveDown\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveUp\" />\n              </SchemaField.Void>\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayTable.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema linkage case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  Switch,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Switch,\n    Input,\n    ArrayTable,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    hideFirstColumn: {\n      type: 'boolean',\n      title: 'Hide A2',\n      'x-decorator': 'FormItem',\n      'x-component': 'Switch',\n    },\n    array: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'ArrayTable',\n      'x-component-props': {\n        pagination: { pageSize: 10 },\n        scroll: { x: '100%' },\n      },\n      items: {\n        type: 'object',\n        properties: {\n          column1: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 50, title: 'Sort', align: 'center' },\n\n            properties: {\n              sort: {\n                type: 'void',\n                'x-component': 'ArrayTable.SortHandle',\n              },\n            },\n          },\n          column2: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 80, title: 'Index', align: 'center' },\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayTable.Index',\n              },\n            },\n          },\n          column3: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 100, title: 'Explicitly hidden->A2' },\n            properties: {\n              a1: {\n                type: 'boolean',\n                'x-decorator': 'FormItem',\n                'x-component': 'Switch',\n              },\n            },\n          },\n          column4: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A2' },\n            'x-reactions': [\n              {\n                dependencies: ['hideFirstColumn'],\n                when: '{{$deps[0]}}',\n                fulfill: {\n                  schema: {\n                    'x-visible': false,\n                  },\n                },\n                otherwise: {\n                  schema: {\n                    'x-visible': true,\n                  },\n                },\n              },\n            ],\n            properties: {\n              a2: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                required: true,\n                'x-reactions': [\n                  {\n                    dependencies: ['.a1', 'hideFirstColumn'],\n                    when: '{{$deps[1] || $deps[0]}}',\n                    fulfill: {\n                      schema: {\n                        'x-visible': false,\n                      },\n                    },\n                    otherwise: {\n                      schema: {\n                        'x-visible': true,\n                      },\n                    },\n                  },\n                ],\n              },\n            },\n          },\n          column5: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A3' },\n            properties: {\n              a3: {\n                type: 'string',\n                required: true,\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column6: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              title: 'Operations',\n              dataIndex: 'operations',\n              width: 200,\n              fixed: 'right',\n            },\n            properties: {\n              item: {\n                type: 'void',\n                'x-component': 'FormItem',\n                properties: {\n                  remove: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.Remove',\n                  },\n                  moveDown: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveDown',\n                  },\n                  moveUp: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveUp',\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          'x-component': 'ArrayTable.Addition',\n          title: 'Add entry',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## Overwrite default behavior of build-in operations\n\n```tsx\n/**\n * title: Markup Schema\n */\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { message } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"array\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayTable\"\n          x-component-props={{\n            pagination: { pageSize: 10 },\n            scroll: { x: '100%' },\n          }}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ width: 80, title: 'Index', align: 'center' }}\n            >\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"ArrayTable.Index\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'A1', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a1\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'A2', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a2\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{\n                title: 'Operations',\n                dataIndex: 'operations',\n                width: 200,\n                fixed: 'right',\n              }}\n            >\n              <SchemaField.Void x-component=\"FormItem\">\n                <SchemaField.Void\n                  x-component=\"ArrayTable.Remove\"\n                  x-component-props={{\n                    onClick: (e) => {\n                      e.preventDefault()\n                      message.info('remove is disabled!')\n                    },\n                  }}\n                />\n                <SchemaField.Void\n                  x-component=\"ArrayTable.Copy\"\n                  x-component-props={{\n                    onClick: (e) => {\n                      e.preventDefault()\n                      message.info('copy is disabled!')\n                    },\n                  }}\n                />\n                <SchemaField.Void\n                  x-component=\"ArrayTable.MoveDown\"\n                  x-component-props={{\n                    onClick: (e) => {\n                      e.preventDefault()\n                      message.info('moveDown is disabled!')\n                    },\n                  }}\n                />\n                <SchemaField.Void\n                  x-component=\"ArrayTable.MoveUp\"\n                  x-component-props={{\n                    onClick: (e) => {\n                      e.preventDefault()\n                      message.info('moveUp is disabled!')\n                    },\n                  }}\n                />\n              </SchemaField.Void>\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayTable.Addition\"\n            x-component-props={{\n              onClick: (e) => {\n                e.preventDefault()\n                const base = form.values.array.length\n                form.values.array.push(\n                  { a1: base + 1 },\n                  { a1: base + 2, a2: base + 2 }\n                )\n              },\n            }}\n            title=\"Add two entries\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n```tsx\n/**\n * title: JSON Schema\n */\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm, onFieldMount } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { message } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayTable,\n  },\n})\n\nconst form = createForm({\n  effects() {\n    onFieldMount('array.add', (field, form) => {\n      field.componentProps.onClick = (e) => {\n        e.preventDefault()\n        const base = form.values.array.length\n        form.values.array.push({ a1: base + 1 }, { a1: base + 2, a2: base + 2 })\n      }\n    })\n\n    onFieldMount('array.*[0:].item.*', (field) => {\n      field.componentProps.onClick = (e) => {\n        e.preventDefault()\n        message.info(`${field.address.segments.slice(-1)[0]} is disabled!`)\n      }\n    })\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    array: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'ArrayTable',\n      'x-component-props': {\n        pagination: { pageSize: 10 },\n        scroll: { x: '100%' },\n      },\n      items: {\n        type: 'object',\n        properties: {\n          column1: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 80, title: 'Index', align: 'center' },\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayTable.Index',\n              },\n            },\n          },\n          column2: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A1' },\n            properties: {\n              a1: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column3: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A2' },\n            properties: {\n              a2: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column4: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              title: 'Operations',\n              dataIndex: 'operations',\n              width: 200,\n              fixed: 'right',\n            },\n            properties: {\n              item: {\n                type: 'void',\n                'x-component': 'FormItem',\n                properties: {\n                  remove: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.Remove',\n                  },\n                  moveDown: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveDown',\n                  },\n                  moveUp: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveUp',\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          'x-component': 'ArrayTable.Addition',\n          title: 'Add two entries',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### ArrayTable\n\n> Form Components\n\nExtended attributes\n\n| Property name | Type                      | Description     | Default value |\n| ------------- | ------------------------- | --------------- | ------------- |\n| onAdd         | `(index: number) => void` | add method      |               |\n| onRemove      | `(index: number) => void` | remove method   |               |\n| onCopy        | `(index: number) => void` | copy method     |               |\n| onMoveUp      | `(index: number) => void` | moveUp method   |               |\n| onMoveDown    | `(index: number) => void` | moveDown method |               |\n\nOther Reference https://ant.design/components/table-cn/\n\n### ArrayTable.Column\n\n> Table Column\n\nReference https://ant.design/components/table-cn/\n\n### ArrayTable.SortHandle\n\n> Drag handle\n\nReference https://ant.design/components/icon-cn/\n\n### ArrayTable.Addition\n\n> Add button\n\nExtended attributes\n\n| Property name | Type                 | Description   | Default value |\n| ------------- | -------------------- | ------------- | ------------- |\n| title         | ReactText            | Copywriting   |               |\n| method        | `'push' \\|'unshift'` | add method    | `'push'`      |\n| defaultValue  | `any`                | Default value |               |\n\nOther references https://ant.design/components/button-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayTable.Remove\n\n> Delete button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayTable.Copy\n\n> Copy button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayTable.MoveDown\n\n> Move down button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayTable.MoveUp\n\n> Move up button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\nNote: You can disable default behavior with `onClick={e => e.preventDefault()}` in props.\n\n### ArrayTable.Index\n\n> Index Renderer\n\nNo attributes\n\n### ArrayTable.useIndex\n\n> Read the React Hook of the current rendering row index\n\n### ArrayTable.useRecord\n\n> Read the React Hook of the current rendering row\n"
  },
  {
    "path": "packages/antd/docs/components/ArrayTable.zh-CN.md",
    "content": "# ArrayTable\n\n> 自增表格，对于数据量超大的场景比较适合使用该组件，虽然数据量大到一定程度会有些许卡顿，但是不会影响基本操作\n>\n> 注意：该组件只适用于 Schema 场景，且只能是对象数组\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  Editable,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button, Alert } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Editable,\n    Input,\n    ArrayTable,\n  },\n})\n\nconst form = createForm()\n\nconst range = (count: number) =>\n  Array.from(new Array(count)).map((_, key) => ({\n    aaa: key,\n  }))\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"array\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayTable\"\n          x-component-props={{\n            pagination: { pageSize: 10 },\n            scroll: { x: '100%' },\n          }}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ width: 50, title: 'Sort', align: 'center' }}\n            >\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"ArrayTable.SortHandle\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ width: 80, title: 'Index', align: 'center' }}\n            >\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"ArrayTable.Index\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'A1', dataIndex: 'a1', width: 200 }}\n            >\n              <SchemaField.String\n                name=\"a1\"\n                x-decorator=\"Editable\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'A2', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a2\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'A3', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a3\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{\n                title: 'Operations',\n                dataIndex: 'operations',\n                width: 200,\n                fixed: 'right',\n              }}\n            >\n              <SchemaField.Void x-component=\"FormItem\">\n                <SchemaField.Void x-component=\"ArrayTable.Remove\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveDown\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveUp\" />\n              </SchemaField.Void>\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayTable.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n        <Button\n          block\n          onClick={() => {\n            form.setInitialValues({\n              array: range(100000),\n            })\n          }}\n        >\n          加载10W条超大数据\n        </Button>\n      </FormButtonGroup>\n      <Alert\n        style={{ marginTop: 10 }}\n        message=\"注意：开启formily插件的页面，因为后台有数据通信，会占用浏览器算力，最好在无痕模式(无formily插件)下测试\"\n        type=\"warning\"\n      />\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  Editable,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Editable,\n    Input,\n    ArrayTable,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    array: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'ArrayTable',\n      'x-component-props': {\n        pagination: { pageSize: 10 },\n        scroll: { x: '100%' },\n      },\n      items: {\n        type: 'object',\n        properties: {\n          column1: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 50, title: 'Sort', align: 'center' },\n            properties: {\n              sort: {\n                type: 'void',\n                'x-component': 'ArrayTable.SortHandle',\n              },\n            },\n          },\n          column2: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 80, title: 'Index', align: 'center' },\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayTable.Index',\n              },\n            },\n          },\n          column3: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A1' },\n            properties: {\n              a1: {\n                type: 'string',\n                'x-decorator': 'Editable',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column4: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A2' },\n            properties: {\n              a2: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column5: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A3' },\n            properties: {\n              a3: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column6: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              title: 'Operations',\n              dataIndex: 'operations',\n              width: 200,\n              fixed: 'right',\n            },\n            properties: {\n              item: {\n                type: 'void',\n                'x-component': 'FormItem',\n                properties: {\n                  remove: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.Remove',\n                  },\n                  moveDown: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveDown',\n                  },\n                  moveUp: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveUp',\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          'x-component': 'ArrayTable.Addition',\n          title: '添加条目',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## Effects 联动案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  Switch,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Switch,\n    Input,\n    Button,\n    ArrayTable,\n  },\n})\n\nconst form = createForm({\n  effects: () => {\n    //主动联动模式\n    onFieldChange('hideFirstColumn', ['value'], (field) => {\n      field.query('array.column4').take((target) => {\n        target.visible = !field.value\n      })\n      field.query('array.*.a2').take((target) => {\n        target.visible = !field.value\n      })\n    })\n    //被动联动模式\n    onFieldReact('array.*.a2', (field) => {\n      field.visible = !field.query('.a1').get('value')\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Boolean\n          name=\"hideFirstColumn\"\n          x-decorator=\"FormItem\"\n          x-component=\"Switch\"\n          title=\"隐藏A2\"\n        />\n        <SchemaField.Array\n          name=\"array\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayTable\"\n          x-component-props={{\n            pagination: { pageSize: 10 },\n            scroll: { x: '100%' },\n          }}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column1\"\n              x-component-props={{ width: 50, title: 'Sort', align: 'center' }}\n            >\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"ArrayTable.SortHandle\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column2\"\n              x-component-props={{ width: 80, title: 'Index', align: 'center' }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"ArrayTable.Index\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column3\"\n              x-component-props={{\n                title: '显隐->A2',\n                dataIndex: 'a1',\n                width: 100,\n              }}\n            >\n              <SchemaField.Boolean\n                name=\"a1\"\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"Switch\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column4\"\n              x-component-props={{ title: 'A2', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a2\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column5\"\n              x-component-props={{ title: 'A3', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a3\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column6\"\n              x-component-props={{\n                title: 'Operations',\n                dataIndex: 'operations',\n                width: 200,\n                fixed: 'right',\n              }}\n            >\n              <SchemaField.Void x-component=\"FormItem\">\n                <SchemaField.Void x-component=\"ArrayTable.Remove\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveDown\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveUp\" />\n              </SchemaField.Void>\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayTable.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 联动案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  Switch,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Switch,\n    Input,\n    ArrayTable,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    hideFirstColumn: {\n      type: 'boolean',\n      title: '隐藏A2',\n      'x-decorator': 'FormItem',\n      'x-component': 'Switch',\n    },\n    array: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'ArrayTable',\n      'x-component-props': {\n        pagination: { pageSize: 10 },\n        scroll: { x: '100%' },\n      },\n      items: {\n        type: 'object',\n        properties: {\n          column1: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 50, title: 'Sort', align: 'center' },\n\n            properties: {\n              sort: {\n                type: 'void',\n                'x-component': 'ArrayTable.SortHandle',\n              },\n            },\n          },\n          column2: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 80, title: 'Index', align: 'center' },\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayTable.Index',\n              },\n            },\n          },\n          column3: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 100, title: '显隐->A2' },\n            properties: {\n              a1: {\n                type: 'boolean',\n                'x-decorator': 'FormItem',\n                'x-component': 'Switch',\n              },\n            },\n          },\n          column4: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A2' },\n            'x-reactions': [\n              {\n                dependencies: ['hideFirstColumn'],\n                when: '{{$deps[0]}}',\n                fulfill: {\n                  schema: {\n                    'x-visible': false,\n                  },\n                },\n                otherwise: {\n                  schema: {\n                    'x-visible': true,\n                  },\n                },\n              },\n            ],\n            properties: {\n              a2: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                required: true,\n                'x-reactions': [\n                  {\n                    dependencies: ['.a1', 'hideFirstColumn'],\n                    when: '{{$deps[1] || $deps[0]}}',\n                    fulfill: {\n                      schema: {\n                        'x-visible': false,\n                      },\n                    },\n                    otherwise: {\n                      schema: {\n                        'x-visible': true,\n                      },\n                    },\n                  },\n                ],\n              },\n            },\n          },\n          column5: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A3' },\n            properties: {\n              a3: {\n                type: 'string',\n                required: true,\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column6: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              title: 'Operations',\n              dataIndex: 'operations',\n              width: 200,\n              fixed: 'right',\n            },\n            properties: {\n              item: {\n                type: 'void',\n                'x-component': 'FormItem',\n                properties: {\n                  remove: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.Remove',\n                  },\n                  moveDown: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveDown',\n                  },\n                  moveUp: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveUp',\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          'x-component': 'ArrayTable.Addition',\n          title: '添加条目',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## 重写内置操作项的默认行为\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { message } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"array\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayTable\"\n          x-component-props={{\n            pagination: { pageSize: 10 },\n            scroll: { x: '100%' },\n          }}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ width: 80, title: 'Index', align: 'center' }}\n            >\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"ArrayTable.Index\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'A1', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a1\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'A2', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a2\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{\n                title: 'Operations',\n                dataIndex: 'operations',\n                width: 200,\n                fixed: 'right',\n              }}\n            >\n              <SchemaField.Void x-component=\"FormItem\">\n                <SchemaField.Void\n                  x-component=\"ArrayTable.Remove\"\n                  x-component-props={{\n                    onClick: (e) => {\n                      e.preventDefault()\n                      message.info('remove 已被禁用!')\n                    },\n                  }}\n                />\n                <SchemaField.Void\n                  x-component=\"ArrayTable.Copy\"\n                  x-component-props={{\n                    onClick: (e) => {\n                      e.preventDefault()\n                      message.info('copy 已被禁用!')\n                    },\n                  }}\n                />\n                <SchemaField.Void\n                  x-component=\"ArrayTable.MoveDown\"\n                  x-component-props={{\n                    onClick: (e) => {\n                      e.preventDefault()\n                      message.info('moveDown 已被禁用!')\n                    },\n                  }}\n                />\n                <SchemaField.Void\n                  x-component=\"ArrayTable.MoveUp\"\n                  x-component-props={{\n                    onClick: (e) => {\n                      e.preventDefault()\n                      message.info('moveUp 已被禁用!')\n                    },\n                  }}\n                />\n              </SchemaField.Void>\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayTable.Addition\"\n            x-component-props={{\n              onClick: (e) => {\n                e.preventDefault()\n                const base = form.values.array.length\n                form.values.array.push(\n                  { a1: base + 1 },\n                  { a1: base + 2, a2: base + 2 }\n                )\n              },\n            }}\n            title=\"添加2个条目\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n```tsx\n/**\n * title: JSON Schema\n */\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm, onFieldMount } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { message } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayTable,\n  },\n})\n\nconst form = createForm({\n  effects() {\n    onFieldMount('array.add', (field, form) => {\n      field.componentProps.onClick = (e) => {\n        e.preventDefault()\n        const base = form.values.array.length\n        form.values.array.push({ a1: base + 1 }, { a1: base + 2, a2: base + 2 })\n      }\n    })\n\n    onFieldMount('array.*[0:].item.*', (field) => {\n      field.componentProps.onClick = (e) => {\n        e.preventDefault()\n        message.info(`${field.address.segments.slice(-1)[0]} 已被禁用!`)\n      }\n    })\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    array: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'ArrayTable',\n      'x-component-props': {\n        pagination: { pageSize: 10 },\n        scroll: { x: '100%' },\n      },\n      items: {\n        type: 'object',\n        properties: {\n          column1: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 80, title: 'Index', align: 'center' },\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayTable.Index',\n              },\n            },\n          },\n          column2: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A1' },\n            properties: {\n              a1: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column3: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A2' },\n            properties: {\n              a2: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column4: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              title: 'Operations',\n              dataIndex: 'operations',\n              width: 200,\n              fixed: 'right',\n            },\n            properties: {\n              item: {\n                type: 'void',\n                'x-component': 'FormItem',\n                properties: {\n                  remove: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.Remove',\n                  },\n                  copy: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.Copy',\n                  },\n                  moveDown: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveDown',\n                  },\n                  moveUp: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveUp',\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          'x-component': 'ArrayTable.Addition',\n          title: '添加2个条目',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### ArrayTable\n\n> 表格组件\n\n扩展属性\n\n| 属性名     | 类型                      | 描述         | 默认值 |\n| ---------- | ------------------------- | ------------ | ------ |\n| onAdd      | `(index: number) => void` | 增加方法     |        |\n| onRemove   | `(index: number) => void` | 删除方法     |        |\n| onCopy     | `(index: number) => void` | 复制方法     |        |\n| onMoveUp   | `(index: number) => void` | 向上移动方法 |        |\n| onMoveDown | `(index: number) => void` | 向下移动方法 |        |\n\n其余参考 https://ant.design/components/table-cn/\n\n### ArrayTable.Column\n\n> 表格列\n\n参考 https://ant.design/components/table-cn/\n\n### ArrayTable.SortHandle\n\n> 拖拽手柄\n\n参考 https://ant.design/components/icon-cn/\n\n### ArrayTable.Addition\n\n> 添加按钮\n\n扩展属性\n\n| 属性名       | 类型                  | 描述     | 默认值   |\n| ------------ | --------------------- | -------- | -------- |\n| title        | ReactText             | 文案     |          |\n| method       | `'push' \\| 'unshift'` | 添加方式 | `'push'` |\n| defaultValue | `any`                 | 默认值   |          |\n\n其余参考 https://ant.design/components/button-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayTable.Remove\n\n> 删除按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayTable.Copy\n\n> 复制按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayTable.MoveDown\n\n> 下移按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayTable.MoveUp\n\n> 上移按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n注意：使用`onClick={e => e.preventDefault()}`可禁用默认行为。\n\n### ArrayTable.Index\n\n> 索引渲染器\n\n无属性\n\n### ArrayTable.useIndex\n\n> 读取当前渲染行索引的 React Hook\n\n### ArrayTable.useRecord\n\n> 读取当前渲染记录的 React Hook\n"
  },
  {
    "path": "packages/antd/docs/components/ArrayTabs.md",
    "content": "# ArrayTabs\n\n> Self-increasing tab, you can consider using this component for scenarios with high vertical space requirements\n>\n> Note: This component is only applicable to Schema scenarios, please avoid cross-tab linkage in interaction\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTabs,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayTabs,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"string_array\"\n          x-decorator=\"FormItem\"\n          title=\"string array\"\n          maxItems={3}\n          x-component=\"ArrayTabs\"\n        >\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"array\"\n          x-decorator=\"FormItem\"\n          title=\"Object array\"\n          maxItems={3}\n          x-component=\"ArrayTabs\"\n        >\n          <SchemaField.Object>\n            <SchemaField.String\n              x-decorator=\"FormItem\"\n              title=\"AAA\"\n              name=\"aaa\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              x-decorator=\"FormItem\"\n              title=\"BBB\"\n              name=\"bbb\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Object>\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTabs,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayTabs,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    string_array: {\n      type: 'array',\n      title: 'String array',\n      'x-decorator': 'FormItem',\n      maxItems: 3,\n      'x-component': 'ArrayTabs',\n      items: {\n        type: 'string',\n        'x-decorator': 'FormItem',\n        required: true,\n        'x-component': 'Input',\n      },\n    },\n    array: {\n      type: 'array',\n      title: 'Object array',\n      'x-decorator': 'FormItem',\n      maxItems: 3,\n      'x-component': 'ArrayTabs',\n      items: {\n        type: 'object',\n        properties: {\n          aaa: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'AAA',\n            required: true,\n            'x-component': 'Input',\n          },\n          bbb: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'BBB',\n            required: true,\n            'x-component': 'Input',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### ArrayTabs\n\nReference https://ant.design/components/tabs-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/ArrayTabs.zh-CN.md",
    "content": "# ArrayTabs\n\n> 自增选项卡，对于纵向空间要求较高的场景可以考虑使用该组件\n>\n> 注意：该组件只适用于 Schema 场景，交互上请避免跨 Tab 联动\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTabs,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayTabs,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"string_array\"\n          x-decorator=\"FormItem\"\n          title=\"字符串数组\"\n          maxItems={3}\n          x-component=\"ArrayTabs\"\n        >\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"array\"\n          x-decorator=\"FormItem\"\n          title=\"对象数组\"\n          maxItems={3}\n          x-component=\"ArrayTabs\"\n        >\n          <SchemaField.Object>\n            <SchemaField.String\n              x-decorator=\"FormItem\"\n              title=\"AAA\"\n              name=\"aaa\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              x-decorator=\"FormItem\"\n              title=\"BBB\"\n              name=\"bbb\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Object>\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTabs,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayTabs,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    string_array: {\n      type: 'array',\n      title: '字符串数组',\n      'x-decorator': 'FormItem',\n      maxItems: 3,\n      'x-component': 'ArrayTabs',\n      items: {\n        type: 'string',\n        'x-decorator': 'FormItem',\n        required: true,\n        'x-component': 'Input',\n      },\n    },\n    array: {\n      type: 'array',\n      title: '对象数组',\n      'x-decorator': 'FormItem',\n      maxItems: 3,\n      'x-component': 'ArrayTabs',\n      items: {\n        type: 'object',\n        properties: {\n          aaa: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'AAA',\n            required: true,\n            'x-component': 'Input',\n          },\n          bbb: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'BBB',\n            required: true,\n            'x-component': 'Input',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### ArrayTabs\n\n参考 https://ant.design/components/tabs-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Cascader.md",
    "content": "# Cascader\n\n> Cascade selector\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm, onFieldReact, FormPathPattern } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Cascader,\n    FormItem,\n  },\n})\n\nconst useAddress = (pattern: FormPathPattern) => {\n  const transform = (data = {}) => {\n    return Object.entries(data).reduce((buf, [key, value]) => {\n      if (typeof value === 'string')\n        return buf.concat({\n          label: value,\n          value: key,\n        })\n      const { name, code, cities, districts } = value\n      const _cities = transform(cities)\n      const _districts = transform(districts)\n      return buf.concat({\n        label: name,\n        value: code,\n        children: _cities.length\n          ? _cities\n          : _districts.length\n          ? _districts\n          : undefined,\n      })\n    }, [])\n  }\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    fetch('//unpkg.com/china-location/dist/location.json')\n      .then((res) => res.json())\n      .then(\n        action.bound((data) => {\n          field.dataSource = transform(data)\n          field.loading = false\n        })\n      )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAddress('address')\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"address\"\n        title=\"Address Selection\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Cascader\"\n        x-component-props={{\n          style: {\n            width: 240,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Cascader,\n    FormItem,\n  },\n})\n\nconst transformAddress = (data = {}) => {\n  return Object.entries(data).reduce((buf, [key, value]) => {\n    if (typeof value === 'string')\n      return buf.concat({\n        label: value,\n        value: key,\n      })\n    const { name, code, cities, districts } = value\n    const _cities = transformAddress(cities)\n    const _districts = transformAddress(districts)\n    return buf.concat({\n      label: name,\n      value: code,\n      children: _cities.length\n        ? _cities\n        : _districts.length\n        ? _districts\n        : undefined,\n    })\n  }, [])\n}\n\nconst useAsyncDataSource =\n  (url: string, transform: (data: any) => any) => (field) => {\n    field.loading = true\n    fetch(url)\n      .then((res) => res.json())\n      .then(\n        action.bound((data) => {\n          field.dataSource = transform(data)\n          field.loading = false\n        })\n      )\n  }\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    address: {\n      type: 'string',\n      title: 'Address Selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'Cascader',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n      'x-reactions': [\n        '{{useAsyncDataSource(\"//unpkg.com/china-location/dist/location.json\",transformAddress)}}',\n      ],\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField\n      schema={schema}\n      scope={{ useAsyncDataSource, transformAddress }}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm, onFieldReact, FormPathPattern } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst useAddress = (pattern: FormPathPattern) => {\n  const transform = (data = {}) => {\n    return Object.entries(data).reduce((buf, [key, value]) => {\n      if (typeof value === 'string')\n        return buf.concat({\n          label: value,\n          value: key,\n        })\n      const { name, code, cities, districts } = value\n      const _cities = transform(cities)\n      const _districts = transform(districts)\n      return buf.concat({\n        label: name,\n        value: code,\n        children: _cities.length\n          ? _cities\n          : _districts.length\n          ? _districts\n          : undefined,\n      })\n    }, [])\n  }\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    fetch('//unpkg.com/china-location/dist/location.json')\n      .then((res) => res.json())\n      .then(\n        action.bound((data) => {\n          field.dataSource = transform(data)\n          field.loading = false\n        })\n      )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAddress('address')\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"address\"\n      title=\"Address Selection\"\n      decorator={[FormItem]}\n      component={[\n        Cascader,\n        {\n          style: {\n            width: 240,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://ant.design/components/cascader-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Cascader.zh-CN.md",
    "content": "# Cascader\n\n> 联级选择器\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm, onFieldReact, FormPathPattern } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Cascader,\n    FormItem,\n  },\n})\n\nconst useAddress = (pattern: FormPathPattern) => {\n  const transform = (data = {}) => {\n    return Object.entries(data).reduce((buf, [key, value]) => {\n      if (typeof value === 'string')\n        return buf.concat({\n          label: value,\n          value: key,\n        })\n      const { name, code, cities, districts } = value\n      const _cities = transform(cities)\n      const _districts = transform(districts)\n      return buf.concat({\n        label: name,\n        value: code,\n        children: _cities.length\n          ? _cities\n          : _districts.length\n          ? _districts\n          : undefined,\n      })\n    }, [])\n  }\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    fetch('//unpkg.com/china-location/dist/location.json')\n      .then((res) => res.json())\n      .then(\n        action.bound((data) => {\n          field.dataSource = transform(data)\n          field.loading = false\n        })\n      )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAddress('address')\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"address\"\n        title=\"地址选择\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Cascader\"\n        x-component-props={{\n          style: {\n            width: 240,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Cascader,\n    FormItem,\n  },\n})\n\nconst transformAddress = (data = {}) => {\n  return Object.entries(data).reduce((buf, [key, value]) => {\n    if (typeof value === 'string')\n      return buf.concat({\n        label: value,\n        value: key,\n      })\n    const { name, code, cities, districts } = value\n    const _cities = transformAddress(cities)\n    const _districts = transformAddress(districts)\n    return buf.concat({\n      label: name,\n      value: code,\n      children: _cities.length\n        ? _cities\n        : _districts.length\n        ? _districts\n        : undefined,\n    })\n  }, [])\n}\n\nconst useAsyncDataSource =\n  (url: string, transform: (data: any) => any) => (field) => {\n    field.loading = true\n    fetch(url)\n      .then((res) => res.json())\n      .then(\n        action.bound((data) => {\n          field.dataSource = transform(data)\n          field.loading = false\n        })\n      )\n  }\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    address: {\n      type: 'string',\n      title: '地址选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'Cascader',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n      'x-reactions': [\n        '{{useAsyncDataSource(\"//unpkg.com/china-location/dist/location.json\",transformAddress)}}',\n      ],\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField\n      schema={schema}\n      scope={{ useAsyncDataSource, transformAddress }}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm, onFieldReact, FormPathPattern } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst useAddress = (pattern: FormPathPattern) => {\n  const transform = (data = {}) => {\n    return Object.entries(data).reduce((buf, [key, value]) => {\n      if (typeof value === 'string')\n        return buf.concat({\n          label: value,\n          value: key,\n        })\n      const { name, code, cities, districts } = value\n      const _cities = transform(cities)\n      const _districts = transform(districts)\n      return buf.concat({\n        label: name,\n        value: code,\n        children: _cities.length\n          ? _cities\n          : _districts.length\n          ? _districts\n          : undefined,\n      })\n    }, [])\n  }\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    fetch('//unpkg.com/china-location/dist/location.json')\n      .then((res) => res.json())\n      .then(\n        action.bound((data) => {\n          field.dataSource = transform(data)\n          field.loading = false\n        })\n      )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAddress('address')\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"address\"\n      title=\"地址选择\"\n      decorator={[FormItem]}\n      component={[\n        Cascader,\n        {\n          style: {\n            width: 240,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://ant.design/components/cascader-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Checkbox.md",
    "content": "# Checkbox\n\n> Checkbox\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Checkbox,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Boolean\n        name=\"single\"\n        title=\"Are you sure\"\n        x-decorator=\"FormItem\"\n        x-component=\"Checkbox\"\n      />\n      <SchemaField.String\n        name=\"multiple\"\n        title=\"Check\"\n        enum={[\n          {\n            label: 'Option 1',\n            value: 1,\n          },\n          {\n            label: 'Option 2',\n            value: 2,\n          },\n        ]}\n        x-decorator=\"FormItem\"\n        x-component=\"Checkbox.Group\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Checkbox,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    single: {\n      type: 'boolean',\n      title: 'Are you sure?',\n      'x-decorator': 'FormItem',\n      'x-component': 'Checkbox',\n    },\n    multiple: {\n      type: 'array',\n      title: 'Check',\n      enum: [\n        {\n          label: 'Option 1',\n          value: 1,\n        },\n        {\n          label: 'Option 2',\n          value: 2,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Checkbox.Group',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"single\"\n      title=\"Are you sure\"\n      decorator={[FormItem]}\n      component={[Checkbox]}\n    />\n    <Field\n      name=\"multiple\"\n      title=\"Check\"\n      dataSource={[\n        {\n          label: 'Option 1',\n          value: 1,\n        },\n        {\n          label: 'Option 2',\n          value: 2,\n        },\n      ]}\n      decorator={[FormItem]}\n      component={[Checkbox.Group]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://ant.design/components/checkbox-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Checkbox.zh-CN.md",
    "content": "# Checkbox\n\n> 复选框\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Checkbox,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Boolean\n        name=\"single\"\n        title=\"是否确认\"\n        x-decorator=\"FormItem\"\n        x-component=\"Checkbox\"\n      />\n      <SchemaField.String\n        name=\"multiple\"\n        title=\"复选\"\n        enum={[\n          {\n            label: '选项1',\n            value: 1,\n          },\n          {\n            label: '选项2',\n            value: 2,\n          },\n        ]}\n        x-decorator=\"FormItem\"\n        x-component=\"Checkbox.Group\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Checkbox,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    single: {\n      type: 'boolean',\n      title: '是否确认',\n      'x-decorator': 'FormItem',\n      'x-component': 'Checkbox',\n    },\n    multiple: {\n      type: 'array',\n      title: '复选',\n      enum: [\n        {\n          label: '选项1',\n          value: 1,\n        },\n        {\n          label: '选项2',\n          value: 2,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Checkbox.Group',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"single\"\n      title=\"是否确认\"\n      decorator={[FormItem]}\n      component={[Checkbox]}\n    />\n    <Field\n      name=\"multiple\"\n      title=\"复选\"\n      dataSource={[\n        {\n          label: '选项1',\n          value: 1,\n        },\n        {\n          label: '选项2',\n          value: 2,\n        },\n      ]}\n      decorator={[FormItem]}\n      component={[Checkbox.Group]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://ant.design/components/checkbox-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/DatePicker.md",
    "content": "# DatePicker\n\n> Date Picker\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { DatePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"date\"\n        required\n        title=\"normal date\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n      />\n      <SchemaField.String\n        name=\"week\"\n        title=\"Week Selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n        x-component-props={{\n          picker: 'week',\n        }}\n      />\n      <SchemaField.String\n        name=\"month\"\n        title=\"Month Selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n        x-component-props={{\n          picker: 'month',\n        }}\n      />\n      <SchemaField.String\n        name=\"quarter\"\n        title=\"Financial Year Selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n        x-component-props={{\n          picker: 'quarter',\n        }}\n      />\n      <SchemaField.String\n        name=\"year\"\n        title=\"Year selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n        x-component-props={{\n          picker: 'year',\n        }}\n      />\n      <SchemaField.String\n        name=\"[startDate,endDate]\"\n        title=\"Date Range\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.RangePicker\"\n        x-component-props={{\n          showTime: true,\n        }}\n      />\n      <SchemaField.String\n        name=\"range_week\"\n        title=\"Week range selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.RangePicker\"\n        x-component-props={{\n          picker: 'week',\n        }}\n      />\n      <SchemaField.String\n        name=\"range_month\"\n        title=\"Month Range Selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.RangePicker\"\n        x-component-props={{\n          picker: 'month',\n        }}\n      />\n      <SchemaField.String\n        name=\"range_quarter\"\n        title=\"Financial Year Range Selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.RangePicker\"\n        x-component-props={{\n          picker: 'quarter',\n        }}\n      />\n      <SchemaField.String\n        name=\"range_year\"\n        title=\"Year range selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.RangePicker\"\n        x-component-props={{\n          picker: 'year',\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { DatePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    date: {\n      title: 'Normal date',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      type: 'string',\n    },\n    week: {\n      title: 'Week Selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      'x-component-props': {\n        picker: 'week',\n      },\n      type: 'string',\n    },\n    month: {\n      title: 'Month Selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      'x-component-props': {\n        picker: 'month',\n      },\n      type: 'string',\n    },\n    quarter: {\n      title: 'Fiscal Year Selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      'x-component-props': {\n        picker: 'quarter',\n      },\n      type: 'string',\n    },\n    year: {\n      title: 'Year selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      'x-component-props': {\n        picker: 'year',\n      },\n      type: 'string',\n    },\n    '[startDate,endDate]': {\n      title: 'Date range',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n      'x-component-props': {\n        showTime: true,\n      },\n      type: 'string',\n    },\n    range_week: {\n      title: 'Week range selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n      'x-component-props': {\n        picker: 'week',\n      },\n      type: 'string',\n    },\n    range_month: {\n      title: 'Month Range Selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n      'x-component-props': {\n        picker: 'month',\n      },\n      type: 'string',\n    },\n    range_quarter: {\n      title: 'Financial year range selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n      'x-component-props': {\n        picker: 'quarter',\n      },\n      type: 'string',\n    },\n    range_year: {\n      name: 'range_year',\n      title: 'Year range selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n      'x-component-props': {\n        picker: 'year',\n      },\n      type: 'string',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { DatePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"date\"\n      title=\"date selection\"\n      decorator={[FormItem]}\n      component={[DatePicker]}\n    />\n    <Field\n      name=\"week\"\n      title=\"Week Selection\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker,\n        {\n          picker: 'week',\n        },\n      ]}\n    />\n    <Field\n      name=\"quarter\"\n      title=\"Financial Year Selection\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker,\n        {\n          picker: 'month',\n        },\n      ]}\n    />\n    <Field\n      name=\"year\"\n      title=\"Year selection\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker,\n        {\n          picker: 'year',\n        },\n      ]}\n    />\n    <Field\n      name=\"[startDate,endDate]\"\n      title=\"Date range selection\"\n      decorator={[FormItem]}\n      component={[DatePicker.RangePicker]}\n    />\n    <Field\n      name=\"range_week\"\n      title=\"Week range selection\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker.RangePicker,\n        {\n          picker: 'week',\n        },\n      ]}\n    />\n    <Field\n      name=\"range_month\"\n      title=\"Month Range Selection\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker.RangePicker,\n        {\n          picker: 'month',\n        },\n      ]}\n    />\n    <Field\n      name=\"range_quarter\"\n      title=\"Financial Year Range Selection\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker.RangePicker,\n        {\n          picker: 'quarter',\n        },\n      ]}\n    />\n    <Field\n      name=\"range_year\"\n      title=\"Year range selection\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker.RangePicker,\n        {\n          picker: 'year',\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://ant.design/components/date-picker-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/DatePicker.zh-CN.md",
    "content": "# DatePicker\n\n> 日期选择器\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { DatePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"date\"\n        required\n        title=\"普通日期\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n      />\n      <SchemaField.String\n        name=\"week\"\n        title=\"周选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n        x-component-props={{\n          picker: 'week',\n        }}\n      />\n      <SchemaField.String\n        name=\"month\"\n        title=\"月选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n        x-component-props={{\n          picker: 'month',\n        }}\n      />\n      <SchemaField.String\n        name=\"quarter\"\n        title=\"财年选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n        x-component-props={{\n          picker: 'quarter',\n        }}\n      />\n      <SchemaField.String\n        name=\"year\"\n        title=\"年选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n        x-component-props={{\n          picker: 'year',\n        }}\n      />\n      <SchemaField.String\n        name=\"[startDate,endDate]\"\n        title=\"日期范围\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.RangePicker\"\n        x-component-props={{\n          showTime: true,\n        }}\n      />\n      <SchemaField.String\n        name=\"range_week\"\n        title=\"周范围选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.RangePicker\"\n        x-component-props={{\n          picker: 'week',\n        }}\n      />\n      <SchemaField.String\n        name=\"range_month\"\n        title=\"月范围选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.RangePicker\"\n        x-component-props={{\n          picker: 'month',\n        }}\n      />\n      <SchemaField.String\n        name=\"range_quarter\"\n        title=\"财年范围选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.RangePicker\"\n        x-component-props={{\n          picker: 'quarter',\n        }}\n      />\n      <SchemaField.String\n        name=\"range_year\"\n        title=\"年范围选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.RangePicker\"\n        x-component-props={{\n          picker: 'year',\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { DatePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    date: {\n      title: '普通日期',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      type: 'string',\n    },\n    week: {\n      title: '周选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      'x-component-props': {\n        picker: 'week',\n      },\n      type: 'string',\n    },\n    month: {\n      title: '月选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      'x-component-props': {\n        picker: 'month',\n      },\n      type: 'string',\n    },\n    quarter: {\n      title: '财年选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      'x-component-props': {\n        picker: 'quarter',\n      },\n      type: 'string',\n    },\n    year: {\n      title: '年选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      'x-component-props': {\n        picker: 'year',\n      },\n      type: 'string',\n    },\n    '[startDate,endDate]': {\n      title: '日期范围',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n      'x-component-props': {\n        showTime: true,\n      },\n      type: 'string',\n    },\n    range_week: {\n      title: '周范围选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n      'x-component-props': {\n        picker: 'week',\n      },\n      type: 'string',\n    },\n    range_month: {\n      title: '月范围选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n      'x-component-props': {\n        picker: 'month',\n      },\n      type: 'string',\n    },\n    range_quarter: {\n      title: '财年范围选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n      'x-component-props': {\n        picker: 'quarter',\n      },\n      type: 'string',\n    },\n    range_year: {\n      name: 'range_year',\n      title: '年范围选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n      'x-component-props': {\n        picker: 'year',\n      },\n      type: 'string',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { DatePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"date\"\n      title=\"日期选择\"\n      decorator={[FormItem]}\n      component={[DatePicker]}\n    />\n    <Field\n      name=\"week\"\n      title=\"周选择\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker,\n        {\n          picker: 'week',\n        },\n      ]}\n    />\n    <Field\n      name=\"quarter\"\n      title=\"财年选择\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker,\n        {\n          picker: 'month',\n        },\n      ]}\n    />\n    <Field\n      name=\"year\"\n      title=\"年选择\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker,\n        {\n          picker: 'year',\n        },\n      ]}\n    />\n    <Field\n      name=\"[startDate,endDate]\"\n      title=\"日期范围选择\"\n      decorator={[FormItem]}\n      component={[DatePicker.RangePicker]}\n    />\n    <Field\n      name=\"range_week\"\n      title=\"周范围选择\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker.RangePicker,\n        {\n          picker: 'week',\n        },\n      ]}\n    />\n    <Field\n      name=\"range_month\"\n      title=\"月范围选择\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker.RangePicker,\n        {\n          picker: 'month',\n        },\n      ]}\n    />\n    <Field\n      name=\"range_quarter\"\n      title=\"财年范围选择\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker.RangePicker,\n        {\n          picker: 'quarter',\n        },\n      ]}\n    />\n    <Field\n      name=\"range_year\"\n      title=\"年范围选择\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker.RangePicker,\n        {\n          picker: 'year',\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://ant.design/components/date-picker-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Editable.md",
    "content": "# Editable\n\n> Partial editor, you can use this component for some form areas with high space requirements\n>\n> Editable component is equivalent to a variant of FormItem component, so it is usually placed in decorator\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  DatePicker,\n  Editable,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker,\n    Editable,\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"date\"\n        title=\"date\"\n        x-decorator=\"Editable\"\n        x-component=\"DatePicker\"\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        x-decorator=\"Editable\"\n        x-component=\"Input\"\n      />\n      <SchemaField.Void\n        name=\"void\"\n        title=\"Virtual Node Container\"\n        x-component=\"Editable.Popover\"\n        x-reactions={(field) => {\n          field.title = field.query('.void.date2').get('value') || field.title\n        }}\n      >\n        <SchemaField.String\n          name=\"date2\"\n          title=\"date\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n        />\n        <SchemaField.String\n          name=\"input2\"\n          title=\"input box\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n      </SchemaField.Void>\n      <SchemaField.Object\n        name=\"iobject\"\n        title=\"Object node container\"\n        x-component=\"Editable.Popover\"\n        x-reactions={(field) => {\n          field.title = field.value?.date || field.title\n        }}\n      >\n        <SchemaField.String\n          name=\"date\"\n          title=\"date\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n        />\n        <SchemaField.String\n          name=\"input\"\n          title=\"input box\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n      </SchemaField.Object>\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  DatePicker,\n  Editable,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker,\n    Editable,\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    date: {\n      type: 'string',\n      title: 'Date',\n      'x-decorator': 'Editable',\n      'x-component': 'DatePicker',\n    },\n    input: {\n      type: 'string',\n      title: 'input box',\n      'x-decorator': 'Editable',\n      'x-component': 'Input',\n    },\n    void: {\n      type: 'void',\n      title: 'Virtual Node Container',\n      'x-component': 'Editable.Popover',\n      'x-reactions':\n        \"{{(field) => field.title = field.query('.void.date2').get('value') || field.title}}\",\n      properties: {\n        date2: {\n          type: 'string',\n          title: 'Date',\n          'x-decorator': 'FormItem',\n          'x-component': 'DatePicker',\n        },\n        input2: {\n          type: 'string',\n          title: 'input box',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n      },\n    },\n    iobject: {\n      type: 'object',\n      title: 'Object node container',\n      'x-component': 'Editable.Popover',\n      'x-reactions':\n        '{{(field) => field.title = field.value && field.value.date || field.title}}',\n      properties: {\n        date: {\n          type: 'string',\n          title: 'Date',\n          'x-decorator': 'FormItem',\n          'x-component': 'DatePicker',\n        },\n        input: {\n          type: 'string',\n          title: 'input box',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  DatePicker,\n  Editable,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, VoidField, ObjectField } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"date\"\n      title=\"date\"\n      decorator={[Editable]}\n      component={[DatePicker]}\n    />\n    <Field\n      name=\"input\"\n      title=\"input box\"\n      decorator={[Editable]}\n      component={[Input]}\n    />\n    <VoidField\n      name=\"void\"\n      title=\"Virtual Node Container\"\n      reactions={(field) => {\n        field.title = field.query('.void.date2').get('value') || field.title\n      }}\n      component={[Editable.Popover]}\n    >\n      <Field\n        name=\"date2\"\n        title=\"date\"\n        decorator={[FormItem]}\n        component={[DatePicker]}\n      />\n      <Field\n        name=\"input2\"\n        title=\"input box\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n    </VoidField>\n    <ObjectField\n      name=\"iobject\"\n      title=\"Object node container\"\n      reactions={(field) => {\n        field.title = field.value?.date || field.title\n      }}\n      component={[Editable.Popover]}\n    >\n      <Field\n        name=\"date\"\n        title=\"date\"\n        decorator={[FormItem]}\n        component={[DatePicker]}\n      />\n      <Field\n        name=\"input\"\n        title=\"input box\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n    </ObjectField>\n\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n### Editable\n\n> Inline editing\n\nRefer to the FormItem property in https://ant.design/components/form-cn/\n\n### Editable.Popover\n\n> Floating layer editing\n\nReference https://ant.design/components/popover-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Editable.zh-CN.md",
    "content": "# Editable\n\n> 局部编辑器，对于一些空间要求较高的表单区域可以使用该组件\n>\n> Editable 组件相当于是 FormItem 组件的变体，所以通常放在 decorator 中\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  DatePicker,\n  Editable,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker,\n    Editable,\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"date\"\n        title=\"日期\"\n        x-decorator=\"Editable\"\n        x-component=\"DatePicker\"\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        x-decorator=\"Editable\"\n        x-component=\"Input\"\n      />\n      <SchemaField.Void\n        name=\"void\"\n        title=\"虚拟节点容器\"\n        x-component=\"Editable.Popover\"\n        x-reactions={(field) => {\n          field.title = field.query('.void.date2').get('value') || field.title\n        }}\n      >\n        <SchemaField.String\n          name=\"date2\"\n          title=\"日期\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n        />\n        <SchemaField.String\n          name=\"input2\"\n          title=\"输入框\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n      </SchemaField.Void>\n      <SchemaField.Object\n        name=\"iobject\"\n        title=\"对象节点容器\"\n        x-component=\"Editable.Popover\"\n        x-reactions={(field) => {\n          field.title = field.value?.date || field.title\n        }}\n      >\n        <SchemaField.String\n          name=\"date\"\n          title=\"日期\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n        />\n        <SchemaField.String\n          name=\"input\"\n          title=\"输入框\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n      </SchemaField.Object>\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  DatePicker,\n  Editable,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker,\n    Editable,\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    date: {\n      type: 'string',\n      title: '日期',\n      'x-decorator': 'Editable',\n      'x-component': 'DatePicker',\n    },\n    input: {\n      type: 'string',\n      title: '输入框',\n      'x-decorator': 'Editable',\n      'x-component': 'Input',\n    },\n    void: {\n      type: 'void',\n      title: '虚拟节点容器',\n      'x-component': 'Editable.Popover',\n      'x-reactions':\n        \"{{(field) => field.title = field.query('.void.date2').get('value') || field.title}}\",\n      properties: {\n        date2: {\n          type: 'string',\n          title: '日期',\n          'x-decorator': 'FormItem',\n          'x-component': 'DatePicker',\n        },\n        input2: {\n          type: 'string',\n          title: '输入框',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n      },\n    },\n    iobject: {\n      type: 'object',\n      title: '对象节点容器',\n      'x-component': 'Editable.Popover',\n      'x-reactions':\n        '{{(field) => field.title = field.value && field.value.date || field.title}}',\n      properties: {\n        date: {\n          type: 'string',\n          title: '日期',\n          'x-decorator': 'FormItem',\n          'x-component': 'DatePicker',\n        },\n        input: {\n          type: 'string',\n          title: '输入框',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  DatePicker,\n  Editable,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, VoidField, ObjectField } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"date\"\n      title=\"日期\"\n      decorator={[Editable]}\n      component={[DatePicker]}\n    />\n    <Field\n      name=\"input\"\n      title=\"输入框\"\n      decorator={[Editable]}\n      component={[Input]}\n    />\n    <VoidField\n      name=\"void\"\n      title=\"虚拟节点容器\"\n      reactions={(field) => {\n        field.title = field.query('.void.date2').get('value') || field.title\n      }}\n      component={[Editable.Popover]}\n    >\n      <Field\n        name=\"date2\"\n        title=\"日期\"\n        decorator={[FormItem]}\n        component={[DatePicker]}\n      />\n      <Field\n        name=\"input2\"\n        title=\"输入框\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n    </VoidField>\n    <ObjectField\n      name=\"iobject\"\n      title=\"对象节点容器\"\n      reactions={(field) => {\n        field.title = field.value?.date || field.title\n      }}\n      component={[Editable.Popover]}\n    >\n      <Field\n        name=\"date\"\n        title=\"日期\"\n        decorator={[FormItem]}\n        component={[DatePicker]}\n      />\n      <Field\n        name=\"input\"\n        title=\"输入框\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n    </ObjectField>\n\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n### Editable\n\n> 内联编辑\n\n参考 https://ant.design/components/form-cn/ 中的 FormItem 属性\n\n### Editable.Popover\n\n> 浮层编辑\n\n参考 https://ant.design/components/popover-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Form.md",
    "content": "# Form\n\n> The combination of FormProvider + FormLayout + form tags can help us quickly implement forms that are submitted with carriage return and can be laid out in batches\n\n## Use Cases\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Select,\n  Form,\n  FormItem,\n  FormGrid,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <Form\n    form={form}\n    layout=\"vertical\"\n    feedbackLayout=\"terse\"\n    onAutoSubmit={console.log}\n    onAutoSubmitFailed={console.log}\n  >\n    <FormGrid maxColumns={4}>\n      <Field\n        name=\"aa\"\n        title=\"select box\"\n        decorator={[FormItem]}\n        component={[Select]}\n        dataSource={[\n          {\n            label: 'Option 1',\n            value: 1,\n          },\n          {\n            label: 'Option 2',\n            value: 2,\n          },\n        ]}\n      />\n      <Field\n        name=\"bb\"\n        title=\"input box\"\n        required\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <Field\n        name=\"cc\"\n        title=\"input box\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <Field\n        name=\"dd\"\n        title=\"input box\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <Field\n        name=\"ee\"\n        title=\"input box\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <FormButtonGroup.FormItem>\n        <Submit>Query</Submit>\n      </FormButtonGroup.FormItem>\n    </FormGrid>\n  </Form>\n)\n```\n\n<Alert style=\"margin-top:20px\">\nNote: 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.\n</Alert>\n\n## API\n\nFor layout-related API properties, we can refer to [FormLayout](./form-layout), and the rest are the unique API properties of the Form component\n\n| Property name          | Type                                                                                             | Description                                                         | Default value |\n| ---------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------- | ------------- |\n| form                   | [Form](https://core.formilyjs.org/api/models/form)                                               | Form example                                                        | -             |\n| component              | string                                                                                           | Rendering component, can be specified as custom component rendering | `form`        |\n| previewTextPlaceholder | ReactNode                                                                                        | Preview State Placeholder                                           | `N/A`         |\n| onAutoSubmit           | `(values:any)=>any`                                                                              | Carriage return submit event callback                               | -             |\n| onAutoSubmitFailed     | (feedbacks: [IFormFeedback](https://core.formilyjs.org/api/models/form#iformfeedback)[]) => void | Carriage return submission verification failure event callback      | -             |\n"
  },
  {
    "path": "packages/antd/docs/components/Form.zh-CN.md",
    "content": "# Form\n\n> FormProvider + FormLayout + form 标签的组合组件，可以帮助我们快速实现带回车提交的且能批量布局的表单\n\n## 使用案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Select,\n  Form,\n  FormItem,\n  FormGrid,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <Form\n    form={form}\n    layout=\"vertical\"\n    feedbackLayout=\"terse\"\n    onAutoSubmit={console.log}\n    onAutoSubmitFailed={console.log}\n  >\n    <FormGrid maxColumns={4}>\n      <Field\n        name=\"aa\"\n        title=\"选择框\"\n        decorator={[FormItem]}\n        component={[Select]}\n        dataSource={[\n          {\n            label: '选项1',\n            value: 1,\n          },\n          {\n            label: '选项2',\n            value: 2,\n          },\n        ]}\n      />\n      <Field\n        name=\"bb\"\n        title=\"输入框\"\n        required\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <Field\n        name=\"cc\"\n        title=\"输入框\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <Field\n        name=\"dd\"\n        title=\"输入框\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <Field\n        name=\"ee\"\n        title=\"输入框\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <FormButtonGroup.FormItem>\n        <Submit>查询</Submit>\n      </FormButtonGroup.FormItem>\n    </FormGrid>\n  </Form>\n)\n```\n\n<Alert style=\"margin-top:20px\">\n注意：想要实现回车提交，我们在使用Submit组件的时候不能给其传onSubmit事件，否则回车提交会失效，这样做的目的是为了防止用户同时在多处写onSubmit事件监听器，处理逻辑不一致的话，提交时很难定位问题。\n</Alert>\n\n## API\n\n布局相关的 API 属性，我们参考 [FormLayout](./form-layout)即可，剩下是 Form 组件独有的 API 属性\n\n| 属性名                 | 类型                                                                                                   | 描述                               | 默认值 |\n| ---------------------- | ------------------------------------------------------------------------------------------------------ | ---------------------------------- | ------ |\n| form                   | [Form](https://core.formilyjs.org/zh-CN/api/models/form)                                               | Form 实例                          | -      |\n| component              | string                                                                                                 | 渲染组件，可以指定为自定义组件渲染 | `form` |\n| previewTextPlaceholder | ReactNode                                                                                              | 预览态占位符                       | `N/A`  |\n| onAutoSubmit           | `(values:any)=>any`                                                                                    | 回车提交事件回调                   | -      |\n| onAutoSubmitFailed     | (feedbacks: [IFormFeedback](https://core.formilyjs.org/zh-CN/api/models/form#iformfeedback)[]) => void | 回车提交校验失败事件回调           | -      |\n"
  },
  {
    "path": "packages/antd/docs/components/FormButtonGroup.md",
    "content": "# FormButtonGroup\n\n> Form button group layout component\n\n## Common case\n\n```tsx\nimport React from 'react'\nimport {\n  FormButtonGroup,\n  Submit,\n  Reset,\n  FormItem,\n  Input,\n  FormLayout,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField>\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaField>\n        <FormButtonGroup.FormItem>\n          <Submit onSubmit={console.log}>Submit</Submit>\n          <Reset>Reset</Reset>\n        </FormButtonGroup.FormItem>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## Suction bottom case\n\n```tsx\nimport React from 'react'\nimport {\n  FormButtonGroup,\n  Submit,\n  Reset,\n  FormItem,\n  FormLayout,\n  Input,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField>\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaField>\n        <FormButtonGroup.Sticky>\n          <FormButtonGroup.FormItem>\n            <Submit onSubmit={console.log}>Submit</Submit>\n            <Reset>Reset</Reset>\n          </FormButtonGroup.FormItem>\n        </FormButtonGroup.Sticky>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## Suction bottom centering case\n\n```tsx\nimport React from 'react'\nimport {\n  FormButtonGroup,\n  Submit,\n  Reset,\n  FormItem,\n  FormLayout,\n  Input,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField>\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaField>\n        <FormButtonGroup.Sticky align=\"center\">\n          <FormButtonGroup>\n            <Submit onSubmit={console.log}>Submit</Submit>\n            <Reset>Reset</Reset>\n          </FormButtonGroup>\n        </FormButtonGroup.Sticky>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormButtonGroup\n\n> This component is mainly used to handle the button group gap\n\n| Property name | Type                        | Description | Default value |\n| ------------- | --------------------------- | ----------- | ------------- |\n| gutter        | number                      | Gap size    | 8px           |\n| align         | `'left'\\|'center'\\|'right'` | Alignment   | `'left'`      |\n\n### FormButtonGroup.FormItem\n\n> This component is mainly used to deal with the alignment of the button group and the main form FormItem\n\nRefer to [FormItem](/components/form-item) property\n\n### FormButtonGroup.Sticky\n\n> This component is mainly used to deal with the floating positioning problem of the button group\n\n| Property name | Type                        | Description | Default value |\n| ------------- | --------------------------- | ----------- | ------------- |\n| align         | `'left'\\|'center'\\|'right'` | Alignment   | `'left'`      |\n"
  },
  {
    "path": "packages/antd/docs/components/FormButtonGroup.zh-CN.md",
    "content": "# FormButtonGroup\n\n> 表单按钮组布局组件\n\n## 普通案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormButtonGroup,\n  Submit,\n  Reset,\n  FormItem,\n  Input,\n  FormLayout,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField>\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaField>\n        <FormButtonGroup.FormItem>\n          <Submit onSubmit={console.log}>提交</Submit>\n          <Reset>重置</Reset>\n        </FormButtonGroup.FormItem>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## 吸底案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormButtonGroup,\n  Submit,\n  Reset,\n  FormItem,\n  FormLayout,\n  Input,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField>\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaField>\n        <FormButtonGroup.Sticky>\n          <FormButtonGroup.FormItem>\n            <Submit onSubmit={console.log}>提交</Submit>\n            <Reset>重置</Reset>\n          </FormButtonGroup.FormItem>\n        </FormButtonGroup.Sticky>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## 吸底居中案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormButtonGroup,\n  Submit,\n  Reset,\n  FormItem,\n  FormLayout,\n  Input,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField>\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaField>\n        <FormButtonGroup.Sticky align=\"center\">\n          <FormButtonGroup>\n            <Submit onSubmit={console.log}>提交</Submit>\n            <Reset>重置</Reset>\n          </FormButtonGroup>\n        </FormButtonGroup.Sticky>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormButtonGroup\n\n> 该组件主要用来处理按钮组间隙\n\n| 属性名 | 类型                        | 描述     | 默认值   |\n| ------ | --------------------------- | -------- | -------- |\n| gutter | number                      | 间隙大小 | 8px      |\n| align  | `'left'\\|'center'\\|'right'` | 对齐方式 | `'left'` |\n\n### FormButtonGroup.FormItem\n\n> 该组件主要用来处理按钮组与主表单 FormItem 对齐问题\n\n参考 [FormItem](/components/form-item) 属性\n\n### FormButtonGroup.Sticky\n\n> 该组件主要用来处理按钮组浮动定位问题\n\n| 属性名 | 类型                        | 描述     | 默认值   |\n| ------ | --------------------------- | -------- | -------- |\n| align  | `'left'\\|'center'\\|'right'` | 对齐方式 | `'left'` |\n"
  },
  {
    "path": "packages/antd/docs/components/FormCollapse.md",
    "content": "# FormCollapse\n\n> Folding panel, usually used in form scenes with high layout space requirements\n>\n> Note: Can only be used in Schema scenarios\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  FormCollapse,\n  FormLayout,\n  FormItem,\n  Input,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormCollapse,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formCollapse = FormCollapse.createFormCollapse()\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField>\n          <SchemaField.Void\n            title=\"Folding Panel\"\n            x-decorator=\"FormItem\"\n            x-component=\"FormCollapse\"\n            x-component-props={{\n              formCollapse,\n            }}\n          >\n            <SchemaField.Void\n              name=\"panel1\"\n              x-component=\"FormCollapse.CollapsePanel\"\n              x-component-props={{ header: 'A1' }}\n            >\n              <SchemaField.String\n                name=\"aaa\"\n                title=\"AAA\"\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              name=\"panel2\"\n              x-component=\"FormCollapse.CollapsePanel\"\n              x-component-props={{ header: 'A2' }}\n            >\n              <SchemaField.String\n                name=\"bbb\"\n                title=\"BBB\"\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              name=\"panel3\"\n              x-component=\"FormCollapse.CollapsePanel\"\n              x-component-props={{ header: 'A3' }}\n            >\n              <SchemaField.String\n                name=\"ccc\"\n                title=\"CCC\"\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n          </SchemaField.Void>\n        </SchemaField>\n        <FormButtonGroup.FormItem>\n          <Button\n            onClick={() => {\n              form.query('panel3').take((field) => {\n                field.visible = !field.visible\n              })\n            }}\n          >\n            Show/hide the last tab\n          </Button>\n          <Button\n            onClick={() => {\n              formCollapse.toggleActiveKey('panel2')\n            }}\n          >\n            Switch to the second Tab\n          </Button>\n          <Submit onSubmit={console.log}>Submit</Submit>\n        </FormButtonGroup.FormItem>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  FormCollapse,\n  FormItem,\n  FormLayout,\n  Input,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormCollapse,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formCollapse = FormCollapse.createFormCollapse()\nconst schema = {\n  type: 'object',\n  properties: {\n    collapse: {\n      type: 'void',\n      title: 'Folding Panel',\n      'x-decorator': 'FormItem',\n      'x-component': 'FormCollapse',\n      'x-component-props': {\n        formCollapse: '{{formCollapse}}',\n      },\n      properties: {\n        panel1: {\n          type: 'void',\n          'x-component': 'FormCollapse.CollapsePanel',\n          'x-component-props': {\n            header: 'A1',\n          },\n          properties: {\n            aaa: {\n              type: 'string',\n              title: 'AAA',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        panel2: {\n          type: 'void',\n          'x-component': 'FormCollapse.CollapsePanel',\n          'x-component-props': {\n            header: 'A2',\n          },\n          properties: {\n            bbb: {\n              type: 'string',\n              title: 'BBB',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        panel3: {\n          type: 'void',\n          'x-component': 'FormCollapse.CollapsePanel',\n          'x-component-props': {\n            header: 'A3',\n          },\n          properties: {\n            ccc: {\n              type: 'string',\n              title: 'CCC',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField schema={schema} scope={{ formCollapse }} />\n        <FormButtonGroup.FormItem>\n          <Button\n            onClick={() => {\n              form.query('panel3').take((field) => {\n                field.visible = !field.visible\n              })\n            }}\n          >\n            Show/hide the last tab\n          </Button>\n          <Button\n            onClick={() => {\n              formCollapse.toggleActiveKey('panel2')\n            }}\n          >\n            Switch to the second Tab\n          </Button>\n          <Submit onSubmit={console.log}>Submit</Submit>\n        </FormButtonGroup.FormItem>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormCollapse\n\n| Property name | Type          | Description                                                     | Default value |\n| ------------- | ------------- | --------------------------------------------------------------- | ------------- |\n| formCollapse  | IFormCollapse | Pass in the model created by createFormCollapse/useFormCollapse |               |\n\nOther references https://ant.design/components/collapse-cn/\n\n### FormCollapse.CollapsePanel\n\nReference https://ant.design/components/collapse-cn/\n\n### FormCollapse.createFormCollapse\n\n```ts pure\ntype ActiveKey = string | number\ntype ActiveKeys = string | number | Array<string | number>\n\ninterface createFormCollapse {\n  (defaultActiveKeys?: ActiveKeys): IFormCollpase\n}\n\ninterface IFormCollapse {\n  //Activate the primary key list\n  activeKeys: ActiveKeys\n  //Does the activation key exist?\n  hasActiveKey(key: ActiveKey): boolean\n  //Set the list of active primary keys\n  setActiveKeys(keys: ActiveKeys): void\n  //Add activation key\n  addActiveKey(key: ActiveKey): void\n  //Delete the active primary key\n  removeActiveKey(key: ActiveKey): void\n  //Switch to activate the main key\n  toggleActiveKey(key: ActiveKey): void\n}\n```\n"
  },
  {
    "path": "packages/antd/docs/components/FormCollapse.zh-CN.md",
    "content": "# FormCollapse\n\n> 折叠面板，通常用在布局空间要求较高的表单场景\n>\n> 注意：只能用在 Schema 场景\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormCollapse,\n  FormLayout,\n  FormItem,\n  Input,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormCollapse,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formCollapse = FormCollapse.createFormCollapse()\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField>\n          <SchemaField.Void\n            title=\"折叠面板\"\n            x-decorator=\"FormItem\"\n            x-component=\"FormCollapse\"\n            x-component-props={{\n              formCollapse,\n            }}\n          >\n            <SchemaField.Void\n              name=\"panel1\"\n              x-component=\"FormCollapse.CollapsePanel\"\n              x-component-props={{ header: 'A1' }}\n            >\n              <SchemaField.String\n                name=\"aaa\"\n                title=\"AAA\"\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              name=\"panel2\"\n              x-component=\"FormCollapse.CollapsePanel\"\n              x-component-props={{ header: 'A2' }}\n            >\n              <SchemaField.String\n                name=\"bbb\"\n                title=\"BBB\"\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              name=\"panel3\"\n              x-component=\"FormCollapse.CollapsePanel\"\n              x-component-props={{ header: 'A3' }}\n            >\n              <SchemaField.String\n                name=\"ccc\"\n                title=\"CCC\"\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n          </SchemaField.Void>\n        </SchemaField>\n        <FormButtonGroup.FormItem>\n          <Button\n            onClick={() => {\n              form.query('panel3').take((field) => {\n                field.visible = !field.visible\n              })\n            }}\n          >\n            显示/隐藏最后一个Tab\n          </Button>\n          <Button\n            onClick={() => {\n              formCollapse.toggleActiveKey('panel2')\n            }}\n          >\n            切换第二个Tab\n          </Button>\n          <Submit onSubmit={console.log}>提交</Submit>\n        </FormButtonGroup.FormItem>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormCollapse,\n  FormItem,\n  FormLayout,\n  Input,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormCollapse,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formCollapse = FormCollapse.createFormCollapse()\nconst schema = {\n  type: 'object',\n  properties: {\n    collapse: {\n      type: 'void',\n      title: '折叠面板',\n      'x-decorator': 'FormItem',\n      'x-component': 'FormCollapse',\n      'x-component-props': {\n        formCollapse: '{{formCollapse}}',\n      },\n      properties: {\n        panel1: {\n          type: 'void',\n          'x-component': 'FormCollapse.CollapsePanel',\n          'x-component-props': {\n            header: 'A1',\n          },\n          properties: {\n            aaa: {\n              type: 'string',\n              title: 'AAA',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        panel2: {\n          type: 'void',\n          'x-component': 'FormCollapse.CollapsePanel',\n          'x-component-props': {\n            header: 'A2',\n          },\n          properties: {\n            bbb: {\n              type: 'string',\n              title: 'BBB',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        panel3: {\n          type: 'void',\n          'x-component': 'FormCollapse.CollapsePanel',\n          'x-component-props': {\n            header: 'A3',\n          },\n          properties: {\n            ccc: {\n              type: 'string',\n              title: 'CCC',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField schema={schema} scope={{ formCollapse }} />\n        <FormButtonGroup.FormItem>\n          <Button\n            onClick={() => {\n              form.query('panel3').take((field) => {\n                field.visible = !field.visible\n              })\n            }}\n          >\n            显示/隐藏最后一个Tab\n          </Button>\n          <Button\n            onClick={() => {\n              formCollapse.toggleActiveKey('panel2')\n            }}\n          >\n            切换第二个Tab\n          </Button>\n          <Submit onSubmit={console.log}>提交</Submit>\n        </FormButtonGroup.FormItem>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormCollapse\n\n| 属性名       | 类型          | 描述                                                       | 默认值 |\n| ------------ | ------------- | ---------------------------------------------------------- | ------ |\n| formCollapse | IFormCollapse | 传入通过 createFormCollapse/useFormCollapse 创建出来的模型 |        |\n\n其余参考 https://ant.design/components/collapse-cn/\n\n### FormCollapse.CollapsePanel\n\n参考 https://ant.design/components/collapse-cn/\n\n### FormCollapse.createFormCollapse\n\n```ts pure\ntype ActiveKey = string | number\ntype ActiveKeys = string | number | Array<string | number>\n\ninterface createFormCollapse {\n  (defaultActiveKeys?: ActiveKeys): IFormCollpase\n}\n\ninterface IFormCollapse {\n  //激活主键列表\n  activeKeys: ActiveKeys\n  //是否存在该激活主键\n  hasActiveKey(key: ActiveKey): boolean\n  //设置激活主键列表\n  setActiveKeys(keys: ActiveKeys): void\n  //添加激活主键\n  addActiveKey(key: ActiveKey): void\n  //删除激活主键\n  removeActiveKey(key: ActiveKey): void\n  //开关切换激活主键\n  toggleActiveKey(key: ActiveKey): void\n}\n```\n"
  },
  {
    "path": "packages/antd/docs/components/FormDialog.md",
    "content": "# FormDialog\n\n> Pop-up form, mainly used in simple event to open the form scene\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { FormDialog, FormItem, FormLayout, Input } from '@formily/antd'\nimport { createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        const dialog = FormDialog('Pop-up form', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={10}>\n              <SchemaField>\n                <SchemaField.String\n                  name=\"aaa\"\n                  required\n                  title=\"input box 1\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"bbb\"\n                  required\n                  title=\"input box 2\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"ccc\"\n                  required\n                  title=\"input box 3\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"ddd\"\n                  required\n                  title=\"input box 4\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n              </SchemaField>\n              <FormDialog.Footer>\n                <span\n                  onClick={() => {\n                    dialog.close()\n                  }}\n                  style={{ marginLeft: 4 }}\n                >\n                  Extended copywriting(Click me to close the form)\n                </span>\n              </FormDialog.Footer>\n            </FormLayout>\n          )\n        })\n        dialog\n          .forOpen((payload, next) => {\n            setTimeout(() => {\n              next({\n                initialValues: {\n                  aaa: '123',\n                },\n              })\n            }, 1000)\n          })\n          .forConfirm((payload, next) => {\n            setTimeout(() => {\n              console.log(payload)\n              next(payload)\n            }, 1000)\n          })\n          .forCancel((payload, next) => {\n            setTimeout(() => {\n              console.log(payload)\n              next(payload)\n            }, 1000)\n          })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      Click me to open the form\n    </Button>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { FormDialog, FormItem, FormLayout, Input } from '@formily/antd'\nimport { createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    aaa: {\n      type: 'string',\n      title: 'input box 1',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    bbb: {\n      type: 'string',\n      title: 'input box 2',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    ccc: {\n      type: 'string',\n      title: 'input box 3',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    ddd: {\n      type: 'string',\n      title: 'input box 4',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        const dialog = FormDialog('Pop-up form', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={10}>\n              <SchemaField schema={schema} />\n              <FormDialog.Footer>\n                <span\n                  onClick={() => {\n                    dialog.close()\n                  }}\n                  style={{ marginLeft: 4 }}\n                >\n                  Extended copywriting(Click me to close the form)\n                </span>\n              </FormDialog.Footer>\n            </FormLayout>\n          )\n        })\n        dialog\n          .forOpen((payload, next) => {\n            setTimeout(() => {\n              next({\n                initialValues: {\n                  aaa: '123',\n                },\n              })\n            }, 1000)\n          })\n          .forConfirm((payload, next) => {\n            setTimeout(() => {\n              console.log(payload)\n              next(payload)\n            }, 1000)\n          })\n          .forCancel((payload, next) => {\n            setTimeout(() => {\n              console.log(payload)\n              next(payload)\n            }, 1000)\n          })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      Click me to open the form\n    </Button>\n  )\n}\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { FormDialog, FormItem, FormLayout, Input } from '@formily/antd'\nimport { Field } from '@formily/react'\nimport { Button } from 'antd'\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        const dialog = FormDialog('Pop-up form', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={10}>\n              <Field\n                name=\"aaa\"\n                required\n                title=\"input box 1\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"bbb\"\n                required\n                title=\"input box 2\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"ccc\"\n                required\n                title=\"input box 3\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"ddd\"\n                required\n                title=\"input box 4\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <FormDialog.Footer>\n                <span\n                  onClick={() => {\n                    dialog.close()\n                  }}\n                  style={{ marginLeft: 4 }}\n                >\n                  Extended copywriting(Click me to close the form)\n                </span>\n              </FormDialog.Footer>\n            </FormLayout>\n          )\n        })\n        dialog\n          .forOpen((payload, next) => {\n            setTimeout(() => {\n              next({\n                initialValues: {\n                  aaa: '123',\n                },\n              })\n            }, 1000)\n          })\n          .forConfirm((payload, next) => {\n            setTimeout(() => {\n              console.log(payload)\n              next(payload)\n            }, 1000)\n          })\n          .forCancel((payload, next) => {\n            setTimeout(() => {\n              console.log(payload)\n              next(payload)\n            }, 1000)\n          })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      Click me to open the form\n    </Button>\n  )\n}\n```\n\n## API\n\n### FormDialog\n\n```ts pure\nimport { IFormProps, Form } from '@formily/core'\n\ntype FormDialogRenderer =\n  | React.ReactElement\n  | ((form: Form) => React.ReactElement)\n\ntype ModalTitle = string | number | React.ReactElement\n\ninterface IFormDialog {\n  forOpen(\n    middleware: (\n      props: IFormProps,\n      next: (props?: IFormProps) => Promise<any>\n    ) => any\n  ): any //Middleware interceptor, can intercept Dialog to open\n  forConfirm(\n    middleware: (props: Form, next: (props?: Form) => Promise<any>) => any\n  ): any //Middleware interceptor, which can intercept Dialog confirmation\n  forCancel(\n    middleware: (props: Form, next: (props?: Form) => Promise<any>) => any\n  ): any //Middleware interceptor, can intercept Dialog to cancel\n  //Open the pop-up window to receive form attributes, you can pass in initialValues/values/effects etc.\n  open(props: IFormProps): Promise<any> //return form data\n  //Close the pop-up window\n  close(): void\n}\n\ninterface IModalProps extends ModalProps {\n  onOk?: (event: React.MouseEvent<HTMLElement>) => void | boolean // return false can prevent onOk\n  onCancel?: (event: React.MouseEvent<HTMLElement>) => void | boolean // return false can prevent onCancel\n  loadingText?: React.ReactNode\n}\n\ninterface FormDialog {\n  (title: IModalProps, id: string, renderer: FormDialogRenderer): IFormDialog\n  (title: IModalProps, renderer: FormDialogRenderer): IFormDialog\n  (title: ModalTitle, id: string, renderer: FormDialogRenderer): IFormDialog\n  (title: ModalTitle, renderer: FormDialogRenderer): IFormDialog\n}\n```\n\n`ModalProps` type definition reference ant design [Modal API](https://ant.design/components/modal-cn/#API)\n\n### FormDialog.Footer\n\nNo attributes, only child nodes are received\n\n### FormDialog.Portal\n\nReceive the optional id attribute, the default value is `form-dialog`, if there are multiple prefixCls in an application, and the prefixCls in the pop-up window of different regions are different, then it is recommended to specify the id as the region-level id\n"
  },
  {
    "path": "packages/antd/docs/components/FormDialog.zh-CN.md",
    "content": "# FormDialog\n\n> 弹窗表单，主要用在简单的事件打开表单场景\n\n## Markup Schema 案例\n\n以下例子演示了 FormDialog 的几个能力：\n\n- 快速打开，关闭能力\n- 中间件能力，自动出现加载态\n- 渲染函数内可以响应式能力\n- 上下文共享能力\n\n```tsx\nimport React, { createContext, useContext } from 'react'\nimport { FormDialog, FormItem, FormLayout, Input } from '@formily/antd'\nimport { createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst Context = createContext()\n\nconst PortalId = '可以传，也可以不传的ID，默认是form-dialog'\n\nexport default () => {\n  return (\n    <Context.Provider value=\"自定义上下文可以直接传到弹窗内部，只需要ID一致即可\">\n      <FormDialog.Portal id={PortalId}>\n        <Button\n          onClick={() => {\n            const dialog = FormDialog('弹窗表单', PortalId, (form) => {\n              console.log(useContext(Context))\n              return (\n                <FormLayout labelCol={6} wrapperCol={10}>\n                  <SchemaField>\n                    <SchemaField.String\n                      name=\"aaa\"\n                      required\n                      title=\"输入框1\"\n                      x-decorator=\"FormItem\"\n                      x-component=\"Input\"\n                    />\n                    <SchemaField.String\n                      name=\"bbb\"\n                      required\n                      title=\"输入框2\"\n                      x-decorator=\"FormItem\"\n                      x-component=\"Input\"\n                    />\n                    <SchemaField.String\n                      name=\"ccc\"\n                      required\n                      title=\"输入框3\"\n                      x-decorator=\"FormItem\"\n                      x-component=\"Input\"\n                    />\n                    <SchemaField.String\n                      name=\"ddd\"\n                      required\n                      title=\"输入框4\"\n                      x-decorator=\"FormItem\"\n                      x-component=\"Input\"\n                    />\n                  </SchemaField>\n                  <FormDialog.Footer>\n                    <span\n                      style={{ marginLeft: 4 }}\n                      onClick={() => {\n                        dialog.close()\n                      }}\n                    >\n                      扩展文案：{form.values.aaa}(点击关闭弹窗)\n                    </span>\n                  </FormDialog.Footer>\n                </FormLayout>\n              )\n            })\n            dialog\n              .forOpen((payload, next) => {\n                setTimeout(() => {\n                  next({\n                    initialValues: {\n                      aaa: '123',\n                    },\n                  })\n                }, 1000)\n              })\n              .forConfirm((payload, next) => {\n                setTimeout(() => {\n                  console.log(payload)\n                  next(payload)\n                }, 1000)\n              })\n              .forCancel((payload, next) => {\n                setTimeout(() => {\n                  console.log(payload)\n                  next(payload)\n                }, 1000)\n              })\n              .open()\n              .then(console.log)\n              .catch(console.error)\n          }}\n        >\n          点我打开表单\n        </Button>\n      </FormDialog.Portal>\n    </Context.Provider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { FormDialog, FormItem, FormLayout, Input } from '@formily/antd'\nimport { createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    aaa: {\n      type: 'string',\n      title: '输入框1',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    bbb: {\n      type: 'string',\n      title: '输入框2',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    ccc: {\n      type: 'string',\n      title: '输入框3',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    ddd: {\n      type: 'string',\n      title: '输入框4',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormDialog.Portal>\n      <Button\n        onClick={() => {\n          const dialog = FormDialog('弹窗表单', () => {\n            return (\n              <FormLayout labelCol={6} wrapperCol={10}>\n                <SchemaField schema={schema} />\n                <FormDialog.Footer>\n                  <span\n                    onClick={() => {\n                      dialog.close()\n                    }}\n                    style={{ marginLeft: 4 }}\n                  >\n                    扩展文案\n                  </span>\n                  (点击关闭弹窗)\n                </FormDialog.Footer>\n              </FormLayout>\n            )\n          })\n          dialog\n            .forOpen((payload, next) => {\n              setTimeout(() => {\n                next({\n                  initialValues: {\n                    aaa: '123',\n                  },\n                })\n              }, 1000)\n            })\n            .forConfirm((payload, next) => {\n              setTimeout(() => {\n                console.log(payload)\n                next(payload)\n              }, 1000)\n            })\n            .forCancel((payload, next) => {\n              setTimeout(() => {\n                console.log(payload)\n                next(payload)\n              }, 1000)\n            })\n            .open()\n            .then(console.log)\n        }}\n      >\n        点我打开表单\n      </Button>\n    </FormDialog.Portal>\n  )\n}\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { FormDialog, FormItem, FormLayout, Input } from '@formily/antd'\nimport { Field } from '@formily/react'\nimport { Button } from 'antd'\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        const dialog = FormDialog('弹窗表单', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={10}>\n              <Field\n                name=\"aaa\"\n                required\n                title=\"输入框1\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"bbb\"\n                required\n                title=\"输入框2\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"ccc\"\n                required\n                title=\"输入框3\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"ddd\"\n                required\n                title=\"输入框4\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <FormDialog.Footer>\n                <span\n                  onClick={() => {\n                    dialog.close()\n                  }}\n                  style={{ marginLeft: 4 }}\n                >\n                  扩展文案\n                </span>\n                (点击关闭弹窗)\n              </FormDialog.Footer>\n            </FormLayout>\n          )\n        })\n        dialog\n          .forOpen((payload, next) => {\n            setTimeout(() => {\n              next({\n                initialValues: {\n                  aaa: '123',\n                },\n              })\n            }, 1000)\n          })\n          .forConfirm((payload, next) => {\n            setTimeout(() => {\n              console.log(payload)\n              next(payload)\n            }, 1000)\n          })\n          .forCancel((payload, next) => {\n            setTimeout(() => {\n              console.log(payload)\n              next(payload)\n            }, 1000)\n          })\n          .open()\n          .then(console.log)\n      }}\n    >\n      点我打开表单\n    </Button>\n  )\n}\n```\n\n## API\n\n### FormDialog\n\n```ts pure\nimport { IFormProps, Form } from '@formily/core'\n\ntype FormDialogRenderer =\n  | React.ReactElement\n  | ((form: Form) => React.ReactElement)\n\ntype ModalTitle = string | number | React.ReactElement\n\ninterface IFormDialog {\n  forOpen(\n    middleware: (\n      props: IFormProps,\n      next: (props?: IFormProps) => Promise<any>\n    ) => any\n  ): any //中间件拦截器，可以拦截Dialog打开\n  forConfirm(\n    middleware: (props: Form, next: (props?: Form) => Promise<any>) => any\n  ): any //中间件拦截器，可以拦截Dialog确认\n  forCancel(\n    middleware: (props: Form, next: (props?: Form) => Promise<any>) => any\n  ): any //中间件拦截器，可以拦截Dialog取消\n  //打开弹窗，接收表单属性，可以传入initialValues/values/effects etc.\n  open(props: IFormProps): Promise<any> //返回表单数据\n  //关闭弹窗\n  close(): void\n}\n\ninterface IModalProps extends ModalProps {\n  onOk?: (event: React.MouseEvent<HTMLElement>) => void | boolean // return false can prevent onOk\n  onCancel?: (event: React.MouseEvent<HTMLElement>) => void | boolean // return false can prevent onCancel\n  loadingText?: React.ReactNode\n}\n\ninterface FormDialog {\n  (title: IModalProps, id: string, renderer: FormDialogRenderer): IFormDialog\n  (title: IModalProps, renderer: FormDialogRenderer): IFormDialog\n  (title: ModalTitle, id: string, renderer: FormDialogRenderer): IFormDialog\n  (title: ModalTitle, renderer: FormDialogRenderer): IFormDialog\n}\n```\n\n`ModalProps`类型定义参考 ant design [Modal API](https://ant.design/components/modal-cn/#API)\n\n### FormDialog.Footer\n\n无属性，只接收子节点\n\n### FormDialog.Portal\n\n接收可选的 id 属性，默认值为`form-dialog`，如果一个应用存在多个 prefixCls，不同区域的弹窗内部 prefixCls 不一样，那推荐指定 id 为区域级 id\n"
  },
  {
    "path": "packages/antd/docs/components/FormDrawer.md",
    "content": "# FormDrawer\n\n> Drawer form, mainly used in simple event to open form scene\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  FormDrawer,\n  FormItem,\n  FormLayout,\n  Input,\n  Submit,\n  Reset,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        FormDrawer('Drawer Form', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={10}>\n              <SchemaField>\n                <SchemaField.String\n                  name=\"aaa\"\n                  required\n                  title=\"input box 1\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"bbb\"\n                  required\n                  title=\"input box 2\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"ccc\"\n                  required\n                  title=\"input box 3\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"ddd\"\n                  required\n                  title=\"input box 4\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n              </SchemaField>\n              <FormDrawer.Extra>\n                <FormButtonGroup align=\"right\">\n                  <Submit\n                    onSubmit={() => {\n                      return new Promise((resolve) => {\n                        setTimeout(resolve, 1000)\n                      })\n                    }}\n                  >\n                    Submit\n                  </Submit>\n                  <Reset>Reset</Reset>\n                </FormButtonGroup>\n              </FormDrawer.Extra>\n            </FormLayout>\n          )\n        })\n          .forOpen((props, next) => {\n            setTimeout(() => {\n              next({\n                initialValues: {\n                  aaa: '123',\n                },\n              })\n            }, 1000)\n          })\n          .open()\n          .then(console.log)\n      }}\n    >\n      Click me to open the form\n    </Button>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  FormDrawer,\n  FormItem,\n  FormLayout,\n  Input,\n  Submit,\n  Reset,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    aaa: {\n      type: 'string',\n      title: 'input box 1',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    bbb: {\n      type: 'string',\n      title: 'input box 2',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    ccc: {\n      type: 'string',\n      title: 'input box 3',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    ddd: {\n      type: 'string',\n      title: 'input box 4',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        FormDrawer('Pop-up form', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={10}>\n              <SchemaField schema={schema} />\n              <FormDrawer.Extra>\n                <FormButtonGroup align=\"right\">\n                  <Submit\n                    onSubmit={() => {\n                      return new Promise((resolve) => {\n                        setTimeout(resolve, 1000)\n                      })\n                    }}\n                  >\n                    Submit\n                  </Submit>\n                  <Reset>Reset</Reset>\n                </FormButtonGroup>\n              </FormDrawer.Extra>\n            </FormLayout>\n          )\n        })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      Click me to open the form\n    </Button>\n  )\n}\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport {\n  FormDrawer,\n  FormItem,\n  FormLayout,\n  Input,\n  Submit,\n  Reset,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { Field } from '@formily/react'\nimport { Button } from 'antd'\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        FormDrawer('Pop-up form', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={10}>\n              <Field\n                name=\"aaa\"\n                required\n                title=\"input box 1\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"bbb\"\n                required\n                title=\"input box 2\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"ccc\"\n                required\n                title=\"input box 3\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"ddd\"\n                required\n                title=\"input box 4\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <FormDrawer.Extra>\n                <FormButtonGroup align=\"right\">\n                  <Submit\n                    onSubmit={() => {\n                      return new Promise((resolve) => {\n                        setTimeout(resolve, 1000)\n                      })\n                    }}\n                  >\n                    Submit\n                  </Submit>\n                  <Reset>Reset</Reset>\n                </FormButtonGroup>\n              </FormDrawer.Extra>\n            </FormLayout>\n          )\n        })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      Click me to open the form\n    </Button>\n  )\n}\n```\n\n## API\n\n### FormDrawer\n\n```ts pure\nimport { IFormProps, Form } from '@formily/core'\n\ntype FormDrawerRenderer =\n  | React.ReactElement\n  | ((form: Form) => React.ReactElement)\n\ninterface IFormDrawer {\n  forOpen(\n    middleware: (\n      props: IFormProps,\n      next: (props?: IFormProps) => Promise<any>\n    ) => any\n  ): any //Middleware interceptor, can intercept Drawer to open\n  //Open the pop-up window to receive form attributes, you can pass in initialValues/values/effects etc.\n  open(props: IFormProps): Promise<any> //return form data\n  //Close the pop-up window\n  close(): void\n}\n\nexport interface IDrawerProps extends DrawerProps {\n  onClose?: (e: EventType) => void | boolean // return false can prevent onClose\n  loadingText?: React.ReactNode\n}\n\ninterface FormDrawer {\n  (title: IDrawerProps, id: string, renderer: FormDrawerRenderer): IFormDrawer\n  (title: IDrawerProps, renderer: FormDrawerRenderer): IFormDrawer\n  (title: ModalTitle, id: string, renderer: FormDrawerRenderer): IFormDrawer\n  (title: ModalTitle, renderer: FormDrawerRenderer): IFormDrawer\n}\n```\n\n`DrawerProps` type definition reference ant design [Drawer API](https://ant.design/components/drawer-cn/#API)\n\n### FormDrawer.Extra\n\nNo attributes, only child nodes are received\n\n### FormDrawer.Footer\n\nNo attributes, only child nodes are received\n\n### FormDrawer.Portal\n\nReceive an optional id attribute, the default value is `form-drawer`, if there are multiple prefixCls in an application, and the prefixCls in the pop-up window of different regions are different, then it is recommended to specify the id as the region-level id\n"
  },
  {
    "path": "packages/antd/docs/components/FormDrawer.zh-CN.md",
    "content": "# FormDrawer\n\n> 抽屉表单，主要用在简单的事件打开表单场景\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormDrawer,\n  FormItem,\n  FormLayout,\n  Input,\n  Submit,\n  Reset,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        FormDrawer('抽屉表单', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={10}>\n              <SchemaField>\n                <SchemaField.String\n                  name=\"aaa\"\n                  required\n                  title=\"输入框1\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"bbb\"\n                  required\n                  title=\"输入框2\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"ccc\"\n                  required\n                  title=\"输入框3\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"ddd\"\n                  required\n                  title=\"输入框4\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n              </SchemaField>\n              <FormDrawer.Extra>\n                <FormButtonGroup align=\"right\">\n                  <Submit\n                    onSubmit={() => {\n                      return new Promise((resolve) => {\n                        setTimeout(resolve, 1000)\n                      })\n                    }}\n                  >\n                    提交\n                  </Submit>\n                  <Reset>重置</Reset>\n                </FormButtonGroup>\n              </FormDrawer.Extra>\n            </FormLayout>\n          )\n        })\n          .forOpen((props, next) => {\n            setTimeout(() => {\n              next()\n            }, 1000)\n          })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      点我打开表单\n    </Button>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormDrawer,\n  FormItem,\n  FormLayout,\n  Input,\n  Submit,\n  Reset,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    aaa: {\n      type: 'string',\n      title: '输入框1',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    bbb: {\n      type: 'string',\n      title: '输入框2',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    ccc: {\n      type: 'string',\n      title: '输入框3',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    ddd: {\n      type: 'string',\n      title: '输入框4',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        FormDrawer('弹窗表单', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={10}>\n              <SchemaField schema={schema} />\n              <FormDrawer.Extra>\n                <FormButtonGroup align=\"right\">\n                  <Submit\n                    onSubmit={() => {\n                      return new Promise((resolve) => {\n                        setTimeout(resolve, 1000)\n                      })\n                    }}\n                  >\n                    提交\n                  </Submit>\n                  <Reset>重置</Reset>\n                </FormButtonGroup>\n              </FormDrawer.Extra>\n            </FormLayout>\n          )\n        })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      点我打开表单\n    </Button>\n  )\n}\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormDrawer,\n  FormItem,\n  FormLayout,\n  Input,\n  Submit,\n  Reset,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { Field } from '@formily/react'\nimport { Button } from 'antd'\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        FormDrawer('弹窗表单', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={10}>\n              <Field\n                name=\"aaa\"\n                required\n                title=\"输入框1\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"bbb\"\n                required\n                title=\"输入框2\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"ccc\"\n                required\n                title=\"输入框3\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"ddd\"\n                required\n                title=\"输入框4\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <FormDrawer.Extra>\n                <FormButtonGroup align=\"right\">\n                  <Submit\n                    onSubmit={() => {\n                      return new Promise((resolve) => {\n                        setTimeout(resolve, 1000)\n                      })\n                    }}\n                  >\n                    提交\n                  </Submit>\n                  <Reset>重置</Reset>\n                </FormButtonGroup>\n              </FormDrawer.Extra>\n            </FormLayout>\n          )\n        })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      点我打开表单\n    </Button>\n  )\n}\n```\n\n## API\n\n### FormDrawer\n\n```ts pure\nimport { IFormProps, Form } from '@formily/core'\n\ntype FormDrawerRenderer =\n  | React.ReactElement\n  | ((form: Form) => React.ReactElement)\n\ninterface IFormDrawer {\n  forOpen(\n    middleware: (\n      props: IFormProps,\n      next: (props?: IFormProps) => Promise<any>\n    ) => any\n  ): any //中间件拦截器，可以拦截Drawer打开\n  //打开弹窗，接收表单属性，可以传入initialValues/values/effects etc.\n  open(props: IFormProps): Promise<any> //返回表单数据\n  //关闭弹窗\n  close(): void\n}\n\nexport interface IDrawerProps extends DrawerProps {\n  onClose?: (e: EventType) => void | boolean // return false can prevent onClose\n  loadingText?: React.ReactNode\n}\n\ninterface FormDrawer {\n  (title: IDrawerProps, id: string, renderer: FormDrawerRenderer): IFormDrawer\n  (title: IDrawerProps, renderer: FormDrawerRenderer): IFormDrawer\n  (title: ModalTitle, id: string, renderer: FormDrawerRenderer): IFormDrawer\n  (title: ModalTitle, renderer: FormDrawerRenderer): IFormDrawer\n}\n```\n\n`DrawerProps`类型定义参考 ant design [Drawer API](https://ant.design/components/drawer-cn/#API)\n\n### FormDrawer.Extra\n\n无属性，只接收子节点\n\n### FormDrawer.Footer\n\n无属性，只接收子节点\n\n### FormDrawer.Portal\n\n接收可选的 id 属性，默认值为`form-drawer`，如果一个应用存在多个 prefixCls，不同区域的弹窗内部 prefixCls 不一样，那推荐指定 id 为区域级 id\n"
  },
  {
    "path": "packages/antd/docs/components/FormGrid.md",
    "content": "# FormGrid\n\n> FormGrid component\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { FormItem, Input, FormGrid } from '@formily/antd'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { createForm } from '@formily/core'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    FormGrid,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Void\n          x-component=\"FormGrid\"\n          x-component-props={{\n            maxColumns: 3,\n            minColumns: 2,\n          }}\n        >\n          <SchemaField.String\n            name=\"aaa\"\n            title=\"aaa\"\n            x-decorator=\"FormItem\"\n            x-decorator-props={{ gridSpan: 2 }}\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"bbb\"\n            title=\"bbb\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"ccc\"\n            title=\"ccc\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"ddd\"\n            title=\"ddd\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"eee\"\n            title=\"eee\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"fff\"\n            title=\"fff\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"ggg\"\n            title=\"ggg\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n        </SchemaField.Void>\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { FormItem, Input, FormGrid } from '@formily/antd'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { createForm } from '@formily/core'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    FormGrid,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    grid: {\n      type: 'void',\n      'x-component': 'FormGrid',\n      'x-component-props': {\n        minColumns: [4, 6, 10],\n      },\n      properties: {\n        aaa: {\n          type: 'string',\n          title: 'AAA',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        bbb: {\n          type: 'string',\n          title: 'BBB',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ccc: {\n          type: 'string',\n          title: 'CCC',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ddd: {\n          type: 'string',\n          title: 'DDD',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        eee: {\n          type: 'string',\n          title: 'EEE',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        fff: {\n          type: 'string',\n          title: 'FFF',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ggg: {\n          type: 'string',\n          title: 'GGG',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n    </FormProvider>\n  )\n}\n```\n\n## Native case\n\n```tsx\nimport React from 'react'\nimport { FormGrid } from '@formily/antd'\n\nconst { GridColumn } = FormGrid\nconst Cell = ({ children }) => {\n  return (\n    <div\n      style={{\n        backgroundColor: '#AAA',\n        color: '#FFF',\n        height: 30,\n        display: 'flex',\n        alignItems: 'center',\n        padding: '0 10px',\n      }}\n    >\n      {children}\n    </div>\n  )\n}\nexport default () => {\n  return (\n    <React.Fragment>\n      <p>maxColumns 3 + minColumns 2</p>\n      <FormGrid maxColumns={3} minColumns={2} columnGap={4}>\n        <GridColumn gridSpan={4}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>maxColumns 3</p>\n      <FormGrid maxColumns={3} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>minColumns 2</p>\n      <FormGrid minColumns={2} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>Null</p>\n      <FormGrid columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>minWidth 150 +maxColumns 3</p>\n      <FormGrid minWidth={150} maxColumns={3} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>maxWidth 120+minColumns 2</p>\n      <FormGrid maxWidth={120} minColumns={2} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>maxWidth 120 + gridSpan -1</p>\n      <FormGrid maxWidth={120} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn gridSpan={-1}>\n          <Cell>3</Cell>\n        </GridColumn>\n      </FormGrid>\n    </React.Fragment>\n  )\n}\n```\n\n## Query Form case\n\n```tsx\nimport React, { useMemo, Fragment } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider, observer } from '@formily/react'\nimport {\n  Form,\n  Input,\n  Select,\n  DatePicker,\n  FormItem,\n  FormGrid,\n  Submit,\n  Reset,\n  FormButtonGroup,\n} from '@formily/antd'\n\nconst useCollapseGrid = (maxRows: number) => {\n  const grid = useMemo(\n    () =>\n      FormGrid.createFormGrid({\n        maxColumns: 4,\n        maxWidth: 240,\n        maxRows: maxRows,\n        shouldVisible: (node, grid) => {\n          if (node.index === grid.childSize - 1) return true\n          if (grid.maxRows === Infinity) return true\n          return node.shadowRow < maxRows + 1\n        },\n      }),\n    []\n  )\n  const expanded = grid.maxRows === Infinity\n  const realRows = grid.shadowRows\n  const computeRows = grid.fullnessLastColumn\n    ? grid.shadowRows - 1\n    : grid.shadowRows\n\n  const toggle = () => {\n    if (grid.maxRows === Infinity) {\n      grid.maxRows = maxRows\n    } else {\n      grid.maxRows = Infinity\n    }\n  }\n  const takeType = () => {\n    if (realRows < maxRows + 1) return 'incomplete-wrap'\n    if (computeRows > maxRows) return 'collapsible'\n    return 'complete-wrap'\n  }\n  return {\n    grid,\n    expanded,\n    toggle,\n    type: takeType(),\n  }\n}\n\nconst QueryForm: React.FC = observer((props) => {\n  const { grid, expanded, toggle, type } = useCollapseGrid(1)\n\n  const renderActions = () => {\n    return (\n      <Fragment>\n        <Submit onSubmit={console.log}>Query</Submit>\n        <Reset>Reset</Reset>\n      </Fragment>\n    )\n  }\n\n  const renderButtonGroup = () => {\n    if (type === 'incomplete-wrap') {\n      return (\n        <FormButtonGroup.FormItem>\n          <FormButtonGroup>{renderActions()}</FormButtonGroup>\n        </FormButtonGroup.FormItem>\n      )\n    }\n    if (type === 'collapsible') {\n      return (\n        <Fragment>\n          <FormButtonGroup>\n            <a\n              href=\"\"\n              onClick={(e) => {\n                e.preventDefault()\n                toggle()\n              }}\n            >\n              {expanded ? 'Fold' : 'UnFold'}\n            </a>\n          </FormButtonGroup>\n          <FormButtonGroup align=\"right\">{renderActions()}</FormButtonGroup>\n        </Fragment>\n      )\n    }\n    return (\n      <FormButtonGroup align=\"right\" style={{ display: 'flex', width: '100%' }}>\n        {renderActions()}\n      </FormButtonGroup>\n    )\n  }\n\n  return (\n    <Form {...props} layout=\"vertical\" feedbackLayout=\"terse\">\n      <FormGrid grid={grid}>\n        {props.children}\n        <FormGrid.GridColumn\n          gridSpan={-1}\n          style={{ display: 'flex', justifyContent: 'space-between' }}\n        >\n          {renderButtonGroup()}\n        </FormGrid.GridColumn>\n      </FormGrid>\n    </Form>\n  )\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    QueryForm,\n    Input,\n    Select,\n    DatePicker,\n    FormItem,\n  },\n})\n\nexport default () => {\n  const form = useMemo(() => createForm(), [])\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Object x-component=\"QueryForm\">\n          <SchemaField.String\n            name=\"input1\"\n            title=\"Input 1\"\n            x-component=\"Input\"\n            x-decorator=\"FormItem\"\n          />\n          <SchemaField.String\n            name=\"input2\"\n            title=\"Input 2\"\n            x-component=\"Input\"\n            x-decorator=\"FormItem\"\n          />\n\n          <SchemaField.String\n            name=\"select1\"\n            title=\"Select 1\"\n            x-component=\"Select\"\n            x-decorator=\"FormItem\"\n          />\n          <SchemaField.String\n            name=\"select2\"\n            title=\"Select 2\"\n            x-component=\"Select\"\n            x-decorator=\"FormItem\"\n          />\n          <SchemaField.String\n            name=\"date\"\n            title=\"DatePicker\"\n            x-component=\"DatePicker\"\n            x-decorator=\"FormItem\"\n          />\n          <SchemaField.String\n            name=\"dateRange\"\n            title=\"DatePicker.RangePicker\"\n            x-component=\"DatePicker.RangePicker\"\n            x-decorator=\"FormItem\"\n            x-decorator-props={{\n              gridSpan: 2,\n            }}\n          />\n          <SchemaField.String\n            name=\"select3\"\n            title=\"Select 3\"\n            x-component=\"Select\"\n            x-decorator=\"FormItem\"\n          />\n        </SchemaField.Object>\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormGrid\n\n| Property name | Type                   | Description                                                                       | Default value     |\n| ------------- | ---------------------- | --------------------------------------------------------------------------------- | ----------------- |\n| minWidth      | `number \\| number[]`   | Minimum element width                                                             | 100               |\n| maxWidth      | `number \\| number[]`   | Maximum element width                                                             | -                 |\n| minColumns    | `number \\| number[]`   | Minimum number of columns                                                         | 0                 |\n| maxColumns    | `number \\| number[]`   | Maximum number of columns                                                         | -                 |\n| breakpoints   | number[]               | Container size breakpoints                                                        | `[720,1280,1920]` |\n| columnGap     | number                 | Column spacing                                                                    | 8                 |\n| rowGap        | number                 | Row spacing                                                                       | 4                 |\n| colWrap       | boolean                | Wrap                                                                              | true              |\n| strictAutoFit | boolean                | Is width strictly limited by maxWidth                                             | false             |\n| shouldVisible | `(node,grid)=>boolean` | Whether to show the current node                                                  | `()=>true`        |\n| grid          | `Grid`                 | Grid instance passed in from outside, used to implement more complex layout logic | -                 |\n\nnote:\n\n- minWidth takes priority over minColumn\n- maxWidth has priority over maxColumn\n- The array format of minWidth/maxWidth/minColumns/maxColumns represents the mapping with the breakpoint array\n\n### FormGrid.GridColumn\n\n| Property name | Type   | Description                                                                                                              | Default value |\n| ------------- | ------ | ------------------------------------------------------------------------------------------------------------------------ | ------------- |\n| gridSpan      | number | The number of columns spanned by the element, if it is -1, it will automatically fill the cell across columns in reverse | 1             |\n\n### FormGrid.createFormGrid\n\nRead the Grid instance from the context\n\n```ts\ninterface createFormGrid {\n  (props: IGridProps): Grid\n}\n```\n\n- IGridProps reference FormGrid properties\n- Grid instance attribute method reference https://github.com/alibaba/formily/tree/formily_next/packages/grid\n\n### FormGrid.useFormGrid\n\nRead the Grid instance from the context\n\n```ts\ninterface useFormGrid {\n  (): Grid\n}\n```\n\n- Grid instance attribute method reference https://github.com/alibaba/formily/tree/formily_next/packages/grid\n"
  },
  {
    "path": "packages/antd/docs/components/FormGrid.zh-CN.md",
    "content": "# FormGrid\n\n> FormGrid 组件\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { FormItem, Input, FormGrid } from '@formily/antd'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { createForm } from '@formily/core'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    FormGrid,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Void\n          x-component=\"FormGrid\"\n          x-component-props={{\n            maxColumns: 3,\n            minColumns: 2,\n          }}\n        >\n          <SchemaField.String\n            name=\"aaa\"\n            title=\"aaa\"\n            x-decorator=\"FormItem\"\n            x-decorator-props={{ gridSpan: 2 }}\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"bbb\"\n            title=\"bbb\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"ccc\"\n            title=\"ccc\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"ddd\"\n            title=\"ddd\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"eee\"\n            title=\"eee\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"fff\"\n            title=\"fff\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"ggg\"\n            title=\"ggg\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n        </SchemaField.Void>\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { FormItem, Input, FormGrid } from '@formily/antd'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { createForm } from '@formily/core'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    FormGrid,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    grid: {\n      type: 'void',\n      'x-component': 'FormGrid',\n      'x-component-props': {\n        minColumns: [4, 6, 10],\n      },\n      properties: {\n        aaa: {\n          type: 'string',\n          title: 'AAA',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        bbb: {\n          type: 'string',\n          title: 'BBB',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ccc: {\n          type: 'string',\n          title: 'CCC',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ddd: {\n          type: 'string',\n          title: 'DDD',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        eee: {\n          type: 'string',\n          title: 'EEE',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        fff: {\n          type: 'string',\n          title: 'FFF',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ggg: {\n          type: 'string',\n          title: 'GGG',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n    </FormProvider>\n  )\n}\n```\n\n## 原生 案例\n\n```tsx\nimport React from 'react'\nimport { FormGrid } from '@formily/antd'\n\nconst { GridColumn } = FormGrid\nconst Cell = ({ children }) => {\n  return (\n    <div\n      style={{\n        backgroundColor: '#AAA',\n        color: '#FFF',\n        height: 30,\n        display: 'flex',\n        alignItems: 'center',\n        padding: '0 10px',\n      }}\n    >\n      {children}\n    </div>\n  )\n}\nexport default () => {\n  return (\n    <React.Fragment>\n      <p>maxColumns 3 + minColumns 2</p>\n      <FormGrid maxColumns={3} minColumns={2} columnGap={4}>\n        <GridColumn gridSpan={4}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>maxColumns 3</p>\n      <FormGrid maxColumns={3} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>minColumns 2</p>\n      <FormGrid minColumns={2} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>Null</p>\n      <FormGrid columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>minWidth 150 +maxColumns 3</p>\n      <FormGrid minWidth={150} maxColumns={3} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>maxWidth 120+minColumns 2</p>\n      <FormGrid maxWidth={120} minColumns={2} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>maxWidth 120 + gridSpan -1</p>\n      <FormGrid maxWidth={120} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn gridSpan={-1}>\n          <Cell>3</Cell>\n        </GridColumn>\n      </FormGrid>\n    </React.Fragment>\n  )\n}\n```\n\n## 查询表单实现案例\n\n```tsx\nimport React, { useMemo, Fragment } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider, observer } from '@formily/react'\nimport {\n  Form,\n  Input,\n  Select,\n  DatePicker,\n  FormItem,\n  FormGrid,\n  Submit,\n  Reset,\n  FormButtonGroup,\n} from '@formily/antd'\n\nconst useCollapseGrid = (maxRows: number) => {\n  const grid = useMemo(\n    () =>\n      FormGrid.createFormGrid({\n        maxColumns: 4,\n        maxWidth: 240,\n        maxRows: maxRows,\n        shouldVisible: (node, grid) => {\n          if (node.index === grid.childSize - 1) return true\n          if (grid.maxRows === Infinity) return true\n          return node.shadowRow < maxRows + 1\n        },\n      }),\n    []\n  )\n  const expanded = grid.maxRows === Infinity\n  const realRows = grid.shadowRows\n  const computeRows = grid.fullnessLastColumn\n    ? grid.shadowRows - 1\n    : grid.shadowRows\n\n  const toggle = () => {\n    if (grid.maxRows === Infinity) {\n      grid.maxRows = maxRows\n    } else {\n      grid.maxRows = Infinity\n    }\n  }\n  const takeType = () => {\n    if (realRows < maxRows + 1) return 'incomplete-wrap'\n    if (computeRows > maxRows) return 'collapsible'\n    return 'complete-wrap'\n  }\n  return {\n    grid,\n    expanded,\n    toggle,\n    type: takeType(),\n  }\n}\n\nconst QueryForm: React.FC = observer((props) => {\n  const { grid, expanded, toggle, type } = useCollapseGrid(1)\n\n  const renderActions = () => {\n    return (\n      <Fragment>\n        <Submit onSubmit={console.log}>查询</Submit>\n        <Reset>重置</Reset>\n      </Fragment>\n    )\n  }\n\n  const renderButtonGroup = () => {\n    if (type === 'incomplete-wrap') {\n      return (\n        <FormButtonGroup.FormItem>\n          <FormButtonGroup>{renderActions()}</FormButtonGroup>\n        </FormButtonGroup.FormItem>\n      )\n    }\n    if (type === 'collapsible') {\n      return (\n        <Fragment>\n          <FormButtonGroup>\n            <a\n              href=\"\"\n              onClick={(e) => {\n                e.preventDefault()\n                toggle()\n              }}\n            >\n              {expanded ? '收起' : '展开'}\n            </a>\n          </FormButtonGroup>\n          <FormButtonGroup align=\"right\">{renderActions()}</FormButtonGroup>\n        </Fragment>\n      )\n    }\n    return (\n      <FormButtonGroup align=\"right\" style={{ display: 'flex', width: '100%' }}>\n        {renderActions()}\n      </FormButtonGroup>\n    )\n  }\n\n  return (\n    <Form {...props} layout=\"vertical\" feedbackLayout=\"terse\">\n      <FormGrid grid={grid}>\n        {props.children}\n        <FormGrid.GridColumn\n          gridSpan={-1}\n          style={{ display: 'flex', justifyContent: 'space-between' }}\n        >\n          {renderButtonGroup()}\n        </FormGrid.GridColumn>\n      </FormGrid>\n    </Form>\n  )\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    QueryForm,\n    Input,\n    Select,\n    DatePicker,\n    FormItem,\n  },\n})\n\nexport default () => {\n  const form = useMemo(() => createForm(), [])\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Object x-component=\"QueryForm\">\n          <SchemaField.String\n            name=\"input1\"\n            title=\"Input 1\"\n            x-component=\"Input\"\n            x-decorator=\"FormItem\"\n          />\n          <SchemaField.String\n            name=\"input2\"\n            title=\"Input 2\"\n            x-component=\"Input\"\n            x-decorator=\"FormItem\"\n          />\n\n          <SchemaField.String\n            name=\"select1\"\n            title=\"Select 1\"\n            x-component=\"Select\"\n            x-decorator=\"FormItem\"\n          />\n          <SchemaField.String\n            name=\"select2\"\n            title=\"Select 2\"\n            x-component=\"Select\"\n            x-decorator=\"FormItem\"\n          />\n          <SchemaField.String\n            name=\"date\"\n            title=\"DatePicker\"\n            x-component=\"DatePicker\"\n            x-decorator=\"FormItem\"\n          />\n          <SchemaField.String\n            name=\"dateRange\"\n            title=\"DatePicker.RangePicker\"\n            x-component=\"DatePicker.RangePicker\"\n            x-decorator=\"FormItem\"\n            x-decorator-props={{\n              gridSpan: 2,\n            }}\n          />\n          <SchemaField.String\n            name=\"select3\"\n            title=\"Select 3\"\n            x-component=\"Select\"\n            x-decorator=\"FormItem\"\n          />\n        </SchemaField.Object>\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormGrid\n\n| 属性名        | 类型                   | 描述                                                           | 默认值            |\n| ------------- | ---------------------- | -------------------------------------------------------------- | ----------------- |\n| minWidth      | `number \\| number[]`   | 元素最小宽度                                                   | 100               |\n| maxWidth      | `number \\| number[]`   | 元素最大宽度                                                   | -                 |\n| minColumns    | `number \\| number[]`   | 最小列数                                                       | 0                 |\n| maxColumns    | `number \\| number[]`   | 最大列数                                                       | -                 |\n| breakpoints   | number[]               | 容器尺寸断点                                                   | `[720,1280,1920]` |\n| columnGap     | number                 | 列间距                                                         | 8                 |\n| rowGap        | number                 | 行间距                                                         | 4                 |\n| colWrap       | boolean                | 自动换行                                                       | true              |\n| strictAutoFit | boolean                | GridItem 宽度是否严格受限于 maxWidth，不受限的话会自动占满容器 | false             |\n| shouldVisible | `(node,grid)=>boolean` | 是否需要显示当前节点                                           | `()=>true`        |\n| grid          | `Grid`                 | 外部传入 Grid 实例，用于实现更复杂的布局逻辑                   | -                 |\n\n注意：\n\n- minWidth 生效优先级高于 minColumn\n- maxWidth 优先级高于 maxColumn\n- minWidth/maxWidth/minColumns/maxColumns 的数组格式代表与断点数组映射\n\n### FormGrid.GridColumn\n\n| 属性名   | 类型   | 描述                                                 | 默认值 |\n| -------- | ------ | ---------------------------------------------------- | ------ |\n| gridSpan | number | 元素所跨列数，如果为-1，那么会自动反向跨列填补单元格 | 1      |\n\n### FormGrid.createFormGrid\n\n从上下文中读取 Grid 实例\n\n```ts\ninterface createFormGrid {\n  (props: IGridProps): Grid\n}\n```\n\n- IGridProps 参考 FormGrid 属性\n- Grid 实例属性方法参考 https://github.com/alibaba/formily/tree/formily_next/packages/grid\n\n### FormGrid.useFormGrid\n\n从上下文中读取 Grid 实例\n\n```ts\ninterface useFormGrid {\n  (): Grid\n}\n```\n\n- Grid 实例属性方法参考 https://github.com/alibaba/formily/tree/formily_next/packages/grid\n"
  },
  {
    "path": "packages/antd/docs/components/FormItem.md",
    "content": "# FormItem\n\n> The brand-new FormItem component, compared to Antd's FormItem, it supports more functions. At the same time, it is positioned as a pure style component and does not manage the state of the form, so it will be lighter and more convenient for customization\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { Input, Select, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        required\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      title: 'input box',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"input\"\n      title=\"input box\"\n      required\n      decorator={[FormItem]}\n      component={[\n        Input,\n        {\n          style: {\n            width: 240,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Commonly used attribute cases\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  FormItem,\n  NumberPicker,\n  Switch,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst Title = (props) => <h3>{props.text}</h3>\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Title,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: 'Display when label is empty' }}\n        />\n        <SchemaField.String\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n          }}\n        />\n        <SchemaField.String\n          title=\"\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n          }}\n        />\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: 'colon' }}\n        />\n        <SchemaField.String\n          title=\"default\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n        <SchemaField.String\n          title=\"no colon (colon=false)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            colon: false,\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: 'Fixed width settings' }}\n        />\n        <SchemaField.String\n          title=\"Fixed label width (labelWidth)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n          }}\n        />\n        <SchemaField.String\n          title=\"Fixed label width (labelWidth) overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow\"\n          description=\"description description\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            tooltip: 'Prompt Tip',\n            tooltipLayout: 'text',\n          }}\n        />\n        <SchemaField.String\n          title=\"Fixed label width (labelWidth) newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline\"\n          description=\"description description\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            labelWrap: true,\n            tooltip: 'Prompt Tip',\n          }}\n        />\n        <SchemaField.String\n          title=\"fixed content width (wrapperWidth)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            wrapperWidth: 300,\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: 'Alignment settings' }}\n        />\n        <SchemaField.String\n          title=\"labelLeft Alignment(labelAlign=left)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            labelAlign: 'left',\n          }}\n        />\n        <SchemaField.String\n          title=\"label right alignment (labelAlign=right default)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            labelAlign: 'right',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Content left aligned (wrapperAlign=left default)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            wrapperWidth: 240,\n            wrapperAlign: 'left',\n          }}\n        />\n        <SchemaField.String\n          title=\"Content align right (wrapperAlign=right)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            wrapperWidth: 240,\n            wrapperAlign: 'right',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"tooltip\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            tooltip: 'tooltip',\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: 'Is it full?' }}\n        />\n\n        <SchemaField.String\n          title=\"The default is not full (fullness=false)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n        />\n        <SchemaField.String\n          title=\"Fullness(fullness=true)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          x-decorator-props={{\n            fullness: true,\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: 'auxiliary information' }}\n        />\n\n        <SchemaField.String\n          title=\"Required asterisk\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            asterisk: true,\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n\n        <SchemaField.String\n          title=\"prefix\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            addonBefore: 'addonBefore',\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n        <SchemaField.String\n          title=\"suffix\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            addonAfter: 'addonAfter',\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Help information feedbackText\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackText: 'feedbackText',\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n\n        <SchemaField.String\n          title=\"extra information extra\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackText: 'feedbackText',\n            extra: 'extra',\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## Required style\n\n```tsx\nimport React, { useState } from 'react'\nimport { Input, FormItem, FormLayout } from '@formily/antd'\nimport { Radio } from 'antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  const [requiredMark, setRequiredMark] = useState(true)\n  return (\n    <div>\n      <p>\n        Required Mark：\n        <Radio.Group\n          value={requiredMark}\n          onChange={(e) => setRequiredMark(e.target.value)}\n        >\n          <Radio.Button value=\"optional\">optional</Radio.Button>\n          <Radio.Button value={true}>true</Radio.Button>\n          <Radio.Button value={false}>false</Radio.Button>\n        </Radio.Group>\n      </p>\n      <FormProvider form={form}>\n        <FormLayout requiredMark={requiredMark}>\n          <SchemaField>\n            <SchemaField.String\n              title=\"I am Required\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              title=\"I am Optional\"\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              default=\"When the field is not editable, always hide the required/optional flag\"\n              x-editable={false}\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              title=\"I am Required\"\n              required\n              default=\"Not editable\"\n              x-editable={false}\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              title=\"I am Optional\"\n              default=\"Not editable\"\n              x-editable={false}\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n          </SchemaField>\n        </FormLayout>\n      </FormProvider>\n    </div>\n  )\n}\n```\n\n## Borderless case\n\nSet to remove the component border\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  FormItem,\n  NumberPicker,\n  Switch,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst Title = (props) => <h3>{props.text}</h3>\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Title,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"input\"\n          title=\"Input\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"Select\"\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"Select\"\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"Cascader\"\n          title=\"Cascader\"\n          x-decorator=\"FormItem\"\n          x-component=\"Cascader\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"DatePicker\"\n          title=\"DatePicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"NumberPicker\"\n          title=\"NumberPicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"NumberPicker\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"TreeSelect\"\n          title=\"TreeSelect\"\n          x-decorator=\"FormItem\"\n          x-component=\"TreeSelect\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.Boolean\n          name=\"Switch\"\n          title=\"Switch\"\n          x-decorator=\"FormItem\"\n          x-component=\"Switch\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## Embedded mode case\n\nSet the form component to inline mode\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  FormItem,\n  NumberPicker,\n  Switch,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst Title = (props) => <h3>{props.text}</h3>\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Title,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"input\"\n          title=\"Input\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"Select\"\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"Select\"\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"Cascader\"\n          title=\"Cascader\"\n          x-decorator=\"FormItem\"\n          x-component=\"Cascader\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"DatePicker\"\n          title=\"DatePicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"NumberPicker\"\n          title=\"NumberPicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"NumberPicker\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"TreeSelect\"\n          title=\"TreeSelect\"\n          x-decorator=\"FormItem\"\n          x-component=\"TreeSelect\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.Boolean\n          name=\"Switch\"\n          title=\"Switch\"\n          x-decorator=\"FormItem\"\n          x-component=\"Switch\"\n          required\n          x-decorator-props={{\n            inset: false,\n          }}\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## Feedback Customization Case\n\nThe button for specifying feedback can be passed in through `feedbackIcon`\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  TimePicker,\n  FormItem,\n  FormLayout,\n  NumberPicker,\n  Switch,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { CheckCircleFilled, LoadingOutlined } from '@ant-design/icons'\nconst Title = (props) => <h3>{props.text}</h3>\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    TimePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Title,\n    FormLayout,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          title=\"error status (feedbackStatus=error)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          description=\"description\"\n          x-decorator-props={{\n            feedbackStatus: 'error',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Warning Status(feedbackStatus=warning)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          description=\"description\"\n          x-decorator-props={{\n            feedbackStatus: 'warning',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Success Status (feedbackStatus=success)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          description=\"description\"\n          x-decorator-props={{\n            feedbackStatus: 'success',\n            feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Loading Status(feedbackStatus=pending)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          description=\"description\"\n          x-decorator-props={{\n            feedbackStatus: 'pending',\n            feedbackIcon: <LoadingOutlined style={{ color: '#1890ff' }} />,\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Status border style disabled(feedbackStatus=error)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          description=\"description\"\n          x-decorator-props={{\n            enableOutlineFeedback: false,\n            feedbackStatus: 'error',\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: 'Layout of feedback information' }}\n        />\n\n        <SchemaField.String\n          title=\"Compact mode required\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          required\n          x-decorator-props={{\n            feedbackLayout: 'terse',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Compact mode has feedback(feedbackLayout=terse)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'error',\n            feedbackText: 'error message',\n            feedbackLayout: 'terse',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Compact mode without feedback(feedbackLayout=terse)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackLayout: 'terse',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"loose mode (feedbackLayout=loose)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'error',\n            feedbackText: 'error message',\n            feedbackLayout: 'loose',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Popup Mode (feedbackLayout=popover)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'warning',\n            feedbackText: 'warning message',\n            feedbackLayout: 'popover',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Popup Mode (feedbackLayout=popover)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'error',\n            feedbackText: 'error message',\n            feedbackLayout: 'popover',\n          }}\n        />\n        <SchemaField.String\n          title=\"Popup Mode (feedbackLayout=popover)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'success',\n            feedbackText: 'success message',\n            feedbackLayout: 'popover',\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: 'Component adaptation' }}\n        />\n        <SchemaField.Void\n          x-component=\"FormLayout\"\n          x-component-props={{ layout: 'vertical' }}\n        >\n          <SchemaField.String\n            title=\"Select\"\n            x-decorator=\"FormItem\"\n            x-component=\"Select\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n\n          <SchemaField.String\n            title=\"DatePicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"DatePicker.RangePicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker.RangePicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"DatePicker.YearPicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker.YearPicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"DatePicker.MonthPicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker.MonthPicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"DatePicker.TimePicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"TimePicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"NumberPicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"NumberPicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n\n          <SchemaField.String\n            title=\"TreeSelect\"\n            x-decorator=\"FormItem\"\n            x-component=\"TreeSelect\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n\n          <SchemaField.String\n            title=\"Cascader\"\n            x-decorator=\"FormItem\"\n            x-component=\"Cascader\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n        </SchemaField.Void>\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## Size control case\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  FormItem,\n  NumberPicker,\n  Switch,\n} from '@formily/antd'\nimport { createForm, onFieldChange } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst Div = (props) => <div {...props} />\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Div,\n  },\n})\n\nconst form = createForm({\n  values: {\n    size: 'default',\n  },\n  effects: () => {\n    onFieldChange('size', ['value'], (field, form) => {\n      form.setFieldState('sizeWrap.*', (state) => {\n        if (state.decorator[1]) {\n          state.decorator[1].size = field.value\n        }\n      })\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"size\"\n          title=\"Radio.Group\"\n          x-decorator=\"FormItem\"\n          x-component=\"Radio.Group\"\n          enum={[\n            { value: 'small', label: 'Small' },\n            { value: 'default', label: 'Default' },\n            { value: 'large', label: 'Large' },\n          ]}\n        />\n        <SchemaField.Void name=\"sizeWrap\" x-component=\"Div\">\n          <SchemaField.String\n            name=\"input\"\n            title=\"Input\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            required\n          />\n          <SchemaField.String\n            name=\"select1\"\n            title=\"Multiple Select\"\n            x-decorator=\"FormItem\"\n            x-component=\"Select\"\n            enum={[\n              {\n                label: 'Option 1',\n                value: 1,\n              },\n              {\n                label: 'Option 2',\n                value: 2,\n              },\n            ]}\n            x-component-props={{\n              mode: 'multiple',\n              placeholder: 'Please choose',\n            }}\n            required\n          />\n          <SchemaField.String\n            name=\"select2\"\n            title=\"Select\"\n            x-decorator=\"FormItem\"\n            x-component=\"Select\"\n            enum={[\n              {\n                label: 'Option 1',\n                value: 1,\n              },\n              {\n                label: 'Option 2',\n                value: 2,\n              },\n            ]}\n            x-component-props={{\n              placeholder: 'Please choose',\n            }}\n            required\n          />\n          <SchemaField.String\n            name=\"Cascader\"\n            title=\"Cascader\"\n            x-decorator=\"FormItem\"\n            x-component=\"Cascader\"\n            required\n          />\n          <SchemaField.String\n            name=\"DatePicker\"\n            title=\"DatePicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker\"\n            required\n          />\n          <SchemaField.String\n            name=\"NumberPicker\"\n            title=\"NumberPicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"NumberPicker\"\n            required\n          />\n          <SchemaField.String\n            name=\"TreeSelect\"\n            title=\"TreeSelect\"\n            x-decorator=\"FormItem\"\n            x-component=\"TreeSelect\"\n            required\n          />\n          <SchemaField.Boolean\n            name=\"Switch\"\n            title=\"Switch\"\n            x-decorator=\"FormItem\"\n            x-component=\"Switch\"\n            required\n          />\n        </SchemaField.Void>\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormItem\n\n| Property name         | Type                                                   | Description                                                                                                                                   | Default value       |\n| --------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- |\n| label                 | ReactNode                                              | label                                                                                                                                         | -                   |\n| style                 | CSSProperties                                          | Style                                                                                                                                         | -                   |\n| labelStyle            | CSSProperties                                          | Label style                                                                                                                                   | -                   |\n| wrapperStyle          | CSSProperties                                          | Component container style                                                                                                                     | -                   |\n| className             | string                                                 | Component style class name                                                                                                                    | -                   |\n| colon                 | boolean                                                | colon                                                                                                                                         | true                |\n| tooltip               | ReactNode                                              | Question mark prompt                                                                                                                          | -                   |\n| tooltipLayout         | `\"icon\" \\| \"text\"`                                     | Ask the prompt layout                                                                                                                         | `\"icon\"`            |\n| tooltipIcon           | ReactNode                                              | Ask the prompt icon                                                                                                                           | `?`                 |\n| labelAlign            | `\"left\"` \\| `\"right\"`                                  | Label text alignment                                                                                                                          | `\"right\"`           |\n| labelWrap             | boolean                                                | Label change, otherwise an ellipsis appears, hover has tooltip                                                                                | false               |\n| labelWidth            | `number \\| string`                                     | Label fixed width                                                                                                                             | -                   |\n| wrapperWidth          | `number \\| string`                                     | Content fixed width                                                                                                                           | -                   |\n| labelCol              | number                                                 | The number of columns occupied by the label grid, and the number of content columns add up to 24                                              | -                   |\n| wrapperCol            | number                                                 | The number of columns occupied by the content grid, and the number of label columns add up to 24                                              | -                   |\n| wrapperAlign          | `\"left\"` \\| `\"right\"`                                  | Content text alignment                                                                                                                        | `\"left\"`            |\n| wrapperWrap           | boolean                                                | Change the content, otherwise an ellipsis appears, and hover has tooltip                                                                      | false               |\n| fullness              | boolean                                                | fullness                                                                                                                                      | false               |\n| addonBefore           | ReactNode                                              | Prefix content                                                                                                                                | -                   |\n| addonAfter            | ReactNode                                              | Suffix content                                                                                                                                | -                   |\n| size                  | `\"small\"` \\| `\"default\"` \\| `\"large\"`                  | size                                                                                                                                          | -                   |\n| inset                 | boolean                                                | Is it an inline layout                                                                                                                        | false               |\n| extra                 | ReactNode                                              | Extended description script                                                                                                                   | -                   |\n| feedbackText          | ReactNode                                              | Feedback Case                                                                                                                                 | -                   |\n| feedbackLayout        | `\"loose\"` \\| `\"terse\"` \\| `\"popover\" \\| \"none\"`        | Feedback layout                                                                                                                               | -                   |\n| feedbackStatus        | `\"error\"` \\| `\"warning\"` \\| `\"success\"` \\| `\"pending\"` | Feedback layout                                                                                                                               | -                   |\n| feedbackIcon          | ReactNode                                              | Feedback icon                                                                                                                                 | -                   |\n| enableOutlineFeedback | boolean                                                | Enable the border color style of the abnormal state, it is recommended to turn off this item when there is a sub-form in the custom component | true                |\n| getPopupContainer     | function(triggerNode)                                  | when `feedbackLayout` is popover， The DOM container of the tip, the default behavior is to create a div element in body                      | () => document.body |\n| asterisk              | boolean                                                | Asterisk reminder                                                                                                                             | -                   |\n| gridSpan              | number                                                 | Grid layout occupies width                                                                                                                    | -                   |\n| bordered              | boolean                                                | Is there a border                                                                                                                             | -                   |\n\n### FormItem.BaseItem\n\nPure style components, the properties are the same as FormItem, and Formily Core does not do state bridging. It is mainly used for scenarios that need to rely on the style layout capabilities of FormItem but do not want to access the Field state.\n"
  },
  {
    "path": "packages/antd/docs/components/FormItem.zh-CN.md",
    "content": "# FormItem\n\n> 全新的 FormItem 组件，相比于 Antd 的 FormItem，它支持的功能更多，同时它的定位是纯样式组件，不管理表单状态，所以也会更轻量，更方便定制\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Input, Select, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        required\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      title: '输入框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"input\"\n      title=\"输入框\"\n      required\n      decorator={[FormItem]}\n      component={[\n        Input,\n        {\n          style: {\n            width: 240,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 常用属性案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  FormItem,\n  NumberPicker,\n  Switch,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst Title = (props) => <h3>{props.text}</h3>\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Title,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: 'label为空时的展示' }}\n        />\n        <SchemaField.String\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n          }}\n        />\n        <SchemaField.String\n          title=\"\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n          }}\n        />\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: '冒号' }}\n        />\n        <SchemaField.String\n          title=\"默认\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n        <SchemaField.String\n          title=\"无冒号(colon=false)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            colon: false,\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: '固定宽度设置' }}\n        />\n        <SchemaField.String\n          title=\"固定label宽度(labelWidth)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n          }}\n        />\n        <SchemaField.String\n          title=\"固定label宽度(labelWidth)溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出\"\n          description=\"描述描述\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            tooltip: '提示提示',\n            tooltipLayout: 'text',\n          }}\n        />\n        <SchemaField.String\n          title=\"固定label宽度(labelWidth)换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行\"\n          description=\"描述描述\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            labelWrap: true,\n            tooltip: '提示提示',\n          }}\n        />\n        <SchemaField.String\n          title=\"固定内容宽度(wrapperWidth)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            wrapperWidth: 300,\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: '对齐方式设置' }}\n        />\n        <SchemaField.String\n          title=\"label左对齐(labelAlign=left)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            labelAlign: 'left',\n          }}\n        />\n        <SchemaField.String\n          title=\"label右对齐(labelAlign=right默认)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            labelAlign: 'right',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"内容左对齐(wrapperAlign=left默认)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            wrapperWidth: 240,\n            wrapperAlign: 'left',\n          }}\n        />\n        <SchemaField.String\n          title=\"内容右对齐(wrapperAlign=right)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            wrapperWidth: 240,\n            wrapperAlign: 'right',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"tooltip\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            tooltip: 'tooltip',\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: '是否撑满' }}\n        />\n\n        <SchemaField.String\n          title=\"默认不撑满(fullness=false)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n        />\n        <SchemaField.String\n          title=\"撑满(fullness=true)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          x-decorator-props={{\n            fullness: true,\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: '辅助信息' }}\n        />\n\n        <SchemaField.String\n          title=\"必填星号\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            asterisk: true,\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n\n        <SchemaField.String\n          title=\"前缀\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            addonBefore: 'addonBefore',\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n        <SchemaField.String\n          title=\"后缀\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            addonAfter: 'addonAfter',\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n\n        <SchemaField.String\n          title=\"帮助信息feedbackText\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackText: 'feedbackText',\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n\n        <SchemaField.String\n          title=\"额外信息extra\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackText: 'feedbackText',\n            extra: 'extra',\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## 必填样式\n\n```tsx\nimport React, { useState } from 'react'\nimport { Input, FormItem, FormLayout } from '@formily/antd'\nimport { Radio, ConfigProvider } from 'antd'\nimport zhCN from 'antd/es/locale/zh_CN'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  const [requiredMark, setRequiredMark] = useState(true)\n  return (\n    <ConfigProvider locale={zhCN}>\n      <p>\n        Required Mark：\n        <Radio.Group\n          value={requiredMark}\n          onChange={(e) => setRequiredMark(e.target.value)}\n        >\n          <Radio.Button value=\"optional\">optional</Radio.Button>\n          <Radio.Button value={true}>true</Radio.Button>\n          <Radio.Button value={false}>false</Radio.Button>\n        </Radio.Group>\n      </p>\n      <FormProvider form={form}>\n        <FormLayout requiredMark={requiredMark}>\n          <SchemaField>\n            <SchemaField.String\n              title=\"我是必填项\"\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              title=\"我是选填项\"\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              default=\"字段不可编辑时，始终隐藏必填/选填标识\"\n              x-editable={false}\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              title=\"我是必填项\"\n              required\n              default=\"不可编辑\"\n              x-editable={false}\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              title=\"我是选填项\"\n              default=\"不可编辑\"\n              x-editable={false}\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n          </SchemaField>\n        </FormLayout>\n      </FormProvider>\n    </ConfigProvider>\n  )\n}\n```\n\n## 无边框案例\n\n设置去除组件边框\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  FormItem,\n  NumberPicker,\n  Switch,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst Title = (props) => <h3>{props.text}</h3>\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Title,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"input\"\n          title=\"Input\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"Select\"\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"Select\"\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"Cascader\"\n          title=\"Cascader\"\n          x-decorator=\"FormItem\"\n          x-component=\"Cascader\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"DatePicker\"\n          title=\"DatePicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"NumberPicker\"\n          title=\"NumberPicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"NumberPicker\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"TreeSelect\"\n          title=\"TreeSelect\"\n          x-decorator=\"FormItem\"\n          x-component=\"TreeSelect\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.Boolean\n          name=\"Switch\"\n          title=\"Switch\"\n          x-decorator=\"FormItem\"\n          x-component=\"Switch\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## 内嵌模式案例\n\n设置表单组件为内嵌模式\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  FormItem,\n  NumberPicker,\n  Switch,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst Title = (props) => <h3>{props.text}</h3>\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Title,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"input\"\n          title=\"Input\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"Select\"\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"Select\"\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"Cascader\"\n          title=\"Cascader\"\n          x-decorator=\"FormItem\"\n          x-component=\"Cascader\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"DatePicker\"\n          title=\"DatePicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"NumberPicker\"\n          title=\"NumberPicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"NumberPicker\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"TreeSelect\"\n          title=\"TreeSelect\"\n          x-decorator=\"FormItem\"\n          x-component=\"TreeSelect\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.Boolean\n          name=\"Switch\"\n          title=\"Switch\"\n          x-decorator=\"FormItem\"\n          x-component=\"Switch\"\n          required\n          x-decorator-props={{\n            inset: false,\n          }}\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## 反馈信息定制案例\n\n可通过 `feedbackIcon` 传入指定反馈的按钮\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  TimePicker,\n  FormItem,\n  FormLayout,\n  NumberPicker,\n  Switch,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { CheckCircleFilled, LoadingOutlined } from '@ant-design/icons'\nconst Title = (props) => <h3>{props.text}</h3>\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    TimePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Title,\n    FormLayout,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          title=\"错误状态(feedbackStatus=error)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          description=\"description\"\n          x-decorator-props={{\n            feedbackStatus: 'error',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"警告状态(feedbackStatus=warning)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          description=\"description\"\n          x-decorator-props={{\n            feedbackStatus: 'warning',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"成功状态(feedbackStatus=success)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          description=\"description\"\n          x-decorator-props={{\n            feedbackStatus: 'success',\n            feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n          }}\n        />\n\n        <SchemaField.String\n          title=\"加载状态(feedbackStatus=pending)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          description=\"description\"\n          x-decorator-props={{\n            feedbackStatus: 'pending',\n            feedbackIcon: <LoadingOutlined style={{ color: '#1890ff' }} />,\n          }}\n        />\n\n        <SchemaField.String\n          title=\"禁用错误状态边框样式(feedbackStatus=error)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          description=\"description\"\n          x-decorator-props={{\n            enableOutlineFeedback: false,\n            feedbackStatus: 'error',\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: '反馈信息的布局' }}\n        />\n\n        <SchemaField.String\n          title=\"紧凑模式required\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          required\n          x-decorator-props={{\n            feedbackLayout: 'terse',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"紧凑模式有feedback(feedbackLayout=terse)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'error',\n            feedbackText: 'error message',\n            feedbackLayout: 'terse',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"紧凑模式无feedback(feedbackLayout=terse)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackLayout: 'terse',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"松散模式(feedbackLayout=loose)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'error',\n            feedbackText: 'error message',\n            feedbackLayout: 'loose',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"弹出模式(feedbackLayout=popover)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'warning',\n            feedbackText: 'warning message',\n            feedbackLayout: 'popover',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"弹出模式(feedbackLayout=popover)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'error',\n            feedbackText: 'error message',\n            feedbackLayout: 'popover',\n          }}\n        />\n        <SchemaField.String\n          title=\"弹出模式(feedbackLayout=popover)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'success',\n            feedbackText: 'success message',\n            feedbackLayout: 'popover',\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: '组件的适配情况' }}\n        />\n        <SchemaField.Void\n          x-component=\"FormLayout\"\n          x-component-props={{ layout: 'vertical' }}\n        >\n          <SchemaField.String\n            title=\"Select\"\n            x-decorator=\"FormItem\"\n            x-component=\"Select\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n\n          <SchemaField.String\n            title=\"DatePicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"DatePicker.RangePicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker.RangePicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"DatePicker.YearPicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker.YearPicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"DatePicker.MonthPicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker.MonthPicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"DatePicker.TimePicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"TimePicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"NumberPicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"NumberPicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n\n          <SchemaField.String\n            title=\"TreeSelect\"\n            x-decorator=\"FormItem\"\n            x-component=\"TreeSelect\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n\n          <SchemaField.String\n            title=\"Cascader\"\n            x-decorator=\"FormItem\"\n            x-component=\"Cascader\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n        </SchemaField.Void>\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## 尺寸控制案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  FormItem,\n  NumberPicker,\n  Switch,\n} from '@formily/antd'\nimport { createForm, onFieldChange } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst Div = (props) => <div {...props} />\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Div,\n  },\n})\n\nconst form = createForm({\n  values: {\n    size: 'default',\n  },\n  effects: () => {\n    onFieldChange('size', ['value'], (field, form) => {\n      form.setFieldState('sizeWrap.*', (state) => {\n        if (state.decorator[1]) {\n          state.decorator[1].size = field.value\n        }\n      })\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"size\"\n          title=\"Radio.Group\"\n          x-decorator=\"FormItem\"\n          x-component=\"Radio.Group\"\n          enum={[\n            { value: 'small', label: 'Small' },\n            { value: 'default', label: 'Default' },\n            { value: 'large', label: 'Large' },\n          ]}\n        />\n        <SchemaField.Void name=\"sizeWrap\" x-component=\"Div\">\n          <SchemaField.String\n            name=\"input\"\n            title=\"Input\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            required\n          />\n          <SchemaField.String\n            name=\"select1\"\n            title=\"Multiple Select\"\n            x-decorator=\"FormItem\"\n            x-component=\"Select\"\n            enum={[\n              {\n                label: '选项1',\n                value: 1,\n              },\n              {\n                label: '选项2',\n                value: 2,\n              },\n            ]}\n            x-component-props={{\n              mode: 'multiple',\n              placeholder: '请选择',\n            }}\n            required\n          />\n          <SchemaField.String\n            name=\"select2\"\n            title=\"Select\"\n            x-decorator=\"FormItem\"\n            x-component=\"Select\"\n            enum={[\n              {\n                label: '选项1',\n                value: 1,\n              },\n              {\n                label: '选项2',\n                value: 2,\n              },\n            ]}\n            x-component-props={{\n              placeholder: '请选择',\n            }}\n            required\n          />\n          <SchemaField.String\n            name=\"Cascader\"\n            title=\"Cascader\"\n            x-decorator=\"FormItem\"\n            x-component=\"Cascader\"\n            required\n          />\n          <SchemaField.String\n            name=\"DatePicker\"\n            title=\"DatePicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker\"\n            required\n          />\n          <SchemaField.String\n            name=\"NumberPicker\"\n            title=\"NumberPicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"NumberPicker\"\n            required\n          />\n          <SchemaField.String\n            name=\"TreeSelect\"\n            title=\"TreeSelect\"\n            x-decorator=\"FormItem\"\n            x-component=\"TreeSelect\"\n            required\n          />\n          <SchemaField.Boolean\n            name=\"Switch\"\n            title=\"Switch\"\n            x-decorator=\"FormItem\"\n            x-component=\"Switch\"\n            required\n          />\n        </SchemaField.Void>\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormItem\n\n| 属性名                | 类型                                                   | 描述                                                                | 默认值              |\n| --------------------- | ------------------------------------------------------ | ------------------------------------------------------------------- | ------------------- |\n| label                 | ReactNode                                              | 标签                                                                | -                   |\n| style                 | CSSProperties                                          | 样式                                                                | -                   |\n| labelStyle            | CSSProperties                                          | 标签样式                                                            | -                   |\n| wrapperStyle          | CSSProperties                                          | 组件容器样式                                                        | -                   |\n| className             | string                                                 | 组件样式类名                                                        | -                   |\n| colon                 | boolean                                                | 冒号                                                                | true                |\n| tooltip               | ReactNode                                              | 问号提示                                                            | -                   |\n| tooltipLayout         | `\"icon\" \\| \"text\"`                                     | 问号提示布局                                                        | `\"icon\"`            |\n| tooltipIcon           | ReactNode                                              | 问号提示图标                                                        | `?`                 |\n| labelAlign            | `\"left\"` \\| `\"right\"`                                  | 标签文本对齐方式                                                    | `\"right\"`           |\n| labelWrap             | boolean                                                | 标签换⾏，否则出现省略号，hover 有 tooltip                          | false               |\n| labelWidth            | `number \\| string`                                     | 标签固定宽度                                                        | -                   |\n| wrapperWidth          | `number \\| string`                                     | 内容固定宽度                                                        | -                   |\n| labelCol              | number                                                 | 标签⽹格所占列数，和内容列数加起来总和为 24                         | -                   |\n| wrapperCol            | number                                                 | 内容⽹格所占列数，和标签列数加起来总和为 24                         | -                   |\n| wrapperAlign          | `\"left\"` \\| `\"right\"`                                  | 内容文本对齐方式⻬                                                  | `\"left\"`            |\n| wrapperWrap           | boolean                                                | 内容换⾏，否则出现省略号，hover 有 tooltip                          | false               |\n| fullness              | boolean                                                | 内容撑满                                                            | false               |\n| addonBefore           | ReactNode                                              | 前缀内容                                                            | -                   |\n| addonAfter            | ReactNode                                              | 后缀内容                                                            | -                   |\n| size                  | `\"small\"` \\| `\"default\"` \\| `\"large\"`                  | 尺⼨                                                                | -                   |\n| inset                 | boolean                                                | 是否是内嵌布局                                                      | false               |\n| extra                 | ReactNode                                              | 扩展描述⽂案                                                        | -                   |\n| feedbackText          | ReactNode                                              | 反馈⽂案                                                            | -                   |\n| feedbackLayout        | `\"loose\"` \\| `\"terse\"` \\| `\"popover\" \\| \"none\"`        | 反馈布局                                                            | -                   |\n| feedbackStatus        | `\"error\"` \\| `\"warning\"` \\| `\"success\"` \\| `\"pending\"` | 反馈布局                                                            | -                   |\n| feedbackIcon          | ReactNode                                              | 反馈图标                                                            | -                   |\n| enableOutlineFeedback | boolean                                                | 开启异常状态的边框颜色样式，当自定义组件内存在子表单时建议关闭此项  | true                |\n| getPopupContainer     | function(triggerNode)                                  | 当 feedbackLayout 为 popover 时，浮层渲染父节点，默认渲染到 body 上 | () => document.body |\n| asterisk              | boolean                                                | 星号提醒                                                            | -                   |\n| gridSpan              | number                                                 | ⽹格布局占宽                                                        | -                   |\n| bordered              | boolean                                                | 是否有边框                                                          | -                   |\n\n### FormItem.BaseItem\n\n纯样式组件，属性与 FormItem 一样，与 Formily Core 不做状态桥接，主要用于一些需要依赖 FormItem 的样式布局能力，但不希望接入 Field 状态的场景\n"
  },
  {
    "path": "packages/antd/docs/components/FormLayout.md",
    "content": "# FormLayout\n\n> Block-level layout batch control component, with the help of this component, we can easily control the layout mode of all FormItem components enclosed by FormLayout\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { Input, Select, FormItem, FormLayout } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    FormItem,\n    FormLayout,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Void\n        x-component=\"FormLayout\"\n        x-component-props={{\n          labelCol: 6,\n          wrapperCol: 10,\n        }}\n      >\n        <SchemaField.String\n          name=\"input\"\n          title=\"input box\"\n          x-decorator=\"FormItem\"\n          x-decorator-props={{\n            tooltip: <div>123</div>,\n          }}\n          x-component=\"Input\"\n          required\n        />\n        <SchemaField.String\n          name=\"select\"\n          title=\"select box\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n        />\n      </SchemaField.Void>\n    </SchemaField>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { Input, Select, FormItem, FormLayout } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    FormItem,\n    FormLayout,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    layout: {\n      type: 'void',\n      'x-component': 'FormLayout',\n      'x-component-props': {\n        labelCol: 6,\n        wrapperCol: 10,\n        layout: 'vertical',\n      },\n      properties: {\n        input: {\n          type: 'string',\n          title: 'input box',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            tooltip: <div>123</div>,\n          },\n          'x-component': 'Input',\n        },\n        select: {\n          type: 'string',\n          title: 'Select box',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Select',\n        },\n      },\n    },\n  },\n}\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Select,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <Field\n        name=\"input\"\n        required\n        title=\"input box\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <Field\n        name=\"select\"\n        required\n        title=\"select box\"\n        decorator={[FormItem]}\n        component={[Select]}\n      />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## API\n\n| Property name  | Type                                                                                   | Description                                                 | Default value |\n| -------------- | -------------------------------------------------------------------------------------- | ----------------------------------------------------------- | ------------- |\n| style          | CSSProperties                                                                          | Style                                                       | -             |\n| className      | string                                                                                 | class name                                                  | -             |\n| colon          | boolean                                                                                | Is there a colon                                            | true          |\n| requiredMark   | boolean \\| `\"optional\"`                                                                | Required mark style. Can use required mark or optional mark | true          |\n| labelAlign     | `'right' \\| 'left' \\| ('right' \\| 'left')[]`                                           | Label content alignment                                     | -             |\n| wrapperAlign   | `'right' \\| 'left' \\| ('right' \\| 'left')[]`                                           | Component container content alignment                       | -             |\n| labelWrap      | boolean                                                                                | Wrap label content                                          | false         |\n| labelWidth     | number                                                                                 | Label width (px)                                            | -             |\n| wrapperWidth   | number                                                                                 | Component container width (px)                              | -             |\n| wrapperWrap    | boolean                                                                                | Component container wrap                                    | false         |\n| labelCol       | `number \\| number[]`                                                                   | Label width (24 column)                                     | -             |\n| wrapperCol     | `number \\| number[]`                                                                   | Component container width (24 column)                       | -             |\n| fullness       | boolean                                                                                | Component container width 100%                              | false         |\n| size           | `'small' \\|'default' \\|'large'`                                                        | component size                                              | default       |\n| layout         | `'vertical' \\| 'horizontal' \\| 'inline' \\| ('vertical' \\| 'horizontal' \\| 'inline')[]` | layout mode                                                 | horizontal    |\n| direction      | `'rtl' \\|'ltr'`                                                                        | direction (not supported yet)                               | ltr           |\n| inset          | boolean                                                                                | Inline layout                                               | false         |\n| shallow        | boolean                                                                                | shallow context transfer                                    | true          |\n| feedbackLayout | `'loose' \\|'terse' \\|'popover' \\|'none'`                                               | feedback layout                                             | true          |\n| tooltipLayout  | `\"icon\" \\| \"text\"`                                                                     | Ask the prompt layout                                       | `\"icon\"`      |\n| tooltipIcon    | ReactNode                                                                              | Ask the prompt icon                                         | -             |\n| bordered       | boolean                                                                                | Is there a border                                           | true          |\n| breakpoints    | number[]                                                                               | Container size breakpoints                                  | -             |\n| gridColumnGap  | number                                                                                 | Grid Column Gap                                             | 8             |\n| gridRowGap     | number                                                                                 | Grid Row Gap                                                | 4             |\n| spaceGap       | number                                                                                 | Space Gap                                                   | 8             |\n"
  },
  {
    "path": "packages/antd/docs/components/FormLayout.zh-CN.md",
    "content": "# FormLayout\n\n> 区块级布局批量控制组件，借助该组件，我们可以轻松的控制被 FormLayout 圈住的所有 FormItem 组件的布局模式\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Input, Select, FormItem, FormLayout } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    FormItem,\n    FormLayout,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Void\n        x-component=\"FormLayout\"\n        x-component-props={{\n          labelCol: 6,\n          wrapperCol: 10,\n        }}\n      >\n        <SchemaField.String\n          name=\"input\"\n          title=\"输入框\"\n          x-decorator=\"FormItem\"\n          x-decorator-props={{\n            tooltip: <div>123</div>,\n          }}\n          x-component=\"Input\"\n          required\n        />\n        <SchemaField.String\n          name=\"select\"\n          title=\"选择框\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n        />\n      </SchemaField.Void>\n    </SchemaField>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Input, Select, FormItem, FormLayout } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    FormItem,\n    FormLayout,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    layout: {\n      type: 'void',\n      'x-component': 'FormLayout',\n      'x-component-props': {\n        labelCol: 6,\n        wrapperCol: 10,\n        layout: 'vertical',\n      },\n      properties: {\n        input: {\n          type: 'string',\n          title: '输入框',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            tooltip: <div>123</div>,\n          },\n          'x-component': 'Input',\n        },\n        select: {\n          type: 'string',\n          title: '选择框',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Select',\n        },\n      },\n    },\n  },\n}\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Select,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout\n      breakpoints={[680]}\n      layout={['vertical', 'horizontal']}\n      labelAlign={['left', 'right']}\n      labelCol={[24, 6]}\n      wrapperCol={[24, 10]}\n    >\n      <Field\n        name=\"input\"\n        required\n        title=\"输入框\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <Field\n        name=\"select\"\n        required\n        title=\"选择框\"\n        decorator={[FormItem]}\n        component={[Select]}\n      />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## API\n\n| 属性名         | 类型                                                                                   | 描述                                     | 默认值     |\n| -------------- | -------------------------------------------------------------------------------------- | ---------------------------------------- | ---------- |\n| style          | CSSProperties                                                                          | 样式                                     | -          |\n| className      | string                                                                                 | 类名                                     | -          |\n| colon          | boolean                                                                                | 是否有冒号                               | true       |\n| requiredMark   | boolean \\| `\"optional\"`                                                                | 必选样式，可以切换为必选或者可选展示样式 | true       |\n| labelAlign     | `'right' \\| 'left' \\| ('right' \\| 'left')[]`                                           | 标签内容对齐                             | -          |\n| wrapperAlign   | `'right' \\| 'left' \\| ('right' \\| 'left')[]`                                           | 组件容器内容对齐                         | -          |\n| labelWrap      | boolean                                                                                | 标签内容换行                             | false      |\n| labelWidth     | number                                                                                 | 标签宽度(px)                             | -          |\n| wrapperWidth   | number                                                                                 | 组件容器宽度(px)                         | -          |\n| wrapperWrap    | boolean                                                                                | 组件容器换行                             | false      |\n| labelCol       | `number \\| number[]`                                                                   | 标签宽度(24 column)                      | -          |\n| wrapperCol     | `number \\| number[]`                                                                   | 组件容器宽度(24 column)                  | -          |\n| fullness       | boolean                                                                                | 组件容器宽度 100%                        | false      |\n| size           | `'small' \\| 'default' \\| 'large'`                                                      | 组件尺寸                                 | default    |\n| layout         | `'vertical' \\| 'horizontal' \\| 'inline' \\| ('vertical' \\| 'horizontal' \\| 'inline')[]` | 布局模式                                 | horizontal |\n| direction      | `'rtl' \\| 'ltr'`                                                                       | 方向(暂不支持)                           | ltr        |\n| inset          | boolean                                                                                | 内联布局                                 | false      |\n| shallow        | boolean                                                                                | 上下文浅层传递                           | true       |\n| feedbackLayout | `'loose' \\| 'terse' \\| 'popover' \\| 'none'`                                            | 反馈布局                                 | true       |\n| tooltipLayout  | `\"icon\" \\| \"text\"`                                                                     | 问号提示布局                             | `\"icon\"`   |\n| tooltipIcon    | ReactNode                                                                              | 问号提示图标                             | -          |\n| bordered       | boolean                                                                                | 是否有边框                               | true       |\n| breakpoints    | number[]                                                                               | 容器尺寸断点                             | -          |\n| gridColumnGap  | number                                                                                 | 网格布局列间距                           | 8          |\n| gridRowGap     | number                                                                                 | 网格布局行间距                           | 4          |\n| spaceGap       | number                                                                                 | 弹性间距                                 | 8          |\n"
  },
  {
    "path": "packages/antd/docs/components/FormStep.md",
    "content": "# FormStep\n\n> Step-by-step form components\n>\n> Note: This component can only be used in Schema scenarios\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { FormStep, FormItem, Input, FormButtonGroup } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormStep,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formStep = FormStep.createFormStep()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Void\n          x-component=\"FormStep\"\n          x-component-props={{ formStep }}\n        >\n          <SchemaField.Void\n            x-component=\"FormStep.StepPane\"\n            x-component-props={{ title: 'First Step' }}\n          >\n            <SchemaField.String\n              name=\"aaa\"\n              x-decorator=\"FormItem\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"FormStep.StepPane\"\n            x-component-props={{ title: 'Second Step' }}\n          >\n            <SchemaField.String\n              name=\"bbb\"\n              x-decorator=\"FormItem\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            type=\"void\"\n            x-component=\"FormStep.StepPane\"\n            x-component-props={{ title: 'Step 3' }}\n          >\n            <SchemaField.String\n              name=\"ccc\"\n              x-decorator=\"FormItem\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n        </SchemaField.Void>\n      </SchemaField>\n      <FormConsumer>\n        {() => (\n          <FormButtonGroup>\n            <Button\n              disabled={!formStep.allowBack}\n              onClick={() => {\n                formStep.back()\n              }}\n            >\n              Previous\n            </Button>\n            <Button\n              disabled={!formStep.allowNext}\n              onClick={() => {\n                formStep.next()\n              }}\n            >\n              Next step\n            </Button>\n            <Button\n              disabled={formStep.allowNext}\n              onClick={() => {\n                formStep.submit(console.log)\n              }}\n            >\n              submit\n            </Button>\n          </FormButtonGroup>\n        )}\n      </FormConsumer>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { FormStep, FormItem, Input, FormButtonGroup } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormStep,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formStep = FormStep.createFormStep()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    step: {\n      type: 'void',\n      'x-component': 'FormStep',\n      'x-component-props': {\n        formStep: '{{formStep}}',\n      },\n      properties: {\n        step1: {\n          type: 'void',\n          'x-component': 'FormStep.StepPane',\n          'x-component-props': {\n            title: 'First Step',\n          },\n          properties: {\n            aaa: {\n              type: 'string',\n              title: 'AAA',\n              required: true,\n              'x-decorator': 'FormItem',\n              'x-component': 'Input',\n            },\n          },\n        },\n        step2: {\n          type: 'void',\n          'x-component': 'FormStep.StepPane',\n          'x-component-props': {\n            title: 'Second Step',\n          },\n          properties: {\n            bbb: {\n              type: 'string',\n              title: 'AAA',\n              required: true,\n              'x-decorator': 'FormItem',\n              'x-component': 'Input',\n            },\n          },\n        },\n        step3: {\n          type: 'void',\n          'x-component': 'FormStep.StepPane',\n          'x-component-props': {\n            title: 'The third step',\n          },\n          properties: {\n            ccc: {\n              type: 'string',\n              title: 'AAA',\n              required: true,\n              'x-decorator': 'FormItem',\n              'x-component': 'Input',\n            },\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} scope={{ formStep }} />\n      <FormConsumer>\n        {() => (\n          <FormButtonGroup>\n            <Button\n              disabled={!formStep.allowBack}\n              onClick={() => {\n                formStep.back()\n              }}\n            >\n              Previous\n            </Button>\n            <Button\n              disabled={!formStep.allowNext}\n              onClick={() => {\n                formStep.next()\n              }}\n            >\n              Next step\n            </Button>\n            <Button\n              disabled={formStep.allowNext}\n              onClick={() => {\n                formStep.submit(console.log)\n              }}\n            >\n              submit\n            </Button>\n          </FormButtonGroup>\n        )}\n      </FormConsumer>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormStep\n\n| Property name | Type      | Description                                             | Default value |\n| ------------- | --------- | ------------------------------------------------------- | ------------- |\n| formStep      | IFormStep | Pass in the model created by createFormStep/useFormStep |               |\n\nOther references https://ant.design/components/steps-cn/\n\n### FormStep.StepPane\n\nRefer to https://ant.design/components/steps-cn/ Steps.Step properties\n\n### FormStep.createFormStep\n\n```ts pure\nimport { Form } from '@formily/core'\n\ninterface createFormStep {\n  (current?: number): IFormStep\n}\n\ninterface IFormTab {\n  //Current index\n  current: number\n  //Whether to allow backwards\n  allowNext: boolean\n  //Whether to allow forward\n  allowBack: boolean\n  //Set the current index\n  setCurrent(key: number): void\n  //submit Form\n  submit: Form['submit']\n  //backward\n  next(): void\n  //forward\n  back(): void\n}\n```\n"
  },
  {
    "path": "packages/antd/docs/components/FormStep.zh-CN.md",
    "content": "# FormStep\n\n> 分步表单组件\n>\n> 注意：该组件只能用在 Schema 场景\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { FormStep, FormItem, Input, FormButtonGroup } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormStep,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formStep = FormStep.createFormStep()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Void\n          x-component=\"FormStep\"\n          x-component-props={{ formStep }}\n        >\n          <SchemaField.Void\n            x-component=\"FormStep.StepPane\"\n            x-component-props={{ title: '第一步' }}\n          >\n            <SchemaField.String\n              name=\"aaa\"\n              x-decorator=\"FormItem\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"FormStep.StepPane\"\n            x-component-props={{ title: '第二步' }}\n          >\n            <SchemaField.String\n              name=\"bbb\"\n              x-decorator=\"FormItem\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            type=\"void\"\n            x-component=\"FormStep.StepPane\"\n            x-component-props={{ title: '第三步' }}\n          >\n            <SchemaField.String\n              name=\"ccc\"\n              x-decorator=\"FormItem\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n        </SchemaField.Void>\n      </SchemaField>\n      <FormConsumer>\n        {() => (\n          <FormButtonGroup>\n            <Button\n              disabled={!formStep.allowBack}\n              onClick={() => {\n                formStep.back()\n              }}\n            >\n              上一步\n            </Button>\n            <Button\n              disabled={!formStep.allowNext}\n              onClick={() => {\n                formStep.next()\n              }}\n            >\n              下一步\n            </Button>\n            <Button\n              disabled={formStep.allowNext}\n              onClick={() => {\n                formStep.submit(console.log)\n              }}\n            >\n              提交\n            </Button>\n          </FormButtonGroup>\n        )}\n      </FormConsumer>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { FormStep, FormItem, Input, FormButtonGroup } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormStep,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formStep = FormStep.createFormStep()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    step: {\n      type: 'void',\n      'x-component': 'FormStep',\n      'x-component-props': {\n        formStep: '{{formStep}}',\n      },\n      properties: {\n        step1: {\n          type: 'void',\n          'x-component': 'FormStep.StepPane',\n          'x-component-props': {\n            title: '第一步',\n          },\n          properties: {\n            aaa: {\n              type: 'string',\n              title: 'AAA',\n              required: true,\n              'x-decorator': 'FormItem',\n              'x-component': 'Input',\n            },\n          },\n        },\n        step2: {\n          type: 'void',\n          'x-component': 'FormStep.StepPane',\n          'x-component-props': {\n            title: '第二步',\n          },\n          properties: {\n            bbb: {\n              type: 'string',\n              title: 'AAA',\n              required: true,\n              'x-decorator': 'FormItem',\n              'x-component': 'Input',\n            },\n          },\n        },\n        step3: {\n          type: 'void',\n          'x-component': 'FormStep.StepPane',\n          'x-component-props': {\n            title: '第三步',\n          },\n          properties: {\n            ccc: {\n              type: 'string',\n              title: 'AAA',\n              required: true,\n              'x-decorator': 'FormItem',\n              'x-component': 'Input',\n            },\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} scope={{ formStep }} />\n      <FormConsumer>\n        {() => (\n          <FormButtonGroup>\n            <Button\n              disabled={!formStep.allowBack}\n              onClick={() => {\n                formStep.back()\n              }}\n            >\n              上一步\n            </Button>\n            <Button\n              disabled={!formStep.allowNext}\n              onClick={() => {\n                formStep.next()\n              }}\n            >\n              下一步\n            </Button>\n            <Button\n              disabled={formStep.allowNext}\n              onClick={() => {\n                formStep.submit(console.log)\n              }}\n            >\n              提交\n            </Button>\n          </FormButtonGroup>\n        )}\n      </FormConsumer>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormStep\n\n| 属性名   | 类型      | 描述                                               | 默认值 |\n| -------- | --------- | -------------------------------------------------- | ------ |\n| formStep | IFormStep | 传入通过 createFormStep/useFormStep 创建出来的模型 |        |\n\n其余参考 https://ant.design/components/steps-cn/\n\n### FormStep.StepPane\n\n参考 https://ant.design/components/steps-cn/ Steps.Step 属性\n\n### FormStep.createFormStep\n\n```ts pure\nimport { Form } from '@formily/core'\n\ninterface createFormStep {\n  (current?: number): IFormStep\n}\n\ninterface IFormTab {\n  //当前索引\n  current: number\n  //是否允许向后\n  allowNext: boolean\n  //是否允许向前\n  allowBack: boolean\n  //设置当前索引\n  setCurrent(key: number): void\n  //提交表单\n  submit: Form['submit']\n  //向后\n  next(): void\n  //向前\n  back(): void\n}\n```\n"
  },
  {
    "path": "packages/antd/docs/components/FormTab.md",
    "content": "# FormTab\n\n> Tab form\n>\n> Note: This component is only applicable to Schema scenarios\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  FormTab,\n  FormItem,\n  Input,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormTab,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formTab = FormTab.createFormTab()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Void\n          type=\"void\"\n          x-component=\"FormTab\"\n          x-component-props={{ formTab }}\n        >\n          <SchemaField.Void\n            type=\"void\"\n            name=\"tab1\"\n            x-component=\"FormTab.TabPane\"\n            x-component-props={{ tab: 'A1' }}\n          >\n            <SchemaField.String\n              name=\"aaa\"\n              x-decorator=\"FormItem\"\n              title=\"AAA\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            name=\"tab2\"\n            x-component=\"FormTab.TabPane\"\n            x-component-props={{ tab: 'A2' }}\n          >\n            <SchemaField.String\n              name=\"bbb\"\n              x-decorator=\"FormItem\"\n              title=\"BBB\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            name=\"tab3\"\n            x-component=\"FormTab.TabPane\"\n            x-component-props={{ tab: 'A3' }}\n          >\n            <SchemaField.String\n              name=\"ccc\"\n              x-decorator=\"FormItem\"\n              title=\"CCC\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n        </SchemaField.Void>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Button\n          onClick={() => {\n            form.query('tab3').take((field) => {\n              field.visible = !field.visible\n            })\n          }}\n        >\n          Show/hide the last tab\n        </Button>\n        <Button\n          onClick={() => {\n            formTab.setActiveKey('tab2')\n          }}\n        >\n          Switch to the second Tab\n        </Button>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  FormTab,\n  FormItem,\n  Input,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormTab,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formTab = FormTab.createFormTab()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    collapse: {\n      type: 'void',\n      'x-component': 'FormTab',\n      'x-component-props': {\n        formTab: '{{formTab}}',\n      },\n      properties: {\n        tab1: {\n          type: 'void',\n          'x-component': 'FormTab.TabPane',\n          'x-component-props': {\n            tab: 'A1',\n          },\n          properties: {\n            aaa: {\n              type: 'string',\n              title: 'AAA',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        tab2: {\n          type: 'void',\n          'x-component': 'FormTab.TabPane',\n          'x-component-props': {\n            tab: 'A2',\n          },\n          properties: {\n            bbb: {\n              type: 'string',\n              title: 'BBB',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        tab3: {\n          type: 'void',\n          'x-component': 'FormTab.TabPane',\n          'x-component-props': {\n            tab: 'A3',\n          },\n          properties: {\n            ccc: {\n              type: 'string',\n              title: 'CCC',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} scope={{ formTab }} />\n      <FormButtonGroup.FormItem>\n        <Button\n          onClick={() => {\n            form.query('tab3').take((field) => {\n              field.visible = !field.visible\n            })\n          }}\n        >\n          Show/hide the last tab\n        </Button>\n        <Button\n          onClick={() => {\n            formTab.setActiveKey('tab2')\n          }}\n        >\n          Switch to the second Tab\n        </Button>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormTab\n\n| Property name | Type     | Description                                           | Default value |\n| ------------- | -------- | ----------------------------------------------------- | ------------- |\n| formTab       | IFormTab | Pass in the model created by createFormTab/useFormTab |               |\n\nOther references https://ant.design/components/tabs-cn/\n\n### FormTab.TabPane\n\nReference https://ant.design/components/tabs-cn/\n\n### FormTab.createFormTab\n\n```ts pure\ntype ActiveKey = string | number\n\ninterface createFormTab {\n  (defaultActiveKey?: ActiveKey): IFormTab\n}\n\ninterface IFormTab {\n  //Activate the primary key\n  activeKey: ActiveKey\n  //Set the activation key\n  setActiveKey(key: ActiveKey): void\n}\n```\n"
  },
  {
    "path": "packages/antd/docs/components/FormTab.zh-CN.md",
    "content": "# FormTab\n\n> 选项卡表单\n>\n> 注意：该组件只适用于 Schema 场景\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormTab,\n  FormItem,\n  Input,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormTab,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formTab = FormTab.createFormTab()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Void\n          type=\"void\"\n          x-component=\"FormTab\"\n          x-component-props={{ formTab }}\n        >\n          <SchemaField.Void\n            type=\"void\"\n            name=\"tab1\"\n            x-component=\"FormTab.TabPane\"\n            x-component-props={{ tab: 'A1' }}\n          >\n            <SchemaField.String\n              name=\"aaa\"\n              x-decorator=\"FormItem\"\n              title=\"AAA\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            name=\"tab2\"\n            x-component=\"FormTab.TabPane\"\n            x-component-props={{ tab: 'A2' }}\n          >\n            <SchemaField.String\n              name=\"bbb\"\n              x-decorator=\"FormItem\"\n              title=\"BBB\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            name=\"tab3\"\n            x-component=\"FormTab.TabPane\"\n            x-component-props={{ tab: 'A3' }}\n          >\n            <SchemaField.String\n              name=\"ccc\"\n              x-decorator=\"FormItem\"\n              title=\"CCC\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n        </SchemaField.Void>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Button\n          onClick={() => {\n            form.query('tab3').take((field) => {\n              field.visible = !field.visible\n            })\n          }}\n        >\n          显示/隐藏最后一个Tab\n        </Button>\n        <Button\n          onClick={() => {\n            formTab.setActiveKey('tab2')\n          }}\n        >\n          切换第二个Tab\n        </Button>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormTab,\n  FormItem,\n  Input,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormTab,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formTab = FormTab.createFormTab()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    collapse: {\n      type: 'void',\n      'x-component': 'FormTab',\n      'x-component-props': {\n        formTab: '{{formTab}}',\n      },\n      properties: {\n        tab1: {\n          type: 'void',\n          'x-component': 'FormTab.TabPane',\n          'x-component-props': {\n            tab: 'A1',\n          },\n          properties: {\n            aaa: {\n              type: 'string',\n              title: 'AAA',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        tab2: {\n          type: 'void',\n          'x-component': 'FormTab.TabPane',\n          'x-component-props': {\n            tab: 'A2',\n          },\n          properties: {\n            bbb: {\n              type: 'string',\n              title: 'BBB',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        tab3: {\n          type: 'void',\n          'x-component': 'FormTab.TabPane',\n          'x-component-props': {\n            tab: 'A3',\n          },\n          properties: {\n            ccc: {\n              type: 'string',\n              title: 'CCC',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} scope={{ formTab }} />\n      <FormButtonGroup.FormItem>\n        <Button\n          onClick={() => {\n            form.query('tab3').take((field) => {\n              field.visible = !field.visible\n            })\n          }}\n        >\n          显示/隐藏最后一个Tab\n        </Button>\n        <Button\n          onClick={() => {\n            formTab.setActiveKey('tab2')\n          }}\n        >\n          切换第二个Tab\n        </Button>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormTab\n\n| 属性名  | 类型     | 描述                                             | 默认值 |\n| ------- | -------- | ------------------------------------------------ | ------ |\n| formTab | IFormTab | 传入通过 createFormTab/useFormTab 创建出来的模型 |        |\n\n其余参考 https://ant.design/components/tabs-cn/\n\n### FormTab.TabPane\n\n参考 https://ant.design/components/tabs-cn/\n\n### FormTab.createFormTab\n\n```ts pure\ntype ActiveKey = string | number\n\ninterface createFormTab {\n  (defaultActiveKey?: ActiveKey): IFormTab\n}\n\ninterface IFormTab {\n  //激活主键\n  activeKey: ActiveKey\n  //设置激活主键\n  setActiveKey(key: ActiveKey): void\n}\n```\n"
  },
  {
    "path": "packages/antd/docs/components/Input.md",
    "content": "# Input\n\n> Text input box\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        required\n        x-component-props={{\n          style: {\n            width: 240,\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"textarea\"\n        title=\"text box\"\n        x-decorator=\"FormItem\"\n        required\n        x-component=\"Input.TextArea\"\n        x-component-props={{\n          style: {\n            width: 400,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      title: 'input box',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n    },\n    textarea: {\n      type: 'string',\n      title: 'input box',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input.TextArea',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"input\"\n      title=\"input box\"\n      required\n      decorator={[FormItem]}\n      component={[\n        Input,\n        {\n          style: {\n            width: 240,\n          },\n        },\n      ]}\n    />\n    <Field\n      name=\"textarea\"\n      title=\"text box\"\n      required\n      decorator={[FormItem]}\n      component={[\n        Input.TextArea,\n        {\n          style: {\n            width: 400,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://ant.design/components/input-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Input.zh-CN.md",
    "content": "# Input\n\n> 文本输入框\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        required\n        x-component-props={{\n          style: {\n            width: 240,\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"textarea\"\n        title=\"文本框\"\n        x-decorator=\"FormItem\"\n        required\n        x-component=\"Input.TextArea\"\n        x-component-props={{\n          style: {\n            width: 400,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      title: '输入框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n    },\n    textarea: {\n      type: 'string',\n      title: '输入框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input.TextArea',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"input\"\n      title=\"输入框\"\n      required\n      decorator={[FormItem]}\n      component={[\n        Input,\n        {\n          style: {\n            width: 240,\n          },\n        },\n      ]}\n    />\n    <Field\n      name=\"textarea\"\n      title=\"文本框\"\n      required\n      decorator={[FormItem]}\n      component={[\n        Input.TextArea,\n        {\n          style: {\n            width: 400,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://ant.design/components/input-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/NumberPicker.md",
    "content": "# NumberPicker\n\n> Number input box\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { NumberPicker, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    NumberPicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        x-decorator=\"FormItem\"\n        x-component=\"NumberPicker\"\n        required\n        x-component-props={{\n          style: {\n            width: 240,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { NumberPicker, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    NumberPicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      title: 'input box',\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { NumberPicker, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"input\"\n      title=\"input box\"\n      required\n      decorator={[FormItem]}\n      component={[\n        NumberPicker,\n        {\n          style: {\n            width: 240,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://ant.design/components/input-number-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/NumberPicker.zh-CN.md",
    "content": "# NumberPicker\n\n> 数字输入框\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { NumberPicker, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    NumberPicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        x-decorator=\"FormItem\"\n        x-component=\"NumberPicker\"\n        required\n        x-component-props={{\n          style: {\n            width: 240,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { NumberPicker, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    NumberPicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      title: '输入框',\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { NumberPicker, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"input\"\n      title=\"输入框\"\n      required\n      decorator={[FormItem]}\n      component={[\n        NumberPicker,\n        {\n          style: {\n            width: 240,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://ant.design/components/input-number-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Password.md",
    "content": "# Password\n\n> Password input box\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  Password,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Password,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"input\"\n          title=\"input box\"\n          x-decorator=\"FormItem\"\n          x-component=\"Password\"\n          required\n          x-component-props={{\n            checkStrength: true,\n          }}\n        />\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  Password,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Password,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      title: 'input box',\n      'x-decorator': 'FormItem',\n      'x-component': 'Password',\n      'x-component-props': {\n        checkStrength: true,\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport {\n  Password,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <Field\n        name=\"input\"\n        title=\"input box\"\n        required\n        decorator={[FormItem]}\n        component={[\n          Password,\n          {\n            checkStrength: true,\n          },\n        ]}\n      />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://ant.design/components/input-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Password.zh-CN.md",
    "content": "# Password\n\n> 密码输入框\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Password,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Password,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"input\"\n          title=\"输入框\"\n          x-decorator=\"FormItem\"\n          x-component=\"Password\"\n          required\n          x-component-props={{\n            checkStrength: true,\n          }}\n        />\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Password,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Password,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      title: '输入框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Password',\n      'x-component-props': {\n        checkStrength: true,\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Password,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <Field\n        name=\"input\"\n        title=\"输入框\"\n        required\n        decorator={[FormItem]}\n        component={[\n          Password,\n          {\n            checkStrength: true,\n          },\n        ]}\n      />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://ant.design/components/input-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/PreviewText.md",
    "content": "# PreviewText\n\n> Reading state components, mainly used to implement the reading state of these components of class Input and DatePicker\n\n## Simple use case\n\n```tsx\nimport React from 'react'\nimport { PreviewText, FormItem, FormLayout } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    PreviewText,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"text preview\"\n            x-component=\"PreviewText.Input\"\n            default={'Hello world'}\n          />\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"Select item preview\"\n            x-component=\"PreviewText.Select\"\n            x-component-props={{\n              mode: 'multiple',\n            }}\n            default={['123', '222']}\n            enum={[\n              { label: 'A111', value: '123' },\n              { label: 'A222', value: '222' },\n            ]}\n          />\n\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"TreeSelect preview\"\n            x-component=\"PreviewText.TreeSelect\"\n            x-component-props={{\n              multiple: true,\n            }}\n            default={['123', '222']}\n            enum={[\n              { label: 'A111', value: '123' },\n              { label: 'A222', value: '222' },\n            ]}\n          />\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"TreeSelect（treeData）preview\"\n            x-component=\"PreviewText.TreeSelect\"\n            x-component-props={{\n              multiple: true,\n              treeNodeLabelProp: 'name',\n              treeData: [\n                { name: 'A111', value: '123' },\n                { name: 'A222', value: '222' },\n              ],\n            }}\n            default={['123', '222']}\n          />\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"date preview\"\n            x-component=\"PreviewText.DatePicker\"\n            default={'2020-11-23 22:15:20'}\n          />\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"Cascader Preview\"\n            x-component=\"PreviewText.Cascader\"\n            default={'yuhang'}\n            enum={[\n              {\n                label: 'Hangzhou',\n                value: 'hangzhou',\n                children: [\n                  {\n                    label: 'Yuhang',\n                    value: 'yuhang',\n                  },\n                ],\n              },\n            ]}\n          />\n        </SchemaField>\n      </FormProvider>\n    </FormLayout>\n  )\n}\n```\n\n## Extended reading mode\n\n```tsx\nimport React from 'react'\nimport {\n  PreviewText,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  mapReadPretty,\n  connect,\n  createSchemaField,\n} from '@formily/react'\nimport { Button, Input as AntdInput } from 'antd'\n\nconst Input = connect(AntdInput, mapReadPretty(PreviewText.Input))\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    PreviewText,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <PreviewText.Placeholder value=\"No data currently available\">\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <FormProvider form={form}>\n          <SchemaField>\n            <SchemaField.Markup\n              type=\"string\"\n              x-decorator=\"FormItem\"\n              title=\"text preview\"\n              required\n              x-component=\"Input\"\n              default={'Hello world'}\n            />\n            <SchemaField.Markup\n              type=\"string\"\n              x-decorator=\"FormItem\"\n              title=\"Select item preview\"\n              x-component=\"PreviewText.Select\"\n              x-component-props={{\n                mode: 'multiple',\n              }}\n              default={['123']}\n              enum={[\n                { label: 'A111', value: '123' },\n                { label: 'A222', value: '222' },\n              ]}\n            />\n            <SchemaField.Markup\n              type=\"string\"\n              x-decorator=\"FormItem\"\n              title=\"date preview\"\n              x-component=\"PreviewText.DatePicker\"\n            />\n            <SchemaField.Markup\n              type=\"string\"\n              x-decorator=\"FormItem\"\n              title=\"Cascader Preview\"\n              x-component=\"PreviewText.Cascader\"\n              default={'yuhang'}\n              enum={[\n                {\n                  label: 'Hangzhou',\n                  value: 'hangzhou',\n                  children: [\n                    {\n                      label: 'Yuhang',\n                      value: 'yuhang',\n                    },\n                  ],\n                },\n              ]}\n            />\n          </SchemaField>\n          <FormButtonGroup.FormItem>\n            <Button\n              onClick={() => {\n                form.setState((state) => {\n                  state.editable = !state.editable\n                })\n              }}\n            >\n              Switch reading mode\n            </Button>\n          </FormButtonGroup.FormItem>\n        </FormProvider>\n      </FormLayout>\n    </PreviewText.Placeholder>\n  )\n}\n```\n\n## API\n\n### PreviewText.Input\n\nReference https://ant.design/components/input-cn/\n\n### PreviewText.Select\n\nReference https://ant.design/components/select-cn/\n\n### PreviewText.TreeSelect\n\nReference https://ant.design/components/tree-select-cn/\n\n### PreviewText.Cascader\n\nReference https://ant.design/components/cascader-cn/\n\n### PreviewText.DatePicker\n\nReference https://ant.design/components/date-picker-cn/\n\n### PreviewText.DateRangePicker\n\nReference https://ant.design/components/date-picker-cn/\n\n### PreviewText.TimePicker\n\nReference https://ant.design/components/time-picker-cn/\n\n### PreviewText.TimeRangePicker\n\nReference https://ant.design/components/time-picker-cn/\n\n### PreviewText.NumberPicker\n\n参考 https://ant.design/components/input-number-cn/\n\n### PreviewText.Placeholder\n\n| Property name | Type   | Description         | Default value |\n| ------------- | ------ | ------------------- | ------------- |\n| value         | stirng | Default placeholder | N/A           |\n\n### PreviewText.usePlaceholder\n\n```ts pure\ninterface usePlaceholder {\n  (): string\n}\n```\n"
  },
  {
    "path": "packages/antd/docs/components/PreviewText.zh-CN.md",
    "content": "# PreviewText\n\n> 阅读态组件，主要用来实现类 Input，类 DatePicker 这些组件的阅读态\n\n## 简单用例\n\n```tsx\nimport React from 'react'\nimport { PreviewText, FormItem, FormLayout } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    PreviewText,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"文本预览\"\n            x-component=\"PreviewText.Input\"\n            default={'Hello world'}\n          />\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"选择项预览\"\n            x-component=\"PreviewText.Select\"\n            x-component-props={{\n              mode: 'multiple',\n            }}\n            default={['123', '222']}\n            enum={[\n              { label: 'A111', value: '123' },\n              { label: 'A222', value: '222' },\n            ]}\n          />\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"树选择预览\"\n            x-component=\"PreviewText.TreeSelect\"\n            x-component-props={{\n              multiple: true,\n            }}\n            default={['123', '222']}\n            enum={[\n              { label: 'A111', value: '123' },\n              { label: 'A222', value: '222' },\n            ]}\n          />\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"树选择（treeData）预览\"\n            x-component=\"PreviewText.TreeSelect\"\n            x-component-props={{\n              multiple: true,\n              treeNodeLabelProp: 'name',\n              treeData: [\n                { name: 'A111', value: '123' },\n                { name: 'A222', value: '222' },\n              ],\n            }}\n            default={['123', '222']}\n          />\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"日期预览\"\n            x-component=\"PreviewText.DatePicker\"\n            default={'2020-11-23 22:15:20'}\n          />\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"Cascader预览\"\n            x-component=\"PreviewText.Cascader\"\n            default={'yuhang'}\n            enum={[\n              {\n                label: '杭州',\n                value: 'hangzhou',\n                children: [\n                  {\n                    label: '余杭',\n                    value: 'yuhang',\n                  },\n                ],\n              },\n            ]}\n          />\n        </SchemaField>\n      </FormProvider>\n    </FormLayout>\n  )\n}\n```\n\n## 扩展阅读态\n\n```tsx\nimport React from 'react'\nimport {\n  PreviewText,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  mapReadPretty,\n  connect,\n  createSchemaField,\n} from '@formily/react'\nimport { Button, Input as AntdInput } from 'antd'\n\nconst Input = connect(AntdInput, mapReadPretty(PreviewText.Input))\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    PreviewText,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <PreviewText.Placeholder value=\"暂无数据\">\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <FormProvider form={form}>\n          <SchemaField>\n            <SchemaField.Markup\n              type=\"string\"\n              x-decorator=\"FormItem\"\n              title=\"文本预览\"\n              required\n              x-component=\"Input\"\n              default={'Hello world'}\n            />\n            <SchemaField.Markup\n              type=\"string\"\n              x-decorator=\"FormItem\"\n              title=\"选择项预览\"\n              x-component=\"PreviewText.Select\"\n              x-component-props={{\n                mode: 'multiple',\n              }}\n              default={['123']}\n              enum={[\n                { label: 'A111', value: '123' },\n                { label: 'A222', value: '222' },\n              ]}\n            />\n            <SchemaField.Markup\n              type=\"string\"\n              x-decorator=\"FormItem\"\n              title=\"日期预览\"\n              x-component=\"PreviewText.DatePicker\"\n            />\n            <SchemaField.Markup\n              type=\"string\"\n              x-decorator=\"FormItem\"\n              title=\"Cascader预览\"\n              x-component=\"PreviewText.Cascader\"\n              default={'yuhang'}\n              enum={[\n                {\n                  label: '杭州',\n                  value: 'hangzhou',\n                  children: [\n                    {\n                      label: '余杭',\n                      value: 'yuhang',\n                    },\n                  ],\n                },\n              ]}\n            />\n          </SchemaField>\n          <FormButtonGroup.FormItem>\n            <Button\n              onClick={() => {\n                form.setState((state) => {\n                  state.editable = !state.editable\n                })\n              }}\n            >\n              切换阅读态\n            </Button>\n          </FormButtonGroup.FormItem>\n        </FormProvider>\n      </FormLayout>\n    </PreviewText.Placeholder>\n  )\n}\n```\n\n## API\n\n### PreviewText.Input\n\n参考 https://ant.design/components/input-cn/\n\n### PreviewText.Select\n\n参考 https://ant.design/components/select-cn/\n\n### PreviewText.TreeSelect\n\n参考 https://ant.design/components/tree-select-cn/\n\n### PreviewText.Cascader\n\n参考 https://ant.design/components/cascader-cn/\n\n### PreviewText.DatePicker\n\n参考 https://ant.design/components/date-picker-cn/\n\n### PreviewText.DateRangePicker\n\n参考 https://ant.design/components/date-picker-cn/\n\n### PreviewText.TimePicker\n\n参考 https://ant.design/components/time-picker-cn/\n\n### PreviewText.TimeRangePicker\n\n参考 https://ant.design/components/time-picker-cn/\n\n### PreviewText.NumberPicker\n\n参考 https://ant.design/components/input-number-cn/\n\n### PreviewText.Placeholder\n\n| 属性名 | 类型   | 描述       | 默认值 |\n| ------ | ------ | ---------- | ------ |\n| value  | stirng | 缺省占位符 | N/A    |\n\n### PreviewText.usePlaceholder\n\n```ts pure\ninterface usePlaceholder {\n  (): string\n}\n```\n"
  },
  {
    "path": "packages/antd/docs/components/Radio.md",
    "content": "# Radio\n\n> Single selection box\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { Radio, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Radio,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"radio\"\n        title=\"single choice\"\n        enum={[\n          {\n            label: 'Option 1',\n            value: 1,\n          },\n          {\n            label: 'Option 2',\n            value: 2,\n          },\n        ]}\n        x-decorator=\"FormItem\"\n        x-component=\"Radio.Group\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { Radio, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Radio,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    radio: {\n      type: 'number',\n      title: 'Single selection',\n      enum: [\n        {\n          label: 'Option 1',\n          value: 1,\n        },\n        {\n          label: 'Option 2',\n          value: 2,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Radio.Group',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { Radio, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"radio\"\n      title=\"single choice\"\n      dataSource={[\n        {\n          label: 'Option 1',\n          value: 1,\n        },\n        {\n          label: 'Option 2',\n          value: 2,\n        },\n      ]}\n      decorator={FormItem}\n      component={Radio.Group}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://ant.design/components/radio-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Radio.zh-CN.md",
    "content": "# Radio\n\n> 单选框\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Radio, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Radio,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"radio\"\n        title=\"单选\"\n        enum={[\n          {\n            label: '选项1',\n            value: 1,\n          },\n          {\n            label: '选项2',\n            value: 2,\n          },\n        ]}\n        x-decorator=\"FormItem\"\n        x-component=\"Radio.Group\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Radio, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Radio,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    radio: {\n      type: 'number',\n      title: '单选',\n      enum: [\n        {\n          label: '选项1',\n          value: 1,\n        },\n        {\n          label: '选项2',\n          value: 2,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Radio.Group',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { Radio, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"radio\"\n      title=\"单选\"\n      dataSource={[\n        {\n          label: '选项1',\n          value: 1,\n        },\n        {\n          label: '选项2',\n          value: 2,\n        },\n      ]}\n      decorator={FormItem}\n      component={Radio.Group}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://ant.design/components/radio-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Reset.md",
    "content": "# Reset\n\n> Reset button\n\n## Normal reset\n\n> Controls with default values cannot be cleared\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Reset } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"input box\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Reset>Reset</Reset>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Force empty reset\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Reset } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"input box\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Reset forceClear>Reset</Reset>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Reset and verify\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Reset } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"input box\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Reset validate>Reset</Reset>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Force empty reset and verify\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Reset } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"input box\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Reset forceClear validate>\n        Reset\n      </Reset>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n### Reset\n\nOther API reference https://ant.design/components/button-cn/\n\n| Property name          | Type                                                                                             | Description                                              | Default value |\n| ---------------------- | ------------------------------------------------------------------------------------------------ | -------------------------------------------------------- | ------------- |\n| onClick                | `(event: MouseEvent) => void \\| boolean`                                                         | Click event, if it returns false, it can block resetting | -             |\n| onResetValidateSuccess | (payload: any) => void                                                                           | Reset validation success event                           | -             |\n| onResetValidateFailed  | (feedbacks: [IFormFeedback](https://core.formilyjs.org/api/models/form#iformfeedback)[]) => void | Reset validation failure event                           | -             |\n"
  },
  {
    "path": "packages/antd/docs/components/Reset.zh-CN.md",
    "content": "# Reset\n\n> 重置按钮\n\n## 普通重置\n\n> 有默认值的控件无法被清空\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Reset } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"输入框\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Reset>重置</Reset>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 强制清空重置\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Reset } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"输入框\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Reset forceClear>重置</Reset>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 重置并校验\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Reset } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"输入框\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Reset validate>重置</Reset>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 强制清空重置并校验\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Reset } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"输入框\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Reset forceClear validate>\n        重置\n      </Reset>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n### Reset\n\n其余 API 参考 https://ant.design/components/button-cn/\n\n| 属性名                 | 类型                                                                                                   | 描述                                  | 默认值 |\n| ---------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------- | ------ |\n| onClick                | `(event: MouseEvent) => void \\| boolean`                                                               | 点击事件，如果返回 false 可以阻塞重置 | -      |\n| onResetValidateSuccess | (payload: any) => void                                                                                 | 重置校验成功事件                      | -      |\n| onResetValidateFailed  | (feedbacks: [IFormFeedback](https://core.formilyjs.org/zh-CN/api/models/form#iformfeedback)[]) => void | 重置校验失败事件                      | -      |\n"
  },
  {
    "path": "packages/antd/docs/components/Select.md",
    "content": "# Select\n\n> Drop-down box components\n\n## Markup Schema synchronization data source case\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"select\"\n        title=\"select box\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        enum={[\n          { label: 'Option 1', value: 1 },\n          { label: 'Option 2', value: 2 },\n        ]}\n        x-component-props={{\n          style: {\n            width: 120,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Markup Schema Asynchronous Search Case\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport {\n  createForm,\n  onFieldReact,\n  onFieldInit,\n  FormPathPattern,\n  Field,\n} from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action, observable } from '@formily/reactive'\nimport { fetch } from 'mfetch'\n\nlet timeout\nlet currentValue\n\nfunction fetchData(value, callback) {\n  if (timeout) {\n    clearTimeout(timeout)\n    timeout = null\n  }\n  currentValue = value\n\n  function fake() {\n    fetch(`https://suggest.taobao.com/sug?q=${value}`, {\n      method: 'jsonp',\n    })\n      .then((response) => response.json())\n      .then((d) => {\n        if (currentValue === value) {\n          const { result } = d\n          const data = []\n          result.forEach((r) => {\n            data.push({\n              value: r[0],\n              text: r[0],\n            })\n          })\n          callback(data)\n        }\n      })\n  }\n\n  timeout = setTimeout(fake, 300)\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    FormItem,\n  },\n})\n\nconst useAsyncDataSource = (\n  pattern: FormPathPattern,\n  service: (param: {\n    keyword: string\n    field: Field\n  }) => Promise<{ label: string; value: any }[]>\n) => {\n  const keyword = observable.ref('')\n\n  onFieldInit(pattern, (field) => {\n    field.setComponentProps({\n      onSearch: (value) => {\n        keyword.value = value\n      },\n    })\n  })\n\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service({ field, keyword: keyword.value }).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async ({ keyword }) => {\n      if (!keyword) {\n        return []\n      }\n      return new Promise((resolve) => {\n        fetchData(keyword, resolve)\n      })\n    })\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"Asynchronous search select box\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        x-component-props={{\n          showSearch: true,\n          filterOption: false,\n          style: {\n            width: 300,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Markup Schema Asynchronous Linkage Data Source Case\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm, onFieldReact, FormPathPattern, Field } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    FormItem,\n  },\n})\n\nconst useAsyncDataSource = (\n  pattern: FormPathPattern,\n  service: (field: Field) => Promise<{ label: string; value: any }[]>\n) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service(field).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async (field) => {\n      const linkage = field.query('linkage').get('value')\n      if (!linkage) return []\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          if (linkage === 1) {\n            resolve([\n              {\n                label: 'AAA',\n                value: 'aaa',\n              },\n              {\n                label: 'BBB',\n                value: 'ccc',\n              },\n            ])\n          } else if (linkage === 2) {\n            resolve([\n              {\n                label: 'CCC',\n                value: 'ccc',\n              },\n              {\n                label: 'DDD',\n                value: 'ddd',\n              },\n            ])\n          }\n        }, 1500)\n      })\n    })\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"linkage\"\n        title=\"Linkage selection box\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        enum={[\n          { label: 'Request 1', value: 1 },\n          { label: 'Request 2', value: 2 },\n        ]}\n        x-component-props={{\n          style: {\n            width: 120,\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"select\"\n        title=\"Asynchronous select box\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        x-component-props={{\n          style: {\n            width: 120,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema synchronization data source case\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    select: {\n      type: 'string',\n      title: 'Select box',\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      enum: [\n        { label: 'Option 1', value: 1 },\n        { label: 'Option 2', value: 2 },\n      ],\n      'x-component-props': {\n        style: {\n          width: 120,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema asynchronous linkage data source case\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    FormItem,\n  },\n})\n\nconst loadData = async (field) => {\n  const linkage = field.query('linkage').get('value')\n  if (!linkage) return []\n  return new Promise((resolve) => {\n    setTimeout(() => {\n      if (linkage === 1) {\n        resolve([\n          {\n            label: 'AAA',\n            value: 'aaa',\n          },\n          {\n            label: 'BBB',\n            value: 'ccc',\n          },\n        ])\n      } else if (linkage === 2) {\n        resolve([\n          {\n            label: 'CCC',\n            value: 'ccc',\n          },\n          {\n            label: 'DDD',\n            value: 'ddd',\n          },\n        ])\n      }\n    }, 1500)\n  })\n}\n\nconst useAsyncDataSource = (service) => (field) => {\n  field.loading = true\n  service(field).then(\n    action.bound((data) => {\n      field.dataSource = data\n      field.loading = false\n    })\n  )\n}\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    linkage: {\n      type: 'string',\n      title: 'Linkage selection box',\n      enum: [\n        { label: 'Request 1', value: 1 },\n        { label: 'Request 2', value: 2 },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      'x-component-props': {\n        style: {\n          width: 120,\n        },\n      },\n    },\n    select: {\n      type: 'string',\n      title: 'Asynchronous selection box',\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      'x-component-props': {\n        style: {\n          width: 120,\n        },\n      },\n      'x-reactions': ['{{useAsyncDataSource(loadData)}}'],\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} scope={{ useAsyncDataSource, loadData }} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX synchronization data source case\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"select\"\n      title=\"select box\"\n      dataSource={[\n        { label: 'Option 1', value: 1 },\n        { label: 'Option 2', value: 2 },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        Select,\n        {\n          style: {\n            width: 120,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX asynchronous linkage data source case\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport {\n  createForm,\n  onFieldReact,\n  FormPathPattern,\n  Field as FieldType,\n} from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst useAsyncDataSource = (\n  pattern: FormPathPattern,\n  service: (field: FieldType) => Promise<{ label: string; value: any }[]>\n) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service(field).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async (field) => {\n      const linkage = field.query('linkage').get('value')\n      if (!linkage) return []\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          if (linkage === 1) {\n            resolve([\n              {\n                label: 'AAA',\n                value: 'aaa',\n              },\n              {\n                label: 'BBB',\n                value: 'ccc',\n              },\n            ])\n          } else if (linkage === 2) {\n            resolve([\n              {\n                label: 'CCC',\n                value: 'ccc',\n              },\n              {\n                label: 'DDD',\n                value: 'ddd',\n              },\n            ])\n          }\n        }, 1500)\n      })\n    })\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"linkage\"\n      title=\"Linkage selection box\"\n      dataSource={[\n        { label: 'Request 1', value: 1 },\n        { label: 'Request 2', value: 2 },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        Select,\n        {\n          style: {\n            width: 120,\n          },\n        },\n      ]}\n    />\n    <Field\n      name=\"select\"\n      title=\"Asynchronous select box\"\n      decorator={[FormItem]}\n      component={[\n        Select,\n        {\n          style: {\n            width: 120,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://ant.design/components/select-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Select.zh-CN.md",
    "content": "# Select\n\n> 下拉框组件\n\n## Markup Schema 同步数据源案例\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"select\"\n        title=\"选择框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        enum={[\n          { label: '选项1', value: 1 },\n          { label: '选项2', value: 2 },\n        ]}\n        x-component-props={{\n          style: {\n            width: 120,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Markup Schema 异步搜索案例\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport {\n  createForm,\n  onFieldReact,\n  onFieldInit,\n  FormPathPattern,\n  Field,\n} from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action, observable } from '@formily/reactive'\nimport { fetch } from 'mfetch'\n\nlet timeout\nlet currentValue\n\nfunction fetchData(value, callback) {\n  if (timeout) {\n    clearTimeout(timeout)\n    timeout = null\n  }\n  currentValue = value\n\n  function fake() {\n    fetch(`https://suggest.taobao.com/sug?q=${value}`, {\n      method: 'jsonp',\n    })\n      .then((response) => response.json())\n      .then((d) => {\n        if (currentValue === value) {\n          const { result } = d\n          const data = []\n          result.forEach((r) => {\n            data.push({\n              value: r[0],\n              text: r[0],\n            })\n          })\n          callback(data)\n        }\n      })\n  }\n\n  timeout = setTimeout(fake, 300)\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    FormItem,\n  },\n})\n\nconst useAsyncDataSource = (\n  pattern: FormPathPattern,\n  service: (param: {\n    keyword: string\n    field: Field\n  }) => Promise<{ label: string; value: any }[]>\n) => {\n  const keyword = observable.ref('')\n\n  onFieldInit(pattern, (field) => {\n    field.setComponentProps({\n      onSearch: (value) => {\n        keyword.value = value\n      },\n    })\n  })\n\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service({ field, keyword: keyword.value }).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async ({ keyword }) => {\n      if (!keyword) {\n        return []\n      }\n      return new Promise((resolve) => {\n        fetchData(keyword, resolve)\n      })\n    })\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"select\"\n        title=\"异步搜索选择框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        x-component-props={{\n          showSearch: true,\n          filterOption: false,\n          style: {\n            width: 300,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Markup Schema 异步联动数据源案例\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm, onFieldReact, FormPathPattern, Field } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    FormItem,\n  },\n})\n\nconst useAsyncDataSource = (\n  pattern: FormPathPattern,\n  service: (field: Field) => Promise<{ label: string; value: any }[]>\n) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service(field).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async (field) => {\n      const linkage = field.query('linkage').get('value')\n      if (!linkage) return []\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          if (linkage === 1) {\n            resolve([\n              {\n                label: 'AAA',\n                value: 'aaa',\n              },\n              {\n                label: 'BBB',\n                value: 'ccc',\n              },\n            ])\n          } else if (linkage === 2) {\n            resolve([\n              {\n                label: 'CCC',\n                value: 'ccc',\n              },\n              {\n                label: 'DDD',\n                value: 'ddd',\n              },\n            ])\n          }\n        }, 1500)\n      })\n    })\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"linkage\"\n        title=\"联动选择框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        enum={[\n          { label: '发请求1', value: 1 },\n          { label: '发请求2', value: 2 },\n        ]}\n        x-component-props={{\n          style: {\n            width: 120,\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"select\"\n        title=\"异步选择框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        x-component-props={{\n          style: {\n            width: 120,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 同步数据源案例\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    select: {\n      type: 'string',\n      title: '选择框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      enum: [\n        { label: '选项1', value: 1 },\n        { label: '选项2', value: 2 },\n      ],\n      'x-component-props': {\n        style: {\n          width: 120,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 异步联动数据源案例\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    FormItem,\n  },\n})\n\nconst loadData = async (field) => {\n  const linkage = field.query('linkage').get('value')\n  if (!linkage) return []\n  return new Promise((resolve) => {\n    setTimeout(() => {\n      if (linkage === 1) {\n        resolve([\n          {\n            label: 'AAA',\n            value: 'aaa',\n          },\n          {\n            label: 'BBB',\n            value: 'ccc',\n          },\n        ])\n      } else if (linkage === 2) {\n        resolve([\n          {\n            label: 'CCC',\n            value: 'ccc',\n          },\n          {\n            label: 'DDD',\n            value: 'ddd',\n          },\n        ])\n      }\n    }, 1500)\n  })\n}\n\nconst useAsyncDataSource = (service) => (field) => {\n  field.loading = true\n  service(field).then(\n    action.bound((data) => {\n      field.dataSource = data\n      field.loading = false\n    })\n  )\n}\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    linkage: {\n      type: 'string',\n      title: '联动选择框',\n      enum: [\n        { label: '发请求1', value: 1 },\n        { label: '发请求2', value: 2 },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      'x-component-props': {\n        style: {\n          width: 120,\n        },\n      },\n    },\n    select: {\n      type: 'string',\n      title: '异步选择框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      'x-component-props': {\n        style: {\n          width: 120,\n        },\n      },\n      'x-reactions': ['{{useAsyncDataSource(loadData)}}'],\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} scope={{ useAsyncDataSource, loadData }} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 同步数据源案例\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"select\"\n      title=\"选择框\"\n      dataSource={[\n        { label: '选项1', value: 1 },\n        { label: '选项2', value: 2 },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        Select,\n        {\n          style: {\n            width: 120,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 异步联动数据源案例\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport {\n  createForm,\n  onFieldReact,\n  FormPathPattern,\n  Field as FieldType,\n} from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst useAsyncDataSource = (\n  pattern: FormPathPattern,\n  service: (field: FieldType) => Promise<{ label: string; value: any }[]>\n) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service(field).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async (field) => {\n      const linkage = field.query('linkage').get('value')\n      if (!linkage) return []\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          if (linkage === 1) {\n            resolve([\n              {\n                label: 'AAA',\n                value: 'aaa',\n              },\n              {\n                label: 'BBB',\n                value: 'ccc',\n              },\n            ])\n          } else if (linkage === 2) {\n            resolve([\n              {\n                label: 'CCC',\n                value: 'ccc',\n              },\n              {\n                label: 'DDD',\n                value: 'ddd',\n              },\n            ])\n          }\n        }, 1500)\n      })\n    })\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"linkage\"\n      title=\"联动选择框\"\n      dataSource={[\n        { label: '发请求1', value: 1 },\n        { label: '发请求2', value: 2 },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        Select,\n        {\n          style: {\n            width: 120,\n          },\n        },\n      ]}\n    />\n    <Field\n      name=\"select\"\n      title=\"异步选择框\"\n      decorator={[FormItem]}\n      component={[\n        Select,\n        {\n          style: {\n            width: 120,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://ant.design/components/select-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/SelectTable.md",
    "content": "# SelectTable\n\n> Optional table components\n\n## Markup Schema single case\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    SelectTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Object\n          type=\"string\"\n          name=\"selectTable\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            bordered: false,\n            mode: 'single',\n          }}\n          enum={[\n            { key: '1', name: 'Title-1', description: 'description-1' },\n            { key: '2', name: 'Title-2', description: 'description-2' },\n          ]}\n        >\n          <SchemaField.Void\n            name=\"name\"\n            title=\"Title\"\n            x-component=\"SelectTable.Column\"\n          />\n          <SchemaField.Void\n            name=\"description\"\n            title=\"Description\"\n            x-component=\"SelectTable.Column\"\n          />\n        </SchemaField.Object>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## Markup Schema filter case\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    SelectTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          type=\"array\"\n          name=\"selectTable\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            bordered: false,\n            showSearch: true,\n            optionAsValue: true,\n          }}\n          enum={[\n            { key: '1', name: 'Title-1', description: 'description-1' },\n            { key: '2', name: 'Title-2', description: 'description-2' },\n          ]}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              name=\"name\"\n              title=\"Title\"\n              x-component=\"SelectTable.Column\"\n            />\n            <SchemaField.Void\n              name=\"description\"\n              title=\"Description\"\n              x-component=\"SelectTable.Column\"\n            />\n          </SchemaField.Object>\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## Markup Schema async data source case\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    SelectTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  const onSearch = (value) => {\n    const field = form.query('selectTable').take()\n    field.loading = true\n    setTimeout(() => {\n      field.setState({\n        dataSource: [\n          {\n            key: '3',\n            name: 'AAA' + value,\n            description: 'aaa',\n          },\n          {\n            key: '4',\n            name: 'BBB' + value,\n            description: 'bbb',\n          },\n        ],\n        loading: false,\n      })\n    }, 1500)\n  }\n\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Object\n          type=\"object\"\n          name=\"selectTable\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            showSearch: true,\n            filterOption: false,\n            onSearch,\n          }}\n          enum={[\n            { key: '1', name: 'title-1', description: 'description-1' },\n            { key: '2', name: 'title-2', description: 'description-2' },\n          ]}\n        >\n          <SchemaField.Void\n            name=\"name\"\n            title=\"Title\"\n            x-component=\"SelectTable.Column\"\n          />\n          <SchemaField.Void\n            name=\"description\"\n            title=\"Description\"\n            x-component=\"SelectTable.Column\"\n          />\n        </SchemaField.Object>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## Markup Schema read-pretty case\n\n```tsx\nimport React from 'react'\nimport {\n  Form,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  SelectTable,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    SelectTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <Form form={form} layout=\"vertical\">\n      <SchemaField>\n        <SchemaField.Object\n          title=\"single\"\n          type=\"string\"\n          name=\"selectTable1\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            mode: 'single',\n          }}\n          default=\"1\"\n          enum={[\n            { key: '1', name: 'title-1', description: 'description-1' },\n            { key: '2', name: 'Title-2', description: 'description-2' },\n          ]}\n          x-read-pretty={true}\n        >\n          <SchemaField.Void\n            name=\"name\"\n            title=\"Title\"\n            x-component=\"SelectTable.Column\"\n          />\n          <SchemaField.Void\n            name=\"description\"\n            title=\"Description\"\n            x-component=\"SelectTable.Column\"\n          />\n        </SchemaField.Object>\n        <SchemaField.Object\n          title=\"single + optionAsValue\"\n          type=\"string\"\n          name=\"selectTable2\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            mode: 'single',\n            optionAsValue: true,\n          }}\n          default={{ key: '1', name: 'Title1', description: 'Description1' }}\n          enum={[\n            { key: '1', name: 'title-1', description: 'description-1' },\n            { key: '2', name: 'Title-2', description: 'description-2' },\n          ]}\n          x-read-pretty={true}\n        >\n          <SchemaField.Void\n            name=\"name\"\n            title=\"Title\"\n            x-component=\"SelectTable.Column\"\n          />\n          <SchemaField.Void\n            name=\"description\"\n            title=\"Description\"\n            x-component=\"SelectTable.Column\"\n          />\n        </SchemaField.Object>\n        <SchemaField.Array\n          title=\"multiple\"\n          type=\"array\"\n          name=\"selectTable3\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          default={['1', '3']}\n          enum={[\n            { key: '1', name: 'title-1', description: 'description-1' },\n            { key: '2', name: 'Title-2', description: 'description-2' },\n            { key: '3', name: 'title-3', description: 'description-3' },\n          ]}\n          x-read-pretty={true}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              name=\"name\"\n              title=\"Title\"\n              x-component=\"SelectTable.Column\"\n            />\n            <SchemaField.Void\n              name=\"description\"\n              title=\"Description\"\n              x-component=\"SelectTable.Column\"\n            />\n          </SchemaField.Object>\n        </SchemaField.Array>\n        <SchemaField.Array\n          title=\"multiple + optionAsValue\"\n          type=\"array\"\n          name=\"selectTable4\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            optionAsValue: true,\n          }}\n          default={[\n            { key: '1', name: 'title-1', description: 'description-1' },\n            { key: '3', name: 'title-3', description: 'description-3' },\n          ]}\n          enum={[\n            { key: '1', name: 'title-1', description: 'description-1' },\n            { key: '2', name: 'Title-2', description: 'description-2' },\n            { key: '3', name: 'title-3', description: 'description-3' },\n          ]}\n          x-read-pretty={true}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              name=\"name\"\n              title=\"Title\"\n              x-component=\"SelectTable.Column\"\n            />\n            <SchemaField.Void\n              name=\"description\"\n              title=\"Description\"\n              x-component=\"SelectTable.Column\"\n            />\n          </SchemaField.Object>\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </Form>\n  )\n}\n```\n\n## JSON Schema multiple case\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    SelectTable,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    selectTable: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'SelectTable',\n      'x-component-props': {\n        bordered: false,\n        mode: 'multiple',\n      },\n      enum: [\n        { key: '1', name: 'Title-1', description: 'description-1' },\n        { key: '2', name: 'Title-2', description: 'description-2' },\n      ],\n      properties: {\n        name: {\n          title: 'Title',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '40%',\n          },\n        },\n        description: {\n          title: 'Description',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '60%',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema custom filter case\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    SelectTable,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    selectTable: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'SelectTable',\n      'x-component-props': {\n        bordered: false,\n        showSearch: true,\n        primaryKey: 'key',\n        isTree: true,\n        filterOption: (input, option) =>\n          option.description.toLowerCase().indexOf(input.toLowerCase()) >= 0,\n        filterSort: (optionA, optionB) =>\n          optionA.description\n            .toLowerCase()\n            .localeCompare(optionB.description.toLowerCase()),\n        optionAsValue: true,\n        rowSelection: {\n          checkStrictly: false,\n        },\n      },\n      enum: [\n        { key: '1', name: 'title-1', description: 'A-description' },\n        {\n          key: '2',\n          name: 'title-2',\n          description: 'X-description',\n          children: [\n            {\n              key: '2-1',\n              name: 'title2-1',\n              description: 'Y-description',\n              children: [\n                {\n                  key: '2-1-1',\n                  name: 'title-2-1-1',\n                  description: 'Z-description',\n                },\n              ],\n            },\n            {\n              key: '2-2',\n              name: 'title2-2',\n              description: 'YY-description',\n            },\n          ],\n        },\n        { key: '3', name: 'title-3', description: 'C-description' },\n      ],\n      properties: {\n        name: {\n          title: 'Title',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '40%',\n          },\n        },\n        description: {\n          title: 'Description',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '60%',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema async data source case\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    SelectTable,\n    FormItem,\n  },\n})\n\nconst loadData = async (value) => {\n  return new Promise((resolve) => {\n    setTimeout(() => {\n      resolve([\n        { key: '3', name: 'AAA' + value, description: 'aaa' },\n        { key: '4', name: 'BBB' + value, description: 'bbb' },\n      ])\n    }, 1500)\n  })\n}\n\nconst useAsyncDataSource = (service, field) => (value) => {\n  field.loading = true\n  service(value).then((data) => {\n    field.setState({\n      dataSource: data,\n      loading: false,\n    })\n  })\n}\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    selectTable: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'SelectTable',\n      'x-component-props': {\n        showSearch: true,\n        filterOption: false,\n        onSearch: '{{useAsyncDataSource(loadData,$self)}}',\n      },\n      enum: [\n        { key: '1', name: 'title-1', description: 'description-1' },\n        { key: '2', name: 'title-2', description: 'description-2' },\n      ],\n      properties: {\n        name: {\n          title: 'Title',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '40%',\n          },\n        },\n        description: {\n          title: 'Description',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '60%',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} scope={{ useAsyncDataSource, loadData }} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"SelectTable\"\n      dataSource={[\n        { key: '1', name: 'title-1', description: 'description-1' },\n        { key: '2', name: 'title-2', description: 'description-2' },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        SelectTable,\n        {\n          columns: [\n            { dataIndex: 'name', title: 'Title' },\n            { dataIndex: 'description', title: 'Description' },\n          ],\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n### SelectTable\n\n| Property name | Type                                               | Description                                                                                                                                                                                                                                                 | Default value |\n| ------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |\n| mode          | `'multiple' \\| 'single'`                           | Set mode of SelectTable                                                                                                                                                                                                                                     | `'multiple'`  |\n| valueType     | `'all' \\| 'parent' \\| 'child' \\| 'path'`           | value type, Only applies when checkStrictly is set to `false`                                                                                                                                                                                               | `'all'`       |\n| optionAsValue | boolean                                            | use `option` as value, Only applies when valueType is not set to `'path'`                                                                                                                                                                                   | false         |\n| showSearch    | boolean                                            | show `Search` component                                                                                                                                                                                                                                     | false         |\n| searchProps   | object                                             | `Search` component props                                                                                                                                                                                                                                    | -             |\n| primaryKey    | `string \\| (record) => string`                     | Row's unique key                                                                                                                                                                                                                                            | `'key'`       |\n| filterOption  | `boolean \\| (inputValue, option) => boolean`       | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns true, the option will be included in the filtered set; Otherwise, it will be excluded |\n| filterSort    | (optionA, optionB) => number                       | Sort function for search options sorting, see Array.sort's compareFunction                                                                                                                                                                                  | -             |\n| onSearch      | Callback function that is fired when input changed | (inputValue) => void                                                                                                                                                                                                                                        | -             |\n\n`TableProps` type definition reference antd https://ant.design/components/table/\n\n### rowSelection\n\n| Property name | Type    | Description                                                                | Default value |\n| ------------- | ------- | -------------------------------------------------------------------------- | ------------- |\n| checkStrictly | boolean | Check table row precisely; parent row and children rows are not associated | true          |\n\n`rowSelectionProps` type definition reference antd https://ant.design/components/table/#rowSelection\n\n### SelectTable.Column\n\n`ColumnProps` type definition reference antd https://ant.design/components/table/ Table.Column\n"
  },
  {
    "path": "packages/antd/docs/components/SelectTable.zh-CN.md",
    "content": "# SelectTable\n\n> 表格选择组件\n\n## Markup Schema 单选案例\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    SelectTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Object\n          type=\"string\"\n          name=\"selectTable\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            bordered: false,\n            mode: 'single',\n          }}\n          enum={[\n            { key: '1', name: '标题1', description: '描述1' },\n            { key: '2', name: '标题2', description: '描述2' },\n          ]}\n        >\n          <SchemaField.Void\n            name=\"name\"\n            title=\"标题\"\n            x-component=\"SelectTable.Column\"\n          />\n          <SchemaField.Void\n            name=\"description\"\n            title=\"描述\"\n            x-component=\"SelectTable.Column\"\n          />\n        </SchemaField.Object>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## Markup Schema 筛选案例\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    SelectTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          type=\"array\"\n          name=\"selectTable\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            bordered: false,\n            showSearch: true,\n            optionAsValue: true,\n          }}\n          enum={[\n            { key: '1', name: '标题1', description: '描述1' },\n            { key: '2', name: '标题2', description: '描述2' },\n          ]}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              name=\"name\"\n              title=\"标题\"\n              x-component=\"SelectTable.Column\"\n            />\n            <SchemaField.Void\n              name=\"description\"\n              title=\"描述\"\n              x-component=\"SelectTable.Column\"\n            />\n          </SchemaField.Object>\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## Markup Schema 异步数据源案例\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    SelectTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  const onSearch = (value) => {\n    const field = form.query('selectTable').take()\n    field.loading = true\n    setTimeout(() => {\n      field.setState({\n        dataSource: [\n          {\n            key: '3',\n            name: 'AAA' + value,\n            description: 'aaa',\n          },\n          {\n            key: '4',\n            name: 'BBB' + value,\n            description: 'bbb',\n          },\n        ],\n        loading: false,\n      })\n    }, 1500)\n  }\n\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Object\n          type=\"object\"\n          name=\"selectTable\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            showSearch: true,\n            filterOption: false,\n            onSearch,\n          }}\n          enum={[\n            { key: '1', name: '标题1', description: '描述1' },\n            { key: '2', name: '标题2', description: '描述2' },\n          ]}\n        >\n          <SchemaField.Void\n            name=\"name\"\n            title=\"标题\"\n            x-component=\"SelectTable.Column\"\n          />\n          <SchemaField.Void\n            name=\"description\"\n            title=\"描述\"\n            x-component=\"SelectTable.Column\"\n          />\n        </SchemaField.Object>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## Markup Schema 阅读态案例\n\n```tsx\nimport React from 'react'\nimport {\n  Form,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  SelectTable,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    SelectTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <Form form={form} layout=\"vertical\">\n      <SchemaField>\n        <SchemaField.Object\n          title=\"单选\"\n          type=\"string\"\n          name=\"selectTable1\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            mode: 'single',\n          }}\n          default=\"1\"\n          enum={[\n            { key: '1', name: '标题1', description: '描述1' },\n            { key: '2', name: '标题2', description: '描述2' },\n          ]}\n          x-read-pretty={true}\n        >\n          <SchemaField.Void\n            name=\"name\"\n            title=\"标题\"\n            x-component=\"SelectTable.Column\"\n          />\n          <SchemaField.Void\n            name=\"description\"\n            title=\"描述\"\n            x-component=\"SelectTable.Column\"\n          />\n        </SchemaField.Object>\n        <SchemaField.Object\n          title=\"单选 + optionAsValue\"\n          type=\"string\"\n          name=\"selectTable2\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            mode: 'single',\n            optionAsValue: true,\n          }}\n          default={{ key: '1', name: '标题1', description: '描述1' }}\n          enum={[\n            { key: '1', name: '标题1', description: '描述1' },\n            { key: '2', name: '标题2', description: '描述2' },\n          ]}\n          x-read-pretty={true}\n        >\n          <SchemaField.Void\n            name=\"name\"\n            title=\"标题\"\n            x-component=\"SelectTable.Column\"\n          />\n          <SchemaField.Void\n            name=\"description\"\n            title=\"描述\"\n            x-component=\"SelectTable.Column\"\n          />\n        </SchemaField.Object>\n        <SchemaField.Array\n          title=\"多选\"\n          type=\"array\"\n          name=\"selectTable3\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          default={['1', '3']}\n          enum={[\n            { key: '1', name: '标题1', description: '描述1' },\n            { key: '2', name: '标题2', description: '描述2' },\n            { key: '3', name: '标题3', description: '描述3' },\n          ]}\n          x-read-pretty={true}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              name=\"name\"\n              title=\"标题\"\n              x-component=\"SelectTable.Column\"\n            />\n            <SchemaField.Void\n              name=\"description\"\n              title=\"描述\"\n              x-component=\"SelectTable.Column\"\n            />\n          </SchemaField.Object>\n        </SchemaField.Array>\n        <SchemaField.Array\n          title=\"多选 + optionAsValue\"\n          type=\"array\"\n          name=\"selectTable4\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            optionAsValue: true,\n          }}\n          default={[\n            { key: '1', name: '标题1', description: '描述1' },\n            { key: '3', name: '标题3', description: '描述3' },\n          ]}\n          enum={[\n            { key: '1', name: '标题1', description: '描述1' },\n            { key: '2', name: '标题2', description: '描述2' },\n            { key: '3', name: '标题3', description: '描述3' },\n          ]}\n          x-read-pretty={true}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              name=\"name\"\n              title=\"标题\"\n              x-component=\"SelectTable.Column\"\n            />\n            <SchemaField.Void\n              name=\"description\"\n              title=\"描述\"\n              x-component=\"SelectTable.Column\"\n            />\n          </SchemaField.Object>\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </Form>\n  )\n}\n```\n\n## JSON Schema 多选案例\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    SelectTable,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    selectTable: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'SelectTable',\n      'x-component-props': {\n        bordered: false,\n        mode: 'multiple',\n      },\n      enum: [\n        { key: '1', name: '标题1', description: '描述1' },\n        { key: '2', name: '标题2', description: '描述2' },\n      ],\n      properties: {\n        name: {\n          title: '标题',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '40%',\n          },\n        },\n        description: {\n          title: '描述',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '60%',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 自定义筛选案例\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    SelectTable,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    selectTable: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'SelectTable',\n      'x-component-props': {\n        bordered: false,\n        showSearch: true,\n        primaryKey: 'key',\n        isTree: true,\n        filterOption: (input, option) =>\n          option.description.toLowerCase().indexOf(input.toLowerCase()) >= 0,\n        filterSort: (optionA, optionB) =>\n          optionA.description\n            .toLowerCase()\n            .localeCompare(optionB.description.toLowerCase()),\n        optionAsValue: true,\n        rowSelection: {\n          checkStrictly: false,\n        },\n      },\n      enum: [\n        { key: '1', name: '标题1', description: 'A-描述' },\n        {\n          key: '2',\n          name: '标题2',\n          description: 'X-描述',\n          children: [\n            {\n              key: '2-1',\n              name: '标题2-1',\n              description: 'Y-描述',\n              children: [\n                { key: '2-1-1', name: '标题2-1-1', description: 'Z-描述' },\n              ],\n            },\n            {\n              key: '2-2',\n              name: '标题2-2',\n              description: 'YY-描述',\n            },\n          ],\n        },\n        { key: '3', name: '标题3', description: 'C-描述' },\n      ],\n      properties: {\n        name: {\n          title: '标题',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '40%',\n          },\n        },\n        description: {\n          title: '描述',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '60%',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 异步数据源案例\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    SelectTable,\n    FormItem,\n  },\n})\n\nconst loadData = async (value) => {\n  return new Promise((resolve) => {\n    setTimeout(() => {\n      resolve([\n        { key: '3', name: 'AAA' + value, description: 'aaa' },\n        { key: '4', name: 'BBB' + value, description: 'bbb' },\n      ])\n    }, 1500)\n  })\n}\n\nconst useAsyncDataSource = (service, field) => (value) => {\n  field.loading = true\n  service(value).then((data) => {\n    field.setState({\n      dataSource: data,\n      loading: false,\n    })\n  })\n}\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    selectTable: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'SelectTable',\n      'x-component-props': {\n        showSearch: true,\n        filterOption: false,\n        onSearch: '{{useAsyncDataSource(loadData,$self)}}',\n      },\n      enum: [\n        { key: '1', name: '标题1', description: '描述1' },\n        { key: '2', name: '标题2', description: '描述2' },\n      ],\n      properties: {\n        name: {\n          title: '标题',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '40%',\n          },\n        },\n        description: {\n          title: '描述',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '60%',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} scope={{ useAsyncDataSource, loadData }} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"SelectTable\"\n      dataSource={[\n        { key: '1', name: '标题1', description: '描述1' },\n        { key: '2', name: '标题2', description: '描述2' },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        SelectTable,\n        {\n          columns: [\n            { dataIndex: 'name', title: '标题' },\n            { dataIndex: 'description', title: '描述' },\n          ],\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n### SelectTable\n\n| 属性名        | 类型                                         | 描述                                                                                                                                 | 默认值       |\n| ------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ------------ |\n| mode          | `'multiple' \\| 'single'`                     | 设置 SelectTable 模式为单选或多选                                                                                                    | `'multiple'` |\n| valueType     | `'all' \\| 'parent' \\| 'child' \\| 'path'`     | 返回值类型，checkStrictly 设置为 `false` 时有效                                                                                      | `'all'`      |\n| optionAsValue | boolean                                      | 使用表格行数据作为值，valueType 值为 `'path'` 时无效                                                                                 | false        |\n| showSearch    | boolean                                      | 是否显示搜索组件                                                                                                                     | false        |\n| searchProps   | object                                       | Search 组件属性                                                                                                                      | -            |\n| primaryKey    | `string \\| (record) => string`               | 表格行 key 的取值                                                                                                                    | `'key'`      |\n| filterOption  | `boolean \\| (inputValue, option) => boolean` | 是否根据输入项进行筛选。当其为一个函数时，会接收 inputValue option 两个参数，当 option 符合筛选条件时，应返回 true，反之则返回 false | true         |\n| filterSort    | (optionA, optionB) => number                 | 搜索时对筛选结果项的排序函数, 类似 Array.sort 里的 compareFunction                                                                   | -            |\n| onSearch      | 文本框值变化时回调                           | (inputValue) => void                                                                                                                 | -            |\n\n参考 https://ant.design/components/table-cn/\n\n### rowSelection\n\n| 属性名        | 类型    | 描述                                                         | 默认值 |\n| ------------- | ------- | ------------------------------------------------------------ | ------ |\n| checkStrictly | boolean | checkable 状态下节点选择完全受控（父子数据选中状态不再关联） | true   |\n\n参考 https://ant.design/components/table/#rowSelection\n\n### SelectTable.Column\n\n参考 https://ant.design/components/table-cn/ Table.Column 属性\n"
  },
  {
    "path": "packages/antd/docs/components/Space.md",
    "content": "# Space\n\n> Super convenient Flex layout component, can help users quickly realize the layout of any element side by side next to each other\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    Space,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={16}>\n      <SchemaField>\n        <SchemaField.Void\n          title=\"name\"\n          x-decorator=\"FormItem\"\n          x-decorator-props={{\n            asterisk: true,\n            feedbackLayout: 'none',\n          }}\n          x-component=\"Space\"\n        >\n          <SchemaField.String\n            name=\"firstName\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            required\n          />\n          <SchemaField.String\n            name=\"lastName\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            required\n          />\n        </SchemaField.Void>\n        <SchemaField.Void\n          title=\"Text concatenation\"\n          x-decorator=\"FormItem\"\n          x-decorator-props={{\n            asterisk: true,\n            feedbackLayout: 'none',\n          }}\n          x-component=\"Space\"\n        >\n          <SchemaField.String\n            name=\"aa\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            x-decorator-props={{\n              addonAfter: 'Unit',\n            }}\n            required\n          />\n          <SchemaField.String\n            name=\"bb\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            x-decorator-props={{\n              addonAfter: 'Unit',\n            }}\n            required\n          />\n          <SchemaField.String\n            name=\"cc\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            x-decorator-props={{\n              addonAfter: 'Unit',\n            }}\n            required\n          />\n        </SchemaField.Void>\n        <SchemaField.String\n          name=\"textarea\"\n          title=\"text box\"\n          x-decorator=\"FormItem\"\n          required\n          x-component=\"Input.TextArea\"\n          x-component-props={{\n            style: {\n              width: 400,\n            },\n          }}\n        />\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    Space,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    name: {\n      type: 'void',\n      title: 'Name',\n      'x-decorator': 'FormItem',\n      'x-decorator-props': {\n        asterisk: true,\n        feedbackLayout: 'none',\n      },\n      'x-component': 'Space',\n      properties: {\n        firstName: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          required: true,\n        },\n        lastName: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          required: true,\n        },\n      },\n    },\n    texts: {\n      type: 'void',\n      title: 'Text concatenation',\n      'x-decorator': 'FormItem',\n      'x-decorator-props': {\n        asterisk: true,\n        feedbackLayout: 'none',\n      },\n      'x-component': 'Space',\n      properties: {\n        aa: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            addonAfter: 'Unit',\n          },\n          'x-component': 'Input',\n          required: true,\n        },\n        bb: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            addonAfter: 'Unit',\n          },\n          'x-component': 'Input',\n          required: true,\n        },\n        cc: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            addonAfter: 'Unit',\n          },\n          'x-component': 'Input',\n          required: true,\n        },\n      },\n    },\n\n    textarea: {\n      type: 'string',\n      title: 'Text box',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input.TextArea',\n      'x-component-props': {\n        style: {\n          width: 400,\n        },\n      },\n      required: true,\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={16}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, VoidField } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={16}>\n      <VoidField\n        name=\"name\"\n        title=\"name\"\n        decorator={[\n          FormItem,\n          {\n            asterisk: true,\n            feedbackLayout: 'none',\n          },\n        ]}\n        component={[Space]}\n      >\n        <Field\n          name=\"firstName\"\n          decorator={[FormItem]}\n          component={[Input]}\n          required\n        />\n        <Field\n          name=\"lastName\"\n          decorator={[FormItem]}\n          component={[Input]}\n          required\n        />\n      </VoidField>\n      <VoidField\n        name=\"texts\"\n        title=\"Text concatenation\"\n        decorator={[\n          FormItem,\n          {\n            asterisk: true,\n            feedbackLayout: 'none',\n          },\n        ]}\n        component={[Space]}\n      >\n        <Field\n          name=\"aa\"\n          decorator={[\n            FormItem,\n            {\n              addonAfter: 'Unit',\n            },\n          ]}\n          component={[Input]}\n          required\n        />\n        <Field\n          name=\"bb\"\n          decorator={[\n            FormItem,\n            {\n              addonAfter: 'Unit',\n            },\n          ]}\n          component={[Input]}\n          required\n        />\n        <Field\n          name=\"cc\"\n          decorator={[\n            FormItem,\n            {\n              addonAfter: 'Unit',\n            },\n          ]}\n          component={[Input]}\n          required\n        />\n      </VoidField>\n      <Field\n        name=\"textarea\"\n        title=\"text box\"\n        decorator={[FormItem]}\n        component={[\n          Input.TextArea,\n          {\n            style: {\n              width: 400,\n            },\n          },\n        ]}\n        required\n      />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://ant.design/components/space-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Space.zh-CN.md",
    "content": "# Space\n\n> 超级便捷的 Flex 布局组件，可以帮助用户快速实现任何元素的并排紧挨布局\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    Space,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={16}>\n      <SchemaField>\n        <SchemaField.Void\n          title=\"姓名\"\n          x-decorator=\"FormItem\"\n          x-decorator-props={{\n            asterisk: true,\n            feedbackLayout: 'none',\n          }}\n          x-component=\"Space\"\n        >\n          <SchemaField.String\n            name=\"firstName\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            required\n          />\n          <SchemaField.String\n            name=\"lastName\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            required\n          />\n        </SchemaField.Void>\n        <SchemaField.Void\n          title=\"文本串联\"\n          x-decorator=\"FormItem\"\n          x-decorator-props={{\n            asterisk: true,\n            feedbackLayout: 'none',\n          }}\n          x-component=\"Space\"\n        >\n          <SchemaField.String\n            name=\"aa\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            x-decorator-props={{\n              addonAfter: '单位',\n            }}\n            required\n          />\n          <SchemaField.String\n            name=\"bb\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            x-decorator-props={{\n              addonAfter: '单位',\n            }}\n            required\n          />\n          <SchemaField.String\n            name=\"cc\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            x-decorator-props={{\n              addonAfter: '单位',\n            }}\n            required\n          />\n        </SchemaField.Void>\n        <SchemaField.String\n          name=\"textarea\"\n          title=\"文本框\"\n          x-decorator=\"FormItem\"\n          required\n          x-component=\"Input.TextArea\"\n          x-component-props={{\n            style: {\n              width: 400,\n            },\n          }}\n        />\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    Space,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    name: {\n      type: 'void',\n      title: '姓名',\n      'x-decorator': 'FormItem',\n      'x-decorator-props': {\n        asterisk: true,\n        feedbackLayout: 'none',\n      },\n      'x-component': 'Space',\n      properties: {\n        firstName: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          required: true,\n        },\n        lastName: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          required: true,\n        },\n      },\n    },\n    texts: {\n      type: 'void',\n      title: '文本串联',\n      'x-decorator': 'FormItem',\n      'x-decorator-props': {\n        asterisk: true,\n        feedbackLayout: 'none',\n      },\n      'x-component': 'Space',\n      properties: {\n        aa: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            addonAfter: '单位',\n          },\n          'x-component': 'Input',\n          required: true,\n        },\n        bb: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            addonAfter: '单位',\n          },\n          'x-component': 'Input',\n          required: true,\n        },\n        cc: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            addonAfter: '单位',\n          },\n          'x-component': 'Input',\n          required: true,\n        },\n      },\n    },\n\n    textarea: {\n      type: 'string',\n      title: '文本框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input.TextArea',\n      'x-component-props': {\n        style: {\n          width: 400,\n        },\n      },\n      required: true,\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={16}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, VoidField } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={16}>\n      <VoidField\n        name=\"name\"\n        title=\"姓名\"\n        decorator={[\n          FormItem,\n          {\n            asterisk: true,\n            feedbackLayout: 'none',\n          },\n        ]}\n        component={[Space]}\n      >\n        <Field\n          name=\"firstName\"\n          decorator={[FormItem]}\n          component={[Input]}\n          required\n        />\n        <Field\n          name=\"lastName\"\n          decorator={[FormItem]}\n          component={[Input]}\n          required\n        />\n      </VoidField>\n      <VoidField\n        name=\"texts\"\n        title=\"文本串联\"\n        decorator={[\n          FormItem,\n          {\n            asterisk: true,\n            feedbackLayout: 'none',\n          },\n        ]}\n        component={[Space]}\n      >\n        <Field\n          name=\"aa\"\n          decorator={[\n            FormItem,\n            {\n              addonAfter: '单位',\n            },\n          ]}\n          component={[Input]}\n          required\n        />\n        <Field\n          name=\"bb\"\n          decorator={[\n            FormItem,\n            {\n              addonAfter: '单位',\n            },\n          ]}\n          component={[Input]}\n          required\n        />\n        <Field\n          name=\"cc\"\n          decorator={[\n            FormItem,\n            {\n              addonAfter: '单位',\n            },\n          ]}\n          component={[Input]}\n          required\n        />\n      </VoidField>\n      <Field\n        name=\"textarea\"\n        title=\"文本框\"\n        decorator={[FormItem]}\n        component={[\n          Input.TextArea,\n          {\n            style: {\n              width: 400,\n            },\n          },\n        ]}\n        required\n      />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://ant.design/components/space-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Submit.md",
    "content": "# Submit\n\n> Submit button\n\n## Ordinary submission\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"input box\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Prevent Duplicate Submission (Loading)\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"input box\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit\n        onSubmit={(values) => {\n          return new Promise((resolve) => {\n            setTimeout(() => {\n              console.log(values)\n              resolve()\n            }, 2000)\n          })\n        }}\n        onSubmitFailed={console.log}\n      >\n        submit\n      </Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nFor 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\n\n| Property name   | Type                                                                                             | Description                                               | Default value |\n| --------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------- | ------------- |\n| onClick         | `(event: MouseEvent) => void \\| boolean`                                                         | Click event, if it returns false, it can block submission | -             |\n| onSubmit        | `(values: any) => Promise<any> \\| any`                                                           | Submit event callback                                     | -             |\n| onSubmitSuccess | (payload: any) => void                                                                           | Submit successful response event                          | -             |\n| onSubmitFailed  | (feedbacks: [IFormFeedback](https://core.formilyjs.org/api/models/form#iformfeedback)[]) => void | Submit verification failure event callback                | -             |\n"
  },
  {
    "path": "packages/antd/docs/components/Submit.zh-CN.md",
    "content": "# Submit\n\n> 提交按钮\n\n## 普通提交\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"输入框\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 防重复提交(Loading)\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"输入框\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit\n        onSubmit={(values) => {\n          return new Promise((resolve) => {\n            setTimeout(() => {\n              console.log(values)\n              resolve()\n            }, 2000)\n          })\n        }}\n        onSubmitFailed={console.log}\n      >\n        提交\n      </Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n按钮相关的 API 属性，我们参考 https://ant.design/components/button-cn/ 即可，剩下是 Submit 组件独有的 API 属性\n\n| 属性名          | 类型                                                                                                   | 描述                                  | 默认值 |\n| --------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------- | ------ |\n| onClick         | `(event: MouseEvent) => void \\| boolean`                                                               | 点击事件，如果返回 false 可以阻塞提交 | -      |\n| onSubmit        | `(values: any) => Promise<any> \\| any`                                                                 | 提交事件回调                          | -      |\n| onSubmitSuccess | (payload: any) => void                                                                                 | 提交成功响应事件                      | -      |\n| onSubmitFailed  | (feedbacks: [IFormFeedback](https://core.formilyjs.org/zh-CN/api/models/form#iformfeedback)[]) => void | 提交校验失败事件回调                  | -      |\n"
  },
  {
    "path": "packages/antd/docs/components/Switch.md",
    "content": "# Switch\n\n> Switch Components\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { Switch, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Switch,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Boolean\n        name=\"switch\"\n        title=\"Switch\"\n        x-decorator=\"FormItem\"\n        x-component=\"Switch\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { Switch, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Switch,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    switch: {\n      type: 'boolean',\n      title: 'Switch',\n      'x-decorator': 'FormItem',\n      'x-component': 'Switch',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { Switch, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"switch\"\n      title=\"Switch\"\n      decorator={[FormItem]}\n      component={[Switch]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://ant.design/components/switch-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Switch.zh-CN.md",
    "content": "# Switch\n\n> 开关组件\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Switch, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Switch,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Boolean\n        name=\"switch\"\n        title=\"开关\"\n        x-decorator=\"FormItem\"\n        x-component=\"Switch\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Switch, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Switch,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    switch: {\n      type: 'boolean',\n      title: '开关',\n      'x-decorator': 'FormItem',\n      'x-component': 'Switch',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { Switch, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"switch\"\n      title=\"开关\"\n      decorator={[FormItem]}\n      component={[Switch]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://ant.design/components/switch-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/TimePicker.md",
    "content": "# TimePicker\n\n> Time Picker\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TimePicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"time\"\n        title=\"time\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"TimePicker\"\n      />\n      <SchemaField.String\n        name=\"[startTime,endTime]\"\n        title=\"time range\"\n        x-decorator=\"FormItem\"\n        x-component=\"TimePicker.RangePicker\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TimePicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    time: {\n      title: 'Time',\n      'x-decorator': 'FormItem',\n      'x-component': 'TimePicker',\n      type: 'string',\n    },\n    '[startTime,endTime]': {\n      title: 'Time Range',\n      'x-decorator': 'FormItem',\n      'x-component': 'TimePicker.RangePicker',\n      type: 'string',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"time\"\n      title=\"time\"\n      decorator={[FormItem]}\n      component={[TimePicker]}\n    />\n    <Field\n      name=\"[startTime,endTime]\"\n      title=\"time range\"\n      decorator={[FormItem]}\n      component={[TimePicker.RangePicker]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://ant.design/components/time-picker-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/TimePicker.zh-CN.md",
    "content": "# TimePicker\n\n> 时间选择器\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TimePicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"time\"\n        title=\"时间\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"TimePicker\"\n      />\n      <SchemaField.String\n        name=\"[startTime,endTime]\"\n        title=\"时间范围\"\n        x-decorator=\"FormItem\"\n        x-component=\"TimePicker.RangePicker\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TimePicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    time: {\n      title: '时间',\n      'x-decorator': 'FormItem',\n      'x-component': 'TimePicker',\n      type: 'string',\n    },\n    '[startTime,endTime]': {\n      title: '时间范围',\n      'x-decorator': 'FormItem',\n      'x-component': 'TimePicker.RangePicker',\n      type: 'string',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"time\"\n      title=\"时间\"\n      decorator={[FormItem]}\n      component={[TimePicker]}\n    />\n    <Field\n      name=\"[startTime,endTime]\"\n      title=\"时间范围\"\n      decorator={[FormItem]}\n      component={[TimePicker.RangePicker]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://ant.design/components/time-picker-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Transfer.md",
    "content": "# Transfer\n\n> Shuttle Box\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Transfer,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Array\n        name=\"transfer\"\n        title=\"shuttle box\"\n        x-decorator=\"FormItem\"\n        x-component=\"Transfer\"\n        enum={[\n          { title: 'Option 1', key: 1 },\n          { title: 'Option 2', key: 2 },\n        ]}\n        x-component-props={{\n          render: (item) => item.title,\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Transfer,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    transfer: {\n      type: 'array',\n      title: 'shuttle box',\n      'x-decorator': 'FormItem',\n      'x-component': 'Transfer',\n      enum: [\n        { title: 'Option 1', key: 1 },\n        { title: 'Option 2', key: 2 },\n      ],\n      'x-component-props': {\n        render: '{{renderTitle}}',\n      },\n    },\n  },\n}\n\nconst renderTitle = (item) => item.title\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} scope={{ renderTitle }} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"transfer\"\n      title=\"shuttle box\"\n      dataSource={[\n        { title: 'Option 1', key: 1 },\n        { title: 'Option 2', key: 2 },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        Transfer,\n        {\n          render: (item) => item.title,\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://ant.design/components/transfer-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Transfer.zh-CN.md",
    "content": "# Transfer\n\n> 穿梭框\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Transfer,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Array\n        name=\"transfer\"\n        title=\"穿梭框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Transfer\"\n        enum={[\n          { title: '选项1', key: 1 },\n          { title: '选项2', key: 2 },\n        ]}\n        x-component-props={{\n          render: (item) => item.title,\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Transfer,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    transfer: {\n      type: 'array',\n      title: '穿梭框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Transfer',\n      enum: [\n        { title: '选项1', key: 1 },\n        { title: '选项2', key: 2 },\n      ],\n      'x-component-props': {\n        render: '{{renderTitle}}',\n      },\n    },\n  },\n}\n\nconst renderTitle = (item) => item.title\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} scope={{ renderTitle }} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"transfer\"\n      title=\"穿梭框\"\n      dataSource={[\n        { title: '选项1', key: 1 },\n        { title: '选项2', key: 2 },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        Transfer,\n        {\n          render: (item) => item.title,\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://ant.design/components/transfer-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/TreeSelect.md",
    "content": "# TreeSelect\n\n> Tree selector\n\n## Markup Schema synchronization data source case\n\n```tsx\nimport React from 'react'\nimport { TreeSelect, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TreeSelect,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"select\"\n        title=\"select box\"\n        x-decorator=\"FormItem\"\n        x-component=\"TreeSelect\"\n        enum={[\n          {\n            label: 'Option 1',\n            value: 1,\n            children: [\n              {\n                title: 'Child Node1',\n                value: '0-0-0',\n                key: '0-0-0',\n              },\n              {\n                title: 'Child Node2',\n                value: '0-0-1',\n                key: '0-0-1',\n              },\n              {\n                title: 'Child Node3',\n                value: '0-0-2',\n                key: '0-0-2',\n              },\n            ],\n          },\n          {\n            label: 'Option 2',\n            value: 2,\n            children: [\n              {\n                title: 'Child Node3',\n                value: '0-1-0',\n                key: '0-1-0',\n              },\n              {\n                title: 'Child Node4',\n                value: '0-1-1',\n                key: '0-1-1',\n              },\n              {\n                title: 'Child Node5',\n                value: '0-1-2',\n                key: '0-1-2',\n              },\n            ],\n          },\n        ]}\n        x-component-props={{\n          style: {\n            width: 200,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Markup Schema Asynchronous Linkage Data Source Case\n\n```tsx\nimport React from 'react'\nimport {\n  TreeSelect,\n  Select,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm, onFieldReact, FormPathPattern, Field } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    TreeSelect,\n    FormItem,\n  },\n})\n\nconst useAsyncDataSource = (\n  pattern: FormPathPattern,\n  service: (field: Field) => Promise<{ label: string; value: any }[]>\n) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service(field).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async (field) => {\n      const linkage = field.query('linkage').get('value')\n      if (!linkage) return []\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          if (linkage === 1) {\n            resolve([\n              {\n                label: 'AAA',\n                value: 'aaa',\n                children: [\n                  {\n                    title: 'Child Node1',\n                    value: '0-0-0',\n                    key: '0-0-0',\n                  },\n                  {\n                    title: 'Child Node2',\n                    value: '0-0-1',\n                    key: '0-0-1',\n                  },\n                  {\n                    title: 'Child Node3',\n                    value: '0-0-2',\n                    key: '0-0-2',\n                  },\n                ],\n              },\n              {\n                label: 'BBB',\n                value: 'ccc',\n                children: [\n                  {\n                    title: 'Child Node1',\n                    value: '0-1-0',\n                    key: '0-1-0',\n                  },\n                  {\n                    title: 'Child Node2',\n                    value: '0-1-1',\n                    key: '0-1-1',\n                  },\n                  {\n                    title: 'Child Node3',\n                    value: '0-1-2',\n                    key: '0-1-2',\n                  },\n                ],\n              },\n            ])\n          } else if (linkage === 2) {\n            resolve([\n              {\n                label: 'CCC',\n                value: 'ccc',\n                children: [\n                  {\n                    title: 'Child Node1',\n                    value: '0-0-0',\n                    key: '0-0-0',\n                  },\n                  {\n                    title: 'Child Node2',\n                    value: '0-0-1',\n                    key: '0-0-1',\n                  },\n                  {\n                    title: 'Child Node3',\n                    value: '0-0-2',\n                    key: '0-0-2',\n                  },\n                ],\n              },\n              {\n                label: 'DDD',\n                value: 'ddd',\n                children: [\n                  {\n                    title: 'Child Node1',\n                    value: '0-1-0',\n                    key: '0-1-0',\n                  },\n                  {\n                    title: 'Child Node2',\n                    value: '0-1-1',\n                    key: '0-1-1',\n                  },\n                  {\n                    title: 'Child Node3',\n                    value: '0-1-2',\n                    key: '0-1-2',\n                  },\n                ],\n              },\n            ])\n          }\n        }, 1500)\n      })\n    })\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"linkage\"\n        title=\"Linkage selection box\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        enum={[\n          { label: 'Request 1', value: 1 },\n          { label: 'Request 2', value: 2 },\n        ]}\n        x-component-props={{\n          style: {\n            width: 200,\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"select\"\n        title=\"Asynchronous select box\"\n        x-decorator=\"FormItem\"\n        x-component=\"TreeSelect\"\n        x-component-props={{\n          style: {\n            width: 200,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema synchronization data source case\n\n```tsx\nimport React from 'react'\nimport { TreeSelect, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TreeSelect,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    select: {\n      type: 'string',\n      title: 'Select box',\n      'x-decorator': 'FormItem',\n      'x-component': 'TreeSelect',\n      enum: [\n        {\n          label: 'Option 1',\n          value: 1,\n          children: [\n            {\n              title: 'Child Node1',\n              value: '0-0-0',\n              key: '0-0-0',\n            },\n            {\n              title: 'Child Node2',\n              value: '0-0-1',\n              key: '0-0-1',\n            },\n            {\n              title: 'Child Node3',\n              value: '0-0-2',\n              key: '0-0-2',\n            },\n          ],\n        },\n        {\n          label: 'Option 2',\n          value: 2,\n          children: [\n            {\n              title: 'Child Node1',\n              value: '0-1-0',\n              key: '0-1-0',\n            },\n            {\n              title: 'Child Node2',\n              value: '0-1-1',\n              key: '0-1-1',\n            },\n            {\n              title: 'Child Node3',\n              value: '0-1-2',\n              key: '0-1-2',\n            },\n          ],\n        },\n      ],\n      'x-component-props': {\n        style: {\n          width: 200,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema asynchronous linkage data source case\n\n```tsx\nimport React from 'react'\nimport {\n  TreeSelect,\n  Select,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    TreeSelect,\n    FormItem,\n  },\n})\n\nconst loadData = async (field) => {\n  const linkage = field.query('linkage').get('value')\n  if (!linkage) return []\n  return new Promise((resolve) => {\n    setTimeout(() => {\n      if (linkage === 1) {\n        resolve([\n          {\n            label: 'AAA',\n            value: 'aaa',\n            children: [\n              {\n                title: 'Child Node1',\n                value: '0-0-0',\n                key: '0-0-0',\n              },\n              {\n                title: 'Child Node2',\n                value: '0-0-1',\n                key: '0-0-1',\n              },\n              {\n                title: 'Child Node3',\n                value: '0-0-2',\n                key: '0-0-2',\n              },\n            ],\n          },\n          {\n            label: 'BBB',\n            value: 'ccc',\n            children: [\n              {\n                title: 'Child Node1',\n                value: '0-1-0',\n                key: '0-1-0',\n              },\n              {\n                title: 'Child Node2',\n                value: '0-1-1',\n                key: '0-1-1',\n              },\n              {\n                title: 'Child Node3',\n                value: '0-1-2',\n                key: '0-1-2',\n              },\n            ],\n          },\n        ])\n      } else if (linkage === 2) {\n        resolve([\n          {\n            label: 'CCC',\n            value: 'ccc',\n            children: [\n              {\n                title: 'Child Node1',\n                value: '0-0-0',\n                key: '0-0-0',\n              },\n              {\n                title: 'Child Node2',\n                value: '0-0-1',\n                key: '0-0-1',\n              },\n              {\n                title: 'Child Node3',\n                value: '0-0-2',\n                key: '0-0-2',\n              },\n            ],\n          },\n          {\n            label: 'DDD',\n            value: 'ddd',\n            children: [\n              {\n                title: 'Child Node1',\n                value: '0-1-0',\n                key: '0-1-0',\n              },\n              {\n                title: 'Child Node2',\n                value: '0-1-1',\n                key: '0-1-1',\n              },\n              {\n                title: 'Child Node3',\n                value: '0-1-2',\n                key: '0-1-2',\n              },\n            ],\n          },\n        ])\n      }\n    }, 1500)\n  })\n}\n\nconst useAsyncDataSource = (service) => (field) => {\n  field.loading = true\n  service(field).then(\n    action.bound((data) => {\n      field.dataSource = data\n      field.loading = false\n    })\n  )\n}\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    linkage: {\n      type: 'string',\n      title: 'Linkage selection box',\n      enum: [\n        { label: 'Request 1', value: 1 },\n        { label: 'Request 2', value: 2 },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      'x-component-props': {\n        style: {\n          width: 200,\n        },\n      },\n    },\n    select: {\n      type: 'string',\n      title: 'Asynchronous selection box',\n      'x-decorator': 'FormItem',\n      'x-component': 'TreeSelect',\n      'x-component-props': {\n        style: {\n          width: 200,\n        },\n      },\n      'x-reactions': ['{{useAsyncDataSource(loadData)}}'],\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} scope={{ useAsyncDataSource, loadData }} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX synchronization data source case\n\n```tsx\nimport React from 'react'\nimport { TreeSelect, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"select\"\n      title=\"select box\"\n      dataSource={[\n        {\n          label: 'Option 1',\n          value: 1,\n          children: [\n            {\n              title: 'Child Node1',\n              value: '0-0-0',\n              key: '0-0-0',\n            },\n            {\n              title: 'Child Node2',\n              value: '0-0-1',\n              key: '0-0-1',\n            },\n            {\n              title: 'Child Node3',\n              value: '0-0-2',\n              key: '0-0-2',\n            },\n          ],\n        },\n        {\n          label: 'Option 2',\n          value: 2,\n          children: [\n            {\n              title: 'Child Node3',\n              value: '0-1-0',\n              key: '0-1-0',\n            },\n            {\n              title: 'Child Node4',\n              value: '0-1-1',\n              key: '0-1-1',\n            },\n            {\n              title: 'Child Node5',\n              value: '0-1-2',\n              key: '0-1-2',\n            },\n          ],\n        },\n      ]}\n      decorator={[FormItem]}\n      component={[TreeSelect]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX asynchronous linkage data source case\n\n```tsx\nimport React from 'react'\nimport {\n  TreeSelect,\n  Select,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport {\n  createForm,\n  onFieldReact,\n  FormPathPattern,\n  Field as FieldType,\n} from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst useAsyncDataSource = (\n  pattern: FormPathPattern,\n  service: (field: FieldType) => Promise<{ label: string; value: any }[]>\n) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service(field).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async (field) => {\n      const linkage = field.query('linkage').get('value')\n      if (!linkage) return []\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          if (linkage === 1) {\n            resolve([\n              {\n                label: 'AAA',\n                value: 'aaa',\n                children: [\n                  {\n                    title: 'Child Node1',\n                    value: '0-0-0',\n                    key: '0-0-0',\n                  },\n                  {\n                    title: 'Child Node2',\n                    value: '0-0-1',\n                    key: '0-0-1',\n                  },\n                  {\n                    title: 'Child Node3',\n                    value: '0-0-2',\n                    key: '0-0-2',\n                  },\n                ],\n              },\n              {\n                label: 'BBB',\n                value: 'ccc',\n                children: [\n                  {\n                    title: 'Child Node1',\n                    value: '0-1-0',\n                    key: '0-1-0',\n                  },\n                  {\n                    title: 'Child Node2',\n                    value: '0-1-1',\n                    key: '0-1-1',\n                  },\n                  {\n                    title: 'Child Node3',\n                    value: '0-1-2',\n                    key: '0-1-2',\n                  },\n                ],\n              },\n            ])\n          } else if (linkage === 2) {\n            resolve([\n              {\n                label: 'CCC',\n                value: 'ccc',\n                children: [\n                  {\n                    title: 'Child Node1',\n                    value: '0-0-0',\n                    key: '0-0-0',\n                  },\n                  {\n                    title: 'Child Node2',\n                    value: '0-0-1',\n                    key: '0-0-1',\n                  },\n                  {\n                    title: 'Child Node3',\n                    value: '0-0-2',\n                    key: '0-0-2',\n                  },\n                ],\n              },\n              {\n                label: 'DDD',\n                value: 'ddd',\n                children: [\n                  {\n                    title: 'Child Node1',\n                    value: '0-1-0',\n                    key: '0-1-0',\n                  },\n                  {\n                    title: 'Child Node2',\n                    value: '0-1-1',\n                    key: '0-1-1',\n                  },\n                  {\n                    title: 'Child Node3',\n                    value: '0-1-2',\n                    key: '0-1-2',\n                  },\n                ],\n              },\n            ])\n          }\n        }, 1500)\n      })\n    })\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"linkage\"\n      title=\"Linkage selection box\"\n      dataSource={[\n        { label: 'Request 1', value: 1 },\n        { label: 'Request 2', value: 2 },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        Select,\n        {\n          style: {\n            width: 200,\n          },\n        },\n      ]}\n    />\n    <Field\n      name=\"select\"\n      title=\"Asynchronous select box\"\n      decorator={[FormItem]}\n      component={[\n        TreeSelect,\n        {\n          style: {\n            width: 200,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://ant.design/components/tree-select-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/TreeSelect.zh-CN.md",
    "content": "# TreeSelect\n\n> 树选择器\n\n## Markup Schema 同步数据源案例\n\n```tsx\nimport React from 'react'\nimport { TreeSelect, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TreeSelect,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"select\"\n        title=\"选择框\"\n        x-decorator=\"FormItem\"\n        x-component=\"TreeSelect\"\n        enum={[\n          {\n            label: '选项1',\n            value: 1,\n            children: [\n              {\n                title: 'Child Node1',\n                value: '0-0-0',\n                key: '0-0-0',\n              },\n              {\n                title: 'Child Node2',\n                value: '0-0-1',\n                key: '0-0-1',\n              },\n              {\n                title: 'Child Node3',\n                value: '0-0-2',\n                key: '0-0-2',\n              },\n            ],\n          },\n          {\n            label: '选项2',\n            value: 2,\n            children: [\n              {\n                title: 'Child Node3',\n                value: '0-1-0',\n                key: '0-1-0',\n              },\n              {\n                title: 'Child Node4',\n                value: '0-1-1',\n                key: '0-1-1',\n              },\n              {\n                title: 'Child Node5',\n                value: '0-1-2',\n                key: '0-1-2',\n              },\n            ],\n          },\n        ]}\n        x-component-props={{\n          style: {\n            width: 200,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Markup Schema 异步联动数据源案例\n\n```tsx\nimport React from 'react'\nimport {\n  TreeSelect,\n  Select,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm, onFieldReact, FormPathPattern, Field } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    TreeSelect,\n    FormItem,\n  },\n})\n\nconst useAsyncDataSource = (\n  pattern: FormPathPattern,\n  service: (field: Field) => Promise<{ label: string; value: any }[]>\n) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service(field).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async (field) => {\n      const linkage = field.query('linkage').get('value')\n      if (!linkage) return []\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          if (linkage === 1) {\n            resolve([\n              {\n                label: 'AAA',\n                value: 'aaa',\n                children: [\n                  {\n                    title: 'Child Node1',\n                    value: '0-0-0',\n                    key: '0-0-0',\n                  },\n                  {\n                    title: 'Child Node2',\n                    value: '0-0-1',\n                    key: '0-0-1',\n                  },\n                  {\n                    title: 'Child Node3',\n                    value: '0-0-2',\n                    key: '0-0-2',\n                  },\n                ],\n              },\n              {\n                label: 'BBB',\n                value: 'ccc',\n                children: [\n                  {\n                    title: 'Child Node1',\n                    value: '0-1-0',\n                    key: '0-1-0',\n                  },\n                  {\n                    title: 'Child Node2',\n                    value: '0-1-1',\n                    key: '0-1-1',\n                  },\n                  {\n                    title: 'Child Node3',\n                    value: '0-1-2',\n                    key: '0-1-2',\n                  },\n                ],\n              },\n            ])\n          } else if (linkage === 2) {\n            resolve([\n              {\n                label: 'CCC',\n                value: 'ccc',\n                children: [\n                  {\n                    title: 'Child Node1',\n                    value: '0-0-0',\n                    key: '0-0-0',\n                  },\n                  {\n                    title: 'Child Node2',\n                    value: '0-0-1',\n                    key: '0-0-1',\n                  },\n                  {\n                    title: 'Child Node3',\n                    value: '0-0-2',\n                    key: '0-0-2',\n                  },\n                ],\n              },\n              {\n                label: 'DDD',\n                value: 'ddd',\n                children: [\n                  {\n                    title: 'Child Node1',\n                    value: '0-1-0',\n                    key: '0-1-0',\n                  },\n                  {\n                    title: 'Child Node2',\n                    value: '0-1-1',\n                    key: '0-1-1',\n                  },\n                  {\n                    title: 'Child Node3',\n                    value: '0-1-2',\n                    key: '0-1-2',\n                  },\n                ],\n              },\n            ])\n          }\n        }, 1500)\n      })\n    })\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"linkage\"\n        title=\"联动选择框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        enum={[\n          { label: '发请求1', value: 1 },\n          { label: '发请求2', value: 2 },\n        ]}\n        x-component-props={{\n          style: {\n            width: 200,\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"select\"\n        title=\"异步选择框\"\n        x-decorator=\"FormItem\"\n        x-component=\"TreeSelect\"\n        x-component-props={{\n          style: {\n            width: 200,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 同步数据源案例\n\n```tsx\nimport React from 'react'\nimport { TreeSelect, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TreeSelect,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    select: {\n      type: 'string',\n      title: '选择框',\n      'x-decorator': 'FormItem',\n      'x-component': 'TreeSelect',\n      enum: [\n        {\n          label: '选项1',\n          value: 1,\n          children: [\n            {\n              title: 'Child Node1',\n              value: '0-0-0',\n              key: '0-0-0',\n            },\n            {\n              title: 'Child Node2',\n              value: '0-0-1',\n              key: '0-0-1',\n            },\n            {\n              title: 'Child Node3',\n              value: '0-0-2',\n              key: '0-0-2',\n            },\n          ],\n        },\n        {\n          label: '选项2',\n          value: 2,\n          children: [\n            {\n              title: 'Child Node1',\n              value: '0-1-0',\n              key: '0-1-0',\n            },\n            {\n              title: 'Child Node2',\n              value: '0-1-1',\n              key: '0-1-1',\n            },\n            {\n              title: 'Child Node3',\n              value: '0-1-2',\n              key: '0-1-2',\n            },\n          ],\n        },\n      ],\n      'x-component-props': {\n        style: {\n          width: 200,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 异步联动数据源案例\n\n```tsx\nimport React from 'react'\nimport {\n  TreeSelect,\n  Select,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    TreeSelect,\n    FormItem,\n  },\n})\n\nconst loadData = async (field) => {\n  const linkage = field.query('linkage').get('value')\n  if (!linkage) return []\n  return new Promise((resolve) => {\n    setTimeout(() => {\n      if (linkage === 1) {\n        resolve([\n          {\n            label: 'AAA',\n            value: 'aaa',\n            children: [\n              {\n                title: 'Child Node1',\n                value: '0-0-0',\n                key: '0-0-0',\n              },\n              {\n                title: 'Child Node2',\n                value: '0-0-1',\n                key: '0-0-1',\n              },\n              {\n                title: 'Child Node3',\n                value: '0-0-2',\n                key: '0-0-2',\n              },\n            ],\n          },\n          {\n            label: 'BBB',\n            value: 'ccc',\n            children: [\n              {\n                title: 'Child Node1',\n                value: '0-1-0',\n                key: '0-1-0',\n              },\n              {\n                title: 'Child Node2',\n                value: '0-1-1',\n                key: '0-1-1',\n              },\n              {\n                title: 'Child Node3',\n                value: '0-1-2',\n                key: '0-1-2',\n              },\n            ],\n          },\n        ])\n      } else if (linkage === 2) {\n        resolve([\n          {\n            label: 'CCC',\n            value: 'ccc',\n            children: [\n              {\n                title: 'Child Node1',\n                value: '0-0-0',\n                key: '0-0-0',\n              },\n              {\n                title: 'Child Node2',\n                value: '0-0-1',\n                key: '0-0-1',\n              },\n              {\n                title: 'Child Node3',\n                value: '0-0-2',\n                key: '0-0-2',\n              },\n            ],\n          },\n          {\n            label: 'DDD',\n            value: 'ddd',\n            children: [\n              {\n                title: 'Child Node1',\n                value: '0-1-0',\n                key: '0-1-0',\n              },\n              {\n                title: 'Child Node2',\n                value: '0-1-1',\n                key: '0-1-1',\n              },\n              {\n                title: 'Child Node3',\n                value: '0-1-2',\n                key: '0-1-2',\n              },\n            ],\n          },\n        ])\n      }\n    }, 1500)\n  })\n}\n\nconst useAsyncDataSource = (service) => (field) => {\n  field.loading = true\n  service(field).then(\n    action.bound((data) => {\n      field.dataSource = data\n      field.loading = false\n    })\n  )\n}\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    linkage: {\n      type: 'string',\n      title: '联动选择框',\n      enum: [\n        { label: '发请求1', value: 1 },\n        { label: '发请求2', value: 2 },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      'x-component-props': {\n        style: {\n          width: 200,\n        },\n      },\n    },\n    select: {\n      type: 'string',\n      title: '异步选择框',\n      'x-decorator': 'FormItem',\n      'x-component': 'TreeSelect',\n      'x-component-props': {\n        style: {\n          width: 200,\n        },\n      },\n      'x-reactions': ['{{useAsyncDataSource(loadData)}}'],\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} scope={{ useAsyncDataSource, loadData }} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 同步数据源案例\n\n```tsx\nimport React from 'react'\nimport { TreeSelect, FormItem, FormButtonGroup, Submit } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"select\"\n      title=\"选择框\"\n      dataSource={[\n        {\n          label: '选项1',\n          value: 1,\n          children: [\n            {\n              title: 'Child Node1',\n              value: '0-0-0',\n              key: '0-0-0',\n            },\n            {\n              title: 'Child Node2',\n              value: '0-0-1',\n              key: '0-0-1',\n            },\n            {\n              title: 'Child Node3',\n              value: '0-0-2',\n              key: '0-0-2',\n            },\n          ],\n        },\n        {\n          label: '选项2',\n          value: 2,\n          children: [\n            {\n              title: 'Child Node3',\n              value: '0-1-0',\n              key: '0-1-0',\n            },\n            {\n              title: 'Child Node4',\n              value: '0-1-1',\n              key: '0-1-1',\n            },\n            {\n              title: 'Child Node5',\n              value: '0-1-2',\n              key: '0-1-2',\n            },\n          ],\n        },\n      ]}\n      decorator={[FormItem]}\n      component={[TreeSelect]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 异步联动数据源案例\n\n```tsx\nimport React from 'react'\nimport {\n  TreeSelect,\n  Select,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport {\n  createForm,\n  onFieldReact,\n  FormPathPattern,\n  Field as FieldType,\n} from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst useAsyncDataSource = (\n  pattern: FormPathPattern,\n  service: (field: FieldType) => Promise<{ label: string; value: any }[]>\n) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service(field).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async (field) => {\n      const linkage = field.query('linkage').get('value')\n      if (!linkage) return []\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          if (linkage === 1) {\n            resolve([\n              {\n                label: 'AAA',\n                value: 'aaa',\n                children: [\n                  {\n                    title: 'Child Node1',\n                    value: '0-0-0',\n                    key: '0-0-0',\n                  },\n                  {\n                    title: 'Child Node2',\n                    value: '0-0-1',\n                    key: '0-0-1',\n                  },\n                  {\n                    title: 'Child Node3',\n                    value: '0-0-2',\n                    key: '0-0-2',\n                  },\n                ],\n              },\n              {\n                label: 'BBB',\n                value: 'ccc',\n                children: [\n                  {\n                    title: 'Child Node1',\n                    value: '0-1-0',\n                    key: '0-1-0',\n                  },\n                  {\n                    title: 'Child Node2',\n                    value: '0-1-1',\n                    key: '0-1-1',\n                  },\n                  {\n                    title: 'Child Node3',\n                    value: '0-1-2',\n                    key: '0-1-2',\n                  },\n                ],\n              },\n            ])\n          } else if (linkage === 2) {\n            resolve([\n              {\n                label: 'CCC',\n                value: 'ccc',\n                children: [\n                  {\n                    title: 'Child Node1',\n                    value: '0-0-0',\n                    key: '0-0-0',\n                  },\n                  {\n                    title: 'Child Node2',\n                    value: '0-0-1',\n                    key: '0-0-1',\n                  },\n                  {\n                    title: 'Child Node3',\n                    value: '0-0-2',\n                    key: '0-0-2',\n                  },\n                ],\n              },\n              {\n                label: 'DDD',\n                value: 'ddd',\n                children: [\n                  {\n                    title: 'Child Node1',\n                    value: '0-1-0',\n                    key: '0-1-0',\n                  },\n                  {\n                    title: 'Child Node2',\n                    value: '0-1-1',\n                    key: '0-1-1',\n                  },\n                  {\n                    title: 'Child Node3',\n                    value: '0-1-2',\n                    key: '0-1-2',\n                  },\n                ],\n              },\n            ])\n          }\n        }, 1500)\n      })\n    })\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"linkage\"\n      title=\"联动选择框\"\n      dataSource={[\n        { label: '发请求1', value: 1 },\n        { label: '发请求2', value: 2 },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        Select,\n        {\n          style: {\n            width: 200,\n          },\n        },\n      ]}\n    />\n    <Field\n      name=\"select\"\n      title=\"异步选择框\"\n      decorator={[FormItem]}\n      component={[\n        TreeSelect,\n        {\n          style: {\n            width: 200,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://ant.design/components/tree-select-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Upload.md",
    "content": "# Upload\n\n> Upload components\n>\n> Note: Using the upload component, it is recommended that users perform secondary packaging. Users do not need to care about the data communication between the upload component and Formily, only the style and basic upload configuration are required.\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  Upload,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\nimport { UploadOutlined, InboxOutlined } from '@ant-design/icons'\n\nconst NormalUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button icon={<UploadOutlined />}>Upload files</Button>\n    </Upload>\n  )\n}\n\nconst CardUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      listType=\"picture-card\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <UploadOutlined style={{ fontSize: 20 }} />\n    </Upload>\n  )\n}\n\nconst DraggerUpload = (props) => {\n  return (\n    <Upload.Dragger\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n    >\n      <p className=\"ant-upload-drag-icon\">\n        <InboxOutlined />\n      </p>\n      <p className=\"ant-upload-text\">\n        Click or drag file to this area to upload\n      </p>\n      <p className=\"ant-upload-hint\">\n        Support for a single or bulk upload. Strictly prohibit from uploading\n        company data or other band files\n      </p>\n    </Upload.Dragger>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    NormalUpload,\n    CardUpload,\n    DraggerUpload,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"upload\"\n          title=\"Upload\"\n          x-decorator=\"FormItem\"\n          x-component=\"NormalUpload\"\n          required\n        />\n        <SchemaField.Array\n          name=\"upload2\"\n          title=\"Card upload\"\n          x-decorator=\"FormItem\"\n          x-component=\"CardUpload\"\n          required\n        />\n        <SchemaField.Array\n          name=\"upload3\"\n          title=\"Drag and drop upload\"\n          x-decorator=\"FormItem\"\n          x-component=\"DraggerUpload\"\n          required\n        />\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  Upload,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\nimport { UploadOutlined, InboxOutlined } from '@ant-design/icons'\n\nconst NormalUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button icon={<UploadOutlined />}>Upload files</Button>\n    </Upload>\n  )\n}\n\nconst CardUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      listType=\"picture-card\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <UploadOutlined style={{ fontSize: 20 }} />\n    </Upload>\n  )\n}\n\nconst DraggerUpload = (props) => {\n  return (\n    <Upload.Dragger\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n    >\n      <p className=\"ant-upload-drag-icon\">\n        <InboxOutlined />\n      </p>\n      <p className=\"ant-upload-text\">\n        Click or drag file to this area to upload\n      </p>\n      <p className=\"ant-upload-hint\">\n        Support for a single or bulk upload. Strictly prohibit from uploading\n        company data or other band files\n      </p>\n    </Upload.Dragger>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    NormalUpload,\n    CardUpload,\n    DraggerUpload,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    upload: {\n      type: 'array',\n      title: 'Upload',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'NormalUpload',\n    },\n    upload2: {\n      type: 'array',\n      title: 'Card upload',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'CardUpload',\n    },\n    upload3: {\n      type: 'array',\n      title: 'Drag and drop upload',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'DraggerUpload',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport {\n  Upload,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { Button } from 'antd'\nimport { UploadOutlined, InboxOutlined } from '@ant-design/icons'\n\nconst NormalUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button icon={<UploadOutlined />}>Upload files</Button>\n    </Upload>\n  )\n}\n\nconst CardUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      listType=\"picture-card\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <UploadOutlined style={{ fontSize: 20 }} />\n    </Upload>\n  )\n}\n\nconst DraggerUpload = (props) => {\n  return (\n    <Upload.Dragger\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n    >\n      <p className=\"ant-upload-drag-icon\">\n        <InboxOutlined />\n      </p>\n      <p className=\"ant-upload-text\">\n        Click or drag file to this area to upload\n      </p>\n      <p className=\"ant-upload-hint\">\n        Support for a single or bulk upload. Strictly prohibit from uploading\n        company data or other band files\n      </p>\n    </Upload.Dragger>\n  )\n}\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <Field\n        name=\"upload\"\n        title=\"Upload\"\n        required\n        decorator={[FormItem]}\n        component={[NormalUpload]}\n      />\n      <Field\n        name=\"upload2\"\n        title=\"Card upload\"\n        required\n        decorator={[FormItem]}\n        component={[CardUpload]}\n      />\n      <Field\n        name=\"upload3\"\n        title=\"Drag and drop upload\"\n        required\n        decorator={[FormItem]}\n        component={[DraggerUpload]}\n      />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://ant.design/components/upload-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/Upload.zh-CN.md",
    "content": "# Upload\n\n> 上传组件\n>\n> 注意：使用上传组件，推荐用户进行二次封装，用户无需关心上传组件与 Formily 的数据通信，只需要处理样式与基本上传配置即可。\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Upload,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\nimport { UploadOutlined, InboxOutlined } from '@ant-design/icons'\n\nconst NormalUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button icon={<UploadOutlined />}>上传文件</Button>\n    </Upload>\n  )\n}\n\nconst CardUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      listType=\"picture-card\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <UploadOutlined style={{ fontSize: 20 }} />\n    </Upload>\n  )\n}\n\nconst DraggerUpload = (props) => {\n  return (\n    <Upload.Dragger\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n    >\n      <p className=\"ant-upload-drag-icon\">\n        <InboxOutlined />\n      </p>\n      <p className=\"ant-upload-text\">\n        Click or drag file to this area to upload\n      </p>\n      <p className=\"ant-upload-hint\">\n        Support for a single or bulk upload. Strictly prohibit from uploading\n        company data or other band files\n      </p>\n    </Upload.Dragger>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    NormalUpload,\n    CardUpload,\n    DraggerUpload,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"upload\"\n          title=\"上传\"\n          x-decorator=\"FormItem\"\n          x-component=\"NormalUpload\"\n          required\n        />\n        <SchemaField.Array\n          name=\"upload2\"\n          title=\"卡片上传\"\n          x-decorator=\"FormItem\"\n          x-component=\"CardUpload\"\n          required\n        />\n        <SchemaField.Array\n          name=\"upload3\"\n          title=\"拖拽上传\"\n          x-decorator=\"FormItem\"\n          x-component=\"DraggerUpload\"\n          required\n        />\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Upload,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from 'antd'\nimport { UploadOutlined, InboxOutlined } from '@ant-design/icons'\n\nconst NormalUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button icon={<UploadOutlined />}>上传文件</Button>\n    </Upload>\n  )\n}\n\nconst CardUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      listType=\"picture-card\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <UploadOutlined style={{ fontSize: 20 }} />\n    </Upload>\n  )\n}\n\nconst DraggerUpload = (props) => {\n  return (\n    <Upload.Dragger\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n    >\n      <p className=\"ant-upload-drag-icon\">\n        <InboxOutlined />\n      </p>\n      <p className=\"ant-upload-text\">\n        Click or drag file to this area to upload\n      </p>\n      <p className=\"ant-upload-hint\">\n        Support for a single or bulk upload. Strictly prohibit from uploading\n        company data or other band files\n      </p>\n    </Upload.Dragger>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    NormalUpload,\n    CardUpload,\n    DraggerUpload,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    upload: {\n      type: 'array',\n      title: '上传',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'NormalUpload',\n    },\n    upload2: {\n      type: 'array',\n      title: '卡片上传',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'CardUpload',\n    },\n    upload3: {\n      type: 'array',\n      title: '拖拽上传',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'DraggerUpload',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Upload,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n} from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { Button } from 'antd'\nimport { UploadOutlined, InboxOutlined } from '@ant-design/icons'\n\nconst NormalUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button icon={<UploadOutlined />}>上传文件</Button>\n    </Upload>\n  )\n}\n\nconst CardUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      listType=\"picture-card\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <UploadOutlined style={{ fontSize: 20 }} />\n    </Upload>\n  )\n}\n\nconst DraggerUpload = (props) => {\n  return (\n    <Upload.Dragger\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n    >\n      <p className=\"ant-upload-drag-icon\">\n        <InboxOutlined />\n      </p>\n      <p className=\"ant-upload-text\">\n        Click or drag file to this area to upload\n      </p>\n      <p className=\"ant-upload-hint\">\n        Support for a single or bulk upload. Strictly prohibit from uploading\n        company data or other band files\n      </p>\n    </Upload.Dragger>\n  )\n}\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <Field\n        name=\"upload\"\n        title=\"上传\"\n        required\n        decorator={[FormItem]}\n        component={[NormalUpload]}\n      />\n      <Field\n        name=\"upload2\"\n        title=\"卡片上传\"\n        required\n        decorator={[FormItem]}\n        component={[CardUpload]}\n      />\n      <Field\n        name=\"upload3\"\n        title=\"拖拽上传\"\n        required\n        decorator={[FormItem]}\n        component={[DraggerUpload]}\n      />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://ant.design/components/upload-cn/\n"
  },
  {
    "path": "packages/antd/docs/components/index.md",
    "content": "# Ant Design\n\n## Introduction\n\n@formily/antd is a professional component library for form scenarios based on Ant Design encapsulation. It has the following characteristics:\n\n- Only Formily 2.x is supported\n  - Most components are not backward compatible\n  - Unfortunately, many components of 1.x have inherent flaws in the API design. This is also because the form scheme has been explored, so there will be version breaks.\n- Richer component system\n  - Layout components\n    - FormLayout\n    - FormItem\n    - FormGrid\n    - FormButtonGroup\n    - Space\n    - Submit\n    - Reset\n  - Input controls\n    - Input\n    - Password\n    - Select\n    - TreeSelect\n    - DatePicker\n    - TimePicker\n    - NumberPicker\n    - Transfer\n    - Cascader\n    - Radio\n    - Checkbox\n    - Upload\n    - Switch\n  - Scene components\n    - ArrayCards\n    - ArrayItems\n    - ArrayTable\n    - ArrayTabs\n    - FormCollapse\n    - FormStep\n    - FormTab\n    - FormDialog\n    - FormDrawer\n    - Editable\n  - Reading state component\n    - PreviewText\n- Theme customization ability\n  - Completely abandon the 1.x styled-components solution, follow the style system of the component library, it is more convenient to customize the theme\n- Support secondary packaging\n  - All components can be repackaged, and the 1.x component system cannot be repackaged, so providing this capability makes it more convenient for users to do business customization\n- Support reading mode\n  - Although 1.x also supports reading mode, 2.x provides a separate PreviewText component, users can make reading mode encapsulation based on it, which is more flexible\n- Type is more friendly\n  - Each component has an extremely complete type definition, and users can feel an unprecedented intelligent reminder experience during the actual development process\n- More complete layout control capabilities\n  - 1.x's layout capabilities have basically converged to FormMegaLayout. This time, we directly removed Mega. Mega is a standard component and is completely internalized into FormLayout and FormItem components. At the same time, MegaLayout's grid layout capabilities are placed in FormGrid components. In, it also provides smarter layout capabilities.\n- More elegant and easy-to-use APIs, such as:\n  - FormStep in the past has many problems. First, the type is not friendly. Second, the API is too hidden. To control the forward and backwards, you need to understand a bunch of private events. In the new version of FormStep, users only need to pay attention to the FormStep Reactive Model. You can create a Reactive Model through createFormStep and pass it to the FormStep component to quickly communicate. Similarly, FormTab/FormCollapse is the same communication mode.\n  - Pop-up forms, drawer forms, presumably in the past, users had to write a lot of code on these two scenarios almost every time. This time, an extremely simple API is directly provided for users to use, which maximizes development efficiency.\n\n## Installation\n\n```bash\n$ npm install --save antd moment\n$ npm install --save @formily/core @formily/react @formily/antd\n\n```\n\n## Q/A\n\nQ: I want to package a set of component libraries by myself, what should I do?\n\nAnswer: If it is an open source component library, you can directly participate in the project co-construction and provide PR. If it is a private component library in the enterprise, you can refer to the source code. The source code does not have too much complicated logic.\n\nQuestion: Why do components such as ArrayCards/ArrayTable/FormStep only support Schema mode and not pure JSX mode?\n\nAnswer: This is the core advantage of Schema mode. With the help of protocols, we can do scene-based abstraction. On the contrary, pure JSX mode is limited by the unparseability of JSX. It is difficult for us to achieve UI-level scene-based abstraction. It's just an abstract hook.\n"
  },
  {
    "path": "packages/antd/docs/components/index.zh-CN.md",
    "content": "# Ant Design\n\n## 介绍\n\n@formily/antd 是基于 Ant Design 封装的针对表单场景专业级(Professional)组件库，它主要有以下几个特点：\n\n- 仅支持 Formily2.x\n  - 大部分组件无法向后兼容\n  - 很遗憾，1.x 的很多组件在 API 设计上存在本质上的缺陷，这也是因为表单方案一直在探索之中，所以才会出现版本断裂。\n- 更丰富的组件体系\n  - 布局组件\n    - FormLayout\n    - FormItem\n    - FormGrid\n    - FormButtonGroup\n    - Space\n    - Submit\n    - Reset\n  - 输入控件\n    - Input\n    - Password\n    - Select\n    - TreeSelect\n    - DatePicker\n    - TimePicker\n    - NumberPicker\n    - Transfer\n    - Cascader\n    - Radio\n    - Checkbox\n    - Upload\n    - Switch\n  - 场景组件\n    - ArrayCards\n    - ArrayItems\n    - ArrayTable\n    - ArrayTabs\n    - FormCollapse\n    - FormStep\n    - FormTab\n    - FormDialog\n    - FormDrawer\n    - Editable\n  - 阅读态组件\n    - PreviewText\n- 主题定制能力\n  - 完全放弃了 1.x styled-components 方案，follow 组件库的样式体系，更方便定制主题\n- 支持二次封装\n  - 所有组件都能二次封装，1.x 的组件体系是不能二次封装的，所以提供了这个能力则更方便用户做业务定制\n- 支持阅读态\n  - 虽然 1.x 同样支持阅读态，但是 2.x 单独提供了 PreviewText 组件，用户可以基于它自己做阅读态封装，灵活性更强\n- 类型更加友好\n  - 每个组件都有着极其完整的类型定义，用户在实际开发过程中，可以感受到前所未有的智能提示体验\n- 更完备的布局控制能力\n  - 1.x 的布局能力基本上都收敛到了 FormMegaLayout 上，这次，我们直接去掉 Mega，Mega 就是标准组件，完全内化到 FormLayout 和 FormItem 组件中，同时将 MegaLayout 的网格布局能力放到了 FormGrid 组件中，也提供了更智能的布局能力。\n- 更优雅易用的 API，比如：\n  - 过去的 FormStep，有很多问题，第一，类型不友好，第二，API 隐藏太深，想要控制前进后退需要理解一堆的私有事件。新版 FormStep，用户只需要关注 FormStep Reactive Model 即可，通过 createFormStep 就可以创建出 Reactive Model，传给 FormStep 组件即可快速通讯。同理，FormTab/FormCollapse 也是一样的通讯模式。\n  - 弹窗表单，抽屉表单，想必过去，用户几乎每次都得在这两个场景上写大量的代码，这次直接提供了极其简易的 API 让用户使用，最大化提升开发效率。\n\n## 安装\n\n```bash\n$ npm install --save antd moment\n$ npm install --save @formily/core @formily/react @formily/antd\n\n```\n\n## Q/A\n\n问：我想自己封装一套组件库，该怎么做？\n\n答：如果是开源组件库，可以直接参与项目共建，提供 PR，如果是企业内私有组件库，参考源码即可，源码并没有太多复杂逻辑。\n\n问：为什么 ArrayCards/ArrayTable/FormStep 这类组件只支持 Schema 模式，不支持纯 JSX 模式？\n\n答：这就是 Schema 模式的核心优势，借助协议，我们可以做场景化抽象，相反，纯 JSX 模式，受限于 JSX 的不可解析性，我们很难做到 UI 级别的场景化抽象，更多的只是抽象 Hook。\n"
  },
  {
    "path": "packages/antd/docs/index.md",
    "content": "---\ntitle: Formily-Alibaba unified front-end form solution\norder: 10\nhero:\n  title: Formily Antd\n  desc: Formily Component System Based on Ant Design Encapsulation\n  actions:\n    - text: Home Site\n      link: //formilyjs.org\n    - text: Document\n      link: /components\nfeatures:\n  - icon: https://img.alicdn.com/imgextra/i2/O1CN016i72sH1c5wh1kyy9U_!!6000000003550-55-tps-800-800.svg\n    title: Easier To Use\n    desc: Out of the box, rich cases\n  - icon: https://img.alicdn.com/imgextra/i1/O1CN01bHdrZJ1rEOESvXEi5_!!6000000005599-55-tps-800-800.svg\n    title: More Efficient\n    desc: Stupid writing, super high performance\n  - icon: https://img.alicdn.com/imgextra/i3/O1CN01xlETZk1G0WSQT6Xii_!!6000000000560-55-tps-800-800.svg\n    title: More Professional\n    desc: complete, flexible, elegant\nfooter: Open-source MIT Licensed | Copyright © 2019-present<br />Powered by self\n---\n\n## Installation\n\n```bash\n$ npm install --save antd moment\n$ npm install --save @formily/core @formily/react @formily/antd\n\n```\n\n## Quick start\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React from 'react'\nimport { NumberPicker, FormItem, Space } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Space>\n      <Field\n        name=\"price\"\n        title=\"price\"\n        initialValue={5.2}\n        decorator={[FormItem]}\n        component={[\n          NumberPicker,\n          {\n            placeholder: 'Please enter',\n            style: {\n              width: 100,\n            },\n          },\n        ]}\n      />\n      <FormItem>×</FormItem>\n      <Field\n        name=\"count\"\n        title=\"quantity\"\n        initialValue={100}\n        decorator={[FormItem]}\n        component={[\n          NumberPicker,\n          {\n            placeholder: 'Please enter',\n            style: {\n              width: 100,\n            },\n          },\n        ]}\n      />\n      <FormConsumer>\n        {(form) => (\n          <FormItem>={` ${form.values.price * form.values.count}元`}</FormItem>\n        )}\n      </FormConsumer>\n    </Space>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/antd/docs/index.zh-CN.md",
    "content": "---\ntitle: Formily - 阿里巴巴统一前端表单解决方案\norder: 10\nhero:\n  title: Formily Antd\n  desc: 基于Ant Design封装的优雅且易用的Formily2.x组件体系\n  actions:\n    - text: 主站文档\n      link: //formilyjs.org\n    - text: 组件文档\n      link: /zh-CN/components\nfeatures:\n  - icon: https://img.alicdn.com/imgextra/i2/O1CN016i72sH1c5wh1kyy9U_!!6000000003550-55-tps-800-800.svg\n    title: 更易用\n    desc: 开箱即用，案例丰富\n  - icon: https://img.alicdn.com/imgextra/i1/O1CN01bHdrZJ1rEOESvXEi5_!!6000000005599-55-tps-800-800.svg\n    title: 更高效\n    desc: 傻瓜写法，超高性能\n  - icon: https://img.alicdn.com/imgextra/i3/O1CN01xlETZk1G0WSQT6Xii_!!6000000000560-55-tps-800-800.svg\n    title: 更专业\n    desc: 完备，灵活，优雅\nfooter: Open-source MIT Licensed | Copyright © 2019-present<br />Powered by self\n---\n\n## 安装\n\n```bash\n$ npm install --save antd moment\n$ npm install --save @formily/core @formily/react @formily/antd\n\n```\n\n## 快速开始\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React from 'react'\nimport { NumberPicker, FormItem, Space } from '@formily/antd'\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Space>\n      <Field\n        name=\"price\"\n        title=\"价格\"\n        initialValue={5.2}\n        decorator={[FormItem]}\n        component={[\n          NumberPicker,\n          {\n            placeholder: '请输入',\n            style: {\n              width: 100,\n            },\n          },\n        ]}\n      />\n      <FormItem>×</FormItem>\n      <Field\n        name=\"count\"\n        title=\"数量\"\n        initialValue={100}\n        decorator={[FormItem]}\n        component={[\n          NumberPicker,\n          {\n            placeholder: '请输入',\n            style: {\n              width: 100,\n            },\n          },\n        ]}\n      />\n      <FormConsumer>\n        {(form) => (\n          <FormItem>={` ${form.values.price * form.values.count} 元`}</FormItem>\n        )}\n      </FormConsumer>\n    </Space>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/antd/package.json",
    "content": "{\n  \"name\": \"@formily/antd\",\n  \"version\": \"2.3.7\",\n  \"license\": \"MIT\",\n  \"main\": \"lib\",\n  \"module\": \"esm\",\n  \"umd:main\": \"dist/formily.antd.umd.production.js\",\n  \"unpkg\": \"dist/formily.antd.umd.production.js\",\n  \"jsdelivr\": \"dist/formily.antd.umd.production.js\",\n  \"jsnext:main\": \"esm\",\n  \"sideEffects\": [\n    \"dist/*\",\n    \"esm/*.js\",\n    \"lib/*.js\",\n    \"src/*.ts\",\n    \"*.less\",\n    \"**/*/style.js\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/alibaba/formily.git\"\n  },\n  \"types\": \"esm/index.d.ts\",\n  \"bugs\": {\n    \"url\": \"https://github.com/alibaba/formily/issues\"\n  },\n  \"homepage\": \"https://github.com/alibaba/formily#readme\",\n  \"engines\": {\n    \"npm\": \">=3.0.0\"\n  },\n  \"scripts\": {\n    \"start\": \"dumi dev\",\n    \"build\": \"rimraf -rf lib esm dist && npm run create:style && npm run build:cjs && npm run build:esm && npm run build:umd && npm run build:style\",\n    \"create:style\": \"ts-node create-style\",\n    \"build:style\": \"ts-node build-style\",\n    \"build:cjs\": \"tsc --project tsconfig.build.json\",\n    \"build:esm\": \"tsc --project tsconfig.build.json --module es2015 --outDir esm\",\n    \"build:umd\": \"rollup --config\",\n    \"build:docs\": \"dumi build\"\n  },\n  \"devDependencies\": {\n    \"@umijs/plugin-sass\": \"^1.1.1\",\n    \"dumi\": \"^1.1.0-rc.8\"\n  },\n  \"peerDependencies\": {\n    \"@ant-design/icons\": \"4.x\",\n    \"@types/react\": \">=16.8.0\",\n    \"@types/react-dom\": \">=16.8.0\",\n    \"antd\": \"<=4.22.8\",\n    \"react\": \">=16.8.0\",\n    \"react-dom\": \">=16.8.0\",\n    \"react-is\": \">=16.8.0\"\n  },\n  \"peerDependenciesMeta\": {\n    \"@types/react\": {\n      \"optional\": true\n    },\n    \"@types/react-dom\": {\n      \"optional\": true\n    }\n  },\n  \"dependencies\": {\n    \"@dnd-kit/core\": \"^6.0.0\",\n    \"@dnd-kit/sortable\": \"^7.0.0\",\n    \"@formily/core\": \"2.3.7\",\n    \"@formily/grid\": \"2.3.7\",\n    \"@formily/json-schema\": \"2.3.7\",\n    \"@formily/react\": \"2.3.7\",\n    \"@formily/reactive\": \"2.3.7\",\n    \"@formily/reactive-react\": \"2.3.7\",\n    \"@formily/shared\": \"2.3.7\",\n    \"classnames\": \"^2.2.6\",\n    \"react-sticky-box\": \"^0.9.3\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"gitHead\": \"ac79c196ae9324889aca5e0501146f9b37b04283\"\n}\n"
  },
  {
    "path": "packages/antd/rollup.config.js",
    "content": "import baseConfig, {\n  removeImportStyleFromInputFilePlugin,\n} from '../../scripts/rollup.base.js'\n\nexport default baseConfig(\n  'formily.antd',\n  'Formily.Antd',\n  removeImportStyleFromInputFilePlugin()\n)\n"
  },
  {
    "path": "packages/antd/src/__builtins__/hooks/index.ts",
    "content": "export * from './useClickAway'\nexport * from './usePrefixCls'\n"
  },
  {
    "path": "packages/antd/src/__builtins__/hooks/useClickAway.ts",
    "content": "import { useRef, useEffect, MutableRefObject } from 'react'\n\nconst defaultEvent = 'click'\n\ntype EventType = MouseEvent | TouchEvent\n\ntype BasicTarget<T = HTMLElement> =\n  | (() => T | null)\n  | T\n  | null\n  | MutableRefObject<T | null | undefined>\n\ntype TargetElement = HTMLElement | Element | Document | Window\n\nfunction getTargetElement(\n  target?: BasicTarget<TargetElement>,\n  defaultElement?: TargetElement\n): TargetElement | undefined | null {\n  if (!target) {\n    return defaultElement\n  }\n\n  let targetElement: TargetElement | undefined | null\n\n  if (typeof target === 'function') {\n    targetElement = target()\n  } else if ('current' in target) {\n    targetElement = target.current\n  } else {\n    targetElement = target\n  }\n\n  return targetElement\n}\n\nexport const useClickAway = (\n  onClickAway: (event: EventType) => void,\n  target: BasicTarget | BasicTarget[],\n  eventName: string = defaultEvent\n) => {\n  const onClickAwayRef = useRef(onClickAway)\n  onClickAwayRef.current = onClickAway\n\n  useEffect(() => {\n    const handler = (event: any) => {\n      const targets = Array.isArray(target) ? target : [target]\n      if (\n        targets.some((targetItem) => {\n          const targetElement = getTargetElement(targetItem) as HTMLElement\n          return !targetElement || targetElement?.contains(event.target)\n        })\n      ) {\n        return\n      }\n      onClickAwayRef.current(event)\n    }\n\n    document.addEventListener(eventName, handler)\n\n    return () => {\n      document.removeEventListener(eventName, handler)\n    }\n  }, [target, eventName])\n}\n"
  },
  {
    "path": "packages/antd/src/__builtins__/hooks/usePrefixCls.ts",
    "content": "import { useContext } from 'react'\nimport { ConfigProvider } from 'antd'\n\nexport const usePrefixCls = (\n  tag?: string,\n  props?: {\n    prefixCls?: string\n  }\n) => {\n  if ('ConfigContext' in ConfigProvider) {\n    const { getPrefixCls } = useContext(ConfigProvider.ConfigContext)\n    return getPrefixCls(tag, props?.prefixCls)\n  } else {\n    const prefix = props?.prefixCls ?? 'ant-'\n    return `${prefix}${tag ?? ''}`\n  }\n}\n"
  },
  {
    "path": "packages/antd/src/__builtins__/index.ts",
    "content": "export * from './moment'\nexport * from './hooks'\nexport * from './portal'\nexport * from './loading'\nexport * from './pickDataProps'\nexport * from './sort'\n"
  },
  {
    "path": "packages/antd/src/__builtins__/loading.ts",
    "content": "import { message } from 'antd'\n\nexport const loading = async (\n  title: React.ReactNode = 'Loading...',\n  processor: () => Promise<any>\n) => {\n  let hide = null\n  let loading = setTimeout(() => {\n    hide = message.loading(title)\n  }, 100)\n  try {\n    return await processor()\n  } finally {\n    hide?.()\n    clearTimeout(loading)\n  }\n}\n"
  },
  {
    "path": "packages/antd/src/__builtins__/moment.ts",
    "content": "import { isArr, isFn, isEmpty } from '@formily/shared'\nimport moment from 'moment'\n\nexport const momentable = (value: any, format?: string) => {\n  return Array.isArray(value)\n    ? value.map((val) => moment(val, format))\n    : value\n    ? moment(value, format)\n    : value\n}\n\nexport const formatMomentValue = (\n  value: any,\n  format: any,\n  placeholder?: string\n): string | string[] => {\n  const formatDate = (date: any, format: any, i = 0) => {\n    if (!date) return placeholder\n    const TIME_REG = /^(?:[01]\\d|2[0-3]):[0-5]\\d(:[0-5]\\d)?$/\n    let _format = format\n    if (isArr(format)) {\n      _format = format[i]\n    }\n    if (isFn(_format)) {\n      return _format(date)\n    }\n    if (isEmpty(_format)) {\n      return date\n    }\n    // moment '19:55:22' 下需要传入第二个参数\n    if (TIME_REG.test(date)) {\n      return moment(date, _format).format(_format)\n    }\n    return moment(date).format(_format)\n  }\n  if (isArr(value)) {\n    return value.map((val, index) => {\n      return formatDate(val, format, index)\n    })\n  } else {\n    return value ? formatDate(value, format) : value || placeholder\n  }\n}\n"
  },
  {
    "path": "packages/antd/src/__builtins__/pickDataProps.ts",
    "content": "export const pickDataProps = (props: any = {}) => {\n  const results = {}\n\n  for (let key in props) {\n    if (key.indexOf('data-') > -1) {\n      results[key] = props[key]\n    }\n  }\n\n  return results\n}\n"
  },
  {
    "path": "packages/antd/src/__builtins__/portal.tsx",
    "content": "import React, { Fragment } from 'react'\nimport { createPortal } from 'react-dom'\nimport { observable } from '@formily/reactive'\nimport { Observer } from '@formily/react'\nimport { render as reactRender, unmount as reactUnmount } from './render'\nexport interface IPortalProps {\n  id?: string | symbol\n}\n\nconst PortalMap = observable(new Map<string | symbol, React.ReactNode>())\n\nexport const createPortalProvider = (id: string | symbol) => {\n  const Portal = (props: React.PropsWithChildren<IPortalProps>) => {\n    const portalId = props.id ?? id\n    if (portalId && !PortalMap.has(portalId)) {\n      PortalMap.set(portalId, null)\n    }\n\n    return (\n      <Fragment>\n        {props.children}\n        <Observer>\n          {() => {\n            if (!portalId) return null\n            const portal = PortalMap.get(portalId)\n            if (portal) return createPortal(portal, document.body)\n            return null\n          }}\n        </Observer>\n      </Fragment>\n    )\n  }\n  return Portal\n}\n\nexport function createPortalRoot<T extends React.ReactNode>(\n  host: HTMLElement,\n  id: string\n) {\n  function render(renderer?: () => T) {\n    if (PortalMap.has(id)) {\n      PortalMap.set(id, renderer?.())\n    } else if (host) {\n      reactRender(<Fragment>{renderer?.()}</Fragment>, host)\n    }\n  }\n\n  function unmount() {\n    if (PortalMap.has(id)) {\n      PortalMap.set(id, null)\n    }\n    if (host) {\n      const unmountResult = reactUnmount(host)\n      if (unmountResult && host.parentNode) {\n        host.parentNode?.removeChild(host)\n      }\n    }\n  }\n\n  return {\n    render,\n    unmount,\n  }\n}\n"
  },
  {
    "path": "packages/antd/src/__builtins__/render.ts",
    "content": "import { ReactElement } from 'react'\nimport * as ReactDOM from 'react-dom'\nimport type { Root } from 'react-dom/client'\n\n// 移植自rc-util: https://github.com/react-component/util/blob/master/src/React/render.ts\n\ntype CreateRoot = (container: ContainerType) => Root\n\n// Let compiler not to search module usage\nconst fullClone = {\n  ...ReactDOM,\n} as typeof ReactDOM & {\n  __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED?: {\n    usingClientEntryPoint?: boolean\n  }\n  createRoot?: CreateRoot\n}\n\nconst { version, render: reactRender, unmountComponentAtNode } = fullClone\n\nlet createRoot: CreateRoot\ntry {\n  const mainVersion = Number((version || '').split('.')[0])\n  if (mainVersion >= 18 && fullClone.createRoot) {\n    // eslint-disable-next-line @typescript-eslint/no-var-requires\n    createRoot = fullClone.createRoot\n  }\n} catch (e) {\n  // Do nothing;\n}\n\nfunction toggleWarning(skip: boolean) {\n  const { __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED } = fullClone\n\n  if (\n    __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED &&\n    typeof __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED === 'object'\n  ) {\n    __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.usingClientEntryPoint =\n      skip\n  }\n}\n\nconst MARK = '__antd_mobile_root__'\n\n// ========================== Render ==========================\ntype ContainerType = (Element | DocumentFragment) & {\n  [MARK]?: Root\n}\n\nfunction legacyRender(node: ReactElement, container: ContainerType) {\n  reactRender(node, container)\n}\n\nfunction concurrentRender(node: ReactElement, container: ContainerType) {\n  toggleWarning(true)\n  const root = container[MARK] || createRoot(container)\n  toggleWarning(false)\n  root.render(node)\n  container[MARK] = root\n}\n\nexport function render(node: ReactElement, container: ContainerType) {\n  if (createRoot as unknown) {\n    concurrentRender(node, container)\n    return\n  }\n  legacyRender(node, container)\n}\n\n// ========================== Unmount =========================\nfunction legacyUnmount(container: ContainerType) {\n  return unmountComponentAtNode(container)\n}\n\nasync function concurrentUnmount(container: ContainerType) {\n  // Delay to unmount to avoid React 18 sync warning\n  return Promise.resolve().then(() => {\n    container[MARK]?.unmount()\n    delete container[MARK]\n  })\n}\n\nexport function unmount(container: ContainerType) {\n  if (createRoot as unknown) {\n    return concurrentUnmount(container)\n  }\n\n  return legacyUnmount(container)\n}"
  },
  {
    "path": "packages/antd/src/__builtins__/sort.tsx",
    "content": "import { DndContext, DragEndEvent, DragStartEvent } from '@dnd-kit/core'\nimport {\n  SortableContext,\n  useSortable,\n  verticalListSortingStrategy,\n} from '@dnd-kit/sortable'\nimport { ReactFC } from '@formily/reactive-react'\nimport React, { createContext, useContext, useMemo } from 'react'\n\nexport interface ISortableContainerProps {\n  list: any[]\n  start?: number\n  accessibility?: {\n    container?: Element\n  }\n  onSortStart?: (event: DragStartEvent) => void\n  onSortEnd?: (event: { oldIndex: number; newIndex: number }) => void\n}\n\nexport function SortableContainer<T extends React.HTMLAttributes<HTMLElement>>(\n  Component: ReactFC<T>\n): ReactFC<ISortableContainerProps & T> {\n  return ({\n    list,\n    start = 0,\n    accessibility,\n    onSortStart,\n    onSortEnd,\n    ...props\n  }) => {\n    const _onSortEnd = (event: DragEndEvent) => {\n      const { active, over } = event\n      const oldIndex = (active.id as number) - 1\n      const newIndex = (over?.id as number) - 1\n      onSortEnd?.({\n        oldIndex,\n        newIndex,\n      })\n    }\n\n    return (\n      <DndContext\n        accessibility={accessibility}\n        onDragStart={onSortStart}\n        onDragEnd={_onSortEnd}\n      >\n        <SortableContext\n          items={list.map((_, index) => index + start + 1)}\n          strategy={verticalListSortingStrategy}\n        >\n          <Component {...(props as unknown as T)}>{props.children}</Component>\n        </SortableContext>\n      </DndContext>\n    )\n  }\n}\n\nexport const useSortableItem = () => {\n  return useContext(SortableItemContext)\n}\n\nexport const SortableItemContext = createContext<\n  Partial<ReturnType<typeof useSortable>>\n>({})\n\nexport interface ISortableElementProps {\n  index?: number\n  lockAxis?: 'x' | 'y'\n}\n\nexport function SortableElement<T extends React.HTMLAttributes<HTMLElement>>(\n  Component: ReactFC<T>\n): ReactFC<T & ISortableElementProps> {\n  return ({ index = 0, lockAxis, ...props }) => {\n    const sortable = useSortable({\n      id: index + 1,\n    })\n    const { setNodeRef, transform, transition, isDragging } = sortable\n    if (transform) {\n      switch (lockAxis) {\n        case 'x':\n          transform.y = 0\n          break\n        case 'y':\n          transform.x = 0\n          break\n        default:\n          break\n      }\n    }\n\n    const style = useMemo(() => {\n      const itemStyle: React.CSSProperties = {\n        position: 'relative',\n        touchAction: 'none',\n        zIndex: 1,\n        transform: `translate3d(${transform?.x || 0}px, ${\n          transform?.y || 0\n        }px, 0)`,\n        transition: `${transform ? 'all 200ms ease' : ''}`,\n      }\n      const dragStyle: React.CSSProperties = {\n        transition,\n        opacity: '0.8',\n        transform: `translate3d(${transform?.x || 0}px, ${\n          transform?.y || 0\n        }px, 0)`,\n      }\n\n      const computedStyle = isDragging\n        ? {\n            ...itemStyle,\n            ...dragStyle,\n            ...props.style,\n          }\n        : {\n            ...itemStyle,\n            ...props.style,\n          }\n\n      return computedStyle\n    }, [isDragging, transform, transition, props.style])\n\n    return (\n      <SortableItemContext.Provider value={sortable}>\n        {Component({\n          ...props,\n          style,\n          ref: setNodeRef,\n        } as unknown as T)}\n      </SortableItemContext.Provider>\n    )\n  }\n}\n\nexport function SortableHandle<T extends React.HTMLAttributes<HTMLElement>>(\n  Component: ReactFC<T>\n): ReactFC<T> {\n  return (props: T) => {\n    const { attributes, listeners } = useSortableItem()\n    return <Component {...props} {...attributes} {...listeners} />\n  }\n}\n"
  },
  {
    "path": "packages/antd/src/array-base/index.tsx",
    "content": "import {\n  CopyOutlined,\n  DeleteOutlined,\n  DownOutlined,\n  MenuOutlined,\n  PlusOutlined,\n  UpOutlined,\n} from '@ant-design/icons'\nimport { ArrayField } from '@formily/core'\nimport { JSXComponent, Schema, useField, useFieldSchema } from '@formily/react'\nimport { clone, isUndef, isValid } from '@formily/shared'\nimport { Button } from 'antd'\nimport { ButtonProps } from 'antd/lib/button'\nimport cls from 'classnames'\nimport React, { createContext, useContext } from 'react'\nimport { SortableHandle, usePrefixCls } from '../__builtins__'\n\nexport interface IArrayBaseAdditionProps extends ButtonProps {\n  title?: string\n  method?: 'push' | 'unshift'\n  defaultValue?: any\n}\nexport interface IArrayBaseOperationProps extends ButtonProps {\n  title?: string\n  index?: number\n  ref?: React.Ref<HTMLElement>\n}\n\nexport interface IArrayBaseContext {\n  props: IArrayBaseProps\n  field: ArrayField\n  schema: Schema\n}\n\nexport interface IArrayBaseItemProps {\n  index: number\n  record: ((index: number) => Record<string, any>) | Record<string, any>\n}\n\nexport type ArrayBaseMixins = {\n  Addition?: React.FC<React.PropsWithChildren<IArrayBaseAdditionProps>>\n  Copy?: React.FC<\n    React.PropsWithChildren<IArrayBaseOperationProps & { index?: number }>\n  >\n  Remove?: React.FC<\n    React.PropsWithChildren<IArrayBaseOperationProps & { index?: number }>\n  >\n  MoveUp?: React.FC<\n    React.PropsWithChildren<IArrayBaseOperationProps & { index?: number }>\n  >\n  MoveDown?: React.FC<\n    React.PropsWithChildren<IArrayBaseOperationProps & { index?: number }>\n  >\n  SortHandle?: React.FC<\n    React.PropsWithChildren<IArrayBaseOperationProps & { index?: number }>\n  >\n  Index?: React.FC\n  useArray?: () => IArrayBaseContext\n  useIndex?: (index?: number) => number\n  useRecord?: (record?: number) => any\n}\n\nexport interface IArrayBaseProps {\n  disabled?: boolean\n  onAdd?: (index: number) => void\n  onCopy?: (index: number) => void\n  onRemove?: (index: number) => void\n  onMoveDown?: (index: number) => void\n  onMoveUp?: (index: number) => void\n}\n\ntype ComposedArrayBase = React.FC<React.PropsWithChildren<IArrayBaseProps>> &\n  ArrayBaseMixins & {\n    Item?: React.FC<React.PropsWithChildren<IArrayBaseItemProps>>\n    mixin?: <T extends JSXComponent>(target: T) => T & ArrayBaseMixins\n  }\n\nconst ArrayBaseContext = createContext<IArrayBaseContext>(null)\n\nconst ItemContext = createContext<IArrayBaseItemProps>(null)\n\nconst takeRecord = (val: any, index?: number) =>\n  typeof val === 'function' ? val(index) : val\n\nconst useArray = () => {\n  return useContext(ArrayBaseContext)\n}\n\nconst useIndex = (index?: number) => {\n  const ctx = useContext(ItemContext)\n  return ctx ? ctx.index : index\n}\n\nconst useRecord = (record?: number) => {\n  const ctx = useContext(ItemContext)\n  return takeRecord(ctx ? ctx.record : record, ctx?.index)\n}\n\nconst getSchemaDefaultValue = (schema: Schema) => {\n  if (schema?.type === 'array') return []\n  if (schema?.type === 'object') return {}\n  if (schema?.type === 'void') {\n    for (let key in schema.properties) {\n      const value = getSchemaDefaultValue(schema.properties[key])\n      if (isValid(value)) return value\n    }\n  }\n}\n\nconst getDefaultValue = (defaultValue: any, schema: Schema) => {\n  if (isValid(defaultValue)) return clone(defaultValue)\n  if (Array.isArray(schema?.items))\n    return getSchemaDefaultValue(schema?.items[0])\n  return getSchemaDefaultValue(schema?.items)\n}\n\nexport const ArrayBase: ComposedArrayBase = (props) => {\n  const field = useField<ArrayField>()\n  const schema = useFieldSchema()\n  return (\n    <ArrayBaseContext.Provider value={{ field, schema, props }}>\n      {props.children}\n    </ArrayBaseContext.Provider>\n  )\n}\n\nArrayBase.Item = ({ children, ...props }) => {\n  return <ItemContext.Provider value={props}>{children}</ItemContext.Provider>\n}\n\nconst SortHandle = SortableHandle((props: any) => {\n  const prefixCls = usePrefixCls('formily-array-base')\n  return (\n    <MenuOutlined\n      {...props}\n      className={cls(`${prefixCls}-sort-handle`, props.className)}\n      style={{ ...props.style }}\n    />\n  )\n}) as any\n\nArrayBase.SortHandle = (props) => {\n  const array = useArray()\n  if (!array) return null\n  if (array.field?.pattern !== 'editable') return null\n  return <SortHandle {...props} />\n}\n\nArrayBase.Index = (props) => {\n  const index = useIndex()\n  const prefixCls = usePrefixCls('formily-array-base')\n  return (\n    <span {...props} className={`${prefixCls}-index`}>\n      #{index + 1}.\n    </span>\n  )\n}\n\nArrayBase.Addition = (props) => {\n  const self = useField()\n  const array = useArray()\n  const prefixCls = usePrefixCls('formily-array-base')\n  if (!array) return null\n  if (\n    array.field?.pattern !== 'editable' &&\n    array.field?.pattern !== 'disabled'\n  )\n    return null\n  return (\n    <Button\n      type=\"dashed\"\n      block\n      {...props}\n      disabled={self?.disabled}\n      className={cls(`${prefixCls}-addition`, props.className)}\n      onClick={(e) => {\n        if (array.props?.disabled) return\n        if (props.onClick) {\n          props.onClick(e)\n          if (e.defaultPrevented) return\n        }\n        const defaultValue = getDefaultValue(props.defaultValue, array.schema)\n        if (props.method === 'unshift') {\n          array.field?.unshift?.(defaultValue)\n          array.props?.onAdd?.(0)\n        } else {\n          array.field?.push?.(defaultValue)\n          array.props?.onAdd?.(array?.field?.value?.length - 1)\n        }\n      }}\n      icon={isUndef(props.icon) ? <PlusOutlined /> : props.icon}\n    >\n      {props.title || self.title}\n    </Button>\n  )\n}\n\nArrayBase.Copy = React.forwardRef((props, ref) => {\n  const self = useField()\n  const array = useArray()\n  const index = useIndex(props.index)\n  const prefixCls = usePrefixCls('formily-array-base')\n  if (!array) return null\n  if (array.field?.pattern !== 'editable') return null\n  return (\n    <Button\n      type=\"text\"\n      {...props}\n      disabled={self?.disabled}\n      className={cls(\n        `${prefixCls}-copy`,\n        self?.disabled ? `${prefixCls}-copy-disabled` : '',\n        props.className\n      )}\n      ref={ref}\n      onClick={(e) => {\n        if (self?.disabled) return\n        e.stopPropagation()\n        if (array.props?.disabled) return\n        if (props.onClick) {\n          props.onClick(e)\n          if (e.defaultPrevented) return\n        }\n        const value = clone(array?.field?.value[index])\n        const distIndex = index + 1\n        array.field?.insert?.(distIndex, value)\n        array.props?.onCopy?.(distIndex)\n      }}\n      icon={isUndef(props.icon) ? <CopyOutlined /> : props.icon}\n    >\n      {props.title || self.title}\n    </Button>\n  )\n})\n\nArrayBase.Remove = React.forwardRef((props, ref) => {\n  const index = useIndex(props.index)\n  const self = useField()\n  const array = useArray()\n  const prefixCls = usePrefixCls('formily-array-base')\n  if (!array) return null\n  if (array.field?.pattern !== 'editable') return null\n  return (\n    <Button\n      type=\"text\"\n      {...props}\n      disabled={self?.disabled}\n      className={cls(\n        `${prefixCls}-remove`,\n        self?.disabled ? `${prefixCls}-remove-disabled` : '',\n        props.className\n      )}\n      ref={ref}\n      onClick={(e) => {\n        if (self?.disabled) return\n        e.stopPropagation()\n        if (props.onClick) {\n          props.onClick(e)\n          if (e.defaultPrevented) return\n        }\n        array.field?.remove?.(index)\n        array.props?.onRemove?.(index)\n      }}\n      icon={isUndef(props.icon) ? <DeleteOutlined /> : props.icon}\n    >\n      {props.title || self.title}\n    </Button>\n  )\n})\n\nArrayBase.MoveDown = React.forwardRef((props, ref) => {\n  const index = useIndex(props.index)\n  const self = useField()\n  const array = useArray()\n  const prefixCls = usePrefixCls('formily-array-base')\n  if (!array) return null\n  if (array.field?.pattern !== 'editable') return null\n  return (\n    <Button\n      type=\"text\"\n      {...props}\n      disabled={self?.disabled}\n      className={cls(\n        `${prefixCls}-move-down`,\n        self?.disabled ? `${prefixCls}-move-down-disabled` : '',\n        props.className\n      )}\n      ref={ref}\n      onClick={(e) => {\n        if (self?.disabled) return\n        e.stopPropagation()\n        if (props.onClick) {\n          props.onClick(e)\n          if (e.defaultPrevented) return\n        }\n        array.field?.moveDown?.(index)\n        array.props?.onMoveDown?.(index)\n      }}\n      icon={isUndef(props.icon) ? <DownOutlined /> : props.icon}\n    >\n      {props.title || self.title}\n    </Button>\n  )\n})\n\nArrayBase.MoveUp = React.forwardRef((props, ref) => {\n  const index = useIndex(props.index)\n  const self = useField()\n  const array = useArray()\n  const prefixCls = usePrefixCls('formily-array-base')\n  if (!array) return null\n  if (array.field?.pattern !== 'editable') return null\n  return (\n    <Button\n      type=\"text\"\n      {...props}\n      disabled={self?.disabled}\n      className={cls(\n        `${prefixCls}-move-up`,\n        self?.disabled ? `${prefixCls}-move-up-disabled` : '',\n        props.className\n      )}\n      ref={ref}\n      onClick={(e) => {\n        if (self?.disabled) return\n        e.stopPropagation()\n        if (props.onClick) {\n          props.onClick(e)\n          if (e.defaultPrevented) return\n        }\n        array?.field?.moveUp(index)\n        array?.props?.onMoveUp?.(index)\n      }}\n      icon={isUndef(props.icon) ? <UpOutlined /> : props.icon}\n    >\n      {props.title || self.title}\n    </Button>\n  )\n})\n\nArrayBase.useArray = useArray\nArrayBase.useIndex = useIndex\nArrayBase.useRecord = useRecord\nArrayBase.mixin = (target: any) => {\n  target.Index = ArrayBase.Index\n  target.SortHandle = ArrayBase.SortHandle\n  target.Addition = ArrayBase.Addition\n  target.Copy = ArrayBase.Copy\n  target.Remove = ArrayBase.Remove\n  target.MoveDown = ArrayBase.MoveDown\n  target.MoveUp = ArrayBase.MoveUp\n  target.useArray = ArrayBase.useArray\n  target.useIndex = ArrayBase.useIndex\n  target.useRecord = ArrayBase.useRecord\n  return target\n}\n\nexport default ArrayBase\n"
  },
  {
    "path": "packages/antd/src/array-base/style.less",
    "content": "@root-entry-name: 'default';\n@import (reference) '~antd/es/style/themes/index.less';\n\n@array-base-prefix-cls: ~'@{ant-prefix}-formily-array-base';\n\n.@{array-base-prefix-cls}-remove,\n.@{array-base-prefix-cls}-copy {\n  transition: all 0.25s ease-in-out;\n  color: @text-color;\n  font-size: 14px;\n  margin-left: 6px;\n  padding: 0;\n  border: none;\n  width: auto;\n  height: auto;\n\n  &:hover {\n    color: @primary-5;\n  }\n\n  &-disabled {\n    color: @disabled-color;\n    cursor: not-allowed !important;\n    &:hover {\n      color: @disabled-color;\n    }\n  }\n}\n\n.@{array-base-prefix-cls}-sort-handle {\n  cursor: move;\n  color: #888 !important;\n  // overrid iconfont.less .anticon[tabindex] cursor\n  &.anticon[tabindex] {\n    cursor: move;\n  }\n}\n\n.@{array-base-prefix-cls}-addition {\n  transition: all 0.25s ease-in-out;\n}\n\n.@{array-base-prefix-cls}-move-down {\n  transition: all 0.25s ease-in-out;\n  color: @text-color;\n  font-size: 14px;\n  margin-left: 6px;\n  padding: 0;\n  border: none;\n  width: auto;\n  height: auto;\n\n  &:hover {\n    color: @primary-5;\n  }\n\n  &-disabled {\n    color: @disabled-color;\n    cursor: not-allowed !important;\n    &:hover {\n      color: @disabled-color;\n    }\n  }\n}\n\n.@{array-base-prefix-cls}-move-up {\n  transition: all 0.25s ease-in-out;\n  color: @text-color;\n  font-size: 14px;\n  margin-left: 6px;\n  padding: 0;\n  border: none;\n  width: auto;\n  height: auto;\n\n  &:hover {\n    color: @primary-5;\n  }\n\n  &-disabled {\n    color: @disabled-color;\n    cursor: not-allowed !important;\n    &:hover {\n      color: @disabled-color;\n    }\n  }\n}\n"
  },
  {
    "path": "packages/antd/src/array-base/style.ts",
    "content": "import 'antd/lib/button/style/index'\nimport './style.less'\n"
  },
  {
    "path": "packages/antd/src/array-cards/index.tsx",
    "content": "import React from 'react'\nimport { Card, Empty } from 'antd'\nimport { CardProps } from 'antd/lib/card'\nimport { ArrayField } from '@formily/core'\nimport {\n  useField,\n  observer,\n  useFieldSchema,\n  RecursionField,\n} from '@formily/react'\nimport cls from 'classnames'\nimport { ISchema } from '@formily/json-schema'\nimport { usePrefixCls } from '../__builtins__'\nimport { ArrayBase, ArrayBaseMixins, IArrayBaseProps } from '../array-base'\n\ntype ComposedArrayCards = React.FC<\n  React.PropsWithChildren<CardProps & IArrayBaseProps>\n> &\n  ArrayBaseMixins\n\nconst isAdditionComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf('Addition') > -1\n}\n\nconst isIndexComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Index') > -1\n}\n\nconst isRemoveComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Remove') > -1\n}\n\nconst isCopyComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Copy') > -1\n}\n\nconst isMoveUpComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('MoveUp') > -1\n}\n\nconst isMoveDownComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('MoveDown') > -1\n}\n\nconst isOperationComponent = (schema: ISchema) => {\n  return (\n    isAdditionComponent(schema) ||\n    isRemoveComponent(schema) ||\n    isCopyComponent(schema) ||\n    isMoveDownComponent(schema) ||\n    isMoveUpComponent(schema)\n  )\n}\n\nexport const ArrayCards: ComposedArrayCards = observer((props) => {\n  const field = useField<ArrayField>()\n  const schema = useFieldSchema()\n  const dataSource = Array.isArray(field.value) ? field.value : []\n  const prefixCls = usePrefixCls('formily-array-cards', props)\n  const { onAdd, onCopy, onRemove, onMoveDown, onMoveUp } = props\n\n  if (!schema) throw new Error('can not found schema object')\n\n  const renderItems = () => {\n    return dataSource?.map((item, index) => {\n      const items = Array.isArray(schema.items)\n        ? schema.items[index] || schema.items[0]\n        : schema.items\n      const title = (\n        <span>\n          <RecursionField\n            schema={items}\n            name={index}\n            filterProperties={(schema) => {\n              if (!isIndexComponent(schema)) return false\n              return true\n            }}\n            onlyRenderProperties\n          />\n          {props.title || field.title}\n        </span>\n      )\n      const extra = (\n        <span>\n          <RecursionField\n            schema={items}\n            name={index}\n            filterProperties={(schema) => {\n              if (!isOperationComponent(schema)) return false\n              return true\n            }}\n            onlyRenderProperties\n          />\n          {props.extra}\n        </span>\n      )\n      const content = (\n        <RecursionField\n          schema={items}\n          name={index}\n          filterProperties={(schema) => {\n            if (isIndexComponent(schema)) return false\n            if (isOperationComponent(schema)) return false\n            return true\n          }}\n        />\n      )\n      return (\n        <ArrayBase.Item\n          key={index}\n          index={index}\n          record={() => field.value?.[index]}\n        >\n          <Card\n            {...props}\n            onChange={() => {}}\n            className={cls(`${prefixCls}-item`, props.className)}\n            title={title}\n            extra={extra}\n          >\n            {content}\n          </Card>\n        </ArrayBase.Item>\n      )\n    })\n  }\n\n  const renderAddition = () => {\n    return schema.reduceProperties((addition, schema, key) => {\n      if (isAdditionComponent(schema)) {\n        return <RecursionField schema={schema} name={key} />\n      }\n      return addition\n    }, null)\n  }\n\n  const renderEmpty = () => {\n    if (dataSource?.length) return\n    return (\n      <Card\n        {...props}\n        onChange={() => {}}\n        className={cls(`${prefixCls}-item`, props.className)}\n        title={props.title || field.title}\n      >\n        <Empty />\n      </Card>\n    )\n  }\n\n  return (\n    <ArrayBase\n      onAdd={onAdd}\n      onCopy={onCopy}\n      onRemove={onRemove}\n      onMoveUp={onMoveUp}\n      onMoveDown={onMoveDown}\n    >\n      {renderEmpty()}\n      {renderItems()}\n      {renderAddition()}\n    </ArrayBase>\n  )\n})\n\nArrayCards.displayName = 'ArrayCards'\n\nArrayBase.mixin(ArrayCards)\n\nexport default ArrayCards\n"
  },
  {
    "path": "packages/antd/src/array-cards/style.less",
    "content": "@root-entry-name: 'default';\n@import (reference) '~antd/es/style/themes/index.less';\n\n@array-base-prefix-cls: ~'@{ant-prefix}-formily-array-base';\n@array-cards-prefix-cls: ~'@{ant-prefix}-formily-array-cards';\n\n.@{array-cards-prefix-cls}-item {\n  margin-bottom: 10px !important;\n}\n\n.ant-card-extra {\n  .@{array-base-prefix-cls}-copy {\n    margin-left: 6px;\n  }\n}\n"
  },
  {
    "path": "packages/antd/src/array-cards/style.ts",
    "content": "import 'antd/lib/card/style/index'\nimport 'antd/lib/empty/style/index'\nimport 'antd/lib/button/style/index'\nimport './style.less'\n"
  },
  {
    "path": "packages/antd/src/array-collapse/index.tsx",
    "content": "import React, { Fragment, useState, useEffect } from 'react'\nimport {\n  Badge,\n  Card,\n  Collapse,\n  CollapsePanelProps,\n  CollapseProps,\n  Empty,\n} from 'antd'\nimport { ArrayField } from '@formily/core'\nimport {\n  RecursionField,\n  useField,\n  useFieldSchema,\n  observer,\n  ISchema,\n} from '@formily/react'\nimport { toArr } from '@formily/shared'\nimport cls from 'classnames'\nimport ArrayBase, { ArrayBaseMixins, IArrayBaseProps } from '../array-base'\nimport { usePrefixCls } from '../__builtins__'\n\nexport interface IArrayCollapseProps extends CollapseProps {\n  defaultOpenPanelCount?: number\n}\ntype ComposedArrayCollapse = React.FC<\n  React.PropsWithChildren<IArrayCollapseProps & IArrayBaseProps>\n> &\n  ArrayBaseMixins & {\n    CollapsePanel?: React.FC<React.PropsWithChildren<CollapsePanelProps>>\n  }\n\nconst isAdditionComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Addition') > -1\n}\n\nconst isIndexComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Index') > -1\n}\n\nconst isRemoveComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Remove') > -1\n}\n\nconst isMoveUpComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('MoveUp') > -1\n}\n\nconst isMoveDownComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('MoveDown') > -1\n}\n\nconst isOperationComponent = (schema: ISchema) => {\n  return (\n    isAdditionComponent(schema) ||\n    isRemoveComponent(schema) ||\n    isMoveDownComponent(schema) ||\n    isMoveUpComponent(schema)\n  )\n}\n\nconst range = (count: number) => Array.from({ length: count }).map((_, i) => i)\n\nconst takeDefaultActiveKeys = (\n  dataSourceLength: number,\n  defaultOpenPanelCount: number\n) => {\n  if (dataSourceLength < defaultOpenPanelCount) return range(dataSourceLength)\n  return range(defaultOpenPanelCount)\n}\n\nconst insertActiveKeys = (activeKeys: number[], index: number) => {\n  if (activeKeys.length <= index) return activeKeys.concat(index)\n  return activeKeys.reduce((buf, key) => {\n    if (key < index) return buf.concat(key)\n    if (key === index) return buf.concat([key, key + 1])\n    return buf.concat(key + 1)\n  }, [])\n}\n\nexport const ArrayCollapse: ComposedArrayCollapse = observer(\n  ({ defaultOpenPanelCount = 5, ...props }) => {\n    const field = useField<ArrayField>()\n    const dataSource = Array.isArray(field.value) ? field.value : []\n    const [activeKeys, setActiveKeys] = useState<number[]>(\n      takeDefaultActiveKeys(dataSource.length, defaultOpenPanelCount)\n    )\n    const schema = useFieldSchema()\n    const prefixCls = usePrefixCls('formily-array-collapse', props)\n    useEffect(() => {\n      if (!field.modified && dataSource.length) {\n        setActiveKeys(\n          takeDefaultActiveKeys(dataSource.length, defaultOpenPanelCount)\n        )\n      }\n    }, [dataSource.length, field])\n    if (!schema) throw new Error('can not found schema object')\n    const { onAdd, onCopy, onRemove, onMoveDown, onMoveUp } = props\n\n    const renderAddition = () => {\n      return schema.reduceProperties((addition, schema, key) => {\n        if (isAdditionComponent(schema)) {\n          return <RecursionField schema={schema} name={key} />\n        }\n        return addition\n      }, null)\n    }\n    const renderEmpty = () => {\n      if (dataSource.length) return\n      return (\n        <Card className={cls(`${prefixCls}-item`, props.className)}>\n          <Empty />\n        </Card>\n      )\n    }\n\n    const renderItems = () => {\n      return (\n        <Collapse\n          {...props}\n          activeKey={activeKeys}\n          onChange={(keys: string[]) => setActiveKeys(toArr(keys).map(Number))}\n          className={cls(`${prefixCls}-item`, props.className)}\n        >\n          {dataSource.map((item, index) => {\n            const items = Array.isArray(schema.items)\n              ? schema.items[index] || schema.items[0]\n              : schema.items\n\n            const panelProps = field\n              .query(`${field.address}.${index}`)\n              .get('componentProps')\n            const props: CollapsePanelProps = items['x-component-props']\n            const header = () => {\n              const header = panelProps?.header || props.header || field.title\n              const path = field.address.concat(index)\n              const errors = field.form.queryFeedbacks({\n                type: 'error',\n                address: `${path}.**`,\n              })\n              return (\n                <ArrayBase.Item\n                  index={index}\n                  record={() => field.value?.[index]}\n                >\n                  <RecursionField\n                    schema={items}\n                    name={index}\n                    filterProperties={(schema) => {\n                      if (!isIndexComponent(schema)) return false\n                      return true\n                    }}\n                    onlyRenderProperties\n                  />\n                  {errors.length ? (\n                    <Badge\n                      size=\"small\"\n                      className=\"errors-badge\"\n                      count={errors.length}\n                    >\n                      {header}\n                    </Badge>\n                  ) : (\n                    header\n                  )}\n                </ArrayBase.Item>\n              )\n            }\n\n            const extra = (\n              <ArrayBase.Item index={index} record={item}>\n                <RecursionField\n                  schema={items}\n                  name={index}\n                  filterProperties={(schema) => {\n                    if (!isOperationComponent(schema)) return false\n                    return true\n                  }}\n                  onlyRenderProperties\n                />\n                {panelProps?.extra}\n              </ArrayBase.Item>\n            )\n\n            const content = (\n              <RecursionField\n                schema={items}\n                name={index}\n                filterProperties={(schema) => {\n                  if (isIndexComponent(schema)) return false\n                  if (isOperationComponent(schema)) return false\n                  return true\n                }}\n              />\n            )\n            return (\n              <Collapse.Panel\n                {...props}\n                {...panelProps}\n                forceRender\n                key={index}\n                header={header()}\n                extra={extra}\n              >\n                <ArrayBase.Item index={index} key={index} record={item}>\n                  {content}\n                </ArrayBase.Item>\n              </Collapse.Panel>\n            )\n          })}\n        </Collapse>\n      )\n    }\n    return (\n      <ArrayBase\n        onAdd={(index) => {\n          onAdd?.(index)\n          setActiveKeys(insertActiveKeys(activeKeys, index))\n        }}\n        onCopy={onCopy}\n        onRemove={onRemove}\n        onMoveUp={onMoveUp}\n        onMoveDown={onMoveDown}\n      >\n        {renderEmpty()}\n        {renderItems()}\n        {renderAddition()}\n      </ArrayBase>\n    )\n  }\n)\n\nconst CollapsePanel: React.FC<React.PropsWithChildren<CollapsePanelProps>> = ({\n  children,\n}) => {\n  return <Fragment>{children}</Fragment>\n}\n\nCollapsePanel.displayName = 'CollapsePanel'\n\nArrayCollapse.displayName = 'ArrayCollapse'\nArrayCollapse.CollapsePanel = CollapsePanel\n\nArrayBase.mixin(ArrayCollapse)\n\nexport default ArrayCollapse\n"
  },
  {
    "path": "packages/antd/src/array-collapse/style.less",
    "content": "@root-entry-name: 'default';\n@import (reference) '~antd/es/style/themes/index.less';\n\n@array-collapse-prefix-cls: ~'@{ant-prefix}-formily-array-collapse';\n\n.@{array-collapse-prefix-cls}-item {\n  margin-bottom: 10px !important;\n}\n"
  },
  {
    "path": "packages/antd/src/array-collapse/style.ts",
    "content": "import 'antd/lib/collapse/style/index'\nimport 'antd/lib/empty/style/index'\nimport 'antd/lib/button/style/index'\nimport 'antd/lib/badge/style/index'\nimport './style.less'\n"
  },
  {
    "path": "packages/antd/src/array-items/index.tsx",
    "content": "import React, { useRef } from 'react'\nimport { ArrayField } from '@formily/core'\nimport {\n  useField,\n  observer,\n  useFieldSchema,\n  RecursionField,\n} from '@formily/react'\nimport cls from 'classnames'\nimport { ISchema } from '@formily/json-schema'\nimport {\n  usePrefixCls,\n  SortableContainer,\n  SortableElement,\n} from '../__builtins__'\nimport { ArrayBase, ArrayBaseMixins, IArrayBaseProps } from '../array-base'\n\ntype ComposedArrayItems = React.FC<\n  React.PropsWithChildren<\n    React.HTMLAttributes<HTMLDivElement> & IArrayBaseProps\n  >\n> &\n  ArrayBaseMixins & {\n    Item?: React.FC<\n      React.HTMLAttributes<HTMLDivElement> & {\n        type?: 'card' | 'divide'\n      }\n    >\n  }\n\nconst SortableItem = SortableElement(\n  (props: React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>) => {\n    const prefixCls = usePrefixCls('formily-array-items')\n    return (\n      <div {...props} className={cls(`${prefixCls}-item`, props.className)}>\n        {props.children}\n      </div>\n    )\n  }\n)\n\nconst SortableList = SortableContainer(\n  (props: React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>) => {\n    const prefixCls = usePrefixCls('formily-array-items')\n    return (\n      <div {...props} className={cls(`${prefixCls}-list`, props.className)}>\n        {props.children}\n      </div>\n    )\n  }\n)\n\nconst isAdditionComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf('Addition') > -1\n}\n\nconst useAddition = () => {\n  const schema = useFieldSchema()\n  return schema.reduceProperties((addition, schema, key) => {\n    if (isAdditionComponent(schema)) {\n      return <RecursionField schema={schema} name={key} />\n    }\n    return addition\n  }, null)\n}\n\nexport const ArrayItems: ComposedArrayItems = observer((props) => {\n  const field = useField<ArrayField>()\n  const prefixCls = usePrefixCls('formily-array-items')\n  const ref = useRef<HTMLDivElement>(null)\n  const schema = useFieldSchema()\n  const addition = useAddition()\n  const dataSource = Array.isArray(field.value) ? field.value : []\n  const { onAdd, onCopy, onRemove, onMoveDown, onMoveUp } = props\n  if (!schema) throw new Error('can not found schema object')\n  return (\n    <ArrayBase\n      onAdd={onAdd}\n      onCopy={onCopy}\n      onRemove={onRemove}\n      onMoveUp={onMoveUp}\n      onMoveDown={onMoveDown}\n    >\n      <div\n        {...props}\n        ref={ref}\n        onChange={() => {}}\n        className={cls(prefixCls, props.className)}\n      >\n        <SortableList\n          list={dataSource.slice()}\n          className={`${prefixCls}-sort-helper`}\n          onSortEnd={({ oldIndex, newIndex }) => {\n            field.move(oldIndex, newIndex)\n          }}\n        >\n          {dataSource?.map((item, index) => {\n            const items = Array.isArray(schema.items)\n              ? schema.items[index] || schema.items[0]\n              : schema.items\n            return (\n              <ArrayBase.Item\n                key={index}\n                index={index}\n                record={() => field.value?.[index]}\n              >\n                <SortableItem key={`item-${index}`} lockAxis=\"y\" index={index}>\n                  <div className={`${prefixCls}-item-inner`}>\n                    <RecursionField schema={items} name={index} />\n                  </div>\n                </SortableItem>\n              </ArrayBase.Item>\n            )\n          })}\n        </SortableList>\n        {addition}\n      </div>\n    </ArrayBase>\n  )\n})\n\nArrayItems.displayName = 'ArrayItems'\n\nArrayItems.Item = (props) => {\n  const prefixCls = usePrefixCls('formily-array-items')\n  return (\n    <div\n      {...props}\n      onChange={() => {}}\n      className={cls(`${prefixCls}-${props.type || 'card'}`, props.className)}\n    >\n      {props.children}\n    </div>\n  )\n}\n\nArrayBase.mixin(ArrayItems)\n\nexport default ArrayItems\n"
  },
  {
    "path": "packages/antd/src/array-items/style.less",
    "content": "@root-entry-name: 'default';\n@import (reference) '~antd/es/style/themes/index.less';\n\n@array-items-prefix-cls: ~'@{ant-prefix}-formily-array-items';\n\n.@{array-items-prefix-cls}-item-inner {\n  visibility: visible;\n}\n\n// fix https://github.com/alibaba/formily/issues/2891\n.@{array-items-prefix-cls}-item {\n  z-index: 100000;\n}\n\n.@{array-items-prefix-cls}-card {\n  display: flex;\n  border: 1px solid @border-color-split;\n  margin-bottom: 10px;\n  padding: 3px 6px;\n  background: @card-background;\n  justify-content: space-between;\n  color: @text-color;\n\n  .@{ant-prefix}-formily-item:not(.@{ant-prefix}-formily-item-feedback-layout-popover) {\n    margin-bottom: 0 !important;\n\n    .@{ant-prefix}-formily-item-help {\n      position: absolute;\n      font-size: 12px;\n      top: 100%;\n      background: @card-background;\n      width: 100%;\n      margin-top: 3px;\n      padding: 3px;\n      z-index: 1;\n      border-radius: 3px;\n      box-shadow: 0 0 10px @border-color-split;\n    }\n  }\n}\n\n.@{array-items-prefix-cls}-divide {\n  display: flex;\n  border-bottom: 1px solid @border-color-split;\n  padding: 10px 0;\n  justify-content: space-between;\n\n  .@{ant-prefix}-formily-item:not(.@{ant-prefix}-formily-item-feedback-layout-popover) {\n    margin-bottom: 0 !important;\n\n    .@{ant-prefix}-formily-item-help {\n      position: absolute;\n      font-size: 12px;\n      top: 100%;\n      background: @card-background;\n      width: 100%;\n      margin-top: 3px;\n      padding: 3px;\n      z-index: 1;\n      border-radius: 3px;\n      box-shadow: 0 0 10px @border-color-split;\n    }\n  }\n}\n"
  },
  {
    "path": "packages/antd/src/array-items/style.ts",
    "content": "import 'antd/lib/button/style/index'\nimport './style.less'\n"
  },
  {
    "path": "packages/antd/src/array-table/index.tsx",
    "content": "import React, {\n  Fragment,\n  useState,\n  useRef,\n  useEffect,\n  createContext,\n  useContext,\n  useCallback,\n} from 'react'\nimport { Table, Pagination, Space, Select, Badge } from 'antd'\nimport { PaginationProps } from 'antd/lib/pagination'\nimport { TableProps, ColumnProps } from 'antd/lib/table'\nimport { SelectProps } from 'antd/lib/select'\nimport cls from 'classnames'\nimport { GeneralField, FieldDisplayTypes, ArrayField } from '@formily/core'\nimport {\n  useField,\n  observer,\n  useFieldSchema,\n  RecursionField,\n  ReactFC,\n} from '@formily/react'\nimport { isArr, isBool, isFn } from '@formily/shared'\nimport { Schema } from '@formily/json-schema'\nimport {\n  usePrefixCls,\n  SortableContainer,\n  SortableElement,\n} from '../__builtins__'\nimport { ArrayBase, ArrayBaseMixins, IArrayBaseProps } from '../array-base'\n\ninterface ObservableColumnSource {\n  field: GeneralField\n  columnProps: ColumnProps<any>\n  schema: Schema\n  display: FieldDisplayTypes\n  name: string\n}\ninterface IArrayTablePaginationProps extends PaginationProps {\n  dataSource?: any[]\n  showPagination?: boolean\n  children?: (\n    dataSource: any[],\n    pagination: React.ReactNode,\n    options: {\n      startIndex: number\n    }\n  ) => React.ReactElement\n}\n\ninterface IStatusSelectProps extends SelectProps<any> {\n  pageSize?: number\n}\n\ntype ComposedArrayTable = React.FC<\n  React.PropsWithChildren<TableProps<any> & IArrayBaseProps>\n> &\n  ArrayBaseMixins & {\n    Column?: React.FC<React.PropsWithChildren<ColumnProps<any>>>\n  }\n\ninterface PaginationAction {\n  totalPage?: number\n  pageSize?: number\n  showPagination?: boolean\n  changePage?: (page: number) => void\n}\n\nconst SortableRow = SortableElement((props: any) => <tr {...props} />)\nconst SortableBody = SortableContainer((props: any) => <tbody {...props} />)\n\nconst isColumnComponent = (schema: Schema) => {\n  return schema['x-component']?.indexOf('Column') > -1\n}\n\nconst isOperationsComponent = (schema: Schema) => {\n  return schema['x-component']?.indexOf('Operations') > -1\n}\n\nconst isAdditionComponent = (schema: Schema) => {\n  return schema['x-component']?.indexOf('Addition') > -1\n}\n\nconst useArrayTableSources = () => {\n  const arrayField = useField()\n  const schema = useFieldSchema()\n  const parseSources = (schema: Schema): ObservableColumnSource[] => {\n    if (\n      isColumnComponent(schema) ||\n      isOperationsComponent(schema) ||\n      isAdditionComponent(schema)\n    ) {\n      if (!schema['x-component-props']?.['dataIndex'] && !schema['name'])\n        return []\n      const name = schema['x-component-props']?.['dataIndex'] || schema['name']\n      const field = arrayField.query(arrayField.address.concat(name)).take()\n      const columnProps =\n        field?.component?.[1] || schema['x-component-props'] || {}\n      const display = field?.display || schema['x-display'] || 'visible'\n      return [\n        {\n          name,\n          display,\n          field,\n          schema,\n          columnProps,\n        },\n      ]\n    } else if (schema.properties) {\n      return schema.reduceProperties((buf, schema) => {\n        return buf.concat(parseSources(schema))\n      }, [])\n    }\n  }\n\n  const parseArrayItems = (schema: Schema['items']) => {\n    if (!schema) return []\n    const sources: ObservableColumnSource[] = []\n    const items = isArr(schema) ? schema : [schema]\n    return items.reduce((columns, schema) => {\n      const item = parseSources(schema)\n      if (item) {\n        return columns.concat(item)\n      }\n      return columns\n    }, sources)\n  }\n\n  if (!schema) throw new Error('can not found schema object')\n\n  return parseArrayItems(schema.items)\n}\n\nconst useArrayTableColumns = (\n  dataSource: any[],\n  field: ArrayField,\n  sources: ObservableColumnSource[]\n): TableProps<any>['columns'] => {\n  return sources.reduce((buf, { name, columnProps, schema, display }, key) => {\n    if (display !== 'visible') return buf\n    if (!isColumnComponent(schema)) return buf\n    return buf.concat({\n      ...columnProps,\n      key,\n      dataIndex: name,\n      render: (value: any, record: any) => {\n        const index = dataSource?.indexOf(record)\n        const children = (\n          <ArrayBase.Item index={index} record={() => field?.value?.[index]}>\n            <RecursionField schema={schema} name={index} onlyRenderProperties />\n          </ArrayBase.Item>\n        )\n        return children\n      },\n    })\n  }, [])\n}\n\nconst useAddition = () => {\n  const schema = useFieldSchema()\n  return schema.reduceProperties((addition, schema, key) => {\n    if (isAdditionComponent(schema)) {\n      return <RecursionField schema={schema} name={key} />\n    }\n    return addition\n  }, null)\n}\n\nconst schedulerRequest = {\n  request: null,\n}\n\nconst StatusSelect: ReactFC<IStatusSelectProps> = observer(\n  (props) => {\n    const field = useField<ArrayField>()\n    const prefixCls = usePrefixCls('formily-array-table')\n    const errors = field.errors\n    const parseIndex = (address: string) => {\n      return Number(\n        address\n          .slice(address.indexOf(field.address.toString()) + 1)\n          .match(/(\\d+)/)?.[1]\n      )\n    }\n    const options = props.options?.map(({ label, value }) => {\n      const val = Number(value)\n      const hasError = errors.some(({ address }) => {\n        const currentIndex = parseIndex(address)\n        const startIndex = (val - 1) * props.pageSize\n        const endIndex = val * props.pageSize\n        return currentIndex >= startIndex && currentIndex <= endIndex\n      })\n      return {\n        label: hasError ? <Badge dot>{label}</Badge> : label,\n        value,\n      }\n    })\n\n    const width = String(options?.length).length * 15\n\n    return (\n      <Select\n        value={props.value}\n        onChange={props.onChange}\n        options={options}\n        virtual\n        style={{\n          width: width < 60 ? 60 : width,\n        }}\n        className={cls(`${prefixCls}-status-select`, {\n          'has-error': errors?.length,\n        })}\n      />\n    )\n  },\n  {\n    scheduler: (update) => {\n      clearTimeout(schedulerRequest.request)\n      schedulerRequest.request = setTimeout(() => {\n        update()\n      }, 100)\n    },\n  }\n)\n\nconst PaginationContext = createContext<PaginationAction>({})\nconst usePagination = () => {\n  return useContext(PaginationContext)\n}\n\nconst ArrayTablePagination: ReactFC<IArrayTablePaginationProps> = (props) => {\n  const [current, setCurrent] = useState(1)\n  const prefixCls = usePrefixCls('formily-array-table')\n  const showPagination = props.showPagination ?? true\n  const pageSize = props.pageSize || 10\n  const size = props.size || 'default'\n  const dataSource = props.dataSource || []\n  const startIndex = (current - 1) * pageSize\n  const endIndex = startIndex + pageSize - 1\n  const total = dataSource?.length || 0\n  const totalPage = Math.ceil(total / pageSize)\n  const pages = Array.from(new Array(totalPage)).map((_, index) => {\n    const page = index + 1\n    return {\n      label: page,\n      value: page,\n    }\n  })\n  const handleChange = (current: number) => {\n    setCurrent(current)\n  }\n\n  useEffect(() => {\n    if (totalPage > 0 && totalPage < current) {\n      handleChange(totalPage)\n    }\n  }, [totalPage, current])\n\n  const renderPagination = () => {\n    if (totalPage <= 1 || !showPagination) return\n    return (\n      <div className={`${prefixCls}-pagination`}>\n        <Space>\n          <StatusSelect\n            value={current}\n            pageSize={pageSize}\n            onChange={handleChange}\n            options={pages}\n            notFoundContent={false}\n          />\n          <Pagination\n            {...props}\n            pageSize={pageSize}\n            current={current}\n            total={dataSource.length}\n            size={size}\n            showSizeChanger={false}\n            onChange={handleChange}\n          />\n        </Space>\n      </div>\n    )\n  }\n\n  return (\n    <Fragment>\n      <PaginationContext.Provider\n        value={{\n          totalPage,\n          pageSize,\n          changePage: handleChange,\n          showPagination,\n        }}\n      >\n        {props.children?.(\n          showPagination\n            ? dataSource?.slice(startIndex, endIndex + 1)\n            : dataSource,\n          renderPagination(),\n          { startIndex }\n        )}\n      </PaginationContext.Provider>\n    </Fragment>\n  )\n}\n\nconst RowComp: ReactFC<React.HTMLAttributes<HTMLTableRowElement>> = (props) => {\n  const prefixCls = usePrefixCls('formily-array-table')\n  const index = props['data-row-key'] || 0\n  return (\n    <SortableRow\n      lockAxis=\"y\"\n      {...props}\n      index={index}\n      className={cls(props.className, `${prefixCls}-row-${index + 1}`)}\n    />\n  )\n}\n\nexport const ArrayTable: ComposedArrayTable = observer((props) => {\n  const ref = useRef<HTMLDivElement>()\n  const field = useField<ArrayField>()\n  const prefixCls = usePrefixCls('formily-array-table')\n  const dataSource = Array.isArray(field.value) ? field.value.slice() : []\n  const sources = useArrayTableSources()\n  const columns = useArrayTableColumns(dataSource, field, sources)\n  const pagination = isBool(props.pagination)\n    ? { showPagination: props.pagination }\n    : props.pagination\n  const addition = useAddition()\n  const { onAdd, onCopy, onRemove, onMoveDown, onMoveUp } = props\n  const defaultRowKey = (record: any) => {\n    return dataSource.indexOf(record)\n  }\n  const addTdStyles = (id: number) => {\n    const node = ref.current?.querySelector(`.${prefixCls}-row-${id}`)\n    const helper = document.body.querySelector(`.${prefixCls}-sort-helper`)\n    if (!helper) return\n    const tds = node?.querySelectorAll('td')\n    if (!tds) return\n    requestAnimationFrame(() => {\n      helper.querySelectorAll('td').forEach((td, index) => {\n        if (tds[index]) {\n          td.style.width = getComputedStyle(tds[index]).width\n        }\n      })\n    })\n  }\n  const getWrapperComp = useCallback(\n    (dataSource: any[], start: number) => (props: any) =>\n      (\n        <SortableBody\n          {...props}\n          start={start}\n          list={dataSource.slice()}\n          accessibility={{\n            container: ref.current || undefined,\n          }}\n          onSortStart={(event) => {\n            addTdStyles(event.active.id as number)\n          }}\n          onSortEnd={({ oldIndex, newIndex }) => {\n            field.move(oldIndex, newIndex)\n          }}\n          className={cls(`${prefixCls}-sort-helper`, props.className)}\n        />\n      ),\n    [field]\n  )\n  return (\n    <ArrayTablePagination {...pagination} dataSource={dataSource}>\n      {(dataSource, pager, { startIndex }) => (\n        <div ref={ref} className={prefixCls}>\n          <ArrayBase\n            onAdd={onAdd}\n            onCopy={onCopy}\n            onRemove={onRemove}\n            onMoveUp={onMoveUp}\n            onMoveDown={onMoveDown}\n          >\n            <Table\n              size=\"small\"\n              bordered\n              rowKey={defaultRowKey}\n              {...props}\n              onChange={() => {}}\n              pagination={false}\n              columns={columns}\n              dataSource={dataSource}\n              components={{\n                body: {\n                  wrapper: getWrapperComp(dataSource, startIndex),\n                  row: RowComp,\n                },\n              }}\n            />\n            <div style={{ marginTop: 5, marginBottom: 5 }}>{pager}</div>\n            {sources.map((column, key) => {\n              //专门用来承接对Column的状态管理\n              if (!isColumnComponent(column.schema)) return\n              return React.createElement(RecursionField, {\n                name: column.name,\n                schema: column.schema,\n                onlyRenderSelf: true,\n                key,\n              })\n            })}\n            {addition}\n          </ArrayBase>\n        </div>\n      )}\n    </ArrayTablePagination>\n  )\n})\n\nArrayTable.displayName = 'ArrayTable'\n\nArrayTable.Column = () => {\n  return <Fragment />\n}\n\nArrayBase.mixin(ArrayTable)\n\nconst Addition: ArrayBaseMixins['Addition'] = (props) => {\n  const array = ArrayBase.useArray()\n  const {\n    totalPage = 0,\n    pageSize = 10,\n    changePage,\n    showPagination,\n  } = usePagination()\n  return (\n    <ArrayBase.Addition\n      {...props}\n      onClick={(e) => {\n        // 如果添加数据后将超过当前页，则自动切换到下一页\n        const total = array?.field?.value.length || 0\n        if (\n          showPagination &&\n          total === totalPage * pageSize + 1 &&\n          isFn(changePage)\n        ) {\n          changePage(totalPage + 1)\n        }\n        props.onClick?.(e)\n      }}\n    />\n  )\n}\nArrayTable.Addition = Addition\n\nexport default ArrayTable\n"
  },
  {
    "path": "packages/antd/src/array-table/style.less",
    "content": "@root-entry-name: 'default';\n@import (reference) '~antd/es/style/themes/index.less';\n\n@array-table-prefix-cls: ~'@{ant-prefix}-formily-array-table';\n\n.@{array-table-prefix-cls} {\n  .@{array-table-prefix-cls}-pagination {\n    display: flex;\n    justify-content: center;\n\n    .@{array-table-prefix-cls}-status-select.has-error {\n      .@{ant-prefix}-select-selector {\n        border-color: @error-color !important;\n      }\n    }\n  }\n\n  .@{ant-prefix}-table {\n    table {\n      overflow: hidden;\n    }\n\n    td {\n      visibility: visible;\n\n      .@{ant-prefix}-formily-item:not(.@{ant-prefix}-formily-item-feedback-layout-popover) {\n        margin-bottom: 0 !important;\n\n        .@{ant-prefix}-formily-item-help {\n          position: absolute;\n          font-size: 12px;\n          top: 100%;\n          background: #fff;\n          width: 100%;\n          margin-top: 3px;\n          padding: 3px;\n          z-index: 1;\n          border-radius: 3px;\n          box-shadow: 0 0 10px #eee;\n          animation: none;\n          transform: translateY(0);\n          opacity: 1;\n        }\n      }\n    }\n  }\n\n  .@{array-table-prefix-cls}-sort-helper {\n    background: #fff;\n    border: 1px solid #eee;\n    z-index: 10;\n  }\n}\n"
  },
  {
    "path": "packages/antd/src/array-table/style.ts",
    "content": "import 'antd/lib/table/style/index'\nimport 'antd/lib/button/style/index'\nimport 'antd/lib/select/style/index'\nimport 'antd/lib/space/style/index'\nimport 'antd/lib/badge/style/index'\nimport 'antd/lib/pagination/style/index'\nimport './style.less'\n"
  },
  {
    "path": "packages/antd/src/array-tabs/index.tsx",
    "content": "import React, { Fragment, useState } from 'react'\nimport { Tabs, Badge } from 'antd'\nimport { ArrayField } from '@formily/core'\nimport {\n  useField,\n  observer,\n  useFieldSchema,\n  RecursionField,\n  ReactFC,\n} from '@formily/react'\nimport { TabsProps } from 'antd/lib/tabs'\n\ninterface IFeedbackBadgeProps {\n  index: number\n}\n\nconst FeedbackBadge: ReactFC<IFeedbackBadgeProps> = observer(\n  (props) => {\n    const field = useField<ArrayField>()\n    const tab = `${field.title || 'Untitled'} ${props.index + 1}`\n    const errors = field.errors.filter((error) =>\n      error.address.includes(`${field.address}.${props.index}`)\n    )\n    if (errors.length) {\n      return (\n        <Badge size=\"small\" className=\"errors-badge\" count={errors.length}>\n          {tab}\n        </Badge>\n      )\n    }\n    return <Fragment>{tab}</Fragment>\n  },\n  {\n    scheduler(request) {\n      requestAnimationFrame(request)\n    },\n  }\n)\n\nexport const ArrayTabs: React.FC<React.PropsWithChildren<TabsProps>> = observer(\n  (props) => {\n    const field = useField<ArrayField>()\n    const schema = useFieldSchema()\n    const [activeKey, setActiveKey] = useState('tab-0')\n    const value = Array.isArray(field.value) ? field.value : []\n    const dataSource = value?.length ? value : [{}]\n    const onEdit = (targetKey: any, type: 'add' | 'remove') => {\n      if (type == 'add') {\n        const id = dataSource.length\n        if (field?.value?.length) {\n          field.push(null)\n        } else {\n          field.push(null, null)\n        }\n        setActiveKey(`tab-${id}`)\n      } else if (type == 'remove') {\n        const index = Number(targetKey.match(/-(\\d+)/)?.[1])\n        if (index - 1 > -1) {\n          setActiveKey(`tab-${index - 1}`)\n        }\n        field.remove(index)\n      }\n    }\n    return (\n      <Tabs\n        {...props}\n        activeKey={activeKey}\n        onChange={(key) => {\n          setActiveKey(key)\n        }}\n        type=\"editable-card\"\n        onEdit={onEdit}\n      >\n        {dataSource?.map((item, index) => {\n          const items = Array.isArray(schema.items)\n            ? schema.items[index]\n            : schema.items\n          const key = `tab-${index}`\n          return (\n            <Tabs.TabPane\n              key={key}\n              forceRender\n              closable={index !== 0}\n              tab={<FeedbackBadge index={index} />}\n            >\n              <RecursionField schema={items} name={index} />\n            </Tabs.TabPane>\n          )\n        })}\n      </Tabs>\n    )\n  },\n  {\n    scheduler(request) {\n      requestAnimationFrame(request)\n    },\n  }\n)\n\nexport default ArrayTabs\n"
  },
  {
    "path": "packages/antd/src/array-tabs/style.ts",
    "content": "import 'antd/lib/tabs/style/index'\nimport 'antd/lib/badge/style/index'\n"
  },
  {
    "path": "packages/antd/src/cascader/index.tsx",
    "content": "import React from 'react'\nimport { connect, mapReadPretty, mapProps } from '@formily/react'\nimport { Cascader as AntdCascader } from 'antd'\nimport { PreviewText } from '../preview-text'\nimport { LoadingOutlined } from '@ant-design/icons'\n\nexport const Cascader = connect(\n  AntdCascader,\n  mapProps(\n    {\n      dataSource: 'options',\n    },\n    (props, field) => {\n      return {\n        ...props,\n        suffixIcon:\n          field?.['loading'] || field?.['validating'] ? (\n            <LoadingOutlined />\n          ) : (\n            props.suffixIcon\n          ),\n      }\n    }\n  ),\n  mapReadPretty(PreviewText.Cascader)\n)\n\nexport default Cascader\n"
  },
  {
    "path": "packages/antd/src/cascader/style.ts",
    "content": "import 'antd/lib/cascader/style/index'\n"
  },
  {
    "path": "packages/antd/src/checkbox/index.tsx",
    "content": "import { connect, mapProps, mapReadPretty } from '@formily/react'\nimport { Checkbox as AntdCheckbox } from 'antd'\nimport { CheckboxProps, CheckboxGroupProps } from 'antd/lib/checkbox'\nimport { PreviewText } from '../preview-text'\n\ntype ComposedCheckbox = React.FC<React.PropsWithChildren<CheckboxProps>> & {\n  Group?: React.FC<React.PropsWithChildren<CheckboxGroupProps>>\n  __ANT_CHECKBOX?: boolean\n}\n\nexport const Checkbox: ComposedCheckbox = connect(\n  AntdCheckbox,\n  mapProps({\n    value: 'checked',\n  })\n)\n\nCheckbox.__ANT_CHECKBOX = true\n\nCheckbox.Group = connect(\n  AntdCheckbox.Group,\n  mapProps({\n    dataSource: 'options',\n  }),\n  mapReadPretty(PreviewText.Select, {\n    mode: 'tags',\n  })\n)\n\nexport default Checkbox\n"
  },
  {
    "path": "packages/antd/src/checkbox/style.ts",
    "content": "import 'antd/lib/checkbox/style/index'\n"
  },
  {
    "path": "packages/antd/src/date-picker/index.tsx",
    "content": "import moment from 'moment'\nimport { connect, mapProps, mapReadPretty } from '@formily/react'\nimport { DatePicker as AntdDatePicker } from 'antd'\nimport {\n  DatePickerProps as AntdDatePickerProps,\n  RangePickerProps,\n} from 'antd/lib/date-picker'\nimport { PreviewText } from '../preview-text'\nimport { formatMomentValue, momentable } from '../__builtins__'\n\ntype DatePickerProps<PickerProps> = Exclude<\n  PickerProps,\n  'value' | 'onChange'\n> & {\n  value: string\n  onChange: (value: string | string[]) => void\n}\n\ntype ComposedDatePicker = React.FC<\n  React.PropsWithChildren<AntdDatePickerProps>\n> & {\n  RangePicker?: React.FC<React.PropsWithChildren<RangePickerProps>>\n}\n\nconst mapDateFormat = function () {\n  const getDefaultFormat = (props: DatePickerProps<AntdDatePickerProps>) => {\n    if (props['picker'] === 'month') {\n      return 'YYYY-MM'\n    } else if (props['picker'] === 'quarter') {\n      return 'YYYY-\\\\QQ'\n    } else if (props['picker'] === 'year') {\n      return 'YYYY'\n    } else if (props['picker'] === 'week') {\n      return 'gggg-wo'\n    }\n    return props['showTime'] ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'\n  }\n  return (props: any) => {\n    const format = props['format'] || getDefaultFormat(props)\n    const onChange = props.onChange\n    return {\n      ...props,\n      format: format,\n      value: momentable(props.value, format === 'gggg-wo' ? 'gggg-ww' : format),\n      onChange: (value: moment.Moment | moment.Moment[]) => {\n        if (onChange) {\n          onChange(formatMomentValue(value, format))\n        }\n      },\n    }\n  }\n}\n\nexport const DatePicker: ComposedDatePicker = connect(\n  AntdDatePicker,\n  mapProps(mapDateFormat()),\n  mapReadPretty(PreviewText.DatePicker)\n)\n\nDatePicker.RangePicker = connect(\n  AntdDatePicker.RangePicker,\n  mapProps(mapDateFormat()),\n  mapReadPretty(PreviewText.DateRangePicker)\n)\n\nexport default DatePicker\n"
  },
  {
    "path": "packages/antd/src/date-picker/style.ts",
    "content": "import 'antd/lib/date-picker/style/index'\n"
  },
  {
    "path": "packages/antd/src/editable/index.tsx",
    "content": "import React, { useLayoutEffect, useRef, useState } from 'react'\nimport { isVoidField, Field } from '@formily/core'\nimport { useField, observer } from '@formily/react'\nimport { Popover } from 'antd'\nimport { EditOutlined, CloseOutlined, MessageOutlined } from '@ant-design/icons'\nimport { BaseItem, IFormItemProps } from '../form-item'\nimport { PopoverProps } from 'antd/lib/popover'\nimport { useClickAway, usePrefixCls } from '../__builtins__'\nimport cls from 'classnames'\n/**\n * 默认Inline展示\n */\n\ntype IPopoverProps = PopoverProps\n\ntype ComposedEditable = React.FC<React.PropsWithChildren<IFormItemProps>> & {\n  Popover?: React.FC<\n    React.PropsWithChildren<IPopoverProps & { title?: React.ReactNode }>\n  >\n}\n\nconst useParentPattern = () => {\n  const field = useField<Field>()\n  return field?.parent?.pattern || field?.form?.pattern\n}\n\nconst useEditable = (): [boolean, (payload: boolean) => void] => {\n  const pattern = useParentPattern()\n  const field = useField<Field>()\n  useLayoutEffect(() => {\n    if (pattern === 'editable') {\n      return field.setPattern('readPretty')\n    }\n  }, [pattern])\n  return [\n    field.pattern === 'editable',\n    (payload: boolean) => {\n      if (pattern !== 'editable') return\n      field.setPattern(payload ? 'editable' : 'readPretty')\n    },\n  ]\n}\n\nconst useFormItemProps = (): IFormItemProps => {\n  const field = useField()\n  if (isVoidField(field)) return {}\n  if (!field) return {}\n  const takeMessage = () => {\n    if (field.selfErrors.length) return field.selfErrors\n    if (field.selfWarnings.length) return field.selfWarnings\n    if (field.selfSuccesses.length) return field.selfSuccesses\n  }\n\n  return {\n    feedbackStatus:\n      field.validateStatus === 'validating' ? 'pending' : field.validateStatus,\n    feedbackText: takeMessage(),\n    extra: field.description,\n  }\n}\n\nexport const Editable: ComposedEditable = observer((props) => {\n  const [editable, setEditable] = useEditable()\n  const pattern = useParentPattern()\n  const itemProps = useFormItemProps()\n  const field = useField<Field>()\n  const basePrefixCls = usePrefixCls()\n  const prefixCls = usePrefixCls('formily-editable')\n  const ref = useRef<boolean>()\n  const innerRef = useRef<HTMLDivElement>()\n  const recover = () => {\n    if (ref.current && !field?.errors?.length) {\n      setEditable(false)\n    }\n  }\n  const renderEditHelper = () => {\n    if (editable) return\n    return (\n      <BaseItem {...props} {...itemProps}>\n        {pattern === 'editable' && (\n          <EditOutlined className={`${prefixCls}-edit-btn`} />\n        )}\n        {pattern !== 'editable' && (\n          <MessageOutlined className={`${prefixCls}-edit-btn`} />\n        )}\n      </BaseItem>\n    )\n  }\n\n  const renderCloseHelper = () => {\n    if (!editable) return\n    return (\n      <BaseItem {...props}>\n        <CloseOutlined className={`${prefixCls}-close-btn`} />\n      </BaseItem>\n    )\n  }\n\n  useClickAway((e) => {\n    const target = e.target as HTMLElement\n    if (target?.closest(`.${basePrefixCls}-select-dropdown`)) return\n    if (target?.closest(`.${basePrefixCls}-picker-dropdown`)) return\n    if (target?.closest(`.${basePrefixCls}-cascader-menus`)) return\n    recover()\n  }, innerRef)\n\n  const onClick = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {\n    const target = e.target as HTMLElement\n    const close = innerRef.current.querySelector(`.${prefixCls}-close-btn`)\n    if (target?.contains(close) || close?.contains(target)) {\n      recover()\n    } else if (!ref.current) {\n      setTimeout(() => {\n        setEditable(true)\n        setTimeout(() => {\n          innerRef.current.querySelector('input')?.focus()\n        })\n      })\n    }\n  }\n\n  ref.current = editable\n\n  return (\n    <div className={prefixCls} ref={innerRef} onClick={onClick}>\n      <div className={`${prefixCls}-content`}>\n        <BaseItem {...props} {...itemProps}>\n          {props.children}\n        </BaseItem>\n        {renderEditHelper()}\n        {renderCloseHelper()}\n      </div>\n    </div>\n  )\n})\n\nEditable.Popover = observer((props) => {\n  const field = useField<Field>()\n  const pattern = useParentPattern()\n  const [visible, setVisible] = useState(false)\n  const prefixCls = usePrefixCls('formily-editable')\n  const closePopover = async () => {\n    try {\n      await field.form.validate(`${field.address}.*`)\n    } finally {\n      const errors = field.form.queryFeedbacks({\n        type: 'error',\n        address: `${field.address}.*`,\n      })\n      if (errors?.length) return\n      setVisible(false)\n    }\n  }\n  const openPopover = () => {\n    setVisible(true)\n  }\n  return (\n    <Popover\n      {...props}\n      title={props.title || field.title}\n      visible={visible}\n      className={cls(prefixCls, props.className)}\n      content={props.children}\n      trigger=\"click\"\n      destroyTooltipOnHide\n      onVisibleChange={(visible) => {\n        if (visible) {\n          openPopover()\n        } else {\n          closePopover()\n        }\n      }}\n    >\n      <div>\n        <BaseItem className={`${prefixCls}-trigger`}>\n          <div className={`${prefixCls}-content`}>\n            <span className={`${prefixCls}-preview`}>\n              {props.title || field.title}\n            </span>\n            {pattern === 'editable' && (\n              <EditOutlined className={`${prefixCls}-edit-btn`} />\n            )}\n            {pattern !== 'editable' && (\n              <MessageOutlined className={`${prefixCls}-edit-btn`} />\n            )}\n          </div>\n        </BaseItem>\n      </div>\n    </Popover>\n  )\n})\n\nexport default Editable\n"
  },
  {
    "path": "packages/antd/src/editable/style.less",
    "content": "@root-entry-name: 'default';\n@import (reference) '~antd/es/style/themes/index.less';\n\n@editable-prefix-cls: ~'@{ant-prefix}-formily-editable';\n\n.@{editable-prefix-cls} {\n  cursor: pointer;\n  display: inline-block !important;\n\n  .@{ant-prefix}-form-text {\n    .@{ant-prefix}-tag {\n      transition: none !important;\n    }\n\n    .@{ant-prefix}-tag:last-child {\n      margin-right: 0 !important;\n    }\n  }\n\n  &-content {\n    display: flex;\n    align-items: center;\n\n    > * {\n      margin-right: 3px;\n      &:last-child {\n        margin-right: 0;\n      }\n    }\n  }\n\n  .@{editable-prefix-cls}-edit-btn,\n  .@{editable-prefix-cls}-close-btn {\n    transition: all 0.25s ease-in-out;\n    color: #aaa;\n    font-size: 12px;\n\n    &:hover {\n      color: @primary-5;\n    }\n  }\n\n  .@{ant-prefix}-form-text {\n    display: flex;\n    align-items: center;\n  }\n\n  .@{editable-prefix-cls}-preview {\n    white-space: nowrap;\n    text-overflow: ellipsis;\n    overflow: hidden;\n    word-break: break-all;\n    max-width: 100px;\n    display: block;\n  }\n}\n"
  },
  {
    "path": "packages/antd/src/editable/style.ts",
    "content": "import 'antd/lib/form/style/index'\nimport 'antd/lib/space/style/index'\nimport 'antd/lib/popover/style/index'\nimport './style.less'\n"
  },
  {
    "path": "packages/antd/src/form/index.tsx",
    "content": "import React from 'react'\nimport { Form as FormType, ObjectField, IFormFeedback } from '@formily/core'\nimport { useParentForm, FormProvider, JSXComponent } from '@formily/react'\nimport { FormLayout, IFormLayoutProps } from '../form-layout'\nimport { PreviewText } from '../preview-text'\nexport interface FormProps extends IFormLayoutProps {\n  form?: FormType\n  component?: JSXComponent\n  onAutoSubmit?: (values: any) => any\n  onAutoSubmitFailed?: (feedbacks: IFormFeedback[]) => void\n  previewTextPlaceholder?: React.ReactNode\n}\n\nexport const Form: React.FC<React.PropsWithChildren<FormProps>> = ({\n  form,\n  component = 'form',\n  onAutoSubmit,\n  onAutoSubmitFailed,\n  previewTextPlaceholder,\n  ...props\n}) => {\n  const top = useParentForm()\n  const renderContent = (form: FormType | ObjectField) => (\n    <PreviewText.Placeholder value={previewTextPlaceholder}>\n      <FormLayout {...props}>\n        {React.createElement(\n          component,\n          {\n            onSubmit(e: React.FormEvent) {\n              e?.stopPropagation?.()\n              e?.preventDefault?.()\n              form.submit(onAutoSubmit).catch(onAutoSubmitFailed)\n            },\n          },\n          props.children\n        )}\n      </FormLayout>\n    </PreviewText.Placeholder>\n  )\n  if (form)\n    return <FormProvider form={form}>{renderContent(form)}</FormProvider>\n  if (!top) throw new Error('must pass form instance by createForm')\n  return renderContent(top)\n}\n\nexport default Form\n"
  },
  {
    "path": "packages/antd/src/form/style.less",
    "content": ""
  },
  {
    "path": "packages/antd/src/form/style.ts",
    "content": "// @ts-ignore\n"
  },
  {
    "path": "packages/antd/src/form-button-group/index.tsx",
    "content": "/**\n * 1. FormItem网格布局\n * 2. 居中，居右，居左布局\n * 3. 行内布局\n * 4. 吸底布局\n */\nimport React, { useRef, useLayoutEffect, useState } from 'react'\nimport { ReactFC } from '@formily/react'\nimport { Space } from 'antd'\nimport { SpaceProps } from 'antd/lib/space'\nimport { BaseItem, IFormItemProps } from '../form-item'\nimport { usePrefixCls } from '../__builtins__'\nimport StickyBox from 'react-sticky-box'\nimport cls from 'classnames'\ninterface IStickyProps extends React.ComponentProps<typeof StickyBox> {\n  align?: React.CSSProperties['textAlign']\n}\n\ntype IFormButtonGroupProps = Omit<SpaceProps, 'align' | 'size'> & {\n  align?: React.CSSProperties['textAlign']\n  gutter?: number\n}\n\ntype ComposedButtonGroup = ReactFC<IFormButtonGroupProps> & {\n  Sticky: ReactFC<React.PropsWithChildren<IStickyProps>>\n  FormItem: ReactFC<\n    IFormItemProps & {\n      gutter?: number\n    }\n  >\n}\n\nfunction getInheritedBackgroundColor(el: HTMLElement) {\n  // get default style for current browser\n  const defaultStyle = getDefaultBackground() // typically \"rgba(0, 0, 0, 0)\"\n\n  // get computed color for el\n  const backgroundColor = window.getComputedStyle(el).backgroundColor\n\n  // if we got a real value, return it\n  if (backgroundColor != defaultStyle) return backgroundColor\n\n  // if we've reached the top parent el without getting an explicit color, return default\n  if (!el.parentElement) return defaultStyle\n\n  // otherwise, recurse and try again on parent element\n  return getInheritedBackgroundColor(el.parentElement)\n}\n\nfunction getDefaultBackground() {\n  // have to add to the document in order to use getComputedStyle\n  let div = document.createElement('div')\n  document.head.appendChild(div)\n  let bg = window.getComputedStyle(div).backgroundColor\n  document.head.removeChild(div)\n  return bg\n}\n\nexport const FormButtonGroup: ComposedButtonGroup = ({\n  align = 'left',\n  gutter,\n  ...props\n}) => {\n  const prefixCls = usePrefixCls('formily-button-group')\n  return (\n    <Space\n      {...props}\n      size={gutter}\n      className={cls(prefixCls, props.className)}\n      style={{\n        ...props.style,\n        justifyContent:\n          align === 'left'\n            ? 'flex-start'\n            : align === 'right'\n            ? 'flex-end'\n            : 'center',\n        display: 'flex',\n      }}\n    >\n      {props.children}\n    </Space>\n  )\n}\n\nFormButtonGroup.FormItem = ({ gutter, ...props }) => {\n  return (\n    <BaseItem\n      {...props}\n      label=\" \"\n      style={{\n        margin: 0,\n        padding: 0,\n        ...props.style,\n        width: '100%',\n      }}\n      colon={false}\n    >\n      {props.children?.['length'] ? (\n        <Space size={gutter}>{props.children}</Space>\n      ) : (\n        props.children\n      )}\n    </BaseItem>\n  )\n}\n\nFormButtonGroup.Sticky = ({ align = 'left', ...props }) => {\n  const ref = useRef()\n  const [color, setColor] = useState('transparent')\n  const prefixCls = usePrefixCls('formily-button-group')\n\n  useLayoutEffect(() => {\n    if (ref.current) {\n      const computed = getInheritedBackgroundColor(ref.current)\n      if (computed !== color) {\n        setColor(computed)\n      }\n    }\n  })\n  return (\n    <StickyBox\n      {...props}\n      className={cls(`${prefixCls}-sticky`, props.className)}\n      style={{\n        backgroundColor: color,\n        ...props.style,\n      }}\n      bottom\n    >\n      <div\n        ref={ref}\n        className={`${prefixCls}-sticky-inner`}\n        style={{\n          ...props.style,\n          justifyContent:\n            align === 'left'\n              ? 'flex-start'\n              : align === 'right'\n              ? 'flex-end'\n              : 'center',\n        }}\n      >\n        {props.children}\n      </div>\n    </StickyBox>\n  )\n}\n\nexport default FormButtonGroup\n"
  },
  {
    "path": "packages/antd/src/form-button-group/style.less",
    "content": "@root-entry-name: 'default';\n@import (reference) '~antd/es/style/themes/index.less';\n\n@btn-group-prefix-cls: ~'@{ant-prefix}-formily-button-group';\n\n.@{btn-group-prefix-cls}-sticky {\n  padding: 10px 0;\n  border-top: 1px solid @border-color-split;\n  z-index: 999;\n  &-inner {\n    display: flex;\n    .@{ant-prefix}-formily-item {\n      flex: 2;\n    }\n  }\n}\n"
  },
  {
    "path": "packages/antd/src/form-button-group/style.ts",
    "content": "import 'antd/lib/form/style/index'\nimport './style.less'\n"
  },
  {
    "path": "packages/antd/src/form-collapse/index.tsx",
    "content": "import React, { Fragment, useMemo } from 'react'\nimport { Collapse, Badge } from 'antd'\nimport { model, markRaw } from '@formily/reactive'\nimport { CollapseProps, CollapsePanelProps } from 'antd/lib/collapse'\nimport {\n  useField,\n  observer,\n  useFieldSchema,\n  RecursionField,\n} from '@formily/react'\nimport { Schema, SchemaKey } from '@formily/json-schema'\nimport cls from 'classnames'\nimport { usePrefixCls } from '../__builtins__'\nimport { toArr } from '@formily/shared'\n\ntype ActiveKeys = string | number | Array<string | number>\n\ntype ActiveKey = string | number\nexport interface IFormCollapse {\n  activeKeys: ActiveKeys\n  hasActiveKey(key: ActiveKey): boolean\n  setActiveKeys(key: ActiveKeys): void\n  addActiveKey(key: ActiveKey): void\n  removeActiveKey(key: ActiveKey): void\n  toggleActiveKey(key: ActiveKey): void\n}\n\nexport interface IFormCollapseProps extends CollapseProps {\n  formCollapse?: IFormCollapse\n}\n\ntype ComposedFormCollapse = React.FC<\n  React.PropsWithChildren<IFormCollapseProps>\n> & {\n  CollapsePanel?: React.FC<React.PropsWithChildren<CollapsePanelProps>>\n  createFormCollapse?: (defaultActiveKeys?: ActiveKeys) => IFormCollapse\n}\n\nconst usePanels = () => {\n  const collapseField = useField()\n  const schema = useFieldSchema()\n  const panels: { name: SchemaKey; props: any; schema: Schema }[] = []\n  schema.mapProperties((schema, name) => {\n    const field = collapseField.query(collapseField.address.concat(name)).take()\n    if (field?.display === 'none' || field?.display === 'hidden') return\n    if (schema['x-component']?.indexOf('CollapsePanel') > -1) {\n      const componentProps = field?.componentProps\n      panels.push({\n        name,\n        props: {\n          ...componentProps,\n          key: componentProps?.key || name,\n        },\n        schema,\n      })\n    }\n  })\n  return panels\n}\n\nconst createFormCollapse = (defaultActiveKeys?: ActiveKeys) => {\n  const formCollapse = model({\n    activeKeys: defaultActiveKeys,\n    setActiveKeys(keys: ActiveKeys) {\n      formCollapse.activeKeys = keys\n    },\n    hasActiveKey(key: ActiveKey) {\n      if (Array.isArray(formCollapse.activeKeys)) {\n        if (formCollapse.activeKeys.includes(key)) {\n          return true\n        }\n      } else if (formCollapse.activeKeys == key) {\n        return true\n      }\n      return false\n    },\n    addActiveKey(key: ActiveKey) {\n      if (formCollapse.hasActiveKey(key)) return\n      formCollapse.activeKeys = toArr(formCollapse.activeKeys).concat(key)\n    },\n    removeActiveKey(key: ActiveKey) {\n      if (Array.isArray(formCollapse.activeKeys)) {\n        formCollapse.activeKeys = formCollapse.activeKeys.filter(\n          (item) => item != key\n        )\n      } else {\n        formCollapse.activeKeys = ''\n      }\n    },\n    toggleActiveKey(key: ActiveKey) {\n      if (formCollapse.hasActiveKey(key)) {\n        formCollapse.removeActiveKey(key)\n      } else {\n        formCollapse.addActiveKey(key)\n      }\n    },\n  })\n  return markRaw(formCollapse)\n}\n\nexport const FormCollapse: ComposedFormCollapse = observer(\n  ({ formCollapse, ...props }) => {\n    const field = useField()\n    const panels = usePanels()\n    const prefixCls = usePrefixCls('formily-collapse', props)\n    const _formCollapse = useMemo(() => {\n      return formCollapse\n        ? formCollapse\n        : createFormCollapse(props.defaultActiveKey)\n    }, [])\n\n    const takeActiveKeys = () => {\n      if (props.activeKey) return props.activeKey\n      if (_formCollapse?.activeKeys) return _formCollapse?.activeKeys\n      if (props.accordion) return panels[0]?.name\n      return panels.map((item) => item.name)\n    }\n\n    const badgedHeader = (key: SchemaKey, props: any) => {\n      const errors = field.form.queryFeedbacks({\n        type: 'error',\n        address: `${field.address.concat(key)}.*`,\n      })\n      if (errors.length) {\n        return (\n          <Badge size=\"small\" className=\"errors-badge\" count={errors.length}>\n            {props.header}\n          </Badge>\n        )\n      }\n      return props.header\n    }\n    return (\n      <Collapse\n        {...props}\n        className={cls(prefixCls, props.className)}\n        activeKey={takeActiveKeys()}\n        onChange={(key) => {\n          props?.onChange?.(key)\n          _formCollapse?.setActiveKeys?.(key)\n        }}\n      >\n        {panels.map(({ props, schema, name }, index) => (\n          <Collapse.Panel\n            key={index}\n            {...props}\n            header={badgedHeader(name, props)}\n            forceRender\n          >\n            <RecursionField schema={schema} name={name} />\n          </Collapse.Panel>\n        ))}\n      </Collapse>\n    )\n  }\n)\n\nconst CollapsePanel: React.FC<React.PropsWithChildren<CollapsePanelProps>> = ({\n  children,\n}) => {\n  return <Fragment>{children}</Fragment>\n}\n\nFormCollapse.CollapsePanel = CollapsePanel\nFormCollapse.createFormCollapse = createFormCollapse\n\nexport default FormCollapse\n"
  },
  {
    "path": "packages/antd/src/form-collapse/style.ts",
    "content": "import 'antd/lib/collapse/style/index'\nimport 'antd/lib/badge/style/index'\n"
  },
  {
    "path": "packages/antd/src/form-dialog/index.tsx",
    "content": "import React, { Fragment, useRef, useLayoutEffect, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport { createForm, IFormProps, Form } from '@formily/core'\nimport { toJS } from '@formily/reactive'\nimport { FormProvider, Observer, observer, ReactFC } from '@formily/react'\nimport {\n  isNum,\n  isStr,\n  isBool,\n  isFn,\n  applyMiddleware,\n  IMiddleware,\n} from '@formily/shared'\nimport { Modal, ModalProps } from 'antd'\nimport {\n  usePrefixCls,\n  loading,\n  createPortalProvider,\n  createPortalRoot,\n} from '../__builtins__'\n\ntype FormDialogRenderer =\n  | React.ReactElement\n  | ((form: Form) => React.ReactElement)\n\ntype ModalTitle = string | number | React.ReactElement\n\nconst isModalTitle = (props: any): props is ModalTitle => {\n  return (\n    isNum(props) || isStr(props) || isBool(props) || React.isValidElement(props)\n  )\n}\n\nconst getModelProps = (props: any): IModalProps => {\n  if (isModalTitle(props)) {\n    return {\n      title: props,\n    }\n  } else {\n    return props\n  }\n}\n\nexport interface IFormDialog {\n  forOpen(middleware: IMiddleware<IFormProps>): IFormDialog\n  forConfirm(middleware: IMiddleware<Form>): IFormDialog\n  forCancel(middleware: IMiddleware<Form>): IFormDialog\n  open(props?: IFormProps): Promise<any>\n  close(): void\n}\n\nexport interface IModalProps extends ModalProps {\n  onOk?: (event: React.MouseEvent<HTMLElement>) => void | boolean\n  onCancel?: (event: React.MouseEvent<HTMLElement>) => void | boolean\n  loadingText?: React.ReactNode\n}\n\nexport function FormDialog(\n  title: IModalProps,\n  id: string,\n  renderer: FormDialogRenderer\n): IFormDialog\nexport function FormDialog(\n  title: IModalProps,\n  renderer: FormDialogRenderer\n): IFormDialog\nexport function FormDialog(\n  title: ModalTitle,\n  id: string,\n  renderer: FormDialogRenderer\n): IFormDialog\nexport function FormDialog(\n  title: ModalTitle,\n  renderer: FormDialogRenderer\n): IFormDialog\nexport function FormDialog(title: any, id: any, renderer?: any): IFormDialog {\n  if (isFn(id) || React.isValidElement(id)) {\n    renderer = id\n    id = 'form-dialog'\n  }\n  const env = {\n    host: document.createElement('div'),\n    form: null,\n    promise: null,\n    openMiddlewares: [],\n    confirmMiddlewares: [],\n    cancelMiddlewares: [],\n  }\n  const root = createPortalRoot(env.host, id)\n  const props = getModelProps(title)\n  const modal = {\n    ...props,\n    afterClose: () => {\n      props?.afterClose?.()\n      root.unmount()\n    },\n  }\n  const DialogContent = observer(() => {\n    return <Fragment>{isFn(renderer) ? renderer(env.form) : renderer}</Fragment>\n  })\n  const renderDialog = (\n    visible = true,\n    resolve?: () => any,\n    reject?: () => any\n  ) => {\n    return (\n      <Observer>\n        {() => (\n          <Modal\n            {...modal}\n            visible={visible}\n            confirmLoading={env.form.submitting}\n            onCancel={(e) => {\n              if (modal?.onCancel?.(e) !== false) {\n                reject()\n              }\n            }}\n            onOk={async (e) => {\n              if (modal?.onOk?.(e) !== false) {\n                resolve()\n              }\n            }}\n          >\n            <FormProvider form={env.form}>\n              <DialogContent />\n            </FormProvider>\n          </Modal>\n        )}\n      </Observer>\n    )\n  }\n\n  document.body.appendChild(env.host)\n  const formDialog = {\n    forOpen: (middleware: IMiddleware<IFormProps>) => {\n      if (isFn(middleware)) {\n        env.openMiddlewares.push(middleware)\n      }\n      return formDialog\n    },\n    forConfirm: (middleware: IMiddleware<Form>) => {\n      if (isFn(middleware)) {\n        env.confirmMiddlewares.push(middleware)\n      }\n      return formDialog\n    },\n    forCancel: (middleware: IMiddleware<Form>) => {\n      if (isFn(middleware)) {\n        env.cancelMiddlewares.push(middleware)\n      }\n      return formDialog\n    },\n    open: async (props: IFormProps) => {\n      if (env.promise) return env.promise\n      env.promise = new Promise(async (resolve, reject) => {\n        try {\n          props = await loading(modal.loadingText, () =>\n            applyMiddleware(props, env.openMiddlewares)\n          )\n          env.form = env.form || createForm(props)\n        } catch (e) {\n          reject(e)\n        }\n        root.render(() =>\n          renderDialog(\n            true,\n            () => {\n              env.form\n                .submit(async () => {\n                  await applyMiddleware(env.form, env.confirmMiddlewares)\n                  resolve(toJS(env.form.values))\n                  formDialog.close()\n                })\n                .catch(() => {})\n            },\n            async () => {\n              await loading(modal.loadingText, () =>\n                applyMiddleware(env.form, env.cancelMiddlewares)\n              )\n              formDialog.close()\n            }\n          )\n        )\n      })\n      return env.promise\n    },\n    close: () => {\n      if (!env.host) return\n      root.render(() => renderDialog(false))\n    },\n  }\n  return formDialog\n}\n\nconst DialogFooter: ReactFC = (props) => {\n  const ref = useRef<HTMLDivElement>()\n  const [footer, setFooter] = useState<HTMLDivElement>()\n  const footerRef = useRef<HTMLDivElement>()\n  const prefixCls = usePrefixCls('modal')\n  useLayoutEffect(() => {\n    const content = ref.current?.closest(`.${prefixCls}-content`)\n    if (content) {\n      if (!footerRef.current) {\n        footerRef.current = content.querySelector(`.${prefixCls}-footer`)\n        if (!footerRef.current) {\n          footerRef.current = document.createElement('div')\n          footerRef.current.classList.add(`${prefixCls}-footer`)\n          content.appendChild(footerRef.current)\n        }\n      }\n      setFooter(footerRef.current)\n    }\n  })\n\n  footerRef.current = footer\n\n  return (\n    <div ref={ref} style={{ display: 'none' }}>\n      {footer && createPortal(props.children, footer)}\n    </div>\n  )\n}\n\nFormDialog.Footer = DialogFooter\n\nFormDialog.Portal = createPortalProvider('form-dialog')\n\nexport default FormDialog\n"
  },
  {
    "path": "packages/antd/src/form-dialog/style.ts",
    "content": "import 'antd/lib/modal/style/index'\n"
  },
  {
    "path": "packages/antd/src/form-drawer/index.tsx",
    "content": "import React, { Fragment, useLayoutEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport {\n  createForm,\n  IFormProps,\n  Form,\n  onFormSubmitSuccess,\n} from '@formily/core'\nimport { toJS } from '@formily/reactive'\nimport { FormProvider, observer, ReactFC } from '@formily/react'\nimport {\n  isNum,\n  isStr,\n  isBool,\n  isFn,\n  applyMiddleware,\n  IMiddleware,\n} from '@formily/shared'\nimport { Drawer, DrawerProps } from 'antd'\nimport {\n  usePrefixCls,\n  createPortalProvider,\n  createPortalRoot,\n  loading,\n} from '../__builtins__'\n\ntype FormDrawerRenderer =\n  | React.ReactElement\n  | ((form: Form) => React.ReactElement)\n\ntype DrawerTitle = string | number | React.ReactElement\n\ntype EventType =\n  | React.KeyboardEvent<HTMLDivElement>\n  | React.MouseEvent<HTMLDivElement | HTMLButtonElement>\n\nconst isDrawerTitle = (props: any): props is DrawerTitle => {\n  return (\n    isNum(props) || isStr(props) || isBool(props) || React.isValidElement(props)\n  )\n}\n\nconst getDrawerProps = (props: any): IDrawerProps => {\n  if (isDrawerTitle(props)) {\n    return {\n      title: props,\n    }\n  } else {\n    return props\n  }\n}\n\nexport interface IFormDrawer {\n  forOpen(middleware: IMiddleware<IFormProps>): IFormDrawer\n  open(props?: IFormProps): Promise<any>\n  close(): void\n}\n\nexport interface IDrawerProps extends DrawerProps {\n  onClose?: (e: EventType) => void | boolean\n  loadingText?: React.ReactNode\n}\n\nexport function FormDrawer(\n  title: IDrawerProps,\n  id: string,\n  renderer: FormDrawerRenderer\n): IFormDrawer\nexport function FormDrawer(\n  title: IDrawerProps,\n  id: FormDrawerRenderer\n): IFormDrawer\nexport function FormDrawer(\n  title: DrawerTitle,\n  id: string,\n  renderer: FormDrawerRenderer\n): IFormDrawer\nexport function FormDrawer(\n  title: DrawerTitle,\n  id: FormDrawerRenderer\n): IFormDrawer\nexport function FormDrawer(title: any, id: any, renderer?: any): IFormDrawer {\n  if (isFn(id) || React.isValidElement(id)) {\n    renderer = id\n    id = 'form-drawer'\n  }\n  const env = {\n    host: document.createElement('div'),\n    openMiddlewares: [],\n    form: null,\n    promise: null,\n  }\n  const root = createPortalRoot(env.host, id)\n  const props = getDrawerProps(title)\n  const drawer = {\n    width: '40%',\n    ...props,\n    onClose: (e: any) => {\n      if (props?.onClose?.(e) !== false) {\n        formDrawer.close()\n      }\n    },\n    afterVisibleChange: (visible: boolean) => {\n      props?.afterVisibleChange?.(visible)\n      if (visible) return\n      root.unmount()\n    },\n  }\n  const DrawerContent = observer(() => {\n    return <Fragment>{isFn(renderer) ? renderer(env.form) : renderer}</Fragment>\n  })\n  const renderDrawer = (visible = true) => {\n    return (\n      <Drawer {...drawer} visible={visible}>\n        <FormProvider form={env.form}>\n          <DrawerContent />\n        </FormProvider>\n      </Drawer>\n    )\n  }\n\n  document.body.appendChild(env.host)\n  const formDrawer = {\n    forOpen: (middleware: IMiddleware<IFormProps>) => {\n      if (isFn(middleware)) {\n        env.openMiddlewares.push(middleware)\n      }\n      return formDrawer\n    },\n    open: (props: IFormProps) => {\n      if (env.promise) return env.promise\n      env.promise = new Promise(async (resolve, reject) => {\n        try {\n          props = await loading(drawer.loadingText, () =>\n            applyMiddleware(props, env.openMiddlewares)\n          )\n          env.form =\n            env.form ||\n            createForm({\n              ...props,\n              effects(form) {\n                onFormSubmitSuccess(() => {\n                  resolve(toJS(form.values))\n                  formDrawer.close()\n                })\n                props?.effects?.(form)\n              },\n            })\n        } catch (e) {\n          reject(e)\n        }\n        root.render(() => renderDrawer(false))\n        setTimeout(() => {\n          root.render(() => renderDrawer(true))\n        }, 16)\n      })\n      return env.promise\n    },\n    close: () => {\n      if (!env.host) return\n      root.render(() => renderDrawer(false))\n    },\n  }\n  return formDrawer\n}\n\nconst DrawerExtra: ReactFC = (props) => {\n  const ref = useRef<HTMLDivElement>()\n  const [extra, setExtra] = useState<HTMLDivElement>()\n  const extraRef = useRef<HTMLDivElement>()\n  const prefixCls = usePrefixCls('drawer')\n  useLayoutEffect(() => {\n    const content = ref.current\n      ?.closest(`.${prefixCls}-wrapper-body`)\n      ?.querySelector(`.${prefixCls}-header`)\n    if (content) {\n      if (!extraRef.current) {\n        extraRef.current = content.querySelector(`.${prefixCls}-extra`)\n        if (!extraRef.current) {\n          extraRef.current = document.createElement('div')\n          extraRef.current.classList.add(`${prefixCls}-extra`)\n          content.appendChild(extraRef.current)\n        }\n      }\n      setExtra(extraRef.current)\n    }\n  })\n\n  extraRef.current = extra\n\n  return (\n    <div ref={ref} style={{ display: 'none' }}>\n      {extra && createPortal(props.children, extra)}\n    </div>\n  )\n}\n\nconst DrawerFooter: ReactFC = (props) => {\n  const ref = useRef<HTMLDivElement>()\n  const [footer, setFooter] = useState<HTMLDivElement>()\n  const footerRef = useRef<HTMLDivElement>()\n  const prefixCls = usePrefixCls('drawer')\n  useLayoutEffect(() => {\n    const content = ref.current?.closest(`.${prefixCls}-wrapper-body`)\n    if (content) {\n      if (!footerRef.current) {\n        footerRef.current = content.querySelector(`.${prefixCls}-footer`)\n        if (!footerRef.current) {\n          footerRef.current = document.createElement('div')\n          footerRef.current.classList.add(`${prefixCls}-footer`)\n          content.appendChild(footerRef.current)\n        }\n      }\n      setFooter(footerRef.current)\n    }\n  })\n\n  footerRef.current = footer\n\n  return (\n    <div ref={ref} style={{ display: 'none' }}>\n      {footer && createPortal(props.children, footer)}\n    </div>\n  )\n}\n\nFormDrawer.Extra = DrawerExtra\n\nFormDrawer.Footer = DrawerFooter\n\nFormDrawer.Portal = createPortalProvider('form-drawer')\n\nexport default FormDrawer\n"
  },
  {
    "path": "packages/antd/src/form-drawer/style.ts",
    "content": "import 'antd/lib/drawer/style/index'\n"
  },
  {
    "path": "packages/antd/src/form-grid/index.tsx",
    "content": "import React, { useLayoutEffect, useRef, useMemo, useContext } from 'react'\nimport { markRaw } from '@formily/reactive'\nimport { observer } from '@formily/react'\nimport { Grid, IGridOptions } from '@formily/grid'\nimport { usePrefixCls, pickDataProps } from '../__builtins__'\nimport { useFormLayout } from '../form-layout'\nimport cls from 'classnames'\n\nconst FormGridContext = React.createContext<Grid<HTMLElement>>(null)\n\nexport interface IFormGridProps extends IGridOptions {\n  grid?: Grid<HTMLElement>\n  prefixCls?: string\n  className?: string\n  style?: React.CSSProperties\n}\n\nexport interface IGridColumnProps {\n  gridSpan?: number\n  style?: React.CSSProperties\n  className?: string\n}\n\ntype ComposedFormGrid = React.FC<React.PropsWithChildren<IFormGridProps>> & {\n  GridColumn: React.FC<React.PropsWithChildren<IGridColumnProps>>\n  useFormGrid: () => Grid<HTMLElement>\n  createFormGrid: (props: IFormGridProps) => Grid<HTMLElement>\n  /**\n   * @deprecated\n   */\n  useGridSpan: (gridSpan: number) => number\n  /**\n   * @deprecated\n   */\n  useGridColumn: (gridSpan: number) => number\n}\n\nexport const createFormGrid = (props: IFormGridProps) => {\n  return markRaw(new Grid(props))\n}\n\nexport const useFormGrid = () => useContext(FormGridContext)\n\n/**\n * @deprecated\n */\nexport const useGridSpan = (gridSpan = 1) => {\n  return gridSpan\n}\n\n/**\n * @deprecated\n */\nexport const useGridColumn = (gridSpan = 1) => {\n  return gridSpan\n}\n\nexport const FormGrid: ComposedFormGrid = observer(\n  ({\n    children,\n    className,\n    style,\n    ...props\n  }: React.PropsWithChildren<IFormGridProps>) => {\n    const layout = useFormLayout()\n    const options = {\n      columnGap: layout?.gridColumnGap ?? 8,\n      rowGap: layout?.gridRowGap ?? 4,\n      ...props,\n    }\n    const grid = useMemo(\n      () => markRaw(options?.grid ? options.grid : new Grid(options)),\n      [Grid.id(options)]\n    )\n    const ref = useRef<HTMLDivElement>()\n    const prefixCls = usePrefixCls('formily-grid', props)\n    const dataProps = pickDataProps(props)\n    useLayoutEffect(() => {\n      return grid.connect(ref.current)\n    }, [grid])\n    return (\n      <FormGridContext.Provider value={grid}>\n        <div\n          {...dataProps}\n          className={cls(`${prefixCls}-layout`, className)}\n          style={{\n            ...style,\n            gridTemplateColumns: grid.templateColumns,\n            gap: grid.gap,\n          }}\n          ref={ref}\n        >\n          {children}\n        </div>\n      </FormGridContext.Provider>\n    )\n  },\n  {\n    forwardRef: true,\n  }\n) as any\n\nexport const GridColumn: React.FC<React.PropsWithChildren<IGridColumnProps>> =\n  observer(({ gridSpan = 1, children, ...props }) => {\n    return (\n      <div {...props} style={props.style} data-grid-span={gridSpan}>\n        {children}\n      </div>\n    )\n  })\n\nFormGrid.createFormGrid = createFormGrid\nFormGrid.useGridSpan = useGridSpan\nFormGrid.useGridColumn = useGridColumn\nFormGrid.useFormGrid = useFormGrid\nFormGrid.GridColumn = GridColumn\n\nexport default FormGrid\n"
  },
  {
    "path": "packages/antd/src/form-grid/style.less",
    "content": "@root-entry-name: 'default';\n@import (reference) '~antd/es/style/themes/index.less';\n\n@form-grid-prefix-cls: ~'@{ant-prefix}-formily-grid';\n\n.@{form-grid-prefix-cls}-layout {\n  display: grid;\n}\n"
  },
  {
    "path": "packages/antd/src/form-grid/style.ts",
    "content": "import './style.less'\n"
  },
  {
    "path": "packages/antd/src/form-item/animation.less",
    "content": "@-webkit-keyframes antShowHelpIn {\n  0% {\n    -webkit-transform: translateY(-5px);\n    transform: translateY(-5px);\n    opacity: 0;\n  }\n\n  to {\n    -webkit-transform: translateY(0);\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n\n.@{form-item-cls}-help-appear,\n.@{form-item-cls}-help-enter {\n  -webkit-animation-duration: 0.3s;\n  animation-duration: 0.3s;\n  -webkit-animation-fill-mode: both;\n  animation-fill-mode: both;\n  -webkit-animation-play-state: paused;\n  animation-play-state: paused;\n}\n\n.@{form-item-cls}-help-appear.@{form-item-cls}-help-appear-active,\n.@{form-item-cls}-help-enter.@{form-item-cls}-help-enter-active {\n  -webkit-animation-name: antShowHelpIn;\n  animation-name: antShowHelpIn;\n  -webkit-animation-play-state: running;\n  animation-play-state: running;\n}\n\n.@{form-item-cls}-help-appear,\n.@{form-item-cls}-help-enter {\n  opacity: 0;\n}\n\n.@{form-item-cls}-help-appear,\n.@{form-item-cls}-help-enter {\n  -webkit-animation-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);\n  animation-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);\n}\n\n@keyframes antShowHelpIn {\n  0% {\n    -webkit-transform: translateY(-5px);\n    transform: translateY(-5px);\n    opacity: 0;\n  }\n\n  to {\n    -webkit-transform: translateY(0);\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n\n@-webkit-keyframes antShowHelpOut {\n  to {\n    -webkit-transform: translateY(-5px);\n    transform: translateY(-5px);\n    opacity: 0;\n  }\n}\n\n@keyframes antShowHelpOut {\n  to {\n    -webkit-transform: translateY(-5px);\n    transform: translateY(-5px);\n    opacity: 0;\n  }\n}\n"
  },
  {
    "path": "packages/antd/src/form-item/grid.less",
    "content": ".@{form-item-cls} {\n  .@{form-item-cls}-item-col-24 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 100%;\n    flex: 0 0 100%;\n    max-width: 100%;\n  }\n\n  .@{form-item-cls}-item-col-23 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 95.83333333%;\n    flex: 0 0 95.83333333%;\n    max-width: 95.83333333%;\n  }\n\n  .@{form-item-cls}-item-col-22 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 91.66666667%;\n    flex: 0 0 91.66666667%;\n    max-width: 91.66666667%;\n  }\n\n  .@{form-item-cls}-item-col-21 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 87.5%;\n    flex: 0 0 87.5%;\n    max-width: 87.5%;\n  }\n\n  .@{form-item-cls}-item-col-20 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 83.33333333%;\n    flex: 0 0 83.33333333%;\n    max-width: 83.33333333%;\n  }\n\n  .@{form-item-cls}-item-col-19 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 79.16666667%;\n    flex: 0 0 79.16666667%;\n    max-width: 79.16666667%;\n  }\n\n  .@{form-item-cls}-item-col-18 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 75%;\n    flex: 0 0 75%;\n    max-width: 75%;\n  }\n\n  .@{form-item-cls}-item-col-17 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 70.83333333%;\n    flex: 0 0 70.83333333%;\n    max-width: 70.83333333%;\n  }\n\n  .@{form-item-cls}-item-col-16 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 66.66666667%;\n    flex: 0 0 66.66666667%;\n    max-width: 66.66666667%;\n  }\n\n  .@{form-item-cls}-item-col-15 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 62.5%;\n    flex: 0 0 62.5%;\n    max-width: 62.5%;\n  }\n\n  .@{form-item-cls}-item-col-14 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 58.33333333%;\n    flex: 0 0 58.33333333%;\n    max-width: 58.33333333%;\n  }\n\n  .@{form-item-cls}-item-col-13 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 54.16666667%;\n    flex: 0 0 54.16666667%;\n    max-width: 54.16666667%;\n  }\n\n  .@{form-item-cls}-item-col-12 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 50%;\n    flex: 0 0 50%;\n    max-width: 50%;\n  }\n\n  .@{form-item-cls}-item-col-11 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 45.83333333%;\n    flex: 0 0 45.83333333%;\n    max-width: 45.83333333%;\n  }\n\n  .@{form-item-cls}-item-col-10 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 41.66666667%;\n    flex: 0 0 41.66666667%;\n    max-width: 41.66666667%;\n  }\n\n  .@{form-item-cls}-item-col-9 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 37.5%;\n    flex: 0 0 37.5%;\n    max-width: 37.5%;\n  }\n\n  .@{form-item-cls}-item-col-8 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 33.33333333%;\n    flex: 0 0 33.33333333%;\n    max-width: 33.33333333%;\n  }\n\n  .@{form-item-cls}-item-col-7 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 29.16666667%;\n    flex: 0 0 29.16666667%;\n    max-width: 29.16666667%;\n  }\n\n  .@{form-item-cls}-item-col-6 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 25%;\n    flex: 0 0 25%;\n    max-width: 25%;\n  }\n\n  .@{form-item-cls}-item-col-5 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 20.83333333%;\n    flex: 0 0 20.83333333%;\n    max-width: 20.83333333%;\n  }\n\n  .@{form-item-cls}-item-col-4 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 16.66666667%;\n    flex: 0 0 16.66666667%;\n    max-width: 16.66666667%;\n  }\n\n  .@{form-item-cls}-item-col-3 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 12.5%;\n    flex: 0 0 12.5%;\n    max-width: 12.5%;\n  }\n\n  .@{form-item-cls}-item-col-2 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 8.33333333%;\n    flex: 0 0 8.33333333%;\n    max-width: 8.33333333%;\n  }\n\n  .@{form-item-cls}-item-col-1 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 4.16666667%;\n    flex: 0 0 4.16666667%;\n    max-width: 4.16666667%;\n  }\n\n  .@{form-item-cls}-item-col-0 {\n    display: none;\n  }\n}\n"
  },
  {
    "path": "packages/antd/src/form-item/index.tsx",
    "content": "import React, { useEffect, useRef, useContext, useState } from 'react'\nimport cls from 'classnames'\nimport { usePrefixCls, pickDataProps } from '../__builtins__'\nimport { isVoidField } from '@formily/core'\nimport { connect, mapProps } from '@formily/react'\nimport { useFormLayout, FormLayoutShallowContext } from '../form-layout'\nimport { isElement } from 'react-is'\nimport { Tooltip, Popover, ConfigProvider } from 'antd'\nimport {\n  QuestionCircleOutlined,\n  CloseCircleOutlined,\n  CheckCircleOutlined,\n  ExclamationCircleOutlined,\n} from '@ant-design/icons'\n\nexport interface IFormItemProps {\n  className?: string\n  style?: React.CSSProperties\n  prefixCls?: string\n  label?: React.ReactNode\n  colon?: boolean\n  tooltip?: React.ReactNode | React.ComponentProps<typeof Tooltip>\n  tooltipIcon?: React.ReactNode\n  layout?: 'vertical' | 'horizontal' | 'inline'\n  tooltipLayout?: 'icon' | 'text'\n  labelStyle?: React.CSSProperties\n  labelAlign?: 'left' | 'right'\n  labelFor?: string\n  labelWrap?: boolean\n  labelWidth?: number | string\n  wrapperWidth?: number | string\n  labelCol?: number\n  wrapperCol?: number\n  wrapperAlign?: 'left' | 'right'\n  wrapperWrap?: boolean\n  wrapperStyle?: React.CSSProperties\n  fullness?: boolean\n  addonBefore?: React.ReactNode\n  addonAfter?: React.ReactNode\n  size?: 'small' | 'default' | 'large'\n  inset?: boolean\n  extra?: React.ReactNode\n  feedbackText?: React.ReactNode\n  feedbackLayout?: 'loose' | 'terse' | 'popover' | 'none' | (string & {})\n  feedbackStatus?: 'error' | 'warning' | 'success' | 'pending' | (string & {})\n  feedbackIcon?: React.ReactNode\n  enableOutlineFeedback?: boolean\n  getPopupContainer?: (node: HTMLElement) => HTMLElement\n  asterisk?: boolean\n  optionalMarkHidden?: boolean\n  gridSpan?: number\n  bordered?: boolean\n}\n\ntype ComposeFormItem = React.FC<React.PropsWithChildren<IFormItemProps>> & {\n  BaseItem?: React.FC<React.PropsWithChildren<IFormItemProps>>\n}\n\nconst isTooltipProps = (\n  tooltip: React.ReactNode | React.ComponentProps<typeof Tooltip>\n): tooltip is React.ComponentProps<typeof Tooltip> => {\n  return !isElement(tooltip)\n}\n\nconst useFormItemLayout = (props: IFormItemProps) => {\n  const layout = useFormLayout()\n  const layoutType = props.layout ?? layout.layout ?? 'horizontal'\n  return {\n    ...props,\n    layout: layoutType,\n    colon: props.colon ?? layout.colon,\n    labelAlign:\n      layoutType === 'vertical'\n        ? props.labelAlign ?? 'left'\n        : props.labelAlign ?? layout.labelAlign ?? 'right',\n    labelWrap: props.labelWrap ?? layout.labelWrap,\n    labelWidth: props.labelWidth ?? layout.labelWidth,\n    wrapperWidth: props.wrapperWidth ?? layout.wrapperWidth,\n    labelCol: props.labelCol ?? layout.labelCol,\n    wrapperCol: props.wrapperCol ?? layout.wrapperCol,\n    wrapperAlign: props.wrapperAlign ?? layout.wrapperAlign,\n    wrapperWrap: props.wrapperWrap ?? layout.wrapperWrap,\n    fullness: props.fullness ?? layout.fullness,\n    size: props.size ?? layout.size,\n    inset: props.inset ?? layout.inset,\n    asterisk: props.asterisk,\n    requiredMark: layout.requiredMark,\n    optionalMarkHidden: props.optionalMarkHidden,\n    bordered: props.bordered ?? layout.bordered,\n    feedbackIcon: props.feedbackIcon,\n    feedbackLayout: props.feedbackLayout ?? layout.feedbackLayout ?? 'loose',\n    tooltipLayout: props.tooltipLayout ?? layout.tooltipLayout ?? 'icon',\n    tooltipIcon: props.tooltipIcon ?? layout.tooltipIcon ?? (\n      <QuestionCircleOutlined />\n    ),\n  }\n}\n\nfunction useOverflow<\n  Container extends HTMLElement,\n  Content extends HTMLElement\n>() {\n  const [overflow, setOverflow] = useState(false)\n  const containerRef = useRef<Container>()\n  const contentRef = useRef<Content>()\n  const layout = useFormLayout()\n  const labelCol = JSON.stringify(layout.labelCol)\n\n  useEffect(() => {\n    requestAnimationFrame(() => {\n      if (containerRef.current && contentRef.current) {\n        const contentWidth = contentRef.current.getBoundingClientRect().width\n        const containerWidth =\n          containerRef.current.getBoundingClientRect().width\n        if (contentWidth && containerWidth && containerWidth < contentWidth) {\n          if (!overflow) setOverflow(true)\n        } else {\n          if (overflow) setOverflow(false)\n        }\n      }\n    })\n  }, [labelCol])\n\n  return {\n    overflow,\n    containerRef,\n    contentRef,\n  }\n}\n\nconst ICON_MAP = {\n  error: <CloseCircleOutlined />,\n  success: <CheckCircleOutlined />,\n  warning: <ExclamationCircleOutlined />,\n}\n\nexport const BaseItem: React.FC<React.PropsWithChildren<IFormItemProps>> = ({\n  children,\n  ...props\n}) => {\n  const [active, setActive] = useState(false)\n  const formLayout = useFormItemLayout(props)\n  const { locale } = useContext(ConfigProvider.ConfigContext)\n  const { containerRef, contentRef, overflow } = useOverflow<\n    HTMLDivElement,\n    HTMLSpanElement\n  >()\n  const {\n    label,\n    style,\n    layout,\n    colon = true,\n    addonBefore,\n    addonAfter,\n    asterisk,\n    requiredMark = true,\n    optionalMarkHidden = false,\n    feedbackStatus,\n    extra,\n    feedbackText,\n    fullness,\n    feedbackLayout,\n    feedbackIcon,\n    enableOutlineFeedback = true,\n    getPopupContainer,\n    inset,\n    bordered = true,\n    labelWidth,\n    wrapperWidth,\n    labelCol,\n    wrapperCol,\n    labelAlign,\n    wrapperAlign = 'left',\n    size,\n    labelWrap,\n    wrapperWrap,\n    tooltipLayout,\n    tooltip,\n    tooltipIcon,\n  } = formLayout\n  const labelStyle = { ...formLayout.labelStyle }\n  const wrapperStyle = { ...formLayout.wrapperStyle }\n  // 固定宽度\n  let enableCol = false\n  if (labelWidth || wrapperWidth) {\n    if (labelWidth) {\n      labelStyle.width = labelWidth === 'auto' ? undefined : labelWidth\n      labelStyle.maxWidth = labelWidth === 'auto' ? undefined : labelWidth\n    }\n    if (wrapperWidth) {\n      wrapperStyle.width = wrapperWidth === 'auto' ? undefined : wrapperWidth\n      wrapperStyle.maxWidth = wrapperWidth === 'auto' ? undefined : wrapperWidth\n    }\n    // 栅格模式\n  }\n  if (labelCol || wrapperCol) {\n    if (!labelStyle.width && !wrapperStyle.width && layout !== 'vertical') {\n      enableCol = true\n    }\n  }\n\n  const prefixCls = usePrefixCls('formily-item', props)\n  const formatChildren =\n    feedbackLayout === 'popover' ? (\n      <Popover\n        autoAdjustOverflow\n        placement=\"top\"\n        content={\n          <div\n            className={cls({\n              [`${prefixCls}-${feedbackStatus}-help`]: !!feedbackStatus,\n              [`${prefixCls}-help`]: true,\n            })}\n          >\n            {ICON_MAP[feedbackStatus]} {feedbackText}\n          </div>\n        }\n        visible={!!feedbackText}\n        getPopupContainer={getPopupContainer}\n      >\n        {children}\n      </Popover>\n    ) : (\n      children\n    )\n\n  const gridStyles: React.CSSProperties = {}\n\n  const tooltipNode = isTooltipProps(tooltip) ? (\n    <Tooltip {...tooltip}></Tooltip>\n  ) : (\n    tooltip\n  )\n\n  const getOverflowTooltip = () => {\n    if (overflow) {\n      return (\n        <div>\n          <div>{label}</div>\n          <div>{tooltipNode}</div>\n        </div>\n      )\n    }\n    return tooltipNode\n  }\n\n  const renderLabelText = () => {\n    const labelChildren = (\n      <div className={`${prefixCls}-label-content`} ref={containerRef}>\n        <span ref={contentRef}>\n          {asterisk && requiredMark === true && (\n            <span className={`${prefixCls}-asterisk`}>{'*'}</span>\n          )}\n          <label htmlFor={props.labelFor}>{label}</label>\n          {!asterisk && requiredMark === 'optional' && !optionalMarkHidden && (\n            <span className={`${prefixCls}-optional`}>\n              {locale?.Form?.optional}\n            </span>\n          )}\n        </span>\n      </div>\n    )\n\n    if ((tooltipLayout === 'text' && tooltip) || overflow) {\n      return (\n        <Tooltip\n          placement=\"top\"\n          align={{ offset: [0, 10] }}\n          title={getOverflowTooltip()}\n        >\n          {labelChildren}\n        </Tooltip>\n      )\n    }\n    return labelChildren\n  }\n\n  const renderTooltipIcon = () => {\n    if (tooltip && tooltipLayout === 'icon' && !overflow) {\n      return (\n        <span className={`${prefixCls}-label-tooltip-icon`}>\n          <Tooltip\n            placement=\"top\"\n            align={{ offset: [0, 2] }}\n            title={tooltipNode}\n          >\n            {tooltipIcon}\n          </Tooltip>\n        </span>\n      )\n    }\n  }\n\n  const renderLabel = () => {\n    if (!label) return null\n    return (\n      <div\n        className={cls({\n          [`${prefixCls}-label`]: true,\n          [`${prefixCls}-label-tooltip`]:\n            (tooltip && tooltipLayout === 'text') || overflow,\n          [`${prefixCls}-item-col-${labelCol}`]: enableCol && !!labelCol,\n        })}\n        style={labelStyle}\n      >\n        {renderLabelText()}\n        {renderTooltipIcon()}\n        {label !== ' ' && (\n          <span className={`${prefixCls}-colon`}>{colon ? ':' : ''}</span>\n        )}\n      </div>\n    )\n  }\n\n  return (\n    <div\n      {...pickDataProps(props)}\n      style={{\n        ...style,\n        ...gridStyles,\n      }}\n      data-grid-span={props.gridSpan}\n      className={cls({\n        [`${prefixCls}`]: true,\n        [`${prefixCls}-layout-${layout}`]: true,\n        [`${prefixCls}-${feedbackStatus}`]:\n          enableOutlineFeedback && !!feedbackStatus,\n        [`${prefixCls}-feedback-has-text`]: !!feedbackText,\n        [`${prefixCls}-size-${size}`]: !!size,\n        [`${prefixCls}-feedback-layout-${feedbackLayout}`]: !!feedbackLayout,\n        [`${prefixCls}-fullness`]: !!fullness || !!inset || !!feedbackIcon,\n        [`${prefixCls}-inset`]: !!inset,\n        [`${prefixCls}-active`]: active,\n        [`${prefixCls}-inset-active`]: !!inset && active,\n        [`${prefixCls}-label-align-${labelAlign}`]: true,\n        [`${prefixCls}-control-align-${wrapperAlign}`]: true,\n        [`${prefixCls}-label-wrap`]: !!labelWrap,\n        [`${prefixCls}-control-wrap`]: !!wrapperWrap,\n        [`${prefixCls}-bordered-none`]:\n          bordered === false || !!inset || !!feedbackIcon,\n        [props.className]: !!props.className,\n      })}\n      onFocus={() => {\n        if (feedbackIcon || inset) {\n          setActive(true)\n        }\n      }}\n      onBlur={() => {\n        if (feedbackIcon || inset) {\n          setActive(false)\n        }\n      }}\n    >\n      {renderLabel()}\n      <div\n        className={cls({\n          [`${prefixCls}-control`]: true,\n          [`${prefixCls}-item-col-${wrapperCol}`]:\n            enableCol && !!wrapperCol && label,\n        })}\n      >\n        <div className={cls(`${prefixCls}-control-content`)}>\n          {addonBefore && (\n            <div className={cls(`${prefixCls}-addon-before`)}>\n              {addonBefore}\n            </div>\n          )}\n          <div\n            style={wrapperStyle}\n            className={cls({\n              [`${prefixCls}-control-content-component`]: true,\n              [`${prefixCls}-control-content-component-has-feedback-icon`]:\n                !!feedbackIcon,\n            })}\n          >\n            <FormLayoutShallowContext.Provider value={undefined}>\n              {formatChildren}\n            </FormLayoutShallowContext.Provider>\n            {feedbackIcon && (\n              <div className={cls(`${prefixCls}-feedback-icon`)}>\n                {feedbackIcon}\n              </div>\n            )}\n          </div>\n          {addonAfter && (\n            <div className={cls(`${prefixCls}-addon-after`)}>{addonAfter}</div>\n          )}\n        </div>\n        {!!feedbackText &&\n          feedbackLayout !== 'popover' &&\n          feedbackLayout !== 'none' && (\n            <div\n              className={cls({\n                [`${prefixCls}-${feedbackStatus}-help`]: !!feedbackStatus,\n                [`${prefixCls}-help`]: true,\n                [`${prefixCls}-help-enter`]: true,\n                [`${prefixCls}-help-enter-active`]: true,\n              })}\n            >\n              {feedbackText}\n            </div>\n          )}\n        {extra && <div className={cls(`${prefixCls}-extra`)}>{extra}</div>}\n      </div>\n    </div>\n  )\n}\n\n// 适配\nexport const FormItem: ComposeFormItem = connect(\n  BaseItem,\n  mapProps((props, field) => {\n    if (isVoidField(field))\n      return {\n        label: field.title || props.label,\n        asterisk: props.asterisk,\n        extra: props.extra || field.description,\n      }\n    if (!field) return props\n    const takeFeedbackStatus = () => {\n      if (field.validating) return 'pending'\n      return field.decoratorProps.feedbackStatus || field.validateStatus\n    }\n    const takeMessage = () => {\n      const split = (messages: any[]) => {\n        return messages.reduce((buf, text, index) => {\n          if (!text) return buf\n          return index < messages.length - 1\n            ? buf.concat([text, ', '])\n            : buf.concat([text])\n        }, [])\n      }\n      if (field.validating) return\n      if (props.feedbackText) return props.feedbackText\n      if (field.selfErrors.length) return split(field.selfErrors)\n      if (field.selfWarnings.length) return split(field.selfWarnings)\n      if (field.selfSuccesses.length) return split(field.selfSuccesses)\n    }\n    const takeAsterisk = () => {\n      if (field.required && field.pattern !== 'readPretty') {\n        return true\n      }\n      if ('asterisk' in props) {\n        return props.asterisk\n      }\n      return false\n    }\n    return {\n      label: props.label || field.title,\n      feedbackStatus: takeFeedbackStatus(),\n      feedbackText: takeMessage(),\n      asterisk: takeAsterisk(),\n      optionalMarkHidden:\n        field.pattern === 'readPretty' && !('asterisk' in props),\n      extra: props.extra || field.description,\n    }\n  })\n)\n\nFormItem.BaseItem = BaseItem\n\nexport default FormItem\n"
  },
  {
    "path": "packages/antd/src/form-item/style.less",
    "content": "@root-entry-name: 'default';\n@import (reference) '~antd/es/style/themes/index.less';\n@import (reference) '~antd/lib/input/style/mixin.less';\n@import './grid.less';\n@import './animation.less';\n\n@form-item-cls: ~'@{ant-prefix}-formily-item';\n\n.@{form-item-cls} {\n  display: flex;\n  margin-bottom: @form-item-margin-bottom - 2;\n  position: relative;\n  font-size: @font-size-base;\n\n  &-label {\n    line-height: @height-base;\n    min-height: @height-base - 2;\n    label {\n      cursor: text;\n    }\n  }\n\n  textarea.@{ant-prefix}-input {\n    height: auto;\n  }\n\n  // input[type=file]\n  .@{ant-prefix}-upload {\n    background: transparent;\n  }\n\n  .@{ant-prefix}-upload.@{ant-prefix}-upload-drag {\n    background: @background-color-light;\n  }\n\n  input[type='radio'],\n  input[type='checkbox'] {\n    width: @font-size-base;\n    height: @font-size-base;\n  }\n\n  // Radios and checkboxes on same line\n  .@{ant-prefix}-radio-inline,\n  .@{ant-prefix}-checkbox-inline {\n    display: inline-block;\n    margin-left: 8px;\n    font-weight: normal;\n    vertical-align: middle;\n    cursor: pointer;\n\n    &:first-child {\n      margin-left: 0;\n    }\n  }\n\n  .@{ant-prefix}-checkbox-vertical,\n  .@{ant-prefix}-radio-vertical {\n    display: block;\n  }\n\n  .@{ant-prefix}-checkbox-vertical + .@{ant-prefix}-checkbox-vertical,\n  .@{ant-prefix}-radio-vertical + .@{ant-prefix}-radio-vertical {\n    margin-left: 0;\n  }\n\n  .@{ant-prefix}-input-number {\n    width: 100%;\n\n    + .@{ant-prefix}-form-text {\n      margin-left: 8px;\n    }\n\n    &-handler-wrap {\n      z-index: 2; // https://github.com/ant-design/ant-design/issues/6289\n    }\n  }\n\n  .@{ant-prefix}-select,\n  .@{ant-prefix}-cascader-picker,\n  .@{ant-prefix}-picker {\n    width: 100%;\n  }\n\n  // Don't impact select inside input group\n  .@{ant-prefix}-input-group .@{ant-prefix}-select,\n  .@{ant-prefix}-input-group .@{ant-prefix}-cascader-picker {\n    width: auto;\n  }\n}\n\n.@{form-item-cls}-label {\n  position: relative;\n  display: flex;\n\n  &-content {\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n\n  &-tooltip {\n    cursor: help;\n\n    * {\n      cursor: help;\n    }\n\n    label {\n      border-bottom: 1px dashed currentColor;\n    }\n  }\n}\n\n.@{form-item-cls}-label {\n  color: @heading-color;\n}\n\n.@{form-item-cls}-label-align-left {\n  > .@{form-item-cls}-label {\n    justify-content: flex-start;\n  }\n}\n\n.@{form-item-cls}-label-align-right {\n  > .@{form-item-cls}-label {\n    justify-content: flex-end;\n  }\n}\n\n.@{form-item-cls}-label-wrap {\n  .@{form-item-cls}-label {\n    label {\n      white-space: pre-line;\n      word-break: break-all;\n    }\n  }\n}\n\n.@{form-item-cls}-feedback-layout-terse {\n  margin-bottom: 8px;\n\n  &.@{form-item-cls}-feedback-has-text:not(.@{form-item-cls}-inset) {\n    margin-bottom: 0;\n  }\n}\n\n.@{form-item-cls}-feedback-layout-loose {\n  margin-bottom: 22px;\n\n  &.@{form-item-cls}-feedback-has-text:not(.@{form-item-cls}-inset) {\n    margin-bottom: 0;\n  }\n}\n\n.@{form-item-cls}-feedback-layout-none {\n  margin-bottom: 0px;\n\n  &.@{form-item-cls}-feedback-has-text:not(.@{form-item-cls}-inset) {\n    margin-bottom: 0;\n  }\n}\n\n.@{form-item-cls}-control {\n  flex: 1;\n  max-width: 100%;\n\n  .@{form-item-cls}-control-content {\n    display: flex;\n\n    .@{form-item-cls}-control-content-component {\n      width: 100%;\n      min-height: @height-base - 2;\n      line-height: @height-base + 2;\n\n      &-has-feedback-icon {\n        flex: 1;\n        position: relative;\n        display: flex;\n        align-items: center;\n      }\n    }\n\n    .@{form-item-cls}-addon-before {\n      margin-right: 8px;\n      display: inline-flex;\n      align-items: center;\n      min-height: @height-base;\n      flex-shrink: 0;\n    }\n\n    .@{form-item-cls}-addon-after {\n      margin-left: 8px;\n      display: inline-flex;\n      align-items: center;\n      min-height: @height-base;\n      flex-shrink: 0;\n    }\n  }\n\n  .@{form-item-cls}-help,\n  .@{form-item-cls}-extra {\n    min-height: 22px;\n    line-height: 22px;\n    color: @text-color-secondary;\n  }\n}\n\n.@{form-item-cls}-size-small {\n  font-size: @font-size-sm;\n\n  line-height: @height-sm;\n\n  .@{form-item-cls}-label {\n    line-height: @height-sm;\n    min-height: @height-sm - 2;\n  }\n\n  .@{form-item-cls}-control-content {\n    .@{form-item-cls}-control-content-component {\n      min-height: @height-sm - 2;\n      line-height: @height-sm + 2;\n    }\n  }\n\n  .@{form-item-cls}-help,\n  .@{form-item-cls}-extra {\n    min-height: @height-sm - 4;\n    line-height: @height-sm - 4;\n  }\n\n  .@{form-item-cls}-control-content {\n    min-height: @height-sm - 2;\n  }\n\n  .@{form-item-cls}-label > label {\n    height: @height-sm - 2;\n  }\n\n  .@{ant-prefix}-input-affix-wrapper,\n  .@{ant-prefix}-input-number,\n  .@{ant-prefix}-picker {\n    padding: 0px 11px;\n\n    input {\n      height: @height-sm - 2;\n      font-size: @font-size-sm;\n    }\n  }\n\n  .@{ant-prefix}-cascader-picker {\n    height: @height-sm - 2;\n\n    input {\n      padding: 0 7px;\n      height: @height-sm - 2;\n      font-size: @font-size-sm;\n    }\n  }\n\n  .@{ant-prefix}-select-single:not(.@{ant-prefix}-select-customize-input)\n    .@{ant-prefix}-select-selector {\n    padding: 0px 11px;\n    height: @height-sm - 2;\n    font-size: @font-size-sm;\n    line-height: @height-sm;\n\n    .@{ant-prefix}-select-selection-search {\n      height: @height-sm;\n      line-height: @height-sm - 2;\n\n      &-input {\n        height: @height-sm;\n        line-height: @height-sm - 2;\n      }\n    }\n\n    .@{ant-prefix}-select-selection-placeholder {\n      line-height: @height-sm - 2;\n      height: @height-sm;\n    }\n\n    .@{ant-prefix}-select-selection-item {\n      line-height: @height-sm - 2;\n      height: @height-sm;\n    }\n  }\n\n  .@{ant-prefix}-select-multiple:not(.@{ant-prefix}-select-customize-input)\n    .@{ant-prefix}-select-selector {\n    padding: 0px 2px;\n    height: @height-sm - 2;\n    font-size: @font-size-sm;\n    line-height: @height-sm;\n\n    &::after {\n      height: @height-sm - 8;\n      line-height: @height-sm - 8;\n    }\n\n    .@{ant-prefix}-select-selection-search {\n      height: @height-sm - 8;\n      line-height: @height-sm - 8;\n      margin-inline-start: 0;\n\n      &-input {\n        height: @height-sm - 12;\n        line-height: @height-sm - 12;\n      }\n    }\n\n    .@{ant-prefix}-select-selection-placeholder {\n      line-height: @height-sm - 8;\n      height: @height-sm - 8;\n      left: 4px;\n    }\n\n    .@{ant-prefix}-select-selection-overflow-item {\n      align-self: flex-start;\n    }\n\n    .@{ant-prefix}-select-selection-item {\n      line-height: @height-sm - 10;\n      height: @height-sm - 8;\n    }\n  }\n\n  &.@{form-item-cls}-feedback-layout-terse {\n    margin-bottom: 8px;\n\n    &.@{form-item-cls}-feedback-has-text:not(.@{form-item-cls}-inset) {\n      margin-bottom: 0;\n    }\n  }\n\n  &.@{form-item-cls}-feedback-layout-loose {\n    margin-bottom: @height-sm - 4;\n\n    &.@{form-item-cls}-feedback-has-text:not(.@{form-item-cls}-inset) {\n      margin-bottom: 0;\n    }\n  }\n}\n\n.@{form-item-cls}-size-large {\n  font-size: @font-size-lg;\n  line-height: @height-lg;\n\n  .@{form-item-cls}-label {\n    line-height: @height-lg;\n    min-height: @height-lg - 2;\n  }\n\n  .@{form-item-cls}-control-content {\n    .@{form-item-cls}-control-content-component {\n      min-height: @height-lg - 2;\n      line-height: @height-lg;\n    }\n  }\n\n  .@{form-item-cls}-help,\n  .@{form-item-cls}-extra {\n    min-height: @form-item-margin-bottom;\n    line-height: @form-item-margin-bottom;\n  }\n\n  .@{form-item-cls}-control-content {\n    min-height: @height-lg - 2;\n  }\n\n  .@{ant-prefix}-input {\n    font-size: @font-size-lg;\n  }\n\n  .@{ant-prefix}-input-number {\n    font-size: @font-size-lg;\n\n    input {\n      height: @height-lg - 2;\n    }\n  }\n\n  .@{ant-prefix}-input-affix-wrapper,\n  .@{ant-prefix}-picker {\n    padding: 0px 11px;\n    line-height: @height-lg - 2;\n\n    input {\n      height: @height-lg - 2;\n      font-size: @font-size-lg;\n    }\n  }\n\n  .@{ant-prefix}-btn {\n    height: @height-lg;\n    padding: 0px 8px;\n  }\n\n  .@{ant-prefix}-radio-button-wrapper {\n    height: @height-lg;\n    line-height: @height-lg;\n  }\n\n  .@{ant-prefix}-cascader-picker {\n    height: @height-lg - 2;\n\n    input {\n      padding: 0px 11px;\n      height: @height-lg - 2;\n      font-size: @font-size-lg;\n    }\n  }\n\n  .@{ant-prefix}-select-single:not(.@{ant-prefix}-select-customize-input)\n    .@{ant-prefix}-select-selector {\n    padding: 0px 11px;\n    height: @height-lg;\n    font-size: @font-size-lg;\n    line-height: @height-lg;\n\n    .@{ant-prefix}-select-selection-search {\n      height: @height-lg;\n      line-height: @height-lg - 2;\n\n      &-input {\n        height: @height-lg;\n        line-height: @height-lg - 2;\n      }\n    }\n\n    .@{ant-prefix}-select-selection-placeholder {\n      line-height: @height-lg - 2;\n      height: @height-lg;\n    }\n\n    .@{ant-prefix}-select-selection-item {\n      line-height: @height-lg - 2;\n      height: @height-lg;\n    }\n  }\n\n  .@{ant-prefix}-select-multiple:not(.@{ant-prefix}-select-customize-input)\n    .@{ant-prefix}-select-selector {\n    padding: 0px 2px;\n    height: @height-lg - 2;\n    font-size: @font-size-lg;\n    line-height: @height-lg;\n\n    &::after {\n      height: @height-lg - 8;\n      line-height: @height-lg - 8;\n    }\n\n    .@{ant-prefix}-select-selection-search {\n      height: @height-lg - 8;\n      line-height: @height-lg - 8;\n\n      &-input {\n        height: @height-lg - 12;\n        line-height: @height-lg - 12;\n      }\n    }\n\n    .@{ant-prefix}-select-selection-placeholder {\n      line-height: @height-lg - 8;\n      height: @height-lg - 8;\n    }\n\n    .@{ant-prefix}-select-selection-overflow-item {\n      align-self: flex-start;\n    }\n\n    .@{ant-prefix}-select-selection-item {\n      line-height: @height-lg - 10;\n      height: @height-lg - 8;\n    }\n  }\n\n  &.@{form-item-cls}-feedback-layout-terse {\n    margin-bottom: 8px;\n\n    &.@{form-item-cls}-feedback-has-text:not(.@{form-item-cls}-inset) {\n      margin-bottom: 0;\n    }\n  }\n\n  &.@{form-item-cls}-feedback-layout-loose {\n    margin-bottom: @form-item-margin-bottom;\n\n    &.@{form-item-cls}-feedback-has-text:not(.@{form-item-cls}-inset) {\n      margin-bottom: 0;\n    }\n  }\n}\n\n.@{form-item-cls} {\n  &-layout-vertical {\n    display: block;\n\n    .@{form-item-cls}-label {\n      min-height: @height-base - 10;\n      line-height: 1.5715;\n    }\n  }\n}\n\n.@{form-item-cls}-feedback-layout-popover {\n  margin-bottom: 8px;\n}\n\n.@{form-item-cls}-label-tooltip-icon {\n  margin-left: 4px;\n  color: #00000073;\n  display: flex;\n  align-items: center;\n  max-height: @height-base;\n\n  span {\n    display: inline-flex;\n  }\n}\n\n.@{form-item-cls}-control-align-left {\n  .@{form-item-cls}-control-content {\n    justify-content: flex-start;\n  }\n}\n\n.@{form-item-cls}-control-align-right {\n  .@{form-item-cls}-control-content {\n    justify-content: flex-end;\n  }\n}\n\n.@{form-item-cls}-control-wrap {\n  .@{form-item-cls}-control {\n    white-space: pre-line;\n    word-break: break-all;\n  }\n}\n\n.@{form-item-cls}-asterisk {\n  color: @error-color;\n  margin-right: 4px;\n  display: inline-block;\n  font-family: SimSun, sans-serif;\n}\n\n.@{form-item-cls}-optional {\n  color: rgba(0, 0, 0, 0.45);\n}\n\n.@{form-item-cls}-colon {\n  margin-left: 2px;\n  margin-right: 8px;\n}\n\n.@{form-item-cls}-help,\n.@{form-item-cls}-extra {\n  clear: both;\n  min-height: @form-item-margin-bottom - 2;\n  color: rgba(0, 0, 0, 0.45);\n  transition: color 0.3s cubic-bezier(0.215, 0.61, 0.355, 1);\n  padding-top: 0px;\n}\n\n.@{form-item-cls}-fullness {\n  > .@{form-item-cls}-control {\n    > .@{form-item-cls}-control-content {\n      > .@{form-item-cls}-control-content-component {\n        > *:first-child {\n          width: 100%;\n        }\n      }\n    }\n  }\n}\n\n.@{form-item-cls}-control-content-component-has-feedback-icon {\n  border-radius: 2px;\n  border: 1px solid @border-color-base;\n  padding-right: 8px;\n  transition: all 0.3s;\n  touch-action: manipulation;\n  outline: none;\n\n  .@{ant-prefix}-input-number,\n  .@{ant-prefix}-picker,\n  .@{ant-prefix}-cascader-picker:focus .@{ant-prefix}-cascader-input,\n  .@{ant-prefix}-select:not(.@{ant-prefix}-select-customize-input)\n    .@{ant-prefix}-select-selector,\n  .@{ant-prefix}-input-affix-wrapper,\n  .@{ant-prefix}-input {\n    border: none !important;\n    box-shadow: none !important;\n  }\n}\n\n.@{form-item-cls}-bordered-none {\n  .@{ant-prefix}-input-number,\n  .@{ant-prefix}-input-affix-wrapper,\n  .@{ant-prefix}-picker,\n  .@{ant-prefix}-cascader-picker:focus .@{ant-prefix}-cascader-input,\n  .@{ant-prefix}-select:not(.@{ant-prefix}-select-customize-input)\n    .@{ant-prefix}-select-selector,\n  .@{ant-prefix}-input {\n    border: none !important;\n    box-shadow: none !important;\n  }\n\n  .@{ant-prefix}-input-number-handler-wrap {\n    border: none !important;\n\n    .@{ant-prefix}-input-number-handler {\n      border: none !important;\n    }\n  }\n}\n\n.@{form-item-cls}-inset {\n  border-radius: 2px;\n  border: 1px solid @border-color-base;\n  padding-left: 12px;\n  transition: 0.3s all;\n\n  .@{ant-prefix}-input-number,\n  .@{ant-prefix}-picker,\n  .@{ant-prefix}-cascader-picker:focus .@{ant-prefix}-cascader-input,\n  .@{ant-prefix}-select:not(.@{ant-prefix}-select-customize-input)\n    .@{ant-prefix}-select-selector,\n  .@{ant-prefix}-input-affix-wrapper,\n  .@{ant-prefix}-input {\n    border: none !important;\n    box-shadow: none !important;\n  }\n\n  .@{ant-prefix}-input-number-handler-wrap {\n    border: none !important;\n\n    .@{ant-prefix}-input-number-handler {\n      border: none !important;\n    }\n  }\n\n  &:hover {\n    .hover();\n  }\n}\n\n.@{form-item-cls}-inset-active {\n  .active();\n}\n\n.@{form-item-cls}-active {\n  .@{form-item-cls}-control-content-component-has-feedback-icon {\n    .active();\n  }\n\n  .@{ant-prefix}-input-number,\n  .@{ant-prefix}-picker,\n  .@{ant-prefix}-cascader-picker:focus .@{ant-prefix}-cascader-input,\n  .@{ant-prefix}-select:not(.@{ant-prefix}-select-customize-input)\n    .@{ant-prefix}-select-selector,\n  .@{ant-prefix}-input {\n    .active();\n  }\n}\n\n.@{form-item-cls} {\n  &:hover {\n    .@{form-item-cls}-control-content-component-has-feedback-icon {\n      .hover();\n    }\n  }\n}\n\n.@{form-item-cls}-error {\n  .@{ant-prefix}-select-selector,\n  .@{ant-prefix}-cascader-picker,\n  .@{ant-prefix}-picker,\n  .@{ant-prefix}-input,\n  .@{ant-prefix}-input-number,\n  .@{ant-prefix}-input-affix-wrapper,\n  .@{ant-prefix}-input-affix-wrapper,\n  .@{ant-prefix}-input {\n    border-color: @error-color !important;\n  }\n\n  .@{ant-prefix}-select-selector,\n  .@{ant-prefix}-cascader-picker,\n  .@{ant-prefix}-picker,\n  .@{ant-prefix}-input,\n  .@{ant-prefix}-input-number,\n  .@{ant-prefix}-input-affix-wrapper,\n  .@{ant-prefix}-input-affix-wrapper:hover,\n  .@{ant-prefix}-input:hover {\n    border-color: @error-color !important;\n  }\n\n  .@{ant-prefix}-select:not(.@{ant-prefix}-select-disabled):not(.@{ant-prefix}-select-customize-input) {\n    .@{ant-prefix}-select-selector {\n      background-color: @form-error-input-bg;\n      border-color: @error-color !important;\n    }\n\n    &.@{ant-prefix}-select-open .@{ant-prefix}-select-selector,\n    &.@{ant-prefix}-select-focused .@{ant-prefix}-select-selector {\n      .active(@error-color);\n    }\n  }\n\n  .@{ant-prefix}-input-number,\n  .@{ant-prefix}-picker {\n    background-color: @form-error-input-bg;\n    border-color: @error-color;\n\n    &-focused,\n    &:focus {\n      .active(@error-color);\n    }\n\n    &:not([disabled]):hover {\n      background-color: @form-error-input-bg;\n      border-color: @error-color;\n    }\n  }\n\n  .@{ant-prefix}-cascader-picker:focus .@{ant-prefix}-cascader-input {\n    background-color: @form-error-input-bg;\n    .active(@error-color);\n  }\n\n  .@{ant-prefix}-input-affix-wrapper-focused,\n  .@{ant-prefix}-input-affix-wrapper:focus,\n  .@{ant-prefix}-input-focused,\n  .@{ant-prefix}-input:focus {\n    .active(@error-color);\n  }\n}\n\n.@{form-item-cls}-error-help {\n  color: @error-color !important;\n}\n\n.@{form-item-cls}-warning-help {\n  color: @warning-color !important;\n}\n\n.@{form-item-cls}-success-help {\n  color: @success-color !important;\n}\n\n.@{form-item-cls}-warning {\n  .@{ant-prefix}-select-selector,\n  .@{ant-prefix}-cascader-picker,\n  .@{ant-prefix}-picker,\n  .@{ant-prefix}-input,\n  .@{ant-prefix}-input-number,\n  .@{ant-prefix}-input-affix-wrapper,\n  .@{ant-prefix}-input-affix-wrapper,\n  .@{ant-prefix}-input {\n    border-color: @warning-color !important;\n  }\n\n  .@{ant-prefix}-select-selector,\n  .@{ant-prefix}-cascader-picker,\n  .@{ant-prefix}-picker,\n  .@{ant-prefix}-input,\n  .@{ant-prefix}-input-number,\n  .@{ant-prefix}-input-affix-wrapper,\n  .@{ant-prefix}-input-affix-wrapper:hover,\n  .@{ant-prefix}-input:hover {\n    border-color: @warning-color !important;\n  }\n\n  .@{ant-prefix}-select:not(.@{ant-prefix}-select-disabled):not(.@{ant-prefix}-select-customize-input) {\n    .@{ant-prefix}-select-selector {\n      background-color: @form-warning-input-bg;\n      border-color: @warning-color !important;\n    }\n\n    &.@{ant-prefix}-select-open .@{ant-prefix}-select-selector,\n    &.@{ant-prefix}-select-focused .@{ant-prefix}-select-selector {\n      .active(@warning-color);\n    }\n  }\n\n  .@{ant-prefix}-input-number,\n  .@{ant-prefix}-picker {\n    background-color: @form-warning-input-bg;\n    border-color: @warning-color;\n\n    &-focused,\n    &:focus {\n      .active(@warning-color);\n    }\n\n    &:not([disabled]):hover {\n      background-color: @form-warning-input-bg;\n      border-color: @warning-color;\n    }\n  }\n\n  .@{ant-prefix}-cascader-picker:focus .@{ant-prefix}-cascader-input {\n    background-color: @form-warning-input-bg;\n    .active(@warning-color);\n  }\n\n  .@{ant-prefix}-input-affix-wrapper-focused,\n  .@{ant-prefix}-input-affix-wrapper:focus,\n  .@{ant-prefix}-input-focused,\n  .@{ant-prefix}-input:focus {\n    .active(@warning-color);\n  }\n}\n\n.@{form-item-cls}-success {\n  .@{ant-prefix}-select-selector,\n  .@{ant-prefix}-cascader-picker,\n  .@{ant-prefix}-picker,\n  .@{ant-prefix}-input,\n  .@{ant-prefix}-input-number,\n  .@{ant-prefix}-input-affix-wrapper,\n  .@{ant-prefix}-input-affix-wrapper,\n  .@{ant-prefix}-input {\n    border-color: @success-color !important;\n  }\n\n  .@{ant-prefix}-select-selector,\n  .@{ant-prefix}-cascader-picker,\n  .@{ant-prefix}-picker,\n  .@{ant-prefix}-input,\n  .@{ant-prefix}-input-number,\n  .@{ant-prefix}-input-affix-wrapper,\n  .@{ant-prefix}-input-affix-wrapper:hover,\n  .@{ant-prefix}-input:hover {\n    border-color: @success-color !important;\n  }\n\n  .@{ant-prefix}-input-affix-wrapper-focused,\n  .@{ant-prefix}-input-affix-wrapper:focus,\n  .@{ant-prefix}-input-focused,\n  .@{ant-prefix}-input:focus {\n    border-color: @success-color !important;\n    border-right-width: 1px !important;\n    outline: 0;\n  }\n}\n"
  },
  {
    "path": "packages/antd/src/form-item/style.ts",
    "content": "import 'antd/lib/form/style/index'\nimport 'antd/lib/tooltip/style/index'\nimport 'antd/lib/popover/style/index'\nimport './style.less'\n"
  },
  {
    "path": "packages/antd/src/form-layout/index.tsx",
    "content": "import React, { createContext, useContext } from 'react'\nimport { useResponsiveFormLayout } from './useResponsiveFormLayout'\nimport { usePrefixCls } from '../__builtins__'\nimport cls from 'classnames'\n\nexport interface IFormLayoutProps {\n  prefixCls?: string\n  className?: string\n  style?: React.CSSProperties\n  colon?: boolean\n  requiredMark?: boolean | 'optional'\n  labelAlign?: 'right' | 'left' | ('right' | 'left')[]\n  wrapperAlign?: 'right' | 'left' | ('right' | 'left')[]\n  labelWrap?: boolean\n  labelWidth?: number\n  wrapperWidth?: number\n  wrapperWrap?: boolean\n  labelCol?: number | number[]\n  wrapperCol?: number | number[]\n  fullness?: boolean\n  size?: 'small' | 'default' | 'large'\n  layout?:\n    | 'vertical'\n    | 'horizontal'\n    | 'inline'\n    | ('vertical' | 'horizontal' | 'inline')[]\n  direction?: 'rtl' | 'ltr'\n  inset?: boolean\n  shallow?: boolean\n  tooltipLayout?: 'icon' | 'text'\n  tooltipIcon?: React.ReactNode\n  feedbackLayout?: 'loose' | 'terse' | 'popover' | 'none'\n  bordered?: boolean\n  breakpoints?: number[]\n  spaceGap?: number\n  gridColumnGap?: number\n  gridRowGap?: number\n}\n\nexport interface IFormLayoutContext\n  extends Omit<\n    IFormLayoutProps,\n    'labelAlign' | 'wrapperAlign' | 'layout' | 'labelCol' | 'wrapperCol'\n  > {\n  labelAlign?: 'right' | 'left'\n  wrapperAlign?: 'right' | 'left'\n  layout?: 'vertical' | 'horizontal' | 'inline'\n  labelCol?: number\n  wrapperCol?: number\n}\n\nexport const FormLayoutDeepContext = createContext<IFormLayoutContext>(null)\n\nexport const FormLayoutShallowContext = createContext<IFormLayoutContext>(null)\n\nexport const useFormDeepLayout = () => useContext(FormLayoutDeepContext)\n\nexport const useFormShallowLayout = () => useContext(FormLayoutShallowContext)\n\nexport const useFormLayout = () => ({\n  ...useFormDeepLayout(),\n  ...useFormShallowLayout(),\n})\n\nexport const FormLayout: React.FC<React.PropsWithChildren<IFormLayoutProps>> & {\n  useFormLayout: () => IFormLayoutContext\n  useFormDeepLayout: () => IFormLayoutContext\n  useFormShallowLayout: () => IFormLayoutContext\n} = ({\n  shallow = true,\n  children,\n  prefixCls,\n  className,\n  style,\n  ...otherProps\n}) => {\n  const { ref, props } = useResponsiveFormLayout(otherProps)\n  const deepLayout = useFormDeepLayout()\n  const formPrefixCls = usePrefixCls('form', { prefixCls })\n  const layoutPrefixCls = usePrefixCls('formily-layout', { prefixCls })\n  const layoutClassName = cls(\n    layoutPrefixCls,\n    {\n      [`${formPrefixCls}-${props.layout}`]: true,\n      [`${formPrefixCls}-rtl`]: props.direction === 'rtl',\n      [`${formPrefixCls}-${props.size}`]: props.size,\n    },\n    className\n  )\n  const renderChildren = () => {\n    const newDeepLayout = {\n      ...deepLayout,\n    }\n    if (!shallow) {\n      Object.assign(newDeepLayout, props)\n    } else {\n      if (props.size) {\n        newDeepLayout.size = props.size\n      }\n      if (props.colon) {\n        newDeepLayout.colon = props.colon\n      }\n    }\n    return (\n      <FormLayoutDeepContext.Provider value={newDeepLayout}>\n        <FormLayoutShallowContext.Provider value={shallow ? props : undefined}>\n          {children}\n        </FormLayoutShallowContext.Provider>\n      </FormLayoutDeepContext.Provider>\n    )\n  }\n  return (\n    <div ref={ref} className={layoutClassName} style={style}>\n      {renderChildren()}\n    </div>\n  )\n}\n\nFormLayout.useFormDeepLayout = useFormDeepLayout\nFormLayout.useFormShallowLayout = useFormShallowLayout\nFormLayout.useFormLayout = useFormLayout\n\nexport default FormLayout\n"
  },
  {
    "path": "packages/antd/src/form-layout/style.less",
    "content": ""
  },
  {
    "path": "packages/antd/src/form-layout/style.ts",
    "content": "// @ts-ignore\n"
  },
  {
    "path": "packages/antd/src/form-layout/useResponsiveFormLayout.ts",
    "content": "import { useRef, useState, useEffect } from 'react'\nimport { isArr, isValid } from '@formily/shared'\n\ninterface IProps {\n  breakpoints?: number[]\n  layout?:\n    | 'vertical'\n    | 'horizontal'\n    | 'inline'\n    | ('vertical' | 'horizontal' | 'inline')[]\n  labelCol?: number | number[]\n  wrapperCol?: number | number[]\n  labelAlign?: 'right' | 'left' | ('right' | 'left')[]\n  wrapperAlign?: 'right' | 'left' | ('right' | 'left')[]\n  [props: string]: any\n}\n\ninterface ICalcBreakpointIndex {\n  (originalBreakpoints: number[], width: number): number\n}\n\ninterface ICalculateProps {\n  (target: HTMLElement, props: IProps): IProps\n}\n\ninterface IUseResponsiveFormLayout {\n  (props: IProps): {\n    ref: React.MutableRefObject<HTMLDivElement>\n    props: any\n  }\n}\n\nconst calcBreakpointIndex: ICalcBreakpointIndex = (breakpoints, width) => {\n  for (let i = 0; i < breakpoints.length; i++) {\n    if (width <= breakpoints[i]) {\n      return i\n    }\n  }\n}\n\nconst calcFactor = <T>(value: T | T[], breakpointIndex: number): T => {\n  if (Array.isArray(value)) {\n    if (breakpointIndex === -1) return value[0]\n    return value[breakpointIndex] ?? value[value.length - 1]\n  } else {\n    return value\n  }\n}\n\nconst factor = <T>(value: T | T[], breakpointIndex: number): T =>\n  isValid(value) ? calcFactor(value as any, breakpointIndex) : value\n\nconst calculateProps: ICalculateProps = (target, props) => {\n  const { clientWidth } = target\n  const {\n    breakpoints,\n    layout,\n    labelAlign,\n    wrapperAlign,\n    labelCol,\n    wrapperCol,\n    ...otherProps\n  } = props\n  const breakpointIndex = calcBreakpointIndex(breakpoints, clientWidth)\n\n  return {\n    layout: factor(layout, breakpointIndex),\n    labelAlign: factor(labelAlign, breakpointIndex),\n    wrapperAlign: factor(wrapperAlign, breakpointIndex),\n    labelCol: factor(labelCol, breakpointIndex),\n    wrapperCol: factor(wrapperCol, breakpointIndex),\n    ...otherProps,\n  }\n}\n\nexport const useResponsiveFormLayout: IUseResponsiveFormLayout = (props) => {\n  const ref = useRef<HTMLDivElement>(null)\n  const { breakpoints } = props\n  if (!isArr(breakpoints)) {\n    return { ref, props }\n  }\n  const [layoutProps, setLayout] = useState<any>(props)\n\n  const updateUI = () => {\n    if (ref.current) {\n      setLayout(calculateProps(ref.current, props))\n    }\n  }\n\n  useEffect(() => {\n    const observer = () => {\n      updateUI()\n    }\n    const resizeObserver = new ResizeObserver(observer)\n    if (ref.current) {\n      resizeObserver.observe(ref.current)\n    }\n    updateUI()\n    return () => {\n      resizeObserver.disconnect()\n    }\n  }, [])\n\n  return {\n    ref,\n    props: layoutProps,\n  }\n}\n"
  },
  {
    "path": "packages/antd/src/form-step/index.tsx",
    "content": "import React, { Fragment } from 'react'\nimport { define, observable, action, markRaw, model } from '@formily/reactive'\nimport { Steps } from 'antd'\nimport cls from 'classnames'\nimport { StepsProps, StepProps } from 'antd/lib/steps'\nimport { Form, VoidField } from '@formily/core'\nimport {\n  connect,\n  useField,\n  observer,\n  useFieldSchema,\n  RecursionField,\n} from '@formily/react'\nimport { Schema, SchemaKey } from '@formily/json-schema'\nimport { usePrefixCls } from '../__builtins__'\n\nexport interface IFormStep {\n  connect: (steps: SchemaStep[], field: VoidField) => void\n  current: number\n  allowNext: boolean\n  allowBack: boolean\n  setCurrent(key: number): void\n  submit: Form['submit']\n  next(): void\n  back(): void\n}\n\nexport interface IFormStepProps extends StepsProps {\n  formStep?: IFormStep\n}\n\ntype ComposedFormStep = React.FC<React.PropsWithChildren<IFormStepProps>> & {\n  StepPane: React.FC<React.PropsWithChildren<StepProps>>\n  createFormStep: (defaultCurrent?: number) => IFormStep\n}\n\ntype SchemaStep = {\n  name: SchemaKey\n  props: any\n  schema: Schema\n}\n\ntype FormStepEnv = {\n  form: Form\n  field: VoidField\n  steps: SchemaStep[]\n}\n\nconst parseSteps = (schema: Schema) => {\n  const steps: SchemaStep[] = []\n  schema.mapProperties((schema, name) => {\n    if (schema['x-component']?.indexOf('StepPane') > -1) {\n      steps.push({\n        name,\n        props: schema['x-component-props'],\n        schema,\n      })\n    }\n  })\n  return steps\n}\n\nconst createFormStep = (defaultCurrent = 0): IFormStep => {\n  const env: FormStepEnv = define(\n    {\n      form: null,\n      field: null,\n      steps: [],\n    },\n    {\n      form: observable.ref,\n      field: observable.ref,\n      steps: observable.shallow,\n    }\n  )\n\n  const setDisplay = action.bound((target: number) => {\n    const currentStep = env.steps[target]\n    env.steps.forEach(({ name }) => {\n      env.form.query(`${env.field.address}.${name}`).take((field) => {\n        if (name === currentStep.name) {\n          field.setDisplay('visible')\n        } else {\n          field.setDisplay('hidden')\n        }\n      })\n    })\n  })\n\n  const next = action.bound(() => {\n    if (formStep.allowNext) {\n      formStep.setCurrent(formStep.current + 1)\n    }\n  })\n\n  const back = action.bound(() => {\n    if (formStep.allowBack) {\n      formStep.setCurrent(formStep.current - 1)\n    }\n  })\n\n  const formStep: IFormStep = model({\n    connect(steps, field) {\n      env.steps = steps\n      env.form = field?.form\n      env.field = field\n    },\n    current: defaultCurrent,\n    setCurrent(key: number) {\n      setDisplay(key)\n      formStep.current = key\n    },\n    get allowNext() {\n      return formStep.current < env.steps.length - 1\n    },\n    get allowBack() {\n      return formStep.current > 0\n    },\n    async next() {\n      try {\n        await env.form.validate()\n        if (env.form.valid) {\n          next()\n        }\n      } catch {}\n    },\n    async back() {\n      back()\n    },\n    async submit(onSubmit) {\n      return env.form?.submit?.(onSubmit)\n    },\n  })\n  return markRaw(formStep)\n}\n\nexport const FormStep = connect(\n  observer(({ formStep, className, ...props }: IFormStepProps) => {\n    const field = useField<VoidField>()\n    const prefixCls = usePrefixCls('formily-step', props)\n    const schema = useFieldSchema()\n    const steps = parseSteps(schema)\n    const current = props.current || formStep?.current || 0\n    formStep?.connect?.(steps, field)\n    return (\n      <div className={cls(prefixCls, className)}>\n        <Steps\n          {...props}\n          style={{ marginBottom: 10, ...props.style }}\n          current={current}\n        >\n          {steps.map(({ props }, key) => {\n            return <Steps.Step {...props} key={key} />\n          })}\n        </Steps>\n        {steps.map(({ name, schema }, key) => {\n          if (key !== current) return\n          return <RecursionField key={key} name={name} schema={schema} />\n        })}\n      </div>\n    )\n  })\n) as unknown as ComposedFormStep\n\nconst StepPane: React.FC<React.PropsWithChildren<StepProps>> = ({\n  children,\n}) => {\n  return <Fragment>{children}</Fragment>\n}\n\nFormStep.StepPane = StepPane\nFormStep.createFormStep = createFormStep\n\nexport default FormStep\n"
  },
  {
    "path": "packages/antd/src/form-step/style.ts",
    "content": "import 'antd/lib/steps/style/index'\n"
  },
  {
    "path": "packages/antd/src/form-tab/index.tsx",
    "content": "import React, { Fragment, useMemo } from 'react'\nimport { Tabs, Badge } from 'antd'\nimport { model, markRaw } from '@formily/reactive'\nimport { TabPaneProps, TabsProps } from 'antd/lib/tabs'\nimport {\n  useField,\n  ReactFC,\n  observer,\n  useFieldSchema,\n  RecursionField,\n} from '@formily/react'\nimport { Schema, SchemaKey } from '@formily/json-schema'\nimport cls from 'classnames'\nimport { usePrefixCls } from '../__builtins__'\nexport interface IFormTab {\n  activeKey: string\n  setActiveKey(key: string): void\n}\n\nexport interface IFormTabProps extends TabsProps {\n  formTab?: IFormTab\n}\n\nexport interface IFormTabPaneProps extends TabPaneProps {\n  key: string | number\n}\n\ninterface IFeedbackBadgeProps {\n  name: SchemaKey\n  tab: React.ReactNode\n}\n\ntype ComposedFormTab = React.FC<React.PropsWithChildren<IFormTabProps>> & {\n  TabPane: React.FC<React.PropsWithChildren<IFormTabPaneProps>>\n  createFormTab: (defaultActiveKey?: string) => IFormTab\n}\n\nconst useTabs = () => {\n  const tabsField = useField()\n  const schema = useFieldSchema()\n  const tabs: { name: SchemaKey; props: any; schema: Schema }[] = []\n  schema.mapProperties((schema, name) => {\n    const field = tabsField.query(tabsField.address.concat(name)).take()\n    if (field?.display === 'none' || field?.display === 'hidden') return\n    if (schema['x-component']?.indexOf('TabPane') > -1) {\n      tabs.push({\n        name,\n        props: {\n          key: schema?.['x-component-props']?.key || name,\n          ...schema?.['x-component-props'],\n        },\n        schema,\n      })\n    }\n  })\n  return tabs\n}\n\nconst FeedbackBadge: ReactFC<IFeedbackBadgeProps> = observer((props) => {\n  const field = useField()\n  const errors = field.form.queryFeedbacks({\n    type: 'error',\n    address: `${field.address.concat(props.name)}.*`,\n  })\n  if (errors.length) {\n    return (\n      <Badge size=\"small\" className=\"errors-badge\" count={errors.length}>\n        {props.tab}\n      </Badge>\n    )\n  }\n  return <Fragment>{props.tab}</Fragment>\n})\n\nconst createFormTab = (defaultActiveKey?: string) => {\n  const formTab = model({\n    activeKey: defaultActiveKey,\n    setActiveKey(key: string) {\n      formTab.activeKey = key\n    },\n  })\n  return markRaw(formTab)\n}\n\nexport const FormTab: ComposedFormTab = observer(\n  ({ formTab, ...props }: IFormTabProps) => {\n    const tabs = useTabs()\n    const _formTab = useMemo(() => {\n      return formTab ? formTab : createFormTab()\n    }, [])\n    const prefixCls = usePrefixCls('formily-tab', props)\n    const activeKey = props.activeKey || _formTab?.activeKey\n\n    return (\n      <Tabs\n        {...props}\n        className={cls(prefixCls, props.className)}\n        activeKey={activeKey}\n        onChange={(key) => {\n          props.onChange?.(key)\n          _formTab?.setActiveKey?.(key)\n        }}\n      >\n        {tabs.map(({ props, schema, name }, key) => (\n          <Tabs.TabPane\n            key={key}\n            {...props}\n            tab={<FeedbackBadge name={name} tab={props.tab} />}\n            forceRender\n          >\n            <RecursionField schema={schema} name={name} />\n          </Tabs.TabPane>\n        ))}\n      </Tabs>\n    )\n  }\n) as unknown as ComposedFormTab\n\nconst TabPane: React.FC<React.PropsWithChildren<IFormTabPaneProps>> = ({\n  children,\n}) => {\n  return <Fragment>{children}</Fragment>\n}\n\nFormTab.TabPane = TabPane\nFormTab.createFormTab = createFormTab\n\nexport default FormTab\n"
  },
  {
    "path": "packages/antd/src/form-tab/style.ts",
    "content": "import 'antd/lib/tabs/style/index'\nimport 'antd/lib/badge/style/index'\n"
  },
  {
    "path": "packages/antd/src/index.ts",
    "content": "import './style'\nexport * from './array-base'\nexport * from './array-table'\nexport * from './array-tabs'\nexport * from './array-cards'\nexport * from './array-collapse'\nexport * from './array-items'\nexport * from './form-dialog'\nexport * from './form-drawer'\nexport * from './form'\nexport * from './form-item'\nexport * from './form-layout'\nexport * from './form-step'\nexport * from './form-grid'\nexport * from './form-tab'\nexport * from './form-collapse'\nexport * from './form-button-group'\nexport * from './input'\nexport * from './password'\nexport * from './cascader'\nexport * from './space'\nexport * from './preview-text'\nexport * from './radio'\nexport * from './checkbox'\nexport * from './select'\nexport * from './tree-select'\nexport * from './transfer'\nexport * from './date-picker'\nexport * from './time-picker'\nexport * from './number-picker'\nexport * from './switch'\nexport * from './upload'\nexport * from './submit'\nexport * from './reset'\nexport * from './editable'\nexport * from './select-table'\n"
  },
  {
    "path": "packages/antd/src/input/index.tsx",
    "content": "import React from 'react'\nimport { connect, mapProps, mapReadPretty } from '@formily/react'\nimport { Input as AntdInput } from 'antd'\nimport { InputProps, TextAreaProps } from 'antd/lib/input'\nimport { PreviewText } from '../preview-text'\nimport { LoadingOutlined } from '@ant-design/icons'\n\ntype ComposedInput = React.FC<React.PropsWithChildren<InputProps>> & {\n  TextArea?: React.FC<React.PropsWithChildren<TextAreaProps>>\n}\n\nexport const Input: ComposedInput = connect(\n  AntdInput,\n  mapProps((props, field) => {\n    return {\n      ...props,\n      suffix: (\n        <span>\n          {field?.['loading'] || field?.['validating'] ? (\n            <LoadingOutlined />\n          ) : (\n            props.suffix\n          )}\n        </span>\n      ),\n    }\n  }),\n  mapReadPretty(PreviewText.Input)\n)\n\nInput.TextArea = connect(AntdInput.TextArea, mapReadPretty(PreviewText.Input))\n\nexport default Input\n"
  },
  {
    "path": "packages/antd/src/input/style.ts",
    "content": "import 'antd/lib/input/style/index'\n"
  },
  {
    "path": "packages/antd/src/number-picker/index.tsx",
    "content": "import { connect, mapReadPretty } from '@formily/react'\nimport { InputNumber } from 'antd'\nimport { PreviewText } from '../preview-text'\n\nexport const NumberPicker = connect(\n  InputNumber,\n  mapReadPretty(PreviewText.NumberPicker)\n)\n\nexport default NumberPicker\n"
  },
  {
    "path": "packages/antd/src/number-picker/style.ts",
    "content": "import 'antd/lib/input-number/style/index'\n"
  },
  {
    "path": "packages/antd/src/password/PasswordStrength.tsx",
    "content": "import React, { Fragment } from 'react'\nimport { ReactFC } from '@formily/react'\nimport { isFn } from '@formily/shared'\n\ntype ReactRenderPropsChildren<T = any> =\n  | React.ReactNode\n  | ((props: T) => React.ReactElement)\n\ninterface IPasswordStrengthProps {\n  value?: React.ReactText\n  children?: ReactRenderPropsChildren<number>\n}\n\nconst isNum = function (c) {\n  return c >= 48 && c <= 57\n}\nconst isLower = function (c) {\n  return c >= 97 && c <= 122\n}\nconst isUpper = function (c) {\n  return c >= 65 && c <= 90\n}\nconst isSymbol = function (c) {\n  return !(isLower(c) || isUpper(c) || isNum(c))\n}\nconst isLetter = function (c) {\n  return isLower(c) || isUpper(c)\n}\n\nconst getStrength = (val) => {\n  if (!val) return 0\n  let num = 0\n  let lower = 0\n  let upper = 0\n  let symbol = 0\n  let MNS = 0\n  let rep = 0\n  let repC = 0\n  let consecutive = 0\n  let sequential = 0\n  const len = () => num + lower + upper + symbol\n  const callme = () => {\n    let re = num > 0 ? 1 : 0\n    re += lower > 0 ? 1 : 0\n    re += upper > 0 ? 1 : 0\n    re += symbol > 0 ? 1 : 0\n    if (re > 2 && len() >= 8) {\n      return re + 1\n    } else {\n      return 0\n    }\n  }\n  for (let i = 0; i < val.length; i++) {\n    const c = val.charCodeAt(i)\n    if (isNum(c)) {\n      num++\n      if (i !== 0 && i !== val.length - 1) {\n        MNS++\n      }\n      if (i > 0 && isNum(val.charCodeAt(i - 1))) {\n        consecutive++\n      }\n    } else if (isLower(c)) {\n      lower++\n      if (i > 0 && isLower(val.charCodeAt(i - 1))) {\n        consecutive++\n      }\n    } else if (isUpper(c)) {\n      upper++\n      if (i > 0 && isUpper(val.charCodeAt(i - 1))) {\n        consecutive++\n      }\n    } else {\n      symbol++\n      if (i !== 0 && i !== val.length - 1) {\n        MNS++\n      }\n    }\n    let exists = false\n    for (let j = 0; j < val.length; j++) {\n      if (val[i] === val[j] && i !== j) {\n        exists = true\n        repC += Math.abs(val.length / (j - i))\n      }\n    }\n    if (exists) {\n      rep++\n      const unique = val.length - rep\n      repC = unique ? Math.ceil(repC / unique) : Math.ceil(repC)\n    }\n    if (i > 1) {\n      const last1 = val.charCodeAt(i - 1)\n      const last2 = val.charCodeAt(i - 2)\n      if (isLetter(c)) {\n        if (isLetter(last1) && isLetter(last2)) {\n          const v = val.toLowerCase()\n          const vi = v.charCodeAt(i)\n          const vi1 = v.charCodeAt(i - 1)\n          const vi2 = v.charCodeAt(i - 2)\n          if (vi - vi1 === vi1 - vi2 && Math.abs(vi - vi1) === 1) {\n            sequential++\n          }\n        }\n      } else if (isNum(c)) {\n        if (isNum(last1) && isNum(last2)) {\n          if (c - last1 === last1 - last2 && Math.abs(c - last1) === 1) {\n            sequential++\n          }\n        }\n      } else {\n        if (isSymbol(last1) && isSymbol(last2)) {\n          if (c - last1 === last1 - last2 && Math.abs(c - last1) === 1) {\n            sequential++\n          }\n        }\n      }\n    }\n  }\n  let sum = 0\n  const length = len()\n  sum += 4 * length\n  if (lower > 0) {\n    sum += 2 * (length - lower)\n  }\n  if (upper > 0) {\n    sum += 2 * (length - upper)\n  }\n  if (num !== length) {\n    sum += 4 * num\n  }\n  sum += 6 * symbol\n  sum += 2 * MNS\n  sum += 2 * callme()\n  if (length === lower + upper) {\n    sum -= length\n  }\n  if (length === num) {\n    sum -= num\n  }\n  sum -= repC\n  sum -= 2 * consecutive\n  sum -= 3 * sequential\n  sum = sum < 0 ? 0 : sum\n  sum = sum > 100 ? 100 : sum\n\n  if (sum >= 80) {\n    return 100\n  } else if (sum >= 60) {\n    return 80\n  } else if (sum >= 40) {\n    return 60\n  } else if (sum >= 20) {\n    return 40\n  } else {\n    return 20\n  }\n}\n\nexport const PasswordStrength: ReactFC<IPasswordStrengthProps> = (props) => {\n  if (isFn(props.children)) {\n    return props.children(getStrength(String(props.value)))\n  } else {\n    return <Fragment>{props.children}</Fragment>\n  }\n}\n"
  },
  {
    "path": "packages/antd/src/password/index.tsx",
    "content": "import React from 'react'\nimport { connect, mapReadPretty } from '@formily/react'\nimport { Input } from 'antd'\nimport { PasswordProps } from 'antd/lib/input'\nimport { PasswordStrength } from './PasswordStrength'\nimport { PreviewText } from '../preview-text'\n\nexport interface IPasswordProps extends PasswordProps {\n  checkStrength: boolean\n}\n\nexport const Password = connect((props: IPasswordProps) => {\n  const { value, className, checkStrength, ...others } = props\n  const blockStyle: React.CSSProperties = {\n    position: 'absolute',\n    zIndex: 1,\n    height: 8,\n    top: 0,\n    background: '#fff',\n    width: 1,\n    transform: 'translate(-50%, 0)',\n  }\n  return (\n    <span className={className}>\n      <Input.Password {...others} value={value} />\n      {checkStrength && (\n        <PasswordStrength value={String(value)}>\n          {(score) => {\n            return (\n              <div\n                style={{\n                  background: '#e0e0e0',\n                  marginBottom: 3,\n                  position: 'relative',\n                }}\n              >\n                <div style={{ ...blockStyle, left: '20%' }} />\n                <div style={{ ...blockStyle, left: '40%' }} />\n                <div style={{ ...blockStyle, left: '60%' }} />\n                <div style={{ ...blockStyle, left: '80%' }} />\n                <div\n                  style={{\n                    position: 'relative',\n                    backgroundImage:\n                      '-webkit-linear-gradient(left, #ff5500, #ff9300)',\n                    transition: 'all 0.35s ease-in-out',\n                    height: 8,\n                    width: '100%',\n                    marginTop: 5,\n                    clipPath: `polygon(0 0,${score}% 0,${score}% 100%,0 100%)`,\n                  }}\n                />\n              </div>\n            )\n          }}\n        </PasswordStrength>\n      )}\n    </span>\n  )\n}, mapReadPretty(PreviewText.Input))\n\nexport default Password\n"
  },
  {
    "path": "packages/antd/src/password/style.ts",
    "content": "import 'antd/lib/input/style/index'\n"
  },
  {
    "path": "packages/antd/src/preview-text/index.tsx",
    "content": "import React, { createContext, useContext } from 'react'\nimport { isArr, toArr, isValid } from '@formily/shared'\nimport { Field } from '@formily/core'\nimport { observer, useField } from '@formily/react'\nimport { InputProps } from 'antd/lib/input'\nimport { InputNumberProps } from 'antd/lib/input-number'\nimport { SelectProps } from 'antd/lib/select'\nimport { TreeSelectProps } from 'antd/lib/tree-select'\nimport { CascaderProps, DefaultOptionType } from 'antd/lib/cascader'\nimport {\n  DatePickerProps,\n  RangePickerProps as DateRangePickerProps,\n} from 'antd/lib/date-picker'\nimport { TimePickerProps, TimeRangePickerProps } from 'antd/lib/time-picker'\nimport { Tag, Space } from 'antd'\nimport cls from 'classnames'\nimport { formatMomentValue, usePrefixCls } from '../__builtins__'\n\nconst PlaceholderContext = createContext<React.ReactNode>('N/A')\n\nconst Placeholder = PlaceholderContext.Provider\n\nconst usePlaceholder = (value?: any) => {\n  const placeholder = useContext(PlaceholderContext) || 'N/A'\n  return isValid(value) && value !== '' ? value : placeholder\n}\n\nconst Input: React.FC<React.PropsWithChildren<InputProps>> = (props) => {\n  const prefixCls = usePrefixCls('form-text', props)\n  return (\n    <Space className={cls(prefixCls, props.className)} style={props.style}>\n      {props.addonBefore}\n      {props.prefix}\n      {usePlaceholder(props.value)}\n      {props.suffix}\n      {props.addonAfter}\n    </Space>\n  )\n}\n\nconst NumberPicker: React.FC<React.PropsWithChildren<InputNumberProps>> = (\n  props\n) => {\n  const prefixCls = usePrefixCls('form-text', props)\n  return (\n    <Space className={cls(prefixCls, props.className)} style={props.style}>\n      {props.addonBefore}\n      {props.prefix}\n      {usePlaceholder(\n        props.formatter\n          ? props.formatter(String(props.value), {\n              userTyping: false,\n              input: '',\n            })\n          : props.value\n      )}\n      {props['suffix']}\n      {props.addonAfter}\n    </Space>\n  )\n}\n\nconst Select: React.FC<React.PropsWithChildren<SelectProps<any>>> = observer(\n  (props) => {\n    const field = useField<Field>()\n    const prefixCls = usePrefixCls('form-text', props)\n    const dataSource: any[] = field?.dataSource?.length\n      ? field.dataSource\n      : props?.options?.length\n      ? props.options\n      : []\n    const placeholder = usePlaceholder()\n    const getSelected = () => {\n      const value = props.value\n      if (props.mode === 'multiple' || props.mode === 'tags') {\n        if (props.labelInValue) {\n          return isArr(value) ? value : []\n        } else {\n          return isArr(value)\n            ? value.map((val) => ({ label: val, value: val }))\n            : []\n        }\n      } else {\n        if (props.labelInValue) {\n          return isValid(value) ? [value] : []\n        } else {\n          return isValid(value) ? [{ label: value, value }] : []\n        }\n      }\n    }\n\n    const getLabel = (target: any) => {\n      const labelKey = props.fieldNames?.label || 'label'\n      return (\n        dataSource?.find((item) => {\n          const valueKey = props.fieldNames?.value || 'value'\n          return item[valueKey] == target?.value\n        })?.[labelKey] ||\n        target.label ||\n        placeholder\n      )\n    }\n\n    const getLabels = () => {\n      const selected = getSelected()\n      if (!selected.length) return placeholder\n      if (selected.length === 1) return getLabel(selected[0])\n      return selected.map((item, key) => {\n        return <Tag key={key}>{getLabel(item)}</Tag>\n      })\n    }\n    return (\n      <div className={cls(prefixCls, props.className)} style={props.style}>\n        {getLabels()}\n      </div>\n    )\n  }\n)\n\nconst TreeSelect: React.FC<React.PropsWithChildren<TreeSelectProps<any>>> =\n  observer((props) => {\n    const field = useField<Field>()\n    const placeholder = usePlaceholder()\n    const prefixCls = usePrefixCls('form-text', props)\n    const dataSource = field?.dataSource?.length\n      ? field.dataSource\n      : props?.treeData?.length\n      ? props.treeData\n      : []\n    const getSelected = () => {\n      const value = props.value\n      if (props.multiple) {\n        if (props.labelInValue) {\n          return isArr(value) ? value : []\n        } else {\n          return isArr(value)\n            ? value.map((val) => ({ label: val, value: val }))\n            : []\n        }\n      } else {\n        if (props.labelInValue) {\n          return value ? [value] : []\n        } else {\n          return value ? [{ label: value, value }] : []\n        }\n      }\n    }\n\n    const findLabel = (\n      value: any,\n      dataSource: any[],\n      treeNodeLabelProp?: string\n    ) => {\n      for (let i = 0; i < dataSource?.length; i++) {\n        const item = dataSource[i]\n        if (item?.value === value) {\n          return item?.label ?? item[treeNodeLabelProp]\n        } else {\n          const childLabel = findLabel(value, item?.children, treeNodeLabelProp)\n          if (childLabel) return childLabel\n        }\n      }\n    }\n\n    const getLabels = () => {\n      const selected = getSelected()\n      if (!selected?.length) return <Tag>{placeholder}</Tag>\n      return selected.map(({ value, label }, key) => {\n        return (\n          <Tag key={key}>\n            {findLabel(value, dataSource, props.treeNodeLabelProp) ||\n              label ||\n              placeholder}\n          </Tag>\n        )\n      })\n    }\n    return (\n      <div className={cls(prefixCls, props.className)} style={props.style}>\n        {getLabels()}\n      </div>\n    )\n  })\n\nconst Cascader: React.FC<React.PropsWithChildren<CascaderProps<any>>> =\n  observer((props) => {\n    const field = useField<Field>()\n    const placeholder = usePlaceholder()\n    const prefixCls = usePrefixCls('form-text', props)\n    const dataSource: any[] = field?.dataSource?.length\n      ? field.dataSource\n      : props?.options?.length\n      ? props.options\n      : []\n    const findSelectedItem = (\n      items: DefaultOptionType[],\n      val: string | number\n    ) => {\n      return items.find((item) => item.value == val)\n    }\n    const findSelectedItems = (\n      sources: DefaultOptionType[],\n      selectedValues: Array<string[] | number[]>\n    ): Array<any[]> => {\n      return selectedValues.map((value) => {\n        const result: Array<DefaultOptionType> = []\n        let items = sources\n        value.forEach((val) => {\n          const selectedItem = findSelectedItem(items, val)\n          result.push({\n            label: selectedItem?.label ?? '',\n            value: selectedItem?.value,\n          })\n          items = selectedItem?.children ?? []\n        })\n        return result\n      })\n    }\n    const getSelected = () => {\n      const val = toArr(props.value)\n      // unified conversion to multi selection mode\n      return props.multiple ? val : [val]\n    }\n    const getLabels = () => {\n      const selected = getSelected()\n      const values = findSelectedItems(dataSource, selected)\n      const labels = values\n        .map((val: Array<DefaultOptionType>) => {\n          return val.map((item) => item.label).join('/')\n        })\n        .join(' ')\n      return labels || placeholder\n    }\n    return (\n      <div className={cls(prefixCls, props.className)} style={props.style}>\n        {getLabels()}\n      </div>\n    )\n  })\n\nconst DatePicker: React.FC<React.PropsWithChildren<DatePickerProps>> = (\n  props\n) => {\n  const placeholder = usePlaceholder()\n  const prefixCls = usePrefixCls('form-text', props)\n  const getLabels = () => {\n    const labels = formatMomentValue(props.value, props.format, placeholder)\n    return isArr(labels) ? labels.join('~') : labels\n  }\n  return <div className={cls(prefixCls, props.className)}>{getLabels()}</div>\n}\n\nconst DateRangePicker: React.FC<\n  React.PropsWithChildren<DateRangePickerProps>\n> = (props) => {\n  const placeholder = usePlaceholder()\n  const prefixCls = usePrefixCls('form-text', props)\n  const getLabels = () => {\n    const labels = formatMomentValue(props.value, props.format, placeholder)\n    return isArr(labels) ? labels.join('~') : labels\n  }\n  return (\n    <div className={cls(prefixCls, props.className)} style={props.style}>\n      {getLabels()}\n    </div>\n  )\n}\n\nconst TimePicker: React.FC<React.PropsWithChildren<TimePickerProps>> = (\n  props\n) => {\n  const placeholder = usePlaceholder()\n  const prefixCls = usePrefixCls('form-text', props)\n  const getLabels = () => {\n    const labels = formatMomentValue(props.value, props.format, placeholder)\n    return isArr(labels) ? labels.join('~') : labels\n  }\n  return (\n    <div className={cls(prefixCls, props.className)} style={props.style}>\n      {getLabels()}\n    </div>\n  )\n}\n\nconst TimeRangePicker: React.FC<\n  React.PropsWithChildren<TimeRangePickerProps>\n> = (props) => {\n  const placeholder = usePlaceholder()\n  const prefixCls = usePrefixCls('form-text', props)\n  const getLabels = () => {\n    const labels = formatMomentValue(props.value, props.format, placeholder)\n    return isArr(labels) ? labels.join('~') : labels\n  }\n  return (\n    <div className={cls(prefixCls, props.className)} style={props.style}>\n      {getLabels()}\n    </div>\n  )\n}\n\nconst Text = (props: React.PropsWithChildren<any>) => {\n  const prefixCls = usePrefixCls('form-text', props)\n\n  return (\n    <div className={cls(prefixCls, props.className)} style={props.style}>\n      {usePlaceholder(props.value)}\n    </div>\n  )\n}\n\nText.Input = Input\nText.Select = Select\nText.TreeSelect = TreeSelect\nText.Cascader = Cascader\nText.DatePicker = DatePicker\nText.DateRangePicker = DateRangePicker\nText.TimePicker = TimePicker\nText.TimeRangePicker = TimeRangePicker\nText.Placeholder = Placeholder\nText.usePlaceholder = usePlaceholder\nText.NumberPicker = NumberPicker\n\nexport const PreviewText = Text\n\nexport default PreviewText\n"
  },
  {
    "path": "packages/antd/src/preview-text/style.less",
    "content": "@root-entry-name: 'default';\n@import (reference) '~antd/es/style/themes/index.less';\n\n@form-text-prefix-cls: ~'@{ant-prefix}-form-text';\n\n.@{form-text-prefix-cls} {\n  font-size: 14px;\n  font-weight: 500;\n\n  .@{ant-prefix}-tag:last-child {\n    margin-right: 0;\n  }\n}\n"
  },
  {
    "path": "packages/antd/src/preview-text/style.ts",
    "content": "import 'antd/lib/tag/style/index'\nimport './style.less'\n"
  },
  {
    "path": "packages/antd/src/radio/index.tsx",
    "content": "import { connect, mapProps, mapReadPretty } from '@formily/react'\nimport { Radio as AntdRadio } from 'antd'\nimport { RadioProps, RadioGroupProps } from 'antd/lib/radio'\nimport { PreviewText } from '../preview-text'\n\ntype ComposedRadio = React.FC<React.PropsWithChildren<RadioProps>> & {\n  Group?: React.FC<React.PropsWithChildren<RadioGroupProps>>\n  __ANT_RADIO?: boolean\n}\n\nexport const Radio: ComposedRadio = connect(\n  AntdRadio,\n  mapProps({\n    value: 'checked',\n  })\n)\n\nRadio.__ANT_RADIO = true\n\nRadio.Group = connect(\n  AntdRadio.Group,\n  mapProps({\n    dataSource: 'options',\n  }),\n  mapReadPretty(PreviewText.Select)\n)\n\nexport default Radio\n"
  },
  {
    "path": "packages/antd/src/radio/style.less",
    "content": "@root-entry-name: 'default';\n@import (reference) '~antd/es/style/themes/index.less';\n"
  },
  {
    "path": "packages/antd/src/radio/style.ts",
    "content": "import 'antd/lib/radio/style/index'\nimport './style.less'\n"
  },
  {
    "path": "packages/antd/src/reset/index.tsx",
    "content": "import React from 'react'\nimport { Button } from 'antd'\nimport { ButtonProps } from 'antd/lib/button'\nimport { IFieldResetOptions, IFormFeedback } from '@formily/core'\nimport { useParentForm } from '@formily/react'\n\nexport interface IResetProps extends IFieldResetOptions, ButtonProps {\n  onClick?: (e: React.MouseEvent<Element, MouseEvent>) => any\n  onResetValidateSuccess?: (payload: any) => void\n  onResetValidateFailed?: (feedbacks: IFormFeedback[]) => void\n}\n\nexport const Reset: React.FC<React.PropsWithChildren<IResetProps>> = ({\n  forceClear,\n  validate,\n  onResetValidateSuccess,\n  onResetValidateFailed,\n  ...props\n}) => {\n  const form = useParentForm()\n  return (\n    <Button\n      {...props}\n      onClick={(e) => {\n        if (props.onClick) {\n          if (props.onClick(e) === false) return\n        }\n        form\n          .reset('*', {\n            forceClear,\n            validate,\n          })\n          .then(onResetValidateSuccess)\n          .catch(onResetValidateFailed)\n      }}\n    >\n      {props.children}\n    </Button>\n  )\n}\n\nexport default Reset\n"
  },
  {
    "path": "packages/antd/src/reset/style.ts",
    "content": "import 'antd/lib/button/style/index'\n"
  },
  {
    "path": "packages/antd/src/select/index.tsx",
    "content": "import React from 'react'\nimport { connect, mapReadPretty, mapProps, ReactFC } from '@formily/react'\nimport { Select as AntdSelect } from 'antd'\nimport { SelectProps } from 'antd/lib/select'\nimport { PreviewText } from '../preview-text'\nimport { LoadingOutlined } from '@ant-design/icons'\n\nexport const Select: ReactFC<SelectProps<any, any>> = connect(\n  AntdSelect,\n  mapProps(\n    {\n      dataSource: 'options',\n      loading: true,\n    },\n    (props, field) => {\n      return {\n        ...props,\n        suffixIcon:\n          field?.['loading'] || field?.['validating'] ? (\n            <LoadingOutlined />\n          ) : (\n            props.suffixIcon\n          ),\n      }\n    }\n  ),\n  mapReadPretty(PreviewText.Select)\n)\n\nexport default Select\n"
  },
  {
    "path": "packages/antd/src/select/style.ts",
    "content": "import 'antd/lib/select/style/index'\n"
  },
  {
    "path": "packages/antd/src/select-table/index.tsx",
    "content": "import React, { useState, useMemo } from 'react'\nimport {\n  observer,\n  useFieldSchema,\n  useField,\n  Schema,\n  RecursionField,\n} from '@formily/react'\nimport cls from 'classnames'\nimport { GeneralField, FieldDisplayTypes } from '@formily/core'\nimport { isArr, isBool, isFn } from '@formily/shared'\nimport { Input, Table } from 'antd'\nimport { TableProps, ColumnProps } from 'antd/lib/table'\nimport { SearchProps } from 'antd/lib/input'\nimport { useFilterOptions } from './useFilterOptions'\nimport { useFlatOptions } from './useFlatOptions'\nimport { useSize } from './useSize'\nimport { useTitleAddon } from './useTitleAddon'\nimport { useCheckSlackly, getIndeterminate } from './useCheckSlackly'\nimport { getUISelected, getOutputData } from './utils'\nimport { usePrefixCls } from '../__builtins__'\n\nconst { Search } = Input\n\ninterface ObservableColumnSource {\n  field: GeneralField\n  columnProps: ColumnProps<any>\n  schema: Schema\n  display: FieldDisplayTypes\n  name: string\n}\n\ntype IFilterOption = boolean | ((option: any, keyword: string) => boolean)\n\ntype IFilterSort = (optionA: any, optionB: any) => number\n\nexport interface ISelectTableColumnProps extends ColumnProps<any> {\n  key: React.ReactText\n}\n\nexport interface ISelectTableProps extends TableProps<any> {\n  mode?: 'multiple' | 'single'\n  dataSource?: any[]\n  optionAsValue?: boolean\n  valueType?: 'all' | 'parent' | 'child' | 'path'\n  showSearch?: boolean\n  searchProps?: SearchProps\n  primaryKey?: string | ((record: any) => string)\n  filterOption?: IFilterOption\n  filterSort?: IFilterSort\n  onSearch?: (keyword: string) => void\n  onChange?: (value: any, options: any) => void\n  value?: any\n}\n\ntype ComposedSelectTable = React.FC<\n  React.PropsWithChildren<ISelectTableProps>\n> & {\n  Column?: React.FC<React.PropsWithChildren<ISelectTableColumnProps>>\n}\n\nconst isColumnComponent = (schema: Schema) => {\n  return schema['x-component']?.indexOf('Column') > -1\n}\n\nconst useSources = () => {\n  const arrayField = useField()\n  const schema = useFieldSchema()\n  const parseSources = (schema: Schema): ObservableColumnSource[] => {\n    if (isColumnComponent(schema)) {\n      if (!schema['x-component-props']?.['dataIndex'] && !schema['name'])\n        return []\n      const name = schema['x-component-props']?.['dataIndex'] || schema['name']\n      const field = arrayField.query(arrayField.address.concat(name)).take()\n      const columnProps =\n        field?.component?.[1] || schema['x-component-props'] || {}\n      const display = field?.display || schema['x-display']\n      return [\n        {\n          name,\n          display,\n          field,\n          schema,\n          columnProps: {\n            title: field?.title || columnProps.title,\n            ...columnProps,\n          },\n        },\n      ]\n    } else if (schema.properties) {\n      return schema.reduceProperties((buf, schema) => {\n        return buf.concat(parseSources(schema))\n      }, [])\n    }\n  }\n\n  const parseArrayItems = (schema: Schema['items']) => {\n    if (!schema) return []\n    const sources: ObservableColumnSource[] = []\n    const items = isArr(schema) ? schema : [schema]\n    return items.reduce((columns, schema) => {\n      const item = parseSources(schema)\n      if (item) {\n        return columns.concat(item)\n      }\n      return columns\n    }, sources)\n  }\n\n  const validSchema = (\n    schema?.type === 'array' && schema?.items ? schema.items : schema\n  ) as Schema\n\n  return parseArrayItems(validSchema)\n}\n\nconst useColumns = (\n  sources: ObservableColumnSource[]\n): TableProps<any>['columns'] => {\n  return sources.reduce((buf, { name, columnProps, schema, display }, key) => {\n    if (display !== 'visible') return buf\n    if (!isColumnComponent(schema)) return buf\n    return buf.concat({\n      ...columnProps,\n      key,\n      dataIndex: name,\n    })\n  }, [])\n}\n\nconst addPrimaryKey = (dataSource, rowKey, primaryKey) =>\n  dataSource.map((item) => {\n    const children = isArr(item.children)\n      ? addPrimaryKey(item.children, rowKey, primaryKey)\n      : {}\n    return {\n      ...item,\n      ...children,\n      [primaryKey]: rowKey(item),\n    }\n  })\n\nexport const SelectTable: ComposedSelectTable = observer((props) => {\n  const {\n    mode = 'multiple',\n    dataSource: propsDataSource,\n    optionAsValue,\n    valueType = 'all',\n    showSearch = false,\n    filterOption,\n    filterSort,\n    onSearch,\n    searchProps,\n    className,\n    value,\n    onChange,\n    rowSelection,\n    primaryKey: rowKey = 'key',\n    ...otherTableProps\n  } = props\n  const prefixCls = usePrefixCls('formily-select-table', props)\n  const [searchValue, setSearchValue] = useState<string>()\n  const field = useField() as any\n  const loading = isBool(props.loading) ? props.loading : field.loading\n  const disabled = field.disabled\n  const readOnly = field.readOnly\n  const readPretty = field.readPretty\n  const { searchSize, tableSize } = useSize(\n    field.decoratorProps?.size,\n    searchProps?.size,\n    props?.size\n  )\n  const primaryKey = isFn(rowKey) ? '__formily_key__' : rowKey\n  const sources = useSources()\n  const columns = useColumns(sources)\n\n  // dataSource\n  let dataSource = isArr(propsDataSource) ? propsDataSource : field.dataSource\n  dataSource = isFn(rowKey)\n    ? addPrimaryKey(dataSource, rowKey, primaryKey)\n    : dataSource\n\n  // Filter dataSource By Search\n  const filteredDataSource = useFilterOptions(\n    dataSource,\n    searchValue,\n    filterOption,\n    rowSelection?.checkStrictly\n  )\n\n  // Order dataSource By filterSort\n  const orderedFilteredDataSource = useMemo(() => {\n    if (!filterSort) {\n      return filteredDataSource\n    }\n    return [...filteredDataSource].sort((a, b) => filterSort(a, b))\n  }, [filteredDataSource, filterSort])\n\n  const flatDataSource = useFlatOptions(dataSource)\n  const flatFilteredDataSource = useFlatOptions(filteredDataSource)\n\n  // 分页或异步查询时，dataSource会丢失已选数据，配置optionAsValue则无法获取已选数据，需要进行合并\n  const getWholeDataSource = () => {\n    if (optionAsValue && mode === 'multiple' && value?.length) {\n      const map = new Map()\n      const arr = [...flatDataSource, ...value]\n      arr.forEach((item) => {\n        if (!map.has(item[primaryKey])) {\n          map.set(item[primaryKey], item)\n        }\n      })\n      return [...map.values()]\n    }\n    return flatDataSource\n  }\n\n  // selected keys for Table UI\n  const selected = getUISelected(\n    value,\n    flatDataSource,\n    primaryKey,\n    valueType,\n    optionAsValue,\n    mode,\n    rowSelection?.checkStrictly,\n    rowKey\n  )\n\n  // readPretty Value\n  const readPrettyDataSource = useFilterOptions(\n    orderedFilteredDataSource,\n    selected,\n    (value, item) => value.includes(item[primaryKey])\n  )\n\n  const onInnerSearch = (searchText) => {\n    const formatted = (searchText || '').trim()\n    setSearchValue(searchText)\n    onSearch?.(formatted)\n  }\n\n  const onInnerChange = (selectedRowKeys: any[]) => {\n    if (readOnly) {\n      return\n    }\n    // 筛选后onChange默认的records数据不完整，此处需使用完整数据过滤\n    const wholeRecords = getWholeDataSource().filter((item) =>\n      selectedRowKeys.includes(item?.[primaryKey])\n    )\n    const { outputValue, outputOptions } = getOutputData(\n      selectedRowKeys,\n      wholeRecords,\n      dataSource,\n      primaryKey,\n      valueType,\n      optionAsValue,\n      mode,\n      rowSelection?.checkStrictly\n    )\n\n    onChange?.(outputValue, outputOptions)\n  }\n\n  const onRowClick = (record) => {\n    if (readPretty || disabled || readOnly || record?.disabled) {\n      return\n    }\n    const selectedRowKey = record?.[primaryKey]\n    const isSelected = selected?.includes(selectedRowKey)\n    let selectedRowKeys = []\n    if (mode === 'single') {\n      selectedRowKeys = [selectedRowKey]\n    } else {\n      if (isSelected) {\n        selectedRowKeys = selected.filter((item) => item !== selectedRowKey)\n      } else {\n        selectedRowKeys = [...selected, selectedRowKey]\n      }\n    }\n    if (rowSelection?.checkStrictly !== false) {\n      onInnerChange(selectedRowKeys)\n    } else {\n      onSlacklyChange(selectedRowKeys)\n    }\n  }\n\n  // TreeData SlacklyChange\n  const onSlacklyChange = (currentSelected: any[]) => {\n    let { selectedRowKeys } = useCheckSlackly(\n      currentSelected,\n      selected,\n      flatDataSource,\n      flatFilteredDataSource,\n      primaryKey,\n      rowSelection?.checkStrictly\n    )\n    onInnerChange(selectedRowKeys)\n  }\n\n  // Table All Checkbox\n  const titleAddon = useTitleAddon(\n    selected,\n    flatDataSource,\n    flatFilteredDataSource,\n    primaryKey,\n    mode,\n    disabled,\n    readOnly,\n    rowSelection?.checkStrictly,\n    onInnerChange\n  )\n\n  // Antd rowSelection type\n  const modeAsType: any = { multiple: 'checkbox', single: 'radio' }?.[mode]\n\n  return (\n    <div className={prefixCls}>\n      {showSearch ? (\n        <Search\n          {...searchProps}\n          className={cls(`${prefixCls}-search`, searchProps?.className)}\n          style={{ width: '100%', ...searchProps?.style }}\n          onSearch={onInnerSearch}\n          onChange={(e) => onInnerSearch(e.target.value)}\n          disabled={disabled}\n          readOnly={readOnly}\n          size={searchSize}\n          loading={loading} // antd\n        />\n      ) : null}\n      <Table\n        {...otherTableProps}\n        className={cls(`${prefixCls}-table`, className)}\n        dataSource={\n          readPretty ? readPrettyDataSource : orderedFilteredDataSource\n        }\n        rowSelection={\n          readPretty\n            ? undefined\n            : ({\n                ...rowSelection,\n                ...titleAddon,\n                getCheckboxProps: (record) => ({\n                  ...(rowSelection?.getCheckboxProps?.(record) as any),\n                  disabled: disabled || record?.disabled,\n                }), // antd\n                ...(rowSelection?.checkStrictly !== false\n                  ? {}\n                  : {\n                      renderCell: (checked, record, index, originNode) => {\n                        return React.cloneElement(\n                          originNode as React.ReactElement,\n                          {\n                            indeterminate: getIndeterminate(\n                              record,\n                              flatDataSource,\n                              selected,\n                              primaryKey\n                            ),\n                          }\n                        )\n                      },\n                    }),\n                selectedRowKeys: selected,\n                onChange:\n                  rowSelection?.checkStrictly !== false\n                    ? onInnerChange\n                    : onSlacklyChange,\n                type: modeAsType,\n                preserveSelectedRowKeys: true,\n                checkStrictly: true,\n              } as any)\n        }\n        columns={props.columns || columns}\n        rowKey={primaryKey}\n        loading={loading}\n        size={tableSize}\n        onRow={(record) => {\n          // antd\n          const onRowResult = otherTableProps.onRow?.(record)\n          return {\n            ...onRowResult,\n            onClick: (e) => {\n              onRowResult?.onClick?.(e)\n              onRowClick(record)\n            },\n          }\n        }}\n      >\n        {''}\n      </Table>\n      {sources.map((column, key) => {\n        //专门用来承接对Column的状态管理\n        if (!isColumnComponent(column.schema)) return\n        return React.createElement(RecursionField, {\n          name: column.name,\n          schema: column.schema,\n          onlyRenderSelf: true,\n          key,\n        })\n      })}\n    </div>\n  )\n})\n\nconst TableColumn: React.FC<\n  React.PropsWithChildren<ISelectTableColumnProps>\n> = () => <></>\n\nSelectTable.Column = TableColumn\n\nexport default SelectTable\n"
  },
  {
    "path": "packages/antd/src/select-table/style.less",
    "content": "@root-entry-name: 'default';\n@import (reference) '~antd/es/style/themes/index.less';\n\n@select-table-prefix-cls: ~'@{ant-prefix}-formily-select-table';\n\n.@{select-table-prefix-cls} {\n  .@{select-table-prefix-cls}-search {\n    margin-bottom: 8px;\n  }\n}\n"
  },
  {
    "path": "packages/antd/src/select-table/style.ts",
    "content": "import 'antd/lib/radio/style/index'\nimport './style.less'\n"
  },
  {
    "path": "packages/antd/src/select-table/useCheckSlackly.tsx",
    "content": "import {\n  getTreeKeys,\n  hasSelectedKey,\n  completedKeys,\n  getCompatibleAllSelected,\n} from './utils'\n\n/**\n * 判断该字段的 indeterminate 属性\n * @param record 当前字段\n * @param flatDataSource 完整平铺数据\n * @param selected 已选中的字段值集合\n * @param primaryKey 键名称\n * @returns indeterminate 属性值\n */\nconst getIndeterminate = (\n  record: any,\n  flatDataSource: any,\n  selected: any[],\n  primaryKey: string\n) => {\n  if (selected?.includes(record[primaryKey])) {\n    return undefined\n  }\n  const wholeRecord = flatDataSource.find(\n    (item) => item[primaryKey] === record[primaryKey]\n  )\n  return hasSelectedKey(wholeRecord.children, selected, primaryKey) || undefined\n}\n\ninterface ICheckSlackly {\n  (\n    currentSelected: any[],\n    selected: any[],\n    flatDataSource: any[],\n    flatFilteredDataSource: any[],\n    primaryKey: string,\n    checkStrictly: boolean\n  ): { selectedRowKeys: any[] }\n}\n\n// 父子节点（节点状态按全完整数据计算，节点操作按筛选数据计算）\nconst useCheckSlackly: ICheckSlackly = (\n  currentSelected, // onChange 返回的 keys\n  selected, // Table UI 展示的 keys\n  flatDataSource,\n  flatFilteredDataSource,\n  primaryKey,\n  checkStrictly\n) => {\n  let isSelected = currentSelected.length > selected.length // 判断是选中还是取消\n\n  const currentKey = [...currentSelected, ...selected].find(\n    (key) => !(currentSelected.includes(key) && selected.includes(key)) // 当前变化key不同时存在于两个selected\n  )\n  // 从过滤后的数据中获取当前record\n  const currentRecord = flatFilteredDataSource.find(\n    (item) => item[primaryKey] === currentKey\n  )\n  const currentTreeKeys = getTreeKeys(currentRecord.children, primaryKey)\n\n  // 在筛选状态下（按钮的indeterminate状态处于异常）需要通过数据对比判断是否处于全选中状态\n  if (\n    getCompatibleAllSelected(\n      selected,\n      currentRecord.children,\n      currentTreeKeys,\n      checkStrictly,\n      primaryKey\n    )\n  ) {\n    isSelected = false\n  }\n\n  let newSelected = []\n  if (isSelected) {\n    // 选中当前key及其子keys\n    newSelected = [...new Set([...selected, currentKey, ...currentTreeKeys])]\n  } else {\n    // 移除当前key及其子keys\n    newSelected = selected.filter(\n      (key) => ![currentKey, ...currentTreeKeys].includes(key)\n    )\n  }\n\n  newSelected = completedKeys(flatDataSource, newSelected, primaryKey)\n\n  return { selectedRowKeys: newSelected }\n}\n\nexport { useCheckSlackly, getIndeterminate }\n"
  },
  {
    "path": "packages/antd/src/select-table/useFilterOptions.tsx",
    "content": "import * as React from 'react'\nimport { isFn, isArr } from '@formily/shared'\n\ntype IFilterOption = boolean | ((option: any, keyword: string) => boolean)\n\nfunction includes(test: React.ReactNode, search: string) {\n  return toArray(test).join('').toUpperCase().includes(search)\n}\n\nfunction includesOption(option: any, search: string) {\n  const searched = new Set()\n  const _includesOption = (option: any) => {\n    const keys = Object.keys(option || {})\n    return keys.some((key) => {\n      if (key === '__level') {\n        return false\n      }\n      const value = option[key]\n      if (React.isValidElement(value)) return false\n      if (key !== 'children' && !searched.has(value)) {\n        if (typeof value === 'object') {\n          searched.add(value)\n          return _includesOption(value)\n        }\n        return includes(value, search)\n      }\n      return false\n    })\n  }\n  return _includesOption(option)\n}\n\nfunction toArray<T>(value: T | T[]): T[] {\n  if (isArr(value)) {\n    return value\n  }\n  return value !== undefined ? [value] : []\n}\n\nconst useFilterOptions = (\n  options: any[],\n  searchValue?: string | string[],\n  filterOption?: IFilterOption,\n  checkStrictly?: boolean\n) =>\n  React.useMemo(() => {\n    if (!searchValue || filterOption === false) {\n      return options\n    }\n    const filterFunc = isFn(filterOption)\n      ? filterOption\n      : (value: any, option: any) => includesOption(option, value.toUpperCase())\n\n    const doFilter = (arr: any[]) => {\n      const filterArr: any[] = []\n      arr?.forEach((item) => {\n        if (item?.children?.length) {\n          const filterChildren = doFilter(item.children)\n          if (filterChildren.length) {\n            filterArr.push({ ...item, children: filterChildren })\n          } else if (filterFunc(searchValue, item) && checkStrictly !== false) {\n            // 父子关系启用时，没有可用子元素，不添加父元素\n            filterArr.push({ ...item, children: [] })\n          }\n        } else if (filterFunc(searchValue, item)) {\n          filterArr.push(item)\n        }\n      })\n      return filterArr\n    }\n\n    return doFilter(options)\n  }, [options, searchValue, filterOption])\n\nexport { useFilterOptions }\n"
  },
  {
    "path": "packages/antd/src/select-table/useFlatOptions.tsx",
    "content": "const useFlatOptions = (tree: any[]) => {\n  const flatData = (data) => {\n    let list = []\n    data?.forEach((item) => {\n      list = [...list, item]\n      if (item?.children?.length) {\n        list = [...list, ...flatData(item.children)]\n      }\n    })\n    return list\n  }\n  return flatData(tree)\n}\n\nexport { useFlatOptions }\n"
  },
  {
    "path": "packages/antd/src/select-table/useSize.tsx",
    "content": "interface ISize {\n  (\n    fieldSize: 'large' | 'default' | 'small',\n    searchSize: 'large' | 'middle' | 'small',\n    tableSize: 'large' | 'middle' | 'small'\n  ): {\n    searchSize: 'large' | 'middle' | 'small'\n    tableSize: 'large' | 'middle' | 'small'\n  }\n}\n\nconst useSize: ISize = (fieldSize = 'default', searchSize, tableSize) => {\n  const fieldSizeMap: any = {\n    small: {\n      searchSize: 'small',\n      tableSize: 'small',\n    },\n    default: {\n      searchSize: 'middle',\n      tableSize: 'middle',\n    },\n    large: {\n      searchSize: 'large',\n      tableSize: 'default',\n    },\n  }\n  const { searchSize: fieldSearchSize, tableSize: fieldTableSize } =\n    fieldSizeMap[fieldSize]\n\n  return {\n    searchSize: searchSize || fieldSearchSize,\n    tableSize: tableSize || fieldTableSize,\n  }\n}\n\nexport { useSize }\n"
  },
  {
    "path": "packages/antd/src/select-table/useTitleAddon.tsx",
    "content": "import React from 'react'\nimport { Checkbox } from 'antd'\nimport { completedKeys, getCompatibleAllSelected } from './utils'\n\n// 重写表格表头Checkbox（节点状态按全完整数据计算，节点操作按筛选数据计算）\nconst newCheckbox =\n  (\n    selected,\n    flatDataSource,\n    flatFilteredDataSource,\n    primaryKey,\n    disabled,\n    readOnly,\n    checkStrictly,\n    onChange\n  ) =>\n  () => {\n    // 全选框是否选中\n    const checked = Boolean(\n      selected?.length &&\n        selected?.length ===\n          flatDataSource.filter((item) => !item.disabled).length\n    )\n    // 全选框是否未完全选中\n    const indeterminate = Boolean(selected?.length && !checked)\n\n    const onInnerChange = (e) => {\n      if (!readOnly) {\n        let isSelected = e.target.checked\n        // 当前可执行全选的keys\n        const usableKeys = flatFilteredDataSource\n          .filter((item) => !item.disabled)\n          .map((item) => item?.[primaryKey])\n        // 在筛选状态下（按钮的indeterminate状态处于异常）需要通过数据对比判断是否处于全选中状态\n        if (\n          getCompatibleAllSelected(\n            selected,\n            flatFilteredDataSource,\n            usableKeys,\n            checkStrictly,\n            primaryKey\n          )\n        ) {\n          isSelected = false\n        }\n\n        let newSelected = []\n        if (isSelected) {\n          // 执行全选\n          newSelected = [...new Set([...selected, ...usableKeys])]\n        } else {\n          // 执行取消全选\n          newSelected = selected.filter((key) => !usableKeys.includes(key))\n        }\n        newSelected = completedKeys(flatDataSource, newSelected, primaryKey)\n        onChange?.(newSelected)\n      }\n    }\n\n    return (\n      <Checkbox\n        key=\"titleAddons\"\n        disabled={disabled}\n        checked={checked}\n        indeterminate={indeterminate}\n        onChange={onInnerChange}\n      />\n    )\n  }\n\nconst useTitleAddon = (\n  selected: any[],\n  flatDataSource: any[],\n  flatFilteredDataSource: any[],\n  primaryKey: string,\n  mode: string,\n  disabled: boolean,\n  readOnly: boolean,\n  checkStrictly: boolean,\n  onChange: (selectedRowKeys: any[], record: any[]) => any\n) => {\n  if (mode === 'single') {\n    return {}\n  }\n  return {\n    columnTitle: newCheckbox(\n      selected,\n      flatDataSource,\n      flatFilteredDataSource,\n      primaryKey,\n      disabled,\n      readOnly,\n      checkStrictly,\n      onChange\n    ),\n  }\n}\n\nexport { useTitleAddon }\n"
  },
  {
    "path": "packages/antd/src/select-table/utils.ts",
    "content": "import { isArr, isFn } from '@formily/shared'\nimport { useFlatOptions } from './useFlatOptions'\n\n/**\n * 获取树列表某个键值的集合\n * @param tree 树列表\n * @param primaryKey 键名称\n * @returns 键值数组集合\n */\nconst getTreeKeys = (tree: any[], primaryKey: string) =>\n  isArr(tree)\n    ? tree.reduce((prev, current) => {\n        if (current?.disabled) {\n          return prev\n        }\n        return [\n          ...prev,\n          current[primaryKey],\n          ...getTreeKeys(current?.children, primaryKey),\n        ]\n      }, [])\n    : []\n\n/**\n * 判断树列表中是否有任一 key 被选中\n * @param tree 树列表\n * @param selected 已选中的 keys\n * @param primaryKey 键名\n * @returns\n */\nconst hasSelectedKey = (tree: any[], selected: any[], primaryKey: string) => {\n  const keys = getTreeKeys(tree, primaryKey)\n  const mergedKeys = [...keys, ...selected]\n  const validKeys = [...new Set(mergedKeys)]\n  return validKeys.length !== mergedKeys.length\n}\n\n/**\n * 判断列表项是否全部被选中\n * @param list 一阶列表\n * @param selected 当前选中的字段值集合\n * @param primaryKey 键名称\n * @returns 是否全部被选中\n */\nconst isAllSelected = (list: any[], selected: any[], primaryKey: string) => {\n  const validList = list.filter((item) => !item?.disabled)\n  const selectedList = validList.filter((item) =>\n    selected?.includes(item[primaryKey])\n  )\n  return selectedList.length === validList.length\n}\n\n/**\n * 完善TableUI Keys（添加选中所有子元素的父元素，或移除未选中所有子元素的父元素）\n * @param flatDataSource 完整数据平铺列表\n * @param selected 当前选中的字段值集合\n * @param primaryKey 键名称\n * @returns 完整的字段值集合\n */\nconst completedKeys = (\n  flatDataSource: any[] = [],\n  selected: any[],\n  primaryKey: string\n) => {\n  let allSelectedKeys = [...selected]\n  flatDataSource.forEach((item) => {\n    if (item.children?.length) {\n      // 优先递归子元素\n      allSelectedKeys = completedKeys(\n        item.children,\n        allSelectedKeys,\n        primaryKey\n      )\n      if (isAllSelected(item.children, allSelectedKeys, primaryKey)) {\n        // 如果该元素的子元素全部选中，且该元素未禁用，则也选中该项（即包含全选子元素的父元素）\n        if (!item?.disabled) {\n          allSelectedKeys = [...new Set([...allSelectedKeys, item[primaryKey]])]\n        }\n      } else {\n        // 如果该元素的子元素未全部选中，则移除该项\n        allSelectedKeys = allSelectedKeys.filter(\n          (key) => key !== item[primaryKey]\n        )\n      }\n    }\n  })\n  return allSelectedKeys\n}\n\n/**\n * 获取数列表中被选中的有效路径\n * @param tree 数列表\n * @param selected 当前选中的字段值集合\n * @param primaryKey 键名称\n * @returns 有效的树路径\n */\nconst getSelectedPath = (tree = [], selected, primaryKey) => {\n  const pathData = []\n\n  tree.forEach((item) => {\n    const validChildren = getSelectedPath(item.children, selected, primaryKey)\n    if (validChildren.length || selected?.includes(item[primaryKey])) {\n      pathData.push({\n        ...item,\n        ...(validChildren.length ? { children: validChildren } : {}),\n      })\n    }\n  })\n\n  return pathData\n}\n\n/**\n * 删除树列表的某个 key/value 键值对\n * @param tree\n * @param key\n * @returns\n */\nconst deleteTreeItem = (tree: any[], key: string) =>\n  tree.map((item) => {\n    const validItem = { ...item }\n    delete validItem[key]\n    if (validItem.children?.length) {\n      validItem.children = deleteTreeItem(validItem.children, key)\n    }\n    return validItem\n  })\n\n/**\n * 根据 valueType 获取最终输出值\n * @param keys 当前选中的 key 集合（all完整类型）\n * @param records 当前选中的 option 集合\n * @param dataSource 数据源集合\n * @param primaryKey 键名\n * @param originalValueType 值输出类型\n * @param originalOptionAsValue\n * @param mode\n * @param checkStrictly\n * @returns 最终输出的 keys 和 options\n */\nconst getOutputData = (\n  keys, // selected\n  options,\n  dataSource,\n  primaryKey,\n  originalValueType,\n  originalOptionAsValue,\n  mode,\n  checkStrictly\n) => {\n  const valueType = checkStrictly !== false ? 'all' : originalValueType // valueType 在 Strictly 为 false 时生效\n  const optionAsValue = valueType === 'path' ? false : originalOptionAsValue // optionAsValue 在 path 模式不生效\n  let outputValue = []\n  let outputOptions = []\n\n  if (valueType === 'parent') {\n    // 移除所有选中值的子值\n    let childrenKeys = []\n    options.forEach((option) => {\n      childrenKeys = [\n        ...childrenKeys,\n        ...getTreeKeys(option.children, primaryKey),\n      ]\n    })\n    outputValue = keys.filter((key) => !childrenKeys.includes(key))\n    outputOptions = options.filter((options) =>\n      outputValue.includes(options[primaryKey])\n    )\n  } else if (valueType === 'child') {\n    outputValue = [...keys]\n    outputOptions = [...options]\n    outputOptions.forEach((option) => {\n      // 移除当前有子值被选中的父值\n      if (hasSelectedKey(option.children, keys, primaryKey)) {\n        outputValue = outputValue.filter((key) => key !== option[primaryKey])\n        outputOptions = outputOptions.filter(\n          (options) => options[primaryKey] !== option[primaryKey]\n        )\n      }\n    })\n  } else if (valueType === 'path') {\n    outputValue = getSelectedPath(dataSource, keys, primaryKey)\n    outputOptions = [...options]\n  } else {\n    // valueType === 'all'\n    outputValue = [...keys]\n    outputOptions = [...options]\n  }\n\n  outputOptions = deleteTreeItem(outputOptions, '__formily_key__')\n  outputValue =\n    optionAsValue && valueType !== 'path' ? outputOptions : outputValue\n  if (mode === 'single') {\n    outputValue = outputValue[0]\n    outputOptions = outputOptions[0]\n  }\n\n  return { outputValue, outputOptions }\n}\n\n/**\n * 根据 valueType 获取 TableUI 显示值\n * @param keys 回填的数据（输出的）keys 集合\n * @param flatDataSource 平铺的数据源集合\n * @param primaryKey 键名称\n * @param originalValueType 值输出类型\n * @param originalOptionAsValue\n * @param mode\n * @param checkStrictly\n * @param rowKey\n * @returns [] TableUI keys 集合\n */\nconst getUISelected = (\n  value,\n  flatDataSource,\n  primaryKey,\n  originalValueType,\n  originalOptionAsValue,\n  mode,\n  checkStrictly,\n  rowKey\n) => {\n  const valueType = checkStrictly !== false ? 'all' : originalValueType // valueType 在 Strictly 为 false 时生效\n  const optionAsValue = valueType === 'path' ? false : originalOptionAsValue // optionAsValue 在 path 模式不生效\n\n  let keys = mode === 'single' ? [value] : isArr(value) ? value : []\n  keys =\n    optionAsValue && valueType !== 'path'\n      ? keys.map((record: any) =>\n          isFn(rowKey) ? rowKey(record) : record?.[primaryKey]\n        )\n      : keys\n\n  let newKeys = []\n  if (valueType === 'parent') {\n    const options = flatDataSource.filter((item) =>\n      keys.includes(item[primaryKey])\n    )\n    let childrenKeys = []\n    options.forEach((option) => {\n      childrenKeys = [\n        ...childrenKeys,\n        ...getTreeKeys(option.children, primaryKey),\n      ]\n    })\n    newKeys = [...new Set([...keys, ...childrenKeys])]\n  } else if (valueType === 'child') {\n    newKeys = completedKeys(flatDataSource, keys, primaryKey)\n  } else if (valueType === 'path') {\n    const pathKeys = useFlatOptions(keys).map((item) => item[primaryKey])\n    newKeys = completedKeys(flatDataSource, pathKeys, primaryKey)\n  } else {\n    // valueType === 'all'\n    newKeys = [...keys]\n  }\n\n  return newKeys\n}\n\n/**\n * 获取兼容筛选模式下是否全部选中子元素\n * @param selected 已选中项\n * @param dataSource 当前数据结构\n * @param usableKeys 当前数据结构的可执行项\n * @param checkStrictly\n * @param primaryKey\n * @returns 是否全部选中\n */\nconst getCompatibleAllSelected = (\n  selected,\n  dataSource,\n  usableKeys,\n  checkStrictly,\n  primaryKey\n) => {\n  if (!usableKeys.length) {\n    return false\n  }\n  // 当前模式下已选中的项\n  const currentSelected = selected.filter((item) => usableKeys.includes(item))\n  // 获取有效选中（父子模式或非父子模式）\n  const validSelected =\n    checkStrictly !== false\n      ? currentSelected // 非父子模式选中项\n      : completedKeys(dataSource, currentSelected, primaryKey) // 父子模式选中项\n  // 有效选中项数量等于可执行项数量则全部选中子元素\n  return validSelected.length === usableKeys.length\n}\n\nexport {\n  hasSelectedKey,\n  getTreeKeys,\n  deleteTreeItem,\n  isAllSelected,\n  getUISelected,\n  getOutputData,\n  completedKeys,\n  getCompatibleAllSelected,\n}\n"
  },
  {
    "path": "packages/antd/src/space/index.tsx",
    "content": "import React from 'react'\nimport { Space as AntdSpace, SpaceProps } from 'antd'\nimport { useFormLayout } from '../form-layout'\n\nexport const Space: React.FC<React.PropsWithChildren<SpaceProps>> = (props) => {\n  const layout = useFormLayout()\n  return React.createElement(AntdSpace, {\n    size: props.size ?? layout?.spaceGap,\n    ...props,\n  })\n}\n\nexport default Space\n"
  },
  {
    "path": "packages/antd/src/space/style.ts",
    "content": "import 'antd/lib/space/style/index'\n"
  },
  {
    "path": "packages/antd/src/style.less",
    "content": "// auto generated code\n@import './array-base/style.less';\n@import './array-cards/style.less';\n@import './array-collapse/style.less';\n@import './array-items/style.less';\n@import './array-table/style.less';\n@import './editable/style.less';\n@import './form-button-group/style.less';\n@import './form-grid/style.less';\n@import './form-item/style.less';\n@import './form-layout/style.less';\n@import './form/style.less';\n@import './preview-text/style.less';\n@import './radio/style.less';\n@import './select-table/style.less';\n"
  },
  {
    "path": "packages/antd/src/style.ts",
    "content": "// auto generated code\nimport './array-base/style.less'\nimport './array-cards/style.less'\nimport './array-collapse/style.less'\nimport './array-items/style.less'\nimport './array-table/style.less'\nimport './editable/style.less'\nimport './form-button-group/style.less'\nimport './form-grid/style.less'\nimport './form-item/style.less'\nimport './form-layout/style.less'\nimport './form/style.less'\nimport './preview-text/style.less'\nimport './radio/style.less'\nimport './select-table/style.less'\n"
  },
  {
    "path": "packages/antd/src/submit/index.tsx",
    "content": "import React from 'react'\nimport { Button } from 'antd'\nimport { ButtonProps } from 'antd/lib/button'\nimport { IFormFeedback } from '@formily/core'\nimport { useParentForm, observer } from '@formily/react'\n\nexport interface ISubmitProps extends ButtonProps {\n  onClick?: (e: React.MouseEvent<Element, MouseEvent>) => any\n  onSubmit?: (values: any) => any\n  onSubmitSuccess?: (payload: any) => void\n  onSubmitFailed?: (feedbacks: IFormFeedback[]) => void\n}\n\nexport const Submit: React.FC<React.PropsWithChildren<ISubmitProps>> = observer(\n  ({ onSubmit, onSubmitFailed, onSubmitSuccess, ...props }: ISubmitProps) => {\n    const form = useParentForm()\n    return (\n      <Button\n        htmlType={onSubmit ? 'button' : 'submit'}\n        type=\"primary\"\n        {...props}\n        loading={props.loading !== undefined ? props.loading : form.submitting}\n        onClick={(e) => {\n          if (props.onClick) {\n            if (props.onClick(e) === false) return\n          }\n          if (onSubmit) {\n            form.submit(onSubmit).then(onSubmitSuccess).catch(onSubmitFailed)\n          }\n        }}\n      >\n        {props.children}\n      </Button>\n    )\n  },\n  {\n    forwardRef: true,\n  }\n)\n\nexport default Submit\n"
  },
  {
    "path": "packages/antd/src/submit/style.ts",
    "content": "import 'antd/lib/button/style/index'\n"
  },
  {
    "path": "packages/antd/src/switch/index.tsx",
    "content": "import { Switch as AntdSwitch } from 'antd'\nimport { connect, mapProps } from '@formily/react'\n\nexport const Switch = connect(\n  AntdSwitch,\n  mapProps(\n    {\n      value: 'checked',\n    },\n    (props) => {\n      const onChange = props.onChange\n      delete props['value']\n      return {\n        ...props,\n        onChange(checked) {\n          onChange?.(checked, null)\n        },\n      }\n    }\n  )\n)\n\nexport default Switch\n"
  },
  {
    "path": "packages/antd/src/switch/style.ts",
    "content": "import 'antd/lib/switch/style/index'\n"
  },
  {
    "path": "packages/antd/src/time-picker/index.tsx",
    "content": "import moment from 'moment'\nimport { connect, mapProps, mapReadPretty } from '@formily/react'\nimport { TimePicker as AntdTimePicker } from 'antd'\nimport {\n  TimePickerProps as AntdTimePickerProps,\n  TimeRangePickerProps,\n} from 'antd/lib/time-picker'\nimport { PreviewText } from '../preview-text'\nimport { formatMomentValue, momentable } from '../__builtins__'\n\ntype ComposedTimePicker = React.FC<\n  React.PropsWithChildren<AntdTimePickerProps>\n> & {\n  RangePicker?: React.FC<React.PropsWithChildren<TimeRangePickerProps>>\n}\n\nconst mapTimeFormat = function () {\n  return (props: any) => {\n    const format = props['format'] || 'HH:mm:ss'\n    const onChange = props.onChange\n    return {\n      ...props,\n      format,\n      value: momentable(props.value, format),\n      onChange: (value: moment.Moment | moment.Moment[]) => {\n        if (onChange) {\n          onChange(formatMomentValue(value, format))\n        }\n      },\n    }\n  }\n}\n\nexport const TimePicker: ComposedTimePicker = connect(\n  AntdTimePicker,\n  mapProps(mapTimeFormat()),\n  mapReadPretty(PreviewText.TimePicker)\n)\n\nTimePicker.RangePicker = connect(\n  AntdTimePicker.RangePicker,\n  mapProps(mapTimeFormat()),\n  mapReadPretty(PreviewText.TimeRangePicker)\n)\n\nexport default TimePicker\n"
  },
  {
    "path": "packages/antd/src/time-picker/style.ts",
    "content": "import 'antd/lib/time-picker/style/index'\n"
  },
  {
    "path": "packages/antd/src/transfer/index.tsx",
    "content": "import { connect, mapProps } from '@formily/react'\nimport { Transfer as AntdTransfer } from 'antd'\nimport { isVoidField } from '@formily/core'\n\nconst renderTitle = (item: any) => item.title\n\nexport const Transfer = connect(\n  AntdTransfer,\n  mapProps(\n    {\n      value: 'targetKeys',\n    },\n    (props, field) => {\n      if (isVoidField(field)) return props\n      return {\n        ...props,\n        render: props.render || renderTitle,\n        dataSource:\n          field.dataSource?.map((item) => {\n            return {\n              ...item,\n              title: item.title || item.label,\n              key: item.key || item.value,\n            }\n          }) || [],\n      }\n    }\n  )\n)\n\nexport default Transfer\n"
  },
  {
    "path": "packages/antd/src/transfer/style.ts",
    "content": "import 'antd/lib/transfer/style/index'\n"
  },
  {
    "path": "packages/antd/src/tree-select/index.tsx",
    "content": "import React from 'react'\nimport { connect, mapReadPretty, mapProps } from '@formily/react'\nimport { TreeSelect as AntdTreeSelect } from 'antd'\nimport { PreviewText } from '../preview-text'\nimport { LoadingOutlined } from '@ant-design/icons'\nexport const TreeSelect = connect(\n  AntdTreeSelect,\n  mapProps(\n    {\n      dataSource: 'treeData',\n    },\n    (props, field) => {\n      return {\n        ...props,\n        suffixIcon:\n          field?.['loading'] || field?.['validating'] ? (\n            <LoadingOutlined />\n          ) : (\n            props.suffixIcon\n          ),\n      }\n    }\n  ),\n  mapReadPretty(PreviewText.TreeSelect)\n)\n\nexport default TreeSelect\n"
  },
  {
    "path": "packages/antd/src/tree-select/style.ts",
    "content": "import 'antd/lib/tree-select/style/index'\n"
  },
  {
    "path": "packages/antd/src/upload/index.tsx",
    "content": "import React, { useEffect } from 'react'\nimport { Field } from '@formily/core'\nimport { connect, mapProps, useField } from '@formily/react'\nimport { Upload as AntdUpload, Button } from 'antd'\nimport {\n  UploadChangeParam,\n  UploadProps as AntdUploadProps,\n  DraggerProps as AntdDraggerProps,\n} from 'antd/lib/upload'\nimport { InboxOutlined, UploadOutlined } from '@ant-design/icons'\nimport { reaction } from '@formily/reactive'\nimport { UploadFile } from 'antd/lib/upload/interface'\nimport { isArr, toArr } from '@formily/shared'\nimport { UPLOAD_PLACEHOLDER } from './placeholder'\nimport { usePrefixCls } from '../__builtins__'\n\nexport type IUploadProps = Omit<AntdUploadProps, 'onChange'> & {\n  textContent?: React.ReactNode\n  onChange?: (fileList: UploadFile[]) => void\n  serviceErrorMessage?: string\n}\n\nexport type IDraggerUploadProps = Omit<AntdDraggerProps, 'onChange'> & {\n  textContent?: React.ReactNode\n  onChange?: (fileList: UploadFile[]) => void\n  serviceErrorMessage?: string\n}\n\ntype ComposedUpload = React.FC<React.PropsWithChildren<IUploadProps>> & {\n  Dragger?: React.FC<React.PropsWithChildren<IDraggerUploadProps>>\n}\n\ntype IExtendsUploadProps = {\n  fileList?: any[]\n  serviceErrorMessage?: string\n  onChange?: (...args: any) => void\n}\n\nconst testOpts = (\n  ext: RegExp,\n  options: { exclude?: string[]; include?: string[] }\n) => {\n  if (options && isArr(options.include)) {\n    return options.include.some((url) => ext.test(url))\n  }\n\n  if (options && isArr(options.exclude)) {\n    return !options.exclude.some((url) => ext.test(url))\n  }\n\n  return true\n}\n\nconst getImageByUrl = (url: string, options: any) => {\n  for (let i = 0; i < UPLOAD_PLACEHOLDER.length; i++) {\n    if (\n      UPLOAD_PLACEHOLDER[i].ext.test(url) &&\n      testOpts(UPLOAD_PLACEHOLDER[i].ext, options)\n    ) {\n      return UPLOAD_PLACEHOLDER[i].icon || url\n    }\n  }\n\n  return url\n}\n\nconst getURL = (target: any) => {\n  return target?.['url'] || target?.['downloadURL'] || target?.['imgURL']\n}\nconst getThumbURL = (target: any) => {\n  return (\n    target?.['thumbUrl'] ||\n    target?.['url'] ||\n    target?.['downloadURL'] ||\n    target?.['imgURL']\n  )\n}\n\nconst getErrorMessage = (target: any) => {\n  return (\n    target?.errorMessage ||\n    target?.errMsg ||\n    target?.errorMsg ||\n    target?.message ||\n    (typeof target?.error === 'string' ? target.error : '')\n  )\n}\n\nconst getState = (target: any) => {\n  if (target?.success === false) return 'error'\n  if (target?.failed === true) return 'error'\n  if (target?.error) return 'error'\n  return target?.state || target?.status\n}\n\nconst normalizeFileList = (fileList: UploadFile[]) => {\n  if (fileList && fileList.length) {\n    return fileList.map((file, index) => {\n      return {\n        ...file,\n        uid: file.uid || `${index}`,\n        status: getState(file.response) || getState(file),\n        url: getURL(file) || getURL(file?.response),\n        thumbUrl: getImageByUrl(\n          getThumbURL(file) || getThumbURL(file?.response),\n          {\n            exclude: ['.png', '.jpg', '.jpeg', '.gif'],\n          }\n        ),\n      }\n    })\n  }\n  return []\n}\n\nconst useValidator = (validator: (value: any) => string) => {\n  const field = useField<Field>()\n  useEffect(() => {\n    const dispose = reaction(\n      () => field.value,\n      (value) => {\n        const message = validator(value)\n        field.setFeedback({\n          type: 'error',\n          code: 'UploadError',\n          messages: message ? [message] : [],\n        })\n      }\n    )\n    return () => {\n      dispose()\n    }\n  }, [])\n}\n\nconst useUploadValidator = (serviceErrorMessage = 'Upload Service Error') => {\n  useValidator((value) => {\n    const list = toArr(value)\n    for (let i = 0; i < list.length; i++) {\n      if (list[i]?.status === 'error') {\n        return (\n          getErrorMessage(list[i]?.response) ||\n          getErrorMessage(list[i]) ||\n          serviceErrorMessage\n        )\n      }\n    }\n  })\n}\n\nfunction useUploadProps<T extends IExtendsUploadProps = IUploadProps>({\n  serviceErrorMessage,\n  ...props\n}: T) {\n  useUploadValidator(serviceErrorMessage)\n  const onChange = (param: UploadChangeParam<UploadFile>) => {\n    props.onChange?.(normalizeFileList([...param.fileList]))\n  }\n  return {\n    ...props,\n    fileList: normalizeFileList(props.fileList),\n    onChange,\n  }\n}\n\nconst getPlaceholder = (props: IUploadProps) => {\n  if (props.listType !== 'picture-card') {\n    return (\n      <Button>\n        <UploadOutlined />\n        {props.textContent}\n      </Button>\n    )\n  }\n  return <UploadOutlined style={{ fontSize: 20 }} />\n}\n\nexport const Upload: ComposedUpload = connect(\n  (props: React.PropsWithChildren<IUploadProps>) => {\n    return (\n      <AntdUpload {...useUploadProps(props)}>\n        {props.children || getPlaceholder(props)}\n      </AntdUpload>\n    )\n  },\n  mapProps({\n    value: 'fileList',\n  })\n)\n\nconst Dragger = connect(\n  (props: React.PropsWithChildren<IDraggerUploadProps>) => {\n    return (\n      <div className={usePrefixCls('upload-dragger')}>\n        <AntdUpload.Dragger {...useUploadProps(props)}>\n          {props.children || (\n            <React.Fragment>\n              <p className=\"ant-upload-drag-icon\">\n                <InboxOutlined />\n              </p>\n              {props.textContent && (\n                <p className=\"ant-upload-text\">{props.textContent}</p>\n              )}\n            </React.Fragment>\n          )}\n        </AntdUpload.Dragger>\n      </div>\n    )\n  },\n  mapProps({\n    value: 'fileList',\n  })\n)\n\nUpload.Dragger = Dragger\n\nexport default Upload\n"
  },
  {
    "path": "packages/antd/src/upload/placeholder.ts",
    "content": "export const UPLOAD_PLACEHOLDER = [\n  {\n    ext: /\\.docx/i,\n    icon: '//img.alicdn.com/tfs/TB1n8jfr1uSBuNjy1XcXXcYjFXa-200-200.png',\n  },\n  {\n    ext: /\\.pptx/i,\n    icon: '//img.alicdn.com/tfs/TB1ItgWr_tYBeNjy1XdXXXXyVXa-200-200.png',\n  },\n  {\n    ext: /\\.jpe?g/i,\n    icon: '//img.alicdn.com/tfs/TB1wrT5r9BYBeNjy0FeXXbnmFXa-200-200.png',\n  },\n  {\n    ext: /\\.pdf/i,\n    icon: '//img.alicdn.com/tfs/TB1GwD8r9BYBeNjy0FeXXbnmFXa-200-200.png',\n  },\n  {\n    ext: /\\.png/i,\n    icon: '//img.alicdn.com/tfs/TB1BHT5r9BYBeNjy0FeXXbnmFXa-200-200.png',\n  },\n  {\n    ext: /\\.eps/i,\n    icon: '//img.alicdn.com/tfs/TB1G_iGrVOWBuNjy0FiXXXFxVXa-200-200.png',\n  },\n  {\n    ext: /\\.ai/i,\n    icon: '//img.alicdn.com/tfs/TB1B2cVr_tYBeNjy1XdXXXXyVXa-200-200.png',\n  },\n  {\n    ext: /\\.gif/i,\n    icon: '//img.alicdn.com/tfs/TB1DTiGrVOWBuNjy0FiXXXFxVXa-200-200.png',\n  },\n  {\n    ext: /\\.svg/i,\n    icon: '//img.alicdn.com/tfs/TB1uUm9rY9YBuNjy0FgXXcxcXXa-200-200.png',\n  },\n  {\n    ext: /\\.xlsx?/i,\n    icon: '//img.alicdn.com/tfs/TB1any1r1OSBuNjy0FdXXbDnVXa-200-200.png',\n  },\n  {\n    ext: /\\.psd?/i,\n    icon: '//img.alicdn.com/tfs/TB1_nu1r1OSBuNjy0FdXXbDnVXa-200-200.png',\n  },\n  {\n    ext: /\\.(wav|aif|aiff|au|mp1|mp2|mp3|ra|rm|ram|mid|rmi)/i,\n    icon: '//img.alicdn.com/tfs/TB1jPvwr49YBuNjy0FfXXXIsVXa-200-200.png',\n  },\n  {\n    ext: /\\.(avi|wmv|mpg|mpeg|vob|dat|3gp|mp4|mkv|rm|rmvb|mov|flv)/i,\n    icon: '//img.alicdn.com/tfs/TB1FrT5r9BYBeNjy0FeXXbnmFXa-200-200.png',\n  },\n  {\n    ext: /\\.(zip|rar|arj|z|gz|iso|jar|ace|tar|uue|dmg|pkg|lzh|cab)/i,\n    icon: '//img.alicdn.com/tfs/TB10jmfr29TBuNjy0FcXXbeiFXa-200-200.png',\n  },\n  {\n    ext: /\\.[^.]+/i,\n    icon: '//img.alicdn.com/tfs/TB10.R4r3mTBuNjy1XbXXaMrVXa-200-200.png',\n  },\n]\n"
  },
  {
    "path": "packages/antd/src/upload/style.ts",
    "content": "import 'antd/lib/upload/style/index'\n"
  },
  {
    "path": "packages/antd/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*\", \"devtools/*\"]\n    },\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/antd/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"include\": [\"./src/**/*.ts\", \"./src/**/*.tsx\"],\n  \"exclude\": [\"./src/__tests__/*\", \"./esm/*\", \"./lib/*\"],\n  \"compilerOptions\": {\n    \"lib\": [\"ESNext\", \"DOM\"]\n  }\n}\n"
  },
  {
    "path": "packages/benchmark/.npmignore",
    "content": "node_modules\n*.log\nbuild\ndocs\ndoc-site\n__tests__\n.eslintrc\njest.config.js\ntsconfig.json\n.umi\nsrc"
  },
  {
    "path": "packages/benchmark/.umirc.js",
    "content": "import { resolve } from 'path'\nexport default {\n  mode: 'site',\n  logo: '//img.alicdn.com/imgextra/i2/O1CN01Kq3OHU1fph6LGqjIz_!!6000000004056-55-tps-1141-150.svg',\n  title: 'Formily',\n  hash: true,\n  favicon:\n    '//img.alicdn.com/imgextra/i3/O1CN01XtT3Tv1Wd1b5hNVKy_!!6000000002810-55-tps-360-360.svg',\n  outputPath: './doc-site',\n  navs: {\n    'en-US': [\n      {\n        title: 'Guide',\n        path: '/guide',\n      },\n      {\n        title: 'API',\n        path: '/api',\n      },\n      {\n        title: 'Home Site',\n        path: 'https://formilyjs.org',\n      },\n      {\n        title: 'GITHUB',\n        path: 'https://github.com/alibaba/formily',\n      },\n    ],\n    'zh-CN': [\n      {\n        title: '指南',\n        path: '/zh-CN/guide',\n      },\n      {\n        title: 'API',\n        path: '/zh-CN/api',\n      },\n      {\n        title: '主站',\n        path: 'https://formilyjs.org',\n      },\n      {\n        title: 'GITHUB',\n        path: 'https://github.com/alibaba/formily',\n      },\n    ],\n  },\n  links: [\n    {\n      rel: 'stylesheet',\n      href: 'https://esm.sh/antd@4.x/dist/antd.css',\n    },\n  ],\n  styles: [\n    `.__dumi-default-navbar-logo{\n      height: 60px !important;\n      width: 150px !important;\n      padding-left:0 !important;\n      color: transparent !important;\n    }\n    .__dumi-default-navbar{\n      padding: 0 28px !important;\n    }\n    .__dumi-default-layout-hero{\n      background-image: url(//img.alicdn.com/imgextra/i4/O1CN01ZcvS4e26XMsdsCkf9_!!6000000007671-2-tps-6001-4001.png);\n      background-size: cover;\n      background-repeat: no-repeat;\n    }\n    nav a{\n      text-decoration: none !important;\n    }\n    `,\n  ],\n  menus: {\n    '/guide': [\n      {\n        title: 'Introduction',\n        path: '/guide',\n      },\n      { title: 'Architecture', path: '/guide/architecture' },\n      { title: 'Concept', path: '/guide/concept' },\n    ],\n    '/zh-CN/guide': [\n      {\n        title: '介绍',\n        path: '/guide',\n      },\n      { title: '核心架构', path: '/zh-CN/guide/architecture' },\n      { title: '核心概念', path: '/zh-CN/guide/concept' },\n    ],\n  },\n}\n"
  },
  {
    "path": "packages/benchmark/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-present, Alibaba Group Holding Limited. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/benchmark/README.md",
    "content": "# @formily/benchmark\n"
  },
  {
    "path": "packages/benchmark/package.json",
    "content": "{\n  \"name\": \"@formily/benchmark\",\n  \"version\": \"2.3.7\",\n  \"license\": \"MIT\",\n  \"private\": true,\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/alibaba/formily.git\"\n  },\n  \"types\": \"esm/index.d.ts\",\n  \"bugs\": {\n    \"url\": \"https://github.com/alibaba/formily/issues\"\n  },\n  \"homepage\": \"https://github.com/alibaba/formily#readme\",\n  \"engines\": {\n    \"npm\": \">=3.0.0\"\n  },\n  \"scripts\": {\n    \"start\": \"webpack-dev-server --config webpack.dev.ts\"\n  },\n  \"devDependencies\": {\n    \"css-loader\": \"^5.0.0\",\n    \"file-loader\": \"^5.0.2\",\n    \"html-webpack-plugin\": \"^3.2.0\",\n    \"mini-css-extract-plugin\": \"^1.6.0\",\n    \"postcss\": \"^8.4.31\",\n    \"postcss-less\": \"^4.0.0\",\n    \"postcss-loader\": \"^3.x\",\n    \"raw-loader\": \"^4.0.0\",\n    \"style-loader\": \"^1.1.3\",\n    \"ts-loader\": \"^7.0.4\",\n    \"webpack\": \"^4.41.5\",\n    \"webpack-bundle-analyzer\": \"^3.9.0\",\n    \"webpack-cli\": \"^3.3.10\",\n    \"webpack-dev-server\": \"^3.10.1\"\n  },\n  \"resolutions\": {\n    \"react\": \"next\",\n    \"react-dom\": \"next\",\n    \"react-is\": \"next\"\n  },\n  \"dependencies\": {\n    \"@formily/reactive\": \"2.3.7\",\n    \"@formily/reactive-react\": \"2.3.7\",\n    \"react\": \"next\",\n    \"react-dom\": \"next\",\n    \"react-is\": \"next\"\n  },\n  \"gitHead\": \"ac79c196ae9324889aca5e0501146f9b37b04283\"\n}\n"
  },
  {
    "path": "packages/benchmark/src/index.tsx",
    "content": "import React, { useMemo, useState } from 'react'\nimport ReactDOM from 'react-dom'\nimport { createForm } from '@formily/core'\nimport { Field, createSchemaField } from '@formily/react'\nimport { Input, Form, FormItem } from '@formily/antd'\nimport { Form as AntdForm, Input as AntdInput } from 'antd'\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst PureAntdInput = () => {\n  return (\n    <>\n      {Array.from({ length: 2000 }).map((_, i) => {\n        return <AntdInput key={i} />\n      })}\n    </>\n  )\n}\n\nconst PureAntd = () => {\n  return (\n    <AntdForm>\n      <h1>Please pay attention to the performance of the form input</h1>\n      {Array.from({ length: 2000 }).map((_, i) => {\n        return (\n          <AntdForm.Item\n            key={i}\n            name={`name_${i}`}\n            required\n            label={`name ${i + 1}`}\n          >\n            <AntdInput />\n          </AntdForm.Item>\n        )\n      })}\n    </AntdForm>\n  )\n}\n\nconst PureJSX = () => {\n  const form = useMemo(() => createForm(), [])\n  return (\n    <Form form={form}>\n      <h1>Please pay attention to the performance of the form input</h1>\n      {Array.from({ length: 2000 }).map((_, i) => {\n        return (\n          <Field\n            key={i}\n            name={`name_${i}`}\n            title={`name ${i + 1}`}\n            required\n            decorator={[FormItem]}\n            component={[Input, { placeholder: 'Please Input' }]}\n          />\n        )\n      })}\n    </Form>\n  )\n}\n\nconst PureJSONSchema = () => {\n  const form = useMemo(() => createForm(), [])\n  const schema = {\n    type: 'object',\n    properties: {},\n  }\n  Array.from({ length: 2000 }).forEach((_, i) => {\n    schema.properties[`name_${i}`] = {\n      type: 'string',\n      title: `name ${i + 1}`,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-component-props': {\n        placeholder: 'Please Input',\n      },\n    }\n  })\n  return (\n    <Form form={form}>\n      <h1>Please pay attention to the performance of the form input</h1>\n      <SchemaField schema={schema} />\n    </Form>\n  )\n}\n\nconst PureMarkupSchema = () => {\n  const form = useMemo(() => createForm(), [])\n  return (\n    <Form form={form}>\n      <h1>Please pay attention to the performance of the form input</h1>\n      <SchemaField>\n        {Array.from({ length: 2000 }).map((_, i) => {\n          return (\n            <SchemaField.String\n              key={i}\n              name={`name_${i}`}\n              title={`name ${i + 1}`}\n              required\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n              x-component-props={{\n                placeholder: 'Please Input',\n              }}\n            />\n          )\n        })}\n      </SchemaField>\n    </Form>\n  )\n}\n\nconst App = () => {\n  const [visibleAntd, setVisibleAntd] = useState(false)\n  const [visibleJSX, setVisibleJSX] = useState(false)\n  const [visibleMarkupSchema, setVisibleMarkupSchema] = useState(false)\n  const [visibleJSONSchema, setVisibleJSONSchema] = useState(false)\n  const [visibleAntdInput, setVisibleAntdInput] = useState(false)\n  return (\n    <div>\n      <button\n        onClick={() => {\n          setVisibleJSX(!visibleJSX)\n        }}\n      >\n        Show JSX\n      </button>\n      <button\n        onClick={() => {\n          setVisibleMarkupSchema(!visibleMarkupSchema)\n        }}\n      >\n        Show Markup Schema\n      </button>\n      <button\n        onClick={() => {\n          setVisibleJSONSchema(!visibleJSONSchema)\n        }}\n      >\n        Show JSON Schema\n      </button>\n      <button\n        onClick={() => {\n          setVisibleAntd(!visibleAntd)\n        }}\n      >\n        Show Antd\n      </button>\n      <button\n        onClick={() => {\n          setVisibleAntdInput(!visibleAntdInput)\n        }}\n      >\n        Show Antd Input\n      </button>\n      {visibleJSX && <PureJSX />}\n      {visibleMarkupSchema && <PureMarkupSchema />}\n      {visibleJSONSchema && <PureJSONSchema />}\n      {visibleAntd && <PureAntd />}\n      {visibleAntdInput && <PureAntdInput />}\n    </div>\n  )\n}\nReactDOM.render(<App />, document.getElementById('root'))\n"
  },
  {
    "path": "packages/benchmark/template.ejs",
    "content": "<!DOCTYPE html>\n\n<head>\n  <title>\n    Formily benchmark\n  </title>\n  <style>\n    html,\n    body {\n      user-select: none;\n      -webkit-user-select: none;\n    }\n  </style>\n  <link type=\"text/css\" rel=\"stylesheet\" href=\"https://esm.sh/antd@4.x/dist/antd.css\"/>\n</head>\n\n<body>\n  <div id=\"root\">\n  </div>\n  <script src=\"https://esm.sh/moment/min/moment-with-locales.js\"></script>\n  <script src=\"https://esm.sh/react@next/umd/react.production.min.js\"></script>\n  <script src=\"https://esm.sh/react-dom@next/umd/react-dom.production.min.js\"></script>\n  <script src=\"https://esm.sh/antd@4.x/dist/antd-with-locales.min.js\"></script>\n</body>"
  },
  {
    "path": "packages/benchmark/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*\", \"devtools/*\"]\n    },\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/benchmark/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"include\": [\"./src/**/*.ts\", \"./src/**/*.tsx\"],\n  \"exclude\": [\"./src/__tests__/*\", \"./esm/*\", \"./lib/*\"],\n  \"compilerOptions\": {\n    \"lib\": [\"ESNext\", \"DOM\"]\n  }\n}\n"
  },
  {
    "path": "packages/benchmark/webpack.base.ts",
    "content": "import path from 'path'\nimport fs from 'fs-extra'\nimport { GlobSync } from 'glob'\nimport MiniCssExtractPlugin from 'mini-css-extract-plugin'\nimport autoprefixer from 'autoprefixer'\n//import { getThemeVariables } from 'antd/dist/theme'\n\nconst getWorkspaceAlias = () => {\n  const basePath = path.resolve(__dirname, '../../')\n  const pkg = fs.readJSONSync(path.resolve(basePath, 'package.json')) || {}\n  const results = {}\n  const workspaces = pkg.workspaces\n  if (Array.isArray(workspaces)) {\n    workspaces.forEach((pattern) => {\n      const { found } = new GlobSync(pattern, { cwd: basePath })\n      found.forEach((name) => {\n        const pkg = fs.readJSONSync(\n          path.resolve(basePath, name, './package.json')\n        )\n        results[pkg.name] = path.resolve(basePath, name, './src')\n      })\n    })\n  }\n  return results\n}\n\nexport default {\n  mode: 'development',\n  devtool: 'inline-source-map', // 嵌入到源文件中\n  stats: {\n    entrypoints: false,\n    children: false,\n  },\n  entry: {\n    index: path.resolve(__dirname, './src/index'),\n  },\n  output: {\n    path: path.resolve(__dirname, 'build'),\n    filename: '[name].[hash].bundle.js',\n  },\n  resolve: {\n    modules: ['node_modules'],\n    extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],\n    alias: getWorkspaceAlias(),\n  },\n  externals: {\n    react: 'React',\n    'react-dom': 'ReactDOM',\n    moment: 'moment',\n    antd: 'antd',\n  },\n  module: {\n    rules: [\n      {\n        test: /\\.tsx?$/,\n        use: [\n          {\n            loader: require.resolve('ts-loader'),\n            options: {\n              transpileOnly: true,\n            },\n          },\n        ],\n      },\n      {\n        test: /\\.css$/,\n        use: [MiniCssExtractPlugin.loader, require.resolve('css-loader')],\n      },\n      {\n        test: /\\.less$/,\n        use: [\n          MiniCssExtractPlugin.loader,\n          { loader: 'css-loader' },\n          {\n            loader: 'postcss-loader',\n            options: {\n              plugins: () => autoprefixer(),\n            },\n          },\n          {\n            loader: 'less-loader',\n            options: {\n              // modifyVars: getThemeVariables({\n              //   dark: true, // 开启暗黑模式\n              // }),\n              javascriptEnabled: true,\n            },\n          },\n        ],\n      },\n      {\n        test: /\\.(woff|woff2|ttf|eot|svg)(\\?v=\\d+\\.\\d+\\.\\d+)?$/,\n        use: ['url-loader'],\n      },\n      {\n        test: /\\.html?$/,\n        loader: require.resolve('file-loader'),\n        options: {\n          name: '[name].[ext]',\n        },\n      },\n    ],\n  },\n}\n"
  },
  {
    "path": "packages/benchmark/webpack.dev.ts",
    "content": "import baseConfig from './webpack.base'\nimport HtmlWebpackPlugin from 'html-webpack-plugin'\nimport MiniCssExtractPlugin from 'mini-css-extract-plugin'\nimport webpack from 'webpack'\nimport path from 'path'\n\nconst PORT = 3000\n\nconst createPages = (pages) => {\n  return pages.map(({ filename, template, chunk }) => {\n    return new HtmlWebpackPlugin({\n      filename,\n      template,\n      inject: 'body',\n      chunks: chunk,\n    })\n  })\n}\n\nfor (const key in baseConfig.entry) {\n  if (Array.isArray(baseConfig.entry[key])) {\n    baseConfig.entry[key].push(\n      require.resolve('webpack/hot/dev-server'),\n      `${require.resolve('webpack-dev-server/client')}?http://localhost:${PORT}`\n    )\n  }\n}\n\nexport default {\n  ...baseConfig,\n  plugins: [\n    new MiniCssExtractPlugin({\n      filename: '[name].[hash].css',\n      chunkFilename: '[id].[hash].css',\n    }),\n    ...createPages([\n      {\n        filename: 'index.html',\n        template: path.resolve(__dirname, './template.ejs'),\n        chunk: ['index'],\n      },\n    ]),\n    new webpack.HotModuleReplacementPlugin(),\n    // new BundleAnalyzerPlugin()\n  ],\n  devServer: {\n    host: '127.0.0.1',\n    open: true,\n    port: PORT,\n  },\n}\n"
  },
  {
    "path": "packages/benchmark/webpack.prod.ts",
    "content": "import baseConfig from './webpack.base'\nimport HtmlWebpackPlugin from 'html-webpack-plugin'\nimport MiniCssExtractPlugin from 'mini-css-extract-plugin'\nimport path from 'path'\n\nconst createPages = (pages) => {\n  return pages.map(({ filename, template, chunk }) => {\n    return new HtmlWebpackPlugin({\n      filename,\n      template,\n      inject: 'body',\n      chunks: chunk,\n    })\n  })\n}\n\nexport default {\n  ...baseConfig,\n  mode: 'production',\n  plugins: [\n    new MiniCssExtractPlugin({\n      filename: '[name].[hash].css',\n      chunkFilename: '[id].[hash].css',\n    }),\n    ...createPages([\n      {\n        filename: 'index.html',\n        template: path.resolve(__dirname, './template.ejs'),\n        chunk: ['index'],\n      },\n    ]),\n  ],\n  optimization: {\n    minimize: true,\n  },\n}\n"
  },
  {
    "path": "packages/core/.npmignore",
    "content": "node_modules\n*.log\nbuild\ndocs\ndoc-site\n__tests__\n.eslintrc\njest.config.js\ntsconfig.json\n.umi\nsrc"
  },
  {
    "path": "packages/core/.umirc.js",
    "content": "import { resolve } from 'path'\nexport default {\n  mode: 'site',\n  logo: 'https://img.alicdn.com/imgextra/i2/O1CN01Kq3OHU1fph6LGqjIz_!!6000000004056-55-tps-1141-150.svg',\n  title: 'Core',\n  hash: true,\n  favicon:\n    'https://img.alicdn.com/imgextra/i3/O1CN01XtT3Tv1Wd1b5hNVKy_!!6000000002810-55-tps-360-360.svg',\n  outputPath: './doc-site',\n  navs: {\n    'en-US': [\n      {\n        title: 'Guide',\n        path: '/guide',\n      },\n      {\n        title: 'API',\n        path: '/api',\n      },\n      {\n        title: 'Home Site',\n        path: 'https://formilyjs.org',\n      },\n      {\n        title: 'GITHUB',\n        path: 'https://github.com/alibaba/formily',\n      },\n    ],\n    'zh-CN': [\n      {\n        title: '指南',\n        path: '/zh-CN/guide',\n      },\n      {\n        title: 'API',\n        path: '/zh-CN/api',\n      },\n      {\n        title: '主站',\n        path: 'https://formilyjs.org',\n      },\n      {\n        title: 'GITHUB',\n        path: 'https://github.com/alibaba/formily',\n      },\n    ],\n  },\n  headScripts: [\n    `\n    function loadAd(){\n      var header = document.querySelector('.__dumi-default-layout-content .markdown h1')\n      if(header && !header.querySelector('#_carbonads_js')){\n        var script = document.createElement('script')\n        script.src = '//cdn.carbonads.com/carbon.js?serve=CEAICK3M&placement=formilyjsorg'\n        script.id = '_carbonads_js'\n        script.classList.add('head-ad')\n        header.appendChild(script)\n      }\n    }\n    var request = null\n    var observer = new MutationObserver(function(){\n      cancelIdleCallback(request)\n      request = requestIdleCallback(loadAd)\n    })\n    document.addEventListener('DOMContentLoaded',function(){\n      loadAd()\n      observer.observe(\n        document.body,\n        {\n          childList:true,\n          subtree:true\n        }\n      )\n    })\n    `,\n  ],\n  styles: [\n    `.__dumi-default-navbar-logo{\n      background-size: 140px!important;\n      background-position: center left!important;\n      background-repeat: no-repeat!important;\n      padding-left: 150px!important;/*可根据title的宽度调整*/\n      font-size: 22px!important;\n      color: #000!important;\n      font-weight: lighter!important;\n    }\n    .__dumi-default-navbar{\n      padding: 0 28px !important;\n    }\n    .__dumi-default-layout-hero{\n      background-image: url(//img.alicdn.com/imgextra/i4/O1CN01ZcvS4e26XMsdsCkf9_!!6000000007671-2-tps-6001-4001.png);\n      background-size: cover;\n      background-repeat: no-repeat;\n      padding: 120px 0 !important;\n    }\n    .__dumi-default-layout-hero h1{\n      color:#45124e !important;\n      font-size:80px !important;\n      padding-bottom: 30px !important;\n    }\n    .__dumi-default-dark-switch {\n      display:none\n    }\n    nav a{\n      text-decoration: none !important;\n    }\n    #carbonads * {\n      margin: initial;\n      padding: initial;\n    }\n    #carbonads {\n      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,\n        Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Helvetica, Arial,\n        sans-serif;\n    }\n    #carbonads {\n      display: flex;\n      max-width: 330px;\n      background-color: hsl(0, 0%, 98%);\n      box-shadow: 0 1px 4px 1px hsla(0, 0%, 0%, 0.1);\n      z-index: 100;\n      float:right;\n    }\n    #carbonads a {\n      color: inherit;\n      text-decoration: none;\n    }\n    #carbonads a:hover {\n      color: inherit;\n    }\n    #carbonads span {\n      position: relative;\n      display: block;\n      overflow: hidden;\n    }\n    #carbonads .carbon-wrap {\n      display: flex;\n    }\n    #carbonads .carbon-img {\n      display: block;\n      margin: 0;\n      line-height: 1;\n    }\n    #carbonads .carbon-img img {\n      display: block;\n    }\n    #carbonads .carbon-text {\n      font-size: 13px;\n      padding: 10px;\n      margin-bottom: 16px;\n      line-height: 1.5;\n      text-align: left;\n    }\n    #carbonads .carbon-poweredby {\n      display: block;\n      padding: 6px 8px;\n      background: #f1f1f2;\n      text-align: center;\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n      font-weight: 600;\n      font-size: 8px;\n      line-height: 1;\n      border-top-left-radius: 3px;\n      position: absolute;\n      bottom: 0;\n      right: 0;\n    }\n    `,\n  ],\n  menus: {\n    '/guide': [\n      {\n        title: 'Introduction',\n        children: [\n          {\n            title: 'Introduction',\n            path: '/guide',\n          },\n          { title: 'Architecture', path: '/guide/architecture' },\n        ],\n      },\n      {\n        title: 'Concept',\n        children: [\n          {\n            title: 'MVVM',\n            path: '/guide/mvvm',\n          },\n          {\n            title: 'Form Model',\n            path: '/guide/form',\n          },\n          {\n            title: 'Field Model',\n            path: '/guide/field',\n          },\n        ],\n      },\n    ],\n\n    '/zh-CN/guide': [\n      {\n        title: '概览',\n        children: [\n          {\n            title: '介绍',\n            path: '/zh-CN/guide',\n          },\n          { title: '核心架构', path: '/zh-CN/guide/architecture' },\n        ],\n      },\n      {\n        title: '概念',\n        children: [\n          {\n            title: 'MVVM',\n            path: '/zh-CN/guide/mvvm',\n          },\n          {\n            title: '表单模型',\n            path: '/zh-CN/guide/form',\n          },\n          {\n            title: '字段模型',\n            path: '/zh-CN/guide/field',\n          },\n        ],\n      },\n    ],\n  },\n}\n"
  },
  {
    "path": "packages/core/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-present, Alibaba Group Holding Limited. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "packages/core/README.md",
    "content": "# @formily/core\n"
  },
  {
    "path": "packages/core/docs/api/entry/ActionResponse.less",
    "content": ".as-wrapper {\n  .as-actions {\n    & button {\n      margin-right: 5px;\n      background-color: #fff;\n      border: 2px solid #d4bbbb;\n      border-radius: 6px;\n      outline: none;\n      padding: 8px 20px;\n      cursor: pointer;\n      transition: all 0.15s ease-in-out;\n      &:hover {\n        border: 2px solid #9db8f3;\n      }\n    }\n  }\n\n  .as-response {\n    border: 2px dashed #f0bdbd;\n    font-size: 14px;\n    border-radius: 6px;\n    padding: 8px 20px;\n    margin-top: 10px;\n  }\n}\n"
  },
  {
    "path": "packages/core/docs/api/entry/ActionResponse.tsx",
    "content": "import React from 'react'\nimport './ActionResponse.less'\n\ntype ActionResponseProps = {\n  response?: React.ReactNode\n}\n\nexport const ActionResponse: React.FC<\n  React.PropsWithChildren<ActionResponseProps>\n> = (props) => {\n  return (\n    <div className=\"as-wrapper\">\n      <div className=\"as-actions\">{props.children}</div>\n      {props.response && (\n        <div className=\"as-response\">Response：{props.response}</div>\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/core/docs/api/entry/FieldEffectHooks.md",
    "content": "---\norder: 2\n---\n\n# Field Effect Hooks\n\n## onFieldInit\n\n#### Description\n\nUsed to monitor the side effect hook of a field initialization, we will trigger the field initialization event when we call createField\n\n#### Signature\n\n```ts\ninterface onFieldInit {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n<Alert>\n  For the syntax format of FormPathPattern, please refer to <a href=\"/api/entry/form-path\">FormPath</a>\n</Alert>\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldInit } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldInit('target', () => {\n            setResponse('target has been initialized')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({ name: 'target' })\n        }}\n      >\n        Create field\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldMount\n\n#### Description\n\nUsed to monitor the side-effect hook of a field that has been mounted, we will trigger the field mount event when we call onMount\n\n#### Signature\n\n```ts\ninterface onFieldMount {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldMount } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldMount('target', () => {\n            setResponse('target is mounted')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({ name: 'target' }).onMount()\n        }}\n      >\n        Create and mount fields\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldUnmount\n\n#### Description\n\nIt is used to monitor the side effect hook that a field has been unloaded. When we call onUnmount, the unmount event will be triggered\n\n#### Signature\n\n```ts\ninterface onFieldUnmount {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldMount, onFieldUnmount } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldMount('target', () => {\n            setResponse('target is mounted')\n          })\n          onFieldUnmount('target', () => {\n            setResponse('target has been uninstalled')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({ name: 'target' }).onMount()\n        }}\n      >\n        Create and mount fields\n      </button>\n      <button\n        onClick={() => {\n          form.createField({ name: 'target' }).onUnmount()\n        }}\n      >\n        Unload field\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldReact\n\nA side-effect hook used to implement field reactive logic. Its core principle is that the callback function will be executed when the field is initialized, and the dependency will be automatically tracked at the same time. The callback function will be executed repeatedly when the dependent data changes.\n\n#### Signature\n\n```ts\ninterface onFieldReact {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects(form) {\n          onFieldReact('target', () => {\n            setResponse(\n              'target ' + (form.values.other === 123 ? 'display' : 'hide')\n            )\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({ name: 'target' })\n        }}\n      >\n        Initialize target\n      </button>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'other' })\n          field.setValue(123)\n        }}\n      >\n        Assign other = 123\n      </button>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'other' })\n          field.setValue(null)\n        }}\n      >\n        Assign other = null\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n> This example will track the changes of values.other, if it is equal to 123, it will control the display of the target, otherwise it will be hidden\n\n## onFieldChange\n\n#### Description\n\nSide effect hook used to monitor the property changes of a field\n\n#### Signature\n\n```ts\ninterface onFieldChange {\n  (\n    pattern: FormPathPattern,\n    watches?: string[],\n    callback: (field: Field, form: Form) => void\n  )\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\nYou can pass in the specific set of attributes you want to monitor, or you can leave it alone, the default is to monitor value changes\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldChange } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldChange('target', (field) => {\n            setResponse('target value change:' + field.value)\n          })\n          onFieldChange('target', ['component'], () => {\n            setResponse('target component change')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target' })\n          field.setValue(field.value ? field.value + 1 : 1)\n        }}\n      >\n        Settings\n      </button>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target' })\n          field.setComponent('Input')\n        }}\n      >\n        Set up components\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldValueChange\n\nSide effect hooks used to monitor changes in a field value\n\n#### Signature\n\n```ts\ninterface onFieldValueChange {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldValueChange } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldValueChange('target', (field) => {\n            setResponse('target value change:' + field.value)\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target' })\n          field.setValue(field.value ? field.value + 1 : 1)\n        }}\n      >\n        Settings\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldInitialValueChange\n\nSide-effect hooks used to monitor changes in the default value of a field\n\n#### Signature\n\n```ts\ninterface onFieldInitialValueChange {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldInitialValueChange } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldInitialValueChange('target', (field) => {\n            setResponse('target default value change:' + field.value)\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target' })\n          field.setInitialValue(field.value ? field.value + 1 : 1)\n        }}\n      >\n        Settings\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldInputValueChange\n\nUsed to monitor the side effect hook triggered by a field onInput\n\n#### Signature\n\n```ts\ninterface onFieldInputValueChange {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldInputValueChange } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldInputValueChange('target', (field) => {\n            setResponse('target value change:' + field.value)\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target' })\n          field.onInput(field.value ? field.value + 1 : 1)\n        }}\n      >\n        Call onInput\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldValidateStart\n\n#### Description\n\nMonitor the side effect hook that triggers the start of a certain field verification\n\n#### Signature\n\n```ts\ninterface onFieldValidateStart {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldValidateStart } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldValidateStart('target', () => {\n            setResponse('target verification start')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target', required: true })\n          field.onInput('')\n        }}\n      >\n        Trigger verification\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldValidateEnd\n\n#### Description\n\nMonitor the side effect hook that triggers the end of a certain field verification\n\n#### Signature\n\n```ts\ninterface onFieldValidateEnd {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldValidateEnd } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldValidateEnd('target', () => {\n            setResponse('target verification is over')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target', required: true })\n          field.onInput('')\n        }}\n      >\n        Trigger verification\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldValidateFailed\n\n#### Description\n\nListen to the side-effect hook of a field verification trigger failure\n\n#### Signature\n\n```ts\ninterface onFieldValidateFailed {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldValidateFailed } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldValidateFailed('target', () => {\n            setResponse('target verification failed')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target', required: true })\n          field.onInput('')\n        }}\n      >\n        Trigger verification\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldValidateSuccess\n\n#### Description\n\nMonitor the side effect hook that triggers a successful verification of a certain field\n\n#### Signature\n\n```ts\ninterface onFieldValidateSuccess {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport {\n  createForm,\n  onFieldValidateFailed,\n  onFieldValidateSuccess,\n} from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldValidateFailed('target', () => {\n            setResponse('target verification failed')\n          })\n          onFieldValidateSuccess('target', () => {\n            setResponse('target verification succeeded')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target', required: true })\n          field.onInput('')\n        }}\n      >\n        Trigger failed\n      </button>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target', required: true })\n          field.onInput('123')\n        }}\n      >\n        Triggered successfully\n      </button>\n    </ActionResponse>\n  )\n}\n```\n"
  },
  {
    "path": "packages/core/docs/api/entry/FieldEffectHooks.zh-CN.md",
    "content": "---\norder: 2\n---\n\n# Field Effect Hooks\n\n## onFieldInit\n\n#### 描述\n\n用于监听某个字段初始化的副作用钩子，我们在调用 createField 的时候就会触发字段初始化事件\n\n#### 签名\n\n```ts\ninterface onFieldInit {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n<Alert>\n  FormPathPattern的语法格式请参考 <a href=\"/api/entry/form-path\">FormPath</a>\n</Alert>\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldInit } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldInit('target', () => {\n            setResponse('target已初始化')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({ name: 'target' })\n        }}\n      >\n        创建字段\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldMount\n\n#### 描述\n\n用于监听某个字段已挂载的副作用钩子，我们在调用 onMount 的时候就会触发字段挂载事件\n\n#### 签名\n\n```ts\ninterface onFieldMount {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldMount } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldMount('target', () => {\n            setResponse('target已挂载')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({ name: 'target' }).onMount()\n        }}\n      >\n        创建并挂载字段\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldUnmount\n\n#### 描述\n\n用于监听某个字段已卸载的副作用钩子，我们在调用 onUnmount 的时候就会触发卸载事件\n\n#### 签名\n\n```ts\ninterface onFieldUnmount {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldMount, onFieldUnmount } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldMount('target', () => {\n            setResponse('target已挂载')\n          })\n          onFieldUnmount('target', () => {\n            setResponse('target已卸载')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({ name: 'target' }).onMount()\n        }}\n      >\n        创建并挂载字段\n      </button>\n      <button\n        onClick={() => {\n          form.createField({ name: 'target' }).onUnmount()\n        }}\n      >\n        卸载字段\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldReact\n\n用于实现字段响应式逻辑的副作用钩子，它的核心原理就是字段初始化的时候会执行回调函数，同时自动追踪依赖，依赖数据发生变化时回调函数会重复执行\n\n#### 签名\n\n```ts\ninterface onFieldReact {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects(form) {\n          onFieldReact('target', () => {\n            setResponse(\n              'target ' + (form.values.other === 123 ? '显示' : '隐藏')\n            )\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({ name: 'target' })\n        }}\n      >\n        初始化target\n      </button>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'other' })\n          field.setValue(123)\n        }}\n      >\n        赋值other = 123\n      </button>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'other' })\n          field.setValue(null)\n        }}\n      >\n        赋值other = null\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n> 该示例会追踪 values.other 的变化，如果等于 123，就会控制 target 显示，否则隐藏\n\n## onFieldChange\n\n#### 描述\n\n用于监听某个字段的属性变化的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFieldChange {\n  (\n    pattern: FormPathPattern,\n    watches?: string[],\n    callback: (field: Field, form: Form) => void\n  )\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n可以传入具体要监听的的属性集合，也可以不传，默认是监听 value 变化\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldChange } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldChange('target', (field) => {\n            setResponse('target值变化：' + field.value)\n          })\n          onFieldChange('target', ['component'], () => {\n            setResponse('target组件变化')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target' })\n          field.setValue(field.value ? field.value + 1 : 1)\n        }}\n      >\n        设置值\n      </button>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target' })\n          field.setComponent('Input')\n        }}\n      >\n        设置组件\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldValueChange\n\n用于监听某个字段值变化的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFieldValueChange {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldValueChange } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldValueChange('target', (field) => {\n            setResponse('target值变化：' + field.value)\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target' })\n          field.setValue(field.value ? field.value + 1 : 1)\n        }}\n      >\n        设置值\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldInitialValueChange\n\n用于监听某个字段默认值变化的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFieldInitialValueChange {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldInitialValueChange } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldInitialValueChange('target', (field) => {\n            setResponse('target默认值变化：' + field.value)\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target' })\n          field.setInitialValue(field.value ? field.value + 1 : 1)\n        }}\n      >\n        设置值\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldInputValueChange\n\n用于监听某个字段 onInput 触发的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFieldInputValueChange {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldInputValueChange } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldInputValueChange('target', (field) => {\n            setResponse('target 值变化：' + field.value)\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target' })\n          field.onInput(field.value ? field.value + 1 : 1)\n        }}\n      >\n        调用onInput\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldValidateStart\n\n#### 描述\n\n监听某个字段校验触发开始的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFieldValidateStart {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldValidateStart } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldValidateStart('target', () => {\n            setResponse('target校验开始')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target', required: true })\n          field.onInput('')\n        }}\n      >\n        触发校验\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldValidateEnd\n\n#### 描述\n\n监听某个字段校验触发结束的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFieldValidateEnd {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldValidateEnd } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldValidateEnd('target', () => {\n            setResponse('target校验结束')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target', required: true })\n          field.onInput('')\n        }}\n      >\n        触发校验\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldValidateFailed\n\n#### 描述\n\n监听某个字段校验触发失败的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFieldValidateFailed {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFieldValidateFailed } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldValidateFailed('target', () => {\n            setResponse('target校验失败')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target', required: true })\n          field.onInput('')\n        }}\n      >\n        触发校验\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFieldValidateSuccess\n\n#### 描述\n\n监听某个字段校验触发成功的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFieldValidateSuccess {\n  (pattern: FormPathPattern, callback: (field: Field, form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport {\n  createForm,\n  onFieldValidateFailed,\n  onFieldValidateSuccess,\n} from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFieldValidateFailed('target', () => {\n            setResponse('target校验失败')\n          })\n          onFieldValidateSuccess('target', () => {\n            setResponse('target校验成功')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target', required: true })\n          field.onInput('')\n        }}\n      >\n        触发失败\n      </button>\n      <button\n        onClick={() => {\n          const field = form.createField({ name: 'target', required: true })\n          field.onInput('123')\n        }}\n      >\n        触发成功\n      </button>\n    </ActionResponse>\n  )\n}\n```\n"
  },
  {
    "path": "packages/core/docs/api/entry/FormChecker.md",
    "content": "---\norder: 4\n---\n\n# Form Checkers\n\n> The type checker is mainly used to determine the specific type of an object\n\n## isForm\n\n#### Description\n\nDetermine whether an object is a [Form](/api/models/form) object\n\n#### Signature\n\n```ts\ninterface isForm {\n  (target: any): target is Form\n}\n```\n\n#### Example\n\n```ts\nimport { createForm, isForm } from '@formily/core'\n\nconst form = createForm()\n\nconsole.log(isForm(form)) //true\n```\n\n## isField\n\n#### Description\n\nDetermine whether an object is a [Field](/api/models/field) object\n\n#### Signature\n\n```ts\ninterface isField {\n  (target: any): target is Field\n}\n```\n\n#### Example\n\n```ts\nimport { createForm, isField } from '@formily/core'\n\nconst form = createForm()\n\nconst field = form.createField({ name: 'target' })\n\nconsole.log(isField(field)) //true\n```\n\n## isArrayField\n\n#### Description\n\nDetermine whether an object is [ArrayField](/api/models/array-field) object\n\n#### Signature\n\n```ts\ninterface isArrayField {\n  (target: any): target is ArrayField\n}\n```\n\n#### Example\n\n```ts\nimport { createForm, isArrayField } from '@formily/core'\n\nconst form = createForm()\n\nconst field = form.createArrayField({ name: 'target' })\n\nconsole.log(isArrayField(field)) //true\n```\n\n## isObjectField\n\n#### Description\n\nDetermine whether an object is a [ObjectField](/api/models/object-field) object\n\n#### Signature\n\n```ts\ninterface isObjectField {\n  (target: any): target is ObjectField\n}\n```\n\n#### Example\n\n```ts\nimport { createForm, isObjectField } from '@formily/core'\n\nconst form = createForm()\n\nconst field = form.createObjectField({ name: 'target' })\n\nconsole.log(isObjectField(field)) //true\n```\n\n## isVoidField\n\n#### Description\n\nDetermine whether an object is a [VoidField](/api/models/void-field) object\n\n#### Signature\n\n```ts\ninterface isVoidField {\n  (target: any): target is VoidField\n}\n```\n\n#### Example\n\n```ts\nimport { createForm, isVoidField } from '@formily/core'\n\nconst form = createForm()\n\nconst field = form.createVoidField({ name: 'target' })\n\nconsole.log(isVoidField(field)) //true\n```\n\n## isGeneralField\n\n#### Description\n\nDetermine whether an object is a Field/ArrayField/ObjectField/VoidField object\n\n#### Signature\n\n```ts\ninterface isGeneralField {\n  (target: any): target is Field | ArrayField | ObjectField | VoidField\n}\n```\n\n#### Example\n\n```ts\nimport { createForm, isGeneralField } from '@formily/core'\n\nconst form = createForm()\n\nconst field = form.createField({ name: 'target' })\nconst arr = form.createArrayField({ name: 'array' })\nconst obj = form.createObjectField({ name: 'object' })\nconst vod = form.createVoidField({ name: 'void' })\n\nconsole.log(isGeneralField(field)) //true\nconsole.log(isGeneralField(arr)) //true\nconsole.log(isGeneralField(obj)) //true\nconsole.log(isGeneralField(vod)) //true\nconsole.log(isGeneralField({})) //false\n```\n\n## isDataField\n\n#### Description\n\nDetermine whether an object is a Field/ArrayField/ObjectField object\n\n#### Signature\n\n```ts\ninterface isDataField {\n  (target: any): target is Field | ArrayField | ObjectField\n}\n```\n\n#### Example\n\n```ts\nimport { createForm, isDataField } from '@formily/core'\n\nconst form = createForm()\n\nconst field = form.createField({ name: 'target' })\nconst arr = form.createArrayField({ name: 'array' })\nconst obj = form.createObjectField({ name: 'object' })\nconst vod = form.createVoidField({ name: 'void' })\n\nconsole.log(isDataField(field)) //true\nconsole.log(isDataField(arr)) //true\nconsole.log(isDataField(obj)) //true\nconsole.log(isDataField(vod)) //false\nconsole.log(isDataField({})) //false\n```\n\n## isFormState\n\n#### Description\n\nDetermine whether an object is [IFormState](/api/models/form#iformstate) object\n\n#### Signature\n\n```ts\ninterface isFormState {\n  (target: any): target is IFormState\n}\n```\n\n#### Example\n\n```ts\nimport { createForm, isFormState } from '@formily/core'\n\nconst form = createForm()\n\nconsole.log(isFormState(form)) //false\nconsole.log(isFormState(form.getState())) //true\n```\n\n## isFieldState\n\n#### Description\n\nDetermine whether an object is [IFieldState](/api/models/field#ifieldstate) object\n\n#### Signature\n\n```ts\ninterface isFieldState {\n  (target: any): target is IFieldState\n}\n```\n\n#### Example\n\n```ts\nimport { createForm, isFieldState } from '@formily/core'\n\nconst form = createForm()\nconst field = form.createField({\n  name: 'target',\n})\n\nconsole.log(isFieldState(field)) //false\nconsole.log(isFieldState(field.getState())) //true\n```\n\n## isArrayFieldState\n\n#### Description\n\nDetermine whether an object is [IArrayFieldState](/api/models/array-field#iarrayfieldstate) object\n\n#### Signature\n\n```ts\ninterface isArrayFieldState {\n  (target: any): target is IArrayFieldState\n}\n```\n\n#### Example\n\n```ts\nimport { createForm, isArrayFieldState } from '@formily/core'\n\nconst form = createForm()\nconst field = form.createArrayField({\n  name: 'target',\n})\n\nconsole.log(isArrayFieldState(field)) //false\nconsole.log(isArrayFieldState(field.getState())) //true\n```\n\n## isObjectFieldState\n\n#### Description\n\nDetermine whether an object is [IObjectFieldState](/api/models/object-field#iobjectfieldstate) object\n\n#### Signature\n\n```ts\ninterface isObjectFieldState {\n  (target: any): target is IObjectFieldState\n}\n```\n\n#### Example\n\n```ts\nimport { createForm, isObjectFieldState } from '@formily/core'\n\nconst form = createForm()\nconst field = form.createObjectField({\n  name: 'target',\n})\n\nconsole.log(isObjectFieldState(field)) //false\nconsole.log(isObjectFieldState(field.getState())) //true\n```\n\n## isVoidFieldState\n\n#### Description\n\nDetermine whether an object is [IVoidFieldState](/api/models/void-field#ivoidfieldstate) object\n\n#### Signature\n\n```ts\ninterface isVoidFieldState {\n  (target: any): target is IVoidFieldState\n}\n```\n\n#### Example\n\n```ts\nimport { createForm, isVoidFieldState } from '@formily/core'\n\nconst form = createForm()\nconst field = form.createVoidField({\n  name: 'target',\n})\n\nconsole.log(isVoidFieldState(field)) //false\nconsole.log(isVoidFieldState(field.getState())) //true\n```\n\n## isGeneralFieldState\n\n#### Description\n\nDetermine whether an object is an IFieldState/IArrayFieldState/IObjectFieldState/IVoidFieldState object\n\n#### Signature\n\n```ts\ninterface isGeneralFieldState {\n  (target: any): target is\n    | IFieldState\n    | IArrayFieldState\n    | IObjectFieldState\n    | IVoidFieldState\n}\n```\n\n#### Example\n\n```ts\nimport { createForm, isGeneralFieldState } from '@formily/core'\n\nconst form = createForm()\n\nconst field = form.createField({ name: 'target' })\nconst arr = form.createArrayField({ name: 'array' })\nconst obj = form.createObjectField({ name: 'object' })\nconst vod = form.createVoidField({ name: 'void' })\n\nconsole.log(isGeneralFieldState(field)) //false\nconsole.log(isGeneralFieldState(arr)) //false\nconsole.log(isGeneralFieldState(obj)) //false\nconsole.log(isGeneralFieldState(vod)) //false\nconsole.log(isGeneralFieldState(field.getState())) //true\nconsole.log(isGeneralFieldState(arr.getState())) //true\nconsole.log(isGeneralFieldState(obj.getState())) //true\nconsole.log(isGeneralFieldState(vod.getState())) //true\nconsole.log(isGeneralFieldState({})) //false\n```\n\n## isDataFieldState\n\n#### Description\n\nDetermine whether an object is an IFieldState/IArrayFieldState/IObjectFieldState object\n\n#### Signature\n\n```ts\ninterface isDataFieldState {\n  (target: any): target is IFieldState | IArrayFieldState | IObjectFieldState\n}\n```\n\n#### Example\n\n```ts\nimport { createForm, isDataFieldState } from '@formily/core'\n\nconst form = createForm()\n\nconst field = form.createField({ name: 'target' })\nconst arr = form.createArrayField({ name: 'array' })\nconst obj = form.createObjectField({ name: 'object' })\nconst vod = form.createVoidField({ name: 'void' })\n\nconsole.log(isDataFieldState(field)) //false\nconsole.log(isDataFieldState(arr)) //false\nconsole.log(isDataFieldState(obj)) //false\nconsole.log(isDataFieldState(vod)) //false\nconsole.log(isDataFieldState(field.getState())) //true\nconsole.log(isDataFieldState(arr.getState())) //true\nconsole.log(isDataFieldState(obj.getState())) //true\nconsole.log(isDataFieldState(vod.getState())) //false\nconsole.log(isDataFieldState({})) //false\n```\n\n## isQuery\n\n#### Description\n\nDetermine whether an object is a Query object\n\n#### Signature\n\n```ts\ninterface isQuery {\n  (target: any): target is Query\n}\n```\n\n#### Example\n\n```ts\nimport { createForm, isQuery } from '@formily/core'\n\nconst form = createForm()\nconsole.log(isQuery(form.query('target'))) //true\n```\n"
  },
  {
    "path": "packages/core/docs/api/entry/FormChecker.zh-CN.md",
    "content": "---\norder: 4\n---\n\n# Form Checkers\n\n> 类型检查器主要用于判断某个对象具体是什么类型\n\n## isForm\n\n#### 描述\n\n判断一个对象是否为 [Form](/api/models/form) 对象\n\n#### 签名\n\n```ts\ninterface isForm {\n  (target: any): target is Form\n}\n```\n\n#### 用例\n\n```ts\nimport { createForm, isForm } from '@formily/core'\n\nconst form = createForm()\n\nconsole.log(isForm(form)) //true\n```\n\n## isField\n\n#### 描述\n\n判断一个对象是否为 [Field](/api/models/field) 对象\n\n#### 签名\n\n```ts\ninterface isField {\n  (target: any): target is Field\n}\n```\n\n#### 用例\n\n```ts\nimport { createForm, isField } from '@formily/core'\n\nconst form = createForm()\n\nconst field = form.createField({ name: 'target' })\n\nconsole.log(isField(field)) //true\n```\n\n## isArrayField\n\n#### 描述\n\n判断一个对象是否为 [ArrayField](/api/models/array-field) 对象\n\n#### 签名\n\n```ts\ninterface isArrayField {\n  (target: any): target is ArrayField\n}\n```\n\n#### 用例\n\n```ts\nimport { createForm, isArrayField } from '@formily/core'\n\nconst form = createForm()\n\nconst field = form.createArrayField({ name: 'target' })\n\nconsole.log(isArrayField(field)) //true\n```\n\n## isObjectField\n\n#### 描述\n\n判断一个对象是否为 [ObjectField](/api/models/object-field) 对象\n\n#### 签名\n\n```ts\ninterface isObjectField {\n  (target: any): target is ObjectField\n}\n```\n\n#### 用例\n\n```ts\nimport { createForm, isObjectField } from '@formily/core'\n\nconst form = createForm()\n\nconst field = form.createObjectField({ name: 'target' })\n\nconsole.log(isObjectField(field)) //true\n```\n\n## isVoidField\n\n#### 描述\n\n判断一个对象是否为 [VoidField](/api/models/void-field) 对象\n\n#### 签名\n\n```ts\ninterface isVoidField {\n  (target: any): target is VoidField\n}\n```\n\n#### 用例\n\n```ts\nimport { createForm, isVoidField } from '@formily/core'\n\nconst form = createForm()\n\nconst field = form.createVoidField({ name: 'target' })\n\nconsole.log(isVoidField(field)) //true\n```\n\n## isGeneralField\n\n#### 描述\n\n判断一个对象是否为 Field/ArrayField/ObjectField/VoidField 对象\n\n#### 签名\n\n```ts\ninterface isGeneralField {\n  (target: any): target is Field | ArrayField | ObjectField | VoidField\n}\n```\n\n#### 用例\n\n```ts\nimport { createForm, isGeneralField } from '@formily/core'\n\nconst form = createForm()\n\nconst field = form.createField({ name: 'target' })\nconst arr = form.createArrayField({ name: 'array' })\nconst obj = form.createObjectField({ name: 'object' })\nconst vod = form.createVoidField({ name: 'void' })\n\nconsole.log(isGeneralField(field)) //true\nconsole.log(isGeneralField(arr)) //true\nconsole.log(isGeneralField(obj)) //true\nconsole.log(isGeneralField(vod)) //true\nconsole.log(isGeneralField({})) //false\n```\n\n## isDataField\n\n#### 描述\n\n判断一个对象是否为 Field/ArrayField/ObjectField 对象\n\n#### 签名\n\n```ts\ninterface isDataField {\n  (target: any): target is Field | ArrayField | ObjectField\n}\n```\n\n#### 用例\n\n```ts\nimport { createForm, isDataField } from '@formily/core'\n\nconst form = createForm()\n\nconst field = form.createField({ name: 'target' })\nconst arr = form.createArrayField({ name: 'array' })\nconst obj = form.createObjectField({ name: 'object' })\nconst vod = form.createVoidField({ name: 'void' })\n\nconsole.log(isDataField(field)) //true\nconsole.log(isDataField(arr)) //true\nconsole.log(isDataField(obj)) //true\nconsole.log(isDataField(vod)) //false\nconsole.log(isDataField({})) //false\n```\n\n## isFormState\n\n#### 描述\n\n判断一个对象是否为 [IFormState](/api/models/form#iformstate) 对象\n\n#### 签名\n\n```ts\ninterface isFormState {\n  (target: any): target is IFormState\n}\n```\n\n#### 用例\n\n```ts\nimport { createForm, isFormState } from '@formily/core'\n\nconst form = createForm()\n\nconsole.log(isFormState(form)) //false\nconsole.log(isFormState(form.getState())) //true\n```\n\n## isFieldState\n\n#### 描述\n\n判断一个对象是否为 [IFieldState](/api/models/field#ifieldstate) 对象\n\n#### 签名\n\n```ts\ninterface isFieldState {\n  (target: any): target is IFieldState\n}\n```\n\n#### 用例\n\n```ts\nimport { createForm, isFieldState } from '@formily/core'\n\nconst form = createForm()\nconst field = form.createField({\n  name: 'target',\n})\n\nconsole.log(isFieldState(field)) //false\nconsole.log(isFieldState(field.getState())) //true\n```\n\n## isArrayFieldState\n\n#### 描述\n\n判断一个对象是否为 [IArrayFieldState](/api/models/array-field#iarrayfieldstate) 对象\n\n#### 签名\n\n```ts\ninterface isArrayFieldState {\n  (target: any): target is IArrayFieldState\n}\n```\n\n#### 用例\n\n```ts\nimport { createForm, isArrayFieldState } from '@formily/core'\n\nconst form = createForm()\nconst field = form.createArrayField({\n  name: 'target',\n})\n\nconsole.log(isArrayFieldState(field)) //false\nconsole.log(isArrayFieldState(field.getState())) //true\n```\n\n## isObjectFieldState\n\n#### 描述\n\n判断一个对象是否为 [IObjectFieldState](/api/models/object-field#iobjectfieldstate) 对象\n\n#### 签名\n\n```ts\ninterface isObjectFieldState {\n  (target: any): target is IObjectFieldState\n}\n```\n\n#### 用例\n\n```ts\nimport { createForm, isObjectFieldState } from '@formily/core'\n\nconst form = createForm()\nconst field = form.createObjectField({\n  name: 'target',\n})\n\nconsole.log(isObjectFieldState(field)) //false\nconsole.log(isObjectFieldState(field.getState())) //true\n```\n\n## isVoidFieldState\n\n#### 描述\n\n判断一个对象是否为 [IVoidFieldState](/api/models/void-field#ivoidfieldstate) 对象\n\n#### 签名\n\n```ts\ninterface isVoidFieldState {\n  (target: any): target is IVoidFieldState\n}\n```\n\n#### 用例\n\n```ts\nimport { createForm, isVoidFieldState } from '@formily/core'\n\nconst form = createForm()\nconst field = form.createVoidField({\n  name: 'target',\n})\n\nconsole.log(isVoidFieldState(field)) //false\nconsole.log(isVoidFieldState(field.getState())) //true\n```\n\n## isGeneralFieldState\n\n#### 描述\n\n判断一个对象是否为 IFieldState/IArrayFieldState/IObjectFieldState/IVoidFieldState 对象\n\n#### 签名\n\n```ts\ninterface isGeneralFieldState {\n  (target: any): target is\n    | IFieldState\n    | IArrayFieldState\n    | IObjectFieldState\n    | IVoidFieldState\n}\n```\n\n#### 用例\n\n```ts\nimport { createForm, isGeneralFieldState } from '@formily/core'\n\nconst form = createForm()\n\nconst field = form.createField({ name: 'target' })\nconst arr = form.createArrayField({ name: 'array' })\nconst obj = form.createObjectField({ name: 'object' })\nconst vod = form.createVoidField({ name: 'void' })\n\nconsole.log(isGeneralFieldState(field)) //false\nconsole.log(isGeneralFieldState(arr)) //false\nconsole.log(isGeneralFieldState(obj)) //false\nconsole.log(isGeneralFieldState(vod)) //false\nconsole.log(isGeneralFieldState(field.getState())) //true\nconsole.log(isGeneralFieldState(arr.getState())) //true\nconsole.log(isGeneralFieldState(obj.getState())) //true\nconsole.log(isGeneralFieldState(vod.getState())) //true\nconsole.log(isGeneralFieldState({})) //false\n```\n\n## isDataFieldState\n\n#### 描述\n\n判断一个对象是否为 IFieldState/IArrayFieldState/IObjectFieldState 对象\n\n#### 签名\n\n```ts\ninterface isDataFieldState {\n  (target: any): target is IFieldState | IArrayFieldState | IObjectFieldState\n}\n```\n\n#### 用例\n\n```ts\nimport { createForm, isDataFieldState } from '@formily/core'\n\nconst form = createForm()\n\nconst field = form.createField({ name: 'target' })\nconst arr = form.createArrayField({ name: 'array' })\nconst obj = form.createObjectField({ name: 'object' })\nconst vod = form.createVoidField({ name: 'void' })\n\nconsole.log(isDataFieldState(field)) //false\nconsole.log(isDataFieldState(arr)) //false\nconsole.log(isDataFieldState(obj)) //false\nconsole.log(isDataFieldState(vod)) //false\nconsole.log(isDataFieldState(field.getState())) //true\nconsole.log(isDataFieldState(arr.getState())) //true\nconsole.log(isDataFieldState(obj.getState())) //true\nconsole.log(isDataFieldState(vod.getState())) //false\nconsole.log(isDataFieldState({})) //false\n```\n\n## isQuery\n\n#### 描述\n\n判断一个对象是否为 Query 对象\n\n#### 签名\n\n```ts\ninterface isQuery {\n  (target: any): target is Query\n}\n```\n\n#### 用例\n\n```ts\nimport { createForm, isQuery } from '@formily/core'\n\nconst form = createForm()\nconsole.log(isQuery(form.query('target'))) //true\n```\n"
  },
  {
    "path": "packages/core/docs/api/entry/FormEffectHooks.md",
    "content": "---\norder: 1\n---\n\n# Form Effect Hooks\n\n## onFormInit\n\n#### Description\n\nUsed to monitor the side effect hook of a form initialization, we will trigger the initialization event when we call createForm\n\n#### Signature\n\n```ts\ninterface onFormInit {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormInit } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormInit(() => {\n            setResponse('The form has been initialized')\n          })\n        },\n      }),\n    []\n  )\n  return <ActionResponse response={response} />\n}\n```\n\n## onFormMount\n\n#### Description\n\nUsed to monitor the side-effect hook that the form has been mounted, we will trigger the mount event when we call onMount\n\n#### Signature\n\n```ts\ninterface onFormMount {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormMount } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormMount(() => {\n            setResponse('The form has been mounted')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.onMount()\n        }}\n      >\n        Mount form\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormUnmount\n\n#### Description\n\nUsed to monitor the side effect hook that the form has been unloaded, we will trigger the unmount event when we call onUnmount\n\n#### Signature\n\n```ts\ninterface onFormUnmount {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormUnmount } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormUnmount(() => {\n            setResponse('Form has been uninstalled')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.onUnmount()\n        }}\n      >\n        Uninstall form\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormReact\n\n#### Description\n\nThe side effect hook used to implement form response logic. Its core principle is that the callback function will be executed when the form is initialized, and dependencies will be automatically tracked at the same time. The callback function will be executed repeatedly when the dependent data changes.\n\n#### Signature\n\n```ts\ninterface onFormReact {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormReact } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormReact((form) => {\n            if (form.values.input == 'Hello') {\n              setResponse('Response Hello')\n            } else if (form.values.input == 'World') {\n              setResponse('Response to World')\n            }\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.setValuesIn('input', 'Hello')\n        }}\n      >\n        Hello\n      </button>\n      <button\n        onClick={() => {\n          form.setValuesIn('input', 'World')\n        }}\n      >\n        World\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormValuesChange\n\n#### Description\n\nSide effect hooks for monitoring form value changes\n\n<Alert>\nIt should be noted that this hook is triggered synchronously. For some behaviors that trigger `set` operation of `Proxy` multiple times, the results may not be as expected. For example, when deleting elements from array by `splice`, the array length will be the same as before deletion. (<a href=\"https://github.com/alibaba/formily/issues/2128\">#2128</a>)\n</Alert>\n\n#### Signature\n\n```ts\ninterface onFormValuesChange {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormValuesChange } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormValuesChange((form) => {\n            setResponse('Form value change: ' + form.values.input)\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.setValuesIn('input', 'Hello World')\n        }}\n      >\n        Hello World\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormInitialValuesChange\n\n#### Description\n\nSide effect hooks used to monitor the changes of the default value of the form\n\n#### Signature\n\n```ts\ninterface onFormInitialValuesChange {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormInitialValuesChange } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormInitialValuesChange((form) => {\n            setResponse('Form default value change: ' + form.values.input)\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.setInitialValuesIn('input', 'Hello World')\n        }}\n      >\n        Hello World\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormInputChange\n\n#### Description\n\nSide effect hook for listening to field input\n\n#### Signature\n\n```ts\ninterface onFormInputChange {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormInputChange } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormInputChange((form) => {\n            setResponse('Character input change: ' + form.values.input)\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form\n            .createField({\n              name: 'input',\n            })\n            .onInput('Hello World')\n        }}\n      >\n        Hello World\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormSubmit\n\n#### Description\n\nSide effect hook for monitoring form submission\n\n#### Signature\n\n```ts\ninterface onFormSubmit {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmit } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmit(() => {\n            setResponse('Form has been submitted')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.submit()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormSubmitStart\n\n#### Description\n\nSide effect hook for monitoring the start of form submission\n\n#### Signature\n\n```ts\ninterface onFormSubmitStart {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmitStart } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmitStart(() => {\n            setResponse('form submission start')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.submit()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormSubmitEnd\n\n#### Description\n\nSide effect hook for monitoring the end of form submission\n\n#### Signature\n\n```ts\ninterface onFormSubmitEnd {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmitEnd } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmitEnd(() => {\n            setResponse('End of form submission')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.submit()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormSubmitFailed\n\n#### Description\n\nSide-effect hooks used to monitor form submission failures\n\n#### Signature\n\n```ts\ninterface onFormSubmitFailed {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmitFailed } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmitFailed(() => {\n            setResponse('Form submission failed')\n          })\n        },\n      }),\n    []\n  )\n  const form2 = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmitFailed(() => {\n            setResponse('Form verification failed')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.submit(() => {\n            return Promise.reject('Runtime Error')\n          })\n        }}\n      >\n        Submit Runtime Error\n      </button>\n      <button\n        onClick={() => {\n          form2.createField({\n            name: 'input',\n            required: true,\n          })\n          form2.submit()\n        }}\n      >\n        Submit Validate Error\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormSubmitSuccess\n\n#### Description\n\nSide effect hook used to monitor the success of form submission\n\n#### Signature\n\n```ts\ninterface onFormSubmitSuccess {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmitSuccess } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmitSuccess(() => {\n            setResponse('Form submission is successful')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.submit()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormSubmitValidateStart\n\n#### Description\n\nSide effect hook used to monitor the start of field validation of the form submission process\n\n#### Signature\n\n```ts\ninterface onFormSubmitValidateStart {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmitValidateStart } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmitValidateStart(() => {\n            setResponse('Form submission verification starts')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({\n            name: 'input',\n            required: true,\n          })\n          form.submit()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormSubmitValidateEnd\n\n#### Description\n\nSide effect hook used to monitor the end of the field validation of the form submission process\n\n#### Signature\n\n```ts\ninterface onFormSubmitValidateEnd {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmitValidateEnd } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmitValidateEnd(() => {\n            setResponse('Form submission verification is over')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({\n            name: 'input',\n            required: true,\n          })\n          form.submit()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormSubmitValidateFailed\n\n#### Description\n\nSide effect hook used to monitor the field validation failure of the form submission process\n\n#### Signature\n\n```ts\ninterface onFormSubmitValidateFailed {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmitValidateFailed } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmitValidateFailed(() => {\n            setResponse('Form submission verification failed')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({\n            name: 'input',\n            required: true,\n          })\n          form.submit()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormSubmitValidateSuccess\n\n#### Description\n\nSide-effect hook used to monitor the successful field verification of the form submission process\n\n#### Signature\n\n```ts\ninterface onFormSubmitValidateSuccess {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmitValidateSuccess } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmitValidateSuccess(() => {\n            setResponse('Form submission verification succeeded')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({\n            name: 'input',\n          })\n          form.submit()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormValidateStart\n\n#### Description\n\nSide effect hook for monitoring the start of form validation\n\n#### Signature\n\n```ts\ninterface onFormValidateStart {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormValidateStart } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormValidateStart(() => {\n            setResponse('Form verification starts')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({\n            name: 'input',\n            required: true,\n          })\n          form.validate()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormValidateEnd\n\n#### Description\n\nSide effect hook for monitoring the end of form validation\n\n#### Signature\n\n```ts\ninterface onFormValidateEnd {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormValidateEnd } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormValidateEnd(() => {\n            setResponse('Form verification end')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({\n            name: 'input',\n            required: true,\n          })\n          form.validate()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormValidateFailed\n\n#### Description\n\nSide-effect hooks used to monitor form validation failures\n\n#### Signature\n\n```ts\ninterface onFormValidateFailed {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormValidateFailed } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormValidateFailed(() => {\n            setResponse('Form verification failed')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({\n            name: 'input',\n            required: true,\n          })\n          form.validate()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormValidateSuccess\n\n#### Description\n\nSide effect hook for monitoring the start of form validation\n\n#### Signature\n\n```ts\ninterface onFormValidateSuccess {\n  (callback: (form: Form) => void)\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormValidateSuccess } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormValidateSuccess(() => {\n            setResponse('Form verification succeeded')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({\n            name: 'input',\n          })\n          form.validate()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n"
  },
  {
    "path": "packages/core/docs/api/entry/FormEffectHooks.zh-CN.md",
    "content": "---\norder: 1\n---\n\n# Form Effect Hooks\n\n## onFormInit\n\n#### 描述\n\n用于监听某个表单初始化的副作用钩子，我们在调用 createForm 的时候就会触发初始化事件\n\n#### 签名\n\n```ts\ninterface onFormInit {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormInit } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormInit(() => {\n            setResponse('表单已初始化')\n          })\n        },\n      }),\n    []\n  )\n  return <ActionResponse response={response} />\n}\n```\n\n## onFormMount\n\n#### 描述\n\n用于监听表单已挂载的副作用钩子，我们在调用 onMount 的时候就会触发挂载事件\n\n#### 签名\n\n```ts\ninterface onFormMount {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormMount } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormMount(() => {\n            setResponse('表单已挂载')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.onMount()\n        }}\n      >\n        挂载表单\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormUnmount\n\n#### 描述\n\n用于监听表单已卸载的副作用钩子，我们在调用 onUnmount 的时候就会触发卸载事件\n\n#### 签名\n\n```ts\ninterface onFormUnmount {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormUnmount } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormUnmount(() => {\n            setResponse('表单已卸载')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.onUnmount()\n        }}\n      >\n        卸载表单\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormReact\n\n#### 描述\n\n用于实现表单响应式逻辑的副作用钩子，它的核心原理就是表单初始化的时候会执行回调函数，同时自动追踪依赖，依赖数据发生变化时回调函数会重复执行\n\n#### 签名\n\n```ts\ninterface onFormReact {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormReact } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormReact((form) => {\n            if (form.values.input == 'Hello') {\n              setResponse('响应Hello')\n            } else if (form.values.input == 'World') {\n              setResponse('响应World')\n            }\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.setValuesIn('input', 'Hello')\n        }}\n      >\n        Hello\n      </button>\n      <button\n        onClick={() => {\n          form.setValuesIn('input', 'World')\n        }}\n      >\n        World\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormValuesChange\n\n#### 描述\n\n用于监听表单值变化的副作用钩子\n\n<Alert>\n需要注意此钩子是同步触发的，对于某些会多次触发 Proxy set 操作的行为，得到的结果可能会与预期不符。例如: 数组 splice 删除元素时，数组长度会和删除之前相同，只是被删除元素被置为了 undefined。此时需要使用方按需添加 debounce 或 setTimeout。(<a href=\"https://github.com/alibaba/formily/issues/2128\">#2128</a>)\n</Alert>\n\n#### 签名\n\n```ts\ninterface onFormValuesChange {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormValuesChange } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormValuesChange((form) => {\n            setResponse('表单值变化: ' + form.values.input)\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.setValuesIn('input', 'Hello World')\n        }}\n      >\n        Hello World\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormInitialValuesChange\n\n#### 描述\n\n用于监听表单默认值变化的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFormInitialValuesChange {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormInitialValuesChange } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormInitialValuesChange((form) => {\n            setResponse('表单默认值变化: ' + form.values.input)\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.setInitialValuesIn('input', 'Hello World')\n        }}\n      >\n        Hello World\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormInputChange\n\n#### 描述\n\n用于监听字段输入的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFormInputChange {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormInputChange } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormInputChange((form) => {\n            setResponse('字符输入变化: ' + form.values.input)\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form\n            .createField({\n              name: 'input',\n            })\n            .onInput('Hello World')\n        }}\n      >\n        Hello World\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormSubmit\n\n#### 描述\n\n用于监听表单提交的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFormSubmit {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmit } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmit(() => {\n            setResponse('表单已提交')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.submit()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormSubmitStart\n\n#### 描述\n\n用于监听表单提交开始的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFormSubmitStart {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmitStart } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmitStart(() => {\n            setResponse('表单提交开始')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.submit()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormSubmitEnd\n\n#### 描述\n\n用于监听表单提交结束的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFormSubmitEnd {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmitEnd } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmitEnd(() => {\n            setResponse('表单提交结束')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.submit()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormSubmitFailed\n\n#### 描述\n\n用于监听表单提交失败的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFormSubmitFailed {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmitFailed } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmitFailed(() => {\n            setResponse('表单提交失败')\n          })\n        },\n      }),\n    []\n  )\n  const form2 = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmitFailed(() => {\n            setResponse('表单校验失败')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.submit(() => {\n            return Promise.reject('Runtime Error')\n          })\n        }}\n      >\n        Submit Runtime Error\n      </button>\n      <button\n        onClick={() => {\n          form2.createField({\n            name: 'input',\n            required: true,\n          })\n          form2.submit()\n        }}\n      >\n        Submit Validate Error\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormSubmitSuccess\n\n#### 描述\n\n用于监听表单提交成功的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFormSubmitSuccess {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmitSuccess } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmitSuccess(() => {\n            setResponse('表单提交成功')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.submit()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormSubmitValidateStart\n\n#### 描述\n\n用于监听表单提交过程的字段校验开始的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFormSubmitValidateStart {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmitValidateStart } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmitValidateStart(() => {\n            setResponse('表单提交校验开始')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({\n            name: 'input',\n            required: true,\n          })\n          form.submit()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormSubmitValidateEnd\n\n#### 描述\n\n用于监听表单提交过程的字段校验结束的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFormSubmitValidateEnd {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmitValidateEnd } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmitValidateEnd(() => {\n            setResponse('表单提交校验结束')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({\n            name: 'input',\n            required: true,\n          })\n          form.submit()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormSubmitValidateFailed\n\n#### 描述\n\n用于监听表单提交过程的字段校验失败的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFormSubmitValidateFailed {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmitValidateFailed } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmitValidateFailed(() => {\n            setResponse('表单提交校验失败')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({\n            name: 'input',\n            required: true,\n          })\n          form.submit()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormSubmitValidateSuccess\n\n#### 描述\n\n用于监听表单提交过程的字段校验成功的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFormSubmitValidateSuccess {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmitValidateSuccess } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormSubmitValidateSuccess(() => {\n            setResponse('表单提交校验成功')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({\n            name: 'input',\n          })\n          form.submit()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormValidateStart\n\n#### 描述\n\n用于监听表单校验开始的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFormValidateStart {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormValidateStart } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormValidateStart(() => {\n            setResponse('表单校验开始')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({\n            name: 'input',\n            required: true,\n          })\n          form.validate()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormValidateEnd\n\n#### 描述\n\n用于监听表单校验结束的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFormValidateEnd {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormValidateEnd } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormValidateEnd(() => {\n            setResponse('表单校验结束')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({\n            name: 'input',\n            required: true,\n          })\n          form.validate()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormValidateFailed\n\n#### 描述\n\n用于监听表单校验失败的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFormValidateFailed {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormValidateFailed } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormValidateFailed(() => {\n            setResponse('表单校验失败')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({\n            name: 'input',\n            required: true,\n          })\n          form.validate()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## onFormValidateSuccess\n\n#### 描述\n\n用于监听表单校验开始的副作用钩子\n\n#### 签名\n\n```ts\ninterface onFormValidateSuccess {\n  (callback: (form: Form) => void)\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormValidateSuccess } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onFormValidateSuccess(() => {\n            setResponse('表单校验成功')\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.createField({\n            name: 'input',\n          })\n          form.validate()\n        }}\n      >\n        Submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n"
  },
  {
    "path": "packages/core/docs/api/entry/FormHooksAPI.md",
    "content": "---\norder: 3\n---\n\n# Form Hooks API\n\n## createEffectHook\n\n#### Description\n\nCreate a custom hook listener\n\n#### Signature\n\n```ts\ninterface createEffectHook {\n  (\n    type: string,\n    callback?: (\n      payload: any,\n      form: Form,\n      ...ctx: any[] //user-injected context\n    ) => (...args: any[]) => void //High-level callbacks are used to process the encapsulation of the listener and help users achieve parameter customization capabilities\n  )\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, createEffectHook } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nconst onCustomEvent = createEffectHook(\n  'custom-event',\n  (payload, form) => (listener) => {\n    listener(payload, form)\n  }\n)\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onCustomEvent((payload, form) => {\n            setResponse(payload + 'Form:' + form.id)\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.notify('custom-event', 'This is Custom Event')\n        }}\n      >\n        Notify\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## createEffectContext\n\n#### Description\n\nIn the effects function, if we abstract a lot of fine-grained hooks, we need to pass it layer by layer if we want to read the top-level context data in hooks, which is obviously very inefficient, so formily provides createEffectContext to help users quickly obtain context data\n\n#### Signature\n\n```ts\ninterface createEffectContext<T> {\n  (defaultValue: T): {\n    provide(value: T): void\n    consume(): T\n  }\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmit, createEffectContext } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nconst { provide, consume } = createEffectContext()\n\nconst useMyHook = () => {\n  const setResponse = consume()\n  onFormSubmit(() => {\n    setResponse('Context communication succeeded')\n  })\n}\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          provide(setResponse)\n          useMyHook()\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.submit()\n        }}\n      >\n        submit\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## useEffectForm\n\n#### Description\n\nuseEffectForm is actually a convenient usage of EffectContext, because most scene users will read Form instances, so there is no need to manually define an EffectFormContext\n\n#### Signature\n\n```ts\ninterface useEffectForm {\n  (): Form\n}\n```\n\n#### Example\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, useEffectForm, createEffectContext } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nconst { provide, consume } = createEffectContext()\n\nconst useMyHook = () => {\n  const form = useEffectForm()\n  const setResponse = consume()\n  setResponse('Communication successful:' + form.id)\n}\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  useMemo(\n    () =>\n      createForm({\n        effects() {\n          provide(setResponse)\n          useMyHook()\n        },\n      }),\n    []\n  )\n  return <ActionResponse response={response} />\n}\n```\n"
  },
  {
    "path": "packages/core/docs/api/entry/FormHooksAPI.zh-CN.md",
    "content": "---\norder: 3\n---\n\n# Form Hooks API\n\n## createEffectHook\n\n#### 描述\n\n创建自定义钩子监听器\n\n#### 签名\n\n```ts\ninterface createEffectHook {\n  (\n    type: string,\n    callback?: (\n      payload: any,\n      form: Form,\n      ...ctx: any[] //用户注入的上下文\n    ) => (...args: any[]) => void //高阶回调用于处理监听器的封装，帮助用户实现参数定制能力\n  )\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, createEffectHook } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nconst onCustomEvent = createEffectHook(\n  'custom-event',\n  (payload, form) => (listener) => {\n    listener(payload, form)\n  }\n)\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          onCustomEvent((payload, form) => {\n            setResponse(payload + ' Form: ' + form.id)\n          })\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.notify('custom-event', 'This is Custom Event')\n        }}\n      >\n        Notify\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## createEffectContext\n\n#### 描述\n\n在 effects 函数中如果我们抽象了很多细粒度的 hooks，想要在 hooks 里读到顶层上下文数据就需要层层传递，这样明显是很低效的事情，所以 formily 提供了 createEffectContext 帮助用户快速获取上下文数据\n\n#### 签名\n\n```ts\ninterface createEffectContext<T> {\n  (defaultValue: T): {\n    provide(value: T): void\n    consume(): T\n  }\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, onFormSubmit, createEffectContext } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nconst { provide, consume } = createEffectContext()\n\nconst useMyHook = () => {\n  const setResponse = consume()\n  onFormSubmit(() => {\n    setResponse('上下文通讯成功')\n  })\n}\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  const form = useMemo(\n    () =>\n      createForm({\n        effects() {\n          provide(setResponse)\n          useMyHook()\n        },\n      }),\n    []\n  )\n  return (\n    <ActionResponse response={response}>\n      <button\n        onClick={() => {\n          form.submit()\n        }}\n      >\n        提交\n      </button>\n    </ActionResponse>\n  )\n}\n```\n\n## useEffectForm\n\n#### 描述\n\nuseEffectForm 其实是 EffectContext 的便利用法，因为大多数场景用户都会读取 Form 实例，所以就不需要手动定义一个 EffectFormContext\n\n#### 签名\n\n```ts\ninterface useEffectForm {\n  (): Form\n}\n```\n\n#### 用例\n\n```tsx\nimport React, { useMemo, useState } from 'react'\nimport { createForm, useEffectForm, createEffectContext } from '@formily/core'\nimport { ActionResponse } from './ActionResponse'\n\nconst { provide, consume } = createEffectContext()\n\nconst useMyHook = () => {\n  const form = useEffectForm()\n  const setResponse = consume()\n  setResponse('通讯成功：' + form.id)\n}\n\nexport default () => {\n  const [response, setResponse] = useState('')\n  useMemo(\n    () =>\n      createForm({\n        effects() {\n          provide(setResponse)\n          useMyHook()\n        },\n      }),\n    []\n  )\n  return <ActionResponse response={response} />\n}\n```\n"
  },
  {
    "path": "packages/core/docs/api/entry/FormPath.md",
    "content": "---\norder: 5\n---\n\n# FormPath\n\nThe core of FormPath in Formily is to solve 2 types of problems:\n\n- Path matching problem\n- Data manipulation issues\n\nPath matching requires that the given path must be a valid path matching syntax, such as `*(aa,bb,cc)`.\n\nData operation requires that the given path must be a legal data operation path, that is, it must be in the form of `a.b.c` and cannot carry `*`\n\n## Constructor\n\n```ts\nclass FormPath {\n  constructor(pattern: FormPathPattern, base?: FormPathPattern)\n}\n```\n\n## Attributes\n\n| Property           | Description                                                                     | Type                      | Default Value |\n| ------------------ | ------------------------------------------------------------------------------- | ------------------------- | ------------- |\n| length             | If the path is a non-matching path, the length of the path can be read          | Number                    | `0`           |\n| entire             | Path complete string, consistent with the input parameter data                  | String                    |               |\n| segments           | If the path is a non-matching path, you can read the complete path segmentation | `Array<String \\| Number>` | `[]`          |\n| isMatchPattern     | Is the path a matching path                                                     | Boolean                   |               |\n| isWildMatchPattern | Is the path a fully wildcarded path, such as `a.b.*`                            | Boolean                   |               |\n| haveExcludePattern | Does the path have reverse matching, such as `*(!a.b.c)`                        | Boolean                   |               |\n| tree               | Parsed AST tree                                                                 | Node                      |               |\n\n## FormPathPattern\n\n### Signature\n\n```ts\ntype FormPathPattern = string | number | Array<string | number> | RegExp\n```\n\n### Data path syntax\n\n#### Point path\n\n**description**\n\nIt is our most commonly used `a.b.c` format, which uses dot notation to divide each path node, mainly used to read and write data\n\n**Example**\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {}\n\nFormPath.setIn(target, 'a.b.c', 'value')\nconsole.log(FormPath.getIn(target, 'a.b.c')) //'value'\nconsole.log(target) //{a:{b:{c:'value'}}}\n```\n\n#### Subscript path\n\nFor array paths, there will be subscripts. Our subscripts can use dot syntax or square brackets.\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {\n  array: [],\n}\n\nFormPath.setIn(target, 'array.0.aa', '000')\nconsole.log(FormPath.getIn(target, 'array.0.aa')) //000\nconsole.log(target) //{array:[{aa:'000'}]}\nFormPath.setIn(target, 'array[1].aa', '111')\nconsole.log(FormPath.getIn(target, 'array.1.aa')) //111\nconsole.log(target) //{array:[{aa:'000'},{aa:'111'}]}\n```\n\n#### Deconstruction expression\n\nThe deconstruction expression is similar to the ES6 deconstruction grammar, except that it does not support `...` deconstruction. It is very suitable for scenarios where the front and back data is inconsistent. It has several characteristics:\n\n- The deconstruction expression will be regarded as a node of the point path, we can regard it as a normal string node, but it will take effect during data manipulation, so only the deconstruction expression needs to be matched as a normal node node in the matching grammar Can\n- Use the deconstruction path in setIn, the data will be deconstructed\n- Use the deconstruction path in getIn, the data will be reorganized\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {}\n\nFormPath.setIn(target, 'parent.[aa,bb]', [11, 22])\nconsole.log(target) //{parent:{aa:11,bb:22}}\nconsole.log(FormPath.getIn(target, 'parent.[aa,bb]')) //[11,22]\nconsole.log(FormPath.parse('parent.[aa,bb]').toString()) //parent.[aa,bb]\n```\n\n#### relative path\n\nThe relative path syntax is mainly expressed in dot syntax at the head of the data type path. It is very useful for calculating adjacent elements of the array. It has several characteristics:\n\n- A dot represents the current path\n- n dots represent n-1 steps forward\n  - Subscripts can be used to calculate expressions in square brackets: `[+]` represents the current subscript +1, `[-]` represents the current subscript - 1, `[+n]` represents the current subscript +n, ` [-n]` represents the current subscript - n\n- When path matching, group matching and range matching cannot be used, such as `*(..[+1].aa,..[+2].bb)`\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('.dd', 'aa.bb.cc').toString()) //aa.bb.dd\nconsole.log(FormPath.parse('..[].dd', 'aa.1.cc').toString()) //aa.1.dd\nconsole.log(FormPath.parse('..[+].dd', 'aa.1.cc').toString()) //aa.2.dd\nconsole.log(FormPath.parse('..[+10].dd', 'aa.1.cc').toString()) //aa.11.dd\n```\n\n### Match path syntax\n\n#### Full match\n\nFull match is equivalent to matching all paths, only a `*` identification is required\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('*').match('aa')) //true\nconsole.log(FormPath.parse('*').match('aa.bb')) //true\nconsole.log(FormPath.parse('*').match('cc')) //true\n```\n\n#### Partial match\n\nLocal matching is equivalent to matching all paths of a node position, and also only needs to use a `*` mark\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.*.cc').match('aa.bb.cc')) //true\nconsole.log(FormPath.parse('aa.*.cc').match('aa.kk.cc')) //true\nconsole.log(FormPath.parse('aa.*.cc').match('aa.dd.cc')) //true\n```\n\n#### Group Match\n\nGrouped matching can match multiple paths, and also supports nesting, syntax: `*(pattern1,pattern2,pattern3...)`\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(\n  FormPath.parse('aa.*(bb,kk,dd,ee.*(oo,gg).gg).cc').match('aa.bb.cc')\n) //true\nconsole.log(\n  FormPath.parse('aa.*(bb,kk,dd,ee.*(oo,gg).gg).cc').match('aa.kk.cc')\n) //true\nconsole.log(\n  FormPath.parse('aa.*(bb,kk,dd,ee.*(oo,gg).gg).cc').match('aa.dd.cc')\n) //true\nconsole.log(\n  FormPath.parse('aa.*(bb,kk,dd,ee.*(oo,gg).gg).cc').match('aa.ee.oo.gg.cc')\n) //true\nconsole.log(\n  FormPath.parse('aa.*(bb,kk,dd,ee.*(oo,gg).gg).cc').match('aa.ee.gg.gg.cc')\n) //true\n```\n\n#### Reverse match\n\nReverse matching is mainly used to exclude the specified path, syntax: `*(!pattern1,pattern2,pattern3)`\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('*(!aa,bb,cc)').match('aa')) //false\nconsole.log(FormPath.parse('*(!aa,bb,cc)').match('kk')) //true\n```\n\n#### Extended matching\n\nExtended matching is mainly used to match the starting substring of the path, syntax: `pattern~`\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('test~').match('test_111')) //true\nconsole.log(FormPath.parse('test~').match('test_222')) //true\n```\n\n#### Range match\n\nRange matching is mainly used to match the array index range, syntax: `*[x:y]`, x and y can be empty, representing open range matching\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.*[1:2].bb').match('aa.1.bb')) //true\nconsole.log(FormPath.parse('aa.*[1:2].bb').match('aa.2.bb')) //true\nconsole.log(FormPath.parse('aa.*[1:2].bb').match('aa.3.bb')) //false\nconsole.log(FormPath.parse('aa.*[1:].bb').match('aa.3.bb')) //true\nconsole.log(FormPath.parse('aa.*[:100].bb').match('aa.3.bb')) //true\nconsole.log(FormPath.parse('aa.*[:100].bb').match('aa.1000.bb')) //false\n```\n\n#### Escape match\n\nFor path nodes that contain keywords, we can use escape syntax matching, the syntax is `\\\\` or `[[]]`\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(\n  FormPath.parse('aa.\\\\,\\\\*\\\\{\\\\}\\\\.\\\\(\\\\).bb').match(\n    'aa.\\\\,\\\\*\\\\{\\\\}\\\\.\\\\(\\\\).bb'\n  )\n) //true\nconsole.log(FormPath.parse('aa.[[,*{}.()]].bb').match('aa.[[,*{}.()]].bb')) // true\n```\n\n#### Destructuring matching\n\nFor the path with deconstruction expression, if we match, we can directly match without escaping\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('target.[aa,bb]').match('target.[aa,bb]')) //true\n```\n\n## Method\n\n### toString\n\n#### Description\n\nThe complete string of the output path, supporting matching paths and data manipulation paths\n\n#### Signature\n\n```ts\ninterface toString {\n  (): string\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').toString()) //aa.bb.cc\nconsole.log(FormPath.parse('aa.bb.*').toString()) //aa.bb.*\nconsole.log(FormPath.parse('*(aa,bb,cc)').toString()) //*(aa,bb,cc)\n```\n\n### toArray\n\n#### Description\n\nArray fragment of output path, only supports data manipulation path\n\n#### Signature\n\n```ts\ninterface toArray {\n  (): Array<string | number>\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').toArray().join('--')) //aa-bb-cc\nconsole.log(FormPath.parse('aa.bb.*').toArray()) //[]\nconsole.log(FormPath.parse('*(aa,bb,cc)').toArray()) //[]\n```\n\n### concat\n\n#### Description\n\nConnection data operation path\n\n#### Signature\n\n```ts\ninterface concat {\n  (...args: FormPathPattern[]): FormPath\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').concat('dd.ee.mm').toString()) //aa.bb.cc.dd.ee.mm\nconsole.log(\n  FormPath.parse('aa.bb.cc').concat(['dd', 'ee', 'mm'], 'kk.oo').toString()\n) //aa.bb.cc.dd.ee.mm.kk.oo\n```\n\n### slice\n\n#### Description\n\nSelect a segment of the data operation path\n\n#### Signature\n\n```ts\ninterface slice {\n  (start?: number, end?: number): FormPath\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').slice(1).toString()) //bb.cc\n```\n\n### push\n\n#### Description\n\nPush a fragment path to the data operation path\n\n#### Signature\n\n```ts\ninterface push {\n  (...args: FormPathPattern[]): FormPath\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').push('dd.kk').toString()) //aa.bb.cc.dd.kk\n```\n\n### pop\n\n#### Description\n\nPop the last key from the data operation path\n\n#### Signature\n\n```ts\ninterface pop {\n  (): FormPath\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').pop().toString()) //aa.bb\n```\n\n### splice\n\n#### Description\n\nSplice the data operation path\n\n#### Signature\n\n```ts\ninterface splice {\n  (\n    startIndex: number,\n    deleteCount?: number,\n    ...inertItems: Array<string | number>\n  ): FormPath\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').splice(2, 1).toString()) //aa.bb\nconsole.log(FormPath.parse('aa.bb.cc').splice(2, 0, 'ee.gg').toString()) //aa.bb.ee.gg.cc\nconsole.log(FormPath.parse('aa.bb.cc').splice(2, 0, ['kk', 'mm']).toString()) //aa.bb.kk.mm.cc\n```\n\n### forEach\n\n#### Description\n\nTraverse the data operation path\n\n#### Signature\n\n```ts\ninterface forEach {\n  (eacher: (key: string | number, index: number) => void): void\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst keys = []\n\nFormPath.parse('aa.bb.cc').forEach((key) => {\n  keys.push(key)\n})\n\nconsole.log(keys) //['aa','bb','cc']\n```\n\n### map\n\n#### Description\n\nLoop mapping data operation path\n\n#### Signature\n\n```ts\ninterface map {\n  (mapper: (key: string | number, index: number) => void): void\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(\n  FormPath.parse('aa.bb.cc').map((key) => {\n    return key + '~'\n  }) //['aa~','bb~','cc~']\n)\n```\n\n### reduce\n\n#### Description\n\nThe reduce method executes a reducer function (executed in ascending order) provided by you on each element in the path, and aggregates the results into a single return value.\n\n#### Signature\n\n```ts\ninterface reduce<T> {\n  (reducer: (value: T, key: string | number, index: number) => void): void\n  accumulator: T\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(\n  FormPath.parse('aa.bb.cc').reduce((count) => {\n    return count + 1\n  }, 0)\n) //3\n```\n\n### parent\n\n#### Description\n\nGet the parent path of the current data operation path\n\n#### Signature\n\n```ts\ninterface parent {\n  (): FormPath\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').parent().toString()) //aa.bb\n```\n\n### includes\n\n#### Description\n\nUsed to determine whether a given data operation path is a subpath of the current data operation path\n\n#### Signature\n\n```ts\ninterface includes {\n  (pattern: FormPathPattern): boolean\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').includes('aa.bb')) //true\n\nconsole.log(FormPath.parse('aa.bb.cc').includes('cc.bb')) //false\n```\n\n### transform\n\n#### Description\n\nBased on regular extraction data to do path assembly\n\n#### Signature\n\n```ts\ninterface transform<T> {\n  (regExp: RegExp, callback: (...matches: string[]) => T): T\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(\n  FormPath.parse('aa.1.cc').transform(\n    /\\d+/,\n    (index) => `aa.${parseInt(index) + 1}.cc`\n  )\n) //aa.2.cc\n```\n\n### match\n\n#### Description\n\nUse path matching syntax to match the current path\n\n#### Signature\n\n```ts\ninterface match {\n  (pattern: FormPathPattern): boolean\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.1.cc').match('aa.*.cc')) //true\n```\n\n### matchAliasGroup\n\n#### Description\n\nAlias group matching, mainly used to match address and path in formily\n\n#### Signature\n\n```ts\ninterface matchAliasGroup {\n  (pattern: FormPathPattern, alias: FormPathPattern): boolean\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').matchAliasGroup('aa.bb.cc', 'aa.cc')) //true\n```\n\n### existIn\n\n#### Description\n\nDetermine whether the specified data exists based on the current path\n\n#### Signature\n\n```ts\ninterface existIn {\n  (pattern: FormPathPattern): boolean\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').existIn({})) //false\n```\n\n### getIn\n\n#### Description\n\nObtain the specified data based on the current path\n\n#### Signature\n\n```ts\ninterface getIn {\n  (pattern: FormPathPattern): any\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').getIn({ aa: { bb: { cc: 'value' } } })) //value\n```\n\n### setIn\n\n#### Description\n\nUpdate the specified data based on the current path\n\n#### Signature\n\n```ts\ninterface setIn {\n  (pattern: FormPathPattern, value: any): void\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {}\n\nFormPath.parse('aa.bb.cc').setIn(target, 'value')\n\nconsole.log(FormPath.parse('aa.bb.cc').getIn(target)) //value\n```\n\n### deleteIn\n\n#### Description\n\nDelete the specified data based on the current path\n\n#### Signature\n\n```ts\ninterface deleteIn {\n  (pattern: FormPathPattern): boolean\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {\n  aa: {\n    bb: {\n      cc: 'value',\n    },\n  },\n}\n\nFormPath.parse('aa.bb.cc').deleteIn(target)\nconsole.log(FormPath.parse('aa.bb.cc').getIn(target)) //undefined\n```\n\n### ensureIn\n\n#### Description\n\nEnsure that there must be data under a certain path, if not, create data\n\n#### Signature\n\n```ts\ninterface ensureIn {\n  (pattern: FormPathPattern, value: any): any\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {}\n\nFormPath.parse('aa.bb.cc').ensureIn(target, 'value')\n\nconsole.log(FormPath.parse('aa.bb.cc').getIn(target)) //value\n```\n\n## Static method\n\n### match\n\n#### Description\n\nGenerate a path matcher based on matching paths\n\n#### Signature\n\n```ts\ninterface match {\n  (pattern: FormPathPattern): (pattern: FormPathPattern) => boolean\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.match('aa.*.cc')('aa.bb.cc')) // true\n```\n\n### transform\n\n#### Description\n\nRegular conversion path\n\n#### Signature\n\n```ts\ninterface transform<T> {\n  (\n    pattern: FormPathPattern,\n    regexp: RegExp,\n    callback: (...matches: string[]) => T\n  ): T\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(\n  FormPath.transform(\n    'aa.0.bb',\n    /\\d+/,\n    (index) => `aa.${parseInt(index) + 1}.bb`\n  )\n) // `aa.1.bb`\n```\n\n### parse\n\n#### Description\n\nResolve path\n\n#### Signature\n\n```ts\ninterface parse {\n  (pattern: FormPathPattern): FormPath\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.0.bb'))\n```\n\n### getIn\n\nGet data based on path\n\n#### Signature\n\n```ts\ninterface getIn {\n  (target: any, pattern: FormPathPattern): any\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.getIn({ aa: [{ bb: 'value' }] }, 'aa.0.bb'))\n```\n\n### setIn\n\nUpdate data based on path\n\n#### Signature\n\n```ts\ninterface setIn {\n  (target: any, pattern: FormPathPattern, value: any): void\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {}\n\nFormPath.setIn(target, 'aa.bb.cc', 'value')\n\nconsole.log(target) //{aa:{bb:{cc:'value'}}}\n```\n\n### deleteIn\n\nDelete data based on path\n\n#### Signature\n\n```ts\ninterface deleteIn {\n  (target: any, pattern: FormPathPattern): void\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {\n  aa: {\n    bb: {\n      cc: 'value',\n    },\n  },\n}\n\nFormPath.deleteIn(target, 'aa.bb.cc')\n\nconsole.log(target) //{aa:{bb:{}}}\n```\n\n### existIn\n\n#### Description\n\nDetermine whether there is data in the specified path\n\n#### Signature\n\n```ts\ninterface existIn {\n  (target: any, pattern: FormPathPattern): void\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {\n  aa: {\n    bb: {\n      cc: 'value',\n    },\n  },\n}\n\nconsole.log(FormPath.existIn(target, 'aa.bb.cc')) //true\nconsole.log(FormPath.existIn(target, 'aa.bb.kk')) //false\n```\n\n### ensureIn\n\n#### Description\n\nEnsure that there must be data under a certain path, if not, create data\n\n#### Signature\n\n```ts\ninterface ensureIn {\n  (target: any, pattern: FormPathPattern, defaultValue: any): any\n}\n```\n\n#### Example\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {}\n\nFormPath.ensureIn(target, 'aa.bb.cc', 'value')\n\nconsole.log(FormPath.getIn(target, 'aa.bb.cc')) //value\n```\n"
  },
  {
    "path": "packages/core/docs/api/entry/FormPath.zh-CN.md",
    "content": "---\norder: 5\n---\n\n# FormPath\n\nFormPath 在 Formily 中核心是解决 2 类问题：\n\n- 路径匹配问题\n- 数据操作问题\n\n路径匹配是要求给定的路径必须是合法的路径匹配语法，比如`*(aa,bb,cc)`。\n\n数据操作则要求给定的路径必须是合法的数据操作路径，也就是必须为`a.b.c`这样的形式，不能带`*`\n\n## 构造函数\n\n```ts\nclass FormPath {\n  constructor(pattern: FormPathPattern, base?: FormPathPattern)\n}\n```\n\n## 属性\n\n| 属性               | 描述                                                   | 类型                      | 默认值 |\n| ------------------ | ------------------------------------------------------ | ------------------------- | ------ |\n| length             | 如果路径为非匹配型路径，则可以读取路径的长度           | Number                    | `0`    |\n| entire             | 路径完整字符串，与入参数据一致                         | String                    |        |\n| segments           | 如果路径为非匹配型路径，则可以读取到完整的路径分割片段 | `Array<String \\| Number>` | `[]`   |\n| isMatchPattern     | 该路径是否是匹配型路径                                 | Boolean                   |        |\n| isWildMatchPattern | 该路径是否是全通配路径，比如`a.b.*`                    | Boolean                   |        |\n| haveExcludePattern | 该路径是否存在反向匹配，比如`*(!a.b.c)`                | Boolean                   |        |\n| tree               | 解析后的 AST 树                                        | Node                      |        |\n\n## FormPathPattern\n\n### 签名\n\n```ts\ntype FormPathPattern = string | number | Array<string | number> | RegExp\n```\n\n### 数据路径语法\n\n#### 点路径\n\n**描述**\n\n就是我们最常用的`a.b.c`格式，用点符号来分割每个路径节点，主要用来读写数据\n\n**用例**\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {}\n\nFormPath.setIn(target, 'a.b.c', 'value')\nconsole.log(FormPath.getIn(target, 'a.b.c')) //'value'\nconsole.log(target) //{a:{b:{c:'value'}}}\n```\n\n#### 下标路径\n\n对于数组路径，都会有下标，我们的下标可以用点语法，也可以用中括号\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {\n  array: [],\n}\n\nFormPath.setIn(target, 'array.0.aa', '000')\nconsole.log(FormPath.getIn(target, 'array.0.aa')) //000\nconsole.log(target) //{array:[{aa:'000'}]}\nFormPath.setIn(target, 'array[1].aa', '111')\nconsole.log(FormPath.getIn(target, 'array.1.aa')) //111\nconsole.log(target) //{array:[{aa:'000'},{aa:'111'}]}\n```\n\n#### 解构表达式\n\n解构表达式类似于 ES6 的解构语法，只是它不支持`...`解构，在前后端数据不一致的场景非常适用，它主要有几个特点：\n\n- 解构表达式会作为点路径的某个节点，我们可以把它看做一个普通字符串节点，只是在数据操作时会生效，所以在匹配语法中只需要把解构表达式作为普通节点节点来匹配即可\n- 在 setIn 中使用解构路径，数据会被解构\n- 在 getIn 中使用解构路径，数据会被重组\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {}\n\nFormPath.setIn(target, 'parent.[aa,bb]', [11, 22])\nconsole.log(target) //{parent:{aa:11,bb:22}}\nconsole.log(FormPath.getIn(target, 'parent.[aa,bb]')) //[11,22]\nconsole.log(FormPath.parse('parent.[aa,bb]').toString()) //parent.[aa,bb]\n```\n\n#### 相对路径\n\n相对路径语法主要是在数据型路径头部用点语法表示，对于计算数组的相邻元素非常好用，它主要有几个特点：\n\n- 一个点代表当前路径\n- n 个点代表往前 n-1 步\n  - 中括号中可以用下标计算表达式：`[+]`代表当前下标+1，`[-]`代表当前下标-1，`[+n]`代表当前下标+n，`[-n]`代表当前下标-n\n- 路径匹配的时候不能使用分组匹配和范围匹配，比如`*(..[+1].aa,..[+2].bb)`这样的形式\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('.dd', 'aa.bb.cc').toString()) //aa.bb.dd\nconsole.log(FormPath.parse('..[].dd', 'aa.1.cc').toString()) //aa.1.dd\nconsole.log(FormPath.parse('..[+].dd', 'aa.1.cc').toString()) //aa.2.dd\nconsole.log(FormPath.parse('..[+10].dd', 'aa.1.cc').toString()) //aa.11.dd\n```\n\n### 匹配路径语法\n\n#### 全匹配\n\n全匹配相当于是匹配所有路径，只需要用一个`*`标识即可\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('*').match('aa')) //true\nconsole.log(FormPath.parse('*').match('aa.bb')) //true\nconsole.log(FormPath.parse('*').match('cc')) //true\n```\n\n#### 局部匹配\n\n局部匹配相当于是匹配一个节点位置的所有路径，同样只需要用一个`*`标识即可\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.*.cc').match('aa.bb.cc')) //true\nconsole.log(FormPath.parse('aa.*.cc').match('aa.kk.cc')) //true\nconsole.log(FormPath.parse('aa.*.cc').match('aa.dd.cc')) //true\n```\n\n#### 分组匹配\n\n分组匹配可以匹配多个路径，同时还支持嵌套，语法：`*(pattern1,pattern2,pattern3...)`\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(\n  FormPath.parse('aa.*(bb,kk,dd,ee.*(oo,gg).gg).cc').match('aa.bb.cc')\n) //true\nconsole.log(\n  FormPath.parse('aa.*(bb,kk,dd,ee.*(oo,gg).gg).cc').match('aa.kk.cc')\n) //true\nconsole.log(\n  FormPath.parse('aa.*(bb,kk,dd,ee.*(oo,gg).gg).cc').match('aa.dd.cc')\n) //true\nconsole.log(\n  FormPath.parse('aa.*(bb,kk,dd,ee.*(oo,gg).gg).cc').match('aa.ee.oo.gg.cc')\n) //true\nconsole.log(\n  FormPath.parse('aa.*(bb,kk,dd,ee.*(oo,gg).gg).cc').match('aa.ee.gg.gg.cc')\n) //true\n```\n\n#### 反向匹配\n\n反向匹配主要用于排除指定路径，语法：`*(!pattern1,pattern2,pattern3)`\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('*(!aa,bb,cc)').match('aa')) //false\nconsole.log(FormPath.parse('*(!aa,bb,cc)').match('kk')) //true\n```\n\n#### 扩展匹配\n\n扩展匹配主要用于匹配路径起始子串，语法：`pattern~`\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('test~').match('test_111')) //true\nconsole.log(FormPath.parse('test~').match('test_222')) //true\n```\n\n#### 范围匹配\n\n范围匹配主要用于匹配数组索引范围，语法：`*[x:y]`，x 和 y 可以为空，代表开区间匹配\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.*[1:2].bb').match('aa.1.bb')) //true\nconsole.log(FormPath.parse('aa.*[1:2].bb').match('aa.2.bb')) //true\nconsole.log(FormPath.parse('aa.*[1:2].bb').match('aa.3.bb')) //false\nconsole.log(FormPath.parse('aa.*[1:].bb').match('aa.3.bb')) //true\nconsole.log(FormPath.parse('aa.*[:100].bb').match('aa.3.bb')) //true\nconsole.log(FormPath.parse('aa.*[:100].bb').match('aa.1000.bb')) //false\n```\n\n#### 转义匹配\n\n对于路径节点中包含关键字的，我们可以使用转义语法匹配，语法`\\\\`或者`[[]]`\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(\n  FormPath.parse('aa.\\\\,\\\\*\\\\{\\\\}\\\\.\\\\(\\\\).bb').match(\n    'aa.\\\\,\\\\*\\\\{\\\\}\\\\.\\\\(\\\\).bb'\n  )\n) //true\nconsole.log(FormPath.parse('aa.[[,*{}.()]].bb').match('aa.[[,*{}.()]].bb')) //true\n```\n\n#### 解构匹配\n\n对于携带解构表达式的路径，我们匹配的话，直接匹配即可，无需转义\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('target.[aa,bb]').match('target.[aa,bb]')) //true\n```\n\n## 方法\n\n### toString\n\n#### 描述\n\n输出路径的完整字符串，支持匹配型路径与数据操作型路径\n\n#### 签名\n\n```ts\ninterface toString {\n  (): string\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').toString()) //aa.bb.cc\nconsole.log(FormPath.parse('aa.bb.*').toString()) //aa.bb.*\nconsole.log(FormPath.parse('*(aa,bb,cc)').toString()) //*(aa,bb,cc)\n```\n\n### toArray\n\n#### 描述\n\n输出路径的数组片段，仅支持数据操作型路径\n\n#### 签名\n\n```ts\ninterface toArray {\n  (): Array<string | number>\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').toArray().join('--')) //aa-bb-cc\nconsole.log(FormPath.parse('aa.bb.*').toArray()) //[]\nconsole.log(FormPath.parse('*(aa,bb,cc)').toArray()) //[]\n```\n\n### concat\n\n#### 描述\n\n连接数据操作型路径\n\n#### 签名\n\n```ts\ninterface concat {\n  (...args: FormPathPattern[]): FormPath\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').concat('dd.ee.mm').toString()) //aa.bb.cc.dd.ee.mm\nconsole.log(\n  FormPath.parse('aa.bb.cc').concat(['dd', 'ee', 'mm'], 'kk.oo').toString()\n) //aa.bb.cc.dd.ee.mm.kk.oo\n```\n\n### slice\n\n#### 描述\n\n选取数据操作路径的某个片段\n\n#### 签名\n\n```ts\ninterface slice {\n  (start?: number, end?: number): FormPath\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').slice(1).toString()) //bb.cc\n```\n\n### push\n\n#### 描述\n\n往数据操作路径推入某个片段路径\n\n#### 签名\n\n```ts\ninterface push {\n  (...args: FormPathPattern[]): FormPath\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').push('dd.kk').toString()) //aa.bb.cc.dd.kk\n```\n\n### pop\n\n#### 描述\n\n从数据操作路径中弹出最后一个 key\n\n#### 签名\n\n```ts\ninterface pop {\n  (): FormPath\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').pop().toString()) //aa.bb\n```\n\n### splice\n\n#### 描述\n\n对数据操作路径做 splice 操作\n\n#### 签名\n\n```ts\ninterface splice {\n  (\n    startIndex: number,\n    deleteCount?: number,\n    ...inertItems: Array<string | number>\n  ): FormPath\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').splice(2, 1).toString()) //aa.bb\nconsole.log(FormPath.parse('aa.bb.cc').splice(2, 0, 'ee.gg').toString()) //aa.bb.ee.gg.cc\nconsole.log(FormPath.parse('aa.bb.cc').splice(2, 0, ['kk', 'mm']).toString()) //aa.bb.kk.mm.cc\n```\n\n### forEach\n\n#### 描述\n\n遍历数据操作路径\n\n#### 签名\n\n```ts\ninterface forEach {\n  (eacher: (key: string | number, index: number) => void): void\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst keys = []\n\nFormPath.parse('aa.bb.cc').forEach((key) => {\n  keys.push(key)\n})\n\nconsole.log(keys) //['aa','bb','cc']\n```\n\n### map\n\n#### 描述\n\n循环映射数据操作路径\n\n#### 签名\n\n```ts\ninterface map {\n  (mapper: (key: string | number, index: number) => void): void\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(\n  FormPath.parse('aa.bb.cc').map((key) => {\n    return key + '~'\n  }) //['aa~','bb~','cc~']\n)\n```\n\n### reduce\n\n#### 描述\n\nreduce 方法法对路径中的每个元素执行一个由您提供的 reducer 函数(升序执行)，将其结果汇总为单个返回值。\n\n#### 签名\n\n```ts\ninterface reduce<T> {\n  (reducer: (value: T, key: string | number, index: number) => void): void\n  accumulator: T\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(\n  FormPath.parse('aa.bb.cc').reduce((count) => {\n    return count + 1\n  }, 0)\n) //3\n```\n\n### parent\n\n#### 描述\n\n获取当前数据操作路径的父级路径\n\n#### 签名\n\n```ts\ninterface parent {\n  (): FormPath\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').parent().toString()) //aa.bb\n```\n\n### includes\n\n#### 描述\n\n用于判断给定数据操作路径是否为当前数据操作路径的子路径\n\n#### 签名\n\n```ts\ninterface includes {\n  (pattern: FormPathPattern): boolean\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').includes('aa.bb')) //true\n\nconsole.log(FormPath.parse('aa.bb.cc').includes('cc.bb')) //false\n```\n\n### transform\n\n#### 描述\n\n基于正则提取数据做路径拼装\n\n#### 签名\n\n```ts\ninterface transform<T> {\n  (regExp: RegExp, callback: (...matches: string[]) => T): T\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(\n  FormPath.parse('aa.1.cc').transform(\n    /\\d+/,\n    (index) => `aa.${parseInt(index) + 1}.cc`\n  )\n) //aa.2.cc\n```\n\n### match\n\n#### 描述\n\n使用路径匹配语法匹配当前路径\n\n#### 签名\n\n```ts\ninterface match {\n  (pattern: FormPathPattern): boolean\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.1.cc').match('aa.*.cc')) //true\n```\n\n### matchAliasGroup\n\n#### 描述\n\n别名组匹配，在 formily 中主要用来匹配 address 和 path\n\n#### 签名\n\n```ts\ninterface matchAliasGroup {\n  (pattern: FormPathPattern, alias: FormPathPattern): boolean\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').matchAliasGroup('aa.bb.cc', 'aa.cc')) //true\n```\n\n### existIn\n\n#### 描述\n\n基于当前路径判断指定数据是否存在\n\n#### 签名\n\n```ts\ninterface existIn {\n  (pattern: FormPathPattern): boolean\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').existIn({})) //false\n```\n\n### getIn\n\n#### 描述\n\n基于当前路径获取指定数据\n\n#### 签名\n\n```ts\ninterface getIn {\n  (pattern: FormPathPattern): any\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.bb.cc').getIn({ aa: { bb: { cc: 'value' } } })) //value\n```\n\n### setIn\n\n#### 描述\n\n基于当前路径更新指定数据\n\n#### 签名\n\n```ts\ninterface setIn {\n  (pattern: FormPathPattern, value: any): void\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {}\n\nFormPath.parse('aa.bb.cc').setIn(target, 'value')\n\nconsole.log(FormPath.parse('aa.bb.cc').getIn(target)) //value\n```\n\n### deleteIn\n\n#### 描述\n\n基于当前路径删除指定数据\n\n#### 签名\n\n```ts\ninterface deleteIn {\n  (pattern: FormPathPattern): boolean\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {\n  aa: {\n    bb: {\n      cc: 'value',\n    },\n  },\n}\n\nFormPath.parse('aa.bb.cc').deleteIn(target)\nconsole.log(FormPath.parse('aa.bb.cc').getIn(target)) //undefined\n```\n\n### ensureIn\n\n#### 描述\n\n确保某个路径下必须有数据，如果没有则创建数据\n\n#### 签名\n\n```ts\ninterface ensureIn {\n  (pattern: FormPathPattern, value: any): any\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {}\n\nFormPath.parse('aa.bb.cc').ensureIn(target, 'value')\n\nconsole.log(FormPath.parse('aa.bb.cc').getIn(target)) //value\n```\n\n## 静态方法\n\n### match\n\n#### 描述\n\n基于匹配型路径生成一个路径匹配器\n\n#### 签名\n\n```ts\ninterface match {\n  (pattern: FormPathPattern): (pattern: FormPathPattern) => boolean\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.match('aa.*.cc')('aa.bb.cc')) // true\n```\n\n### transform\n\n#### 描述\n\n正则转换路径\n\n#### 签名\n\n```ts\ninterface transform<T> {\n  (\n    pattern: FormPathPattern,\n    regexp: RegExp,\n    callback: (...matches: string[]) => T\n  ): T\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(\n  FormPath.transform(\n    'aa.0.bb',\n    /\\d+/,\n    (index) => `aa.${parseInt(index) + 1}.bb`\n  )\n) // `aa.1.bb`\n```\n\n### parse\n\n#### 描述\n\n解析路径\n\n#### 签名\n\n```ts\ninterface parse {\n  (pattern: FormPathPattern): FormPath\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.parse('aa.0.bb'))\n```\n\n### getIn\n\n基于路径获取数据\n\n#### 签名\n\n```ts\ninterface getIn {\n  (target: any, pattern: FormPathPattern): any\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconsole.log(FormPath.getIn({ aa: [{ bb: 'value' }] }, 'aa.0.bb'))\n```\n\n### setIn\n\n基于路径更新数据\n\n#### 签名\n\n```ts\ninterface setIn {\n  (target: any, pattern: FormPathPattern, value: any): void\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {}\n\nFormPath.setIn(target, 'aa.bb.cc', 'value')\n\nconsole.log(target) //{aa:{bb:{cc:'value'}}}\n```\n\n### deleteIn\n\n基于路径删除数据\n\n#### 签名\n\n```ts\ninterface deleteIn {\n  (target: any, pattern: FormPathPattern): void\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {\n  aa: {\n    bb: {\n      cc: 'value',\n    },\n  },\n}\n\nFormPath.deleteIn(target, 'aa.bb.cc')\n\nconsole.log(target) //{aa:{bb:{}}}\n```\n\n### existIn\n\n#### 描述\n\n判断指定路径是否存在数据\n\n#### 签名\n\n```ts\ninterface existIn {\n  (target: any, pattern: FormPathPattern): void\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {\n  aa: {\n    bb: {\n      cc: 'value',\n    },\n  },\n}\n\nconsole.log(FormPath.existIn(target, 'aa.bb.cc')) //true\nconsole.log(FormPath.existIn(target, 'aa.bb.kk')) //false\n```\n\n### ensureIn\n\n#### 描述\n\n确保某个路径下必须有数据，如果没有则创建数据\n\n#### 签名\n\n```ts\ninterface ensureIn {\n  (target: any, pattern: FormPathPattern, defaultValue: any): any\n}\n```\n\n#### 用例\n\n```ts\nimport { FormPath } from '@formily/core'\n\nconst target = {}\n\nFormPath.ensureIn(target, 'aa.bb.cc', 'value')\n\nconsole.log(FormPath.getIn(target, 'aa.bb.cc')) //value\n```\n"
  },
  {
    "path": "packages/core/docs/api/entry/FormValidatorRegistry.md",
    "content": "---\norder: 6\n---\n\n# Form Validator Registry\n\n## setValidateLanguage\n\n#### Description\n\nSet the built-in verification rule language\n\n#### Signature\n\n```ts\ninterface setValidateLanguage {\n  (language: string): void\n}\n```\n\n#### Example\n\n```ts\nimport { setValidateLanguage } from '@formily/core'\n\nsetValidateLanguage('en-US')\n\nsetValidateLanguage('zh-CN')\n```\n\n## registerValidateFormats\n\n#### Description\n\nRegister general regular rules, the current built-in regular library reference: [formats.ts](https://github.com/alibaba/formily/blob/master/packages/validator/src/formats.ts)\n\n#### Signature\n\n```ts\ninterface registerValidateFormats {\n  (rules: { [key: string]: RegExp }): void\n}\n```\n\n#### Example\n\n```ts\nimport { registerValidateFormats } from '@formily/core'\n\nregisterValidateFormats({\n  integer: /^[+-]?\\d+$/,\n})\n```\n\n## registerValidateLocale\n\n#### Description\n\nGlobal registration verification language package, the current built-in language package reference: [locale.ts](https://github.com/alibaba/formily/blob/master/packages/validator/src/locale.ts)\n\n#### Signature\n\n```ts\ninterface registerValidateLocale {\n  (locales: {\n    [key: string]: {\n      key: string\n    }\n  }): void\n}\n```\n\n#### Example\n\n```ts\nimport { registerValidateLocale } from '@formily/core'\n\nregisterValidateLocale({\n  ja: {\n    required: 'このProjectは mustです',\n  },\n})\n```\n\n## registerValidateMessageTemplateEngine\n\n#### Description\n\nGlobally register the verification message template engine. When we return the verification message in the validator, we can perform conversion based on the template engine syntax\n\n#### Signature\n\n```ts\ninterface registerValidateMessageTemplateEngine {\n  (template: (message: ValidatorFunctionResponse, context: any) => any): void\n}\n```\n\n#### Example\n\n```ts\nimport { registerValidateMessageTemplateEngine } from '@formily/core'\n\nregisterValidateMessageTemplateEngine((message, context) => {\n  return message.replace(/\\<\\%\\s*([\\w.]+)\\s*\\%\\>/g, (_, $0) => {\n    return FormPath.getIn(context, $0)\n  })\n})\n```\n\n## registerValidateRules\n\n#### Description\n\nRegister general verification rules, the current built-in rule library reference: [rules.ts](https://github.com/alibaba/formily/blob/master/packages/validator/src/rules.ts)\n\n#### Signature\n\n```ts\ninterface registerValidateRules {\n  (rules: {\n    [key: string]: (\n      value: any,\n      rule: ValidatorRules,\n      ctx: Context\n    ) => ValidateResult | Promise<ValidateResult>\n  }): void\n}\n```\n\n#### Example\n\n```ts\nimport { registerValidateRules } from '@formily/core'\n\nregisterValidateRules({\n  custom(value) {\n    return value > 100 ? 'error' : ''\n  },\n})\n```\n\n## getValidateLocaleIOSCode\n\n#### Description\n\nGet the built-in ISO Code\n\n#### Signature\n\n```ts\ninterface getValidateLocaleIOSCode {\n  (language: string): string | undefined\n}\n```\n\n#### Example\n\n```ts\nimport { getValidateLocaleIOSCode } from '@formily/core'\n\ngetValidateLocaleIOSCode('en')\n\n// ==> en_US\n```\n"
  },
  {
    "path": "packages/core/docs/api/entry/FormValidatorRegistry.zh-CN.md",
    "content": "---\norder: 6\n---\n\n# Form Validator Registry\n\n## setValidateLanguage\n\n#### 描述\n\n设置内置校验规则语言\n\n#### 签名\n\n```ts\ninterface setValidateLanguage {\n  (language: string): void\n}\n```\n\n#### 用例\n\n```ts\nimport { setValidateLanguage } from '@formily/core'\n\nsetValidateLanguage('en-US')\n\nsetValidateLanguage('zh-CN')\n```\n\n## registerValidateFormats\n\n#### 描述\n\n注册通用正则规则，目前内置正则库参考：[formats.ts](https://github.com/alibaba/formily/blob/master/packages/validator/src/formats.ts)\n\n#### 签名\n\n```ts\ninterface registerValidateFormats {\n  (rules: { [key: string]: RegExp }): void\n}\n```\n\n#### 用例\n\n```ts\nimport { registerValidateFormats } from '@formily/core'\n\nregisterValidateFormats({\n  integer: /^[+-]?\\d+$/,\n})\n```\n\n## registerValidateLocale\n\n#### 描述\n\n全局注册校验语言包，目前内置语言包参考：[locale.ts](https://github.com/alibaba/formily/blob/master/packages/validator/src/locale.ts)\n\n#### 签名\n\n```ts\ninterface registerValidateLocale {\n  (locales: {\n    [key: string]: {\n      key: string\n    }\n  }): void\n}\n```\n\n#### 用例\n\n```ts\nimport { registerValidateLocale } from '@formily/core'\n\nregisterValidateLocale({\n  ja: {\n    required: 'この項目は必須です',\n  },\n})\n```\n\n## registerValidateMessageTemplateEngine\n\n#### 描述\n\n全局注册校验消息模板引擎，我们在校验器中返回校验消息的时候，可以基于模板引擎语法做转换\n\n#### 签名\n\n```ts\ninterface registerValidateMessageTemplateEngine {\n  (template: (message: ValidatorFunctionResponse, context: any) => any): void\n}\n```\n\n#### 用例\n\n```ts\nimport { registerValidateMessageTemplateEngine } from '@formily/core'\n\nregisterValidateMessageTemplateEngine((message, context) => {\n  return message.replace(/\\<\\%\\s*([\\w.]+)\\s*\\%\\>/g, (_, $0) => {\n    return FormPath.getIn(context, $0)\n  })\n})\n```\n\n## registerValidateRules\n\n#### 描述\n\n注册通用校验规则，目前内置规则库参考：[rules.ts](https://github.com/alibaba/formily/blob/master/packages/validator/src/rules.ts)\n\n#### 签名\n\n```ts\ninterface registerValidateRules {\n  (rules: {\n    [key: string]: (\n      value: any,\n      rule: ValidatorRules,\n      ctx: Context\n    ) => ValidateResult | Promise<ValidateResult>\n  }): void\n}\n```\n\n#### 用例\n\n```ts\nimport { registerValidateRules } from '@formily/core'\n\nregisterValidateRules({\n  custom(value) {\n    return value > 100 ? 'error' : ''\n  },\n})\n```\n\n## getValidateLocaleIOSCode\n\n#### 描述\n\n获取内置存在的 ISO Code\n\n#### 签名\n\n```ts\ninterface getValidateLocaleIOSCode {\n  (language: string): string | undefined\n}\n```\n\n#### 用例\n\n```ts\nimport { getValidateLocaleIOSCode } from '@formily/core'\n\ngetValidateLocaleIOSCode('en')\n\n// ==>  en_US\n```\n"
  },
  {
    "path": "packages/core/docs/api/entry/createForm.md",
    "content": "---\norder: 0\n---\n\n# createForm\n\n## Description\n\nCreate a Form instance as a ViewModel for consumption by the UI framework layer\n\n## Signature\n\n```ts\ninterface createForm {\n  (props: IFormProps): Form\n}\n```\n\n## IFormProps\n\n| Property      | Description                                                | Type                                                     | Default Value |\n| ------------- | ---------------------------------------------------------- | -------------------------------------------------------- | ------------- |\n| values        | form values                                                | Object                                                   | `{}`          |\n| initialValues | Form default values                                        | Object                                                   | `{}`          |\n| pattern       | Form interaction mode                                      | `\"editable\" \\| \"disabled\" \\| \"readOnly\" \\| \"readPretty\"` | `\"editable\"`  |\n| display       | The form is visible and hidden                             | `\"visible\" \\| \"hidden\" \\| \"none\"`                        | `\"visible`    |\n| hidden        | UI hidden                                                  | Boolean                                                  | `false`       |\n| visible       | show/hide (data hiding)                                    | Boolean                                                  | `true`        |\n| editable      | Editable                                                   | Boolean                                                  | `true`        |\n| disabled      | Whether to disable                                         | Boolean                                                  | `false`       |\n| readOnly      | Is it read-only                                            | Boolean                                                  | `false`       |\n| readPretty    | Is it an elegant reading state                             | Boolean                                                  | `false`       |\n| effects       | Side effect logic, used to implement various linkage logic | `(form:Form)=>void`                                      |               |\n| validateFirst | Whether to validate only the first illegal rule            | Boolean                                                  | `false`       |\n\n## Example\n\n```ts\nimport { createForm } from '@formily/core'\n\nconst form = createForm({\n  initialValues: {\n    say: 'hello',\n  },\n})\n```\n"
  },
  {
    "path": "packages/core/docs/api/entry/createForm.zh-CN.md",
    "content": "---\norder: 0\n---\n\n# createForm\n\n## 描述\n\n创建一个 Form 实例，作为 ViewModel 给 UI 框架层消费\n\n## 签名\n\n```ts\ninterface createForm {\n  (props: IFormProps): Form\n}\n```\n\n## IFormProps\n\n| 属性          | 描述                             | 类型                                                     | 默认值       |\n| ------------- | -------------------------------- | -------------------------------------------------------- | ------------ |\n| values        | 表单值                           | Object                                                   | `{}`         |\n| initialValues | 表单默认值                       | Object                                                   | `{}`         |\n| pattern       | 表单交互模式                     | `\"editable\" \\| \"disabled\" \\| \"readOnly\" \\| \"readPretty\"` | `\"editable\"` |\n| display       | 表单显隐                         | `\"visible\" \\| \"hidden\" \\| \"none\"`                        | `\"visible`   |\n| hidden        | UI 隐藏                          | Boolean                                                  | `false`      |\n| visible       | 显示/隐藏(数据隐藏)              | Boolean                                                  | `true`       |\n| editable      | 是否可编辑                       | Boolean                                                  | `true`       |\n| disabled      | 是否禁用                         | Boolean                                                  | `false`      |\n| readOnly      | 是否只读                         | Boolean                                                  | `false`      |\n| readPretty    | 是否是优雅阅读态                 | Boolean                                                  | `false`      |\n| effects       | 副作用逻辑，用于实现各种联动逻辑 | `(form:Form)=>void`                                      |              |\n| validateFirst | 是否只校验第一个非法规则         | Boolean                                                  | `false`      |\n\n## 用例\n\n```ts\nimport { createForm } from '@formily/core'\n\nconst form = createForm({\n  initialValues: {\n    say: 'hello',\n  },\n})\n```\n"
  },
  {
    "path": "packages/core/docs/api/models/ArrayField.md",
    "content": "---\norder: 2\n---\n\n# ArrayField\n\nCall the ArrayField model returned by [createArrayField](/api/models/form#createarrayfield).\n\nBecause ArrayField is inherited from the [Field](/api/models/field) model, most APIs can refer to the Field model. This document only explains the extension method\n\n## Method\n\n<Alert>\n\nNote: The following method not only updates the array data, but also transposes the state of the child nodes. If you don't want to automatically transpose the state, you can directly call the `setValue` method to overwrite the update value.\n\n</Alert>\n\n### push\n\n#### Description\n\nAppend an element to the end of the array and trigger onInput\n\n#### Signature\n\n```ts\ninterface push {\n  (...items: any[]): Promise<void>\n}\n```\n\n### pop\n\n#### Description\n\nPop the last element of the array and trigger onInput\n\n#### Signature\n\n```ts\ninterface pop {\n  (): Promise<void>\n}\n```\n\n### insert\n\n#### Description\n\nInsert an element into the array and trigger onInput\n\n#### Signature\n\n```ts\ninterface insert {\n  (index: number, ...items: any[]): Promise<void>\n}\n```\n\n### remove\n\n#### Description\n\nDelete the array element and trigger onInput\n\n#### Signature\n\n```ts\ninterface remove {\n  (index: number): Promise<void>\n}\n```\n\n### shift\n\n#### Description\n\nPop the first element of the array and trigger onInput\n\n#### Signature\n\n```ts\ninterface shift {\n  (): Promise<void>\n}\n```\n\n### unshift\n\n#### Description\n\nAppend an element to the head of the array and trigger onInput\n\n#### Signature\n\n```ts\ninterface unshift {\n  (...items: any[]): Promise<void>\n}\n```\n\n### move\n\n#### Description\n\nMove the array element and trigger onInput\n\n#### Signature\n\n```ts\ninterface move {\n  (fromIndex: number, toIndex: number): Promise<void>\n}\n```\n\n### moveUp\n\n#### Description\n\nMove the array element up and trigger onInput\n\n#### Signature\n\n```ts\ninterface moveUp {\n  (index: number): Promise<void>\n}\n```\n\n### moveDown\n\n#### Description\n\nMove the array element down and trigger onInput\n\n#### Signature\n\n```ts\ninterface moveDown {\n  (index: number): Promise<void>\n}\n```\n\n## Types of\n\n### IArrayFieldState\n\nThe main attributes refer to [IFieldState](/api/models/field#ifieldstate), but the data type of value is required to be an array\n"
  },
  {
    "path": "packages/core/docs/api/models/ArrayField.zh-CN.md",
    "content": "---\norder: 2\n---\n\n# ArrayField\n\n调用[createArrayField](/api/models/form#createarrayfield)所返回的 ArrayField 模型。\n\n因为 ArrayField 是继承至 [Field](/api/models/field) 模型的，所以大部分 API 参考 Field 模型即可，该文档只讲解扩展方法\n\n## 方法\n\n<Alert>\n\n注意：以下方法不仅会对数组数据做更新，同时还会对子节点做状态转置，如果不希望自动转置状态，可以直接调用`setValue`方法覆盖式更新值即可。\n\n</Alert>\n\n### push\n\n#### 描述\n\n往数组尾部追加元素，并触发 onInput\n\n#### 签名\n\n```ts\ninterface push {\n  (...items: any[]): Promise<void>\n}\n```\n\n### pop\n\n#### 描述\n\n弹出数组最后一个元素，并触发 onInput\n\n#### 签名\n\n```ts\ninterface pop {\n  (): Promise<void>\n}\n```\n\n### insert\n\n#### 描述\n\n往数组中插入元素，并触发 onInput\n\n#### 签名\n\n```ts\ninterface insert {\n  (index: number, ...items: any[]): Promise<void>\n}\n```\n\n### remove\n\n#### 描述\n\n删除数组元素，并触发 onInput\n\n#### 签名\n\n```ts\ninterface remove {\n  (index: number): Promise<void>\n}\n```\n\n### shift\n\n#### 描述\n\n弹出数组第一个元素，并触发 onInput\n\n#### 签名\n\n```ts\ninterface shift {\n  (): Promise<void>\n}\n```\n\n### unshift\n\n#### 描述\n\n往数组头部追加元素，并触发 onInput\n\n#### 签名\n\n```ts\ninterface unshift {\n  (...items: any[]): Promise<void>\n}\n```\n\n### move\n\n#### 描述\n\n移动数组元素，并触发 onInput\n\n#### 签名\n\n```ts\ninterface move {\n  (fromIndex: number, toIndex: number): Promise<void>\n}\n```\n\n### moveUp\n\n#### 描述\n\n上移数组元素，并触发 onInput\n\n#### 签名\n\n```ts\ninterface moveUp {\n  (index: number): Promise<void>\n}\n```\n\n### moveDown\n\n#### 描述\n\n下移数组元素，并触发 onInput\n\n#### 签名\n\n```ts\ninterface moveDown {\n  (index: number): Promise<void>\n}\n```\n\n## 类型\n\n### IArrayFieldState\n\n主要属性参考[IFieldState](/api/models/field#ifieldstate)，只是 value 的数据类型要求是数组\n"
  },
  {
    "path": "packages/core/docs/api/models/Field.md",
    "content": "---\norder: 1\n---\n\n# Field\n\nCall the Field model returned by [createField](/api/models/form#createfield).\n\nAll model attributes are listed below. If the attribute is writable, then we can directly refer to it to modify the attribute, and @formily/reactive will respond to trigger the UI update.\n\n## Attributes\n\n| Property       | Description                                         | Type                                               | Read-only or not | Default value |\n| -------------- | --------------------------------------------------- | -------------------------------------------------- | ---------------- | ------------- |\n| initialized    | Has the field been initialized                      | Boolean                                            | No               | `false`       |\n| mounted        | Is the field mounted                                | Boolean                                            | No               | `false`       |\n| unmounted      | Is the field unmounted                              | Boolean                                            | No               | `false`       |\n| address        | Field node path                                     | [FormPath](/api/entry/form-path)                   | Yes              |               |\n| path           | Field data path                                     | [FormPath](/api/entry/form-path)                   | Yes              |               |\n| title          | Field Title                                         | [FieldMessage](#fieldmessage)                      | No               | `\"\"`          |\n| description    | Field description                                   | [FieldMessage](#fieldmessage)                      | No               | `\"\"`          |\n| loading        | Field loading status                                | Boolean                                            | No               | `false`       |\n| validating     | Is the field being validated                        | Boolean                                            | No               | `false`       |\n| modified       | Whether the field tree has been manually modified   | Boolean                                            | No               | `false`       |\n| selfModified   | Whether the field has been manually modified        | Boolean                                            | No               | `false`       |\n| active         | Is the field active                                 | Boolean                                            | No               | `false`       |\n| visited        | Whether the field has been visited                  | Boolean                                            | No               | `false`       |\n| inputValue     | Field input value                                   | Any                                                | No               | `null`        |\n| inputValues    | Field input value collection                        | Array                                              | No               | `[]`          |\n| dataSource     | Field data source                                   | Array                                              | No               | `[]`          |\n| validator      | Field validator                                     | [FieldValidator](#fieldvalidator)                  | No               | `null`        |\n| decorator      | field decorator                                     | Any[]                                              | No               | `null`        |\n| component      | Field component                                     | Any[]                                              | No               | `null`        |\n| feedbacks      | Field feedback information                          | [IFieldFeedback](#ifieldfeedback)[]                | No               | `[]`          |\n| parent         | Parent field                                        | [GeneralField](#generalfield)                      | yes              | `null`        |\n| errors         | Field all error message(include children)           | [IFormFeedback](/api/models/form/#iformfeedback)[] | Yes              | `[]`          |\n| warnings       | Field all warning message(include children)         | [IFormFeedback](/api/models/form/#iformfeedback)[] | Yes              | `[]`          |\n| successes      | Field all success message(include children)         | [IFormFeedback](/api/models/form/#iformfeedback)[] | Yes              | `[]`          |\n| valid          | Is the all field valid(include children)            | Boolean                                            | Yes              | `true`        |\n| invalid        | Is the all field illegal(include children)          | Boolean                                            | Yes              | `false`       |\n| value          | Field value                                         | Any                                                | No               |               |\n| initialValue   | Field default value                                 | Any                                                | No               |               |\n| display        | Field display status                                | [FieldDisplayTypes](#fielddisplaytypes)            | No               | `\"visible\"`   |\n| pattern        | Field interaction mode                              | [FieldPatternTypes](#fieldpatterntypes)            | No               | `\"editable\"`  |\n| required       | Is the field required                               | Boolean                                            | No               | `false`       |\n| hidden         | Whether the field is hidden                         | Boolean                                            | No               | `false`       |\n| visible        | Whether the field is displayed                      | Boolean                                            | No               | `true`        |\n| disabled       | Whether the field is disabled                       | Boolean                                            | No               | `false`       |\n| readOnly       | Is the field read-only                              | Boolean                                            | No               | `false`       |\n| readPretty     | Whether the field is in the reading state           | Boolean                                            | No               | `false`       |\n| editable       | Field is editable                                   | Boolean                                            | No               | `true`        |\n| validateStatus | Field validation status                             | [FieldValidateStatus](#fieldvalidatestatus)        | yes              | `null`        |\n| content        | Field content, usually as a child node              | any                                                | No               | `null`        |\n| data           | Field extends properties                            | Object                                             | No               | `null`        |\n| selfErrors     | Field own error message                             | [FieldMessage](#fieldmessage)[]                    | No               | `[]`          |\n| selfWarnings   | Field own warning message                           | [FieldMessage](#fieldmessage)[]                    | No               | `[]`          |\n| selfSuccesses  | Success message of the field itself                 | [FieldMessage](#fieldmessage)[]                    | No               | `[]`          |\n| selfValid      | Is the field valid                                  | Boolean                                            | Yes              | `true`        |\n| selfInvalid    | Is the field itself illegal                         | Boolean                                            | Yes              | `false`       |\n| indexes        | collection of field numeric indexes                 | Number                                             | yes              | `-`           |\n| index          | field numeric index, take the last index of indexes | Number                                             | Yes              | `-`           |\n\n#### explain in detail\n\n**active**\n\nTrigger onFocus is true, trigger onBlur is false\n\n**visited**\n\nTriggered onFocus will always be true\n\n**inputValue**\n\nTrigger the value collected by onInput\n\n**inputValues**\n\nTrigger the multi-parameter values collected by onInput\n\n**hidden**\n\nWhen true, display is hidden, when false, display is visible\n\n**visible**\n\nWhen true, display is visible, when false, display is none\n\n## Method\n\n### setTitle\n\n#### Description\n\nSet field title\n\n#### Signature\n\n```ts\ninterface setTitle {\n  (title?: FieldMessage): void\n}\n```\n\nFieldMessage Reference [FieldMessage](#fieldmessage)\n\n### setDescription\n\n#### Description\n\nSet field description information\n\n#### Signature\n\n```ts\ninterface setDescription {\n  (title?: FieldMessage): void\n}\n```\n\nFieldMessage Reference [FieldMessage](#fieldmessage)\n\n### setDataSource\n\n#### Description\n\nSet field data source\n\n#### Signature\n\n```ts\ninterface setDataSource {\n  (dataSource?: FieldDataSource): void\n}\n```\n\nFieldDataSource Reference [FieldDataSource](#fielddatasource)\n\n### setFeedback\n\n#### Description\n\nSet field message feedback\n\n#### Signature\n\n```ts\ninterface setFeedback {\n  (feedback?: IFieldFeedback): void\n}\n```\n\nIFieldFeedback Reference [IFieldFeedback](#ifieldfeedback)\n\n### setSelfErrors\n\n#### Description\n\nSet the field error message, here is a feedback update with EffectError as the code, mainly to prevent pollution of the checker result, if you want to force overwrite, you can use setFeedback\n\n#### Signature\n\n```ts\ninterface setSelfErrors {\n  (messages?: FieldMessage[]): void\n}\n```\n\n### setSelfWarnings\n\n#### Description\n\nSet the field warning information, here is a feedback update with EffectWarning as the code, mainly to prevent pollution of the checker result, if you want to force overwrite, you can use setFeedback\n\n#### Signature\n\n```ts\ninterface setSelfWarning {\n  (messages?: FieldMessage[]): void\n}\n```\n\n### setSelfSuccesses\n\n#### Description\n\nSet the field success information, here is a feedback update with EffectSuccess as the code, mainly to prevent pollution of the checker result, if you want to force overwrite, you can use setFeedback\n\n#### Signature\n\n```ts\ninterface setSelfSuccesses {\n  (messages?: FieldMessage[]): void\n}\n```\n\n### setValidator\n\n#### Description\n\nSet field validator\n\n#### Signature\n\n```ts\ninterface setValidator {\n  (validator?: FieldValidator): void\n}\n```\n\nFieldValidator Reference [FieldValidator](#fieldvalidator)\n\n### setRequired\n\n#### Description\n\nWhether the setting field is required\n\n#### Signature\n\n```ts\ninterface setRequired {\n  (required?: boolean): void\n}\n```\n\n### setValidatorRule\n\n#### 描述\n\nSet the field validator according to the rules, similar to setRequired\n\n#### 签名\n\n```ts\ninterface setValidatorRule {\n  (ruleName?: string, ruleValue: any): void\n}\n```\n\n### setValue\n\n#### Description\n\nSet field value\n\n#### Signature\n\n```ts\ninterface setValue {\n  (value?: FieldValue): void\n}\n```\n\nFieldValue Reference [FieldValue](#fieldvalue)\n\n### setInitialValue\n\n#### Description\n\nSet field default value\n\n#### Signature\n\n```ts\ninterface setInitialValue {\n  (initialValue?: FieldValue): void\n}\n```\n\nFieldValue Reference [FieldValue](#fieldvalue)\n\n### setDisplay\n\n#### Description\n\nSet field display status\n\n#### Signature\n\n```ts\ninterface setDisplay {\n  (display?: FieldDisplayTypes): void\n}\n```\n\nFieldDisplayTypes Reference [FieldDisplayTypes](#fielddisplaytypes)\n\n### setPattern\n\n#### Description\n\nSet field interaction mode\n\n#### Signature\n\n```ts\ninterface setPattern {\n  (pattern?: FieldPatternTypes): void\n}\n```\n\nFieldPatternTypes Reference [FieldPatternTypes](#fieldpatterntypes)\n\n### setLoading\n\n#### Description\n\nSet field loading status\n\n#### Signature\n\n```ts\ninterface setLoading {\n  (loading?: boolean): void\n}\n```\n\n### setValidating\n\n#### Description\n\nSet field verification status\n\n#### Signature\n\n```ts\ninterface setValidating {\n  (validating?: boolean): void\n}\n```\n\n### setComponent\n\n#### Description\n\nSet field component\n\n#### Signature\n\n```ts\ninterface setComponent {\n  (component?: FieldComponent, props?: any): void\n}\n```\n\nFieldComponent Reference [FieldComponent](#fieldcomponent)\n\n### setComponentProps\n\n#### Description\n\nSet field component properties\n\n#### Signature\n\n```ts\ninterface setComponentProps {\n  (props?: any): void\n}\n```\n\n### setDecorator\n\n#### Description\n\nSet field decorator\n\n#### Signature\n\n```ts\ninterface setDecorator {\n  (decorator?: FieldDecorator, props?: any): void\n}\n```\n\nFieldDecorator Reference [FieldDecorator](#fielddecorator)\n\n### setDecoratorProps\n\n#### Description\n\nSet field decorator properties\n\n#### Signature\n\n```ts\ninterface setDecoratorProps {\n  (props?: any): void\n}\n```\n\n### setState\n\n#### Description\n\nSet field status\n\n#### Signature\n\n```ts\ninterface setState {\n  (state: IFieldState): void\n  (callback: (state: IFieldState) => void): void\n}\n```\n\nIFieldState Reference [IFieldState](#ifieldstate)\n\n### getState\n\n#### Description\n\nGet field status\n\n#### Signature\n\n```ts\ninterface getState<T> {\n  (): IFieldState\n  (callback: (state: IFieldState) => T): T\n}\n```\n\nIFieldState Reference [IFieldState](#ifieldstate)\n\n### setData\n\n#### Description\n\nset field data\n\n#### Signature\n\n```ts\ninterface setData {\n  (data: any): void\n}\n```\n\n### setContent\n\n#### Description\n\nset field content\n\n#### Signature\n\n```ts\ninterface setContent {\n  (content: any): void\n}\n```\n\n### onInit\n\n#### Description\n\nTrigger field initialization, no need to call manually\n\n#### Signature\n\n```ts\ninterface onInit {\n  (): void\n}\n```\n\n### onMount\n\n#### Description\n\nTrigger field mount\n\n#### Signature\n\n```ts\ninterface onMount {\n  (): void\n}\n```\n\n### onUnmount\n\n#### Description\n\nTrigger field unloading\n\n#### Signature\n\n```ts\ninterface onUnmount {\n  (): void\n}\n```\n\n### onInput\n\n#### Description\n\nTrigger field entry\n\n#### Signature\n\n```ts\ninterface onInput {\n  (...args: any[]): Promise<void>\n}\n```\n\n### onFocus\n\n#### Description\n\nTrigger field focus\n\n#### Signature\n\n```ts\ninterface onFocus {\n  (...args: any[]): Promise<void>\n}\n```\n\n### onBlur\n\n#### Description\n\nTrigger field out of focus\n\n#### Signature\n\n```ts\ninterface onBlur {\n  (...args: any[]): Promise<void>\n}\n```\n\n### submit\n\n#### describe\n\nTrigger field submission (including all sub-nodes, this API is mainly used in sub-form scenarios)\n\n#### sign\n\n```ts\ninterface submit<T> {\n  (): Promise<Field['value']>\n  (onSubmit?: (values: Field['value']) => Promise<T> | void): Promise<T>\n}\n```\n\n### validate\n\n#### Description\n\nTrigger field verification(Contains all sub-nodes, this API is mainly used in sub-form scenarios)\n\n#### Signature\n\n```ts\ninterface validate {\n  (triggerType?: 'onInput' | 'onFocus' | 'onBlur'): Promise<IValidateResults>\n}\n```\n\nIValidateResults Reference [IValidateResults](#ivalidateresults)\n\n### reset\n\n#### Description\n\nTrigger field reset(Contains all sub-nodes, this API is mainly used in sub-form scenarios), if verification is set, then the returned result is the verification result\n\n#### Signature\n\n```ts\ninterface reset {\n  (options?: IFieldResetOptions): Promise<IValidateResults>\n}\n```\n\nIFieldResetOptions Reference [IFieldResetOptions](#ifieldresetoptions)\n\nIValidateResults Reference [IValidateResults](#ivalidateresults)\n\n### query\n\n#### Description\n\nQuery field, you can query adjacent fields based on the current field\n\n#### Signature\n\n```ts\ninterface query {\n  (pattern: FormPathPattern): Query\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\nQuery object API reference [Query](/api/models/query)\n\n### queryFeedbacks\n\n#### Description\n\nQuery the feedback information of the current field\n\n#### Signature\n\n```ts\ninterface queryFeedbacks {\n  (search: ISearchFeedback): IFieldFeedback[]\n}\n```\n\nISearchFeedback Reference [ISearchFeedback](/api/models/field#isearchfeedback)\n\nIFieldFeedback Reference [IFieldFeedback](#ifieldfeedback)\n\n### dispose\n\n#### Description\n\nRelease observer, no need to release manually by default\n\n#### Signature\n\n```ts\ninterface dispose {\n  (): void\n}\n```\n\n### destroy\n\n#### Description\n\nRelease observer, and remove current field model\n\n#### Signature\n\n```ts\ninterface destroy {\n  (): void\n}\n```\n\n### match\n\n#### Description\n\nMatch fields based on path\n\n#### Signature\n\n```ts\ninterface match {\n  (pattern: FormPathPattern): boolean\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\n### inject\n\n#### Description\n\nInject executable methods into field models\n\n#### Signature\n\n```ts\ninterface inject {\n  (actions: Record<string, (...args: any[]) => any>): void\n}\n```\n\n### invoke\n\n#### Description\n\nInvoke an executable method injected by the field model via inject\n\n#### Signature\n\n```ts\ninterface invoke {\n  (name: string, ...args: any[]): any\n}\n```\n\n## Types of\n\n<Alert>\nNote: If you want to manually consume the type, just export it directly from the package module\n</Alert>\n\n### FieldValidator\n\nField validator, the type is more complicated and needs to be digested carefully by the user\n\n```ts\n//String format validator\ntype ValidatorFormats =\n  | 'url'\n  | 'email'\n  | 'ipv6'\n  | 'ipv4'\n  | 'number'\n  | 'integer'\n  | 'idcard'\n  | 'qq'\n  | 'phone'\n  | 'money'\n  | 'zh'\n  | 'date'\n  | 'zip'\n  | (string & {}) //Other format validators need to be registered through registerValidateFormats\n\n//Object type verification result\ninterface IValidateResult {\n  type: 'error' | 'warning' | 'success' | (string & {})\n  message: string\n}\n//Object validator\ninterface IValidatorRules<Context = any> {\n  triggerType?: 'onInput' | 'onFocus' | 'onBlur'\n  format?: ValidatorFormats\n  validator?: ValidatorFunction<Context>\n  required?: boolean\n  pattern?: RegExp | string\n  max?: number\n  maximum?: number\n  exclusiveMaximum?: number\n  exclusiveMinimum?: number\n  minimum?: number\n  min?: number\n  len?: number\n  whitespace?: boolean\n  enum?: any[]\n  const?: any\n  multipleOf?: number\n  uniqueItems?: boolean\n  maxProperties?: number\n  minProperties?: number\n  maxItems?: number\n  maxLength?: number\n  minItems?: number\n  minLength?: number\n  message?: string\n  [key: string]: any //Other attributes need to be registered through registerValidateRules\n}\n//Function type validator check result type\ntype ValidatorFunctionResponse = null | string | boolean | IValidateResult\n\n//Functional validator\ntype ValidatorFunction<Context = any> = (\n  value: any,\n  rule: IValidatorRules<Context>,\n  ctx: Context\n) => ValidatorFunctionResponse | Promise<ValidatorFunctionResponse> | null\n\n//Non-array validator\ntype ValidatorDescription =\n  | ValidatorFormats\n  | ValidatorFunction<Context>\n  | IValidatorRules<Context>\n\n//Array type validator\ntype MultiValidator<Context = any> = ValidatorDescription<Context>[]\n\ntype FieldValidator<Context = any> =\n  | ValidatorDescription<Context>\n  | MultiValidator<Context>\n```\n\n### FieldMessage\n\n```ts\ntype FieldMessage = string | JSXElement\n```\n\nIf under the UI framework that supports JSX, we can directly pass the Node of JSX, otherwise, we can only pass the string\n\n### FieldDataSource\n\n```ts\ntype FieldDataSource<ValueType> = Array<{\n  label: string | JSXElement\n  value: ValueType\n  [key: string]: any\n}>\n```\n\nThe field data source is actually an array. The form of the content is determined by the user, but we recommend that users express the data source in the form of label/value. It should be noted here that if it is to be used in the UI framework, it is not set directly. To be effective, the dataSource property must be bound to a specific UI component to be effective. For example, using @formily/react, if you want to bind the state, you can use the connect function, or you can directly get the field instance through useField in the component. consumption.\n\n### FieldValue\n\nThe field value type is actually the `Any` type, but it is important to mention that if it is a mandatory array type in ArrayField, it is a mandatory object type in ObjectField.\n\n### FieldComponent\n\n```ts\ntype FieldComponent = string | JSXComponentConstructor\n```\n\nField component, if we use it in a framework that supports JSX, FieldComponent recommends to store the JSX component reference directly, otherwise it can store a component identification string and distribute it during actual rendering.\n\n### FieldDecorator\n\n```ts\ntype FieldDecorator = string | JSXComponentConstructor\n```\n\nField decorator, if we use it in a framework that supports JSX, FieldDecorator recommends to store the JSX component reference directly, otherwise it can store a component identification string and distribute it during actual rendering.\n\n### FieldReaction\n\n```ts\ntype FieldReaction = (field: GeneralField) => void\n```\n\n### FieldDisplayTypes\n\n```ts\ntype FieldDisplayTypes = 'none' | 'hidden' | 'visible'\n```\n\n### FieldPatternTypes\n\n```ts\ntype FieldPatternTypes = 'editable' | 'disabled' | 'readOnly' | 'readPretty'\n```\n\n### FieldValidateStatus\n\n```ts\ntype FieldValidateStatus = 'error' | 'warning' | 'success' | 'validating'\n```\n\n### GeneralField\n\n```ts\ntype GeneralField = Field | VoidField | ArrayField | ObjectField\n```\n\nVoidField Reference [VoidField](/api/models/void-field)\n\nArrayField Reference [ArrayField](/api/models/array-field)\n\nObjectField Reference [ObjectField](/api/models/object-field)\n\n### IFieldFeedback\n\n```ts\ninterface IFieldFeedback {\n  triggerType?: 'onInput' | 'onFocus' | 'onBlur' //Verify the trigger type\n  type?: 'error' | 'success' | 'warning' //feedback type\n  code?: //Feedback code\n  | 'ValidateError'\n    | 'ValidateSuccess'\n    | 'ValidateWarning'\n    | 'EffectError'\n    | 'EffectSuccess'\n    | 'EffectWarning'\n  messages?: string[] //Feedback message\n}\n```\n\n### ISearchFeedback\n\n```ts\ninterface ISearchFeedback {\n  triggerType?: 'onInput' | 'onFocus' | 'onBlur' //Verify the trigger type\n  type?: 'error' | 'success' | 'warning' //feedback type\n  code?: //Feedback code\n  | 'ValidateError'\n    | 'ValidateSuccess'\n    | 'ValidateWarning'\n    | 'EffectError'\n    | 'EffectSuccess'\n    | 'EffectWarning'\n  address?: FormPathPattern\n  path?: FormPathPattern\n  messages?: string[]\n}\n```\n\n### IFieldState\n\n```ts\ninterface IFieldState {\n  hidden?: boolean\n  visible?: boolean\n  editable?: boolean\n  readOnly?: boolean\n  disabled?: boolean\n  readPretty?: boolean\n  title?: any\n  description?: any\n  loading?: boolean\n  validating?: boolean\n  modified?: boolean\n  active?: boolean\n  visited?: boolean\n  inputValue?: FieldValue\n  inputValues?: any[]\n  initialized?: boolean\n  dataSource?: FieldDataSource\n  mounted?: boolean\n  unmounted?: boolean\n  validator?: FieldValidator\n  decorator?: FieldDecorator\n  component?: FieldComponent\n  readonly parent?: GeneralField\n  errors?: FieldMessage[]\n  warnings?: FieldMessage[]\n  successes?: FieldMessage[]\n  readonly valid?: boolean\n  readonly invalid?: boolean\n  value?: FieldValue\n  initialValue?: FieldValue\n  display?: FieldDisplayTypes\n  pattern?: FieldPatternTypes\n  required?: boolean\n  readonly validateStatus?: 'error' | 'success' | 'warning' | 'validating'\n}\n```\n\n### IGeneralFieldState\n\n```ts\ntype IGeneralFieldState = IFieldState & IVoidFieldState\n```\n\nIVoidFieldState Reference [IVoidFieldState](/api/models/void-field#ivoidfieldstate)\n\n### IFieldResetOptions\n\n```ts\ninterface IFieldResetOptions {\n  forceClear?: boolean //Whether to force clear\n  validate?: boolean //Whether to verify\n}\n```\n\n### IValidateResults\n\n```ts\ninterface IValidateResults {\n  error?: string[]\n  warning?: string[]\n  success?: string[]\n}\n```\n\n> Formily Typescript type convention\n>\n> - Simple non-object data types or Union data types use type to define the type, and cannot start with an uppercase `I` character\n> - Simple object types use interface to define the type uniformly, and start with an uppercase `I` character. If there are combinations of different interfaces (Intersection or Extends), use type to define the type, and also start with an uppercase `I` character\n"
  },
  {
    "path": "packages/core/docs/api/models/Field.zh-CN.md",
    "content": "---\norder: 1\n---\n\n# Field\n\n调用[createField](/api/models/form#createfield)所返回的 Field 模型。\n\n以下会列出所有模型属性，如果该属性是可写的，那么我们可以直接引用是修改该属性，@formily/reactive 便会响应从而触发 UI 更新。\n\n## 属性\n\n| 属性           | 描述                              | 类型                                               | 是否只读 | 默认值       |\n| -------------- | --------------------------------- | -------------------------------------------------- | -------- | ------------ |\n| initialized    | 字段是否已被初始化                | Boolean                                            | 否       | `false`      |\n| mounted        | 字段是否已挂载                    | Boolean                                            | 否       | `false`      |\n| unmounted      | 字段是否已卸载                    | Boolean                                            | 否       | `false`      |\n| address        | 字段节点路径                      | [FormPath](/api/entry/form-path)                   | 是       |              |\n| path           | 字段数据路径                      | [FormPath](/api/entry/form-path)                   | 是       |              |\n| title          | 字段标题                          | [FieldMessage](#fieldmessage)                      | 否       | `\"\"`         |\n| description    | 字段描述                          | [FieldMessage](#fieldmessage)                      | 否       | `\"\"`         |\n| loading        | 字段加载状态                      | Boolean                                            | 否       | `false`      |\n| validating     | 字段是否正在校验                  | Boolean                                            | 否       | `false`      |\n| modified       | 字段子树是否被手动修改过          | Boolean                                            | 否       | `false`      |\n| selfModified   | 字段自身是否被手动修改过          | Boolean                                            | 否       | `false`      |\n| active         | 字段是否处于激活态                | Boolean                                            | 否       | `false`      |\n| visited        | 字段是否被浏览过                  | Boolean                                            | 否       | `false`      |\n| inputValue     | 字段输入值                        | Any                                                | 否       | `null`       |\n| inputValues    | 字段输入值集合                    | Array                                              | 否       | `[]`         |\n| dataSource     | 字段数据源                        | Array                                              | 否       | `[]`         |\n| validator      | 字段校验器                        | [FieldValidator](#fieldvalidator)                  | 否       | `null`       |\n| decorator      | 字段装饰器                        | Any[]                                              | 否       | `null`       |\n| component      | 字段组件                          | Any[]                                              | 否       | `null`       |\n| feedbacks      | 字段反馈信息                      | [IFieldFeedback](#ifieldfeedback)[]                | 否       | `[]`         |\n| parent         | 父级字段                          | [GeneralField](#generalfield)                      | 是       | `null`       |\n| errors         | 字段汇总(包含子节点)错误消息      | [IFormFeedback](/api/models/form/#iformfeedback)[] | 是       | `[]`         |\n| warnings       | 字段汇总(包含子节点)警告消息      | [IFormFeedback](/api/models/form/#iformfeedback)[] | 是       | `[]`         |\n| successes      | 字段汇总(包含子节点)成功消息      | [IFormFeedback](/api/models/form/#iformfeedback)[] | 是       | `[]`         |\n| valid          | 字段是否合法(包含子节点)          | Boolean                                            | 否       | `true`       |\n| invalid        | 字段是否非法(包含子节点)          | Boolean                                            | 否       | `false`      |\n| value          | 字段值                            | Any                                                | 否       |              |\n| initialValue   | 字段默认值                        | Any                                                | 否       |              |\n| display        | 字段展示状态                      | [FieldDisplayTypes](#fielddisplaytypes)            | 否       | `\"visible\"`  |\n| pattern        | 字段交互模式                      | [FieldPatternTypes](#fieldpatterntypes)            | 否       | `\"editable\"` |\n| required       | 字段是否必填                      | Boolean                                            | 否       | `false`      |\n| hidden         | 字段是否隐藏                      | Boolean                                            | 否       | `false`      |\n| visible        | 字段是否显示                      | Boolean                                            | 否       | `true`       |\n| disabled       | 字段是否禁用                      | Boolean                                            | 否       | `false`      |\n| readOnly       | 字段是否只读                      | Boolean                                            | 否       | `false`      |\n| readPretty     | 字段是否为阅读态                  | Boolean                                            | 否       | `false`      |\n| editable       | 字段是可编辑                      | Boolean                                            | 否       | `true`       |\n| validateStatus | 字段校验状态                      | [FieldValidateStatus](#fieldvalidatestatus)        | 是       | `null`       |\n| content        | 字段内容，一般作为子节点          | any                                                | 否       | `null`       |\n| data           | 字段扩展属性                      | Object                                             | 否       | `null`       |\n| selfErrors     | 字段自身错误消息                  | [FieldMessage](#fieldmessage)[]                    | 否       | `[]`         |\n| selfWarnings   | 字段自身警告消息                  | [FieldMessage](#fieldmessage)[]                    | 否       | `[]`         |\n| selfSuccesses  | 字段自身成功消息                  | [FieldMessage](#fieldmessage)[]                    | 否       | `[]`         |\n| selfValid      | 字段自身是否合法                  | Boolean                                            | 否       | `true`       |\n| selfInvalid    | 字段自身是否非法                  | Boolean                                            | 否       | `false`      |\n| indexes        | 字段数字索引集合                  | Number                                             | 是       | `-`          |\n| index          | 字段数字索引，取 indexes 最后一个 | Number                                             | 是       | `-`          |\n\n#### 详细解释\n\n**active**\n\n触发 onFocus 为 true，触发 onBlur 为 false\n\n**visited**\n\n触发过 onFocus 则永远为 true\n\n**inputValue**\n\n触发 onInput 收集到的值\n\n**inputValues**\n\n触发 onInput 收集到的多参值\n\n**hidden**\n\n为 true 时， display 为 hidden；为 false 时 display 为 visible\n\n**visible**\n\n为 true 时， display 为 visible；为 false 时 display 为 none\n\n## 方法\n\n### setTitle\n\n#### 描述\n\n设置字段标题\n\n#### 签名\n\n```ts\ninterface setTitle {\n  (title?: FieldMessage): void\n}\n```\n\nFieldMessage 参考 [FieldMessage](#fieldmessage)\n\n### setDescription\n\n#### 描述\n\n设置字段描述信息\n\n#### 签名\n\n```ts\ninterface setDescription {\n  (title?: FieldMessage): void\n}\n```\n\nFieldMessage 参考 [FieldMessage](#fieldmessage)\n\n### setDataSource\n\n#### 描述\n\n设置字段数据源\n\n#### 签名\n\n```ts\ninterface setDataSource {\n  (dataSource?: FieldDataSource): void\n}\n```\n\nFieldDataSource 参考 [FieldDataSource](#fielddatasource)\n\n### setFeedback\n\n#### 描述\n\n设置字段消息反馈\n\n#### 签名\n\n```ts\ninterface setFeedback {\n  (feedback?: IFieldFeedback): void\n}\n```\n\nIFieldFeedback 参考 [IFieldFeedback](#ifieldfeedback)\n\n### setSelfErrors\n\n#### 描述\n\n设置字段自身错误消息，这里是以 EffectError 为 code 的 feedback 更新，主要是防止污染校验器结果，如果希望强制覆盖，则可以使用 setFeedback\n\n#### 签名\n\n```ts\ninterface setSelfErrors {\n  (messages?: FieldMessage[]): void\n}\n```\n\n### setSelfWarnings\n\n#### 描述\n\n设置字段自身警告信息，这里是以 EffectWarning 为 code 的 feedback 更新，主要是防止污染校验器结果，如果希望强制覆盖，则可以使用 setFeedback\n\n#### 签名\n\n```ts\ninterface setSelfWarning {\n  (messages?: FieldMessage[]): void\n}\n```\n\n### setSelfSuccesses\n\n#### 描述\n\n设置字段自身成功信息，这里是以 EffectSuccess 为 code 的 feedback 更新，主要是防止污染校验器结果，如果希望强制覆盖，则可以使用 setFeedback\n\n#### 签名\n\n```ts\ninterface setSelfSuccesses {\n  (messages?: FieldMessage[]): void\n}\n```\n\n### setValidator\n\n#### 描述\n\n设置字段校验器\n\n#### 签名\n\n```ts\ninterface setValidator {\n  (validator?: FieldValidator): void\n}\n```\n\nFieldValidator 参考 [FieldValidator](#fieldvalidator)\n\n### setRequired\n\n#### 描述\n\n设置字段是否必填\n\n#### 签名\n\n```ts\ninterface setRequired {\n  (required?: boolean): void\n}\n```\n\n### setValidatorRule\n\n#### 描述\n\n按照规则设置字段 validator，类似于 setRequired\n\n#### 签名\n\n```ts\ninterface setValidatorRule {\n  (ruleName?: string, ruleValue: any): void\n}\n```\n\n### setValue\n\n#### 描述\n\n设置字段值\n\n#### 签名\n\n```ts\ninterface setValue {\n  (value?: FieldValue): void\n}\n```\n\nFieldValue 参考 [FieldValue](#fieldvalue)\n\n### setInitialValue\n\n#### 描述\n\n设置字段默认值\n\n#### 签名\n\n```ts\ninterface setInitialValue {\n  (initialValue?: FieldValue): void\n}\n```\n\nFieldValue 参考 [FieldValue](#fieldvalue)\n\n### setDisplay\n\n#### 描述\n\n设置字段展示状态\n\n#### 签名\n\n```ts\ninterface setDisplay {\n  (display?: FieldDisplayTypes): void\n}\n```\n\nFieldDisplayTypes 参考 [FieldDisplayTypes](#fielddisplaytypes)\n\n### setPattern\n\n#### 描述\n\n设置字段交互模式\n\n#### 签名\n\n```ts\ninterface setPattern {\n  (pattern?: FieldPatternTypes): void\n}\n```\n\nFieldPatternTypes 参考 [FieldPatternTypes](#fieldpatterntypes)\n\n### setLoading\n\n#### 描述\n\n设置字段加载状态\n\n#### 签名\n\n```ts\ninterface setLoading {\n  (loading?: boolean): void\n}\n```\n\n### setValidating\n\n#### 描述\n\n设置字段校验中状态\n\n#### 签名\n\n```ts\ninterface setValidating {\n  (validating?: boolean): void\n}\n```\n\n### setComponent\n\n#### 描述\n\n设置字段组件\n\n#### 签名\n\n```ts\ninterface setComponent {\n  (component?: FieldComponent, props?: any): void\n}\n```\n\nFieldComponent 参考 [FieldComponent](#fieldcomponent)\n\n### setComponentProps\n\n#### 描述\n\n设置字段组件属性\n\n#### 签名\n\n```ts\ninterface setComponentProps {\n  (props?: any): void\n}\n```\n\n### setDecorator\n\n#### 描述\n\n设置字段装饰器\n\n#### 签名\n\n```ts\ninterface setDecorator {\n  (decorator?: FieldDecorator, props?: any): void\n}\n```\n\nFieldDecorator 参考 [FieldDecorator](#fielddecorator)\n\n### setDecoratorProps\n\n#### 描述\n\n设置字段装饰器属性\n\n#### 签名\n\n```ts\ninterface setDecoratorProps {\n  (props?: any): void\n}\n```\n\n### setState\n\n#### 描述\n\n设置字段状态\n\n#### 签名\n\n```ts\ninterface setState {\n  (state: IFieldState): void\n  (callback: (state: IFieldState) => void): void\n}\n```\n\nIFieldState 参考 [IFieldState](#ifieldstate)\n\n### getState\n\n#### 描述\n\n获取字段状态\n\n#### 签名\n\n```ts\ninterface getState<T> {\n  (): IFieldState\n  (callback: (state: IFieldState) => T): T\n}\n```\n\nIFieldState 参考 [IFieldState](#ifieldstate)\n\n### setData\n\n#### 描述\n\n设置 Data 值\n\n#### 签名\n\n```ts\ninterface setData {\n  (data: any): void\n}\n```\n\n### setContent\n\n#### 描述\n\n设置 Content 值\n\n#### 签名\n\n```ts\ninterface setContent {\n  (content: any): void\n}\n```\n\n### onInit\n\n#### 描述\n\n触发字段初始化，默认不需要手动调用\n\n#### 签名\n\n```ts\ninterface onInit {\n  (): void\n}\n```\n\n### onMount\n\n#### 描述\n\n触发字段挂载\n\n#### 签名\n\n```ts\ninterface onMount {\n  (): void\n}\n```\n\n### onUnmount\n\n#### 描述\n\n触发字段卸载\n\n#### 签名\n\n```ts\ninterface onUnmount {\n  (): void\n}\n```\n\n### onInput\n\n#### 描述\n\n触发字段输入\n\n#### 签名\n\n```ts\ninterface onInput {\n  (...args: any[]): Promise<void>\n}\n```\n\n### onFocus\n\n#### 描述\n\n触发字段聚焦\n\n#### 签名\n\n```ts\ninterface onFocus {\n  (...args: any[]): Promise<void>\n}\n```\n\n### onBlur\n\n#### 描述\n\n触发字段失焦\n\n#### 签名\n\n```ts\ninterface onBlur {\n  (...args: any[]): Promise<void>\n}\n```\n\n### submit\n\n#### 描述\n\n触发字段提交(包含所有子节点，该 API 主要用于子表单场景)\n\n#### 签名\n\n```ts\ninterface submit<T> {\n  (): Promise<Field['value']>\n  (onSubmit?: (values: Field['value']) => Promise<T> | void): Promise<T>\n}\n```\n\n### validate\n\n#### 描述\n\n触发字段校验(包含所有子节点，该 API 主要用于子表单场景)\n\n#### 签名\n\n```ts\ninterface validate {\n  (triggerType?: 'onInput' | 'onFocus' | 'onBlur'): Promise<IValidateResults>\n}\n```\n\nIValidateResults 参考 [IValidateResults](#ivalidateresults)\n\n### reset\n\n#### 描述\n\n触发字段重置(包含所有子节点，该 API 主要用于子表单场景)，如果设置了校验，那么返回结果就是校验结果\n\n#### 签名\n\n```ts\ninterface reset {\n  (options?: IFieldResetOptions): Promise<IValidateResults>\n}\n```\n\nIFieldResetOptions 参考 [IFieldResetOptions](#ifieldresetoptions)\n\nIValidateResults 参考 [IValidateResults](#ivalidateresults)\n\n### query\n\n#### 描述\n\n查询字段，可以基于当前字段查询相邻字段\n\n#### 签名\n\n```ts\ninterface query {\n  (pattern: FormPathPattern): Query\n}\n```\n\nFormPathPattern API 参考 [FormPath](/api/entry/form-path#formpathpattern)\n\nQuery 对象 API 参考 [Query](/api/models/query)\n\n### queryFeedbacks\n\n#### 描述\n\n查询当前字段的反馈信息\n\n#### 签名\n\n```ts\ninterface queryFeedbacks {\n  (search: ISearchFeedback): IFieldFeedback[]\n}\n```\n\nISearchFeedback 参考 [ISearchFeedback](/api/models/field#isearchfeedback)\n\nIFieldFeedback 参考[IFieldFeedback](#ifieldfeedback)\n\n### dispose\n\n#### 描述\n\n释放 observer，默认不需要手动释放\n\n#### 签名\n\n```ts\ninterface dispose {\n  (): void\n}\n```\n\n### destroy\n\n#### 描述\n\n释放 observer，并删除字段模型\n\n#### 签名\n\n```ts\ninterface destroy {\n  (): void\n}\n```\n\n### match\n\n#### 描述\n\n基于路径匹配字段\n\n#### 签名\n\n```ts\ninterface match {\n  (pattern: FormPathPattern): boolean\n}\n```\n\nFormPathPattern API 参考 [FormPath](/api/entry/form-path#formpathpattern)\n\n### inject\n\n#### 描述\n\n给字段模型注入可执行方法\n\n#### 签名\n\n```ts\ninterface inject {\n  (actions: Record<string, (...args: any[]) => any>): void\n}\n```\n\n### invoke\n\n#### 描述\n\n调用字段模型通过 inject 注入的可执行方法\n\n#### 签名\n\n```ts\ninterface invoke {\n  (name: string, ...args: any[]): any\n}\n```\n\n## 类型\n\n<Alert>\n注意：如果要手动消费类型，直接从包模块中导出即可\n</Alert>\n\n### FieldValidator\n\n字段校验器，类型较为复杂，需要用户仔细消化\n\n```ts\n//字符串型格式校验器\ntype ValidatorFormats =\n  | 'url'\n  | 'email'\n  | 'ipv6'\n  | 'ipv4'\n  | 'number'\n  | 'integer'\n  | 'idcard'\n  | 'qq'\n  | 'phone'\n  | 'money'\n  | 'zh'\n  | 'date'\n  | 'zip'\n  | (string & {}) //其他格式校验器需要通过registerValidateFormats进行注册\n\n//对象型校验结果\ninterface IValidateResult {\n  type: 'error' | 'warning' | 'success' | (string & {})\n  message: string\n}\n//对象型校验器\ninterface IValidatorRules<Context = any> {\n  triggerType?: 'onInput' | 'onFocus' | 'onBlur'\n  format?: ValidatorFormats\n  validator?: ValidatorFunction<Context>\n  required?: boolean\n  pattern?: RegExp | string\n  max?: number\n  maximum?: number\n  exclusiveMaximum?: number\n  exclusiveMinimum?: number\n  minimum?: number\n  min?: number\n  len?: number\n  whitespace?: boolean\n  enum?: any[]\n  const?: any\n  multipleOf?: number\n  uniqueItems?: boolean\n  maxProperties?: number\n  minProperties?: number\n  maxItems?: number\n  maxLength?: number\n  minItems?: number\n  minLength?: number\n  message?: string\n  [key: string]: any //其他属性需要通过registerValidateRules进行注册\n}\n//函数型校验器校验结果类型\ntype ValidatorFunctionResponse = null | string | boolean | IValidateResult\n\n//函数型校验器\ntype ValidatorFunction<Context = any> = (\n  value: any,\n  rule: IValidatorRules<Context>,\n  ctx: Context\n) => ValidatorFunctionResponse | Promise<ValidatorFunctionResponse> | null\n\n//非数组型校验器\ntype ValidatorDescription =\n  | ValidatorFormats\n  | ValidatorFunction<Context>\n  | IValidatorRules<Context>\n\n//数组型校验器\ntype MultiValidator<Context = any> = ValidatorDescription<Context>[]\n\ntype FieldValidator<Context = any> =\n  | ValidatorDescription<Context>\n  | MultiValidator<Context>\n```\n\n### FieldMessage\n\n```ts\ntype FieldMessage = string | JSXElement\n```\n\n如果在支持 JSX 的 UI 框架下，我们可以直接传 JSX 的 Node，否则，我们只能传字符串\n\n### FieldDataSource\n\n```ts\ntype FieldDataSource<ValueType> = Array<{\n  label: string | JSXElement\n  value: ValueType\n  [key: string]: any\n}>\n```\n\n字段数据源其实就是一个数组，内容是啥形式由用户定，只是我们推荐用户都以 label/value 形式来表达数据源，这里需要注意的是，如果要在 UI 框架中使用，不是设置了就直接能生效，dataSource 属性必须是与具体 UI 组件产生了绑定才能生效，比如使用@formily/react，想要绑定状态，可以使用 connect 函数，也可以直接在组件内通过 useField 拿到字段实例，直接消费。\n\n### FieldValue\n\n字段值类型其实是`Any`类型，只是需要着重提一下，如果在 ArrayField 中是强制数组类型，ObjectField 中是强制对象类型\n\n### FieldComponent\n\n```ts\ntype FieldComponent = string | JSXComponentConstructor\n```\n\n字段组件，如果我们在支持 JSX 的框架中使用，FieldComponent 推荐直接存储 JSX 组件引用，否则可以存储一个组件标识字符串，在实际渲染的时候做一次分发。\n\n### FieldDecorator\n\n```ts\ntype FieldDecorator = string | JSXComponentConstructor\n```\n\n字段装饰器，如果我们在支持 JSX 的框架中使用，FieldDecorator 推荐直接存储 JSX 组件引用，否则可以存储一个组件标识字符串，在实际渲染的时候做一次分发。\n\n### FieldReaction\n\n```ts\ntype FieldReaction = (field: GeneralField) => void\n```\n\n### FieldDisplayTypes\n\n```ts\ntype FieldDisplayTypes = 'none' | 'hidden' | 'visible'\n```\n\n### FieldPatternTypes\n\n```ts\ntype FieldPatternTypes = 'editable' | 'disabled' | 'readOnly' | 'readPretty'\n```\n\n### FieldValidateStatus\n\n```ts\ntype FieldValidateStatus = 'error' | 'warning' | 'success' | 'validating'\n```\n\n### GeneralField\n\n```ts\ntype GeneralField = Field | VoidField | ArrayField | ObjectField\n```\n\nVoidField 参考 [VoidField](/api/models/void-field)\n\nArrayField 参考 [ArrayField](/api/models/array-field)\n\nObjectField 参考 [ObjectField](/api/models/object-field)\n\n### IFieldFeedback\n\n```ts\ninterface IFieldFeedback {\n  triggerType?: 'onInput' | 'onFocus' | 'onBlur' //校验触发类型\n  type?: 'error' | 'success' | 'warning' //反馈类型\n  code?: //反馈编码\n  | 'ValidateError'\n    | 'ValidateSuccess'\n    | 'ValidateWarning'\n    | 'EffectError'\n    | 'EffectSuccess'\n    | 'EffectWarning'\n  messages?: string[] //反馈消息\n}\n```\n\n### ISearchFeedback\n\n```ts\ninterface ISearchFeedback {\n  triggerType?: 'onInput' | 'onFocus' | 'onBlur' //校验触发类型\n  type?: 'error' | 'success' | 'warning' //反馈类型\n  code?: //反馈编码\n  | 'ValidateError'\n    | 'ValidateSuccess'\n    | 'ValidateWarning'\n    | 'EffectError'\n    | 'EffectSuccess'\n    | 'EffectWarning'\n  address?: FormPathPattern\n  path?: FormPathPattern\n  messages?: string[]\n}\n```\n\n### IFieldState\n\n```ts\ninterface IFieldState {\n  hidden?: boolean\n  visible?: boolean\n  editable?: boolean\n  readOnly?: boolean\n  disabled?: boolean\n  readPretty?: boolean\n  title?: any\n  description?: any\n  loading?: boolean\n  validating?: boolean\n  modified?: boolean\n  active?: boolean\n  visited?: boolean\n  inputValue?: FieldValue\n  inputValues?: any[]\n  initialized?: boolean\n  dataSource?: FieldDataSource\n  mounted?: boolean\n  unmounted?: boolean\n  validator?: FieldValidator\n  decorator?: FieldDecorator\n  component?: FieldComponent\n  readonly parent?: GeneralField\n  errors?: FieldMessage[]\n  warnings?: FieldMessage[]\n  successes?: FieldMessage[]\n  readonly valid?: boolean\n  readonly invalid?: boolean\n  value?: FieldValue\n  initialValue?: FieldValue\n  display?: FieldDisplayTypes\n  pattern?: FieldPatternTypes\n  required?: boolean\n  readonly validateStatus?: 'error' | 'success' | 'warning' | 'validating'\n}\n```\n\n### IGeneralFieldState\n\n```ts\ntype IGeneralFieldState = IFieldState & IVoidFieldState\n```\n\nIVoidFieldState 参考 [IVoidFieldState](/api/models/void-field#ivoidfieldstate)\n\n### IFieldResetOptions\n\n```ts\ninterface IFieldResetOptions {\n  forceClear?: boolean //是否强制清除\n  validate?: boolean //是否校验\n}\n```\n\n### IValidateResults\n\n```ts\ninterface IValidateResults {\n  error?: string[]\n  warning?: string[]\n  success?: string[]\n}\n```\n\n> Formily Typescript 类型约定\n>\n> - 简单非对象数据类型或 Union 数据类型用 type 定义类型，不能以大写`I`字符开头\n> - 简单对象类型统一用 interface 定义类型，且以大写`I`字符开头，如果存在不同 interface 的组合(Intersection or Extends)使用 type 定义类型，同样以大写`I`字符开头\n"
  },
  {
    "path": "packages/core/docs/api/models/Form.md",
    "content": "---\norder: 0\n---\n\n# Form\n\nCall the core [Form Model](/guide/form) API returned by [createForm](/api/entry/create-form), the following will list all model attributes, if the attribute is writable, then we can directly The reference is to modify the attribute, and @formily/reactive will respond to trigger the UI update.\n\n## Attributes\n\n| Property      | Description                                       | Type                                  | Read-only or not | Default value     |\n| ------------- | ------------------------------------------------- | ------------------------------------- | ---------------- | ----------------- |\n| initialized   | Whether the form is initialized                   | Boolean                               | No               | `false`           |\n| validating    | Is the form being validated                       | Boolean                               | No               | `false`           |\n| submitting    | Is the form being submitted                       | Boolean                               | No               | `false`           |\n| modified      | Whether the form value has been manually modified | Boolean                               | No               | `false`           |\n| pattern       | Form interaction mode                             | [FormPatternTypes](#formpatterntypes) | No               | `\"editable\"`      |\n| display       | Form display form                                 | [FormDisplayTypes](#formdisplaytypes) | No               | `\"visible\"`       |\n| mounted       | Is the form mounted                               | Boolean                               | No               | `false`           |\n| unmounted     | Is the form unmounted                             | Boolean                               | No               | `false`           |\n| values        | form values                                       | Object                                | No               | `{}`              |\n| initialValues | Form default values                               | Object                                | No               | `{}`              |\n| valid         | Is the form valid                                 | Boolean                               | Yes              | `true`            |\n| invalid       | Is the form illegal                               | Boolean                               | Yes              | `false`           |\n| errors        | Form validation error message                     | [IFormFeedback](#iformfeedback)[]     | Yes              | `[]`              |\n| warnings      | Form verification warning message                 | [IFormFeedback](#iformfeedback)[]     | Yes              | `[]`              |\n| successes     | Form verification success message                 | [IFormFeedback](#iformfeedback)[]     | Yes              | `[]`              |\n| hidden        | Whether the form is hidden                        | Boolean                               | No               | `false`           |\n| visible       | Whether the form is displayed                     | Boolean                               | No               | `true`            |\n| editable      | Is the form editable                              | Boolean                               | No               | `true`            |\n| readOnly      | Is the form read-only                             | Boolean                               | No               | `false`           |\n| disabled      | Whether the form is disabled                      | Boolean                               | No               | `false`           |\n| readPretty    | Is the form in a read state                       | Boolean                               | No               | `false`           |\n| id            | Form ID                                           | String                                | No               | `{RANDOM_STRING}` |\n| displayName   | Model label                                       | String                                | No               | `\"Form\"`          |\n\n## Method\n\n### createField\n\n#### Description\n\nCreate a factory function for a Field instance. If the path is the same and called multiple times, the instance object will be reused\n\n#### Signature\n\n```ts\ninterface createField {\n  (props: IFieldFactoryProps): Field\n}\n```\n\nFor function entry, please refer to [IFieldFactoryProps](#ifieldfactoryprops)\n\n### createArrayField\n\n#### Description\n\nA factory function for creating an ArrayField instance. If the path is the same and called multiple times, the instance object will be reused\n\n#### Signature\n\n```ts\ninterface createArrayField {\n  (props: IFieldFactoryProps): ArrayField\n}\n```\n\nFor function entry, please refer to [IFieldFactoryProps](#ifieldfactoryprops)\n\n### createObjectField\n\n#### Description\n\nA factory function to create an ObjectField instance. If the path is the same and called multiple times, it will reuse the instance object\n\n#### Signature\n\n```ts\ninterface createObjectField {\n  (props: IFieldFactoryProps): ArrayField\n}\n```\n\nFor function entry, please refer to [IFieldFactoryProps](#ifieldfactoryprops)\n\n### createVoidField\n\n#### Description\n\nA factory function to create a VoidField instance. If the path is the same and called multiple times, the instance object will be reused\n\n#### Signature\n\n```ts\ninterface createVoidField {\n  (props: IVoidFieldFactoryProps): ArrayField\n}\n```\n\nFor function entry, please refer to [IVoidFieldFactoryProps](#ivoidfieldfactoryprops)\n\n### setValues\n\n#### Description\n\nSet the form value, you can set the merge strategy [IFormMergeStrategy](#iformmergestrategy)\n\n#### Signature\n\n```ts\ninterface setValues {\n  (values: object, strategy: IFormMergeStrategy = 'merge'): void\n}\n```\n\n### setInitialValues\n\n#### Description\n\nSet the default value of the form, you can set the merge strategy\n\n#### Signature\n\n```ts\ninterface setInitialValues {\n  (initialValues: object, strategy: IFormMergeStrategy = 'merge'): void\n}\n```\n\n### setValuesIn\n\n#### Description\n\nPrecisely set form values\n\n#### Signature\n\n```ts\ninterface setValuesIn {\n  (path: FormPathPattern, value: any): void\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\n### setInitialValuesIn\n\n#### Description\n\nPrecisely set the form default value\n\n#### Signature\n\n```ts\ninterface setInitialValuesIn {\n  (path: FormPathPattern, initialValue: any): void\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\n### existValuesIn\n\n#### Description\n\nDetermine whether the value exists according to the specified path\n\n#### Signature\n\n```ts\ninterface existValuesIn {\n  (path: FormPathPattern): boolean\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\n### existInitialValuesIn\n\n#### Description\n\nDetermine whether the default value exists according to the specified path\n\n#### Signature\n\n```ts\ninterface existInitialValuesIn {\n  (path: FormPathPattern): boolean\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\n### getValuesIn\n\n#### Description\n\nGet the form value according to the specified path\n\n#### Signature\n\n```ts\ninterface getValuesIn {\n  (path: FormPathPattern): any\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\n### getInitialValuesIn\n\n#### Description\n\nGet the default value of the form according to the specified path\n\n#### Signature\n\n```ts\ninterface getInitialValuesIn {\n  (path: FormPathPattern): any\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\n### deleteValuesIn\n\n#### Description\n\nDelete the form value according to the specified path\n\n#### Signature\n\n```ts\ninterface deleteValuesIn {\n  (path: FormPathPattern): void\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\n### deleteInitialValuesIn\n\n#### Description\n\nDelete the default value of the form according to the specified path\n\n#### Signature\n\n```ts\ninterface deleteInitialValuesIn {\n  (path: FormPathPattern): void\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\n### setSubmitting\n\n#### Description\n\nSet whether the form is being submitted\n\n#### Signature\n\n```ts\ninterface setSubmitting {\n  (submitting: boolean): void\n}\n```\n\n### setValidating\n\n#### Description\n\nSet whether the form is verifying status\n\n#### Signature\n\n```ts\ninterface setValidating {\n  (validating: boolean): void\n}\n```\n\n### setDisplay\n\n#### Description\n\nSet form display status\n\n#### Signature\n\n```ts\ninterface setDisplay {\n  (display: FormDisplayTypes): void\n}\n```\n\nFor function entry, please refer to [FormDisplayTypes](#formdisplaytypes)\n\n### setPattern\n\n#### Description\n\nSet the form interaction mode\n\n#### Signature\n\n```ts\ninterface setPattern {\n  (pattern: FormPatternTypes): void\n}\n```\n\nFor function entry, please refer to [FormPatternTypes](#formpatterntypes)\n\n### addEffects\n\n#### Description\n\nAdd side effects\n\n#### Signature\n\n```ts\ninterface addEffects {\n  (id: string, effects: (form: Form) => void): void\n}\n```\n\n### removeEffects\n\n#### Description\n\nRemove side effects, the id is consistent with the id of addEffects\n\n#### Signature\n\n```ts\ninterface removeEffects {\n  (id: string): void\n}\n```\n\n### setEffects\n\n#### Description\n\nOverwrite update side effects\n\n#### Signature\n\n```ts\ninterface setEffects {\n  (effects: (form: Form) => void): void\n}\n```\n\n### clearErrors\n\n#### Description\n\nClear error message\n\n#### Signature\n\n```ts\ninterface clearErrors {\n  (pattern?: FormPathPattern): void\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\n### clearWarnings\n\n#### Description\n\nClear warning message\n\n#### Signature\n\n```ts\ninterface clearWarnings {\n  (pattern?: FormPathPattern): void\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\n### clearSuccesses\n\n#### Description\n\nClear success message\n\n#### Signature\n\n```ts\ninterface clearSuccesses {\n  (pattern?: FormPathPattern): void\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\n### query\n\n#### Description\n\nQuery field node\n\n#### Signature\n\n```ts\ninterface query {\n  (pattern: FormPathPattern): Query\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\nQuery object API reference [Query](/api/models/query)\n\n### queryFeedbacks\n\n#### Description\n\nQuery message feedback\n\n#### Signature\n\n```ts\ninterface queryFeedbacks {\n  (search: ISearchFeedback): IFormFeedback[]\n}\n```\n\nISearchFeedback Reference [ISearchFeedback](/api/models/field#isearchfeedback)\n\nIFormFeedback Reference [IFormFeedback](#iformfeedback)\n\n### notify\n\n#### Description\n\nBroadcast message\n\n#### Signature\n\n```ts\ninterface notify<T> {\n  (type?: string, payload: T): void\n}\n```\n\n### subscribe\n\n#### Description\n\nSubscribe to news\n\n#### Signature\n\n```ts\ninterface subscribe<T> {\n  (callback: (payload: T) => void): number\n}\n```\n\n### unsubscribe\n\n#### Description\n\nunsubscribe\n\n#### Signature\n\n```ts\ninterface unsubscribe {\n  (id: number): void\n}\n```\n\n### onInit\n\n#### Description\n\nTrigger form initialization, no need to manually call by default\n\n#### Signature\n\n```ts\ninterface onInit {\n  (): void\n}\n```\n\n### onMount\n\n#### Description\n\nTrigger mount\n\n#### Signature\n\n```ts\ninterface onMount {\n  (): void\n}\n```\n\n### onUnmount\n\n#### Description\n\nTrigger offload\n\n#### Signature\n\n```ts\ninterface onUnmount {\n  (): void\n}\n```\n\n### setState\n\n#### Description\n\nSet form status\n\n#### Signature\n\n```ts\ninterface setState {\n  (callback: (state: IFormState) => void): void\n  (state: IFormState): void\n}\n```\n\nIFormState Reference [IFormState](#iformstate)\n\n### getState\n\n#### Description\n\nGet form status\n\n#### Signature\n\n```ts\ninterface getState<T> {\n  (): IFormState\n  (callback: (state: IFormState) => T): T\n}\n```\n\nIFormState Reference [IFormState](#iformstate)\n\n### setFormState\n\nConsistent with setState API\n\n### getFormState\n\nConsistent with getState API\n\n### setFieldState\n\n#### Description\n\nSet field status\n\n#### Signature\n\n```ts\ninterface setFieldState {\n  (pattern: FormPathPattern, setter: (state: IGeneralFieldState) => void): void\n  (pattern: FormPathPattern, setter: IGeneralFieldState): void\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\nIGeneralFieldState Reference [IGeneralFieldState](/api/models/field/#igeneralfieldstate)\n\n### getFieldState\n\n#### Description\n\nGet field status\n\n#### Signature\n\n```ts\ninterface getFieldState<T> {\n  (pattern: FormPathPattern): IGeneralFieldState\n  (pattern: FormPathPattern, callback: (state: IGeneralFieldState) => T): T\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\nIGeneralFieldState Reference [IGeneralFieldState](/api/models/field/#igeneralfieldstate)\n\n### getFormGraph\n\n#### Description\n\nGet form field set\n\n#### Signature\n\n```ts\ninterface getFormGraph {\n  (): {\n    [key: string]: GeneralFieldState | FormState\n  }\n}\n```\n\n### setFormGraph\n\n#### Description\n\nSet the form field set\n\n#### Signature\n\n```ts\ninterface setFormGraph {\n  (graph: { [key: string]: GeneralFieldState | FormState }): void\n}\n```\n\n### clearFormGraph\n\n#### Description\n\nClear the field set\n\n#### Signature\n\n```ts\ninterface clearFormGraph {\n  (pattern: FormPathPattern): void\n}\n```\n\n### validate\n\n#### Description\n\nThe form verification trigger can be verified according to the specified path. If the verification is successful, there will be no return, and the verification failure will be returned in the promise reject [IFormFeedback](#iformfeedback)[]\n\n#### Signature\n\n```ts\ninterface validate {\n  (pattern: FormPathPattern): Promise<void>\n}\n```\n\n### submit\n\n#### Description\n\nIn the form submission method, if the Promise is returned in the onSubmit callback function, the form will set the submitting status to true at the beginning of the submission, and then set it to false when the Promise resolves. The view layer can consume the submitting status to prevent repeated submissions.\n\n#### Signature\n\n```ts\ninterface submit<T> {\n  (): Promise<Form['values']>\n  (onSubmit?: (values: Form['values']) => Promise<T> | void): Promise<T>\n}\n```\n\n### reset\n\n#### Description\n\nForm reset method, you can specify the specific field to be reset, or you can specify automatic verification when reset\n\n#### Description\n\n```ts\ninterface reset {\n  (pattern: FormPathPattern, options?: IFieldResetOptions): Promise<void>\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\nIFieldResetOptions Reference [IFieldResetOptions](/api/models/field/#ifieldresetoptions)\n\n## Types of\n\n<Alert>\nNote: If you want to manually consume the type, just export it directly from the package module\n</Alert>\n\n### FormPatternTypes\n\n```ts\ntype FormPatternTypes = 'editable' | 'disabled' | 'readOnly' | 'readPretty'\n```\n\n### FormDisplayTypes\n\n```ts\ntype FormDisplayTypes = 'none' | 'hidden' | 'visible'\n```\n\n### IFormFeedback\n\n```ts\ninterface IFormFeedback {\n  path?: string //Check field data path\n  address?: string //The absolute path of the verification field\n  triggerType?: 'onInput' | 'onFocus' | 'onBlur' //Verify the trigger type\n  type?: 'error' | 'success' | 'warning' //feedback type\n  code?: //Feedback code\n  | 'ValidateError'\n    | 'ValidateSuccess'\n    | 'ValidateWarning'\n    | 'EffectError'\n    | 'EffectSuccess'\n    | 'EffectWarning'\n  messages?: string[] //Feedback message\n}\n```\n\n### IFormState\n\n```ts\ninterface IFormState {\n  editable?: boolean\n  readOnly?: boolean\n  disabled?: boolean\n  readPretty?: boolean\n  hidden?: boolean\n  visible?: boolean\n  initialized?: boolean\n  validating?: boolean\n  submitting?: boolean\n  modified?: boolean\n  pattern?: FormPatternTypes\n  display?: FormDisplayTypes\n  values?: any\n  initialValues?: any\n  mounted?: boolean\n  unmounted?: boolean\n  readonly valid?: boolean\n  readonly invalid?: boolean\n  readonly errors?: IFormFeedback[]\n  readonly warnings?: IFormFeedback[]\n  readonly successes?: IFormFeedback[]\n}\n```\n\n### IFormMergeStrategy\n\n```ts\ntype IFormMergeStrategy = 'overwrite' | 'merge' | 'deepMerge' | 'shallowMerge'\n```\n\n### IFieldFactoryProps\n\n```ts\ninterface IFieldFactoryProps {\n  name: FormPathPattern //Field name, the path name of the current node\n  basePath?: FormPathPattern //base path\n  title?: string | JSXElement //Field title\n  description?: string | JSXElement //Field description\n  value?: any //Field value\n  initialValue?: any //Field default value\n  required?: boolean //Is the field required\n  display?: 'none' | 'hidden' | 'visible' //Field display form\n  pattern?: 'editable' | 'disabled' | 'readOnly' | 'readPretty' //Field interaction mode\n  hidden?: boolean //whether the field is hidden\n  visible?: boolean //Whether the field is displayed\n  editable?: boolean //Is the field editable\n  disabled?: boolean //Whether the field is disabled\n  readOnly?: boolean //Is the field read-only\n  readPretty?: boolean //Whether the field is in the read state\n  dataSource?: any[] //Field data source\n  validateFirst?: boolean //Does the field verification only verify the first illegal rule?\n  validatePattern?: ('editable' | 'disabled' | 'readOnly' | 'readPretty')[] // Which patterns the validator can run in\n  validateDisplay?: ('none' | 'hidden' | 'visible')[] // Which displays the validator can run in\n  validator?: FieldValidator //Field validator\n  decorator?: any[] //Field decorator, the first element represents the component reference, the second element represents the component attribute\n  component?: any[] //Field component, the first element represents the component reference, the second element represents the component attribute\n  reactions?: FieldReaction[] | FieldReaction //Field responder\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\nFieldValidator Reference [FieldValidator](/api/models/field#fieldvalidator)\n\nFieldReaction Reference [FieldReaction](/api/models/field#fieldreaction)\n\n### IVoidFieldFactoryProps\n\n```ts\ninterface IFieldFactoryProps {\n  name: FormPathPattern //Field name, the path name of the current node\n  basePath?: FormPathPattern //base path\n  title?: string | JSXElement //Field title\n  description?: string | JSXElement //Field description\n  required?: boolean //Is the field required\n  display?: 'none' | 'hidden' | 'visible' //Field display form\n  pattern?: 'editable' | 'disabled' | 'readOnly' | 'readPretty' //Field interaction mode\n  hidden?: boolean //whether the field is hidden\n  visible?: boolean //Whether the field is displayed\n  editable?: boolean //Is the field editable\n  disabled?: boolean //Whether the field is disabled\n  readOnly?: boolean //Is the field read-only\n  readPretty?: boolean //Whether the field is in the read state\n  decorator?: any[] //Field decorator, the first element represents the component reference, the second element represents the component attribute\n  component?: any[] //Field component, the first element represents the component reference, the second element represents the component attribute\n  reactions?: FieldReaction[] | FieldReaction //Field responder\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\nFieldReaction Reference [FieldReaction](/api/models/field#fieldreaction)\n\n> Formily Typescript type convention\n>\n> - Simple non-object data types or Union data types use type to define the type, and cannot start with an uppercase `I` character\n> - Simple object types use interface to define the type uniformly, and start with an uppercase `I` character. If there are combinations of different interfaces (Intersection or Extends), use type to define the type, and also start with an uppercase `I` character\n"
  },
  {
    "path": "packages/core/docs/api/models/Form.zh-CN.md",
    "content": "---\norder: 0\n---\n\n# Form\n\n调用[createForm](/zh-CN/api/entry/create-form)所返回的核心[表单模型](/zh-CN/guide/form) API，以下会列出所有模型属性，如果该属性是可写的，那么我们可以直接引用是修改该属性，@formily/reactive 便会响应从而触发 UI 更新。\n\n## 属性\n\n| 属性          | 描述                   | 类型                                  | 是否只读 | 默认值            |\n| ------------- | ---------------------- | ------------------------------------- | -------- | ----------------- |\n| initialized   | 表单是否初始化         | Boolean                               | 否       | `false`           |\n| validating    | 表单是否正在校验       | Boolean                               | 否       | `false`           |\n| submitting    | 表单是否正在提交       | Boolean                               | 否       | `false`           |\n| modified      | 表单值是否已被手动修改 | Boolean                               | 否       | `false`           |\n| pattern       | 表单交互模式           | [FormPatternTypes](#formpatterntypes) | 否       | `\"editable\"`      |\n| display       | 表单展示形态           | [FormDisplayTypes](#formdisplaytypes) | 否       | `\"visible\"`       |\n| mounted       | 表单是否已挂载         | Boolean                               | 否       | `false`           |\n| unmounted     | 表单是否已卸载         | Boolean                               | 否       | `false`           |\n| values        | 表单值                 | Object                                | 否       | `{}`              |\n| initialValues | 表单默认值             | Object                                | 否       | `{}`              |\n| valid         | 表单是否合法           | Boolean                               | 是       | `true`            |\n| invalid       | 表单是否非法           | Boolean                               | 是       | `false`           |\n| errors        | 表单校验错误消息       | [IFormFeedback](#iformfeedback)[]     | 是       | `[]`              |\n| warnings      | 表单校验警告消息       | [IFormFeedback](#iformfeedback)[]     | 是       | `[]`              |\n| successes     | 表单校验成功消息       | [IFormFeedback](#iformfeedback)[]     | 是       | `[]`              |\n| hidden        | 表单是否隐藏           | Boolean                               | 否       | `false`           |\n| visible       | 表单是否显示           | Boolean                               | 否       | `true`            |\n| editable      | 表单是否可编辑         | Boolean                               | 否       | `true`            |\n| readOnly      | 表单是否只读           | Boolean                               | 否       | `false`           |\n| disabled      | 表单是否禁用           | Boolean                               | 否       | `false`           |\n| readPretty    | 表单是否为阅读态       | Boolean                               | 否       | `false`           |\n| id            | 表单 ID                | String                                | 否       | `{RANDOM_STRING}` |\n| displayName   | 模型标签               | String                                | 否       | `\"Form\"`          |\n\n## 方法\n\n### createField\n\n#### 描述\n\n创建一个 Field 实例的工厂函数，如果路径相同，多次调用，会复用实例对象\n\n#### 签名\n\n```ts\ninterface createField {\n  (props: IFieldFactoryProps): Field\n}\n```\n\n函数入参请参考[IFieldFactoryProps](#ifieldfactoryprops)\n\n### createArrayField\n\n#### 描述\n\n创建一个 ArrayField 实例的工厂函数，如果路径相同，多次调用，会复用实例对象\n\n#### 签名\n\n```ts\ninterface createArrayField {\n  (props: IFieldFactoryProps): ArrayField\n}\n```\n\n函数入参请参考[IFieldFactoryProps](#ifieldfactoryprops)\n\n### createObjectField\n\n#### 描述\n\n创建一个 ObjectField 实例的工厂函数，如果路径相同，多次调用，会复用实例对象\n\n#### 签名\n\n```ts\ninterface createObjectField {\n  (props: IFieldFactoryProps): ArrayField\n}\n```\n\n函数入参请参考[IFieldFactoryProps](#ifieldfactoryprops)\n\n### createVoidField\n\n#### 描述\n\n创建一个 VoidField 实例的工厂函数，如果路径相同，多次调用，会复用实例对象\n\n#### 签名\n\n```ts\ninterface createVoidField {\n  (props: IVoidFieldFactoryProps): ArrayField\n}\n```\n\n函数入参请参考[IVoidFieldFactoryProps](#ivoidfieldfactoryprops)\n\n### setValues\n\n#### 描述\n\n设置表单值，可以设置合并策略 [IFormMergeStrategy](#iformmergestrategy)\n\n#### 签名\n\n```ts\ninterface setValues {\n  (values: object, strategy: IFormMergeStrategy = 'merge'): void\n}\n```\n\n### setInitialValues\n\n#### 描述\n\n设置表单默认值，可以设置合并策略\n\n#### 签名\n\n```ts\ninterface setInitialValues {\n  (initialValues: object, strategy: IFormMergeStrategy = 'merge'): void\n}\n```\n\n### setValuesIn\n\n#### 描述\n\n精确设置表单值\n\n#### 签名\n\n```ts\ninterface setValuesIn {\n  (path: FormPathPattern, value: any): void\n}\n```\n\nFormPathPattern API 参考 [FormPath](/zh-CN/api/entry/form-path#formpathpattern)\n\n### setInitialValuesIn\n\n#### 描述\n\n精确设置表单默认值\n\n#### 签名\n\n```ts\ninterface setInitialValuesIn {\n  (path: FormPathPattern, initialValue: any): void\n}\n```\n\nFormPathPattern API 参考 [FormPath](/zh-CN/api/entry/form-path#formpathpattern)\n\n### existValuesIn\n\n#### 描述\n\n根据指定路径判断值是否存在\n\n#### 签名\n\n```ts\ninterface existValuesIn {\n  (path: FormPathPattern): boolean\n}\n```\n\nFormPathPattern API 参考 [FormPath](/zh-CN/api/entry/form-path#formpathpattern)\n\n### existInitialValuesIn\n\n#### 描述\n\n根据指定路径判断默认值是否存在\n\n#### 签名\n\n```ts\ninterface existInitialValuesIn {\n  (path: FormPathPattern): boolean\n}\n```\n\nFormPathPattern API 参考 [FormPath](/zh-CN/api/entry/form-path#formpathpattern)\n\n### getValuesIn\n\n#### 描述\n\n根据指定路径获取表单值\n\n#### 签名\n\n```ts\ninterface getValuesIn {\n  (path: FormPathPattern): any\n}\n```\n\nFormPathPattern API 参考 [FormPath](/zh-CN/api/entry/form-path#formpathpattern)\n\n### getInitialValuesIn\n\n#### 描述\n\n根据指定路径获取表单默认值\n\n#### 签名\n\n```ts\ninterface getInitialValuesIn {\n  (path: FormPathPattern): any\n}\n```\n\nFormPathPattern API 参考 [FormPath](/zh-CN/api/entry/form-path#formpathpattern)\n\n### deleteValuesIn\n\n#### 描述\n\n根据指定路径删除表单值\n\n#### 签名\n\n```ts\ninterface deleteValuesIn {\n  (path: FormPathPattern): void\n}\n```\n\nFormPathPattern API 参考 [FormPath](/zh-CN/api/entry/form-path#formpathpattern)\n\n### deleteInitialValuesIn\n\n#### 描述\n\n根据指定路径删除表单默认值\n\n#### 签名\n\n```ts\ninterface deleteInitialValuesIn {\n  (path: FormPathPattern): void\n}\n```\n\nFormPathPattern API 参考 [FormPath](/zh-CN/api/entry/form-path#formpathpattern)\n\n### setSubmitting\n\n#### 描述\n\n设置表单是否正在提交状态\n\n#### 签名\n\n```ts\ninterface setSubmitting {\n  (submitting: boolean): void\n}\n```\n\n### setValidating\n\n#### 描述\n\n设置表单是否正在校验状态\n\n#### 签名\n\n```ts\ninterface setValidating {\n  (validating: boolean): void\n}\n```\n\n### setDisplay\n\n#### 描述\n\n设置表单展示状态\n\n#### 签名\n\n```ts\ninterface setDisplay {\n  (display: FormDisplayTypes): void\n}\n```\n\n函数入参请参考[FormDisplayTypes](#formdisplaytypes)\n\n### setPattern\n\n#### 描述\n\n设置表单交互模式\n\n#### 签名\n\n```ts\ninterface setPattern {\n  (pattern: FormPatternTypes): void\n}\n```\n\n函数入参请参考[FormPatternTypes](#formpatterntypes)\n\n### addEffects\n\n#### 描述\n\n添加副作用\n\n#### 签名\n\n```ts\ninterface addEffects {\n  (id: string, effects: (form: Form) => void): void\n}\n```\n\n### removeEffects\n\n#### 描述\n\n移除副作用，id 与 addEffects 的 id 保持一致\n\n#### 签名\n\n```ts\ninterface removeEffects {\n  (id: string): void\n}\n```\n\n### setEffects\n\n#### 描述\n\n覆盖式更新副作用\n\n#### 签名\n\n```ts\ninterface setEffects {\n  (effects: (form: Form) => void): void\n}\n```\n\n### clearErrors\n\n#### 描述\n\n清空错误消息\n\n#### 签名\n\n```ts\ninterface clearErrors {\n  (pattern?: FormPathPattern): void\n}\n```\n\nFormPathPattern API 参考 [FormPath](/zh-CN/api/entry/form-path#formpathpattern)\n\n### clearWarnings\n\n#### 描述\n\n清空警告消息\n\n#### 签名\n\n```ts\ninterface clearWarnings {\n  (pattern?: FormPathPattern): void\n}\n```\n\nFormPathPattern API 参考 [FormPath](/zh-CN/api/entry/form-path#formpathpattern)\n\n### clearSuccesses\n\n#### 描述\n\n清空成功消息\n\n#### 签名\n\n```ts\ninterface clearSuccesses {\n  (pattern?: FormPathPattern): void\n}\n```\n\nFormPathPattern API 参考 [FormPath](/zh-CN/api/entry/form-path#formpathpattern)\n\n### query\n\n#### 描述\n\n查询字段节点\n\n#### 签名\n\n```ts\ninterface query {\n  (pattern: FormPathPattern): Query\n}\n```\n\nFormPathPattern API 参考 [FormPath](/zh-CN/api/entry/form-path#formpathpattern)\n\nQuery 对象 API 参考 [Query](/zh-CN/api/models/query)\n\n### queryFeedbacks\n\n#### 描述\n\n查询消息反馈\n\n#### 签名\n\n```ts\ninterface queryFeedbacks {\n  (search: ISearchFeedback): IFormFeedback[]\n}\n```\n\nISearchFeedback 参考 [ISearchFeedback](/zh-CN/api/models/field#isearchfeedback)\n\nIFormFeedback 参考[IFormFeedback](#iformfeedback)\n\n### notify\n\n#### 描述\n\n广播消息\n\n#### 签名\n\n```ts\ninterface notify<T> {\n  (type?: string, payload: T): void\n}\n```\n\n### subscribe\n\n#### 描述\n\n订阅消息\n\n#### 签名\n\n```ts\ninterface subscribe<T> {\n  (callback: (payload: T) => void): number\n}\n```\n\n### unsubscribe\n\n#### 描述\n\n取消订阅\n\n#### 签名\n\n```ts\ninterface unsubscribe {\n  (id: number): void\n}\n```\n\n### onInit\n\n#### 描述\n\n触发表单初始化，默认不需要手动调用\n\n#### 签名\n\n```ts\ninterface onInit {\n  (): void\n}\n```\n\n### onMount\n\n#### 描述\n\n触发挂载\n\n#### 签名\n\n```ts\ninterface onMount {\n  (): void\n}\n```\n\n### onUnmount\n\n#### 描述\n\n触发卸载\n\n#### 签名\n\n```ts\ninterface onUnmount {\n  (): void\n}\n```\n\n### setState\n\n#### 描述\n\n设置表单状态\n\n#### 签名\n\n```ts\ninterface setState {\n  (callback: (state: IFormState) => void): void\n  (state: IFormState): void\n}\n```\n\nIFormState 参考 [IFormState](#iformstate)\n\n### getState\n\n#### 描述\n\n获取表单状态\n\n#### 签名\n\n```ts\ninterface getState<T> {\n  (): IFormState\n  (callback: (state: IFormState) => T): T\n}\n```\n\nIFormState 参考 [IFormState](#iformstate)\n\n### setFormState\n\n与 setState API 一致\n\n### getFormState\n\n与 getState API 一致\n\n### setFieldState\n\n#### 描述\n\n设置字段状态\n\n#### 签名\n\n```ts\ninterface setFieldState {\n  (pattern: FormPathPattern, setter: (state: IGeneralFieldState) => void): void\n  (pattern: FormPathPattern, setter: IGeneralFieldState): void\n}\n```\n\nFormPathPattern API 参考 [FormPath](/zh-CN/api/entry/form-path#formpathpattern)\n\nIGeneralFieldState 参考 [IGeneralFieldState](/zh-CN/api/models/field/#igeneralfieldstate)\n\n### getFieldState\n\n#### 描述\n\n获取字段状态\n\n#### 签名\n\n```ts\ninterface getFieldState<T> {\n  (pattern: FormPathPattern): IGeneralFieldState\n  (pattern: FormPathPattern, callback: (state: IGeneralFieldState) => T): T\n}\n```\n\nFormPathPattern API 参考 [FormPath](/zh-CN/api/entry/form-path#formpathpattern)\n\nIGeneralFieldState 参考 [IGeneralFieldState](/zh-CN/api/models/field/#igeneralfieldstate)\n\n### getFormGraph\n\n#### 描述\n\n获取表单字段集\n\n#### 签名\n\n```ts\ninterface getFormGraph {\n  (): {\n    [key: string]: GeneralFieldState | FormState\n  }\n}\n```\n\n### setFormGraph\n\n#### 描述\n\n设置表单字段集\n\n#### 签名\n\n```ts\ninterface setFormGraph {\n  (graph: { [key: string]: GeneralFieldState | FormState }): void\n}\n```\n\n### clearFormGraph\n\n#### 描述\n\n清空字段集\n\n#### 签名\n\n```ts\ninterface clearFormGraph {\n  (pattern: FormPathPattern): void\n}\n```\n\n### validate\n\n#### 描述\n\n表单校验触发器，可以按照指定路径校验，如果校验成功是不会有任何返回，校验失败会在 promise reject 中返回[IFormFeedback](#iformfeedback)[]\n\n#### 签名\n\n```ts\ninterface validate {\n  (pattern: FormPathPattern): Promise<void>\n}\n```\n\n### submit\n\n#### 描述\n\n表单提交方法，如果在 onSubmit 回调函数中返回 Promise，表单会在提交开始的时候设置 submitting 状态为 true，Promise resolve 的时候再设置为 false，视图层可以消费 submitting 状态来实现防重复提交\n\n#### 签名\n\n```ts\ninterface submit<T> {\n  (): Promise<Form['values']>\n  (onSubmit?: (values: Form['values']) => Promise<T> | void): Promise<T>\n}\n```\n\n### reset\n\n#### 描述\n\n表单重置方法，可以指定重置具体字段，也可以指定重置时自动校验\n\n#### 描述\n\n```ts\ninterface reset {\n  (pattern: FormPathPattern, options?: IFieldResetOptions): Promise<void>\n}\n```\n\nFormPathPattern API 参考 [FormPath](/zh-CN/api/entry/form-path#formpathpattern)\n\nIFieldResetOptions 参考 [IFieldResetOptions](/zh-CN/api/models/field/#ifieldresetoptions)\n\n## 类型\n\n<Alert>\n注意：如果要手动消费类型，直接从包模块中导出即可\n</Alert>\n\n### FormPatternTypes\n\n```ts\ntype FormPatternTypes = 'editable' | 'disabled' | 'readOnly' | 'readPretty'\n```\n\n### FormDisplayTypes\n\n```ts\ntype FormDisplayTypes = 'none' | 'hidden' | 'visible'\n```\n\n### IFormFeedback\n\n```ts\ninterface IFormFeedback {\n  path?: string //校验字段数据路径\n  address?: string //校验字段绝对路径\n  triggerType?: 'onInput' | 'onFocus' | 'onBlur' //校验触发类型\n  type?: 'error' | 'success' | 'warning' //反馈类型\n  code?: //反馈编码\n  | 'ValidateError'\n    | 'ValidateSuccess'\n    | 'ValidateWarning'\n    | 'EffectError'\n    | 'EffectSuccess'\n    | 'EffectWarning'\n  messages?: string[] //反馈消息\n}\n```\n\n### IFormState\n\n```ts\ninterface IFormState {\n  editable?: boolean\n  readOnly?: boolean\n  disabled?: boolean\n  readPretty?: boolean\n  hidden?: boolean\n  visible?: boolean\n  initialized?: boolean\n  validating?: boolean\n  submitting?: boolean\n  modified?: boolean\n  pattern?: FormPatternTypes\n  display?: FormDisplayTypes\n  values?: any\n  initialValues?: any\n  mounted?: boolean\n  unmounted?: boolean\n  readonly valid?: boolean\n  readonly invalid?: boolean\n  readonly errors?: IFormFeedback[]\n  readonly warnings?: IFormFeedback[]\n  readonly successes?: IFormFeedback[]\n}\n```\n\n### IFormMergeStrategy\n\n```ts\ntype IFormMergeStrategy = 'overwrite' | 'merge' | 'deepMerge' | 'shallowMerge'\n```\n\n### IFieldFactoryProps\n\n```ts\ninterface IFieldFactoryProps {\n  name: FormPathPattern //字段名称，当前节点的路径名称\n  basePath?: FormPathPattern //基础路径\n  title?: string | JSXElement //字段标题\n  description?: string | JSXElement //字段描述\n  value?: any //字段值\n  initialValue?: any //字段默认值\n  required?: boolean //字段是否必填\n  display?: 'none' | 'hidden' | 'visible' //字段展示形式\n  pattern?: 'editable' | 'disabled' | 'readOnly' | 'readPretty' //字段交互模式\n  hidden?: boolean //字段是否隐藏\n  visible?: boolean //字段是否显示\n  editable?: boolean //字段是否可编辑\n  disabled?: boolean //字段是否禁用\n  readOnly?: boolean //字段是否只读\n  readPretty?: boolean //字段是否为阅读态\n  dataSource?: any[] //字段数据源\n  validateFirst?: boolean //字段校验是否只校验第一个非法规则\n  validatePattern?: ('editable' | 'disabled' | 'readOnly' | 'readPretty')[] // validator 可以在哪些 pattern 下运行\n  validateDisplay?: ('none' | 'hidden' | 'visible')[] // validator 可以在哪些 display 下运行\n  validator?: FieldValidator //字段校验器\n  decorator?: any[] //字段装饰器，第一个元素代表组件引用，第二个元素代表组件属性\n  component?: any[] //字段组件，第一个元素代表组件引用，第二个元素代表组件属性\n  reactions?: FieldReaction[] | FieldReaction //字段响应器\n}\n```\n\nFormPathPattern API 参考 [FormPath](/zh-CN/api/entry/form-path#formpathpattern)\n\nFieldValidator 参考 [FieldValidator](/zh-CN/api/models/field#fieldvalidator)\n\nFieldReaction 参考 [FieldReaction](/zh-CN/api/models/field#fieldreaction)\n\n### IVoidFieldFactoryProps\n\n```ts\ninterface IFieldFactoryProps {\n  name: FormPathPattern //字段名称，当前节点的路径名称\n  basePath?: FormPathPattern //基础路径\n  title?: string | JSXElement //字段标题\n  description?: string | JSXElement //字段描述\n  required?: boolean //字段是否必填\n  display?: 'none' | 'hidden' | 'visible' //字段展示形式\n  pattern?: 'editable' | 'disabled' | 'readOnly' | 'readPretty' //字段交互模式\n  hidden?: boolean //字段是否隐藏\n  visible?: boolean //字段是否显示\n  editable?: boolean //字段是否可编辑\n  disabled?: boolean //字段是否禁用\n  readOnly?: boolean //字段是否只读\n  readPretty?: boolean //字段是否为阅读态\n  decorator?: any[] //字段装饰器，第一个元素代表组件引用，第二个元素代表组件属性\n  component?: any[] //字段组件，第一个元素代表组件引用，第二个元素代表组件属性\n  reactions?: FieldReaction[] | FieldReaction //字段响应器\n}\n```\n\nFormPathPattern API 参考 [FormPath](/zh-CN/api/entry/form-path#formpathpattern)\n\nFieldReaction 参考 [FieldReaction](/zh-CN/api/models/field#fieldreaction)\n\n> Formily Typescript 类型约定\n>\n> - 简单非对象数据类型或 Union 数据类型用 type 定义类型，不能以大写`I`字符开头\n> - 简单对象类型统一用 interface 定义类型，且以大写`I`字符开头，如果存在不同 interface 的组合(Intersection or Extends)使用 type 定义类型，同样以大写`I`字符开头\n"
  },
  {
    "path": "packages/core/docs/api/models/ObjectField.md",
    "content": "---\norder: 3\n---\n\n# ObjectField\n\nCall the ObjectField model returned by [createObjectField](/api/models/form#createobjectfield).\n\nBecause ObjectField is inherited from the [Field](/api/models/field) model, most APIs can refer to the Field model. This document only explains the extension method\n\n## Method\n\n### addProperty\n\n#### Description\n\nAdd attributes to the object and trigger onInput\n\n#### Signature\n\n```ts\ninterface addProperty {\n  (key: FormPathPattern, value: any): Promise<void>\n}\n```\n\n### removeProperty\n\n#### Description\n\nRemove object properties and trigger onInput\n\n#### Signature\n\n```ts\ninterface removeProperty {\n  (key: FormPathPattern): Promise<void>\n}\n```\n\n### existProperty\n\n#### Description\n\nDetermine whether the attribute exists\n\n#### Signature\n\n```ts\ninterface existProperty {\n  (key: FormPathPattern): boolean\n}\n```\n\n## Types of\n\n### IObjectFieldState\n\nThe main attributes refer to [IFieldState](/api/models/field#ifieldstate), but the data type of value is required to be an object\n"
  },
  {
    "path": "packages/core/docs/api/models/ObjectField.zh-CN.md",
    "content": "---\norder: 3\n---\n\n# ObjectField\n\n调用[createObjectField](/api/models/form#createobjectfield)所返回的 ObjectField 模型。\n\n因为 ObjectField 是继承至 [Field](/api/models/field) 模型的，所以大部分 API 参考 Field 模型即可，该文档只讲解扩展方法\n\n## 方法\n\n### addProperty\n\n#### 描述\n\n给对象添加属性，并触发 onInput\n\n#### 签名\n\n```ts\ninterface addProperty {\n  (key: FormPathPattern, value: any): Promise<void>\n}\n```\n\n### removeProperty\n\n#### 描述\n\n移除对象属性，并触发 onInput\n\n#### 签名\n\n```ts\ninterface removeProperty {\n  (key: FormPathPattern): Promise<void>\n}\n```\n\n### existProperty\n\n#### 描述\n\n判断属性是否存在\n\n#### 签名\n\n```ts\ninterface existProperty {\n  (key: FormPathPattern): boolean\n}\n```\n\n## 类型\n\n### IObjectFieldState\n\n主要属性参考[IFieldState](/api/models/field#ifieldstate)，只是 value 的数据类型要求是对象\n"
  },
  {
    "path": "packages/core/docs/api/models/Query.md",
    "content": "---\norder: 5\n---\n\n# Query\n\nThe Query object returned by calling the query method in the [Form](/api/models/form#query) or [Field](/api/models/field#query) instance\n\n## Method\n\n### take\n\n#### Description\n\nExtract the first result from the query result set\n\nNote that there must be a corresponding node to be able to read\n\n#### Signature\n\n```ts\ninterface take {\n  (): GeneralField\n  <Result>(getter: (field: GeneralField, address: FormPath) => Result): Result\n}\n```\n\n### map\n\n#### Description\n\nTraverse and map the query result set\n\nNote that there must be a corresponding node to traverse\n\n#### Signature\n\n```ts\ninterface map {\n  (): GeneralField[]\n  <Result>(\n    mapper?: (field: GeneralField, address: FormPath) => Result\n  ): Result[]\n}\n```\n\n### forEach\n\n#### Description\n\nTraverse the query result set\n\nNote that there must be a corresponding node to traverse\n\n#### Signature\n\n```ts\ninterface forEach {\n  <Result>(eacher: (field: GeneralField, address: FormPath) => Result): void\n}\n```\n\n### reduce\n\n#### Description\n\nPerform a reduce operation on the query result set\n\nNote that there must be a corresponding node to traverse\n\n#### Signature\n\n```ts\ninterface reduce {\n  <Result>(\n    reducer: (value: Result, field: GeneralField, address: FormPath) => Result,\n    initial?: Result\n  ): Result\n}\n```\n\n### get\n\n#### Description\n\nFind the first result from the query result set and read its attributes\n\nNote that there must be a corresponding node to be able to read\n\n#### Signature\n\n```ts\ninterface get {\n  <K extends keyof IGeneralFieldState>(key: K): IGeneralFieldState[K]\n}\n```\n\n### getIn\n\n#### Description\n\nFind the first result from the query result set and read its attributes, support [FormPathPattern](/api/entry/form-path#formpathpattern) path syntax\n\nNote that there must be a corresponding node to be able to read\n\n#### Signature\n\n```ts\ninterface getIn {\n  (pattern?: FormPathPattern): any\n}\n```\n\n### value\n\n#### Description\n\nQuery the specified path value, not limited to Field nodes\n\n#### Signature\n\n```ts\ninterface value {\n  (): any\n}\n```\n\n### initialValue\n\n#### Description\n\nQuery the initial value of the specified path, not limited to the Field node\n\n#### Signature\n\n```ts\ninterface initialValue {\n  (): any\n}\n```\n"
  },
  {
    "path": "packages/core/docs/api/models/Query.zh-CN.md",
    "content": "---\norder: 5\n---\n\n# Query\n\n调用[Form](/api/models/form#query)或[Field](/api/models/field#query)实例中的 query 方法所返回的 Query 对象\n\n## 方法\n\n### take\n\n#### 描述\n\n从查询结果集中提取第一个结果\n\n注意，必须要存在对应的节点才能读取\n\n#### 签名\n\n```ts\ninterface take {\n  (): GeneralField\n  <Result>(getter: (field: GeneralField, address: FormPath) => Result): Result\n}\n```\n\n### map\n\n#### 描述\n\n遍历并映射查询结果集\n\n注意，必须要存在对应的节点才能遍历\n\n#### 签名\n\n```ts\ninterface map {\n  (): GeneralField[]\n  <Result>(\n    mapper?: (field: GeneralField, address: FormPath) => Result\n  ): Result[]\n}\n```\n\n### forEach\n\n#### 描述\n\n遍历查询结果集\n\n注意，必须要存在对应的节点才能遍历\n\n#### 签名\n\n```ts\ninterface forEach {\n  <Result>(eacher: (field: GeneralField, address: FormPath) => Result): void\n}\n```\n\n### reduce\n\n#### 描述\n\n对查询结果集执行 reduce 操作\n\n注意，必须要存在对应的节点才能遍历\n\n#### 签名\n\n```ts\ninterface reduce {\n  <Result>(\n    reducer: (value: Result, field: GeneralField, address: FormPath) => Result,\n    initial?: Result\n  ): Result\n}\n```\n\n### get\n\n#### 描述\n\n从查询结果集中找到第一个结果，并读取其属性\n\n注意，必须要存在对应的节点才能读取\n\n#### 签名\n\n```ts\ninterface get {\n  <K extends keyof IGeneralFieldState>(key: K): IGeneralFieldState[K]\n}\n```\n\n### getIn\n\n#### 描述\n\n从查询结果集中找到第一个结果，并读取其属性，支持 [FormPathPattern](/api/entry/form-path#formpathpattern) 路径语法\n\n注意，必须要存在对应的节点才能读取\n\n#### 签名\n\n```ts\ninterface getIn {\n  (pattern?: FormPathPattern): any\n}\n```\n\n### value\n\n#### 描述\n\n查询指定路径值，不局限于 Field 节点\n\n#### 签名\n\n```ts\ninterface value {\n  (): any\n}\n```\n\n### initialValue\n\n#### 描述\n\n查询指定路径初始值，不局限于 Field 节点\n\n#### 签名\n\n```ts\ninterface initialValue {\n  (): any\n}\n```\n"
  },
  {
    "path": "packages/core/docs/api/models/VoidField.md",
    "content": "---\norder: 4\n---\n\n# VoidField\n\nCall the VoidField model returned by [createVoidField](/api/models/form#createvoidfield).\n\nAll model attributes are listed below. If the attribute is writable, then we can directly refer to it to modify the attribute, and @formily/reactive will respond to trigger the UI update.\n\n## Attributes\n\n| Property    | Description                               | Type                                    | Read-only or not | Default value |\n| ----------- | ----------------------------------------- | --------------------------------------- | ---------------- | ------------- |\n| initialized | Whether the field has been initialized    | Boolean                                 | No               | `false`       |\n| mounted     | Is the field mounted                      | Boolean                                 | No               | `false`       |\n| unmounted   | Is the field unmounted                    | Boolean                                 | No               | `false`       |\n| address     | Field node path                           | [FormPath](/api/entry/form-path)        | Yes              |               |\n| path        | Field data path                           | [FormPath](/api/entry/form-path)        | Yes              |               |\n| title       | Field Title                               | [FieldMessage](#fieldmessage)           | No               | `\"\"`          |\n| description | Field description                         | [FieldMessage](#fieldmessage)           | No               | `\"\"`          |\n| decorator   | field decorator                           | Any[]                                   | No               | `null`        |\n| component   | Field component                           | Any[]                                   | No               | `null`        |\n| parent      | Parent field                              | [GeneralField](#generalfield)           | yes              | `null`        |\n| display     | Field display status                      | [FieldDisplayTypes](#fielddisplaytypes) | No               | `\"visible\"`   |\n| pattern     | Field interaction mode                    | [FieldPatternTypes](#fieldpatterntypes) | No               | `\"editable\"`  |\n| hidden      | Whether the field is hidden               | Boolean                                 | No               | `false`       |\n| visible     | Whether the field is displayed            | Boolean                                 | No               | `true`        |\n| disabled    | Whether the field is disabled             | Boolean                                 | No               | `false`       |\n| readOnly    | Is the field read-only                    | Boolean                                 | No               | `false`       |\n| readPretty  | Whether the field is in the reading state | Boolean                                 | No               | `false`       |\n| editable    | Field is editable                         | Boolean                                 | No               | `true`        |\n\n#### explain in detail\n\n**hidden**\n\nWhen true, display is hidden, when false, display is visible\n\n**visible**\n\nWhen true, display is visible, when false, display is none\n\n## Method\n\n### setTitle\n\n#### Description\n\nSet field title\n\n#### Signature\n\n```ts\ninterface setTitle {\n  (title?: FieldMessage): void\n}\n```\n\nFieldMessage Reference [FieldMessage](#fieldmessage)\n\n### setDescription\n\n#### Description\n\nSet field description information\n\n#### Signature\n\n```ts\ninterface setDescription {\n  (title?: FieldMessage): void\n}\n```\n\nFieldMessage Reference [FieldMessage](#fieldmessage)\n\n### setDisplay\n\n#### Description\n\nSet field display status\n\n#### Signature\n\n```ts\ninterface setDisplay {\n  (display?: FieldDisplayTypes): void\n}\n```\n\nFieldDisplayTypes Reference [FieldDisplayTypes](#fielddisplaytypes)\n\n### setPattern\n\n#### Description\n\nSet field interaction mode\n\n#### Signature\n\n```ts\ninterface setPattern {\n  (pattern?: FieldPatternTypes): void\n}\n```\n\nFieldPatternTypes Reference [FieldPatternTypes](#fieldpatterntypes)\n\n### setComponent\n\n#### Description\n\nSet field component\n\n#### Signature\n\n```ts\ninterface setComponent {\n  (component?: FieldComponent, props?: any): void\n}\n```\n\nFieldComponent Reference [FieldComponent](#fieldcomponent)\n\n### setComponentProps\n\n#### Description\n\nSet field component properties\n\n#### Signature\n\n```ts\ninterface setComponentProps {\n  (props?: any): void\n}\n```\n\n### setDecorator\n\n#### Description\n\nSet field decorator\n\n#### Signature\n\n```ts\ninterface setDecorator {\n  (decorator?: FieldDecorator, props?: any): void\n}\n```\n\nFieldDecorator Reference [FieldDecorator](#fielddecorator)\n\n### setDecoratorProps\n\n#### Description\n\nSet field decorator properties\n\n#### Signature\n\n```ts\ninterface setDecoratorProps {\n  (props?: any): void\n}\n```\n\n### setState\n\n#### Description\n\nSet field status\n\n#### Signature\n\n```ts\ninterface setState {\n  (state: IVoidFieldState): void\n  (callback: (state: IVoidFieldState) => void): void\n}\n```\n\nIVoidFieldState Reference [IVoidFieldState](#ifieldstate)\n\n### getState\n\n#### Description\n\nGet field status\n\n#### Signature\n\n```ts\ninterface getState<T> {\n  (): IVoidFieldState\n  (callback: (state: IVoidFieldState) => T): T\n}\n```\n\nIVoidFieldState Reference [IVoidFieldState](#ifieldstate)\n\n### setData\n\n#### Description\n\nset field data\n\n#### Signature\n\n```ts\ninterface setData {\n  (data: any): void\n}\n```\n\n### setContent\n\n#### Description\n\nset field content\n\n#### Signature\n\n```ts\ninterface setContent {\n  (content: any): void\n}\n```\n\n### onInit\n\n#### Description\n\nTrigger field initialization, no need to call manually\n\n#### Signature\n\n```ts\ninterface onInit {\n  (): void\n}\n```\n\n### onMount\n\n#### Description\n\nTrigger field mount\n\n#### Signature\n\n```ts\ninterface onMount {\n  (): void\n}\n```\n\n### onUnmount\n\n#### Description\n\nTrigger field unloading\n\n#### Signature\n\n```ts\ninterface onUnmount {\n  (): void\n}\n```\n\n### query\n\n#### Description\n\nQuery field, you can query adjacent fields based on the current field\n\n#### Signature\n\n```ts\ninterface query {\n  (pattern: FormPathPattern): Query\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\nQuery object API reference [Query](/api/models/query)\n\n### dispose\n\n#### Description\n\nRelease observer, no need to release manually by default\n\n#### Signature\n\n```ts\ninterface dispose {\n  (): void\n}\n```\n\n### destroy\n\n#### Description\n\nRelease observer, and remove current field model\n\n#### Signature\n\n```ts\ninterface destroy {\n  (): void\n}\n```\n\n### match\n\n#### Description\n\nMatch fields based on path\n\n#### Signature\n\n```ts\ninterface match {\n  (pattern: FormPathPattern): boolean\n}\n```\n\nFormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern)\n\n### inject\n\n#### Description\n\nInject executable methods into field models\n\n#### Signature\n\n```ts\ninterface inject {\n  (actions: Record<string, (...args: any[]) => any>): void\n}\n```\n\n### invoke\n\n#### Description\n\nInvoke an executable method injected by the field model via inject\n\n#### Signature\n\n```ts\ninterface invoke {\n  (name: string, ...args: any[]): any\n}\n```\n\n## Types of\n\n<Alert>\nNote: If you want to manually consume the type, just export it directly from the package module\n</Alert>\n\n### FieldMessage\n\n```ts\ntype FieldMessage = string | JSXElement\n```\n\nIf under the UI framework that supports JSX, we can directly pass the Node of JSX, otherwise, we can only pass the string\n\n### FieldComponent\n\n```ts\ntype FieldComponent = string | JSXComponentConstructor\n```\n\nField component, if we use it in a framework that supports JSX, FieldComponent recommends to store the JSX component reference directly, otherwise it can store a component identification string and distribute it during actual rendering.\n\n### FieldDecorator\n\n```ts\ntype FieldDecorator = string | JSXComponentConstructor\n```\n\nField decorator, if we use it in a framework that supports JSX, FieldDecorator recommends to store the JSX component reference directly, otherwise it can store a component identification string and distribute it during actual rendering.\n\n### FieldReaction\n\n```ts\ntype FieldReaction = (field: GeneralField) => void\n```\n\n### FieldDisplayTypes\n\n```ts\ntype FieldDisplayTypes = 'none' | 'hidden' | 'visible'\n```\n\n### FieldPatternTypes\n\n```ts\ntype FieldPatternTypes = 'editable' | 'disabled' | 'readOnly' | 'readPretty'\n```\n\n### GeneralField\n\n```ts\ntype GeneralField = Field | VoidField | ArrayField | ObjectField\n```\n\nField Reference [Field](/api/models/field)\n\nArrayField Reference [ArrayField](/api/models/array-field)\n\nObjectField Reference [ObjectField](/api/models/object-field)\n\n### IVoidFieldState\n\n```ts\ninterface IVoidFieldState {\n  hidden?: boolean\n  visible?: boolean\n  editable?: boolean\n  readOnly?: boolean\n  disabled?: boolean\n  readPretty?: boolean\n  title?: any\n  description?: any\n  modified?: boolean\n  active?: boolean\n  visited?: boolean\n  initialized?: boolean\n  mounted?: boolean\n  unmounted?: boolean\n  decorator?: FieldDecorator\n  component?: FieldComponent\n  readonly parent?: GeneralField\n  display?: FieldDisplayTypes\n  pattern?: FieldPatternTypes\n}\n```\n\n### IGeneralFieldState\n\n```ts\ntype IGeneralFieldState = IVoidFieldState & IFieldState\n```\n\nIFieldState Reference [IFieldState](/api/models/field#ifieldstate)\n"
  },
  {
    "path": "packages/core/docs/api/models/VoidField.zh-CN.md",
    "content": "---\norder: 4\n---\n\n# VoidField\n\n调用[createVoidField](/api/models/form#createvoidfield)所返回的 VoidField 模型。\n\n以下会列出所有模型属性，如果该属性是可写的，那么我们可以直接引用是修改该属性，@formily/reactive 便会响应从而触发 UI 更新。\n\n## 属性\n\n| 属性        | 描述               | 类型                                    | 是否只读 | 默认值       |\n| ----------- | ------------------ | --------------------------------------- | -------- | ------------ |\n| initialized | 字段是否已被初始化 | Boolean                                 | 否       | `false`      |\n| mounted     | 字段是否已挂载     | Boolean                                 | 否       | `false`      |\n| unmounted   | 字段是否已卸载     | Boolean                                 | 否       | `false`      |\n| address     | 字段节点路径       | [FormPath](/api/entry/form-path)        | 是       |              |\n| path        | 字段数据路径       | [FormPath](/api/entry/form-path)        | 是       |              |\n| title       | 字段标题           | [FieldMessage](#fieldmessage)           | 否       | `\"\"`         |\n| description | 字段描述           | [FieldMessage](#fieldmessage)           | 否       | `\"\"`         |\n| decorator   | 字段装饰器         | Any[]                                   | 否       | `null`       |\n| component   | 字段组件           | Any[]                                   | 否       | `null`       |\n| parent      | 父级字段           | [GeneralField](#generalfield)           | 是       | `null`       |\n| display     | 字段展示状态       | [FieldDisplayTypes](#fielddisplaytypes) | 否       | `\"visible\"`  |\n| pattern     | 字段交互模式       | [FieldPatternTypes](#fieldpatterntypes) | 否       | `\"editable\"` |\n| hidden      | 字段是否隐藏       | Boolean                                 | 否       | `false`      |\n| visible     | 字段是否显示       | Boolean                                 | 否       | `true`       |\n| disabled    | 字段是否禁用       | Boolean                                 | 否       | `false`      |\n| readOnly    | 字段是否只读       | Boolean                                 | 否       | `false`      |\n| readPretty  | 字段是否为阅读态   | Boolean                                 | 否       | `false`      |\n| editable    | 字段是可编辑       | Boolean                                 | 否       | `true`       |\n\n#### 详细解释\n\n**hidden**\n\n为 true 时是 display 为 hidden，为 false 时是 display 为 visible\n\n**visible**\n\n为 true 时是 display 为 visible，为 false 时是 display 为 none\n\n## 方法\n\n### setTitle\n\n#### 描述\n\n设置字段标题\n\n#### 签名\n\n```ts\ninterface setTitle {\n  (title?: FieldMessage): void\n}\n```\n\nFieldMessage 参考 [FieldMessage](#fieldmessage)\n\n### setDescription\n\n#### 描述\n\n设置字段描述信息\n\n#### 签名\n\n```ts\ninterface setDescription {\n  (title?: FieldMessage): void\n}\n```\n\nFieldMessage 参考 [FieldMessage](#fieldmessage)\n\n### setDisplay\n\n#### 描述\n\n设置字段展示状态\n\n#### 签名\n\n```ts\ninterface setDisplay {\n  (display?: FieldDisplayTypes): void\n}\n```\n\nFieldDisplayTypes 参考 [FieldDisplayTypes](#fielddisplaytypes)\n\n### setPattern\n\n#### 描述\n\n设置字段交互模式\n\n#### 签名\n\n```ts\ninterface setPattern {\n  (pattern?: FieldPatternTypes): void\n}\n```\n\nFieldPatternTypes 参考 [FieldPatternTypes](#fieldpatterntypes)\n\n### setComponent\n\n#### 描述\n\n设置字段组件\n\n#### 签名\n\n```ts\ninterface setComponent {\n  (component?: FieldComponent, props?: any): void\n}\n```\n\nFieldComponent 参考 [FieldComponent](#fieldcomponent)\n\n### setComponentProps\n\n#### 描述\n\n设置字段组件属性\n\n#### 签名\n\n```ts\ninterface setComponentProps {\n  (props?: any): void\n}\n```\n\n### setDecorator\n\n#### 描述\n\n设置字段装饰器\n\n#### 签名\n\n```ts\ninterface setDecorator {\n  (decorator?: FieldDecorator, props?: any): void\n}\n```\n\nFieldDecorator 参考 [FieldDecorator](#fielddecorator)\n\n### setDecoratorProps\n\n#### 描述\n\n设置字段装饰器属性\n\n#### 签名\n\n```ts\ninterface setDecoratorProps {\n  (props?: any): void\n}\n```\n\n### setState\n\n#### 描述\n\n设置字段状态\n\n#### 签名\n\n```ts\ninterface setState {\n  (state: IVoidFieldState): void\n  (callback: (state: IVoidFieldState) => void): void\n}\n```\n\nIVoidFieldState 参考 [IVoidFieldState](#ifieldstate)\n\n### getState\n\n#### 描述\n\n获取字段状态\n\n#### 签名\n\n```ts\ninterface getState<T> {\n  (): IVoidFieldState\n  (callback: (state: IVoidFieldState) => T): T\n}\n```\n\nIVoidFieldState 参考 [IVoidFieldState](#ifieldstate)\n\n### setData\n\n#### 描述\n\n设置 Data 值\n\n#### 签名\n\n```ts\ninterface setData {\n  (data: any): void\n}\n```\n\n### setContent\n\n#### 描述\n\n设置 Content 值\n\n#### 签名\n\n```ts\ninterface setContent {\n  (content: any): void\n}\n```\n\n### onInit\n\n#### 描述\n\n触发字段初始化，默认不需要手动调用\n\n#### 签名\n\n```ts\ninterface onInit {\n  (): void\n}\n```\n\n### onMount\n\n#### 描述\n\n触发字段挂载\n\n#### 签名\n\n```ts\ninterface onMount {\n  (): void\n}\n```\n\n### onUnmount\n\n#### 描述\n\n触发字段卸载\n\n#### 签名\n\n```ts\ninterface onUnmount {\n  (): void\n}\n```\n\n### query\n\n#### 描述\n\n查询字段，可以基于当前字段查询相邻字段\n\n#### 签名\n\n```ts\ninterface query {\n  (pattern: FormPathPattern): Query\n}\n```\n\nFormPathPattern API 参考 [FormPath](/api/entry/form-path#formpathpattern)\n\nQuery 对象 API 参考 [Query](/api/models/query)\n\n### dispose\n\n#### 描述\n\n释放 observer，默认不需要手动释放\n\n#### 签名\n\n```ts\ninterface dispose {\n  (): void\n}\n```\n\n### destroy\n\n#### 描述\n\n释放 observer，并删除字段模型\n\n#### 签名\n\n```ts\ninterface destroy {\n  (): void\n}\n```\n\n### match\n\n#### 描述\n\n基于路径匹配字段\n\n#### 签名\n\n```ts\ninterface match {\n  (pattern: FormPathPattern): boolean\n}\n```\n\nFormPathPattern API 参考 [FormPath](/api/entry/form-path#formpathpattern)\n\n### inject\n\n#### 描述\n\n给字段模型注入可执行方法\n\n#### 签名\n\n```ts\ninterface inject {\n  (actions: Record<string, (...args: any[]) => any>): void\n}\n```\n\n### invoke\n\n#### 描述\n\n调用字段模型通过 inject 注入的可执行方法\n\n#### 签名\n\n```ts\ninterface invoke {\n  (name: string, ...args: any[]): any\n}\n```\n\n## 类型\n\n<Alert>\n注意：如果要手动消费类型，直接从包模块中导出即可\n</Alert>\n\n### FieldMessage\n\n```ts\ntype FieldMessage = string | JSXElement\n```\n\n如果在支持 JSX 的 UI 框架下，我们可以直接传 JSX 的 Node，否则，我们只能传字符串\n\n### FieldComponent\n\n```ts\ntype FieldComponent = string | JSXComponentConstructor\n```\n\n字段组件，如果我们在支持 JSX 的框架中使用，FieldComponent 推荐直接存储 JSX 组件引用，否则可以存储一个组件标识字符串，在实际渲染的时候做一次分发。\n\n### FieldDecorator\n\n```ts\ntype FieldDecorator = string | JSXComponentConstructor\n```\n\n字段装饰器，如果我们在支持 JSX 的框架中使用，FieldDecorator 推荐直接存储 JSX 组件引用，否则可以存储一个组件标识字符串，在实际渲染的时候做一次分发。\n\n### FieldReaction\n\n```ts\ntype FieldReaction = (field: GeneralField) => void\n```\n\n### FieldDisplayTypes\n\n```ts\ntype FieldDisplayTypes = 'none' | 'hidden' | 'visible'\n```\n\n### FieldPatternTypes\n\n```ts\ntype FieldPatternTypes = 'editable' | 'disabled' | 'readOnly' | 'readPretty'\n```\n\n### GeneralField\n\n```ts\ntype GeneralField = Field | VoidField | ArrayField | ObjectField\n```\n\nField 参考 [Field](/api/models/field)\n\nArrayField 参考 [ArrayField](/api/models/array-field)\n\nObjectField 参考 [ObjectField](/api/models/object-field)\n\n### IVoidFieldState\n\n```ts\ninterface IVoidFieldState {\n  hidden?: boolean\n  visible?: boolean\n  editable?: boolean\n  readOnly?: boolean\n  disabled?: boolean\n  readPretty?: boolean\n  title?: any\n  description?: any\n  modified?: boolean\n  active?: boolean\n  visited?: boolean\n  initialized?: boolean\n  mounted?: boolean\n  unmounted?: boolean\n  decorator?: FieldDecorator\n  component?: FieldComponent\n  readonly parent?: GeneralField\n  display?: FieldDisplayTypes\n  pattern?: FieldPatternTypes\n}\n```\n\n### IGeneralFieldState\n\n```ts\ntype IGeneralFieldState = IVoidFieldState & IFieldState\n```\n\nIFieldState 参考 [IFieldState](/api/models/field#ifieldstate)\n"
  },
  {
    "path": "packages/core/docs/guide/architecture.md",
    "content": "# Core Architecture\n\n## Domain Model\n\nFormily's kernel architecture is very complicated, because it is necessary to solve a domain-level problem, rather than a single point of specific problem, first go to the architecture diagram:\n\n![](https://img.alicdn.com/imgextra/i4/O1CN01HlrsLS1hQAJnihhh1_!!6000000004271-55-tps-2431-2037.svg)\n\n## Description\n\nFrom the above figure, we can see that the Formily kernel is actually a @formily/reactive domain model.\n\nThe actual consumption domain model mainly relies on the @formily/reactive responder mechanism for dependency tracking to consume.\n\nWe can consume any attribute in the Form/Field/ArrayField/ObjectField/VoidField model in the responder (Reactions). When the dependent attribute changes, the responder will execute repeatedly.\n\nSo as to realize the Reactive programming model at the form level.\n"
  },
  {
    "path": "packages/core/docs/guide/architecture.zh-CN.md",
    "content": "# 核心架构\n\n## 领域模型\n\nFormily 内核架构非常复杂，因为要解决一个领域级的问题，而不是单点具体的问题，先上架构图：\n\n![](https://img.alicdn.com/imgextra/i4/O1CN01HlrsLS1hQAJnihhh1_!!6000000004271-55-tps-2431-2037.svg)\n\n## 说明\n\n从上图中我们可以看到 Formily 内核其实是一个 @formily/reactive 领域模型。\n\n实际消费领域模型则主要是依赖 @formily/reactive 的 响应器 机制做依赖追踪来消费。\n\n我们可以在响应器(Reactions)中消费 Form/Field/ArrayField/ObjectField/VoidField 模型中的任意属性，依赖的属性发生变化，响应器就会重复执行。\n\n从而实现了表单层面的 Reactive 编程模型。\n"
  },
  {
    "path": "packages/core/docs/guide/field.md",
    "content": "# Field model\n\nFormily's field model core contains two types of field models:\n\n- Data type field\n- Dummy data type field\n\nData type field (Field), the core is responsible for maintaining the form data (the value when the form is submitted).\n\nVoidField, you can understand that it is a Field that has castrated data maintenance capabilities, so it is more of a UI form that maintains a batch of fields as a container.\n\nLet's analyze these two types of fields in detail.\n\n## Data field\n\nThere are 3 data type fields in the field model:\n\n- Field\n- ArrayField\n- ObjectField\n\nArrayField and ObjectField are both inherited from Field. The positioning of Field is to maintain non-incremental data fields. Compared with ArrayField/Object, it does not mean that Field cannot store data of array type or object type. Field can store data of any data type. However, if the user expects to realize the interaction of adding, deleting, and moving arrays, they need to use ArrayField, and for the interaction of adding and deleting object properties, they need to use ObjectField. If there is no such requirement, all data types can be unified with Field.\n\nThen let's look at the specific Field rules:\n\n- Path rules\n- Explicit and implicit rules\n- Data read and write rules\n- Data source rules\n- Field component rules\n- Field decorator rules\n- Validation rules\n\n### Path Rules\n\nBecause the form structure of our actual business itself is a tree structure, in Formily, each field will have an absolute path in the form model. This absolute path roughly describes the position of the field in the form data (why use roughly, later I will talk about it), any field can be found through the absolute path, and at the same time the parent-child relationship between the fields can be expressed. Therefore, in the field model, we define the address attribute to express the absolute path of the field, which is mainly described by dot syntax, such as abc The path of represents that the father of field c is field b, and the father of field b is a.\n\nOf course, things are not that simple, because we also have a VoidField, which is a dummy data field, and it also has its own absolute path, because it can be the father of the data field. If we only have an absolute path, we cannot make a data field correct. Write field data to the form data. Reading data will also read the wrong position.\n\nTherefore, we actually need a data path as a dedicated data field for writing data and reading data. Here we use path to describe the data path of the field. You can look at this picture for general rules:\n\n![](//img.alicdn.com/imgextra/i1/O1CN01cdzULJ1et4PBak8si_!!6000000003928-2-tps-3506-2042.png)\n\nIn summary, Address is always the absolute path representing the node, and Path is the node path that skips the VoidField, but if it is the Path of the VoidField, it will retain its own path position.\n\nTherefore, whether it is a Field or a VoidField, it will have its Address and Path, so when we use the query method to query the field, we can either use the Address rule to query, or use the Path rule to query, such as `query(\"bc\")` The c field can be queried, and the c field can also be queried with `query(\"abc\")`.\n\n### Explicit and Implicit Rules\n\nThe display and hiding of the fields are mainly expressed by the display attribute:\n\n- If display is none, it means that the field UI is hidden and the field data is not retained\n- display is hidden, which means that the field UI is hidden and the field data is preserved\n- display is visible, which means the field UI is displayed, and the field data is restored at the same time\n\nOn top of the display property, we also provide two convenient properties\n\n1. visible, if true, display is equal to visible, if false, display is equal to none\n2. hidden, if true, display is equal to hidden, if false, display is equal to visible\n\nThe above is about the writing rules of explicit and implicit attributes. The reading rules will be more complicated. Here is a default inheritance logic:\n\nIf the parent node actively sets the display property, and the child node does not actively set the display property, then the child node will inherit the display of the parent node\n\nSo what is the active setting of display? mainly includes:\n\n- Configure the initial attributes display/visible/hidden for the field\n- If there is no configuration during initialization, but display/visible/hidden is set to the field later\n\nSo what if you want to change from no inheritance to inheritance? Just set display to null.\n\n### Data read and write rules\n\nBecause Field is a data-type field, it is responsible for maintaining the data of a certain node of the form data. The reading here is actually the form data read directly, which is addressed through the path attribute, which also guarantees the form data and field data. Absolutely idempotent, just read value/initialValue directly.\n\nThe data writing rules are consistent with the reading rules. Field does not independently maintain a copy of data. It directly operates on the data of the specific form, which is addressed through the path attribute. The main writing methods are:\n\n- Modify the value/initialValue attribute directly\n- Calling onInput will write data, and at the same time, set the inputValue of the field as input parameter data, inputValues as multi-parameter data, and then set the modified attribute to true, which means that the field has been manually modified, and finally trigger the verification rule that triggerType is onInput\n- Call the setValue method\n\n### Data source rules\n\nConsidering that the value source of the field is not only input through the Input input box, but also selected from a data source, such as a drop-down box, the field model adds a data source attribute dataSource, which is dedicated to reading data source. Only a layer of mapping needs to be done on the component consumer side. The method of writing to the data source can directly modify the dataSource property, or call the setDataSource method\n\n### Component Rules\n\nField model, if there is no proxy UI component information, then more refined linkage control cannot be achieved. For example, if the value of A field changes to control the placeholder of B field, then the field attributes must be proxyed, so formily provides The component property is used to proxy UI component information. The component is an array `[Component,ComponentProps]`. The first element represents which component it is, and the second represents the properties of the component. Why use an array? This is convenient for type prompting, and the writing method is relatively simple.\n\nThe way to read component information is to read the component property directly.\n\nThe main ways to write component information are:\n\n- Modify the component property directly and pass in the array\n- Call the setComponent method, the first parameter is the component, the second is the component property\n- Call the setComponentProps method to directly set the component properties\n\n### Decorator rules\n\nSimilar to the field component rules, the field decorator is mainly used to maintain the package container of the field, such as FormItem, which is more partial to the control of the UI layout. Here we use the decorator attribute to describe the field decorator.\n\nThe way to read the decorator information is to directly read the decorator attribute.\n\nThe main ways to write decorator information are:\n\n- Modify the decorator property directly and pass in an array\n- Call the setDecorator method, the first parameter is the component, and the second is the component property\n- Call the setDecoratorProps method to directly set the component properties\n\n### Validation rules\n\nThe verification rules mainly include:\n\n- Verifier\n- Timing of calibration\n- Verification strategy\n- Verification result\n\n#### Validator\n\nThe validator in the field model is mainly described by the validator attribute. The validator can be passed to the field when the field is initialized, and the validator can be modified again after initialization.\n\nA validator mainly has the following forms:\n\n- Pure string format verification, such as `\"phone\" | validator = \"url\" | validator= \"email\"`. This format verification is a short form of regular rules. Formily provides some standard regular rules. Of course Users can also manually create rules through registerValidateFormats to facilitate reuse\n- Custom function verification, there are 3 return value modes:\n  - `(value)=>\"message\"`, a string returned means there is an error, and no string means no error\n  - `(value)=>({type:\"error\",message:\"message\"})`, return object form, you can specify type as error or warning or success\n  - `{validator:()=>false,message:\"message\"}`, returns a boolean form, the error message will reuse the message field of the object structure\n- Object structure verification is a more complete expression, such as:\n  - `{format:\"url\"}` This can specify the regular format\n  - `{required:true}` This can specify required fields\n  - There are more rule attributes can refer to the API documentation, and we can also register similar validation rules through registerValidateRules\n- Object array structure verification is a combination of the previous three types. In fact, the first three types will all be converted into object array structures, such as:\n  - `[\"url\",{required:true},(value)=>\"message\"]` is actually equivalent to `[{format:\"url\"},{required:true},{validator:(value)=> \"message\"}]`\n\n#### Check timing\n\nSometimes, we want certain verification rules to be triggered only when focusing or out of focus. We can add a triggerType to each verification rule object, such as `{validator:(value)=>\"message\",triggerType: \"onBlur\"}` In this way, you can precisely control a verification rule to perform verification only in a certain event. The triggerType here mainly includes `\"onInput\" | \"onBlur\" | \"onFocus\"`, if you call `form. validate` is a rule that verifies all triggerTypes at once. If you manually call `field.validate`, you can specify the triggerType in the input parameters, and all triggerTypes will be verified if you don’t pass them.\n\n#### Verification Strategy\n\nSometimes, we hope that the verification strategy of a certain field is that when all the verification rules are executed, if a verification rule fails, the result will be returned immediately. We only need to pass the parameter validateFirst to true when the field is initialized. That is, the default is false, that is, the verification will continue if the verification fails, and the verification result obtained is an array.\n\n#### Read the verification result\n\nThe verification results are mainly stored in the feedbacks property in the field model. Feedbacks is an array of Feedback objects. The structure of each Feedback is:\n\n```ts\ninterface Feedback {\n  path: string //Field data path\n  address: string //field absolute path\n  type: 'error' | 'success' | 'warning' //Verification result type\n  code: //Check result code\n  | 'ValidateError'\n    | 'ValidateSuccess'\n    | 'ValidateWarning'\n    | 'EffectError'\n    | 'EffectSuccess'\n    | 'EffectWarning'\n  messages: string[] //Check the message\n}\n```\n\nThere are four main ways to read:\n\n- Read feedbacks properties directly\n- Reading the errors attribute is equivalent to filtering out all verification results with type error from feedbacks\n- Reading the warnings attribute is equivalent to filtering out all the verification results whose type is warning from feedbacks\n- Reading the successes attribute is equivalent to filtering out all verification results with type success from feedbacks\n\n#### Write verification result\n\nThere are 3 ways to write:\n\n- Call the validate method to trigger the field validator to perform the validation action, and the code of the validation result is uniformly Validate\\*`\n  - Calling onInput will trigger validate\n  - Calling onFocus will trigger validate\n  - Calling onBlur will trigger validate\n  - Call reset and specify validate as true to trigger validate\n- Modify the feedbacks attribute directly\n- Modify the errors property directly, it will be converted into an array of feedbacks objects, and the code of Feedback will be forcibly overwritten as EffectError\n- Modify the warnings attribute directly, it will be converted into an array of feedbacks objects, and the code of Feedback will be forcibly overwritten as EffectWarning\n- Modify the successes property directly, it will be converted into an array of feedbacks objects, and the code of Feedback will be forcibly overwritten as EffectSuccess\n\nSuch writing logic is mainly to prevent users from modifying the verification results from polluting the verification results of their own verifiers, strictly separating them, and easy to restore the scene.\n\n#### Verification result query\n\nThe query of the verification result is mainly queried through queryFeedbacks. The query has the same participating Feedback objects, which can be filtered by type or code, or by path.\n\n## ArrayField\n\nCompared with Field, ArrayField only extends array-related methods on the basis of inheriting Field, such as push/pop/insert/move. Why should these methods be provided? Its ability is not only to process the field data, it It also provides internal state transposition processing for the sub-nodes of ArrayField mainly to ensure that the order of the fields is consistent with the order of the data. Can cite an example:\n\n![](//img.alicdn.com/imgextra/i3/O1CN01mpGugu1QFlnfQ4qfo_!!6000000001947-2-tps-3506-1794.png)\n\nThis is a move call process, the value of the array element will move, and the state of the corresponding field will also move.\n\n## ObjectField\n\nBecause the object type is disordered, there is no state transposition, so ObjectField provides addProperty/removeProperty/existProperty three APIs for users to use.\n\n## VoidField\n\nCompared with Field, VoidField mainly castrates data read and write rules, data source rules, and verification rules. When users use it, they mainly use explicit and implicit rules, components, and decorator rules.\n\n<Alert>\n\nThe series of field rules mentioned above did not mention the detailed API usage details. It is more to help users sort out formily from the perspective of ideas. If you are not familiar with the API, it is best to read the API documentation first.\n\n</Alert>\n"
  },
  {
    "path": "packages/core/docs/guide/field.zh-CN.md",
    "content": "# 字段模型\n\nFormily 的字段模型核心包含了两类字段模型：\n\n- 数据型字段\n- 虚数据型字段\n\n数据型字段(Field)，核心是负责维护表单数据(表单提交时候的值)。\n\n虚数据型字段(VoidField)，你可以理解为它就是一个阉割了数据维护能力的 Field，所以它更多的是作为容器维护一批字段的 UI 形式。\n\n下面我们具体分析这两种类型字段。\n\n## 数据型字段\n\n在 字段模型 中有 3 种数据型字段：\n\n- Field\n- ArrayField\n- ObjectField\n\nArrayField 和 ObjectField 都是继承自 Field，Field 的定位就是维护非自增型数据字段，对比 ArrayField/Object，并不是说 Field 就不能存数组类型或者对象类型的数据，Field 其实可以存任意数据类型的数据，只是，如果用户期望实现数组的添加删除移动这样的交互，则需要使用 ArrayField，对象属性的添加删除交互，则需要使用 ObjectField，如果没有这样的需求，所有数据类型统一用 Field 即可。\n\n然后咱们再看具体 Field 领域规则：\n\n- 路径规则\n- 显隐规则\n- 数据读写规则\n- 数据源规则\n- 字段组件规则\n- 字段装饰器规则\n- 校验规则\n\n### 路径规则\n\n因为我们实际业务的表单结构本身就是一个树结构，所以在 Formily 中，每个字段在表单模型中都会有一个绝对路径，这个绝对路径大致描述了字段在表单数据中的位置(为什么用大致，后面会讲)，通过绝对路径可以找到任意一个字段，同时还能表达字段间的父子关系，所以字段模型中，我们定义了 address 属性来表达字段的绝对路径，主要用点语法来描述，比如 a.b.c 这样的路径代表了字段 c 的父亲是字段 b，字段 b 的父亲是 a。\n\n当然，事情并没有这么简单，因为我们还有 VoidField，VoidField 作为虚数据字段，它同样也有自己的绝对路径，因为它可以作为数据字段的父亲，如果我们只有绝对路径， 就无法让一个数据字段正确的往表单数据里写入字段数据。读取数据也会读错位置。\n\n所以，我们其实还需要一个数据路径作为专门用于数据字段写入数据和读取数据的，这里我们用 path 来描述字段的数据路径，大概的规则可以看看这张图：\n\n![](//img.alicdn.com/imgextra/i1/O1CN01cdzULJ1et4PBak8si_!!6000000003928-2-tps-3506-2042.png)\n\n总结下来就是，Address 永远是代表节点的绝对路径，Path 是会跳过 VoidField 的节点路径，但是如果是 VoidField 的 Path，是会保留它自身的路径位置。\n\n所以，不管是 Field 还是 VoidField，都会有它的 Address 和 Path，所以我们在用 query 方法查询字段的时候，既可以用 Address 规则查询，也可以用 Path 规则查询，比如`query(\"b.c\")`可以查询到 c 字段，同样用`query(\"a.b.c\")`也能查询到 c 字段。\n\n### 显隐规则\n\n字段的显示隐藏，主要用 display 属性来表达：\n\n- display 为 none 代表字段 UI 隐藏，同时不保留字段数据\n- display 为 hidden 代表字段 UI 隐藏，保留字段数据\n- display 为 visible 代表字段 UI 显示，同时恢复字段数据\n\n在 display 属性之上，我们还提供了两个便捷属性\n\n1. visible，如果为 true 代表 display 等于 visible，如果为 false 代表 display 等于 none\n2. hidden，如果为 true 代表 display 等于 hidden，如果为 false 代表 display 等于 visible\n\n上面讲的是显隐属性的写规则，读取规则就会更复杂一些，这里有一个默认继承逻辑：\n\n如果父节点主动设置了 display 属性，子节点没有主动设置 display 属性，那么子节点会继承父节点的 display\n\n那什么才是主动设置 display 呢？主要包括：\n\n- 给字段配置了初始化属性 display/visible/hidden\n- 如果初始化时没有配置，但是在后期又给字段设置了 display/visible/hidden\n\n那如果希望从不继承变为继承怎么办？把 display 设置为 null 即可。\n\n### 数据读写规则\n\n因为 Field 是数据型字段，它负责维护表单数据的某个节点的数据，这里的读取，其实是直接读取的表单数据，通过 path 属性来寻址，这样也保证了表单数据与字段数据的绝对幂等，读取的方式直接读取 value/initialValue 即可。\n\n数据写入规则与读取规则一致，Field 不会独立维护一份数据，它操作的直接就是具体表单的数据，通过 path 属性来寻址，写入的方式主要有：\n\n- 直接修改 value/initialValue 属性\n- 调用 onInput 会写入数据，同时设置字段的 inputValue 为入参数据，inputValues 为多参数据，然后设置 modified 属性为 true，代表该字段被手动修改过，最后触发 triggerType 为 onInput 的校验规则\n- 调用 setValue 方法\n\n### 数据源规则\n\n考虑到字段的值来源不是只有通过 Input 输入框输入的，还有会从一个数据源中选取的，比如下拉框之类的，所以字段模型加了一个数据源的属性 dataSource，专门用于读取数据源。只是在组件消费端需要做一层映射。写入数据源的方式可以直接修改 dataSource 属性，也可以调用 setDataSource 方法\n\n### 组件规则\n\n字段模型，如果没有代理 UI 组件信息，那就没法实现更加精细化的联动控制了，比如 A 字段的值变化要控制 B 字段的 placeholder，那就必须将字段的属性给代理起来，所以 formily 提供了 component 属性，专门用于代理 UI 组件信息，component 是一个数组`[Component,ComponentProps]`，第一个元素代表是哪个组件，第二个代表组件的属性有哪些，为什么用数组，主要原因是这样方便类型提示，同时写法也比较简单。\n\n读取组件信息的方式直接读取 component 属性即可。\n\n写入组件信息的方式主要有：\n\n- 直接修改 component 属性，传入数组\n- 调用 setComponent 方法，第一个参数是组件，第二个是组件属性\n- 调用 setComponentProps 方法，直接会设置组件属性\n\n### 装饰器规则\n\n与字段组件规则相似，字段装饰器主要用来维护字段的包裹容器，比如 FormItem，更偏 UI 布局的控制，这里我们用 decorator 属性来描述字段装饰器。\n\n读取装饰器信息的方式直接读取 decorator 属性即可。\n\n写入装饰器信息的方式主要有：\n\n- 直接修改 decorator 属性，传入数组\n- 调用 setDecorator 方法，第一个参数是组件，第二个是组件属性\n- 调用 setDecoratorProps 方法，直接会设置组件属性\n\n### 校验规则\n\n校验规则主要包含：\n\n- 校验器\n- 校验时机\n- 校验策略\n- 校验结果\n\n#### 校验器\n\n在字段模型中的校验器主要用 validator 属性描述，在字段初始化的时候可以给字段传入 validator，初始化之后也可以再次修改 validator\n\n一个 validator 主要有以下几种形态：\n\n- 纯字符串格式校验，比如`\"phone\" | validator = \"url\" | validator= \"email\"` ，这样的格式校验是正则规则的简写形式，formily 内部提供了一些标准的正则规则，当然用户也能通过 registerValidateFormats 来手动创建规则，方便复用\n- 自定义函数校验，有 3 种返回值模式：\n  - `(value)=>\"message\"`，返回字符串代表有错误，不返回字符串代表无错误\n  - `(value)=>({type:\"error\",message:\"message\"})`，返回对象形式，可以指定 type 是 error 或 warning 或 success\n  - `{validator:()=>false,message:\"message\"}`，返回布尔形式，错误消息会复用对象结构的 message 字段\n- 对象结构校验，是一种更完备的表达，比如：\n  - `{format:\"url\"}` 这样可以指定正则格式\n  - `{required:true}`这样可以指定必填\n  - 还有更多的规则属性可以参考 API 文档，同时我们还能通过 registerValidateRules 来注册类似的校验规则\n- 对象数组结构校验，是前面三种的组合表达，其实前 3 种，都会转换成对象数组结构，比如：\n  - `[\"url\",{required:true},(value)=>\"message\"]`其实相当于 `[{format:\"url\"},{required:true},{validator:(value)=>\"message\"}]`\n\n#### 校验时机\n\n有些时候，我们希望某些校验规则只在聚焦或者失焦的时候触发，我们可以在每个校验规则对象中加一个 triggerType，比如`{validator:(value)=>\"message\",triggerType:\"onBlur\"}` 这样就可以精确的控制某个校验规则只在某个事件中执行校验，这里的 triggerType 主要有`\"onInput\" | \"onBlur\" | \"onFocus\"` ，如果调用`form.validate`，是会一次性校验所有 triggerType 的规则，如果手动调用`field.validate`，则可以在入参中指定 triggerType，不传参就会校验所有。\n\n#### 校验策略\n\n有些时候，我们希望某个字段的校验策略是，执行所有校验规则的时候，如果某个校验规则校验失败则立即返回结果，我们只需要在 field 初始化的时候传入参数 validateFirst 为 true 即可，默认是 false，也就是校验失败也会继续校验，拿到的校验结果是一个数组。\n\n#### 校验结果读取\n\n对于校验结果，在字段模型中主要是存放在 feedbacks 属性中的，feedbacks 是由 Feedback 对象组成的数组，每个 Feedback 的结构是：\n\n```ts\ninterface Feedback {\n  path: string //字段数据路径\n  address: string //字段绝对路径\n  type: 'error' | 'success' | 'warning' //校验结果类型\n  code: //校验结果编码\n  | 'ValidateError'\n    | 'ValidateSuccess'\n    | 'ValidateWarning'\n    | 'EffectError'\n    | 'EffectSuccess'\n    | 'EffectWarning'\n  messages: string[] //校验消息\n}\n```\n\n读取方式主要有 4 种：\n\n- 直接读取 feedbacks 属性\n- 读取 errors 属性，相当于是从 feedbacks 中过滤出 type 为 error 的所有校验结果\n- 读取 warnings 属性，相当于是从 feedbacks 中过滤出 type 为 warning 的所有校验结果\n- 读取 successes 属性，相当于是从 feedbacks 中过滤出 type 为 success 的所有校验结果\n\n#### 校验结果写入\n\n写入方式有 3 种：\n\n- 调用 validate 方法，触发字段校验器执行校验动作，校验结果的 Code 统一是 Validate\\*`\n  - 调用 onInput 会触发 validate\n  - 调用 onFocus 会触发 validate\n  - 调用 onBlur 会触发 validate\n  - 调用 reset，并指定 validate 为 true 会触发 validate\n- 直接修改 feedbacks 属性\n- 直接修改 errors 属性，会转换成 feedbacks 对象数组，同时 Feedback 的 code 会被强制覆盖为 EffectError\n- 直接修改 warnings 属性，会转换成 feedbacks 对象数组，同时 Feedback 的 code 会被强制覆盖为 EffectWarning\n- 直接修改 successes 属性，会转换成 feedbacks 对象数组，同时 Feedback 的 code 会被强制覆盖为 EffectSuccess\n\n这样的写入逻辑主要是为了防止用户修改校验结果污染本身校验器的校验结果，做严格分离，容易恢复现场。\n\n#### 校验结果查询\n\n校验结果的查询主要通过 queryFeedbacks 来查询，查询的入参与 Feedback 对象一致，可以按照 type 或者 code，也可以按照路径进行过滤。\n\n## ArrayField\n\nArrayField 相比于 Field，仅仅只是在继承 Field 的基础上扩展了数组相关的方法，比如 push/pop/insert/move 这些，为什么要提供这些方法，它的能力不只是对字段的数据做处理，它内部还提供了对 ArrayField 子节点的状态转置处理主要为了保证字段的顺序与数据的顺序是一致。可以举个例子：\n\n![](//img.alicdn.com/imgextra/i3/O1CN01mpGugu1QFlnfQ4qfo_!!6000000001947-2-tps-3506-1794.png)\n\n这是一个 move 调用的过程，数组元素的值会发生移动，同时对应字段的状态也会发生移动。\n\n## ObjectField\n\n因为 object 类型是无序的，也就不存在状态转置，所以 ObjectField 就提供了 addProperty/removeProperty/existProperty 3 个 API 给用户使用。\n\n## VoidField\n\nVoidField 相比于 Field，主要是阉割了数据读写规则、数据源规则和校验规则，用户使用的时候，主要还是使用显隐规则和组件，装饰器规则。\n\n<Alert>\n\n前面讲的一系列字段领域规则，并没有提到详细的 API 使用细节，更多的是从思路上帮助用户梳理 formily，如果对 API 不熟悉的，最好先看 API 文档。\n\n</Alert>\n"
  },
  {
    "path": "packages/core/docs/guide/form.md",
    "content": "# Form model\n\nEarlier I talked about the overall architecture of the Formily kernel, and also talked about MVVM. You should also be able to roughly understand what Formily's form model is. Let's take a deeper look at the specific domain logic of the form model, which is mainly biased. Concluding content, if you don't understand it the first time, you can go directly to the API documentation, and come back after reading it, you can deepen your understanding of formily.\n\n## Combing\n\nThe entire form model is very large and complicated. In fact, the core of the decomposition is the following sub-models:\n\n- Field management model\n- Field model\n- Data model\n- Linkage model\n- Path system\n\nLet's talk about how the form model is managed in detail below.\n\n## Field Management Model\n\nThe field management model mainly includes:\n\n- Field addition\n- Field query\n- Import field set\n- Export field set\n- Clear the field set\n\n#### Field addition\n\nThe field is created mainly through the createField/createArrayField/createObjectField/createVoidField method. If the field already exists, it will not be created repeatedly\n\n#### Field query\n\nThe query method is mainly used to query the field. The query method can pass in the path of the field or regular expression to match the field.\n\nBecause the detailed rules of the field path are still more complicated, they will be explained in detail in the following [Path System](/api/entry/form-path) article.\n\nThen calling the query method will return a Query object. The Query object can have a forEach/map/reduce method that traverses all fields in batches, or a take method that takes only the first field that is queried, as well as direct reading of fields. The get method of properties, and the getIn method that can read field properties in depth, the difference between the two methods is that the former can have smart prompts, and the latter has no prompts, so it is recommended that users use the get method.\n\n#### Import field set\n\nThe field set is imported mainly through setFormGraph. The input parameter format is a flat object format, the key is the absolute path of the field, and the value is the state of the field. Use this API to import the Immutable field state into the form in some scenarios that require time travel. In the model.\n\n#### Export field set\n\nThe field set is mainly exported through getFormGraph. The export format is a flat object format, the key is the absolute path of the field, and the value is the state of the field, which is consistent with the imported field set input parameters. Because the returned data is an Immutable data, it is OK Completely persistent storage, convenient for time travel.\n\n#### Clear the field set\n\nThe field set is cleared mainly through clearFormGraph.\n\n## Field Model\n\nThe field model mainly includes:\n\n- Field model, which is mainly responsible for managing the state of non-incremental fields, such as Input/Select/NumberPicker/DatePicker components\n- The ArrayField model is mainly responsible for managing the state of the auto-increment list field, and can add, delete, and move list items.\n- ObjectField model, which is mainly responsible for managing the state of auto-incremented object fields, and can add or delete the key of the object.\n- The VoidField model is mainly responsible for managing the state of the virtual field. The virtual field is a node that does not pollute the form data, but it can control the display and hiding of its child nodes, and the interactive mode.\n\nBecause the field model is very complicated, it will be explained in detail in the following [Field Model](/guide/field) article.\n\n## Data Model\n\nFor the form data model, the previous version of Formily will more or less have some boundary problems. After reorganizing a version in 2.x, it really broke through the previous legacy problems.\n\nThe data model mainly includes:\n\n- Form values (values) management\n- Form default value (initialValues) management\n- Field value (value) management\n- Field default value (initialValue) management\n- Value and default value selection merge strategy\n\nForm value management is actually the values attribute of an object structure, but it is an @formily/reactive observable attribute. At the same time, with the help of @formily/reactive's deep observer capability, it monitors any attribute changes, and if it changes, it will trigger The life cycle hook of onFormValuesChange.\n\nIn the same way, the default value management is actually the initialValues property of an object structure. It will also deeply monitor property changes and trigger the onFormInitialValues life cycle hook.\n\nField value management is reflected in the value attribute of each data type field. Formily will maintain a data path attribute called path for each field, and then read and write values are all read and write the values of the top-level form. This ensures that the value of the field and the value of the form are absolutely idempotent, and the default value of the field is the same.\n\nTo sum up, the management of **values is all managed on the top-level form, and the value of the field and the value of the form are absolutely idempotent through path. **\n\n<Alert>\n\nThe difference between the value and the default value is actually whether the field will be reset to the default value state when the form is reset\n\n</Alert>\n\n#### Value and default value selection merge strategy\n\nUsually, in the process of business development, there is always a need for data echo. This data is generally used as an asynchronous default value. If it is used as a detail page, it is okay, but as an editing page, there will be some problems. :\n\n**There is a conflict**\n\nFor example, the form value is `{xx:123}`, and the default form value is `{xx:321}`. The strategy here is:\n\n- If `xx` does not have a corresponding field model, it means it is just redundant data and cannot be modified by the user\n  - If the form value is assigned first, and the default value is assigned later, then the default value directly overrides the form value. This scenario is suitable for asynchronous data echo scenarios. Different business states have different default data echoes, and the data is finally submitted.` {xx:321}`\n  - If the default value is assigned first, and the form value is assigned later, the form value directly overrides the default value. This scenario is suitable for synchronizing the default value and finally submitting the data `{xx:123}`\n- If `xx` has a field model\n  - If the form value is assigned first, the default value is assigned later\n    - If the current field has been modified by the user (modified is true), then the default value cannot overwrite the form value, and finally submit the data `{xx:123}`\n    - If the current field has not been modified by the user (modified is false), then the default value will directly override the field value. This scenario is suitable for asynchronous data echo scenarios. Different business states have different default data echoes, and the data is finally submitted `{xx:321}`\n  - If the default value is assigned first, and the form value is assigned later, the form value directly overrides the default value. This scenario is suitable for synchronizing the default value and finally submitting the data `{xx:123}`\n\n**No conflicts**\n\nFor example, the form value is `{xx:123}`, and the default form value is `{yy:321}`. The strategy here is to merge directly.\n\nTo sum up, the selection and merging strategy of the value and the default value, the core is to see whether the field has been modified by the user, everything is subject to the user, if it has not been modified by the user, the order of assignment shall prevail.\\*\\*\n\n<Alert>\n\nThe default value mentioned here can be assigned repeatedly, and it is also the question of whether to discard the value in the process of repeated assignment.\n\n</Alert>\n\n## Validation model\n\nThe core of the form verification model is to verify the validity of the data, and then manage the verification results, so the verification model mainly includes:\n\n- Validation rule management\n- Calibration result management\n\nBecause the verification model belongs to the field model, it will be explained in detail in the following [Field Model](/guide/field#Verification Rules)\n\n## Linkage model\n\nThe core of the linkage model in formily1.x is the active linkage model, which is roughly expressed in one sentence:\n\n```ts\nsetFieldState(Subscribe(FormLifeCycle, Selector(Path)), TargetState)\n```\n\nThe explanation is that any linkage is based on a certain life cycle hook of the form to trigger the state of the field under the specified path. Such a model can solve many problems, but it also has an obvious problem, which is the many-to-one linkage. In the scenario where you need to monitor changes in multiple fields at the same time to control the state of a field, the implementation cost is still relatively high for users, especially to achieve some calculator linkage requirements, and the amount of code increases sharply. Of course, for one-to-many scenarios, this model is the most efficient.\n\nTherefore, in formily 2.x, a passive linkage model is added to the active linkage model, which is also an expression:\n\n```ts\nsubscribe(Dependencies, Reactions)\n```\n\nSimplified a lot, the core is to respond to dependent data changes. The dependent data can be form model attributes or attributes of any field model. The response action can be to change the attributes of any field model or do other asynchronous actions. . Such a model is also a complete linkage model, but in a one-to-many scenario, the implementation cost will be higher than the active model.\n\nTherefore, the two linkage models require users to choose according to their own needs.\n\n## Path system\n\nThe path system is very important. The path system is used everywhere in almost the entire form model. It mainly provides the following capabilities for the form model:\n\n- It can be used to find any field from the field set, and it also supports batch search according to the rules\n- It can be used to express the model of the relationship between the fields. With the help of the path system, we can find the father of a certain field, can find the father, and can also realize the data inheritance ability of the tree level. Similarly, we can also find the data of a certain field. Adjacent node\n- It can be used to read and write field data, read and write data with deconstruction\n\nThe entire path system is actually implemented based on the path DSL of @formily/path. If you want to know more about the path system, you can take a look at [FormPath API](/api/entry/form-path) in detail\n"
  },
  {
    "path": "packages/core/docs/guide/form.zh-CN.md",
    "content": "# 表单模型\n\n前面讲到了 Formily 内核的整体架构，同时也讲了 MVVM，你应该也能大致能理解什么是 Formily 的表单模型了，下面我们再深一步来讲表单模型的具体领域逻辑，主要是偏思路性的总结性内容，如果第一遍看不懂，可以先直接去看 API 文档，看完之后再回来看，就能加深对 formily 的理解了。\n\n## 梳理\n\n整个表单模型很大很复杂，分解下来其实核心是以下几个子模型：\n\n- 字段管理模型\n- 字段模型\n- 数据模型\n- 联动模型\n- 路径系统\n\n下面具体来讲一下表单模型是如何管理的。\n\n## 字段管理模型\n\n字段管理模型，主要包含：\n\n- 字段添加\n- 字段查询\n- 导入字段集\n- 导出字段集\n- 清空字段集\n\n#### 字段添加\n\n主要通过 createField/createArrayField/createObjectField/createVoidField 方法来创建字段，如果字段已经存在，则不会重复创建\n\n#### 字段查询\n\n主要通过 query 方法来查询字段，query 方法可以传入字段的路径或者正则表达式来匹配字段。\n\n因为字段路径的详细规则还是比较复杂的，在后面的[路径系统](/api/entry/form-path)篇中会详细讲解。\n\n然后调用 query 方法会返回一个 Query 对象，Query 对象中可以有批量遍历所有字段的 forEach/map/reduce 方法，也可以有只取查询到的第一个字段的 take 方法，同时还有直接读取字段属性的 get 方法，还有可以深层读取字段属性的 getIn 方法，两个方法的差别就是前者可以有智能提示，后者没有提示，所以推荐用户都用 get 方法。\n\n#### 导入字段集\n\n主要通过 setFormGraph 来导入字段集，入参格式是一个扁平对象格式，key 是字段的绝对路径，value 是字段的状态，使用该 API 主要在一些需要做时间旅行的场景，将 Immutable 字段状态导入至表单模型中。\n\n#### 导出字段集\n\n主要通过 getFormGraph 来导出字段集，导出格式是一个扁平对象格式，key 是字段的绝对路径，value 是字段的状态，与导入字段集入参一致，因为返回的数据是一个 Immutable 的数据，所以是可以完全做持久化存储的，方便时间旅行。\n\n#### 清空字段集\n\n主要通过 clearFormGraph 来清空字段集。\n\n## 字段模型\n\n字段模型主要包含了：\n\n- Field 模型，主要负责管理非自增型字段状态，比如 Input/Select/NumberPicker/DatePicker 这些组件\n- ArrayField 模型，主要负责管理自增列表字段状态，可以对列表项进行增删移动的。\n- ObjectField 模型，主要负责管理自增对象字段状态，可以对对象的 key 做增删操作。\n- VoidField 模型，主要负责管理虚字段状态，虚字段是一种不会污染表单数据的节点存在，但是它可以控制它的子节点显示隐藏，交互模式。\n\n因为字段模型非常复杂，所以会在后面的[字段模型](/guide/field)篇中详细讲解。\n\n## 数据模型\n\n表单数据模型，formily 之前的版本或多或少都会存在一些边界问题，在 2.x 中重新梳理了一版，才真正把之前的遗留问题突破掉了。\n\n数据模型主要包含：\n\n- 表单值(values)管理\n- 表单默认值(initialValues)管理\n- 字段值(value)管理\n- 字段默认值(initialValue)管理\n- 值与默认值的选择合并策略\n\n表单值管理，其实就是一个对象结构的 values 属性，只是它是一个 @formily/reactive observable 属性，同时借助了 @formily/reactive 的深度 observer 能力，监听了它任意属性变化，如果发生变化，便会触发 onFormValuesChange 的生命周期钩子。\n\n同理，默认值管理其实也是一个对象结构的 initialValues 属性，同样会深度监听属性变化，触发 onFormInitialValues 的生命周期钩子。\n\n字段值管理，是在每个数据型字段的 value 属性上体现的，formily 会给每个字段维护一个叫 path 的数据路径属性，然后 value 的读写，都是对顶层表单的 values 进行读写，这样保证了字段的值与表单的值是绝对幂等的，同理字段默认值也一样。\n\n总结一下，**值的管理，都是在顶层表单上管理的，字段的值与表单的值是通过 path 来实现的绝对幂等。**\n\n<Alert>\n\n值与默认值的差别其实就在于表单重置的时候，字段是否会重置为默认值状态\n\n</Alert>\n\n#### 值与默认值的选择合并策略\n\n平时我们在业务开发的过程中，总会有数据回显的需求，这份数据一般都是作为异步默认值，作为详情页面的话，都还好，但是作为编辑页面的话，就会存在一些问题了：\n\n**存在冲突**\n\n比如表单值为`{xx:123}`，表单默认值为`{xx:321}`，这里的策略是：\n\n- 如果`xx`没有相应的字段模型，代表仅仅只是冗余数据，用户无法修改\n  - 如果表单值是先赋值，默认值是后赋值的，那么默认值直接覆盖表单值，这种场景适用于异步数据回显场景，不同业务状态，回显的默认数据不一样，最终提交数据`{xx:321}`\n  - 如果默认值先赋值，表单值是后赋值的，那么表单值直接覆盖默认值，这种场景适用于同步默认值，最终提交数据`{xx:123}`\n- 如果`xx`有字段模型\n  - 如果表单值先赋值，默认值是后赋值的\n    - 如果当前字段被用户修改过(modified 为 true)，那么默认值不能覆盖表单值，最终提交数据`{xx:123}`\n    - 如果当前字段没有被用户修改过(modified 为 false)，那么默认值会直接覆盖字段值，这种场景适用于异步数据回显场景，不同业务状态，回显的默认数据不一样，最终提交数据`{xx:321}`\n  - 如果默认值先赋值，表单值是后赋值的，那么表单值直接覆盖默认值，这种场景适用于同步默认值，最终提交数据`{xx:123}`\n\n**不存在冲突**\n\n比如表单值为`{xx:123}`，表单默认值为`{yy:321}`，这里的策略是直接合并。\n\n总结一下，值与默认值的选择合并策略，**核心是看该字段是否被用户修改过，一切以用户为准，如果没被用户修改过就以赋值顺序为准**\n\n<Alert>\n\n这里提到的默认值，是可以重复赋值的，说的也是在重复赋值的过程中，要不要舍弃值的问题。\n\n</Alert>\n\n## 校验模型\n\n表单校验模型核心是对数据的合法性校验，然后将校验结果管理起来，所以校验模型主要包含了：\n\n- 校验规则管理\n- 校验结果管理\n\n因为校验模型隶属于字段模型，所以会在后面的[字段模型](/guide/field#校验规则)篇中详细讲解\n\n## 联动模型\n\n联动模型在 formily1.x 中核心是走的主动式联动模型，大致用一句表达式来表达就是：\n\n```ts\nsetFieldState(Subscribe(FormLifeCycle, Selector(Path)), TargetState)\n```\n\n解释下就是，任意一次联动，都是基于表单的某个生命周期钩子去触发指定路径下字段的状态，这样的模型能解决很多问题，但是它也有个很明显的问题，就是在多对一联动的场景下，需要同时监听多个字段变化去控制某个字段的状态，这样对用户而言，实现成本还是比较高的，特别是实现一些计算器联动需求，代码量剧增。当然，对于一对多场景，反而这种模型又是最高效的。\n\n所以，在 formily2.x 中，在主动联动模型上新增了被动联动模型，同样是一句表达式表达：\n\n```ts\nsubscribe(Dependencies, Reactions)\n```\n\n简化了很多，核心就是针对依赖数据变化做响应，依赖的数据可以是表单模型属性，也可以是任意字段模型的属性，响应的动作可以是改任意字段模型的属性，也可以是做其他异步动作。这样的模型同样是一个完备的联动模型，只是在一对多场景下，比起主动模型而言，实现成本会比较高。\n\n所以，两种联动模型，需要用户根据自身需求来选择。\n\n## 路径系统\n\n路径系统，非常重要，几乎整个表单模型处处都有用到路径系统，它的主要给表单模型提供了以下几个能力：\n\n- 它可以用来从字段集中查找任意一个字段，同时支持按照规则批量查找\n- 它可以用来表达字段间关系的模型，借助路径系统，我们可以实现查找某个字段父亲，能查找父亲，也就能实现树级别的数据继承能力，同样，我们也能查找某个字段的相邻节点\n- 它可以用来实现字段数据的读写，带解构的数据读写\n\n整个路径系统，其实是基于@formily/path 的路径 DSL 来实现的，想要了解更多路径系统的内容，可以详细看看[FormPath API](/api/entry/form-path)篇\n"
  },
  {
    "path": "packages/core/docs/guide/index.md",
    "content": "# Introduction\n\n## Pure Core,No UI\n\nBecause @formily/core exists as an independent package, its core meaning is to separate the domain model from the UI framework, and at the same time, it can bring the following two intuitive benefits to developers:\n\n1. It is convenient for formily developers to release from the coupling relationship between UI and logic, and improve code maintainability;\n\n2. Allow formily to have cross-terminal and cross-framework capabilities. Whether you are a React user, Vue user or Angular user, you can enjoy the efficiency improvement brought by formily's domain model.\n\n## Ultra high performance\n\nWith the help of @formily/reactive, @formily/core naturally gains the ability to track dependencies, update efficiently, and render on-demand. Whether it is under React or Vue/Angular, whether it is frequent field input or field linkage, it can give Users bring O(1) performance experience, developers do not need to care about performance optimization, only need to focus on business logic implementation.\n\n## Domain Model\n\nIf we break down the form question, we can actually break it down:\n\n- Data management issues\n- Field management issues\n- Calibration management issues\n- Linkage management issues\n\nThe problems in these directions can actually be solved as domain-level problems. Each domain problem is actually a very complex problem. In Formily, all of them are solved by breakthroughs, so you only need to focus on business logic. That's it.\n\n## Smart tips\n\nBecause formily is a complete Typescript project, users can develop on VSCode or WebStorm to get the maximum intelligent prompt experience\n\n![](https://img.alicdn.com/imgextra/i2/O1CN01yiREHk1X95KJPPz1c_!!6000000002880-2-tps-2014-868.png)\n\n## Status observable\n\nInstall [FormilyDevtools](https://chrome.google.com/webstore/detail/formily-devtools/kkocalmbfnplecdmbadaapgapdioecfm?hl=zh-CN) to observe the model status changes in real time and troubleshoot problems\n\n![](//img.alicdn.com/imgextra/i4/O1CN01DSci5h1rAGfRafpXw_!!6000000005590-2-tps-2882-1642.png)\n"
  },
  {
    "path": "packages/core/docs/guide/index.zh-CN.md",
    "content": "# 介绍\n\n## UI 无关\n\n因为 @formily/core 作为一个独立的包而存在，它的核心意义是将领域模型从 UI 框架中抽离出来，同时给开发者带来了以下两个直观收益：\n\n1. 可以方便 formily 开发者从 UI 与逻辑的耦合关系中释放出来，提升代码可维护性；\n\n2. 可以让 formily 拥有跨终端，跨框架的能力，不管你是 React 用户，Vue 用户还是 Angular 用户，都能享受到 formily 的领域模型带来的提效。\n\n## 超高性能\n\n借助 @formily/reactive，@formily/core 天然获得了依赖追踪，高效更新，按需渲染的能力，不管是在 React 下，还是 Vue/Angular 下，不管是字段频繁输入，还是字段联动，都能给用户带来 O(1)的性能体验，开发者无需关心性能优化的事情，只需要专注于业务逻辑实现即可。\n\n## 领域模型\n\n如果把表单问题做分解，其实我们可以分解出：\n\n- 数据管理问题\n- 字段管理问题\n- 校验管理问题\n- 联动管理问题\n\n这几个方向的问题其实都可以作为领域级问题去解决，每一个领域问题，其实都是非常复杂的问题，在 Formily 中，全部一一给您突破解决了，所以您只需要专注于业务逻辑即可。\n\n## 智能提示\n\n因为 formily 是完全的 Typescript 项目，所以用户在 VSCode 或 WebStorm 等上开发可以获得最大化的智能提示体验\n\n![](https://img.alicdn.com/imgextra/i2/O1CN01yiREHk1X95KJPPz1c_!!6000000002880-2-tps-2014-868.png)\n\n## 状态可观测\n\n安装 [FormilyDevtools](https://chrome.google.com/webstore/detail/formily-devtools/kkocalmbfnplecdmbadaapgapdioecfm?hl=zh-CN) 可以实时观测模型状态变化，排查问题\n\n![](//img.alicdn.com/imgextra/i4/O1CN01DSci5h1rAGfRafpXw_!!6000000005590-2-tps-2882-1642.png)\n"
  },
  {
    "path": "packages/core/docs/guide/mvvm.md",
    "content": "# MVVM\n\n## OOP architecture\n\n**MVVM** (**Model–view–viewmodel**) is an OOP software architecture model. Its core is to separate the logic and view of our application to improve code maintainability and application robustness. We can use a picture to describe:\n\n![](//img.alicdn.com/imgextra/i3/O1CN01jiB7h723ZFf0lBCTo_!!6000000007269-55-tps-1244-432.svg)\n\nTo explain, the View (view layer) is responsible for maintaining the UI structure and style, and is responsible for data binding with the ViewModel (view model). The data binding relationship here is two-way, that is, the ViewModel (view model) data occurs. Changes will trigger the update of the View (view layer), and at the same time changes in the data of the view layer will trigger the changes of the ViewModel (view model). Model is more biased towards the actual business data processing model. Both ViewModel and Model are congested models, and both are injected with business logic from different fields. For example, the business logic of ViewModel is more biased towards the domain logic of the view interaction layer, while the business logic of Model is more biased towards the processing logic of business data.\n\nSo, what should the Formily solution be positioned in MVVM?\n\nObviously, Formily provides two tiers of View and ViewModel capabilities. View is @formily/react @formily/vue, which is specifically used to bridge communication with @formily/core. Therefore, @formily/core is positioned at the ViewModel layer. ,\n\nWhere is the Model layer?\n\nOf course it is our actual business code layer, this layer formily will not manage, so at this layer, whether users maintain a Model in OOP mode or maintain a series of business logic function sets in FP mode, formily Don't care.\n\nTherefore, this also makes formily's intrusion into the business very low, because formily's goal is to reduce the cost of users designing ViewModels, allowing users to focus more on the realization of business logic.\n\n## FP architecture\n\nRemember before the React team used the simplest expression **UI = fn(State)** to express the entire React system? Such a functional UI is very simple and clear. Will it conflict with the MVVM model?\n\nThere is no conflict, because in the MVVM mode, the relationship between View and ViewModel is actually approximately equal to **UI = fn(State)**, because ViewModel is a congestion model injected with logic, which is related to **fn(State) ** can achieve the same goal, but it is a more OOP expression, but **fn(State)** is a more functional expression, the state exists as an anemia model, through one function after another, Immutable updates to the anemia model are finally reflected in the UI.\n\nTherefore, from the perspective of separation of logic and data, functional expression is clearer, but functional expression requires all data to be Immutable. Therefore, in scenarios with high performance requirements, the benefits of using a functional model will not be too great, of course, this is only the case in the js language. On the contrary, the MVVM model requires more data for Reactive data, that is, a responsive data model that can manipulate data by reference, so that data changes can be accurately monitored, and finally reflected on the UI.\n\nTherefore, in the form scenario, the performance advantage of the MVVM mode will be better. The most important thing is that most of the GUI products that have survived for decades almost all use MVVM coincidentally. It seems that in the front-end field, the function The type system will be more academic. In terms of the actual benefits to the business, MVVM is still the first choice.\n"
  },
  {
    "path": "packages/core/docs/guide/mvvm.zh-CN.md",
    "content": "# MVVM\n\n## OOP 架构\n\n**MVVM**（**Model–view–viewmodel**）是一种 OOP 软件架构模式，它的核心是将我们的应用程序的逻辑与视图做分离，提升代码可维护性与应用健壮性。我们可以用一张图来描述：\n\n![](//img.alicdn.com/imgextra/i3/O1CN01jiB7h723ZFf0lBCTo_!!6000000007269-55-tps-1244-432.svg)\n\n解释一下就是，View(视图层)负责维护 UI 结构与样式，同时负责与 ViewModel(视图模型)做数据绑定，这里的数据绑定关系是双向的，也就是，ViewModel(视图模型)的数据发生变化，会触发 View(视图层)的更新，同时视图层的数据变化又会触发 ViewModel(视图模型)的变化。Model 则更偏实际业务数据处理模型。ViewModel 和 Model 都是充血模型，两者都注入了不同领域的业务逻辑，比如 ViewModel 的业务逻辑更偏视图交互层的领域逻辑，而 Model 的业务逻辑则更偏业务数据的处理逻辑。\n\n那么，Formily 解决方案在 MVVM 中应该是什么样的定位呢？\n\n很明显，Formily 它提供了 View 和 ViewModel 两层能力，View 则是@formily/react @formily/vue，专门用来与@formily/core 做桥接通讯的，所以，@formily/core 的定位就是 ViewModel 层，\n\n那 Model 层在哪里呢？\n\n当然就是我们的实际业务代码层了，这一层 formily 就不会管了，所以这一层，用户到底是用 OOP 模式维护了一个 Model 还是用 FP 模式维护了一系列的业务逻辑函数集，formily 都不关心。\n\n所以，这也使得 formily 对业务的入侵性很低，因为 formily 的目标是减少用户设计 ViewModel 的成本，让用户更加专注于业务逻辑的实现。\n\n## FP 架构\n\n还记得之前 React 团队用了一个最简单的表达式 **UI = fn(State)** 来表达整个 React 体系吗？这样的函数式表达 UI，非常简单清晰，那会不会和 MVVM 模式产生冲突呢？\n\n并不会冲突，因为在 MVVM 的模式中，View 和 ViewModel 的关系其实就约等于 **UI = fn(State)** ，因为 ViewModel 是一个注入逻辑的充血模型，它与 **fn(State)** 都能达到相同的目标，只是它是更 OOP 的表达，只是**fn(State)** 是一种更加函数式的表达，将状态作为贫血模型而存在，通过一个又一个的函数，对贫血模型做 Immutable 式的更新，最终反应到 UI 上。\n\n所以，从逻辑和数据分离的角度上来看，函数式表达更加清晰，只是函数式表达要求所有数据都是 Immutable 的。所以在性能要求高的场景上，采用函数式模型收益并不会太大，当然只是在 js 语言下是这样的。相反，MVVM 这种模式对数据的要求更多的是 Reactive 数据，也就是可以通过引用式操作数据的响应式数据模型，这样可以做到精确监控数据变化，最终反应到 UI 上。\n\n所以，在表单场景上，MVVM 模式性能优势会更好一些，最重要的是，目前大多数存活了几十年的 GUI 产品，几乎都是不约而同的使用 MVVM，这么看来，在前端领域，函数式体系会更偏学术化一些，从实际对业务的收益来看的话，MVVM 还是首选。\n"
  },
  {
    "path": "packages/core/docs/guide/values.md",
    "content": "# Data Model\n"
  },
  {
    "path": "packages/core/docs/guide/values.zh-CN.md",
    "content": "# 数据模型\n"
  },
  {
    "path": "packages/core/docs/index.md",
    "content": "---\ntitle: Formily-Alibaba unified front-end form solution\norder: 10\nhero:\n  title: Core Library\n  desc: Alibaba Unified Form Solution\n  actions:\n    - text: Home Site\n      link: //formilyjs.org\n    - text: Document\n      link: /guide\nfeatures:\n  - icon: https://img.alicdn.com/imgextra/i1/O1CN01bHdrZJ1rEOESvXEi5_!!6000000005599-55-tps-800-800.svg\n    title: High Performance\n    desc: Efficient update, Demand rendering\n  - icon: https://img.alicdn.com/imgextra/i3/O1CN0194OqFF1ui6mMT4g7O_!!6000000006070-55-tps-800-800.svg\n    title: Excellent Reusability\n    desc: Independent side effects, Pluggable\n  - icon: https://img.alicdn.com/imgextra/i2/O1CN01QnfYS71E44I1ZpxU9_!!6000000000297-55-tps-800-800.svg\n    title: Elegant Linkage Writing\n    desc: Flexible, Complete, Elegant\n  - icon: https://img.alicdn.com/imgextra/i2/O1CN01YqmcpN1tDalwgyHBH_!!6000000005868-55-tps-800-800.svg\n    title: Complete domain model\n    desc: Pure Core, No UI, No Framework\n  - icon: https://img.alicdn.com/imgextra/i4/O1CN018vDmpl2186xdLu6KI_!!6000000006939-55-tps-800-800.svg\n    title: Friendly debugging\n    desc: Natural docking with Formily DevTools\n  - icon: https://img.alicdn.com/imgextra/i4/O1CN01u6jHgs1ZMwXpjAYnh_!!6000000003181-55-tps-800-800.svg\n    title: Smart Tips\n    desc: Embrace Typescript\nfooter: Open-source MIT Licensed | Copyright © 2019-present<br />Powered by self\n---\n\n## Installation\n\n```bash\n$ npm install --save @formily/core\n\n```\n\n## Quick start\n\n> The following case is to teach you step by step to implement a form from scratch\n>\n> @formily/core brings you the following capabilities:\n>\n> 1. Responsive computing capabilities\n> 2. Verification capability, verification internationalization capability\n> 3. Value Management Ability\n> 4. Linkage management capabilities\n> 5. Development tool debugging capabilities, [download Formily Devtools](https://chrome.google.com/webstore/detail/formily-devtools/kkocalmbfnplecdmbadaapgapdioecfm?hl=zh-CN)\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React, { createContext, useMemo, useContext, useEffect } from 'react'\nimport { createForm, setValidateLanguage } from '@formily/core'\nimport { observer } from '@formily/reactive-react'\n\n//Create a context to facilitate Field consumption\nconst FormContext = createContext()\n//Create a context to facilitate the consumption of FormItem\nconst FieldContext = createContext()\n\n//State bridge component\nconst Field = observer((props) => {\n  const form = useContext(FormContext)\n  //Create a field\n  const field = form.createField(props)\n  useEffect(() => {\n    //Mount field\n    field.onMount()\n    return () => {\n      //Unload field\n      field.onUnmount()\n    }\n  })\n  if (!field.visible || field.hidden) return null\n  //Render the field, associate the field state with the UI component\n  const component = React.createElement(field.component[0], {\n    ...field.component[1],\n    value: field.value,\n    onChange: field.onInput,\n  })\n\n  //Render field wrapper\n  const decorator = React.createElement(\n    field.decorator[0],\n    field.decorator[1],\n    component\n  )\n\n  return (\n    <FieldContext.Provider value={field}>{decorator}</FieldContext.Provider>\n  )\n})\n\n// FormItem UI component\nconst FormItem = observer(({ children }) => {\n  const field = useContext(FieldContext)\n  return (\n    <div>\n      <div style={{ height: 20 }}>{field.title}:</div>\n      {children}\n      <div style={{ height: 20, fontSize: 12, color: 'red' }}>\n        {field.selfErrors.join(',')}\n      </div>\n    </div>\n  )\n})\n\n// Input UI component\nconst Input = (props) => {\n  return (\n    <input\n      {...props}\n      value={props.value || ''}\n      style={{\n        ...props.style,\n        border: '2px solid rgb(186 203 255)',\n        borderRadius: 6,\n        width: '100%',\n        height: 28,\n        padding: '0 5px',\n      }}\n    />\n  )\n}\n\n//Form management entrance\nconst FormProvider = (props) => {\n  useEffect(() => {\n    //Mount form\n    props.form?.onMount()\n    return () => {\n      //Uninstall the form\n      props.form?.onUnmount()\n    }\n  })\n  return (\n    <FormContext.Provider value={props.form}>\n      {props.children}\n    </FormContext.Provider>\n  )\n}\n\n//Form response monitor\nconst FormConsumer = observer((props) => {\n  const form = useContext(FormContext)\n  return <div>{props.children(form)}</div>\n})\n\n/*\n * The above logic has been implemented in @formily/react or @formily/vue, and there is no need to rewrite it in actual use\n */\n\n//Switch the built-in check internationalization copy to English\nsetValidateLanguage('en')\n\nexport default () => {\n  const form = useMemo(() => createForm({ validateFirst: true }))\n\n  const createPasswordEqualValidate = (equalName) => (field) => {\n    if (\n      form.values.confirm_password &&\n      field.value &&\n      form.values[equalName] !== field.value\n    ) {\n      field.selfErrors = ['Password does not match Confirm Password.']\n    } else {\n      field.selfErrors = []\n    }\n  }\n\n  return (\n    <FormProvider form={form}>\n      <Field\n        name=\"name\"\n        title=\"Name\"\n        required\n        decorator={[FormItem]}\n        component={[Input, { placeholder: 'Please Input' }]}\n      />\n      <Field\n        name=\"password\"\n        title=\"Password\"\n        required\n        decorator={[FormItem]}\n        component={[Input, { type: 'password', placeholder: 'Please Input' }]}\n        reactions={createPasswordEqualValidate('confirm_password')}\n      />\n      <Field\n        name=\"confirm_password\"\n        title=\"Confirm Password\"\n        required\n        decorator={[FormItem]}\n        component={[Input, { type: 'password', placeholder: 'Please Input' }]}\n        reactions={createPasswordEqualValidate('password')}\n      />\n      <code>\n        <pre>\n          <FormConsumer>\n            {(form) => JSON.stringify(form.values, null, 2)}\n          </FormConsumer>\n        </pre>\n      </code>\n    </FormProvider>\n  )\n}\n```\n"
  },
  {
    "path": "packages/core/docs/index.zh-CN.md",
    "content": "---\ntitle: Formily - 阿里巴巴统一前端表单解决方案\norder: 10\nhero:\n  title: Core Library\n  desc: 阿里巴巴统一前端表单解决方案\n  actions:\n    - text: 主站文档\n      link: //formilyjs.org\n    - text: 内核文档\n      link: /zh-CN/guide\nfeatures:\n  - icon: https://img.alicdn.com/imgextra/i1/O1CN01bHdrZJ1rEOESvXEi5_!!6000000005599-55-tps-800-800.svg\n    title: 超高的性能\n    desc: 依赖追踪，高效更新，按需渲染\n  - icon: https://img.alicdn.com/imgextra/i3/O1CN0194OqFF1ui6mMT4g7O_!!6000000006070-55-tps-800-800.svg\n    title: 极佳的复用性\n    desc: 副作用独立，逻辑可拔插\n  - icon: https://img.alicdn.com/imgextra/i2/O1CN01QnfYS71E44I1ZpxU9_!!6000000000297-55-tps-800-800.svg\n    title: 优雅的联动写法\n    desc: 灵活，完备，优雅\n  - icon: https://img.alicdn.com/imgextra/i2/O1CN01YqmcpN1tDalwgyHBH_!!6000000005868-55-tps-800-800.svg\n    title: 完备的领域模型\n    desc: 跨终端，跨框架，UI无关\n  - icon: https://img.alicdn.com/imgextra/i4/O1CN018vDmpl2186xdLu6KI_!!6000000006939-55-tps-800-800.svg\n    title: 友好的调试体验\n    desc: 天然对接Formily DevTools\n  - icon: https://img.alicdn.com/imgextra/i4/O1CN01u6jHgs1ZMwXpjAYnh_!!6000000003181-55-tps-800-800.svg\n    title: 完美的智能提示\n    desc: 拥抱Typescript\nfooter: Open-source MIT Licensed | Copyright © 2019-present<br />Powered by self\n---\n\n## 安装\n\n```bash\n$ npm install --save @formily/core\n\n```\n\n## 快速开始\n\n> 以下案例是一步步教您从零实现一个表单\n>\n> @formily/core 给您带来了以下几个能力：\n>\n> 1. 响应式计算能力\n> 2. 校验能力、校验国际化能力\n> 3. 值管理能力\n> 4. 联动管理能力\n> 5. 开发工具调试能力，[下载 Formily Devtools](https://chrome.google.com/webstore/detail/formily-devtools/kkocalmbfnplecdmbadaapgapdioecfm?hl=zh-CN)\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React, { createContext, useMemo, useContext, useEffect } from 'react'\nimport { createForm, setValidateLanguage } from '@formily/core'\nimport { observer } from '@formily/reactive-react'\n\n//创建上下文，方便Field消费\nconst FormContext = createContext()\n//创建上下文，方便FormItem消费\nconst FieldContext = createContext()\n\n//状态桥接器组件\nconst Field = observer((props) => {\n  const form = useContext(FormContext)\n  //创建字段\n  const field = form.createField(props)\n  useEffect(() => {\n    //挂载字段\n    field.onMount()\n    return () => {\n      //卸载字段\n      field.onUnmount()\n    }\n  })\n  if (!field.visible || field.hidden) return null\n  //渲染字段，将字段状态与UI组件关联\n  const component = React.createElement(field.component[0], {\n    ...field.component[1],\n    value: field.value,\n    onChange: field.onInput,\n  })\n\n  //渲染字段包装器\n  const decorator = React.createElement(\n    field.decorator[0],\n    field.decorator[1],\n    component\n  )\n\n  return (\n    <FieldContext.Provider value={field}>{decorator}</FieldContext.Provider>\n  )\n})\n\n// FormItem UI组件\nconst FormItem = observer(({ children }) => {\n  const field = useContext(FieldContext)\n  return (\n    <div>\n      <div style={{ height: 20 }}>{field.title}:</div>\n      {children}\n      <div style={{ height: 20, fontSize: 12, color: 'red' }}>\n        {field.selfErrors.join(',')}\n      </div>\n    </div>\n  )\n})\n\n// Input UI组件\nconst Input = (props) => {\n  return (\n    <input\n      {...props}\n      value={props.value || ''}\n      style={{\n        ...props.style,\n        border: '2px solid rgb(186 203 255)',\n        borderRadius: 6,\n        width: '100%',\n        height: 28,\n        padding: '0 5px',\n      }}\n    />\n  )\n}\n\n//表单管理入口\nconst FormProvider = (props) => {\n  useEffect(() => {\n    //挂载表单\n    props.form?.onMount()\n    return () => {\n      //卸载表单\n      props.form?.onUnmount()\n    }\n  })\n  return (\n    <FormContext.Provider value={props.form}>\n      {props.children}\n    </FormContext.Provider>\n  )\n}\n\n//表单响应式监控器\nconst FormConsumer = observer((props) => {\n  const form = useContext(FormContext)\n  return <div>{props.children(form)}</div>\n})\n\n/*\n * 以上逻辑都已经在 @formily/react 或 @formily/vue 中实现，实际使用无需重复编写\n */\n\n//切换内置校验国际化文案为英文\nsetValidateLanguage('en')\n\nexport default () => {\n  const form = useMemo(() => createForm({ validateFirst: true }))\n\n  const createPasswordEqualValidate = (equalName) => (field) => {\n    if (\n      form.values.confirm_password &&\n      field.value &&\n      form.values[equalName] !== field.value\n    ) {\n      field.selfErrors = ['Password does not match Confirm Password.']\n    } else {\n      field.selfErrors = []\n    }\n  }\n\n  return (\n    <FormProvider form={form}>\n      <Field\n        name=\"name\"\n        title=\"Name\"\n        required\n        decorator={[FormItem]}\n        component={[Input, { placeholder: 'Please Input' }]}\n      />\n      <Field\n        name=\"password\"\n        title=\"Password\"\n        required\n        decorator={[FormItem]}\n        component={[Input, { type: 'password', placeholder: 'Please Input' }]}\n        reactions={createPasswordEqualValidate('confirm_password')}\n      />\n      <Field\n        name=\"confirm_password\"\n        title=\"Confirm Password\"\n        required\n        decorator={[FormItem]}\n        component={[Input, { type: 'password', placeholder: 'Please Input' }]}\n        reactions={createPasswordEqualValidate('password')}\n      />\n      <code>\n        <pre>\n          <FormConsumer>\n            {(form) => JSON.stringify(form.values, null, 2)}\n          </FormConsumer>\n        </pre>\n      </code>\n    </FormProvider>\n  )\n}\n```\n"
  },
  {
    "path": "packages/core/package.json",
    "content": "{\n  \"name\": \"@formily/core\",\n  \"version\": \"2.3.7\",\n  \"license\": \"MIT\",\n  \"main\": \"lib\",\n  \"module\": \"esm\",\n  \"umd:main\": \"dist/formily.core.umd.production.js\",\n  \"unpkg\": \"dist/formily.core.umd.production.js\",\n  \"jsdelivr\": \"dist/formily.core.umd.production.js\",\n  \"jsnext:main\": \"esm\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/alibaba/formily.git\"\n  },\n  \"types\": \"esm/index.d.ts\",\n  \"bugs\": {\n    \"url\": \"https://github.com/alibaba/formily/issues\"\n  },\n  \"homepage\": \"https://github.com/alibaba/formily#readme\",\n  \"engines\": {\n    \"npm\": \">=3.0.0\"\n  },\n  \"scripts\": {\n    \"start\": \"dumi dev\",\n    \"build\": \"rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm && npm run build:umd\",\n    \"build:cjs\": \"tsc --project tsconfig.build.json\",\n    \"build:esm\": \"tsc --project tsconfig.build.json --module es2015 --outDir esm\",\n    \"build:umd\": \"rollup --config\",\n    \"build:docs\": \"dumi build\"\n  },\n  \"devDependencies\": {\n    \"dumi\": \"^1.1.0-rc.8\"\n  },\n  \"dependencies\": {\n    \"@formily/reactive\": \"2.3.7\",\n    \"@formily/shared\": \"2.3.7\",\n    \"@formily/validator\": \"2.3.7\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"gitHead\": \"ac79c196ae9324889aca5e0501146f9b37b04283\"\n}\n"
  },
  {
    "path": "packages/core/rollup.config.js",
    "content": "import baseConfig from '../../scripts/rollup.base.js'\n\nexport default baseConfig('formily.core', 'Formily.Core')\n"
  },
  {
    "path": "packages/core/src/__tests__/array.spec.ts",
    "content": "import { createForm } from '../'\nimport {\n  onFieldValueChange,\n  onFormInitialValuesChange,\n  onFormValuesChange,\n} from '../effects'\nimport { DataField } from '../types'\nimport { attach } from './shared'\n\ntest('create array field', () => {\n  const form = attach(createForm())\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  expect(array.value).toEqual([])\n  expect(array.push).toBeDefined()\n  expect(array.pop).toBeDefined()\n  expect(array.shift).toBeDefined()\n  expect(array.unshift).toBeDefined()\n  expect(array.move).toBeDefined()\n  expect(array.moveDown).toBeDefined()\n  expect(array.moveUp).toBeDefined()\n  expect(array.insert).toBeDefined()\n  expect(array.remove).toBeDefined()\n})\n\ntest('array field methods', () => {\n  const form = attach(createForm())\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n      value: [],\n    })\n  )\n  array.push({ aa: 11 }, { bb: 22 })\n  expect(array.value).toEqual([{ aa: 11 }, { bb: 22 }])\n  array.pop()\n  expect(array.value).toEqual([{ aa: 11 }])\n  array.unshift({ cc: 33 })\n  expect(array.value).toEqual([{ cc: 33 }, { aa: 11 }])\n  array.remove(1)\n  expect(array.value).toEqual([{ cc: 33 }])\n  array.insert(1, { dd: 44 }, { ee: 55 })\n  expect(array.value).toEqual([{ cc: 33 }, { dd: 44 }, { ee: 55 }])\n  array.move(0, 2)\n  expect(array.value).toEqual([{ dd: 44 }, { ee: 55 }, { cc: 33 }])\n  array.shift()\n  expect(array.value).toEqual([{ ee: 55 }, { cc: 33 }])\n  array.moveDown(0)\n  expect(array.value).toEqual([{ cc: 33 }, { ee: 55 }])\n  array.moveUp(1)\n  expect(array.value).toEqual([{ ee: 55 }, { cc: 33 }])\n  array.move(1, 0)\n  expect(array.value).toEqual([{ cc: 33 }, { ee: 55 }])\n})\n\ntest('array field children state exchanges', () => {\n  //注意：插入新节点，如果指定位置有节点，会丢弃，需要重新插入节点，主要是为了防止上一个节点状态对新节点状态产生污染\n  const form = attach(createForm())\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'other',\n      basePath: 'array',\n    })\n  )\n  array.push({ value: 11 }, { value: 22 })\n  attach(\n    form.createField({\n      name: 'value',\n      basePath: 'array.0',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'value',\n      basePath: 'array.1',\n    })\n  )\n  expect(array.value).toEqual([{ value: 11 }, { value: 22 }])\n  expect(form.query('array.0.value').get('value')).toEqual(11)\n  expect(form.query('array.1.value').get('value')).toEqual(22)\n  expect(Object.keys(form.fields).sort()).toEqual([\n    'array',\n    'array.0.value',\n    'array.1.value',\n    'array.other',\n  ])\n  array.pop()\n  expect(array.value).toEqual([{ value: 11 }])\n  expect(form.query('array.0.value').get('value')).toEqual(11)\n  expect(form.query('array.1.value').get('value')).toBeUndefined()\n  array.unshift({ value: 33 })\n  attach(\n    form.createField({\n      name: 'value',\n      basePath: 'array.0',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'value',\n      basePath: 'array.1',\n    })\n  )\n  expect(array.value).toEqual([{ value: 33 }, { value: 11 }])\n  expect(form.query('array.0.value').get('value')).toEqual(33)\n  expect(form.query('array.1.value').get('value')).toEqual(11)\n  array.remove(1)\n  expect(array.value).toEqual([{ value: 33 }])\n  expect(form.query('array.0.value').get('value')).toEqual(33)\n  expect(form.query('array.1.value').get('value')).toBeUndefined()\n  array.insert(1, { value: 44 }, { value: 55 })\n  attach(\n    form.createField({\n      name: 'value',\n      basePath: 'array.1',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'value',\n      basePath: 'array.2',\n    })\n  )\n  expect(array.value).toEqual([{ value: 33 }, { value: 44 }, { value: 55 }])\n  expect(form.query('array.0.value').get('value')).toEqual(33)\n  expect(form.query('array.1.value').get('value')).toEqual(44)\n  expect(form.query('array.2.value').get('value')).toEqual(55)\n  array.move(0, 2)\n  expect(array.value).toEqual([{ value: 44 }, { value: 55 }, { value: 33 }])\n  expect(form.query('array.0.value').get('value')).toEqual(44)\n  expect(form.query('array.1.value').get('value')).toEqual(55)\n  expect(form.query('array.2.value').get('value')).toEqual(33)\n  array.move(2, 0)\n  expect(array.value).toEqual([{ value: 33 }, { value: 44 }, { value: 55 }])\n  expect(form.query('array.0.value').get('value')).toEqual(33)\n  expect(form.query('array.1.value').get('value')).toEqual(44)\n  expect(form.query('array.2.value').get('value')).toEqual(55)\n})\n\ntest('array field move up/down then fields move', () => {\n  const form = attach(createForm())\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'value',\n      basePath: 'array.0',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'value',\n      basePath: 'array.1',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'value',\n      basePath: 'array.2',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'value',\n      basePath: 'array.3',\n    })\n  )\n  const line0 = form.fields['array.0.value']\n  const line1 = form.fields['array.1.value']\n  const line2 = form.fields['array.2.value']\n  const line3 = form.fields['array.3.value']\n\n  array.push({ value: '0' }, { value: '1' }, { value: '2' }, { value: '3' })\n\n  array.move(0, 3)\n\n  // 1,2,3,0\n  expect(form.fields['array.0.value']).toBe(line1)\n  expect(form.fields['array.1.value']).toBe(line2)\n  expect(form.fields['array.2.value']).toBe(line3)\n  expect(form.fields['array.3.value']).toBe(line0)\n\n  array.move(3, 1)\n\n  // 1,0,2,3\n  expect(form.fields['array.0.value']).toBe(line1)\n  expect(form.fields['array.1.value']).toBe(line0)\n  expect(form.fields['array.2.value']).toBe(line2)\n  expect(form.fields['array.3.value']).toBe(line3)\n})\n\n// 重现 issues #3932 , 补全 PR #3992 测试用例\ntest('lazy array field query each', () => {\n  const form = attach(createForm())\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n\n  const init = Array.from({ length: 6 }).map((_, i) => ({ value: i }))\n  array.setValue(init)\n\n  // page1: 0, 1\n  // page2: 2, 3 untouch\n  // page3: 4, 5\n  init.forEach((item) => {\n    const len = item.value\n    //2, 3\n    if (len >= 2 && len <= 3) {\n    } else {\n      // 0, 1, 4, 5\n      attach(\n        form.createField({\n          name: 'value',\n          basePath: 'array.' + len,\n        })\n      )\n    }\n  })\n\n  array.insert(1, { value: '11' })\n  expect(() => form.query('*').take()).not.toThrowError()\n  expect(Object.keys(form.fields)).toEqual([\n    'array',\n    'array.0.value',\n    'array.5.value',\n    'array.2.value',\n    'array.6.value',\n  ])\n})\n\ntest('void children', () => {\n  const form = attach(createForm())\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'other',\n      basePath: 'array',\n    })\n  )\n  attach(\n    form.createVoidField({\n      name: 0,\n      basePath: 'array',\n    })\n  )\n  const aaa = attach(\n    form.createField({\n      name: 'aaa',\n      basePath: 'array.0',\n      value: 123,\n    })\n  )\n  expect(aaa.value).toEqual(123)\n  expect(array.value).toEqual([123])\n})\n\ntest('exchange children', () => {\n  const form = attach(createForm())\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'other',\n      basePath: 'array',\n    })\n  )\n  attach(\n    form.createField({\n      name: '0.aaa',\n      basePath: 'array',\n      value: '123',\n    })\n  )\n  attach(\n    form.createField({\n      name: '0.bbb',\n      basePath: 'array',\n      value: '321',\n    })\n  )\n  attach(\n    form.createField({\n      name: '1.bbb',\n      basePath: 'array',\n      value: 'kkk',\n    })\n  )\n  expect(array.value).toEqual([{ aaa: '123', bbb: '321' }, { bbb: 'kkk' }])\n  array.move(0, 1)\n  expect(array.value).toEqual([{ bbb: 'kkk' }, { aaa: '123', bbb: '321' }])\n  expect(form.query('array.0.aaa').take()).toBeUndefined()\n})\n\ntest('fault tolerance', () => {\n  const form = attach(createForm())\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  const array2 = attach(\n    form.createArrayField({\n      name: 'array2',\n      value: [1, 2],\n    })\n  )\n  array.setValue({} as any)\n  array.push(11)\n  expect(array.value).toEqual([11])\n  array.pop()\n  expect(array.value).toEqual([])\n  array.remove(1)\n  expect(array.value).toEqual([])\n  array.shift()\n  expect(array.value).toEqual([])\n  array.unshift(1)\n  expect(array.value).toEqual([1])\n  array.move(0, 1)\n  expect(array.value).toEqual([1])\n  array.moveUp(1)\n  expect(array.value).toEqual([1])\n  array.moveDown(1)\n  expect(array.value).toEqual([1])\n  array.insert(1)\n  expect(array.value).toEqual([1])\n  array2.move(1, 1)\n  expect(array2.value).toEqual([1, 2])\n  array2.push(3)\n  array2.moveUp(2)\n  expect(array2.value).toEqual([1, 3, 2])\n  array2.moveUp(0)\n  expect(array2.value).toEqual([3, 2, 1])\n  array2.moveDown(0)\n  expect(array2.value).toEqual([2, 3, 1])\n  array2.moveDown(1)\n  expect(array2.value).toEqual([2, 1, 3])\n  array2.moveDown(2)\n  expect(array2.value).toEqual([3, 2, 1])\n})\n\ntest('mutation fault tolerance', () => {\n  const form = attach(createForm())\n  const pushArray = attach(\n    form.createArrayField({\n      name: 'array1',\n    })\n  )\n  const popArray = attach(\n    form.createArrayField({\n      name: 'array2',\n    })\n  )\n  const insertArray = attach(\n    form.createArrayField({\n      name: 'array3',\n    })\n  )\n  const removeArray = attach(\n    form.createArrayField({\n      name: 'array4',\n    })\n  )\n  const shiftArray = attach(\n    form.createArrayField({\n      name: 'array5',\n    })\n  )\n  const unshiftArray = attach(\n    form.createArrayField({\n      name: 'array6',\n    })\n  )\n  const moveArray = attach(\n    form.createArrayField({\n      name: 'array7',\n    })\n  )\n  const moveUpArray = attach(\n    form.createArrayField({\n      name: 'array8',\n    })\n  )\n  const moveDownArray = attach(\n    form.createArrayField({\n      name: 'array9',\n    })\n  )\n  pushArray.setValue({} as any)\n  pushArray.push(123)\n  expect(pushArray.value).toEqual([123])\n  popArray.setValue({} as any)\n  popArray.pop()\n  expect(popArray.value).toEqual({})\n  insertArray.setValue({} as any)\n  insertArray.insert(0, 123)\n  expect(insertArray.value).toEqual([123])\n  removeArray.setValue({} as any)\n  removeArray.remove(0)\n  expect(removeArray.value).toEqual({})\n  shiftArray.setValue({} as any)\n  shiftArray.shift()\n  expect(shiftArray.value).toEqual({})\n  unshiftArray.setValue({} as any)\n  unshiftArray.unshift(123)\n  expect(unshiftArray.value).toEqual([123])\n  moveArray.setValue({} as any)\n  moveArray.move(0, 1)\n  expect(moveArray.value).toEqual({})\n  moveUpArray.setValue({} as any)\n  moveUpArray.moveUp(0)\n  expect(moveUpArray.value).toEqual({})\n  moveDownArray.setValue({} as any)\n  moveDownArray.moveDown(1)\n  expect(moveDownArray.value).toEqual({})\n})\n\ntest('array field move api with children', async () => {\n  const form = attach(createForm())\n  attach(\n    form.createField({\n      name: 'other',\n    })\n  )\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  attach(\n    form.createArrayField({\n      name: '0',\n      basePath: 'array',\n    })\n  )\n  attach(\n    form.createArrayField({\n      name: '1',\n      basePath: 'array',\n    })\n  )\n  attach(\n    form.createArrayField({\n      name: '2',\n      basePath: 'array',\n    })\n  )\n  attach(\n    form.createArrayField({\n      name: 'name',\n      basePath: 'array.2',\n    })\n  )\n  await array.move(0, 2)\n  expect(form.fields['array.0.name']).toBeUndefined()\n  expect(form.fields['array.2.name']).toBeUndefined()\n  expect(form.fields['array.1.name']).not.toBeUndefined()\n})\n\ntest('array field remove memo leak', async () => {\n  const handler = jest.fn()\n  const valuesChange = jest.fn()\n  const initialValuesChange = jest.fn()\n  const form = attach(\n    createForm({\n      effects() {\n        onFormValuesChange(valuesChange)\n        onFormInitialValuesChange(initialValuesChange)\n        onFieldValueChange('*', handler)\n      },\n    })\n  )\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  await array.push('')\n  attach(\n    form.createField({\n      name: '0',\n      basePath: 'array',\n    })\n  )\n  await array.remove(0)\n  await array.push('')\n  attach(\n    form.createField({\n      name: '0',\n      basePath: 'array',\n    })\n  )\n  expect(handler).toBeCalledTimes(0)\n  expect(valuesChange).toBeCalledTimes(4)\n  expect(initialValuesChange).toBeCalledTimes(0)\n})\n\ntest('nest array remove', async () => {\n  const form = attach(createForm())\n\n  const metrics = attach(\n    form.createArrayField({\n      name: 'metrics',\n    })\n  )\n\n  attach(\n    form.createObjectField({\n      name: '0',\n      basePath: 'metrics',\n    })\n  )\n\n  attach(\n    form.createObjectField({\n      name: '1',\n      basePath: 'metrics',\n    })\n  )\n\n  attach(\n    form.createArrayField({\n      name: 'content',\n      basePath: 'metrics.0',\n    })\n  )\n\n  attach(\n    form.createArrayField({\n      name: 'content',\n      basePath: 'metrics.1',\n    })\n  )\n\n  const obj00 = attach(\n    form.createObjectField({\n      name: '0',\n      basePath: 'metrics.0.content',\n    })\n  )\n\n  const obj10 = attach(\n    form.createObjectField({\n      name: '0',\n      basePath: 'metrics.1.content',\n    })\n  )\n\n  attach(\n    form.createField({\n      name: 'attr',\n      basePath: 'metrics.0.content.0',\n      initialValue: '123',\n    })\n  )\n\n  attach(\n    form.createField({\n      name: 'attr',\n      basePath: 'metrics.1.content.0',\n      initialValue: '123',\n    })\n  )\n  expect(obj00.indexes[0]).toBe(0)\n  expect(obj00.index).toBe(0)\n  expect(obj10.index).toBe(0)\n  expect(obj10.indexes[0]).toBe(1)\n  await (form.query('metrics.1.content').take() as any).remove(0)\n  expect(form.fields['metrics.0.content.0.attr']).not.toBeUndefined()\n  await metrics.remove(1)\n  expect(form.fields['metrics.0.content.0.attr']).not.toBeUndefined()\n  expect(\n    form.initialValues.metrics?.[1]?.content?.[0]?.attr\n  ).not.toBeUndefined()\n})\n\ntest('indexes: nest path need exclude incomplete number', () => {\n  const form = attach(createForm())\n\n  const objPathIncludeNum = attach(\n    form.createField({\n      name: 'attr',\n      basePath: 'metrics.0.a.10.iconWidth50',\n    })\n  )\n\n  expect(objPathIncludeNum.indexes.length).toBe(2)\n  expect(objPathIncludeNum.indexes).toEqual([0, 10])\n  expect(objPathIncludeNum.index).toBe(10)\n})\n\ntest('incomplete insertion of array elements', async () => {\n  const form = attach(\n    createForm({\n      values: {\n        array: [{ aa: 1 }, { aa: 2 }, { aa: 3 }],\n      },\n    })\n  )\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  attach(\n    form.createObjectField({\n      name: '0',\n      basePath: 'array',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'aa',\n      basePath: 'array.0',\n    })\n  )\n  attach(\n    form.createObjectField({\n      name: '2',\n      basePath: 'array',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'aa',\n      basePath: 'array.2',\n    })\n  )\n  expect(form.fields['array.0.aa']).not.toBeUndefined()\n  expect(form.fields['array.1.aa']).toBeUndefined()\n  expect(form.fields['array.2.aa']).not.toBeUndefined()\n  await array.unshift({})\n  expect(form.fields['array.0.aa']).toBeUndefined()\n  expect(form.fields['array.1.aa']).not.toBeUndefined()\n  expect(form.fields['array.2.aa']).toBeUndefined()\n  expect(form.fields['array.3.aa']).not.toBeUndefined()\n})\n\ntest('void array items need skip data', () => {\n  const form = attach(createForm())\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  const array2 = attach(\n    form.createArrayField({\n      name: 'array2',\n    })\n  )\n  attach(\n    form.createVoidField({\n      name: '0',\n      basePath: 'array',\n    })\n  )\n  attach(\n    form.createVoidField({\n      name: '0',\n      basePath: 'array2',\n    })\n  )\n  attach(\n    form.createVoidField({\n      name: 'space',\n      basePath: 'array.0',\n    })\n  )\n  const select = attach(\n    form.createField({\n      name: 'select',\n      basePath: 'array.0.space',\n    })\n  )\n  const select2 = attach(\n    form.createField({\n      name: 'select2',\n      basePath: 'array2.0',\n    })\n  )\n\n  select.value = 123\n  select2.value = 123\n  expect(array.value).toEqual([123])\n  expect(array2.value).toEqual([123])\n})\n\ntest('array field reset', () => {\n  const form = attach(createForm())\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  attach(\n    form.createObjectField({\n      name: '0',\n      basePath: 'array',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'input',\n      initialValue: '123',\n      basePath: 'array.0',\n    })\n  )\n  form.reset('*', { forceClear: true })\n  expect(form.values).toEqual({ array: [] })\n  expect(array.value).toEqual([])\n})\n\ntest('array field remove can not memory leak', async () => {\n  const handler = jest.fn()\n  const form = attach(\n    createForm({\n      values: {\n        array: [{ aa: 1 }, { aa: 2 }],\n      },\n      effects() {\n        onFieldValueChange('array.*.aa', handler)\n      },\n    })\n  )\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  attach(\n    form.createObjectField({\n      name: '0',\n      basePath: 'array',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'aa',\n      basePath: 'array.0',\n    })\n  )\n  attach(\n    form.createObjectField({\n      name: '1',\n      basePath: 'array',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'aa',\n      basePath: 'array.1',\n    })\n  )\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n      basePath: 'array.1',\n      reactions: (field) => {\n        field.visible = field.query('.aa').value() === '123'\n      },\n    })\n  )\n  expect(bb.visible).toBeFalsy()\n  await array.remove(0)\n  form.query('array.0.aa').take((field) => {\n    ;(field as DataField).value = '123'\n  })\n  expect(bb.visible).toBeTruthy()\n  expect(handler).toBeCalledTimes(1)\n})\n\ntest('array field patch values', async () => {\n  const form = attach(createForm())\n\n  const arr = attach(\n    form.createArrayField({\n      name: 'a',\n    })\n  )\n\n  await arr.unshift({})\n  attach(\n    form.createObjectField({\n      name: '0',\n      basePath: 'a',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'c',\n      initialValue: 'A',\n      basePath: 'a.0',\n    })\n  )\n  expect(form.values).toEqual({ a: [{ c: 'A' }] })\n  await arr.unshift({})\n  attach(\n    form.createObjectField({\n      name: '0',\n      basePath: 'a',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'c',\n      initialValue: 'A',\n      basePath: 'a.0',\n    })\n  )\n  attach(\n    form.createObjectField({\n      name: '1',\n      basePath: 'a',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'c',\n      initialValue: 'A',\n      basePath: 'a.1',\n    })\n  )\n  expect(form.values).toEqual({ a: [{ c: 'A' }, { c: 'A' }] })\n})\n\ntest('array remove with initialValues', async () => {\n  const form = attach(\n    createForm({\n      initialValues: {\n        array: [{ a: 1 }, { a: 2 }],\n      },\n    })\n  )\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  attach(\n    form.createObjectField({\n      name: '0',\n      basePath: 'array',\n    })\n  )\n  attach(\n    form.createObjectField({\n      name: '1',\n      basePath: 'array',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'a',\n      basePath: 'array.0',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'a',\n      basePath: 'array.1',\n    })\n  )\n  expect(form.values).toEqual({ array: [{ a: 1 }, { a: 2 }] })\n  await array.remove(1)\n  expect(form.values).toEqual({ array: [{ a: 1 }] })\n  expect(form.initialValues).toEqual({ array: [{ a: 1 }, { a: 2 }] })\n  await array.reset()\n  attach(\n    form.createObjectField({\n      name: '1',\n      basePath: 'array',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'a',\n      basePath: 'array.0',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'a',\n      basePath: 'array.1',\n    })\n  )\n  expect(form.values).toEqual({ array: [{ a: 1 }, { a: 2 }] })\n  expect(form.initialValues).toEqual({ array: [{ a: 1 }, { a: 2 }] })\n})\n\ntest('records: find array fields', () => {\n  const form = attach(\n    createForm({\n      initialValues: {\n        array: [{ a: 1 }, { a: 2 }],\n      },\n    })\n  )\n\n  attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n\n  attach(\n    form.createObjectField({\n      name: '0',\n      basePath: 'array',\n    })\n  )\n  attach(\n    form.createObjectField({\n      name: '1',\n      basePath: 'array',\n    })\n  )\n  const field0 = attach(\n    form.createField({\n      name: 'a',\n      basePath: 'array.0',\n    })\n  )\n  const field1 = attach(\n    form.createField({\n      name: 'a',\n      basePath: 'array.1',\n    })\n  )\n\n  expect(field0.records.length).toBe(2)\n  expect(field0.record).toEqual({ a: 1 })\n  expect(field1.record).toEqual({ a: 2 })\n})\n\ntest('record: find array nest field record', () => {\n  const form = attach(\n    createForm({\n      initialValues: {\n        array: [{ a: { b: { c: 1, d: 1 } } }, { a: { b: { c: 2, d: 2 } } }],\n      },\n    })\n  )\n\n  attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n\n  attach(\n    form.createObjectField({\n      name: '0',\n      basePath: 'array',\n    })\n  )\n  attach(\n    form.createObjectField({\n      name: '1',\n      basePath: 'array',\n    })\n  )\n\n  attach(\n    form.createObjectField({\n      name: 'a',\n      basePath: 'array.0',\n    })\n  )\n  attach(\n    form.createObjectField({\n      name: 'a',\n      basePath: 'array.1',\n    })\n  )\n\n  attach(\n    form.createObjectField({\n      name: 'b',\n      basePath: 'array.0.a',\n    })\n  )\n\n  attach(\n    form.createObjectField({\n      name: 'b',\n      basePath: 'array.1.a',\n    })\n  )\n\n  const field0 = attach(\n    form.createField({\n      name: 'c',\n      basePath: 'array.0.a.b',\n    })\n  )\n\n  const field1 = attach(\n    form.createField({\n      name: 'c',\n      basePath: 'array.1.a.b',\n    })\n  )\n\n  const field2 = attach(\n    form.createField({\n      name: 'cc',\n      basePath: 'array.1.a.b.c',\n    })\n  )\n\n  expect(field0.records.length).toBe(2)\n  expect(field1.records.length).toBe(2)\n  expect(field1.records).toEqual([\n    { a: { b: { c: 1, d: 1 } } },\n    { a: { b: { c: 2, d: 2 } } },\n  ])\n  expect(field0.record).toEqual({ c: 1, d: 1 })\n  expect(field1.record).toEqual({ c: 2, d: 2 })\n  expect(field2.record).toEqual({ c: 2, d: 2 })\n})\n\ntest('record: find array field record', () => {\n  const form = attach(\n    createForm({\n      initialValues: {\n        array: [1, 2, 3],\n      },\n    })\n  )\n\n  attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n\n  const field = attach(\n    form.createField({\n      basePath: 'array',\n      name: '0',\n    })\n  )\n\n  expect(field.records.length).toBe(3)\n  expect(field.record).toEqual(1)\n})\n\ntest('record: find object field record', () => {\n  const form = attach(\n    createForm({\n      initialValues: {\n        a: {\n          b: {\n            c: 1,\n            d: 1,\n          },\n        },\n      },\n    })\n  )\n\n  attach(\n    form.createArrayField({\n      name: 'a',\n    })\n  )\n\n  attach(\n    form.createObjectField({\n      name: 'b',\n      basePath: 'a',\n    })\n  )\n\n  const fieldc = attach(\n    form.createObjectField({\n      name: 'c',\n      basePath: 'a.b',\n    })\n  )\n\n  expect(fieldc.records).toEqual(undefined)\n  expect(fieldc.record).toEqual({\n    c: 1,\n    d: 1,\n  })\n})\n\ntest('record: find form fields', () => {\n  const form = attach(\n    createForm({\n      initialValues: {\n        array: [{ a: 1 }, { a: 2 }],\n      },\n    })\n  )\n\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n\n  expect(array.record).toEqual({ array: [{ a: 1 }, { a: 2 }] })\n})\n"
  },
  {
    "path": "packages/core/src/__tests__/effects.spec.ts",
    "content": "import {\n  createForm,\n  createEffectContext,\n  onFieldChange,\n  onFieldInit,\n  onFieldInitialValueChange,\n  onFieldInputValueChange,\n  onFieldMount,\n  onFieldReact,\n  onFieldUnmount,\n  onFieldValidateEnd,\n  onFieldValidateStart,\n  onFieldValidateFailed,\n  onFieldValidateSuccess,\n  onFieldValueChange,\n  onFormInit,\n  onFormInitialValuesChange,\n  onFormInputChange,\n  onFormMount,\n  onFormReact,\n  onFormReset,\n  onFormSubmit,\n  onFormSubmitEnd,\n  onFormSubmitFailed,\n  onFormSubmitStart,\n  onFormSubmitSuccess,\n  onFormSubmitValidateFailed,\n  onFormSubmitValidateStart,\n  onFormSubmitValidateSuccess,\n  onFormSubmitValidateEnd,\n  onFormUnmount,\n  onFormValidateEnd,\n  onFormValidateStart,\n  onFormValidateFailed,\n  onFormValidateSuccess,\n  onFormValuesChange,\n  isVoidField,\n} from '../'\nimport { runEffects } from '../shared/effective'\nimport { attach, sleep } from './shared'\n\ntest('onFormInit/onFormMount/onFormUnmount', () => {\n  const mount = jest.fn()\n  const init = jest.fn()\n  const unmount = jest.fn()\n  const form = attach(\n    createForm({\n      effects() {\n        onFormInit(init)\n        onFormMount(mount)\n        onFormUnmount(unmount)\n      },\n    })\n  )\n  expect(init).toBeCalled()\n  expect(mount).toBeCalled()\n  expect(unmount).not.toBeCalled()\n  form.onUnmount()\n  expect(unmount).toBeCalled()\n})\n\ntest('onFormValuesChange/onFormInitialValuesChange', () => {\n  const valuesChange = jest.fn()\n  const initialValuesChange = jest.fn()\n  const form = attach(\n    createForm({\n      effects() {\n        onFormValuesChange(valuesChange)\n        onFormInitialValuesChange(initialValuesChange)\n      },\n    })\n  )\n  expect(valuesChange).not.toBeCalled()\n  expect(initialValuesChange).not.toBeCalled()\n  form.setValues({\n    aa: '123',\n  })\n  expect(form.values.aa).toEqual('123')\n  expect(valuesChange).toBeCalled()\n  form.setInitialValues({\n    aa: '321',\n    bb: '123',\n  })\n  expect(form.values.aa).toEqual('321')\n  expect(form.values.bb).toEqual('123')\n  expect(initialValuesChange).toBeCalled()\n})\n\ntest('onFormInputChange', () => {\n  const inputChange = jest.fn()\n  const valuesChange = jest.fn()\n  const form = attach(\n    createForm({\n      effects() {\n        onFormValuesChange(valuesChange)\n        onFormInputChange(inputChange)\n      },\n    })\n  )\n  const field = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  expect(inputChange).not.toBeCalled()\n  expect(valuesChange).not.toBeCalled()\n  field.setValue('123')\n  expect(inputChange).not.toBeCalled()\n  expect(valuesChange).toBeCalledTimes(1)\n  field.onInput('123')\n  expect(inputChange).toBeCalled()\n  expect(valuesChange).toBeCalledTimes(1)\n  field.onInput('321')\n  expect(inputChange).toBeCalledTimes(2)\n  expect(valuesChange).toBeCalledTimes(2)\n})\n\ntest('onFormReact', () => {\n  const react = jest.fn()\n  const form = attach(\n    createForm({\n      effects() {\n        onFormReact((form) => {\n          if (form.values.aa) {\n            react()\n          }\n        })\n      },\n    })\n  )\n  expect(react).not.toBeCalled()\n  form.setValues({ aa: 123 })\n  expect(react).toBeCalled()\n  form.onUnmount()\n\n  // will not throw error\n  const form2 = attach(\n    createForm({\n      effects() {\n        onFormReact()\n      },\n    })\n  )\n\n  form2.onUnmount()\n})\n\ntest('onFormReset', async () => {\n  const reset = jest.fn()\n  const form = attach(\n    createForm({\n      initialValues: {\n        aa: 123,\n      },\n      effects() {\n        onFormReset(reset)\n      },\n    })\n  )\n\n  const field = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n\n  field.setValue('xxxx')\n\n  expect(field.value).toEqual('xxxx')\n  expect(form.values.aa).toEqual('xxxx')\n  expect(reset).not.toBeCalled()\n  await form.reset()\n  expect(field.value).toEqual(123)\n  expect(form.values.aa).toEqual(123)\n  expect(reset).toBeCalled()\n})\n\ntest('onFormSubmit', async () => {\n  const submit = jest.fn()\n  const submitStart = jest.fn()\n  const submitEnd = jest.fn()\n  const submitSuccess = jest.fn()\n  const submitFailed = jest.fn()\n  const submitValidateStart = jest.fn()\n  const submitValidateFailed = jest.fn()\n  const submitValidateSuccess = jest.fn()\n  const submitValidateEnd = jest.fn()\n  const form = attach(\n    createForm({\n      effects() {\n        onFormSubmitStart(submitStart)\n        onFormSubmit(submit)\n        onFormSubmitEnd(submitEnd)\n        onFormSubmitFailed(submitFailed)\n        onFormSubmitSuccess(submitSuccess)\n        onFormSubmitValidateStart(submitValidateStart)\n        onFormSubmitValidateFailed(submitValidateFailed)\n        onFormSubmitValidateSuccess(submitValidateSuccess)\n        onFormSubmitValidateEnd(submitValidateEnd)\n      },\n    })\n  )\n\n  const field = attach(\n    form.createField({\n      name: 'aa',\n      required: true,\n    })\n  )\n  try {\n    await form.submit()\n  } catch {}\n  expect(submitStart).toBeCalled()\n  expect(submit).toBeCalled()\n  expect(submitEnd).toBeCalled()\n  expect(submitSuccess).not.toBeCalled()\n  expect(submitFailed).toBeCalled()\n  expect(submitValidateStart).toBeCalled()\n  expect(submitValidateFailed).toBeCalled()\n  expect(submitValidateSuccess).not.toBeCalled()\n  expect(submitValidateEnd).toBeCalled()\n  field.onInput('123')\n  try {\n    await form.submit()\n  } catch (e) {}\n  expect(submitStart).toBeCalledTimes(2)\n  expect(submit).toBeCalledTimes(2)\n  expect(submitEnd).toBeCalledTimes(2)\n  expect(submitSuccess).toBeCalledTimes(1)\n  expect(submitFailed).toBeCalledTimes(1)\n  expect(submitValidateStart).toBeCalledTimes(2)\n  expect(submitValidateFailed).toBeCalledTimes(1)\n  expect(submitValidateSuccess).toBeCalledTimes(1)\n  expect(submitValidateEnd).toBeCalledTimes(2)\n})\n\ntest('onFormValidate', async () => {\n  const validateStart = jest.fn()\n  const validateEnd = jest.fn()\n  const validateFailed = jest.fn()\n  const validateSuccess = jest.fn()\n  const form = attach(\n    createForm({\n      effects() {\n        onFormValidateStart(validateStart)\n        onFormValidateEnd(validateEnd)\n        onFormValidateFailed(validateFailed)\n        onFormValidateSuccess(validateSuccess)\n      },\n    })\n  )\n  const field = attach(\n    form.createField({\n      name: 'aa',\n      required: true,\n    })\n  )\n  try {\n    await form.validate()\n  } catch {}\n  expect(validateStart).toBeCalled()\n  expect(validateEnd).toBeCalled()\n  expect(validateFailed).toBeCalled()\n  expect(validateSuccess).not.toBeCalled()\n  field.onInput('123')\n  try {\n    await form.validate()\n  } catch {}\n  expect(validateStart).toBeCalledTimes(2)\n  expect(validateEnd).toBeCalledTimes(2)\n  expect(validateFailed).toBeCalledTimes(1)\n  expect(validateSuccess).toBeCalledTimes(1)\n})\n\ntest('onFieldChange', async () => {\n  const fieldChange = jest.fn()\n  const valueChange = jest.fn()\n  const valueChange2 = jest.fn()\n  const form = attach(\n    createForm({\n      effects() {\n        onFieldChange(\n          'aa',\n          [\n            'value',\n            'disabled',\n            'initialized',\n            'inputValue',\n            'loading',\n            'visible',\n            'editable',\n          ],\n          fieldChange\n        )\n        onFieldChange('aa', valueChange)\n        onFieldChange('aa', undefined, valueChange2)\n        onFieldChange('aa')\n      },\n    })\n  )\n  const field = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  expect(fieldChange).toBeCalledTimes(1)\n  field.setValue('123')\n  expect(fieldChange).toBeCalledTimes(2)\n  field.onInput('321')\n  expect(fieldChange).toBeCalledTimes(3)\n  field.setLoading(true)\n  expect(fieldChange).toBeCalledTimes(3)\n  await sleep()\n  expect(fieldChange).toBeCalledTimes(4)\n  field.setPattern('disabled')\n  expect(fieldChange).toBeCalledTimes(5)\n  field.setDisplay('none')\n  expect(fieldChange).toBeCalledTimes(6)\n  form.onUnmount()\n  expect(valueChange).toBeCalledTimes(4)\n  expect(valueChange2).toBeCalledTimes(4)\n})\n\ntest('onFieldInit/onFieldMount/onFieldUnmount', () => {\n  const fieldInit = jest.fn()\n  const fieldMount = jest.fn()\n  const fieldUnmount = jest.fn()\n  const form = attach(\n    createForm({\n      effects() {\n        onFieldInit('aa', fieldInit)\n        onFieldMount('aa', fieldMount)\n        onFieldUnmount('aa', fieldUnmount)\n      },\n    })\n  )\n  const field = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  expect(fieldInit).toBeCalledTimes(1)\n  expect(fieldMount).toBeCalledTimes(1)\n  expect(fieldUnmount).toBeCalledTimes(0)\n  field.onUnmount()\n  expect(fieldUnmount).toBeCalledTimes(1)\n})\n\ntest('onFieldInitialValueChange/onFieldValueChange/onFieldInputValueChange', () => {\n  const fieldValueChange = jest.fn()\n  const fieldInitialValueChange = jest.fn()\n  const fieldInputValueChange = jest.fn()\n  const notTrigger = jest.fn()\n  const form = attach(\n    createForm({\n      effects() {\n        onFieldInitialValueChange('aa', fieldInitialValueChange)\n        onFieldValueChange('aa', fieldValueChange)\n        onFieldInputValueChange('aa', fieldInputValueChange)\n        onFieldValueChange('xx', notTrigger)\n      },\n    })\n  )\n  const field = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  field.setValue('123')\n  expect(fieldValueChange).toBeCalledTimes(1)\n  expect(fieldInitialValueChange).toBeCalledTimes(0)\n  expect(fieldInputValueChange).toBeCalledTimes(0)\n  field.setInitialValue('xxx')\n  expect(fieldValueChange).toBeCalledTimes(2)\n  expect(fieldInitialValueChange).toBeCalledTimes(1)\n  expect(fieldInputValueChange).toBeCalledTimes(0)\n  field.onInput('321')\n  expect(fieldValueChange).toBeCalledTimes(3)\n  expect(fieldInitialValueChange).toBeCalledTimes(1)\n  expect(fieldInputValueChange).toBeCalledTimes(1)\n  expect(notTrigger).toBeCalledTimes(0)\n})\n\ntest('onFieldReact', () => {\n  const react = jest.fn()\n  const form = attach(\n    createForm({\n      effects() {\n        onFieldReact('aa', (field) => {\n          if (isVoidField(field)) return\n          if (field.value) {\n            react()\n          }\n          if (field.display === 'hidden') {\n            react()\n          }\n        })\n        onFieldReact('aa', null)\n      },\n    })\n  )\n  const field = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  expect(react).not.toBeCalled()\n  form.setValues({ aa: 123 })\n  expect(react).toBeCalledTimes(1)\n  field.setDisplay('hidden')\n  expect(react).toBeCalledTimes(3)\n  form.onUnmount()\n})\n\ntest('onFieldValidate', async () => {\n  const validateStart = jest.fn()\n  const validateFailed = jest.fn()\n  const validateSuccess = jest.fn()\n  const validateEnd = jest.fn()\n  const form = attach(\n    createForm({\n      effects() {\n        onFieldValidateStart('aa', validateStart)\n        onFieldValidateEnd('aa', validateEnd)\n        onFieldValidateFailed('aa', validateFailed)\n        onFieldValidateSuccess('aa', validateSuccess)\n      },\n    })\n  )\n  const field = attach(\n    form.createField({\n      name: 'aa',\n      required: true,\n    })\n  )\n  try {\n    await field.validate()\n  } catch {}\n  expect(validateStart).toBeCalled()\n  expect(validateFailed).toBeCalled()\n  expect(validateSuccess).not.toBeCalled()\n  expect(validateEnd).toBeCalled()\n  field.setValue('123')\n  try {\n    await field.validate()\n  } catch {}\n  expect(validateStart).toBeCalledTimes(2)\n  expect(validateFailed).toBeCalledTimes(1)\n  expect(validateSuccess).toBeCalledTimes(1)\n  expect(validateEnd).toBeCalledTimes(2)\n})\n\ntest('async use will throw error', async () => {\n  const valueChange = jest.fn()\n  let error\n  const form = attach(\n    createForm({\n      effects() {\n        setTimeout(() => {\n          try {\n            onFieldValueChange('aa', valueChange)\n          } catch (e) {\n            error = e\n          }\n        }, 0)\n      },\n    })\n  )\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  await sleep(10)\n  aa.setValue('123')\n  expect(valueChange).toBeCalledTimes(0)\n  expect(error).not.toBeUndefined()\n})\n\ntest('effect context', async () => {\n  const context = createEffectContext<number>()\n  const context2 = createEffectContext<number>()\n  const context3 = createEffectContext<number>(123)\n  let results: any\n  let error: any\n  let error2: any\n  const consumer = () => {\n    results = context.consume()\n  }\n  const consumer2 = () => {\n    setTimeout(() => {\n      try {\n        results = context2.consume()\n      } catch (e) {\n        error2 = e\n      }\n    }, 0)\n  }\n  attach(\n    createForm({\n      effects() {\n        context.provide(123)\n        context3.provide()\n        consumer()\n        setTimeout(() => {\n          try {\n            context2.provide(123)\n          } catch (e) {\n            error = e\n          }\n        }, 0)\n        consumer2()\n      },\n    })\n  )\n  await sleep(10)\n  expect(results).toEqual(123)\n  expect(error).not.toBeUndefined()\n  expect(error2).not.toBeUndefined()\n})\n\ntest('runEffects', () => {\n  expect(\n    runEffects(123, () => {\n      onFormMount(() => {})\n    }).length\n  ).toEqual(1)\n})\n"
  },
  {
    "path": "packages/core/src/__tests__/externals.spec.ts",
    "content": "import { createForm } from '..'\nimport {\n  isArrayField,\n  isArrayFieldState,\n  isDataField,\n  isDataFieldState,\n  isField,\n  isFieldState,\n  isForm,\n  isFormState,\n  isGeneralField,\n  isGeneralFieldState,\n  isObjectField,\n  isObjectFieldState,\n  isQuery,\n  isVoidField,\n  isVoidFieldState,\n  createEffectHook,\n} from '../shared/externals'\nimport { attach } from './shared'\n\ntest('type checkers', () => {\n  const form = attach(createForm())\n  const normal = attach(\n    form.createField({\n      name: 'normal',\n    })\n  )\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  const object = attach(\n    form.createObjectField({\n      name: 'object',\n    })\n  )\n  const void_ = attach(\n    form.createVoidField({\n      name: 'void',\n    })\n  )\n  expect(isField(normal)).toBeTruthy()\n  expect(isFieldState(normal.getState())).toBeTruthy()\n  expect(isFieldState(null)).toBeFalsy()\n  expect(isFieldState({})).toBeFalsy()\n  expect(isFieldState(normal)).toBeFalsy()\n\n  expect(isArrayField(array)).toBeTruthy()\n  expect(isArrayFieldState(array.getState())).toBeTruthy()\n  expect(isArrayFieldState(null)).toBeFalsy()\n  expect(isArrayFieldState({})).toBeFalsy()\n  expect(isArrayFieldState(array)).toBeFalsy()\n\n  expect(isObjectField(object)).toBeTruthy()\n  expect(isObjectFieldState(object.getState())).toBeTruthy()\n  expect(isObjectFieldState(null)).toBeFalsy()\n  expect(isObjectFieldState({})).toBeFalsy()\n  expect(isObjectFieldState(object)).toBeFalsy()\n\n  expect(isVoidField(void_)).toBeTruthy()\n  expect(isVoidFieldState(void_.getState())).toBeTruthy()\n  expect(isVoidFieldState(null)).toBeFalsy()\n  expect(isVoidFieldState({})).toBeFalsy()\n  expect(isVoidFieldState(void_)).toBeFalsy()\n\n  expect(isDataField(void_)).toBeFalsy()\n  expect(isDataFieldState(void_.getState())).toBeFalsy()\n\n  expect(isDataField(normal)).toBeTruthy()\n  expect(isDataFieldState(normal.getState())).toBeTruthy()\n  expect(isGeneralField(normal)).toBeTruthy()\n  expect(isGeneralField(array)).toBeTruthy()\n  expect(isGeneralField(object)).toBeTruthy()\n  expect(isGeneralField(void_)).toBeTruthy()\n\n  expect(isGeneralFieldState(normal.getState())).toBeTruthy()\n  expect(isGeneralFieldState(array.getState())).toBeTruthy()\n  expect(isGeneralFieldState(object.getState())).toBeTruthy()\n  expect(isGeneralFieldState(void_.getState())).toBeTruthy()\n  expect(isGeneralFieldState(null)).toBeFalsy()\n  expect(isGeneralFieldState({})).toBeFalsy()\n  expect(isGeneralFieldState(void_)).toBeFalsy()\n\n  expect(isForm(form)).toBeTruthy()\n  expect(isFormState(form.getState())).toBeTruthy()\n  expect(isFormState({})).toBeFalsy()\n  expect(isFormState(form)).toBeFalsy()\n  expect(isFormState(null)).toBeFalsy()\n  expect(isQuery(form.query('*'))).toBeTruthy()\n})\n\ntest('createEffectHook', () => {\n  try {\n    createEffectHook('xxx')()\n  } catch {}\n  const form = attach(\n    createForm({\n      effects() {\n        createEffectHook('xxx')()\n        createEffectHook('yyy', () => () => {})()\n      },\n    })\n  )\n  form.notify('xxx')\n  form.notify('yyy')\n})\n"
  },
  {
    "path": "packages/core/src/__tests__/field.spec.ts",
    "content": "import { autorun, batch, observable } from '@formily/reactive'\nimport { createForm, onFieldReact, isField } from '../'\nimport { DataField } from '../types'\nimport { attach, sleep } from './shared'\n\ntest('create field', () => {\n  const form = attach(createForm())\n  const field = attach(\n    form.createField({\n      name: 'normal',\n    })\n  )\n  expect(field).not.toBeUndefined()\n})\n\ntest('create field props', () => {\n  const form = attach(createForm())\n  const field1 = attach(\n    form.createField({\n      name: 'field1',\n      title: 'Field 1',\n      description: 'This is Field 1',\n      required: true,\n    })\n  )\n  expect(field1.title).toEqual('Field 1')\n  expect(field1.description).toEqual('This is Field 1')\n  expect(field1.required).toBeTruthy()\n  expect(field1.validator).not.toBeUndefined()\n  const field2 = attach(\n    form.createField({\n      name: 'field2',\n      disabled: true,\n      hidden: true,\n    })\n  )\n  expect(field2.pattern).toEqual('disabled')\n  expect(field2.disabled).toBeTruthy()\n  expect(field2.display).toEqual('hidden')\n  expect(field2.hidden).toBeTruthy()\n  const field3 = attach(\n    form.createField({\n      name: 'field3',\n      readOnly: true,\n      visible: false,\n    })\n  )\n  expect(field3.pattern).toEqual('readOnly')\n  expect(field3.readOnly).toBeTruthy()\n  expect(field3.display).toEqual('none')\n  expect(field3.visible).toBeFalsy()\n  const field4 = attach(\n    form.createField({\n      name: 'field4',\n      value: 123,\n    })\n  )\n  expect(field4.value).toEqual(123)\n  expect(field4.initialValue).toBeUndefined()\n  const field5 = attach(\n    form.createField({\n      name: 'field5',\n      initialValue: 123,\n    })\n  )\n  expect(field5.value).toEqual(123)\n  expect(field5.initialValue).toEqual(123)\n})\n\ntest('field display and value', () => {\n  const form = attach(createForm())\n  const objectField = attach(\n    form.createObjectField({\n      name: 'object',\n    })\n  )\n  const arrayField = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  const valueField = attach(\n    form.createField({\n      name: 'value',\n    })\n  )\n  expect(objectField.value).toEqual({})\n  expect(arrayField.value).toEqual([])\n  expect(valueField.value).toBeUndefined()\n\n  objectField.hidden = true\n  arrayField.hidden = true\n  valueField.hidden = true\n  expect(objectField.value).toEqual({})\n  expect(arrayField.value).toEqual([])\n  expect(valueField.value).toBeUndefined()\n\n  objectField.hidden = false\n  arrayField.hidden = false\n  valueField.hidden = false\n  expect(objectField.value).toEqual({})\n  expect(arrayField.value).toEqual([])\n  expect(valueField.value).toBeUndefined()\n\n  objectField.visible = false\n  arrayField.visible = false\n  valueField.visible = false\n  expect(objectField.value).toBeUndefined()\n  expect(arrayField.value).toBeUndefined()\n  expect(valueField.value).toBeUndefined()\n\n  objectField.visible = true\n  arrayField.visible = true\n  valueField.visible = true\n  expect(objectField.value).toEqual({})\n  expect(arrayField.value).toEqual([])\n  expect(valueField.value).toBeUndefined()\n\n  objectField.value = { value: '123' }\n  arrayField.value = ['123']\n  valueField.value = '123'\n  expect(objectField.value).toEqual({ value: '123' })\n  expect(arrayField.value).toEqual(['123'])\n  expect(valueField.value).toEqual('123')\n\n  objectField.hidden = true\n  arrayField.hidden = true\n  valueField.hidden = true\n  expect(objectField.value).toEqual({ value: '123' })\n  expect(arrayField.value).toEqual(['123'])\n  expect(valueField.value).toEqual('123')\n\n  objectField.hidden = false\n  arrayField.hidden = false\n  valueField.hidden = false\n  expect(objectField.value).toEqual({ value: '123' })\n  expect(arrayField.value).toEqual(['123'])\n  expect(valueField.value).toEqual('123')\n\n  objectField.visible = false\n  arrayField.visible = false\n  valueField.visible = false\n  expect(objectField.value).toBeUndefined()\n  expect(arrayField.value).toBeUndefined()\n  expect(valueField.value).toBeUndefined()\n\n  objectField.visible = true\n  arrayField.visible = true\n  valueField.visible = true\n  expect(objectField.value).toEqual({ value: '123' })\n  expect(arrayField.value).toEqual(['123'])\n  expect(valueField.value).toEqual('123')\n})\n\ntest('nested display/pattern', () => {\n  const form = attach(createForm())\n  const object_ = attach(\n    form.createObjectField({\n      name: 'object',\n    })\n  )\n  const void_ = attach(\n    form.createVoidField({\n      name: 'void',\n      basePath: 'object',\n    })\n  )\n  const aaa = attach(\n    form.createField({\n      name: 'aaa',\n      basePath: 'object.void',\n    })\n  )\n  const bbb = attach(\n    form.createField({\n      name: 'bbb',\n      basePath: 'object',\n    })\n  )\n  const ddd = attach(\n    form.createField({\n      name: 'ddd',\n    })\n  )\n  expect(ddd.visible).toBeTruthy()\n  expect(ddd.editable).toBeTruthy()\n  object_.setPattern('readPretty')\n  expect(void_.pattern).toEqual('readPretty')\n  expect(aaa.pattern).toEqual('readPretty')\n  expect(bbb.pattern).toEqual('readPretty')\n  object_.setPattern('readOnly')\n  expect(void_.pattern).toEqual('readOnly')\n  expect(aaa.pattern).toEqual('readOnly')\n  expect(bbb.pattern).toEqual('readOnly')\n  object_.setPattern('disabled')\n  expect(void_.pattern).toEqual('disabled')\n  expect(aaa.pattern).toEqual('disabled')\n  expect(bbb.pattern).toEqual('disabled')\n  object_.setPattern()\n  expect(void_.pattern).toEqual('editable')\n  expect(aaa.pattern).toEqual('editable')\n  expect(bbb.pattern).toEqual('editable')\n\n  object_.setDisplay('hidden')\n  expect(void_.display).toEqual('hidden')\n  expect(aaa.display).toEqual('hidden')\n  expect(bbb.display).toEqual('hidden')\n  object_.setDisplay('none')\n  expect(void_.display).toEqual('none')\n  expect(aaa.display).toEqual('none')\n  expect(bbb.display).toEqual('none')\n  object_.setDisplay()\n  expect(void_.display).toEqual('visible')\n  expect(aaa.display).toEqual('visible')\n  expect(bbb.display).toEqual('visible')\n\n  aaa.setValue('123')\n  expect(aaa.value).toEqual('123')\n  aaa.setDisplay('none')\n  expect(aaa.value).toBeUndefined()\n  aaa.setDisplay('visible')\n  expect(aaa.value).toEqual('123')\n  aaa.setValue('123')\n  object_.setDisplay('none')\n  expect(aaa.value).toBeUndefined()\n  object_.setDisplay('visible')\n  expect(aaa.value).toEqual('123')\n})\n\ntest('setValue/setInitialValue', () => {\n  const form = attach(createForm())\n  const aaa = attach(\n    form.createField({\n      name: 'aaa',\n    })\n  )\n  const bbb = attach(\n    form.createField({\n      name: 'bbb',\n    })\n  )\n  aaa.setValue('123')\n  expect(aaa.value).toEqual('123')\n  expect(form.values.aaa).toEqual('123')\n  bbb.setValue('123')\n  expect(bbb.value).toEqual('123')\n  expect(form.values.bbb).toEqual('123')\n  const ccc = attach(\n    form.createField({\n      name: 'ccc',\n    })\n  )\n  const ddd = attach(\n    form.createField({\n      name: 'ddd',\n    })\n  )\n  ccc.setInitialValue('123')\n  expect(ccc.value).toEqual('123')\n  expect(ccc.initialValue).toEqual('123')\n  expect(form.values.ccc).toEqual('123')\n  ddd.setInitialValue('123')\n  expect(ddd.value).toEqual('123')\n  expect(ddd.initialValue).toEqual('123')\n  expect(form.values.ddd).toEqual('123')\n  ccc.setInitialValue('222')\n  expect(ccc.value).toEqual('222')\n  expect(ccc.initialValue).toEqual('222')\n  expect(form.values.ccc).toEqual('222')\n  ddd.setInitialValue('222')\n  expect(ddd.value).toEqual('222')\n  expect(ddd.initialValue).toEqual('222')\n  expect(form.values.ddd).toEqual('222')\n})\n\ntest('setLoading/setValidating', async () => {\n  const form = attach(createForm())\n  const field = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  field.setLoading(true)\n  expect(field.loading).toBeFalsy()\n  await sleep()\n  expect(field.loading).toBeTruthy()\n  field.setLoading(false)\n  field.setLoading(false)\n  expect(field.loading).toBeFalsy()\n  field.setValidating(true)\n  expect(field.validating).toBeFalsy()\n  await sleep()\n  expect(field.validating).toBeTruthy()\n  field.setValidating(false)\n  expect(field.validating).toBeFalsy()\n})\n\ntest('setComponent/setComponentProps', () => {\n  const component = () => null\n  const form = attach(createForm())\n  const field = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n\n  field.setComponent(undefined, { props: 123 })\n  field.setComponent(component)\n  expect(field.component[0]).toEqual(component)\n  expect(field.component[1]).toEqual({ props: 123 })\n  field.setComponentProps({\n    hello: 'world',\n  })\n  expect(field.component[1]).toEqual({ props: 123, hello: 'world' })\n})\n\ntest('setDecorator/setDecoratorProps', () => {\n  const component = () => null\n  const form = attach(createForm())\n  const field = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  field.setDecorator(undefined, { props: 123 })\n  field.setDecorator(component)\n  expect(field.decorator[0]).toEqual(component)\n  expect(field.decorator[1]).toEqual({ props: 123 })\n  field.setDecoratorProps({\n    hello: 'world',\n  })\n  expect(field.decorator[1]).toEqual({ props: 123, hello: 'world' })\n})\n\ntest('reaction initialValue', () => {\n  const form = attach(\n    createForm({\n      values: {\n        aa: 123,\n      },\n    })\n  )\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      reactions(field) {\n        field.initialValue = 321\n      },\n    })\n  )\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n      value: 123,\n      reactions(field) {\n        field.initialValue = 321\n      },\n    })\n  )\n  expect(aa.value).toEqual(123)\n  expect(bb.value).toEqual(123)\n})\n\ntest('selfValidate/errors/warnings/successes/valid/invalid/validateStatus/queryFeedbacks', async () => {\n  const form = attach(createForm())\n  const field = attach(\n    form.createField({\n      name: 'aa',\n      required: true,\n      validateFirst: true,\n      validator: [\n        (value) => {\n          if (value == '123') {\n            return {\n              type: 'success',\n              message: 'success',\n            }\n          } else if (value == '321') {\n            return {\n              type: 'warning',\n              message: 'warning',\n            }\n          } else if (value == '111') {\n            return 'error'\n          }\n        },\n        {\n          triggerType: 'onBlur',\n          format: 'url',\n        },\n        {\n          triggerType: 'onFocus',\n          format: 'date',\n        },\n      ],\n    })\n  )\n  const field2 = attach(\n    form.createField({\n      name: 'bb',\n      required: true,\n      value: '111',\n      validator: [\n        (value) => {\n          if (value == '123') {\n            return {\n              type: 'success',\n              message: 'success',\n            }\n          } else if (value == '321') {\n            return {\n              type: 'warning',\n              message: 'warning',\n            }\n          } else if (value == '111') {\n            return 'error'\n          }\n        },\n        {\n          triggerType: 'onBlur',\n          format: 'url',\n        },\n        {\n          triggerType: 'onFocus',\n          format: 'date',\n        },\n      ],\n    })\n  )\n  const field3 = attach(\n    form.createField({\n      name: 'xxx',\n    })\n  )\n  const field4 = attach(\n    form.createField({\n      name: 'ppp',\n      required: true,\n    })\n  )\n  try {\n    await field.validate()\n  } catch {}\n  try {\n    await field2.validate()\n  } catch {}\n  expect(field.invalid).toBeTruthy()\n  expect(field.selfErrors.length).toEqual(1)\n  expect(field2.invalid).toBeTruthy()\n  expect(field2.selfErrors.length).toEqual(3)\n  await field.onInput('123')\n  expect(field.selfSuccesses).toEqual(['success'])\n  await field.onInput('321')\n  expect(field.selfWarnings).toEqual(['warning'])\n  await field.onInput('111')\n  expect(field.selfErrors).toEqual(['error'])\n  await field.onBlur()\n  expect(field.selfErrors).toEqual([\n    'error',\n    'The field value is a invalid url',\n  ])\n  await field.onFocus()\n  expect(field.selfErrors).toEqual([\n    'error',\n    'The field value is a invalid url',\n    'The field value is not a valid date format',\n  ])\n  field.setFeedback()\n  expect(field.selfErrors).toEqual([\n    'error',\n    'The field value is a invalid url',\n    'The field value is not a valid date format',\n  ])\n  expect(field3.feedbacks).toEqual([])\n  field3.setFeedback()\n  field3.setFeedback({ messages: null })\n  field3.setFeedback({ messages: ['error'], code: 'EffectError' })\n  field3.setFeedback({ messages: ['error2'], code: 'EffectError' })\n  expect(field3.feedbacks).toEqual([\n    { code: 'EffectError', messages: ['error2'] },\n  ])\n  expect(\n    field3.queryFeedbacks({\n      address: 'xxx',\n    })\n  ).toEqual([{ code: 'EffectError', messages: ['error2'] }])\n  expect(\n    field3.queryFeedbacks({\n      address: 'yyy',\n    })\n  ).toEqual([])\n  expect(\n    field3.queryFeedbacks({\n      path: 'yyy',\n    })\n  ).toEqual([])\n  field3.setFeedback({ messages: null, code: 'EffectError' })\n  field3.setFeedback({ messages: [], code: 'EffectError' })\n  field4.setDisplay('none')\n  await field4.validate()\n  expect(field4.selfErrors).toEqual([])\n})\n\ntest('setValidateRule', () => {\n  const form = attach(createForm())\n  const field1 = attach(\n    form.createField({\n      name: 'aa',\n      validator: [{ required: true }],\n    })\n  )\n  const field2 = attach(\n    form.createField({\n      name: 'bb',\n      validator: 'phone',\n    })\n  )\n  const field3 = attach(\n    form.createField({\n      name: 'cc',\n      validator: 'phone',\n    })\n  )\n  const field4 = attach(\n    form.createField({\n      name: 'dd',\n      validator: { format: 'phone' },\n    })\n  )\n  const field5 = attach(\n    form.createField({\n      name: 'ee',\n      validator: [{ format: 'phone' }],\n    })\n  )\n  const field6 = attach(\n    form.createField({\n      name: 'ff',\n    })\n  )\n  field1.setValidatorRule('format', 'phone')\n  field2.setValidatorRule('max', 3)\n  field3.setValidatorRule('format', 'url')\n  field4.setValidatorRule('min', 3)\n  field5.setValidatorRule('min', 3)\n  field6.setValidatorRule('min', 3)\n  expect(field1.validator).toEqual([{ required: true }, { format: 'phone' }])\n  expect(field2.validator).toEqual([{ format: 'phone' }, { max: 3 }])\n  expect(field3.validator).toEqual([{ format: 'url' }])\n  expect(field4.validator).toEqual([{ format: 'phone' }, { min: 3 }])\n  expect(field5.validator).toEqual([{ format: 'phone' }, { min: 3 }])\n  expect(field6.validator).toEqual([{ min: 3 }])\n})\n\ntest('query', () => {\n  const form = attach(createForm())\n  const object_ = attach(\n    form.createObjectField({\n      name: 'object',\n    })\n  )\n  const void_ = attach(\n    form.createVoidField({\n      name: 'void',\n      basePath: 'object',\n    })\n  )\n  const aaa = attach(\n    form.createField({\n      name: 'aaa',\n      basePath: 'object.void',\n    })\n  )\n  const bbb = attach(\n    form.createField({\n      name: 'bbb',\n      basePath: 'object',\n    })\n  )\n  expect(object_.query('object.void').take()).not.toBeUndefined()\n  expect(object_.query('object.void.aaa').take()).not.toBeUndefined()\n  expect(void_.query('.')).not.toBeUndefined()\n  expect(void_.query('.bbb').take()).not.toBeUndefined()\n  expect(aaa.query('.ccc').take()).toBeUndefined()\n  expect(aaa.query('..').take()).not.toBeUndefined()\n  expect(aaa.query('..bbb').take()).not.toBeUndefined()\n  expect(bbb.query('.void').take()).not.toBeUndefined()\n  expect(bbb.query('.void.aaa').take()).not.toBeUndefined()\n  expect(bbb.query('.void.ccc').take()).toBeUndefined()\n})\n\ntest('empty initialValue', () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      initialValue: '',\n    })\n  )\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n    })\n  )\n  expect(aa.value).toEqual('')\n  expect(form.values.aa).toEqual('')\n  expect(bb.value).toEqual(undefined)\n  expect(form.values.bb).toEqual(undefined)\n})\n\ntest('objectFieldWithInitialValue', async () => {\n  const form = attach(\n    createForm({\n      initialValues: {\n        obj: {\n          a: 'a',\n        },\n      },\n    })\n  )\n  attach(\n    form.createObjectField({\n      name: 'obj',\n    })\n  )\n  const fieldObjA = attach(\n    form.createField({\n      name: 'obj.a',\n    })\n  )\n\n  expect(fieldObjA.initialValue).toEqual('a')\n  fieldObjA.value = 'aa'\n  expect(fieldObjA.value).toEqual('aa')\n  expect(fieldObjA.initialValue).toEqual('a')\n})\n\ntest('initialValueWithArray', () => {\n  const form = attach(createForm())\n  const field = attach(\n    form.createArrayField({\n      name: 'aaa',\n      initialValue: [1, 2],\n    })\n  )\n  expect(field.initialValue).toEqual([1, 2])\n  expect(field.value).toEqual([1, 2])\n  expect(form.initialValues.aaa).toEqual([1, 2])\n  expect(form.values.aaa).toEqual([1, 2])\n})\n\ntest('resetObjectFieldWithInitialValue', async () => {\n  const form = attach(createForm())\n  attach(\n    form.createObjectField({\n      name: 'obj',\n    })\n  )\n  const fieldObjA = attach(\n    form.createField({\n      name: 'obj.a',\n      initialValue: 'a',\n    })\n  )\n\n  fieldObjA.value = 'aa'\n  expect(fieldObjA.value).toEqual('aa')\n  await form.reset()\n  expect(fieldObjA.value).toEqual('a')\n\n  fieldObjA.value = 'aa'\n  expect(fieldObjA.value).toEqual('aa')\n  await form.reset()\n  expect(fieldObjA.initialValue).toEqual('a')\n  expect(fieldObjA.value).toEqual('a')\n})\n\ntest('reset', async () => {\n  const form = attach(\n    createForm<any>({\n      values: {\n        bb: 123,\n      },\n      initialValues: {\n        aa: 123,\n        cc: null,\n      },\n    })\n  )\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      required: true,\n    })\n  )\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n      required: true,\n    })\n  )\n  const cc = attach(\n    form.createField({\n      name: 'cc',\n      required: true,\n    })\n  )\n  const dd = attach(\n    form.createField({\n      name: 'dd',\n      required: true,\n    })\n  )\n  expect(aa.value).toEqual(123)\n  expect(bb.value).toEqual(123)\n  expect(cc.value).toEqual(null)\n  expect(form.values.aa).toEqual(123)\n  expect(form.values.bb).toEqual(123)\n  expect(form.values.cc).toEqual(null)\n  aa.onInput('xxxxx')\n  expect(form.values.aa).toEqual('xxxxx')\n  dd.onInput(null)\n  expect(form.values.dd).toEqual(null)\n  aa.reset()\n  expect(aa.value).toEqual(123)\n  expect(form.values.aa).toEqual(123)\n  bb.onInput('xxxxx')\n  expect(form.values.bb).toEqual('xxxxx')\n  bb.reset()\n  expect(bb.value).toBeUndefined()\n  expect(form.values.bb).toBeUndefined()\n\n  cc.onInput('xxxxx')\n  expect(form.values.cc).toEqual('xxxxx')\n  cc.reset()\n  expect(cc.value).toBeNull()\n  expect(form.values.cc).toBeNull()\n  dd.reset()\n  expect(dd.value).toBeUndefined()\n  expect(form.values.dd).toBeUndefined()\n\n  aa.reset({\n    forceClear: true,\n  })\n  expect(aa.value).toBeUndefined()\n  expect(form.values.aa).toBeUndefined()\n  cc.reset({\n    forceClear: true,\n  })\n  expect(cc.value).toBeUndefined()\n  expect(form.values.cc).toBeUndefined()\n\n  expect(aa.valid).toBeTruthy()\n  await aa.reset({\n    forceClear: true,\n    validate: true,\n  })\n  expect(aa.valid).toBeFalsy()\n\n  expect(cc.valid).toBeTruthy()\n  await cc.reset({\n    forceClear: true,\n    validate: true,\n  })\n  expect(cc.valid).toBeFalsy()\n})\n\ntest('match', () => {\n  const form = attach(\n    createForm<any>({\n      values: {\n        bb: 123,\n      },\n      initialValues: {\n        aa: 123,\n      },\n    })\n  )\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      required: true,\n    })\n  )\n  expect(aa.match('aa')).toBeTruthy()\n  expect(aa.match('*')).toBeTruthy()\n  expect(aa.match('a~')).toBeTruthy()\n  expect(aa.match('*(aa,bb)')).toBeTruthy()\n})\n\ntest('setState/getState', () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      required: true,\n    })\n  )\n  const state = aa.getState()\n  aa.setState((state) => {\n    state.value = '123'\n    state.title = 'AAA'\n  })\n  expect(aa.value).toEqual('123')\n  expect(aa.title).toEqual('AAA')\n  state['setState'] = () => {}\n  aa.setState(state)\n  expect(aa.value).toBeUndefined()\n  expect(aa.title).toBeUndefined()\n  aa.setState((state) => {\n    state.hidden = false\n  })\n  expect(aa.display).toEqual('visible')\n  aa.setState((state) => {\n    state.visible = true\n  })\n  expect(aa.display).toEqual('visible')\n  aa.setState((state) => {\n    state.readOnly = false\n  })\n  expect(aa.pattern).toEqual('editable')\n  aa.setState((state) => {\n    state.disabled = false\n  })\n  expect(aa.pattern).toEqual('editable')\n  aa.setState((state) => {\n    state.editable = true\n  })\n  expect(aa.pattern).toEqual('editable')\n  aa.setState((state) => {\n    state.editable = false\n  })\n  expect(aa.pattern).toEqual('readPretty')\n  aa.setState((state) => {\n    state.readPretty = true\n  })\n  expect(aa.pattern).toEqual('readPretty')\n  aa.setState((state) => {\n    state.readPretty = false\n  })\n  expect(aa.pattern).toEqual('editable')\n  form.setFieldState('bb', (state) => {\n    state.value = 'bbb'\n  })\n  form.setFieldState('bb', (state) => {\n    state.visible = false\n  })\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n    })\n  )\n  expect(bb.value).toEqual(undefined)\n  expect(bb.visible).toBeFalsy()\n  form.setFieldState('*', (state) => {\n    state.value = '123'\n  })\n  const cc = attach(\n    form.createField({\n      name: 'cc',\n    })\n  )\n  expect(aa.value).toEqual('123')\n  expect(bb.value).toBeUndefined()\n  expect(cc.value).toEqual('123')\n  form.setFieldState(form.query('cc'), (state) => {\n    state.value = 'ccc'\n  })\n  expect(cc.value).toEqual('ccc')\n  form.setFieldState(cc, (state) => {\n    state.value = '123'\n  })\n  expect(cc.value).toEqual('123')\n  expect(form.getFieldState(aa)).not.toBeUndefined()\n  expect(form.getFieldState(form.query('aa'))).not.toBeUndefined()\n})\n\ntest('setDataSource', () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      required: true,\n    })\n  )\n  aa.setDataSource([\n    { label: 's1', value: 's1' },\n    { label: 's2', value: 's2' },\n  ])\n  expect(aa.dataSource).toEqual([\n    { label: 's1', value: 's1' },\n    { label: 's2', value: 's2' },\n  ])\n})\n\ntest('setTitle/setDescription', () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      required: true,\n    })\n  )\n  aa.setTitle('AAA')\n  aa.setDescription('This is AAA')\n  expect(aa.title).toEqual('AAA')\n  expect(aa.description).toEqual('This is AAA')\n})\n\ntest('required/setRequired', () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  aa.setRequired(true)\n  expect(aa.required).toBeTruthy()\n  aa.setRequired(false)\n  expect(aa.required).toBeFalsy()\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n      validator: {\n        max: 3,\n        required: true,\n      },\n    })\n  )\n  expect(bb.required).toBeTruthy()\n  bb.setRequired(false)\n  expect(bb.required).toBeFalsy()\n  const cc = attach(\n    form.createField({\n      name: 'cc',\n      validator: [\n        'date',\n        {\n          max: 3,\n        },\n        {\n          required: true,\n        },\n      ],\n    })\n  )\n  expect(cc.required).toBeTruthy()\n  cc.setRequired(false)\n  expect(cc.required).toBeFalsy()\n  const dd = attach(\n    form.createField({\n      name: 'dd',\n      validator: {\n        max: 3,\n      },\n    })\n  )\n  expect(dd.required).toBeFalsy()\n  dd.setRequired(true)\n  expect(dd.required).toBeTruthy()\n})\n\ntest('setData/setContent', () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      required: true,\n    })\n  )\n  aa.setData('This is data')\n  aa.setContent('This is Content')\n  expect(aa.data).toEqual('This is data')\n  expect(aa.content).toEqual('This is Content')\n})\n\ntest('setData/setContent in void field', () => {\n  const form = attach(createForm())\n  const voidFeild = attach(\n    form.createVoidField({\n      name: 'voidFeild',\n    })\n  )\n  voidFeild.setData('This is data')\n  voidFeild.setContent('This is Content')\n  expect(voidFeild.data).toEqual('This is data')\n  expect(voidFeild.content).toEqual('This is Content')\n})\n\ntest('setErrors/setWarnings/setSuccesses/setValidator', async () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n    })\n  )\n  const cc = attach(\n    form.createField({\n      name: 'cc',\n    })\n  )\n  const dd = attach(\n    form.createField({\n      name: 'dd',\n      validator() {\n        return new Promise(() => {})\n      },\n    })\n  )\n  aa.setSelfErrors(['error'])\n  aa.setSelfWarnings(['warning'])\n  aa.setSelfSuccesses(['success'])\n  bb.setSelfSuccesses(['success'])\n  cc.setSelfWarnings(['warning'])\n  expect(aa.selfErrors).toEqual(['error'])\n  expect(aa.valid).toBeFalsy()\n  expect(aa.selfWarnings).toEqual(['warning'])\n  expect(aa.selfSuccesses).toEqual(['success'])\n  expect(bb.validateStatus).toEqual('success')\n  expect(cc.validateStatus).toEqual('warning')\n  aa.setValidator('date')\n  await aa.onInput('123')\n  expect(aa.selfErrors.length).toEqual(2)\n  dd.onInput('123')\n  await sleep()\n  expect(dd.validateStatus).toEqual('validating')\n})\n\ntest('reactions', async () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n      reactions: [\n        (field) => {\n          const aa = field.query('aa')\n          if (aa.get('value') === '123') {\n            field.visible = false\n          } else {\n            field.visible = true\n          }\n          if (aa.get('inputValue') === '333') {\n            field.editable = false\n          } else if (aa.get('inputValue') === '444') {\n            field.editable = true\n          }\n          if (aa.get('initialValue') === '555') {\n            field.readOnly = true\n          } else if (aa.get('initialValue') === '666') {\n            field.readOnly = false\n          }\n        },\n        null,\n      ],\n    })\n  )\n  expect(bb.visible).toBeTruthy()\n  aa.setValue('123')\n  expect(bb.visible).toBeFalsy()\n  await aa.onInput('333')\n  expect(bb.editable).toBeFalsy()\n  await aa.onInput('444')\n  expect(bb.editable).toBeTruthy()\n  aa.setInitialValue('555')\n  expect(bb.readOnly).toBeTruthy()\n  aa.setInitialValue('666')\n  expect(bb.readOnly).toBeFalsy()\n  form.onUnmount()\n})\n\ntest('fault tolerance', () => {\n  const form = attach(createForm())\n  const field = attach(\n    form.createField({\n      name: 'aa',\n      value: 123,\n    })\n  )\n  field.setDisplay('none')\n  expect(field.value).toBeUndefined()\n  field.setDisplay('visible')\n  expect(field.value).toEqual(123)\n  field.setDisplay('none')\n  expect(field.value).toBeUndefined()\n  field.setValue(321)\n  expect(field.value).toBeUndefined()\n  field.setDisplay('visible')\n  expect(field.value).toEqual(321)\n  form.setDisplay(null)\n  form.setPattern(null)\n  const field2 = attach(\n    form.createField({\n      name: 'xxx',\n    })\n  )\n  expect(field2.display).toEqual('visible')\n  expect(field2.pattern).toEqual('editable')\n})\n\ntest('initialValue', () => {\n  const form = attach(createForm())\n  const field = attach(\n    form.createField({\n      name: 'aaa',\n      initialValue: 123,\n    })\n  )\n  expect(form.values.aaa).toEqual(123)\n  expect(form.initialValues.aaa).toEqual(123)\n  expect(field.value).toEqual(123)\n  expect(field.initialValue).toEqual(123)\n})\n\ntest('array path calculation with none index', async () => {\n  const form = attach(createForm())\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  await array.push({})\n  const input = attach(\n    form.createField({\n      name: '0.input',\n      basePath: 'array',\n    })\n  )\n  expect(input.path.toString()).toEqual('array.0.input')\n})\n\ntest('array path calculation with none index and void nested', async () => {\n  const form = attach(createForm())\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  await array.push({})\n  attach(\n    form.createVoidField({\n      name: '0.column',\n      basePath: 'array',\n    })\n  )\n  const input = attach(\n    form.createField({\n      name: 'input',\n      basePath: 'array.0.column',\n    })\n  )\n  expect(input.path.toString()).toEqual('array.0.input')\n})\n\ntest('array path calculation with object index', async () => {\n  const form = attach(createForm())\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  await array.push({})\n  attach(\n    form.createObjectField({\n      name: '0',\n      basePath: 'array',\n    })\n  )\n  const input = attach(\n    form.createField({\n      name: 'input',\n      basePath: 'array.0',\n    })\n  )\n  expect(input.path.toString()).toEqual('array.0.input')\n})\n\ntest('array path calculation with void index', async () => {\n  const form = attach(createForm())\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  await array.push('')\n  attach(\n    form.createVoidField({\n      name: '0',\n      basePath: 'array',\n    })\n  )\n  const input = attach(\n    form.createField({\n      name: 'input',\n      basePath: 'array.0',\n    })\n  )\n  expect(input.path.toString()).toEqual('array.0')\n})\n\ntest('array path calculation with void index and void wrapper', async () => {\n  const form = attach(createForm())\n  attach(\n    form.createVoidField({\n      name: 'layout',\n    })\n  )\n  const array_in_layout = attach(\n    form.createArrayField({\n      name: 'array_in_layout',\n      basePath: 'layout',\n    })\n  )\n  await array_in_layout.push('')\n  attach(\n    form.createVoidField({\n      name: '0',\n      basePath: 'layout.array_in_layout',\n    })\n  )\n  const input = attach(\n    form.createField({\n      name: 'input',\n      basePath: 'layout.array_in_layout.0',\n    })\n  )\n  expect(input.path.toString()).toEqual('array_in_layout.0')\n})\n\ntest('reaction in reaction', () => {\n  const form = attach(createForm())\n  const void_ = attach(\n    form.createVoidField({\n      name: 'void',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'field1',\n      basePath: 'void',\n      initialValue: 123,\n    })\n  )\n  const field2 = attach(\n    form.createField({\n      name: 'field2',\n      basePath: 'void',\n      initialValue: 456,\n      reactions: (field) => {\n        const f1 = field.query('field1')\n        if (f1.get('value') === 123) {\n          field.display = 'visible'\n        } else {\n          field.display = 'none'\n        }\n      },\n    })\n  )\n  void_.setDisplay('none')\n  expect(field2.value).toEqual(undefined)\n  expect(field2.display).toEqual('none')\n})\n\ntest('nested fields hidden and selfValidate', async () => {\n  const form = attach(createForm())\n  const parent = attach(\n    form.createVoidField({\n      name: 'parent',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'aa',\n      basePath: 'parent',\n      required: true,\n    })\n  )\n  attach(\n    form.createField({\n      name: 'bb',\n      basePath: 'parent',\n      required: true,\n    })\n  )\n  try {\n    await form.validate()\n  } catch {}\n  expect(form.invalid).toBeTruthy()\n  parent.display = 'hidden'\n  await form.validate()\n  expect(form.invalid).toBeFalsy()\n})\n\ntest('deep nested fields hidden and selfValidate', async () => {\n  const form = attach(createForm())\n  const parent1 = attach(\n    form.createVoidField({\n      name: 'parent1',\n    })\n  )\n  const parent2 = attach(\n    form.createVoidField({\n      name: 'parent2',\n      basePath: 'parent1',\n    })\n  )\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      basePath: 'parent1.parent2',\n      required: true,\n    })\n  )\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n      basePath: 'parent1.parent2',\n      required: true,\n    })\n  )\n  try {\n    await form.validate()\n  } catch {}\n  expect(form.invalid).toBeTruthy()\n  parent2.display = 'visible'\n  parent1.display = 'hidden'\n  expect(parent2.display).toEqual('hidden')\n  expect(aa.display).toEqual('hidden')\n  expect(bb.display).toEqual('hidden')\n  await form.validate()\n  expect(form.invalid).toBeFalsy()\n})\n\ntest('deep nested fields hidden and selfValidate with middle hidden', async () => {\n  const form = attach(createForm())\n  const parent1 = attach(\n    form.createVoidField({\n      name: 'parent1',\n    })\n  )\n  const parent2 = attach(\n    form.createVoidField({\n      name: 'parent2',\n      basePath: 'parent1',\n    })\n  )\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      basePath: 'parent1.parent2',\n      required: true,\n    })\n  )\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n      basePath: 'parent1.parent2',\n      required: true,\n    })\n  )\n  try {\n    await form.validate()\n  } catch {}\n  expect(form.invalid).toBeTruthy()\n  parent2.display = 'hidden'\n  parent1.display = 'none'\n  expect(parent2.display).toEqual('hidden')\n  expect(aa.display).toEqual('hidden')\n  expect(bb.display).toEqual('hidden')\n  await form.validate()\n  expect(form.invalid).toBeFalsy()\n})\n\ntest('fields unmount and selfValidate', async () => {\n  const form = attach(createForm())\n  const field = attach(\n    form.createField({\n      name: 'parent',\n      required: true,\n    })\n  )\n  try {\n    await form.validate()\n  } catch {}\n  expect(form.invalid).toBeTruthy()\n  field.onUnmount()\n  try {\n    await form.validate()\n  } catch {}\n  expect(form.invalid).toBeTruthy()\n  form.clearFormGraph('parent')\n  await form.validate()\n  expect(form.invalid).toBeFalsy()\n})\n\ntest('auto clean with ArrayField', () => {\n  const form = attach(createForm())\n  attach(\n    form.createArrayField({\n      name: 'array',\n      initialValue: [{}, {}],\n    })\n  )\n  attach(\n    form.createField({\n      name: '0.aa',\n      basePath: 'array',\n    })\n  )\n  attach(\n    form.createField({\n      name: '1.aa',\n      basePath: 'array',\n    })\n  )\n  const array1 = attach(\n    form.createArrayField({\n      name: 'array1',\n      initialValue: [{}, {}],\n    })\n  )\n  attach(\n    form.createField({\n      name: '0.aa',\n      basePath: 'array1',\n    })\n  )\n  attach(\n    form.createField({\n      name: '1.aa',\n      basePath: 'array1',\n    })\n  )\n  const array2 = attach(\n    form.createArrayField({\n      name: 'array2',\n      initialValue: [{}, {}],\n    })\n  )\n  attach(\n    form.createField({\n      name: '0.aa',\n      basePath: 'array2',\n    })\n  )\n  attach(\n    form.createField({\n      name: '1.aa',\n      basePath: 'array2',\n    })\n  )\n  expect(form.fields['array.1.aa']).not.toBeUndefined()\n  expect(form.values.array).toEqual([{}, {}])\n  form.setValues(\n    {\n      array: [{}],\n    },\n    'shallowMerge'\n  )\n  expect(form.values.array).toEqual([{}])\n  expect(form.fields['array.1.aa']).toBeUndefined()\n  expect(form.fields['array1.0.aa']).not.toBeUndefined()\n  expect(form.fields['array1.1.aa']).not.toBeUndefined()\n  expect(form.values.array1).toEqual([{}, {}])\n  array1.setValue([])\n  expect(form.fields['array1.0.aa']).toBeUndefined()\n  expect(form.fields['array1.1.aa']).toBeUndefined()\n  expect(form.fields['array2.0.aa']).not.toBeUndefined()\n  expect(form.fields['array2.1.aa']).not.toBeUndefined()\n  array2.setValue([])\n  expect(form.fields['array2.0.aa']).toBeUndefined()\n  expect(form.fields['array2.1.aa']).toBeUndefined()\n})\n\ntest('auto clean with ObjectField', () => {\n  const form = attach(createForm())\n  attach(\n    form.createObjectField({\n      name: 'obj',\n      initialValue: {\n        aa: 'aa',\n        bb: 'bb',\n      },\n    })\n  )\n  attach(\n    form.createField({\n      name: 'aa',\n      basePath: 'obj',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'bb',\n      basePath: 'obj',\n    })\n  )\n  const obj1 = attach(\n    form.createObjectField({\n      name: 'obj1',\n      initialValue: {\n        aa: 'aa',\n        bb: 'bb',\n      },\n    })\n  )\n  attach(\n    form.createField({\n      name: 'aa',\n      basePath: 'obj1',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'bb',\n      basePath: 'obj1',\n    })\n  )\n  const obj2 = attach(\n    form.createObjectField({\n      name: 'obj2',\n      initialValue: {\n        aa: 'aa',\n        bb: 'bb',\n      },\n    })\n  )\n  attach(\n    form.createField({\n      name: 'aa',\n      basePath: 'obj2',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'bb',\n      basePath: 'obj2',\n    })\n  )\n  expect(form.fields['obj.aa']).not.toBeUndefined()\n  expect(form.fields['obj.bb']).not.toBeUndefined()\n  expect(form.values.obj).toEqual({ aa: 'aa', bb: 'bb' })\n  form.setValues(\n    {\n      obj: {\n        aa: '123',\n      },\n    },\n    'shallowMerge'\n  )\n  expect(form.values.obj).toEqual({ aa: '123' })\n  expect(form.fields['obj.aa']).not.toBeUndefined()\n  expect(form.fields['obj.bb']).not.toBeUndefined()\n  expect(form.fields['obj1.aa']).not.toBeUndefined()\n  expect(form.fields['obj1.bb']).not.toBeUndefined()\n  expect(form.values.obj1).toEqual({ aa: 'aa', bb: 'bb' })\n  obj1.setValue({})\n  expect(form.values.obj1).toEqual({})\n  expect(form.fields['obj1.aa']).not.toBeUndefined()\n  expect(form.fields['obj1.bb']).not.toBeUndefined()\n  expect(form.fields['obj2.aa']).not.toBeUndefined()\n  expect(form.fields['obj2.bb']).not.toBeUndefined()\n  expect(form.values.obj2).toEqual({ aa: 'aa', bb: 'bb' })\n  obj2.setValue({ aa: 'aa', bb: 'bb', cc: 'cc' })\n  expect(form.fields['obj2.aa']).not.toBeUndefined()\n  expect(form.fields['obj2.bb']).not.toBeUndefined()\n  expect(form.fields['obj2.cc']).toBeUndefined()\n  obj2.addProperty('cc', '123')\n  attach(\n    form.createField({\n      name: 'cc',\n      basePath: 'obj2',\n    })\n  )\n  expect(form.fields['obj2.cc']).not.toBeUndefined()\n  obj2.removeProperty('cc')\n  expect(form.fields['obj2.cc']).toBeUndefined()\n})\n\ntest('initial value with empty', () => {\n  const form = attach(createForm())\n  const array = attach(form.createField({ name: 'array', initialValue: '' }))\n  expect(array.value).toEqual('')\n\n  const beNull = attach(form.createField({ name: 'null', initialValue: null }))\n  expect(beNull.value).toEqual(null)\n})\n\ntest('field submit', async () => {\n  const form = attach(\n    createForm({\n      initialValues: {\n        aa: {\n          cc: 'cc',\n        },\n        bb: 'bb',\n      },\n    })\n  )\n  const childForm = attach(\n    form.createObjectField({\n      name: 'aa',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'bb',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'cc',\n      basePath: 'aa',\n    })\n  )\n  const onSubmit = jest.fn()\n  await childForm.submit(onSubmit)\n  expect(onSubmit).toBeCalledWith({\n    cc: 'cc',\n  })\n})\n\ntest('field submit with error', async () => {\n  const form = attach(createForm())\n  const childForm = attach(\n    form.createObjectField({\n      name: 'aa',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'bb',\n      required: true,\n    })\n  )\n  attach(\n    form.createField({\n      name: 'cc',\n      basePath: 'aa',\n      required: true,\n    })\n  )\n  const onSubmit = jest.fn()\n  try {\n    await childForm.submit(onSubmit)\n  } catch (e) {\n    expect(e).not.toBeUndefined()\n  }\n  expect(onSubmit).toBeCalledTimes(0)\n})\n\ntest('initial display with value', () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      value: 123,\n      visible: false,\n    })\n  )\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n      value: 123,\n      visible: true,\n    })\n  )\n  const cc = attach(\n    form.createField({\n      name: 'cc',\n      value: 123,\n      hidden: true,\n    })\n  )\n  expect(aa.value).toBeUndefined()\n  expect(aa.visible).toBeFalsy()\n  expect(bb.value).toEqual(123)\n  expect(bb.visible).toBeTruthy()\n  expect(cc.value).toEqual(123)\n  expect(cc.hidden).toBeTruthy()\n})\n\ntest('state depend field visible value', async () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n      reactions(field) {\n        field.visible = aa.value === '123'\n      },\n    })\n  )\n  const cc = attach(\n    form.createField({\n      name: 'cc',\n      reactions(field) {\n        field.visible = aa.value === '123'\n        field.disabled = !bb.value\n      },\n    })\n  )\n  expect(bb.visible).toBeFalsy()\n  expect(cc.visible).toBeFalsy()\n  expect(cc.disabled).toBeTruthy()\n  aa.value = '123'\n  await sleep(10)\n  expect(bb.visible).toBeTruthy()\n  expect(cc.visible).toBeTruthy()\n  expect(cc.disabled).toBeTruthy()\n  bb.value = '321'\n  await sleep(10)\n  expect(bb.visible).toBeTruthy()\n  expect(cc.visible).toBeTruthy()\n  expect(cc.disabled).toBeFalsy()\n  aa.value = ''\n  await sleep(10)\n  expect(bb.visible).toBeFalsy()\n  expect(cc.visible).toBeFalsy()\n  expect(cc.disabled).toBeTruthy()\n  aa.value = '123'\n  await sleep(10)\n  expect(bb.visible).toBeTruthy()\n  expect(cc.visible).toBeTruthy()\n  expect(cc.disabled).toBeFalsy()\n})\n\ntest('reactions initialValue and value', () => {\n  const form = attach(\n    createForm({\n      values: {\n        aa: {\n          input: '111',\n        },\n      },\n    })\n  )\n  attach(\n    form.createObjectField({\n      name: 'aa',\n      reactions: [\n        (field) => {\n          field.initialValue = {}\n          field.initialValue.input = 123\n        },\n      ],\n    })\n  )\n  attach(\n    form.createField({\n      name: 'input',\n      basePath: 'aa',\n    })\n  )\n  expect(form.values.aa.input).toEqual('111')\n})\n\ntest('field name is length in initialize', () => {\n  const form = attach(createForm())\n  const field = attach(\n    form.createField({\n      name: 'length',\n      initialValue: 123,\n    })\n  )\n  expect(field.value).toEqual(123)\n})\n\ntest('field name is length in dynamic assign', () => {\n  const form = attach(createForm())\n  const field = attach(\n    form.createField({\n      name: 'length',\n    })\n  )\n  field.initialValue = 123\n  expect(field.value).toEqual(123)\n})\n\ntest('nested field modified', async () => {\n  const form = attach(createForm())\n  const obj = attach(\n    form.createObjectField({\n      name: 'object',\n    })\n  )\n  const child = attach(\n    form.createField({\n      name: 'child',\n      basePath: 'object',\n    })\n  )\n  await child.onInput()\n  expect(child.modified).toBeTruthy()\n  expect(child.selfModified).toBeTruthy()\n  expect(obj.modified).toBeTruthy()\n  expect(obj.selfModified).toBeFalsy()\n  expect(form.modified).toBeTruthy()\n  await obj.reset()\n  expect(child.modified).toBeFalsy()\n  expect(child.selfModified).toBeFalsy()\n  expect(obj.modified).toBeFalsy()\n  expect(obj.selfModified).toBeFalsy()\n  expect(form.modified).toBeTruthy()\n  await form.reset()\n  expect(form.modified).toBeFalsy()\n})\n\ntest('field setValidator repeat call', async () => {\n  const form = attach(createForm())\n  const field = attach(\n    form.createField({\n      name: 'normal',\n    })\n  )\n\n  const validator1 = jest.fn(() => '')\n  const validator2 = jest.fn(() => '')\n  const validator3 = jest.fn(() => '')\n\n  field.setValidator([validator1, validator2, validator3])\n\n  await form.validate()\n  expect(validator1).toBeCalledTimes(1)\n})\n\ntest('custom validator to get ctx.field', async () => {\n  const form = attach(createForm())\n  let ctxField = null\n  let ctxForm = null\n  attach(\n    form.createField({\n      name: 'aaa',\n      validator(value, rule, ctx) {\n        ctxField = ctx.field\n        ctxForm = ctx.form\n        return ''\n      },\n    })\n  )\n  await form.submit()\n  expect(!!ctxField).toBeTruthy()\n  expect(!!ctxForm).toBeTruthy()\n})\n\ntest('single direction linkage effect', async () => {\n  const form = attach(createForm())\n\n  const input1 = form.createField({\n    name: 'input1',\n    reactions: (field: DataField) => {\n      if (!field.selfModified) {\n        return\n      }\n      input2.value = field.value\n    },\n  })\n\n  const input2 = form.createField({\n    name: 'input2',\n  })\n\n  await input1.onInput('123')\n  expect(input2.value).toBe('123')\n  await input2.onInput('321')\n  expect(input2.value).toBe('321')\n})\n\ntest('path change will update computed value', () => {\n  const form = attach(createForm())\n\n  const input = form.createField({\n    name: 'input',\n  })\n\n  const value = jest.fn()\n\n  autorun(() => {\n    value(input.value)\n  })\n  batch(() => {\n    input.locate('select')\n    input.value = '123'\n  })\n  expect(value).nthCalledWith(2, '123')\n})\n\ntest('object field reset', async () => {\n  const form = attach(createForm())\n\n  attach(\n    form.createObjectField({\n      name: 'obj',\n    })\n  )\n\n  const input = attach(\n    form.createField({\n      name: 'input',\n      basePath: 'obj',\n    })\n  )\n\n  await form.reset()\n  form.setValues({\n    obj: {\n      input: '123',\n    },\n  })\n  expect(input.value).toBe('123')\n})\n\ntest('field visible default value should work', () => {\n  const form = attach(\n    createForm({\n      effects(form) {\n        onFieldReact('obj.input1', (field) => {\n          field.pattern = 'disabled'\n        })\n        onFieldReact('obj', (field) => {\n          field.visible = form.values.select !== 'none'\n        })\n        onFieldReact('obj.input1', (field) => {\n          if (isField(field)) {\n            field.initialValue = '123'\n          }\n        })\n        onFieldReact('obj.input2', (field) => {\n          if (isField(field)) {\n            field.value = form.values.select\n          }\n        })\n      },\n    })\n  )\n\n  const select = attach(\n    form.createField({\n      name: 'select',\n    })\n  )\n\n  attach(\n    form.createObjectField({\n      name: 'obj',\n    })\n  )\n\n  attach(\n    form.createField({\n      name: 'input1',\n      basePath: 'obj',\n    })\n  )\n\n  attach(\n    form.createField({\n      name: 'input2',\n      basePath: 'obj',\n    })\n  )\n\n  select.value = 'none'\n  expect(form.values.obj?.input1).toBeUndefined()\n  select.value = 'visible'\n  expect(form.values.obj.input1).toBe('123')\n})\n\ntest('query value with sibling path syntax', () => {\n  const form = attach(createForm())\n  const fn = jest.fn()\n  attach(\n    form.createVoidField({\n      name: 'void',\n    })\n  )\n  attach(\n    form.createObjectField({\n      name: 'obj',\n      basePath: 'void',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'input',\n      basePath: 'void.obj',\n      reactions: [\n        (field) => {\n          fn(\n            field.query('.textarea').value(),\n            field.query('.textarea').initialValue()\n          )\n        },\n      ],\n    })\n  )\n  const textarea = attach(\n    form.createField({\n      name: 'textarea',\n      basePath: 'void.obj',\n      initialValue: 'aaa',\n    })\n  )\n  textarea.value = '123'\n  expect(fn).toBeCalledWith('123', 'aaa')\n})\n\ntest('relative query with void field', () => {\n  const form = attach(createForm())\n  attach(\n    form.createVoidField({\n      name: 'void',\n    })\n  )\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      basePath: 'void',\n    })\n  )\n  attach(\n    form.createVoidField({\n      name: 'mm',\n    })\n  )\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n      basePath: 'mm',\n    })\n  )\n\n  expect(bb.query('.aa').take()).toBe(aa)\n})\n\ntest('empty string or number or null value need rewrite default value', () => {\n  const form = attach(\n    createForm<any>({\n      values: {\n        aa: '',\n        bb: 0,\n        ee: null,\n      },\n    })\n  )\n  attach(\n    form.createField({\n      name: 'aa',\n      initialValue: 'test',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'bb',\n      initialValue: 123,\n    })\n  )\n  attach(\n    form.createField({\n      name: 'cc',\n      initialValue: 'test',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'dd',\n      initialValue: 123,\n    })\n  )\n  attach(\n    form.createField({\n      name: 'ee',\n      initialValue: 'test',\n    })\n  )\n  expect(form.values.aa).toEqual('')\n  expect(form.values.bb).toEqual(0)\n  expect(form.values.cc).toEqual('test')\n  expect(form.values.dd).toEqual(123)\n  expect(form.values.ee).toEqual(null)\n})\n\ntest('destroy field need auto remove initialValues', () => {\n  const form = attach(createForm<any>())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      initialValue: 'test',\n    })\n  )\n  expect(form.initialValues.aa).toEqual('test')\n  expect(form.values.aa).toEqual('test')\n  aa.destroy()\n  expect(form.initialValues.aa).toBeUndefined()\n  expect(form.values.aa).toBeUndefined()\n})\n\ntest('validateFirst', async () => {\n  const form = attach(\n    createForm<any>({\n      validateFirst: false,\n    })\n  )\n  const aaValidate = jest.fn(() => 'aaError')\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      validateFirst: true,\n      validator: [aaValidate, aaValidate],\n    })\n  )\n  await aa.onInput('aa')\n  const bbValidate = jest.fn(() => 'bbError')\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n      validator: [bbValidate, bbValidate],\n      validateFirst: false,\n    })\n  )\n  await bb.onInput('bb')\n  const ccValidate = jest.fn(() => 'ccError')\n  const cc = attach(\n    form.createField({\n      name: 'cc',\n      validator: [ccValidate, ccValidate],\n    })\n  )\n  await cc.onInput('cc')\n\n  expect(aaValidate).toBeCalledTimes(1)\n  expect(bbValidate).toBeCalledTimes(2)\n  expect(ccValidate).toBeCalledTimes(2)\n})\n\ntest('reactions should not be triggered when field destroyed', () => {\n  const form = attach(createForm<any>())\n  const handler = jest.fn()\n  const obs = observable({ bb: 123 })\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      initialValue: 'test',\n      reactions() {\n        handler(obs.bb)\n      },\n    })\n  )\n  obs.bb = 321\n  aa.destroy()\n  obs.bb = 111\n  expect(handler).toBeCalledTimes(2)\n})\n\ntest('parent readPretty will overwrite self disabled or readOnly', () => {\n  const form = attach(\n    createForm<any>({\n      readPretty: true,\n    })\n  )\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      initialValue: 'test',\n      disabled: true,\n    })\n  )\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n      initialValue: 'test',\n      editable: true,\n    })\n  )\n  expect(aa.pattern).toBe('readPretty')\n  expect(bb.pattern).toBe('editable')\n})\n\ntest('conflict name for errors filter', async () => {\n  const form = attach(createForm<any>())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      required: true,\n    })\n  )\n  const aa1 = attach(\n    form.createField({\n      name: 'aa1',\n      required: true,\n    })\n  )\n\n  await aa1.onInput('')\n  expect(aa.invalid).toBe(false)\n})\n\ntest('field destroyed can not be assign value', () => {\n  const form = attach(createForm<any>())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  aa.destroy()\n  aa.initialValue = 222\n  aa.value = 111\n  expect(form.values).toEqual({})\n  expect(form.initialValues).toEqual({})\n})\n\ntest('onInput could pass value with target', async () => {\n  const form = attach(createForm<any>())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  await aa.onInput({\n    target: '123',\n  })\n  expect(aa.value).toEqual({ target: '123' })\n})\n\ntest('field destroyed or display none should not be assign value from patch initialValues', () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      display: 'none',\n    })\n  )\n\n  aa.initialValue = '123'\n\n  expect(form.values).toEqual({})\n\n  aa.display = 'visible'\n\n  expect(aa.value).toBe('123')\n  expect(form.values).toEqual({ aa: '123' })\n})\n\ntest('onFieldReact with field destroyed', () => {\n  const fn = jest.fn()\n  const obs = observable<any>({ value: 123 })\n  const form = attach(\n    createForm({\n      effects() {\n        onFieldReact('aa', () => {\n          fn(obs.value)\n        })\n      },\n    })\n  )\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  obs.value = '321'\n  expect(fn).toBeCalledTimes(2)\n  aa.destroy()\n  obs.value = '111'\n  expect(fn).toBeCalledTimes(2)\n})\n\ntest('field actions', () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  expect(aa.actions).toEqual({})\n  aa.inject({\n    test: () => 123,\n  })\n  expect(aa.invoke('test')).toEqual(123)\n  aa.inject({\n    test: () => 321,\n  })\n  expect(aa.invoke('test')).toEqual(321)\n})\n\ntest('field hidden value', () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      hidden: true,\n      initialValue: '123',\n    })\n  )\n  expect(form.values).toEqual({ aa: '123' })\n\n  const objectField = attach(\n    form.createObjectField({\n      name: 'object',\n      hidden: true,\n    })\n  )\n  const arrayField = attach(\n    form.createArrayField({\n      name: 'array',\n      hidden: true,\n    })\n  )\n\n  aa.setDisplay('none')\n  objectField.setDisplay('none')\n  arrayField.setDisplay('none')\n  expect(aa.value).toBeUndefined()\n  expect(objectField.value).toBeUndefined()\n  expect(arrayField.value).toBeUndefined()\n\n  aa.setDisplay('hidden')\n  objectField.setDisplay('hidden')\n  arrayField.setDisplay('hidden')\n  expect(aa.value).toEqual('123')\n  expect(objectField.value).toEqual({})\n  expect(arrayField.value).toEqual([])\n})\n\ntest('field destructor path with display none', () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createArrayField({\n      name: '[aa,bb]',\n    })\n  )\n  aa.setDisplay('none')\n  expect(form.values).toEqual({})\n  expect(aa.value).toEqual([])\n})\n\ntest('onInput should ignore HTMLInputEvent propagation', async () => {\n  const form = attach(createForm<any>())\n  const mockHTMLInput = { value: '321' }\n  const mockDomEvent = { target: mockHTMLInput, currentTarget: mockHTMLInput }\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  await aa.onInput(mockDomEvent)\n  expect(aa.value).toEqual('321')\n\n  await aa.onInput({ target: { value: '2' }, currentTarget: { value: '4' } })\n  expect(aa.value).toEqual('321')\n\n  // currentTarget is undefined, skip ignore\n  await aa.onInput({ target: { value: '123' } })\n  expect(aa.value).toEqual('123')\n})\n\ntest('onFocus and onBlur with invalid target value', async () => {\n  const form = attach(createForm<any>())\n  const field = attach(\n    form.createField({\n      name: 'aa',\n      validateFirst: true,\n      value: '111',\n      validator: [\n        {\n          triggerType: 'onFocus',\n          format: 'date',\n        },\n        {\n          triggerType: 'onBlur',\n          format: 'url',\n        },\n      ],\n    })\n  )\n\n  await field.onFocus({ target: {} })\n  expect(field.selfErrors).toEqual([])\n  await field.onBlur({ target: {} })\n  expect(field.selfErrors).toEqual([])\n\n  await field.onFocus()\n  expect(field.selfErrors).toEqual([\n    'The field value is not a valid date format',\n  ])\n  await field.onBlur()\n  expect(field.selfErrors).toEqual([\n    'The field value is not a valid date format',\n    'The field value is a invalid url',\n  ])\n})\n\ntest('validatePattern and validateDisplay', async () => {\n  const form = attach(\n    createForm<any>({\n      validatePattern: ['editable'],\n      validateDisplay: ['visible'],\n    })\n  )\n  const field1 = attach(\n    form.createField({\n      name: 'a',\n      required: true,\n    })\n  )\n  const field2 = attach(\n    form.createField({\n      name: 'b',\n      required: true,\n      validatePattern: ['readOnly'],\n      validateDisplay: ['hidden'],\n    })\n  )\n  const field3 = attach(\n    form.createField({\n      name: 'c',\n      required: true,\n      validatePattern: ['readOnly', 'editable'],\n      validateDisplay: ['hidden', 'visible'],\n    })\n  )\n\n  try {\n    await form.validate()\n  } catch {}\n  expect(field1.selfErrors.length).toBe(1)\n  expect(field2.selfErrors.length).toBe(0)\n  expect(field3.selfErrors.length).toBe(1)\n\n  form.setPattern('readOnly')\n  form.setDisplay('hidden')\n  try {\n    await form.validate()\n  } catch {}\n  expect(field1.selfErrors.length).toBe(0)\n  expect(field2.selfErrors.length).toBe(1)\n  expect(field3.selfErrors.length).toBe(1)\n})\n"
  },
  {
    "path": "packages/core/src/__tests__/form.spec.ts",
    "content": "import { createForm } from '../'\nimport {\n  onFieldValidateStart,\n  onFieldValueChange,\n  onFormInitialValuesChange,\n  onFormValuesChange,\n} from '../effects'\nimport { attach, sleep } from './shared'\nimport { LifeCycleTypes } from '../types'\nimport { observable, batch } from '@formily/reactive'\n\ntest('create form', () => {\n  const form = attach(createForm())\n  expect(form).not.toBeUndefined()\n})\n\ntest('createField/createArrayField/createObjectField/createVoidField', () => {\n  const form = attach(createForm())\n  const normal = attach(\n    form.createField({\n      name: 'normal',\n      basePath: 'parent',\n    })\n  )\n  const normal2 = attach(\n    form.createField({\n      name: 'normal',\n      basePath: 'parent',\n    })\n  )\n  const array_ = attach(\n    form.createArrayField({ name: 'array', basePath: 'parent' })\n  )\n  const array2_ = attach(\n    form.createArrayField({ name: 'array', basePath: 'parent' })\n  )\n  const object_ = attach(\n    form.createObjectField({ name: 'object', basePath: 'parent' })\n  )\n  const object2_ = attach(\n    form.createObjectField({ name: 'object', basePath: 'parent' })\n  )\n  const void_ = attach(\n    form.createVoidField({ name: 'void', basePath: 'parent' })\n  )\n  const void2_ = attach(\n    form.createVoidField({ name: 'void', basePath: 'parent' })\n  )\n  const children_ = attach(\n    form.createField({ name: 'children', basePath: 'parent.void' })\n  )\n  expect(normal).not.toBeUndefined()\n  expect(array_).not.toBeUndefined()\n  expect(object_).not.toBeUndefined()\n  expect(void_).not.toBeUndefined()\n  expect(normal.address.toString()).toEqual('parent.normal')\n  expect(normal.path.toString()).toEqual('parent.normal')\n  expect(array_.address.toString()).toEqual('parent.array')\n  expect(array_.path.toString()).toEqual('parent.array')\n  expect(object_.address.toString()).toEqual('parent.object')\n  expect(object_.path.toString()).toEqual('parent.object')\n  expect(void_.address.toString()).toEqual('parent.void')\n  expect(void_.path.toString()).toEqual('parent.void')\n  expect(children_.address.toString()).toEqual('parent.void.children')\n  expect(children_.path.toString()).toEqual('parent.children')\n  expect(form.createField({ name: '' })).toBeUndefined()\n  expect(form.createArrayField({ name: '' })).toBeUndefined()\n  expect(form.createObjectField({ name: '' })).toBeUndefined()\n  expect(form.createVoidField({ name: '' })).toBeUndefined()\n  expect(array_ === array2_).toBeTruthy()\n  expect(object_ === object2_).toBeTruthy()\n  expect(void_ === void2_).toBeTruthy()\n  expect(normal === normal2).toBeTruthy()\n})\n\ntest('setValues/setInitialValues', () => {\n  const form = attach(createForm())\n  form.setValues({\n    aa: 123,\n    cc: {\n      kk: 321,\n    },\n  })\n  const field = attach(\n    form.createField({\n      name: 'cc.mm',\n      initialValue: 'ooo',\n    })\n  )\n  const field2 = attach(\n    form.createField({\n      name: 'cc.pp',\n      initialValue: 'www',\n    })\n  )\n  expect(form.values.aa).toEqual(123)\n  expect(form.values.cc.kk).toEqual(321)\n  expect(form.values.cc.mm).toEqual('ooo')\n  expect(form.initialValues.cc.mm).toEqual('ooo')\n  expect(form.values.cc.pp).toEqual('www')\n  expect(form.initialValues.cc.pp).toEqual('www')\n  expect(field.value).toEqual('ooo')\n  expect(field2.value).toEqual('www')\n  form.setInitialValues({\n    bb: '123',\n    cc: {\n      dd: 'xxx',\n      pp: 'www2',\n    },\n  })\n  expect(form.values.aa).toEqual(123)\n  expect(form.values.bb).toEqual('123')\n  expect(form.values.cc.kk).toEqual(321)\n  expect(form.values.cc.dd).toEqual('xxx')\n  expect(form.initialValues.bb).toEqual('123')\n  expect(form.initialValues.cc.kk).toBeUndefined()\n  expect(form.initialValues.cc.dd).toEqual('xxx')\n  expect(form.values.cc.mm).toEqual('ooo')\n  expect(form.initialValues.cc.mm).toEqual('ooo')\n  expect(field.value).toEqual('ooo')\n  expect(form.values.cc.pp).toEqual('www2')\n  expect(form.initialValues.cc.pp).toEqual('www2')\n  expect(field2.value).toEqual('www2')\n  form.setInitialValues({}, 'overwrite')\n  expect(form.initialValues?.cc?.pp).toBeUndefined()\n  form.setValues({}, 'overwrite')\n  expect(form.values.aa).toBeUndefined()\n  form.setInitialValues({ aa: { bb: [{ cc: 123 }] } }, 'deepMerge')\n  expect(form.values).toEqual({ aa: { bb: [{ cc: 123 }] } })\n  form.setValues({ bb: { bb: [{ cc: 123 }] } }, 'deepMerge')\n  expect(form.values).toEqual({\n    aa: { bb: [{ cc: 123 }] },\n    bb: { bb: [{ cc: 123 }] },\n  })\n  form.setInitialValues({ aa: [123] }, 'shallowMerge')\n  expect(form.values).toEqual({\n    aa: [123],\n    bb: { bb: [{ cc: 123 }] },\n  })\n  form.setValues({ bb: [123] }, 'shallowMerge')\n  expect(form.values).toEqual({\n    aa: [123],\n    bb: [123],\n  })\n})\n\ntest('no field initialValues merge', () => {\n  const form = attach(\n    createForm<any>({\n      values: {\n        aa: '123',\n      },\n      initialValues: {\n        aa: '333',\n        bb: '321',\n      },\n    })\n  )\n\n  expect(form.values).toEqual({\n    aa: '123',\n    bb: '321',\n  })\n})\n\ntest('setLoading', async () => {\n  const form = attach(createForm())\n  expect(form.loading).toBeFalsy()\n  form.setLoading(true)\n  await sleep(100)\n  expect(form.loading).toBeTruthy()\n})\n\ntest('setValues with null', () => {\n  const form = attach(createForm())\n  form.setInitialValues({\n    'object-1': {\n      'array-1': null,\n    },\n    'object-2': {\n      'array-2': null,\n    },\n  })\n  form.setValues({\n    'object-1': {\n      'array-1': null,\n    },\n    'object-2': {\n      'array-2': null,\n    },\n  })\n  expect(form.values).toEqual({\n    'object-1': {\n      'array-1': null,\n    },\n    'object-2': {\n      'array-2': null,\n    },\n  })\n})\n\ntest('observable values/initialValues', () => {\n  const values: any = observable({\n    aa: 123,\n    bb: 321,\n  })\n  const initialValues: any = observable({\n    cc: 321,\n    dd: 444,\n  })\n  const form = attach(\n    createForm({\n      values,\n      initialValues,\n    })\n  )\n  batch(() => {\n    values.kk = 321\n  })\n  expect(form.values.kk).toEqual(321)\n})\n\ntest('deleteValuesIn/deleteInitialValuesIn', () => {\n  const form = attach(\n    createForm<{\n      aa?: number\n      bb?: number\n    }>({\n      values: {\n        aa: 123,\n      },\n      initialValues: {\n        bb: 123,\n      },\n    })\n  )\n  expect(form.values.aa).toEqual(123)\n  expect(form.values.bb).toEqual(123)\n  form.deleteValuesIn('aa')\n  form.deleteInitialValuesIn('bb')\n  expect(form.existValuesIn('aa')).toBeFalsy()\n  expect(form.existInitialValuesIn('bb')).toBeFalsy()\n})\n\ntest('setSubmitting/setValidating', async () => {\n  const form = attach(createForm())\n  form.setSubmitting(true)\n  expect(form.submitting).toBeFalsy()\n  await sleep()\n  expect(form.submitting).toBeTruthy()\n  form.setSubmitting(false)\n  expect(form.submitting).toBeFalsy()\n  form.setValidating(true)\n  expect(form.validating).toBeFalsy()\n  await sleep()\n  expect(form.validating).toBeTruthy()\n  form.setValidating(false)\n  expect(form.validating).toBeFalsy()\n})\n\ntest('setEffects/addEffects/removeEffects', () => {\n  const form = attach(createForm())\n  const valueChange = jest.fn()\n  const valueChange2 = jest.fn()\n  form.addEffects('e1', () => {\n    onFieldValueChange('aa', valueChange)\n  })\n  const field = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  field.setValue('123')\n  expect(valueChange).toBeCalledTimes(1)\n  form.removeEffects('e1')\n  field.setValue('321')\n  expect(valueChange).toBeCalledTimes(1)\n  form.addEffects('e2', () => {\n    onFieldValueChange('aa', valueChange)\n  })\n  field.setValue('444')\n  expect(valueChange).toBeCalledTimes(2)\n  form.setEffects(() => {\n    onFieldValueChange('aa', valueChange2)\n  })\n  field.setValue('555')\n  expect(valueChange).toBeCalledTimes(3)\n  expect(valueChange2).toBeCalledTimes(1)\n})\n\ntest('query', () => {\n  const form = attach(createForm())\n  attach(\n    form.createObjectField({\n      name: 'object',\n    })\n  )\n  attach(\n    form.createVoidField({\n      name: 'void',\n      basePath: 'object',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'normal',\n      basePath: 'object.void',\n    })\n  )\n  attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  expect(form.query('object').take()).not.toBeUndefined()\n  expect(form.query('object.void').take()).not.toBeUndefined()\n  expect(form.query('object.void.normal').take()).not.toBeUndefined()\n  expect(form.query('object.normal').take()).not.toBeUndefined()\n  expect(form.query('object.*').map((field) => field.path.toString())).toEqual([\n    'object.void',\n    'object.normal',\n  ])\n  expect(form.query('*').map((field) => field.path.toString())).toEqual([\n    'object',\n    'object.void',\n    'object.normal',\n    'array',\n  ])\n  expect(form.query('array').take()).not.toBeUndefined()\n  expect(form.query('*').take()).not.toBeUndefined()\n  expect(form.query('*(oo)').take()).toBeUndefined()\n  expect(form.query('*(oo)').map()).toEqual([])\n  expect(form.query('object.void').get('value')).toBeUndefined()\n  expect(form.query('object.void').get('initialValue')).toBeUndefined()\n  expect(form.query('object.void').get('inputValue')).toBeUndefined()\n  expect(form.query('array').get('value')).toEqual([])\n  expect(form.query('array').get('initialValue')).toBeUndefined()\n  expect(form.query('array').get('inputValue')).toBeNull()\n  form.setFieldState('array', (state) => {\n    state.value = [111]\n    state.initialValue = [111]\n    state.inputValue = [111]\n  })\n  expect(form.query('array').get('value')).toEqual([111])\n  expect(form.query('array').get('initialValue')).toEqual([111])\n  expect(form.query('array').get('inputValue')).toEqual([111])\n  expect(form.query('array').getIn('inputValue')).toEqual([111])\n  expect(form.query('opo').get('value')).toBeUndefined()\n  expect(form.query('opo').getIn('value')).toBeUndefined()\n  expect(form.query('opo').get('initialValue')).toBeUndefined()\n  expect(form.query('opo').get('inputValue')).toBeUndefined()\n})\n\ntest('notify/subscribe/unsubscribe', () => {\n  const form = attach(createForm())\n  const subscribe = jest.fn()\n  const id = form.subscribe(subscribe)\n  expect(subscribe).toBeCalledTimes(0)\n  form.setInitialValues({ aa: 123 })\n  expect(subscribe).toBeCalledTimes(2)\n  expect(form.values).toEqual({ aa: 123 })\n  form.notify(LifeCycleTypes.ON_FORM_SUBMIT)\n  expect(subscribe).toBeCalledTimes(3)\n  form.unsubscribe(id)\n  form.notify(LifeCycleTypes.ON_FORM_SUBMIT)\n  expect(subscribe).toBeCalledTimes(3)\n})\n\ntest('setState/getState/setFormState/getFormState/setFieldState/getFieldState', () => {\n  const form = attach(createForm())\n  const state = form.getState()\n  form.setState((state) => {\n    state.pattern = 'disabled'\n    state.values = { aa: 123 }\n  })\n  expect(form.pattern).toEqual('disabled')\n  expect(form.disabled).toBeTruthy()\n  expect(form.values.aa).toEqual(123)\n  form.setState(state)\n  expect(form.pattern).toEqual('editable')\n  expect(form.disabled).toBeFalsy()\n  expect(form.values.aa).toBeUndefined()\n  form.setFormState((state) => {\n    state.pattern = 'readOnly'\n    state.values = { bb: 321 }\n  })\n  expect(form.pattern).toEqual('readOnly')\n  expect(form.disabled).toBeFalsy()\n  expect(form.readOnly).toBeTruthy()\n  expect(form.values.aa).toBeUndefined()\n  expect(form.values.bb).toEqual(321)\n  form.setFormState(state)\n  expect(form.pattern).toEqual('editable')\n  expect(form.disabled).toBeFalsy()\n  expect(form.readOnly).toBeFalsy()\n  expect(form.values.aa).toBeUndefined()\n  expect(form.values.bb).toBeUndefined()\n  attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  const fieldState = form.getFieldState('aa')\n  form.setFieldState('aa', (state) => {\n    state.title = 'AA'\n    state.description = 'This is AA'\n    state.value = '123'\n  })\n  expect(form.getFieldState('aa', (state) => state.title)).toEqual('AA')\n  expect(form.getFieldState('aa', (state) => state.description)).toEqual(\n    'This is AA'\n  )\n  expect(form.getFieldState('aa', (state) => state.value)).toEqual('123')\n  form.setFieldState('aa', fieldState)\n  expect(form.getFieldState('aa', (state) => state.title)).toBeUndefined()\n  expect(form.getFieldState('aa', (state) => state.description)).toBeUndefined()\n  expect(form.getFieldState('aa', (state) => state.value)).toBeUndefined()\n  form.setState((state) => {\n    state.display = 'none'\n  })\n  expect(form.getFieldState('aa', (state) => state.visible)).toBeFalsy()\n  const update = (value: any) => (state: any) => {\n    state.value = value\n  }\n  const update2 = (state: any) => {\n    state.value = 123\n  }\n  form.setFieldState('kk', update(123))\n  form.setFieldState('kk', update(321))\n  form.setFieldState('oo', update2)\n  form.setFieldState('oo', update2)\n  const oo = attach(\n    form.createField({\n      name: 'oo',\n    })\n  )\n  const kk = attach(\n    form.createField({\n      name: 'kk',\n    })\n  )\n  expect(oo.value).toBeUndefined()\n  expect(kk.value).toBeUndefined()\n})\n\ntest('validate/valid/invalid/errors/warnings/successes/clearErrors/clearWarnings/clearSuccesses/queryFeedbacks', async () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      required: true,\n      validator(value) {\n        if (value == '123') {\n          return {\n            type: 'success',\n            message: 'success',\n          }\n        } else if (value == '321') {\n          return {\n            type: 'warning',\n            message: 'warning',\n          }\n        } else if (value == '111') {\n          return 'error'\n        }\n      },\n    })\n  )\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n      required: true,\n    })\n  )\n  attach(\n    form.createVoidField({\n      name: 'cc',\n    })\n  )\n  try {\n    await form.validate()\n  } catch {}\n  expect(form.invalid).toBeTruthy()\n  expect(form.valid).toBeFalsy()\n  expect(form.errors).toEqual([\n    {\n      type: 'error',\n      address: 'aa',\n      path: 'aa',\n      code: 'ValidateError',\n      triggerType: 'onInput',\n      messages: ['The field value is required'],\n    },\n    {\n      type: 'error',\n      address: 'bb',\n      path: 'bb',\n      code: 'ValidateError',\n      triggerType: 'onInput',\n      messages: ['The field value is required'],\n    },\n  ])\n  await aa.onInput('123')\n  expect(form.errors).toEqual([\n    {\n      type: 'error',\n      address: 'bb',\n      path: 'bb',\n      code: 'ValidateError',\n      triggerType: 'onInput',\n      messages: ['The field value is required'],\n    },\n  ])\n  expect(form.successes).toEqual([\n    {\n      type: 'success',\n      address: 'aa',\n      path: 'aa',\n      code: 'ValidateSuccess',\n      triggerType: 'onInput',\n      messages: ['success'],\n    },\n  ])\n  await aa.onInput('321')\n  expect(form.errors).toEqual([\n    {\n      type: 'error',\n      address: 'bb',\n      path: 'bb',\n      code: 'ValidateError',\n      triggerType: 'onInput',\n      messages: ['The field value is required'],\n    },\n  ])\n  expect(form.warnings).toEqual([\n    {\n      type: 'warning',\n      address: 'aa',\n      path: 'aa',\n      code: 'ValidateWarning',\n      triggerType: 'onInput',\n      messages: ['warning'],\n    },\n  ])\n  await aa.onInput('111')\n  expect(form.errors).toEqual([\n    {\n      type: 'error',\n      address: 'aa',\n      path: 'aa',\n      code: 'ValidateError',\n      triggerType: 'onInput',\n      messages: ['error'],\n    },\n    {\n      type: 'error',\n      address: 'bb',\n      path: 'bb',\n      code: 'ValidateError',\n      triggerType: 'onInput',\n      messages: ['The field value is required'],\n    },\n  ])\n  await aa.onInput('yes')\n  await bb.onInput('yes')\n  await form.validate()\n  expect(form.invalid).toBeFalsy()\n  expect(form.valid).toBeTruthy()\n  expect(form.errors).toEqual([])\n  expect(form.successes).toEqual([])\n  expect(form.warnings).toEqual([])\n  await aa.onInput('')\n  await bb.onInput('')\n  try {\n    await form.validate()\n  } catch {}\n  expect(form.errors).toEqual([\n    {\n      type: 'error',\n      address: 'aa',\n      path: 'aa',\n      code: 'ValidateError',\n      triggerType: 'onInput',\n      messages: ['The field value is required'],\n    },\n    {\n      type: 'error',\n      address: 'bb',\n      path: 'bb',\n      code: 'ValidateError',\n      triggerType: 'onInput',\n      messages: ['The field value is required'],\n    },\n  ])\n  form.clearErrors('aa')\n  expect(form.errors).toEqual([\n    {\n      type: 'error',\n      address: 'bb',\n      path: 'bb',\n      code: 'ValidateError',\n      triggerType: 'onInput',\n      messages: ['The field value is required'],\n    },\n  ])\n  form.clearErrors('*')\n  expect(form.errors).toEqual([])\n  await aa.onInput('123')\n  expect(form.errors).toEqual([])\n  expect(form.successes).toEqual([\n    {\n      type: 'success',\n      address: 'aa',\n      path: 'aa',\n      code: 'ValidateSuccess',\n      triggerType: 'onInput',\n      messages: ['success'],\n    },\n  ])\n  form.clearSuccesses('aa')\n  expect(form.successes).toEqual([])\n  await aa.onInput('321')\n  expect(form.errors).toEqual([])\n  expect(form.successes).toEqual([])\n  expect(form.warnings).toEqual([\n    {\n      type: 'warning',\n      address: 'aa',\n      path: 'aa',\n      code: 'ValidateWarning',\n      triggerType: 'onInput',\n      messages: ['warning'],\n    },\n  ])\n  form.clearWarnings('*')\n  expect(form.errors).toEqual([])\n  expect(form.successes).toEqual([])\n  expect(form.warnings).toEqual([])\n  await aa.onInput('123')\n  await bb.onInput('')\n  expect(\n    form.queryFeedbacks({\n      type: 'error',\n    }).length\n  ).toEqual(1)\n  expect(\n    form.queryFeedbacks({\n      type: 'success',\n    }).length\n  ).toEqual(1)\n  expect(\n    form.queryFeedbacks({\n      code: 'ValidateError',\n    }).length\n  ).toEqual(1)\n  expect(\n    form.queryFeedbacks({\n      code: 'ValidateSuccess',\n    }).length\n  ).toEqual(1)\n  expect(\n    form.queryFeedbacks({\n      code: 'EffectError',\n    }).length\n  ).toEqual(0)\n  expect(\n    form.queryFeedbacks({\n      code: 'EffectSuccess',\n    }).length\n  ).toEqual(0)\n  expect(\n    form.queryFeedbacks({\n      path: 'aa',\n    }).length\n  ).toEqual(1)\n  expect(\n    form.queryFeedbacks({\n      path: 'bb',\n    }).length\n  ).toEqual(1)\n  expect(\n    form.queryFeedbacks({\n      address: 'aa',\n    }).length\n  ).toEqual(1)\n  expect(\n    form.queryFeedbacks({\n      address: 'bb',\n    }).length\n  ).toEqual(1)\n  aa.setValue('')\n  bb.setValue('')\n  form.clearErrors()\n  form.clearSuccesses()\n  form.clearWarnings()\n  try {\n    await form.validate('aa')\n  } catch {}\n  expect(\n    form.queryFeedbacks({\n      type: 'error',\n    }).length\n  ).toEqual(1)\n  try {\n    await form.validate('*')\n  } catch {}\n  expect(\n    form.queryFeedbacks({\n      type: 'error',\n    }).length\n  ).toEqual(2)\n})\n\ntest('setPattern/pattern/editable/readOnly/disabled/readPretty', () => {\n  const form = attach(\n    createForm({\n      pattern: 'disabled',\n    })\n  )\n  const field = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  expect(form.pattern).toEqual('disabled')\n  expect(form.disabled).toBeTruthy()\n  expect(field.pattern).toEqual('disabled')\n  expect(field.disabled).toBeTruthy()\n  form.setPattern('readOnly')\n  expect(form.pattern).toEqual('readOnly')\n  expect(form.readOnly).toBeTruthy()\n  expect(field.pattern).toEqual('readOnly')\n  expect(field.readOnly).toBeTruthy()\n  form.setPattern('readPretty')\n  expect(form.pattern).toEqual('readPretty')\n  expect(form.readPretty).toBeTruthy()\n  expect(field.pattern).toEqual('readPretty')\n  expect(field.readPretty).toBeTruthy()\n  const form2 = attach(\n    createForm({\n      editable: false,\n    })\n  )\n  expect(form2.pattern).toEqual('readPretty')\n  expect(form2.readPretty).toBeTruthy()\n  const form3 = attach(\n    createForm({\n      disabled: true,\n    })\n  )\n  expect(form3.pattern).toEqual('disabled')\n  expect(form3.disabled).toBeTruthy()\n  const form4 = attach(\n    createForm({\n      readOnly: true,\n    })\n  )\n  expect(form4.pattern).toEqual('readOnly')\n  expect(form4.readOnly).toBeTruthy()\n  const form5 = attach(\n    createForm({\n      readPretty: true,\n    })\n  )\n  expect(form5.pattern).toEqual('readPretty')\n  expect(form5.readPretty).toBeTruthy()\n})\n\ntest('setDisplay/display/visible/hidden', () => {\n  const form = attach(\n    createForm({\n      display: 'hidden',\n    })\n  )\n  const field = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  expect(form.display).toEqual('hidden')\n  expect(form.hidden).toBeTruthy()\n  expect(field.display).toEqual('hidden')\n  expect(field.hidden).toBeTruthy()\n  form.setDisplay('visible')\n  expect(form.display).toEqual('visible')\n  expect(form.visible).toBeTruthy()\n  expect(field.display).toEqual('visible')\n  expect(field.visible).toBeTruthy()\n  form.setDisplay('none')\n  expect(form.display).toEqual('none')\n  expect(form.visible).toBeFalsy()\n  expect(field.display).toEqual('none')\n  expect(field.visible).toBeFalsy()\n  const form2 = attach(\n    createForm({\n      hidden: true,\n    })\n  )\n  expect(form2.display).toEqual('hidden')\n  expect(form2.hidden).toBeTruthy()\n  expect(form2.visible).toBeFalsy()\n  const form3 = attach(\n    createForm({\n      visible: false,\n    })\n  )\n  expect(form3.display).toEqual('none')\n  expect(form3.visible).toBeFalsy()\n})\n\ntest('submit', async () => {\n  const form = attach(createForm())\n  const onSubmit = jest.fn()\n  const field = attach(\n    form.createField({\n      name: 'aa',\n      required: true,\n    })\n  )\n  let errors1: Error\n  try {\n    await form.submit(onSubmit)\n  } catch (e) {\n    errors1 = e\n  }\n  expect(errors1).not.toBeUndefined()\n  expect(onSubmit).toBeCalledTimes(0)\n  field.onInput('123')\n  await form.submit(onSubmit)\n  expect(onSubmit).toBeCalledTimes(1)\n  let errors2: Error\n  try {\n    await form.submit(() => {\n      throw new Error('xxx')\n    })\n  } catch (e) {\n    errors2 = e\n  }\n  expect(errors2).not.toBeUndefined()\n  expect(form.valid).toBeTruthy()\n})\n\ntest('reset', async () => {\n  const form = attach(\n    createForm<{\n      aa?: number\n      bb?: number\n    }>({\n      values: {\n        bb: 123,\n      },\n      initialValues: {\n        aa: 123,\n      },\n    })\n  )\n  const field = attach(\n    form.createField({\n      name: 'aa',\n      required: true,\n    })\n  )\n  const field2 = attach(\n    form.createField({\n      name: 'bb',\n      required: true,\n    })\n  )\n  attach(\n    form.createVoidField({\n      name: 'cc',\n    })\n  )\n  expect(field.value).toEqual(123)\n  expect(field2.value).toEqual(123)\n  expect(form.values.aa).toEqual(123)\n  expect(form.values.bb).toEqual(123)\n  field.onInput('xxxxx')\n  expect(form.values.aa).toEqual('xxxxx')\n  try {\n    await form.reset()\n  } catch {}\n  expect(form.valid).toBeTruthy()\n  expect(form.values.aa).toEqual(123)\n  expect(field.value).toEqual(123)\n  expect(form.values.bb).toBeUndefined()\n  expect(field2.value).toBeUndefined()\n  field.onInput('aaa')\n  field2.onInput('bbb')\n  expect(form.valid).toBeTruthy()\n  expect(form.values.aa).toEqual('aaa')\n  expect(field.value).toEqual('aaa')\n  expect(form.values.bb).toEqual('bbb')\n  expect(field2.value).toEqual('bbb')\n  try {\n    await form.reset('*', {\n      validate: true,\n    })\n  } catch {}\n  expect(form.valid).toBeFalsy()\n  expect(form.values.aa).toEqual(123)\n  expect(field.value).toEqual(123)\n  expect(form.values.bb).toBeUndefined()\n  expect(field2.value).toBeUndefined()\n  field.onInput('aaa')\n  field2.onInput('bbb')\n  try {\n    await form.reset('*', {\n      forceClear: true,\n    })\n  } catch {}\n  expect(form.valid).toBeTruthy()\n  expect(form.values.aa).toBeUndefined()\n  expect(field.value).toBeUndefined()\n  expect(form.values.bb).toBeUndefined()\n  expect(field2.value).toBeUndefined()\n  field.onInput('aaa')\n  field2.onInput('bbb')\n  try {\n    await form.reset('aa', {\n      forceClear: true,\n    })\n  } catch {}\n  expect(form.valid).toBeTruthy()\n  expect(form.values.aa).toBeUndefined()\n  expect(field.value).toBeUndefined()\n  expect(form.values.bb).toEqual('bbb')\n  expect(field2.value).toEqual('bbb')\n})\n\ntest('devtools', () => {\n  // @ts-ignore\n  window['__FORMILY_DEV_TOOLS_HOOK__'] = {\n    inject() {},\n    unmount() {},\n  }\n  const form = attach(createForm())\n  form.onUnmount()\n})\n\ntest('reset array field', async () => {\n  const form = attach(\n    createForm({\n      values: {\n        array: [{ value: 123 }],\n      },\n    })\n  )\n  attach(\n    form.createArrayField({\n      name: 'array',\n      required: true,\n    })\n  )\n  expect(form.values).toEqual({\n    array: [{ value: 123 }],\n  })\n  await form.reset('*', {\n    forceClear: true,\n  })\n  expect(form.values).toEqual({\n    array: [],\n  })\n})\n\ntest('reset object field', async () => {\n  const form = attach(\n    createForm({\n      values: {\n        object: { value: 123 },\n      },\n    })\n  )\n  attach(\n    form.createObjectField({\n      name: 'object',\n      required: true,\n    })\n  )\n  expect(form.values).toEqual({\n    object: { value: 123 },\n  })\n  await form.reset('*', {\n    forceClear: true,\n  })\n  expect(form.values).toEqual({\n    object: {},\n  })\n})\n\ntest('initialValues merge values before create field', () => {\n  const form = attach(createForm())\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  form.values.array = [{ aa: '321' }]\n  const arr_0_aa = attach(\n    form.createField({\n      name: 'aa',\n      basePath: 'array.0',\n      initialValue: '123',\n    })\n  )\n  expect(array.value).toEqual([{ aa: '321' }])\n  expect(arr_0_aa.value).toEqual('321')\n})\n\ntest('no patch with empty initialValues', () => {\n  const form = attach(\n    createForm({\n      values: {\n        array: [1, 2, 3],\n      },\n    })\n  )\n  attach(\n    form.createObjectField({\n      name: 'array.0.1',\n    })\n  )\n\n  expect(form.values).toEqual({\n    array: [1, 2, 3],\n  })\n})\n\ntest('initialValues merge values after create field', () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createArrayField({\n      name: 'aa',\n      initialValue: '111',\n    })\n  )\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  const arr_0_aa = attach(\n    form.createField({\n      name: 'aa',\n      basePath: 'array.0',\n      initialValue: '123',\n    })\n  )\n  form.values.aa = '222'\n  form.values.array = [{ aa: '321' }]\n  expect(array.value).toEqual([{ aa: '321' }])\n  expect(arr_0_aa.value).toEqual('321')\n  expect(aa.value).toEqual('222')\n})\n\ntest('remove property of form values with undefined value', () => {\n  const form = attach(createForm())\n  const field = attach(\n    form.createField({\n      name: 'aaa',\n      initialValue: 123,\n    })\n  )\n  expect(form.values).toMatchObject({ aaa: 123 })\n  field.display = 'none'\n  expect(form.values.hasOwnProperty('aaa')).toBeFalsy()\n  field.display = 'visible'\n  expect(form.values.hasOwnProperty('aaa')).toBeTruthy()\n  field.setValue(undefined)\n  expect(form.values.hasOwnProperty('aaa')).toBeTruthy()\n})\n\ntest('empty array initialValues', () => {\n  const form = attach(\n    createForm({\n      initialValues: {\n        aa: [0],\n        bb: [''],\n        cc: [],\n        dd: [null],\n        ee: [undefined],\n      },\n    })\n  )\n  form.createArrayField({\n    name: 'aa',\n  })\n  form.createArrayField({\n    name: 'bb',\n  })\n  form.createArrayField({\n    name: 'cc',\n  })\n  form.createArrayField({\n    name: 'dd',\n  })\n  form.createArrayField({\n    name: 'ee',\n  })\n  expect(form.values.aa).toEqual([0])\n  expect(form.values.bb).toEqual([''])\n  expect(form.values.cc).toEqual([])\n  expect(form.values.dd).toEqual([null])\n  expect(form.values.ee).toEqual([undefined])\n})\n\ntest('form lifecycle can be triggered after call form.setXXX', () => {\n  let initialValuesTriggerNum = 0\n  let valuesTriggerNum = 0\n\n  const form = attach(\n    createForm<{\n      aa?: number\n      bb?: number\n    }>({\n      initialValues: {\n        aa: 1,\n      },\n      values: {\n        bb: 1,\n      },\n    })\n  )\n\n  form.setEffects(() => {\n    onFormInitialValuesChange(() => {\n      initialValuesTriggerNum++\n    })\n\n    onFormValuesChange(() => {\n      valuesTriggerNum++\n    })\n  })\n\n  expect(initialValuesTriggerNum).toEqual(0)\n  expect(valuesTriggerNum).toEqual(0)\n\n  form.initialValues.aa = 2\n  form.values.bb = 2\n\n  expect(initialValuesTriggerNum).toEqual(1)\n  // initialValues 会通过 applyValuesPatch 改变 values，导致 onFormValuesChange 多触发一次\n  expect(valuesTriggerNum).toEqual(2)\n\n  form.setInitialValues({ aa: 3 })\n  form.setValues({ bb: 3 })\n\n  expect(initialValuesTriggerNum).toEqual(2)\n  expect(valuesTriggerNum).toEqual(4)\n\n  // 测试 form.setXXX 之后还能正常触发：https://github.com/alibaba/formily/issues/1675\n  form.initialValues.aa = 4\n  form.values.bb = 4\n\n  expect(initialValuesTriggerNum).toEqual(3)\n  expect(valuesTriggerNum).toEqual(6)\n})\n\ntest('form values change with array field(default value)', async () => {\n  const handler = jest.fn()\n  const form = attach(\n    createForm({\n      effects() {\n        onFormValuesChange(handler)\n      },\n    })\n  )\n  const array = attach(\n    form.createArrayField({\n      name: 'array',\n      initialValue: [\n        {\n          hello: 'world',\n        },\n      ],\n    })\n  )\n  await array.push({})\n  expect(handler).toBeCalledTimes(2)\n})\n\ntest('setValues deep merge', () => {\n  const form = attach(\n    createForm({\n      initialValues: {\n        aa: {\n          bb: 123,\n          cc: 321,\n          dd: [11, 22, 33],\n        },\n      },\n    })\n  )\n  expect(form.values).toEqual({\n    aa: {\n      bb: 123,\n      cc: 321,\n      dd: [11, 22, 33],\n    },\n  })\n  form.setValues({\n    aa: {\n      bb: '',\n      cc: '',\n      dd: [44, 55, 66],\n    },\n  })\n  expect(form.values).toEqual({\n    aa: {\n      bb: '',\n      cc: '',\n      dd: [44, 55, 66],\n    },\n  })\n})\n\ntest('exception validate', async () => {\n  const form = attach(createForm())\n  attach(\n    form.createField({\n      name: 'aa',\n      validator() {\n        throw new Error('runtime error')\n      },\n    })\n  )\n  try {\n    await form.validate()\n  } catch {}\n  expect(form.invalid).toBeTruthy()\n  expect(form.validating).toBeFalsy()\n})\n\ntest('designable form', () => {\n  const form = attach(\n    createForm({\n      designable: true,\n    })\n  )\n  attach(\n    form.createField({\n      name: 'bb',\n      initialValue: 123,\n    })\n  )\n  attach(\n    form.createField({\n      name: 'bb',\n      initialValue: 321,\n    })\n  )\n  attach(\n    form.createField({\n      name: 'aa',\n      value: 123,\n    })\n  )\n  attach(\n    form.createField({\n      name: 'aa',\n      value: 321,\n    })\n  )\n  expect(form.values.aa).toEqual(321)\n  expect(form.initialValues.bb).toEqual(321)\n})\n\ntest('validate will skip display none', async () => {\n  const validateA = jest.fn()\n  const validateB = jest.fn()\n  const form = attach(\n    createForm({\n      effects() {\n        onFieldValidateStart('aa', validateA)\n        onFieldValidateStart('bb', validateB)\n      },\n    })\n  )\n  const validator = jest.fn()\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      validator() {\n        validator()\n        return 'error'\n      },\n    })\n  )\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n      validator() {\n        validator()\n        return 'error'\n      },\n    })\n  )\n  try {\n    await form.validate()\n  } catch (e) {\n    expect(e).toEqual([\n      {\n        triggerType: 'onInput',\n        type: 'error',\n        code: 'ValidateError',\n        messages: ['error'],\n        address: 'aa',\n        path: 'aa',\n      },\n      {\n        triggerType: 'onInput',\n        type: 'error',\n        code: 'ValidateError',\n        messages: ['error'],\n        address: 'bb',\n        path: 'bb',\n      },\n    ])\n  }\n  expect(validateA).toBeCalledTimes(1)\n  expect(validateB).toBeCalledTimes(1)\n  expect(aa.invalid).toBeTruthy()\n  expect(bb.invalid).toBeTruthy()\n  expect(validator).toBeCalledTimes(2)\n  aa.display = 'none'\n  try {\n    await form.validate()\n  } catch (e) {\n    expect(e).toEqual([\n      {\n        triggerType: 'onInput',\n        type: 'error',\n        code: 'ValidateError',\n        messages: ['error'],\n        address: 'bb',\n        path: 'bb',\n      },\n    ])\n  }\n  expect(validateA).toBeCalledTimes(1)\n  expect(validateB).toBeCalledTimes(2)\n  expect(aa.invalid).toBeFalsy()\n  expect(bb.invalid).toBeTruthy()\n  expect(validator).toBeCalledTimes(3)\n  bb.display = 'none'\n  await form.validate()\n  expect(validateA).toBeCalledTimes(1)\n  expect(validateB).toBeCalledTimes(2)\n  expect(aa.invalid).toBeFalsy()\n  expect(bb.invalid).toBeFalsy()\n  expect(validator).toBeCalledTimes(3)\n})\n\ntest('validate will skip unmounted', async () => {\n  const validateA = jest.fn()\n  const validateB = jest.fn()\n  const form = attach(\n    createForm({\n      effects() {\n        onFieldValidateStart('aa', validateA)\n        onFieldValidateStart('bb', validateB)\n      },\n    })\n  )\n  const validator = jest.fn()\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      validator() {\n        validator()\n        return 'error'\n      },\n    })\n  )\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n      validator() {\n        validator()\n        return 'error'\n      },\n    })\n  )\n  try {\n    await form.validate()\n  } catch (e) {\n    expect(e).toEqual([\n      {\n        triggerType: 'onInput',\n        type: 'error',\n        code: 'ValidateError',\n        messages: ['error'],\n        address: 'aa',\n        path: 'aa',\n      },\n      {\n        triggerType: 'onInput',\n        type: 'error',\n        code: 'ValidateError',\n        messages: ['error'],\n        address: 'bb',\n        path: 'bb',\n      },\n    ])\n  }\n  expect(validateA).toBeCalledTimes(1)\n  expect(validateB).toBeCalledTimes(1)\n  expect(aa.invalid).toBeTruthy()\n  expect(bb.invalid).toBeTruthy()\n  expect(validator).toBeCalledTimes(2)\n  aa.onUnmount()\n  try {\n    await form.validate()\n  } catch (e) {\n    expect(e).toEqual([\n      {\n        triggerType: 'onInput',\n        type: 'error',\n        code: 'ValidateError',\n        messages: ['error'],\n        address: 'aa',\n        path: 'aa',\n      },\n      {\n        triggerType: 'onInput',\n        type: 'error',\n        code: 'ValidateError',\n        messages: ['error'],\n        address: 'bb',\n        path: 'bb',\n      },\n    ])\n  }\n  expect(validateA).toBeCalledTimes(2)\n  expect(validateB).toBeCalledTimes(2)\n  expect(aa.invalid).toBeTruthy()\n  expect(bb.invalid).toBeTruthy()\n  expect(validator).toBeCalledTimes(4)\n  form.clearFormGraph('*(aa,bb)')\n  await form.validate()\n  expect(validateA).toBeCalledTimes(2)\n  expect(validateB).toBeCalledTimes(2)\n  expect(aa.invalid).toBeFalsy()\n  expect(bb.invalid).toBeFalsy()\n  expect(validator).toBeCalledTimes(4)\n})\n\ntest('validate will skip uneditable', async () => {\n  const validateA = jest.fn()\n  const validateB = jest.fn()\n  const form = attach(\n    createForm({\n      effects() {\n        onFieldValidateStart('aa', validateA)\n        onFieldValidateStart('bb', validateB)\n      },\n    })\n  )\n  const validator = jest.fn()\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n      validator() {\n        validator()\n        return 'error'\n      },\n    })\n  )\n  const bb = attach(\n    form.createField({\n      name: 'bb',\n      validator() {\n        validator()\n        return 'error'\n      },\n    })\n  )\n  try {\n    await form.validate()\n  } catch (e) {\n    expect(e).toEqual([\n      {\n        triggerType: 'onInput',\n        type: 'error',\n        code: 'ValidateError',\n        messages: ['error'],\n        address: 'aa',\n        path: 'aa',\n      },\n      {\n        triggerType: 'onInput',\n        type: 'error',\n        code: 'ValidateError',\n        messages: ['error'],\n        address: 'bb',\n        path: 'bb',\n      },\n    ])\n  }\n  expect(validateA).toBeCalledTimes(1)\n  expect(validateB).toBeCalledTimes(1)\n  expect(aa.invalid).toBeTruthy()\n  expect(bb.invalid).toBeTruthy()\n  expect(validator).toBeCalledTimes(2)\n  aa.editable = false\n  try {\n    await form.validate()\n  } catch (e) {\n    expect(e).toEqual([\n      {\n        triggerType: 'onInput',\n        type: 'error',\n        code: 'ValidateError',\n        messages: ['error'],\n        address: 'bb',\n        path: 'bb',\n      },\n    ])\n  }\n  expect(validateA).toBeCalledTimes(1)\n  expect(validateB).toBeCalledTimes(2)\n  expect(aa.invalid).toBeFalsy()\n  expect(bb.invalid).toBeTruthy()\n  expect(validator).toBeCalledTimes(3)\n  bb.editable = false\n  await form.validate()\n  expect(validateA).toBeCalledTimes(1)\n  expect(validateB).toBeCalledTimes(2)\n  expect(aa.invalid).toBeFalsy()\n  expect(bb.invalid).toBeFalsy()\n  expect(validator).toBeCalledTimes(3)\n})\n\ntest('validator order with format', async () => {\n  const form = attach(createForm())\n\n  attach(\n    form.createField({\n      name: 'aa',\n      required: true,\n      validator: {\n        format: 'url',\n        message: 'custom',\n      },\n    })\n  )\n\n  attach(\n    form.createField({\n      name: 'bb',\n      required: true,\n      validator: (value) => {\n        if (!value) return ''\n        return value !== '111' ? 'custom' : ''\n      },\n    })\n  )\n  const results = await form.submit<any[]>(() => {}).catch((e) => e)\n  expect(results.map(({ messages }) => messages)).toEqual([\n    ['The field value is required'],\n    ['The field value is required'],\n  ])\n})\n\ntest('form unmount can not effect field values', () => {\n  const form = attach(\n    createForm({\n      values: {\n        aa: '123',\n      },\n    })\n  )\n  attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  expect(form.values.aa).toEqual('123')\n  form.onUnmount()\n  expect(form.values.aa).toEqual('123')\n})\n\ntest('form clearFormGraph need clear field values', () => {\n  const form = attach(\n    createForm({\n      values: {\n        aa: '123',\n      },\n    })\n  )\n  attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  expect(form.values.aa).toEqual('123')\n  form.clearFormGraph('*')\n  expect(form.values.aa).toBeUndefined()\n})\n\ntest('form clearFormGraph not clear field values', () => {\n  const form = attach(\n    createForm({\n      values: {\n        aa: '123',\n      },\n    })\n  )\n  attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  expect(form.values.aa).toEqual('123')\n  form.clearFormGraph('*', false)\n  expect(form.values.aa).toEqual('123')\n})\n\ntest('form values auto clean with visible false', () => {\n  const form = attach(\n    createForm({\n      initialValues: {\n        aa: '123',\n        bb: '321',\n        cc: 'cc',\n      },\n    })\n  )\n  attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'bb',\n      reactions: (field) => {\n        field.visible = form.values.aa === '1233'\n      },\n    })\n  )\n  attach(\n    form.createField({\n      name: 'cc',\n    })\n  )\n\n  expect(form.values).toEqual({\n    aa: '123',\n    cc: 'cc',\n  })\n})\n\ntest('form values auto clean with visible false in async setInitialValues', () => {\n  const form = attach(createForm())\n  attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'bb',\n      reactions: (field) => {\n        field.visible = form.values.aa === '1233'\n      },\n    })\n  )\n  attach(\n    form.createField({\n      name: 'cc',\n    })\n  )\n\n  form.setInitialValues({\n    aa: '123',\n    bb: '321',\n    cc: 'cc',\n  })\n\n  expect(form.values).toEqual({\n    aa: '123',\n    cc: 'cc',\n  })\n})\n\ntest('form values ref should not changed with setValues', () => {\n  const form = attach(\n    createForm({\n      values: {\n        aa: '123',\n      },\n    })\n  )\n  const values = form.values\n  form.setValues({\n    bb: '321',\n  })\n  expect(form.values === values).toBeTruthy()\n})\n\ntest('form initial values ref should not changed with setInitialValues', () => {\n  const form = attach(\n    createForm({\n      initialValues: {\n        aa: '123',\n      },\n    })\n  )\n  const values = form.initialValues\n  form.setInitialValues({\n    bb: '321',\n  })\n  expect(form.initialValues === values).toBeTruthy()\n})\n\ntest('form query undefined query should not throw error', () => {\n  const form = attach(createForm())\n\n  ;(form.fields as any)['a'] = undefined\n  expect(() => form.query('*').take()).not.toThrowError()\n  expect(Object.keys(form.fields)).toEqual([])\n})\n"
  },
  {
    "path": "packages/core/src/__tests__/graph.spec.ts",
    "content": "import { createForm } from '../'\nimport { isVoidField } from '../shared/checkers'\nimport { attach } from './shared'\n\ntest('getGraph/setGraph', () => {\n  const form = attach(createForm())\n  attach(\n    form.createField({\n      name: 'normal',\n    })\n  )\n  attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  attach(\n    form.createObjectField({\n      name: 'object',\n    })\n  )\n  attach(\n    form.createVoidField({\n      name: 'void',\n    })\n  )\n  form.query('normal').take((field) => {\n    if (isVoidField(field)) return\n    field.selfErrors = ['error']\n  })\n  const graph = form.getFormGraph()\n  form.clearFormGraph()\n  form.setFormGraph(graph)\n  const graph2 = form.getFormGraph()\n  expect(graph).toEqual(graph2)\n  form.setFormGraph({\n    object: {\n      value: 123,\n    },\n  })\n  expect(form.query('object').get('value')).toEqual(123)\n})\n\ntest('clearFormGraph', () => {\n  const form = attach(createForm())\n  attach(\n    form.createField({\n      name: 'normal',\n    })\n  )\n  attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  attach(\n    form.createObjectField({\n      name: 'object',\n    })\n  )\n  form.clearFormGraph('normal')\n  expect(form.fields['normal']).toBeUndefined()\n  expect(form.fields['array']).not.toBeUndefined()\n})\n"
  },
  {
    "path": "packages/core/src/__tests__/heart.spec.ts",
    "content": "import { Heart, LifeCycle } from '../models'\n\ntest('buildLifecycles', () => {\n  const heart = new Heart({\n    lifecycles: [{} as any, [{}], 123],\n  })\n  expect(heart.lifecycles.length).toEqual(0)\n})\n\ntest('clear heart', () => {\n  const handler = jest.fn()\n  const heart = new Heart({\n    lifecycles: [new LifeCycle('event', handler)],\n  })\n  heart.publish('event')\n  expect(handler).toBeCalledTimes(1)\n  heart.clear()\n  heart.publish('event')\n  expect(handler).toBeCalledTimes(1)\n  heart.publish({})\n})\n\ntest('set lifecycles', () => {\n  const handler = jest.fn()\n  const heart = new Heart()\n  heart.setLifeCycles([new LifeCycle('event', handler)])\n  heart.publish('event')\n  expect(handler).toBeCalledTimes(1)\n  heart.setLifeCycles()\n})\n\ntest('add/remove lifecycle', () => {\n  const handler = jest.fn()\n  const heart = new Heart()\n  heart.addLifeCycles('xxx', [new LifeCycle('event', handler)])\n  heart.addLifeCycles('yyy')\n  heart.publish('event')\n  expect(handler).toBeCalledTimes(1)\n  heart.removeLifeCycles('xxx')\n  heart.publish('event')\n  expect(handler).toBeCalledTimes(1)\n})\n\ntest('add/clear lifecycle', () => {\n  const handler = jest.fn()\n  const heart = new Heart()\n  heart.addLifeCycles('xxx', [new LifeCycle('event', handler)])\n  heart.addLifeCycles('yyy')\n  heart.publish('event')\n  expect(handler).toBeCalledTimes(1)\n  heart.clear()\n  heart.publish('event')\n  expect(handler).toBeCalledTimes(1)\n})\n"
  },
  {
    "path": "packages/core/src/__tests__/internals.spec.ts",
    "content": "import {\n  getValuesFromEvent,\n  matchFeedback,\n  patchFieldStates,\n  deserialize,\n  isHTMLInputEvent,\n} from '../shared/internals'\nimport { createForm } from '../'\nimport { attach } from './shared'\n\ntest('getValuesFromEvent', () => {\n  expect(getValuesFromEvent([{ target: { value: 123 } }])).toEqual([123])\n  expect(getValuesFromEvent([{ target: { checked: true } }])).toEqual([true])\n  expect(getValuesFromEvent([{ target: {} }])).toEqual([undefined])\n  expect(getValuesFromEvent([{ target: null }])).toEqual([{ target: null }])\n  expect(getValuesFromEvent([123])).toEqual([123])\n  expect(getValuesFromEvent([null])).toEqual([null])\n})\n\ntest('empty', () => {\n  expect(matchFeedback()).toBeFalsy()\n})\n\ntest('patchFieldStates', () => {\n  const fields = {}\n  patchFieldStates(fields, [{ type: 'update', address: 'aaa', payload: null }])\n  patchFieldStates(fields, [\n    { type: 'update3' as any, address: 'aaa', payload: null },\n  ])\n  expect(fields).toEqual({})\n})\n\ntest('patchFieldStates should be sequence', () => {\n  const form = attach(createForm())\n  attach(\n    form.createArrayField({\n      name: 'array',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'input',\n      basePath: 'array.0',\n    })\n  )\n  attach(\n    form.createField({\n      name: 'input',\n      basePath: 'array.1',\n    })\n  )\n  const before = Object.keys(form.fields)\n  form.fields['array'].move(1, 0)\n  const after = Object.keys(form.fields)\n  expect(after).toEqual(before)\n\n  const form2 = attach(createForm())\n  attach(\n    form2.createField({\n      name: 'field1',\n      title: 'Field 1',\n    })\n  )\n  attach(\n    form2.createField({\n      name: 'field2',\n      title: 'Field 1',\n    })\n  )\n\n  patchFieldStates(form2.fields, [\n    {\n      type: 'update',\n      address: 'field2',\n      oldAddress: 'field1',\n      payload: form2.field1,\n    },\n    {\n      type: 'update',\n      address: 'field1',\n      oldAddress: 'field2',\n      payload: form2.field2,\n    },\n  ])\n\n  expect(Object.keys(form2.fields)).toEqual(['field1', 'field2'])\n})\n\ntest('deserialize', () => {\n  expect(deserialize(null, null)).toBeUndefined()\n  expect(\n    deserialize(\n      {},\n      {\n        parent: null,\n      }\n    )\n  ).toEqual({})\n})\n\ntest('isHTMLInputEvent', () => {\n  expect(isHTMLInputEvent({ target: { checked: true } })).toBeTruthy()\n  expect(isHTMLInputEvent({ target: { value: 123 } })).toBeTruthy()\n  expect(\n    isHTMLInputEvent({ target: { tagName: 'INPUT', value: null } })\n  ).toBeTruthy()\n  expect(isHTMLInputEvent({ target: { tagName: 'INPUT' } })).toBeFalsy()\n  expect(isHTMLInputEvent({ target: { tagName: 'DIV' } })).toBeFalsy()\n  expect(isHTMLInputEvent({ target: {}, stopPropagation() {} })).toBeFalsy()\n  expect(isHTMLInputEvent({})).toBeFalsy()\n})\n"
  },
  {
    "path": "packages/core/src/__tests__/lifecycle.spec.ts",
    "content": "import { LifeCycle } from '../models'\n\ntest('create lifecycle', () => {\n  const handler1 = jest.fn()\n  const lifecycle1 = new LifeCycle(handler1)\n  lifecycle1.notify('event1')\n  expect(handler1).toBeCalledTimes(1)\n  expect(handler1).toBeCalledWith(\n    {\n      type: 'event1',\n      payload: undefined,\n    },\n    undefined\n  )\n  lifecycle1.notify('event11', 'payload1')\n  expect(handler1).toBeCalledTimes(2)\n  expect(handler1).toBeCalledWith(\n    {\n      type: 'event11',\n      payload: 'payload1',\n    },\n    undefined\n  )\n  const context: any = {}\n  lifecycle1.notify('event12', 'payload11', context)\n  expect(handler1).toBeCalledTimes(3)\n  expect(handler1).toBeCalledWith(\n    {\n      type: 'event12',\n      payload: 'payload11',\n    },\n    context\n  )\n\n  const handler2 = jest.fn()\n  const lifecycle2 = new LifeCycle('event2', handler2)\n  lifecycle2.notify('event1')\n  expect(handler2).not.toBeCalled()\n  lifecycle2.notify('event2')\n  expect(handler2).toBeCalledTimes(1)\n\n  const handler31 = jest.fn()\n  const handler32 = jest.fn()\n  const lifecycle3 = new LifeCycle({\n    event31: handler31,\n    event32: handler32,\n  })\n  lifecycle3.notify('event3')\n  expect(handler31).not.toBeCalled()\n  expect(handler32).not.toBeCalled()\n  lifecycle3.notify('event31')\n  expect(handler31).toBeCalledTimes(1)\n  expect(handler32).not.toBeCalled()\n  lifecycle3.notify('event32')\n  expect(handler31).toBeCalledTimes(1)\n  expect(handler32).toBeCalledTimes(1)\n})\n"
  },
  {
    "path": "packages/core/src/__tests__/object.spec.ts",
    "content": "import { createForm } from '../'\nimport { attach } from './shared'\n\ntest('create object field', () => {\n  const form = attach(createForm())\n  const object = attach(\n    form.createObjectField({\n      name: 'object',\n    })\n  )\n  expect(object.value).toEqual({})\n  expect(object.addProperty).toBeDefined()\n  expect(object.removeProperty).toBeDefined()\n  expect(object.existProperty).toBeDefined()\n})\n\ntest('create object field methods', () => {\n  const form = attach(createForm())\n  const object = attach(\n    form.createObjectField({\n      name: 'object',\n      value: {},\n    })\n  )\n  expect(object.value).toEqual({})\n  object.addProperty('aaa', 123)\n  expect(object.value).toEqual({ aaa: 123 })\n  object.removeProperty('aaa')\n  expect(object.value).toEqual({})\n  expect(object.existProperty('aaa')).toBeFalsy()\n})\n"
  },
  {
    "path": "packages/core/src/__tests__/shared.ts",
    "content": "export const attach = <T extends { onMount: () => void }>(target: T): T => {\n  target.onMount()\n  return target\n}\n\nexport const sleep = (duration = 100) =>\n  new Promise((resolve) => {\n    setTimeout(resolve, duration)\n  })\n"
  },
  {
    "path": "packages/core/src/__tests__/void.spec.ts",
    "content": "import { createForm } from '../'\nimport { attach } from './shared'\n\ntest('create void field', () => {\n  const form = attach(createForm())\n  const field = attach(\n    form.createVoidField({\n      name: 'void',\n    })\n  )\n  field.destroy()\n})\n\ntest('create void field props', () => {\n  const form = attach(createForm())\n  const field1 = attach(\n    form.createVoidField({\n      name: 'field1',\n      title: 'Field 1',\n      description: 'This is Field 1',\n    })\n  )\n  expect(field1.title).toEqual('Field 1')\n  expect(field1.description).toEqual('This is Field 1')\n  const field2 = attach(\n    form.createVoidField({\n      name: 'field2',\n      disabled: true,\n      hidden: true,\n    })\n  )\n  expect(field2.pattern).toEqual('disabled')\n  expect(field2.disabled).toBeTruthy()\n  expect(field2.display).toEqual('hidden')\n  expect(field2.hidden).toBeTruthy()\n  const field3 = attach(\n    form.createVoidField({\n      name: 'field3',\n      readOnly: true,\n      visible: false,\n    })\n  )\n  expect(field3.pattern).toEqual('readOnly')\n  expect(field3.readOnly).toBeTruthy()\n  expect(field3.display).toEqual('none')\n  expect(field3.visible).toBeFalsy()\n})\n\ntest('setComponent/setComponentProps', () => {\n  const form = attach(createForm())\n  const field = attach(\n    form.createVoidField({\n      name: 'aa',\n    })\n  )\n  const component = () => null\n  field.setComponent(component, { props: 123 })\n  expect(field.component[0]).toEqual(component)\n  expect(field.component[1]).toEqual({ props: 123 })\n  field.setComponentProps({\n    hello: 'world',\n  })\n  expect(field.component[1]).toEqual({ props: 123, hello: 'world' })\n})\n\ntest('setTitle/setDescription', () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createVoidField({\n      name: 'aa',\n    })\n  )\n  aa.setTitle('AAA')\n  aa.setDescription('This is AAA')\n  expect(aa.title).toEqual('AAA')\n  expect(aa.description).toEqual('This is AAA')\n})\n\ntest('setComponent/setComponentProps', () => {\n  const component = () => null\n  const form = attach(createForm())\n  const field = attach(\n    form.createVoidField({\n      name: 'aa',\n    })\n  )\n\n  field.setComponent(undefined, { props: 123 })\n  field.setComponent(component)\n  expect(field.component[0]).toEqual(component)\n  expect(field.component[1]).toEqual({ props: 123 })\n  field.setComponentProps({\n    hello: 'world',\n  })\n  expect(field.component[1]).toEqual({ props: 123, hello: 'world' })\n})\n\ntest('setDecorator/setDecoratorProps', () => {\n  const component = () => null\n  const form = attach(createForm())\n  const field = attach(\n    form.createVoidField({\n      name: 'aa',\n    })\n  )\n  field.setDecorator(undefined, { props: 123 })\n  field.setDecorator(component)\n  expect(field.decorator[0]).toEqual(component)\n  expect(field.decorator[1]).toEqual({ props: 123 })\n  field.setDecoratorProps({\n    hello: 'world',\n  })\n  expect(field.decorator[1]).toEqual({ props: 123, hello: 'world' })\n})\n\ntest('setState/getState', () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createVoidField({\n      name: 'aa',\n    })\n  )\n  const state = aa.getState()\n  aa.setState((state) => {\n    state.title = 'AAA'\n  })\n  expect(aa.title).toEqual('AAA')\n  aa.setState(state)\n  expect(aa.title).toBeUndefined()\n  aa.setState((state) => {\n    state.hidden = false\n  })\n  expect(aa.display).toEqual('visible')\n  aa.setState((state) => {\n    state.visible = true\n  })\n  expect(aa.display).toEqual('visible')\n  aa.setState((state) => {\n    state.readOnly = false\n  })\n  expect(aa.pattern).toEqual('editable')\n  aa.setState((state) => {\n    state.disabled = false\n  })\n  expect(aa.pattern).toEqual('editable')\n  aa.setState((state) => {\n    state.editable = true\n  })\n  expect(aa.pattern).toEqual('editable')\n  aa.setState((state) => {\n    state.editable = false\n  })\n  expect(aa.pattern).toEqual('readPretty')\n  aa.setState((state) => {\n    state.readPretty = true\n  })\n  expect(aa.pattern).toEqual('readPretty')\n  aa.setState((state) => {\n    state.readPretty = false\n  })\n  expect(aa.pattern).toEqual('editable')\n  expect(aa.parent).toBeUndefined()\n})\n\ntest('nested display/pattern', () => {\n  const form = attach(createForm())\n  attach(\n    form.createObjectField({\n      name: 'object',\n    })\n  )\n  const void_ = attach(\n    form.createVoidField({\n      name: 'void',\n      basePath: 'object',\n    })\n  )\n  const void2_ = attach(\n    form.createVoidField({\n      name: 'void',\n      basePath: 'object.void.0',\n    })\n  )\n  const aaa = attach(\n    form.createField({\n      name: 'aaa',\n      basePath: 'object.void',\n    })\n  )\n  const bbb = attach(\n    form.createField({\n      name: 'bbb',\n      basePath: 'object.void',\n    })\n  )\n  void_.setPattern('readPretty')\n  expect(void_.pattern).toEqual('readPretty')\n  expect(aaa.pattern).toEqual('readPretty')\n  expect(bbb.pattern).toEqual('readPretty')\n  void_.setPattern('readOnly')\n  expect(void_.pattern).toEqual('readOnly')\n  expect(aaa.pattern).toEqual('readOnly')\n  expect(bbb.pattern).toEqual('readOnly')\n  void_.setPattern('disabled')\n  expect(void_.pattern).toEqual('disabled')\n  expect(aaa.pattern).toEqual('disabled')\n  expect(bbb.pattern).toEqual('disabled')\n  void_.setPattern()\n  expect(void_.pattern).toEqual('editable')\n  expect(aaa.pattern).toEqual('editable')\n  expect(bbb.pattern).toEqual('editable')\n\n  void_.setDisplay('hidden')\n  expect(void_.display).toEqual('hidden')\n  expect(aaa.display).toEqual('hidden')\n  expect(bbb.display).toEqual('hidden')\n  void_.setDisplay('none')\n  expect(void_.display).toEqual('none')\n  expect(aaa.display).toEqual('none')\n  expect(bbb.display).toEqual('none')\n  void_.setDisplay()\n  expect(void_.display).toEqual('visible')\n  expect(aaa.display).toEqual('visible')\n  expect(bbb.display).toEqual('visible')\n  void_.onUnmount()\n  expect(void2_.parent === void_).toBeTruthy()\n})\n\ntest('reactions', async () => {\n  const form = attach(createForm())\n  const aa = attach(\n    form.createField({\n      name: 'aa',\n    })\n  )\n  const bb = attach(\n    form.createVoidField({\n      name: 'bb',\n      reactions: [\n        (field) => {\n          const aa = field.query('aa')\n          if (aa.get('value') === '123') {\n            field.visible = false\n          } else {\n            field.visible = true\n          }\n          if (aa.get('inputValue') === '333') {\n            field.editable = false\n          } else if (aa.get('inputValue') === '444') {\n            field.editable = true\n          }\n          if (aa.get('initialValue') === '555') {\n            field.readOnly = true\n          } else if (aa.get('initialValue') === '666') {\n            field.readOnly = false\n          }\n        },\n        null,\n      ],\n    })\n  )\n  expect(bb.visible).toBeTruthy()\n  aa.setValue('123')\n  expect(bb.visible).toBeFalsy()\n  await aa.onInput('333')\n  expect(bb.editable).toBeFalsy()\n  await aa.onInput('444')\n  expect(bb.editable).toBeTruthy()\n  aa.setInitialValue('555')\n  expect(bb.readOnly).toBeTruthy()\n  aa.setInitialValue('666')\n  expect(bb.readOnly).toBeFalsy()\n  form.onUnmount()\n})\n\ntest('fault tolerance', () => {\n  const form = attach(createForm())\n  form.setDisplay(null)\n  form.setPattern(null)\n  const field = attach(\n    form.createVoidField({\n      name: 'xxx',\n    })\n  )\n  expect(field.display).toEqual('visible')\n  expect(field.pattern).toEqual('editable')\n})\n\ntest('child field reactions', () => {\n  const form = attach(createForm())\n  const voidField = attach(form.createVoidField({ name: 'void' }))\n  const field1 = attach(\n    form.createField({\n      name: 'field1',\n      basePath: voidField.address,\n      reactions: [\n        (field) => {\n          field.value = field.query('field3').getIn('value')\n        },\n      ],\n    })\n  )\n  const field2 = attach(\n    form.createField({\n      name: 'field2',\n      basePath: voidField.address,\n      reactions: [\n        (field) => {\n          field.value = field.query('.field3').getIn('value')\n        },\n      ],\n    })\n  )\n  expect(field1.value).toBeUndefined()\n  expect(field2.value).toBeUndefined()\n  const field3 = attach(\n    form.createField({\n      name: 'field3',\n      basePath: voidField.address,\n      value: 1,\n    })\n  )\n  expect(field1.value).toBe(1)\n  expect(field2.value).toBe(1)\n  field3.value = 2\n  expect(field1.value).toBe(2)\n  expect(field2.value).toBe(2)\n})\n"
  },
  {
    "path": "packages/core/src/effects/index.ts",
    "content": "export * from './onFormEffects'\nexport * from './onFieldEffects'\n"
  },
  {
    "path": "packages/core/src/effects/onFieldEffects.ts",
    "content": "import { FormPath, isFn, toArr } from '@formily/shared'\nimport { autorun, reaction, batch } from '@formily/reactive'\nimport { Form } from '../models'\nimport {\n  LifeCycleTypes,\n  FormPathPattern,\n  GeneralField,\n  DataField,\n  IFieldState,\n} from '../types'\nimport { createEffectHook, useEffectForm } from '../shared/effective'\n\nfunction createFieldEffect<Result extends GeneralField = GeneralField>(\n  type: LifeCycleTypes\n) {\n  return createEffectHook(\n    type,\n    (field: Result, form: Form) =>\n      (\n        pattern: FormPathPattern,\n        callback: (field: Result, form: Form) => void\n      ) => {\n        if (\n          FormPath.parse(pattern).matchAliasGroup(field.address, field.path)\n        ) {\n          batch(() => {\n            callback(field, form)\n          })\n        }\n      }\n  )\n}\nconst _onFieldInit = createFieldEffect(LifeCycleTypes.ON_FIELD_INIT)\nexport const onFieldMount = createFieldEffect(LifeCycleTypes.ON_FIELD_MOUNT)\nexport const onFieldUnmount = createFieldEffect(LifeCycleTypes.ON_FIELD_UNMOUNT)\nexport const onFieldValueChange = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_VALUE_CHANGE\n)\nexport const onFieldInitialValueChange = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_INITIAL_VALUE_CHANGE\n)\nexport const onFieldInputValueChange = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_INPUT_VALUE_CHANGE\n)\nexport const onFieldValidateStart = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_VALIDATE_START\n)\nexport const onFieldValidateEnd = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_VALIDATE_END\n)\nexport const onFieldValidating = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_VALIDATING\n)\nexport const onFieldValidateFailed = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_VALIDATE_FAILED\n)\nexport const onFieldValidateSuccess = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_VALIDATE_SUCCESS\n)\nexport const onFieldSubmit = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_SUBMIT\n)\nexport const onFieldSubmitStart = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_SUBMIT_START\n)\nexport const onFieldSubmitEnd = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_SUBMIT_END\n)\nexport const onFieldSubmitValidateStart = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_SUBMIT_VALIDATE_START\n)\nexport const onFieldSubmitValidateEnd = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_SUBMIT_VALIDATE_END\n)\nexport const onFieldSubmitSuccess = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_SUBMIT_SUCCESS\n)\nexport const onFieldSubmitFailed = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_SUBMIT_FAILED\n)\nexport const onFieldSubmitValidateSuccess = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_SUBMIT_VALIDATE_SUCCESS\n)\nexport const onFieldSubmitValidateFailed = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_SUBMIT_VALIDATE_FAILED\n)\nexport const onFieldReset = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_RESET\n)\nexport const onFieldLoading = createFieldEffect<DataField>(\n  LifeCycleTypes.ON_FIELD_LOADING\n)\n\nexport function onFieldInit(\n  pattern: FormPathPattern,\n  callback?: (field: GeneralField, form: Form) => void\n) {\n  const form = useEffectForm()\n  const count = form.query(pattern).reduce((count, field) => {\n    callback(field, form)\n    return count + 1\n  }, 0)\n  if (count === 0) {\n    _onFieldInit(pattern, callback)\n  }\n}\n\nexport function onFieldReact(\n  pattern: FormPathPattern,\n  callback?: (field: GeneralField, form: Form) => void\n) {\n  onFieldInit(pattern, (field, form) => {\n    field.disposers.push(\n      autorun(() => {\n        if (isFn(callback)) callback(field, form)\n      })\n    )\n  })\n}\nexport function onFieldChange(\n  pattern: FormPathPattern,\n  callback?: (field: GeneralField, form: Form) => void\n): void\nexport function onFieldChange(\n  pattern: FormPathPattern,\n  watches: (keyof IFieldState)[],\n  callback?: (field: GeneralField, form: Form) => void\n): void\nexport function onFieldChange(\n  pattern: FormPathPattern,\n  watches: any,\n  callback?: (field: GeneralField, form: Form) => void\n): void {\n  if (isFn(watches)) {\n    callback = watches\n    watches = ['value']\n  } else {\n    watches = watches || ['value']\n  }\n  onFieldInit(pattern, (field, form) => {\n    if (isFn(callback)) callback(field, form)\n    const dispose = reaction(\n      () => {\n        return toArr(watches).map((key) => {\n          return field[key]\n        })\n      },\n      () => {\n        if (isFn(callback)) callback(field, form)\n      }\n    )\n    field.disposers.push(dispose)\n  })\n}\n"
  },
  {
    "path": "packages/core/src/effects/onFormEffects.ts",
    "content": "import { isFn } from '@formily/shared'\nimport { autorun, batch } from '@formily/reactive'\nimport { Form } from '../models'\nimport { LifeCycleTypes } from '../types'\nimport { createEffectHook } from '../shared/effective'\n\nfunction createFormEffect(type: LifeCycleTypes) {\n  return createEffectHook(\n    type,\n    (form: Form) => (callback: (form: Form) => void) => {\n      batch(() => {\n        callback(form)\n      })\n    }\n  )\n}\n\nexport const onFormInit = createFormEffect(LifeCycleTypes.ON_FORM_INIT)\nexport const onFormMount = createFormEffect(LifeCycleTypes.ON_FORM_MOUNT)\nexport const onFormUnmount = createFormEffect(LifeCycleTypes.ON_FORM_UNMOUNT)\nexport const onFormValuesChange = createFormEffect(\n  LifeCycleTypes.ON_FORM_VALUES_CHANGE\n)\nexport const onFormInitialValuesChange = createFormEffect(\n  LifeCycleTypes.ON_FORM_INITIAL_VALUES_CHANGE\n)\nexport const onFormInputChange = createFormEffect(\n  LifeCycleTypes.ON_FORM_INPUT_CHANGE\n)\nexport const onFormSubmit = createFormEffect(LifeCycleTypes.ON_FORM_SUBMIT)\nexport const onFormReset = createFormEffect(LifeCycleTypes.ON_FORM_RESET)\nexport const onFormSubmitStart = createFormEffect(\n  LifeCycleTypes.ON_FORM_SUBMIT_START\n)\nexport const onFormSubmitEnd = createFormEffect(\n  LifeCycleTypes.ON_FORM_SUBMIT_END\n)\nexport const onFormSubmitSuccess = createFormEffect(\n  LifeCycleTypes.ON_FORM_SUBMIT_SUCCESS\n)\nexport const onFormSubmitFailed = createFormEffect(\n  LifeCycleTypes.ON_FORM_SUBMIT_FAILED\n)\nexport const onFormSubmitValidateStart = createFormEffect(\n  LifeCycleTypes.ON_FORM_SUBMIT_VALIDATE_START\n)\nexport const onFormSubmitValidateSuccess = createFormEffect(\n  LifeCycleTypes.ON_FORM_SUBMIT_VALIDATE_SUCCESS\n)\nexport const onFormSubmitValidateFailed = createFormEffect(\n  LifeCycleTypes.ON_FORM_SUBMIT_VALIDATE_FAILED\n)\nexport const onFormSubmitValidateEnd = createFormEffect(\n  LifeCycleTypes.ON_FORM_SUBMIT_VALIDATE_END\n)\nexport const onFormValidateStart = createFormEffect(\n  LifeCycleTypes.ON_FORM_VALIDATE_START\n)\nexport const onFormValidateSuccess = createFormEffect(\n  LifeCycleTypes.ON_FORM_VALIDATE_SUCCESS\n)\nexport const onFormValidateFailed = createFormEffect(\n  LifeCycleTypes.ON_FORM_VALIDATE_FAILED\n)\nexport const onFormValidateEnd = createFormEffect(\n  LifeCycleTypes.ON_FORM_VALIDATE_END\n)\nexport const onFormGraphChange = createFormEffect(\n  LifeCycleTypes.ON_FORM_GRAPH_CHANGE\n)\nexport const onFormLoading = createFormEffect(LifeCycleTypes.ON_FORM_LOADING)\nexport function onFormReact(callback?: (form: Form) => void) {\n  let dispose = null\n  onFormInit((form) => {\n    dispose = autorun(() => {\n      if (isFn(callback)) callback(form)\n    })\n  })\n  onFormUnmount(() => {\n    dispose()\n  })\n}\n"
  },
  {
    "path": "packages/core/src/global.d.ts",
    "content": "import * as Types from './types'\nimport * as Models from './models'\n\ndeclare global {\n  namespace Formily.Core {\n    export { Types, Models }\n  }\n}\n"
  },
  {
    "path": "packages/core/src/index.ts",
    "content": "export * from './shared/externals'\nexport * from './models/types'\nexport * from './effects'\nexport * from './types'\n"
  },
  {
    "path": "packages/core/src/models/ArrayField.ts",
    "content": "import { isArr, move } from '@formily/shared'\nimport { action, reaction } from '@formily/reactive'\nimport {\n  spliceArrayState,\n  exchangeArrayState,\n  cleanupArrayChildren,\n} from '../shared/internals'\nimport { Field } from './Field'\nimport { Form } from './Form'\nimport { JSXComponent, IFieldProps, FormPathPattern } from '../types'\n\nexport class ArrayField<\n  Decorator extends JSXComponent = any,\n  Component extends JSXComponent = any\n> extends Field<Decorator, Component, any, any[]> {\n  displayName = 'ArrayField'\n\n  constructor(\n    address: FormPathPattern,\n    props: IFieldProps<Decorator, Component>,\n    form: Form,\n    designable: boolean\n  ) {\n    super(address, props, form, designable)\n    this.makeAutoCleanable()\n  }\n\n  protected makeAutoCleanable() {\n    this.disposers.push(\n      reaction(\n        () => this.value?.length,\n        (newLength, oldLength) => {\n          if (oldLength && !newLength) {\n            cleanupArrayChildren(this, 0)\n          } else if (newLength < oldLength) {\n            cleanupArrayChildren(this, newLength)\n          }\n        }\n      )\n    )\n  }\n\n  push = (...items: any[]) => {\n    return action(() => {\n      if (!isArr(this.value)) {\n        this.value = []\n      }\n      this.value.push(...items)\n      return this.onInput(this.value)\n    })\n  }\n\n  pop = () => {\n    if (!isArr(this.value)) return\n    return action(() => {\n      const index = this.value.length - 1\n      spliceArrayState(this, {\n        startIndex: index,\n        deleteCount: 1,\n      })\n      this.value.pop()\n      return this.onInput(this.value)\n    })\n  }\n\n  insert = (index: number, ...items: any[]) => {\n    return action(() => {\n      if (!isArr(this.value)) {\n        this.value = []\n      }\n      if (items.length === 0) {\n        return\n      }\n      spliceArrayState(this, {\n        startIndex: index,\n        insertCount: items.length,\n      })\n      this.value.splice(index, 0, ...items)\n      return this.onInput(this.value)\n    })\n  }\n\n  remove = (index: number) => {\n    if (!isArr(this.value)) return\n    return action(() => {\n      spliceArrayState(this, {\n        startIndex: index,\n        deleteCount: 1,\n      })\n      this.value.splice(index, 1)\n      return this.onInput(this.value)\n    })\n  }\n\n  shift = () => {\n    if (!isArr(this.value)) return\n    return action(() => {\n      this.value.shift()\n      return this.onInput(this.value)\n    })\n  }\n\n  unshift = (...items: any[]) => {\n    return action(() => {\n      if (!isArr(this.value)) {\n        this.value = []\n      }\n      spliceArrayState(this, {\n        startIndex: 0,\n        insertCount: items.length,\n      })\n      this.value.unshift(...items)\n      return this.onInput(this.value)\n    })\n  }\n\n  move = (fromIndex: number, toIndex: number) => {\n    if (!isArr(this.value)) return\n    if (fromIndex === toIndex) return\n    return action(() => {\n      move(this.value, fromIndex, toIndex)\n      exchangeArrayState(this, {\n        fromIndex,\n        toIndex,\n      })\n      return this.onInput(this.value)\n    })\n  }\n\n  moveUp = (index: number) => {\n    if (!isArr(this.value)) return\n    return this.move(index, index - 1 < 0 ? this.value.length - 1 : index - 1)\n  }\n\n  moveDown = (index: number) => {\n    if (!isArr(this.value)) return\n    return this.move(index, index + 1 >= this.value.length ? 0 : index + 1)\n  }\n}\n"
  },
  {
    "path": "packages/core/src/models/BaseField.ts",
    "content": "import {\n  FormPath,\n  FormPathPattern,\n  isValid,\n  toArr,\n  each,\n  isFn,\n} from '@formily/shared'\nimport {\n  JSXComponent,\n  LifeCycleTypes,\n  FieldDisplayTypes,\n  FieldPatternTypes,\n  FieldDecorator,\n  FieldComponent,\n  IFieldActions,\n} from '../types'\nimport {\n  locateNode,\n  destroy,\n  initFieldUpdate,\n  getArrayParent,\n  getObjectParent,\n} from '../shared/internals'\nimport { Form } from './Form'\nimport { Query } from './Query'\n\nexport class BaseField<Decorator = any, Component = any, TextType = any> {\n  title: TextType\n  description: TextType\n\n  selfDisplay: FieldDisplayTypes\n  selfPattern: FieldPatternTypes\n  initialized: boolean\n  mounted: boolean\n  unmounted: boolean\n\n  content: any\n\n  data: any\n\n  decoratorType: Decorator\n  decoratorProps: Record<string, any>\n  componentType: Component\n  componentProps: Record<string, any>\n\n  designable: boolean\n  address: FormPath\n  path: FormPath\n  form: Form\n\n  disposers: (() => void)[] = []\n\n  actions: IFieldActions = {}\n\n  locate(address: FormPathPattern) {\n    this.form.fields[address.toString()] = this as any\n    locateNode(this as any, address)\n  }\n\n  get indexes(): number[] {\n    return this.path.transform(/^\\d+$/, (...args) =>\n      args.map((index) => Number(index))\n    ) as number[]\n  }\n\n  get index() {\n    return this.indexes[this.indexes.length - 1] ?? -1\n  }\n\n  get records() {\n    const array = getArrayParent(this)\n    return array?.value\n  }\n\n  get record() {\n    const obj = getObjectParent(this)\n    if (obj) {\n      return obj.value\n    }\n    const index = this.index\n    const array = getArrayParent(this, index)\n    if (array) {\n      return array.value?.[index]\n    }\n    return this.form.values\n  }\n\n  get component() {\n    return [this.componentType, this.componentProps]\n  }\n\n  set component(value: FieldComponent<Component>) {\n    const component = toArr(value)\n    this.componentType = component[0]\n    this.componentProps = component[1] || {}\n  }\n\n  get decorator() {\n    return [this.decoratorType, this.decoratorProps]\n  }\n\n  set decorator(value: FieldDecorator<Decorator>) {\n    const decorator = toArr(value)\n    this.decoratorType = decorator[0]\n    this.decoratorProps = decorator[1] || {}\n  }\n\n  get parent() {\n    let parent = this.address.parent()\n    let identifier = parent.toString()\n    while (!this.form.fields[identifier]) {\n      parent = parent.parent()\n      identifier = parent.toString()\n      if (!identifier) return\n    }\n    return this.form.fields[identifier]\n  }\n\n  get display(): FieldDisplayTypes {\n    const parentDisplay = (this.parent as any)?.display\n    if (parentDisplay && parentDisplay !== 'visible') {\n      if (this.selfDisplay && this.selfDisplay !== 'visible')\n        return this.selfDisplay\n      return parentDisplay\n    }\n    if (isValid(this.selfDisplay)) return this.selfDisplay\n    return parentDisplay || this.form.display || 'visible'\n  }\n\n  get pattern(): FieldPatternTypes {\n    const parentPattern: FieldPatternTypes =\n      (this.parent as any)?.pattern || this.form.pattern || 'editable'\n    const selfPattern = this.selfPattern\n    if (isValid(selfPattern)) {\n      if (parentPattern === 'readPretty' && selfPattern !== 'editable') {\n        return parentPattern\n      }\n      return selfPattern\n    }\n    return parentPattern\n  }\n\n  get editable() {\n    return this.pattern === 'editable'\n  }\n\n  get disabled() {\n    return this.pattern === 'disabled'\n  }\n\n  get readOnly() {\n    return this.pattern === 'readOnly'\n  }\n\n  get readPretty() {\n    return this.pattern === 'readPretty'\n  }\n\n  get hidden() {\n    return this.display === 'hidden'\n  }\n\n  get visible() {\n    return this.display === 'visible'\n  }\n\n  get destroyed() {\n    return !this.form.fields[this.address.toString()]\n  }\n\n  set hidden(hidden: boolean) {\n    if (!isValid(hidden)) return\n    if (hidden) {\n      this.display = 'hidden'\n    } else {\n      this.display = 'visible'\n    }\n  }\n\n  set visible(visible: boolean) {\n    if (!isValid(visible)) return\n    if (visible) {\n      this.display = 'visible'\n    } else {\n      this.display = 'none'\n    }\n  }\n\n  set editable(editable: boolean) {\n    if (!isValid(editable)) return\n    if (editable) {\n      this.pattern = 'editable'\n    } else {\n      this.pattern = 'readPretty'\n    }\n  }\n\n  set readOnly(readOnly: boolean) {\n    if (!isValid(readOnly)) return\n    if (readOnly) {\n      this.pattern = 'readOnly'\n    } else {\n      this.pattern = 'editable'\n    }\n  }\n\n  set disabled(disabled: boolean) {\n    if (!isValid(disabled)) return\n    if (disabled) {\n      this.pattern = 'disabled'\n    } else {\n      this.pattern = 'editable'\n    }\n  }\n\n  set readPretty(readPretty: boolean) {\n    if (!isValid(readPretty)) return\n    if (readPretty) {\n      this.pattern = 'readPretty'\n    } else {\n      this.pattern = 'editable'\n    }\n  }\n\n  set pattern(pattern: FieldPatternTypes) {\n    this.selfPattern = pattern\n  }\n\n  set display(display: FieldDisplayTypes) {\n    this.selfDisplay = display\n  }\n\n  setTitle = (title?: TextType) => {\n    this.title = title\n  }\n\n  setDescription = (description?: TextType) => {\n    this.description = description\n  }\n\n  setDisplay = (type?: FieldDisplayTypes) => {\n    this.display = type\n  }\n\n  setPattern = (type?: FieldPatternTypes) => {\n    this.pattern = type\n  }\n\n  setComponent = <C extends JSXComponent, ComponentProps extends object = {}>(\n    component?: C,\n    props?: ComponentProps\n  ) => {\n    if (component) {\n      this.componentType = component as any\n    }\n    if (props) {\n      this.componentProps = this.componentProps || {}\n      Object.assign(this.componentProps, props)\n    }\n  }\n\n  setComponentProps = <ComponentProps extends object = {}>(\n    props?: ComponentProps\n  ) => {\n    if (props) {\n      this.componentProps = this.componentProps || {}\n      Object.assign(this.componentProps, props)\n    }\n  }\n\n  setDecorator = <D extends JSXComponent, ComponentProps extends object = {}>(\n    component?: D,\n    props?: ComponentProps\n  ) => {\n    if (component) {\n      this.decoratorType = component as any\n    }\n    if (props) {\n      this.decoratorProps = this.decoratorProps || {}\n      Object.assign(this.decoratorProps, props)\n    }\n  }\n\n  setDecoratorProps = <ComponentProps extends object = {}>(\n    props?: ComponentProps\n  ) => {\n    if (props) {\n      this.decoratorProps = this.decoratorProps || {}\n      Object.assign(this.decoratorProps, props)\n    }\n  }\n\n  setData = (data: any) => {\n    this.data = data\n  }\n\n  setContent = (content: any) => {\n    this.content = content\n  }\n\n  onInit = () => {\n    this.initialized = true\n    initFieldUpdate(this as any)\n    this.notify(LifeCycleTypes.ON_FIELD_INIT)\n  }\n\n  onMount = () => {\n    this.mounted = true\n    this.unmounted = false\n    this.notify(LifeCycleTypes.ON_FIELD_MOUNT)\n  }\n\n  onUnmount = () => {\n    this.mounted = false\n    this.unmounted = true\n    this.notify(LifeCycleTypes.ON_FIELD_UNMOUNT)\n  }\n\n  query = (pattern: FormPathPattern | RegExp) => {\n    return new Query({\n      pattern,\n      base: this.address,\n      form: this.form,\n    })\n  }\n\n  notify = (type: LifeCycleTypes, payload?: any) => {\n    return this.form.notify(type, payload ?? this)\n  }\n\n  dispose = () => {\n    this.disposers.forEach((dispose) => {\n      dispose()\n    })\n    this.form.removeEffects(this)\n  }\n\n  destroy = (forceClear = true) => {\n    destroy(this.form.fields, this.address.toString(), forceClear)\n  }\n\n  match = (pattern: FormPathPattern) => {\n    return FormPath.parse(pattern).matchAliasGroup(this.address, this.path)\n  }\n\n  inject = (actions: IFieldActions) => {\n    each(actions, (action, key) => {\n      if (isFn(action)) {\n        this.actions[key] = action\n      }\n    })\n  }\n\n  invoke = (name: string, ...args: any[]) => {\n    return this.actions[name]?.(...args)\n  }\n}\n"
  },
  {
    "path": "packages/core/src/models/Field.ts",
    "content": "import {\n  isValid,\n  isEmpty,\n  toArr,\n  FormPathPattern,\n  isArr,\n} from '@formily/shared'\nimport {\n  ValidatorTriggerType,\n  parseValidatorDescriptions,\n} from '@formily/validator'\nimport { define, observable, batch, toJS, action } from '@formily/reactive'\nimport {\n  JSXComponent,\n  LifeCycleTypes,\n  IFieldFeedback,\n  FeedbackMessage,\n  IFieldCaches,\n  IFieldRequests,\n  FieldValidator,\n  FieldDataSource,\n  ISearchFeedback,\n  IFieldProps,\n  IFieldResetOptions,\n  IFieldState,\n  IModelSetter,\n  IModelGetter,\n} from '../types'\nimport {\n  updateFeedback,\n  queryFeedbacks,\n  allowAssignDefaultValue,\n  queryFeedbackMessages,\n  getValuesFromEvent,\n  createReactions,\n  createStateSetter,\n  createStateGetter,\n  isHTMLInputEvent,\n  setValidatorRule,\n  batchValidate,\n  batchSubmit,\n  batchReset,\n  setValidating,\n  setSubmitting,\n  setLoading,\n  validateSelf,\n  modifySelf,\n  getValidFieldDefaultValue,\n  initializeStart,\n  initializeEnd,\n  createChildrenFeedbackFilter,\n  createReaction,\n} from '../shared/internals'\nimport { Form } from './Form'\nimport { BaseField } from './BaseField'\nimport { IFormFeedback } from '../types'\nexport class Field<\n  Decorator extends JSXComponent = any,\n  Component extends JSXComponent = any,\n  TextType = any,\n  ValueType = any\n> extends BaseField<Decorator, Component, TextType> {\n  displayName = 'Field'\n\n  props: IFieldProps<Decorator, Component, TextType, ValueType>\n\n  loading: boolean\n  validating: boolean\n  submitting: boolean\n  active: boolean\n  visited: boolean\n  selfModified: boolean\n  modified: boolean\n  inputValue: ValueType\n  inputValues: any[]\n  dataSource: FieldDataSource\n  validator: FieldValidator\n  feedbacks: IFieldFeedback[]\n  caches: IFieldCaches = {}\n  requests: IFieldRequests = {}\n  constructor(\n    address: FormPathPattern,\n    props: IFieldProps<Decorator, Component, TextType, ValueType>,\n    form: Form,\n    designable: boolean\n  ) {\n    super()\n    this.form = form\n    this.props = props\n    this.designable = designable\n    initializeStart()\n    this.locate(address)\n    this.initialize()\n    this.makeObservable()\n    this.makeReactive()\n    this.onInit()\n    initializeEnd()\n  }\n\n  protected initialize() {\n    this.initialized = false\n    this.loading = false\n    this.validating = false\n    this.submitting = false\n    this.selfModified = false\n    this.active = false\n    this.visited = false\n    this.mounted = false\n    this.unmounted = false\n    this.inputValues = []\n    this.inputValue = null\n    this.feedbacks = []\n    this.title = this.props.title\n    this.description = this.props.description\n    this.display = this.props.display\n    this.pattern = this.props.pattern\n    this.editable = this.props.editable\n    this.disabled = this.props.disabled\n    this.readOnly = this.props.readOnly\n    this.readPretty = this.props.readPretty\n    this.visible = this.props.visible\n    this.hidden = this.props.hidden\n    this.dataSource = this.props.dataSource\n    this.validator = this.props.validator\n    this.required = this.props.required\n    this.content = this.props.content\n    this.initialValue = this.props.initialValue\n    this.value = this.props.value\n    this.data = this.props.data\n    this.decorator = toArr(this.props.decorator)\n    this.component = toArr(this.props.component)\n  }\n\n  protected makeObservable() {\n    if (this.designable) return\n    define(this, {\n      path: observable.ref,\n      title: observable.ref,\n      description: observable.ref,\n      dataSource: observable.ref,\n      selfDisplay: observable.ref,\n      selfPattern: observable.ref,\n      loading: observable.ref,\n      validating: observable.ref,\n      submitting: observable.ref,\n      selfModified: observable.ref,\n      modified: observable.ref,\n      active: observable.ref,\n      visited: observable.ref,\n      initialized: observable.ref,\n      mounted: observable.ref,\n      unmounted: observable.ref,\n      inputValue: observable.ref,\n      inputValues: observable.ref,\n      decoratorType: observable.ref,\n      componentType: observable.ref,\n      content: observable.ref,\n      feedbacks: observable.ref,\n      decoratorProps: observable,\n      componentProps: observable,\n      validator: observable.shallow,\n      data: observable.shallow,\n      component: observable.computed,\n      decorator: observable.computed,\n      errors: observable.computed,\n      warnings: observable.computed,\n      successes: observable.computed,\n      valid: observable.computed,\n      invalid: observable.computed,\n      selfErrors: observable.computed,\n      selfWarnings: observable.computed,\n      selfSuccesses: observable.computed,\n      selfValid: observable.computed,\n      selfInvalid: observable.computed,\n      validateStatus: observable.computed,\n      value: observable.computed,\n      initialValue: observable.computed,\n      display: observable.computed,\n      pattern: observable.computed,\n      required: observable.computed,\n      hidden: observable.computed,\n      visible: observable.computed,\n      disabled: observable.computed,\n      readOnly: observable.computed,\n      readPretty: observable.computed,\n      editable: observable.computed,\n      indexes: observable.computed,\n      setDisplay: action,\n      setTitle: action,\n      setDescription: action,\n      setDataSource: action,\n      setValue: action,\n      setPattern: action,\n      setInitialValue: action,\n      setLoading: action,\n      setValidating: action,\n      setFeedback: action,\n      setSelfErrors: action,\n      setSelfWarnings: action,\n      setSelfSuccesses: action,\n      setValidator: action,\n      setRequired: action,\n      setComponent: action,\n      setComponentProps: action,\n      setDecorator: action,\n      setDecoratorProps: action,\n      setData: action,\n      setContent: action,\n      validate: action,\n      reset: action,\n      onInit: batch,\n      onInput: batch,\n      onMount: batch,\n      onUnmount: batch,\n      onFocus: batch,\n      onBlur: batch,\n    })\n  }\n\n  protected makeReactive() {\n    if (this.designable) return\n    this.disposers.push(\n      createReaction(\n        () => this.value,\n        (value) => {\n          this.notify(LifeCycleTypes.ON_FIELD_VALUE_CHANGE)\n          if (isValid(value)) {\n            if (this.selfModified && !this.caches.inputting) {\n              validateSelf(this)\n            }\n            if (!isEmpty(value) && this.display === 'none') {\n              this.caches.value = toJS(value)\n              this.form.deleteValuesIn(this.path)\n            }\n          }\n        }\n      ),\n      createReaction(\n        () => this.initialValue,\n        () => {\n          this.notify(LifeCycleTypes.ON_FIELD_INITIAL_VALUE_CHANGE)\n        }\n      ),\n      createReaction(\n        () => this.display,\n        (display) => {\n          const value = this.value\n          if (display !== 'none') {\n            if (value === undefined && this.caches.value !== undefined) {\n              this.setValue(this.caches.value)\n              this.caches.value = undefined\n            }\n          } else {\n            this.caches.value = toJS(value) ?? toJS(this.initialValue)\n            this.form.deleteValuesIn(this.path)\n          }\n          if (display === 'none' || display === 'hidden') {\n            this.setFeedback({\n              type: 'error',\n              messages: [],\n            })\n          }\n        }\n      ),\n      createReaction(\n        () => this.pattern,\n        (pattern) => {\n          if (pattern !== 'editable') {\n            this.setFeedback({\n              type: 'error',\n              messages: [],\n            })\n          }\n        }\n      )\n    )\n    createReactions(this)\n  }\n\n  get selfErrors(): FeedbackMessage {\n    return queryFeedbackMessages(this, {\n      type: 'error',\n    })\n  }\n\n  get errors(): IFormFeedback[] {\n    return this.form.errors.filter(createChildrenFeedbackFilter(this))\n  }\n\n  get selfWarnings(): FeedbackMessage {\n    return queryFeedbackMessages(this, {\n      type: 'warning',\n    })\n  }\n\n  get warnings(): IFormFeedback[] {\n    return this.form.warnings.filter(createChildrenFeedbackFilter(this))\n  }\n\n  get selfSuccesses(): FeedbackMessage {\n    return queryFeedbackMessages(this, {\n      type: 'success',\n    })\n  }\n\n  get successes(): IFormFeedback[] {\n    return this.form.successes.filter(createChildrenFeedbackFilter(this))\n  }\n\n  get selfValid() {\n    return !this.selfErrors.length\n  }\n\n  get valid() {\n    return !this.errors.length\n  }\n\n  get selfInvalid() {\n    return !this.selfValid\n  }\n\n  get invalid() {\n    return !this.valid\n  }\n\n  get value(): ValueType {\n    return this.form.getValuesIn(this.path)\n  }\n\n  get initialValue(): ValueType {\n    return this.form.getInitialValuesIn(this.path)\n  }\n\n  get required() {\n    const validators = isArr(this.validator)\n      ? this.validator\n      : parseValidatorDescriptions(this.validator)\n    return validators.some((desc) => !!desc?.['required'])\n  }\n\n  get validateStatus() {\n    if (this.validating) return 'validating'\n    if (this.selfInvalid) return 'error'\n    if (this.selfWarnings.length) return 'warning'\n    if (this.selfSuccesses.length) return 'success'\n  }\n\n  set required(required: boolean) {\n    if (this.required === required) return\n    this.setValidatorRule('required', required)\n  }\n\n  set value(value: ValueType) {\n    this.setValue(value)\n  }\n\n  set initialValue(initialValue: ValueType) {\n    this.setInitialValue(initialValue)\n  }\n\n  set selfErrors(messages: FeedbackMessage) {\n    this.setFeedback({\n      type: 'error',\n      code: 'EffectError',\n      messages,\n    })\n  }\n\n  set selfWarnings(messages: FeedbackMessage) {\n    this.setFeedback({\n      type: 'warning',\n      code: 'EffectWarning',\n      messages,\n    })\n  }\n\n  set selfSuccesses(messages: FeedbackMessage) {\n    this.setFeedback({\n      type: 'success',\n      code: 'EffectSuccess',\n      messages,\n    })\n  }\n\n  setDataSource = (dataSource?: FieldDataSource) => {\n    this.dataSource = dataSource\n  }\n\n  setFeedback = (feedback?: IFieldFeedback) => {\n    updateFeedback(this, feedback)\n  }\n\n  setSelfErrors = (messages?: FeedbackMessage) => {\n    this.selfErrors = messages\n  }\n\n  setSelfWarnings = (messages?: FeedbackMessage) => {\n    this.selfWarnings = messages\n  }\n\n  setSelfSuccesses = (messages?: FeedbackMessage) => {\n    this.selfSuccesses = messages\n  }\n\n  setValidator = (validator?: FieldValidator) => {\n    this.validator = validator\n  }\n\n  setValidatorRule = (name: string, value: any) => {\n    setValidatorRule(this, name, value)\n  }\n\n  setRequired = (required?: boolean) => {\n    this.required = required\n  }\n\n  setValue = (value?: ValueType) => {\n    if (this.destroyed) return\n    if (!this.initialized) {\n      if (this.display === 'none') {\n        this.caches.value = value\n        return\n      }\n      value = getValidFieldDefaultValue(value, this.initialValue)\n      if (!allowAssignDefaultValue(this.value, value) && !this.designable) {\n        return\n      }\n    }\n    this.form.setValuesIn(this.path, value)\n  }\n\n  setInitialValue = (initialValue?: ValueType) => {\n    if (this.destroyed) return\n    if (!this.initialized) {\n      if (\n        !allowAssignDefaultValue(this.initialValue, initialValue) &&\n        !this.designable\n      ) {\n        return\n      }\n    }\n    this.form.setInitialValuesIn(this.path, initialValue)\n  }\n\n  setLoading = (loading?: boolean) => {\n    setLoading(this, loading)\n  }\n\n  setValidating = (validating?: boolean) => {\n    setValidating(this, validating)\n  }\n\n  setSubmitting = (submitting?: boolean) => {\n    setSubmitting(this, submitting)\n  }\n\n  setState: IModelSetter<IFieldState> = createStateSetter(this)\n\n  getState: IModelGetter<IFieldState> = createStateGetter(this)\n\n  onInput = async (...args: any[]) => {\n    const isHTMLInputEventFromSelf = (args: any[]) =>\n      isHTMLInputEvent(args[0]) && 'currentTarget' in args[0]\n        ? args[0]?.target === args[0]?.currentTarget\n        : true\n    const getValues = (args: any[]) => {\n      if (args[0]?.target) {\n        if (!isHTMLInputEvent(args[0])) return args\n      }\n      return getValuesFromEvent(args)\n    }\n\n    if (!isHTMLInputEventFromSelf(args)) return\n\n    const values = getValues(args)\n    const value = values[0]\n    this.caches.inputting = true\n    this.inputValue = value\n    this.inputValues = values\n    this.value = value\n    this.modify()\n    this.notify(LifeCycleTypes.ON_FIELD_INPUT_VALUE_CHANGE)\n    this.notify(LifeCycleTypes.ON_FORM_INPUT_CHANGE, this.form)\n    await validateSelf(this, 'onInput')\n    this.caches.inputting = false\n  }\n\n  onFocus = async (...args: any[]) => {\n    if (args[0]?.target) {\n      if (!isHTMLInputEvent(args[0], false)) return\n    }\n    this.active = true\n    this.visited = true\n    await validateSelf(this, 'onFocus')\n  }\n\n  onBlur = async (...args: any[]) => {\n    if (args[0]?.target) {\n      if (!isHTMLInputEvent(args[0], false)) return\n    }\n    this.active = false\n    await validateSelf(this, 'onBlur')\n  }\n\n  validate = (triggerType?: ValidatorTriggerType) => {\n    return batchValidate(this, `${this.address}.**`, triggerType)\n  }\n\n  submit = <T>(onSubmit?: (values: any) => Promise<T> | void): Promise<T> => {\n    return batchSubmit(this, onSubmit)\n  }\n\n  reset = (options?: IFieldResetOptions) => {\n    return batchReset(this, `${this.address}.**`, options)\n  }\n\n  queryFeedbacks = (search?: ISearchFeedback): IFieldFeedback[] => {\n    return queryFeedbacks(this, search)\n  }\n\n  modify = () => modifySelf(this)\n}\n"
  },
  {
    "path": "packages/core/src/models/Form.ts",
    "content": "import { define, observable, batch, action, observe } from '@formily/reactive'\nimport {\n  FormPath,\n  FormPathPattern,\n  isValid,\n  uid,\n  globalThisPolyfill,\n  merge,\n  isPlainObj,\n  isArr,\n  isObj,\n} from '@formily/shared'\nimport { Heart } from './Heart'\nimport { Field } from './Field'\nimport {\n  JSXComponent,\n  LifeCycleTypes,\n  HeartSubscriber,\n  FormPatternTypes,\n  IFormRequests,\n  IFormFeedback,\n  ISearchFeedback,\n  IFormGraph,\n  IFormProps,\n  IFieldResetOptions,\n  IFormFields,\n  IFieldFactoryProps,\n  IVoidFieldFactoryProps,\n  IFormState,\n  IModelGetter,\n  IModelSetter,\n  IFieldStateGetter,\n  IFieldStateSetter,\n  FormDisplayTypes,\n  IFormMergeStrategy,\n} from '../types'\nimport {\n  createStateGetter,\n  createStateSetter,\n  createBatchStateSetter,\n  createBatchStateGetter,\n  triggerFormInitialValuesChange,\n  triggerFormValuesChange,\n  batchValidate,\n  batchReset,\n  batchSubmit,\n  setValidating,\n  setSubmitting,\n  setLoading,\n  getValidFormValues,\n} from '../shared/internals'\nimport { isVoidField } from '../shared/checkers'\nimport { runEffects } from '../shared/effective'\nimport { ArrayField } from './ArrayField'\nimport { ObjectField } from './ObjectField'\nimport { VoidField } from './VoidField'\nimport { Query } from './Query'\nimport { Graph } from './Graph'\n\nconst DEV_TOOLS_HOOK = '__FORMILY_DEV_TOOLS_HOOK__'\n\nexport class Form<ValueType extends object = any> {\n  displayName = 'Form'\n  id: string\n  initialized: boolean\n  validating: boolean\n  submitting: boolean\n  loading: boolean\n  modified: boolean\n  pattern: FormPatternTypes\n  display: FormDisplayTypes\n  values: ValueType\n  initialValues: ValueType\n  mounted: boolean\n  unmounted: boolean\n  props: IFormProps<ValueType>\n  heart: Heart\n  graph: Graph\n  fields: IFormFields = {}\n  requests: IFormRequests = {}\n  indexes: Record<string, string> = {}\n  disposers: (() => void)[] = []\n\n  constructor(props: IFormProps<ValueType>) {\n    this.initialize(props)\n    this.makeObservable()\n    this.makeReactive()\n    this.makeValues()\n    this.onInit()\n  }\n\n  protected initialize(props: IFormProps<ValueType>) {\n    this.id = uid()\n    this.props = { ...props }\n    this.initialized = false\n    this.submitting = false\n    this.validating = false\n    this.loading = false\n    this.modified = false\n    this.mounted = false\n    this.unmounted = false\n    this.display = this.props.display || 'visible'\n    this.pattern = this.props.pattern || 'editable'\n    this.editable = this.props.editable\n    this.disabled = this.props.disabled\n    this.readOnly = this.props.readOnly\n    this.readPretty = this.props.readPretty\n    this.visible = this.props.visible\n    this.hidden = this.props.hidden\n    this.graph = new Graph(this)\n    this.heart = new Heart({\n      lifecycles: this.lifecycles,\n      context: this,\n    })\n  }\n\n  protected makeValues() {\n    this.values = getValidFormValues(this.props.values)\n    this.initialValues = getValidFormValues(this.props.initialValues)\n  }\n\n  protected makeObservable() {\n    define(this, {\n      fields: observable.shallow,\n      indexes: observable.shallow,\n      initialized: observable.ref,\n      validating: observable.ref,\n      submitting: observable.ref,\n      loading: observable.ref,\n      modified: observable.ref,\n      pattern: observable.ref,\n      display: observable.ref,\n      mounted: observable.ref,\n      unmounted: observable.ref,\n      values: observable,\n      initialValues: observable,\n      valid: observable.computed,\n      invalid: observable.computed,\n      errors: observable.computed,\n      warnings: observable.computed,\n      successes: observable.computed,\n      hidden: observable.computed,\n      visible: observable.computed,\n      editable: observable.computed,\n      readOnly: observable.computed,\n      readPretty: observable.computed,\n      disabled: observable.computed,\n      setValues: action,\n      setValuesIn: action,\n      setInitialValues: action,\n      setInitialValuesIn: action,\n      setPattern: action,\n      setDisplay: action,\n      setState: action,\n      deleteInitialValuesIn: action,\n      deleteValuesIn: action,\n      setSubmitting: action,\n      setValidating: action,\n      reset: action,\n      submit: action,\n      validate: action,\n      onMount: batch,\n      onUnmount: batch,\n      onInit: batch,\n    })\n  }\n\n  protected makeReactive() {\n    this.disposers.push(\n      observe(\n        this,\n        (change) => {\n          triggerFormInitialValuesChange(this, change)\n          triggerFormValuesChange(this, change)\n        },\n        true\n      )\n    )\n  }\n\n  get valid() {\n    return !this.invalid\n  }\n\n  get invalid() {\n    return this.errors.length > 0\n  }\n\n  get errors() {\n    return this.queryFeedbacks({\n      type: 'error',\n    })\n  }\n\n  get warnings() {\n    return this.queryFeedbacks({\n      type: 'warning',\n    })\n  }\n\n  get successes() {\n    return this.queryFeedbacks({\n      type: 'success',\n    })\n  }\n\n  get lifecycles() {\n    return runEffects(this, this.props.effects)\n  }\n\n  get hidden() {\n    return this.display === 'hidden'\n  }\n\n  get visible() {\n    return this.display === 'visible'\n  }\n\n  set hidden(hidden: boolean) {\n    if (!isValid(hidden)) return\n    if (hidden) {\n      this.display = 'hidden'\n    } else {\n      this.display = 'visible'\n    }\n  }\n\n  set visible(visible: boolean) {\n    if (!isValid(visible)) return\n    if (visible) {\n      this.display = 'visible'\n    } else {\n      this.display = 'none'\n    }\n  }\n\n  get editable() {\n    return this.pattern === 'editable'\n  }\n\n  set editable(editable) {\n    if (!isValid(editable)) return\n    if (editable) {\n      this.pattern = 'editable'\n    } else {\n      this.pattern = 'readPretty'\n    }\n  }\n\n  get readOnly() {\n    return this.pattern === 'readOnly'\n  }\n\n  set readOnly(readOnly) {\n    if (!isValid(readOnly)) return\n    if (readOnly) {\n      this.pattern = 'readOnly'\n    } else {\n      this.pattern = 'editable'\n    }\n  }\n\n  get disabled() {\n    return this.pattern === 'disabled'\n  }\n\n  set disabled(disabled) {\n    if (!isValid(disabled)) return\n    if (disabled) {\n      this.pattern = 'disabled'\n    } else {\n      this.pattern = 'editable'\n    }\n  }\n\n  get readPretty() {\n    return this.pattern === 'readPretty'\n  }\n\n  set readPretty(readPretty) {\n    if (!isValid(readPretty)) return\n    if (readPretty) {\n      this.pattern = 'readPretty'\n    } else {\n      this.pattern = 'editable'\n    }\n  }\n\n  /** 创建字段 **/\n\n  createField = <\n    Decorator extends JSXComponent,\n    Component extends JSXComponent\n  >(\n    props: IFieldFactoryProps<Decorator, Component>\n  ): Field<Decorator, Component> => {\n    const address = FormPath.parse(props.basePath).concat(props.name)\n    const identifier = address.toString()\n    if (!identifier) return\n    if (!this.fields[identifier] || this.props.designable) {\n      batch(() => {\n        new Field(address, props, this, this.props.designable)\n      })\n      this.notify(LifeCycleTypes.ON_FORM_GRAPH_CHANGE)\n    }\n    return this.fields[identifier] as any\n  }\n\n  createArrayField = <\n    Decorator extends JSXComponent,\n    Component extends JSXComponent\n  >(\n    props: IFieldFactoryProps<Decorator, Component>\n  ): ArrayField<Decorator, Component> => {\n    const address = FormPath.parse(props.basePath).concat(props.name)\n    const identifier = address.toString()\n    if (!identifier) return\n    if (!this.fields[identifier] || this.props.designable) {\n      batch(() => {\n        new ArrayField(\n          address,\n          {\n            ...props,\n            value: isArr(props.value) ? props.value : [],\n          },\n          this,\n          this.props.designable\n        )\n      })\n      this.notify(LifeCycleTypes.ON_FORM_GRAPH_CHANGE)\n    }\n    return this.fields[identifier] as any\n  }\n\n  createObjectField = <\n    Decorator extends JSXComponent,\n    Component extends JSXComponent\n  >(\n    props: IFieldFactoryProps<Decorator, Component>\n  ): ObjectField<Decorator, Component> => {\n    const address = FormPath.parse(props.basePath).concat(props.name)\n    const identifier = address.toString()\n    if (!identifier) return\n    if (!this.fields[identifier] || this.props.designable) {\n      batch(() => {\n        new ObjectField(\n          address,\n          {\n            ...props,\n            value: isObj(props.value) ? props.value : {},\n          },\n          this,\n          this.props.designable\n        )\n      })\n      this.notify(LifeCycleTypes.ON_FORM_GRAPH_CHANGE)\n    }\n    return this.fields[identifier] as any\n  }\n\n  createVoidField = <\n    Decorator extends JSXComponent,\n    Component extends JSXComponent\n  >(\n    props: IVoidFieldFactoryProps<Decorator, Component>\n  ): VoidField<Decorator, Component> => {\n    const address = FormPath.parse(props.basePath).concat(props.name)\n    const identifier = address.toString()\n    if (!identifier) return\n    if (!this.fields[identifier] || this.props.designable) {\n      batch(() => {\n        new VoidField(address, props, this, this.props.designable)\n      })\n      this.notify(LifeCycleTypes.ON_FORM_GRAPH_CHANGE)\n    }\n    return this.fields[identifier] as any\n  }\n\n  /** 状态操作模型 **/\n\n  setValues = (values: any, strategy: IFormMergeStrategy = 'merge') => {\n    if (!isPlainObj(values)) return\n    if (strategy === 'merge' || strategy === 'deepMerge') {\n      merge(this.values, values, {\n        // never reach\n        arrayMerge: (target, source) => source,\n        assign: true,\n      })\n    } else if (strategy === 'shallowMerge') {\n      Object.assign(this.values, values)\n    } else {\n      this.values = values as any\n    }\n  }\n\n  setInitialValues = (\n    initialValues: any,\n    strategy: IFormMergeStrategy = 'merge'\n  ) => {\n    if (!isPlainObj(initialValues)) return\n    if (strategy === 'merge' || strategy === 'deepMerge') {\n      merge(this.initialValues, initialValues, {\n        // never reach\n        arrayMerge: (target, source) => source,\n        assign: true,\n      })\n    } else if (strategy === 'shallowMerge') {\n      Object.assign(this.initialValues, initialValues)\n    } else {\n      this.initialValues = initialValues as any\n    }\n  }\n\n  setValuesIn = (pattern: FormPathPattern, value: any) => {\n    FormPath.setIn(this.values, pattern, value)\n  }\n\n  deleteValuesIn = (pattern: FormPathPattern) => {\n    FormPath.deleteIn(this.values, pattern)\n  }\n\n  existValuesIn = (pattern: FormPathPattern) => {\n    return FormPath.existIn(this.values, pattern)\n  }\n\n  getValuesIn = (pattern: FormPathPattern) => {\n    return FormPath.getIn(this.values, pattern)\n  }\n\n  setInitialValuesIn = (pattern: FormPathPattern, initialValue: any) => {\n    FormPath.setIn(this.initialValues, pattern, initialValue)\n  }\n\n  deleteInitialValuesIn = (pattern: FormPathPattern) => {\n    FormPath.deleteIn(this.initialValues, pattern)\n  }\n\n  existInitialValuesIn = (pattern: FormPathPattern) => {\n    return FormPath.existIn(this.initialValues, pattern)\n  }\n\n  getInitialValuesIn = (pattern: FormPathPattern) => {\n    return FormPath.getIn(this.initialValues, pattern)\n  }\n\n  setLoading = (loading: boolean) => {\n    setLoading(this, loading)\n  }\n\n  setSubmitting = (submitting: boolean) => {\n    setSubmitting(this, submitting)\n  }\n\n  setValidating = (validating: boolean) => {\n    setValidating(this, validating)\n  }\n\n  setDisplay = (display: FormDisplayTypes) => {\n    this.display = display\n  }\n\n  setPattern = (pattern: FormPatternTypes) => {\n    this.pattern = pattern\n  }\n\n  addEffects = (id: any, effects: IFormProps['effects']) => {\n    if (!this.heart.hasLifeCycles(id)) {\n      this.heart.addLifeCycles(id, runEffects(this, effects))\n    }\n  }\n\n  removeEffects = (id: any) => {\n    this.heart.removeLifeCycles(id)\n  }\n\n  setEffects = (effects: IFormProps['effects']) => {\n    this.heart.setLifeCycles(runEffects(this, effects))\n  }\n\n  clearErrors = (pattern: FormPathPattern = '*') => {\n    this.query(pattern).forEach((field) => {\n      if (!isVoidField(field)) {\n        field.setFeedback({\n          type: 'error',\n          messages: [],\n        })\n      }\n    })\n  }\n\n  clearWarnings = (pattern: FormPathPattern = '*') => {\n    this.query(pattern).forEach((field) => {\n      if (!isVoidField(field)) {\n        field.setFeedback({\n          type: 'warning',\n          messages: [],\n        })\n      }\n    })\n  }\n\n  clearSuccesses = (pattern: FormPathPattern = '*') => {\n    this.query(pattern).forEach((field) => {\n      if (!isVoidField(field)) {\n        field.setFeedback({\n          type: 'success',\n          messages: [],\n        })\n      }\n    })\n  }\n\n  query = (pattern: FormPathPattern): Query => {\n    return new Query({\n      pattern,\n      base: '',\n      form: this,\n    })\n  }\n\n  queryFeedbacks = (search: ISearchFeedback): IFormFeedback[] => {\n    return this.query(search.address || search.path || '*').reduce(\n      (messages, field) => {\n        if (isVoidField(field)) return messages\n        return messages.concat(\n          field\n            .queryFeedbacks(search)\n            .map((feedback) => ({\n              ...feedback,\n              address: field.address.toString(),\n              path: field.path.toString(),\n            }))\n            .filter((feedback) => feedback.messages.length > 0)\n        )\n      },\n      []\n    )\n  }\n\n  notify = (type: string, payload?: any) => {\n    this.heart.publish(type, payload ?? this)\n  }\n\n  subscribe = (subscriber?: HeartSubscriber) => {\n    return this.heart.subscribe(subscriber)\n  }\n\n  unsubscribe = (id: number) => {\n    this.heart.unsubscribe(id)\n  }\n\n  /**事件钩子**/\n\n  onInit = () => {\n    this.initialized = true\n    this.notify(LifeCycleTypes.ON_FORM_INIT)\n  }\n\n  onMount = () => {\n    this.mounted = true\n    this.notify(LifeCycleTypes.ON_FORM_MOUNT)\n    if (globalThisPolyfill[DEV_TOOLS_HOOK] && !this.props.designable) {\n      globalThisPolyfill[DEV_TOOLS_HOOK].inject(this.id, this)\n    }\n  }\n\n  onUnmount = () => {\n    this.notify(LifeCycleTypes.ON_FORM_UNMOUNT)\n    this.query('*').forEach((field) => field.destroy(false))\n    this.disposers.forEach((dispose) => dispose())\n    this.unmounted = true\n    this.indexes = {}\n    this.heart.clear()\n    if (globalThisPolyfill[DEV_TOOLS_HOOK] && !this.props.designable) {\n      globalThisPolyfill[DEV_TOOLS_HOOK].unmount(this.id)\n    }\n  }\n\n  setState: IModelSetter<IFormState<ValueType>> = createStateSetter(this)\n\n  getState: IModelGetter<IFormState<ValueType>> = createStateGetter(this)\n\n  setFormState: IModelSetter<IFormState<ValueType>> = createStateSetter(this)\n\n  getFormState: IModelGetter<IFormState<ValueType>> = createStateGetter(this)\n\n  setFieldState: IFieldStateSetter = createBatchStateSetter(this)\n\n  getFieldState: IFieldStateGetter = createBatchStateGetter(this)\n\n  getFormGraph = () => {\n    return this.graph.getGraph()\n  }\n\n  setFormGraph = (graph: IFormGraph) => {\n    this.graph.setGraph(graph)\n  }\n\n  clearFormGraph = (pattern: FormPathPattern = '*', forceClear = true) => {\n    this.query(pattern).forEach((field) => {\n      field.destroy(forceClear)\n    })\n  }\n\n  validate = (pattern: FormPathPattern = '*') => {\n    return batchValidate(this, pattern)\n  }\n\n  submit = <T>(\n    onSubmit?: (values: ValueType) => Promise<T> | void\n  ): Promise<T> => {\n    return batchSubmit(this, onSubmit)\n  }\n\n  reset = (pattern: FormPathPattern = '*', options?: IFieldResetOptions) => {\n    return batchReset(this, pattern, options)\n  }\n}\n"
  },
  {
    "path": "packages/core/src/models/Graph.ts",
    "content": "import { define, batch } from '@formily/reactive'\nimport { each, FormPath } from '@formily/shared'\nimport { IFormGraph } from '../types'\nimport { Form } from './Form'\nimport {\n  isFormState,\n  isFieldState,\n  isArrayFieldState,\n  isObjectFieldState,\n} from '../shared/checkers'\n\nexport class Graph {\n  form: Form\n\n  constructor(form: Form) {\n    this.form = form\n    define(this, {\n      setGraph: batch,\n    })\n  }\n\n  getGraph = (): IFormGraph => {\n    const graph = {}\n    graph[''] = this.form.getState()\n    each(this.form.fields, (field: any, identifier) => {\n      graph[identifier] = field.getState()\n    })\n    return graph\n  }\n\n  setGraph = (graph: IFormGraph) => {\n    const form = this.form\n    const createField = (identifier: string, state: any) => {\n      const address = FormPath.parse(identifier)\n      const name = address.segments[address.segments.length - 1]\n      const basePath = address.parent()\n      if (isFieldState(state)) {\n        return this.form.createField({ name, basePath })\n      } else if (isArrayFieldState(state)) {\n        return this.form.createArrayField({ name, basePath })\n      } else if (isObjectFieldState(state)) {\n        return this.form.createObjectField({ name, basePath })\n      } else {\n        return this.form.createVoidField({ name, basePath })\n      }\n    }\n    each(graph, (state, address) => {\n      if (isFormState(state)) {\n        form.setState(state)\n      } else {\n        const field = form.fields[address]\n        if (field) {\n          field.setState(state)\n        } else {\n          createField(address, state).setState(state)\n        }\n      }\n    })\n  }\n}\n"
  },
  {
    "path": "packages/core/src/models/Heart.ts",
    "content": "import { isStr, isArr, Subscribable } from '@formily/shared'\nimport { LifeCycle } from './LifeCycle'\nimport { IHeartProps } from '../types'\nexport class Heart<Payload = any, Context = any> extends Subscribable {\n  lifecycles: LifeCycle<Payload>[] = []\n\n  outerLifecycles: Map<any, LifeCycle<Payload>[]> = new Map()\n\n  context: Context\n\n  constructor({ lifecycles, context }: IHeartProps<Context> = {}) {\n    super()\n    this.lifecycles = this.buildLifeCycles(lifecycles || [])\n    this.context = context\n  }\n\n  buildLifeCycles = (lifecycles: LifeCycle[]) => {\n    return lifecycles.reduce((buf, item) => {\n      if (item instanceof LifeCycle) {\n        return buf.concat(item)\n      } else {\n        if (isArr(item)) {\n          return this.buildLifeCycles(item)\n        } else if (typeof item === 'object') {\n          this.context = item\n          return buf\n        }\n        return buf\n      }\n    }, [])\n  }\n\n  addLifeCycles = (id: any, lifecycles: LifeCycle[] = []) => {\n    const observers = this.buildLifeCycles(lifecycles)\n    if (observers.length) {\n      this.outerLifecycles.set(id, observers)\n    }\n  }\n\n  hasLifeCycles = (id: any) => {\n    return this.outerLifecycles.has(id)\n  }\n\n  removeLifeCycles = (id: any) => {\n    this.outerLifecycles.delete(id)\n  }\n\n  setLifeCycles = (lifecycles: LifeCycle[] = []) => {\n    this.lifecycles = this.buildLifeCycles(lifecycles)\n  }\n\n  publish = <P, C>(type: any, payload?: P, context?: C) => {\n    if (isStr(type)) {\n      this.lifecycles.forEach((lifecycle) => {\n        lifecycle.notify(type, payload, context || this.context)\n      })\n      this.outerLifecycles.forEach((lifecycles) => {\n        lifecycles.forEach((lifecycle) => {\n          lifecycle.notify(type, payload, context || this.context)\n        })\n      })\n      this.notify({\n        type,\n        payload,\n      })\n    }\n  }\n\n  clear = () => {\n    this.lifecycles = []\n    this.outerLifecycles.clear()\n    this.unsubscribe()\n  }\n}\n"
  },
  {
    "path": "packages/core/src/models/LifeCycle.ts",
    "content": "import { isFn, isStr, each } from '@formily/shared'\nimport { LifeCycleHandler, LifeCyclePayload } from '../types'\n\ntype LifeCycleParams<Payload> = Array<\n  | string\n  | LifeCycleHandler<Payload>\n  | { [key: string]: LifeCycleHandler<Payload> }\n>\nexport class LifeCycle<Payload = any> {\n  private listener: LifeCyclePayload<Payload>\n\n  constructor(...params: LifeCycleParams<Payload>) {\n    this.listener = this.buildListener(params)\n  }\n  buildListener = (params: any[]) => {\n    return function (payload: { type: string; payload: Payload }, ctx: any) {\n      for (let index = 0; index < params.length; index++) {\n        let item = params[index]\n        if (isFn(item)) {\n          item.call(this, payload, ctx)\n        } else if (isStr(item) && isFn(params[index + 1])) {\n          if (item === payload.type) {\n            params[index + 1].call(this, payload.payload, ctx)\n          }\n          index++\n        } else {\n          each<any, any>(item, (handler, type) => {\n            if (isFn(handler) && isStr(type)) {\n              if (type === payload.type) {\n                handler.call(this, payload.payload, ctx)\n                return false\n              }\n            }\n          })\n        }\n      }\n    }\n  }\n\n  notify = <Payload>(type: any, payload?: Payload, ctx?: any) => {\n    if (isStr(type)) {\n      this.listener.call(ctx, { type, payload }, ctx)\n    }\n  }\n}\n"
  },
  {
    "path": "packages/core/src/models/ObjectField.ts",
    "content": "import { reaction } from '@formily/reactive'\nimport { cleanupObjectChildren } from '../shared/internals'\nimport { JSXComponent, IFieldProps, FormPathPattern } from '../types'\nimport { Field } from './Field'\nimport { Form } from './Form'\n\nexport class ObjectField<\n  Decorator extends JSXComponent = any,\n  Component extends JSXComponent = any\n> extends Field<Decorator, Component, any, Record<string, any>> {\n  displayName = 'ObjectField'\n  private additionalProperties: string[] = []\n  constructor(\n    address: FormPathPattern,\n    props: IFieldProps<Decorator, Component>,\n    form: Form,\n    designable: boolean\n  ) {\n    super(address, props, form, designable)\n    this.makeAutoCleanable()\n  }\n\n  protected makeAutoCleanable() {\n    this.disposers.push(\n      reaction(\n        () => Object.keys(this.value || {}),\n        (newKeys) => {\n          const filterKeys = this.additionalProperties.filter(\n            (key) => !newKeys.includes(key)\n          )\n          cleanupObjectChildren(this, filterKeys)\n        }\n      )\n    )\n  }\n\n  addProperty = (key: string, value: any) => {\n    this.form.setValuesIn(this.path.concat(key), value)\n    this.additionalProperties.push(key)\n    return this.onInput(this.value)\n  }\n\n  removeProperty = (key: string) => {\n    this.form.deleteValuesIn(this.path.concat(key))\n    this.additionalProperties.splice(this.additionalProperties.indexOf(key), 1)\n    return this.onInput(this.value)\n  }\n\n  existProperty = (key: string) => {\n    return this.form.existValuesIn(this.path.concat(key))\n  }\n}\n"
  },
  {
    "path": "packages/core/src/models/Query.ts",
    "content": "import { FormPath, isFn, each, FormPathPattern } from '@formily/shared'\nimport { buildDataPath } from '../shared/internals'\nimport { GeneralField, IGeneralFieldState, IQueryProps } from '../types'\nimport { Form } from './Form'\n\nconst output = (\n  field: GeneralField,\n  taker: (field: GeneralField, address: FormPath) => any\n) => {\n  if (!field) return\n  if (isFn(taker)) {\n    return taker(field, field.address)\n  }\n  return field\n}\n\nconst takeMatchPattern = (form: Form, pattern: FormPath) => {\n  const identifier = pattern.toString()\n  const indexIdentifier = form.indexes[identifier]\n  const absoluteField = form.fields[identifier]\n  const indexField = form.fields[indexIdentifier]\n  if (absoluteField) {\n    return identifier\n  } else if (indexField) {\n    return indexIdentifier\n  }\n}\n\nexport class Query {\n  private pattern: FormPath\n  private addresses: string[] = []\n  private form: Form\n  constructor(props: IQueryProps) {\n    this.pattern = FormPath.parse(props.pattern, props.base)\n    this.form = props.form\n    if (!this.pattern.isMatchPattern) {\n      const matched = takeMatchPattern(\n        this.form,\n        this.pattern.haveRelativePattern\n          ? buildDataPath(props.form.fields, this.pattern)\n          : this.pattern\n      )\n      if (matched) {\n        this.addresses = [matched]\n      }\n    } else {\n      each(this.form.fields, (field, address) => {\n        if (!field) {\n          delete this.form.fields[address]\n          return\n        }\n        if (field.match(this.pattern)) {\n          this.addresses.push(address)\n        }\n      })\n    }\n  }\n\n  take(): GeneralField | undefined\n  take<Result>(\n    getter: (field: GeneralField, address: FormPath) => Result\n  ): Result\n  take(taker?: any): any {\n    return output(this.form.fields[this.addresses[0]], taker)\n  }\n\n  map(): GeneralField[]\n  map<Result>(\n    iterator?: (field: GeneralField, address: FormPath) => Result\n  ): Result[]\n  map(iterator?: any): any {\n    return this.addresses.map((address) =>\n      output(this.form.fields[address], iterator)\n    )\n  }\n\n  forEach<Result>(\n    iterator: (field: GeneralField, address: FormPath) => Result\n  ) {\n    return this.addresses.forEach((address) =>\n      output(this.form.fields[address], iterator)\n    )\n  }\n\n  reduce<Result>(\n    reducer: (value: Result, field: GeneralField, address: FormPath) => Result,\n    initial?: Result\n  ): Result {\n    return this.addresses.reduce(\n      (value, address) =>\n        output(this.form.fields[address], (field, address) =>\n          reducer(value, field, address)\n        ),\n      initial\n    )\n  }\n\n  get<K extends keyof IGeneralFieldState>(key: K): IGeneralFieldState[K] {\n    const results: any = this.take()\n    if (results) {\n      return results[key]\n    }\n  }\n\n  getIn(pattern?: FormPathPattern) {\n    return FormPath.getIn(this.take(), pattern)\n  }\n\n  value() {\n    return this.get('value')\n  }\n\n  initialValue() {\n    return this.get('initialValue')\n  }\n}\n"
  },
  {
    "path": "packages/core/src/models/VoidField.ts",
    "content": "import { toArr, FormPathPattern } from '@formily/shared'\nimport { define, observable, batch, action } from '@formily/reactive'\nimport {\n  createReactions,\n  createStateSetter,\n  createStateGetter,\n  initializeStart,\n  initializeEnd,\n} from '../shared/internals'\nimport {\n  IModelSetter,\n  IModelGetter,\n  IVoidFieldProps,\n  IVoidFieldState,\n} from '../types'\nimport { Form } from './Form'\nimport { BaseField } from './BaseField'\n\nexport class VoidField<\n  Decorator = any,\n  Component = any,\n  TextType = any\n> extends BaseField<Decorator, Component, TextType> {\n  displayName: 'VoidField' = 'VoidField'\n  props: IVoidFieldProps<Decorator, Component>\n\n  constructor(\n    address: FormPathPattern,\n    props: IVoidFieldProps<Decorator, Component>,\n    form: Form,\n    designable: boolean\n  ) {\n    super()\n    this.form = form\n    this.props = props\n    this.designable = designable\n    initializeStart()\n    this.locate(address)\n    this.initialize()\n    this.makeObservable()\n    this.makeReactive()\n    this.onInit()\n    initializeEnd()\n  }\n\n  protected initialize() {\n    this.mounted = false\n    this.unmounted = false\n    this.initialized = false\n    this.title = this.props.title\n    this.description = this.props.description\n    this.pattern = this.props.pattern\n    this.display = this.props.display\n    this.hidden = this.props.hidden\n    this.editable = this.props.editable\n    this.disabled = this.props.disabled\n    this.readOnly = this.props.readOnly\n    this.readPretty = this.props.readPretty\n    this.visible = this.props.visible\n    this.content = this.props.content\n    this.data = this.props.data\n    this.decorator = toArr(this.props.decorator)\n    this.component = toArr(this.props.component)\n  }\n\n  protected makeObservable() {\n    if (this.designable) return\n    define(this, {\n      path: observable.ref,\n      title: observable.ref,\n      description: observable.ref,\n      selfDisplay: observable.ref,\n      selfPattern: observable.ref,\n      initialized: observable.ref,\n      mounted: observable.ref,\n      unmounted: observable.ref,\n      decoratorType: observable.ref,\n      componentType: observable.ref,\n      content: observable.ref,\n      data: observable.shallow,\n      decoratorProps: observable,\n      componentProps: observable,\n      display: observable.computed,\n      pattern: observable.computed,\n      hidden: observable.computed,\n      visible: observable.computed,\n      disabled: observable.computed,\n      readOnly: observable.computed,\n      readPretty: observable.computed,\n      editable: observable.computed,\n      component: observable.computed,\n      decorator: observable.computed,\n      indexes: observable.computed,\n      setTitle: action,\n      setDescription: action,\n      setDisplay: action,\n      setPattern: action,\n      setComponent: action,\n      setComponentProps: action,\n      setDecorator: action,\n      setDecoratorProps: action,\n      setData: action,\n      setContent: action,\n      onInit: batch,\n      onMount: batch,\n      onUnmount: batch,\n    })\n  }\n\n  protected makeReactive() {\n    if (this.designable) return\n    createReactions(this)\n  }\n\n  setState: IModelSetter<IVoidFieldState> = createStateSetter(this)\n\n  getState: IModelGetter<IVoidFieldState> = createStateGetter(this)\n}\n"
  },
  {
    "path": "packages/core/src/models/index.ts",
    "content": "export * from './Heart'\nexport * from './LifeCycle'\nexport * from './Graph'\nexport * from './Query'\nexport * from './Form'\nexport * from './Field'\nexport * from './ArrayField'\nexport * from './ObjectField'\nexport * from './VoidField'\n"
  },
  {
    "path": "packages/core/src/models/types.ts",
    "content": "export type { Form } from './Form'\nexport type { Field } from './Field'\nexport type { Query } from './Query'\nexport type { Heart } from './Heart'\nexport type { Graph } from './Graph'\nexport type { LifeCycle } from './LifeCycle'\nexport type { ArrayField } from './ArrayField'\nexport type { ObjectField } from './ObjectField'\nexport type { VoidField } from './VoidField'\n"
  },
  {
    "path": "packages/core/src/shared/checkers.ts",
    "content": "import { isFn } from '@formily/shared'\nimport { DataField, JSXComponent } from '..'\nimport {\n  Form,\n  Field,\n  ArrayField,\n  ObjectField,\n  VoidField,\n  Query,\n} from '../models'\nimport {\n  IFormState,\n  IFieldState,\n  IVoidFieldState,\n  GeneralField,\n  IGeneralFieldState,\n} from '../types'\n\nexport const isForm = (node: any): node is Form => {\n  return node instanceof Form\n}\n\nexport const isGeneralField = (node: any): node is GeneralField => {\n  return node instanceof Field || node instanceof VoidField\n}\n\nexport const isField = <\n  Decorator extends JSXComponent = any,\n  Component extends JSXComponent = any,\n  TextType = any,\n  ValueType = any\n>(\n  node: any\n): node is Field<Decorator, Component, TextType, ValueType> => {\n  return node instanceof Field\n}\n\nexport const isArrayField = <\n  Decorator extends JSXComponent = any,\n  Component extends JSXComponent = any\n>(\n  node: any\n): node is ArrayField<Decorator, Component> => {\n  return node instanceof ArrayField\n}\n\nexport const isObjectField = <\n  Decorator extends JSXComponent = any,\n  Component extends JSXComponent = any\n>(\n  node: any\n): node is ObjectField<Decorator, Component> => {\n  return node instanceof ObjectField\n}\n\nexport const isVoidField = <Decorator = any, Component = any, TextType = any>(\n  node: any\n): node is VoidField<Decorator, Component, TextType> => {\n  return node instanceof VoidField\n}\n\nexport const isFormState = <T extends Record<any, any> = any>(\n  state: any\n): state is IFormState<T> => {\n  if (isFn(state?.initialize)) return false\n  return state?.displayName === 'Form'\n}\n\nexport const isFieldState = (state: any): state is IFieldState => {\n  if (isFn(state?.initialize)) return false\n  return state?.displayName === 'Field'\n}\n\nexport const isGeneralFieldState = (node: any): node is IGeneralFieldState => {\n  if (isFn(node?.initialize)) return false\n  return node?.displayName?.indexOf('Field') > -1\n}\n\nexport const isArrayFieldState = (state: any): state is IFieldState => {\n  if (isFn(state?.initialize)) return false\n  return state?.displayName === 'ArrayField'\n}\n\nexport const isDataField = (node: any): node is DataField => {\n  return isField(node) || isArrayField(node) || isObjectField(node)\n}\n\nexport const isDataFieldState = (node: any) => {\n  return (\n    isFieldState(node) || isObjectFieldState(node) || isArrayFieldState(node)\n  )\n}\n\nexport const isObjectFieldState = (state: any): state is IFieldState => {\n  if (isFn(state?.initialize)) return false\n  return state?.displayName === 'ObjectField'\n}\n\nexport const isVoidFieldState = (state: any): state is IVoidFieldState => {\n  if (isFn(state?.initialize)) return false\n  return state?.displayName === 'VoidField'\n}\n\nexport const isQuery = (query: any): query is Query => {\n  return query && query instanceof Query\n}\n"
  },
  {
    "path": "packages/core/src/shared/constants.ts",
    "content": "export const ReservedProperties = {\n  form: true,\n  parent: true,\n  props: true,\n  caches: true,\n  requests: true,\n  disposers: true,\n  heart: true,\n  graph: true,\n  indexes: true,\n  fields: true,\n  lifecycles: true,\n  componentType: true,\n  componentProps: true,\n  decoratorType: true,\n  decoratorProps: true,\n}\n\nexport const ReadOnlyProperties = {\n  address: true,\n  path: true,\n  valid: true,\n  invalid: true,\n  selfValid: true,\n  selfInvalid: true,\n  errors: true,\n  successes: true,\n  warnings: true,\n  validateStatus: true,\n}\n\nconst SELF_DISPLAY = 'selfDisplay'\nconst SELF_PATTERN = 'selfPattern'\n\nexport const MutuallyExclusiveProperties = {\n  pattern: SELF_PATTERN,\n  editable: SELF_PATTERN,\n  readOnly: SELF_PATTERN,\n  readPretty: SELF_PATTERN,\n  disabled: SELF_PATTERN,\n  display: SELF_DISPLAY,\n  hidden: SELF_DISPLAY,\n  visible: SELF_DISPLAY,\n}\n\nexport const RESPONSE_REQUEST_DURATION = 100\n\nexport const GlobalState = {\n  lifecycles: [],\n  context: [],\n  effectStart: false,\n  effectEnd: false,\n  initializing: false,\n}\n\nexport const NumberIndexReg = /^\\.(\\d+)/\n"
  },
  {
    "path": "packages/core/src/shared/effective.ts",
    "content": "import { isFn, isValid } from '@formily/shared'\nimport { LifeCycle, Form } from '../models'\nimport { AnyFunction } from '../types'\nimport { isForm } from './checkers'\nimport { GlobalState } from './constants'\n\nexport const createEffectHook = <\n  F extends (payload: any, ...ctxs: any[]) => AnyFunction\n>(\n  type: string,\n  callback?: F\n) => {\n  return (...args: Parameters<ReturnType<F>>) => {\n    if (GlobalState.effectStart) {\n      GlobalState.lifecycles.push(\n        new LifeCycle(type, (payload, ctx) => {\n          if (isFn(callback)) {\n            callback(payload, ctx, ...GlobalState.context)(...args)\n          }\n        })\n      )\n    } else {\n      throw new Error(\n        'Effect hooks cannot be used in asynchronous function body'\n      )\n    }\n  }\n}\n\nexport const createEffectContext = <T = any>(defaultValue?: T) => {\n  let index: number\n  return {\n    provide(value?: T) {\n      if (GlobalState.effectStart) {\n        index = GlobalState.context.length\n        GlobalState.context[index] = isValid(value) ? value : defaultValue\n      } else {\n        throw new Error(\n          'Provide method cannot be used in asynchronous function body'\n        )\n      }\n    },\n    consume(): T {\n      if (!GlobalState.effectStart) {\n        throw new Error(\n          'Consume method cannot be used in asynchronous function body'\n        )\n      }\n      return GlobalState.context[index]\n    },\n  }\n}\n\nconst FormEffectContext = createEffectContext<Form>()\n\nexport const useEffectForm = FormEffectContext.consume\n\nexport const runEffects = <Context>(\n  context?: Context,\n  ...args: ((context: Context) => void)[]\n): LifeCycle[] => {\n  GlobalState.lifecycles = []\n  GlobalState.context = []\n  GlobalState.effectStart = true\n  GlobalState.effectEnd = false\n  if (isForm(context)) {\n    FormEffectContext.provide(context)\n  }\n  args.forEach((effects) => {\n    if (isFn(effects)) {\n      effects(context)\n    }\n  })\n  GlobalState.context = []\n  GlobalState.effectStart = false\n  GlobalState.effectEnd = true\n  return GlobalState.lifecycles\n}\n"
  },
  {
    "path": "packages/core/src/shared/externals.ts",
    "content": "import { FormPath } from '@formily/shared'\nimport { Form } from '../models'\nimport { IFormProps } from '../types'\nimport {\n  getValidateLocaleIOSCode,\n  getLocaleByPath,\n  setValidateLanguage,\n  registerValidateFormats,\n  registerValidateLocale,\n  registerValidateMessageTemplateEngine,\n  registerValidateRules,\n} from '@formily/validator'\nimport {\n  createEffectHook,\n  createEffectContext,\n  useEffectForm,\n} from './effective'\nimport {\n  isArrayField,\n  isArrayFieldState,\n  isDataField,\n  isDataFieldState,\n  isField,\n  isFieldState,\n  isForm,\n  isFormState,\n  isGeneralField,\n  isGeneralFieldState,\n  isObjectField,\n  isObjectFieldState,\n  isQuery,\n  isVoidField,\n  isVoidFieldState,\n} from './checkers'\n\nconst createForm = <T extends object = any>(options?: IFormProps<T>) => {\n  return new Form(options)\n}\n\nexport {\n  FormPath,\n  createForm,\n  isArrayField,\n  isArrayFieldState,\n  isDataField,\n  isDataFieldState,\n  isField,\n  isFieldState,\n  isForm,\n  isFormState,\n  isGeneralField,\n  isGeneralFieldState,\n  isObjectField,\n  isObjectFieldState,\n  isQuery,\n  isVoidField,\n  isVoidFieldState,\n  getValidateLocaleIOSCode,\n  getLocaleByPath,\n  setValidateLanguage,\n  registerValidateFormats,\n  registerValidateLocale,\n  registerValidateMessageTemplateEngine,\n  registerValidateRules,\n  createEffectHook,\n  createEffectContext,\n  useEffectForm,\n}\n"
  },
  {
    "path": "packages/core/src/shared/internals.ts",
    "content": "import {\n  FormPath,\n  FormPathPattern,\n  each,\n  pascalCase,\n  isFn,\n  isValid,\n  isUndef,\n  isEmpty,\n  isPlainObj,\n  isNumberLike,\n  clone,\n  toArr,\n} from '@formily/shared'\nimport {\n  ValidatorTriggerType,\n  validate,\n  parseValidatorDescriptions,\n} from '@formily/validator'\nimport {\n  autorun,\n  batch,\n  contains,\n  toJS,\n  isObservable,\n  DataChange,\n  reaction,\n  untracked,\n} from '@formily/reactive'\nimport { Field, ArrayField, Form, ObjectField } from '../models'\nimport {\n  ISpliceArrayStateProps,\n  IExchangeArrayStateProps,\n  IFieldResetOptions,\n  ISearchFeedback,\n  IFieldFeedback,\n  INodePatch,\n  GeneralField,\n  IFormFeedback,\n  LifeCycleTypes,\n  FieldMatchPattern,\n  FieldFeedbackTypes,\n} from '../types'\nimport {\n  isArrayField,\n  isObjectField,\n  isGeneralField,\n  isDataField,\n  isForm,\n  isQuery,\n  isVoidField,\n} from './externals'\nimport {\n  RESPONSE_REQUEST_DURATION,\n  ReservedProperties,\n  MutuallyExclusiveProperties,\n  NumberIndexReg,\n  GlobalState,\n  ReadOnlyProperties,\n} from './constants'\nimport { BaseField } from '../models/BaseField'\n\nconst hasOwnProperty = Object.prototype.hasOwnProperty\n\nconst notify = (\n  target: Form | Field,\n  formType: LifeCycleTypes,\n  fieldType: LifeCycleTypes\n) => {\n  if (isForm(target)) {\n    target.notify(formType)\n  } else {\n    target.notify(fieldType)\n  }\n}\n\nexport const isHTMLInputEvent = (event: any, stopPropagation = true) => {\n  if (event?.target) {\n    if (\n      typeof event.target === 'object' &&\n      ('value' in event.target || 'checked' in event.target)\n    )\n      return true\n    if (stopPropagation) event.stopPropagation?.()\n  }\n  return false\n}\n\nexport const getValuesFromEvent = (args: any[]) => {\n  return args.map((event) => {\n    if (event?.target) {\n      if (isValid(event.target.value)) return event.target.value\n      if (isValid(event.target.checked)) return event.target.checked\n      return\n    }\n    return event\n  })\n}\n\nexport const getTypedDefaultValue = (field: Field) => {\n  if (isArrayField(field)) return []\n  if (isObjectField(field)) return {}\n}\n\nexport const buildFieldPath = (field: GeneralField) => {\n  return buildDataPath(field.form.fields, field.address)\n}\n\nexport const buildDataPath = (\n  fields: Record<string, GeneralField>,\n  pattern: FormPath\n) => {\n  let prevArray = false\n  const segments = pattern.segments\n  const path = segments.reduce((path: string[], key: string, index: number) => {\n    const currentPath = path.concat(key)\n    const currentAddress = segments.slice(0, index + 1)\n    const current = fields[currentAddress.join('.')]\n    if (prevArray) {\n      if (!isVoidField(current)) {\n        prevArray = false\n      }\n      return path\n    }\n    if (index >= segments.length - 1) {\n      return currentPath\n    }\n    if (isVoidField(current)) {\n      const parentAddress = segments.slice(0, index)\n      const parent = fields[parentAddress.join('.')]\n      if (isArrayField(parent) && isNumberLike(key)) {\n        prevArray = true\n        return currentPath\n      }\n      return path\n    } else {\n      prevArray = false\n    }\n    return currentPath\n  }, [])\n  return new FormPath(path)\n}\n\nexport const locateNode = (field: GeneralField, address: FormPathPattern) => {\n  field.address = FormPath.parse(address)\n  field.path = buildFieldPath(field)\n  field.form.indexes[field.path.toString()] = field.address.toString()\n  return field\n}\n\nexport const patchFieldStates = (\n  target: Record<string, GeneralField>,\n  patches: INodePatch<GeneralField>[]\n) => {\n  patches.forEach(({ type, address, oldAddress, payload }) => {\n    if (type === 'remove') {\n      destroy(target, address, false)\n    } else if (type === 'update') {\n      if (payload) {\n        target[address] = payload\n        if (target[oldAddress] === payload) {\n          target[oldAddress] = undefined\n        }\n      }\n      if (address && payload) {\n        locateNode(payload, address)\n      }\n    }\n  })\n}\n\nexport const destroy = (\n  target: Record<string, GeneralField>,\n  address: string,\n  forceClear = true\n) => {\n  const field = target[address]\n  field?.dispose()\n  if (isDataField(field) && forceClear) {\n    const form = field.form\n    const path = field.path\n    form.deleteValuesIn(path)\n    form.deleteInitialValuesIn(path)\n  }\n  delete target[address]\n}\n\nexport const patchFormValues = (\n  form: Form,\n  path: Array<string | number>,\n  source: any\n) => {\n  const update = (path: Array<string | number>, source: any) => {\n    if (path.length) {\n      form.setValuesIn(path, clone(source))\n    } else {\n      Object.assign(form.values, clone(source))\n    }\n  }\n\n  const patch = (source: any, path: Array<string | number> = []) => {\n    const targetValue = form.getValuesIn(path)\n    const targetField = form.query(path).take()\n    const isUnVoidField = targetField && !isVoidField(targetField)\n\n    if (isUnVoidField && targetField.display === 'none') {\n      targetField.caches.value = clone(source)\n      return\n    }\n\n    if (allowAssignDefaultValue(targetValue, source)) {\n      update(path, source)\n    } else {\n      if (isEmpty(source)) return\n      if (GlobalState.initializing) return\n      if (isPlainObj(targetValue) && isPlainObj(source)) {\n        each(source, (value, key) => {\n          patch(value, path.concat(key))\n        })\n      } else {\n        if (targetField) {\n          if (isUnVoidField && !targetField.selfModified) {\n            update(path, source)\n          }\n        } else if (form.initialized) {\n          update(path, source)\n        }\n      }\n    }\n  }\n  patch(source, path)\n}\n\nexport const matchFeedback = (\n  search?: ISearchFeedback,\n  feedback?: IFormFeedback\n) => {\n  if (!search || !feedback) return false\n  if (search.type && search.type !== feedback.type) return false\n  if (search.code && search.code !== feedback.code) return false\n  if (search.path && feedback.path) {\n    if (!FormPath.parse(search.path).match(feedback.path)) return false\n  }\n  if (search.address && feedback.address) {\n    if (!FormPath.parse(search.address).match(feedback.address)) return false\n  }\n  if (search.triggerType && search.triggerType !== feedback.triggerType)\n    return false\n  return true\n}\n\nexport const queryFeedbacks = (field: Field, search?: ISearchFeedback) => {\n  return field.feedbacks.filter((feedback) => {\n    if (!feedback.messages?.length) return false\n    return matchFeedback(search, {\n      ...feedback,\n      address: field.address?.toString(),\n      path: field.path?.toString(),\n    })\n  })\n}\n\nexport const queryFeedbackMessages = (\n  field: Field,\n  search: ISearchFeedback\n) => {\n  if (!field.feedbacks.length) return []\n  return queryFeedbacks(field, search).reduce(\n    (buf, info) => (isEmpty(info.messages) ? buf : buf.concat(info.messages)),\n    []\n  )\n}\n\nexport const updateFeedback = (field: Field, feedback?: IFieldFeedback) => {\n  if (!feedback) return\n  return batch(() => {\n    if (!field.feedbacks.length) {\n      if (!feedback.messages?.length) {\n        return\n      }\n      field.feedbacks = [feedback]\n    } else {\n      const searched = queryFeedbacks(field, feedback)\n      if (searched.length) {\n        field.feedbacks = field.feedbacks.reduce((buf, item) => {\n          if (searched.includes(item)) {\n            if (feedback.messages?.length) {\n              item.messages = feedback.messages\n              return buf.concat(item)\n            } else {\n              return buf\n            }\n          } else {\n            return buf.concat(item)\n          }\n        }, [])\n        return\n      } else if (feedback.messages?.length) {\n        field.feedbacks = field.feedbacks.concat(feedback)\n      }\n    }\n  })\n}\n\nexport const validateToFeedbacks = async (\n  field: Field,\n  triggerType: ValidatorTriggerType = 'onInput'\n) => {\n  const results = await validate(field.value, field.validator, {\n    triggerType,\n    validateFirst: field.props.validateFirst ?? field.form.props.validateFirst,\n    context: { field, form: field.form },\n  })\n\n  batch(() => {\n    each(results, (messages, type: FieldFeedbackTypes) => {\n      field.setFeedback({\n        triggerType,\n        type,\n        code: pascalCase(`validate-${type}`),\n        messages: messages,\n      })\n    })\n  })\n  return results\n}\n\nexport const setValidatorRule = (field: Field, name: string, value: any) => {\n  if (!isValid(value)) return\n  const validators = parseValidatorDescriptions(field.validator)\n  const hasRule = validators.some((desc) => name in desc)\n  const rule = {\n    [name]: value,\n  }\n  if (hasRule) {\n    field.validator = validators.map((desc: any) => {\n      if (isPlainObj(desc) && hasOwnProperty.call(desc, name)) {\n        desc[name] = value\n        return desc\n      }\n      return desc\n    })\n  } else {\n    if (name === 'required') {\n      field.validator = [rule].concat(validators)\n    } else {\n      field.validator = validators.concat(rule)\n    }\n  }\n}\n\nexport const spliceArrayState = (\n  field: ArrayField,\n  props?: ISpliceArrayStateProps\n) => {\n  const { startIndex, deleteCount, insertCount } = {\n    startIndex: 0,\n    deleteCount: 0,\n    insertCount: 0,\n    ...props,\n  }\n  const address = field.address.toString()\n  const addrLength = address.length\n  const form = field.form\n  const fields = form.fields\n  const fieldPatches: INodePatch<GeneralField>[] = []\n  const offset = insertCount - deleteCount\n  const isArrayChildren = (identifier: string) => {\n    return identifier.indexOf(address) === 0 && identifier.length > addrLength\n  }\n  const isAfterNode = (identifier: string) => {\n    const afterStr = identifier.substring(addrLength)\n    const number = afterStr.match(NumberIndexReg)?.[1]\n    if (number === undefined) return false\n    const index = Number(number)\n    return index > startIndex + deleteCount - 1\n  }\n  const isInsertNode = (identifier: string) => {\n    const afterStr = identifier.substring(addrLength)\n    const number = afterStr.match(NumberIndexReg)?.[1]\n    if (number === undefined) return false\n    const index = Number(number)\n    return index >= startIndex && index < startIndex + insertCount\n  }\n  const isDeleteNode = (identifier: string) => {\n    const preStr = identifier.substring(0, addrLength)\n    const afterStr = identifier.substring(addrLength)\n    const number = afterStr.match(NumberIndexReg)?.[1]\n    if (number === undefined) return false\n    const index = Number(number)\n    return (\n      (index > startIndex &&\n        !fields[\n          `${preStr}${afterStr.replace(/^\\.\\d+/, `.${index + deleteCount}`)}`\n        ]) ||\n      index === startIndex\n    )\n  }\n  const moveIndex = (identifier: string) => {\n    if (offset === 0) return identifier\n    const preStr = identifier.substring(0, addrLength)\n    const afterStr = identifier.substring(addrLength)\n    const number = afterStr.match(NumberIndexReg)?.[1]\n    if (number === undefined) return identifier\n    const index = Number(number) + offset\n    return `${preStr}${afterStr.replace(/^\\.\\d+/, `.${index}`)}`\n  }\n\n  batch(() => {\n    each(fields, (field, identifier) => {\n      if (isArrayChildren(identifier)) {\n        if (isAfterNode(identifier)) {\n          const newIdentifier = moveIndex(identifier)\n          fieldPatches.push({\n            type: 'update',\n            address: newIdentifier,\n            oldAddress: identifier,\n            payload: field,\n          })\n        }\n        if (isInsertNode(identifier) || isDeleteNode(identifier)) {\n          fieldPatches.push({ type: 'remove', address: identifier })\n        }\n      }\n    })\n    patchFieldStates(fields, fieldPatches)\n  })\n  field.form.notify(LifeCycleTypes.ON_FORM_GRAPH_CHANGE)\n}\n\nexport const exchangeArrayState = (\n  field: ArrayField,\n  props: IExchangeArrayStateProps\n) => {\n  const { fromIndex, toIndex } = {\n    fromIndex: 0,\n    toIndex: 0,\n    ...props,\n  }\n  const address = field.address.toString()\n  const fields = field.form.fields\n  const addrLength = address.length\n  const fieldPatches: INodePatch<GeneralField>[] = []\n  const isArrayChildren = (identifier: string) => {\n    return identifier.indexOf(address) === 0 && identifier.length > addrLength\n  }\n\n  const isDown = fromIndex < toIndex\n\n  const isMoveNode = (identifier: string) => {\n    const afterStr = identifier.slice(address.length)\n    const number = afterStr.match(NumberIndexReg)?.[1]\n    if (number === undefined) return false\n    const index = Number(number)\n    return isDown\n      ? index > fromIndex && index <= toIndex\n      : index < fromIndex && index >= toIndex\n  }\n\n  const isFromNode = (identifier: string) => {\n    const afterStr = identifier.substring(addrLength)\n    const number = afterStr.match(NumberIndexReg)?.[1]\n    if (number === undefined) return false\n    const index = Number(number)\n    return index === fromIndex\n  }\n\n  const moveIndex = (identifier: string) => {\n    const preStr = identifier.substring(0, addrLength)\n    const afterStr = identifier.substring(addrLength)\n    const number = afterStr.match(NumberIndexReg)[1]\n    const current = Number(number)\n    let index = current\n    if (index === fromIndex) {\n      index = toIndex\n    } else {\n      index += isDown ? -1 : 1\n    }\n\n    return `${preStr}${afterStr.replace(/^\\.\\d+/, `.${index}`)}`\n  }\n\n  batch(() => {\n    each(fields, (field, identifier) => {\n      if (isArrayChildren(identifier)) {\n        if (isMoveNode(identifier) || isFromNode(identifier)) {\n          const newIdentifier = moveIndex(identifier)\n          fieldPatches.push({\n            type: 'update',\n            address: newIdentifier,\n            oldAddress: identifier,\n            payload: field,\n          })\n          if (!fields[newIdentifier]) {\n            fieldPatches.push({\n              type: 'remove',\n              address: identifier,\n            })\n          }\n        }\n      }\n    })\n    patchFieldStates(fields, fieldPatches)\n  })\n  field.form.notify(LifeCycleTypes.ON_FORM_GRAPH_CHANGE)\n}\n\nexport const cleanupArrayChildren = (field: ArrayField, start: number) => {\n  const address = field.address.toString()\n  const fields = field.form.fields\n\n  const isArrayChildren = (identifier: string) => {\n    return (\n      identifier.indexOf(address) === 0 && identifier.length > address.length\n    )\n  }\n\n  const isNeedCleanup = (identifier: string) => {\n    const afterStr = identifier.slice(address.length)\n    const numStr = afterStr.match(NumberIndexReg)?.[1]\n    if (numStr === undefined) return false\n    const index = Number(numStr)\n    return index >= start\n  }\n\n  batch(() => {\n    each(fields, (field, identifier) => {\n      if (isArrayChildren(identifier) && isNeedCleanup(identifier)) {\n        field.destroy()\n      }\n    })\n  })\n}\n\nexport const cleanupObjectChildren = (field: ObjectField, keys: string[]) => {\n  if (keys.length === 0) return\n  const address = field.address.toString()\n  const fields = field.form.fields\n\n  const isObjectChildren = (identifier: string) => {\n    return (\n      identifier.indexOf(address) === 0 && identifier.length > address.length\n    )\n  }\n\n  const isNeedCleanup = (identifier: string) => {\n    const afterStr = identifier.slice(address.length)\n    const key = afterStr.match(/^\\.([^.]+)/)?.[1]\n    if (key === undefined) return false\n    return keys.includes(key)\n  }\n\n  batch(() => {\n    each(fields, (field, identifier) => {\n      if (isObjectChildren(identifier) && isNeedCleanup(identifier)) {\n        field.destroy()\n      }\n    })\n  })\n}\n\nexport const initFieldUpdate = batch.scope.bound((field: GeneralField) => {\n  const form = field.form\n  const updates = FormPath.ensureIn(form, 'requests.updates', [])\n  const indexes = FormPath.ensureIn(form, 'requests.updateIndexes', {})\n  for (let index = 0; index < updates.length; index++) {\n    const { pattern, callbacks } = updates[index]\n    let removed = false\n    if (field.match(pattern)) {\n      callbacks.forEach((callback) => {\n        field.setState(callback)\n      })\n      if (!pattern.isWildMatchPattern && !pattern.isMatchPattern) {\n        updates.splice(index--, 1)\n        removed = true\n      }\n    }\n    if (!removed) {\n      indexes[pattern.toString()] = index\n    } else {\n      delete indexes[pattern.toString()]\n    }\n  }\n})\n\nexport const subscribeUpdate = (\n  form: Form,\n  pattern: FormPath,\n  callback: (...args: any[]) => void\n) => {\n  const updates = FormPath.ensureIn(form, 'requests.updates', [])\n  const indexes = FormPath.ensureIn(form, 'requests.updateIndexes', {})\n  const id = pattern.toString()\n  const current = indexes[id]\n  if (isValid(current)) {\n    if (\n      updates[current] &&\n      !updates[current].callbacks.some((fn: any) =>\n        fn.toString() === callback.toString() ? fn === callback : false\n      )\n    ) {\n      updates[current].callbacks.push(callback)\n    }\n  } else {\n    indexes[id] = updates.length\n    updates.push({\n      pattern,\n      callbacks: [callback],\n    })\n  }\n}\n\nexport const deserialize = (model: any, setter: any) => {\n  if (!model) return\n  if (isFn(setter)) {\n    setter(model)\n  } else {\n    for (let key in setter) {\n      if (!hasOwnProperty.call(setter, key)) continue\n      if (ReadOnlyProperties[key] || ReservedProperties[key]) continue\n      const MutuallyExclusiveKey = MutuallyExclusiveProperties[key]\n      if (\n        MutuallyExclusiveKey &&\n        hasOwnProperty.call(setter, MutuallyExclusiveKey) &&\n        !isValid(setter[MutuallyExclusiveKey])\n      )\n        continue\n      const value = setter[key]\n      if (isFn(value)) continue\n      model[key] = value\n    }\n  }\n  return model\n}\n\nexport const serialize = (model: any, getter?: any) => {\n  if (isFn(getter)) {\n    return getter(model)\n  } else {\n    const results = {}\n    for (let key in model) {\n      if (!hasOwnProperty.call(model, key)) continue\n      if (ReservedProperties[key]) continue\n      if (key === 'address' || key === 'path') {\n        results[key] = model[key].toString()\n        continue\n      }\n      const value = model[key]\n      if (isFn(value)) continue\n      results[key] = toJS(value)\n    }\n    return results\n  }\n}\n\nexport const createChildrenFeedbackFilter = (field: Field) => {\n  const identifier = field.address?.toString()\n  return ({ address }: IFormFeedback) => {\n    return address === identifier || address.indexOf(identifier + '.') === 0\n  }\n}\n\nexport const createStateSetter = (model: any) => {\n  return batch.bound((setter?: any) => deserialize(model, setter))\n}\n\nexport const createStateGetter = (model: any) => {\n  return (getter?: any) => serialize(model, getter)\n}\n\nexport const createBatchStateSetter = (form: Form) => {\n  return batch.bound((pattern: FieldMatchPattern, payload?: any) => {\n    if (isQuery(pattern)) {\n      pattern.forEach((field) => {\n        field.setState(payload)\n      })\n    } else if (isGeneralField(pattern)) {\n      pattern.setState(payload)\n    } else {\n      let matchCount = 0,\n        path = FormPath.parse(pattern)\n      form.query(path).forEach((field) => {\n        field.setState(payload)\n        matchCount++\n      })\n\n      if (matchCount === 0 || path.isWildMatchPattern) {\n        subscribeUpdate(form, path, payload)\n      }\n    }\n  })\n}\n\nexport const createBatchStateGetter = (form: Form) => {\n  return (pattern: FieldMatchPattern, payload?: any) => {\n    if (isQuery(pattern)) {\n      return pattern.take(payload)\n    } else if (isGeneralField(pattern)) {\n      return (pattern as any).getState(payload)\n    } else {\n      return form.query(pattern).take((field: any) => {\n        return field.getState(payload)\n      })\n    }\n  }\n}\n\nexport const triggerFormInitialValuesChange = (\n  form: Form,\n  change: DataChange\n) => {\n  if (Array.isArray(change.object) && change.key === 'length') return\n  if (\n    contains(form.initialValues, change.object) ||\n    form.initialValues === change.value\n  ) {\n    if (change.type === 'add' || change.type === 'set') {\n      patchFormValues(form, change.path.slice(1), change.value)\n    }\n    if (form.initialized) {\n      form.notify(LifeCycleTypes.ON_FORM_INITIAL_VALUES_CHANGE)\n    }\n  }\n}\n\nexport const triggerFormValuesChange = (form: Form, change: DataChange) => {\n  if (Array.isArray(change.object) && change.key === 'length') return\n  if (\n    (contains(form.values, change.object) || form.values === change.value) &&\n    form.initialized\n  ) {\n    form.notify(LifeCycleTypes.ON_FORM_VALUES_CHANGE)\n  }\n}\n\nexport const setValidating = (target: Form | Field, validating: boolean) => {\n  clearTimeout(target.requests.validate)\n  if (validating) {\n    target.requests.validate = setTimeout(() => {\n      batch(() => {\n        target.validating = validating\n        notify(\n          target,\n          LifeCycleTypes.ON_FORM_VALIDATING,\n          LifeCycleTypes.ON_FIELD_VALIDATING\n        )\n      })\n    }, RESPONSE_REQUEST_DURATION)\n    notify(\n      target,\n      LifeCycleTypes.ON_FORM_VALIDATE_START,\n      LifeCycleTypes.ON_FIELD_VALIDATE_START\n    )\n  } else {\n    if (target.validating !== validating) {\n      target.validating = validating\n    }\n    notify(\n      target,\n      LifeCycleTypes.ON_FORM_VALIDATE_END,\n      LifeCycleTypes.ON_FIELD_VALIDATE_END\n    )\n  }\n}\n\nexport const setSubmitting = (target: Form | Field, submitting: boolean) => {\n  clearTimeout(target.requests.submit)\n  if (submitting) {\n    target.requests.submit = setTimeout(() => {\n      batch(() => {\n        target.submitting = submitting\n        notify(\n          target,\n          LifeCycleTypes.ON_FORM_SUBMITTING,\n          LifeCycleTypes.ON_FIELD_SUBMITTING\n        )\n      })\n    }, RESPONSE_REQUEST_DURATION)\n    notify(\n      target,\n      LifeCycleTypes.ON_FORM_SUBMIT_START,\n      LifeCycleTypes.ON_FIELD_SUBMIT_START\n    )\n  } else {\n    if (target.submitting !== submitting) {\n      target.submitting = submitting\n    }\n    notify(\n      target,\n      LifeCycleTypes.ON_FORM_SUBMIT_END,\n      LifeCycleTypes.ON_FIELD_SUBMIT_END\n    )\n  }\n}\n\nexport const setLoading = (target: Form | Field, loading: boolean) => {\n  clearTimeout(target.requests.loading)\n  if (loading) {\n    target.requests.loading = setTimeout(() => {\n      batch(() => {\n        target.loading = loading\n        notify(\n          target,\n          LifeCycleTypes.ON_FORM_LOADING,\n          LifeCycleTypes.ON_FIELD_LOADING\n        )\n      })\n    }, RESPONSE_REQUEST_DURATION)\n  } else if (target.loading !== loading) {\n    target.loading = loading\n  }\n}\n\nexport const batchSubmit = async <T>(\n  target: Form | Field,\n  onSubmit?: (values: any) => Promise<T> | void\n): Promise<T> => {\n  const getValues = (target: Form | Field) => {\n    if (isForm(target)) {\n      return toJS(target.values)\n    }\n    return toJS(target.value)\n  }\n  target.setSubmitting(true)\n  try {\n    notify(\n      target,\n      LifeCycleTypes.ON_FORM_SUBMIT_VALIDATE_START,\n      LifeCycleTypes.ON_FIELD_SUBMIT_VALIDATE_START\n    )\n    await target.validate()\n    notify(\n      target,\n      LifeCycleTypes.ON_FORM_SUBMIT_VALIDATE_SUCCESS,\n      LifeCycleTypes.ON_FIELD_SUBMIT_VALIDATE_SUCCESS\n    )\n  } catch (e) {\n    notify(\n      target,\n      LifeCycleTypes.ON_FORM_SUBMIT_VALIDATE_FAILED,\n      LifeCycleTypes.ON_FIELD_SUBMIT_VALIDATE_FAILED\n    )\n  }\n  notify(\n    target,\n    LifeCycleTypes.ON_FORM_SUBMIT_VALIDATE_END,\n    LifeCycleTypes.ON_FIELD_SUBMIT_VALIDATE_END\n  )\n  let results: any\n  try {\n    if (target.invalid) {\n      throw target.errors\n    }\n    if (isFn(onSubmit)) {\n      results = await onSubmit(getValues(target))\n    } else {\n      results = getValues(target)\n    }\n    notify(\n      target,\n      LifeCycleTypes.ON_FORM_SUBMIT_SUCCESS,\n      LifeCycleTypes.ON_FIELD_SUBMIT_SUCCESS\n    )\n  } catch (e) {\n    target.setSubmitting(false)\n    notify(\n      target,\n      LifeCycleTypes.ON_FORM_SUBMIT_FAILED,\n      LifeCycleTypes.ON_FIELD_SUBMIT_FAILED\n    )\n    notify(\n      target,\n      LifeCycleTypes.ON_FORM_SUBMIT,\n      LifeCycleTypes.ON_FIELD_SUBMIT\n    )\n    throw e\n  }\n  target.setSubmitting(false)\n  notify(target, LifeCycleTypes.ON_FORM_SUBMIT, LifeCycleTypes.ON_FIELD_SUBMIT)\n  return results\n}\n\nconst shouldValidate = (field: Field) => {\n  const validatePattern = field.props.validatePattern ??\n    field.form.props.validatePattern ?? ['editable']\n  const validateDisplay = field.props.validateDisplay ??\n    field.form.props.validateDisplay ?? ['visible']\n  return (\n    validatePattern.includes(field.pattern) &&\n    validateDisplay.includes(field.display)\n  )\n}\n\nexport const batchValidate = async (\n  target: Form | Field,\n  pattern: FormPathPattern,\n  triggerType?: ValidatorTriggerType\n) => {\n  if (isForm(target)) target.setValidating(true)\n  else {\n    if (!shouldValidate(target)) return\n  }\n  const tasks = []\n  target.query(pattern).forEach((field) => {\n    if (!isVoidField(field)) {\n      tasks.push(validateSelf(field, triggerType, field === target))\n    }\n  })\n  await Promise.all(tasks)\n  if (isForm(target)) target.setValidating(false)\n  if (target.invalid) {\n    notify(\n      target,\n      LifeCycleTypes.ON_FORM_VALIDATE_FAILED,\n      LifeCycleTypes.ON_FIELD_VALIDATE_FAILED\n    )\n    throw target.errors\n  }\n  notify(\n    target,\n    LifeCycleTypes.ON_FORM_VALIDATE_SUCCESS,\n    LifeCycleTypes.ON_FIELD_VALIDATE_SUCCESS\n  )\n}\n\nexport const batchReset = async (\n  target: Form | Field,\n  pattern: FormPathPattern,\n  options?: IFieldResetOptions\n) => {\n  const tasks = []\n  target.query(pattern).forEach((field) => {\n    if (!isVoidField(field)) {\n      tasks.push(resetSelf(field, options, target === field))\n    }\n  })\n  if (isForm(target)) {\n    target.modified = false\n  }\n  notify(target, LifeCycleTypes.ON_FORM_RESET, LifeCycleTypes.ON_FIELD_RESET)\n  await Promise.all(tasks)\n}\n\nexport const validateSelf = batch.bound(\n  async (target: Field, triggerType?: ValidatorTriggerType, noEmit = false) => {\n    const start = () => {\n      setValidating(target, true)\n    }\n    const end = () => {\n      setValidating(target, false)\n      if (noEmit) return\n      if (target.selfValid) {\n        target.notify(LifeCycleTypes.ON_FIELD_VALIDATE_SUCCESS)\n      } else {\n        target.notify(LifeCycleTypes.ON_FIELD_VALIDATE_FAILED)\n      }\n    }\n\n    if (!shouldValidate(target)) return {}\n    start()\n    if (!triggerType) {\n      const allTriggerTypes = parseValidatorDescriptions(\n        target.validator\n      ).reduce(\n        (types, desc) =>\n          types.indexOf(desc.triggerType) > -1\n            ? types\n            : types.concat(desc.triggerType),\n        []\n      )\n      const results = {}\n      for (let i = 0; i < allTriggerTypes.length; i++) {\n        const payload = await validateToFeedbacks(target, allTriggerTypes[i])\n        each(payload, (result, key) => {\n          results[key] = results[key] || []\n          results[key] = results[key].concat(result)\n        })\n      }\n      end()\n      return results\n    }\n    const results = await validateToFeedbacks(target, triggerType)\n    end()\n    return results\n  }\n)\n\nexport const resetSelf = batch.bound(\n  async (target: Field, options?: IFieldResetOptions, noEmit = false) => {\n    const typedDefaultValue = getTypedDefaultValue(target)\n    target.modified = false\n    target.selfModified = false\n    target.visited = false\n    target.feedbacks = []\n    target.inputValue = typedDefaultValue\n    target.inputValues = []\n    target.caches = {}\n    if (!isUndef(target.value)) {\n      if (options?.forceClear) {\n        target.value = typedDefaultValue\n      } else {\n        const initialValue = target.initialValue\n        target.value = toJS(\n          !isUndef(initialValue) ? initialValue : typedDefaultValue\n        )\n      }\n    }\n    if (!noEmit) {\n      target.notify(LifeCycleTypes.ON_FIELD_RESET)\n    }\n    if (options?.validate) {\n      return await validateSelf(target)\n    }\n  }\n)\n\nexport const modifySelf = (target: Field) => {\n  if (target.selfModified) return\n  target.selfModified = true\n  target.modified = true\n  let parent = target.parent\n  while (parent) {\n    if (isDataField(parent)) {\n      if (parent.modified) return\n      parent.modified = true\n    }\n    parent = parent.parent\n  }\n  target.form.modified = true\n}\n\nexport const getValidFormValues = (values: any) => {\n  if (isObservable(values)) return values\n  return clone(values || {})\n}\n\nexport const getValidFieldDefaultValue = (value: any, initialValue: any) => {\n  if (allowAssignDefaultValue(value, initialValue)) return clone(initialValue)\n  return value\n}\n\nexport const allowAssignDefaultValue = (target: any, source: any) => {\n  const isValidTarget = !isUndef(target)\n  const isValidSource = !isUndef(source)\n  if (!isValidTarget) {\n    return isValidSource\n  }\n\n  if (typeof target === typeof source) {\n    if (target === '') return false\n    if (target === 0) return false\n  }\n\n  const isEmptyTarget = target !== null && isEmpty(target, true)\n  const isEmptySource = source !== null && isEmpty(source, true)\n  if (isEmptyTarget) {\n    return !isEmptySource\n  }\n  return false\n}\n\nexport const createReactions = (field: GeneralField) => {\n  const reactions = toArr(field.props.reactions)\n  field.form.addEffects(field, () => {\n    reactions.forEach((reaction) => {\n      if (isFn(reaction)) {\n        field.disposers.push(\n          autorun(\n            batch.scope.bound(() => {\n              if (field.destroyed) return\n              reaction(field)\n            })\n          )\n        )\n      }\n    })\n  })\n}\n\nexport const createReaction = <T>(\n  tracker: () => T,\n  scheduler?: (value: T) => void\n) => {\n  return reaction(tracker, untracked.bound(scheduler))\n}\n\nexport const initializeStart = () => {\n  GlobalState.initializing = true\n}\n\nexport const initializeEnd = () => {\n  batch.endpoint(() => {\n    GlobalState.initializing = false\n  })\n}\n\nexport const getArrayParent = (field: BaseField, index = field.index) => {\n  if (index > -1) {\n    let parent: any = field.parent\n    while (parent) {\n      if (isArrayField(parent)) return parent\n      if (parent === field.form) return\n      parent = parent.parent\n    }\n  }\n}\n\nexport const getObjectParent = (field: BaseField) => {\n  let parent: any = field.parent\n  while (parent) {\n    if (isArrayField(parent)) return\n    if (isObjectField(parent)) return parent\n    if (parent === field.form) return\n    parent = parent.parent\n  }\n}\n"
  },
  {
    "path": "packages/core/src/types.ts",
    "content": "import {\n  IValidatorRules,\n  Validator,\n  ValidatorTriggerType,\n} from '@formily/validator'\nimport { FormPath } from '@formily/shared'\nimport {\n  Form,\n  Field,\n  LifeCycle,\n  ArrayField,\n  VoidField,\n  ObjectField,\n  Query,\n} from './models'\n\nexport type NonFunctionPropertyNames<T> = {\n  [K in keyof T]: T[K] extends (...args: any) => any ? never : K\n}[keyof T]\n\nexport type NonFunctionProperties<T> = Pick<T, NonFunctionPropertyNames<T>>\n\nexport type AnyFunction = (...args: any[]) => any\n\nexport type JSXComponent = any\n\nexport type LifeCycleHandler<T> = (payload: T, context: any) => void\n\nexport type LifeCyclePayload<T> = (\n  params: {\n    type: string\n    payload: T\n  },\n  context: any\n) => void\n\nexport enum LifeCycleTypes {\n  /**\n   * Form LifeCycle\n   **/\n\n  ON_FORM_INIT = 'onFormInit',\n  ON_FORM_MOUNT = 'onFormMount',\n  ON_FORM_UNMOUNT = 'onFormUnmount',\n\n  ON_FORM_INPUT_CHANGE = 'onFormInputChange',\n  ON_FORM_VALUES_CHANGE = 'onFormValuesChange',\n  ON_FORM_INITIAL_VALUES_CHANGE = 'onFormInitialValuesChange',\n\n  ON_FORM_SUBMIT = 'onFormSubmit',\n  ON_FORM_RESET = 'onFormReset',\n  ON_FORM_SUBMIT_START = 'onFormSubmitStart',\n  ON_FORM_SUBMITTING = 'onFormSubmitting',\n  ON_FORM_SUBMIT_END = 'onFormSubmitEnd',\n  ON_FORM_SUBMIT_VALIDATE_START = 'onFormSubmitValidateStart',\n  ON_FORM_SUBMIT_VALIDATE_SUCCESS = 'onFormSubmitValidateSuccess',\n  ON_FORM_SUBMIT_VALIDATE_FAILED = 'onFormSubmitValidateFailed',\n  ON_FORM_SUBMIT_VALIDATE_END = 'onFormSubmitValidateEnd',\n  ON_FORM_SUBMIT_SUCCESS = 'onFormSubmitSuccess',\n  ON_FORM_SUBMIT_FAILED = 'onFormSubmitFailed',\n  ON_FORM_VALIDATE_START = 'onFormValidateStart',\n  ON_FORM_VALIDATING = 'onFormValidating',\n  ON_FORM_VALIDATE_SUCCESS = 'onFormValidateSuccess',\n  ON_FORM_VALIDATE_FAILED = 'onFormValidateFailed',\n  ON_FORM_VALIDATE_END = 'onFormValidateEnd',\n\n  ON_FORM_GRAPH_CHANGE = 'onFormGraphChange',\n  ON_FORM_LOADING = 'onFormLoading',\n\n  /**\n   * Field LifeCycle\n   **/\n\n  ON_FIELD_INIT = 'onFieldInit',\n  ON_FIELD_INPUT_VALUE_CHANGE = 'onFieldInputValueChange',\n  ON_FIELD_VALUE_CHANGE = 'onFieldValueChange',\n  ON_FIELD_INITIAL_VALUE_CHANGE = 'onFieldInitialValueChange',\n\n  ON_FIELD_SUBMIT = 'onFieldSubmit',\n  ON_FIELD_SUBMIT_START = 'onFieldSubmitStart',\n  ON_FIELD_SUBMITTING = 'onFieldSubmitting',\n  ON_FIELD_SUBMIT_END = 'onFieldSubmitEnd',\n  ON_FIELD_SUBMIT_VALIDATE_START = 'onFieldSubmitValidateStart',\n  ON_FIELD_SUBMIT_VALIDATE_SUCCESS = 'onFieldSubmitValidateSuccess',\n  ON_FIELD_SUBMIT_VALIDATE_FAILED = 'onFieldSubmitValidateFailed',\n  ON_FIELD_SUBMIT_VALIDATE_END = 'onFieldSubmitValidateEnd',\n  ON_FIELD_SUBMIT_SUCCESS = 'onFieldSubmitSuccess',\n  ON_FIELD_SUBMIT_FAILED = 'onFieldSubmitFailed',\n  ON_FIELD_VALIDATE_START = 'onFieldValidateStart',\n  ON_FIELD_VALIDATING = 'onFieldValidating',\n  ON_FIELD_VALIDATE_SUCCESS = 'onFieldValidateSuccess',\n  ON_FIELD_VALIDATE_FAILED = 'onFieldValidateFailed',\n  ON_FIELD_VALIDATE_END = 'onFieldValidateEnd',\n\n  ON_FIELD_LOADING = 'onFieldLoading',\n  ON_FIELD_RESET = 'onFieldReset',\n  ON_FIELD_MOUNT = 'onFieldMount',\n  ON_FIELD_UNMOUNT = 'onFieldUnmount',\n}\n\nexport type HeartSubscriber = ({\n  type,\n  payload,\n}: {\n  type: string\n  payload: any\n}) => void\n\nexport interface INodePatch<T> {\n  type: 'remove' | 'update'\n  address: string\n  oldAddress?: string\n  payload?: T\n}\n\nexport interface IHeartProps<Context> {\n  lifecycles?: LifeCycle[]\n  context?: Context\n}\n\nexport interface IFieldFeedback {\n  triggerType?: FieldFeedbackTriggerTypes\n  type?: FieldFeedbackTypes\n  code?: FieldFeedbackCodeTypes\n  messages?: FeedbackMessage\n}\n\nexport type IFormFeedback = IFieldFeedback & {\n  path?: string\n  address?: string\n}\n\nexport interface ISearchFeedback {\n  triggerType?: FieldFeedbackTriggerTypes\n  type?: FieldFeedbackTypes\n  code?: FieldFeedbackCodeTypes\n  address?: FormPathPattern\n  path?: FormPathPattern\n  messages?: FeedbackMessage\n}\n\nexport type FeedbackMessage = any[]\n\nexport type IFieldUpdate = {\n  pattern: FormPath\n  callbacks: ((...args: any[]) => any)[]\n}\n\nexport interface IFormRequests {\n  validate?: number\n  submit?: number\n  loading?: number\n  updates?: IFieldUpdate[]\n  updateIndexes?: Record<string, number>\n}\n\nexport type IFormFields = Record<string, GeneralField>\n\nexport type FieldFeedbackTypes = 'error' | 'success' | 'warning'\n\nexport type FieldFeedbackTriggerTypes = ValidatorTriggerType\n\nexport type FieldFeedbackCodeTypes =\n  | 'ValidateError'\n  | 'ValidateSuccess'\n  | 'ValidateWarning'\n  | 'EffectError'\n  | 'EffectSuccess'\n  | 'EffectWarning'\n  | (string & {})\n\nexport type FormPatternTypes =\n  | 'editable'\n  | 'readOnly'\n  | 'disabled'\n  | 'readPretty'\n  | ({} & string)\nexport type FormDisplayTypes = 'none' | 'hidden' | 'visible' | ({} & string)\n\nexport type FormPathPattern =\n  | string\n  | number\n  | Array<string | number>\n  | FormPath\n  | RegExp\n  | (((address: Array<string | number>) => boolean) & {\n      path: FormPath\n    })\n\ntype OmitState<P> = Omit<\n  P,\n  | 'selfDisplay'\n  | 'selfPattern'\n  | 'originValues'\n  | 'originInitialValues'\n  | 'id'\n  | 'address'\n  | 'path'\n  | 'lifecycles'\n  | 'disposers'\n  | 'requests'\n  | 'fields'\n  | 'graph'\n  | 'heart'\n  | 'indexes'\n  | 'props'\n  | 'displayName'\n  | 'setState'\n  | 'getState'\n  | 'getFormGraph'\n  | 'setFormGraph'\n  | 'setFormState'\n  | 'getFormState'\n>\n\nexport type IFieldState = Partial<\n  Pick<\n    Field,\n    NonFunctionPropertyNames<OmitState<Field<any, any, string, string>>>\n  >\n>\n\nexport type IVoidFieldState = Partial<\n  Pick<\n    VoidField,\n    NonFunctionPropertyNames<OmitState<VoidField<any, any, string>>>\n  >\n>\n\nexport type IFormState<T extends Record<any, any> = any> = Pick<\n  Form<T>,\n  NonFunctionPropertyNames<OmitState<Form<{ [key: string]: any }>>>\n>\n\nexport type IFormGraph = Record<string, IGeneralFieldState | IFormState>\n\nexport interface IFormProps<T extends object = any> {\n  values?: Partial<T>\n  initialValues?: Partial<T>\n  pattern?: FormPatternTypes\n  display?: FormDisplayTypes\n  hidden?: boolean\n  visible?: boolean\n  editable?: boolean\n  disabled?: boolean\n  readOnly?: boolean\n  readPretty?: boolean\n  effects?: (form: Form<T>) => void\n  validateFirst?: boolean\n  validatePattern?: FormPatternTypes[]\n  validateDisplay?: FormDisplayTypes[]\n  designable?: boolean\n}\n\nexport type IFormMergeStrategy =\n  | 'overwrite'\n  | 'merge'\n  | 'deepMerge'\n  | 'shallowMerge'\n\nexport interface IFieldFactoryProps<\n  Decorator extends JSXComponent,\n  Component extends JSXComponent,\n  TextType = any,\n  ValueType = any\n> extends IFieldProps<Decorator, Component, TextType, ValueType> {\n  name: FormPathPattern\n  basePath?: FormPathPattern\n}\n\nexport interface IVoidFieldFactoryProps<\n  Decorator extends JSXComponent,\n  Component extends JSXComponent,\n  TextType = any\n> extends IVoidFieldProps<Decorator, Component, TextType> {\n  name: FormPathPattern\n  basePath?: FormPathPattern\n}\n\nexport interface IFieldRequests {\n  validate?: number\n  submit?: number\n  loading?: number\n  batch?: () => void\n}\n\nexport interface IFieldCaches {\n  value?: any\n  initialValue?: any\n  inputting?: boolean\n}\n\nexport type FieldDisplayTypes = 'none' | 'hidden' | 'visible' | ({} & string)\n\nexport type FieldPatternTypes =\n  | 'editable'\n  | 'readOnly'\n  | 'disabled'\n  | 'readPretty'\n  | ({} & string)\n\nexport type FieldValidatorContext = IValidatorRules & {\n  field?: Field\n  form?: Form\n  value?: any\n}\n\nexport type FieldValidator = Validator<FieldValidatorContext>\n\nexport type FieldDataSource = {\n  label?: any\n  value?: any\n  title?: any\n  key?: any\n  text?: any\n  children?: FieldDataSource\n  [key: string]: any\n}[]\n\nexport type FieldComponent<\n  Component extends JSXComponent,\n  ComponentProps = any\n> = [Component] | [Component, ComponentProps] | boolean | any[]\n\nexport type FieldDecorator<\n  Decorator extends JSXComponent,\n  ComponentProps = any\n> = [Decorator] | [Decorator, ComponentProps] | boolean | any[]\n\nexport type FieldReaction = (field: Field) => void\nexport interface IFieldProps<\n  Decorator extends JSXComponent = any,\n  Component extends JSXComponent = any,\n  TextType = any,\n  ValueType = any\n> {\n  name: FormPathPattern\n  basePath?: FormPathPattern\n  title?: TextType\n  description?: TextType\n  value?: ValueType\n  initialValue?: ValueType\n  required?: boolean\n  display?: FieldDisplayTypes\n  pattern?: FieldPatternTypes\n  hidden?: boolean\n  visible?: boolean\n  editable?: boolean\n  disabled?: boolean\n  readOnly?: boolean\n  readPretty?: boolean\n  dataSource?: FieldDataSource\n  validateFirst?: boolean\n  validatePattern?: FieldPatternTypes[]\n  validateDisplay?: FieldDisplayTypes[]\n  validator?: FieldValidator\n  decorator?: FieldDecorator<Decorator>\n  component?: FieldComponent<Component>\n  reactions?: FieldReaction[] | FieldReaction\n  content?: any\n  data?: any\n}\n\nexport interface IVoidFieldProps<\n  Decorator extends JSXComponent = any,\n  Component extends JSXComponent = any,\n  TextType = any\n> {\n  name: FormPathPattern\n  basePath?: FormPathPattern\n  title?: TextType\n  description?: TextType\n  display?: FieldDisplayTypes\n  pattern?: FieldPatternTypes\n  hidden?: boolean\n  visible?: boolean\n  editable?: boolean\n  disabled?: boolean\n  readOnly?: boolean\n  readPretty?: boolean\n  decorator?: FieldDecorator<Decorator>\n  component?: FieldComponent<Component>\n  reactions?: FieldReaction[] | FieldReaction\n  content?: any\n  data?: any\n}\n\nexport interface IFieldResetOptions {\n  forceClear?: boolean\n  validate?: boolean\n}\n\nexport type IGeneralFieldState = IFieldState & IVoidFieldState\n\nexport type GeneralField = Field | VoidField | ArrayField | ObjectField\n\nexport type DataField = Field | ArrayField | ObjectField\nexport interface ISpliceArrayStateProps {\n  startIndex?: number\n  deleteCount?: number\n  insertCount?: number\n}\n\nexport interface IExchangeArrayStateProps {\n  fromIndex?: number\n  toIndex?: number\n}\n\nexport interface IQueryProps {\n  pattern: FormPathPattern\n  base: FormPathPattern\n  form: Form\n}\n\nexport interface IModelSetter<P = any> {\n  (setter: (state: P) => void): void\n  (setter: Partial<P>): void\n  (): void\n}\n\nexport interface IModelGetter<P = any> {\n  <Getter extends (state: P) => any>(getter: Getter): ReturnType<Getter>\n  (): P\n}\n\nexport type FieldMatchPattern = FormPathPattern | Query | GeneralField\n\nexport interface IFieldStateSetter {\n  (pattern: FieldMatchPattern, setter: (state: IFieldState) => void): void\n  (pattern: FieldMatchPattern, setter: Partial<IFieldState>): void\n}\n\nexport interface IFieldStateGetter {\n  <Getter extends (state: IGeneralFieldState) => any>(\n    pattern: FieldMatchPattern,\n    getter: Getter\n  ): ReturnType<Getter>\n  (pattern: FieldMatchPattern): IGeneralFieldState\n}\n\nexport interface IFieldActions {\n  [key: string]: (...args: any[]) => any\n}\n"
  },
  {
    "path": "packages/core/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*\", \"devtools/*\"]\n    },\n    \"declaration\": true,\n    \"types\": []\n  }\n}\n"
  },
  {
    "path": "packages/core/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"include\": [\"./src/**/*.ts\", \"./src/**/*.tsx\"],\n  \"exclude\": [\"./src/__tests__/*\", \"./esm/*\", \"./lib/*\"],\n  \"compilerOptions\": {\n    \"lib\": [\"ESNext\", \"DOM\"],\n    \"types\": []\n  }\n}\n"
  },
  {
    "path": "packages/element/.npmignore",
    "content": "node_modules\n*.log\nbuild\ndocs\ndoc-site\n__tests__\n.eslintrc\njest.config.js\nvue.config.js\ntsconfig.json\n.umi\nsrc"
  },
  {
    "path": "packages/element/README.md",
    "content": "# @formily/element\n\n### Requirement\n\nvue^2.6.0 + @vue/composition-api^1.0.0-beta.1\n\n### Install\n\n```bash\nnpm install --save @formily/element\n```\n"
  },
  {
    "path": "packages/element/build-style.ts",
    "content": "import { build } from '../../scripts/build-style'\n\nbuild({\n  esStr: 'element/es/',\n  libStr: 'element/lib/',\n  allStylesOutputFile: 'dist/element.css',\n})\n"
  },
  {
    "path": "packages/element/create-style.ts",
    "content": "import glob from 'glob'\nimport path from 'path'\nimport fs from 'fs-extra'\n\nglob(\n  './*/style.scss',\n  { cwd: path.resolve(__dirname, './src') },\n  (err, files) => {\n    if (err) return console.error(err)\n    fs.writeFile(\n      path.resolve(__dirname, './src/style.ts'),\n      `// auto generated code\n${files\n  .map((path) => {\n    return `import '${path}'\\n`\n  })\n  .join('')}`,\n      'utf8'\n    )\n  }\n)\n"
  },
  {
    "path": "packages/element/docs/.vuepress/components/createCodeSandBox.js",
    "content": "import { getParameters } from 'codesandbox/lib/api/define'\n\nconst CodeSandBoxHTML = '<div id=\"app\"></div>'\nconst CodeSandBoxJS = `\nimport Vue from 'vue'\nimport App from './App.vue'\nimport Element  from 'element-ui';\nimport 'element-ui/lib/theme-chalk/index.css';\n\nVue.config.productionTip = false\nVue.use(Element, { size: 'small' });\n\nnew Vue({\n  render: h => h(App),\n}).$mount('#app')`\n\nconst createForm = ({ method, action, data }) => {\n  const form = document.createElement('form') // 构造 form\n  form.style.display = 'none' // 设置为不显示\n  form.target = '_blank' // 指向 iframe\n\n  // 构造 formdata\n  Object.keys(data).forEach((key) => {\n    const input = document.createElement('input') // 创建 input\n\n    input.name = key // 设置 name\n    input.value = data[key] // 设置 value\n\n    form.appendChild(input)\n  })\n\n  form.method = method // 设置方法\n  form.action = action // 设置地址\n\n  document.body.appendChild(form)\n\n  // 对该 form 执行提交\n  form.submit()\n\n  document.body.removeChild(form)\n}\n\nexport function createCodeSandBox(codeStr) {\n  const parameters = getParameters({\n    files: {\n      'sandbox.config.json': {\n        content: {\n          template: 'node',\n          infiniteLoopProtection: true,\n          hardReloadOnChange: false,\n          view: 'browser',\n          container: {\n            port: 8080,\n            node: '14',\n          },\n        },\n      },\n      'package.json': {\n        content: {\n          scripts: {\n            serve: 'vue-cli-service serve',\n            build: 'vue-cli-service build',\n            lint: 'vue-cli-service lint',\n          },\n          dependencies: {\n            '@formily/core': 'latest',\n            '@formily/vue': 'latest',\n            '@formily/element': 'latest',\n            axios: '^0.21.1',\n            'core-js': '^3.6.5',\n            'element-ui': 'latest',\n            'vue-demi': 'latest',\n            vue: '^2.6.11',\n          },\n          devDependencies: {\n            '@vue/cli-plugin-babel': '~4.5.0',\n            '@vue/cli-service': '~4.5.0',\n            '@vue/composition-api': 'latest',\n            'vue-template-compiler': '^2.6.11',\n            sass: '^1.34.1',\n            'sass-loader': '^8.0.2',\n          },\n          babel: {\n            presets: [\n              [\n                '@vue/babel-preset-jsx',\n                {\n                  vModel: false,\n                  compositionAPI: true,\n                },\n              ],\n            ],\n          },\n          vue: {\n            devServer: {\n              host: '0.0.0.0',\n              disableHostCheck: true, // 必须\n            },\n          },\n        },\n      },\n      'src/App.vue': {\n        content: codeStr,\n      },\n      'src/main.js': {\n        content: CodeSandBoxJS,\n      },\n      'public/index.html': {\n        content: CodeSandBoxHTML,\n      },\n    },\n  })\n\n  createForm({\n    method: 'post',\n    action: 'https://codesandbox.io/api/v1/sandboxes/define',\n    data: {\n      parameters,\n      query: 'file=/src/App.vue',\n    },\n  })\n}\n"
  },
  {
    "path": "packages/element/docs/.vuepress/components/dumi-previewer.vue",
    "content": "<template>\n  <client-only>\n    <section class=\"dumi-previewer\">\n      <div class=\"dumi-previewer-demo\">\n        <template v-if=\"demoPath && demo\">\n          <component :is=\"demo\" />\n        </template>\n\n        <template v-else>\n          <slot name=\"demo\"></slot>\n        </template>\n      </div>\n\n      <div class=\"dumi-previewer-actions\">\n        <div>\n          <svg\n            xmlns=\"http://www.w3.org/2000/svg\"\n            xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n            class=\"dumi-previewer-actions__icon\"\n            viewBox=\"0 0 256 296\"\n            @click=\"openCodeSandBox\"\n          >\n            <path\n              d=\"M115.498 261.088v-106.61L23.814 101.73v60.773l41.996 24.347v45.7l49.688 28.54zm23.814.627l50.605-29.151V185.78l42.269-24.495v-60.011l-92.874 53.621v106.82zm80.66-180.887l-48.817-28.289l-42.863 24.872l-43.188-24.897l-49.252 28.667l91.914 52.882l92.206-53.235zM0 222.212V74.495L127.987 0L256 74.182v147.797l-128.016 73.744L0 222.212z\"\n              fill=\"#000\"\n            ></path>\n          </svg>\n        </div>\n\n        <div>\n          <svg\n            v-if=\"copied\"\n            class=\"dumi-previewer-actions__icon\"\n            style=\"fill: green\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n            viewBox=\"0 0 24 24\"\n            width=\"24\"\n            height=\"24\"\n          >\n            <path fill=\"none\" d=\"M0 0h24v24H0z\" />\n            <path\n              d=\"M10 15.172l9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z\"\n            />\n          </svg>\n\n          <svg\n            v-else\n            class=\"dumi-previewer-actions__icon\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n            viewBox=\"0 0 24 24\"\n            width=\"24\"\n            height=\"24\"\n            @click=\"handleCopy\"\n          >\n            <path fill=\"none\" d=\"M0 0h24v24H0z\" />\n            <path\n              d=\"M7 6V3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-3v3c0 .552-.45 1-1.007 1H4.007A1.001 1.001 0 0 1 3 21l.003-14c0-.552.45-1 1.007-1H7zM5.003 8L5 20h10V8H5.003zM9 6h8v10h2V4H9v2z\"\n            />\n          </svg>\n\n          <svg\n            class=\"dumi-previewer-actions__icon\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n            viewBox=\"0 0 24 24\"\n            width=\"24\"\n            height=\"24\"\n            @click=\"handleCollapse\"\n          >\n            <path fill=\"none\" d=\"M0 0h24v24H0z\" />\n            <path\n              d=\"M24 12l-5.657 5.657-1.414-1.414L21.172 12l-4.243-4.243 1.414-1.414L24 12zM2.828 12l4.243 4.243-1.414 1.414L0 12l5.657-5.657L7.07 7.757 2.828 12zm6.96 9H7.66l6.552-18h2.128L9.788 21z\"\n            />\n          </svg>\n        </div>\n      </div>\n\n      <div v-show=\"!innerCollapsed\" class=\"dumi-previewer-source\">\n        <div v-html=\"highlightCode\" class=\"language-vue extra-class\" />\n      </div>\n    </section>\n  </client-only>\n</template>\n\n<script>\nimport copy from 'copy-to-clipboard'\nimport highlight from './highlight'\nimport { createCodeSandBox } from './createCodeSandBox'\n\nexport default {\n  name: 'dumi-previewer',\n\n  props: {\n    code: {\n      type: String,\n      default: '',\n    },\n\n    demoPath: {\n      type: String,\n      default: '',\n    },\n    collapsed: {\n      type: Boolean,\n      default: true,\n    },\n  },\n\n  data() {\n    return {\n      innerCollapsed: this.collapsed,\n      copied: false,\n      timerId: null,\n      demoStr: '',\n      /**\n       * take over VuePress render\n       * 接管VuePress渲染\n       */\n      demo: null,\n    }\n  },\n\n  computed: {\n    decodedCode() {\n      return this.code || this.demoStr\n    },\n\n    highlightCode() {\n      return highlight(this.decodedCode, 'vue')\n    },\n  },\n\n  created() {\n    if (this.demoPath) {\n      import(\n        /* webpackPrefetch: true */ `../../demos/${this.demoPath}.vue`\n      ).then((module) => {\n        this.demo = module.default\n      })\n      import(\n        /* webpackPrefetch: true */ `!raw-loader!../../demos/${this.demoPath}.vue`\n      ).then((module) => {\n        this.demoStr = module.default\n      })\n    }\n  },\n\n  beforeDestroy() {\n    clearTimeout(this.timerId)\n  },\n\n  methods: {\n    handleCollapse() {\n      this.innerCollapsed = !this.innerCollapsed\n    },\n\n    handleCopy() {\n      this.copied = true\n      copy(this.decodedCode)\n\n      clearTimeout(this.timer)\n      this.timerId = setTimeout(() => {\n        this.copied = false\n      }, 2000)\n    },\n\n    openCodeSandBox() {\n      createCodeSandBox(this.demoStr)\n    },\n  },\n}\n</script>\n\n<style lang=\"stylus\">\n.dumi-previewer {\n  background-color: #fff;\n  border: 1px solid #ebedf1;\n  border-radius: 1px;\n\n  .dumi-previewer-demo {\n    padding: 40px 24px;\n  }\n\n  .dumi-previewer-actions {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    border-top: 1px dashed #ebedf1;\n    height: 40px;\n    padding: 0 1em;\n\n    .dumi-previewer-actions__icon {\n      width: 16px;\n      height: 16px;\n      padding: 8px 4px;\n      opacity: 0.4;\n      cursor: pointer;\n      transition: opacity .3s;\n\n      &:hover {\n        opacity: 0.6;\n      }\n    }\n  }\n\n  .dumi-previewer-source {\n    border-top: 1px dashed #ebedf1;\n\n    div[class*=\"language-\"] {\n      background-color: #f9fafb;\n      border-radius: 0;\n    }\n\n    pre[class*=\"language-\"] {\n      margin: 0 !important;\n    }\n\n    pre[class*=\"language-\"] code {\n      color: #000 !important;\n    }\n\n    .token.cdata,.token.comment,.token.doctype,.token.prolog {\n      color: #708090\n    }\n\n    .token.punctuation {\n      color: #999\n    }\n\n    .token.namespace {\n      opacity: .7\n    }\n\n    .token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag {\n      color: #905\n    }\n\n    .token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string {\n      color: #690\n    }\n\n    .language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url {\n      color: #9a6e3a;\n      background: hsla(0,0%,100%,.5)\n    }\n\n    .token.atrule,.token.attr-value,.token.keyword {\n      color: #07a\n    }\n\n    .token.class-name,.token.function {\n      color: #dd4a68\n    }\n\n    .token.important,.token.regex,.token.variable {\n      color: #e90\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "packages/element/docs/.vuepress/components/highlight.js",
    "content": "const prism = require('prismjs')\nconst escapeHtml = require('escape-html')\nconst loadLanguages = require('prismjs/components/index')\n\nfunction wrap(code, lang) {\n  if (lang === 'text') {\n    code = escapeHtml(code)\n  }\n  return `<pre v-pre class=\"language-${lang}\"><code>${code}</code></pre>`\n}\n\nfunction getLangCodeFromExtension(extension) {\n  const extensionMap = {\n    vue: 'markup',\n    html: 'markup',\n    md: 'markdown',\n    rb: 'ruby',\n    ts: 'typescript',\n    py: 'python',\n    sh: 'bash',\n    yml: 'yaml',\n    styl: 'stylus',\n    kt: 'kotlin',\n    rs: 'rust',\n  }\n\n  return extensionMap[extension] || extension\n}\n\nmodule.exports = (str, lang) => {\n  if (!lang) {\n    return wrap(str, 'text')\n  }\n  lang = lang.toLowerCase()\n  const rawLang = lang\n\n  lang = getLangCodeFromExtension(lang)\n\n  if (!prism.languages[lang]) {\n    try {\n      loadLanguages([lang])\n    } catch (e) {\n      console.warn(\n        `[vuepress] Syntax highlight for language \"${lang}\" is not supported.`\n      )\n    }\n  }\n  if (prism.languages[lang]) {\n    const code = prism.highlight(str, prism.languages[lang], lang)\n    return wrap(code, rawLang)\n  }\n  return wrap(str, 'text')\n}\n"
  },
  {
    "path": "packages/element/docs/.vuepress/config.js",
    "content": "const path = require('path')\nconst utils = require('./util')\n\nconst componentFiles = utils\n  .getFiles(path.resolve(__dirname, '../guide'))\n  .map((item) => item.replace(/(\\.md)/g, ''))\n  .filter((item) => !['el-form', 'el-form-item', 'index'].includes(item))\n\nmodule.exports = {\n  title: 'Element',\n  description: 'Alibaba unified front-end form solution',\n  dest: './doc-site',\n  theme: '@vuepress-dumi/dumi',\n  head: [\n    [\n      'link',\n      {\n        rel: 'icon',\n        href: '//img.alicdn.com/imgextra/i3/O1CN01XtT3Tv1Wd1b5hNVKy_!!6000000002810-55-tps-360-360.svg',\n      },\n    ],\n    [\n      'link',\n      {\n        rel: 'stylesheet',\n        href: 'https://esm.sh/element-ui/lib/theme-chalk/index.css',\n      },\n    ],\n  ],\n  themeConfig: {\n    logo: '//img.alicdn.com/imgextra/i2/O1CN01Kq3OHU1fph6LGqjIz_!!6000000004056-55-tps-1141-150.svg',\n    nav: [\n      {\n        text: 'Element',\n        link: '/guide/',\n      },\n      {\n        text: '主站',\n        link: 'https://formilyjs.org',\n      },\n      {\n        text: 'GITHUB',\n        link: 'https://github.com/alibaba/formily',\n      },\n    ],\n    sidebar: {\n      '/guide/': ['', ...componentFiles],\n    },\n    lastUpdated: 'Last Updated',\n    smoothScroll: true,\n  },\n  plugins: [\n    'vuepress-plugin-typescript',\n    '@vuepress/back-to-top',\n    '@vuepress/last-updated',\n    '@vuepress-dumi/dumi-previewer',\n    [\n      '@vuepress/medium-zoom',\n      {\n        selector: '.content__default :not(a) > img',\n      },\n    ],\n  ],\n  configureWebpack: (config, isServer) => {\n    return {\n      resolve: {\n        alias: {\n          '@formily/element': path.resolve(__dirname, '../../src'),\n          vue$: 'vue/dist/vue.esm.js',\n        },\n      },\n    }\n  },\n  chainWebpack: (config, isServer) => {\n    config.module\n      .rule('js') // Find the rule.\n      .use('babel-loader') // Find the loader\n      .tap((options) =>\n        Object.assign(options, {\n          // Modifying options\n          presets: [\n            [\n              '@vue/babel-preset-jsx',\n              {\n                vModel: false,\n                compositionAPI: true,\n              },\n            ],\n          ],\n        })\n      )\n  },\n}\n"
  },
  {
    "path": "packages/element/docs/.vuepress/enhanceApp.js",
    "content": "import pageComponents from '@internal/page-components'\nimport Element from 'element-ui'\nimport '@formily/element/style.ts'\n\nexport default ({ Vue }) => {\n  for (const [name, component] of Object.entries(pageComponents)) {\n    Vue.component(name, component)\n  }\n  Vue.use(Element, { size: 'small' })\n}\n"
  },
  {
    "path": "packages/element/docs/.vuepress/styles/index.styl",
    "content": ".navbar {\n  padding: 0 28px !important;\n}\n\n.navbar .logo {\n  height: auto !important;\n  width: 150px !important;\n}\n\n.navbar .site-name {\n  // display: none;\n}\n\n.navbar .sidebar-button {\n  padding: 0;\n}\n\n.home .feature {\n  margin-bottom: 40px;\n  text-align: center;\n}\n\n.theme-dumi-content:not(.custom) {\n  max-width: 100%;\n}\n\n.page .page-nav {\n  max-width: 100%;\n}\n\n.dumi-previewer .dumi-previewer-actions .dumi-previewer-actions__icon {\n  padding: 0 !important;\n}\n\n.page .page-edit {\n  max-width 100%\n}\n\n.sidebar-group .sidebar-heading {\n  color: #454d64;\n  font-size: 16px;\n}\n\n.sidebar-group a.sidebar-link {\n  font-size: 0.9em;\n}\n\n.theme-dumi-content .custom-block.warning {\n  padding: 10px 20px;\n  border-color: #FFC11F;\n  box-shadow: 0 6px 16px -2px rgba(0,0,0,.06);\n  background: rgba(255,229,100,0.1);\n}\n.theme-dumi-content .custom-block.danger {\n  padding: 10px 20px;\n  p {\n    margin: 0;\n  }\n}\n\n.theme-dumi-content:not(.custom) > h1, .theme-dumi-content:not(.custom) > h2, .theme-dumi-content:not(.custom) > h3, .theme-dumi-content:not(.custom) > h4, .theme-dumi-content:not(.custom) > h5, .theme-dumi-content:not(.custom) > h6 {\n  margin-bottom: 18px;\n}\n\n.theme-dumi-content p {\n  margin: 1em 0;\n}\n\n.custom-block.warning p {\n  margin: 0;\n}\n\n// .theme-dumi-content div[class*=\"language-\"] {\n//   background-color: #f9fafb;\n// }\n\n// .theme-dumi-content pre[class*=\"language-\"] code {\n//   color: #000;\n// }\n\n.dumi-previewer .dumi-previewer-source,\n.dumi-previewer .dumi-previewer-demo {\n  overflow: auto;\n}\n\n@media (max-width: 719px) {\n  .sidebar-button + .home-link {\n    margin-left: 20px;\n  }\n}\n\n@media (max-width: 419px) {\n  .theme-dumi-content div[class*=\"language-\"] {\n    margin: 0;\n    border-radius: 0;\n  }\n}\n\n"
  },
  {
    "path": "packages/element/docs/.vuepress/util.js",
    "content": "const fs = require('fs')\n\nmodule.exports = {\n  getFiles(dir) {\n    return fs.readdirSync(dir)\n  },\n}\n"
  },
  {
    "path": "packages/element/docs/README.md",
    "content": "---\nhome: true\nheroText: Formily Element\ntagline: 基于 Element UI 封装的Formily2.x组件体系\nactionText: 组件文档\nactionLink: /guide/\nfeatures:\n  - title: 更易用\n    details: 开箱即用，案例丰富\n  - title: 更高效\n    details: 傻瓜写法，超高性能\n  - title: 更专业\n    details: 完备，灵活，优雅\nfooter: Open-source MIT Licensed | Copyright © 2019-present\n---\n\n## 安装\n\nvue2:\n\n```bash\n$ npm install --save element-ui\n$ npm install --save @formily/core @formily/vue @vue/composition-api @formily/element\n```\n\nmain.js 中添加 element 样式\n\n```javascript\nimport 'element-ui/lib/theme-chalk/index.css'\n```\n\n## 快速开始\n\n<dumi-previewer demoPath=\"index\" :collapsed=\"false\" />\n"
  },
  {
    "path": "packages/element/docs/demos/guide/array-cards/effects-json-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  Input,\n  ArrayCards,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    FormButtonGroup,\n    Button,\n    Submit,\n    ...SchemaField,\n  },\n\n  data() {\n    const form = createForm()\n    const schema = {\n      type: 'object',\n      properties: {\n        array: {\n          type: 'array',\n          'x-component': 'ArrayCards',\n          maxItems: 3,\n          title: '对象数组',\n          items: {\n            type: 'object',\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayCards.Index',\n              },\n              aa: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                title: 'AA',\n                required: true,\n                'x-component': 'Input',\n                description: '输入123',\n              },\n              bb: {\n                type: 'string',\n                title: 'BB',\n                required: true,\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-reactions': [\n                  {\n                    dependencies: ['.aa'],\n                    when: \"{{$deps[0] != '123'}}\",\n                    fulfill: {\n                      schema: {\n                        title: 'BB',\n                        'x-disabled': true,\n                      },\n                    },\n                    otherwise: {\n                      schema: {\n                        title: 'Changed',\n                        'x-disabled': false,\n                      },\n                    },\n                  },\n                ],\n              },\n              remove: {\n                type: 'void',\n                'x-component': 'ArrayCards.Remove',\n              },\n              moveUp: {\n                type: 'void',\n                'x-component': 'ArrayCards.MoveUp',\n              },\n              moveDown: {\n                type: 'void',\n                'x-component': 'ArrayCards.MoveDown',\n              },\n            },\n          },\n          properties: {\n            addition: {\n              type: 'void',\n              title: '添加条目',\n              'x-component': 'ArrayCards.Addition',\n            },\n          },\n        },\n      },\n    }\n\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/array-cards/effects-markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaArrayField\n        name=\"array\"\n        :maxItems=\"3\"\n        x-component=\"ArrayCards\"\n        x-decorator=\"FormItem\"\n        :x-component-props=\"{\n          title: '对象数组',\n        }\"\n      >\n        <SchemaObjectField>\n          <SchemaVoidField x-component=\"ArrayCards.Index\" />\n          <SchemaStringField\n            name=\"aa\"\n            x-decorator=\"FormItem\"\n            title=\"AA\"\n            required\n            description=\"AA输入123时隐藏BB\"\n            x-component=\"Input\"\n          />\n          <SchemaStringField\n            name=\"bb\"\n            x-decorator=\"FormItem\"\n            title=\"BB\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaStringField\n            name=\"cc\"\n            x-decorator=\"FormItem\"\n            title=\"CC\"\n            required\n            description=\"CC输入123时隐藏DD\"\n            x-component=\"Input\"\n          />\n          <SchemaStringField\n            name=\"dd\"\n            x-decorator=\"FormItem\"\n            title=\"DD\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaVoidField x-component=\"ArrayCards.Remove\" />\n          <SchemaVoidField x-component=\"ArrayCards.MoveUp\" />\n          <SchemaVoidField x-component=\"ArrayCards.MoveDown\" />\n        </SchemaObjectField>\n        <SchemaVoidField x-component=\"ArrayCards.Addition\" title=\"添加条目\" />\n      </SchemaArrayField>\n    </SchemaField>\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  Input,\n  ArrayCards,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    FormButtonGroup,\n    Button,\n    Submit,\n    ...SchemaField,\n  },\n\n  data() {\n    const form = createForm({\n      effects: () => {\n        //主动联动模式\n        onFieldChange('array.*.aa', ['value'], (field, form) => {\n          form.setFieldState(field.query('.bb'), (state) => {\n            state.visible = field.value != '123'\n          })\n        })\n        //被动联动模式\n        onFieldReact('array.*.dd', (field) => {\n          field.visible = field.query('.cc').get('value') != '123'\n        })\n      },\n    })\n\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/array-cards/json-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  Input,\n  ArrayCards,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    FormButtonGroup,\n    Button,\n    Submit,\n    ...SchemaField,\n  },\n\n  data() {\n    const form = createForm()\n    const schema = {\n      type: 'object',\n      properties: {\n        string_array: {\n          type: 'array',\n          'x-component': 'ArrayCards',\n          maxItems: 3,\n          'x-decorator': 'FormItem',\n          'x-component-props': {\n            title: '字符串数组',\n          },\n          items: {\n            type: 'void',\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayCards.Index',\n              },\n              input: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                title: 'Input',\n                required: true,\n                'x-component': 'Input',\n              },\n              remove: {\n                type: 'void',\n                'x-component': 'ArrayCards.Remove',\n              },\n              moveUp: {\n                type: 'void',\n                'x-component': 'ArrayCards.MoveUp',\n              },\n              moveDown: {\n                type: 'void',\n                'x-component': 'ArrayCards.MoveDown',\n              },\n            },\n          },\n          properties: {\n            addition: {\n              type: 'void',\n              title: '添加条目',\n              'x-component': 'ArrayCards.Addition',\n            },\n          },\n        },\n        array: {\n          type: 'array',\n          'x-component': 'ArrayCards',\n          maxItems: 3,\n          'x-decorator': 'FormItem',\n          'x-component-props': {\n            title: '对象数组',\n          },\n          items: {\n            type: 'object',\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayCards.Index',\n              },\n              input: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                title: 'Input',\n                required: true,\n                'x-component': 'Input',\n              },\n              remove: {\n                type: 'void',\n                'x-component': 'ArrayCards.Remove',\n              },\n              moveUp: {\n                type: 'void',\n                'x-component': 'ArrayCards.MoveUp',\n              },\n              moveDown: {\n                type: 'void',\n                'x-component': 'ArrayCards.MoveDown',\n              },\n            },\n          },\n          properties: {\n            addition: {\n              type: 'void',\n              title: '添加条目',\n              'x-component': 'ArrayCards.Addition',\n            },\n          },\n        },\n      },\n    }\n\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/array-cards/markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaArrayField\n        name=\"string_array\"\n        :maxItems=\"3\"\n        x-decorator=\"FormItem\"\n        x-component=\"ArrayCards\"\n        :x-component-props=\"{\n          title: '字符串数组',\n        }\"\n      >\n        <SchemaVoidField>\n          <SchemaVoidField x-component=\"ArrayCards.Index\" />\n          <SchemaStringField\n            name=\"input\"\n            x-decorator=\"FormItem\"\n            title=\"Input\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaVoidField x-component=\"ArrayCards.Remove\" />\n          <SchemaVoidField x-component=\"ArrayCards.MoveUp\" />\n          <SchemaVoidField x-component=\"ArrayCards.MoveDown\" />\n        </SchemaVoidField>\n        <SchemaVoidField x-component=\"ArrayCards.Addition\" title=\"添加条目\" />\n      </SchemaArrayField>\n      <SchemaArrayField\n        name=\"array\"\n        :maxItems=\"3\"\n        x-decorator=\"FormItem\"\n        x-component=\"ArrayCards\"\n        :x-component-props=\"{\n          title: '对象数组',\n        }\"\n      >\n        <SchemaObjectField>\n          <SchemaVoidField x-component=\"ArrayCards.Index\" />\n          <SchemaStringField\n            name=\"input\"\n            x-decorator=\"FormItem\"\n            title=\"Input\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaVoidField x-component=\"ArrayCards.Remove\" />\n          <SchemaVoidField x-component=\"ArrayCards.MoveUp\" />\n          <SchemaVoidField x-component=\"ArrayCards.MoveDown\" />\n        </SchemaObjectField>\n        <SchemaVoidField x-component=\"ArrayCards.Addition\" title=\"添加条目\" />\n      </SchemaArrayField>\n    </SchemaField>\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  Input,\n  ArrayCards,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    FormButtonGroup,\n    Button,\n    Submit,\n    ...SchemaField,\n  },\n\n  data() {\n    const form = createForm()\n\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/array-collapse/effects-json-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  Input,\n  ArrayCollapse,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    FormButtonGroup,\n    Button,\n    Submit,\n    ...SchemaField,\n  },\n\n  data() {\n    const form = createForm()\n    const schema = {\n      type: 'object',\n      properties: {\n        array: {\n          type: 'array',\n          'x-component': 'ArrayCollapse',\n          maxItems: 3,\n          title: '对象数组',\n          items: {\n            type: 'object',\n            'x-component': 'ArrayCollapse.Item',\n            'x-component-props': {\n              header: '对象数组',\n            },\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayCollapse.Index',\n              },\n              aa: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                title: 'AA',\n                required: true,\n                'x-component': 'Input',\n                description: '输入123',\n              },\n              bb: {\n                type: 'string',\n                title: 'BB',\n                required: true,\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-reactions': [\n                  {\n                    dependencies: ['.aa'],\n                    when: \"{{$deps[0] != '123'}}\",\n                    fulfill: {\n                      schema: {\n                        title: 'BB',\n                        'x-disabled': true,\n                      },\n                    },\n                    otherwise: {\n                      schema: {\n                        title: 'Changed',\n                        'x-disabled': false,\n                      },\n                    },\n                  },\n                ],\n              },\n              remove: {\n                type: 'void',\n                'x-component': 'ArrayCollapse.Remove',\n              },\n              moveUp: {\n                type: 'void',\n                'x-component': 'ArrayCollapse.MoveUp',\n              },\n              moveDown: {\n                type: 'void',\n                'x-component': 'ArrayCollapse.MoveDown',\n              },\n            },\n          },\n          properties: {\n            addition: {\n              type: 'void',\n              title: '添加条目',\n              'x-component': 'ArrayCollapse.Addition',\n            },\n          },\n        },\n      },\n    }\n\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/array-collapse/effects-markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaArrayField\n        name=\"array\"\n        :maxItems=\"3\"\n        x-component=\"ArrayCollapse\"\n        x-decorator=\"FormItem\"\n        :x-component-props=\"{\n          title: '对象数组',\n        }\"\n      >\n        <SchemaObjectField\n          x-component=\"ArrayCollapse.Item\"\n          x-decorator=\"FormItem\"\n          :x-component-props=\"{\n            title: '对象数组',\n          }\"\n        >\n          <SchemaVoidField x-component=\"ArrayCollapse.Index\" />\n          <SchemaStringField\n            name=\"aa\"\n            x-decorator=\"FormItem\"\n            title=\"AA\"\n            required\n            description=\"AA输入123时隐藏BB\"\n            x-component=\"Input\"\n          />\n          <SchemaStringField\n            name=\"bb\"\n            x-decorator=\"FormItem\"\n            title=\"BB\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaStringField\n            name=\"cc\"\n            x-decorator=\"FormItem\"\n            title=\"CC\"\n            required\n            description=\"CC输入123时隐藏DD\"\n            x-component=\"Input\"\n          />\n          <SchemaStringField\n            name=\"dd\"\n            x-decorator=\"FormItem\"\n            title=\"DD\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaVoidField x-component=\"ArrayCollapse.Remove\" />\n          <SchemaVoidField x-component=\"ArrayCollapse.MoveUp\" />\n          <SchemaVoidField x-component=\"ArrayCollapse.MoveDown\" />\n        </SchemaObjectField>\n        <SchemaVoidField\n          x-component=\"ArrayCollapse.Addition\"\n          title=\"添加条目\"\n        />\n      </SchemaArrayField>\n    </SchemaField>\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  Input,\n  ArrayCollapse,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    FormButtonGroup,\n    Button,\n    Submit,\n    ...SchemaField,\n  },\n\n  data() {\n    const form = createForm({\n      effects: () => {\n        //主动联动模式\n        onFieldChange('array.*.aa', ['value'], (field, form) => {\n          form.setFieldState(field.query('.bb'), (state) => {\n            state.visible = field.value != '123'\n          })\n        })\n        //被动联动模式\n        onFieldReact('array.*.dd', (field) => {\n          field.visible = field.query('.cc').get('value') != '123'\n        })\n      },\n    })\n\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/array-collapse/json-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  Input,\n  ArrayCollapse,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    FormButtonGroup,\n    Button,\n    Submit,\n    ...SchemaField,\n  },\n\n  data() {\n    const form = createForm()\n    const schema = {\n      type: 'object',\n      properties: {\n        string_array: {\n          type: 'array',\n          'x-component': 'ArrayCollapse',\n          maxItems: 3,\n          'x-decorator': 'FormItem',\n          items: {\n            type: 'object',\n            'x-component': 'ArrayCollapse.Item',\n            'x-component-props': {\n              title: '字符串数组',\n            },\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayCollapse.Index',\n              },\n              input: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                title: 'Input',\n                required: true,\n                'x-component': 'Input',\n              },\n              remove: {\n                type: 'void',\n                'x-component': 'ArrayCollapse.Remove',\n              },\n              moveUp: {\n                type: 'void',\n                'x-component': 'ArrayCollapse.MoveUp',\n              },\n              moveDown: {\n                type: 'void',\n                'x-component': 'ArrayCollapse.MoveDown',\n              },\n            },\n          },\n          properties: {\n            addition: {\n              type: 'void',\n              title: '添加条目',\n              'x-component': 'ArrayCollapse.Addition',\n            },\n          },\n        },\n        array: {\n          type: 'array',\n          'x-component': 'ArrayCollapse',\n          maxItems: 3,\n          'x-decorator': 'FormItem',\n          items: {\n            type: 'object',\n            'x-component': 'ArrayCollapse.Item',\n            'x-component-props': {\n              title: '对象数组',\n            },\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayCollapse.Index',\n              },\n              input: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                title: 'Input',\n                required: true,\n                'x-component': 'Input',\n              },\n              remove: {\n                type: 'void',\n                'x-component': 'ArrayCollapse.Remove',\n              },\n              moveUp: {\n                type: 'void',\n                'x-component': 'ArrayCollapse.MoveUp',\n              },\n              moveDown: {\n                type: 'void',\n                'x-component': 'ArrayCollapse.MoveDown',\n              },\n            },\n          },\n          properties: {\n            addition: {\n              type: 'void',\n              title: '添加条目',\n              'x-component': 'ArrayCollapse.Addition',\n            },\n          },\n        },\n        array_unshift: {\n          type: 'array',\n          'x-component': 'ArrayCollapse',\n          maxItems: 3,\n          'x-decorator': 'FormItem',\n          items: {\n            type: 'object',\n            'x-component': 'ArrayCollapse.Item',\n            'x-component-props': {\n              title: '对象数组',\n            },\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayCollapse.Index',\n              },\n              input: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                title: 'Input',\n                required: true,\n                'x-component': 'Input',\n              },\n              remove: {\n                type: 'void',\n                'x-component': 'ArrayCollapse.Remove',\n              },\n              moveUp: {\n                type: 'void',\n                'x-component': 'ArrayCollapse.MoveUp',\n              },\n              moveDown: {\n                type: 'void',\n                'x-component': 'ArrayCollapse.MoveDown',\n              },\n            },\n          },\n          properties: {\n            addition: {\n              type: 'void',\n              title: '添加条目(unshift)',\n              'x-component': 'ArrayCollapse.Addition',\n              'x-component-props': {\n                method: 'unshift',\n              },\n            },\n          },\n        },\n      },\n    }\n\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/array-collapse/markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaArrayField\n        name=\"string_array\"\n        :maxItems=\"3\"\n        x-decorator=\"FormItem\"\n        x-component=\"ArrayCollapse\"\n        :x-component-props=\"{\n          accordion: true,\n          defaultOpenPanelCount: 3,\n        }\"\n      >\n        <SchemaVoidField\n          x-component=\"ArrayCollapse.Item\"\n          :x-component-props=\"{\n            title: '字符串数组',\n          }\"\n        >\n          <SchemaVoidField x-component=\"ArrayCollapse.Index\" />\n          <SchemaStringField\n            name=\"input\"\n            x-decorator=\"FormItem\"\n            title=\"Input\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaVoidField x-component=\"ArrayCollapse.Remove\" />\n          <SchemaVoidField x-component=\"ArrayCollapse.MoveUp\" />\n          <SchemaVoidField x-component=\"ArrayCollapse.MoveDown\" />\n        </SchemaVoidField>\n        <SchemaVoidField\n          x-component=\"ArrayCollapse.Addition\"\n          title=\"添加条目\"\n        />\n      </SchemaArrayField>\n      <SchemaArrayField\n        name=\"array\"\n        :maxItems=\"3\"\n        x-decorator=\"FormItem\"\n        x-component=\"ArrayCollapse\"\n      >\n        <SchemaObjectField\n          x-component=\"ArrayCollapse.Item\"\n          :x-component-props=\"{\n            title: '对象数组',\n          }\"\n        >\n          <SchemaVoidField x-component=\"ArrayCollapse.Index\" />\n          <SchemaStringField\n            name=\"input\"\n            x-decorator=\"FormItem\"\n            title=\"Input\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaVoidField x-component=\"ArrayCollapse.Remove\" />\n          <SchemaVoidField x-component=\"ArrayCollapse.MoveUp\" />\n          <SchemaVoidField x-component=\"ArrayCollapse.MoveDown\" />\n        </SchemaObjectField>\n        <SchemaVoidField\n          x-component=\"ArrayCollapse.Addition\"\n          title=\"添加条目\"\n        />\n      </SchemaArrayField>\n      <SchemaArrayField\n        name=\"string_array_unshift\"\n        :maxItems=\"3\"\n        x-decorator=\"FormItem\"\n        x-component=\"ArrayCollapse\"\n        :x-component-props=\"{\n          defaultOpenPanelCount: 8,\n        }\"\n      >\n        <SchemaVoidField\n          x-component=\"ArrayCollapse.Item\"\n          :x-component-props=\"{\n            title: '字符串数组',\n          }\"\n        >\n          <SchemaVoidField x-component=\"ArrayCollapse.Index\" />\n          <SchemaStringField\n            name=\"input\"\n            x-decorator=\"FormItem\"\n            title=\"Input\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaVoidField x-component=\"ArrayCollapse.Remove\" />\n          <SchemaVoidField x-component=\"ArrayCollapse.MoveUp\" />\n          <SchemaVoidField x-component=\"ArrayCollapse.MoveDown\" />\n        </SchemaVoidField>\n        <SchemaVoidField\n          x-component=\"ArrayCollapse.Addition\"\n          title=\"添加条目（unshift）\"\n          :x-component-props=\"{\n            method: 'unshift',\n          }\"\n        />\n      </SchemaArrayField>\n    </SchemaField>\n    <FormButtonGroup>\n      <Button\n        @click=\"\n          () => {\n            form.setInitialValues({\n              array: Array.from({ length: 10 }).map(() => ({\n                input: 'default value',\n              })),\n              string_array: Array.from({ length: 10 }).map(\n                () => 'default value'\n              ),\n              string_array_unshift: Array.from({ length: 10 }).map(\n                () => 'default value'\n              ),\n            })\n          }\n        \"\n      >\n        加载默认数据\n      </Button>\n      <Submit @submit=\"log\">提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  Input,\n  ArrayCollapse,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    FormButtonGroup,\n    Button,\n    Submit,\n    ...SchemaField,\n  },\n\n  data() {\n    const form = createForm()\n\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/array-items/json-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormButtonGroup,\n  Submit,\n  FormItem,\n  Space,\n  Input,\n  Select,\n  DatePicker,\n  ArrayItems,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Space,\n    Input,\n    Select,\n    DatePicker,\n    ArrayItems,\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    FormButtonGroup,\n    Button,\n    Submit,\n    ...SchemaField,\n  },\n\n  data() {\n    const form = createForm()\n    const schema = {\n      type: 'object',\n      properties: {\n        string_array: {\n          type: 'array',\n          'x-component': 'ArrayItems',\n          'x-decorator': 'FormItem',\n          title: '字符串数组',\n          items: {\n            type: 'void',\n            'x-component': 'Space',\n            properties: {\n              sort: {\n                type: 'void',\n                'x-decorator': 'FormItem',\n                'x-component': 'ArrayItems.SortHandle',\n              },\n              input: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n              remove: {\n                type: 'void',\n                'x-decorator': 'FormItem',\n                'x-component': 'ArrayItems.Remove',\n              },\n            },\n          },\n          properties: {\n            add: {\n              type: 'void',\n              title: '添加条目',\n              'x-component': 'ArrayItems.Addition',\n            },\n          },\n        },\n        array: {\n          type: 'array',\n          'x-component': 'ArrayItems',\n          'x-decorator': 'FormItem',\n          title: '对象数组',\n          items: {\n            type: 'object',\n            properties: {\n              space: {\n                type: 'void',\n                'x-component': 'Space',\n                properties: {\n                  sort: {\n                    type: 'void',\n                    'x-decorator': 'FormItem',\n                    'x-component': 'ArrayItems.SortHandle',\n                  },\n                  date: {\n                    type: 'string',\n                    title: '日期',\n                    'x-decorator': 'FormItem',\n                    'x-component': 'DatePicker',\n                    'x-component-props': {\n                      type: 'daterange',\n                      style: {\n                        width: '250px',\n                      },\n                    },\n                  },\n                  input: {\n                    type: 'string',\n                    title: '输入框',\n                    'x-decorator': 'FormItem',\n                    'x-component': 'Input',\n                  },\n                  select: {\n                    type: 'string',\n                    title: '下拉框',\n                    enum: [\n                      { label: '选项1', value: 1 },\n                      { label: '选项2', value: 2 },\n                    ],\n                    'x-decorator': 'FormItem',\n                    'x-component': 'Select',\n                    'x-component-props': {\n                      style: {\n                        width: '250px',\n                      },\n                    },\n                  },\n                  remove: {\n                    type: 'void',\n                    'x-decorator': 'FormItem',\n                    'x-component': 'ArrayItems.Remove',\n                  },\n                },\n              },\n            },\n          },\n          properties: {\n            add: {\n              type: 'void',\n              title: '添加条目',\n              'x-component': 'ArrayItems.Addition',\n            },\n          },\n        },\n        array2: {\n          type: 'array',\n          'x-component': 'ArrayItems',\n          'x-decorator': 'FormItem',\n          'x-component-props': { style: { width: '600px' } },\n          title: '对象数组',\n          items: {\n            type: 'object',\n            'x-decorator': 'ArrayItems.Item',\n            properties: {\n              space: {\n                type: 'void',\n                'x-component': 'Space',\n                properties: {\n                  sort: {\n                    type: 'void',\n                    'x-decorator': 'FormItem',\n                    'x-component': 'ArrayItems.SortHandle',\n                  },\n                  date: {\n                    type: 'string',\n                    title: '日期',\n                    'x-decorator': 'FormItem',\n                    'x-component': 'DatePicker',\n                    'x-component-props': {\n                      type: 'daterange',\n                      style: {\n                        width: '250px',\n                      },\n                    },\n                  },\n                  input: {\n                    type: 'string',\n                    title: '输入框',\n                    'x-decorator': 'FormItem',\n                    'x-component': 'Input',\n                  },\n                  remove: {\n                    type: 'void',\n                    'x-decorator': 'FormItem',\n                    'x-component': 'ArrayItems.Remove',\n                  },\n                },\n              },\n            },\n          },\n          properties: {\n            add: {\n              type: 'void',\n              title: '添加条目',\n              'x-component': 'ArrayItems.Addition',\n            },\n          },\n        },\n      },\n    }\n\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/array-items/markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaArrayField\n        name=\"string_array\"\n        title=\"字符串数组\"\n        x-decorator=\"FormItem\"\n        x-component=\"ArrayItems\"\n      >\n        <SchemaVoidField x-component=\"Space\">\n          <SchemaVoidField\n            x-decorator=\"FormItem\"\n            x-component=\"ArrayItems.SortHandle\"\n          />\n          <SchemaStringField\n            x-decorator=\"FormItem\"\n            required\n            name=\"input\"\n            x-component=\"Input\"\n            :x-component-props=\"{\n              style: {\n                width: '160px',\n              },\n            }\"\n          />\n          <SchemaVoidField\n            x-decorator=\"FormItem\"\n            x-component=\"ArrayItems.Remove\"\n          />\n        </SchemaVoidField>\n        <SchemaVoidField x-component=\"ArrayItems.Addition\" title=\"添加条目\" />\n      </SchemaArrayField>\n      <SchemaArrayField\n        name=\"array\"\n        title=\"对象数组\"\n        x-decorator=\"FormItem\"\n        x-component=\"ArrayItems\"\n      >\n        <SchemaObjectField>\n          <SchemaVoidField x-component=\"Space\">\n            <SchemaVoidField\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.SortHandle\"\n            />\n            <SchemaStringField\n              x-decorator=\"FormItem\"\n              required\n              title=\"日期\"\n              name=\"date\"\n              x-component=\"DatePicker\"\n              :x-component-props=\"{\n                type: 'daterange',\n                style: {\n                  width: '160px',\n                },\n              }\"\n            />\n            <SchemaStringField\n              x-decorator=\"FormItem\"\n              required\n              title=\"输入框\"\n              name=\"input\"\n              x-component=\"Input\"\n            />\n            <SchemaStringField\n              x-decorator=\"FormItem\"\n              required\n              title=\"选择框\"\n              name=\"select\"\n              :enum=\"[\n                { label: '选项1', value: 1 },\n                { label: '选项2', value: 2 },\n              ]\"\n              x-component=\"Select\"\n              :x-component-props=\"{\n                style: {\n                  width: 160,\n                },\n              }\"\n            />\n            <SchemaVoidField\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.Remove\"\n            />\n          </SchemaVoidField>\n        </SchemaObjectField>\n        <SchemaVoidField x-component=\"ArrayItems.Addition\" title=\"添加条目\" />\n      </SchemaArrayField>\n      <SchemaArrayField\n        name=\"array2\"\n        title=\"对象数组\"\n        x-decorator=\"FormItem\"\n        x-component=\"ArrayItems\"\n        :x-component-props=\"{ style: { width: '600px' } }\"\n      >\n        <SchemaObjectField x-decorator=\"ArrayItems.Item\">\n          <SchemaVoidField x-component=\"Space\">\n            <SchemaVoidField\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.SortHandle\"\n            />\n            <SchemaStringField\n              x-decorator=\"FormItem\"\n              required\n              title=\"日期\"\n              name=\"date\"\n              x-component=\"DatePicker\"\n              :x-component-props=\"{\n                type: 'daterange',\n                style: {\n                  width: '250px',\n                },\n              }\"\n            />\n            <SchemaStringField\n              x-decorator=\"FormItem\"\n              required\n              title=\"输入框\"\n              name=\"input\"\n              x-component=\"Input\"\n            />\n            <SchemaVoidField\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.Remove\"\n            />\n          </SchemaVoidField>\n        </SchemaObjectField>\n        <SchemaVoidField x-component=\"ArrayItems.Addition\" title=\"添加条目\" />\n      </SchemaArrayField>\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit @submit=\"log\">提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  Input,\n  Select,\n  Space,\n  DatePicker,\n  ArrayItems,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Space,\n    Input,\n    Select,\n    DatePicker,\n    ArrayItems,\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    FormButtonGroup,\n    Button,\n    Submit,\n    ...SchemaField,\n  },\n\n  data() {\n    const form = createForm()\n\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/array-table/effects-json-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  Submit,\n  FormItem,\n  ArrayTable,\n  Input,\n  Editable,\n  Switch,\n} from '@formily/element'\n\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    ArrayTable,\n    Input,\n    Editable,\n    Switch,\n  },\n})\n\nexport default {\n  components: { FormProvider, Submit, ...fields },\n  data() {\n    const form = createForm({\n      effects: () => {\n        //主动联动模式\n        onFieldChange('hideFirstColumn', ['value'], (field) => {\n          field.query('array.column3').take((target) => {\n            target.visible = !field.value\n          })\n          field.query('array.*.a2').take((target) => {\n            target.visible = !field.value\n          })\n        })\n        //被动联动模式\n        onFieldReact('array.*.a2', (field) => {\n          field.visible = !field.query('.a1').get('value')\n        })\n      },\n    })\n    const schema = {\n      type: 'object',\n      properties: {\n        hideFirstColumn: {\n          type: 'boolean',\n          title: '隐藏A2',\n          'x-decorator': 'FormItem',\n          'x-component': 'Switch',\n        },\n        array: {\n          type: 'array',\n          'x-decorator': 'FormItem',\n          'x-component': 'ArrayTable',\n          items: {\n            type: 'object',\n            properties: {\n              column1: {\n                type: 'void',\n                'x-component': 'ArrayTable.Column',\n                'x-component-props': {\n                  width: 80,\n                  title: 'Index',\n                  align: 'center',\n                },\n                properties: {\n                  index: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.Index',\n                  },\n                },\n              },\n              column2: {\n                type: 'void',\n                'x-component': 'ArrayTable.Column',\n                'x-component-props': { width: 100, title: '显隐->A2' },\n                properties: {\n                  a1: {\n                    type: 'boolean',\n                    'x-decorator': 'FormItem',\n                    'x-component': 'Switch',\n                  },\n                },\n              },\n              column3: {\n                type: 'void',\n                'x-component': 'ArrayTable.Column',\n                'x-component-props': { width: 200, title: 'A2' },\n                properties: {\n                  a2: {\n                    type: 'string',\n                    'x-decorator': 'FormItem',\n                    'x-component': 'Input',\n                  },\n                },\n              },\n              column4: {\n                type: 'void',\n                'x-component': 'ArrayTable.Column',\n                'x-component-props': { title: 'A3' },\n                properties: {\n                  a3: {\n                    type: 'string',\n                    'x-decorator': 'FormItem',\n                    'x-component': 'Input',\n                  },\n                },\n              },\n              column5: {\n                type: 'void',\n                'x-component': 'ArrayTable.Column',\n                'x-component-props': {\n                  title: 'Operations',\n                  prop: 'operations',\n                  width: 200,\n                  fixed: 'right',\n                },\n                properties: {\n                  item: {\n                    type: 'void',\n                    'x-component': 'FormItem',\n                    properties: {\n                      remove: {\n                        type: 'void',\n                        'x-component': 'ArrayTable.Remove',\n                      },\n                      moveDown: {\n                        type: 'void',\n                        'x-component': 'ArrayTable.MoveDown',\n                      },\n                      moveUp: {\n                        type: 'void',\n                        'x-component': 'ArrayTable.MoveUp',\n                      },\n                    },\n                  },\n                },\n              },\n            },\n          },\n          properties: {\n            add: {\n              type: 'void',\n              'x-component': 'ArrayTable.Addition',\n              title: '添加条目',\n            },\n          },\n        },\n      },\n    }\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    log(...v) {\n      console.log(...v)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/array-table/effects-markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaBooleanField\n        name=\"hideFirstColumn\"\n        x-decorator=\"FormItem\"\n        x-component=\"Switch\"\n        title=\"隐藏A2\"\n      />\n      <SchemaArrayField\n        name=\"array\"\n        x-decorator=\"FormItem\"\n        x-component=\"ArrayTable\"\n      >\n        <SchemaObjectField>\n          <SchemaVoidField\n            name=\"column1\"\n            x-component=\"ArrayTable.Column\"\n            :x-component-props=\"{ width: 80, title: 'Index' }\"\n            ><SchemaVoidField x-component=\"ArrayTable.Index\" />\n          </SchemaVoidField>\n          <SchemaVoidField\n            name=\"column2\"\n            x-component=\"ArrayTable.Column\"\n            :x-component-props=\"{\n              title: '显隐->A2',\n              width: 100,\n            }\"\n          >\n            <SchemaBooleanField\n              name=\"a1\"\n              x-decorator=\"FormItem\"\n              x-component=\"Switch\"\n            />\n          </SchemaVoidField>\n          <SchemaVoidField\n            x-component=\"ArrayTable.Column\"\n            name=\"column3\"\n            :x-component-props=\"{ title: 'A2', width: 200 }\"\n          >\n            <SchemaStringField\n              x-decorator=\"FormItem\"\n              name=\"a2\"\n              x-component=\"Input\"\n            />\n          </SchemaVoidField>\n          <SchemaVoidField\n            name=\"column4\"\n            x-component=\"ArrayTable.Column\"\n            :x-component-props=\"{ title: 'A3' }\"\n          >\n            <SchemaStringField\n              name=\"a3\"\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n          </SchemaVoidField>\n          <SchemaVoidField\n            name=\"column5\"\n            x-component=\"ArrayTable.Column\"\n            :x-component-props=\"{\n              title: 'Operations',\n              prop: 'operations',\n              width: 200,\n              fixed: 'right',\n            }\"\n          >\n            <SchemaVoidField x-component=\"FormItem\">\n              <SchemaVoidField x-component=\"ArrayTable.Remove\" />\n              <SchemaVoidField x-component=\"ArrayTable.MoveUp\" />\n              <SchemaVoidField x-component=\"ArrayTable.MoveDown\" />\n            </SchemaVoidField>\n          </SchemaVoidField>\n        </SchemaObjectField>\n        <SchemaVoidField x-component=\"ArrayTable.Addition\" title=\"添加条目\" />\n      </SchemaArrayField>\n    </SchemaField>\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  Submit,\n  FormItem,\n  ArrayTable,\n  Input,\n  Editable,\n  Switch,\n} from '@formily/element'\n\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    ArrayTable,\n    Input,\n    Editable,\n    Switch,\n  },\n})\n\nexport default {\n  components: { FormProvider, Submit, ...fields },\n  data() {\n    const form = createForm({\n      effects: () => {\n        //主动联动模式\n        onFieldChange('hideFirstColumn', ['value'], (field) => {\n          field.query('array.column3').take((target) => {\n            console.log('target', target)\n            target.visible = !field.value\n          })\n          field.query('array.*.a2').take((target) => {\n            target.visible = !field.value\n          })\n        })\n        //被动联动模式\n        onFieldReact('array.*.a2', (field) => {\n          field.visible = !field.query('.a1').get('value')\n        })\n      },\n    })\n\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(...v) {\n      console.log(...v)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/array-table/json-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport { Submit, FormItem, ArrayTable, Input, Editable } from '@formily/element'\n\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    ArrayTable,\n    Input,\n    Editable,\n  },\n})\n\nexport default {\n  components: { FormProvider, Submit, ...fields },\n  data() {\n    const form = createForm()\n    const schema = {\n      type: 'object',\n      properties: {\n        array: {\n          type: 'array',\n          'x-decorator': 'FormItem',\n          'x-component': 'ArrayTable',\n          items: {\n            type: 'object',\n            properties: {\n              column1: {\n                type: 'void',\n                'x-component': 'ArrayTable.Column',\n                'x-component-props': {\n                  width: 80,\n                  title: 'Index',\n                  align: 'center',\n                },\n                properties: {\n                  index: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.Index',\n                  },\n                },\n              },\n              column2: {\n                type: 'void',\n                'x-component': 'ArrayTable.Column',\n                'x-component-props': { width: 200, title: 'A1' },\n                properties: {\n                  a1: {\n                    type: 'string',\n                    'x-decorator': 'Editable',\n                    'x-component': 'Input',\n                  },\n                },\n              },\n              column3: {\n                type: 'void',\n                'x-component': 'ArrayTable.Column',\n                'x-component-props': { width: 200, title: 'A2' },\n                properties: {\n                  a2: {\n                    type: 'string',\n                    'x-decorator': 'FormItem',\n                    'x-component': 'Input',\n                  },\n                },\n              },\n              column4: {\n                type: 'void',\n                'x-component': 'ArrayTable.Column',\n                'x-component-props': { title: 'A3' },\n                properties: {\n                  a3: {\n                    type: 'string',\n                    'x-decorator': 'FormItem',\n                    'x-component': 'Input',\n                  },\n                },\n              },\n              column5: {\n                type: 'void',\n                'x-component': 'ArrayTable.Column',\n                'x-component-props': {\n                  title: 'Operations',\n                  prop: 'operations',\n                  width: 200,\n                  fixed: 'right',\n                },\n                properties: {\n                  item: {\n                    type: 'void',\n                    'x-component': 'FormItem',\n                    properties: {\n                      remove: {\n                        type: 'void',\n                        'x-component': 'ArrayTable.Remove',\n                      },\n                      moveDown: {\n                        type: 'void',\n                        'x-component': 'ArrayTable.MoveDown',\n                      },\n                      moveUp: {\n                        type: 'void',\n                        'x-component': 'ArrayTable.MoveUp',\n                      },\n                    },\n                  },\n                },\n              },\n            },\n          },\n          properties: {\n            add: {\n              type: 'void',\n              'x-component': 'ArrayTable.Addition',\n              title: '添加条目',\n            },\n          },\n        },\n      },\n    }\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    log(...v) {\n      console.log(...v)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/array-table/markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaArrayField\n        name=\"array\"\n        x-decorator=\"FormItem\"\n        x-component=\"ArrayTable\"\n        :x-component-props=\"{\n          pagination: { pageSize: 10 },\n        }\"\n      >\n        <SchemaObjectField>\n          <SchemaVoidField\n            x-component=\"ArrayTable.Column\"\n            :x-component-props=\"{ width: 80, title: 'Index' }\"\n            ><SchemaVoidField\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayTable.Index\"\n            />\n          </SchemaVoidField>\n          <SchemaVoidField\n            x-component=\"ArrayTable.Column\"\n            :x-component-props=\"{ prop: 'a1', title: 'A1', width: 200 }\"\n          >\n            <SchemaStringField\n              x-decorator=\"Editable\"\n              name=\"a1\"\n              :required=\"true\"\n              x-component=\"Input\"\n            />\n          </SchemaVoidField>\n          <SchemaVoidField\n            x-component=\"ArrayTable.Column\"\n            :x-component-props=\"{ title: 'A2', width: 200 }\"\n          >\n            <SchemaStringField\n              x-decorator=\"FormItem\"\n              name=\"a2\"\n              :required=\"true\"\n              x-component=\"Input\"\n            />\n          </SchemaVoidField>\n          <SchemaVoidField\n            x-component=\"ArrayTable.Column\"\n            :x-component-props=\"{ title: 'A3' }\"\n          >\n            <SchemaStringField\n              name=\"a3\"\n              :required=\"true\"\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n            />\n          </SchemaVoidField>\n          <SchemaVoidField\n            x-component=\"ArrayTable.Column\"\n            :x-component-props=\"{\n              title: 'Operations',\n              prop: 'operations',\n              width: 200,\n              fixed: 'right',\n            }\"\n          >\n            <SchemaVoidField x-component=\"FormItem\">\n              <SchemaVoidField x-component=\"ArrayTable.Remove\" />\n              <SchemaVoidField x-component=\"ArrayTable.MoveUp\" />\n              <SchemaVoidField x-component=\"ArrayTable.MoveDown\" />\n            </SchemaVoidField>\n          </SchemaVoidField>\n        </SchemaObjectField>\n        <SchemaVoidField x-component=\"ArrayTable.Addition\" title=\"添加条目\" />\n      </SchemaArrayField>\n    </SchemaField>\n    <Submit @submit=\"log\">提交</Submit>\n    <Button\n      @click=\"\n        () => {\n          form.setInitialValues({\n            array: range(100000),\n          })\n        }\n      \"\n    >\n      加载10W条超大数据\n    </Button>\n    <Alert\n      :style=\"{ marginTop: '10px' }\"\n      title=\"注意：开启formily插件的页面，因为后台有数据通信，会占用浏览器算力，最好在无痕模式(无formily插件)下测试\"\n      type=\"warning\"\n    />\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport { Submit, FormItem, ArrayTable, Input, Editable } from '@formily/element'\nimport { Button, Alert } from 'element-ui'\n\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    ArrayTable,\n    Input,\n    Editable,\n  },\n})\n\nexport default {\n  components: { FormProvider, Submit, Button, Alert, ...fields },\n  data() {\n    const form = createForm()\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(...v) {\n      console.log(...v)\n    },\n    range(count) {\n      return Array.from(new Array(count)).map((_, key) => ({\n        aaa: key,\n      }))\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/array-tabs/json-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormButtonGroup,\n  Submit,\n  FormItem,\n  Space,\n  Input,\n  ArrayTabs,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Space,\n    Input,\n    ArrayTabs,\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    FormButtonGroup,\n    Button,\n    Submit,\n    ...SchemaField,\n  },\n\n  data() {\n    const form = createForm()\n    const schema = {\n      type: 'object',\n      properties: {\n        string_array: {\n          type: 'array',\n          title: '字符串数组',\n          'x-decorator': 'FormItem',\n          maxItems: 3,\n          'x-component': 'ArrayTabs',\n          items: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            required: true,\n            'x-component': 'Input',\n          },\n        },\n        array: {\n          type: 'array',\n          title: '对象数组',\n          'x-decorator': 'FormItem',\n          maxItems: 3,\n          'x-component': 'ArrayTabs',\n          items: {\n            type: 'object',\n            properties: {\n              aaa: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                title: 'AAA',\n                required: true,\n                'x-component': 'Input',\n              },\n              bbb: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                title: 'BBB',\n                required: true,\n                'x-component': 'Input',\n              },\n            },\n          },\n        },\n      },\n    }\n\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/array-tabs/markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaArrayField\n        name=\"string_array\"\n        x-decorator=\"FormItem\"\n        title=\"字符串数组\"\n        :maxItems=\"3\"\n        x-component=\"ArrayTabs\"\n      >\n        <SchemaStringField\n          x-decorator=\"FormItem\"\n          required\n          x-component=\"Input\"\n        />\n      </SchemaArrayField>\n      <SchemaArrayField\n        name=\"array\"\n        x-decorator=\"FormItem\"\n        title=\"对象数组\"\n        :maxItems=\"3\"\n        x-component=\"ArrayTabs\"\n      >\n        <SchemaObjectField>\n          <SchemaStringField\n            x-decorator=\"FormItem\"\n            title=\"AAA\"\n            name=\"aaa\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaStringField\n            x-decorator=\"FormItem\"\n            title=\"BBB\"\n            name=\"bbb\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaObjectField>\n      </SchemaArrayField>\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit @submit=\"log\">提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  Input,\n  Select,\n  ArrayTabs,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n    ArrayTabs,\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    FormButtonGroup,\n    Button,\n    Submit,\n    ...SchemaField,\n  },\n\n  data() {\n    const form = createForm()\n\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/cascader/json-schema.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField\n      :schema=\"schema\"\n      :scope=\"{ useAsyncDataSource, transformAddress }\"\n    />\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport { Form, FormItem, Cascader, Submit } from '@formily/element'\nimport { action } from '@formily/reactive'\nimport axios from 'axios'\n\nconst transformAddress = (data = {}) => {\n  return Object.entries(data).reduce((buf, [key, value]) => {\n    if (typeof value === 'string')\n      return buf.concat({\n        label: value,\n        value: key,\n      })\n    const { name, code, cities, districts } = value\n    const _cities = transformAddress(cities)\n    const _districts = transformAddress(districts)\n    return buf.concat({\n      label: name,\n      value: code,\n      children: _cities.length\n        ? _cities\n        : _districts.length\n        ? _districts\n        : undefined,\n    })\n  }, [])\n}\n\nconst useAsyncDataSource = (url, transform) => {\n  return (field) => {\n    field.loading = true\n    axios\n      .get(url)\n      .then((res) => res.data)\n      .then(\n        action.bound((data) => {\n          field.dataSource = transform(data)\n          field.loading = false\n        })\n      )\n  }\n}\n\nconst schema = {\n  type: 'object',\n  properties: {\n    cascader: {\n      type: 'string',\n      title: '地址选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'Cascader',\n      'x-component-props': {\n        style: {\n          width: '240px',\n        },\n      },\n      'x-reactions': [\n        '{{useAsyncDataSource(\"//unpkg.com/china-location/dist/location.json\",transformAddress)}}',\n      ],\n    },\n  },\n}\n\nconst form = createForm()\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    Cascader,\n  },\n})\n\nexport default {\n  components: { Form, SchemaField, Submit },\n  data() {\n    return {\n      useAsyncDataSource,\n      transformAddress,\n      form,\n      schema,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/cascader/markup-schema.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        name=\"address\"\n        title=\"地址选择\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Cascader\"\n        :x-component-props=\"{\n          style: {\n            width: '240px',\n          },\n        }\"\n      />\n    </SchemaField>\n\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm, onFieldReact } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport { Form, FormItem, Cascader, Submit } from '@formily/element'\nimport { action } from '@formily/reactive'\nimport axios from 'axios'\n\nconst transformAddress = (data = {}) => {\n  return Object.entries(data).reduce((buf, [key, value]) => {\n    if (typeof value === 'string')\n      return buf.concat({\n        label: value,\n        value: key,\n      })\n    const { name, code, cities, districts } = value\n    const _cities = transformAddress(cities)\n    const _districts = transformAddress(districts)\n    return buf.concat({\n      label: name,\n      value: code,\n      children: _cities.length\n        ? _cities\n        : _districts.length\n        ? _districts\n        : undefined,\n    })\n  }, [])\n}\n\nconst useAddress = (pattern) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    axios('//unpkg.com/china-location/dist/location.json')\n      .then((res) => res.data)\n      .then(\n        action.bound((data) => {\n          field.dataSource = transformAddress(data)\n          field.loading = false\n        })\n      )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAddress('address')\n  },\n})\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Cascader,\n  },\n})\n\nexport default {\n  components: { Form, ...fields, Submit },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/cascader/template.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <Field\n      name=\"address\"\n      title=\"地址选择\"\n      required\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        Cascader,\n        {\n          style: {\n            width: '240px',\n          },\n        },\n      ]\"\n    />\n\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm, onFieldReact } from '@formily/core'\nimport { Field } from '@formily/vue'\nimport { Form, FormItem, Cascader, Submit } from '@formily/element'\nimport { action } from '@formily/reactive'\nimport axios from 'axios'\n\nconst transformAddress = (data = {}) => {\n  return Object.entries(data).reduce((buf, [key, value]) => {\n    if (typeof value === 'string')\n      return buf.concat({\n        label: value,\n        value: key,\n      })\n    const { name, code, cities, districts } = value\n    const _cities = transformAddress(cities)\n    const _districts = transformAddress(districts)\n    return buf.concat({\n      label: name,\n      value: code,\n      children: _cities.length\n        ? _cities\n        : _districts.length\n        ? _districts\n        : undefined,\n    })\n  }, [])\n}\n\nconst useAddress = (pattern) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    axios('//unpkg.com/china-location/dist/location.json')\n      .then((res) => res.data)\n      .then(\n        action.bound((data) => {\n          field.dataSource = transformAddress(data)\n          field.loading = false\n        })\n      )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAddress('address')\n  },\n})\n\nexport default {\n  components: { Form, Field, Submit },\n  data() {\n    return {\n      FormItem,\n      Cascader,\n      form,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/checkbox/json-schema.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport { Form, FormItem, Checkbox, Submit } from '@formily/element'\n\nconst schema = {\n  type: 'object',\n  properties: {\n    checkbox: {\n      type: 'number',\n      title: '是否确认',\n      'x-decorator': 'FormItem',\n      'x-component': 'Checkbox',\n    },\n    checkboxGroup: {\n      type: 'array',\n      title: '复选',\n      'x-decorator': 'FormItem',\n      'x-component': 'Checkbox.Group',\n      enum: [\n        {\n          label: '选项1',\n          value: 1,\n        },\n        {\n          label: '选项2',\n          value: 2,\n        },\n      ],\n    },\n  },\n}\n\nconst form = createForm()\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    Checkbox,\n  },\n})\n\nexport default {\n  components: { Form, SchemaField, Submit },\n  data() {\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/checkbox/markup-schema.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField>\n      <SchemaBooleanField\n        name=\"single\"\n        title=\"是否确认\"\n        x-decorator=\"FormItem\"\n        x-component=\"Checkbox\"\n      />\n      <SchemaArrayField\n        name=\"multiple\"\n        title=\"复选\"\n        :enum=\"[\n          { label: '选项1', value: 1 },\n          { label: '选项2', value: 2 },\n        ]\"\n        x-decorator=\"FormItem\"\n        x-component=\"Checkbox.Group\"\n      />\n    </SchemaField>\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport { Form, FormItem, Checkbox, Submit } from '@formily/element'\n\nconst form = createForm()\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Checkbox,\n  },\n})\n\nexport default {\n  components: { Form, ...fields, Submit },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/checkbox/template.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <Field\n      name=\"single\"\n      title=\"是否确认\"\n      :decorator=\"[FormItem]\"\n      :component=\"[Checkbox]\"\n    />\n    <ArrayField\n      name=\"multiple\"\n      title=\"复选\"\n      :dataSource=\"[\n        { label: '选项1', value: 1 },\n        { label: '选项2', value: 2 },\n      ]\"\n      :decorator=\"[FormItem]\"\n      :component=\"[Checkbox.Group, { optionType: 'button' }]\"\n    >\n      <template v-slot:option=\"{ option }\">\n        <div>{{ option.label }}</div>\n      </template>\n    </ArrayField>\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { Field, ArrayField } from '@formily/vue'\nimport { Form, FormItem, Checkbox, Submit } from '@formily/element'\n\nconst form = createForm()\n\nexport default {\n  components: { Form, Field, ArrayField, Submit },\n  data() {\n    return {\n      FormItem,\n      Checkbox,\n      form,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/date-picker/json-schema.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport { Form, FormItem, DatePicker, Submit } from '@formily/element'\n\nconst schema = {\n  type: 'object',\n  properties: {\n    date: {\n      type: 'string',\n      title: '普通日期',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n    },\n    week: {\n      type: 'string',\n      title: '周',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      'x-component-props': {\n        type: 'week',\n      },\n    },\n    month: {\n      type: 'string',\n      title: '月',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      'x-component-props': {\n        type: 'month',\n      },\n    },\n    year: {\n      type: 'string',\n      title: '年',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      'x-component-props': {\n        type: 'year',\n      },\n    },\n    dateTime: {\n      type: 'string',\n      title: '日期时间',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      'x-component-props': {\n        type: 'datetime',\n      },\n    },\n    dates: {\n      type: 'array',\n      title: '多个日期',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      'x-component-props': {\n        type: 'dates',\n      },\n    },\n    dateRange: {\n      type: 'string',\n      title: '日期范围',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      'x-component-props': {\n        type: 'daterange',\n      },\n    },\n    monthRange: {\n      type: 'string',\n      title: '月范围',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      'x-component-props': {\n        type: 'monthrange',\n      },\n    },\n    dateTimeRange: {\n      type: 'string',\n      title: '日期时间范围',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      'x-component-props': {\n        type: 'datetimerange',\n      },\n    },\n  },\n}\n\nconst form = createForm()\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    DatePicker,\n  },\n})\n\nexport default {\n  components: { Form, SchemaField, Submit },\n  data() {\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/date-picker/markup-schema.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        name=\"date\"\n        title=\"普通日期\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n      />\n      <SchemaStringField\n        name=\"week\"\n        title=\"周\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n        :x-component-props=\"{\n          type: 'week',\n        }\"\n      />\n      <SchemaStringField\n        name=\"month\"\n        title=\"月\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n        :x-component-props=\"{\n          type: 'month',\n        }\"\n      />\n      <SchemaStringField\n        name=\"year\"\n        title=\"年\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n        :x-component-props=\"{\n          type: 'year',\n        }\"\n      />\n      <SchemaStringField\n        name=\"dateTime\"\n        title=\"日期时间\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n        :x-component-props=\"{\n          type: 'datetime',\n        }\"\n      />\n      <SchemaArrayField\n        name=\"dates\"\n        title=\"多个日期\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n        :x-component-props=\"{\n          type: 'dates',\n        }\"\n      />\n      <SchemaArrayField\n        name=\"dateRange\"\n        title=\"日期范围\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n        :x-component-props=\"{\n          type: 'daterange',\n        }\"\n      />\n      <SchemaArrayField\n        name=\"monthRange\"\n        title=\"月范围\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n        :x-component-props=\"{\n          type: 'monthrange',\n        }\"\n      />\n      <SchemaArrayField\n        name=\"dateTimeRange\"\n        title=\"日期时间范围\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n        :x-component-props=\"{\n          type: 'datetimerange',\n        }\"\n      />\n    </SchemaField>\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport { Form, FormItem, DatePicker, Submit } from '@formily/element'\n\nconst form = createForm()\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    DatePicker,\n  },\n})\n\nexport default {\n  components: { Form, ...fields, Submit },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>"
  },
  {
    "path": "packages/element/docs/demos/guide/date-picker/template.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <Field\n      name=\"date\"\n      title=\"普通日期\"\n      :decorator=\"[FormItem]\"\n      :component=\"[DatePicker]\"\n    />\n    <Field\n      name=\"week\"\n      title=\"周\"\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        DatePicker,\n        {\n          type: 'week',\n        },\n      ]\"\n    />\n    <Field\n      name=\"month\"\n      title=\"月\"\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        DatePicker,\n        {\n          type: 'month',\n        },\n      ]\"\n    />\n    <Field\n      name=\"year\"\n      title=\"年\"\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        DatePicker,\n        {\n          type: 'year',\n        },\n      ]\"\n    />\n    <Field\n      name=\"dateTime\"\n      title=\"日期时间\"\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        DatePicker,\n        {\n          type: 'datetime',\n        },\n      ]\"\n    />\n    <ArrayField\n      name=\"dates\"\n      title=\"多个日期\"\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        DatePicker,\n        {\n          type: 'dates',\n        },\n      ]\"\n    />\n    <ArrayField\n      name=\"dateRange\"\n      title=\"日期范围\"\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        DatePicker,\n        {\n          type: 'daterange',\n        },\n      ]\"\n    />\n    <ArrayField\n      name=\"monthRange\"\n      title=\"月范围\"\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        DatePicker,\n        {\n          type: 'monthrange',\n        },\n      ]\"\n    />\n    <ArrayField\n      name=\"dateTimeRange\"\n      title=\"日期时间范围\"\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        DatePicker,\n        {\n          type: 'datetimerange',\n        },\n      ]\"\n    />\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { Field, ArrayField } from '@formily/vue'\nimport { Form, FormItem, DatePicker, Submit } from '@formily/element'\n\nconst form = createForm()\n\nexport default {\n  components: { Form, Field, ArrayField, Submit },\n  data() {\n    return {\n      FormItem,\n      DatePicker,\n      form,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/editable/json-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <FormButtonGroup>\n      <Submit @submit=\"log\">提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormButtonGroup,\n  FormItem,\n  Submit,\n  Input,\n  DatePicker,\n  Editable,\n} from '@formily/element'\n\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    DatePicker,\n    Editable,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    date: {\n      type: 'string',\n      title: '日期',\n      'x-decorator': 'Editable',\n      'x-component': 'DatePicker',\n    },\n    input: {\n      type: 'string',\n      title: '输入框',\n      'x-decorator': 'Editable',\n      'x-component': 'Input',\n    },\n    void: {\n      type: 'void',\n      title: '虚拟节点容器',\n      'x-component': 'Editable.Popover',\n      'x-reactions':\n        \"{{(field) => field.title = field.query('.void.date2').get('value') || field.title}}\",\n      properties: {\n        date2: {\n          type: 'string',\n          title: '日期',\n          'x-decorator': 'FormItem',\n          'x-component': 'DatePicker',\n        },\n        input2: {\n          type: 'string',\n          title: '输入框',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n      },\n    },\n    iobject: {\n      type: 'object',\n      title: '对象节点容器',\n      'x-component': 'Editable.Popover',\n      'x-reactions':\n        '{{(field) => field.title = field.value && field.value.date || field.title}}',\n      properties: {\n        date: {\n          type: 'string',\n          title: '日期',\n          'x-decorator': 'FormItem',\n          'x-component': 'DatePicker',\n        },\n        input: {\n          type: 'string',\n          title: '输入框',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n      },\n    },\n  },\n}\n\nexport default {\n  components: {\n    FormButtonGroup,\n    FormProvider,\n    Submit,\n    SchemaField,\n  },\n\n  data() {\n    const form = createForm()\n\n    return {\n      schema,\n      form,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/editable/markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        name=\"date\"\n        title=\"日期\"\n        x-decorator=\"Editable\"\n        x-component=\"DatePicker\"\n      />\n      <SchemaStringField\n        name=\"input\"\n        title=\"输入框\"\n        x-decorator=\"Editable\"\n        x-component=\"Input\"\n      />\n      <SchemaVoidField\n        name=\"void\"\n        title=\"虚拟节点容器\"\n        x-component=\"Editable.Popover\"\n        :x-reactions=\"\n          (field) => {\n            field.title = field.query('.void.date2').get('value') || field.title\n          }\n        \"\n      >\n        <SchemaStringField\n          name=\"date2\"\n          title=\"日期\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n        />\n        <SchemaStringField\n          name=\"input2\"\n          title=\"输入框\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n      </SchemaVoidField>\n      <SchemaObjectField\n        name=\"object\"\n        title=\"对象节点容器\"\n        x-component=\"Editable.Popover\"\n        :x-reactions=\"\n          (field) => {\n            field.title = (field.value && field.value.date) || field.title\n          }\n        \"\n      >\n        <SchemaStringField\n          name=\"date\"\n          title=\"日期\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n        />\n        <SchemaStringField\n          name=\"input\"\n          title=\"输入框\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n      </SchemaObjectField>\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit @submit=\"log\">提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormButtonGroup,\n  FormItem,\n  Submit,\n  Input,\n  DatePicker,\n  Editable,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    DatePicker,\n    Editable,\n  },\n})\n\nexport default {\n  components: {\n    FormButtonGroup,\n    FormProvider,\n    Button,\n    Submit,\n    ...SchemaField,\n  },\n\n  data() {\n    const form = createForm()\n\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/editable/template.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Field\n      name=\"date\"\n      title=\"日期\"\n      :decorator=\"[Editable]\"\n      :component=\"[DatePicker]\"\n    />\n    <Field\n      name=\"input\"\n      title=\"输入框\"\n      :decorator=\"[Editable]\"\n      :component=\"[Input]\"\n    />\n    <VoidField\n      name=\"void\"\n      title=\"虚拟节点容器\"\n      :component=\"[Editable.Popover]\"\n      :reactions=\"\n        (field) => {\n          field.title = field.query('.void.date2').get('value') || field.title\n        }\n      \"\n    >\n      <Field\n        name=\"date2\"\n        title=\"日期\"\n        :decorator=\"[FormItem]\"\n        :component=\"[DatePicker]\"\n      />\n      <Field\n        name=\"input2\"\n        title=\"输入框\"\n        :decorator=\"[FormItem]\"\n        :component=\"[Input]\"\n      />\n    </VoidField>\n    <ObjectField\n      name=\"iobject\"\n      title=\"对象节点容器\"\n      :component=\"[Editable.Popover]\"\n      :reactions=\"\n        (field) => {\n          field.title = (field.value && field.value.date) || field.title\n        }\n      \"\n    >\n      <Field\n        name=\"date\"\n        title=\"日期\"\n        :decorator=\"[FormItem]\"\n        :component=\"[DatePicker]\"\n      />\n      <Field\n        name=\"input\"\n        title=\"输入框\"\n        :decorator=\"[FormItem]\"\n        :component=\"[Input]\"\n      />\n    </ObjectField>\n\n    <FormButtonGroup>\n      <Submit @submit=\"log\">提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, VoidField, ObjectField } from '@formily/vue'\nimport {\n  FormButtonGroup,\n  FormItem,\n  Submit,\n  Input,\n  DatePicker,\n  Editable,\n} from '@formily/element'\n\nexport default {\n  components: {\n    FormButtonGroup,\n    FormProvider,\n    Submit,\n    Field,\n    VoidField,\n    ObjectField,\n  },\n\n  data() {\n    const form = createForm()\n\n    return {\n      FormItem,\n      Input,\n      DatePicker,\n      Editable,\n      form,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-button-group.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <FormLayout :labelCol=\"6\" :wrapperCol=\"10\">\n      <SchemaField>\n        <SchemaStringField\n          required\n          title=\"输入框\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n        <SchemaStringField\n          required\n          title=\"输入框\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n      </SchemaField>\n      <FormButtonGroup align-form-item>\n        <Submit @submit=\"log\">提交</Submit>\n        <Reset>重置</Reset>\n      </FormButtonGroup>\n    </FormLayout>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormLayout,\n  Submit,\n  Reset,\n  FormButtonGroup,\n  FormItem,\n  Input,\n  Select,\n} from '@formily/element'\n\nconst fields = createSchemaField({ components: { FormItem, Input, Select } })\n\nexport default {\n  components: {\n    FormProvider,\n    FormLayout,\n    Submit,\n    Reset,\n    FormButtonGroup,\n    ...fields,\n  },\n  data() {\n    const form = createForm()\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(v) {\n      console.log(v)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-collapse/json-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <FormLayout :label-col=\"6\" :wrapper-col=\"10\">\n      <SchemaField :schema=\"schema\" :scope=\"{ formCollapse }\" />\n      <FormButtonGroup alignFormItem>\n        <Button\n          @click=\"\n            () => {\n              form.query('tab3').take((field) => {\n                field.visible = !field.visible\n              })\n            }\n          \"\n        >\n          显示/隐藏最后一个Tab\n        </Button>\n        <Button\n          @click=\"\n            () => {\n              formCollapse.toggleActiveKey('tab2')\n            }\n          \"\n        >\n          切换第二个Tab\n        </Button>\n        <Submit @submit=\"log\">提交</Submit>\n      </FormButtonGroup>\n    </FormLayout>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormItem,\n  FormCollapse,\n  FormButtonGroup,\n  Form,\n  FormLayout,\n  Submit,\n  Input,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    FormCollapse,\n    Input,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    collapse: {\n      type: 'void',\n      title: '折叠面板',\n      'x-decorator': 'FormItem',\n      'x-component': 'FormCollapse',\n      'x-component-props': {\n        formCollapse: '{{formCollapse}}',\n      },\n      properties: {\n        tab1: {\n          type: 'void',\n          'x-component': 'FormCollapse.Item',\n          'x-component-props': {\n            title: 'A1',\n          },\n          properties: {\n            aaa: {\n              type: 'string',\n              title: 'AAA',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        tab2: {\n          type: 'void',\n          'x-component': 'FormCollapse.Item',\n          'x-component-props': {\n            title: 'A2',\n          },\n          properties: {\n            bbb: {\n              type: 'string',\n              title: 'BBB',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        tab3: {\n          type: 'void',\n          'x-component': 'FormCollapse.Item',\n          'x-component-props': {\n            title: 'A3',\n          },\n          properties: {\n            ccc: {\n              type: 'string',\n              title: 'CCC',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default {\n  components: {\n    Form,\n    FormButtonGroup,\n    Button,\n    Submit,\n    SchemaField,\n    FormProvider,\n    FormLayout,\n  },\n\n  data() {\n    const form = createForm()\n    const formCollapse = FormCollapse.createFormCollapse()\n\n    return {\n      schema,\n      form,\n      formCollapse,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-collapse/markup-schema.vue",
    "content": "<template>\n  <Form :form=\"form\" :label-col=\"6\" :wrapper-col=\"10\">\n    <SchemaField>\n      <SchemaVoidField\n        type=\"void\"\n        title=\"折叠面板\"\n        x-decorator=\"FormItem\"\n        x-component=\"FormCollapse\"\n        :x-component-props=\"{ formCollapse }\"\n      >\n        <SchemaVoidField\n          type=\"void\"\n          name=\"tab1\"\n          x-component=\"FormCollapse.Item\"\n          :x-component-props=\"{ title: 'A1' }\"\n        >\n          <SchemaStringField\n            name=\"aaa\"\n            x-decorator=\"FormItem\"\n            title=\"AAA\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaVoidField>\n        <SchemaVoidField\n          name=\"tab2\"\n          x-component=\"FormCollapse.Item\"\n          :x-component-props=\"{ title: 'A2' }\"\n        >\n          <SchemaStringField\n            name=\"bbb\"\n            x-decorator=\"FormItem\"\n            title=\"BBB\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaVoidField>\n        <SchemaVoidField\n          name=\"tab3\"\n          x-component=\"FormCollapse.Item\"\n          :x-component-props=\"{ title: 'A3' }\"\n        >\n          <SchemaStringField\n            name=\"ccc\"\n            x-decorator=\"FormItem\"\n            title=\"CCC\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaVoidField>\n      </SchemaVoidField>\n    </SchemaField>\n    <FormButtonGroup alignFormItem>\n      <Button\n        @click=\"\n          () => {\n            form.query('tab3').take((field) => {\n              field.visible = !field.visible\n            })\n          }\n        \"\n      >\n        显示/隐藏最后一个Tab\n      </Button>\n      <Button\n        @click=\"\n          () => {\n            formCollapse.toggleActiveKey('tab2')\n          }\n        \"\n      >\n        切换第二个Tab\n      </Button>\n      <Submit @submit=\"log\">提交</Submit>\n    </FormButtonGroup>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport {\n  FormItem,\n  FormCollapse,\n  FormButtonGroup,\n  Submit,\n  Input,\n  Form,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormCollapse,\n    Input,\n  },\n})\n\nexport default {\n  components: {\n    Form,\n    FormButtonGroup,\n    Button,\n    Submit,\n    ...SchemaField,\n  },\n\n  data() {\n    const form = createForm()\n    const formCollapse = FormCollapse.createFormCollapse()\n\n    return {\n      form,\n      formCollapse,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-dialog/json-schema.vue",
    "content": "<template>\n  <Button @click=\"handleOpen\">点击打开表单</Button>\n</template>\n\n<script>\nimport { FormDialog, FormLayout, FormItem, Input } from '@formily/element'\nimport { Button } from 'element-ui'\nimport { createSchemaField } from '@formily/vue'\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\n// 弹框表单组件\nconst DialogForm = {\n  data() {\n    const schema = {\n      type: 'object',\n      properties: {\n        aaa: {\n          type: 'string',\n          title: '输入框1',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        bbb: {\n          type: 'string',\n          title: '输入框2',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ccc: {\n          type: 'string',\n          title: '输入框3',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ddd: {\n          type: 'string',\n          title: '输入框4',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n      },\n    }\n    return {\n      schema,\n    }\n  },\n  render(h) {\n    return (\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField schema={this.schema} />\n        <FormDialog.Footer>\n          <span style={{ marginLeft: '4px' }}>扩展文案</span>\n        </FormDialog.Footer>\n      </FormLayout>\n    )\n  },\n}\n\nexport default {\n  components: { Button },\n  data() {\n    return {}\n  },\n  methods: {\n    handleOpen() {\n      FormDialog('弹框表单', DialogForm)\n        .forOpen((payload, next) => {\n          setTimeout(() => {\n            next({\n              initialValues: {\n                aaa: '123',\n              },\n            })\n          }, 1000)\n        })\n        .forConfirm((payload, next) => {\n          setTimeout(() => {\n            console.log(payload)\n            next(payload)\n          }, 1000)\n        })\n        .forCancel((payload, next) => {\n          setTimeout(() => {\n            console.log(payload)\n            next(payload)\n          }, 1000)\n        })\n        .open()\n        .then(console.log)\n        .catch(console.error)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-dialog/markup-schema.vue",
    "content": "<template>\n  <FormDialogPortal :id=\"portalId\">\n    <Button @click=\"handleOpen\">点击打开表单</Button>\n  </FormDialogPortal>\n</template>\n\n<script>\nimport { FormDialog, FormLayout, FormItem, Input } from '@formily/element'\nimport { Button } from 'element-ui'\nimport { createSchemaField } from '@formily/vue'\n\nconst { SchemaField, SchemaStringField } = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\n// 弹框表单组件\nconst DialogForm = {\n  props: ['form'],\n  inject: ['foo'],\n  render() {\n    const form = this.form\n    console.log(this.foo)\n    return (\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField>\n          <SchemaStringField\n            name=\"aaa\"\n            required\n            title=\"输入框1\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaStringField\n            name=\"bbb\"\n            required\n            title=\"输入框2\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaStringField\n            name=\"ccc\"\n            required\n            title=\"输入框3\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaStringField\n            name=\"ddd\"\n            required\n            title=\"输入框4\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n        </SchemaField>\n        <FormDialog.Footer>\n          <span style={{ marginLeft: '4px' }}>扩展文案: {form.values.aaa}</span>\n        </FormDialog.Footer>\n      </FormLayout>\n    )\n  },\n}\n\nexport default {\n  components: { Button, FormDialogPortal: FormDialog.Portal },\n  data() {\n    return {\n      portalId: '可以传，也可以不传的ID，默认是form-dialog',\n    }\n  },\n  provide: {\n    foo: '自定义上下文可以直接传到弹窗内部，只需要ID一致即可',\n  },\n  methods: {\n    handleOpen() {\n      FormDialog('弹框表单', this.portalId, DialogForm)\n        .forOpen((payload, next) => {\n          setTimeout(() => {\n            next({\n              initialValues: {\n                aaa: '123',\n              },\n            })\n          }, 1000)\n        })\n        .forConfirm((payload, next) => {\n          setTimeout(() => {\n            console.log(payload)\n            next(payload)\n          }, 1000)\n        })\n        .forCancel((payload, next) => {\n          setTimeout(() => {\n            console.log(payload)\n            next(payload)\n          }, 1000)\n        })\n        .open()\n        .then(console.log)\n        .catch(console.error)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-dialog/template.vue",
    "content": "<template>\n  <Button @click=\"handleOpen\">点击打开表单</Button>\n</template>\n\n<script>\nimport { FormDialog, FormLayout, FormItem, Input } from '@formily/element'\nimport { Button } from 'element-ui'\nimport { Field } from '@formily/vue'\n\nexport default {\n  components: { Button },\n  data() {\n    return {}\n  },\n  methods: {\n    handleOpen() {\n      FormDialog('弹框表单', () => (\n        <FormLayout labelCol={6} wrapperCol={10}>\n          <Field\n            name=\"aaa\"\n            required\n            title=\"输入框1\"\n            decorator={[FormItem]}\n            component={[Input]}\n          />\n          <Field\n            name=\"bbb\"\n            required\n            title=\"输入框2\"\n            decorator={[FormItem]}\n            component={[Input]}\n          />\n          <Field\n            name=\"ccc\"\n            required\n            title=\"输入框3\"\n            decorator={[FormItem]}\n            component={[Input]}\n          />\n          <Field\n            name=\"ddd\"\n            required\n            title=\"输入框4\"\n            decorator={[FormItem]}\n            component={[Input]}\n          />\n          <FormDialog.Footer>\n            <span style={{ marginLeft: '4px' }}>扩展文案</span>\n          </FormDialog.Footer>\n        </FormLayout>\n      ))\n        .forOpen((payload, next) => {\n          setTimeout(() => {\n            next({\n              initialValues: {\n                aaa: '123',\n              },\n            })\n          }, 1000)\n        })\n        .forConfirm((payload, next) => {\n          setTimeout(() => {\n            console.log(payload)\n            next(payload)\n          }, 1000)\n        })\n        .forCancel((payload, next) => {\n          setTimeout(() => {\n            console.log(payload)\n            next(payload)\n          }, 1000)\n        })\n        .open()\n        .then(console.log)\n        .catch(console.error)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-drawer/json-schema.vue",
    "content": "<template>\n  <Button @click=\"handleOpen\">点击打开表单</Button>\n</template>\n\n<script>\nimport { FormDrawer, FormLayout, FormItem, Input } from '@formily/element'\nimport { Button } from 'element-ui'\nimport { createSchemaField } from '@formily/vue'\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\n// 抽屉表单组件\nconst DrawerForm = {\n  data() {\n    const schema = {\n      type: 'object',\n      properties: {\n        aaa: {\n          type: 'string',\n          title: '输入框1',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        bbb: {\n          type: 'string',\n          title: '输入框2',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ccc: {\n          type: 'string',\n          title: '输入框3',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ddd: {\n          type: 'string',\n          title: '输入框4',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n      },\n    }\n    return {\n      schema,\n    }\n  },\n  render(h) {\n    return (\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField schema={this.schema} />\n        <FormDrawer.Footer>\n          <span style={{ marginLeft: '4px' }}>扩展文案</span>\n        </FormDrawer.Footer>\n      </FormLayout>\n    )\n  },\n}\n\nexport default {\n  components: { Button },\n  data() {\n    return {}\n  },\n  methods: {\n    handleOpen() {\n      FormDrawer('抽屉表单', DrawerForm)\n        .open({\n          initialValues: {\n            aaa: '123',\n          },\n        })\n        .then((values) => {\n          console.log('values', values)\n        })\n        .catch((e) => {\n          console.log(e)\n        })\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-drawer/markup-schema.vue",
    "content": "<template>\n  <Button @click=\"handleOpen\">点击打开表单</Button>\n</template>\n\n<script>\nimport { FormDrawer, FormLayout, FormItem, Input } from '@formily/element'\nimport { Button } from 'element-ui'\nimport { createSchemaField } from '@formily/vue'\n\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\n// 抽屉表单组件\nconst DrawerForm = {\n  props: ['form'],\n  data() {\n    const schema = {\n      type: 'object',\n      properties: {\n        aaa: {\n          type: 'string',\n          title: '输入框1',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        bbb: {\n          type: 'string',\n          title: '输入框2',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ccc: {\n          type: 'string',\n          title: '输入框3',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ddd: {\n          type: 'string',\n          title: '输入框4',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n      },\n    }\n    return {\n      schema,\n    }\n  },\n  render() {\n    return (\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField schema={this.schema} />\n        <FormDrawer.Footer>\n          <span style={{ marginLeft: '4px' }}>扩展文案</span>\n        </FormDrawer.Footer>\n      </FormLayout>\n    )\n  },\n}\n\nexport default {\n  components: { Button },\n  data() {\n    return {}\n  },\n  methods: {\n    handleOpen() {\n      FormDrawer('抽屉表单', DrawerForm)\n        .forOpen((props, next) => {\n          setTimeout(() => {\n            next()\n          }, 1000)\n        })\n        .open({\n          initialValues: {\n            aaa: '123',\n          },\n        })\n        .then(console.log)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-drawer/template.vue",
    "content": "<template>\n  <Button @click=\"handleOpen\">点击打开表单</Button>\n</template>\n\n<script>\nimport { FormDrawer, FormLayout, FormItem, Input } from '@formily/element'\nimport { Button } from 'element-ui'\nimport { Field } from '@formily/vue'\n\nexport default {\n  components: { Button },\n  data() {\n    return {}\n  },\n  methods: {\n    handleOpen() {\n      FormDrawer('抽屉表单', () => (\n        <FormLayout labelCol={6} wrapperCol={10}>\n          <Field\n            name=\"aaa\"\n            required\n            title=\"输入框1\"\n            decorator={[FormItem]}\n            component={[Input]}\n          />\n          <Field\n            name=\"bbb\"\n            required\n            title=\"输入框2\"\n            decorator={[FormItem]}\n            component={[Input]}\n          />\n          <Field\n            name=\"ccc\"\n            required\n            title=\"输入框3\"\n            decorator={[FormItem]}\n            component={[Input]}\n          />\n          <Field\n            name=\"ddd\"\n            required\n            title=\"输入框4\"\n            decorator={[FormItem]}\n            component={[Input]}\n          />\n          <FormDrawer.Footer>\n            <span style={{ marginLeft: '4px' }}>扩展文案</span>\n          </FormDrawer.Footer>\n        </FormLayout>\n      ))\n        .open({\n          initialValues: {\n            aaa: '123',\n          },\n        })\n        .then((values) => {\n          console.log('values', values)\n        })\n        .catch((e) => {\n          console.log(e)\n        })\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-grid/form.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaObjectField x-component=\"QueryForm\">\n        <SchemaStringField\n          name=\"input1\"\n          title=\"Input 1\"\n          x-component=\"Input\"\n          x-decorator=\"FormItem\"\n        />\n        <SchemaStringField\n          name=\"input2\"\n          title=\"Input 2\"\n          x-component=\"Input\"\n          x-decorator=\"FormItem\"\n        />\n\n        <SchemaStringField\n          name=\"select1\"\n          title=\"Select 1\"\n          x-component=\"Select\"\n          x-decorator=\"FormItem\"\n        />\n        <SchemaStringField\n          name=\"select2\"\n          title=\"Select 2\"\n          x-component=\"Select\"\n          x-decorator=\"FormItem\"\n        />\n        <SchemaStringField\n          name=\"date\"\n          title=\"DatePicker\"\n          x-component=\"DatePicker\"\n          x-decorator=\"FormItem\"\n        />\n        <SchemaStringField\n          name=\"dateRange\"\n          title=\"DatePicker\"\n          x-component=\"DatePicker\"\n          x-decorator=\"FormItem\"\n          :x-decorator-props=\"{\n            gridSpan: 2,\n          }\"\n          :x-component-props=\"{\n            type: 'daterange',\n          }\"\n        />\n        <SchemaStringField\n          name=\"select3\"\n          title=\"Select 3\"\n          x-component=\"Select\"\n          x-decorator=\"FormItem\"\n        />\n      </SchemaObjectField>\n    </SchemaField>\n  </FormProvider>\n</template>\n\n<script>\nimport { defineComponent, ref, onUnmounted } from 'vue-demi'\nimport { createForm } from '@formily/core'\nimport {\n  createSchemaField,\n  FormProvider,\n  FragmentComponent,\n} from '@formily/vue'\nimport { autorun } from '@formily/reactive'\nimport { observer } from '@formily/reactive-vue'\nimport {\n  Form,\n  Input,\n  Select,\n  DatePicker,\n  FormItem,\n  FormGrid,\n  Submit,\n  Reset,\n  FormButtonGroup,\n} from '@formily/element'\n\nconst useCollapseGrid = (maxRows) => {\n  const grid = FormGrid.createFormGrid({\n    maxColumns: 4,\n    maxWidth: 240,\n    maxRows: maxRows,\n    shouldVisible: (node, grid) => {\n      if (node.index === grid.childSize - 1) return true\n      if (grid.maxRows === Infinity) return true\n      return node.shadowRow < maxRows + 1\n    },\n  })\n\n  const expanded = ref(false)\n  const type = ref('')\n\n  const takeType = (realRows, computeRows) => {\n    if (realRows < maxRows + 1) return 'incomplete-wrap'\n    if (computeRows > maxRows) return 'collapsible'\n    return 'complete-wrap'\n  }\n\n  const dispose = autorun(() => {\n    expanded.value = grid.maxRows === Infinity\n\n    const realRows = grid.shadowRows\n    const computeRows = grid.fullnessLastColumn\n      ? grid.shadowRows - 1\n      : grid.shadowRows\n\n    type.value = takeType(realRows, computeRows)\n  })\n\n  onUnmounted(dispose)\n\n  const toggle = () => {\n    if (grid.maxRows === Infinity) {\n      grid.maxRows = maxRows\n    } else {\n      grid.maxRows = Infinity\n    }\n  }\n  return {\n    grid,\n    expanded,\n    toggle,\n    type,\n  }\n}\n\nconst QueryForm = observer(\n  defineComponent({\n    setup(props, { slots }) {\n      const { grid, expanded, toggle, type } = useCollapseGrid(1)\n\n      const renderActions = () => {\n        return (\n          <FragmentComponent>\n            <Submit onSubmit={console.log}>查询</Submit>\n            <Reset>重置</Reset>\n          </FragmentComponent>\n        )\n      }\n\n      const renderButtonGroup = () => {\n        if (type.value === 'incomplete-wrap') {\n          return (\n            <FormButtonGroup.FormItem>\n              <FormButtonGroup>{renderActions()}</FormButtonGroup>\n            </FormButtonGroup.FormItem>\n          )\n        }\n        if (type.value === 'collapsible') {\n          return (\n            <FragmentComponent>\n              <FormButtonGroup>\n                <a\n                  href=\"\"\n                  onClick={(e) => {\n                    e.preventDefault()\n                    toggle()\n                  }}\n                >\n                  {expanded.value ? '收起' : '展开'}\n                </a>\n              </FormButtonGroup>\n              <FormButtonGroup align=\"right\">{renderActions()}</FormButtonGroup>\n            </FragmentComponent>\n          )\n        }\n        return (\n          <FormButtonGroup\n            align=\"right\"\n            style={{ display: 'flex', width: '100%' }}\n          >\n            {renderActions()}\n          </FormButtonGroup>\n        )\n      }\n\n      return () => {\n        return (\n          <Form {...props} layout=\"vertical\" feedbackLayout=\"terse\">\n            <FormGrid grid={grid}>\n              {slots.default()}\n              <FormGrid.GridColumn\n                gridSpan={-1}\n                style={{ display: 'flex', justifyContent: 'space-between' }}\n              >\n                {renderButtonGroup()}\n              </FormGrid.GridColumn>\n            </FormGrid>\n          </Form>\n        )\n      }\n    },\n  })\n)\n\nconst form = createForm()\nconst fields = createSchemaField({\n  components: {\n    QueryForm,\n    Input,\n    Select,\n    DatePicker,\n    FormItem,\n  },\n})\n\nexport default {\n  components: { FormProvider, ...fields, Submit },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-grid/json-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider } from '@formily/vue'\nimport { FormItem, Input, Submit, FormGrid } from '@formily/element'\n\nconst schema = {\n  type: 'object',\n  properties: {\n    grid: {\n      type: 'void',\n      'x-component': 'FormGrid',\n      'x-component-props': {\n        minColumns: [4, 6, 10],\n      },\n      properties: {\n        aaa: {\n          type: 'string',\n          title: 'AAA',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        bbb: {\n          type: 'string',\n          title: 'BBB',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ccc: {\n          type: 'string',\n          title: 'CCC',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ddd: {\n          type: 'string',\n          title: 'DDD',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        eee: {\n          type: 'string',\n          title: 'EEE',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        fff: {\n          type: 'string',\n          title: 'FFF',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ggg: {\n          type: 'string',\n          title: 'GGG',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n      },\n    },\n  },\n}\n\nconst form = createForm()\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    FormGrid,\n  },\n})\n\nexport default {\n  components: { FormProvider, SchemaField, Submit },\n  data() {\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-grid/markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaVoidField\n        x-component=\"FormGrid\"\n        :x-component-props=\"{\n          maxColumns: 3,\n          minColumns: 2,\n        }\"\n      >\n        <SchemaStringField\n          name=\"aaa\"\n          title=\"aaa\"\n          x-decorator=\"FormItem\"\n          :x-decorator-props=\"{ gridSpan: 2 }\"\n          x-component=\"Input\"\n        />\n        <SchemaStringField\n          name=\"bbb\"\n          title=\"bbb\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n        <SchemaStringField\n          name=\"ccc\"\n          title=\"ccc\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n        <SchemaStringField\n          name=\"ddd\"\n          title=\"ddd\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n        <SchemaStringField\n          name=\"eee\"\n          title=\"eee\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n        <SchemaStringField\n          name=\"fff\"\n          title=\"fff\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n        <SchemaStringField\n          name=\"ggg\"\n          title=\"ggg\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n      </SchemaVoidField>\n    </SchemaField>\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider } from '@formily/vue'\nimport { FormItem, Input, Submit, FormGrid } from '@formily/element'\n\nconst form = createForm()\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    FormGrid,\n  },\n})\n\nexport default {\n  components: { FormProvider, ...fields, Submit },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-grid/native.vue",
    "content": "<template>\n  <div>\n    <p>maxColumns 3 + minColumns 2</p>\n    <FormGrid :maxColumns=\"3\" :minColumns=\"2\" :columnGap=\"4\">\n      <FormGridColumn :gridSpan=\"4\">\n        <Cell>1</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>2</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>3</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>4</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>5</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>6</Cell>\n      </FormGridColumn>\n    </FormGrid>\n    <p>maxColumns 3</p>\n    <FormGrid :maxColumns=\"3\" :columnGap=\"4\">\n      <FormGridColumn :gridSpan=\"2\">\n        <Cell>1</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>2</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>3</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>4</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>5</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>6</Cell>\n      </FormGridColumn>\n    </FormGrid>\n    <p>minColumns 2</p>\n    <FormGrid :minColumns=\"2\" :columnGap=\"4\">\n      <FormGridColumn :gridSpan=\"2\">\n        <Cell>1</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>2</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>3</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>4</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>5</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>6</Cell>\n      </FormGridColumn>\n    </FormGrid>\n    <p>Null</p>\n    <FormGrid :columnGap=\"4\">\n      <FormGridColumn :gridSpan=\"2\">\n        <Cell>1</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>2</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>3</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>4</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>5</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>6</Cell>\n      </FormGridColumn>\n    </FormGrid>\n    <p>minWidth 150 +maxColumns 3</p>\n    <FormGrid :minWidth=\"150\" :maxColumns=\"3\" :columnGap=\"4\">\n      <FormGridColumn :gridSpan=\"2\">\n        <Cell>1</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>2</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>3</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>4</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>5</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>6</Cell>\n      </FormGridColumn>\n    </FormGrid>\n    <p>maxWidth 120+minColumns 2</p>\n    <FormGrid :maxWidth=\"120\" :minColumns=\"2\" :columnGap=\"4\">\n      <FormGridColumn :gridSpan=\"2\">\n        <Cell>1</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>2</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>3</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>4</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>5</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>6</Cell>\n      </FormGridColumn>\n    </FormGrid>\n    <p>maxWidth 120 + gridSpan -1</p>\n    <FormGrid :maxWidth=\"120\" :columnGap=\"4\">\n      <FormGridColumn :gridSpan=\"2\">\n        <Cell>1</Cell>\n      </FormGridColumn>\n      <FormGridColumn>\n        <Cell>2</Cell>\n      </FormGridColumn>\n      <FormGridColumn :gridSpan=\"-1\">\n        <Cell>3</Cell>\n      </FormGridColumn>\n    </FormGrid>\n  </div>\n</template>\n\n<script>\nimport { FormGrid } from '@formily/element'\n\nconst Cell = {\n  functional: true,\n  render(h, context) {\n    return h(\n      'div',\n      {\n        style: {\n          backgroundColor: '#AAA',\n          color: '#FFF',\n          height: '30px',\n          display: 'flex',\n          alignItems: 'center',\n          padding: '0 10px',\n        },\n      },\n      context.children\n    )\n  },\n}\n\nexport default {\n  components: { FormGrid, FormGridColumn: FormGrid.GridColumn, Cell },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-item/bordered-none.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        name=\"input\"\n        title=\"Input\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        required\n        :x-decorator-props=\"{\n          bordered: false,\n        }\"\n      />\n      <SchemaStringField\n        name=\"Select\"\n        title=\"Select\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        required\n        :x-decorator-props=\"{\n          bordered: false,\n        }\"\n      />\n      <SchemaStringField\n        name=\"Cascader\"\n        title=\"Cascader\"\n        x-decorator=\"FormItem\"\n        x-component=\"Cascader\"\n        required\n        :x-decorator-props=\"{\n          bordered: false,\n        }\"\n      />\n      <SchemaStringField\n        name=\"DatePicker\"\n        title=\"DatePicker\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n        required\n        :x-decorator-props=\"{\n          bordered: false,\n        }\"\n      />\n      <SchemaStringField\n        name=\"InputNumber\"\n        title=\"InputNumber\"\n        x-decorator=\"FormItem\"\n        x-component=\"InputNumber\"\n        required\n        :x-decorator-props=\"{\n          bordered: false,\n        }\"\n      />\n      <SchemaBooleanField\n        name=\"Switch\"\n        title=\"Switch\"\n        x-decorator=\"FormItem\"\n        x-component=\"Switch\"\n        required\n        :x-decorator-props=\"{\n          bordered: false,\n        }\"\n      />\n    </SchemaField>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport {\n  Form,\n  FormItem,\n  Input,\n  Select,\n  Cascader,\n  DatePicker,\n  Switch,\n  InputNumber,\n} from '@formily/element'\n\nconst form = createForm()\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n    Cascader,\n    DatePicker,\n    Switch,\n    InputNumber,\n  },\n})\n\nexport default {\n  components: { Form, ...fields },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-item/common.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaVoidField x-component=\"Title\" x-content=\"label为空时的展示: \" />\n      <SchemaStringField\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          labelWidth: 300,\n        }\"\n      />\n      <SchemaStringField\n        title=\"\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          labelWidth: 300,\n        }\"\n      />\n      <SchemaVoidField x-component=\"Title\" x-content=\"冒号: \" />\n      <SchemaStringField\n        title=\"默认\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaStringField\n        title=\"无冒号(colon=false)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          colon: false,\n        }\"\n      />\n      <SchemaVoidField x-component=\"Title\" x-content=\"固定宽度设置: \" />\n      <SchemaStringField\n        title=\"固定label宽度(labelWidth)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          labelWidth: 300,\n        }\"\n      />\n      <SchemaStringField\n        title=\"固定label宽度(labelWidth)溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出\"\n        description=\"描述描述\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          labelWidth: 300,\n          tooltip: '提示提示',\n        }\"\n      />\n      <SchemaStringField\n        title=\"固定label宽度(labelWidth)换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行\"\n        description=\"描述描述\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          labelWidth: 300,\n          labelWrap: true,\n          tooltip: '提示提示',\n        }\"\n      />\n      <SchemaStringField\n        title=\"固定内容宽度(wrapperWidth)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          labelWidth: 300,\n          wrapperWidth: 300,\n        }\"\n      />\n      <SchemaVoidField x-component=\"Title\" x-content=\"对齐方式设置:\" />\n      <SchemaStringField\n        title=\"label左对齐(labelAlign=left)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          labelWidth: 300,\n          labelAlign: 'left',\n        }\"\n      />\n      <SchemaStringField\n        title=\"label右对齐(labelAlign=right默认)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          labelWidth: 300,\n          labelAlign: 'right',\n        }\"\n      />\n      <SchemaStringField\n        title=\"内容左对齐(wrapperAlign=left默认)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          labelWidth: 300,\n          wrapperWidth: 240,\n          wrapperAlign: 'left',\n        }\"\n      />\n      <SchemaStringField\n        title=\"内容右对齐(wrapperAlign=right)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          labelWidth: 300,\n          wrapperWidth: 240,\n          wrapperAlign: 'right',\n        }\"\n      />\n      <SchemaStringField\n        title=\"tooltip\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          tooltip: 'tooltip',\n        }\"\n      />\n      <SchemaStringField\n        title=\"tooltip\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          tooltip: 'tooltip',\n          tooltipLayout: 'text',\n        }\"\n      />\n      <SchemaVoidField x-component=\"Title\" x-content=\"是否撑满: \" />\n      <SchemaStringField\n        title=\"默认不撑满(fullness=false)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n      />\n      <SchemaStringField\n        title=\"撑满(fullness=true)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        :x-decorator-props=\"{\n          fullness: true,\n        }\"\n      />\n      <SchemaVoidField x-component=\"Title\" x-content=\"辅助信息: \" />\n      <SchemaStringField\n        title=\"必填星号\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          asterisk: true,\n          labelCol: 6,\n          wrapperCol: 10,\n        }\"\n      />\n      <SchemaStringField\n        title=\"前缀\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          addonBefore: 'addonBefore',\n          labelCol: 6,\n          wrapperCol: 10,\n        }\"\n      />\n      <SchemaStringField\n        title=\"后缀\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          addonAfter: 'addonAfter',\n          labelCol: 6,\n          wrapperCol: 10,\n        }\"\n      />\n      <SchemaStringField\n        title=\"帮助信息feedbackText\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          feedbackText: 'feedbackText',\n          labelCol: 6,\n          wrapperCol: 10,\n        }\"\n      />\n      <SchemaStringField\n        title=\"额外信息extra\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          feedbackText: 'feedbackText',\n          extra: 'extra',\n          labelCol: 6,\n          wrapperCol: 10,\n        }\"\n      />\n      <SchemaVoidField x-component=\"Title\" x-content=\"表单状态: \" />\n      <SchemaStringField\n        title=\"错误状态(feedbackStatus=error)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        description=\"description\"\n        :x-decorator-props=\"{\n          feedbackStatus: 'error',\n        }\"\n      />\n      <SchemaStringField\n        title=\"警告状态(feedbackStatus=warning)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        description=\"description\"\n        :x-decorator-props=\"{\n          feedbackStatus: 'warning',\n        }\"\n      />\n      <SchemaStringField\n        title=\"成功状态(feedbackStatus=success)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        description=\"description\"\n        :x-decorator-props=\"{\n          feedbackStatus: 'success',\n        }\"\n      />\n      <SchemaStringField\n        title=\"加载状态(feedbackStatus=pending)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        description=\"description\"\n        :x-decorator-props=\"{\n          feedbackStatus: 'pending',\n        }\"\n      />\n      <SchemaVoidField x-component=\"Title\" x-content=\"反馈信息的布局: \" />\n      <SchemaStringField\n        title=\"紧凑模式required\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :required=\"true\"\n        :x-decorator-props=\"{\n          feedbackLayout: 'terse',\n        }\"\n      />\n      <SchemaStringField\n        title=\"紧凑模式有feedback(feedbackLayout=terse)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          feedbackStatus: 'error',\n          feedbackText: 'error message',\n          feedbackLayout: 'terse',\n        }\"\n      />\n      <SchemaStringField\n        title=\"紧凑模式无feedback(feedbackLayout=terse)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          feedbackLayout: 'terse',\n        }\"\n      />\n      <SchemaStringField\n        title=\"松散模式(feedbackLayout=loose)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          feedbackStatus: 'error',\n          feedbackText: 'error message',\n          feedbackLayout: 'loose',\n        }\"\n      />\n      <SchemaStringField\n        title=\"弹出模式(feedbackLayout=popover)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          feedbackStatus: 'warning',\n          feedbackText: 'warning message',\n          feedbackLayout: 'popover',\n        }\"\n      />\n      <SchemaStringField\n        title=\"弹出模式(feedbackLayout=popover)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          feedbackStatus: 'error',\n          feedbackText: 'error message',\n          feedbackLayout: 'popover',\n        }\"\n      />\n      <SchemaStringField\n        title=\"弹出模式(feedbackLayout=popover)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          feedbackStatus: 'success',\n          feedbackText: 'success message',\n          feedbackLayout: 'popover',\n        }\"\n      />\n      <SchemaVoidField x-component=\"Title\" x-content=\"组件的适配情况: \" />\n      <SchemaVoidField\n        x-component=\"FormLayout\"\n        :x-component-props=\"{\n          labelCol: 6,\n          wrapperCol: 10,\n        }\"\n      >\n        <SchemaStringField\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          :x-decorator-props=\"{\n            feedbackStatus: 'success',\n            feedbackIcon: SuccessIcon,\n          }\"\n        />\n        <SchemaStringField\n          title=\"DatePicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          :x-decorator-props=\"{\n            feedbackStatus: 'success',\n            feedbackIcon: SuccessIcon,\n          }\"\n        />\n        <SchemaStringField\n          title=\"DateRangePicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          :x-decorator-props=\"{\n            feedbackStatus: 'success',\n            feedbackIcon: SuccessIcon,\n          }\"\n          :x-component-props=\"{\n            type: 'daterange',\n          }\"\n        />\n        <SchemaStringField\n          title=\"YearPicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          :x-decorator-props=\"{\n            feedbackStatus: 'success',\n            feedbackIcon: SuccessIcon,\n          }\"\n          :x-component-props=\"{\n            type: 'year',\n          }\"\n        />\n        <SchemaStringField\n          title=\"MonthPicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          :x-decorator-props=\"{\n            feedbackStatus: 'success',\n            feedbackIcon: SuccessIcon,\n          }\"\n          :x-component-props=\"{\n            type: 'month',\n          }\"\n        />\n        <SchemaStringField\n          title=\"TimePicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"TimePicker\"\n          :x-decorator-props=\"{\n            feedbackStatus: 'success',\n            feedbackIcon: SuccessIcon,\n          }\"\n        />\n        <SchemaStringField\n          title=\"InputNumber\"\n          x-decorator=\"FormItem\"\n          x-component=\"InputNumber\"\n          :x-decorator-props=\"{\n            feedbackStatus: 'success',\n            feedbackIcon: SuccessIcon,\n          }\"\n        />\n        <SchemaStringField\n          title=\"Cascader\"\n          x-decorator=\"FormItem\"\n          x-component=\"Cascader\"\n          :x-decorator-props=\"{\n            feedbackStatus: 'success',\n            feedbackIcon: SuccessIcon,\n          }\"\n        />\n      </SchemaVoidField>\n    </SchemaField>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider } from '@formily/vue'\nimport {\n  FormItem,\n  InputNumber,\n  Input,\n  Cascader,\n  Select,\n  DatePicker,\n  FormLayout,\n  TimePicker,\n} from '@formily/element'\n\nconst SuccessIcon = {\n  functional: true,\n  render(h) {\n    return h('i', {\n      class: 'el-icon-circle-check',\n      style: { color: '#8AE65C' },\n    })\n  },\n}\n\nconst Title = {\n  functional: true,\n  render(h, context) {\n    return h('p', context.data, context.children)\n  },\n}\n\nconst fields = createSchemaField({\n  components: {\n    Title,\n    FormItem,\n    InputNumber,\n    Input,\n    Cascader,\n    Select,\n    DatePicker,\n    FormLayout,\n    TimePicker,\n  },\n})\n\nexport default {\n  components: { FormProvider, ...fields },\n  data() {\n    const form = createForm()\n    return {\n      form,\n      SuccessIcon,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-item/feedback.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaVoidField x-component=\"Title\" x-content=\"表单状态: \" />\n      <SchemaStringField\n        title=\"错误状态(feedbackStatus=error)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        description=\"description\"\n        :x-decorator-props=\"{\n          feedbackStatus: 'error',\n        }\"\n      />\n      <SchemaStringField\n        title=\"警告状态(feedbackStatus=warning)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        description=\"description\"\n        :x-decorator-props=\"{\n          feedbackStatus: 'warning',\n        }\"\n      />\n      <SchemaStringField\n        title=\"成功状态(feedbackStatus=success)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        description=\"description\"\n        :x-decorator-props=\"{\n          feedbackStatus: 'success',\n        }\"\n      />\n      <SchemaStringField\n        title=\"加载状态(feedbackStatus=pending)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        description=\"description\"\n        :x-decorator-props=\"{\n          feedbackStatus: 'pending',\n        }\"\n      />\n      <SchemaVoidField x-component=\"Title\" x-content=\"反馈信息的布局: \" />\n      <SchemaStringField\n        title=\"紧凑模式required\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :required=\"true\"\n        :x-decorator-props=\"{\n          feedbackLayout: 'terse',\n        }\"\n      />\n      <SchemaStringField\n        title=\"紧凑模式有feedback(feedbackLayout=terse)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          feedbackStatus: 'error',\n          feedbackText: 'error message',\n          feedbackLayout: 'terse',\n        }\"\n      />\n      <SchemaStringField\n        title=\"紧凑模式无feedback(feedbackLayout=terse)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          feedbackLayout: 'terse',\n        }\"\n      />\n      <SchemaStringField\n        title=\"松散模式(feedbackLayout=loose)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          feedbackStatus: 'error',\n          feedbackText: 'error message',\n          feedbackLayout: 'loose',\n        }\"\n      />\n      <SchemaStringField\n        title=\"弹出模式(feedbackLayout=popover)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          feedbackStatus: 'warning',\n          feedbackText: 'warning message',\n          feedbackLayout: 'popover',\n        }\"\n      />\n      <SchemaStringField\n        title=\"弹出模式(feedbackLayout=popover)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          feedbackStatus: 'error',\n          feedbackText: 'error message',\n          feedbackLayout: 'popover',\n        }\"\n      />\n      <SchemaStringField\n        title=\"弹出模式(feedbackLayout=popover)\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :x-decorator-props=\"{\n          feedbackStatus: 'success',\n          feedbackText: 'success message',\n          feedbackLayout: 'popover',\n        }\"\n      />\n      <SchemaVoidField x-component=\"Title\" x-content=\"组件的适配情况: \" />\n      <SchemaVoidField\n        x-component=\"FormLayout\"\n        :x-component-props=\"{\n          labelCol: 6,\n          wrapperCol: 10,\n        }\"\n      >\n        <SchemaStringField\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          :x-decorator-props=\"{\n            feedbackStatus: 'success',\n            feedbackIcon: SuccessIcon,\n          }\"\n        />\n        <SchemaStringField\n          title=\"DatePicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          :x-decorator-props=\"{\n            feedbackStatus: 'success',\n            feedbackIcon: SuccessIcon,\n          }\"\n        />\n        <SchemaStringField\n          title=\"DateRangePicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          :x-decorator-props=\"{\n            feedbackStatus: 'success',\n            feedbackIcon: SuccessIcon,\n          }\"\n          :x-component-props=\"{\n            type: 'daterange',\n          }\"\n        />\n        <SchemaStringField\n          title=\"YearPicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          :x-decorator-props=\"{\n            feedbackStatus: 'success',\n            feedbackIcon: SuccessIcon,\n          }\"\n          :x-component-props=\"{\n            type: 'year',\n          }\"\n        />\n        <SchemaStringField\n          title=\"MonthPicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          :x-decorator-props=\"{\n            feedbackStatus: 'success',\n            feedbackIcon: SuccessIcon,\n          }\"\n          :x-component-props=\"{\n            type: 'month',\n          }\"\n        />\n        <SchemaStringField\n          title=\"TimePicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"TimePicker\"\n          :x-decorator-props=\"{\n            feedbackStatus: 'success',\n            feedbackIcon: SuccessIcon,\n          }\"\n        />\n        <SchemaStringField\n          title=\"InputNumber\"\n          x-decorator=\"FormItem\"\n          x-component=\"InputNumber\"\n          :x-decorator-props=\"{\n            feedbackStatus: 'success',\n            feedbackIcon: SuccessIcon,\n          }\"\n        />\n        <SchemaStringField\n          title=\"Cascader\"\n          x-decorator=\"FormItem\"\n          x-component=\"Cascader\"\n          :x-decorator-props=\"{\n            feedbackStatus: 'success',\n            feedbackIcon: SuccessIcon,\n          }\"\n        />\n      </SchemaVoidField>\n    </SchemaField>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider } from '@formily/vue'\nimport {\n  FormItem,\n  InputNumber,\n  Input,\n  Cascader,\n  Select,\n  DatePicker,\n  FormLayout,\n  TimePicker,\n} from '@formily/element'\n\nconst SuccessIcon = {\n  functional: true,\n  render(h) {\n    return h('i', {\n      class: 'el-icon-circle-check',\n      style: { color: '#8AE65C' },\n    })\n  },\n}\n\nconst Title = {\n  functional: true,\n  render(h, context) {\n    return h('p', context.data, context.children)\n  },\n}\n\nconst fields = createSchemaField({\n  components: {\n    Title,\n    FormItem,\n    InputNumber,\n    Input,\n    Cascader,\n    Select,\n    DatePicker,\n    FormLayout,\n    TimePicker,\n  },\n})\n\nexport default {\n  components: { FormProvider, ...fields },\n  data() {\n    const form = createForm()\n    return {\n      form,\n      SuccessIcon,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-item/inset.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        name=\"input\"\n        title=\"Input\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        required\n        :x-decorator-props=\"{\n          inset: true,\n        }\"\n      />\n      <SchemaStringField\n        name=\"Select\"\n        title=\"Select\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        required\n        :x-decorator-props=\"{\n          inset: true,\n        }\"\n      />\n      <SchemaStringField\n        name=\"Cascader\"\n        title=\"Cascader\"\n        x-decorator=\"FormItem\"\n        x-component=\"Cascader\"\n        required\n        :x-decorator-props=\"{\n          inset: true,\n        }\"\n      />\n      <SchemaStringField\n        name=\"DatePicker\"\n        title=\"DatePicker\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n        required\n        :x-decorator-props=\"{\n          inset: true,\n        }\"\n      />\n      <SchemaStringField\n        name=\"InputNumber\"\n        title=\"InputNumber\"\n        x-decorator=\"FormItem\"\n        x-component=\"InputNumber\"\n        required\n        :x-decorator-props=\"{\n          inset: true,\n        }\"\n      />\n      <SchemaBooleanField\n        name=\"Switch\"\n        title=\"Switch\"\n        x-decorator=\"FormItem\"\n        x-component=\"Switch\"\n        required\n        :x-decorator-props=\"{\n          inset: true,\n        }\"\n      />\n    </SchemaField>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport {\n  Form,\n  FormItem,\n  Input,\n  Select,\n  Cascader,\n  DatePicker,\n  Switch,\n  InputNumber,\n} from '@formily/element'\n\nconst form = createForm()\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n    Cascader,\n    DatePicker,\n    Switch,\n    InputNumber,\n  },\n})\n\nexport default {\n  components: { Form, ...fields },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-item/json-schema.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport { Form, FormItem, Input, Submit } from '@formily/element'\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      title: '输入框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n  },\n}\n\nconst form = createForm()\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default {\n  components: { Form, SchemaField, Submit },\n  data() {\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-item/markup-schema.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        name=\"input\"\n        title=\"输入框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        required\n      />\n    </SchemaField>\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport { Form, FormItem, Input, Submit } from '@formily/element'\n\nconst form = createForm()\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default {\n  components: { Form, ...fields, Submit },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-item/size.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        name=\"size\"\n        title=\"Radio.Group\"\n        x-decorator=\"FormItem\"\n        x-component=\"Radio.Group\"\n        :enum=\"[\n          { value: 'small', label: 'Small' },\n          { value: 'default', label: 'Default' },\n          { value: 'large', label: 'Large' },\n        ]\"\n      />\n      <SchemaVoidField name=\"sizeWrap\" x-component=\"Div\">\n        <SchemaStringField\n          name=\"input\"\n          title=\"Input\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          required\n        />\n        <SchemaStringField\n          name=\"select1\"\n          title=\"Multiple Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          :enum=\"[\n            {\n              label: '选项1',\n              value: 1,\n            },\n            {\n              label: '选项2',\n              value: 2,\n            },\n          ]\"\n          :x-component-props=\"{\n            multiple: true,\n            placeholder: '请选择',\n          }\"\n          required\n        />\n        <SchemaStringField\n          name=\"select2\"\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          :enum=\"[\n            {\n              label: '选项1',\n              value: 1,\n            },\n            {\n              label: '选项2',\n              value: 2,\n            },\n          ]\"\n          :x-component-props=\"{\n            placeholder: '请选择',\n          }\"\n          required\n        />\n        <SchemaStringField\n          name=\"Cascader\"\n          title=\"Cascader\"\n          x-decorator=\"FormItem\"\n          x-component=\"Cascader\"\n          required\n        />\n        <SchemaStringField\n          name=\"DatePicker\"\n          title=\"DatePicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          required\n        />\n        <SchemaStringField\n          name=\"InputNumber\"\n          title=\"InputNumber\"\n          x-decorator=\"FormItem\"\n          x-component=\"InputNumber\"\n          required\n        />\n        <SchemaBooleanField\n          name=\"Switch\"\n          title=\"Switch\"\n          x-decorator=\"FormItem\"\n          x-component=\"Switch\"\n          required\n        />\n      </SchemaVoidField>\n    </SchemaField>\n  </Form>\n</template>\n\n<script>\nimport { createForm, onFieldChange } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport {\n  Form,\n  FormItem,\n  Input,\n  Select,\n  Cascader,\n  DatePicker,\n  Switch,\n  InputNumber,\n  Radio,\n} from '@formily/element'\n\nconst Div = {\n  functional: true,\n  render(h, context) {\n    return h('div', context.data, context.children)\n  },\n}\n\nconst form = createForm({\n  values: {\n    size: 'default',\n  },\n  effects: () => {\n    onFieldChange('size', ['value'], (field, form) => {\n      form.setFieldState('sizeWrap.*', (state) => {\n        if (state.decorator[1]) {\n          state.decorator[1].size = field.value\n        }\n      })\n    })\n  },\n})\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    Select,\n    Cascader,\n    DatePicker,\n    Switch,\n    InputNumber,\n    Radio,\n    Div,\n  },\n})\n\nexport default {\n  components: { Form, ...fields },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-item/template.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <Field\n      name=\"input\"\n      title=\"输入框\"\n      :decorator=\"[FormItem]\"\n      :component=\"[Input]\"\n      required\n    />\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/vue'\nimport { Form, FormItem, Input, Submit } from '@formily/element'\n\nconst form = createForm()\n\nexport default {\n  components: { Form, Field, Submit },\n  data() {\n    return {\n      FormItem,\n      Input,\n      form,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-layout/json-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider } from '@formily/vue'\nimport { FormItem, FormLayout, Input, Select, Submit } from '@formily/element'\n\nconst schema = {\n  type: 'object',\n  properties: {\n    layout: {\n      type: 'void',\n      'x-component': 'FormLayout',\n      'x-component-props': {\n        labelCol: 6,\n        wrapperCol: 10,\n        layout: 'vertical',\n      },\n      properties: {\n        input: {\n          type: 'string',\n          title: '输入框',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            tooltip: '123',\n          },\n          'x-component': 'Input',\n        },\n        select: {\n          type: 'string',\n          title: '选择框',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Select',\n        },\n      },\n    },\n  },\n}\n\nconst form = createForm()\nconst fields = createSchemaField({\n  components: {\n    FormLayout,\n    FormItem,\n    Input,\n    Select,\n  },\n})\n\nexport default {\n  components: { FormProvider, ...fields, Submit },\n  data() {\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-layout/markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaVoidField\n        x-component=\"FormLayout\"\n        :x-component-props=\"{\n          labelCol: 6,\n          wrapperCol: 10,\n        }\"\n      >\n        <SchemaStringField\n          name=\"input\"\n          title=\"输入框\"\n          x-decorator=\"FormItem\"\n          :x-decorator-props=\"{\n            tooltip: '123',\n          }\"\n          x-component=\"Input\"\n          :required=\"true\"\n        />\n        <SchemaStringField\n          name=\"select\"\n          title=\"选择框\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          :required=\"true\"\n        />\n      </SchemaVoidField>\n    </SchemaField>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider } from '@formily/vue'\nimport { FormLayout, FormItem, Input, Select } from '@formily/element'\n\nconst fields = createSchemaField({\n  components: { FormLayout, FormItem, Input, Select },\n})\n\nexport default {\n  components: { FormProvider, ...fields },\n  data() {\n    const form = createForm()\n    return {\n      form,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-layout/template.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <FormLayout\n      :breakpoints=\"[680]\"\n      :layout=\"['vertical', 'horizontal']\"\n      :labelAlign=\"['left', 'right']\"\n      :labelCol=\"[24, 6]\"\n      :wrapperCol=\"[24, 10]\"\n    >\n      <Field\n        name=\"input\"\n        title=\"输入框\"\n        :decorator=\"[\n          FormItem,\n          {\n            tooltip: '123',\n          },\n        ]\"\n        :component=\"[Input]\"\n        :required=\"true\"\n      />\n      <Field\n        name=\"select\"\n        title=\"选择框\"\n        :decorator=\"[FormItem]\"\n        :component=\"[Select]\"\n        :required=\"true\"\n      />\n    </FormLayout>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/vue'\nimport { FormLayout, FormItem, Input, Select } from '@formily/element'\n\nexport default {\n  components: { FormProvider, Field, FormLayout },\n  data() {\n    const form = createForm()\n    return {\n      FormLayout,\n      FormItem,\n      Input,\n      Select,\n      form,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-step/json-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" :scope=\"{ formStep }\" />\n    <FormConsumer>\n      <template #default>\n        <FormButtonGroup>\n          <Button\n            :disabled=\"!formStep.allowBack\"\n            @click=\"\n              () => {\n                formStep.back()\n              }\n            \"\n          >\n            上一步\n          </Button>\n          <Button\n            :disabled=\"!formStep.allowNext\"\n            @click=\"\n              () => {\n                formStep.next()\n              }\n            \"\n          >\n            下一步\n          </Button>\n          <Submit :disabled=\"formStep.allowNext\" @submit=\"log\">提交</Submit>\n        </FormButtonGroup>\n      </template>\n    </FormConsumer>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField, FormConsumer } from '@formily/vue'\nimport {\n  FormItem,\n  FormStep,\n  FormButtonGroup,\n  Submit,\n  Input,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    FormStep,\n    Input,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    collapse: {\n      type: 'void',\n      'x-component': 'FormStep',\n      'x-component-props': {\n        formStep: '{{formStep}}',\n      },\n      properties: {\n        step1: {\n          type: 'void',\n          'x-component': 'FormStep.StepPane',\n          'x-component-props': {\n            title: '第一步',\n          },\n          properties: {\n            aaa: {\n              type: 'string',\n              title: 'AAA',\n              required: true,\n              'x-decorator': 'FormItem',\n              'x-component': 'Input',\n            },\n          },\n        },\n        step2: {\n          type: 'void',\n          'x-component': 'FormStep.StepPane',\n          'x-component-props': {\n            title: '第二步',\n          },\n          properties: {\n            bbb: {\n              type: 'string',\n              title: 'AAA',\n              required: true,\n              'x-decorator': 'FormItem',\n              'x-component': 'Input',\n            },\n          },\n        },\n        step3: {\n          type: 'void',\n          'x-component': 'FormStep.StepPane',\n          'x-component-props': {\n            title: '第三步',\n          },\n          properties: {\n            ccc: {\n              type: 'string',\n              title: 'AAA',\n              required: true,\n              'x-decorator': 'FormItem',\n              'x-component': 'Input',\n            },\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default {\n  components: {\n    FormProvider,\n    FormConsumer,\n    FormButtonGroup,\n    Button,\n    Submit,\n    SchemaField,\n  },\n\n  data() {\n    const form = createForm()\n    const formStep = FormStep.createFormStep()\n    return {\n      schema,\n      form,\n      formStep,\n    }\n  },\n  methods: {\n    log() {\n      this.formStep.submit(console.log)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-step/markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaVoidField x-component=\"FormStep\" :x-component-props=\"{ formStep }\">\n        <SchemaVoidField\n          x-component=\"FormStep.StepPane\"\n          :x-component-props=\"{ title: '第一步' }\"\n        >\n          <SchemaStringField\n            name=\"aaa\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaVoidField>\n        <SchemaVoidField\n          x-component=\"FormStep.StepPane\"\n          :x-component-props=\"{ title: '第二步' }\"\n        >\n          <SchemaStringField\n            name=\"bbb\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaVoidField>\n        <SchemaVoidField\n          type=\"void\"\n          x-component=\"FormStep.StepPane\"\n          :x-component-props=\"{ title: '第三步' }\"\n        >\n          <SchemaStringField\n            name=\"ccc\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaVoidField>\n      </SchemaVoidField>\n    </SchemaField>\n    <FormConsumer>\n      <template #default>\n        <FormButtonGroup>\n          <Button\n            :disabled=\"!formStep.allowBack\"\n            @click=\"\n              () => {\n                formStep.back()\n              }\n            \"\n          >\n            上一步\n          </Button>\n          <Button\n            :disabled=\"!formStep.allowNext\"\n            @click=\"\n              () => {\n                formStep.next()\n              }\n            \"\n          >\n            下一步\n          </Button>\n          <Submit :disabled=\"formStep.allowNext\" @submit=\"log\">提交</Submit>\n        </FormButtonGroup>\n      </template>\n    </FormConsumer>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, createSchemaField } from '@formily/vue'\nimport {\n  FormItem,\n  FormStep,\n  FormButtonGroup,\n  Submit,\n  Input,\n} from '@formily/element'\nimport { Button } from 'element-ui'\nimport Template from '../editable/template.vue'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormStep,\n    Input,\n  },\n})\nconst formStep = FormStep.createFormStep()\n\nexport default {\n  components: {\n    FormConsumer,\n    FormProvider,\n    FormButtonGroup,\n    Button,\n    Submit,\n    Template,\n    ...SchemaField,\n  },\n\n  data() {\n    const form = createForm()\n\n    return {\n      form,\n      formStep,\n    }\n  },\n  methods: {\n    log() {\n      this.formStep.submit(console.log)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-tab/json-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" :scope=\"{ formTab }\" />\n    <FormButtonGroup alignFormItem>\n      <Button\n        @click=\"\n          () => {\n            form.query('tab3').take((field) => {\n              field.visible = !field.visible\n            })\n          }\n        \"\n      >\n        显示/隐藏最后一个Tab\n      </Button>\n      <Button\n        @click=\"\n          () => {\n            formTab.setActiveKey('tab2')\n          }\n        \"\n      >\n        切换第二个Tab\n      </Button>\n      <Submit @submit=\"log\">提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormItem,\n  FormTab,\n  FormButtonGroup,\n  Submit,\n  Input,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    FormTab,\n    Input,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    collapse: {\n      type: 'void',\n      'x-component': 'FormTab',\n      'x-component-props': {\n        formTab: '{{formTab}}',\n      },\n      properties: {\n        tab1: {\n          type: 'void',\n          'x-component': 'FormTab.TabPane',\n          'x-component-props': {\n            label: 'A1',\n          },\n          properties: {\n            aaa: {\n              type: 'string',\n              title: 'AAA',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        tab2: {\n          type: 'void',\n          'x-component': 'FormTab.TabPane',\n          'x-component-props': {\n            label: 'A2',\n          },\n          properties: {\n            bbb: {\n              type: 'string',\n              title: 'BBB',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        tab3: {\n          type: 'void',\n          'x-component': 'FormTab.TabPane',\n          'x-component-props': {\n            label: 'A3',\n          },\n          properties: {\n            ccc: {\n              type: 'string',\n              title: 'CCC',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default {\n  components: {\n    FormProvider,\n    FormButtonGroup,\n    Button,\n    Submit,\n    SchemaField,\n  },\n\n  data() {\n    const form = createForm()\n    const formTab = FormTab.createFormTab()\n\n    return {\n      schema,\n      form,\n      formTab,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form-tab/markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaVoidField\n        type=\"void\"\n        x-component=\"FormTab\"\n        :x-component-props=\"{ formTab }\"\n      >\n        <SchemaVoidField\n          type=\"void\"\n          name=\"tab1\"\n          x-component=\"FormTab.TabPane\"\n          :x-component-props=\"{ label: 'A1' }\"\n        >\n          <SchemaStringField\n            name=\"aaa\"\n            x-decorator=\"FormItem\"\n            title=\"AAA\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaVoidField>\n        <SchemaVoidField\n          name=\"tab2\"\n          x-component=\"FormTab.TabPane\"\n          :x-component-props=\"{ label: 'A2' }\"\n        >\n          <SchemaStringField\n            name=\"bbb\"\n            x-decorator=\"FormItem\"\n            title=\"BBB\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaVoidField>\n        <SchemaVoidField\n          name=\"tab3\"\n          x-component=\"FormTab.TabPane\"\n          :x-component-props=\"{ label: 'A3' }\"\n        >\n          <SchemaStringField\n            name=\"ccc\"\n            x-decorator=\"FormItem\"\n            title=\"CCC\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaVoidField>\n      </SchemaVoidField>\n    </SchemaField>\n    <FormButtonGroup alignFormItem>\n      <Button\n        @click=\"\n          () => {\n            form.query('tab3').take((field) => {\n              field.visible = !field.visible\n            })\n          }\n        \"\n      >\n        显示/隐藏最后一个Tab\n      </Button>\n      <Button\n        @click=\"\n          () => {\n            formTab.setActiveKey('tab2')\n          }\n        \"\n      >\n        切换第二个Tab\n      </Button>\n      <Submit @submit=\"log\">提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormItem,\n  FormTab,\n  FormButtonGroup,\n  Submit,\n  Input,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormTab,\n    Input,\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    FormButtonGroup,\n    Button,\n    Submit,\n    ...SchemaField,\n  },\n\n  data() {\n    const form = createForm()\n    const formTab = FormTab.createFormTab()\n\n    return {\n      form,\n      formTab,\n    }\n  },\n  methods: {\n    log(values) {\n      console.log(values)\n    },\n  },\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/form.vue",
    "content": "<template>\n  <Form\n    :form=\"form\"\n    :label-col=\"6\"\n    :wrapper-col=\"10\"\n    @autoSubmit=\"log\"\n    @autoSubmitFailed=\"log\"\n  >\n    <SchemaField>\n      <SchemaStringField\n        name=\"input\"\n        title=\"输入框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        :required=\"true\"\n      />\n      <SchemaStringField\n        name=\"select\"\n        title=\"选择框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        :enum=\"[\n          {\n            label: '选项1',\n            value: 1,\n          },\n          {\n            label: '选项2',\n            value: 2,\n          },\n        ]\"\n        :required=\"true\"\n      />\n    </SchemaField>\n    <FormButtonGroup alignFormItem>\n      <Submit>提交</Submit>\n    </FormButtonGroup>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport {\n  Form,\n  Input,\n  Select,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/element'\n\nconst form = createForm()\nconst fields = createSchemaField({ components: { Input, Select, FormItem } })\n\nexport default {\n  components: { FormButtonGroup, Submit, Form, ...fields },\n  data() {\n    return {\n      form,\n    }\n  },\n\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/input/json-schema.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport { Form, FormItem, Input, Submit } from '@formily/element'\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      title: '输入框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    textarea: {\n      type: 'string',\n      title: '文本框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input.TextArea',\n    },\n  },\n}\n\nconst form = createForm()\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default {\n  components: { Form, SchemaField, Submit },\n  data() {\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/input/markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        name=\"input\"\n        title=\"输入框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaStringField\n        name=\"textarea\"\n        title=\"文本框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input.TextArea\"\n      />\n    </SchemaField>\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider } from '@formily/vue'\nimport { FormItem, Input, Submit } from '@formily/element'\n\nconst form = createForm()\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default {\n  components: { FormProvider, ...fields, Submit },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/input/template.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Field\n      name=\"input\"\n      title=\"输入框\"\n      :decorator=\"[FormItem]\"\n      :component=\"[Input]\"\n    />\n    <Field\n      name=\"textarea\"\n      title=\"文本框\"\n      :decorator=\"[FormItem]\"\n      :component=\"[Input.TextArea]\"\n    />\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/vue'\nimport { FormItem, Input, Submit } from '@formily/element'\n\nconst form = createForm()\n\nexport default {\n  components: { FormProvider, Field, Submit },\n  data() {\n    return {\n      FormItem,\n      Input,\n      form,\n    }\n  },\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/input-number/json-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider } from '@formily/vue'\nimport { FormItem, InputNumber, Submit } from '@formily/element'\n\nconst schema = {\n  type: 'object',\n  properties: {\n    inputNumber: {\n      type: 'number',\n      title: '输入框',\n      'x-decorator': 'FormItem',\n      'x-component': 'InputNumber',\n      'x-component-props': {\n        style: {\n          width: '240px',\n        },\n      },\n    },\n  },\n}\n\nconst form = createForm()\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    InputNumber,\n  },\n})\n\nexport default {\n  components: { FormProvider, SchemaField, Submit },\n  data() {\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/input-number/markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        name=\"input\"\n        title=\"输入框\"\n        x-decorator=\"FormItem\"\n        x-component=\"InputNumber\"\n        :x-component-props=\"{\n          style: {\n            width: '240px',\n          },\n        }\"\n      />\n    </SchemaField>\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider } from '@formily/vue'\nimport { FormItem, InputNumber, Submit } from '@formily/element'\n\nconst form = createForm()\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    InputNumber,\n  },\n})\n\nexport default {\n  components: { FormProvider, ...fields, Submit },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/input-number/template.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Field\n      name=\"input\"\n      title=\"输入框\"\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        InputNumber,\n        {\n          style: {\n            width: '240px',\n          },\n        },\n      ]\"\n    />\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/vue'\nimport { FormItem, InputNumber, Submit } from '@formily/element'\n\nconst form = createForm()\n\nexport default {\n  components: { FormProvider, Field, Submit },\n  data() {\n    return {\n      FormItem,\n      InputNumber,\n      form,\n    }\n  },\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/password/json-schema.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport { Form, FormItem, Password, Submit } from '@formily/element'\n\nconst schema = {\n  type: 'object',\n  properties: {\n    password: {\n      type: 'string',\n      title: '密码框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Password',\n    },\n  },\n}\n\nconst form = createForm()\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    Password,\n  },\n})\n\nexport default {\n  components: { Form, SchemaField, Submit },\n  data() {\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/password/markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        name=\"input\"\n        title=\"密码框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Password\"\n      />\n    </SchemaField>\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider } from '@formily/vue'\nimport { FormItem, Password, Submit } from '@formily/element'\n\nconst form = createForm()\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Password,\n  },\n})\n\nexport default {\n  components: { FormProvider, ...fields, Submit },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/password/template.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Field\n      name=\"input\"\n      title=\"密码框\"\n      :decorator=\"[FormItem]\"\n      :component=\"[Password]\"\n    />\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/vue'\nimport { FormItem, Password, Submit } from '@formily/element'\n\nconst form = createForm()\n\nexport default {\n  components: { FormProvider, Field, Submit },\n  data() {\n    return {\n      FormItem,\n      Password,\n      form,\n    }\n  },\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/preview-text/base.vue",
    "content": "<template>\n  <FormLayout :labelCol=\"6\" :wrapperCol=\"10\">\n    <FormProvider :form=\"form\">\n      <SchemaField>\n        <SchemaStringField\n          x-decorator=\"FormItem\"\n          title=\"文本预览\"\n          x-component=\"PreviewText.Input\"\n          default=\"Hello world\"\n        />\n        <SchemaStringField\n          x-decorator=\"FormItem\"\n          title=\"选择项预览\"\n          x-component=\"PreviewText.Select\"\n          :x-component-props=\"{\n            multiple: true,\n          }\"\n          :default=\"['123', '222']\"\n          :enum=\"[\n            { label: 'A111', value: '123' },\n            {\n              label: 'A222',\n              value: '222',\n            },\n          ]\"\n        />\n        <SchemaStringField\n          x-decorator=\"FormItem\"\n          title=\"日期预览\"\n          x-component=\"PreviewText.DatePicker\"\n          default=\"2020-11-23 22:15:20\"\n        />\n        <SchemaStringField\n          x-decorator=\"FormItem\"\n          title=\"时间预览\"\n          x-component=\"PreviewText.TimePicker\"\n          :default=\"['2020-11-23 22:15:20', '2020-11-23 23:15:20']\"\n        />\n        <SchemaStringField\n          x-decorator=\"FormItem\"\n          title=\"Cascader预览\"\n          x-component=\"PreviewText.Cascader\"\n          :default=\"['hangzhou', 'yuhang']\"\n          :enum=\"[\n            { label: '杭州', value: 'hangzhou' },\n            { label: '余杭', value: 'yuhang' },\n          ]\"\n        />\n      </SchemaField>\n    </FormProvider>\n  </FormLayout>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport { FormLayout, FormItem, PreviewText } from '@formily/element'\n\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    PreviewText,\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    FormLayout,\n    ...fields,\n  },\n  data() {\n    const form = createForm()\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(v) {\n      console.log(v)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/preview-text/extend.vue",
    "content": "<template>\n  <Form\n    :labelCol=\"6\"\n    :wrapperCol=\"10\"\n    :form=\"form\"\n    :previewTextPlaceholder=\"vnode\"\n  >\n    <SchemaField>\n      <SchemaStringField\n        x-decorator=\"FormItem\"\n        title=\"文本预览\"\n        x-component=\"Input\"\n        default=\"Hello world\"\n      />\n      <SchemaStringField\n        x-decorator=\"FormItem\"\n        title=\"选择项预览\"\n        x-component=\"PreviewText.Select\"\n        :x-component-props=\"{\n          multiple: true,\n        }\"\n        :default=\"['123', '222']\"\n        :enum=\"[\n          { label: 'A111', value: '123' },\n          {\n            label: 'A222',\n            value: '222',\n          },\n        ]\"\n      />\n      <SchemaStringField\n        x-decorator=\"FormItem\"\n        title=\"日期预览\"\n        x-component=\"PreviewText.DatePicker\"\n        default=\"2020-11-23 22:15:20\"\n      />\n      <SchemaStringField\n        x-decorator=\"FormItem\"\n        title=\"日期范围预览\"\n        x-component=\"PreviewText.DatePicker\"\n        :default=\"['2020-11-23 22:15:20', '2020-11-24 22:15:20']\"\n      />\n      <SchemaStringField\n        x-decorator=\"FormItem\"\n        title=\"Cascader预览\"\n        x-component=\"PreviewText.Cascader\"\n        :default=\"['hangzhou', 'yuhang']\"\n        :enum=\"[\n          { label: '杭州', value: 'hangzhou' },\n          { label: '余杭', value: 'yuhang' },\n        ]\"\n      />\n    </SchemaField>\n    <FormButtonGroup alignFormItem>\n      <Button\n        @click=\"\n          () => {\n            form.setState((state) => {\n              state.editable = !state.editable\n            })\n          }\n        \"\n        >切换阅读态</Button\n      >\n    </FormButtonGroup>\n  </Form>\n</template>\n\n<script>\nimport { h } from 'vue-demi'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport {\n  Form,\n  FormItem,\n  Input,\n  PreviewText,\n  FormButtonGroup,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    PreviewText,\n  },\n})\n\nexport default {\n  components: {\n    Form,\n    FormButtonGroup,\n    Button,\n    ...fields,\n  },\n  data() {\n    const form = createForm()\n    return {\n      form,\n      vnode: () => h('div', {}, '123'),\n    }\n  },\n\n  mounted() {},\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/radio/json-schema.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport { Form, FormItem, Radio, Submit } from '@formily/element'\n\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    Radio,\n  },\n})\n\nexport default {\n  components: { Form, SchemaField, Submit },\n  data() {\n    const schema = {\n      type: 'object',\n      properties: {\n        radio: {\n          type: 'boolean',\n          title: '单选',\n          enum: [\n            {\n              label: '选项1',\n              value: 1,\n            },\n            {\n              label: '选项2',\n              value: 2,\n            },\n          ],\n          'x-decorator': 'FormItem',\n          'x-component': 'Radio.Group',\n          'x-component-props': {\n            optionType: 'button',\n          },\n        },\n      },\n    }\n\n    const form = createForm()\n\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/radio/markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        name=\"input\"\n        title=\"单选\"\n        x-decorator=\"FormItem\"\n        x-component=\"Radio.Group\"\n        :enum=\"[\n          {\n            label: '选项1',\n            value: 1,\n          },\n          {\n            label: '选项2',\n            value: 2,\n          },\n        ]\"\n      />\n    </SchemaField>\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider } from '@formily/vue'\nimport { FormItem, Radio, Submit } from '@formily/element'\n\nconst form = createForm()\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Radio,\n  },\n})\n\nexport default {\n  components: { FormProvider, ...fields, Submit },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/radio/template.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Field\n      name=\"input\"\n      title=\"单选\"\n      :decorator=\"[FormItem]\"\n      :component=\"[Radio.Group]\"\n      :dataSource=\"[\n        {\n          label: '选项1',\n          value: 1,\n        },\n        {\n          label: '选项2',\n          value: 2,\n        },\n      ]\"\n    />\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/vue'\nimport { FormItem, Radio, Submit } from '@formily/element'\n\nconst form = createForm()\n\nexport default {\n  components: { FormProvider, Field, Submit },\n  data() {\n    return {\n      FormItem,\n      Radio,\n      form,\n    }\n  },\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/reset/base.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        required\n        name=\"input1\"\n        title=\"输入框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaStringField\n        required\n        title=\"输入框\"\n        name=\"input2\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        default=\"123\"\n      />\n    </SchemaField>\n    <FormButtonGroup align-form-item>\n      <Reset>重置</Reset>\n    </FormButtonGroup>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormLayout,\n  Reset,\n  FormButtonGroup,\n  FormItem,\n  Input,\n} from '@formily/element'\n\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    FormLayout,\n    Reset,\n    FormButtonGroup,\n    ...fields,\n  },\n  data() {\n    const form = createForm()\n    return {\n      form,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/reset/force.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        required\n        name=\"input1\"\n        title=\"输入框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaStringField\n        required\n        title=\"输入框\"\n        name=\"input2\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        default=\"123\"\n      />\n    </SchemaField>\n    <FormButtonGroup align-form-item>\n      <Reset forceClear>重置</Reset>\n    </FormButtonGroup>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormLayout,\n  Reset,\n  FormButtonGroup,\n  FormItem,\n  Input,\n} from '@formily/element'\n\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    FormLayout,\n    Reset,\n    FormButtonGroup,\n    ...fields,\n  },\n  data() {\n    const form = createForm()\n    return {\n      form,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/reset/validate.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        required\n        name=\"input1\"\n        title=\"输入框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaStringField\n        required\n        title=\"输入框\"\n        name=\"input2\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        default=\"123\"\n      />\n    </SchemaField>\n    <FormButtonGroup align-form-item>\n      <Reset validate forceClear>重置</Reset>\n    </FormButtonGroup>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormLayout,\n  Reset,\n  FormButtonGroup,\n  FormItem,\n  Input,\n} from '@formily/element'\n\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    FormLayout,\n    Reset,\n    FormButtonGroup,\n    ...fields,\n  },\n  data() {\n    const form = createForm()\n    return {\n      form,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/select/json-schema-async.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField :schema=\"schema\" :scope=\"{ useAsyncDataSource, loadData }\" />\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport { action } from '@formily/reactive'\nimport { Form, FormItem, Select, Submit, Reset } from '@formily/element'\n\nconst schema = {\n  type: 'object',\n  properties: {\n    linkage: {\n      type: 'string',\n      title: '联动选择框',\n      enum: [\n        {\n          label: '发请求1',\n          value: 1,\n        },\n        {\n          label: '发请求2',\n          value: 2,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      'x-component-props': {\n        style: 'width: 240px;',\n      },\n    },\n    select: {\n      type: 'string',\n      title: '异步选择框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      'x-component-props': {\n        style: 'width: 240px;',\n      },\n      'x-reactions': ['{{useAsyncDataSource(loadData)}}'],\n    },\n  },\n}\n\nconst useAsyncDataSource = (service) => (field) => {\n  field.loading = true\n  service(field).then(\n    action.bound((data) => {\n      field.dataSource = data\n      field.loading = false\n    })\n  )\n}\n\nconst loadData = async (field) => {\n  const linkage = field.query('linkage').get('value')\n  if (!linkage) return []\n  return new Promise((resolve) => {\n    setTimeout(() => {\n      if (linkage === 1) {\n        resolve([\n          {\n            label: 'AAA',\n            value: 'aaa',\n          },\n          {\n            label: 'BBB',\n            value: 'ccc',\n          },\n        ])\n      } else if (linkage === 2) {\n        resolve([\n          {\n            label: 'CCC',\n            value: 'ccc',\n          },\n          {\n            label: 'DDD',\n            value: 'ddd',\n          },\n        ])\n      }\n    }, 1500)\n  })\n}\n\nconst form = createForm()\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    Select,\n  },\n})\n\nexport default {\n  components: { Form, SchemaField, Submit, Reset },\n  data() {\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    useAsyncDataSource,\n    loadData,\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/select/json-schema-sync.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport { Form, FormItem, Select, Submit, Reset } from '@formily/element'\n\nconst schema = {\n  type: 'object',\n  properties: {\n    select: {\n      type: 'string',\n      title: '选择框',\n      enum: [\n        {\n          label: '选项1',\n          value: 1,\n        },\n        {\n          label: '选项2',\n          value: 2,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      'x-component-props': {\n        style: 'width: 240px;',\n      },\n    },\n  },\n}\n\nconst form = createForm()\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    Select,\n  },\n})\n\nexport default {\n  components: { Form, SchemaField, Submit, Reset },\n  data() {\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/select/markup-schema-async-search.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        name=\"select\"\n        title=\"异步搜索选择框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        :x-component-props=\"{\n          filterable: true,\n          remote: true,\n          style: {\n            width: '240px',\n          },\n        }\"\n      />\n    </SchemaField>\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm, onFieldInit, onFieldReact } from '@formily/core'\nimport { action, observable } from '@formily/reactive'\nimport { createSchemaField, FormProvider } from '@formily/vue'\nimport { FormItem, Select, Submit } from '@formily/element'\n\nlet timeout\nlet currentValue\n\nfunction fetchData(value, callback) {\n  if (timeout) {\n    clearTimeout(timeout)\n    timeout = null\n  }\n  currentValue = value\n\n  function fake() {\n    callback([\n      {\n        label: 'AAA',\n        value: 'aaa',\n      },\n      {\n        label: 'BBB',\n        value: 'ccc',\n      },\n    ])\n  }\n\n  timeout = setTimeout(fake, 300)\n}\n\nconst useAsyncDataSource = (pattern, service) => {\n  const keyword = observable.ref('')\n\n  onFieldInit(pattern, (field) => {\n    field.setComponentProps({\n      remoteMethod: (value) => {\n        keyword.value = value\n      },\n    })\n  })\n\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service({ field, keyword: keyword.value }).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async ({ keyword }) => {\n      if (!keyword) {\n        return []\n      }\n      return new Promise((resolve) => {\n        fetchData(keyword, resolve)\n      })\n    })\n  },\n})\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Select,\n  },\n})\n\nexport default {\n  components: { FormProvider, ...fields, Submit },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/select/markup-schema-async.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField>\n      <SchemaNumberField\n        name=\"linkage\"\n        title=\"联动选择框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        :enum=\"[\n          { label: '发请求1', value: 1 },\n          { label: '发请求2', value: 2 },\n        ]\"\n        :x-component-props=\"{\n          style: {\n            width: '240px',\n          },\n        }\"\n      />\n      <SchemaStringField\n        name=\"select\"\n        title=\"异步选择框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        :x-component-props=\"{\n          style: {\n            width: '240px',\n          },\n        }\"\n      />\n    </SchemaField>\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm, onFieldReact } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport { action } from '@formily/reactive'\nimport { Form, FormItem, Select, Submit, Reset } from '@formily/element'\n\nconst useAsyncDataSource = (pattern, service) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service(field).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async (field) => {\n      const linkage = field.query('linkage').get('value')\n      if (!linkage) return []\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          if (linkage === 1) {\n            resolve([\n              {\n                label: 'AAA',\n                value: 'aaa',\n              },\n              {\n                label: 'BBB',\n                value: 'ccc',\n              },\n            ])\n          } else if (linkage === 2) {\n            resolve([\n              {\n                label: 'CCC',\n                value: 'ccc',\n              },\n              {\n                label: 'DDD',\n                value: 'ddd',\n              },\n            ])\n          }\n        }, 1500)\n      })\n    })\n  },\n})\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Select,\n  },\n})\n\nexport default {\n  components: { Form, ...fields, Submit, Reset },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/select/markup-schema-sync.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        name=\"select\"\n        title=\"选择框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        :x-component-props=\"{\n          style: {\n            width: '240px',\n          },\n        }\"\n        :enum=\"[\n          {\n            label: '选项1',\n            value: 1,\n          },\n          {\n            label: '选项2',\n            value: 2,\n          },\n        ]\"\n      />\n    </SchemaField>\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider } from '@formily/vue'\nimport { FormItem, Select, Submit } from '@formily/element'\n\nconst form = createForm()\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Select,\n  },\n})\n\nexport default {\n  components: { FormProvider, ...fields, Submit },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/select/template-async.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <Field\n      name=\"linkage\"\n      title=\"联动选择框\"\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        Select,\n        {\n          style: {\n            width: '240px',\n          },\n        },\n      ]\"\n      :dataSource=\"[\n        { label: '发请求1', value: 1 },\n        { label: '发请求2', value: 2 },\n      ]\"\n    />\n    <Field\n      name=\"select\"\n      title=\"异步选择框\"\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        Select,\n        {\n          style: {\n            width: '240px',\n          },\n        },\n      ]\"\n    />\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm, onFieldReact } from '@formily/core'\nimport { Field } from '@formily/vue'\nimport { action } from '@formily/reactive'\nimport { Form, FormItem, Select, Submit, Reset } from '@formily/element'\n\nconst useAsyncDataSource = (pattern, service) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service(field).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async (field) => {\n      const linkage = field.query('linkage').get('value')\n      if (!linkage) return []\n\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          if (linkage === 1) {\n            resolve([\n              {\n                label: 'AAA',\n                value: 'aaa',\n              },\n              {\n                label: 'BBB',\n                value: 'ccc',\n              },\n            ])\n          } else if (linkage === 2) {\n            resolve([\n              {\n                label: 'CCC',\n                value: 'ccc',\n              },\n              {\n                label: 'DDD',\n                value: 'ddd',\n              },\n            ])\n          }\n        }, 1500)\n      })\n    })\n  },\n})\n\nexport default {\n  components: { Form, Field, Submit, Reset },\n  data() {\n    return {\n      form,\n      FormItem,\n      Select,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/select/template-sync.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Field\n      name=\"select\"\n      title=\"选择框\"\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        Select,\n        {\n          style: {\n            width: '240px',\n          },\n        },\n      ]\"\n      :dataSource=\"[\n        {\n          label: '选项1',\n          value: 1,\n        },\n        {\n          label: '选项2',\n          value: 2,\n        },\n      ]\"\n    />\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/vue'\nimport { FormItem, Select, Submit } from '@formily/element'\n\nconst form = createForm()\n\nexport default {\n  components: { FormProvider, Field, Submit },\n  data() {\n    return {\n      FormItem,\n      Select,\n      form,\n    }\n  },\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/space/json-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <FormLayout :labelCol=\"6\" :wrapperCol=\"16\">\n      <SchemaField :schema=\"schema\" />\n      <FormButtonGroup alignFormItem>\n        <Submit onSubmit=\"log\">提交</Submit>\n      </FormButtonGroup>\n    </FormLayout>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider } from '@formily/vue'\nimport {\n  FormButtonGroup,\n  FormLayout,\n  FormItem,\n  Input,\n  Submit,\n  Space,\n} from '@formily/element'\n\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormLayout,\n    FormItem,\n    Input,\n    Space,\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    FormButtonGroup,\n    FormLayout,\n    SchemaField,\n    Submit,\n  },\n  data() {\n    const schema = {\n      type: 'object',\n      properties: {\n        name: {\n          type: 'void',\n          title: '姓名',\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            asterisk: true,\n            feedbackLayout: 'none',\n          },\n          'x-component': 'Space',\n          properties: {\n            firstName: {\n              type: 'string',\n              'x-decorator': 'FormItem',\n              'x-component': 'Input',\n              required: true,\n            },\n            lastName: {\n              type: 'string',\n              'x-decorator': 'FormItem',\n              'x-component': 'Input',\n              required: true,\n            },\n          },\n        },\n        texts: {\n          type: 'void',\n          title: '文本串联',\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            asterisk: true,\n            feedbackLayout: 'none',\n          },\n          'x-component': 'Space',\n          properties: {\n            aa: {\n              type: 'string',\n              'x-decorator': 'FormItem',\n              'x-decorator-props': {\n                addonAfter: '单位',\n              },\n              'x-component': 'Input',\n              required: true,\n            },\n            bb: {\n              type: 'string',\n              'x-decorator': 'FormItem',\n              'x-decorator-props': {\n                addonAfter: '单位',\n              },\n              'x-component': 'Input',\n              required: true,\n            },\n            cc: {\n              type: 'string',\n              'x-decorator': 'FormItem',\n              'x-decorator-props': {\n                addonAfter: '单位',\n              },\n              'x-component': 'Input',\n              required: true,\n            },\n          },\n        },\n\n        textarea: {\n          type: 'string',\n          title: '文本框',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input.TextArea',\n          'x-component-props': {\n            style: {\n              width: 400,\n            },\n          },\n          required: true,\n        },\n      },\n    }\n\n    const form = createForm()\n\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    logs(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/space/markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <FormLayout :labelCol=\"6\" :wrapperCol=\"16\">\n      <SchemaField>\n        <SchemaVoidField\n          x-component=\"FormLayout\"\n          :x-component-props=\"{\n            labelCol: 6,\n            wrapperCol: 10,\n          }\"\n        >\n          <SchemaVoidField\n            title=\"姓名\"\n            x-decorator=\"FormItem\"\n            :x-decorator-props=\"{\n              asterisk: true,\n              feedbackLayout: 'none',\n            }\"\n            x-component=\"Space\"\n          >\n            <SchemaStringField\n              name=\"firstName\"\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n              :required=\"true\"\n            />\n            <SchemaStringField\n              name=\"lastName\"\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n              :required=\"true\"\n            />\n          </SchemaVoidField>\n          <SchemaVoidField\n            title=\"文本串联\"\n            x-decorator=\"FormItem\"\n            :x-decorator-props=\"{\n              asterisk: true,\n              feedbackLayout: 'none',\n            }\"\n            x-component=\"Space\"\n          >\n            <SchemaStringField\n              name=\"aa\"\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n              :x-decorator-props=\"{\n                addonAfter: '单位',\n              }\"\n              :required=\"true\"\n            />\n            <SchemaStringField\n              name=\"bb\"\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n              :x-decorator-props=\"{\n                addonAfter: '单位',\n              }\"\n              :required=\"true\"\n            />\n            <SchemaStringField\n              name=\"cc\"\n              x-decorator=\"FormItem\"\n              x-component=\"Input\"\n              :x-decorator-props=\"{\n                addonAfter: '单位',\n              }\"\n              :required=\"true\"\n            />\n          </SchemaVoidField>\n          <SchemaStringField\n            name=\"textarea\"\n            title=\"文本框\"\n            x-decorator=\"FormItem\"\n            :required=\"true\"\n            x-component=\"Input\"\n            :x-component-props=\"{\n              style: {\n                width: 400,\n              },\n              type: 'textarea',\n            }\"\n          />\n        </SchemaVoidField>\n      </SchemaField>\n      <FormButtonGroup alignFormItem>\n        <Submit onSubmit=\"log\">提交</Submit>\n      </FormButtonGroup>\n    </FormLayout>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider } from '@formily/vue'\nimport {\n  FormLayout,\n  FormItem,\n  Input,\n  Space,\n  FormButtonGroup,\n  Submit,\n} from '@formily/element'\n\nconst fields = createSchemaField({\n  components: { FormItem, FormLayout, Input, Space },\n})\n\nexport default {\n  components: { FormProvider, FormLayout, FormButtonGroup, Submit, ...fields },\n  data() {\n    const form = createForm()\n    return {\n      form,\n    }\n  },\n\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/space/template.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <FormLayout :labelCol=\"6\" :wrapperCol=\"16\">\n      <VoidField\n        name=\"name\"\n        title=\"姓名\"\n        :decorator=\"[\n          FormItem,\n          {\n            asterisk: true,\n            feedbackLayout: 'none',\n          },\n        ]\"\n        :component=\"[Space]\"\n      >\n        <Field\n          name=\"firstName\"\n          :decorator=\"[FormItem]\"\n          :component=\"[Input]\"\n          required\n        />\n        <Field\n          name=\"lastName\"\n          :decorator=\"[FormItem]\"\n          :component=\"[Input]\"\n          required\n        />\n      </VoidField>\n      <VoidField\n        name=\"texts\"\n        title=\"文本串联\"\n        :decorator=\"[\n          FormItem,\n          {\n            asterisk: true,\n            feedbackLayout: 'none',\n          },\n        ]\"\n        :component=\"[Space]\"\n      >\n        <Field\n          name=\"aa\"\n          :decorator=\"[\n            FormItem,\n            {\n              addonAfter: '单位',\n            },\n          ]\"\n          :component=\"[Input]\"\n          required\n        />\n        <Field\n          name=\"bb\"\n          :decorator=\"[\n            FormItem,\n            {\n              addonAfter: '单位',\n            },\n          ]\"\n          :component=\"[Input]\"\n          required\n        />\n        <Field\n          name=\"cc\"\n          :decorator=\"[\n            FormItem,\n            {\n              addonAfter: '单位',\n            },\n          ]\"\n          :component=\"[Input]\"\n          required\n        />\n      </VoidField>\n      <Field\n        name=\"textarea\"\n        title=\"文本框\"\n        :decorator=\"[FormItem]\"\n        :component=\"[\n          TextArea,\n          {\n            style: {\n              width: 400,\n            },\n          },\n        ]\"\n        required\n      />\n      <FormButtonGroup alignFormItem>\n        <Submit :onSubmit=\"log\">提交</Submit>\n      </FormButtonGroup>\n    </FormLayout>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, VoidField } from '@formily/vue'\nimport {\n  FormLayout,\n  FormItem,\n  Input,\n  TextArea,\n  Submit,\n  Space,\n  FormButtonGroup,\n} from '@formily/element'\n\nconst form = createForm()\n\nexport default {\n  components: {\n    FormProvider,\n    FormLayout,\n    FormButtonGroup,\n    VoidField,\n    Field,\n    Submit,\n  },\n  data() {\n    return {\n      FormItem,\n      Input,\n      TextArea,\n      Space,\n      form,\n    }\n  },\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/submit/base.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        required\n        name=\"input1\"\n        title=\"输入框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaStringField\n        required\n        title=\"输入框\"\n        name=\"input2\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup align-form-item>\n      <Submit :onSubmit=\"log\">提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormLayout,\n  Submit,\n  FormButtonGroup,\n  FormItem,\n  Input,\n} from '@formily/element'\n\nconst fields = createSchemaField({ components: { FormItem, Input } })\n\nexport default {\n  components: {\n    FormProvider,\n    FormLayout,\n    Submit,\n    FormButtonGroup,\n    ...fields,\n  },\n  data() {\n    const form = createForm()\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(v) {\n      console.log(v)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/submit/loading.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        required\n        name=\"input1\"\n        title=\"输入框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaStringField\n        required\n        title=\"输入框\"\n        name=\"input2\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup align-form-item>\n      <Submit @submit=\"handleSubmit\">提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport {\n  FormLayout,\n  Submit,\n  FormButtonGroup,\n  FormItem,\n  Input,\n} from '@formily/element'\n\nconst fields = createSchemaField({ components: { FormItem, Input } })\n\nexport default {\n  components: {\n    FormProvider,\n    FormLayout,\n    Submit,\n    FormButtonGroup,\n    ...fields,\n  },\n  data() {\n    const form = createForm()\n    return {\n      form,\n    }\n  },\n  methods: {\n    handleSubmit(values) {\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          console.log(values)\n          resolve()\n        }, 2000)\n      })\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/switch/json-schema.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport { Form, FormItem, Switch, Submit } from '@formily/element'\n\nconst schema = {\n  type: 'object',\n  properties: {\n    switch: {\n      type: 'boolean',\n      title: '开关',\n      'x-decorator': 'FormItem',\n      'x-component': 'Switch',\n    },\n  },\n}\n\nconst form = createForm()\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    Switch,\n  },\n})\n\nexport default {\n  components: { Form, SchemaField, Submit },\n  data() {\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/switch/markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaBooleanField\n        name=\"switch\"\n        title=\"开关\"\n        x-decorator=\"FormItem\"\n        x-component=\"Switch\"\n      />\n    </SchemaField>\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider } from '@formily/vue'\nimport { FormItem, Switch, Submit } from '@formily/element'\n\nconst form = createForm()\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Switch,\n  },\n})\n\nexport default {\n  components: { FormProvider, ...fields, Submit },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/switch/template.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Field\n      name=\"switch\"\n      title=\"开关\"\n      :decorator=\"[FormItem]\"\n      :component=\"[Switch]\"\n    />\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/vue'\nimport { FormItem, Switch, Submit } from '@formily/element'\n\nconst form = createForm()\n\nexport default {\n  components: { FormProvider, Field, Submit },\n  data() {\n    return {\n      FormItem,\n      Switch,\n      form,\n    }\n  },\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/time-picker/json-schema.vue",
    "content": "<template>\n  <Form :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport { Form, FormItem, TimePicker, Submit } from '@formily/element'\n\nconst schema = {\n  type: 'object',\n  properties: {\n    time: {\n      type: 'string',\n      title: '时间',\n      'x-decorator': 'FormItem',\n      'x-component': 'TimePicker',\n      'x-component-props': {\n        style: {\n          width: '240px',\n        },\n      },\n    },\n    '[startTime,endTime]': {\n      title: '时间范围',\n      'x-decorator': 'FormItem',\n      'x-component': 'TimePicker',\n      'x-component-props': {\n        isRange: true,\n        style: {\n          width: '240px',\n        },\n      },\n      type: 'string',\n    },\n  },\n}\n\nconst form = createForm()\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    TimePicker,\n  },\n})\n\nexport default {\n  components: { Form, SchemaField, Submit },\n  data() {\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/time-picker/markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        name=\"time\"\n        title=\"时间\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"TimePicker\"\n        :x-component-props=\"{\n          style: {\n            width: '240px',\n          },\n        }\"\n      />\n      <SchemaStringField\n        name=\"[startTime, endTime]\"\n        title=\"时间范围\"\n        x-decorator=\"FormItem\"\n        x-component=\"TimePicker\"\n        :x-component-props=\"{\n          isRange: true,\n          style: {\n            width: '240px',\n          },\n        }\"\n      />\n    </SchemaField>\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider } from '@formily/vue'\nimport { FormItem, TimePicker, Submit } from '@formily/element'\n\nconst form = createForm()\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    TimePicker,\n  },\n})\n\nexport default {\n  components: { FormProvider, ...fields, Submit },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/time-picker/template.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Field\n      name=\"time\"\n      title=\"时间\"\n      required\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        TimePicker,\n        {\n          style: {\n            width: '240px',\n          },\n        },\n      ]\"\n    />\n    <Field\n      name=\"[startTime,endTime]\"\n      title=\"时间范围\"\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        TimePicker,\n        {\n          isRange: true,\n          style: {\n            width: '240px',\n          },\n        },\n      ]\"\n    />\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/vue'\nimport { FormItem, TimePicker, Submit } from '@formily/element'\n\nconst form = createForm()\n\nexport default {\n  components: { FormProvider, Field, Submit },\n  data() {\n    return {\n      FormItem,\n      TimePicker,\n      form,\n    }\n  },\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/transfer/json-schema.vue",
    "content": "<template>\n  <Form :form=\"form\" label-align=\"left\" :label-width=\"160\">\n    <SchemaField :schema=\"schema\" />\n    <Submit @submit=\"onSubmit\">提交</Submit>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport { Form, FormItem, Transfer, Submit } from '@formily/element'\n\nconst schema = {\n  type: 'object',\n  properties: {\n    transfer: {\n      type: 'array',\n      title: '穿梭框',\n      enum: [\n        { label: '选项1', key: 1 },\n        { label: '选项2', key: 2 },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Transfer',\n    },\n  },\n}\n\nconst form = createForm()\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    Transfer,\n  },\n})\n\nexport default {\n  components: { Form, SchemaField, Submit },\n  data() {\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/transfer/markup-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        name=\"input\"\n        title=\"单选\"\n        x-decorator=\"FormItem\"\n        x-component=\"Transfer\"\n        :enum=\"[\n          {\n            label: '选项1',\n            key: 1,\n          },\n          {\n            label: '选项2',\n            key: 2,\n          },\n        ]\"\n      />\n    </SchemaField>\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider } from '@formily/vue'\nimport { FormItem, Transfer, Submit } from '@formily/element'\n\nconst form = createForm()\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Transfer,\n  },\n})\n\nexport default {\n  components: { FormProvider, ...fields, Submit },\n  data() {\n    return {\n      form,\n    }\n  },\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/transfer/template.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Field\n      name=\"input\"\n      title=\"单选\"\n      :decorator=\"[FormItem]\"\n      :component=\"[Transfer]\"\n      :dataSource=\"[\n        {\n          label: '选项1',\n          key: 1,\n        },\n        {\n          label: '选项2',\n          key: 2,\n        },\n      ]\"\n    />\n    <Submit @submit=\"log\">提交</Submit>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/vue'\nimport { FormItem, Transfer, Submit } from '@formily/element'\n\nconst form = createForm()\n\nexport default {\n  components: { FormProvider, Field, Submit },\n  data() {\n    return {\n      FormItem,\n      Transfer,\n      form,\n    }\n  },\n  methods: {\n    log(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/upload/json-schema.vue",
    "content": "<template>\n  <Form :form=\"form\" :label-col=\"4\" :wrapper-col=\"10\">\n    <SchemaField :schema=\"schema\" />\n    <FormButtonGroup align-form-item>\n      <Submit @submit=\"onSubmit\">提交</Submit>\n    </FormButtonGroup>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport {\n  Form,\n  FormItem,\n  Upload,\n  Submit,\n  FormButtonGroup,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst UploadButton = {\n  functional: true,\n  render(h) {\n    return h(Button, {}, '上传图片')\n  },\n}\n\nconst schema = {\n  type: 'object',\n  properties: {\n    base: {\n      type: 'array',\n      title: '上传',\n      'x-decorator': 'FormItem',\n      'x-component': 'Upload',\n      'x-component-props': {\n        action: 'https://formily-vue.free.beeceptor.com/file',\n        textContent: '上传',\n      },\n      required: true,\n    },\n    card: {\n      type: 'array',\n      title: '卡片上传',\n      'x-decorator': 'FormItem',\n      'x-component': 'Upload',\n      'x-component-props': {\n        listType: 'picture-card',\n        action: 'https://formily-vue.free.beeceptor.com/file',\n      },\n      required: true,\n    },\n    drag: {\n      type: 'array',\n      title: '拖拽上传',\n      'x-decorator': 'FormItem',\n      'x-component': 'Upload',\n      'x-component-props': {\n        action: 'https://formily-vue.free.beeceptor.com/file',\n        textContent: '将文件拖到此处，或者点击上传',\n        drag: true,\n      },\n      required: true,\n    },\n    custom: {\n      type: 'array',\n      title: '自定义按钮',\n      'x-decorator': 'FormItem',\n      'x-component': 'Upload',\n      'x-component-props': {\n        action: 'https://formily-vue.free.beeceptor.com/file',\n      },\n      'x-content': UploadButton,\n      required: true,\n    },\n  },\n}\n\nconst form = createForm()\nconst { SchemaField } = createSchemaField({\n  components: {\n    FormItem,\n    Upload,\n  },\n})\n\nexport default {\n  components: { Form, SchemaField, Submit, FormButtonGroup },\n  data() {\n    return {\n      form,\n      schema,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/upload/markup-schema.vue",
    "content": "<template>\n  <Form :form=\"form\" :label-col=\"4\" :wrapper-col=\"10\">\n    <SchemaField>\n      <SchemaArrayField\n        name=\"upload\"\n        title=\"上传\"\n        x-decorator=\"FormItem\"\n        x-component=\"Upload\"\n        :x-component-props=\"{\n          action: 'https://formily-vue.free.beeceptor.com/file',\n          textContent: '上传',\n        }\"\n        required\n      />\n      <SchemaArrayField\n        name=\"upload2\"\n        title=\"卡片上传\"\n        x-decorator=\"FormItem\"\n        x-component=\"Upload\"\n        :x-component-props=\"{\n          listType: 'picture-card',\n          action: 'https://formily-vue.free.beeceptor.com/file',\n        }\"\n        required\n      />\n      <SchemaArrayField\n        name=\"upload3\"\n        title=\"拖拽上传\"\n        x-decorator=\"FormItem\"\n        x-component=\"Upload\"\n        :x-component-props=\"{\n          action: 'https://formily-vue.free.beeceptor.com/file',\n          textContent: '将文件拖到此处，或者点击上传',\n          drag: true,\n        }\"\n        required\n      />\n      <SchemaArrayField\n        name=\"custom\"\n        title=\"自定义按钮\"\n        x-decorator=\"FormItem\"\n        x-component=\"Upload\"\n        :x-component-props=\"{\n          action: 'https://formily-vue.free.beeceptor.com/file',\n        }\"\n        required\n        :x-content=\"UploadButton\"\n      />\n    </SchemaField>\n    <FormButtonGroup align-form-item>\n      <Submit @submit=\"onSubmit\">提交</Submit>\n    </FormButtonGroup>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/vue'\nimport {\n  Form,\n  FormItem,\n  Upload,\n  Submit,\n  FormButtonGroup,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst UploadButton = {\n  functional: true,\n  render(h) {\n    return h(Button, {}, '上传图片')\n  },\n}\n\nconst form = createForm()\nconst fields = createSchemaField({\n  components: {\n    FormItem,\n    Upload,\n  },\n})\n\nexport default {\n  components: { Form, ...fields, Submit, FormButtonGroup },\n  data() {\n    return {\n      UploadButton,\n      form,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/guide/upload/template.vue",
    "content": "<template>\n  <Form :form=\"form\" :label-col=\"4\" :wrapper-col=\"10\">\n    <ArrayField\n      name=\"upload\"\n      title=\"上传\"\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        Upload,\n        {\n          action: 'https://formily-vue.free.beeceptor.com/file',\n          textContent: '上传',\n        },\n      ]\"\n      required\n    />\n    <ArrayField\n      name=\"upload2\"\n      title=\"卡片上传\"\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        Upload,\n        {\n          listType: 'picture-card',\n          action: 'https://formily-vue.free.beeceptor.com/file',\n        },\n      ]\"\n      required\n    />\n    <ArrayField\n      name=\"upload3\"\n      title=\"拖拽上传\"\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        Upload,\n        {\n          action: 'https://formily-vue.free.beeceptor.com/file',\n          textContent: '将文件拖到此处，或者点击上传',\n          drag: true,\n        },\n      ]\"\n      required\n    />\n    <ArrayField\n      name=\"custom\"\n      title=\"自定义按钮\"\n      :decorator=\"[FormItem]\"\n      :component=\"[\n        Upload,\n        {\n          action: 'https://formily-vue.free.beeceptor.com/file',\n        },\n      ]\"\n      required\n      ><UploadButton\n    /></ArrayField>\n    <FormButtonGroup align-form-item>\n      <Submit @submit=\"onSubmit\">提交</Submit>\n    </FormButtonGroup>\n  </Form>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { ArrayField } from '@formily/vue'\nimport {\n  Form,\n  FormItem,\n  Upload,\n  Submit,\n  FormButtonGroup,\n} from '@formily/element'\nimport { Button } from 'element-ui'\n\nconst UploadButton = {\n  functional: true,\n  render(h) {\n    return h(Button, {}, '上传图片')\n  },\n}\n\nconst form = createForm()\n\nexport default {\n  components: { UploadButton, Form, ArrayField, Submit, FormButtonGroup },\n  data() {\n    return {\n      FormItem,\n      Upload,\n      form,\n    }\n  },\n  methods: {\n    onSubmit(value) {\n      console.log(value)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/demos/index.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Space>\n      <Field\n        name=\"price\"\n        title=\"价格\"\n        :initialValue=\"5.2\"\n        :decorator=\"[FormItem]\"\n        :component=\"[\n          InputNumber,\n          {\n            placeholder: '请输入',\n            style: {\n              width: 100,\n            },\n          },\n        ]\"\n      />\n      <FormItem>×</FormItem>\n      <Field\n        name=\"count\"\n        title=\"数量\"\n        :initialValue=\"100\"\n        :decorator=\"[FormItem]\"\n        :component=\"[\n          InputNumber,\n          {\n            placeholder: '请输入',\n            style: {\n              width: 100,\n            },\n          },\n        ]\"\n      />\n      <FormConsumer>\n        <template #default=\"{ form }\">\n          <FormItem>\n            = {{ `${form.values.price * form.values.count} 元` }}</FormItem\n          >\n        </template>\n      </FormConsumer>\n    </Space>\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { InputNumber, FormItem, Space } from '@formily/element'\nimport { FormProvider, FormConsumer, Field } from '@formily/vue'\n\nconst form = createForm()\n\nexport default {\n  components: { FormProvider, FormConsumer, Field, FormItem, Space },\n  data() {\n    return {\n      form,\n      InputNumber,\n      FormItem,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/element/docs/guide/array-cards.md",
    "content": "# ArrayCards\n\n> 卡片列表，对于每行字段数量较多，联动较多的场景比较适合使用 ArrayCards\n>\n> 注意：该组件只适用于 Schema 场景\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/array-cards/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/array-cards/json-schema\" />\n\n## Effects 联动案例\n\n<dumi-previewer demoPath=\"guide/array-cards/effects-markup-schema\" />\n\n## JSON Schema 联动案例\n\n<dumi-previewer demoPath=\"guide/array-cards/effects-json-schema\" />\n\n## API\n\n### ArrayCards\n\n> 表格组件\n\n参考 [https://element.eleme.io/#/zh-CN/component/card](https://element.eleme.io/#/zh-CN/component/card)\n\n### ArrayCards.Addition\n\n> 添加按钮\n\n扩展属性\n\n| 属性名       | 类型    | 描述       | 默认值   |\n| ------------ | ------- | ---------- | -------- | -------- |\n| title        | string  | 文案       |          |\n| method       | `'push' | 'unshift'` | 添加方式 | `'push'` |\n| defaultValue | any     | 默认值     |          |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button)\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayCards.Remove\n\n> 删除按钮\n\n| 属性名 | 类型   | 描述 | 默认值 |\n| ------ | ------ | ---- | ------ |\n| title  | string | 文案 |        |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button)\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayCards.MoveDown\n\n> 下移按钮\n\n| 属性名 | 类型   | 描述 | 默认值 |\n| ------ | ------ | ---- | ------ |\n| title  | string | 文案 |        |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button)\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayCards.MoveUp\n\n> 上移按钮\n\n| 属性名 | 类型   | 描述 | 默认值 |\n| ------ | ------ | ---- | ------ |\n| title  | string | 文案 |        |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button)\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayCards.Index\n\n> 索引渲染器\n\n无属性\n\n### ArrayCards.useIndex\n\n> 读取当前渲染行索引的 Hook\n\n### ArrayCards.useRecord\n\n> 读取当前渲染记录的 Hook\n"
  },
  {
    "path": "packages/element/docs/guide/array-collapse.md",
    "content": "# ArrayCollapse\n\n> 折叠面板，对于每行字段数量较多，联动较多的场景比较适合使用 ArrayCollapse\n>\n> 注意：该组件只适用于 Schema 场景\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/array-collapse/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/array-collapse/json-schema\" />\n\n## Effects 联动案例\n\n<dumi-previewer demoPath=\"guide/array-collapse/effects-markup-schema\" />\n\n## JSON Schema 联动案例\n\n<dumi-previewer demoPath=\"guide/array-collapse/effects-json-schema\" />\n\n## API\n\n### ArrayCollapse\n\n参考 [https://element.eleme.io/#/zh-CN/component/collapse](https://element.eleme.io/#/zh-CN/component/collapse)\n\n### ArrayCollapse.Item\n\n参考 [https://element.eleme.io/#/zh-CN/component/collapse](https://element.eleme.io/#/zh-CN/component/collapse)\n\n### ArrayCollapse.Addition\n\n> 添加按钮\n\n扩展属性\n\n| 属性名       | 类型    | 描述       | 默认值   |\n| ------------ | ------- | ---------- | -------- | -------- |\n| title        | string  | 文案       |          |\n| method       | `'push' | 'unshift'` | 添加方式 | `'push'` |\n| defaultValue | any     | 默认值     |          |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button)\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayCollapse.Remove\n\n> 删除按钮\n\n| 属性名 | 类型   | 描述 | 默认值 |\n| ------ | ------ | ---- | ------ |\n| title  | string | 文案 |        |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button)\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayCollapse.MoveDown\n\n> 下移按钮\n\n| 属性名 | 类型   | 描述 | 默认值 |\n| ------ | ------ | ---- | ------ |\n| title  | string | 文案 |        |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button)\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayCollapse.MoveUp\n\n> 上移按钮\n\n| 属性名 | 类型   | 描述 | 默认值 |\n| ------ | ------ | ---- | ------ |\n| title  | string | 文案 |        |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button)\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayCollapse.Index\n\n> 索引渲染器\n\n无属性\n\n### ArrayCollapse.useIndex\n\n> 读取当前渲染行索引的 Hook\n\n### ArrayCollapse.useRecord\n\n> 读取当前渲染记录的 Hook\n"
  },
  {
    "path": "packages/element/docs/guide/array-items.md",
    "content": "# ArrayItems\n\n> 自增列表，对于简单的自增编辑场景比较适合，或者对于空间要求高的场景比较适合\n>\n> 注意：该组件只适用于 Schema 场景\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/array-items/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/array-items/json-schema\" />\n\n## API\n\n### ArrayItems\n\n继承 HTMLDivElement Props\n\n### ArrayItems.Item\n\n> 列表区块\n\n继承 HTMLDivElement Props\n\n### ArrayItems.SortHandle\n\n> 拖拽手柄\n\n参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button)\n\n### ArrayItems.Addition\n\n> 添加按钮\n\n扩展属性\n\n| 属性名       | 类型    | 描述       | 默认值   |\n| ------------ | ------- | ---------- | -------- | -------- |\n| title        | string  | 文案       |          |\n| method       | `'push' | 'unshift'` | 添加方式 | `'push'` |\n| defaultValue | any     | 默认值     |          |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button)\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayItems.Remove\n\n> 删除按钮\n\n| 属性名 | 类型   | 描述 | 默认值 |\n| ------ | ------ | ---- | ------ |\n| title  | string | 文案 |        |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button)\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayItems.MoveDown\n\n> 下移按钮\n\n| 属性名 | 类型   | 描述 | 默认值 |\n| ------ | ------ | ---- | ------ |\n| title  | string | 文案 |        |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button)\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayItems.MoveUp\n\n> 上移按钮\n\n| 属性名 | 类型   | 描述 | 默认值 |\n| ------ | ------ | ---- | ------ |\n| title  | string | 文案 |        |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button)\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayItems.Index\n\n> 索引渲染器\n\n无属性\n\n### ArrayItems.useIndex\n\n> 读取当前渲染行索引的 Hook\n\n### ArrayItems.useRecord\n\n> 读取当前渲染记录的 Hook\n"
  },
  {
    "path": "packages/element/docs/guide/array-table.md",
    "content": "# ArrayTable\n\n> 自增表格，对于数据量超大的场景比较适合使用该组件，虽然数据量大到一定程度会有些许卡顿，但是不会影响基本操作\n>\n> 注意：该组件只适用于 Schema 场景，且只能是对象数组\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/array-table/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/array-table/json-schema\" />\n\n## Effects 联动案例\n\n<dumi-previewer demoPath=\"guide/array-table/effects-markup-schema\" />\n\n## JSON Schema 联动案例\n\n<dumi-previewer demoPath=\"guide/array-table/effects-json-schema\" />\n\n## API\n\n### ArrayTable\n\n> 表格组件\n\n参考 [https://element.eleme.io/#/zh-CN/component/table](https://element.eleme.io/#/zh-CN/component/table)\n\n### ArrayTable.Column\n\n> 表格列\n\n参考 [https://element.eleme.io/#/zh-CN/component/table](https://element.eleme.io/#/zh-CN/component/table)\n\n扩展属性\n\n| 属性名   | 类型    | 描述     | 默认值 |\n| -------- | ------- | -------- | ------ |\n| asterisk | boolean | 星号显示 | true   |\n\n> ArrayTableColumn 会自动检查内部的 FormItem 是否必填，并自动在表头加上红色星号。如果不希望显示，可通过 `asterisk` 属性进行覆盖。\n\n### ArrayTable.Addition\n\n> 添加按钮\n\n扩展属性\n\n| 属性名 | 类型    | 描述       | 默认值   |\n| ------ | ------- | ---------- | -------- | -------- |\n| title  | string  | 文案       |          |\n| method | `'push' | 'unshift'` | 添加方式 | `'push'` |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button)\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayTable.Remove\n\n> 删除按钮\n\n| 属性名 | 类型   | 描述 | 默认值 |\n| ------ | ------ | ---- | ------ |\n| title  | string | 文案 |        |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button)\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayTable.MoveDown\n\n> 下移按钮\n\n| 属性名 | 类型   | 描述 | 默认值 |\n| ------ | ------ | ---- | ------ |\n| title  | string | 文案 |        |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button)\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayTable.MoveUp\n\n> 上移按钮\n\n| 属性名 | 类型   | 描述 | 默认值 |\n| ------ | ------ | ---- | ------ |\n| title  | string | 文案 |        |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button)\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayTable.Index\n\n> 索引渲染器\n\n无属性\n\n### ArrayTable.useIndex\n\n> 读取当前渲染行索引的 Hook\n\n### ArrayTable.useRecord\n\n> 读取当前渲染记录的 Hook\n"
  },
  {
    "path": "packages/element/docs/guide/array-tabs.md",
    "content": "# ArrayTabs\n\n> 自增选项卡，对于纵向空间要求较高的场景可以考虑使用该组件\n>\n> 注意：该组件只适用于 Schema 场景\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/array-tabs/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/array-tabs/json-schema\" />\n\n## API\n\n### ArrayTabs\n\n参考 [https://element.eleme.io/#/zh-CN/component/tab](https://element.eleme.io/#/zh-CN/component/tab)\n"
  },
  {
    "path": "packages/element/docs/guide/cascader.md",
    "content": "# Cascader\n\n> 级联选择器\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/cascader/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/cascader/json-schema\" />\n\n## Template 案例\n\n<dumi-previewer demoPath=\"guide/cascader/template\" />\n\n## API\n\n参考 [https://element.eleme.io/#/zh-CN/component/cascader](https://element.eleme.io/#/zh-CN/component/cascader)\n"
  },
  {
    "path": "packages/element/docs/guide/checkbox.md",
    "content": "# Checkbox\n\n> 复选框\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/checkbox/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/checkbox/json-schema\" />\n\n## Template 案例\n\n<dumi-previewer demoPath=\"guide/checkbox/template\" />\n\n## API\n\n参考 [https://element.eleme.io/#/zh-CN/component/checkbox](https://element.eleme.io/#/zh-CN/component/checkbox)\n\n### 扩展属性\n\n| 属性名     | 类型                                                                                       | 描述     | 默认值  |\n| ---------- | ------------------------------------------------------------------------------------------ | -------- | ------- |\n| options    | [CheckboxProps](https://element.eleme.io/#/zh-CN/component/checkbox#checkbox-attributes)[] | 选项     | []      |\n| optionType | default/button                                                                             | 样式类型 | default |\n"
  },
  {
    "path": "packages/element/docs/guide/date-picker.md",
    "content": "# DatePicker\n\n> 日期选择器\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/date-picker/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/date-picker/json-schema\" />\n\n## Template 案例\n\n<dumi-previewer demoPath=\"guide/date-picker/template\" />\n\n## API\n\n参考 [https://element.eleme.io/#/zh-CN/component/date-picker](https://element.eleme.io/#/zh-CN/component/date-picker)\n"
  },
  {
    "path": "packages/element/docs/guide/editable.md",
    "content": "# Editable\n\n> 局部编辑器，对于一些空间要求较高的表单区域可以使用该组件\n>\n> Editable 组件相当于是 FormItem 组件的变体，所以通常放在 decorator 中\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/editable/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/editable/json-schema\" />\n\n## Template 案例\n\n<dumi-previewer demoPath=\"guide/editable/template\" />\n\n## API\n\n### Editable\n\n> 内联编辑\n\n参考 [https://element.formilyjs.org/guide/form-item.html#api](https://element.formilyjs.org/guide/form-item.html#api)\n\n### Editable.Popover\n\n> 浮层编辑\n\n参考 [https://element.eleme.io/#/zh-CN/component/popover](https://element.eleme.io/#/zh-CN/component/popover)\n"
  },
  {
    "path": "packages/element/docs/guide/form-button-group.md",
    "content": "# FormButtonGroup\n\n> 表单按钮组布局组件\n\n## 使用案例\n\n<dumi-previewer demoPath=\"guide/form-button-group\" />\n\n## API\n\n| 属性名        | 类型    | 描述          | 默认值   |\n| ------------- | ------- | ------------- | -------- | -------- | -------- |\n| gutter        | number  | 间隙大小      | 8px      |\n| align         | `'left' | 'center'      | 'right'` | 对齐方式 | `'left'` |\n| alignFormItem | boolean | 对齐 FormItem | `false`  |\n"
  },
  {
    "path": "packages/element/docs/guide/form-collapse.md",
    "content": "# FormCollapse\n\n> 折叠面板，通常用在布局空间要求较高的表单场景\n>\n> 注意：只能用在 Schema 场景\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/form-collapse/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/form-collapse/json-schema\" />\n\n## API\n\n### FormCollapse\n\n| 属性名       | 类型          | 描述                                                       | 默认值 |\n| ------------ | ------------- | ---------------------------------------------------------- | ------ |\n| formCollapse | IFormCollapse | 传入通过 createFormCollapse/useFormCollapse 创建出来的模型 |        |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/collapse](https://element.eleme.io/#/zh-CN/component/collapse)\n\n### FormCollapse.Item\n\n参考 [https://element.eleme.io/#/zh-CN/component/collapse](https://element.eleme.io/#/zh-CN/component/collapse)\n\n### FormCollapse.createFormCollapse\n\n```ts pure\ntype ActiveKey = string | number\ntype ActiveKeys = string | number | Array<string | number>\n\ninterface createFormCollapse {\n  (defaultActiveKeys?: ActiveKeys): IFormCollpase\n}\n\ninterface IFormCollapse {\n  //激活主键列表\n  activeKeys: ActiveKeys\n  //是否存在该激活主键\n  hasActiveKey(key: ActiveKey): boolean\n  //设置激活主键列表\n  setActiveKeys(keys: ActiveKeys): void\n  //添加激活主键\n  addActiveKey(key: ActiveKey): void\n  //删除激活主键\n  removeActiveKey(key: ActiveKey): void\n  //开关切换激活主键\n  toggleActiveKey(key: ActiveKey): void\n}\n```\n"
  },
  {
    "path": "packages/element/docs/guide/form-dialog.md",
    "content": "# FormDialog\n\n> 弹窗表单，主要用在简单的事件打开表单场景\n\n## Markup Schema 案例\n\n以下例子演示了 FormDialog 的几个能力：\n\n- 快速打开，关闭能力\n- 中间件能力，自动出现加载态\n- 渲染函数内可以响应式能力\n- 上下文共享能力\n\n<dumi-previewer demoPath=\"guide/form-dialog/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/form-dialog/json-schema\" />\n\n## Template 案例\n\n<dumi-previewer demoPath=\"guide/form-dialog/template\" />\n\n## API\n\n### FormDialog\n\n```ts pure\nimport { IFormProps, Form } from '@formily/core'\n\ntype FormDialogContentProps = { form: Form }\n\ntype FormDialogContent = Component | ((props: FormDialogContentProps) => VNode)\n\ntype DialogTitle = string | number | Component | VNode | (() => VNode)\n\ntype IFormDialogProps = Omit<DialogProps, 'title'> & {\n  title?: DialogTitle\n  footer?: null | Component | VNode | (() => VNode)\n  cancelText?: string | Component | VNode | (() => VNode)\n  cancelButtonProps?: ButtonProps\n  okText?: string | Component | VNode | (() => VNode)\n  okButtonProps?: ButtonProps\n  onOpen?: () => void\n  onOpened?: () => void\n  onClose?: () => void\n  onClosed?: () => void\n  onCancel?: () => void\n  onOK?: () => void\n  loadingText?: string\n}\n\ninterface IFormDialog {\n  forOpen(\n    middleware: (\n      props: IFormProps,\n      next: (props?: IFormProps) => Promise<any>\n    ) => any\n  ): IFormDialog\n  forConfirm(\n    middleware: (props: Form, next: (props?: Form) => Promise<any>) => any\n  ): IFormDialog\n  forCancel(\n    middleware: (props: Form, next: (props?: Form) => Promise<any>) => any\n  ): IFormDialog\n  open(props?: IFormProps): Promise<any>\n  close(): void\n}\n\ninterface FormDialog {\n  (title: IFormDialogProps, id: string, content: FormDialogContent): IFormDialog\n  (title: IFormDialogProps, id: FormDialogContent): IFormDialog\n  (title: DialogTitle, id: string, content: FormDialogContent): IFormDialog\n  (title: DialogTitle, id: FormDialogContent): IFormDialog\n}\n```\n\n`DialogProps`类型定义参考 [Element-UI Dialog API](https://element.eleme.io/#/zh-CN/component/dialog#attributes)\n\n### FormDialog.Footer\n\n无属性，只接收子节点\n\n### FormDialog.Portal\n\n接收可选的 id 属性，默认值为 form-dialog，如果一个应用存在多个 prefixCls，不同区域的弹窗内部 prefixCls 不一样，那推荐指定 id 为区域级 id\n"
  },
  {
    "path": "packages/element/docs/guide/form-drawer.md",
    "content": "# FormDrawer\n\n> 抽屉表单，主要用在简单的事件打开表单场景\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/form-drawer/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/form-drawer/json-schema\" />\n\n## Template 案例\n\n<dumi-previewer demoPath=\"guide/form-drawer/template\" />\n\n## API\n\n### FormDrawer\n\n```ts pure\nimport { IFormProps, Form } from '@formily/core'\n\ntype FormDrawerContentProps = { form: Form }\n\ntype FormDrawerContent = Component | ((props: FormDrawerContentProps) => VNode)\n\ntype DrawerTitle = string | number | Component | VNode | (() => VNode)\n\ntype IFormDrawerProps = Omit<DrawerProps, 'title'> & {\n  title?: DrawerTitle\n  footer?: null | Component | VNode | (() => VNode)\n  cancelText?: string | Component | VNode | (() => VNode)\n  cancelButtonProps?: ButtonProps\n  okText?: string | Component | VNode | (() => VNode)\n  okButtonProps?: ButtonProps\n  onOpen?: () => void\n  onOpened?: () => void\n  onClose?: () => void\n  onClosed?: () => void\n  onCancel?: () => void\n  onOK?: () => void\n  loadingText?: string\n}\n\ninterface FormDrawer {\n  (title: IFormDrawerProps, id: string, content: FormDrawerContent): IFormDrawer\n  (title: IFormDrawerProps, id: FormDrawerContent): IFormDrawer\n  (title: DrawerTitle, id: string, content: FormDrawerContent): IFormDrawer\n  (title: DrawerTitle, id: FormDrawerContent): IFormDrawer\n}\n```\n\n`DrawerProps`类型定义参考 [Element-UI Drawer API](https://element.eleme.io/#/zh-CN/component/drawer#attributes)\n\n### FormDrawer.Footer\n\n无属性，只接收子节点\n\n### FormDrawer.Portal\n\n接收可选的 id 属性，默认值为 form-dialog，如果一个应用存在多个 prefixCls，不同区域的弹窗内部 prefixCls 不一样，那推荐指定 id 为区域级 id\n"
  },
  {
    "path": "packages/element/docs/guide/form-grid.md",
    "content": "# FormGrid\n\n> FormGrid 组件\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/form-grid/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/form-grid/json-schema\" />\n\n## 原生案例\n\n<dumi-previewer demoPath=\"guide/form-grid/native\" />\n\n## 查询表单实现案例\n\n<dumi-previewer demoPath=\"guide/form-grid/form\" />\n\n## API\n\n### FormGrid\n\n| 属性名        | 类型                   | 描述                                                           | 默认值            |\n| ------------- | ---------------------- | -------------------------------------------------------------- | ----------------- |\n| minWidth      | `number / number[]`    | 元素最小宽度                                                   | 100               |\n| maxWidth      | `number / number[]`    | 元素最大宽度                                                   | -                 |\n| minColumns    | `number / number[]`    | 最小列数                                                       | 0                 |\n| maxColumns    | `number / number[]`    | 最大列数                                                       | -                 |\n| breakpoints   | number[]               | 容器尺寸断点                                                   | `[720,1280,1920]` |\n| columnGap     | number                 | 列间距                                                         | 8                 |\n| rowGap        | number                 | 行间距                                                         | 4                 |\n| colWrap       | boolean                | 自动换行                                                       | true              |\n| strictAutoFit | boolean                | GridItem 宽度是否严格受限于 maxWidth，不受限的话会自动占满容器 | false             |\n| shouldVisible | `(node,grid)=>boolean` | 是否需要显示当前节点                                           | `()=>true`        |\n| grid          | `Grid`                 | 外部传入 Grid 实例，用于实现更复杂的布局逻辑                   | -                 |\n\n注意：\n\n- minWidth 生效优先级高于 minColumn\n- maxWidth 优先级高于 maxColumn\n- minWidth/maxWidth/minColumns/maxColumns 的数组格式代表与断点数组映射\n\n### FormGrid.GridColumn\n\n| 属性名   | 类型   | 描述                                                 | 默认值 |\n| -------- | ------ | ---------------------------------------------------- | ------ |\n| gridSpan | number | 元素所跨列数，如果为-1，那么会自动反向跨列填补单元格 | 1      |\n\n### FormGrid.createFormGrid\n\n从上下文中读取 Grid 实例\n\n```ts\ninterface createFormGrid {\n  (props: IGridProps): Grid\n}\n```\n\n- IGridProps 参考 FormGrid 属性\n- Grid 实例属性方法参考 https://github.com/alibaba/formily/tree/formily_next/packages/grid\n\n### FormGrid.useFormGrid\n\n从上下文中读取 Grid 实例\n\n```ts\ninterface useFormGrid {\n  (): Grid\n}\n```\n\n- Grid 实例属性方法参考 https://github.com/alibaba/formily/tree/formily_next/packages/grid\n"
  },
  {
    "path": "packages/element/docs/guide/form-item.md",
    "content": "# FormItem\n\n> 全新的 FormItem 组件，相比于 Element 的 FormItem，它支持的功能更多，同时它的定位是纯样式组件，不管理表单状态，所以也会更轻量，更方便定制\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/form-item/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/form-item/json-schema\" />\n\n## Template 案例\n\n<dumi-previewer demoPath=\"guide/form-item/template\" />\n\n## 常用属性案例\n\n<dumi-previewer demoPath=\"guide/form-item/common\" />\n\n## 无边框案例\n\n设置去除组件边框\n\n<dumi-previewer demoPath=\"guide/form-item/bordered-none\" />\n\n## 内嵌模式案例\n\n设置表单组件为内嵌模式\n\n<dumi-previewer demoPath=\"guide/form-item/inset\" />\n\n## 反馈信息定制案例\n\n可通过 `feedbackIcon` 传入指定反馈的按钮\n\n<dumi-previewer demoPath=\"guide/form-item/feedback\" />\n\n## 尺寸控制案例\n\n<dumi-previewer demoPath=\"guide/form-item/size\" />\n\n## API\n\n### FormItem\n\n| 属性名         | 类型                                                   | 描述                                        | 默认值     |\n| -------------- | ------------------------------------------------------ | ------------------------------------------- | ---------- | -------- |\n| style          | CSSProperties                                          | 样式                                        | -          |\n| label          | String \\| Vue Component                                | 标签                                        | -          |\n| labelStyle     | CSSProperties                                          | 标签样式                                    | -          |\n| wrapperStyle   | CSSProperties                                          | 组件容器样式                                | -          |\n| className      | string                                                 | 组件样式类名                                | -          |\n| colon          | boolean                                                | 冒号                                        | -          |\n| tooltip        | String \\| Vue Component                                | 问号提示                                    | -          |\n| tooltipLayout  | `\"icon\"                                                | \"text\"`                                     | 问提示布局 | `\"icon\"` |\n| labelAlign     | `\"left\"` \\| `\"right\"`                                  | 标签文本对齐方式                            | `\"right\"`  |\n| labelWrap      | boolean                                                | 标签换⾏，否则出现省略号，hover 有 tooltip  | false      |\n| labelWidth     | `number`                                               | 标签固定宽度                                | -          |\n| wrapperWidth   | `number`                                               | 内容固定宽度                                | -          |\n| labelCol       | number                                                 | 标签⽹格所占列数，和内容列数加起来总和为 24 | -          |\n| wrapperCol     | number                                                 | 内容⽹格所占列数，和标签列数加起来总和为 24 | -          |\n| wrapperAlign   | `\"left\"` \\| `\"right\"`                                  | 内容文本对齐方式⻬                          | `\"left\"`   |\n| wrapperWrap    | boolean                                                | 内容换⾏，否则出现省略号，hover 有 tooltip  | false      |\n| fullness       | boolean                                                | 内容撑满                                    | false      |\n| addonBefore    | String \\| Vue Component                                | 前缀内容                                    | -          |\n| addonAfter     | String \\| Vue Component                                | 后缀内容                                    | -          |\n| size           | `\"small\"` \\| `\"default\"` \\| `\"large\"`                  | 尺⼨                                        | -          |\n| extra          | ReactNode                                              | 扩展描述⽂案                                | -          |\n| feedbackText   | ReactNode                                              | 反馈⽂案                                    | -          |\n| feedbackLayout | `\"loose\"` \\| `\"terse\"` \\| `\"popover\"` \\| `\"none\"`      | 反馈布局                                    | -          |\n| feedbackStatus | `\"error\"` \\| `\"warning\"` \\| `\"success\"` \\| `\"pending\"` | 反馈布局                                    | -          |\n| feedbackIcon   | string                                                 | 反馈图标                                    | -          |\n| required       | boolean                                                | 星号提醒                                    | -          |\n| asterisk       | boolean                                                | 星号提醒                                    | -          |\n| gridSpan       | number                                                 | ⽹格布局占宽                                | -          |\n\n### FormItem.BaseItem\n\n纯样式组件，属性与 FormItem 一样，与 Formily Core 不做状态桥接，主要用于一些需要依赖 FormItem 的样式布局能力，但不希望接入 Field 状态的场景\n"
  },
  {
    "path": "packages/element/docs/guide/form-layout.md",
    "content": "# FormLayout\n\n> 区块级布局批量控制组件，借助该组件，我们可以轻松的控制被 FormLayout 圈住的所有 FormItem 组件的布局模式\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/form-layout/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/form-layout/json-schema\" />\n\n## Template 案例\n\n<dumi-previewer demoPath=\"guide/form-layout/template\" />\n\n## API\n\n| 属性名         | 类型          | 描述              | 默认值                  |\n| -------------- | ------------- | ----------------- | ----------------------- | ----------- | ---------------- | ------------ | -------- | ---------- |\n| style          | CSSProperties | 样式              | -                       |\n| className      | string        | 类名              | -                       |\n| colon          | boolean       | 是否有冒号        | true                    |\n| labelAlign     | `'right'      | 'left'            | ('right'                | 'left')[]`  | 标签内容对齐     | -            |\n| wrapperAlign   | `'right'      | 'left'            | ('right'                | 'left')[]`  | 组件容器内容对齐 | -            |\n| labelWrap      | boolean       | 标签内容换行      | false                   |\n| labelWidth     | number        | 标签宽度(px)      | -                       |\n| wrapperWidth   | number        | 组件容器宽度(px)  | -                       |\n| wrapperWrap    | boolean       | 组件容器换行      | false                   |\n| labelCol       | `number       | number[]`         | 标签宽度(24 column)     | -           |\n| wrapperCol     | `number       | number[]`         | 组件容器宽度(24 column) | -           |\n| fullness       | boolean       | 组件容器宽度 100% | false                   |\n| size           | `'small'      | 'default'         | 'large'`                | 组件尺寸    | default          |\n| layout         | `'vertical'   | 'horizontal'      | 'inline'                | ('vertical' | 'horizontal'     | 'inline')[]` | 布局模式 | horizontal |\n| direction      | `'rtl'        | 'ltr'`            | 方向(暂不支持)          | ltr         |\n| inset          | boolean       | 内联布局          | false                   |\n| shallow        | boolean       | 上下文浅层传递    | true                    |\n| feedbackLayout | `'loose'      | 'terse'           | 'popover'               | 'none'`     | 反馈布局         | true         |\n| tooltipLayout  | `'icon'`      | `'text'`          | 问提示布局              | `\"icon\"`    |\n| bordered       | boolean       | 是否有边框        | true                    |\n| breakpoints    | number[]      | 容器尺寸断点      | -                       |\n| gridColumnGap  | number        | 网格布局列间距    | 8                       |\n| gridRowGap     | number        | 网格布局行间距    | 4                       |\n| spaceGap       | number        | 弹性间距          | 8                       |\n"
  },
  {
    "path": "packages/element/docs/guide/form-step.md",
    "content": "# FormStep\n\n> 分步表单组件\n>\n> 注意：该组件只能用在 Schema 场景\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/form-step/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/form-step/json-schema\" />\n\n## API\n\n### FormStep\n\n| 属性名   | 类型      | 描述                                   | 默认值 |\n| -------- | --------- | -------------------------------------- | ------ |\n| formStep | IFormStep | 传入通过 createFormStep 创建出来的模型 |        |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/steps](https://element.eleme.io/#/zh-CN/component/steps)\n\n### FormStep.StepPane\n\n参考 [https://element.eleme.io/#/zh-CN/component/steps](https://element.eleme.io/#/zh-CN/component/steps)\n\n### FormStep.createFormStep\n\n```ts pure\ninterface createFormStep {\n  (current?: number): IFormStep\n}\n\ninterface IFormStep {\n  //当前索引\n  current: number\n  //是否允许向后\n  allowNext: boolean\n  //是否允许向前\n  allowBack: boolean\n  //设置当前索引\n  setCurrent(key: number): void\n  //提交表单\n  submit: Formily.Core.Models.Form['submit']\n  //向后\n  next(): void\n  //向前\n  back(): void\n}\n```\n"
  },
  {
    "path": "packages/element/docs/guide/form-tab.md",
    "content": "# FormTab\n\n> 选项卡表单\n>\n> 注意：该组件只适用于 Schema 场景\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/form-tab/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/form-tab/json-schema\" />\n\n## API\n\n### FormTab\n\n| 属性名  | 类型     | 描述                                  | 默认值 |\n| ------- | -------- | ------------------------------------- | ------ |\n| formTab | IFormTab | 传入通过 createFormTab 创建出来的模型 |        |\n\n其余参考 [https://element.eleme.io/#/zh-CN/component/tabs](https://element.eleme.io/#/zh-CN/component/tabs)\n\n### FormTab.TabPane\n\n参考 [https://element.eleme.io/#/zh-CN/component/tabs](https://element.eleme.io/#/zh-CN/component/tabs)\n\n### FormTab.createFormTab\n\n```ts pure\ntype ActiveKey = string | number\n\ninterface createFormTab {\n  (defaultActiveKey?: ActiveKey): IFormTab\n}\n\ninterface IFormTab {\n  //激活主键\n  activeKey: ActiveKey\n  //设置激活主键\n  setActiveKey(key: ActiveKey): void\n}\n```\n"
  },
  {
    "path": "packages/element/docs/guide/form.md",
    "content": "# Form\n\n> FormProvider + FormLayout + form 标签的组合组件，可以帮助我们快速实现带回车提交的且能批量布局的表单\n\n## 使用案例\n\n<dumi-previewer demoPath=\"guide/form\" />\n\n> 注意：想要实现回车提交，我们在使用 Submit 组件的时候不能给其传 submit 事件，否则回车提交会失效，这样做的目的是为了防止用户同时在多处写 submit 事件监听器，处理逻辑不一致的话，提交时很难定位问题。\n\n## API\n\n布局相关的 API 属性，我们参考 [FormLayout](./form-layout) 即可，剩下是 Form 组件独有的 API 属性\n\n| 属性名                 | 类型                                                                                             | 描述                               | 默认值 |\n| ---------------------- | ------------------------------------------------------------------------------------------------ | ---------------------------------- | ------ |\n| form                   | [Form](https://core.formilyjs.org/api/models/form)                                               | Form 实例                          | -      |\n| component              | string                                                                                           | 渲染组件，可以指定为自定义组件渲染 | `form` |\n| previewTextPlaceholder | string \\| Vue Component                                                                          | 预览态占位符                       | `N/A`  |\n| onAutoSubmit           | `(values:any)=>any`                                                                              | 回车提交事件回调                   | -      |\n| onAutoSubmitFailed     | (feedbacks: [IFormFeedback](https://core.formilyjs.org/api/models/form#iformfeedback)[]) => void | 回车提交校验失败事件回调           | -      |\n"
  },
  {
    "path": "packages/element/docs/guide/index.md",
    "content": "# Element-UI\n\n## 介绍\n\n@formily/element 是基于 Element UI 封装的针对表单场景专业级(Professional)组件库，它主要有以下几个特点：\n\n- 更丰富的组件体系\n\n  - 布局组件\n\n    - FormLayout\n    - FormItem\n    - FormGrid\n    - FormButtonGroup\n    - Space\n    - Submit\n    - Reset\n\n  - 输入控件\n    - Input\n    - Password\n    - Select\n    - DatePicker\n    - TimePicker\n    - InputNumber\n    - Transfer\n    - Cascader\n    - Radio\n    - Checkbox\n    - Upload\n    - Switch\n  - 场景组件\n    - ArrayCards\n    - ArrayItems\n    - ArrayTable\n    - ArrayTabs\n    - FormCollapse\n    - FormStep\n    - FormTab\n    - FormDialog\n    - FormDrawer\n    - Editable\n  - 阅读态组件\n    - PreviewText\n\n- 主题定制能力\n  - follow 组件库的样式体系，更方便定制主题\n- 支持二次封装\n  - 所有组件都能二次封装\n- 支持阅读态\n  - 提供了 PreviewText 组件，用户可以基于它自己做阅读态封装，灵活性更强\n- 类型更加友好\n  - 每个组件都有着极其完整的类型定义，用户在实际开发过程中，可以感受到前所未有的智能提示体验\n- 更完备的布局控制能力\n  - 基于 FormLayout、FormItem、FormGrid 组件，提供更智能的布局能力。\n- 更优雅易用的 API\n  - FormStep，用户只需要关注 FormStep Reactive Model 即可，通过 createFormStep 就可以创建出 Reactive Model，传给 FormStep 组件即可快速通讯。同理，FormTab/FormCollapse 也是一样的通讯模式\n  - 弹窗表单，抽屉表单，想必过去，用户几乎每次都得在这两个场景上写大量的代码，这次直接提供了极其简易的 API 让用户使用，最大化提升开发效率\n\n## 注意\n\n因为 Element UI 是基于 Sass 构建的，如果你用 Webpack 配置请使用以下两个 Sass 工具\n\n```\n\"sass\": \"^1.32.11\",\n\"sass-loader\": \"^8.0.2\"\n```\n\n## 安装\n\n```bash\n$ npm install --save element-ui\n$ npm install --save @formily/core @formily/vue @vue/composition-api @formily/element\n```\n\n## 按需打包\n\n`Element-UI` 按需引入参见 [https://element.eleme.io/#/zh-CN/component/quickstart#an-xu-yin-ru](https://element.eleme.io/#/zh-CN/component/quickstart#an-xu-yin-ru)\n\n`@formily/element`按需引入需借助 `babel-plugin-import`\n\n#### 安装 `babel-plugin-import`\n\n```shell\nnpm install babel-plugin-import --save-dev\n```\n\n或者\n\n```shell\nyarn add babel-plugin-import --dev\n```\n\n修改 `.babelrc`\n\n```json\n{\n  \"plugins\": [\n    [\n      \"component\",\n      {\n        \"libraryName\": \"element-ui\",\n        \"styleLibraryName\": \"theme-chalk\"\n      }\n    ],\n    [\n      \"import\",\n      {\n        \"libraryName\": \"@formily/element\",\n        \"libraryDirectory\": \"esm\",\n        \"style\": true\n      }\n    ]\n  ]\n}\n```\n\n## Q/A\n\n问：我想自己封装一套组件库，该怎么做？\n\n答：如果是开源组件库，可以直接参与项目共建，提供 PR，如果是企业内私有组件库，参考源码即可，源码并没有太多复杂逻辑。\n\n问：为什么 ArrayCards/ArrayTable/FormStep 这类组件只支持 Schema 模式，不支持纯 Template 模式？\n\n答：这就是 Schema 模式的核心优势，借助协议，我们可以做场景化抽象，相反，纯 Template 模式，受限于 Template 的不可解析性，我们很难做到 UI 级别的场景化抽象，更多的只是抽象 Hook。\n"
  },
  {
    "path": "packages/element/docs/guide/input-number.md",
    "content": "# InputNumber\n\n> 数字输入框\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/input-number/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/input-number/json-schema\" />\n\n## Template 案例\n\n<dumi-previewer demoPath=\"guide/input-number/template\" />\n\n## API\n\n参考 [https://element.eleme.io/#/zh-CN/component/input-number](https://element.eleme.io/#/zh-CN/component/input-number)\n"
  },
  {
    "path": "packages/element/docs/guide/input.md",
    "content": "# Input\n\n> 文本输入框\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/input/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/input/json-schema\" />\n\n## Template 案例\n\n<dumi-previewer demoPath=\"guide/input/template\" />\n\n## API\n\n参考 [https://element.eleme.io/#/zh-CN/component/input](https://element.eleme.io/#/zh-CN/component/input)\n"
  },
  {
    "path": "packages/element/docs/guide/password.md",
    "content": "# Password\n\n> 密码输入框\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/password/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/password/json-schema\" />\n\n## Template 案例\n\n<dumi-previewer demoPath=\"guide/password/template\" />\n\n## API\n\n参考 [https://element.eleme.io/#/zh-CN/component/input](https://element.eleme.io/#/zh-CN/component/input)\n"
  },
  {
    "path": "packages/element/docs/guide/preview-text.md",
    "content": "# PreviewText\n\n> 阅读态组件，主要用来实现类 Input，类 DatePicker 这些组件的阅读态\n\n## 简单案例\n\n<dumi-previewer demoPath=\"guide/preview-text/base\" />\n\n## 扩展案例\n\n<dumi-previewer demoPath=\"guide/preview-text/extend\" />\n\n## API\n\n### PreviewText.Input\n\n参考 [https://element.eleme.io/#/zh-CN/component/input](https://element.eleme.io/#/zh-CN/component/input)\n\n### PreviewText.Select\n\n参考 [https://element.eleme.io/#/zh-CN/component/select](https://element.eleme.io/#/zh-CN/component/select)\n\n### PreviewText.Cascader\n\n参考 [https://element.eleme.io/#/zh-CN/component/cascader](https://element.eleme.io/#/zh-CN/component/cascader)\n\n### PreviewText.DatePicker\n\n参考 [https://element.eleme.io/#/zh-CN/component/date-picker](https://element.eleme.io/#/zh-CN/component/date-picker)\n\n### PreviewText.TimePicker\n\n参考 [https://element.eleme.io/#/zh-CN/component/time-picker](https://element.eleme.io/#/zh-CN/component/time-picker)\n\n### PreviewText\n\n| 属性名 | 类型   | 描述       | 默认值 |\n| ------ | ------ | ---------- | ------ |\n| value  | stirng | 缺省占位符 | N/A    |\n\n### PreviewText.Placeholder\n\n| 属性名 | 类型   | 描述       | 默认值 |\n| ------ | ------ | ---------- | ------ |\n| value  | stirng | 缺省占位符 | N/A    |\n\n### PreviewText.usePlaceholder\n\n```ts pure\ninterface usePreviewTextPlaceholder {\n  (): string\n}\n```\n"
  },
  {
    "path": "packages/element/docs/guide/radio.md",
    "content": "# Radio\n\n> 单选框\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/radio/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/radio/json-schema\" />\n\n## Template 案例\n\n<dumi-previewer demoPath=\"guide/radio/template\" />\n\n## API\n\n参考 [https://element.eleme.io/#/zh-CN/component/radio](https://element.eleme.io/#/zh-CN/component/radio)\n\n### 扩展属性\n\n| 属性名     | 类型                                                                              | 描述     | 默认值  |\n| ---------- | --------------------------------------------------------------------------------- | -------- | ------- |\n| options    | [RadioProps](https://element.eleme.io/#/zh-CN/component/radio#radio-attributes)[] | 选项     | []      |\n| optionType | default/button                                                                    | 样式类型 | default |\n"
  },
  {
    "path": "packages/element/docs/guide/reset.md",
    "content": "# Reset\n\n> 重置按钮\n\n## 普通重置\n\n> 有默认值的控件无法清空\n\n<dumi-previewer demoPath=\"guide/reset/base\" />\n\n## 强制清空重置\n\n<dumi-previewer demoPath=\"guide/reset/force\" />\n\n## 强制清空重置并校验\n\n<dumi-previewer demoPath=\"guide/reset/validate\" />\n\n## API\n\n按钮相关的 API 属性，我们参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button) 即可，剩下是 Reset 组件独有的 API 属性\n\n### 事件\n\n| 属性名                 | 类型                                                                                             | 描述             | 默认值                                |\n| ---------------------- | ------------------------------------------------------------------------------------------------ | ---------------- | ------------------------------------- | --- |\n| onClick                | `(event: MouseEvent) => void                                                                     | boolean`         | 点击事件，如果返回 false 可以阻塞重置 | -   |\n| onResetValidateSuccess | (payload: any) => void                                                                           | 重置校验成功事件 | -                                     |\n| onResetValidateFailed  | (feedbacks: [IFormFeedback](https://core.formilyjs.org/api/models/form#iformfeedback)[]) => void | 重置校验失败事件 | -                                     |\n"
  },
  {
    "path": "packages/element/docs/guide/select.md",
    "content": "# Select\n\n> 下拉框组件\n\n## Markup Schema 同步数据源案例\n\n<dumi-previewer demoPath=\"guide/select/markup-schema-sync\" />\n\n## Markup Schema 异步搜索案例\n\n<dumi-previewer demoPath=\"guide/select/markup-schema-async-search\" />\n\n## Markup Schema 异步联动数据源案例\n\n<dumi-previewer demoPath=\"guide/select/markup-schema-async\" />\n\n## JSON Schema 同步数据源案例\n\n<dumi-previewer demoPath=\"guide/select/json-schema-sync\" />\n\n## JSON Schema 异步联动数据源案例\n\n<dumi-previewer demoPath=\"guide/select/json-schema-async\" />\n\n## Template 同步数据源案例\n\n<dumi-previewer demoPath=\"guide/select/template-sync\" />\n\n## Template 异步联动数据源案例\n\n<dumi-previewer demoPath=\"guide/select/template-async\" />\n\n## API\n\n参考 [https://element.eleme.io/#/zh-CN/component/select](https://element.eleme.io/#/zh-CN/component/select)\n\n### 扩展属性\n\n| 属性名  | 类型                                                                                       | 描述 | 默认值 |\n| ------- | ------------------------------------------------------------------------------------------ | ---- | ------ |\n| options | [SelectOptionProps](https://element.eleme.io/#/zh-CN/component/select#option-attributes)[] | 选项 | []     |\n"
  },
  {
    "path": "packages/element/docs/guide/space.md",
    "content": "# Space\n\n> 超级便捷的 Flex 布局组件，可以帮助用户快速实现任何元素的并排紧挨布局\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/space/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/space/json-schema\" />\n\n## Template 案例\n\n<dumi-previewer demoPath=\"guide/space/template\" />\n\n## API\n\n参考 [https://ant.design/components/space-cn/](https://ant.design/components/space-cn/)\n"
  },
  {
    "path": "packages/element/docs/guide/submit.md",
    "content": "# Submit\n\n> 提交按钮\n\n## 普通提交\n\n<dumi-previewer demoPath=\"guide/submit/base\" />\n\n## 防重提交\n\n<dumi-previewer demoPath=\"guide/submit/loading\" />\n\n## API\n\n按钮相关的 API 属性，我们参考 [https://element.eleme.io/#/zh-CN/component/button](https://element.eleme.io/#/zh-CN/component/button) 即可，剩下是 Submit 组件独有的 API 属性\n\n| 属性名          | 类型                                                                                             | 描述                 | 默认值                                |\n| --------------- | ------------------------------------------------------------------------------------------------ | -------------------- | ------------------------------------- | --- |\n| onClick         | `(event: MouseEvent) => void                                                                     | boolean`             | 点击事件，如果返回 false 可以阻塞提交 | -   |\n| onSubmit        | `(values: any) => Promise<any>                                                                   | any`                 | 提交事件回调                          | -   |\n| onSubmitSuccess | (payload: any) => void                                                                           | 提交成功响应事件     | -                                     |\n| onSubmitFailed  | (feedbacks: [IFormFeedback](https://core.formilyjs.org/api/models/form#iformfeedback)[]) => void | 提交校验失败事件回调 | -                                     |\n"
  },
  {
    "path": "packages/element/docs/guide/switch.md",
    "content": "# Switch\n\n> 开关组件\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/switch/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/switch/json-schema\" />\n\n## Template 案例\n\n<dumi-previewer demoPath=\"guide/switch/template\" />\n\n## API\n\n参考 [https://element.eleme.io/#/zh-CN/component/switch](https://element.eleme.io/#/zh-CN/component/switch)\n"
  },
  {
    "path": "packages/element/docs/guide/time-picker.md",
    "content": "# TimePicker\n\n> 时间选择器\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/time-picker/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/time-picker/json-schema\" />\n\n## Template 案例\n\n<dumi-previewer demoPath=\"guide/time-picker/template\" />\n\n## API\n\n参考 [https://element.eleme.io/#/zh-CN/component/time-picker](https://element.eleme.io/#/zh-CN/component/time-picker)\n"
  },
  {
    "path": "packages/element/docs/guide/transfer.md",
    "content": "# Transfer\n\n> 穿梭框\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/transfer/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/transfer/json-schema\" />\n\n## Template 案例\n\n<dumi-previewer demoPath=\"guide/transfer/template\" />\n\n## API\n\n参考 [https://element.eleme.io/#/zh-CN/component/transfer](https://element.eleme.io/#/zh-CN/component/transfer)\n"
  },
  {
    "path": "packages/element/docs/guide/upload.md",
    "content": "# Upload\n\n> 上传组件\n>\n> 注意：使用上传组件，推荐用户进行二次封装，用户无需关心上传组件与 Formily 的数据通信，只需要处理样式与基本上传配置即可。\n\n## Markup Schema 案例\n\n<dumi-previewer demoPath=\"guide/upload/markup-schema\" />\n\n## JSON Schema 案例\n\n<dumi-previewer demoPath=\"guide/upload/json-schema\" />\n\n## Template 案例\n\n<dumi-previewer demoPath=\"guide/upload/template\" />\n\n## API\n\n参考 [https://element.eleme.io/#/zh-CN/component/upload](https://element.eleme.io/#/zh-CN/component/upload)\n"
  },
  {
    "path": "packages/element/package.json",
    "content": "{\n  \"name\": \"@formily/element\",\n  \"version\": \"2.3.7\",\n  \"license\": \"MIT\",\n  \"main\": \"lib\",\n  \"module\": \"esm\",\n  \"umd:main\": \"dist/formily.element.umd.production.js\",\n  \"unpkg\": \"dist/formily.element.umd.production.js\",\n  \"jsdelivr\": \"dist/formily.element.umd.production.js\",\n  \"jsnext:main\": \"esm\",\n  \"types\": \"lib/index.d.ts\",\n  \"engines\": {\n    \"npm\": \">=3.0.0\"\n  },\n  \"sideEffects\": [\n    \"dist/*\",\n    \"esm/*.js\",\n    \"lib/*.js\",\n    \"src/*.ts\",\n    \"*.scss\"\n  ],\n  \"scripts\": {\n    \"start\": \"vuepress dev docs\",\n    \"build\": \"rimraf -rf lib esm dist && npm run create:style && npm run build:cjs && npm run build:esm && npm run build:umd && npm run build:style\",\n    \"create:style\": \"ts-node create-style\",\n    \"build:style\": \"ts-node build-style\",\n    \"build:cjs\": \"ttsc  --declaration\",\n    \"build:esm\": \"ttsc --declaration --module es2015 --outDir esm\",\n    \"build:umd\": \"rollup --config\",\n    \"build:docs\": \"vuepress build docs\"\n  },\n  \"devDependencies\": {\n    \"@vue/composition-api\": \"^1.0.0-rc.7\",\n    \"@vuepress-dumi/vuepress-plugin-dumi-previewer\": \"0.3.3\",\n    \"@vuepress-dumi/vuepress-theme-dumi\": \"0.3.3\",\n    \"@vuepress/plugin-back-to-top\": \"^1.8.2\",\n    \"@vuepress/plugin-medium-zoom\": \"^1.8.2\",\n    \"codesandbox\": \"^2.2.3\",\n    \"core-js\": \"^2.4.0\",\n    \"element-ui\": \"^2.15.7\",\n    \"sass\": \"^1.34.1\",\n    \"ts-import-plugin\": \"^2.0.0\",\n    \"ttypescript\": \"^1.5.15\",\n    \"vue\": \"^2.6.0\",\n    \"vuepress\": \"^1.8.2\",\n    \"vuepress-plugin-typescript\": \"^0.3.1\"\n  },\n  \"dependencies\": {\n    \"@formily/core\": \"2.3.7\",\n    \"@formily/grid\": \"2.3.7\",\n    \"@formily/json-schema\": \"2.3.7\",\n    \"@formily/reactive\": \"2.3.7\",\n    \"@formily/reactive-vue\": \"2.3.7\",\n    \"@formily/shared\": \"2.3.7\",\n    \"@formily/vue\": \"2.3.7\",\n    \"portal-vue\": \"^2.1.7\",\n    \"vue-demi\": \">=0.13.6\",\n    \"vue-slicksort\": \"^1.2.0\"\n  },\n  \"peerDependencies\": {\n    \"@vue/composition-api\": \"^1.0.0-beta.1\",\n    \"element-ui\": \"^2.14.0\",\n    \"vue\": \"^2.6.0\"\n  },\n  \"peerDependenciesMeta\": {\n    \"@vue/composition-api\": {\n      \"optional\": true\n    }\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"gitHead\": \"ac79c196ae9324889aca5e0501146f9b37b04283\"\n}\n"
  },
  {
    "path": "packages/element/rollup.config.js",
    "content": "import baseConfig, {\n  removeImportStyleFromInputFilePlugin,\n} from '../../scripts/rollup.base.js'\n\nexport default baseConfig(\n  'formily.element',\n  'Formily.Element',\n  removeImportStyleFromInputFilePlugin()\n)\n"
  },
  {
    "path": "packages/element/src/__builtins__/configs/index.ts",
    "content": "export const stylePrefix = 'formily-element'\n"
  },
  {
    "path": "packages/element/src/__builtins__/index.ts",
    "content": "export * from './configs'\nexport * from './shared'\n"
  },
  {
    "path": "packages/element/src/__builtins__/shared/create-context.ts",
    "content": "import type { Component } from 'vue'\nimport {\n  defineComponent,\n  inject,\n  InjectionKey,\n  provide,\n  readonly,\n  ref,\n  Ref,\n  toRef,\n} from 'vue-demi'\n\nexport type CreateContext<T> = {\n  Provider: Component\n  Consumer: Component\n  injectKey: InjectionKey<Ref<T>>\n}\n\nexport const createContext = <T>(defaultValue?: T): CreateContext<T> => {\n  const injectKey: InjectionKey<Ref<T>> = Symbol()\n\n  return {\n    Provider: defineComponent({\n      name: 'ContextProvider',\n      props: {\n        value: {\n          type: null,\n          default() {\n            return defaultValue ?? null\n          },\n        },\n      },\n      setup(props, { slots }) {\n        const value = toRef(props, 'value')\n        provide(injectKey, readonly(value))\n\n        return () => slots?.default?.()\n      },\n    }),\n\n    Consumer: defineComponent({\n      name: 'ContextConsumer',\n      setup(_props, { slots }) {\n        const value = inject(injectKey)\n\n        return () => slots?.default?.(value)\n      },\n    }),\n    injectKey,\n  }\n}\n\nexport const useContext = <T>(context: CreateContext<T>) => {\n  const key = context.injectKey\n\n  return inject(key, ref(null))\n}\n"
  },
  {
    "path": "packages/element/src/__builtins__/shared/index.ts",
    "content": "export * from './transform-component'\nexport * from './resolve-component'\nexport * from './create-context'\nexport * from './utils'\nexport * from './portal'\nexport * from './loading'\nexport * from './types'\n"
  },
  {
    "path": "packages/element/src/__builtins__/shared/loading.ts",
    "content": "import { Loading } from 'element-ui'\n\nexport const loading = async (\n  loadingText = 'Loading...',\n  processor: () => Promise<any>\n) => {\n  let loadingInstance = null\n  let loading = setTimeout(() => {\n    loadingInstance = Loading.service({\n      text: loadingText,\n      background: 'transparent',\n    })\n  }, 100)\n  try {\n    return await processor()\n  } finally {\n    loadingInstance?.close()\n    clearTimeout(loading)\n  }\n}\n"
  },
  {
    "path": "packages/element/src/__builtins__/shared/portal.ts",
    "content": "import { Fragment, h } from '@formily/vue'\nimport { defineComponent, onBeforeUnmount } from 'vue-demi'\nexport interface IPortalProps {\n  id?: string | symbol\n}\n\nconst PortalMap = new Map<string | symbol, any>()\n\nexport const createPortalProvider = (id: string | symbol) => {\n  const Portal = defineComponent({\n    name: 'ProtalProvider',\n    props: {\n      id: {\n        type: [String, Symbol],\n        default: id,\n      },\n    },\n\n    setup(props) {\n      onBeforeUnmount(() => {\n        const { id } = props\n        if (id && PortalMap.has(id)) {\n          PortalMap.delete(id)\n        }\n      })\n    },\n\n    render() {\n      const { id } = this\n      if (id && !PortalMap.has(id)) {\n        PortalMap.set(id, this)\n      }\n\n      return h(Fragment, {}, this.$scopedSlots)\n    },\n  })\n\n  return Portal\n}\n\nexport function getProtalContext(id: string | symbol) {\n  return PortalMap.get(id)\n}\n"
  },
  {
    "path": "packages/element/src/__builtins__/shared/resolve-component.ts",
    "content": "import { Component } from 'vue'\nimport { h, toRaw } from 'vue-demi'\nimport { SlotTypes } from '.'\nimport { isVnode } from './utils'\n\nexport const resolveComponent = (\n  child?: SlotTypes,\n  props?: Record<string, any>\n) => {\n  if (child) {\n    if (typeof child === 'string' || typeof child === 'number') {\n      return child\n    } else if (typeof child === 'function') {\n      return (child as Function)(props)\n    } else if (isVnode(child)) {\n      return child\n    } else {\n      return h(toRaw(child as Component), { props })\n    }\n  }\n\n  return null\n}\n"
  },
  {
    "path": "packages/element/src/__builtins__/shared/transform-component.ts",
    "content": "import type { Component } from 'vue'\nimport { merge } from '@formily/shared'\nimport { h } from '@formily/vue'\nimport { isVue2, defineComponent } from 'vue-demi'\n\ntype ListenersTransformRules = Record<string, string>\nconst noop = () => {}\n\nexport const transformComponent = <T extends Record<string, any>>(\n  tag: any,\n  transformRules?: ListenersTransformRules,\n  defaultProps?: Partial<T>\n): Component<T> | any => {\n  if (isVue2) {\n    return defineComponent({\n      setup(props, { attrs, slots, listeners }) {\n        return () => {\n          const data = {\n            attrs: {\n              ...attrs,\n            },\n            on: {\n              ...listeners,\n            },\n          }\n\n          if (transformRules) {\n            const transformListeners = transformRules\n            Object.keys(transformListeners).forEach((extract) => {\n              if (data.on !== undefined) {\n                data.on[transformListeners[extract]] = listeners[extract] || noop\n              }\n            })\n          }\n          if (defaultProps) {\n            data.attrs = merge(defaultProps, data.attrs)\n          }\n\n          return h(tag, data, slots)\n        }\n      },\n    })\n  } else {\n    return defineComponent({\n      setup(props, { attrs, slots }) {\n        return () => {\n          let data = {\n            ...attrs,\n          }\n          if (transformRules) {\n            const listeners = transformRules\n            Object.keys(listeners).forEach((extract) => {\n              const event = listeners[extract]\n              data[`on${event[0].toUpperCase()}${event.slice(1)}`] =\n                attrs[`on${extract[0].toUpperCase()}${extract.slice(1)}`] || noop\n            })\n          }\n          if (defaultProps) {\n            data = merge(defaultProps, data)\n          }\n          return h(tag, data, slots)\n        }\n      },\n    })\n  }\n}\n"
  },
  {
    "path": "packages/element/src/__builtins__/shared/types.ts",
    "content": "import { Component, VNode } from 'vue'\n\nexport type SlotTypes =\n  | Component\n  | string\n  | number\n  | ((props: Record<string, any>) => VNode[] | VNode)\n  | VNode\n"
  },
  {
    "path": "packages/element/src/__builtins__/shared/utils.ts",
    "content": "import { onMounted, ref } from 'vue-demi'\n\nexport function isValidElement(element) {\n  return (\n    isVueOptions(element) ||\n    (element &&\n      typeof element === 'object' &&\n      'componentOptions' in element &&\n      'context' in element &&\n      element.tag !== undefined)\n  ) // remove text node\n}\n\nexport function isVnode(element: any): boolean {\n  return (\n    element &&\n    typeof element === 'object' &&\n    'componentOptions' in element &&\n    'context' in element &&\n    element.tag !== undefined\n  )\n}\n\nexport function isVueOptions(options) {\n  return (\n    options &&\n    (typeof options.template === 'string' ||\n      typeof options.render === 'function')\n  )\n}\n\nexport function composeExport<T0 extends {}, T1 extends {}>(\n  s0: T0,\n  s1: T1\n): T0 & T1 {\n  return Object.assign(s0, s1)\n}\n\n/**\n * 处理 vue 2.6 和 2.7 的 ref 兼容问题\n * composition-api 不支持 setup ref\n * @param refs\n * @returns\n */\nexport function useCompatRef(refs?: {\n  [key: string]: Vue | Element | Vue[] | Element[]\n}) {\n  const elRef = ref(null)\n  const elRefBinder = Math.random().toString(36).slice(-8)\n\n  onMounted(() => {\n    if (refs) {\n      elRef.value = refs[elRefBinder]\n    }\n  })\n\n  return {\n    elRef,\n    elRefBinder: refs ? elRefBinder : elRef,\n  }\n}\n"
  },
  {
    "path": "packages/element/src/__builtins__/styles/common.scss",
    "content": "$formily-prefix: 'formily-element';\n$namespace: 'el';\n@import '~element-ui/packages/theme-chalk/src/common/var.scss';\n\n@mixin active {\n  border-color: $--color-primary;\n  outline: 0;\n  border-right-width: $--border-width-base !important;\n}\n\n@mixin hover {\n  border-color: $--border-color-hover;\n  outline: 0;\n  border-right-width: $--border-width-base !important;\n}\n"
  },
  {
    "path": "packages/element/src/array-base/index.ts",
    "content": "import { ArrayField } from '@formily/core'\nimport { clone, isValid, uid } from '@formily/shared'\nimport {\n  ExpressionScope,\n  Fragment,\n  h,\n  useField,\n  useFieldSchema,\n} from '@formily/vue'\nimport {\n  defineComponent,\n  inject,\n  InjectionKey,\n  onBeforeUnmount,\n  PropType,\n  provide,\n  Ref,\n  ref,\n  toRefs,\n} from 'vue-demi'\nimport { stylePrefix } from '../__builtins__/configs'\n\nimport type { Schema } from '@formily/json-schema'\nimport type { Button as ButtonProps } from 'element-ui'\nimport { Button } from 'element-ui'\nimport { HandleDirective } from 'vue-slicksort'\nimport { composeExport } from '../__builtins__/shared'\n\nexport interface IArrayBaseAdditionProps extends ButtonProps {\n  title?: string\n  method?: 'push' | 'unshift'\n  defaultValue?: any\n}\n\nexport type ArrayBaseMixins = {\n  Addition?: typeof ArrayBaseAddition\n  Remove?: typeof ArrayBaseRemove\n  MoveUp?: typeof ArrayBaseMoveUp\n  MoveDown?: typeof ArrayBaseMoveDown\n  SortHandle?: typeof ArrayBaseSortHandle\n  Index?: typeof ArrayBaseIndex\n  useArray?: typeof useArray\n  useIndex?: typeof useIndex\n  useRecord?: typeof useRecord\n}\n\nexport interface IArrayBaseProps {\n  disabled?: boolean\n  keyMap?: WeakMap<Object, String> | String[] | null\n}\n\nexport interface IArrayBaseItemProps {\n  index: number\n  record: any\n}\n\nexport interface IArrayBaseContext {\n  field: Ref<ArrayField>\n  schema: Ref<Schema>\n  props: IArrayBaseProps\n  listeners: {\n    [key in string]?: Function\n  }\n  keyMap?: WeakMap<Object, String> | String[] | null\n}\n\nconst ArrayBaseSymbol: InjectionKey<IArrayBaseContext> =\n  Symbol('ArrayBaseContext')\nconst ItemSymbol: InjectionKey<IArrayBaseItemProps> = Symbol('ItemContext')\n\nconst useArray = () => {\n  return inject(ArrayBaseSymbol, null)\n}\n\nconst useIndex = (index?: number) => {\n  const { index: indexRef } = toRefs(inject(ItemSymbol))\n  return indexRef ?? ref(index)\n}\n\nconst useRecord = (record?: number) => {\n  const { record: recordRef } = toRefs(inject(ItemSymbol))\n  return recordRef ?? ref(record)\n}\n\nconst isObjectValue = (schema: Schema) => {\n  if (Array.isArray(schema?.items)) return isObjectValue(schema.items[0])\n\n  if (schema?.items?.type === 'array' || schema?.items?.type === 'object') {\n    return true\n  }\n  return false\n}\n\nconst useKey = (schema: Schema) => {\n  const isObject = isObjectValue(schema)\n  let keyMap: WeakMap<Object, String> | String[] | null = null\n\n  if (isObject) {\n    keyMap = new WeakMap()\n  } else {\n    keyMap = []\n  }\n\n  onBeforeUnmount(() => {\n    keyMap = null\n  })\n\n  return {\n    keyMap,\n    getKey: (record: any, index?: number) => {\n      if (keyMap instanceof WeakMap) {\n        if (!keyMap.has(record)) {\n          keyMap.set(record, uid())\n        }\n        return `${keyMap.get(record)}-${index}`\n      }\n\n      if (!keyMap[index]) {\n        keyMap[index] = uid()\n      }\n\n      return `${keyMap[index]}-${index}`\n    },\n  }\n}\n\nconst getDefaultValue = (defaultValue: any, schema: Schema): any => {\n  if (isValid(defaultValue)) return clone(defaultValue)\n  if (Array.isArray(schema?.items))\n    return getDefaultValue(defaultValue, schema.items[0])\n  if (schema?.items?.type === 'array') return []\n  if (schema?.items?.type === 'boolean') return true\n  if (schema?.items?.type === 'date') return ''\n  if (schema?.items?.type === 'datetime') return ''\n  if (schema?.items?.type === 'number') return 0\n  if (schema?.items?.type === 'object') return {}\n  if (schema?.items?.type === 'string') return ''\n  return null\n}\n\nconst ArrayBaseInner = defineComponent<IArrayBaseProps>({\n  name: 'ArrayBase',\n  props: {\n    disabled: {\n      type: Boolean,\n      default: false,\n    },\n    keyMap: {\n      type: [WeakMap, Array] as PropType<WeakMap<Object, String> | String[]>,\n    },\n  },\n  setup(props, { slots, listeners }) {\n    const field = useField<ArrayField>()\n    const schema = useFieldSchema()\n\n    provide(ArrayBaseSymbol, {\n      field,\n      schema,\n      props,\n      listeners,\n      keyMap: props.keyMap,\n    })\n    return () => {\n      return h(Fragment, {}, slots)\n    }\n  },\n})\n\nconst ArrayBaseItem = defineComponent({\n  name: 'ArrayBaseItem',\n  props: ['index', 'record'],\n  setup(props: IArrayBaseItemProps, { slots }) {\n    provide(ItemSymbol, props)\n    return () => {\n      return h(\n        ExpressionScope,\n        { props: { value: { $record: props.record, $index: props.index } } },\n        {\n          default: () => h(Fragment, {}, slots),\n        }\n      )\n    }\n  },\n})\n\nconst ArrayBaseSortHandle = defineComponent({\n  name: 'ArrayBaseSortHandle',\n  props: ['index'],\n  directives: {\n    handle: HandleDirective,\n  },\n  setup(props, { attrs }) {\n    const array = useArray()\n    const prefixCls = `${stylePrefix}-array-base`\n\n    return () => {\n      if (!array) return null\n      if (array.field.value?.pattern !== 'editable') return null\n\n      return h(\n        Button,\n        {\n          directives: [{ name: 'handle' }],\n          class: [`${prefixCls}-sort-handle`],\n          attrs: {\n            size: 'mini',\n            type: 'text',\n            icon: 'el-icon-rank',\n            ...attrs,\n          },\n        },\n        {}\n      )\n    }\n  },\n})\n\nconst ArrayBaseIndex = defineComponent({\n  name: 'ArrayBaseIndex',\n  setup(props, { attrs }) {\n    const index = useIndex()\n    const prefixCls = `${stylePrefix}-array-base`\n    return () => {\n      return h(\n        'span',\n        {\n          class: `${prefixCls}-index`,\n          attrs,\n        },\n        {\n          default: () => [`#${index.value + 1}.`],\n        }\n      )\n    }\n  },\n})\n\nconst ArrayBaseAddition = defineComponent({\n  name: 'ArrayBaseAddition',\n  props: ['title', 'method', 'defaultValue'],\n  setup(props: IArrayBaseAdditionProps, { listeners }) {\n    const self = useField()\n    const array = useArray()\n    const prefixCls = `${stylePrefix}-array-base`\n    return () => {\n      if (!array) return null\n      if (array?.field.value.pattern !== 'editable') return null\n      return h(\n        Button,\n        {\n          class: `${prefixCls}-addition`,\n          attrs: {\n            type: 'ghost',\n            icon: 'qax-icon-Alone-Plus',\n            ...props,\n          },\n          on: {\n            ...listeners,\n            click: (e) => {\n              if (array.props?.disabled) return\n              const defaultValue = getDefaultValue(\n                props.defaultValue,\n                array?.schema.value\n              )\n              if (props.method === 'unshift') {\n                array?.field?.value.unshift(defaultValue)\n                array.listeners?.add?.(0)\n              } else {\n                array?.field?.value.push(defaultValue)\n                array.listeners?.add?.(array?.field?.value?.value?.length - 1)\n              }\n              if (listeners.click) {\n                listeners.click(e)\n              }\n            },\n          },\n        },\n        {\n          default: () => [self.value.title || props.title],\n        }\n      )\n    }\n  },\n})\n\nconst ArrayBaseRemove = defineComponent<\n  ButtonProps & { title?: string; index?: number }\n>({\n  name: 'ArrayBaseRemove',\n  props: ['title', 'index'],\n  setup(props, { attrs, listeners }) {\n    const indexRef = useIndex(props.index)\n    const base = useArray()\n    const prefixCls = `${stylePrefix}-array-base`\n    return () => {\n      if (base?.field.value.pattern !== 'editable') return null\n      return h(\n        Button,\n        {\n          class: `${prefixCls}-remove`,\n          attrs: {\n            type: 'text',\n            size: 'mini',\n            icon: 'el-icon-delete',\n            ...attrs,\n          },\n          on: {\n            ...listeners,\n            click: (e: MouseEvent) => {\n              e.stopPropagation()\n              if (Array.isArray(base?.keyMap)) {\n                base?.keyMap?.splice(indexRef.value, 1)\n              }\n\n              base?.field.value.remove(indexRef.value as number)\n              base?.listeners?.remove?.(indexRef.value as number)\n\n              if (listeners.click) {\n                listeners.click(e)\n              }\n            },\n          },\n        },\n        {\n          default: () => [props.title],\n        }\n      )\n    }\n  },\n})\n\nconst ArrayBaseMoveDown = defineComponent<\n  ButtonProps & { title?: string; index?: number }\n>({\n  name: 'ArrayBaseMoveDown',\n  props: ['title', 'index'],\n  setup(props, { attrs, listeners }) {\n    const indexRef = useIndex(props.index)\n    const base = useArray()\n    const prefixCls = `${stylePrefix}-array-base`\n    return () => {\n      if (base?.field.value.pattern !== 'editable') return null\n      return h(\n        Button,\n        {\n          class: `${prefixCls}-move-down`,\n          attrs: {\n            size: 'mini',\n            type: 'text',\n            icon: 'el-icon-arrow-down',\n            ...attrs,\n          },\n          on: {\n            ...listeners,\n            click: (e: MouseEvent) => {\n              e.stopPropagation()\n              if (Array.isArray(base?.keyMap)) {\n                base.keyMap.splice(\n                  indexRef.value + 1,\n                  0,\n                  base.keyMap.splice(indexRef.value, 1)[0]\n                )\n              }\n\n              base?.field.value.moveDown(indexRef.value as number)\n              base?.listeners?.moveDown?.(indexRef.value as number)\n\n              if (listeners.click) {\n                listeners.click(e)\n              }\n            },\n          },\n        },\n        {\n          default: () => [props.title],\n        }\n      )\n    }\n  },\n})\n\nconst ArrayBaseMoveUp = defineComponent<\n  ButtonProps & { title?: string; index?: number }\n>({\n  name: 'ArrayBaseMoveUp',\n  props: ['title', 'index'],\n  setup(props, { attrs, listeners }) {\n    const indexRef = useIndex(props.index)\n    const base = useArray()\n    const prefixCls = `${stylePrefix}-array-base`\n    return () => {\n      if (base?.field.value.pattern !== 'editable') return null\n      return h(\n        Button,\n        {\n          class: `${prefixCls}-move-up`,\n          attrs: {\n            size: 'mini',\n            type: 'text',\n            icon: 'el-icon-arrow-up',\n            ...attrs,\n          },\n          on: {\n            ...listeners,\n            click: (e: MouseEvent) => {\n              e.stopPropagation()\n              if (Array.isArray(base?.keyMap)) {\n                base.keyMap.splice(\n                  indexRef.value - 1,\n                  0,\n                  base.keyMap.splice(indexRef.value, 1)[0]\n                )\n              }\n\n              base?.field.value.moveUp(indexRef.value as number)\n              base?.listeners?.moveUp?.(indexRef.value as number)\n\n              if (listeners.click) {\n                listeners.click(e)\n              }\n            },\n          },\n        },\n        {\n          default: () => [props.title],\n        }\n      )\n    }\n  },\n})\n\nexport const ArrayBase = composeExport(ArrayBaseInner, {\n  Index: ArrayBaseIndex,\n  Item: ArrayBaseItem,\n  SortHandle: ArrayBaseSortHandle,\n  Addition: ArrayBaseAddition,\n  Remove: ArrayBaseRemove,\n  MoveDown: ArrayBaseMoveDown,\n  MoveUp: ArrayBaseMoveUp,\n  useArray: useArray,\n  useIndex: useIndex,\n  useKey: useKey,\n  useRecord: useRecord,\n})\n\nexport default ArrayBase\n"
  },
  {
    "path": "packages/element/src/array-base/style.scss",
    "content": "@import '../__builtins__/styles/common.scss';\n\n$array-base-prefix-cls: '#{$formily-prefix}-array-base';\n\n.#{$array-base-prefix-cls}-addition {\n  transition: $--all-transition;\n}\n\n.#{$array-base-prefix-cls}-remove {\n  i {\n    font-size: $--font-size-base;\n  }\n}\n\n.#{$array-base-prefix-cls}-move-down {\n  i {\n    font-size: $--font-size-base;\n  }\n}\n\n.#{$array-base-prefix-cls}-move-up {\n  i {\n    font-size: $--font-size-base;\n  }\n}\n\n.#{$array-base-prefix-cls}-sort-handle {\n  i {\n    font-size: $--font-size-base;\n    cursor: move;\n  }\n}\n"
  },
  {
    "path": "packages/element/src/array-base/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/button.scss'\nimport './style.scss'\n"
  },
  {
    "path": "packages/element/src/array-cards/index.ts",
    "content": "import { ArrayField } from '@formily/core'\nimport { ISchema } from '@formily/json-schema'\nimport { observer } from '@formily/reactive-vue'\nimport { h, RecursionField, useField, useFieldSchema } from '@formily/vue'\nimport type { Card as CardProps } from 'element-ui'\nimport { Card, Empty, Row } from 'element-ui'\nimport { defineComponent } from 'vue-demi'\nimport { ArrayBase } from '../array-base'\nimport { stylePrefix } from '../__builtins__/configs'\nimport { composeExport } from '../__builtins__/shared'\n\nconst isAdditionComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Addition') > -1\n}\n\nconst isIndexComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Index') > -1\n}\n\nconst isRemoveComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Remove') > -1\n}\n\nconst isMoveUpComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('MoveUp') > -1\n}\n\nconst isMoveDownComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('MoveDown') > -1\n}\n\nconst isOperationComponent = (schema: ISchema) => {\n  return (\n    isAdditionComponent(schema) ||\n    isRemoveComponent(schema) ||\n    isMoveDownComponent(schema) ||\n    isMoveUpComponent(schema)\n  )\n}\nconst ArrayCardsInner = observer(\n  defineComponent<CardProps>({\n    name: 'FArrayCards',\n    props: [],\n    setup(props, { attrs }) {\n      const fieldRef = useField<ArrayField>()\n      const schemaRef = useFieldSchema()\n      const prefixCls = `${stylePrefix}-array-cards`\n      const { getKey, keyMap } = ArrayBase.useKey(schemaRef.value)\n\n      return () => {\n        const field = fieldRef.value\n        const schema = schemaRef.value\n        const dataSource = Array.isArray(field.value) ? field.value : []\n        if (!schema) throw new Error('can not found schema object')\n\n        const renderItems = () => {\n          return dataSource?.map((item, index) => {\n            const items = Array.isArray(schema.items)\n              ? schema.items[index] || schema.items[0]\n              : schema.items\n\n            const title = h(\n              'span',\n              {},\n              {\n                default: () => [\n                  h(\n                    RecursionField,\n                    {\n                      props: {\n                        schema: items,\n                        name: index,\n                        filterProperties: (schema) => {\n                          if (!isIndexComponent(schema)) return false\n                          return true\n                        },\n                        onlyRenderProperties: true,\n                      },\n                    },\n                    {}\n                  ),\n                  attrs.title || field.title,\n                ],\n              }\n            )\n            const extra = h(\n              'span',\n              {},\n              {\n                default: () => [\n                  h(\n                    RecursionField,\n                    {\n                      props: {\n                        schema: items,\n                        name: index,\n                        filterProperties: (schema) => {\n                          if (!isOperationComponent(schema)) return false\n                          return true\n                        },\n                        onlyRenderProperties: true,\n                      },\n                    },\n                    {}\n                  ),\n                  attrs.extra,\n                ],\n              }\n            )\n            const content = h(\n              RecursionField,\n              {\n                props: {\n                  schema: items,\n                  name: index,\n                  filterProperties: (schema) => {\n                    if (isIndexComponent(schema)) return false\n                    if (isOperationComponent(schema)) return false\n                    return true\n                  },\n                },\n              },\n              {}\n            )\n\n            return h(\n              ArrayBase.Item,\n              {\n                key: getKey(item, index),\n                props: {\n                  index,\n                  record: item,\n                },\n              },\n              {\n                default: () =>\n                  h(\n                    Card,\n                    {\n                      class: [`${prefixCls}-item`],\n                      attrs: {\n                        shadow: 'never',\n                        ...attrs,\n                      },\n                    },\n                    {\n                      default: () => [content],\n                      header: () =>\n                        h(\n                          Row,\n                          {\n                            props: {\n                              type: 'flex',\n                              justify: 'space-between',\n                            },\n                          },\n                          {\n                            default: () => [title, extra],\n                          }\n                        ),\n                    }\n                  ),\n              }\n            )\n          })\n        }\n        const renderAddition = () => {\n          return schema.reduceProperties((addition, schema) => {\n            if (isAdditionComponent(schema)) {\n              return h(\n                RecursionField,\n                {\n                  props: {\n                    schema,\n                    name: 'addition',\n                  },\n                },\n                {}\n              )\n            }\n            return addition\n          }, null)\n        }\n        const renderEmpty = () => {\n          if (dataSource?.length) return\n          return h(\n            Card,\n            {\n              class: [`${prefixCls}-item`],\n              attrs: {\n                shadow: 'never',\n                ...attrs,\n                header: attrs.title || field.title,\n              },\n            },\n            {\n              default: () =>\n                h(\n                  Empty,\n                  { props: { description: 'No Data', imageSize: 100 } },\n                  {}\n                ),\n            }\n          )\n        }\n\n        return h(\n          'div',\n          {\n            class: [prefixCls],\n          },\n          {\n            default: () =>\n              h(\n                ArrayBase,\n                {\n                  props: {\n                    keyMap,\n                  },\n                },\n                {\n                  default: () => [\n                    renderEmpty(),\n                    renderItems(),\n                    renderAddition(),\n                  ],\n                }\n              ),\n          }\n        )\n      }\n    },\n  })\n)\n\nexport const ArrayCards = composeExport(ArrayCardsInner, {\n  Index: ArrayBase.Index,\n  SortHandle: ArrayBase.SortHandle,\n  Addition: ArrayBase.Addition,\n  Remove: ArrayBase.Remove,\n  MoveDown: ArrayBase.MoveDown,\n  MoveUp: ArrayBase.MoveUp,\n  useArray: ArrayBase.useArray,\n  useIndex: ArrayBase.useIndex,\n  useRecord: ArrayBase.useRecord,\n})\n\nexport default ArrayCards\n"
  },
  {
    "path": "packages/element/src/array-cards/style.scss",
    "content": "@import '../__builtins__/styles/common.scss';\n\n$array-table-prefix-cls: '#{$formily-prefix}-array-cards';\n\n.#{$array-table-prefix-cls} {\n  .el-card__header {\n    padding-top: 12.5px;\n    padding-bottom: 12.5px;\n  }\n  .el-empty {\n    padding: 0;\n  }\n\n  .#{$array-table-prefix-cls}-item {\n    margin-bottom: 10px;\n  }\n\n  .#{$formily-prefix}-array-base-addition {\n    width: 100%;\n    border: $--border-width-base dashed $--border-color-base;\n\n    &:hover {\n      background-color: $--color-white;\n      border-color: $--border-color-hover;\n    }\n\n    &:active,\n    &:focus {\n      background-color: $--color-white;\n      border-color: $--color-primary;\n    }\n  }\n}\n"
  },
  {
    "path": "packages/element/src/array-cards/style.ts",
    "content": "import './style.scss'\nimport 'element-ui/packages/theme-chalk/src/card.scss'\nimport 'element-ui/packages/theme-chalk/src/empty.scss'\nimport 'element-ui/packages/theme-chalk/src/row.scss'\n\n// 依赖\nimport '../array-base/style'\n"
  },
  {
    "path": "packages/element/src/array-collapse/index.ts",
    "content": "import { ArrayField } from '@formily/core'\nimport { ISchema } from '@formily/json-schema'\nimport { observer } from '@formily/reactive-vue'\nimport {\n  Fragment,\n  h,\n  RecursionField,\n  useField,\n  useFieldSchema,\n} from '@formily/vue'\nimport type {\n  Collapse as CollapseProps,\n  CollapseItem as CollapseItemProps,\n} from 'element-ui'\nimport { Badge, Card, Collapse, CollapseItem, Empty, Row } from 'element-ui'\nimport { defineComponent, ref, Ref, watchEffect } from 'vue-demi'\nimport { ArrayBase } from '../array-base'\nimport { stylePrefix } from '../__builtins__/configs'\nimport { composeExport } from '../__builtins__/shared'\n\nexport interface IArrayCollapseProps extends CollapseProps {\n  defaultOpenPanelCount?: number\n}\n\nconst isAdditionComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Addition') > -1\n}\n\nconst isIndexComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Index') > -1\n}\n\nconst isRemoveComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Remove') > -1\n}\n\nconst isMoveUpComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('MoveUp') > -1\n}\n\nconst isMoveDownComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('MoveDown') > -1\n}\n\nconst isOperationComponent = (schema: ISchema) => {\n  return (\n    isAdditionComponent(schema) ||\n    isRemoveComponent(schema) ||\n    isMoveDownComponent(schema) ||\n    isMoveUpComponent(schema)\n  )\n}\n\nconst range = (count: number) => Array.from({ length: count }).map((_, i) => i)\n\nconst takeDefaultActiveKeys = (\n  dataSourceLength: number,\n  defaultOpenPanelCount: number,\n  accordion = false\n) => {\n  if (accordion) {\n    return 0\n  }\n  if (dataSourceLength < defaultOpenPanelCount) return range(dataSourceLength)\n\n  return range(defaultOpenPanelCount)\n}\n\nconst insertActiveKeys = (\n  activeKeys: number[] | number,\n  index: number,\n  accordion = false\n) => {\n  if (accordion) return index\n  if ((activeKeys as number[]).length <= index)\n    return (activeKeys as number[]).concat(index)\n  return (activeKeys as number[]).reduce((buf, key) => {\n    if (key < index) return buf.concat(key)\n    if (key === index) return buf.concat([key, key + 1])\n    return buf.concat(key + 1)\n  }, [])\n}\n\nexport const ArrayCollapseInner = observer(\n  defineComponent<IArrayCollapseProps>({\n    name: 'FArrayCollapse',\n    props: {\n      defaultOpenPanelCount: {\n        type: Number,\n        default: 5,\n      },\n    },\n    setup(props, { attrs }) {\n      const fieldRef = useField<ArrayField>()\n      const schemaRef = useFieldSchema()\n\n      const prefixCls = `${stylePrefix}-array-collapse`\n      const activeKeys: Ref<number[] | number> = ref([])\n\n      watchEffect(() => {\n        const field = fieldRef.value\n        const dataSource = Array.isArray(field.value) ? field.value.slice() : []\n        if (!field.modified && dataSource.length) {\n          activeKeys.value = takeDefaultActiveKeys(\n            dataSource.length,\n            props.defaultOpenPanelCount,\n            attrs.accordion as boolean\n          )\n        }\n      })\n\n      const { getKey, keyMap } = ArrayBase.useKey(schemaRef.value)\n\n      return () => {\n        const field = fieldRef.value\n        const schema = schemaRef.value\n        const dataSource = Array.isArray(field.value) ? field.value.slice() : []\n        if (!schema) throw new Error('can not found schema object')\n\n        const renderItems = () => {\n          if (!dataSource.length) {\n            return null\n          }\n\n          const items = dataSource?.map((item, index) => {\n            const items = Array.isArray(schema.items)\n              ? schema.items[index] || schema.items[0]\n              : schema.items\n            const key = getKey(item, index)\n            const panelProps = field\n              .query(`${field.address}.${index}`)\n              .get('componentProps')\n            const props: CollapseItemProps = items['x-component-props']\n            const headerTitle = panelProps?.title || props.title || field.title\n            const path = field.address.concat(index)\n            const errors = field.form.queryFeedbacks({\n              type: 'error',\n              address: `${path}.**`,\n            })\n\n            const title = h(\n              ArrayBase.Item,\n              {\n                props: {\n                  index,\n                  record: item,\n                },\n              },\n              {\n                default: () => [\n                  h(\n                    RecursionField,\n                    {\n                      props: {\n                        schema: items,\n                        name: index,\n                        filterProperties: (schema) => {\n                          if (!isIndexComponent(schema)) return false\n                          return true\n                        },\n                        onlyRenderProperties: true,\n                      },\n                    },\n                    {}\n                  ),\n                  errors.length\n                    ? h(\n                        Badge,\n                        {\n                          class: [`${prefixCls}-errors-badge`],\n                          props: {\n                            value: errors.length,\n                          },\n                        },\n                        { default: () => headerTitle }\n                      )\n                    : headerTitle,\n                ],\n              }\n            )\n            const extra = h(\n              ArrayBase.Item,\n              {\n                props: {\n                  index,\n                  record: item,\n                },\n              },\n              {\n                default: () => [\n                  h(\n                    RecursionField,\n                    {\n                      props: {\n                        schema: items,\n                        name: index,\n                        filterProperties: (schema) => {\n                          if (!isOperationComponent(schema)) return false\n                          return true\n                        },\n                        onlyRenderProperties: true,\n                      },\n                    },\n                    {}\n                  ),\n                ],\n              }\n            )\n            const content = h(\n              RecursionField,\n              {\n                props: {\n                  schema: items,\n                  name: index,\n                  filterProperties: (schema) => {\n                    if (isIndexComponent(schema)) return false\n                    if (isOperationComponent(schema)) return false\n                    return true\n                  },\n                },\n              },\n              {}\n            )\n\n            return h(\n              CollapseItem,\n              {\n                attrs: {\n                  ...props,\n                  ...panelProps,\n                  name: index,\n                },\n                key,\n              },\n              {\n                default: () => [\n                  h(\n                    ArrayBase.Item,\n                    {\n                      props: {\n                        index,\n                        record: item,\n                      },\n                    },\n                    {\n                      default: () => [content],\n                    }\n                  ),\n                ],\n                title: () =>\n                  h(\n                    Row,\n                    {\n                      style: { flex: 1 },\n                      props: {\n                        type: 'flex',\n                        justify: 'space-between',\n                      },\n                    },\n                    {\n                      default: () => [\n                        h('span', {}, { default: () => title }),\n                        h('span', {}, { default: () => extra }),\n                      ],\n                    }\n                  ),\n              }\n            )\n          })\n\n          return h(\n            Collapse,\n            {\n              class: [`${prefixCls}-item`],\n              attrs: {\n                ...attrs,\n                value: activeKeys.value,\n              },\n              on: {\n                change: (keys: number[] | number) => {\n                  activeKeys.value = keys\n                },\n              },\n            },\n            {\n              default: () => [items],\n            }\n          )\n        }\n        const renderAddition = () => {\n          return schema.reduceProperties((addition, schema) => {\n            if (isAdditionComponent(schema)) {\n              return h(\n                RecursionField,\n                {\n                  props: {\n                    schema,\n                    name: 'addition',\n                  },\n                },\n                {}\n              )\n            }\n            return addition\n          }, null)\n        }\n        const renderEmpty = () => {\n          if (dataSource?.length) return\n          return h(\n            Card,\n            {\n              class: [`${prefixCls}-item`],\n              attrs: {\n                shadow: 'never',\n                ...attrs,\n                header: attrs.title || field.title,\n              },\n            },\n            {\n              default: () =>\n                h(\n                  Empty,\n                  { props: { description: 'No Data', imageSize: 100 } },\n                  {}\n                ),\n            }\n          )\n        }\n\n        return h(\n          'div',\n          {\n            class: [prefixCls],\n          },\n          {\n            default: () =>\n              h(\n                ArrayBase,\n                {\n                  props: {\n                    keyMap,\n                  },\n                  on: {\n                    add: (index: number) => {\n                      activeKeys.value = insertActiveKeys(\n                        activeKeys.value,\n                        index,\n                        attrs.accordion as boolean\n                      )\n                    },\n                  },\n                },\n                {\n                  default: () => [\n                    renderEmpty(),\n                    renderItems(),\n                    renderAddition(),\n                  ],\n                }\n              ),\n          }\n        )\n      }\n    },\n  })\n)\n\nexport const ArrayCollapseItem = defineComponent<CollapseItemProps>({\n  name: 'FArrayCollapseItem',\n  setup(_props, { slots }) {\n    return () => h(Fragment, {}, slots)\n  },\n})\n\nexport const ArrayCollapse = composeExport(ArrayCollapseInner, {\n  Item: ArrayCollapseItem,\n  Index: ArrayBase.Index,\n  SortHandle: ArrayBase.SortHandle,\n  Addition: ArrayBase.Addition,\n  Remove: ArrayBase.Remove,\n  MoveDown: ArrayBase.MoveDown,\n  MoveUp: ArrayBase.MoveUp,\n  useArray: ArrayBase.useArray,\n  useIndex: ArrayBase.useIndex,\n  useRecord: ArrayBase.useRecord,\n})\n\nexport default ArrayCollapse\n"
  },
  {
    "path": "packages/element/src/array-collapse/style.scss",
    "content": "@import '../__builtins__/styles/common.scss';\n\n$array-table-prefix-cls: '#{$formily-prefix}-array-collapse';\n\n.#{$array-table-prefix-cls} {\n  .el-card__header {\n    padding-top: 12.5px;\n    padding-bottom: 12.5px;\n  }\n  .el-empty {\n    padding: 0;\n  }\n\n  .#{$array-table-prefix-cls}-item {\n    margin-bottom: 10px;\n  }\n\n  .#{$array-table-prefix-cls}-errors-badge {\n    line-height: 1;\n    vertical-align: initial;\n  }\n\n  .#{$formily-prefix}-array-base-addition {\n    width: 100%;\n    border: $--border-width-base dashed $--border-color-base;\n\n    &:hover {\n      background-color: $--color-white;\n      border-color: $--border-color-hover;\n    }\n\n    &:active,\n    &:focus {\n      background-color: $--color-white;\n      border-color: $--color-primary;\n    }\n  }\n}\n"
  },
  {
    "path": "packages/element/src/array-collapse/style.ts",
    "content": "import './style.scss'\nimport 'element-ui/packages/theme-chalk/src/empty.scss'\nimport 'element-ui/packages/theme-chalk/src/row.scss'\nimport 'element-ui/packages/theme-chalk/src/collapse.scss'\nimport 'element-ui/packages/theme-chalk/src/collapse-item.scss'\nimport 'element-ui/packages/theme-chalk/src/card.scss'\nimport 'element-ui/packages/theme-chalk/src/badge.scss'\n\n// 依赖\nimport '../array-base/style'\n"
  },
  {
    "path": "packages/element/src/array-items/index.ts",
    "content": "import { ArrayField } from '@formily/core'\nimport { ISchema } from '@formily/json-schema'\nimport { observer } from '@formily/reactive-vue'\nimport { h, RecursionField, useField, useFieldSchema } from '@formily/vue'\nimport { defineComponent } from 'vue-demi'\nimport { SlickItem, SlickList } from 'vue-slicksort'\nimport { ArrayBase } from '../array-base'\nimport { stylePrefix } from '../__builtins__/configs'\nimport { composeExport } from '../__builtins__/shared'\n\nconst isAdditionComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf('Addition') > -1\n}\n\nexport interface IArrayItemsItemProps {\n  type?: 'card' | 'divide'\n}\n\nconst ArrayItemsInner = observer(\n  defineComponent({\n    name: 'FArrayItems',\n    setup() {\n      const fieldRef = useField<ArrayField>()\n      const schemaRef = useFieldSchema()\n\n      const prefixCls = `${stylePrefix}-array-items`\n      const { getKey, keyMap } = ArrayBase.useKey(schemaRef.value)\n\n      return () => {\n        const field = fieldRef.value\n        const schema = schemaRef.value\n        const dataSource = Array.isArray(field.value) ? field.value.slice() : []\n\n        const renderItems = () => {\n          const items = dataSource?.map((item, index) => {\n            const items = Array.isArray(schema.items)\n              ? schema.items[index] || schema.items[0]\n              : schema.items\n            const key = getKey(item, index)\n            return h(\n              ArrayBase.Item,\n              {\n                key,\n                props: {\n                  index,\n                  record: item,\n                },\n              },\n              {\n                default: () =>\n                  h(\n                    SlickItem,\n                    {\n                      class: [`${prefixCls}-item-inner`],\n                      props: {\n                        index,\n                      },\n                      key,\n                    },\n                    {\n                      default: () =>\n                        h(\n                          RecursionField,\n                          {\n                            props: {\n                              schema: items,\n                              name: index,\n                            },\n                          },\n                          {}\n                        ),\n                    }\n                  ),\n              }\n            )\n          })\n\n          return h(\n            SlickList,\n            {\n              class: [`${prefixCls}-list`],\n              props: {\n                useDragHandle: true,\n                lockAxis: 'y',\n                helperClass: `${prefixCls}-sort-helper`,\n                value: [],\n              },\n              on: {\n                'sort-end': ({ oldIndex, newIndex }) => {\n                  if (Array.isArray(keyMap)) {\n                    keyMap.splice(newIndex, 0, keyMap.splice(oldIndex, 1)[0])\n                  }\n                  field.move(oldIndex, newIndex)\n                },\n              },\n            },\n            { default: () => items }\n          )\n        }\n        const renderAddition = () => {\n          return schema.reduceProperties((addition, schema) => {\n            if (isAdditionComponent(schema)) {\n              return h(\n                RecursionField,\n                {\n                  props: {\n                    schema,\n                    name: 'addition',\n                  },\n                },\n                {}\n              )\n            }\n            return addition\n          }, null)\n        }\n\n        return h(\n          ArrayBase,\n          {\n            props: {\n              keyMap,\n            },\n          },\n          {\n            default: () =>\n              h(\n                'div',\n                {\n                  class: [prefixCls],\n                  on: {\n                    change: () => {},\n                  },\n                },\n                {\n                  default: () => [renderItems(), renderAddition()],\n                }\n              ),\n          }\n        )\n      }\n    },\n  })\n)\n\nconst ArrayItemsItem = defineComponent<IArrayItemsItemProps>({\n  name: 'FArrayItemsItem',\n  props: ['type'],\n  setup(props, { attrs, slots }) {\n    const prefixCls = `${stylePrefix}-array-items`\n\n    return () =>\n      h(\n        'div',\n        {\n          class: [`${prefixCls}-${props.type || 'card'}`],\n          attrs: {\n            ...attrs,\n          },\n          on: {\n            change: () => {},\n          },\n        },\n        slots\n      )\n  },\n})\n\nexport const ArrayItems = composeExport(ArrayItemsInner, {\n  Item: ArrayItemsItem,\n  Index: ArrayBase.Index,\n  SortHandle: ArrayBase.SortHandle,\n  Addition: ArrayBase.Addition,\n  Remove: ArrayBase.Remove,\n  MoveDown: ArrayBase.MoveDown,\n  MoveUp: ArrayBase.MoveUp,\n  useArray: ArrayBase.useArray,\n  useIndex: ArrayBase.useIndex,\n  useRecord: ArrayBase.useRecord,\n})\n\nexport default ArrayItems\n"
  },
  {
    "path": "packages/element/src/array-items/style.scss",
    "content": "@import '../__builtins__/styles/common.scss';\n\n$array-items-prefix-cls: '#{$formily-prefix}-array-items';\n\n.#{$array-items-prefix-cls}-item-inner {\n  visibility: visible;\n}\n\n.#{$array-items-prefix-cls} {\n  .#{$formily-prefix}-array-base-addition {\n    width: 100%;\n    border: $--border-width-base dashed $--border-color-base;\n\n    &:hover {\n      background-color: $--color-white;\n      border-color: $--border-color-hover;\n    }\n\n    &:active,\n    &:focus {\n      background-color: $--color-white;\n      border-color: $--color-primary;\n    }\n  }\n}\n\n.#{$array-items-prefix-cls}-card {\n  display: flex;\n  border: 1px solid $--card-border-color;\n  margin-bottom: 10px;\n  padding: 3px 6px;\n  background: $--color-white;\n  justify-content: space-between;\n\n  .#{$formily-prefix}-form-item:not(.#{$formily-prefix}-form-item-feedback-layout-popover) {\n    margin-bottom: 0 !important;\n\n    .#{$formily-prefix}-form-item-help {\n      position: absolute;\n      font-size: 12px;\n      top: 100%;\n      background: $--color-white;\n      width: 100%;\n      margin-top: 3px;\n      padding: 3px;\n      z-index: 1;\n      border-radius: 3px;\n      box-shadow: 0 0 10px $--border-color-base;\n    }\n  }\n}\n\n.#{$array-items-prefix-cls}-divide {\n  display: flex;\n  border-bottom: 1px solid $--card-border-color;\n  padding: 10px 0;\n  justify-content: space-between;\n\n  .#{$formily-prefix}-form-item:not(.#{$formily-prefix}-form-item-feedback-layout-popover) {\n    margin-bottom: 0 !important;\n\n    .#{$formily-prefix}-form-item-help {\n      position: absolute;\n      font-size: 12px;\n      top: 100%;\n      background: $--color-white;\n      width: 100%;\n      margin-top: 3px;\n      padding: 3px;\n      z-index: 1;\n      border-radius: 3px;\n      box-shadow: 0 0 10px $--card-border-color;\n    }\n  }\n}\n"
  },
  {
    "path": "packages/element/src/array-items/style.ts",
    "content": "import './style.scss'\n\n// 依赖\nimport '../array-base/style'\n"
  },
  {
    "path": "packages/element/src/array-table/index.ts",
    "content": "import {\n  ArrayField,\n  FieldDisplayTypes,\n  GeneralField,\n  IVoidFieldFactoryProps,\n} from '@formily/core'\nimport type { Schema } from '@formily/json-schema'\nimport { observer } from '@formily/reactive-vue'\nimport { isArr, isBool, isFn } from '@formily/shared'\nimport {\n  Fragment,\n  h,\n  RecursionField as _RecursionField,\n  useField,\n  useFieldSchema,\n} from '@formily/vue'\nimport type {\n  Pagination as PaginationProps,\n  Table as TableProps,\n  TableColumn as ElColumnProps,\n} from 'element-ui'\nimport {\n  Badge,\n  Option,\n  Pagination,\n  Select,\n  Table as ElTable,\n  TableColumn as ElTableColumn,\n} from 'element-ui'\nimport type { Component, VNode } from 'vue'\nimport { computed, defineComponent, inject, provide, ref, Ref } from 'vue-demi'\nimport { ArrayBase } from '../array-base'\nimport { Space } from '../space'\nimport { stylePrefix } from '../__builtins__/configs'\nimport { composeExport } from '../__builtins__/shared'\n\nconst RecursionField = _RecursionField as unknown as Component\n\ninterface IArrayTableProps extends TableProps {\n  pagination?: PaginationProps | boolean\n}\ninterface IArrayTablePaginationProps extends PaginationProps {\n  dataSource?: any[]\n}\n\ninterface ObservableColumnSource {\n  field: GeneralField\n  fieldProps: IVoidFieldFactoryProps<any, any>\n  columnProps: ElColumnProps & { title: string; asterisk: boolean }\n  schema: Schema\n  display: FieldDisplayTypes\n  required: boolean\n  name: string\n}\n\ntype ColumnProps = ElColumnProps & {\n  key: string | number\n  asterisk: boolean\n  render?: (\n    startIndex?: Ref<number>\n  ) => (props: {\n    row: Record<string, any>\n    column: ElColumnProps\n    $index: number\n  }) => VNode\n}\n\ninterface PaginationAction {\n  totalPage?: number\n  pageSize?: number\n  changePage?: (page: number) => void\n}\n\nconst PaginationSymbol = Symbol('pagination')\n\nconst isColumnComponent = (schema: Schema) => {\n  return schema['x-component']?.indexOf('Column') > -1\n}\n\nconst isOperationsComponent = (schema: Schema) => {\n  return schema['x-component']?.indexOf('Operations') > -1\n}\n\nconst isAdditionComponent = (schema: Schema) => {\n  return schema['x-component']?.indexOf('Addition') > -1\n}\n\nconst getArrayTableSources = (\n  arrayFieldRef: Ref<ArrayField>,\n  schemaRef: Ref<Schema>\n) => {\n  const arrayField = arrayFieldRef.value\n  const parseSources = (schema: Schema): ObservableColumnSource[] => {\n    if (\n      isColumnComponent(schema) ||\n      isOperationsComponent(schema) ||\n      isAdditionComponent(schema)\n    ) {\n      if (!schema['x-component-props']?.['prop'] && !schema['name']) return []\n      const name = schema['x-component-props']?.['prop'] || schema['name']\n      const field = arrayField.query(arrayField.address.concat(name)).take()\n      const fieldProps = field?.props || schema.toFieldProps()\n      const columnProps =\n        (field?.component as any[])?.[1] || schema['x-component-props'] || {}\n      const display = field?.display || schema['x-display']\n      const required = schema.reduceProperties((required, property) => {\n        if (required) {\n          return required\n        }\n        return !!property.required\n      }, false)\n\n      return [\n        {\n          name,\n          display,\n          required,\n          field,\n          fieldProps,\n          schema,\n          columnProps,\n        },\n      ]\n    } else if (schema.properties) {\n      return schema.reduceProperties((buf: any[], schema) => {\n        return buf.concat(parseSources(schema))\n      }, [])\n    } else {\n      return []\n    }\n  }\n\n  const parseArrayTable = (schema: Schema['items']) => {\n    if (!schema) return []\n    const sources: ObservableColumnSource[] = []\n    const items = isArr(schema) ? schema : ([schema] as Schema[])\n    return items.reduce((columns, schema) => {\n      const item = parseSources(schema)\n      if (item) {\n        return columns.concat(item)\n      }\n      return columns\n    }, sources)\n  }\n\n  if (!schemaRef.value) throw new Error('can not found schema object')\n\n  return parseArrayTable(schemaRef.value.items)\n}\n\nconst getArrayTableColumns = (\n  sources: ObservableColumnSource[]\n): ColumnProps[] => {\n  return sources.reduce(\n    (\n      buf: ColumnProps[],\n      { name, columnProps, schema, display, required },\n      key\n    ) => {\n      const { title, asterisk, ...props } = columnProps\n      if (display !== 'visible') return buf\n      if (!isColumnComponent(schema)) return buf\n\n      const render = (startIndex?: Ref<number>) => {\n        return columnProps?.type && columnProps?.type !== 'default'\n          ? undefined\n          : (props: {\n              row: Record<string, any>\n              column: ElColumnProps\n              $index: number\n            }): VNode => {\n              let index = (startIndex?.value ?? 0) + props.$index\n              // const index = reactiveDataSource.value.indexOf(props.row)\n\n              const children = h(\n                ArrayBase.Item,\n                { props: { index, record: props.row }, key: `${key}${index}` },\n                {\n                  default: () =>\n                    h(\n                      RecursionField,\n                      {\n                        props: {\n                          schema,\n                          name: index,\n                          onlyRenderProperties: true,\n                        },\n                      },\n                      {}\n                    ),\n                }\n              )\n              return children\n            }\n      }\n\n      return buf.concat({\n        label: title,\n        ...props,\n        key,\n        prop: name,\n        asterisk: asterisk ?? required,\n        render,\n      })\n    },\n    []\n  )\n}\n\nconst renderAddition = () => {\n  const schema = useFieldSchema()\n  return schema.value.reduceProperties((addition, schema) => {\n    if (isAdditionComponent(schema)) {\n      return h(\n        RecursionField,\n        {\n          props: {\n            schema,\n            name: 'addition',\n          },\n        },\n        {}\n      )\n    }\n    return addition\n  }, null)\n}\n\nconst schedulerRequest = {\n  request: null,\n}\n\nconst StatusSelect = observer(\n  defineComponent({\n    props: {\n      value: Number,\n      onChange: Function,\n      options: Array,\n      pageSize: Number,\n    },\n    setup(props) {\n      const fieldRef = useField<ArrayField>()\n      const prefixCls = `${stylePrefix}-array-table`\n\n      return () => {\n        const field = fieldRef.value\n        const width = String(props.options?.length).length * 15\n        const errors = field.errors\n        const parseIndex = (address: string) => {\n          return Number(\n            address\n              .slice(address.indexOf(field.address.toString()) + 1)\n              .match(/(\\d+)/)?.[1]\n          )\n        }\n\n        return h(\n          Select,\n          {\n            style: {\n              width: `${width < 60 ? 60 : width}px`,\n            },\n            class: [\n              `${prefixCls}-status-select`,\n              {\n                'has-error': errors?.length,\n              },\n            ],\n            props: {\n              value: props.value,\n              popperClass: `${prefixCls}-status-select-dropdown`,\n            },\n            on: {\n              input: props.onChange,\n            },\n          },\n          {\n            default: () => {\n              return props.options?.map(({ label, value }) => {\n                const hasError = errors.some(({ address }) => {\n                  const currentIndex = parseIndex(address)\n                  const startIndex = (value - 1) * props.pageSize\n                  const endIndex = value * props.pageSize\n                  return currentIndex >= startIndex && currentIndex <= endIndex\n                })\n\n                return h(\n                  Option,\n                  {\n                    key: value,\n                    props: {\n                      label,\n                      value,\n                    },\n                  },\n                  {\n                    default: () => {\n                      if (hasError) {\n                        return h(\n                          Badge,\n                          {\n                            props: {\n                              isDot: true,\n                            },\n                          },\n                          { default: () => label }\n                        )\n                      }\n\n                      return label\n                    },\n                  }\n                )\n              })\n            },\n          }\n        )\n      }\n    },\n  }),\n  {\n    scheduler: (update) => {\n      clearTimeout(schedulerRequest.request)\n      schedulerRequest.request = setTimeout(() => {\n        update()\n      }, 100)\n    },\n  }\n)\n\nconst usePagination = () => {\n  return inject<Ref<PaginationAction>>(PaginationSymbol, ref({}))\n}\n\nconst ArrayTablePagination = defineComponent<IArrayTablePaginationProps>({\n  inheritAttrs: false,\n  props: ['pageSize', 'dataSource'],\n  setup(props, { attrs, slots }) {\n    const prefixCls = `${stylePrefix}-array-table`\n    const current = ref(1)\n    const pageSize = computed(() => props.pageSize || 10)\n    const dataSource = computed(() => props.dataSource || [])\n    const startIndex = computed(() => (current.value - 1) * pageSize.value)\n    const endIndex = computed(() => startIndex.value + pageSize.value - 1)\n    const total = computed(() => dataSource.value?.length || 0)\n    const totalPage = computed(() => Math.ceil(total.value / pageSize.value))\n    const pages = computed(() => {\n      return Array.from(new Array(totalPage.value)).map((_, index) => {\n        const page = index + 1\n        return {\n          label: page,\n          value: page,\n        }\n      })\n    })\n\n    const renderPagination = function () {\n      if (totalPage.value <= 1) return\n      return h(\n        'div',\n        {\n          class: [`${prefixCls}-pagination`],\n        },\n        {\n          default: () =>\n            h(\n              Space,\n              {},\n              {\n                default: () => [\n                  h(\n                    StatusSelect,\n                    {\n                      props: {\n                        value: current.value,\n                        onChange: (val: number) => {\n                          current.value = val\n                        },\n                        pageSize: pageSize.value,\n                        options: pages.value,\n                      },\n                    },\n                    {}\n                  ),\n                  h(\n                    Pagination,\n                    {\n                      props: {\n                        background: true,\n                        layout: 'prev, pager, next',\n                        ...attrs,\n                        pageSize: pageSize.value,\n                        pageCount: totalPage.value,\n                        currentPage: current.value,\n                      },\n                      on: {\n                        'current-change': (val: number) => {\n                          current.value = val\n                        },\n                      },\n                    },\n                    {}\n                  ),\n                ],\n              }\n            ),\n        }\n      )\n    }\n\n    const paginationContext = computed<PaginationAction>(() => {\n      return {\n        totalPage: totalPage.value,\n        pageSize: pageSize.value,\n        changePage: (page: number) => (current.value = page),\n      }\n    })\n    provide(PaginationSymbol, paginationContext)\n\n    return () => {\n      return h(\n        Fragment,\n        {},\n        {\n          default: () =>\n            slots?.default?.(\n              dataSource.value?.slice(startIndex.value, endIndex.value + 1),\n              renderPagination,\n              startIndex\n            ),\n        }\n      )\n    }\n  },\n})\n\nconst ArrayTableInner = observer(\n  defineComponent<IArrayTableProps>({\n    name: 'FArrayTable',\n    inheritAttrs: false,\n    setup(props, { attrs, listeners, slots }) {\n      const fieldRef = useField<ArrayField>()\n      const schemaRef = useFieldSchema()\n      const prefixCls = `${stylePrefix}-array-table`\n      const { getKey, keyMap } = ArrayBase.useKey(schemaRef.value)\n\n      const defaultRowKey = (record: any) => {\n        return getKey(record)\n      }\n\n      return () => {\n        const props = attrs as unknown as IArrayTableProps\n        const field = fieldRef.value\n        const dataSource = Array.isArray(field.value) ? field.value.slice() : []\n        const pagination = props.pagination\n        const sources = getArrayTableSources(fieldRef, schemaRef)\n        const columns = getArrayTableColumns(sources)\n\n        const renderColumns = (startIndex?: Ref<number>) => {\n          return columns.map(({ key, render, asterisk, ...props }) => {\n            const children = {} as Record<string, any>\n            if (render) {\n              children.default = render(startIndex)\n            }\n            if (asterisk) {\n              children.header = ({ column }: { column: ElColumnProps }) =>\n                h(\n                  'span',\n                  {},\n                  {\n                    default: () => [\n                      h(\n                        'span',\n                        { class: `${prefixCls}-asterisk` },\n                        { default: () => ['*'] }\n                      ),\n                      column.label,\n                    ],\n                  }\n                )\n            }\n            return h(\n              ElTableColumn,\n              {\n                key,\n                props,\n              },\n              children\n            )\n          })\n        }\n\n        const renderStateManager = () =>\n          sources.map((column, key) => {\n            //专门用来承接对Column的状态管理\n            if (!isColumnComponent(column.schema)) return\n            return h(\n              RecursionField,\n              {\n                props: {\n                  name: column.name,\n                  schema: column.schema,\n                  onlyRenderSelf: true,\n                },\n                key,\n              },\n              {}\n            )\n          })\n\n        const renderTable = (\n          dataSource?: any[],\n          pager?: () => VNode,\n          startIndex?: Ref<number>\n        ) => {\n          return h(\n            'div',\n            { class: prefixCls },\n            {\n              default: () =>\n                h(\n                  ArrayBase,\n                  {\n                    props: {\n                      keyMap,\n                    },\n                  },\n                  {\n                    default: () => [\n                      h(\n                        ElTable,\n                        {\n                          props: {\n                            rowKey: defaultRowKey,\n                            ...attrs,\n                            data: dataSource,\n                          },\n                          on: listeners,\n                        },\n                        {\n                          ...slots,\n                          default: () => renderColumns(startIndex),\n                        }\n                      ),\n                      pager?.(),\n                      renderStateManager(),\n                      renderAddition(),\n                    ],\n                  }\n                ),\n            }\n          )\n        }\n\n        if (!pagination) {\n          return renderTable(dataSource, null)\n        }\n        return h(\n          ArrayTablePagination,\n          {\n            attrs: {\n              ...(isBool(pagination) ? {} : pagination),\n              dataSource,\n            },\n          },\n          { default: renderTable }\n        )\n      }\n    },\n  })\n)\n\nconst ArrayTableColumn: Component = {\n  name: 'FArrayTableColumn',\n  render(h) {\n    return h()\n  },\n}\n\nconst ArrayAddition = defineComponent({\n  name: 'ArrayAddition',\n  setup(props, { attrs, listeners, slots }) {\n    const array = ArrayBase.useArray()\n    const paginationRef = usePagination()\n\n    const onClick = listeners['click']\n    listeners['click'] = (e) => {\n      const { totalPage = 0, pageSize = 10, changePage } = paginationRef.value\n      // 如果添加数据后超过当前页，则自动切换到下一页\n      const total = array?.field?.value?.value.length || 0\n      if (total === (totalPage - 1) * pageSize + 1 && isFn(changePage)) {\n        changePage(totalPage)\n      }\n      if (onClick) onClick(e)\n    }\n    return () => {\n      return h(\n        ArrayBase.Addition,\n        {\n          props,\n          attrs,\n          on: listeners,\n        },\n        slots\n      )\n    }\n  },\n})\n\nexport const ArrayTable = composeExport(ArrayTableInner, {\n  Column: ArrayTableColumn,\n  Index: ArrayBase.Index,\n  SortHandle: ArrayBase.SortHandle,\n  Addition: ArrayAddition,\n  Remove: ArrayBase.Remove,\n  MoveDown: ArrayBase.MoveDown,\n  MoveUp: ArrayBase.MoveUp,\n  useArray: ArrayBase.useArray,\n  useIndex: ArrayBase.useIndex,\n  useRecord: ArrayBase.useRecord,\n})\n\nexport default ArrayTable\n"
  },
  {
    "path": "packages/element/src/array-table/style.scss",
    "content": "@import '../__builtins__/styles/common.scss';\n\n$array-table-prefix-cls: '#{$formily-prefix}-array-table';\n\n.#{$array-table-prefix-cls} {\n  .#{$formily-prefix}-form-item:not(.#{$formily-prefix}-form-item-feedback-layout-popover) {\n    margin-bottom: 0 !important;\n  }\n\n  &-status-select-dropdown {\n    .#{$namespace}-badge {\n      line-height: 1;\n    }\n  }\n\n  &-pagination {\n    display: flex;\n    justify-content: center;\n    margin-top: 8px;\n\n    .#{$array-table-prefix-cls}-status-select.has-error {\n      .#{$namespace}-input__inner {\n        border-color: $--color-danger !important;\n      }\n    }\n  }\n\n  .#{$namespace}-table {\n    .cell {\n      overflow: visible;\n    }\n\n    .cell.el-tooltip {\n      overflow: hidden;\n    }\n\n    &__fixed {\n      box-shadow: 10px 0 10px -10px rgb(0 0 0 / 12%);\n    }\n\n    &__fixed-right {\n      box-shadow: -10px 0 10px -10px rgb(0 0 0 / 12%);\n    }\n  }\n\n  .#{$formily-prefix}-form-item-help {\n    position: absolute;\n    font-size: 12px;\n    top: 100%;\n    background: #fff;\n    width: 100%;\n    margin-top: 3px;\n    padding: 3px;\n    z-index: 2;\n    border-radius: 3px;\n    box-shadow: 0 0 10px #eee;\n  }\n\n  .#{$formily-prefix}-array-base-addition {\n    margin-top: 8px;\n    width: 100%;\n    border: $--border-width-base dashed $--border-color-base;\n\n    &:hover {\n      background-color: $--color-white;\n      border-color: $--border-color-hover;\n    }\n\n    &:active,\n    &:focus {\n      background-color: $--color-white;\n      border-color: $--color-primary;\n    }\n  }\n\n  .#{$formily-prefix}-form-item-feedback-layout-popover {\n    margin-bottom: 0;\n  }\n\n  &-inner-asterisk {\n    color: $--color-danger;\n    font-weight: $--font-weight-primary;\n  }\n}\n"
  },
  {
    "path": "packages/element/src/array-table/style.ts",
    "content": "import './style.scss'\n\nimport 'element-ui/packages/theme-chalk/src/table.scss'\nimport 'element-ui/packages/theme-chalk/src/table-column.scss'\nimport 'element-ui/packages/theme-chalk/src/button.scss'\nimport 'element-ui/packages/theme-chalk/src/select.scss'\nimport 'element-ui/packages/theme-chalk/src/badge.scss'\n\n// 依赖\nimport '../array-base/style'\nimport '../space/style'\n"
  },
  {
    "path": "packages/element/src/array-tabs/index.ts",
    "content": "import { ArrayField } from '@formily/core'\nimport { observer } from '@formily/reactive-vue'\nimport { h, RecursionField, useField, useFieldSchema } from '@formily/vue'\nimport { Badge, TabPane, Tabs } from 'element-ui'\nimport { defineComponent, ref } from 'vue-demi'\nimport { stylePrefix } from '../__builtins__/configs'\n\nimport type { Tabs as TabsProps } from 'element-ui'\n\nexport const ArrayTabs = observer(\n  defineComponent<TabsProps>({\n    name: 'ArrayTabs',\n    props: [],\n    setup(props, { attrs, listeners }) {\n      const fieldRef = useField<ArrayField>()\n      const schemaRef = useFieldSchema()\n\n      const prefixCls = `${stylePrefix}-array-tabs`\n      const activeKey = ref('tab-0')\n\n      return () => {\n        const field = fieldRef.value\n        const schema = schemaRef.value\n        const value = Array.isArray(field.value) ? field.value : []\n        const dataSource = value?.length ? value : [{}]\n\n        const onEdit = (targetKey: any, type: 'add' | 'remove') => {\n          if (type == 'add') {\n            const id = dataSource.length\n            if (field?.value?.length) {\n              field.push(null)\n            } else {\n              field.push(null, null)\n            }\n            activeKey.value = `tab-${id}`\n          } else if (type == 'remove') {\n            const index = targetKey.match(/-(\\d+)/)?.[1]\n            field.remove(Number(index))\n            if (activeKey.value === targetKey) {\n              activeKey.value = `tab-${index - 1}`\n            }\n          }\n        }\n\n        const badgedTab = (index: number) => {\n          const tab = `${field.title || 'Untitled'} ${index + 1}`\n          const path = field.address.concat(index)\n          const errors = field.form.queryFeedbacks({\n            type: 'error',\n            address: `${path}.**`,\n          })\n          if (errors.length) {\n            return h(\n              'span',\n              {},\n              {\n                default: () => [\n                  h(\n                    Badge,\n                    {\n                      class: [`${prefixCls}-errors-badge`],\n                      props: {\n                        value: errors.length,\n                      },\n                    },\n                    {\n                      default: () => [tab],\n                    }\n                  ),\n                ],\n              }\n            )\n          }\n          return h(\n            'span',\n            {},\n            {\n              default: () => [tab],\n            }\n          )\n        }\n\n        const renderItems = () =>\n          dataSource?.map((item, index) => {\n            const items = Array.isArray(schema.items)\n              ? schema.items[index]\n              : schema.items\n            const key = `tab-${index}`\n\n            return h(\n              TabPane,\n              {\n                key,\n                attrs: {\n                  closable: index !== 0,\n                  name: key,\n                },\n              },\n              {\n                default: () =>\n                  h(\n                    RecursionField,\n                    {\n                      props: {\n                        schema: items,\n                        name: index,\n                      },\n                    },\n                    {}\n                  ),\n\n                label: () => [badgedTab(index)],\n              }\n            )\n          })\n        return h(\n          Tabs,\n          {\n            class: [prefixCls],\n            attrs: {\n              ...attrs,\n              type: 'card',\n              value: activeKey.value,\n              addable: true,\n            },\n            on: {\n              ...listeners,\n              input: (key) => {\n                activeKey.value = key\n              },\n              'tab-remove': (target) => {\n                onEdit(target, 'remove')\n                listeners?.['tab-remove']?.(target)\n              },\n              'tab-add': () => {\n                onEdit(null, 'add')\n                listeners?.['tab-add']?.()\n              },\n            },\n          },\n          {\n            default: () => [renderItems()],\n          }\n        )\n      }\n    },\n  })\n)\n\nexport default ArrayTabs\n"
  },
  {
    "path": "packages/element/src/array-tabs/style.scss",
    "content": "@import '../__builtins__/styles/common.scss';\n\n$array-table-prefix-cls: '#{$formily-prefix}-array-tabs';\n\n.#{$array-table-prefix-cls} {\n  .#{$formily-prefix}-array-tabs-addition {\n    position: absolute;\n    right: -56px;\n    top: -1px;\n  }\n\n  .#{$array-table-prefix-cls}-errors-badge {\n    line-height: 1;\n    vertical-align: initial;\n  }\n}\n"
  },
  {
    "path": "packages/element/src/array-tabs/style.ts",
    "content": "import './style.scss'\nimport 'element-ui/packages/theme-chalk/src/tabs.scss'\nimport 'element-ui/packages/theme-chalk/src/tab-pane.scss'\nimport 'element-ui/packages/theme-chalk/src/badge.scss'\nimport 'element-ui/packages/theme-chalk/src/button.scss'\n"
  },
  {
    "path": "packages/element/src/cascader/index.ts",
    "content": "import { connect, mapProps, mapReadPretty } from '@formily/vue'\nimport { Cascader as ELCascader } from 'element-ui'\n\nimport type { Cascader as ElCascaderProps } from 'element-ui'\nimport { PreviewText } from '../preview-text'\n\nexport type CascaderProps = ElCascaderProps\n\nexport const Cascader = connect(\n  ELCascader,\n  mapProps({ dataSource: 'options' }),\n  mapReadPretty(PreviewText.Cascader)\n)\n\nexport default Cascader\n"
  },
  {
    "path": "packages/element/src/cascader/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/cascader.scss'\n\n// 依赖\nimport '../preview-text/style'\n"
  },
  {
    "path": "packages/element/src/checkbox/index.ts",
    "content": "import { connect, h, mapProps, mapReadPretty } from '@formily/vue'\nimport type {\n  Checkbox as _ElCheckboxProps,\n  CheckboxGroup as ElCheckboxGroupProps,\n} from 'element-ui'\nimport {\n  Checkbox as ElCheckbox,\n  CheckboxButton as ElCheckboxButton,\n  CheckboxGroup as ElCheckboxGroup,\n} from 'element-ui'\nimport { defineComponent, PropType } from 'vue-demi'\nimport { PreviewText } from '../preview-text'\nimport {\n  composeExport,\n  resolveComponent,\n  SlotTypes,\n  transformComponent,\n} from '../__builtins__/shared'\n\ntype ElCheckboxProps = Omit<_ElCheckboxProps, 'value'> & {\n  value: ElCheckboxProps['label']\n}\n\nexport interface CheckboxProps extends ElCheckboxProps {\n  option: Omit<_ElCheckboxProps, 'value'> & {\n    value: ElCheckboxProps['label']\n    label: SlotTypes\n  }\n}\n\nconst CheckboxOption = defineComponent<CheckboxProps>({\n  name: 'Checkbox',\n  inheritAttrs: false,\n  props: {\n    option: {\n      type: Object,\n      default: null,\n    },\n  },\n  setup(curtomProps, { attrs, slots, listeners }) {\n    return () => {\n      const props = attrs as unknown as CheckboxProps\n      const option = curtomProps?.option\n      if (option) {\n        const children = {\n          default: () => [\n            resolveComponent(slots.default ?? option.label, { option }),\n          ],\n        }\n        const newProps = {} as Partial<ElCheckboxProps>\n        Object.assign(newProps, option)\n        newProps.label = option.value\n        delete newProps.value\n\n        return h(\n          attrs.optionType === 'button' ? ElCheckboxButton : ElCheckbox,\n          {\n            attrs: {\n              ...newProps,\n            },\n          },\n          children\n        )\n      }\n\n      return h(\n        ElCheckbox,\n        {\n          attrs: {\n            ...props,\n          },\n          on: listeners,\n        },\n        slots\n      )\n    }\n  },\n})\n\nexport type CheckboxGroupProps = ElCheckboxGroupProps & {\n  value: any[]\n  options?: Array<CheckboxProps | string>\n  optionType: 'default' | 'button'\n}\n\nconst TransformElCheckboxGroup = transformComponent(ElCheckboxGroup, {\n  change: 'input',\n  uselessChange: 'change'\n})\n\nconst CheckboxGroupOption = defineComponent<CheckboxGroupProps>({\n  name: 'CheckboxGroup',\n  props: {\n    options: {\n      type: Array,\n      default: () => [],\n    },\n    optionType: {\n      type: String as PropType<CheckboxGroupProps['optionType']>,\n      default: 'default',\n    },\n  },\n  setup(customProps, { attrs, slots, listeners }) {\n    return () => {\n      const options = customProps.options || []\n      const children =\n        options.length !== 0\n          ? {\n              default: () =>\n                options.map((option) => {\n                  if (typeof option === 'string') {\n                    return h(\n                      Checkbox,\n                      {\n                        props: {\n                          option: {\n                            label: option,\n                            value: option,\n                          },\n                        },\n                        attrs: {\n                          optionType: customProps.optionType,\n                        },\n                      },\n                      slots?.option\n                        ? { default: () => slots.option({ option }) }\n                        : {}\n                    )\n                  } else {\n                    return h(\n                      Checkbox,\n                      {\n                        props: {\n                          option,\n                        },\n                        attrs: {\n                          optionType: customProps.optionType,\n                        },\n                      },\n                      slots?.option\n                        ? { default: () => slots.option({ option }) }\n                        : {}\n                    )\n                  }\n                }),\n            }\n          : slots\n      return h(\n        TransformElCheckboxGroup,\n        {\n          attrs: {\n            ...attrs,\n          },\n          on: listeners,\n        },\n        children\n      )\n    }\n  },\n})\n\nconst CheckboxGroup = connect(\n  CheckboxGroupOption,\n  mapProps({ dataSource: 'options' }),\n  mapReadPretty(PreviewText.Select, {\n    multiple: true,\n  })\n)\n\nexport const Checkbox = composeExport(connect(CheckboxOption), {\n  Group: CheckboxGroup,\n})\n\nexport default Checkbox\n"
  },
  {
    "path": "packages/element/src/checkbox/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/checkbox.scss'\nimport 'element-ui/packages/theme-chalk/src/checkbox-group.scss'\nimport 'element-ui/packages/theme-chalk/src/checkbox-button.scss'\n// 依赖\nimport '../preview-text/style'\n"
  },
  {
    "path": "packages/element/src/date-picker/index.ts",
    "content": "import { transformComponent } from '../__builtins__/shared'\nimport { connect, mapProps, mapReadPretty } from '@formily/vue'\n\nimport type { DatePicker as ElDatePickerProps } from 'element-ui'\nimport { DatePicker as ElDatePicker } from 'element-ui'\nimport { PreviewText } from '../preview-text'\n\nexport type DatePickerProps = ElDatePickerProps\n\nconst TransformElDatePicker = transformComponent<DatePickerProps>(\n  ElDatePicker,\n  {\n    change: 'input',\n  }\n)\n\nconst getDefaultFormat = (props, formatType = 'format') => {\n  const type = props.type\n\n  if (type === 'week' && formatType === 'format') {\n    return 'yyyy-WW'\n  } else if (type === 'month') {\n    return 'yyyy-MM'\n  } else if (type === 'year') {\n    return 'yyyy'\n  } else if (type === 'datetime' || type === 'datetimerange') {\n    return 'yyyy-MM-dd HH:mm:ss'\n  }\n\n  return 'yyyy-MM-dd'\n}\n\nexport const DatePicker = connect(\n  TransformElDatePicker,\n  mapProps({ readOnly: 'readonly' }, (props) => {\n    return {\n      ...props,\n      format: props.format || getDefaultFormat(props),\n      valueFormat: props.valueFormat || getDefaultFormat(props, 'valueFormat'),\n    }\n  }),\n  mapReadPretty(PreviewText.DatePicker)\n)\n\nexport default DatePicker\n"
  },
  {
    "path": "packages/element/src/date-picker/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/date-picker.scss'\n\n// 依赖\nimport '../preview-text/style'\n"
  },
  {
    "path": "packages/element/src/editable/index.ts",
    "content": "import { Field, isVoidField } from '@formily/core'\nimport { reaction } from '@formily/reactive'\nimport { observer } from '@formily/reactive-vue'\nimport { h, useField } from '@formily/vue'\nimport { Popover } from 'element-ui'\nimport { defineComponent, onBeforeUnmount, ref } from 'vue-demi'\nimport { stylePrefix } from '../__builtins__/configs'\n\nimport type { Popover as PopoverProps } from 'element-ui'\nimport { FormBaseItem, FormItemProps } from '../form-item'\nimport { composeExport, useCompatRef } from '../__builtins__/shared'\n\nexport type EditableProps = FormItemProps\nexport type EditablePopoverProps = PopoverProps\n\nconst getParentPattern = (fieldRef) => {\n  const field = fieldRef.value\n  return field?.parent?.pattern || field?.form?.pattern\n}\n\nconst getFormItemProps = (fieldRef): FormItemProps => {\n  const field = fieldRef.value\n\n  if (isVoidField(field)) return {}\n  if (!field) return {}\n  const takeMessage = () => {\n    if (field.selfErrors.length) return field.selfErrors[0]\n    if (field.selfWarnings.length) return field.selfWarnings[0]\n    if (field.selfSuccesses.length) return field.selfSuccesses[0]\n  }\n\n  return {\n    feedbackStatus:\n      field.validateStatus === 'validating' ? 'pending' : field.validateStatus,\n    feedbackText: takeMessage(),\n    extra: field.description,\n  }\n}\n\nconst EditableInner = observer(\n  defineComponent<EditableProps>({\n    name: 'FEditable',\n    setup(props, { attrs, slots, refs }) {\n      const fieldRef = useField<Field>()\n      const { elRef: innerRef, elRefBinder } = useCompatRef(refs)\n      const prefixCls = `${stylePrefix}-editable`\n      const setEditable = (payload: boolean) => {\n        const pattern = getParentPattern(fieldRef)\n\n        if (pattern !== 'editable') return\n        fieldRef.value.setPattern(payload ? 'editable' : 'readPretty')\n      }\n\n      const dispose = reaction(\n        () => {\n          const pattern = getParentPattern(fieldRef)\n\n          return pattern\n        },\n        (pattern) => {\n          if (pattern === 'editable') {\n            fieldRef.value.setPattern('readPretty')\n          }\n        },\n        {\n          fireImmediately: true,\n        }\n      )\n\n      onBeforeUnmount(dispose)\n\n      return () => {\n        const field = fieldRef.value\n        const editable = field.pattern === 'editable'\n        const pattern = getParentPattern(fieldRef)\n        const itemProps = getFormItemProps(fieldRef)\n\n        const recover = () => {\n          if (editable && !fieldRef.value?.errors?.length) {\n            setEditable(false)\n          }\n        }\n\n        const onClick = (e: MouseEvent) => {\n          const target = e.target as HTMLElement\n          const close = innerRef.value.querySelector(`.${prefixCls}-close-btn`)\n\n          if (target?.contains(close) || close?.contains(target)) {\n            recover()\n          } else if (!editable) {\n            setTimeout(() => {\n              setEditable(true)\n              setTimeout(() => {\n                innerRef.value.querySelector('input')?.focus()\n              })\n            })\n          }\n        }\n\n        const renderEditHelper = () => {\n          if (editable) return null\n\n          return h(\n            FormBaseItem,\n            {\n              attrs: {\n                ...attrs,\n                ...itemProps,\n              },\n            },\n            {\n              default: () => {\n                return h(\n                  'i',\n                  {\n                    class: [\n                      `${prefixCls}-edit-btn`,\n                      pattern === 'editable'\n                        ? 'el-icon-edit'\n                        : 'el-icon-chat-dot-round',\n                    ],\n                  },\n                  {}\n                )\n              },\n            }\n          )\n        }\n\n        const renderCloseHelper = () => {\n          if (!editable) return null\n          return h(\n            FormBaseItem,\n            {\n              attrs: {\n                ...attrs,\n              },\n            },\n            {\n              default: () => {\n                return h(\n                  'i',\n                  {\n                    class: [`${prefixCls}-close-btn`, 'el-icon-close'],\n                  },\n                  {}\n                )\n              },\n            }\n          )\n        }\n\n        return h(\n          'div',\n          {\n            class: prefixCls,\n            ref: elRefBinder,\n            on: {\n              click: onClick,\n            },\n          },\n          {\n            default: () =>\n              h(\n                'div',\n                {\n                  class: `${prefixCls}-content`,\n                },\n                {\n                  default: () => [\n                    h(\n                      FormBaseItem,\n                      {\n                        attrs: {\n                          ...attrs,\n                          ...itemProps,\n                        },\n                      },\n                      slots\n                    ),\n                    renderEditHelper(),\n                    renderCloseHelper(),\n                  ],\n                }\n              ),\n          }\n        )\n      }\n    },\n  })\n)\n\nconst EditablePopover = observer(\n  defineComponent<EditablePopoverProps>({\n    name: 'FEditablePopover',\n    setup(props, { attrs, slots }) {\n      const fieldRef = useField<Field>()\n\n      const prefixCls = `${stylePrefix}-editable`\n      const visible = ref(false)\n\n      return () => {\n        const field = fieldRef.value\n        const pattern = getParentPattern(fieldRef)\n        return h(\n          Popover,\n          {\n            class: [prefixCls],\n            attrs: {\n              ...attrs,\n              title: attrs.title || field.title,\n              value: visible.value,\n              trigger: 'click',\n            },\n            on: {\n              input: (value) => {\n                visible.value = value\n              },\n            },\n          },\n          {\n            default: () => [slots.default()],\n            reference: () =>\n              h(\n                FormBaseItem,\n                { class: [`${prefixCls}-trigger`] },\n                {\n                  default: () =>\n                    h(\n                      'div',\n                      {\n                        class: [`${prefixCls}-content`],\n                      },\n                      {\n                        default: () => [\n                          h(\n                            'span',\n                            {\n                              class: [`${prefixCls}-preview`],\n                            },\n                            {\n                              default: () => [attrs.title || field.title],\n                            }\n                          ),\n                          h(\n                            'i',\n                            {\n                              class: [\n                                `${prefixCls}-edit-btn`,\n                                pattern === 'editable'\n                                  ? 'el-icon-edit'\n                                  : 'el-icon-chat-dot-round',\n                              ],\n                            },\n                            {}\n                          ),\n                        ],\n                      }\n                    ),\n                }\n              ),\n          }\n        )\n      }\n    },\n  })\n)\n\nexport const Editable = composeExport(EditableInner, {\n  Popover: EditablePopover,\n})\n\nexport default Editable\n"
  },
  {
    "path": "packages/element/src/editable/style.scss",
    "content": "@import '../__builtins__/styles/common.scss';\n\n$editable-prefix-cls: '#{$formily-prefix}-editable';\n\n.#{$editable-prefix-cls} {\n  cursor: pointer;\n  display: inline-block !important;\n\n  .#{$formily-prefix}-form-text {\n    .#{$formily-prefix}-tag {\n      transition: none !important;\n    }\n\n    .#{$formily-prefix}-tag:last-child {\n      margin-right: 0 !important;\n    }\n  }\n\n  &-content {\n    display: flex;\n    align-items: center;\n\n    > * {\n      margin-right: 3px;\n      &:last-child {\n        margin-right: 0;\n      }\n    }\n  }\n\n  .#{$editable-prefix-cls}-edit-btn,\n  .#{$editable-prefix-cls}-close-btn {\n    transition: all 0.25s ease-in-out;\n\n    &:hover {\n      color: $--color-primary;\n    }\n  }\n\n  .#{$formily-prefix}-form-text {\n    display: flex;\n    align-items: center;\n  }\n\n  .#{$editable-prefix-cls}-preview {\n    white-space: nowrap;\n    text-overflow: ellipsis;\n    overflow: hidden;\n    word-break: break-all;\n    max-width: 100px;\n    display: block;\n  }\n}\n"
  },
  {
    "path": "packages/element/src/editable/style.ts",
    "content": "import './style.scss'\nimport 'element-ui/packages/theme-chalk/src/popover.scss'\n\n// 依赖\nimport '../form-item/style'\n"
  },
  {
    "path": "packages/element/src/el-form/index.ts",
    "content": "import { Form } from '@formily/core'\nimport { FormProvider as _FormProvider, createForm } from '@formily/vue'\nimport type { Form as _ElFormProps } from 'element-ui'\nimport type { FunctionalComponentOptions, Component } from 'vue'\nimport { Form as ElFormComponent } from 'element-ui'\n\nconst FormProvider = _FormProvider as unknown as Component\n\nexport type ElFormProps = _ElFormProps & {\n  form?: Form\n  component: Component\n  onAutoSubmit?: (values: any) => any\n}\n\nexport const ElForm: FunctionalComponentOptions<ElFormProps> = {\n  functional: true,\n  render(h, context) {\n    const {\n      form = createForm({}),\n      component = ElFormComponent,\n      onAutoSubmit = context.listeners?.autoSubmit,\n      ...props\n    } = context.props\n    const submitHandler = (\n      Array.isArray(onAutoSubmit) ? onAutoSubmit[0] : onAutoSubmit\n    ) as (values: any) => any\n    return h(FormProvider, { props: { form } }, [\n      h(\n        component,\n        {\n          ...context.data,\n          props,\n          nativeOn: {\n            submit: (e: Event) => {\n              e?.stopPropagation?.()\n              e?.preventDefault?.()\n              form.submit(submitHandler)\n            },\n          },\n        },\n        context.children\n      ),\n    ])\n  },\n}\n\nexport default ElForm\n"
  },
  {
    "path": "packages/element/src/el-form/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/form.scss'\n"
  },
  {
    "path": "packages/element/src/el-form-item/index.ts",
    "content": "import { isVoidField } from '@formily/core'\nimport { connect, mapProps } from '@formily/vue'\n\nimport type { FormItem as _ElFormItemProps } from 'element-ui'\nimport { FormItem as ElFormItemComponent } from 'element-ui'\n\nexport type ElFormItemProps = _ElFormItemProps & { title: string }\n\nexport const ElFormItem = connect(\n  ElFormItemComponent,\n  mapProps({ title: 'label', required: true }, (props, field) => ({\n    error: !isVoidField(field)\n      ? field.errors.length\n        ? field.errors.join('，')\n        : undefined\n      : undefined,\n  }))\n)\n\nexport default ElFormItem\n"
  },
  {
    "path": "packages/element/src/el-form-item/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/form-item.scss'\n"
  },
  {
    "path": "packages/element/src/form/index.ts",
    "content": "import { Form as FormType, IFormFeedback } from '@formily/core'\nimport { FormProvider as _FormProvider, h, useForm } from '@formily/vue'\nimport { Component, VNode } from 'vue'\nimport { defineComponent } from 'vue-demi'\nimport { FormLayout, FormLayoutProps } from '../form-layout'\nimport { PreviewText } from '../preview-text'\n\nconst FormProvider = _FormProvider as unknown as Component\n\nexport interface FormProps extends FormLayoutProps {\n  form?: FormType\n  component?: Component\n  previewTextPlaceholder: string | (() => VNode)\n  onAutoSubmit?: (values: any) => any\n  onAutoSubmitFailed?: (feedbacks: IFormFeedback[]) => void\n}\n\nexport const Form = defineComponent<FormProps>({\n  name: 'FForm',\n  props: [\n    'form',\n    'component',\n    'previewTextPlaceholder',\n    'onAutoSubmit',\n    'onAutoSubmitFailed',\n  ],\n  setup(props, { attrs, slots, listeners }) {\n    const top = useForm()\n\n    return () => {\n      const {\n        form,\n        component = 'form',\n        onAutoSubmit = listeners?.autoSubmit,\n        onAutoSubmitFailed = listeners?.autoSubmitFailed,\n        previewTextPlaceholder = slots?.previewTextPlaceholder,\n      } = props\n\n      const renderContent = (form: FormType) => {\n        return h(\n          PreviewText.Placeholder,\n          {\n            props: {\n              value: previewTextPlaceholder,\n            },\n          },\n          {\n            default: () => [\n              h(\n                FormLayout,\n                {\n                  attrs: {\n                    ...attrs,\n                  },\n                },\n                {\n                  default: () => [\n                    h(\n                      component,\n                      {\n                        on: {\n                          submit: (e: Event) => {\n                            e?.stopPropagation?.()\n                            e?.preventDefault?.()\n                            form\n                              .submit(onAutoSubmit as (e: any) => void)\n                              .catch(onAutoSubmitFailed as (e: any) => void)\n                          },\n                        },\n                      },\n                      slots\n                    ),\n                  ],\n                }\n              ),\n            ],\n          }\n        )\n      }\n\n      if (form) {\n        return h(\n          FormProvider,\n          { props: { form } },\n          {\n            default: () => renderContent(form),\n          }\n        )\n      }\n\n      if (!top.value) throw new Error('must pass form instance by createForm')\n\n      return renderContent(top.value)\n    }\n  },\n})\n\nexport default Form\n"
  },
  {
    "path": "packages/element/src/form/style.scss",
    "content": ""
  },
  {
    "path": "packages/element/src/form/style.ts",
    "content": "// 依赖\nimport '../preview-text/style'\nimport '../form-layout/style'\n"
  },
  {
    "path": "packages/element/src/form-button-group/index.ts",
    "content": "import { h } from '@formily/vue'\nimport { defineComponent } from 'vue-demi'\nimport { FormBaseItem } from '../form-item'\nimport { Space, SpaceProps } from '../space'\nimport { stylePrefix } from '../__builtins__/configs'\n\nexport type FormButtonGroupProps = Omit<SpaceProps, 'align' | 'size'> & {\n  align?: 'left' | 'right' | 'center'\n  gutter?: number\n  className?: string\n  alignFormItem: boolean\n}\n\nexport const FormButtonGroup = defineComponent<FormButtonGroupProps>({\n  name: 'FFormButtonGroup',\n  props: {\n    align: {\n      type: String,\n      default: 'left',\n    },\n    gutter: {\n      type: Number,\n      default: 8,\n    },\n    alignFormItem: {\n      type: Boolean,\n      default: false,\n    },\n  },\n  setup(props, { slots, attrs }) {\n    const prefixCls = `${stylePrefix}-form-button-group`\n    return () => {\n      if (props.alignFormItem) {\n        return h(\n          FormBaseItem,\n          {\n            style: {\n              margin: 0,\n              padding: 0,\n              width: '100%',\n            },\n            attrs: {\n              colon: false,\n              label: ' ',\n              ...attrs,\n            },\n          },\n          {\n            default: () => h(Space, { props: { size: props.gutter } }, slots),\n          }\n        )\n      } else {\n        return h(\n          Space,\n          {\n            class: [prefixCls],\n            style: {\n              justifyContent:\n                props.align === 'left'\n                  ? 'flex-start'\n                  : props.align === 'right'\n                  ? 'flex-end'\n                  : 'center',\n              display: 'flex',\n            },\n            props: {\n              ...attrs,\n              size: props.gutter,\n            },\n            attrs,\n          },\n          slots\n        )\n      }\n    }\n  },\n})\n\nexport default FormButtonGroup\n"
  },
  {
    "path": "packages/element/src/form-button-group/style.scss",
    "content": ""
  },
  {
    "path": "packages/element/src/form-button-group/style.ts",
    "content": "import './style.scss'\n\n// 依赖\nimport '../form-item/style'\nimport '../space/style'\n"
  },
  {
    "path": "packages/element/src/form-collapse/index.ts",
    "content": "import { Collapse, CollapseItem, Badge } from 'element-ui'\nimport { model } from '@formily/reactive'\nimport type {\n  Collapse as CollapseProps,\n  CollapseItem as CollapseItemProps,\n} from 'element-ui'\nimport {\n  useField,\n  useFieldSchema,\n  RecursionField,\n  h,\n  Fragment,\n} from '@formily/vue'\nimport { observer } from '@formily/reactive-vue'\nimport { Schema, SchemaKey } from '@formily/json-schema'\nimport { composeExport, stylePrefix } from '../__builtins__'\nimport { toArr } from '@formily/shared'\nimport { computed, defineComponent, PropType } from 'vue-demi'\nimport { GeneralField } from '@formily/core'\n\ntype ActiveKeys = string | number | Array<string | number>\n\ntype ActiveKey = string | number\n\ntype Panels = { name: SchemaKey; props: any; schema: Schema }[]\n\nexport interface IFormCollapse {\n  activeKeys: ActiveKeys\n  hasActiveKey(key: ActiveKey): boolean\n  setActiveKeys(key: ActiveKeys): void\n  addActiveKey(key: ActiveKey): void\n  removeActiveKey(key: ActiveKey): void\n  toggleActiveKey(key: ActiveKey): void\n}\n\nexport interface IFormCollapseProps extends CollapseProps {\n  formCollapse?: IFormCollapse\n  activeKey?: ActiveKey\n}\n\nconst usePanels = (collapseField: GeneralField, schema: Schema) => {\n  const panels: Panels = []\n  schema.mapProperties((schema, name) => {\n    const field = collapseField.query(collapseField.address.concat(name)).take()\n    if (field?.display === 'none' || field?.display === 'hidden') return\n    if (schema['x-component']?.indexOf('FormCollapse.Item') > -1) {\n      panels.push({\n        name,\n        props: {\n          ...schema?.['x-component-props'],\n          key: schema?.['x-component-props']?.key || name,\n        },\n        schema,\n      })\n    }\n  })\n  return panels\n}\n\nconst createFormCollapse = (defaultActiveKeys?: ActiveKeys) => {\n  const formCollapse = model({\n    activeKeys: defaultActiveKeys,\n    setActiveKeys(keys: ActiveKeys) {\n      formCollapse.activeKeys = keys\n    },\n    hasActiveKey(key: ActiveKey) {\n      if (Array.isArray(formCollapse.activeKeys)) {\n        if (formCollapse.activeKeys.includes(key)) {\n          return true\n        }\n      } else if (formCollapse.activeKeys == key) {\n        return true\n      }\n      return false\n    },\n    addActiveKey(key: ActiveKey) {\n      if (formCollapse.hasActiveKey(key)) return\n      formCollapse.activeKeys = toArr(formCollapse.activeKeys).concat(key)\n    },\n    removeActiveKey(key: ActiveKey) {\n      if (Array.isArray(formCollapse.activeKeys)) {\n        formCollapse.activeKeys = formCollapse.activeKeys.filter(\n          (item) => item != key\n        )\n      } else {\n        formCollapse.activeKeys = ''\n      }\n    },\n    toggleActiveKey(key: ActiveKey) {\n      if (formCollapse.hasActiveKey(key)) {\n        formCollapse.removeActiveKey(key)\n      } else {\n        formCollapse.addActiveKey(key)\n      }\n    },\n  })\n  return formCollapse\n}\n\nconst FormCollapse = observer(\n  defineComponent({\n    inheritAttrs: false,\n    props: {\n      formCollapse: { type: Object as PropType<IFormCollapse> },\n      activeKey: {\n        type: [String, Number],\n      },\n    },\n    setup(props, { attrs, emit }) {\n      const field = useField()\n      const schema = useFieldSchema()\n      const prefixCls = `${stylePrefix}-form-collapse`\n      const _formCollapse = computed(\n        () => props.formCollapse ?? createFormCollapse()\n      )\n\n      const takeActiveKeys = (panels: Panels) => {\n        if (props.activeKey) return props.activeKey\n        if (_formCollapse.value?.activeKeys)\n          return _formCollapse.value?.activeKeys\n        if (attrs.accordion) return panels[0]?.name\n        return panels.map((item) => item.name)\n      }\n\n      const badgedHeader = (key: SchemaKey, props: any) => {\n        const errors = field.value.form.queryFeedbacks({\n          type: 'error',\n          address: `${field.value.address.concat(key)}.*`,\n        })\n        if (errors.length) {\n          return h(\n            Badge,\n            {\n              class: [`${prefixCls}-errors-badge`],\n              props: {\n                value: errors.length,\n              },\n            },\n            { default: () => props.title }\n          )\n        }\n        return props.title\n      }\n\n      return () => {\n        const panels = usePanels(field.value, schema.value)\n        const activeKey = takeActiveKeys(panels)\n        return h(\n          Collapse,\n          {\n            class: prefixCls,\n            props: {\n              value: activeKey,\n            },\n            on: {\n              change: (key: string | string[]) => {\n                emit('input', key)\n                _formCollapse.value.setActiveKeys(key)\n              },\n            },\n          },\n          {\n            default: () => {\n              return panels.map(({ props, schema, name }, index) => {\n                return h(\n                  CollapseItem,\n                  {\n                    key: index,\n                    props: {\n                      ...props,\n                      name,\n                    },\n                  },\n                  {\n                    default: () => [\n                      h(RecursionField, { props: { schema, name } }, {}),\n                    ],\n                    title: () =>\n                      h(\n                        'span',\n                        {},\n                        { default: () => badgedHeader(name, props) }\n                      ),\n                  }\n                )\n              })\n            },\n          }\n        )\n      }\n    },\n  })\n)\n\nexport const FormCollapseItem = defineComponent<CollapseItemProps>({\n  name: 'FFormCollapseItem',\n  setup(_props, { slots }) {\n    return () => h(Fragment, {}, slots)\n  },\n})\n\nconst composeFormCollapse = composeExport(FormCollapse, {\n  Item: FormCollapseItem,\n  createFormCollapse,\n})\n\nexport { composeFormCollapse as FormCollapse }\nexport default composeFormCollapse\n"
  },
  {
    "path": "packages/element/src/form-collapse/style.scss",
    "content": "@import '../__builtins__/styles/common.scss';\n\n.#{$formily-prefix}-form-collapse-errors-badge {\n  line-height: 1;\n  vertical-align: initial;\n}\n"
  },
  {
    "path": "packages/element/src/form-collapse/style.ts",
    "content": "import './style.scss'\nimport 'element-ui/packages/theme-chalk/src/collapse.scss'\nimport 'element-ui/packages/theme-chalk/src/collapse-item.scss'\nimport 'element-ui/packages/theme-chalk/src/badge.scss'\n"
  },
  {
    "path": "packages/element/src/form-dialog/index.ts",
    "content": "import { createForm, Form, IFormProps } from '@formily/core'\nimport { toJS } from '@formily/reactive'\nimport { observer } from '@formily/reactive-vue'\nimport {\n  applyMiddleware,\n  IMiddleware,\n  isBool,\n  isFn,\n  isNum,\n  isStr,\n} from '@formily/shared'\nimport { FormProvider, Fragment, h } from '@formily/vue'\nimport type { Button as ButtonProps, Dialog as DialogProps } from 'element-ui'\nimport { Button, Dialog } from 'element-ui'\nimport { t } from 'element-ui/src/locale'\nimport { Portal, PortalTarget } from 'portal-vue'\nimport Vue, { Component, VNode } from 'vue'\nimport { defineComponent } from 'vue-demi'\nimport { stylePrefix } from '../__builtins__/configs'\nimport {\n  createPortalProvider,\n  getProtalContext,\n  isValidElement,\n  loading,\n  resolveComponent,\n} from '../__builtins__/shared'\n\ntype FormDialogContentProps = { form: Form }\n\ntype FormDialogContent = Component | ((props: FormDialogContentProps) => VNode)\n\ntype DialogTitle = string | number | Component | VNode | (() => VNode)\n\ntype IFormDialogProps = Omit<DialogProps, 'title'> & {\n  title?: DialogTitle\n  footer?: null | Component | VNode | (() => VNode)\n  cancelText?: string | Component | VNode | (() => VNode)\n  cancelButtonProps?: ButtonProps\n  okText?: string | Component | VNode | (() => VNode)\n  okButtonProps?: ButtonProps\n  onOpen?: () => void\n  onOpened?: () => void\n  onClose?: () => void\n  onClosed?: () => void\n  onCancel?: () => void\n  onOK?: () => void\n  loadingText?: string\n}\n\nconst PORTAL_TARGET_NAME = 'FormDialogFooter'\n\nconst isDialogTitle = (props: any): props is DialogTitle => {\n  return isNum(props) || isStr(props) || isBool(props) || isValidElement(props)\n}\n\nconst getDialogProps = (props: any): IFormDialogProps => {\n  if (isDialogTitle(props)) {\n    return {\n      title: props,\n    } as IFormDialogProps\n  } else {\n    return props\n  }\n}\n\nexport interface IFormDialog {\n  forOpen(middleware: IMiddleware<IFormProps>): IFormDialog\n  forConfirm(middleware: IMiddleware<Form>): IFormDialog\n  forCancel(middleware: IMiddleware<Form>): IFormDialog\n  open(props?: IFormProps): Promise<any>\n  close(): void\n}\n\nexport interface IFormDialogComponentProps {\n  content: FormDialogContent\n  resolve: () => any\n  reject: () => any\n}\n\nexport function FormDialog(\n  title: IFormDialogProps | DialogTitle,\n  content: FormDialogContent\n): IFormDialog\n\nexport function FormDialog(\n  title: IFormDialogProps | DialogTitle,\n  id: string | symbol,\n  content: FormDialogContent\n): IFormDialog\n\nexport function FormDialog(\n  title: DialogTitle,\n  id: string,\n  content: FormDialogContent\n): IFormDialog\n\nexport function FormDialog(\n  title: IFormDialogProps | DialogTitle,\n  id: string | symbol | FormDialogContent,\n  content?: FormDialogContent\n): IFormDialog {\n  if (isFn(id) || isValidElement(id)) {\n    content = id as FormDialogContent\n    id = 'form-dialog'\n  }\n\n  const prefixCls = `${stylePrefix}-form-dialog`\n  const env = {\n    root: document.createElement('div'),\n    form: null,\n    promise: null,\n    instance: null,\n    openMiddlewares: [],\n    confirmMiddlewares: [],\n    cancelMiddlewares: [],\n  }\n\n  document.body.appendChild(env.root)\n\n  const props = getDialogProps(title)\n  const dialogProps = {\n    ...props,\n    onClosed: () => {\n      props.onClosed?.()\n      env.instance.$destroy()\n      env.instance = null\n      env.root?.parentNode?.removeChild(env.root)\n      env.root = undefined\n    },\n  }\n\n  const component = observer(\n    defineComponent({\n      setup() {\n        return () =>\n          h(\n            Fragment,\n            {},\n            {\n              default: () =>\n                resolveComponent(content, {\n                  form: env.form,\n                }),\n            }\n          )\n      },\n    })\n  )\n\n  const render = (visible = true, resolve?: () => any, reject?: () => any) => {\n    if (!env.instance) {\n      const ComponentConstructor = observer(\n        Vue.extend({\n          props: ['dialogProps'],\n          data() {\n            return {\n              visible: false,\n            }\n          },\n          render() {\n            const {\n              onClose,\n              onClosed,\n              onOpen,\n              onOpened,\n              onOK,\n              onCancel,\n              title,\n              footer,\n              okText,\n              cancelText,\n              okButtonProps,\n              cancelButtonProps,\n              ...dialogProps\n            } = this.dialogProps\n\n            return h(\n              FormProvider,\n              {\n                props: {\n                  form: env.form,\n                },\n              },\n              {\n                default: () =>\n                  h(\n                    Dialog,\n                    {\n                      class: [`${prefixCls}`],\n                      attrs: {\n                        visible: this.visible,\n                        ...dialogProps,\n                      },\n                      on: {\n                        'update:visible': (val) => {\n                          this.visible = val\n                        },\n                        close: () => {\n                          onClose?.()\n                        },\n\n                        closed: () => {\n                          onClosed?.()\n                        },\n                        open: () => {\n                          onOpen?.()\n                        },\n                        opened: () => {\n                          onOpened?.()\n                        },\n                      },\n                    },\n                    {\n                      default: () => [h(component, {}, {})],\n                      title: () =>\n                        h(\n                          'div',\n                          {},\n                          { default: () => resolveComponent(title) }\n                        ),\n                      footer: () =>\n                        h(\n                          'div',\n                          {},\n                          {\n                            default: () => {\n                              const FooterProtalTarget = h(\n                                PortalTarget,\n                                {\n                                  props: {\n                                    name: PORTAL_TARGET_NAME,\n                                    slim: true,\n                                  },\n                                },\n                                {}\n                              )\n                              if (footer === null) {\n                                return [null, FooterProtalTarget]\n                              } else if (footer) {\n                                return [\n                                  resolveComponent(footer),\n                                  FooterProtalTarget,\n                                ]\n                              }\n\n                              return [\n                                h(\n                                  Button,\n                                  {\n                                    attrs: {\n                                      ...cancelButtonProps\n                                    },\n                                    on: {\n                                      click: (e) => {\n                                        onCancel?.(e)\n                                        reject()\n                                      },\n                                    },\n                                  },\n                                  {\n                                    default: () =>\n                                      resolveComponent(\n                                        cancelText ||\n                                          t('el.popconfirm.cancelButtonText')\n                                      ),\n                                  }\n                                ),\n\n                                h(\n                                  Button,\n                                  {\n                                    attrs: {\n                                      type: 'primary',\n                                      ...okButtonProps,\n                                      loading: env.form.submitting,\n                                    },\n                                    on: {\n                                      click: (e) => {\n                                        onOK?.(e)\n                                        resolve()\n                                      },\n                                    },\n                                  },\n                                  {\n                                    default: () =>\n                                      resolveComponent(\n                                        okText ||\n                                          t('el.popconfirm.confirmButtonText')\n                                      ),\n                                  }\n                                ),\n                                FooterProtalTarget,\n                              ]\n                            },\n                          }\n                        ),\n                    }\n                  ),\n              }\n            )\n          },\n        })\n      )\n      env.instance = new ComponentConstructor({\n        propsData: {\n          dialogProps,\n        },\n        parent: getProtalContext(id as string | symbol),\n      })\n      env.instance.$mount(env.root)\n      env.root = env.instance.$el\n    }\n\n    env.instance.visible = visible\n  }\n\n  const formDialog = {\n    forOpen: (middleware: IMiddleware<IFormProps>) => {\n      if (isFn(middleware)) {\n        env.openMiddlewares.push(middleware)\n      }\n      return formDialog\n    },\n    forConfirm: (middleware: IMiddleware<Form>) => {\n      if (isFn(middleware)) {\n        env.confirmMiddlewares.push(middleware)\n      }\n      return formDialog\n    },\n    forCancel: (middleware: IMiddleware<Form>) => {\n      if (isFn(middleware)) {\n        env.cancelMiddlewares.push(middleware)\n      }\n      return formDialog\n    },\n    open: (props: IFormProps) => {\n      if (env.promise) return env.promise\n\n      env.promise = new Promise(async (resolve, reject) => {\n        try {\n          props = await loading(dialogProps.loadingText, () =>\n            applyMiddleware(props, env.openMiddlewares)\n          )\n          env.form = env.form || createForm(props)\n        } catch (e) {\n          reject(e)\n        }\n\n        render(\n          true,\n          () => {\n            env.form\n              .submit(async () => {\n                await applyMiddleware(env.form, env.confirmMiddlewares)\n                resolve(toJS(env.form.values))\n                if (dialogProps.beforeClose) {\n                  setTimeout(() => {\n                    dialogProps.beforeClose(() => {\n                      formDialog.close()\n                    })\n                  })\n                } else {\n                  formDialog.close()\n                }\n              })\n              .catch(() => {})\n          },\n          async () => {\n            await loading(dialogProps.loadingText, () =>\n              applyMiddleware(env.form, env.cancelMiddlewares)\n            )\n\n            if (dialogProps.beforeClose) {\n              dialogProps.beforeClose(() => {\n                formDialog.close()\n              })\n            } else {\n              formDialog.close()\n            }\n          }\n        )\n      })\n      return env.promise\n    },\n    close: () => {\n      if (!env.root) return\n      render(false)\n    },\n  }\n  return formDialog\n}\n\nconst FormDialogFooter = defineComponent({\n  name: 'FFormDialogFooter',\n  setup(props, { slots }) {\n    return () => {\n      return h(\n        Portal,\n        {\n          props: {\n            to: PORTAL_TARGET_NAME,\n          },\n        },\n        slots\n      )\n    }\n  },\n})\n\nFormDialog.Footer = FormDialogFooter\nFormDialog.Portal = createPortalProvider('form-dialog')\n\nexport default FormDialog\n"
  },
  {
    "path": "packages/element/src/form-dialog/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/dialog.scss'\nimport 'element-ui/packages/theme-chalk/src/button.scss'\nimport 'element-ui/packages/theme-chalk/src/loading.scss'\n"
  },
  {
    "path": "packages/element/src/form-drawer/index.ts",
    "content": "import { createForm, Form, IFormProps } from '@formily/core'\nimport { toJS } from '@formily/reactive'\nimport { observer } from '@formily/reactive-vue'\nimport {\n  applyMiddleware,\n  IMiddleware,\n  isBool,\n  isFn,\n  isNum,\n  isStr,\n} from '@formily/shared'\nimport { FormProvider, Fragment, h } from '@formily/vue'\nimport type { Button as ButtonProps, Drawer as DrawerProps } from 'element-ui'\nimport { Button, Drawer } from 'element-ui'\nimport { t } from 'element-ui/src/locale'\nimport { Portal, PortalTarget } from 'portal-vue'\nimport Vue, { Component, VNode } from 'vue'\nimport { defineComponent } from 'vue-demi'\nimport { stylePrefix } from '../__builtins__/configs'\nimport {\n  createPortalProvider,\n  getProtalContext,\n  isValidElement,\n  loading,\n  resolveComponent,\n} from '../__builtins__/shared'\n\ntype FormDrawerContentProps = { form: Form }\n\ntype FormDrawerContent = Component | ((props: FormDrawerContentProps) => VNode)\n\ntype DrawerTitle = string | number | Component | VNode | (() => VNode)\n\ntype IFormDrawerProps = Omit<DrawerProps, 'title'> & {\n  title?: DrawerTitle\n  footer?: null | Component | VNode | (() => VNode)\n  cancelText?: string | Component | VNode | (() => VNode)\n  cancelButtonProps?: ButtonProps\n  okText?: string | Component | VNode | (() => VNode)\n  okButtonProps?: ButtonProps\n  onOpen?: () => void\n  onOpened?: () => void\n  onClose?: () => void\n  onClosed?: () => void\n  onCancel?: () => void\n  onOK?: () => void\n  loadingText?: string\n}\n\nconst PORTAL_TARGET_NAME = 'FormDrawerFooter'\n\nconst isDrawerTitle = (props: any): props is DrawerTitle => {\n  return isNum(props) || isStr(props) || isBool(props) || isValidElement(props)\n}\n\nconst getDrawerProps = (props: any): IFormDrawerProps => {\n  if (isDrawerTitle(props)) {\n    return {\n      title: props,\n    } as IFormDrawerProps\n  } else {\n    return props\n  }\n}\n\nexport interface IFormDrawer {\n  forOpen(middleware: IMiddleware<IFormProps>): IFormDrawer\n  forConfirm(middleware: IMiddleware<IFormProps>): IFormDrawer\n  forCancel(middleware: IMiddleware<IFormProps>): IFormDrawer\n  open(props?: IFormProps): Promise<any>\n  close(): void\n}\n\nexport interface IFormDrawerComponentProps {\n  content: FormDrawerContent\n  resolve: () => any\n  reject: () => any\n}\n\nexport function FormDrawer(\n  title: IFormDrawerProps | DrawerTitle,\n  content: FormDrawerContent\n): IFormDrawer\n\nexport function FormDrawer(\n  title: IFormDrawerProps | DrawerTitle,\n  id: string | symbol,\n  content: FormDrawerContent\n): IFormDrawer\n\nexport function FormDrawer(\n  title: DrawerTitle,\n  id: string,\n  content: FormDrawerContent\n): IFormDrawer\n\nexport function FormDrawer(\n  title: IFormDrawerProps | DrawerTitle,\n  id: string | symbol | FormDrawerContent,\n  content?: FormDrawerContent\n): IFormDrawer {\n  if (isFn(id) || isValidElement(id)) {\n    content = id as FormDrawerContent\n    id = 'form-drawer'\n  }\n\n  const prefixCls = `${stylePrefix}-form-drawer`\n  const env = {\n    root: document.createElement('div'),\n    form: null,\n    promise: null,\n    instance: null,\n    openMiddlewares: [],\n    confirmMiddlewares: [],\n    cancelMiddlewares: [],\n  }\n\n  document.body.appendChild(env.root)\n\n  const props = getDrawerProps(title)\n  const drawerProps = {\n    ...props,\n    onClosed: () => {\n      props.onClosed?.()\n      env.instance.$destroy()\n      env.instance = null\n      env.root?.parentNode?.removeChild(env.root)\n      env.root = undefined\n    },\n  }\n\n  const component = observer(\n    defineComponent({\n      setup() {\n        return () =>\n          h(\n            Fragment,\n            {},\n            {\n              default: () =>\n                resolveComponent(content, {\n                  form: env.form,\n                }),\n            }\n          )\n      },\n    })\n  )\n\n  const render = (visible = true, resolve?: () => any, reject?: () => any) => {\n    if (!env.instance) {\n      const ComponentConstructor = Vue.extend({\n        props: ['drawerProps'],\n        data() {\n          return {\n            visible: false,\n          }\n        },\n        render() {\n          const {\n            onClose,\n            onClosed,\n            onOpen,\n            onOpened,\n            onOK,\n            onCancel,\n            title,\n            footer,\n            okText,\n            cancelText,\n            okButtonProps,\n            cancelButtonProps,\n            ...drawerProps\n          } = this.drawerProps\n\n          return h(\n            FormProvider,\n            {\n              props: {\n                form: env.form,\n              },\n            },\n            {\n              default: () =>\n                h(\n                  Drawer,\n                  {\n                    class: [`${prefixCls}`],\n                    attrs: {\n                      visible: this.visible,\n                      ...drawerProps,\n                    },\n                    on: {\n                      'update:visible': (val) => {\n                        this.visible = val\n                      },\n                      close: () => {\n                        onClose?.()\n                      },\n\n                      closed: () => {\n                        onClosed?.()\n                      },\n                      open: () => {\n                        onOpen?.()\n                      },\n                      opened: () => {\n                        onOpened?.()\n                      },\n                    },\n                  },\n                  {\n                    default: () => [\n                      h(\n                        'div',\n                        {\n                          class: [`${prefixCls}-body`],\n                        },\n                        {\n                          default: () => h(component, {}, {}),\n                        }\n                      ),\n                      h(\n                        'div',\n                        {\n                          class: [`${prefixCls}-footer`],\n                        },\n                        {\n                          default: () => {\n                            const FooterProtalTarget = h(\n                              PortalTarget,\n                              {\n                                props: {\n                                  name: PORTAL_TARGET_NAME,\n                                  slim: true,\n                                },\n                              },\n                              {}\n                            )\n\n                            if (footer === null) {\n                              return [null, FooterProtalTarget]\n                            } else if (footer) {\n                              return [\n                                resolveComponent(footer),\n                                FooterProtalTarget,\n                              ]\n                            }\n\n                            return [\n                              h(\n                                Button,\n                                {\n                                  attrs: cancelButtonProps,\n                                  on: {\n                                    click: (e) => {\n                                      onCancel?.(e)\n                                      reject()\n                                    },\n                                  },\n                                },\n                                {\n                                  default: () =>\n                                    resolveComponent(\n                                      cancelText ||\n                                        t('el.popconfirm.cancelButtonText')\n                                    ),\n                                }\n                              ),\n\n                              h(\n                                Button,\n                                {\n                                  attrs: {\n                                    type: 'primary',\n                                    ...okButtonProps,\n                                  },\n                                  on: {\n                                    click: (e) => {\n                                      onOK?.(e)\n                                      resolve()\n                                    },\n                                  },\n                                },\n                                {\n                                  default: () =>\n                                    resolveComponent(\n                                      okText ||\n                                        t('el.popconfirm.confirmButtonText')\n                                    ),\n                                }\n                              ),\n                              FooterProtalTarget,\n                            ]\n                          },\n                        }\n                      ),\n                    ],\n                    title: () =>\n                      h('div', {}, { default: () => resolveComponent(title) }),\n                  }\n                ),\n            }\n          )\n        },\n      })\n      env.instance = new ComponentConstructor({\n        propsData: {\n          drawerProps,\n        },\n        parent: getProtalContext(id as string | symbol),\n      })\n      env.instance.$mount(env.root)\n    }\n\n    env.instance.visible = visible\n  }\n\n  const formDrawer = {\n    forOpen: (middleware: IMiddleware<IFormProps>) => {\n      if (isFn(middleware)) {\n        env.openMiddlewares.push(middleware)\n      }\n      return formDrawer\n    },\n    forConfirm: (middleware: IMiddleware<Form>) => {\n      if (isFn(middleware)) {\n        env.confirmMiddlewares.push(middleware)\n      }\n      return formDrawer\n    },\n    forCancel: (middleware: IMiddleware<Form>) => {\n      if (isFn(middleware)) {\n        env.cancelMiddlewares.push(middleware)\n      }\n      return formDrawer\n    },\n    open: (props: IFormProps) => {\n      if (env.promise) return env.promise\n\n      env.promise = new Promise(async (resolve, reject) => {\n        try {\n          props = await loading(drawerProps.loadingText, () =>\n            applyMiddleware(props, env.openMiddlewares)\n          )\n          env.form = env.form || createForm(props)\n        } catch (e) {\n          reject(e)\n        }\n\n        render(\n          true,\n          () => {\n            env.form\n              .submit(async () => {\n                await applyMiddleware(env.form, env.confirmMiddlewares)\n                resolve(toJS(env.form.values))\n                if (drawerProps.beforeClose) {\n                  setTimeout(() => {\n                    drawerProps.beforeClose(() => {\n                      formDrawer.close()\n                    })\n                  })\n                } else {\n                  formDrawer.close()\n                }\n              })\n              .catch(() => {})\n          },\n          async () => {\n            await loading(drawerProps.loadingText, () =>\n              applyMiddleware(env.form, env.cancelMiddlewares)\n            )\n\n            if (drawerProps.beforeClose) {\n              drawerProps.beforeClose(() => {\n                formDrawer.close()\n              })\n            } else {\n              formDrawer.close()\n            }\n          }\n        )\n      })\n      return env.promise\n    },\n    close: () => {\n      if (!env.root) return\n      render(false)\n    },\n  }\n  return formDrawer\n}\n\nconst FormDrawerFooter = defineComponent({\n  name: 'FFormDrawerFooter',\n  setup(props, { slots }) {\n    return () => {\n      return h(\n        Portal,\n        {\n          props: {\n            to: PORTAL_TARGET_NAME,\n          },\n        },\n        slots\n      )\n    }\n  },\n})\n\nFormDrawer.Footer = FormDrawerFooter\nFormDrawer.Protal = createPortalProvider('form-drawer')\n\nexport default FormDrawer\n"
  },
  {
    "path": "packages/element/src/form-drawer/style.scss",
    "content": "@import '../__builtins__/styles/common.scss';\n\n.#{$formily-prefix}-form-drawer {\n  .el-drawer__body {\n    display: flex;\n    flex-direction: column;\n  }\n\n  &-body {\n    flex: 1;\n    overflow: auto;\n    padding: $--dialog-padding-primary;\n  }\n\n  &-footer {\n    padding: $--dialog-padding-primary;\n    display: flex;\n    justify-content: flex-end;\n    align-items: center;\n  }\n}\n"
  },
  {
    "path": "packages/element/src/form-drawer/style.ts",
    "content": "import './style.scss'\nimport 'element-ui/packages/theme-chalk/src/drawer.scss'\nimport 'element-ui/packages/theme-chalk/src/button.scss'\nimport 'element-ui/packages/theme-chalk/src/loading.scss'\n"
  },
  {
    "path": "packages/element/src/form-grid/index.ts",
    "content": "import { Grid, IGridOptions } from '@formily/grid'\nimport { markRaw } from '@formily/reactive'\nimport { observer } from '@formily/reactive-vue'\nimport { h } from '@formily/vue'\nimport {\n  computed,\n  defineComponent,\n  inject,\n  InjectionKey,\n  onMounted,\n  PropType,\n  provide,\n  ref,\n  Ref,\n  watchEffect,\n} from 'vue-demi'\nimport { useFormLayout } from '../form-layout'\nimport { stylePrefix } from '../__builtins__/configs'\nimport { composeExport } from '../__builtins__/shared'\n\nexport interface IFormGridProps extends IGridOptions {\n  grid?: Grid<HTMLElement>\n  prefixCls?: string\n  className?: string\n  style?: React.CSSProperties\n}\n\nconst FormGridSymbol: InjectionKey<Ref<Grid<HTMLElement>>> =\n  Symbol('FormGridContext')\n\ninterface GridColumnProps {\n  gridSpan: number\n}\n\nexport const createFormGrid = (props: IFormGridProps): Grid<HTMLElement> => {\n  return markRaw(new Grid(props))\n}\n\nexport const useFormGrid = (): Ref<Grid<HTMLElement>> => inject(FormGridSymbol)\n\n/**\n * @deprecated\n */\nconst useGridSpan = (gridSpan: number) => {\n  return gridSpan\n}\n\n/**\n * @deprecated\n */\nexport const useGridColumn = (gridSpan = 1) => {\n  return gridSpan\n}\n\nconst FormGridInner = observer(\n  defineComponent({\n    name: 'FFormGrid',\n    props: {\n      columnGap: {\n        type: Number,\n      },\n      rowGap: {\n        type: Number,\n      },\n      minColumns: {\n        type: [Number, Array],\n      },\n      minWidth: {\n        type: [Number, Array],\n      },\n      maxColumns: {\n        type: [Number, Array],\n      },\n      maxWidth: {\n        type: [Number, Array],\n      },\n      breakpoints: {\n        type: Array,\n      },\n      colWrap: {\n        type: Boolean,\n        default: true,\n      },\n      strictAutoFit: {\n        type: Boolean,\n        default: false,\n      },\n      shouldVisible: {\n        type: Function as PropType<IGridOptions['shouldVisible']>,\n        default() {\n          return () => true\n        },\n      },\n      grid: {\n        type: Object as PropType<Grid<HTMLElement>>,\n      },\n    },\n    setup(props: IFormGridProps) {\n      const layout = useFormLayout()\n\n      const gridInstance = computed(() => {\n        const newProps: IFormGridProps = {}\n        Object.keys(props).forEach((key) => {\n          if (typeof props[key] !== 'undefined') {\n            newProps[key] = props[key]\n          }\n        })\n        const options = {\n          columnGap: layout.value?.gridColumnGap ?? 8,\n          rowGap: layout.value?.gridRowGap ?? 4,\n          ...newProps,\n        }\n        return markRaw(options?.grid ? options.grid : new Grid(options))\n      })\n      const prefixCls = `${stylePrefix}-form-grid`\n      const root = ref(null)\n\n      provide(FormGridSymbol, gridInstance)\n\n      onMounted(() => {\n        watchEffect((onInvalidate) => {\n          const dispose = gridInstance.value.connect(root.value)\n          onInvalidate(() => {\n            dispose()\n          })\n        })\n      })\n\n      return {\n        prefixCls,\n        root,\n        gridInstance,\n      }\n    },\n    render() {\n      const { prefixCls, gridInstance } = this\n      return h(\n        'div',\n        {\n          attrs: {\n            class: `${prefixCls}`,\n          },\n          style: {\n            gridTemplateColumns: gridInstance.templateColumns,\n            gap: gridInstance.gap,\n          },\n          ref: 'root',\n        },\n        {\n          default: () => this.$slots.default,\n        }\n      )\n    },\n  })\n) as any\n\nconst FormGridColumn = observer(\n  defineComponent({\n    name: 'FFormGridColumn',\n    props: {\n      gridSpan: {\n        type: Number,\n        default: 1,\n      },\n    },\n    setup(props: GridColumnProps, { slots }) {\n      return () => {\n        return h(\n          'div',\n          {\n            attrs: {\n              'data-grid-span': props.gridSpan,\n            },\n          },\n          slots\n        )\n      }\n    },\n  })\n)\n\nexport const FormGrid = composeExport(FormGridInner, {\n  GridColumn: FormGridColumn,\n  useGridSpan,\n  useFormGrid,\n  createFormGrid,\n})\n\nexport default FormGrid\n"
  },
  {
    "path": "packages/element/src/form-grid/style.scss",
    "content": "@import '../__builtins__/styles/common.scss';\n\n.#{$formily-prefix}-form-grid {\n  display: grid;\n}\n"
  },
  {
    "path": "packages/element/src/form-grid/style.ts",
    "content": "import './style.scss'\n"
  },
  {
    "path": "packages/element/src/form-item/animation.scss",
    "content": "@-webkit-keyframes antShowHelpIn {\n  0% {\n    -webkit-transform: translateY(-5px);\n    transform: translateY(-5px);\n    opacity: 0;\n  }\n\n  to {\n    -webkit-transform: translateY(0);\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n\n.#{$form-item-prefix}-help-appear,\n.#{$form-item-prefix}-help-enter {\n  -webkit-animation-duration: 0.3s;\n  animation-duration: 0.3s;\n  -webkit-animation-fill-mode: both;\n  animation-fill-mode: both;\n  -webkit-animation-play-state: paused;\n  animation-play-state: paused;\n}\n\n.#{$form-item-prefix}-help-appear.#{$form-item-prefix}-help-appear-active,\n.#{$form-item-prefix}-help-enter.#{$form-item-prefix}-help-enter-active {\n  -webkit-animation-name: antShowHelpIn;\n  animation-name: antShowHelpIn;\n  -webkit-animation-play-state: running;\n  animation-play-state: running;\n}\n\n.#{$form-item-prefix}-help-appear,\n.#{$form-item-prefix}-help-enter {\n  opacity: 0;\n}\n\n.#{$form-item-prefix}-help-appear,\n.#{$form-item-prefix}-help-enter {\n  -webkit-animation-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);\n  animation-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);\n}\n\n@keyframes antShowHelpIn {\n  0% {\n    -webkit-transform: translateY(-5px);\n    transform: translateY(-5px);\n    opacity: 0;\n  }\n\n  to {\n    -webkit-transform: translateY(0);\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n\n@-webkit-keyframes antShowHelpOut {\n  to {\n    -webkit-transform: translateY(-5px);\n    transform: translateY(-5px);\n    opacity: 0;\n  }\n}\n\n@keyframes antShowHelpOut {\n  to {\n    -webkit-transform: translateY(-5px);\n    transform: translateY(-5px);\n    opacity: 0;\n  }\n}\n"
  },
  {
    "path": "packages/element/src/form-item/grid.scss",
    "content": ".#{$form-item-prefix}-item-col-24 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 100%;\n  flex: 0 0 100%;\n  max-width: 100%;\n}\n\n.#{$form-item-prefix}-item-col-23 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 95.83333333%;\n  flex: 0 0 95.83333333%;\n  max-width: 95.83333333%;\n}\n\n.#{$form-item-prefix}-item-col-22 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 91.66666667%;\n  flex: 0 0 91.66666667%;\n  max-width: 91.66666667%;\n}\n\n.#{$form-item-prefix}-item-col-21 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 87.5%;\n  flex: 0 0 87.5%;\n  max-width: 87.5%;\n}\n\n.#{$form-item-prefix}-item-col-20 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 83.33333333%;\n  flex: 0 0 83.33333333%;\n  max-width: 83.33333333%;\n}\n\n.#{$form-item-prefix}-item-col-19 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 79.16666667%;\n  flex: 0 0 79.16666667%;\n  max-width: 79.16666667%;\n}\n\n.#{$form-item-prefix}-item-col-18 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 75%;\n  flex: 0 0 75%;\n  max-width: 75%;\n}\n\n.#{$form-item-prefix}-item-col-17 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 70.83333333%;\n  flex: 0 0 70.83333333%;\n  max-width: 70.83333333%;\n}\n\n.#{$form-item-prefix}-item-col-16 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 66.66666667%;\n  flex: 0 0 66.66666667%;\n  max-width: 66.66666667%;\n}\n\n.#{$form-item-prefix}-item-col-15 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 62.5%;\n  flex: 0 0 62.5%;\n  max-width: 62.5%;\n}\n\n.#{$form-item-prefix}-item-col-14 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 58.33333333%;\n  flex: 0 0 58.33333333%;\n  max-width: 58.33333333%;\n}\n\n.#{$form-item-prefix}-item-col-13 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 54.16666667%;\n  flex: 0 0 54.16666667%;\n  max-width: 54.16666667%;\n}\n\n.#{$form-item-prefix}-item-col-12 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 50%;\n  flex: 0 0 50%;\n  max-width: 50%;\n}\n\n.#{$form-item-prefix}-item-col-11 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 45.83333333%;\n  flex: 0 0 45.83333333%;\n  max-width: 45.83333333%;\n}\n\n.#{$form-item-prefix}-item-col-10 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 41.66666667%;\n  flex: 0 0 41.66666667%;\n  max-width: 41.66666667%;\n}\n\n.#{$form-item-prefix}-item-col-9 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 37.5%;\n  flex: 0 0 37.5%;\n  max-width: 37.5%;\n}\n\n.#{$form-item-prefix}-item-col-8 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 33.33333333%;\n  flex: 0 0 33.33333333%;\n  max-width: 33.33333333%;\n}\n\n.#{$form-item-prefix}-item-col-7 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 29.16666667%;\n  flex: 0 0 29.16666667%;\n  max-width: 29.16666667%;\n}\n\n.#{$form-item-prefix}-item-col-6 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 25%;\n  flex: 0 0 25%;\n  max-width: 25%;\n}\n\n.#{$form-item-prefix}-item-col-5 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 20.83333333%;\n  flex: 0 0 20.83333333%;\n  max-width: 20.83333333%;\n}\n\n.#{$form-item-prefix}-item-col-4 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 16.66666667%;\n  flex: 0 0 16.66666667%;\n  max-width: 16.66666667%;\n}\n\n.#{$form-item-prefix}-item-col-3 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 12.5%;\n  flex: 0 0 12.5%;\n  max-width: 12.5%;\n}\n\n.#{$form-item-prefix}-item-col-2 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 8.33333333%;\n  flex: 0 0 8.33333333%;\n  max-width: 8.33333333%;\n}\n\n.#{$form-item-prefix}-item-col-1 {\n  -webkit-box-flex: 0;\n  -ms-flex: 0 0 4.16666667%;\n  flex: 0 0 4.16666667%;\n  max-width: 4.16666667%;\n}\n\n.#{$form-item-prefix}-item-col-0 {\n  display: none;\n}\n"
  },
  {
    "path": "packages/element/src/form-item/index.ts",
    "content": "import { isVoidField } from '@formily/core'\nimport { connect, h, mapProps } from '@formily/vue'\nimport { Tooltip } from 'element-ui'\nimport ResizeObserver from 'resize-observer-polyfill'\nimport { Component } from 'vue'\nimport {\n  defineComponent,\n  onBeforeUnmount,\n  provide,\n  ref,\n  Ref,\n  watch,\n} from 'vue-demi'\nimport { FormLayoutShallowContext, useFormLayout } from '../form-layout'\nimport { stylePrefix } from '../__builtins__/configs'\nimport {\n  composeExport,\n  resolveComponent,\n  useCompatRef,\n} from '../__builtins__/shared'\n\nexport type FormItemProps = {\n  className?: string\n  required?: boolean\n  label?: string | Component\n  colon?: boolean\n  tooltip?: string | Component\n  layout?: 'vertical' | 'horizontal' | 'inline'\n  labelStyle?: Record<string, any>\n  labelAlign?: 'left' | 'right'\n  labelWrap?: boolean\n  labelWidth?: number\n  wrapperWidth?: number\n  labelCol?: number\n  wrapperCol?: number\n  wrapperAlign?: 'left' | 'right'\n  wrapperWrap?: boolean\n  wrapperStyle?: Record<string, any>\n  fullness?: boolean\n  addonBefore?: string | Component\n  addonAfter?: string | Component\n  size?: 'small' | 'default' | 'large'\n  extra?: string\n  feedbackText?: string | Component\n  feedbackLayout?: 'loose' | 'terse' | 'popover' | 'none' | (string & {})\n  feedbackStatus?: 'error' | 'warning' | 'success' | 'pending' | (string & {})\n  tooltipLayout?: 'icon' | 'text'\n  feedbackIcon?: string | Component\n  asterisk?: boolean\n  gridSpan?: number\n  bordered?: boolean\n  inset?: boolean\n}\n\nconst useOverflow = (containerRef: Ref<HTMLElement>) => {\n  const overflow = ref(false)\n  let resizeObserver: ResizeObserver | undefined\n\n  const cleanup = () => {\n    if (resizeObserver) {\n      resizeObserver.unobserve(containerRef.value)\n      resizeObserver = null\n    }\n  }\n\n  const observer = () => {\n    const container = containerRef.value\n    const content = container.querySelector('label')\n    const containerWidth = container.getBoundingClientRect().width\n    const contentWidth = content?.getBoundingClientRect().width\n\n    if (containerWidth !== 0) {\n      if (contentWidth > containerWidth) {\n        overflow.value = true\n      } else {\n        overflow.value = false\n      }\n    }\n  }\n\n  const stopWatch = watch(\n    () => containerRef.value,\n    (el) => {\n      cleanup()\n\n      if (el) {\n        resizeObserver = new ResizeObserver(observer)\n        resizeObserver.observe(el)\n      }\n    },\n    { immediate: true, flush: 'post' }\n  )\n\n  onBeforeUnmount(() => {\n    cleanup()\n    stopWatch()\n  })\n\n  return overflow\n}\n\nconst ICON_MAP = {\n  error: () => h('i', { class: 'el-icon-circle-close' }, {}),\n  success: () => h('i', { class: 'el-icon-circle-check' }, {}),\n  warning: () => h('i', { class: 'el-icon-warning-outline' }, {}),\n}\n\nexport const FormBaseItem = defineComponent<FormItemProps>({\n  name: 'FormItem',\n  props: {\n    className: {},\n    required: {},\n    label: {},\n    colon: {},\n    layout: {},\n    tooltip: {},\n    labelStyle: {},\n    labelAlign: {},\n    labelWrap: {},\n    labelWidth: {},\n    wrapperWidth: {},\n    labelCol: {},\n    wrapperCol: {},\n    wrapperAlign: {},\n    wrapperWrap: {},\n    wrapperStyle: {},\n    fullness: {},\n    addonBefore: {},\n    addonAfter: {},\n    size: {},\n    extra: {},\n    feedbackText: {},\n    feedbackLayout: {},\n    tooltipLayout: {},\n    feedbackStatus: {},\n    feedbackIcon: {},\n    asterisk: {},\n    gridSpan: {},\n    bordered: { default: true },\n    inset: { default: false },\n  },\n  setup(props, { slots, refs }) {\n    const active = ref(false)\n    const deepLayoutRef = useFormLayout()\n\n    const prefixCls = `${stylePrefix}-form-item`\n\n    const { elRef: containerRef, elRefBinder } = useCompatRef(refs)\n    const overflow = useOverflow(containerRef)\n\n    provide(FormLayoutShallowContext, ref(null))\n\n    return () => {\n      const gridStyles: Record<string, any> = {}\n\n      const deepLayout = deepLayoutRef.value\n      const {\n        label,\n        colon = deepLayout.colon ?? true,\n        layout = deepLayout.layout ?? 'horizontal',\n        tooltip,\n        labelStyle = {},\n        labelWrap = deepLayout.labelWrap ?? false,\n        labelWidth = deepLayout.labelWidth,\n        wrapperWidth = deepLayout.wrapperWidth,\n        labelCol = deepLayout.labelCol,\n        wrapperCol = deepLayout.wrapperCol,\n        wrapperAlign = deepLayout.wrapperAlign ?? 'left',\n        wrapperWrap = deepLayout.wrapperWrap,\n        wrapperStyle = {},\n        fullness = deepLayout.fullness,\n        addonBefore,\n        addonAfter,\n        size = deepLayout.size,\n        extra,\n        feedbackText,\n        feedbackLayout = deepLayout.feedbackLayout ?? 'loose',\n        tooltipLayout = deepLayout.tooltipLayout ?? 'icon',\n        feedbackStatus,\n        feedbackIcon,\n        asterisk,\n        bordered = deepLayout.bordered,\n        inset = deepLayout.inset,\n      } = props\n      const labelAlign =\n        deepLayout.layout === 'vertical'\n          ? props.labelAlign ?? deepLayout.labelAlign ?? 'left'\n          : props.labelAlign ?? deepLayout.labelAlign ?? 'right'\n\n      // 固定宽度\n      let enableCol = false\n      if (labelWidth || wrapperWidth) {\n        if (labelWidth) {\n          labelStyle.width = `${labelWidth}px`\n          labelStyle.maxWidth = `${labelWidth}px`\n        }\n        if (wrapperWidth) {\n          wrapperStyle.width = `${wrapperWidth}px`\n          wrapperStyle.maxWidth = `${wrapperWidth}px`\n        }\n        // 栅格模式\n      } else if (labelCol || wrapperCol) {\n        enableCol = true\n      }\n\n      const formatChildren =\n        feedbackLayout === 'popover'\n          ? h(\n              'el-popover',\n              {\n                props: {\n                  disabled: !feedbackText,\n                  placement: 'top',\n                },\n              },\n              {\n                reference: () =>\n                  h('div', {}, { default: () => slots.default?.() }),\n                default: () => [\n                  h(\n                    'div',\n                    {\n                      class: {\n                        [`${prefixCls}-${feedbackStatus}-help`]:\n                          !!feedbackStatus,\n                        [`${prefixCls}-help`]: true,\n                      },\n                    },\n                    {\n                      default: () => [\n                        feedbackStatus &&\n                        ['error', 'success', 'warning'].includes(feedbackStatus)\n                          ? ICON_MAP[\n                              feedbackStatus as 'error' | 'success' | 'warning'\n                            ]()\n                          : '',\n                        resolveComponent(feedbackText),\n                      ],\n                    }\n                  ),\n                ],\n              }\n            )\n          : slots.default?.()\n\n      const renderLabelText = () => {\n        const labelChildren = h(\n          'div',\n          {\n            class: `${prefixCls}-label-content`,\n            ref: elRefBinder,\n          },\n          {\n            default: () => [\n              asterisk &&\n                h(\n                  'span',\n                  { class: `${prefixCls}-asterisk` },\n                  { default: () => ['*'] }\n                ),\n              h('label', {}, { default: () => [resolveComponent(label)] }),\n            ],\n          }\n        )\n        const isTextTooltip = tooltip && tooltipLayout === 'text'\n        if (isTextTooltip || overflow.value) {\n          return h(\n            Tooltip,\n            {\n              props: {\n                placement: 'top',\n              },\n            },\n            {\n              default: () => [labelChildren],\n              content: () =>\n                h(\n                  'div',\n                  {},\n                  {\n                    default: () => [\n                      overflow.value && resolveComponent(label),\n                      isTextTooltip && resolveComponent(tooltip),\n                    ],\n                  }\n                ),\n            }\n          )\n        } else {\n          return labelChildren\n        }\n      }\n      const renderTooltipIcon = () => {\n        if (tooltip && tooltipLayout === 'icon') {\n          return h(\n            'span',\n            {\n              class: `${prefixCls}-label-tooltip`,\n            },\n            {\n              default: () => [\n                h(\n                  Tooltip,\n                  {\n                    props: {\n                      placement: 'top',\n                    },\n                  },\n                  {\n                    default: () => [h('i', { class: 'el-icon-info' }, {})],\n                    content: () =>\n                      h(\n                        'div',\n                        {\n                          class: `${prefixCls}-label-tooltip-content`,\n                        },\n                        {\n                          default: () => [resolveComponent(tooltip)],\n                        }\n                      ),\n                  }\n                ),\n              ],\n            }\n          )\n        }\n      }\n      const renderLabel =\n        label &&\n        h(\n          'div',\n          {\n            class: {\n              [`${prefixCls}-label`]: true,\n              [`${prefixCls}-label-tooltip`]:\n                (tooltip && tooltipLayout === 'text') || overflow.value,\n              [`${prefixCls}-item-col-${labelCol}`]: enableCol && !!labelCol,\n            },\n            style: labelStyle,\n          },\n          {\n            default: () => [\n              // label content\n              renderLabelText(),\n              // label tooltip\n              renderTooltipIcon(),\n              // label colon\n              label &&\n                h(\n                  'span',\n                  {\n                    class: `${prefixCls}-colon`,\n                  },\n                  { default: () => [colon ? ':' : ''] }\n                ),\n            ],\n          }\n        )\n\n      const renderFeedback =\n        !!feedbackText &&\n        feedbackLayout !== 'popover' &&\n        feedbackLayout !== 'none' &&\n        h(\n          'div',\n          {\n            class: {\n              [`${prefixCls}-${feedbackStatus}-help`]: !!feedbackStatus,\n              [`${prefixCls}-help`]: true,\n              [`${prefixCls}-help-enter`]: true,\n              [`${prefixCls}-help-enter-active`]: true,\n            },\n          },\n          { default: () => [resolveComponent(feedbackText)] }\n        )\n\n      const renderExtra =\n        extra &&\n        h(\n          'div',\n          { class: `${prefixCls}-extra` },\n          { default: () => [resolveComponent(extra)] }\n        )\n      const renderContent = h(\n        'div',\n        {\n          class: {\n            [`${prefixCls}-control`]: true,\n            [`${prefixCls}-item-col-${wrapperCol}`]: enableCol && !!wrapperCol,\n          },\n        },\n        {\n          default: () => [\n            h(\n              'div',\n              { class: `${prefixCls}-control-content` },\n              {\n                default: () => [\n                  addonBefore &&\n                    h(\n                      'div',\n                      { class: `${prefixCls}-addon-before` },\n                      {\n                        default: () => [resolveComponent(addonBefore)],\n                      }\n                    ),\n                  h(\n                    'div',\n                    {\n                      class: {\n                        [`${prefixCls}-control-content-component`]: true,\n                        [`${prefixCls}-control-content-component-has-feedback-icon`]:\n                          !!feedbackIcon,\n                      },\n                      style: wrapperStyle,\n                    },\n                    {\n                      default: () => [\n                        formatChildren,\n                        feedbackIcon &&\n                          h(\n                            'div',\n                            { class: `${prefixCls}-feedback-icon` },\n                            {\n                              default: () => [\n                                typeof feedbackIcon === 'string'\n                                  ? h('i', { class: feedbackIcon }, {})\n                                  : resolveComponent(feedbackIcon),\n                              ],\n                            }\n                          ),\n                      ],\n                    }\n                  ),\n                  addonAfter &&\n                    h(\n                      'div',\n                      { class: `${prefixCls}-addon-after` },\n                      {\n                        default: () => [resolveComponent(addonAfter)],\n                      }\n                    ),\n                ],\n              }\n            ),\n            renderFeedback,\n            renderExtra,\n          ],\n        }\n      )\n      return h(\n        'div',\n        {\n          style: {\n            ...gridStyles,\n          },\n          attrs: {\n            'data-grid-span': props.gridSpan,\n          },\n          class: {\n            [`${prefixCls}`]: true,\n            [`${prefixCls}-layout-${layout}`]: true,\n            [`${prefixCls}-${feedbackStatus}`]: !!feedbackStatus,\n            [`${prefixCls}-feedback-has-text`]: !!feedbackText,\n            [`${prefixCls}-size-${size}`]: !!size,\n            [`${prefixCls}-feedback-layout-${feedbackLayout}`]:\n              !!feedbackLayout,\n            [`${prefixCls}-fullness`]: !!fullness || !!inset || !!feedbackIcon,\n            [`${prefixCls}-inset`]: !!inset,\n            [`${prefixCls}-active`]: active.value,\n            [`${prefixCls}-inset-active`]: !!inset && active.value,\n            [`${prefixCls}-label-align-${labelAlign}`]: true,\n            [`${prefixCls}-control-align-${wrapperAlign}`]: true,\n            [`${prefixCls}-label-wrap`]: !!labelWrap,\n            [`${prefixCls}-control-wrap`]: !!wrapperWrap,\n            [`${prefixCls}-bordered-none`]:\n              bordered === false || !!inset || !!feedbackIcon,\n            [`${props.className}`]: !!props.className,\n          },\n          on: {\n            focus: () => {\n              if (feedbackIcon || inset) {\n                active.value = true\n              }\n            },\n            blur: () => {\n              if (feedbackIcon || inset) {\n                active.value = false\n              }\n            },\n          },\n        },\n        {\n          default: () => [renderLabel, renderContent],\n        }\n      )\n    }\n  },\n})\n\nconst Item = connect(\n  FormBaseItem,\n  mapProps(\n    { validateStatus: true, title: 'label', required: true },\n    (props, field) => {\n      if (isVoidField(field)) return props\n      if (!field) return props\n      const takeMessage = () => {\n        if (field.validating) return\n        if (props.feedbackText) return props.feedbackText\n        if (field.selfErrors.length) return field.selfErrors\n        if (field.selfWarnings.length) return field.selfWarnings\n        if (field.selfSuccesses.length) return field.selfSuccesses\n      }\n      const errorMessages = takeMessage()\n      return {\n        feedbackText: Array.isArray(errorMessages)\n          ? errorMessages.join(', ')\n          : errorMessages,\n        extra: props.extra || field.description,\n      }\n    },\n    (props, field) => {\n      if (isVoidField(field)) return props\n      if (!field) return props\n      return {\n        feedbackStatus:\n          field.validateStatus === 'validating'\n            ? 'pending'\n            : (Array.isArray(field.decorator) &&\n                field.decorator[1]?.feedbackStatus) ||\n              field.validateStatus,\n      }\n    },\n    (props, field) => {\n      if (isVoidField(field)) return props\n\n      if (!field) return props\n      let asterisk = false\n      if (field.required && field.pattern !== 'readPretty') {\n        asterisk = true\n      }\n      if ('asterisk' in props) {\n        asterisk = props.asterisk\n      }\n      return {\n        asterisk,\n      }\n    }\n  )\n)\n\nexport const FormItem = composeExport(Item, {\n  BaseItem: FormBaseItem,\n})\n\nexport default FormItem\n"
  },
  {
    "path": "packages/element/src/form-item/style.scss",
    "content": "@use 'sass:math';\n@import '../__builtins__/styles/common.scss';\n@import './var.scss';\n@import './grid.scss';\n@import './animation.scss';\n\n.#{$form-item-prefix} {\n  display: flex;\n  margin-bottom: $--form-item-margin-bottom;\n  position: relative;\n  line-height: $--form-item-medium-line-height;\n  font-size: $--form-font-size;\n\n  &-label * {\n    line-height: $--form-item-medium-line-height;\n  }\n\n  &-label-content {\n    min-height: $--form-item-medium-line-height;\n  }\n\n  &-content-component {\n    line-height: $--form-item-medium-line-height;\n  }\n\n  .#{$namespace}-input,\n  .#{$namespace}-input-number,\n  .#{$namespace}-input-number.is-controls-right,\n  .#{$namespace}-select,\n  .#{$namespace}-cascader,\n  .#{$namespace}-date-editor--daterange,\n  .#{$namespace}-date-editor--timerange,\n  .#{$namespace}-date-editor--datetimerange,\n  .#{$namespace}-date-editor.#{$namespace}-input,\n  .#{$namespace}-date-editor.#{$namespace}-input__inner,\n  .#{$namespace}-tree-select {\n    width: 100%;\n  }\n\n  .#{$namespace}-input-group {\n    vertical-align: top;\n  }\n}\n\n.#{$form-item-prefix}-label {\n  position: relative;\n  display: flex;\n\n  &-content {\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n\n  &-tooltip {\n    cursor: help;\n\n    * {\n      cursor: help;\n    }\n\n    label {\n      border-bottom: 1px dashed currentColor;\n    }\n  }\n}\n\n.#{$form-item-prefix}-label label {\n  color: $--color-text-regular;\n}\n\n.#{$form-item-prefix}-label-align-left {\n  > .#{$form-item-prefix}-label {\n    justify-content: flex-start;\n  }\n}\n\n.#{$form-item-prefix}-label-align-right {\n  > .#{$form-item-prefix}-label {\n    justify-content: flex-end;\n  }\n}\n\n.#{$form-item-prefix}-label-wrap {\n  .#{$form-item-prefix}-label {\n    label {\n      white-space: pre-line;\n    }\n  }\n}\n\n.#{$form-item-prefix}-feedback-layout-terse {\n  margin-bottom: 8px;\n\n  &.#{$form-item-prefix}-feedback-has-text:not(.#{$form-item-prefix}-inset) {\n    margin-bottom: 0;\n  }\n}\n\n.#{$form-item-prefix}-feedback-layout-loose {\n  margin-bottom: $--form-error-line-height;\n\n  &.#{$form-item-prefix}-feedback-has-text:not(.#{$form-item-prefix}-inset) {\n    margin-bottom: 0;\n  }\n}\n\n.#{$form-item-prefix}-feedback-layout-none {\n  margin-bottom: 0;\n\n  &.#{$form-item-prefix}-feedback-has-text:not(.#{$form-item-prefix}-inset) {\n    margin-bottom: 0;\n  }\n}\n\n.#{$form-item-prefix}-control {\n  width: 100%;\n  flex: 1;\n\n  .#{$form-item-prefix}-control-content {\n    display: flex;\n\n    .#{$form-item-prefix}-control-content-component {\n      width: 100%;\n      min-height: $--form-item-medium-line-height;\n      line-height: $--form-item-medium-line-height;\n\n      &-has-feedback-icon {\n        flex: 1;\n        position: relative;\n        display: flex;\n        align-items: center;\n      }\n    }\n\n    .#{$form-item-prefix}-addon-before {\n      margin-right: 8px;\n      display: inline-flex;\n      align-items: center;\n      min-height: $--form-item-medium-line-height;\n      flex-shrink: 0;\n    }\n\n    .#{$form-item-prefix}-addon-after {\n      margin-left: 8px;\n      display: inline-flex;\n      align-items: center;\n      min-height: $--form-item-medium-line-height;\n      flex-shrink: 0;\n    }\n  }\n}\n\n.#{$form-item-prefix}-size-small {\n  font-size: $--font-size-extra-small;\n\n  .#{$form-item-prefix}-label * {\n    line-height: $--form-item-small-line-height;\n  }\n\n  .#{$form-item-prefix}-label-content {\n    min-height: $--form-item-small-line-height;\n  }\n\n  .#{$form-item-prefix}-control-content {\n    .#{$form-item-prefix}-control-content-component {\n      line-height: $--form-item-small-line-height;\n      min-height: $--form-item-small-line-height;\n    }\n  }\n\n  .#{$form-item-prefix}-help,\n  .#{$form-item-prefix}-extra {\n    min-height: $--form-error-line-height;\n  }\n\n  .#{$form-item-prefix}-control-content {\n    min-height: $--form-item-small-line-height;\n  }\n\n  .#{$form-item-prefix}-label > label {\n    height: $--form-item-small-line-height;\n  }\n\n  .#{$namespace}-input {\n    input {\n      height: $--form-item-small-line-height;\n      line-height: $--form-item-small-line-height;\n    }\n  }\n\n  .#{$namespace}-input-number {\n    line-height: $--form-item-small-line-height;\n    &.is-controls-right {\n      .#{$namespace}-input-number__increase,\n      .#{$namespace}-input-number__decrease {\n        line-height: math.div($--form-item-small-line-height, 2);\n        height: math.div($--form-item-small-line-height, 2);\n        font-size: $--font-size-extra-small;\n        box-sizing: border-box;\n      }\n    }\n  }\n}\n\n.#{$form-item-prefix}-size-large {\n  font-size: $--font-size-medium;\n\n  .#{$form-item-prefix}-label * {\n    line-height: $--form-item-large-line-height;\n  }\n\n  .#{$form-item-prefix}-label-content {\n    min-height: $--form-item-large-line-height;\n  }\n\n  .#{$form-item-prefix}-control-content {\n    .#{$form-item-prefix}-control-content-component {\n      line-height: $--form-item-large-line-height;\n      min-height: $--form-item-large-line-height;\n    }\n  }\n\n  .#{$form-item-prefix}-help,\n  .#{$form-item-prefix}-extra {\n    min-height: $--form-error-line-height;\n  }\n\n  .#{$form-item-prefix}-control-content {\n    min-height: $--form-item-large-line-height;\n  }\n\n  .#{$namespace}-input {\n    input {\n      height: $--form-item-large-line-height;\n      line-height: $--form-item-large-line-height;\n    }\n  }\n\n  .#{$namespace}-select {\n    input {\n      height: $--form-item-large-line-height !important;\n      line-height: $--form-item-large-line-height;\n    }\n  }\n\n  .#{$namespace}-select__tags .el-tag {\n    height: $--form-item-large-line-height - 12px;\n    line-height: $--form-item-large-line-height - 12px;\n  }\n\n  .#{$namespace}-input-number {\n    line-height: $--form-item-large-line-height;\n    &.is-controls-right {\n      .#{$namespace}-input-number__increase,\n      .#{$namespace}-input-number__decrease {\n        line-height: math.div($--form-item-large-line-height, 2) - 1;\n        font-size: $--font-size-medium;\n      }\n    }\n  }\n}\n\n.#{$form-item-prefix} {\n  &-layout-vertical {\n    display: block;\n\n    .#{$form-item-prefix}-label * {\n      line-height: $--form-item-label-top-line-height;\n    }\n\n    .#{$form-item-prefix}-label-content {\n      min-height: $--form-item-label-top-line-height;\n    }\n  }\n}\n\n.#{$form-item-prefix}-feedback-layout-popover {\n  margin-bottom: 8px;\n}\n\n.#{$form-item-prefix}-label-tooltip {\n  margin-left: 4px;\n  color: $--color-text-secondary;\n  display: flex;\n  align-items: center;\n  height: $--form-item-medium-line-height;\n  cursor: pointer;\n  i {\n    line-height: 1;\n  }\n}\n\n.#{$form-item-prefix}-control-align-left {\n  .#{$form-item-prefix}-control-content {\n    justify-content: flex-start;\n  }\n}\n\n.#{$form-item-prefix}-control-align-right {\n  .#{$form-item-prefix}-control-content {\n    justify-content: flex-end;\n  }\n}\n\n.#{$form-item-prefix}-control-wrap {\n  .#{$form-item-prefix}-control {\n    white-space: pre-line;\n  }\n}\n\n.#{$form-item-prefix}-asterisk {\n  color: $--color-danger;\n  margin-right: 4px;\n  display: inline-block;\n  font-family: SimSun, sans-serif;\n}\n\n.#{$form-item-prefix}-colon {\n  margin-left: 2px;\n  margin-right: 8px;\n}\n\n.#{$form-item-prefix}-help,\n.#{$form-item-prefix}-extra {\n  clear: both;\n  min-height: $--form-error-line-height;\n  line-height: $--form-error-line-height;\n  color: $--color-text-secondary;\n  transition: $--color-transition-base;\n  padding-top: 0;\n}\n\n.#{$form-item-prefix}-fullness {\n  > .#{$form-item-prefix}-control {\n    > .#{$form-item-prefix}-control-content {\n      > .#{$form-item-prefix}-control-content-component {\n        > *:first-child {\n          width: 100%;\n        }\n      }\n    }\n  }\n}\n\n.#{$form-item-prefix}-control-content-component-has-feedback-icon {\n  border-radius: $--border-radius-base;\n  border: $--border-base;\n  padding-right: 8px;\n  transition: $--all-transition;\n  touch-action: manipulation;\n  outline: none;\n\n  .#{$namespace}-input-number,\n  .#{$namespace}-date-editor .#{$namespace}-input__inner,\n  .#{$namespace}-select .#{$namespace}-input__inner,\n  .#{$namespace}-input .#{$namespace}-input__inner {\n    border: none !important;\n    box-shadow: none !important;\n  }\n  .#{$namespace}-input-number.is-controls-right .#{$namespace}-input__inner {\n    padding-right: 40px;\n  }\n  .#{$namespace}-input-number.is-controls-right\n    .#{$namespace}-input-number__increase {\n    top: 0;\n    right: 8px;\n    border-right: $--border-base;\n  }\n  .#{$namespace}-input-number.is-controls-right\n    .#{$namespace}-input-number__decrease {\n    bottom: 0;\n    right: 8px;\n    border-right: $--border-base;\n  }\n}\n\n.#{$form-item-prefix} {\n  &:hover {\n    .#{$form-item-prefix}-control-content-component-has-feedback-icon {\n      @include hover;\n    }\n  }\n}\n\n.#{$form-item-prefix}-active {\n  .#{$form-item-prefix}-control-content-component-has-feedback-icon {\n    @include active;\n  }\n}\n\n.#{$form-item-prefix}-error {\n  & .#{$namespace}-input__inner,\n  & .#{$namespace}-textarea__inner {\n    &,\n    &.hover {\n      border-color: $--color-danger;\n    }\n  }\n\n  & .#{$namespace}-input__inner,\n  & .#{$namespace}-textarea__inner {\n    &:focus {\n      border-color: $--color-danger;\n    }\n  }\n\n  & .#{$namespace}-input-group__append,\n  & .#{$namespace}-input-group__prepend {\n    & .#{$namespace}-input__inner {\n      border-color: transparent;\n    }\n  }\n  .#{$namespace}-input__validateIcon {\n    color: $--color-danger !important;\n  }\n}\n\n.#{$form-item-prefix}-error-help,\n.#{$form-item-prefix}-warning-help,\n.#{$form-item-prefix}-success-help {\n  i {\n    margin-right: 8px;\n  }\n}\n\n.#{$form-item-prefix}-error-help {\n  color: $--color-danger;\n}\n\n.#{$form-item-prefix}-warning-help {\n  color: $--color-warning;\n}\n\n.#{$form-item-prefix}-success-help {\n  color: $--color-success;\n}\n\n.#{$form-item-prefix}-warning {\n  & .#{$namespace}-input__inner,\n  & .#{$namespace}-textarea__inner {\n    &,\n    &.hover {\n      border-color: $--color-warning;\n    }\n  }\n\n  & .#{$namespace}-input__inner,\n  & .#{$namespace}-textarea__inner {\n    &:focus {\n      border-color: $--color-warning;\n    }\n  }\n\n  & .#{$namespace}-input-group__append,\n  & .#{$namespace}-input-group__prepend {\n    & .#{$namespace}-input__inner {\n      border-color: transparent;\n    }\n  }\n  .#{$namespace}-input__validateIcon {\n    color: $--color-warning !important;\n  }\n}\n\n.#{$form-item-prefix}-success {\n  & .#{$namespace}-input__inner,\n  & .#{$namespace}-textarea__inner {\n    &,\n    &.hover {\n      border-color: $--color-success;\n    }\n  }\n\n  & .#{$namespace}-input__inner,\n  & .#{$namespace}-textarea__inner {\n    &:focus {\n      border-color: $--color-success;\n    }\n  }\n\n  & .#{$namespace}-input-group__append,\n  & .#{$namespace}-input-group__prepend {\n    & .#{$namespace}-input__inner {\n      border-color: transparent;\n    }\n  }\n  .#{$namespace}-input__validateIcon {\n    color: $--color-success !important;\n  }\n}\n\n.#{$form-item-prefix}-bordered-none {\n  .#{$namespace}-input__inner {\n    border: none !important;\n  }\n\n  .#{$namespace}-input-number__decrease,\n  .#{$namespace}-input-number__increase {\n    border: none !important;\n    background: transparent !important;\n  }\n}\n\n.#{$form-item-prefix}-inset {\n  border-radius: $--border-radius-base;\n  border: $--border-base;\n  padding-left: 12px;\n  transition: 0.3s all;\n\n  &:hover {\n    @include hover;\n  }\n}\n\n.#{$form-item-prefix}-inset-active {\n  @include active;\n}\n"
  },
  {
    "path": "packages/element/src/form-item/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/tooltip.scss'\nimport './style.scss'\n"
  },
  {
    "path": "packages/element/src/form-item/var.scss",
    "content": "$form-item-prefix: '#{$formily-prefix}-form-item';\n\n$--form-font-size: $--font-size-base !default;\n\n$--form-label-font-size: $--form-font-size !default;\n\n$--form-item-large-line-height: 40px;\n\n$--form-item-medium-line-height: 32px;\n\n$--form-item-small-line-height: 24px;\n\n$--form-item-label-top-line-height: 40px;\n\n$--form-error-line-height: 22px !default;\n\n$--form-item-margin-bottom: $--form-error-line-height !default;\n"
  },
  {
    "path": "packages/element/src/form-layout/index.ts",
    "content": "import { h } from '@formily/vue'\nimport {\n  defineComponent,\n  inject,\n  InjectionKey,\n  provide,\n  Ref,\n  ref,\n  watch,\n} from 'vue-demi'\nimport { stylePrefix } from '../__builtins__/configs'\nimport { useCompatRef } from '../__builtins__/shared'\nimport { useResponsiveFormLayout } from './useResponsiveFormLayout'\n\nexport type FormLayoutProps = {\n  className?: string\n  colon?: boolean\n  labelAlign?: 'right' | 'left' | ('right' | 'left')[]\n  wrapperAlign?: 'right' | 'left' | ('right' | 'left')[]\n  labelWrap?: boolean\n  labelWidth?: number\n  wrapperWidth?: number\n  wrapperWrap?: boolean\n  labelCol?: number | number[]\n  wrapperCol?: number | number[]\n  fullness?: boolean\n  size?: 'small' | 'default' | 'large'\n  layout?:\n    | 'vertical'\n    | 'horizontal'\n    | 'inline'\n    | ('vertical' | 'horizontal' | 'inline')[]\n  direction?: 'rtl' | 'ltr'\n  shallow?: boolean\n  feedbackLayout?: 'loose' | 'terse' | 'popover'\n  tooltipLayout?: 'icon' | 'text'\n  bordered?: boolean\n  breakpoints?: number[]\n  inset?: boolean\n  spaceGap?: number\n  gridColumnGap?: number\n  gridRowGap?: number\n}\n\nexport const FormLayoutDeepContext: InjectionKey<Ref<FormLayoutProps>> = Symbol(\n  'FormLayoutDeepContext'\n)\n\nexport const FormLayoutShallowContext: InjectionKey<Ref<FormLayoutProps>> =\n  Symbol('FormLayoutShallowContext')\n\nexport const useFormDeepLayout = (): Ref<FormLayoutProps> =>\n  inject(FormLayoutDeepContext, ref({}))\n\nexport const useFormShallowLayout = (): Ref<FormLayoutProps> =>\n  inject(FormLayoutShallowContext, ref({}))\n\nexport const useFormLayout = (): Ref<FormLayoutProps> => {\n  const shallowLayout = useFormShallowLayout()\n  const deepLayout = useFormDeepLayout()\n  const formLayout = ref({\n    ...deepLayout.value,\n    ...shallowLayout.value,\n  })\n\n  watch(\n    [shallowLayout, deepLayout],\n    () => {\n      formLayout.value = {\n        ...deepLayout.value,\n        ...shallowLayout.value,\n      }\n    },\n    {\n      deep: true,\n    }\n  )\n  return formLayout\n}\n\nexport const FormLayout = defineComponent<FormLayoutProps>({\n  name: 'FFormLayout',\n  props: {\n    className: {},\n    colon: { default: true },\n    labelAlign: {},\n    wrapperAlign: {},\n    labelWrap: { default: false },\n    labelWidth: {},\n    wrapperWidth: {},\n    wrapperWrap: { default: false },\n    labelCol: {},\n    wrapperCol: {},\n    fullness: { default: false },\n    size: { default: 'default' },\n    layout: { default: 'horizontal' },\n    direction: { default: 'ltr' },\n    shallow: { default: true },\n    feedbackLayout: {},\n    tooltipLayout: {},\n    bordered: { default: true },\n    inset: { default: false },\n    breakpoints: {},\n    spaceGap: {},\n    gridColumnGap: {},\n    gridRowGap: {},\n  },\n  setup(customProps, { slots, refs }) {\n    const { elRef: root, elRefBinder } = useCompatRef(refs)\n    const { props } = useResponsiveFormLayout(customProps, root)\n\n    const deepLayout = useFormDeepLayout()\n    const newDeepLayout = ref({\n      ...deepLayout,\n    })\n    const shallowProps = ref({})\n\n    watch(\n      [props, deepLayout],\n      () => {\n        shallowProps.value = props.value.shallow ? props.value : undefined\n        if (!props.value.shallow) {\n          Object.assign(newDeepLayout.value, props.value)\n        } else {\n          if (props.value.size) {\n            newDeepLayout.value.size = props.value.size\n          }\n          if (props.value.colon) {\n            newDeepLayout.value.colon = props.value.colon\n          }\n        }\n      },\n      { deep: true, immediate: true }\n    )\n\n    provide(FormLayoutDeepContext, newDeepLayout)\n    provide(FormLayoutShallowContext, shallowProps)\n\n    const formPrefixCls = `${stylePrefix}-form`\n    return () => {\n      const classNames = {\n        [`${formPrefixCls}-${props.value.layout}`]: true,\n        [`${formPrefixCls}-rtl`]: props.value.direction === 'rtl',\n        [`${formPrefixCls}-${props.value.size}`]:\n          props.value.size !== undefined,\n        [`${props.value.className}`]: props.value.className !== undefined,\n      }\n      return h(\n        'div',\n        {\n          ref: elRefBinder,\n          class: classNames,\n        },\n        slots\n      )\n    }\n  },\n})\n\nexport default FormLayout\n"
  },
  {
    "path": "packages/element/src/form-layout/style.scss",
    "content": "@import '../__builtins__/styles/common.scss';\n\n.#{$formily-prefix}-form-inline {\n  display: flex;\n  flex-wrap: wrap;\n}\n"
  },
  {
    "path": "packages/element/src/form-layout/style.ts",
    "content": "import './style.scss'\n"
  },
  {
    "path": "packages/element/src/form-layout/useResponsiveFormLayout.ts",
    "content": "import { isArr, isValid } from '@formily/shared'\nimport { onMounted, Ref, ref } from 'vue-demi'\n\ninterface IProps {\n  breakpoints?: number[]\n  layout?:\n    | 'vertical'\n    | 'horizontal'\n    | 'inline'\n    | ('vertical' | 'horizontal' | 'inline')[]\n  labelCol?: number | number[]\n  wrapperCol?: number | number[]\n  labelAlign?: 'right' | 'left' | ('right' | 'left')[]\n  wrapperAlign?: 'right' | 'left' | ('right' | 'left')[]\n  [props: string]: any\n}\n\ninterface ICalcBreakpointIndex {\n  (originalBreakpoints: number[], width: number): number\n}\n\ninterface ICalculateProps {\n  (target: Element, props: IProps): IProps\n}\n\ninterface IUseResponsiveFormLayout {\n  (props: IProps, root: Ref<Element>): {\n    props: Ref<IProps>\n  }\n}\n\nconst calcBreakpointIndex: ICalcBreakpointIndex = (breakpoints, width) => {\n  for (let i = 0; i < breakpoints.length; i++) {\n    if (width <= breakpoints[i]) {\n      return i\n    }\n  }\n}\n\nconst calcFactor = <T>(value: T | T[], breakpointIndex: number): T => {\n  if (Array.isArray(value)) {\n    if (breakpointIndex === -1) return value[0]\n    return value[breakpointIndex] ?? value[value.length - 1]\n  } else {\n    return value\n  }\n}\n\nconst factor = <T>(value: T | T[], breakpointIndex: number): T =>\n  isValid(value) ? calcFactor(value as any, breakpointIndex) : value\n\nconst calculateProps: ICalculateProps = (target, props) => {\n  const { clientWidth } = target\n  const {\n    breakpoints,\n    layout,\n    labelAlign,\n    wrapperAlign,\n    labelCol,\n    wrapperCol,\n    ...otherProps\n  } = props\n  const breakpointIndex = calcBreakpointIndex(breakpoints, clientWidth)\n\n  return {\n    layout: factor(layout, breakpointIndex),\n    labelAlign: factor(labelAlign, breakpointIndex),\n    wrapperAlign: factor(wrapperAlign, breakpointIndex),\n    labelCol: factor(labelCol, breakpointIndex),\n    wrapperCol: factor(wrapperCol, breakpointIndex),\n    ...otherProps,\n  }\n}\n\nexport const useResponsiveFormLayout: IUseResponsiveFormLayout = (\n  props,\n  root\n) => {\n  const { breakpoints } = props\n  if (!isArr(breakpoints)) {\n    return { props: ref(props) }\n  }\n  const layoutProps = ref<IProps>(props)\n\n  const updateUI = () => {\n    if (root.value) {\n      layoutProps.value = calculateProps(root.value, props)\n    }\n  }\n\n  onMounted(() => {\n    const observer = () => {\n      updateUI()\n    }\n    const resizeObserver = new ResizeObserver(observer)\n    if (root.value) {\n      resizeObserver.observe(root.value)\n    }\n\n    updateUI()\n\n    return () => {\n      resizeObserver.disconnect()\n    }\n  })\n\n  return {\n    props: layoutProps,\n  }\n}\n"
  },
  {
    "path": "packages/element/src/form-step/index.ts",
    "content": "import { Form, VoidField } from '@formily/core'\nimport { Schema, SchemaKey } from '@formily/json-schema'\nimport { action, model, observable } from '@formily/reactive'\nimport { observer } from '@formily/reactive-vue'\nimport {\n  Fragment,\n  h,\n  RecursionField,\n  useField,\n  useFieldSchema,\n} from '@formily/vue'\nimport { Step, Steps } from 'element-ui'\nimport { defineComponent, PropType } from 'vue-demi'\nimport { stylePrefix } from '../__builtins__/configs'\n\nimport type { Step as StepProps, Steps as StepsProps } from 'element-ui'\nimport { composeExport } from '../__builtins__/shared'\n\nexport interface IFormStep {\n  connect: (steps: SchemaStep[], field: VoidField) => void\n  current: number\n  allowNext: boolean\n  allowBack: boolean\n  setCurrent(key: number): void\n  submit: Form['submit']\n  next(): void\n  back(): void\n}\n\nexport interface IFormStepProps extends StepsProps {\n  formStep?: IFormStep\n}\n\ntype SchemaStep = {\n  name: SchemaKey\n  props: any\n  schema: Schema\n}\n\ntype FormStepEnv = {\n  form: Form\n  field: VoidField\n  steps: SchemaStep[]\n}\n\nconst parseSteps = (schema: Schema) => {\n  const steps: SchemaStep[] = []\n  schema.mapProperties((schema, name) => {\n    if (schema['x-component']?.indexOf('StepPane') > -1) {\n      steps.push({\n        name,\n        props: schema['x-component-props'],\n        schema,\n      })\n    }\n  })\n  return steps\n}\n\nconst createFormStep = (defaultCurrent = 0): IFormStep => {\n  const env: FormStepEnv = observable({\n    form: null,\n    field: null,\n    steps: [],\n  })\n\n  const setDisplay = action.bound((target: number) => {\n    const currentStep = env.steps[target]\n    env.steps.forEach(({ name }) => {\n      env.form.query(`${env.field.address}.${name}`).take((field) => {\n        if (name === currentStep.name) {\n          field.setDisplay('visible')\n        } else {\n          field.setDisplay('hidden')\n        }\n      })\n    })\n  })\n\n  const next = action.bound(() => {\n    if (formStep.allowNext) {\n      setDisplay(formStep.current + 1)\n      formStep.setCurrent(formStep.current + 1)\n    }\n  })\n\n  const back = action.bound(() => {\n    if (formStep.allowBack) {\n      setDisplay(formStep.current - 1)\n      formStep.setCurrent(formStep.current - 1)\n    }\n  })\n\n  const formStep: IFormStep = model({\n    connect(steps, field) {\n      env.steps = steps\n      env.form = field?.form\n      env.field = field\n    },\n    current: defaultCurrent,\n    setCurrent(key: number) {\n      formStep.current = key\n    },\n    get allowNext() {\n      return formStep.current < env.steps.length - 1\n    },\n    get allowBack() {\n      return formStep.current > 0\n    },\n    async next() {\n      try {\n        await env.form.validate()\n        next()\n      } catch {}\n    },\n    async back() {\n      back()\n    },\n    async submit(onSubmit) {\n      return env.form?.submit?.(onSubmit)\n    },\n  })\n  return formStep\n}\n\nconst FormStepInner = observer(\n  defineComponent<IFormStepProps>({\n    name: 'FFormStep',\n    props: {\n      formStep: {\n        type: Object as PropType<IFormStep>,\n        default() {\n          return {\n            current: 0,\n          }\n        },\n      },\n    },\n    setup(props, { attrs }) {\n      const field = useField<VoidField>().value\n      const prefixCls = `${stylePrefix}-form-step`\n      const fieldSchemaRef = useFieldSchema()\n\n      const steps = parseSteps(fieldSchemaRef.value)\n\n      props.formStep.connect?.(steps, field)\n\n      return () => {\n        const current = props.active || props.formStep?.current || 0\n\n        const renderSteps = (steps: SchemaStep[], callback) => {\n          return steps.map(callback)\n        }\n\n        return h(\n          'div',\n          {\n            class: [prefixCls],\n          },\n          {\n            default: () => [\n              h(\n                Steps,\n                {\n                  props: {\n                    active: current,\n                  },\n                  style: [{ marginBottom: '10px' }, attrs.style],\n                  attrs,\n                },\n                {\n                  default: () =>\n                    renderSteps(steps, ({ props }, key) => {\n                      return h(Step, { props, key }, {})\n                    }),\n                }\n              ),\n\n              renderSteps(steps, ({ name, schema }, key) => {\n                if (key !== current) return\n                return h(RecursionField, { props: { name, schema }, key }, {})\n              }),\n            ],\n          }\n        )\n      }\n    },\n  })\n)\n\nconst StepPane = defineComponent<StepProps>({\n  name: 'FFormStepPane',\n  setup(_props, { slots }) {\n    return () => h(Fragment, {}, slots)\n  },\n})\n\nexport const FormStep = composeExport(FormStepInner, {\n  StepPane,\n  createFormStep,\n})\n\nexport default FormStep\n"
  },
  {
    "path": "packages/element/src/form-step/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/steps.scss'\nimport 'element-ui/packages/theme-chalk/src/step.scss'\n"
  },
  {
    "path": "packages/element/src/form-tab/index.ts",
    "content": "import { Schema, SchemaKey } from '@formily/json-schema'\nimport { model } from '@formily/reactive'\nimport { observer } from '@formily/reactive-vue'\nimport {\n  Fragment,\n  h,\n  RecursionField,\n  useField,\n  useFieldSchema,\n} from '@formily/vue'\nimport { Badge, TabPane, Tabs } from 'element-ui'\nimport { computed, defineComponent, reactive } from 'vue-demi'\nimport { stylePrefix } from '../__builtins__/configs'\n\nimport type { TabPane as TabPaneProps, Tabs as TabsProps } from 'element-ui'\nimport { composeExport } from '../__builtins__/shared'\n\nexport interface IFormTab {\n  activeKey: string\n  setActiveKey(key: string): void\n}\n\nexport interface IFormTabProps extends TabsProps {\n  formTab?: IFormTab\n}\n\nexport interface IFormTabPaneProps extends TabPaneProps {\n  key: string | number\n}\n\nconst useTabs = () => {\n  const tabsField = useField().value\n  const schema = useFieldSchema().value\n  const tabs: { name: SchemaKey; props: any; schema: Schema }[] = reactive([])\n  schema.mapProperties((schema, name) => {\n    const field = tabsField.query(tabsField.address.concat(name)).take()\n    if (field?.display === 'none' || field?.display === 'hidden') return\n    if (schema['x-component']?.indexOf('TabPane') > -1) {\n      tabs.push({\n        name,\n        props: {\n          name: schema?.['x-component-props']?.name || name,\n          ...schema?.['x-component-props'],\n        },\n        schema,\n      })\n    }\n  })\n  return tabs\n}\n\nconst createFormTab = (defaultActiveKey?: string) => {\n  const formTab = model({\n    activeKey: defaultActiveKey,\n    setActiveKey(key: string) {\n      formTab.activeKey = key\n    },\n  })\n  return formTab\n}\n\nconst FormTabInner = observer(\n  defineComponent<IFormTabProps>({\n    name: 'FFormTab',\n    props: ['formTab'],\n    setup(props, { attrs, listeners }) {\n      const field = useField().value\n      const formTabRef = computed(() => props.formTab ?? createFormTab())\n\n      const prefixCls = `${stylePrefix}-form-tab`\n\n      return () => {\n        const formTab = formTabRef.value\n        const tabs = useTabs()\n        const activeKey = props.value || formTab?.activeKey || tabs?.[0]?.name\n        const badgedTab = (key: SchemaKey, props: any) => {\n          const errors = field.form.queryFeedbacks({\n            type: 'error',\n            address: `${field.address.concat(key)}.*`,\n          })\n          if (errors.length) {\n            return () =>\n              h(\n                Badge,\n                {\n                  class: [`${prefixCls}-errors-badge`],\n                  props: {\n                    value: errors.length,\n                  },\n                },\n                { default: () => props.label }\n              )\n          }\n          return () => props.label\n        }\n\n        const getTabs = (tabs) => {\n          return tabs.map(({ props, schema, name }, key) => {\n            return h(\n              TabPane,\n              {\n                key,\n                props,\n              },\n              {\n                default: () => [\n                  h(\n                    RecursionField,\n                    {\n                      props: {\n                        schema,\n                        name,\n                      },\n                    },\n                    {}\n                  ),\n                ],\n                label: () => [\n                  h('div', {}, { default: badgedTab(name, props) }),\n                ],\n              }\n            )\n          })\n        }\n\n        return h(\n          Tabs,\n          {\n            class: [prefixCls],\n            style: attrs.style,\n            props: {\n              ...attrs,\n              value: activeKey,\n            },\n            on: {\n              ...listeners,\n              input: (key) => {\n                listeners.input?.(key)\n                formTab.setActiveKey?.(key)\n              },\n            },\n          },\n          {\n            default: () => getTabs(tabs),\n          }\n        )\n      }\n    },\n  })\n)\n\nconst FormTabPane = defineComponent<IFormTabPaneProps>({\n  name: 'FFormTabPane',\n  setup(_props, { slots }) {\n    return () => h(Fragment, {}, slots)\n  },\n})\n\nexport const FormTab = composeExport(FormTabInner, {\n  TabPane: FormTabPane,\n  createFormTab,\n})\n\nexport default FormTab\n"
  },
  {
    "path": "packages/element/src/form-tab/style.scss",
    "content": "@import '../__builtins__/styles/common.scss';\n\n.#{$formily-prefix}-form-tab-errors-badge {\n  line-height: 1;\n  vertical-align: initial;\n}\n"
  },
  {
    "path": "packages/element/src/form-tab/style.ts",
    "content": "import './style.scss'\nimport 'element-ui/packages/theme-chalk/src/tabs.scss'\nimport 'element-ui/packages/theme-chalk/src/tab-pane.scss'\nimport 'element-ui/packages/theme-chalk/src/badge.scss'\n"
  },
  {
    "path": "packages/element/src/index.ts",
    "content": "import './style'\n\nexport * from './array-base'\nexport * from './array-table'\nexport * from './cascader'\nexport * from './checkbox'\nexport * from './date-picker'\nexport * from './el-form'\nexport * from './el-form-item'\nexport * from './form'\nexport * from './form-button-group'\nexport * from './form-grid'\nexport * from './form-item'\nexport * from './form-layout'\nexport * from './input'\nexport * from './input-number'\nexport * from './password'\nexport * from './radio'\nexport * from './reset'\nexport * from './select'\nexport * from './space'\nexport * from './submit'\nexport * from './switch'\nexport * from './time-picker'\nexport * from './transfer'\nexport * from './upload'\nexport * from './preview-text'\nexport * from './form-collapse'\nexport * from './form-tab'\nexport * from './form-step'\nexport * from './array-cards'\nexport * from './array-collapse'\nexport * from './array-items'\nexport * from './array-tabs'\nexport * from './editable'\nexport * from './form-dialog'\nexport * from './form-drawer'\n"
  },
  {
    "path": "packages/element/src/input/index.ts",
    "content": "import { composeExport, transformComponent } from '../__builtins__/shared'\nimport { connect, mapProps, mapReadPretty } from '@formily/vue'\nimport { PreviewText } from '../preview-text'\nimport type { Input as ElInputProps } from 'element-ui'\nimport { Input as ElInput } from 'element-ui'\n\nexport type InputProps = ElInputProps\n\nconst TransformElInput = transformComponent<InputProps>(ElInput, {\n  change: 'input',\n})\n\nconst InnerInput = connect(\n  TransformElInput,\n  mapProps({ readOnly: 'readonly' }),\n  mapReadPretty(PreviewText.Input)\n)\n\nconst TextArea = connect(\n  InnerInput,\n  mapProps((props) => {\n    return {\n      ...props,\n      type: 'textarea',\n    }\n  }),\n  mapReadPretty(PreviewText.Input)\n)\n\nexport const Input = composeExport(InnerInput, {\n  TextArea,\n})\n\nexport default Input\n"
  },
  {
    "path": "packages/element/src/input/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/input.scss'\n\n// 依赖\nimport '../preview-text/style'\n"
  },
  {
    "path": "packages/element/src/input-number/index.ts",
    "content": "import { transformComponent } from '../__builtins__/shared'\nimport { connect, mapProps, mapReadPretty } from '@formily/vue'\n\nimport type { InputNumber as _ElInputNumberProps } from 'element-ui'\nimport { InputNumber as ElInputNumber } from 'element-ui'\nimport { PreviewText } from '../preview-text'\n\nexport type InputNumberProps = _ElInputNumberProps\n\nconst TransformElInputNumber = transformComponent<InputNumberProps>(\n  ElInputNumber,\n  {\n    change: 'input',\n  }\n)\n\nexport const InputNumber = connect(\n  TransformElInputNumber,\n  mapProps({ readOnly: 'readonly' }, (props) => {\n    let controlsPosition = 'right'\n    if (props.controlsPosition) {\n      controlsPosition = props.controlsPosition\n    }\n    return {\n      controlsPosition,\n    }\n  }),\n  mapReadPretty(PreviewText.Input)\n)\n\nexport default InputNumber\n"
  },
  {
    "path": "packages/element/src/input-number/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/input-number.scss'\n\n// 依赖\nimport '../preview-text/style'\n"
  },
  {
    "path": "packages/element/src/password/index.ts",
    "content": "import { Input } from '../input'\nimport { connect, mapProps, mapReadPretty } from '@formily/vue'\nimport { PreviewText } from '../preview-text'\nimport type { Input as ElInputProps } from 'element-ui'\n\nexport type PasswordProps = ElInputProps\n\nexport const Password = connect(\n  Input,\n  mapProps((props) => {\n    return {\n      ...props,\n      showPassword: true,\n    }\n  }),\n  mapReadPretty(PreviewText.Input)\n)\n\nexport default Password\n"
  },
  {
    "path": "packages/element/src/password/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/input.scss'\n\n// 依赖\nimport '../preview-text/style'\n"
  },
  {
    "path": "packages/element/src/preview-text/index.ts",
    "content": "import { Field } from '@formily/core'\nimport { observer } from '@formily/reactive-vue'\nimport { isArr, isValid } from '@formily/shared'\nimport { h, useField } from '@formily/vue'\nimport { Tag } from 'element-ui'\nimport { formatDate } from 'element-ui/src/utils/date-util'\nimport { computed, defineComponent, Ref, toRef } from 'vue-demi'\nimport type { CascaderProps } from '../cascader'\nimport type { DatePickerProps } from '../date-picker'\nimport { InputProps } from '../input'\nimport type { SelectProps } from '../select'\nimport { Space } from '../space'\nimport type { TimePickerProps } from '../time-picker'\nimport { stylePrefix } from '../__builtins__/configs'\nimport {\n  composeExport,\n  createContext,\n  resolveComponent,\n  useContext,\n} from '../__builtins__/shared'\n\nconst prefixCls = `${stylePrefix}-preview-text`\nconst PlaceholderContext = createContext('N/A')\n\nexport const usePlaceholder = (value?: Ref<any>) => {\n  const placeholderCtx = useContext(PlaceholderContext)\n  const placeholder = computed(() => {\n    return isValid(value?.value) && value.value !== ''\n      ? value.value\n      : resolveComponent(placeholderCtx.value) || 'N/A'\n  })\n  return placeholder\n}\n\nconst Input = defineComponent<InputProps>({\n  name: 'FPreviewTextInput',\n  props: ['value'],\n  setup(props, { attrs, slots }) {\n    const value = toRef(props, 'value')\n    const placeholder = usePlaceholder(value)\n    return () => {\n      return h(\n        Space,\n        {\n          class: [prefixCls],\n          style: attrs.style,\n        },\n        {\n          default: () => [\n            slots?.prepend?.(),\n            slots?.prefix?.(),\n            placeholder.value,\n            slots?.suffix?.(),\n            slots?.append?.(),\n          ],\n        }\n      )\n    }\n  },\n})\n\nconst Select = observer(\n  defineComponent<SelectProps>({\n    name: 'FPreviewTextSelect',\n    props: [],\n    setup(_props, { attrs }) {\n      const fieldRef = useField<Field>()\n      const field = fieldRef.value\n      const props = attrs as unknown as SelectProps\n      const dataSource: any[] = field?.dataSource?.length\n        ? field.dataSource\n        : props?.options?.length\n        ? props.options\n        : []\n      const placeholder = usePlaceholder()\n      const getSelected = () => {\n        const value = props.value\n        if (props.multiple) {\n          return isArr(value)\n            ? value.map((val) => ({ label: val, value: val }))\n            : []\n        } else {\n          return isValid(value) ? [{ label: value, value }] : []\n        }\n      }\n\n      const getLabels = () => {\n        const selected = getSelected()\n        if (!selected.length) {\n          return h(\n            Tag,\n            {},\n            {\n              default: () => placeholder.value,\n            }\n          )\n        }\n        return selected.map(({ value, label }, key) => {\n          const text =\n            dataSource?.find((item) => item.value == value)?.label || label\n          return h(\n            Tag,\n            {\n              key,\n              props: {\n                type: 'info',\n                effect: 'light',\n              },\n            },\n            {\n              default: () => text || placeholder.value,\n            }\n          )\n        })\n      }\n\n      return () => {\n        return h(\n          Space,\n          {\n            class: [prefixCls],\n            style: attrs.style,\n          },\n          {\n            default: () => getLabels(),\n          }\n        )\n      }\n    },\n  })\n)\n\nconst Cascader = observer(\n  defineComponent<CascaderProps>({\n    name: 'FPreviewTextCascader',\n    props: [],\n    setup(_props, { attrs }) {\n      const fieldRef = useField<Field>()\n      const field = fieldRef.value\n      const props = attrs as unknown as CascaderProps\n      const dataSource: any[] = field?.dataSource?.length\n        ? field.dataSource\n        : props?.options?.length\n        ? props.options\n        : []\n      const placeholder = usePlaceholder()\n      const valueKey = props.props?.value || 'value'\n      const labelKey = props.props?.label || 'label'\n      const getSelected = () => {\n        return isArr(props.value) ? props.value : []\n      }\n\n      const findLabel = (value: any, dataSource: any[]) => {\n        for (let i = 0; i < dataSource?.length; i++) {\n          const item = dataSource[i]\n          if (item?.[valueKey] === value) {\n            return item?.[labelKey]\n          } else {\n            const childLabel = findLabel(value, item?.children)\n            if (childLabel) return childLabel\n          }\n        }\n      }\n\n      const getLabels = () => {\n        const selected = getSelected()\n        if (!selected?.length) {\n          return h(\n            Tag,\n            {},\n            {\n              default: () => placeholder.value,\n            }\n          )\n        }\n        return selected.map((value, key) => {\n          const text = findLabel(value, dataSource)\n          return h(\n            Tag,\n            {\n              key,\n              props: {\n                type: 'info',\n                effect: 'light',\n              },\n            },\n            {\n              default: () => text || placeholder.value,\n            }\n          )\n        })\n      }\n\n      return () => {\n        return h(\n          Space,\n          {\n            class: [prefixCls],\n            style: attrs.style,\n          },\n          {\n            default: () => getLabels(),\n          }\n        )\n      }\n    },\n  })\n)\n\nconst DatePicker = defineComponent<DatePickerProps>({\n  name: 'FPreviewTextDatePicker',\n  props: [],\n  setup(_props, { attrs }) {\n    const props = attrs as unknown as DatePickerProps\n    const placeholder = usePlaceholder()\n    const getLabels = () => {\n      if (isArr(props.value)) {\n        const labels = (props.value as any[]).map(\n          (value: String | Date) =>\n            formatDate(value, props.format) || placeholder.value\n        )\n\n        return labels.join('~')\n      } else {\n        return formatDate(props.value, props.format) || placeholder.value\n      }\n    }\n\n    return () => {\n      return h(\n        'div',\n        {\n          class: [prefixCls],\n          style: attrs.style,\n        },\n        {\n          default: () => getLabels(),\n        }\n      )\n    }\n  },\n})\n\nconst TimePicker = defineComponent<TimePickerProps>({\n  name: 'FPreviewTextTimePicker',\n  props: [],\n  setup(_props, { attrs }) {\n    const props = attrs as unknown as TimePickerProps\n    const format = props.pickerOptions?.format || 'HH:mm:ss'\n    const placeholder = usePlaceholder()\n    const getLabels = () => {\n      if (isArr(props.value)) {\n        const labels = props.value.map(\n          (value) => formatDate(value, format) || placeholder.value\n        )\n\n        return labels.join('~')\n      } else {\n        return formatDate(props.value, format) || placeholder.value\n      }\n    }\n\n    return () => {\n      return h(\n        'div',\n        {\n          class: [prefixCls],\n          style: attrs.style,\n        },\n        {\n          default: () => getLabels(),\n        }\n      )\n    }\n  },\n})\n\nconst Text = defineComponent<any>({\n  name: 'FPreviewText',\n  setup(_props, { attrs }) {\n    const placeholder = usePlaceholder()\n\n    return () => {\n      return h(\n        'div',\n        {\n          class: [prefixCls],\n          style: attrs.style,\n        },\n        {\n          default: () => placeholder.value,\n        }\n      )\n    }\n  },\n})\n\nexport const PreviewText = composeExport(Text, {\n  Input,\n  Select,\n  Cascader,\n  DatePicker,\n  TimePicker,\n  Placeholder: PlaceholderContext.Provider,\n  usePlaceholder,\n})\n\nexport default PreviewText\n"
  },
  {
    "path": "packages/element/src/preview-text/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/tag.scss'\n\n// 依赖\nimport '../input/style'\nimport '../select/style'\nimport '../cascader/style'\nimport '../time-picker/style'\nimport '../date-picker/style'\nimport '../space/style'\n"
  },
  {
    "path": "packages/element/src/radio/index.ts",
    "content": "import { connect, h, mapProps, mapReadPretty } from '@formily/vue'\nimport type {\n  Radio as ElRadioProps,\n  RadioGroup as ElRadioGroupProps,\n} from 'element-ui'\nimport {\n  Radio as ElRadio,\n  RadioButton,\n  RadioGroup as ElRadioGroup,\n} from 'element-ui'\nimport { defineComponent, PropType } from 'vue-demi'\nimport { PreviewText } from '../preview-text'\nimport {\n  composeExport,\n  resolveComponent,\n  SlotTypes,\n  transformComponent,\n} from '../__builtins__/shared'\n\nexport type RadioGroupProps = ElRadioGroupProps & {\n  value: any\n  options?: (\n    | (Omit<ElRadioProps, 'value'> & {\n        value: ElRadioProps['label']\n        label: SlotTypes\n      })\n    | string\n  )[]\n  optionType: 'default' | 'button'\n}\n\nexport type RadioProps = ElRadioProps\n\nconst TransformElRadioGroup = transformComponent(ElRadioGroup, {\n  change: 'input',\n  uselessChange:'change'\n})\n\nconst RadioGroupOption = defineComponent<RadioGroupProps>({\n  name: 'FRadioGroup',\n  props: {\n    options: {\n      type: Array as PropType<RadioGroupProps['options']>,\n      default: () => [],\n    },\n    optionType: {\n      type: String as PropType<RadioGroupProps['optionType']>,\n      default: 'default',\n    },\n  },\n  setup(customProps, { attrs, slots, listeners }) {\n    return () => {\n      const options = customProps.options || []\n      const OptionType =\n        customProps.optionType === 'button' ? RadioButton : ElRadio\n      const children =\n        options.length !== 0\n          ? {\n              default: () =>\n                options.map((option) => {\n                  if (typeof option === 'string') {\n                    return h(\n                      OptionType,\n                      { props: { label: option } },\n                      {\n                        default: () => [\n                          resolveComponent(slots?.option ?? option, { option }),\n                        ],\n                      }\n                    )\n                  } else {\n                    return h(\n                      OptionType,\n                      {\n                        props: {\n                          ...option,\n                          value: undefined,\n                          label: option.value,\n                        },\n                      },\n                      {\n                        default: () => [\n                          resolveComponent(slots?.option ?? option.label, {\n                            option,\n                          }),\n                        ],\n                      }\n                    )\n                  }\n                }),\n            }\n          : slots\n      return h(\n        TransformElRadioGroup,\n        {\n          attrs: {\n            ...attrs,\n          },\n          on: listeners,\n        },\n        children\n      )\n    }\n  },\n})\n\nconst RadioGroup = connect(\n  RadioGroupOption,\n  mapProps({ dataSource: 'options' }),\n  mapReadPretty(PreviewText.Select)\n)\nexport const Radio = composeExport(ElRadio, {\n  Group: RadioGroup,\n})\n\nexport default Radio\n"
  },
  {
    "path": "packages/element/src/radio/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/radio.scss'\nimport 'element-ui/packages/theme-chalk/src/radio-group.scss'\nimport 'element-ui/packages/theme-chalk/src/radio-button.scss'\n"
  },
  {
    "path": "packages/element/src/reset/index.ts",
    "content": "import { IFieldResetOptions } from '@formily/core'\nimport { observer } from '@formily/reactive-vue'\nimport { h, useParentForm } from '@formily/vue'\nimport { defineComponent } from 'vue-demi'\n\nimport type { Button as IElButton } from 'element-ui'\nimport { Button as ElButton } from 'element-ui'\n\nexport type ResetProps = IFieldResetOptions & IElButton\n\nexport const Reset = observer(\n  defineComponent<ResetProps>({\n    name: 'FReset',\n    props: {\n      forceClear: {\n        type: Boolean,\n        default: false,\n      },\n      validate: {\n        type: Boolean,\n        default: false,\n      },\n    },\n    setup(props, context) {\n      const formRef = useParentForm()\n      const { listeners, slots } = context\n      return () => {\n        const form = formRef?.value\n        return h(\n          ElButton,\n          {\n            attrs: context.attrs,\n            on: {\n              ...listeners,\n              click: (e: any) => {\n                if (listeners?.click) {\n                  if (listeners.click(e) === false) return\n                }\n                form\n                  ?.reset('*', {\n                    forceClear: props.forceClear,\n                    validate: props.validate,\n                  })\n                  .then(listeners.resetValidateSuccess as (e: any) => void)\n                  .catch(listeners.resetValidateFailed as (e: any) => void)\n              },\n            },\n          },\n          slots\n        )\n      }\n    },\n  })\n)\n\nexport default Reset\n"
  },
  {
    "path": "packages/element/src/reset/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/button.scss'\n"
  },
  {
    "path": "packages/element/src/select/index.ts",
    "content": "import { connect, h, mapProps, mapReadPretty } from '@formily/vue'\nimport { defineComponent } from 'vue-demi'\nimport { PreviewText } from '../preview-text'\n\nimport type {\n  Option as ElOptionProps,\n  Select as ElSelectProps,\n} from 'element-ui'\nimport { Option as ElOption, Select as ElSelect } from 'element-ui'\nimport { resolveComponent } from '../__builtins__'\n\nexport type SelectProps = ElSelectProps & {\n  options?: Array<ElOptionProps>\n}\n\nconst SelectOption = defineComponent<SelectProps>({\n  name: 'FSelect',\n  props: ['options'],\n  setup(customProps, { attrs, slots, listeners }) {\n    return () => {\n      const options = customProps.options || []\n      const children =\n        options.length !== 0\n          ? {\n              default: () =>\n                options.map((option) => {\n                  if (typeof option === 'string') {\n                    return h(\n                      ElOption,\n                      { props: { value: option, label: option } },\n                      {\n                        default: () => [\n                          resolveComponent(slots?.option, { option }),\n                        ],\n                      }\n                    )\n                  } else {\n                    return h(\n                      ElOption,\n                      {\n                        props: {\n                          ...option,\n                        },\n                      },\n                      {\n                        default: () => [\n                          resolveComponent(slots?.option, {\n                            option,\n                          }),\n                        ],\n                      }\n                    )\n                  }\n                }),\n            }\n          : slots\n      return h(\n        ElSelect,\n        {\n          attrs: {\n            ...attrs,\n          },\n          on: listeners,\n        },\n        children\n      )\n    }\n  },\n})\n\nexport const Select = connect(\n  SelectOption,\n  mapProps({ dataSource: 'options', loading: true }),\n  mapReadPretty(PreviewText.Select)\n)\n\nexport default Select\n"
  },
  {
    "path": "packages/element/src/select/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/select.scss'\n\n// 依赖\nimport '../preview-text/style'\n"
  },
  {
    "path": "packages/element/src/space/index.ts",
    "content": "// https://github.com/vueComponent/ant-design-vue/blob/next/components/space/index.tsx\n\nimport { h } from '@formily/vue'\nimport { defineComponent } from 'vue-demi'\nimport { stylePrefix } from '../__builtins__/configs'\n\nimport type { VNode } from 'vue'\nimport { useFormLayout } from '../form-layout'\n\nexport type SpaceProps = {\n  size: 'small' | 'middle' | 'large' | number\n  direction: 'horizontal' | 'vertical'\n  align: 'start' | 'end' | 'center' | 'baseline'\n}\n\nconst spaceSize = {\n  small: 8,\n  middle: 16,\n  large: 24,\n}\n\nexport const Space = defineComponent<SpaceProps>({\n  name: 'FSpace',\n  props: ['size', 'direction', 'align'],\n  setup(props, { attrs, slots }) {\n    const layout = useFormLayout()\n\n    return () => {\n      const {\n        align,\n        size = layout.value?.spaceGap ?? 'small',\n        direction = 'horizontal',\n      } = props\n\n      const prefixCls = `${stylePrefix}-space`\n      const children = slots.default?.()\n      let items: VNode[] = []\n      if (Array.isArray(children)) {\n        if (children.length === 1) {\n          if ((children[0]['tag'] as string)?.endsWith('Fragment')) {\n            // Fragment hack\n            items = (children[0]['componentOptions'] as { children: VNode[] })\n              ?.children\n          } else {\n            items = children\n          }\n        } else {\n          items = children\n        }\n      }\n      const len = items.length\n\n      if (len === 0) {\n        return null\n      }\n\n      const mergedAlign =\n        align === undefined && direction === 'horizontal' ? 'center' : align\n\n      const someSpaceClass = {\n        [prefixCls]: true,\n        [`${prefixCls}-${direction}`]: true,\n        [`${prefixCls}-align-${mergedAlign}`]: mergedAlign,\n      }\n\n      const itemClassName = `${prefixCls}-item`\n      const marginDirection = 'marginRight' // directionConfig === 'rtl' ? 'marginLeft' : 'marginRight';\n\n      const renderItems = items.map((child, i) =>\n        h(\n          'div',\n          {\n            class: itemClassName,\n            key: `${itemClassName}-${i}`,\n          },\n          { default: () => [child] }\n        )\n      )\n\n      return h(\n        'div',\n        {\n          ...attrs,\n          class: { ...(attrs as any).class, ...someSpaceClass },\n          style: {\n            ...(attrs as any).style,\n            gap:\n              typeof size === 'string' ? `${spaceSize[size]}px` : `${size}px`,\n          },\n        },\n        { default: () => renderItems }\n      )\n    }\n  },\n})\n\nexport default Space\n"
  },
  {
    "path": "packages/element/src/space/style.scss",
    "content": "@import '../__builtins__/styles/common.scss';\n\n.#{$formily-prefix}-space {\n  display: inline-flex;\n  &-vertical {\n    flex-direction: column;\n  }\n\n  &-align {\n    &-center {\n      align-items: center;\n    }\n    &-start {\n      align-items: flex-start;\n    }\n    &-end {\n      align-items: flex-end;\n    }\n    &-baseline {\n      align-items: baseline;\n    }\n  }\n\n  &-item {\n    display: contents;\n  }\n}\n"
  },
  {
    "path": "packages/element/src/space/style.ts",
    "content": "import './style.scss'\n"
  },
  {
    "path": "packages/element/src/style.ts",
    "content": "// auto generated code\nimport './array-base/style.scss'\nimport './array-cards/style.scss'\nimport './array-collapse/style.scss'\nimport './array-items/style.scss'\nimport './array-table/style.scss'\nimport './array-tabs/style.scss'\nimport './editable/style.scss'\nimport './form-button-group/style.scss'\nimport './form-collapse/style.scss'\nimport './form-drawer/style.scss'\nimport './form-grid/style.scss'\nimport './form-item/style.scss'\nimport './form-layout/style.scss'\nimport './form-tab/style.scss'\nimport './form/style.scss'\nimport './space/style.scss'\n"
  },
  {
    "path": "packages/element/src/submit/index.ts",
    "content": "import { IFormFeedback } from '@formily/core'\nimport { observer } from '@formily/reactive-vue'\nimport { h, useParentForm } from '@formily/vue'\nimport { defineComponent } from 'vue-demi'\n\nimport type { Button as ElButtonProps } from 'element-ui'\nimport { Button as ElButton } from 'element-ui'\n\nexport interface ISubmitProps extends ElButtonProps {\n  onClick?: (e: MouseEvent) => any\n  onSubmit?: (values: any) => any\n  onSubmitSuccess?: (payload: any) => void\n  onSubmitFailed?: (feedbacks: IFormFeedback[]) => void\n}\n\nexport const Submit = observer(\n  defineComponent<ISubmitProps>({\n    name: 'FSubmit',\n    props: ['onClick', 'onSubmit', 'onSubmitSuccess', 'onSubmitFailed'],\n    setup(props, { attrs, slots, listeners }) {\n      const formRef = useParentForm()\n\n      return () => {\n        const {\n          onClick = listeners?.click,\n          onSubmit = listeners?.submit,\n          onSubmitSuccess = listeners?.submitSuccess,\n          onSubmitFailed = listeners?.submitFailed,\n        } = props\n\n        const form = formRef?.value\n        return h(\n          ElButton,\n          {\n            attrs: {\n              nativeType: listeners?.submit ? 'button' : 'submit',\n              type: 'primary',\n              ...attrs,\n              loading:\n                attrs.loading !== undefined ? attrs.loading : form?.submitting,\n            },\n            on: {\n              ...listeners,\n              click: (e: any) => {\n                if (onClick) {\n                  if (onClick(e) === false) return\n                }\n                if (onSubmit) {\n                  form\n                    ?.submit(onSubmit as (e: any) => void)\n                    .then(onSubmitSuccess as (e: any) => void)\n                    .catch(onSubmitFailed as (e: any) => void)\n                }\n              },\n            },\n          },\n          slots\n        )\n      }\n    },\n  })\n)\n\nexport default Submit\n"
  },
  {
    "path": "packages/element/src/submit/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/button.scss'\n"
  },
  {
    "path": "packages/element/src/switch/index.ts",
    "content": "import { connect, mapProps } from '@formily/vue'\n\nimport type { Switch as ElSwitchProps } from 'element-ui'\nimport { Switch as ElSwitch } from 'element-ui'\n\nexport type SwitchProps = ElSwitchProps\n\nexport const Switch = connect(ElSwitch, mapProps({ readOnly: 'readonly' }))\n\nexport default Switch\n"
  },
  {
    "path": "packages/element/src/switch/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/switch.scss'\n"
  },
  {
    "path": "packages/element/src/time-picker/index.ts",
    "content": "import { transformComponent } from '../__builtins__/shared'\nimport { connect, mapProps, mapReadPretty } from '@formily/vue'\nimport { PreviewText } from '../preview-text'\nimport type { TimePicker as ElTimePickerProps } from 'element-ui'\nimport { TimePicker as ElTimePicker } from 'element-ui'\n\nexport type TimePickerProps = ElTimePickerProps\n\nconst TransformElTimePicker = transformComponent<TimePickerProps>(\n  ElTimePicker,\n  {\n    change: 'input',\n  }\n)\n\nexport const TimePicker = connect(\n  TransformElTimePicker,\n  mapProps({ readOnly: 'readonly' }),\n  mapReadPretty(PreviewText.TimePicker)\n)\n\nexport default TimePicker\n"
  },
  {
    "path": "packages/element/src/time-picker/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/time-picker.scss'\n\n// 依赖\nimport '../preview-text/style'\n"
  },
  {
    "path": "packages/element/src/transfer/index.ts",
    "content": "import { connect, mapProps } from '@formily/vue'\n\nimport type { Transfer as ElTransferProps } from 'element-ui'\nimport { Transfer as ElTransfer } from 'element-ui'\n\nexport type TransferProps = ElTransferProps\n\nexport const Transfer = connect(ElTransfer, mapProps({ dataSource: 'data' }))\n\nexport default Transfer\n"
  },
  {
    "path": "packages/element/src/transfer/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/transfer.scss'\n"
  },
  {
    "path": "packages/element/src/upload/index.ts",
    "content": "import { Field } from '@formily/core'\nimport { connect, Fragment, h, mapProps, useField } from '@formily/vue'\nimport { defineComponent } from 'vue-demi'\n\nimport type {\n  ElUpload as ElUploadProps,\n  ElUploadInternalFileDetail,\n} from 'element-ui/types/upload'\n\nimport { Button as ElButton, Upload as ElUpload } from 'element-ui'\n\nexport type UploadProps = ElUploadProps & {\n  textContent?: String\n  errorAdaptor?: (error?: ErrorEvent) => String\n}\n\nconst UploadWrapper = defineComponent<UploadProps>({\n  name: 'FUpload',\n  props: {\n    textContent: {\n      type: String,\n      default: '',\n    },\n    errorAdaptor: {\n      type: Function,\n      default(error?: ErrorEvent) {\n        return error?.message || ''\n      },\n    },\n  },\n  setup(curProps: UploadProps, { slots, attrs, listeners, emit }) {\n    return () => {\n      const fieldRef = useField<Field>()\n      const setFeedBack = (error?: ErrorEvent) => {\n        const message = curProps.errorAdaptor(error)\n\n        fieldRef.value.setFeedback({\n          type: 'error',\n          code: 'UploadError',\n          messages: message ? [message] : [],\n        })\n      }\n\n      const props = {\n        ...attrs,\n        onChange(\n          file: ElUploadInternalFileDetail,\n          fileList: ElUploadInternalFileDetail[]\n        ) {\n          ;(attrs.onChange as Function)?.(file, fileList)\n          setFeedBack()\n          emit('change', fileList)\n        },\n\n        onRemove(\n          file: ElUploadInternalFileDetail,\n          fileList: ElUploadInternalFileDetail[]\n        ) {\n          ;(attrs.onRemove as Function)?.(file, fileList)\n          setFeedBack()\n          emit('change', fileList)\n        },\n\n        onError(\n          error: ErrorEvent,\n          file: ElUploadInternalFileDetail,\n          fileList: ElUploadInternalFileDetail[]\n        ) {\n          ;(attrs.onError as Function)?.(error, file, fileList)\n\n          setTimeout(() => {\n            setFeedBack(error)\n          }, 0)\n        },\n      }\n      const children = {\n        ...slots,\n      }\n      if (!slots.default) {\n        children.default = () => {\n          const listType = attrs.listType\n          const drag = attrs.drag\n\n          if (drag) {\n            return h(\n              Fragment,\n              {},\n              {\n                default: () => [\n                  h('i', { staticClass: 'el-icon-upload' }, {}),\n                  h(\n                    'div',\n                    { staticClass: 'el-upload__text' },\n                    { default: () => [curProps.textContent] }\n                  ),\n                ],\n              }\n            )\n          }\n\n          if (listType === 'picture-card') {\n            return h(\n              'i',\n              {\n                staticClass: 'el-icon-plus',\n              },\n              {}\n            )\n          }\n\n          return h(\n            ElButton,\n            { props: { icon: 'el-icon-upload2' } },\n            { default: () => [curProps.textContent] }\n          )\n        }\n      }\n      return h(ElUpload, { attrs: props, on: listeners }, children)\n    }\n  },\n})\n\nexport const Upload = connect(\n  UploadWrapper,\n  mapProps({ readOnly: 'readonly', value: 'fileList' })\n)\n\nexport default Upload\n"
  },
  {
    "path": "packages/element/src/upload/style.ts",
    "content": "import 'element-ui/packages/theme-chalk/src/upload.scss'\nimport 'element-ui/packages/theme-chalk/src/button.scss'\n"
  },
  {
    "path": "packages/element/transformer.ts",
    "content": "import createTransformer from 'ts-import-plugin'\n\nconst transformer = createTransformer({\n  libraryName: 'element-ui',\n  libraryDirectory: 'lib',\n  camel2DashComponentName: true,\n  style: false,\n})\n\nexport default function () {\n  return transformer\n}\n"
  },
  {
    "path": "packages/element/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*\", \"devtools/*\"]\n    },\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/element/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"skipLibCheck\": true,\n    \"paths\": {\n      \"@formily/*\": [\"../../packages/*\", \"../../devtools/*\"]\n    },\n    \"plugins\": [{ \"transform\": \"./transformer.ts\", \"after\": true }],\n    \"lib\": [\"ESNext\", \"DOM\"]\n  },\n  \"include\": [\"./src/**/*.ts\", \"./src/**/*.tsx\"],\n  \"exclude\": [\"./esm/*\", \"./lib/*\"]\n}\n"
  },
  {
    "path": "packages/grid/.npmignore",
    "content": "node_modules\n*.log\nbuild\ndocs\ndoc-site\n__tests__\n.eslintrc\njest.config.js\ntsconfig.json\n.umi\nsrc"
  },
  {
    "path": "packages/grid/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-present, Alibaba Group Holding Limited. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/grid/README.md",
    "content": "# @formily/grid\n"
  },
  {
    "path": "packages/grid/package.json",
    "content": "{\n  \"name\": \"@formily/grid\",\n  \"version\": \"2.3.7\",\n  \"license\": \"MIT\",\n  \"main\": \"lib\",\n  \"module\": \"esm\",\n  \"umd:main\": \"dist/formily.grid.umd.production.js\",\n  \"unpkg\": \"dist/formily.grid.umd.production.js\",\n  \"jsdelivr\": \"dist/formily.grid.umd.production.js\",\n  \"jsnext:main\": \"esm\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/alibaba/formily.git\"\n  },\n  \"types\": \"esm/index.d.ts\",\n  \"bugs\": {\n    \"url\": \"https://github.com/alibaba/formily/issues\"\n  },\n  \"homepage\": \"https://github.com/alibaba/formily#readme\",\n  \"engines\": {\n    \"npm\": \">=3.0.0\"\n  },\n  \"scripts\": {\n    \"build\": \"rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm && npm run build:umd\",\n    \"build:cjs\": \"tsc --project tsconfig.build.json\",\n    \"build:esm\": \"tsc --project tsconfig.build.json --module es2015 --outDir esm\",\n    \"build:umd\": \"rollup --config\"\n  },\n  \"peerDependencies\": {\n    \"typescript\": \"4.x || 5.x\"\n  },\n  \"dependencies\": {\n    \"@formily/reactive\": \"2.3.7\",\n    \"@juggle/resize-observer\": \"^3.3.1\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"gitHead\": \"ac79c196ae9324889aca5e0501146f9b37b04283\"\n}\n"
  },
  {
    "path": "packages/grid/rollup.config.js",
    "content": "import baseConfig from '../../scripts/rollup.base.js'\n\nexport default baseConfig('formily.grid', 'Formily.Grid')\n"
  },
  {
    "path": "packages/grid/src/index.ts",
    "content": "import { define, observable, batch, reaction } from '@formily/reactive'\nimport { ChildListMutationObserver } from './observer'\nimport { ResizeObserver } from '@juggle/resize-observer'\nexport interface IGridOptions {\n  maxRows?: number\n  maxColumns?: number | number[]\n  minColumns?: number | number[]\n  maxWidth?: number | number[]\n  minWidth?: number | number[]\n  breakpoints?: number[]\n  columnGap?: number\n  rowGap?: number\n  colWrap?: boolean\n  strictAutoFit?: boolean\n  shouldVisible?: (node: GridNode, grid: Grid<HTMLElement>) => boolean\n  onDigest?: (grid: Grid<HTMLElement>) => void\n  onInitialized?: (grid: Grid<HTMLElement>) => void\n}\n\nconst SpanRegExp = /span\\s*(\\d+)/\n\nconst isValid = (value: any) => value !== undefined && value !== null\n\nconst calcBreakpointIndex = (breakpoints: number[], width: number) => {\n  if (Array.isArray(breakpoints)) {\n    for (let i = 0; i < breakpoints.length; i++) {\n      if (width <= breakpoints[i]) {\n        return i\n      }\n    }\n  }\n  return -1\n}\n\nconst calcFactor = <T>(value: T | T[], breakpointIndex: number): T => {\n  if (Array.isArray(value)) {\n    if (breakpointIndex === -1) return value[0]\n    return value[breakpointIndex] ?? value[value.length - 1]\n  } else {\n    return value\n  }\n}\n\nconst parseGridNode = (elements: HTMLCollection): GridNode[] => {\n  return Array.from(elements).reduce((buf, element: HTMLElement, index) => {\n    const style = getComputedStyle(element)\n    const visible = !(style.display === 'none')\n    const origin = element.getAttribute('data-grid-span')\n    const span = parseSpan(style.gridColumnStart) ?? 1\n    const originSpan = Number(origin ?? span)\n    const node: GridNode = {\n      index,\n      span,\n      visible,\n      originSpan,\n      element,\n    }\n    if (!origin) {\n      element.setAttribute('data-grid-span', String(span))\n    }\n    return buf.concat(node)\n  }, [])\n}\n\nconst calcChildTotalColumns = (nodes: GridNode[], shadow = false) =>\n  nodes.reduce((buf, node) => {\n    if (!shadow) {\n      if (!node.visible) return buf\n    }\n    if (node.originSpan === -1) return buf + (node.span ?? 1)\n    return buf + node.span\n  }, 0)\n\nconst calcChildOriginTotalColumns = (nodes: GridNode[], shadow = false) =>\n  nodes.reduce((buf, node) => {\n    if (!shadow) {\n      if (!node.visible) return buf\n    }\n    if (node.originSpan === -1) return buf + (node.span ?? 1)\n    return buf + node.originSpan\n  }, 0)\n\nconst calcSatisfyColumns = (\n  width: number,\n  maxColumns: number,\n  minColumns: number,\n  maxWidth: number,\n  minWidth: number,\n  gap: number\n) => {\n  const results = []\n  for (let columns = minColumns; columns <= maxColumns; columns++) {\n    const innerWidth = width - (columns - 1) * gap\n    const columnWidth = innerWidth / columns\n    if (columnWidth >= minWidth && columnWidth <= maxWidth) {\n      results.push(columns)\n    } else if (columnWidth < minWidth) {\n      results.push(Math.min(Math.floor(innerWidth / minWidth), maxColumns))\n    } else if (columnWidth > maxWidth) {\n      results.push(Math.min(Math.floor(innerWidth / maxWidth), maxColumns))\n    }\n  }\n  return Math.max(...results)\n}\n\nconst parseSpan = (gridColumnStart: string) => {\n  return Number(String(gridColumnStart).match(SpanRegExp)?.[1] ?? 1)\n}\n\nconst factor = <T>(value: T | T[], grid: Grid<HTMLElement>): T =>\n  isValid(value) ? calcFactor(value as any, grid.breakpoint) : value\n\nconst resolveChildren = (grid: Grid<HTMLElement>) => {\n  let walked = 0,\n    shadowWalked = 0,\n    rowIndex = 0,\n    shadowRowIndex = 0\n  if (!grid.ready) return\n  grid.children = grid.children.map((node) => {\n    const columnIndex = walked % grid.columns\n    const shadowColumnIndex = shadowWalked % grid.columns\n    const remainColumns = grid.columns - columnIndex\n    const originSpan = node.originSpan\n    const targetSpan = originSpan > grid.columns ? grid.columns : originSpan\n    const span = grid.options.strictAutoFit\n      ? targetSpan\n      : targetSpan > remainColumns\n      ? remainColumns\n      : targetSpan\n    const gridColumn =\n      originSpan === -1 ? `span ${remainColumns} / -1` : `span ${span} / auto`\n    if (node.element.style.gridColumn !== gridColumn) {\n      node.element.style.gridColumn = gridColumn\n    }\n    if (node.visible) {\n      walked += span\n    }\n    shadowWalked += span\n    if (columnIndex === 0) {\n      rowIndex++\n    }\n    if (shadowColumnIndex == 0) {\n      shadowRowIndex++\n    }\n    node.shadowRow = shadowRowIndex\n    node.shadowColumn = shadowColumnIndex + 1\n    if (node.visible) {\n      node.row = rowIndex\n      node.column = columnIndex + 1\n    }\n    if (grid.options?.shouldVisible) {\n      if (!grid.options.shouldVisible(node, grid)) {\n        if (node.visible) {\n          node.element.style.display = 'none'\n        }\n        node.visible = false\n      } else {\n        if (!node.visible) {\n          node.element.style.display = ''\n        }\n        node.visible = true\n      }\n    }\n    return node\n  })\n}\n\nconst nextTick = (callback?: () => void) => Promise.resolve(0).then(callback)\n\nexport type GridNode = {\n  index?: number\n  visible?: boolean\n  column?: number\n  shadowColumn?: number\n  row?: number\n  shadowRow?: number\n  span?: number\n  originSpan?: number\n  element?: HTMLElement\n}\nexport class Grid<Container extends HTMLElement> {\n  options: IGridOptions\n  width = 0\n  height = 0\n  container: Container\n  children: GridNode[] = []\n  childTotalColumns = 0\n  shadowChildTotalColumns = 0\n  childOriginTotalColumns = 0\n  shadowChildOriginTotalColumns = 0\n  ready = false\n  constructor(options?: IGridOptions) {\n    this.options = {\n      breakpoints: [720, 1280, 1920],\n      columnGap: 8,\n      rowGap: 4,\n      minWidth: 100,\n      colWrap: true,\n      strictAutoFit: false,\n      ...options,\n    }\n    define(this, {\n      options: observable.shallow,\n      width: observable.ref,\n      height: observable.ref,\n      ready: observable.ref,\n      children: observable.ref,\n      childOriginTotalColumns: observable.ref,\n      shadowChildOriginTotalColumns: observable.ref,\n      shadowChildTotalColumns: observable.ref,\n      childTotalColumns: observable.ref,\n      columns: observable.computed,\n      templateColumns: observable.computed,\n      gap: observable.computed,\n      maxColumns: observable.computed,\n      minColumns: observable.computed,\n      maxWidth: observable.computed,\n      minWidth: observable.computed,\n      breakpoints: observable.computed,\n      breakpoint: observable.computed,\n      rowGap: observable.computed,\n      columnGap: observable.computed,\n      colWrap: observable.computed,\n    })\n  }\n\n  set breakpoints(breakpoints) {\n    this.options.breakpoints = breakpoints\n  }\n\n  get breakpoints() {\n    return this.options.breakpoints\n  }\n\n  get breakpoint() {\n    return calcBreakpointIndex(this.options.breakpoints, this.width)\n  }\n\n  set maxWidth(maxWidth) {\n    this.options.maxWidth = maxWidth\n  }\n\n  get maxWidth() {\n    return factor(this.options.maxWidth, this) ?? Infinity\n  }\n\n  set minWidth(minWidth) {\n    this.options.minWidth = minWidth\n  }\n\n  get minWidth() {\n    return factor(this.options.minWidth, this) ?? 100\n  }\n\n  set maxColumns(maxColumns) {\n    this.options.maxColumns = maxColumns\n  }\n\n  get maxColumns() {\n    return factor(this.options.maxColumns, this) ?? Infinity\n  }\n\n  set maxRows(maxRows) {\n    this.options.maxRows = maxRows\n  }\n\n  get maxRows() {\n    return this.options.maxRows ?? Infinity\n  }\n\n  set minColumns(minColumns) {\n    this.options.minColumns = minColumns\n  }\n\n  get minColumns() {\n    return factor(this.options.minColumns, this) ?? 1\n  }\n\n  set rowGap(rowGap) {\n    this.options.rowGap = rowGap\n  }\n\n  get rowGap() {\n    return factor(this.options.rowGap, this) ?? 5\n  }\n\n  set columnGap(columnGap) {\n    this.options.columnGap = columnGap\n  }\n\n  get columnGap() {\n    return factor(this.options.columnGap, this) ?? 10\n  }\n\n  set colWrap(colWrap) {\n    this.options.colWrap = colWrap\n  }\n\n  get colWrap() {\n    return factor(this.options.colWrap, this) ?? true\n  }\n\n  get columns() {\n    if (!this.ready) return 0\n\n    const originTotalColumns = this.childOriginTotalColumns\n\n    if (this.colWrap === false) {\n      return originTotalColumns\n    }\n\n    const baseColumns = this.childSize\n\n    const strictMaxWidthColumns = Math.round(\n      this.width / (this.maxWidth + this.columnGap)\n    )\n\n    const looseMaxWidthColumns = Math.min(\n      originTotalColumns,\n      strictMaxWidthColumns\n    )\n\n    const maxWidthColumns = this.options.strictAutoFit\n      ? strictMaxWidthColumns\n      : looseMaxWidthColumns\n\n    const strictMinWidthColumns = Math.round(\n      this.width / (this.minWidth + this.columnGap)\n    )\n\n    const looseMinWidthColumns = Math.min(\n      originTotalColumns,\n      strictMinWidthColumns\n    )\n\n    const minWidthColumns = this.options.strictAutoFit\n      ? strictMinWidthColumns\n      : looseMinWidthColumns\n\n    const minCalculatedColumns = Math.min(\n      baseColumns,\n      originTotalColumns,\n      maxWidthColumns,\n      minWidthColumns\n    )\n\n    const maxCalculatedColumns = Math.max(\n      baseColumns,\n      originTotalColumns,\n      maxWidthColumns,\n      minWidthColumns\n    )\n\n    const finalColumns = calcSatisfyColumns(\n      this.width,\n      maxCalculatedColumns,\n      minCalculatedColumns,\n      this.maxWidth,\n      this.minWidth,\n      this.columnGap\n    )\n    if (finalColumns >= this.maxColumns) {\n      return this.maxColumns\n    }\n    if (finalColumns <= this.minColumns) {\n      return this.minColumns\n    }\n    return finalColumns\n  }\n\n  get rows() {\n    return Math.ceil(this.childTotalColumns / this.columns)\n  }\n\n  get shadowRows() {\n    return Math.ceil(this.shadowChildTotalColumns / this.columns)\n  }\n\n  get templateColumns() {\n    if (!this.width) return ''\n    if (this.maxWidth === Infinity) {\n      return `repeat(${this.columns},minmax(0,1fr))`\n    }\n    if (this.options.strictAutoFit !== true) {\n      const columnWidth =\n        (this.width - (this.columns - 1) * this.columnGap) / this.columns\n      if (columnWidth < this.minWidth || columnWidth > this.maxWidth) {\n        return `repeat(${this.columns},minmax(0,1fr))`\n      }\n    }\n    return `repeat(${this.columns},minmax(${this.minWidth}px,${this.maxWidth}px))`\n  }\n\n  get gap() {\n    return `${this.rowGap}px ${this.columnGap}px`\n  }\n\n  get childSize() {\n    return this.children.length\n  }\n\n  get fullnessLastColumn() {\n    return this.columns === this.children[this.childSize - 1]?.span\n  }\n\n  connect = (container: Container) => {\n    if (container) {\n      this.container = container\n      const initialize = batch.bound(() => {\n        digest()\n        this.ready = true\n      })\n      const digest = batch.bound(() => {\n        this.children = parseGridNode(this.container.children)\n        this.childTotalColumns = calcChildTotalColumns(this.children)\n        this.shadowChildTotalColumns = calcChildTotalColumns(\n          this.children,\n          true\n        )\n        this.childOriginTotalColumns = calcChildOriginTotalColumns(\n          this.children\n        )\n        this.shadowChildOriginTotalColumns = calcChildOriginTotalColumns(\n          this.children,\n          true\n        )\n        const rect = this.container.getBoundingClientRect()\n        if (rect.width && rect.height) {\n          this.width = rect.width\n          this.height = rect.height\n        }\n        resolveChildren(this)\n        nextTick(() => {\n          this.options?.onDigest?.(this)\n        })\n        if (!this.ready) {\n          nextTick(() => {\n            this.options?.onInitialized?.(this)\n          })\n        }\n      })\n      const mutationObserver = new ChildListMutationObserver(digest)\n      // add requestAnimationFrame to smooth digest\n      const smoothDigest = () => {\n        requestAnimationFrame(() => {\n          digest()\n        })\n      }\n      const resizeObserver = new ResizeObserver(smoothDigest)\n      const dispose = reaction(() => ({ ...this.options }), digest)\n      resizeObserver.observe(this.container)\n      mutationObserver.observe(this.container, {\n        attributeFilter: ['data-grid-span'],\n        attributes: true,\n      })\n      initialize()\n      return () => {\n        resizeObserver.unobserve(this.container)\n        resizeObserver.disconnect()\n        mutationObserver.disconnect()\n        dispose()\n        this.children = []\n      }\n    }\n\n    return () => {}\n  }\n\n  static id = (options: IGridOptions = {}) =>\n    JSON.stringify(\n      [\n        'maxRows',\n        'maxColumns',\n        'minColumns',\n        'maxWidth',\n        'minWidth',\n        'breakpoints',\n        'columnGap',\n        'rowGap',\n        'colWrap',\n        'strictAutoFit',\n      ].map((key) => options[key])\n    )\n}\n"
  },
  {
    "path": "packages/grid/src/observer.ts",
    "content": "const isHTMLElement = (node: Node): node is HTMLElement => node.nodeType === 1\n\ntype ChildNode = {\n  element?: HTMLElement\n  observer?: MutationObserver\n  dispose?: () => void\n}\n\nexport class ChildListMutationObserver {\n  observer: MutationObserver\n  callback: MutationCallback\n  childList: ChildNode[] = []\n  init: MutationObserverInit\n  constructor(callback: MutationCallback) {\n    this.callback = callback\n    this.observer = new MutationObserver(this.handler)\n  }\n\n  observeChildList(element: HTMLElement) {\n    Array.from(element.children).forEach((node: HTMLElement) => {\n      this.addObserver(node)\n    })\n  }\n\n  addObserver(element: HTMLElement) {\n    const child = this.childList.find((t) => t.element === element)\n    if (!child) {\n      const childIndex = this.childList.length\n      const child = {\n        element,\n        observer: new MutationObserver(this.callback),\n        dispose: () => {\n          if (child.observer) {\n            child.observer.disconnect()\n            delete child.observer\n            this.childList.splice(childIndex, 1)\n          }\n        },\n      }\n      child.observer.observe(child.element, {\n        ...this.init,\n        subtree: false,\n        childList: false,\n        characterData: false,\n        characterDataOldValue: false,\n        attributeOldValue: false,\n      })\n      this.childList.push(child)\n    }\n  }\n\n  removeObserver(element: HTMLElement) {\n    const child = this.childList.find((t) => t.element === element)\n    if (child) {\n      child.dispose?.()\n    }\n  }\n\n  handler = (mutations: MutationRecord[]) => {\n    mutations.forEach((mutation) => {\n      if (mutation.type === 'childList') {\n        mutation.addedNodes.forEach((node) => {\n          if (isHTMLElement(node)) {\n            this.addObserver(node)\n          }\n        })\n        mutation.removedNodes.forEach((node) => {\n          if (isHTMLElement(node)) {\n            this.removeObserver(node)\n          }\n        })\n      }\n    })\n    this.callback(mutations, this.observer)\n  }\n\n  observe = (element: HTMLElement, init?: MutationObserverInit) => {\n    this.init = init\n    this.observeChildList(element)\n    this.observer.observe(element, {\n      ...this.init,\n      subtree: false,\n      childList: true,\n      characterData: false,\n      characterDataOldValue: false,\n      attributeOldValue: false,\n    })\n  }\n\n  disconnect = () => {\n    this.observer.disconnect()\n  }\n}\n"
  },
  {
    "path": "packages/grid/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*\", \"devtools/*\"]\n    },\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/grid/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"include\": [\"./src/**/*.ts\", \"./src/**/*.tsx\"],\n  \"exclude\": [\"./src/__tests__/*\", \"./esm/*\", \"./lib/*\"],\n  \"compilerOptions\": {\n    \"lib\": [\"ESNext\", \"DOM\"]\n  }\n}\n"
  },
  {
    "path": "packages/json-schema/.npmignore",
    "content": "node_modules\n*.log\nbuild\ndocs\ndoc-site\n__tests__\n.eslintrc\njest.config.js\ntsconfig.json\n.umi\nsrc"
  },
  {
    "path": "packages/json-schema/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-present, Alibaba Group Holding Limited. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/json-schema/README.md",
    "content": "# @formily/json-schema\n"
  },
  {
    "path": "packages/json-schema/package.json",
    "content": "{\n  \"name\": \"@formily/json-schema\",\n  \"version\": \"2.3.7\",\n  \"license\": \"MIT\",\n  \"main\": \"lib\",\n  \"module\": \"esm\",\n  \"umd:main\": \"dist/formily.json-schema.umd.production.js\",\n  \"unpkg\": \"dist/formily.json-schema.umd.production.js\",\n  \"jsdelivr\": \"dist/formily.json-schema.umd.production.js\",\n  \"jsnext:main\": \"esm\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/alibaba/formily.git\"\n  },\n  \"types\": \"esm/index.d.ts\",\n  \"bugs\": {\n    \"url\": \"https://github.com/alibaba/formily/issues\"\n  },\n  \"homepage\": \"https://github.com/alibaba/formily#readme\",\n  \"engines\": {\n    \"npm\": \">=3.0.0\"\n  },\n  \"scripts\": {\n    \"build\": \"rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm && npm run build:umd\",\n    \"build:cjs\": \"tsc --project tsconfig.build.json\",\n    \"build:esm\": \"tsc --project tsconfig.build.json --module es2015 --outDir esm\",\n    \"build:umd\": \"rollup --config\"\n  },\n  \"peerDependencies\": {\n    \"typescript\": \">4.1.5\"\n  },\n  \"dependencies\": {\n    \"@formily/core\": \"2.3.7\",\n    \"@formily/reactive\": \"2.3.7\",\n    \"@formily/shared\": \"2.3.7\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"gitHead\": \"ac79c196ae9324889aca5e0501146f9b37b04283\"\n}\n"
  },
  {
    "path": "packages/json-schema/rollup.config.js",
    "content": "import baseConfig from '../../scripts/rollup.base.js'\n\nexport default baseConfig('formily.json-schema', 'Formily.JSONSchema')\n"
  },
  {
    "path": "packages/json-schema/src/__tests__/__snapshots__/schema.spec.ts.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`all methods 1`] = `\nObject {\n  \"_isJSONSchemaObject\": true,\n  \"additionalProperties\": Object {\n    \"_isJSONSchemaObject\": true,\n    \"type\": \"string\",\n    \"version\": \"2.0\",\n  },\n  \"patternProperties\": Object {\n    \"^[a-zA-Z0-9]*$\": Object {\n      \"_isJSONSchemaObject\": true,\n      \"name\": \"^[a-zA-Z0-9]*$\",\n      \"properties\": Object {\n        \"made\": Object {\n          \"_isJSONSchemaObject\": true,\n          \"name\": \"made\",\n          \"type\": \"string\",\n          \"version\": \"2.0\",\n          \"x-index\": 1,\n        },\n        \"model\": Object {\n          \"_isJSONSchemaObject\": true,\n          \"name\": \"model\",\n          \"type\": \"string\",\n          \"version\": \"2.0\",\n          \"x-index\": 2,\n        },\n        \"year\": Object {\n          \"_isJSONSchemaObject\": true,\n          \"name\": \"year\",\n          \"type\": \"string\",\n          \"version\": \"2.0\",\n          \"x-index\": 0,\n        },\n      },\n      \"version\": \"2.0\",\n    },\n  },\n  \"properties\": Object {\n    \"array\": Object {\n      \"_isJSONSchemaObject\": true,\n      \"additionalItems\": Object {\n        \"_isJSONSchemaObject\": true,\n        \"type\": \"string\",\n        \"version\": \"2.0\",\n      },\n      \"items\": Array [\n        Object {\n          \"_isJSONSchemaObject\": true,\n          \"type\": \"integer\",\n          \"version\": \"2.0\",\n        },\n        Object {\n          \"_isJSONSchemaObject\": true,\n          \"type\": \"integer\",\n          \"version\": \"2.0\",\n        },\n      ],\n      \"name\": \"array\",\n      \"title\": \"string\",\n      \"type\": \"string\",\n      \"version\": \"2.0\",\n    },\n    \"string\": Object {\n      \"_isJSONSchemaObject\": true,\n      \"description\": null,\n      \"name\": \"string\",\n      \"title\": \"string\",\n      \"type\": \"string\",\n      \"version\": \"2.0\",\n      \"x-reactions\": Array [\n        Object {\n          \"fulfill\": Object {\n            \"schema\": Object {},\n          },\n          \"target\": \"xxx\",\n          \"when\": true,\n        },\n      ],\n    },\n  },\n  \"type\": \"object\",\n  \"version\": \"2.0\",\n  \"x-reactions\": null,\n}\n`;\n\nexports[`all methods 2`] = `\nObject {\n  \"_isJSONSchemaObject\": true,\n  \"additionalProperties\": Object {\n    \"_isJSONSchemaObject\": true,\n    \"type\": \"string\",\n    \"version\": \"2.0\",\n  },\n  \"patternProperties\": Object {\n    \"^[a-zA-Z0-9]*$\": Object {\n      \"_isJSONSchemaObject\": true,\n      \"name\": \"^[a-zA-Z0-9]*$\",\n      \"properties\": Object {\n        \"made\": Object {\n          \"_isJSONSchemaObject\": true,\n          \"name\": \"made\",\n          \"type\": \"string\",\n          \"version\": \"2.0\",\n          \"x-index\": 1,\n        },\n        \"model\": Object {\n          \"_isJSONSchemaObject\": true,\n          \"name\": \"model\",\n          \"type\": \"string\",\n          \"version\": \"2.0\",\n          \"x-index\": 2,\n        },\n        \"year\": Object {\n          \"_isJSONSchemaObject\": true,\n          \"name\": \"year\",\n          \"type\": \"string\",\n          \"version\": \"2.0\",\n          \"x-index\": 0,\n        },\n      },\n      \"version\": \"2.0\",\n    },\n  },\n  \"properties\": Object {\n    \"array\": Object {\n      \"_isJSONSchemaObject\": true,\n      \"additionalItems\": Object {\n        \"_isJSONSchemaObject\": true,\n        \"type\": \"string\",\n        \"version\": \"2.0\",\n      },\n      \"items\": Array [\n        Object {\n          \"_isJSONSchemaObject\": true,\n          \"type\": \"integer\",\n          \"version\": \"2.0\",\n        },\n        Object {\n          \"_isJSONSchemaObject\": true,\n          \"type\": \"integer\",\n          \"version\": \"2.0\",\n        },\n      ],\n      \"name\": \"array\",\n      \"title\": \"string\",\n      \"type\": \"string\",\n      \"version\": \"2.0\",\n    },\n    \"string\": Object {\n      \"_isJSONSchemaObject\": true,\n      \"description\": null,\n      \"name\": \"string\",\n      \"title\": \"string\",\n      \"type\": \"string\",\n      \"version\": \"2.0\",\n      \"x-reactions\": Array [\n        Object {\n          \"fulfill\": Object {\n            \"schema\": Object {},\n          },\n          \"target\": \"xxx\",\n          \"when\": true,\n        },\n      ],\n    },\n  },\n  \"type\": \"object\",\n  \"version\": \"2.0\",\n  \"x-reactions\": null,\n}\n`;\n\nexports[`all methods 3`] = `\nObject {\n  \"_isJSONSchemaObject\": true,\n  \"additionalProperties\": Object {\n    \"_isJSONSchemaObject\": true,\n    \"type\": \"string\",\n    \"version\": \"2.0\",\n  },\n  \"patternProperties\": Object {},\n  \"properties\": Object {\n    \"array\": Object {\n      \"_isJSONSchemaObject\": true,\n      \"additionalItems\": Object {\n        \"_isJSONSchemaObject\": true,\n        \"type\": \"string\",\n        \"version\": \"2.0\",\n      },\n      \"items\": Array [\n        Object {\n          \"_isJSONSchemaObject\": true,\n          \"type\": \"integer\",\n          \"version\": \"2.0\",\n        },\n        Object {\n          \"_isJSONSchemaObject\": true,\n          \"type\": \"integer\",\n          \"version\": \"2.0\",\n        },\n      ],\n      \"name\": \"array\",\n      \"title\": \"string\",\n      \"type\": \"string\",\n      \"version\": \"2.0\",\n    },\n  },\n  \"type\": \"object\",\n  \"version\": \"2.0\",\n  \"x-reactions\": null,\n}\n`;\n\nexports[`all methods 4`] = `\nObject {\n  \"_isJSONSchemaObject\": true,\n  \"description\": null,\n  \"name\": \"string\",\n  \"title\": \"string\",\n  \"type\": \"string\",\n  \"version\": \"2.0\",\n  \"x-reactions\": Array [\n    Object {\n      \"fulfill\": Object {\n        \"schema\": Object {},\n      },\n      \"target\": \"xxx\",\n      \"when\": true,\n    },\n  ],\n}\n`;\n\nexports[`all methods 5`] = `\nObject {\n  \"_isJSONSchemaObject\": true,\n  \"additionalItems\": undefined,\n  \"additionalProperties\": undefined,\n  \"items\": Array [\n    undefined,\n  ],\n  \"properties\": Object {\n    \"xxx\": undefined,\n  },\n  \"type\": \"object\",\n  \"version\": \"2.0\",\n}\n`;\n\nexports[`all methods 6`] = `\nObject {\n  \"_isJSONSchemaObject\": true,\n  \"additionalItems\": undefined,\n  \"additionalProperties\": undefined,\n  \"items\": Array [\n    undefined,\n  ],\n  \"properties\": Object {\n    \"xxx\": undefined,\n  },\n  \"type\": \"object\",\n  \"version\": \"2.0\",\n}\n`;\n\nexports[`all props 1`] = `\nObject {\n  \"_isJSONSchemaObject\": true,\n  \"additionalProperties\": Object {\n    \"_isJSONSchemaObject\": true,\n    \"type\": \"string\",\n    \"version\": \"2.0\",\n  },\n  \"description\": \"description\",\n  \"patternProperties\": Object {\n    \"^[a-zA-Z0-9]*$\": Object {\n      \"_isJSONSchemaObject\": true,\n      \"name\": \"^[a-zA-Z0-9]*$\",\n      \"properties\": Object {\n        \"made\": Object {\n          \"_isJSONSchemaObject\": true,\n          \"name\": \"made\",\n          \"type\": \"string\",\n          \"version\": \"2.0\",\n        },\n        \"model\": Object {\n          \"_isJSONSchemaObject\": true,\n          \"name\": \"model\",\n          \"type\": \"string\",\n          \"version\": \"2.0\",\n        },\n        \"year\": Object {\n          \"_isJSONSchemaObject\": true,\n          \"name\": \"year\",\n          \"type\": \"string\",\n          \"version\": \"2.0\",\n        },\n      },\n      \"version\": \"2.0\",\n    },\n  },\n  \"properties\": Object {\n    \"array\": Object {\n      \"_isJSONSchemaObject\": true,\n      \"additionalItems\": Object {\n        \"_isJSONSchemaObject\": true,\n        \"type\": \"number\",\n        \"version\": \"2.0\",\n      },\n      \"items\": Object {\n        \"_isJSONSchemaObject\": true,\n        \"type\": \"string\",\n        \"version\": \"2.0\",\n      },\n      \"name\": \"array\",\n      \"type\": \"array\",\n      \"version\": \"2.0\",\n    },\n    \"array2\": Object {\n      \"_isJSONSchemaObject\": true,\n      \"items\": Array [\n        Object {\n          \"_isJSONSchemaObject\": true,\n          \"type\": \"string\",\n          \"version\": \"2.0\",\n        },\n        Object {\n          \"_isJSONSchemaObject\": true,\n          \"type\": \"object\",\n          \"version\": \"2.0\",\n        },\n      ],\n      \"name\": \"array2\",\n      \"type\": \"array\",\n      \"version\": \"2.0\",\n    },\n    \"boolean\": Object {\n      \"_isJSONSchemaObject\": true,\n      \"default\": false,\n      \"name\": \"boolean\",\n      \"type\": \"boolean\",\n      \"version\": \"2.0\",\n    },\n    \"date\": Object {\n      \"_isJSONSchemaObject\": true,\n      \"default\": \"2020-12-23\",\n      \"name\": \"date\",\n      \"type\": \"date\",\n      \"version\": \"2.0\",\n    },\n    \"datetime\": Object {\n      \"_isJSONSchemaObject\": true,\n      \"default\": \"2020-12-23 23:00:00\",\n      \"name\": \"datetime\",\n      \"type\": \"datetime\",\n      \"version\": \"2.0\",\n    },\n    \"number\": Object {\n      \"_isJSONSchemaObject\": true,\n      \"default\": 100,\n      \"name\": \"number\",\n      \"type\": \"number\",\n      \"version\": \"2.0\",\n    },\n    \"string\": Object {\n      \"_isJSONSchemaObject\": true,\n      \"default\": \"default\",\n      \"name\": \"string\",\n      \"required\": true,\n      \"type\": \"string\",\n      \"version\": \"2.0\",\n      \"x-component\": \"Input\",\n      \"x-component-props\": Object {\n        \"placeholder\": \"placeholder\",\n      },\n      \"x-decorator\": \"FormItem\",\n      \"x-decorator-props\": Object {\n        \"labelCol\": 3,\n      },\n      \"x-disabled\": true,\n      \"x-display\": \"visible\",\n      \"x-editable\": false,\n      \"x-hidden\": false,\n      \"x-pattern\": \"readPretty\",\n      \"x-reactions\": Array [\n        Object {\n          \"target\": \"xxx\",\n          \"when\": \"{{aa > bb}}\",\n        },\n      ],\n      \"x-read-only\": true,\n      \"x-validator\": Array [\n        \"phone\",\n      ],\n    },\n    \"void\": Object {\n      \"_isJSONSchemaObject\": true,\n      \"name\": \"void\",\n      \"type\": \"void\",\n      \"version\": \"2.0\",\n    },\n  },\n  \"title\": \"title\",\n  \"type\": \"object\",\n  \"version\": \"2.0\",\n}\n`;\n"
  },
  {
    "path": "packages/json-schema/src/__tests__/compiler.spec.ts",
    "content": "import {\n  compile,\n  silent,\n  registerCompiler,\n  shallowCompile,\n  patchCompile,\n  patchSchemaCompile,\n} from '../compiler'\nimport { Schema } from '../schema'\n\ntest('compile', () => {\n  expect(compile('{{123}}xx')).toEqual('{{123}}xx')\n  expect(compile('{{123}}  ')).toEqual(123)\n  expect(compile('{{123}}')).toEqual(123)\n  expect(\n    compile({\n      hello: '{{123}}',\n    })\n  ).toEqual({\n    hello: 123,\n  })\n  expect(\n    compile({\n      array: ['{{123}}'],\n    })\n  ).toEqual({\n    array: [123],\n  })\n  const date = new Date()\n  date['expression'] = '{{123}}'\n  const compiledDate = compile(date)\n  expect(compiledDate).toEqual(date)\n  expect(compiledDate['expression']).toEqual('{{123}}')\n  const moment = { _isAMomentObject: true, expression: '{{123}}' }\n  const compiledMoment = compile(moment)\n  expect(compiledMoment).toEqual(moment)\n  expect(compiledMoment['expression']).toEqual('{{123}}')\n  const react = { _owner: true, $$typeof: true, expression: '{{123}}' }\n  const compiledReact = compile(react)\n  expect(compiledReact).toEqual(react)\n  expect(compiledReact['expression']).toEqual('{{123}}')\n  const actions = {\n    [Symbol.for('__REVA_ACTIONS')]: true,\n    expression: '{{123}}',\n  }\n  const compiledActions = compile(actions)\n  expect(compiledActions).toEqual(actions)\n  expect(compiledActions['expression']).toEqual('{{123}}')\n\n  const schema = new Schema({\n    type: 'object',\n    properties: {\n      aa: {\n        type: 'string',\n        'x-component': 'Input',\n        'x-component-props': '{{123}}',\n      },\n    },\n  })\n  const compiledSchema = schema.compile()\n  expect(compiledSchema.toJSON()).toEqual(schema.toJSON())\n  expect(compiledSchema.properties?.['aa']['x-component-props']).toEqual(\n    '{{123}}'\n  )\n  const toJSable = {\n    toJS() {\n      return {\n        aa: 123,\n      }\n    },\n    expression: '{{123}}',\n  }\n\n  const compiledToJSable = compile(toJSable)\n  expect(compiledToJSable).toEqual(toJSable)\n  expect(compiledToJSable['expression']).toEqual('{{123}}')\n\n  const toJSONable = {\n    toJSON() {\n      return {\n        aa: 123,\n      }\n    },\n    expression: '{{123}}',\n  }\n\n  const compiledToJSONable = compile(toJSONable)\n  expect(compiledToJSONable).toEqual(toJSONable)\n  expect(compiledToJSONable['expression']).toEqual('{{123}}')\n\n  const circularRef = {\n    expression: '{{123}}',\n  }\n  circularRef['self'] = circularRef\n\n  const compiledCircularRef = compile(circularRef)\n  expect(compiledCircularRef['expression']).toEqual(123)\n})\n\ntest('shallowCompile', () => {\n  expect(shallowCompile('{{123}}xx')).toEqual('{{123}}xx')\n  expect(shallowCompile('{{123}}  ')).toEqual(123)\n  expect(shallowCompile('{{123}}')).toEqual(123)\n  expect(\n    shallowCompile({\n      hello: '{{123}}',\n    })\n  ).toEqual({\n    hello: '{{123}}',\n  })\n  expect(\n    shallowCompile({\n      array: ['{{123}}'],\n    })\n  ).toEqual({\n    array: ['{{123}}'],\n  })\n  expect(shallowCompile(['{{123}}'])).toEqual(['{{123}}'])\n  expect(shallowCompile([{ kk: '{{123}}' }])).toEqual([{ kk: '{{123}}' }])\n})\n\ntest('unsilent', () => {\n  silent(false)\n  expect(() => compile('{{ ( }}')).toThrowError()\n})\n\ntest('silent', () => {\n  silent(true)\n  expect(() => compile('{{ ( }}')).not.toThrowError()\n  silent(false)\n})\n\ntest('patchCompile', () => {\n  const targetState = {\n    title: '',\n    description: '',\n    dataSource: [22],\n  }\n  patchCompile(\n    targetState as any,\n    {\n      title: '132',\n      description: '{{\"Hello world\"}}',\n      dataSource: [1, 2, 3, '{{333}}'],\n      extend: '333',\n    },\n    {}\n  )\n  expect(targetState).toEqual({\n    title: '132',\n    description: 'Hello world',\n    dataSource: [1, 2, 3, 333],\n  })\n})\n\ntest('patchSchemaCompile', () => {\n  const targetState = {\n    title: '',\n    description: '',\n    dataSource: [22],\n  }\n  patchSchemaCompile(\n    targetState as any,\n    {\n      title: '132',\n      description: '{{\"Hello world\"}}',\n      enum: [1, 2, 3, '{{333}}'],\n      'x-reactions': {\n        fulfill: {\n          schema: {\n            title: 'hello',\n          },\n        },\n      },\n      version: '1.2.3',\n    },\n    {}\n  )\n  expect(targetState).toEqual({\n    title: '132',\n    description: 'Hello world',\n    dataSource: [\n      { label: 1, value: 1 },\n      { label: 2, value: 2 },\n      { label: 3, value: 3 },\n      { label: 333, value: 333 },\n    ],\n  })\n})\n\ntest('patchSchemaCompile demand un initialized', () => {\n  const setValidatorRule = (name: string, value: any) => {\n    targetState[name] = value\n  }\n  const targetState = {\n    title: '',\n    description: '',\n    dataSource: [22],\n    setValidatorRule,\n  }\n  patchSchemaCompile(\n    targetState as any,\n    {\n      title: '132',\n      'x-display': undefined,\n      'x-hidden': null,\n      description: '{{\"Hello world\"}}',\n      enum: [1, 2, 3, '{{333}}'],\n      format: 'phone',\n      'x-reactions': {\n        fulfill: {\n          schema: {\n            title: 'hello',\n          },\n        },\n      },\n      version: '1.2.3',\n    },\n    {},\n    true\n  )\n  expect(targetState).toEqual({\n    title: '132',\n    description: 'Hello world',\n    hidden: null,\n    format: 'phone',\n    setValidatorRule,\n    dataSource: [\n      { label: 1, value: 1 },\n      { label: 2, value: 2 },\n      { label: 3, value: 3 },\n      { label: 333, value: 333 },\n    ],\n  })\n})\n\ntest('patchSchemaCompile demand initialized', () => {\n  const targetState = {\n    initialized: true,\n    title: '',\n    description: '',\n    dataSource: [22],\n  }\n  patchSchemaCompile(\n    targetState as any,\n    {\n      title: '132',\n      description: '{{\"Hello world\"}}',\n      enum: [1, 2, 3, '{{333}}'],\n      'x-reactions': {\n        fulfill: {\n          schema: {\n            title: 'hello',\n          },\n        },\n      },\n      version: '1.2.3',\n    },\n    {},\n    true\n  )\n  expect(targetState).toEqual({\n    initialized: true,\n    title: '',\n    description: '',\n    dataSource: [22],\n  })\n})\n\ntest('patchSchemaCompile x-compile-omitted', () => {\n  const targetState = {\n    title: '',\n    validator: [],\n  }\n  patchSchemaCompile(\n    targetState as any,\n    {\n      title: '132',\n      'x-validator': [\n        {\n          remoteCheckUniq: '{{field.value}}',\n        },\n      ],\n      version: '1.2.3',\n    },\n    {\n      field: {\n        value: 888,\n      },\n    }\n  )\n  expect(targetState).toEqual({\n    title: '132',\n    validator: [{ remoteCheckUniq: 888 }],\n  })\n\n  const targetOmitState = {\n    title: '',\n    validator: [],\n  }\n  patchSchemaCompile(\n    targetOmitState as any,\n    {\n      title: '132',\n      'x-compile-omitted': ['x-validator'],\n      'x-validator': [\n        {\n          remoteCheckUniq: '{{field.value}}',\n        },\n      ],\n      version: '1.2.3',\n    },\n    {\n      field: {\n        value: 888,\n      },\n    }\n  )\n  expect(targetOmitState).toEqual({\n    title: '132',\n    validator: [{ remoteCheckUniq: '{{field.value}}' }],\n  })\n})\n\ntest('registerCompiler', () => {\n  registerCompiler(() => {\n    return 'compiled'\n  })\n  expect(compile('{{123}}xx')).toEqual('{{123}}xx')\n  expect(compile('{{123}}  ')).toEqual('compiled')\n  expect(compile('{{123}}')).toEqual('compiled')\n  expect(\n    compile({\n      hello: '{{123}}',\n    })\n  ).toEqual({\n    hello: 'compiled',\n  })\n  expect(\n    compile({\n      array: ['{{123}}'],\n    })\n  ).toEqual({\n    array: ['compiled'],\n  })\n  registerCompiler(null)\n})\n"
  },
  {
    "path": "packages/json-schema/src/__tests__/patches.spec.ts",
    "content": "import { Schema } from '../schema'\nimport {\n  registerTypeDefaultComponents,\n  registerVoidComponents,\n} from '../polyfills'\n\nregisterVoidComponents(['MyCard'])\nregisterTypeDefaultComponents({\n  string: 'Input',\n})\n\nSchema.enablePolyfills(['1.0'])\n\ntest('v1 polyfill', () => {\n  const schema = new Schema({\n    type: 'string',\n    editable: true,\n  } as any)\n  expect(schema['x-editable']).toEqual(true)\n  const schema1 = new Schema({\n    type: 'string',\n    visible: true,\n  } as any)\n  expect(schema1['x-visible']).toEqual(true)\n  const schema2 = new Schema({\n    type: 'string',\n    display: false,\n  } as any)\n  expect(schema2['x-display']).toEqual('hidden')\n  expect(schema2['x-display']).toEqual('hidden')\n  const schema3 = new Schema({\n    type: 'string',\n    'x-linkages': [\n      {\n        type: 'value:visible',\n        condition: '{{$value == 123}}',\n      },\n    ],\n  } as any)\n  expect(schema3['x-reactions']).toEqual([\n    {\n      when: '{{$self.value == 123}}',\n      fulfill: {\n        state: {\n          visible: true,\n        },\n      },\n      otherwise: {\n        state: {\n          visible: false,\n        },\n      },\n    },\n  ])\n  const schema4 = new Schema({\n    type: 'string',\n    'x-linkages': [\n      {\n        type: 'value:schema',\n        target: 'xxx',\n        condition: '{{$value == 123}}',\n        schema: {\n          title: 'xxx',\n        },\n        otherwise: {\n          title: '123',\n        },\n      },\n    ],\n  } as any)\n  expect(schema4['x-reactions']).toEqual([\n    {\n      when: '{{$self.value == 123}}',\n      target: 'xxx',\n      fulfill: {\n        schema: {\n          version: '1.0',\n          title: 'xxx',\n          'x-decorator': 'FormItem',\n        },\n      },\n      otherwise: {\n        schema: {\n          version: '1.0',\n          title: '123',\n          'x-decorator': 'FormItem',\n        },\n      },\n    },\n  ])\n  const schema5 = new Schema({\n    type: 'string',\n    'x-linkages': [\n      {\n        type: 'value:state',\n        target: 'xxx',\n        condition: '{{$value == 123}}',\n        state: {\n          title: 'xxx',\n        },\n        otherwise: {\n          title: '123',\n        },\n      },\n    ],\n  } as any)\n  expect(schema5['x-reactions']).toEqual([\n    {\n      when: '{{$self.value == 123}}',\n      target: 'xxx',\n      fulfill: {\n        state: {\n          title: 'xxx',\n        },\n      },\n      otherwise: {\n        state: {\n          title: '123',\n        },\n      },\n    },\n  ])\n  const schema6 = new Schema({\n    type: 'string',\n    'x-props': {\n      labelCol: 3,\n      wrapperCol: 4,\n    },\n    'x-linkages': [\n      {\n        type: 'value:visible',\n        condition: null,\n      },\n    ],\n  } as any)\n  expect(schema6['x-component']).toEqual('Input')\n  expect(schema6['x-decorator']).toEqual('FormItem')\n  expect(schema6['x-decorator-props']).toEqual({\n    labelCol: 3,\n    wrapperCol: 4,\n  })\n  const schema7 = new Schema({\n    type: 'object',\n    'x-component': 'MyCard',\n    'x-linkages': {},\n  } as any)\n  expect(schema7.type === 'void').toBeTruthy()\n  new Schema({\n    type: 'object',\n    'x-component': 'MyCard',\n    'x-linkages': [null],\n  } as any)\n  new Schema({\n    type: 'object',\n    'x-component': 'MyCard',\n    'x-linkages': [{}],\n  } as any)\n  const schema8 = new Schema({\n    type: 'string',\n    'x-rules': ['phone'],\n  } as any)\n  expect(schema8['x-validator']).toEqual(['phone'])\n})\n"
  },
  {
    "path": "packages/json-schema/src/__tests__/schema.spec.ts",
    "content": "import { Schema } from '../'\nimport { isFn } from '@formily/shared'\n\ntest('has methods', () => {\n  const schema = new Schema({\n    type: 'object',\n    properties: {\n      aa: {\n        type: 'string',\n      },\n    },\n  })\n  expect(isFn(schema.setAdditionalItems)).toBeTruthy()\n  expect(isFn(schema.setAdditionalProperties)).toBeTruthy()\n  expect(isFn(schema.setItems)).toBeTruthy()\n  expect(isFn(schema.setPatternProperties)).toBeTruthy()\n  expect(isFn(schema.setProperties)).toBeTruthy()\n  expect(isFn(schema.addPatternProperty)).toBeTruthy()\n  expect(isFn(schema.addProperty)).toBeTruthy()\n  expect(isFn(schema.fromJSON)).toBeTruthy()\n  expect(isFn(schema.toJSON)).toBeTruthy()\n  expect(isFn(schema.reducePatternProperties)).toBeTruthy()\n  expect(isFn(schema.reduceProperties)).toBeTruthy()\n  expect(isFn(schema.removeProperty)).toBeTruthy()\n  expect(isFn(schema.removePatternProperty)).toBeTruthy()\n  expect(isFn(schema.mapPatternProperties)).toBeTruthy()\n  expect(isFn(schema.mapProperties)).toBeTruthy()\n\n  expect(isFn(Schema.isSchemaInstance)).toBeTruthy()\n  expect(isFn(Schema.registerCompiler)).toBeTruthy()\n  expect(isFn(Schema.registerPatches)).toBeTruthy()\n  expect(isFn(Schema.shallowCompile)).toBeTruthy()\n  expect(isFn(Schema.compile)).toBeTruthy()\n  expect(isFn(Schema.getOrderProperties)).toBeTruthy()\n})\n\ntest('all props', () => {\n  const schema = new Schema({\n    type: 'object',\n    title: 'title',\n    description: 'description',\n    patternProperties: {\n      '^[a-zA-Z0-9]*$': {\n        properties: {\n          model: { type: 'string' },\n          made: { type: 'string' },\n          year: { type: 'string' },\n        },\n      },\n    },\n    additionalProperties: {\n      type: 'string',\n    },\n    properties: {\n      string: {\n        type: 'string',\n        default: 'default',\n        required: true,\n        'x-component': 'Input',\n        'x-component-props': {\n          placeholder: 'placeholder',\n        },\n        'x-decorator': 'FormItem',\n        'x-decorator-props': {\n          labelCol: 3,\n        },\n        'x-disabled': true,\n        'x-display': 'visible',\n        'x-editable': false,\n        'x-hidden': false,\n        'x-pattern': 'readPretty',\n        'x-read-only': true,\n        'x-validator': ['phone'],\n        'x-reactions': [\n          {\n            target: 'xxx',\n            when: '{{aa > bb}}',\n          },\n        ],\n      },\n      boolean: {\n        type: 'boolean',\n        default: false,\n      },\n      number: {\n        type: 'number',\n        default: 100,\n      },\n      date: {\n        type: 'date',\n        default: '2020-12-23',\n      },\n      datetime: {\n        type: 'datetime',\n        default: '2020-12-23 23:00:00',\n      },\n      array: {\n        type: 'array',\n        items: {\n          type: 'string',\n        },\n        additionalItems: {\n          type: 'number',\n        },\n      },\n      array2: {\n        type: 'array',\n        items: [\n          {\n            type: 'string',\n          },\n          {\n            type: 'object',\n          },\n        ],\n      },\n      void: {\n        type: 'void',\n      },\n    },\n  })\n  expect(schema).toMatchSnapshot()\n})\n\ntest('all methods', () => {\n  const schema = new Schema({\n    type: 'object',\n    'x-reactions': null,\n  })\n  const schema2 = new Schema({\n    type: 'object',\n    fn: () => {},\n  } as any)\n  const schema3 = new Schema({\n    type: 'object',\n    additionalItems: null,\n    additionalProperties: null,\n    properties: null,\n  })\n  schema3.additionalItems = null\n  schema3.additionalProperties = null\n  schema3.properties = {\n    xxx: null,\n  }\n  schema3.items = [null]\n  const schema4 = new Schema({\n    type: 'object',\n    additionalItems: {},\n    additionalProperties: {},\n    properties: {},\n  })\n  schema4.additionalItems = {} as any\n  schema4.additionalProperties = {} as any\n  schema4.properties = {\n    xxx: {} as any,\n  }\n  schema4.items = [{}] as any\n  const schema5 = new Schema({\n    type: 'array',\n  })\n  schema5.items = null\n  const schema6 = new Schema({\n    type: 'array',\n  })\n  schema6.items = {} as any\n  const schema7 = new Schema({\n    type: 'array',\n    items: {\n      type: 'string',\n    },\n  })\n  const string = schema.addProperty('string', {\n    type: 'string',\n    title: 'string',\n    description: null,\n    'x-reactions': [\n      {\n        target: 'xxx',\n        when: true,\n        fulfill: {\n          schema: {},\n        },\n      },\n    ],\n  })\n\n  const array = schema.addProperty('array', {\n    type: 'string',\n    title: 'string',\n    items: [{ type: 'integer' }, { type: 'integer' }],\n  })\n  const pattern = schema.addPatternProperty('^[a-zA-Z0-9]*$', {\n    properties: {\n      model: { type: 'string', 'x-index': 2 },\n      made: { type: 'string', 'x-index': 1 },\n      year: { type: 'string', 'x-index': 0 },\n    },\n  })\n  schema.addPatternProperty('xxx', null)\n  schema.setAdditionalProperties({\n    type: 'string',\n  })\n  schema.setAdditionalProperties(null)\n  array.setItems(null)\n  array.setAdditionalItems({\n    type: 'string',\n  })\n  array.setAdditionalItems(null)\n  schema.setPatternProperties(null)\n  schema.fromJSON(null)\n  expect(schema2['fn']).toBeUndefined()\n  expect(schema.properties.string).not.toBeUndefined()\n  expect(schema.patternProperties['^[a-zA-Z0-9]*$']).not.toBeUndefined()\n  expect(schema).toMatchSnapshot()\n  expect(schema.toJSON()).toMatchSnapshot()\n  expect(pattern.mapProperties((schema, key) => key)).toEqual([\n    'year',\n    'made',\n    'model',\n  ])\n  expect(\n    pattern.reduceProperties((buf, schema, key) => buf.concat('_' + key), [])\n  ).toEqual(['_year', '_made', '_model'])\n  expect(schema.mapPatternProperties((schema, key) => key)).toEqual([\n    '^[a-zA-Z0-9]*$',\n  ])\n  expect(\n    schema.reducePatternProperties(\n      (buf, schema, key) => buf.concat('_' + key),\n      []\n    )\n  ).toEqual(['_^[a-zA-Z0-9]*$'])\n  schema5.toJSON()\n  schema6.toJSON()\n  schema7.toJSON()\n  schema.removeProperty('string')\n  expect(schema.properties.string).toBeUndefined()\n  schema.removePatternProperty('^[a-zA-Z0-9]*$')\n  expect(schema.patternProperties['^[a-zA-Z0-9]*$']).toBeUndefined()\n  expect(schema.compile()).toMatchSnapshot()\n  expect(string.compile()).toMatchSnapshot()\n  expect(schema3.toJSON()).toMatchSnapshot()\n  expect(schema4.toJSON()).toMatchSnapshot()\n})\n\ndescribe('all static methods', () => {\n  expect(Schema.compile({ aa: '{{123}}' })).toEqual({ aa: 123 })\n  expect(Schema.shallowCompile('{{123}}')).toEqual(123)\n  expect(Schema.getOrderProperties()).toEqual([])\n  Schema.registerPatches(null)\n})\n\ntest('single function x-reactions', () => {\n  const reactions = () => console.info('x-reactions')\n  const schema = new Schema({\n    type: 'string',\n    'x-reactions': reactions,\n  })\n  expect(schema.compile()['x-reactions']).toEqual(reactions)\n})\n\ntest('definitions and $ref', () => {\n  const schema = new Schema({\n    definitions: {\n      address: {\n        type: 'object',\n        properties: {\n          street_address: {\n            type: 'string',\n          },\n          city: {\n            type: 'string',\n          },\n          state: {\n            type: 'string',\n          },\n        },\n        required: ['street_address', 'city', 'state'],\n      },\n    },\n    type: 'object',\n    properties: {\n      billing_address: {\n        title: 'Billing address',\n        $ref: '#/definitions/address',\n      },\n      shipping_address: {\n        title: 'Shipping address',\n        $ref: '#/definitions/address',\n      },\n    },\n  })\n  expect(schema.properties.billing_address.required).toEqual([\n    'street_address',\n    'city',\n    'state',\n  ])\n})\n"
  },
  {
    "path": "packages/json-schema/src/__tests__/server-validate.spec.ts",
    "content": "import { createForm, Form } from '@formily/core'\nimport { ISchema, Schema, SchemaKey } from '../'\n\n// 这是schema\nconst schemaJson = {\n  type: 'object',\n  title: 'xxx配置',\n  properties: {\n    string: {\n      type: 'string',\n      title: 'string',\n      maxLength: 5,\n      required: true,\n    },\n    number: {\n      type: 'number',\n      title: 'number',\n      required: true,\n    },\n    url: {\n      type: 'string',\n      title: 'url',\n      format: 'url',\n    },\n    arr: {\n      type: 'array',\n      title: 'array',\n      maxItems: 2,\n      required: true,\n      items: {\n        type: 'object',\n        properties: {\n          string: {\n            type: 'string',\n            title: 'string',\n            required: true,\n          },\n        },\n      },\n    },\n  },\n}\n// 这是需要校验的数据\nconst schemaData = {\n  string: '123456', // 超过5个字\n  // number 字段不存在\n  url: 'xxxxx', // 不合法的url\n  arr: [\n    {\n      string: '1',\n    },\n    {\n      string: '2',\n    },\n    {\n      // 数组超出2项\n      string: '', // 没有填\n    },\n  ],\n}\n\nfunction recursiveField(\n  form: Form,\n  schema: ISchema,\n  basePath?: string,\n  name?: SchemaKey\n) {\n  const fieldSchema = new Schema(schema)\n  const fieldProps = fieldSchema.toFieldProps()\n\n  function recursiveProperties(propBasePath?: string) {\n    fieldSchema.mapProperties((propSchema, propName) => {\n      recursiveField(form, propSchema, propBasePath, propName)\n    })\n  }\n\n  if (name === undefined || name === null) {\n    recursiveProperties(basePath)\n    return\n  }\n\n  if (schema.type === 'object') {\n    const field = form.createObjectField({\n      ...fieldProps,\n      name,\n      basePath,\n    })\n\n    recursiveProperties(field.address.toString())\n  } else if (schema.type === 'array') {\n    const field = form.createArrayField({\n      ...fieldProps,\n      name,\n      basePath,\n    })\n\n    const fieldAddress = field.address.toString()\n    const fieldValues = form.getValuesIn(fieldAddress)\n    fieldValues.forEach((value: any, index: number) => {\n      if (schema.items) {\n        const itemsSchema = Array.isArray(schema.items)\n          ? schema.items[index] || schema.items[0]\n          : schema.items\n\n        recursiveField(form, itemsSchema as ISchema, fieldAddress, index)\n      }\n    })\n  } else if (schema.type === 'void') {\n    const field = form.createVoidField({\n      ...fieldProps,\n      name,\n      basePath,\n    })\n\n    recursiveProperties(field.address.toString())\n  } else {\n    form.createField({\n      ...fieldProps,\n      name,\n      basePath,\n    })\n  }\n}\ntest('server validate', async () => {\n  const form = createForm({\n    values: schemaData,\n  })\n  recursiveField(form, schemaJson)\n  let errors: any[]\n  try {\n    await form.validate()\n  } catch (e) {\n    errors = e\n  }\n  expect(errors).not.toBeUndefined()\n})\n"
  },
  {
    "path": "packages/json-schema/src/__tests__/shared.spec.ts",
    "content": "import { isNoNeedCompileObject, createDataSource } from '../shared'\nimport { observable } from '@formily/reactive'\nimport { Schema } from '../schema'\n\ntest('isNoNeedCompileObject', () => {\n  expect(isNoNeedCompileObject({})).toBeFalsy()\n  expect(isNoNeedCompileObject({ $$typeof: null, _owner: null })).toBeTruthy()\n  expect(isNoNeedCompileObject({ _isAMomentObject: true })).toBeTruthy()\n  expect(\n    isNoNeedCompileObject({ [Symbol.for('__REVA_ACTIONS')]: true })\n  ).toBeTruthy()\n  expect(isNoNeedCompileObject({ toJSON: () => {} })).toBeTruthy()\n  expect(isNoNeedCompileObject({ toJS: () => {} })).toBeTruthy()\n  expect(isNoNeedCompileObject(observable({}))).toBeTruthy()\n  expect(isNoNeedCompileObject(new Schema({}))).toBeTruthy()\n})\n\ntest('createDataSource', () => {\n  expect(createDataSource(['111'])).toEqual([{ label: '111', value: '111' }])\n  expect(createDataSource([{ label: '111', value: '111' }])).toEqual([\n    { label: '111', value: '111' },\n  ])\n})\n"
  },
  {
    "path": "packages/json-schema/src/__tests__/transformer.spec.ts",
    "content": "import { Schema } from '../schema'\nimport { createForm } from '@formily/core'\nimport { isObservable } from '@formily/reactive'\nimport { ISchema, ISchemaTransformerOptions } from '../types'\n\nconst attach = <T extends { onMount: () => void }>(target: T): T => {\n  target.onMount()\n  return target\n}\n\nconst getFormAndFields = (\n  field1SchemaProps: Omit<ISchema, 'name'> = {},\n  field2SchemaProps: Omit<ISchema, 'name'> = {},\n  options: ISchemaTransformerOptions = {}\n) => {\n  const filed1Schema = new Schema({\n    name: 'field1',\n    ...field1SchemaProps,\n  }).toFieldProps(options)\n\n  const filed2Schema = new Schema({\n    name: 'field2',\n    ...field2SchemaProps,\n  }).toFieldProps(options)\n\n  const form = createForm()\n  const field1 = form.createField(filed1Schema)\n  const field2 = form.createField(filed2Schema)\n\n  return {\n    form,\n    field1,\n    field2,\n  }\n}\n\ntest('baseReaction', () => {\n  const { field1, field2 } = getFormAndFields(\n    {\n      title: 'field1Title',\n    },\n    {\n      title: 'field2Title',\n    }\n  )\n\n  expect(field1.title).toBe('field1Title')\n  expect(field2.title).toBe('field2Title')\n})\n\ntest('baseReaction with scopes', () => {\n  const scopeTitle = 'fieldTitle'\n  const scopeDescription = 'fieldDescription'\n\n  const { field1, field2 } = getFormAndFields(\n    {\n      title: '{{scopeTitle}}',\n    },\n    {\n      description: '{{scopeDescription}}',\n    },\n    {\n      scope: {\n        scopeTitle,\n        scopeDescription,\n      },\n    }\n  )\n\n  expect(field1.title).toBe(scopeTitle)\n  expect(field2.description).toBe(scopeDescription)\n})\n\ntest('userReactions with target(state)', () => {\n  const field2Title = 'field2Title'\n  const { field2 } = getFormAndFields({\n    'x-reactions': {\n      target: 'field2',\n      fulfill: {\n        state: {\n          title: field2Title,\n        },\n      },\n    },\n  })\n\n  expect(field2.title).toBe(field2Title)\n})\n\ntest('userReactions with target(schema)', () => {\n  const field2Data = 'fieldData'\n  const { field2 } = getFormAndFields({\n    'x-reactions': {\n      target: 'field2',\n      fulfill: {\n        schema: {\n          'x-data': field2Data,\n        },\n      },\n    },\n  })\n\n  expect(field2.data).toBe(field2Data)\n})\n\ntest('userReactions with target(runner)', () => {\n  const mockFn = jest.fn()\n  const field2Title = 'field2Title'\n  const { field2 } = getFormAndFields(\n    {\n      'x-reactions': {\n        target: 'field2',\n        fulfill: {\n          run: `$target.title='${field2Title}';fn()`,\n        },\n      },\n    },\n    {},\n    {\n      scope: {\n        fn: mockFn,\n      },\n    }\n  )\n\n  expect(mockFn).toBeCalledTimes(1)\n  expect(field2.title).toBe(field2Title)\n})\n\ntest('userReactions without target(state)', () => {\n  const field1Title = 'field1Title'\n  const { field1 } = getFormAndFields({\n    'x-reactions': {\n      fulfill: {\n        state: {\n          title: field1Title,\n        },\n      },\n    },\n  })\n\n  expect(field1.title).toBe(field1Title)\n})\n\ntest('userReactions without target(schema)', () => {\n  const field1Data = 'fieldData'\n  const { field1 } = getFormAndFields({\n    'x-reactions': {\n      fulfill: {\n        schema: {\n          'x-data': field1Data,\n        },\n      },\n    },\n  })\n\n  expect(field1.data).toBe(field1Data)\n})\n\ntest('userReactions without target(runner)', () => {\n  const mockFn = jest.fn()\n  const { field1 } = getFormAndFields(\n    {\n      'x-reactions': {\n        fulfill: {\n          run: `$self.__target__=$target;fn()`,\n        },\n      },\n    },\n    {},\n    {\n      scope: {\n        fn: mockFn,\n      },\n    }\n  )\n\n  expect(mockFn).toBeCalledTimes(1)\n  expect((field1 as any).__target__).toBe(null)\n})\n\ntest('userReactions with condition', () => {\n  const mockFn = jest.fn()\n  const { field1 } = getFormAndFields(\n    {\n      'x-value': true,\n      'x-reactions': {\n        when: '$self.value===true',\n        fulfill: {\n          run: 'mockFn($self.value)',\n        },\n        otherwise: {\n          run: 'mockFn($self.value)',\n        },\n      },\n    },\n    {},\n    {\n      scope: {\n        mockFn,\n      },\n    }\n  )\n\n  expect(mockFn).nthCalledWith(1, true)\n\n  field1.value = false\n\n  expect(mockFn).nthCalledWith(2, false)\n})\n\ntest('userReactions with condition(wrong type)', () => {\n  const field1Value = 'field1Value'\n  const mockFn = jest.fn()\n  getFormAndFields(\n    {\n      'x-value': field1Value,\n      'x-reactions': {\n        dependencies: 'value',\n        fulfill: {\n          run: 'mockFn($deps, $dependencies)',\n        },\n      },\n    },\n    {},\n    {\n      scope: {\n        mockFn,\n      },\n    }\n  )\n\n  expect(mockFn).nthCalledWith(1, [], [])\n})\n\ntest('userReactions with condition(array)', () => {\n  const field1Value = 'field1Value'\n  const field2Value = 'field2Value'\n  const field1Title = 'field1Title'\n  const field1Description = 'field1Description'\n  const mockFn = jest.fn()\n\n  getFormAndFields(\n    {\n      title: field1Title,\n      description: field1Description,\n      'x-value': field1Value,\n    },\n    {\n      'x-value': field2Value,\n      'x-reactions': {\n        dependencies: [\n          'field2',\n          {\n            name: 1,\n            source: 'field1',\n          },\n          {\n            name: 2,\n            source: 'field1#title',\n          },\n          {\n            name: 3,\n            source: 'field1',\n            property: 'description',\n          },\n        ],\n        fulfill: {\n          run: `mockFn($deps)`,\n        },\n      },\n    },\n    {\n      scope: {\n        mockFn,\n      },\n    }\n  )\n\n  expect(mockFn).nthCalledWith(1, [\n    field2Value,\n    field1Value,\n    field1Title,\n    field1Description,\n  ])\n})\n\ntest('userReactions with condition(object)', () => {\n  const field2Value = 'field2Value'\n  const field1Title = 'field1Title'\n  const mockFn = jest.fn()\n\n  getFormAndFields(\n    {\n      title: field1Title,\n    },\n    {\n      'x-value': field2Value,\n      'x-reactions': {\n        dependencies: {\n          key1: 'field1#title',\n          key2: 'field2',\n        },\n        fulfill: {\n          run: `mockFn($deps)`,\n        },\n      },\n    },\n    {\n      scope: {\n        mockFn,\n      },\n    }\n  )\n\n  expect(mockFn).nthCalledWith(1, {\n    key1: field1Title,\n    key2: field2Value,\n  })\n})\n\ntest('userReactions with user-defined effects', () => {\n  const field2Value = 'field2Value'\n  const field1Title = 'field1Title'\n  const mockFn = jest.fn()\n\n  const { field2 } = getFormAndFields(\n    {\n      title: field1Title,\n      'x-reactions': {\n        target: 'field2',\n        fulfill: {\n          run: `mockFn($target.value)`,\n        },\n        effects: ['onFieldInit'],\n      },\n    },\n    {\n      'x-value': field2Value,\n    },\n    {\n      scope: {\n        mockFn,\n      },\n    }\n  )\n\n  expect(mockFn).toBeCalledTimes(1)\n  expect(mockFn).nthCalledWith(1, field2Value)\n\n  field2.value = field1Title\n  expect(mockFn).toBeCalledTimes(1)\n})\n\ntest('userReactions with function type', () => {\n  const componentProps = {\n    prop: 1,\n  }\n  let observable: any = {}\n  const { field1 } = getFormAndFields({\n    'x-reactions': (field, baseScope) => {\n      baseScope.$props(componentProps)\n      observable = baseScope.$observable({})\n    },\n  })\n\n  expect(field1.componentProps).toMatchObject(componentProps)\n  expect(isObservable(observable)).toBe(true)\n})\n\ntest('userReactions with $lookup $record $records $index', () => {\n  const initialValues = {\n    array: [\n      { a: 1, b: 2 },\n      { a: 3, b: 4 },\n    ],\n  }\n  const form = attach(\n    createForm({\n      initialValues,\n    })\n  )\n\n  form.createArrayField({\n    name: 'array',\n  })\n  form.createObjectField({\n    name: '0',\n    basePath: 'array',\n  })\n  form.createObjectField({\n    name: '1',\n    basePath: 'array',\n  })\n\n  const field0aSchema = new Schema({\n    name: 'array.0.a',\n    'x-reactions': `{{$self.title = $record.b}}`,\n  }).toFieldProps({})\n\n  const field0bSchema = new Schema({\n    name: 'array.0.b',\n    'x-reactions': '{{$self.title = $lookup.array[0].a}}',\n  }).toFieldProps({})\n\n  const field1aSchema = new Schema({\n    name: 'array.1.a',\n    'x-reactions': '{{$self.title = $records[$index].b}}',\n  }).toFieldProps({})\n\n  const field1bSchema = new Schema({\n    name: 'array.1.b',\n    'x-reactions': `{{$self.title = $record.$lookup.array[$record.$index].a}}`,\n  }).toFieldProps({})\n\n  const field0a = attach(form.createField(field0aSchema))\n  const field0b = attach(form.createField(field0bSchema))\n  const field1a = attach(form.createField(field1aSchema))\n  const field1b = attach(form.createField(field1bSchema))\n\n  expect(field0a.title).toEqual(2)\n  expect(field0b.title).toEqual(1)\n  expect(field1a.title).toEqual(4)\n  expect(field1b.title).toEqual(3)\n})\n\ntest('userReactions with primary type record', () => {\n  const initialValues = {\n    array: [1, 2, 3],\n  }\n\n  const form = attach(\n    createForm({\n      initialValues,\n    })\n  )\n\n  const field0Schema = new Schema({\n    name: 'array.0',\n    'x-reactions': `{{$self.title = $record}}`,\n  }).toFieldProps({})\n\n  const field1Schema = new Schema({\n    name: 'array.1',\n    'x-reactions': '{{$self.title = $record}}',\n  }).toFieldProps({})\n\n  form.createArrayField({\n    name: 'array',\n  })\n  const field0 = attach(form.createField(field0Schema))\n  const field1 = attach(form.createField(field1Schema))\n  expect(field0.title).toEqual(1)\n  expect(field1.title).toEqual(2)\n})\n"
  },
  {
    "path": "packages/json-schema/src/__tests__/traverse.spec.ts",
    "content": "import { traverse, traverseSchema } from '../shared'\nimport { FormPath } from '@formily/shared'\n\ntest('traverseSchema', () => {\n  const visited = []\n  const omitted = []\n  traverseSchema(\n    {\n      type: 'string',\n      title: '{{aa}}',\n      required: true,\n      'x-validator': 'phone',\n      'x-compile-omitted': ['title'],\n      default: {\n        input: 123,\n      },\n    },\n    (value, path, omitCompile) => {\n      if (omitCompile) {\n        omitted.push(value)\n      } else {\n        visited.push(path)\n      }\n    }\n  )\n  expect(visited).toEqual([\n    ['x-validator'],\n    ['type'],\n    ['required'],\n    ['default'],\n  ])\n  expect(omitted).toEqual(['{{aa}}'])\n})\n\ntest('traverse circular reference', () => {\n  // eslint-disable-next-line\n  var a = {\n    dd: {\n      mm: null,\n    },\n    bb: {\n      cc: {\n        dd: 123,\n      },\n    },\n    kk: {\n      toJS() {},\n    },\n  }\n  a.dd.mm = a\n  traverse(a, () => {})\n  traverseSchema(a as any, () => {})\n})\n\ntest('traverse none circular reference', () => {\n  // eslint-disable-next-line\n  var dd = {\n    mm: null,\n  }\n  let a = {\n    dd,\n    bb: {\n      dd,\n    },\n  }\n  const paths = []\n  traverse(a, (value, path) => {\n    paths.push(path)\n  })\n  traverseSchema(a, () => {})\n  expect(\n    paths.some((path) => FormPath.parse(path).includes('dd.mm'))\n  ).toBeTruthy()\n  expect(\n    paths.some((path) => FormPath.parse(path).includes('bb.dd.mm'))\n  ).toBeTruthy()\n})\n"
  },
  {
    "path": "packages/json-schema/src/compiler.ts",
    "content": "import {\n  isArr,\n  isFn,\n  isPlainObj,\n  isStr,\n  reduce,\n  FormPath,\n} from '@formily/shared'\nimport { IGeneralFieldState } from '@formily/core'\nimport { untracked, hasCollected } from '@formily/reactive'\nimport {\n  traverse,\n  traverseSchema,\n  isNoNeedCompileObject,\n  hasOwnProperty,\n  patchStateFormSchema,\n} from './shared'\nimport { ISchema } from './types'\n\nconst ExpRE = /^\\s*\\{\\{([\\s\\S]*)\\}\\}\\s*$/\nconst Registry = {\n  silent: false,\n  compile(expression: string, scope = {}) {\n    if (Registry.silent) {\n      try {\n        return new Function('$root', `with($root) { return (${expression}); }`)(\n          scope\n        )\n      } catch {}\n    } else {\n      return new Function('$root', `with($root) { return (${expression}); }`)(\n        scope\n      )\n    }\n  },\n}\n\nexport const silent = (value = true) => {\n  Registry.silent = !!value\n}\n\nexport const registerCompiler = (\n  compiler: (expression: string, scope: any) => any\n) => {\n  if (isFn(compiler)) {\n    Registry.compile = compiler\n  }\n}\n\nexport const shallowCompile = <Source = any, Scope = any>(\n  source: Source,\n  scope?: Scope\n) => {\n  if (isStr(source)) {\n    const matched = source.match(ExpRE)\n    if (!matched) return source\n    return Registry.compile(matched[1], scope)\n  }\n  return source\n}\n\nexport const compile = <Source = any, Scope = any>(\n  source: Source,\n  scope?: Scope\n): any => {\n  const seenObjects = []\n  const compile = (source: any) => {\n    if (isStr(source)) {\n      return shallowCompile(source, scope)\n    } else if (isArr(source)) {\n      return source.map((value: any) => compile(value))\n    } else if (isPlainObj(source)) {\n      if (isNoNeedCompileObject(source)) return source\n      const seenIndex = seenObjects.indexOf(source)\n      if (seenIndex > -1) {\n        return source\n      }\n      const addIndex = seenObjects.length\n      seenObjects.push(source)\n      const results = reduce(\n        source,\n        (buf, value, key) => {\n          buf[key] = compile(value)\n          return buf\n        },\n        {}\n      )\n      seenObjects.splice(addIndex, 1)\n      return results\n    }\n    return source\n  }\n  return compile(source)\n}\n\nexport const patchCompile = (\n  targetState: IGeneralFieldState,\n  sourceState: any,\n  scope: any\n) => {\n  traverse(sourceState, (value, pattern) => {\n    const compiled = compile(value, scope)\n    if (compiled === undefined) return\n    const path = FormPath.parse(pattern)\n    const key = path.segments[0]\n    if (hasOwnProperty.call(targetState, key)) {\n      untracked(() => FormPath.setIn(targetState, path, compiled))\n    }\n  })\n}\n\nexport const patchSchemaCompile = (\n  targetState: IGeneralFieldState,\n  sourceSchema: ISchema,\n  scope: any,\n  demand = false\n) => {\n  traverseSchema(sourceSchema, (value, path, omitCompile) => {\n    let compiled = value\n    let collected = hasCollected(() => {\n      if (!omitCompile) {\n        compiled = compile(value, scope)\n      }\n    })\n    if (compiled === undefined) return\n    if (demand) {\n      if (collected || !targetState.initialized) {\n        patchStateFormSchema(targetState, path, compiled)\n      }\n    } else {\n      patchStateFormSchema(targetState, path, compiled)\n    }\n  })\n}\n"
  },
  {
    "path": "packages/json-schema/src/global.d.ts",
    "content": "/// <reference types=\"@formily/core\" />\nimport * as Types from './types'\ndeclare global {\n  namespace Formily.Schema {\n    export { Types }\n  }\n}\n"
  },
  {
    "path": "packages/json-schema/src/index.ts",
    "content": "export * from './schema'\nexport * from './types'\n"
  },
  {
    "path": "packages/json-schema/src/patches.ts",
    "content": "import { isFn, isArr } from '@formily/shared'\nimport { SchemaPatch } from './types'\n\nconst patches: SchemaPatch[] = []\n\nconst polyfills: Record<string, SchemaPatch[]> = {}\n\nexport const reducePatches = (schema: any) => {\n  return patches.reduce(\n    (buf, patch) => {\n      return patch(buf)\n    },\n    { ...schema }\n  )\n}\n\nexport const registerPatches = (...args: SchemaPatch[]) => {\n  args.forEach((patch) => {\n    if (isFn(patch)) {\n      patches.push(patch)\n    }\n  })\n}\n\nexport const registerPolyfills = (version: string, patch: SchemaPatch) => {\n  if (version && isFn(patch)) {\n    polyfills[version] = polyfills[version] || []\n    polyfills[version].push(patch)\n  }\n}\n\nexport const enablePolyfills = (versions?: string[]) => {\n  if (isArr(versions)) {\n    versions.forEach((version) => {\n      if (isArr(polyfills[version])) {\n        polyfills[version].forEach((patch) => {\n          registerPatches(patch)\n        })\n      }\n    })\n  }\n}\n"
  },
  {
    "path": "packages/json-schema/src/polyfills/SPECIFICATION_1_0.ts",
    "content": "import { registerPolyfills } from '../patches'\nimport { toArr, isArr, isStr, lowerCase, isValid } from '@formily/shared'\nimport { ISchema } from '../types'\n\nconst VOID_COMPONENTS = [\n  'card',\n  'block',\n  'grid-col',\n  'grid-row',\n  'grid',\n  'layout',\n  'step',\n  'tab',\n  'text-box',\n]\n\nconst TYPE_DEFAULT_COMPONENTS = {}\n\nconst transformCondition = (condition: string) => {\n  if (isStr(condition)) {\n    return condition.replace(/\\$value/, '$self.value')\n  }\n}\n\nconst transformXLinkage = (linkages: any[]) => {\n  if (isArr(linkages)) {\n    return linkages.reduce((buf, item) => {\n      if (!item) return buf\n      if (item.type === 'value:visible') {\n        return buf.concat({\n          target: item.target,\n          when: transformCondition(item.condition),\n          fulfill: {\n            state: {\n              visible: true,\n            },\n          },\n          otherwise: {\n            state: {\n              visible: false,\n            },\n          },\n        })\n      } else if (item.type === 'value:schema') {\n        return buf.concat({\n          target: item.target,\n          when: transformCondition(item.condition),\n          fulfill: {\n            schema: SpecificationV1Polyfill({ version: '1.0', ...item.schema }),\n          },\n          otherwise: {\n            schema: SpecificationV1Polyfill({\n              version: '1.0',\n              ...item.otherwise,\n            }),\n          },\n        })\n      } else if (item.type === 'value:state') {\n        return buf.concat({\n          target: item.target,\n          when: transformCondition(item.condition),\n          fulfill: {\n            state: item.state,\n          },\n          otherwise: {\n            state: item.otherwise,\n          },\n        })\n      }\n    }, [])\n  }\n  return []\n}\n\nconst SpecificationV1Polyfill = (schema: ISchema) => {\n  if (isValid(schema['editable'])) {\n    schema['x-editable'] = schema['x-editable'] || schema['editable']\n    delete schema['editable']\n  }\n  if (isValid(schema['visible'])) {\n    schema['x-visible'] = schema['x-visible'] || schema['visible']\n    delete schema['visible']\n  }\n  if (isValid(schema['display'])) {\n    schema['x-display'] =\n      schema['x-display'] || (schema['display'] ? 'visible' : 'hidden')\n    delete schema['display']\n  }\n  if (isValid(schema['x-props'])) {\n    schema['x-decorator-props'] =\n      schema['x-decorator-props'] || schema['x-props']\n    delete schema['display']\n  }\n  if (schema['x-linkages']) {\n    schema['x-reactions'] = toArr(schema['x-reactions']).concat(\n      transformXLinkage(schema['x-linkages'])\n    )\n    delete schema['x-linkages']\n  }\n  if (schema['x-component']) {\n    if (\n      VOID_COMPONENTS.some(\n        (component) => lowerCase(component) === lowerCase(schema['x-component'])\n      )\n    ) {\n      schema['type'] = 'void'\n    }\n  } else {\n    if (TYPE_DEFAULT_COMPONENTS[schema['type']]) {\n      schema['x-component'] = TYPE_DEFAULT_COMPONENTS[schema['type']]\n    }\n  }\n  if (\n    !schema['x-decorator'] &&\n    schema['type'] !== 'void' &&\n    schema['type'] !== 'object'\n  ) {\n    schema['x-decorator'] = schema['x-decorator'] || 'FormItem'\n  }\n  if (schema['x-rules']) {\n    schema['x-validator'] = []\n      .concat(schema['x-validator'] || [])\n      .concat(schema['x-rules'])\n  }\n  return schema\n}\n\nregisterPolyfills('1.0', SpecificationV1Polyfill)\n\nexport const registerVoidComponents = (components: string[]) => {\n  VOID_COMPONENTS.push(...components)\n}\n\nexport const registerTypeDefaultComponents = (maps: Record<string, string>) => {\n  Object.assign(TYPE_DEFAULT_COMPONENTS, maps)\n}\n"
  },
  {
    "path": "packages/json-schema/src/polyfills/index.ts",
    "content": "export * from './SPECIFICATION_1_0'\n"
  },
  {
    "path": "packages/json-schema/src/schema.ts",
    "content": "import {\n  ISchema,\n  SchemaEnum,\n  SchemaProperties,\n  SchemaReaction,\n  SchemaTypes,\n  SchemaKey,\n  ISchemaTransformerOptions,\n  Slot,\n} from './types'\nimport { IFieldFactoryProps } from '@formily/core'\nimport { map, each, isFn, instOf, FormPath, isStr } from '@formily/shared'\nimport { compile, silent, shallowCompile, registerCompiler } from './compiler'\nimport { transformFieldProps } from './transformer'\nimport {\n  reducePatches,\n  registerPatches,\n  registerPolyfills,\n  enablePolyfills,\n} from './patches'\nimport {\n  registerVoidComponents,\n  registerTypeDefaultComponents,\n} from './polyfills'\nimport { SchemaNestedMap } from './shared'\n\nexport class Schema<\n  Decorator = any,\n  Component = any,\n  DecoratorProps = any,\n  ComponentProps = any,\n  Pattern = any,\n  Display = any,\n  Validator = any,\n  Message = any,\n  ReactionField = any\n> implements ISchema\n{\n  parent?: Schema\n  root?: Schema\n  name?: SchemaKey\n  title?: Message\n  description?: Message\n  default?: any\n  readOnly?: boolean\n  writeOnly?: boolean\n  type?: SchemaTypes\n  enum?: SchemaEnum<Message>\n  const?: any\n  multipleOf?: number\n  maximum?: number\n  exclusiveMaximum?: number\n  minimum?: number\n  exclusiveMinimum?: number\n  maxLength?: number\n  minLength?: number\n  pattern?: string | RegExp\n  maxItems?: number\n  minItems?: number\n  uniqueItems?: boolean\n  maxProperties?: number\n  minProperties?: number\n  required?: string[] | boolean | string\n  format?: string\n  /** nested json schema spec **/\n  definitions?: Record<\n    string,\n    Schema<\n      Decorator,\n      Component,\n      DecoratorProps,\n      ComponentProps,\n      Pattern,\n      Display,\n      Validator,\n      Message\n    >\n  >\n  properties?: Record<\n    string,\n    Schema<\n      Decorator,\n      Component,\n      DecoratorProps,\n      ComponentProps,\n      Pattern,\n      Display,\n      Validator,\n      Message\n    >\n  >\n  items?:\n    | Schema<\n        Decorator,\n        Component,\n        DecoratorProps,\n        ComponentProps,\n        Pattern,\n        Display,\n        Validator,\n        Message\n      >\n    | Schema<\n        Decorator,\n        Component,\n        DecoratorProps,\n        ComponentProps,\n        Pattern,\n        Display,\n        Validator,\n        Message\n      >[]\n  additionalItems?: Schema<\n    Decorator,\n    Component,\n    DecoratorProps,\n    ComponentProps,\n    Pattern,\n    Display,\n    Validator,\n    Message\n  >\n  patternProperties?: Record<\n    string,\n    Schema<\n      Decorator,\n      Component,\n      DecoratorProps,\n      ComponentProps,\n      Pattern,\n      Display,\n      Validator,\n      Message\n    >\n  >\n  additionalProperties?: Schema<\n    Decorator,\n    Component,\n    DecoratorProps,\n    ComponentProps,\n    Pattern,\n    Display,\n    Validator,\n    Message\n  >;\n\n  //顺序描述\n  ['x-index']?: number;\n  //交互模式\n  ['x-pattern']?: Pattern;\n  //展示状态\n  ['x-display']?: Display;\n  //校验器\n  ['x-validator']?: Validator;\n  //装饰器\n  ['x-decorator']?: Decorator;\n  //装饰器属性\n  ['x-decorator-props']?: DecoratorProps;\n  //组件\n  ['x-component']?: Component;\n  //组件属性\n  ['x-component-props']?: ComponentProps;\n\n  ['x-reactions']?: SchemaReaction<ReactionField>[];\n\n  ['x-content']?: any;\n\n  ['x-data']?: any;\n\n  ['x-visible']?: boolean;\n\n  ['x-hidden']?: boolean;\n\n  ['x-disabled']?: boolean;\n\n  ['x-editable']?: boolean;\n\n  ['x-read-only']?: boolean;\n\n  ['x-read-pretty']?: boolean;\n\n  ['x-compile-omitted']?: string[];\n\n  ['x-slot-node']?: Slot;\n\n  [key: `x-${string | number}` | symbol]: any\n\n  _isJSONSchemaObject = true\n\n  version = '2.0'\n\n  constructor(\n    json: ISchema<\n      Decorator,\n      Component,\n      DecoratorProps,\n      ComponentProps,\n      Pattern,\n      Display,\n      Validator,\n      Message\n    >,\n    parent?: Schema\n  ) {\n    if (parent) {\n      this.parent = parent\n      this.root = parent.root\n    } else {\n      this.root = this\n    }\n    return this.fromJSON(json)\n  }\n\n  addProperty = (\n    key: SchemaKey,\n    schema: ISchema<\n      Decorator,\n      Component,\n      DecoratorProps,\n      ComponentProps,\n      Pattern,\n      Display,\n      Validator,\n      Message\n    >\n  ) => {\n    this.properties = this.properties || {}\n    this.properties[key] = new Schema(schema, this)\n    this.properties[key].name = key\n    return this.properties[key]\n  }\n\n  removeProperty = (key: SchemaKey) => {\n    const schema = this.properties[key]\n    delete this.properties[key]\n    return schema\n  }\n\n  setProperties = (\n    properties: SchemaProperties<\n      Decorator,\n      Component,\n      DecoratorProps,\n      ComponentProps,\n      Pattern,\n      Display,\n      Validator,\n      Message\n    >\n  ) => {\n    for (const key in properties) {\n      this.addProperty(key, properties[key])\n    }\n    return this\n  }\n\n  addPatternProperty = (\n    key: SchemaKey,\n    schema: ISchema<\n      Decorator,\n      Component,\n      DecoratorProps,\n      ComponentProps,\n      Pattern,\n      Display,\n      Validator,\n      Message\n    >\n  ) => {\n    if (!schema) return\n    this.patternProperties = this.patternProperties || {}\n    this.patternProperties[key] = new Schema(schema, this)\n    this.patternProperties[key].name = key\n    return this.patternProperties[key]\n  }\n\n  removePatternProperty = (key: SchemaKey) => {\n    const schema = this.patternProperties[key]\n    delete this.patternProperties[key]\n    return schema\n  }\n\n  setPatternProperties = (\n    properties: SchemaProperties<\n      Decorator,\n      Component,\n      DecoratorProps,\n      ComponentProps,\n      Pattern,\n      Display,\n      Validator,\n      Message\n    >\n  ) => {\n    if (!properties) return this\n    for (const key in properties) {\n      this.addPatternProperty(key, properties[key])\n    }\n    return this\n  }\n\n  setAdditionalProperties = (\n    properties: ISchema<\n      Decorator,\n      Component,\n      DecoratorProps,\n      ComponentProps,\n      Pattern,\n      Display,\n      Validator,\n      Message\n    >\n  ) => {\n    if (!properties) return\n    this.additionalProperties = new Schema(properties)\n    return this.additionalProperties\n  }\n\n  setItems = (\n    schema:\n      | ISchema<\n          Decorator,\n          Component,\n          DecoratorProps,\n          ComponentProps,\n          Pattern,\n          Display,\n          Validator,\n          Message\n        >\n      | ISchema<\n          Decorator,\n          Component,\n          DecoratorProps,\n          ComponentProps,\n          Pattern,\n          Display,\n          Validator,\n          Message\n        >[]\n  ) => {\n    if (!schema) return\n    if (Array.isArray(schema)) {\n      this.items = schema.map((item) => new Schema(item, this))\n    } else {\n      this.items = new Schema(schema, this)\n    }\n    return this.items\n  }\n\n  setAdditionalItems = (\n    items: ISchema<\n      Decorator,\n      Component,\n      DecoratorProps,\n      ComponentProps,\n      Pattern,\n      Display,\n      Validator,\n      Message\n    >\n  ) => {\n    if (!items) return\n    this.additionalItems = new Schema(items, this)\n    return this.additionalItems\n  }\n\n  findDefinitions = (ref: string) => {\n    if (!ref || !this.root || !isStr(ref)) return\n    if (ref.indexOf('#/') !== 0) return\n    return FormPath.getIn(this.root, ref.substring(2).split('/'))\n  }\n\n  mapProperties = <T>(\n    callback?: (\n      schema: Schema<\n        Decorator,\n        Component,\n        DecoratorProps,\n        ComponentProps,\n        Pattern,\n        Display,\n        Validator,\n        Message\n      >,\n      key: SchemaKey,\n      index: number\n    ) => T\n  ): T[] => {\n    return Schema.getOrderProperties(this).map(({ schema, key }, index) => {\n      return callback(schema, key, index)\n    })\n  }\n\n  mapPatternProperties = <T>(\n    callback?: (\n      schema: Schema<\n        Decorator,\n        Component,\n        DecoratorProps,\n        ComponentProps,\n        Pattern,\n        Display,\n        Validator,\n        Message\n      >,\n      key: SchemaKey,\n      index: number\n    ) => T\n  ): T[] => {\n    return Schema.getOrderProperties(this, 'patternProperties').map(\n      ({ schema, key }, index) => {\n        return callback(schema, key, index)\n      }\n    )\n  }\n\n  reduceProperties = <P, R>(\n    callback?: (\n      buffer: P,\n      schema: Schema<\n        Decorator,\n        Component,\n        DecoratorProps,\n        ComponentProps,\n        Pattern,\n        Display,\n        Validator,\n        Message\n      >,\n      key: SchemaKey,\n      index: number\n    ) => R,\n    predicate?: P\n  ): R => {\n    let results: any = predicate\n    Schema.getOrderProperties(this, 'properties').forEach(\n      ({ schema, key }, index) => {\n        results = callback(results, schema, key, index)\n      }\n    )\n    return results\n  }\n\n  reducePatternProperties = <P, R>(\n    callback?: (\n      buffer: P,\n      schema: Schema<\n        Decorator,\n        Component,\n        DecoratorProps,\n        ComponentProps,\n        Pattern,\n        Display,\n        Validator,\n        Message\n      >,\n      key: SchemaKey,\n      index: number\n    ) => R,\n    predicate?: P\n  ): R => {\n    let results: any = predicate\n    Schema.getOrderProperties(this, 'patternProperties').forEach(\n      ({ schema, key }, index) => {\n        results = callback(results, schema, key, index)\n      }\n    )\n    return results\n  }\n\n  compile = (scope?: any) => {\n    const schema = new Schema({}, this.parent)\n    each(this, (value, key) => {\n      if (isFn(value) && !key.includes('x-')) return\n      if (key === 'parent' || key === 'root') return\n      if (!SchemaNestedMap[key]) {\n        schema[key] = value ? compile(value, scope) : value\n      } else {\n        schema[key] = value ? shallowCompile(value, scope) : value\n      }\n    })\n    return schema\n  }\n\n  fromJSON = (\n    json: ISchema<\n      Decorator,\n      Component,\n      DecoratorProps,\n      ComponentProps,\n      Pattern,\n      Display,\n      Validator,\n      Message\n    >\n  ) => {\n    if (!json) return this\n    if (Schema.isSchemaInstance(json)) return json\n    each(reducePatches(json), (value, key) => {\n      if (isFn(value) && !key.includes('x-')) return\n      if (key === 'properties') {\n        this.setProperties(value)\n      } else if (key === 'patternProperties') {\n        this.setPatternProperties(value)\n      } else if (key === 'additionalProperties') {\n        this.setAdditionalProperties(value)\n      } else if (key === 'items') {\n        this.setItems(value)\n      } else if (key === 'additionalItems') {\n        this.setAdditionalItems(value)\n      } else if (key === '$ref') {\n        this.fromJSON(this.findDefinitions(value))\n      } else {\n        this[key] = value\n      }\n    })\n    return this\n  }\n\n  toJSON = (\n    recursion = true\n  ): ISchema<\n    Decorator,\n    Component,\n    DecoratorProps,\n    ComponentProps,\n    Pattern,\n    Display,\n    Validator,\n    Message\n  > => {\n    const results = {}\n    each(this, (value: any, key) => {\n      if (\n        (isFn(value) && !key.includes('x-')) ||\n        key === 'parent' ||\n        key === 'root'\n      )\n        return\n      if (key === 'properties' || key === 'patternProperties') {\n        if (!recursion) return\n        results[key] = map(value, (item) => item?.toJSON?.())\n      } else if (key === 'additionalProperties' || key === 'additionalItems') {\n        if (!recursion) return\n        results[key] = value?.toJSON?.()\n      } else if (key === 'items') {\n        if (!recursion) return\n        if (Array.isArray(value)) {\n          results[key] = value.map((item) => item?.toJSON?.())\n        } else {\n          results[key] = value?.toJSON?.()\n        }\n      } else {\n        results[key] = value\n      }\n    })\n    return results\n  }\n\n  toFieldProps = (\n    options?: ISchemaTransformerOptions\n  ): IFieldFactoryProps<any, any> => {\n    return transformFieldProps(this, options)\n  }\n\n  static getOrderProperties = (\n    schema: ISchema = {},\n    propertiesName: keyof ISchema = 'properties'\n  ) => {\n    const orderProperties = []\n    const unorderProperties = []\n    for (const key in schema[propertiesName]) {\n      const item = schema[propertiesName][key]\n      const index = item['x-index']\n      if (!isNaN(index)) {\n        orderProperties[index] = { schema: item, key }\n      } else {\n        unorderProperties.push({ schema: item, key })\n      }\n    }\n    return orderProperties.concat(unorderProperties).filter((item) => !!item)\n  }\n\n  static compile = (expression: any, scope?: any) => {\n    return compile(expression, scope)\n  }\n\n  static shallowCompile = (expression: any, scope?: any) => {\n    return shallowCompile(expression, scope)\n  }\n\n  static isSchemaInstance = (value: any): value is Schema => {\n    return instOf(value, Schema)\n  }\n\n  static registerCompiler = registerCompiler\n\n  static registerPatches = registerPatches\n\n  static registerVoidComponents = registerVoidComponents\n\n  static registerTypeDefaultComponents = registerTypeDefaultComponents\n\n  static registerPolyfills = registerPolyfills\n\n  static enablePolyfills = enablePolyfills\n\n  static silent = silent\n}\n"
  },
  {
    "path": "packages/json-schema/src/shared.ts",
    "content": "import { isFn, each, isPlainObj, isArr, toArr, FormPath } from '@formily/shared'\nimport { isObservable, untracked } from '@formily/reactive'\nimport { Schema } from './schema'\nimport { ISchema } from './types'\n\nconst REVA_ACTIONS_KEY = Symbol.for('__REVA_ACTIONS')\n\nexport const SchemaNestedMap = {\n  parent: true,\n  root: true,\n  properties: true,\n  patternProperties: true,\n  additionalProperties: true,\n  items: true,\n  additionalItems: true,\n  'x-linkages': true,\n  'x-reactions': true,\n}\n\nexport const SchemaStateMap = {\n  title: 'title',\n  description: 'description',\n  default: 'initialValue',\n  enum: 'dataSource',\n  readOnly: 'readOnly',\n  writeOnly: 'editable',\n  'x-content': 'content',\n  'x-data': 'data',\n  'x-value': 'value',\n  'x-editable': 'editable',\n  'x-disabled': 'disabled',\n  'x-read-pretty': 'readPretty',\n  'x-read-only': 'readOnly',\n  'x-visible': 'visible',\n  'x-hidden': 'hidden',\n  'x-display': 'display',\n  'x-pattern': 'pattern',\n  'x-validator': 'validator',\n  'x-decorator': 'decoratorType',\n  'x-component': 'componentType',\n  'x-decorator-props': 'decoratorProps',\n  'x-component-props': 'componentProps',\n}\n\nexport const SchemaValidatorMap = {\n  required: true,\n  format: true,\n  maxItems: true,\n  minItems: true,\n  maxLength: true,\n  minLength: true,\n  maximum: true,\n  minimum: true,\n  exclusiveMaximum: true,\n  exclusiveMinimum: true,\n  pattern: true,\n  const: true,\n  multipleOf: true,\n  maxProperties: true,\n  minProperties: true,\n  uniqueItems: true,\n}\n\nexport const SchemaNormalKeys = Object.keys(SchemaStateMap)\n\nexport const SchemaValidatorKeys = Object.keys(SchemaValidatorMap)\n\nexport const hasOwnProperty = Object.prototype.hasOwnProperty\n\nexport const traverse = (\n  target: any,\n  visitor: (value: any, path: Array<string | number>) => void\n) => {\n  const seenObjects = []\n  const root = target\n  const traverse = (target: any, path = []) => {\n    if (isPlainObj(target)) {\n      const seenIndex = seenObjects.indexOf(target)\n      if (seenIndex > -1) {\n        return\n      }\n      const addIndex = seenObjects.length\n      seenObjects.push(target)\n      if (isNoNeedCompileObject(target) && root !== target) {\n        visitor(target, path)\n        return\n      }\n      each(target, (value, key) => {\n        traverse(value, path.concat(key))\n      })\n      seenObjects.splice(addIndex, 1)\n    } else {\n      visitor(target, path)\n    }\n  }\n  traverse(target)\n}\n\nexport const traverseSchema = (\n  schema: ISchema,\n  visitor: (value: any, path: any[], omitCompile?: boolean) => void\n) => {\n  if (schema['x-validator'] !== undefined) {\n    visitor(\n      schema['x-validator'],\n      ['x-validator'],\n      schema['x-compile-omitted']?.includes('x-validator')\n    )\n  }\n  const seenObjects = []\n  const root = schema\n  const traverse = (target: any, path = []) => {\n    if (\n      path[0] === 'x-compile-omitted' ||\n      path[0] === 'x-validator' ||\n      path[0] === 'version' ||\n      path[0] === '_isJSONSchemaObject'\n    )\n      return\n    if (String(path[0]).indexOf('x-') == -1 && isFn(target)) return\n    if (SchemaNestedMap[path[0]]) return\n    if (schema['x-compile-omitted']?.indexOf(path[0]) > -1) {\n      visitor(target, path, true)\n      return\n    }\n    if (isPlainObj(target)) {\n      if (path[0] === 'default' || path[0] === 'x-value') {\n        visitor(target, path)\n        return\n      }\n      const seenIndex = seenObjects.indexOf(target)\n      if (seenIndex > -1) {\n        return\n      }\n      const addIndex = seenObjects.length\n      seenObjects.push(target)\n      if (isNoNeedCompileObject(target) && root !== target) {\n        visitor(target, path)\n        return\n      }\n      each(target, (value, key) => {\n        traverse(value, path.concat(key))\n      })\n      seenObjects.splice(addIndex, 1)\n    } else {\n      visitor(target, path)\n    }\n  }\n  traverse(schema)\n}\n\nexport const isNoNeedCompileObject = (source: any) => {\n  if ('$$typeof' in source && '_owner' in source) {\n    return true\n  }\n  if (source['_isAMomentObject']) {\n    return true\n  }\n  if (Schema.isSchemaInstance(source)) {\n    return true\n  }\n  if (source[REVA_ACTIONS_KEY]) {\n    return true\n  }\n  if (isFn(source['toJS'])) {\n    return true\n  }\n  if (isFn(source['toJSON'])) {\n    return true\n  }\n  if (isObservable(source)) {\n    return true\n  }\n  return false\n}\n\nexport const createDataSource = (source: any[]) => {\n  return toArr(source).map((item) => {\n    if (typeof item === 'object') {\n      return item\n    } else {\n      return {\n        label: item,\n        value: item,\n      }\n    }\n  })\n}\n\nexport const patchStateFormSchema = (\n  targetState: any,\n  pattern: any[],\n  compiled: any\n) => {\n  untracked(() => {\n    const path = FormPath.parse(pattern)\n    const segments = path.segments\n    const key = segments[0]\n    const isEnum = key === 'enum' && isArr(compiled)\n    const schemaMapKey = SchemaStateMap[key]\n    if (schemaMapKey) {\n      FormPath.setIn(\n        targetState,\n        [schemaMapKey].concat(segments.slice(1)),\n        isEnum ? createDataSource(compiled) : compiled\n      )\n    } else {\n      const isValidatorKey = SchemaValidatorMap[key]\n      if (isValidatorKey) {\n        targetState['setValidatorRule']?.(key, compiled)\n      }\n    }\n  })\n}\n"
  },
  {
    "path": "packages/json-schema/src/transformer.ts",
    "content": "import { untracked, autorun, observable } from '@formily/reactive'\nimport {\n  isArr,\n  isStr,\n  toArr,\n  each,\n  isFn,\n  isPlainObj,\n  reduce,\n  lazyMerge,\n} from '@formily/shared'\nimport { Schema } from './schema'\nimport {\n  ISchema,\n  ISchemaTransformerOptions,\n  IFieldStateSetterOptions,\n  SchemaReaction,\n} from './types'\nimport {\n  onFieldInit,\n  onFieldMount,\n  onFieldUnmount,\n  onFieldValueChange,\n  onFieldInputValueChange,\n  onFieldInitialValueChange,\n  onFieldValidateStart,\n  onFieldValidateEnd,\n  onFieldValidateFailed,\n  onFieldValidateSuccess,\n  IFieldFactoryProps,\n  Field,\n} from '@formily/core'\nimport { patchCompile, patchSchemaCompile, shallowCompile } from './compiler'\n\nconst FieldEffects = {\n  onFieldInit,\n  onFieldMount,\n  onFieldUnmount,\n  onFieldValueChange,\n  onFieldInputValueChange,\n  onFieldInitialValueChange,\n  onFieldValidateStart,\n  onFieldValidateEnd,\n  onFieldValidateFailed,\n  onFieldValidateSuccess,\n}\n\nconst DefaultFieldEffects = ['onFieldInit', 'onFieldValueChange']\n\nconst getDependencyValue = (\n  field: Field,\n  pattern: string,\n  property?: string\n) => {\n  const [target, path] = String(pattern).split(/\\s*#\\s*/)\n  return field.query(target).getIn(path || property || 'value')\n}\n\nconst getDependencies = (\n  field: Field,\n  dependencies:\n    | Array<string | { name?: string; source?: string; property?: string }>\n    | object\n) => {\n  if (isArr(dependencies)) {\n    const results = []\n    dependencies.forEach((pattern) => {\n      if (isStr(pattern)) {\n        results.push(getDependencyValue(field, pattern))\n      } else if (isPlainObj(pattern)) {\n        if (pattern.name && pattern.source) {\n          results[pattern.name] = getDependencyValue(\n            field,\n            pattern.source,\n            pattern.property\n          )\n        }\n      }\n    })\n    return results\n  } else if (isPlainObj(dependencies)) {\n    return reduce(\n      dependencies,\n      (buf, pattern, key) => {\n        buf[key] = getDependencyValue(field, pattern)\n        return buf\n      },\n      {}\n    )\n  }\n  return []\n}\n\nconst setSchemaFieldState = (\n  options: IFieldStateSetterOptions,\n  demand = false\n) => {\n  const { request, target, runner, field, scope } = options || {}\n  if (!request) return\n  if (target) {\n    if (request.state) {\n      field.form.setFieldState(target, (state) =>\n        patchCompile(\n          state,\n          request.state,\n          lazyMerge(scope, {\n            $target: state,\n          })\n        )\n      )\n    }\n    if (request.schema) {\n      field.form.setFieldState(target, (state) =>\n        patchSchemaCompile(\n          state,\n          request.schema,\n          lazyMerge(scope, {\n            $target: state,\n          }),\n          demand\n        )\n      )\n    }\n    if (isStr(runner) && runner) {\n      field.form.setFieldState(target, (state) => {\n        shallowCompile(\n          `{{function(){${runner}}}}`,\n          lazyMerge(scope, {\n            $target: state,\n          })\n        )()\n      })\n    }\n  } else {\n    if (request.state) {\n      field.setState((state) => patchCompile(state, request.state, scope))\n    }\n    if (request.schema) {\n      field.setState((state) =>\n        patchSchemaCompile(state, request.schema, scope, demand)\n      )\n    }\n    if (isStr(runner) && runner) {\n      shallowCompile(`{{function(){${runner}}}}`, scope)()\n    }\n  }\n}\n\nconst getBaseScope = (\n  field: Field,\n  options: ISchemaTransformerOptions = {}\n) => {\n  const $observable = (target: any, deps?: any[]) =>\n    autorun.memo(() => observable(target), deps)\n  const $props = (props: any) => field.setComponentProps(props)\n  const $effect = autorun.effect\n  const $memo = autorun.memo\n  const $self = field\n  const $form = field.form\n  const $values = field.form.values\n  return lazyMerge(\n    {\n      get $lookup() {\n        return options?.scope?.$record ?? $values\n      },\n      get $records() {\n        return field.records\n      },\n      get $record() {\n        const record = field.record\n        if (typeof record === 'object') {\n          return lazyMerge(record, {\n            get $lookup() {\n              return options?.scope?.$record ?? $values\n            },\n            get $index() {\n              return field.index\n            },\n          })\n        }\n        return record\n      },\n      get $index() {\n        return field.index\n      },\n    },\n    options.scope,\n    {\n      $form,\n      $self,\n      $observable,\n      $effect,\n      $memo,\n      $props,\n      $values,\n    }\n  )\n}\n\nconst getBaseReactions =\n  (schema: ISchema, options: ISchemaTransformerOptions) => (field: Field) => {\n    setSchemaFieldState(\n      {\n        field,\n        request: { schema },\n        scope: getBaseScope(field, options),\n      },\n      true\n    )\n  }\n\nconst getUserReactions = (\n  schema: ISchema,\n  options: ISchemaTransformerOptions\n) => {\n  const reactions: SchemaReaction[] = toArr(schema['x-reactions'])\n  return reactions.map((unCompiled) => {\n    return (field: Field) => {\n      const baseScope = getBaseScope(field, options)\n      const reaction = shallowCompile(unCompiled, baseScope)\n      if (!reaction) return\n      if (isFn(reaction)) {\n        return reaction(field, baseScope)\n      }\n      const { when, fulfill, otherwise, target, effects } = reaction\n      const run = () => {\n        const $deps = getDependencies(field, reaction.dependencies)\n        const $dependencies = $deps\n        const scope = lazyMerge(baseScope, {\n          $target: null,\n          $deps,\n          $dependencies,\n        })\n        const compiledWhen = shallowCompile(when, scope)\n        const condition = when ? compiledWhen : true\n        const request = condition ? fulfill : otherwise\n        const runner = request?.run\n        setSchemaFieldState({\n          field,\n          target,\n          request,\n          runner,\n          scope,\n        })\n      }\n\n      if (target) {\n        reaction.effects = effects?.length ? effects : DefaultFieldEffects\n      }\n      if (reaction.effects) {\n        autorun.memo(() => {\n          untracked(() => {\n            each(reaction.effects, (type) => {\n              if (FieldEffects[type]) {\n                FieldEffects[type](field.address, run)\n              }\n            })\n          })\n        }, [])\n      } else {\n        run()\n      }\n    }\n  })\n}\n\nexport const transformFieldProps = (\n  schema: Schema,\n  options: ISchemaTransformerOptions\n): IFieldFactoryProps<any, any> => {\n  return {\n    name: schema.name,\n    reactions: [getBaseReactions(schema, options)].concat(\n      getUserReactions(schema, options)\n    ),\n  }\n}\n"
  },
  {
    "path": "packages/json-schema/src/types.ts",
    "content": "import {\n  IGeneralFieldState,\n  GeneralField,\n  FormPathPattern,\n} from '@formily/core'\nexport type SchemaEnum<Message> = Array<\n  | string\n  | number\n  | boolean\n  | { label?: Message; value?: any; [key: string]: any }\n  | { key?: any; title?: Message; [key: string]: any }\n>\n\nexport type SchemaTypes =\n  | 'string'\n  | 'object'\n  | 'array'\n  | 'number'\n  | 'boolean'\n  | 'void'\n  | 'date'\n  | 'datetime'\n  | (string & {})\n\nexport type SchemaProperties<\n  Decorator,\n  Component,\n  DecoratorProps,\n  ComponentProps,\n  Pattern,\n  Display,\n  Validator,\n  Message\n> = Record<\n  string,\n  ISchema<\n    Decorator,\n    Component,\n    DecoratorProps,\n    ComponentProps,\n    Pattern,\n    Display,\n    Validator,\n    Message\n  >\n>\n\nexport type SchemaPatch = (schema: ISchema) => ISchema\n\nexport type SchemaKey = string | number\n\nexport type SchemaEffectTypes =\n  | 'onFieldInit'\n  | 'onFieldMount'\n  | 'onFieldUnmount'\n  | 'onFieldValueChange'\n  | 'onFieldInputValueChange'\n  | 'onFieldInitialValueChange'\n  | 'onFieldValidateStart'\n  | 'onFieldValidateEnd'\n  | 'onFieldValidateFailed'\n  | 'onFieldValidateSuccess'\n\nexport type SchemaReaction<Field = any> =\n  | {\n      dependencies?:\n        | Array<\n            | string\n            | {\n                name?: string\n                type?: string\n                source?: string\n                property?: string\n              }\n          >\n        | Record<string, string>\n      when?: string | boolean\n      target?: string\n      effects?: (SchemaEffectTypes | (string & {}))[]\n      fulfill?: {\n        state?: Stringify<IGeneralFieldState>\n        schema?: ISchema\n        run?: string\n      }\n      otherwise?: {\n        state?: Stringify<IGeneralFieldState>\n        schema?: ISchema\n        run?: string\n      }\n      [key: string]: any\n    }\n  | ((field: Field, scope: IScopeContext) => void)\n\nexport type SchemaReactions<Field = any> =\n  | SchemaReaction<Field>\n  | SchemaReaction<Field>[]\n\nexport type SchemaItems<\n  Decorator,\n  Component,\n  DecoratorProps,\n  ComponentProps,\n  Pattern,\n  Display,\n  Validator,\n  Message\n> =\n  | ISchema<\n      Decorator,\n      Component,\n      DecoratorProps,\n      ComponentProps,\n      Pattern,\n      Display,\n      Validator,\n      Message\n    >\n  | ISchema<\n      Decorator,\n      Component,\n      DecoratorProps,\n      ComponentProps,\n      Pattern,\n      Display,\n      Validator,\n      Message\n    >[]\n\nexport type SchemaComponents = Record<string, any>\n\nexport interface ISchemaFieldUpdateRequest {\n  state?: Stringify<IGeneralFieldState>\n  schema?: ISchema\n  run?: string\n}\n\nexport interface IScopeContext {\n  [key: string]: any\n}\n\nexport interface IFieldStateSetterOptions {\n  field: GeneralField\n  target?: FormPathPattern\n  request: ISchemaFieldUpdateRequest\n  runner?: string\n  scope?: IScopeContext\n}\n\nexport interface ISchemaTransformerOptions {\n  scope?: IScopeContext\n}\n\nexport type Slot = {\n  target: string\n  isRenderProp?: boolean\n}\n\nexport type Stringify<P extends { [key: string]: any }> = {\n  /**\n   * Use `string & {}` instead of string to keep Literal Type for ISchema#component and ISchema#decorator\n   */\n  [key in keyof P]?: P[key] | (string & {})\n}\n\nexport type ISchema<\n  Decorator = any,\n  Component = any,\n  DecoratorProps = any,\n  ComponentProps = any,\n  Pattern = any,\n  Display = any,\n  Validator = any,\n  Message = any,\n  ReactionField = any\n> = Stringify<{\n  version?: string\n  name?: SchemaKey\n  title?: Message\n  description?: Message\n  default?: any\n  readOnly?: boolean\n  writeOnly?: boolean\n  type?: SchemaTypes\n  enum?: SchemaEnum<Message>\n  const?: any\n  multipleOf?: number\n  maximum?: number\n  exclusiveMaximum?: number\n  minimum?: number\n  exclusiveMinimum?: number\n  maxLength?: number\n  minLength?: number\n  pattern?: string | RegExp\n  maxItems?: number\n  minItems?: number\n  uniqueItems?: boolean\n  maxProperties?: number\n  minProperties?: number\n  required?: string[] | boolean | string\n  format?: string\n  $ref?: string\n  $namespace?: string\n  /** nested json schema spec **/\n  definitions?: SchemaProperties<\n    Decorator,\n    Component,\n    DecoratorProps,\n    ComponentProps,\n    Pattern,\n    Display,\n    Validator,\n    Message\n  >\n  properties?: SchemaProperties<\n    Decorator,\n    Component,\n    DecoratorProps,\n    ComponentProps,\n    Pattern,\n    Display,\n    Validator,\n    Message\n  >\n  items?: SchemaItems<\n    Decorator,\n    Component,\n    DecoratorProps,\n    ComponentProps,\n    Pattern,\n    Display,\n    Validator,\n    Message\n  >\n  additionalItems?: ISchema<\n    Decorator,\n    Component,\n    DecoratorProps,\n    ComponentProps,\n    Pattern,\n    Display,\n    Validator,\n    Message\n  >\n  patternProperties?: SchemaProperties<\n    Decorator,\n    Component,\n    DecoratorProps,\n    ComponentProps,\n    Pattern,\n    Display,\n    Validator,\n    Message\n  >\n  additionalProperties?: ISchema<\n    Decorator,\n    Component,\n    DecoratorProps,\n    ComponentProps,\n    Pattern,\n    Display,\n    Validator,\n    Message\n  >\n\n  ['x-value']?: any\n\n  //顺序描述\n  ['x-index']?: number\n  //交互模式\n  ['x-pattern']?: Pattern\n  //展示状态\n  ['x-display']?: Display\n  //校验器\n  ['x-validator']?: Validator\n  //装饰器\n  ['x-decorator']?: Decorator | (string & {}) | ((...args: any[]) => any)\n  //装饰器属性\n  ['x-decorator-props']?: DecoratorProps\n  //组件\n  ['x-component']?: Component | (string & {}) | ((...args: any[]) => any)\n  //组件属性\n  ['x-component-props']?: ComponentProps\n  //组件响应器\n  ['x-reactions']?: SchemaReactions<ReactionField>\n  //内容\n  ['x-content']?: any\n\n  ['x-data']?: any\n\n  ['x-visible']?: boolean\n\n  ['x-hidden']?: boolean\n\n  ['x-disabled']?: boolean\n\n  ['x-editable']?: boolean\n\n  ['x-read-only']?: boolean\n\n  ['x-read-pretty']?: boolean\n\n  ['x-compile-omitted']?: string[]\n\n  [key: `x-${string | number}` | symbol]: any\n}>\n"
  },
  {
    "path": "packages/json-schema/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*\", \"devtools/*\"]\n    },\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/json-schema/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"include\": [\"./src/**/*.ts\", \"./src/**/*.tsx\"],\n  \"exclude\": [\"./src/__tests__/*\", \"./esm/*\", \"./lib/*\"]\n}\n"
  },
  {
    "path": "packages/next/.npmignore",
    "content": "node_modules\n*.log\nbuild\ndocs\ndoc-site\n__tests__\n.eslintrc\njest.config.js\ntsconfig.json\n.umi\nsrc"
  },
  {
    "path": "packages/next/.umirc.js",
    "content": "import { resolve } from 'path'\nexport default {\n  mode: 'site',\n  logo: '//img.alicdn.com/imgextra/i2/O1CN01Kq3OHU1fph6LGqjIz_!!6000000004056-55-tps-1141-150.svg',\n  title: 'Fusion',\n  favicon:\n    '//img.alicdn.com/imgextra/i3/O1CN01XtT3Tv1Wd1b5hNVKy_!!6000000002810-55-tps-360-360.svg',\n  hash: true,\n  outputPath: './doc-site',\n  navs: {\n    'en-US': [\n      {\n        title: 'Alibaba Fusion',\n        path: '/components',\n      },\n      {\n        title: 'Home Site',\n        path: 'https://formilyjs.org',\n      },\n      {\n        title: 'GITHUB',\n        path: 'https://github.com/alibaba/formily',\n      },\n    ],\n    'zh-CN': [\n      {\n        title: 'Alibaba Fusion',\n        path: '/zh-CN/components',\n      },\n      {\n        title: '主站',\n        path: 'https://formilyjs.org',\n      },\n      {\n        title: 'GITHUB',\n        path: 'https://github.com/alibaba/formily',\n      },\n    ],\n  },\n  links: [\n    {\n      rel: 'stylesheet',\n      href: 'https://esm.sh/@alifd/next/dist/next-noreset.css',\n    },\n  ],\n  headScripts: [\n    `\n    function loadAd(){\n      var header = document.querySelector('.__dumi-default-layout-content .markdown h1')\n      if(header && !header.querySelector('#_carbonads_js')){\n        var script = document.createElement('script')\n        script.src = '//cdn.carbonads.com/carbon.js?serve=CEAICK3M&placement=formilyjsorg'\n        script.id = '_carbonads_js'\n        script.classList.add('head-ad')\n        header.appendChild(script)\n      }\n    }\n    var request = null\n    var observer = new MutationObserver(function(){\n      cancelIdleCallback(request)\n      request = requestIdleCallback(loadAd)\n    })\n    document.addEventListener('DOMContentLoaded',function(){\n      loadAd()\n      observer.observe(\n        document.body,\n        {\n          childList:true,\n          subtree:true\n        }\n      )\n    })\n    `,\n  ],\n  styles: [\n    `.__dumi-default-navbar-logo{\n      background-size: 140px!important;\n      background-position: center left!important;\n      background-repeat: no-repeat!important;\n      padding-left: 150px!important;/*可根据title的宽度调整*/\n      font-size: 22px!important;\n      color: #000!important;\n      font-weight: lighter!important;\n    }\n    .__dumi-default-navbar{\n      padding: 0 28px !important;\n    }\n    .__dumi-default-layout-hero{\n      background-image: url(//img.alicdn.com/imgextra/i4/O1CN01ZcvS4e26XMsdsCkf9_!!6000000007671-2-tps-6001-4001.png);\n      background-size: cover;\n      background-repeat: no-repeat;\n      padding: 120px 0 !important;\n    }\n    .__dumi-default-layout-hero h1{\n      color:#45124e !important;\n      font-size:80px !important;\n      padding-bottom: 30px !important;\n    }\n    .__dumi-default-dark-switch {\n      display:none\n    }\n    nav a{\n      text-decoration: none !important;\n    }\n    #carbonads * {\n      margin: initial;\n      padding: initial;\n    }\n    #carbonads {\n      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,\n        Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Helvetica, Arial,\n        sans-serif;\n    }\n    #carbonads {\n      display: flex;\n      max-width: 330px;\n      background-color: hsl(0, 0%, 98%);\n      box-shadow: 0 1px 4px 1px hsla(0, 0%, 0%, 0.1);\n      z-index: 100;\n      float:right;\n    }\n    #carbonads a {\n      color: inherit;\n      text-decoration: none;\n    }\n    #carbonads a:hover {\n      color: inherit;\n    }\n    #carbonads span {\n      position: relative;\n      display: block;\n      overflow: hidden;\n    }\n    #carbonads .carbon-wrap {\n      display: flex;\n    }\n    #carbonads .carbon-img {\n      display: block;\n      margin: 0;\n      line-height: 1;\n    }\n    #carbonads .carbon-img img {\n      display: block;\n    }\n    #carbonads .carbon-text {\n      font-size: 13px;\n      padding: 10px;\n      margin-bottom: 16px;\n      line-height: 1.5;\n      text-align: left;\n    }\n    #carbonads .carbon-poweredby {\n      display: block;\n      padding: 6px 8px;\n      background: #f1f1f2;\n      text-align: center;\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n      font-weight: 600;\n      font-size: 8px;\n      line-height: 1;\n      border-top-left-radius: 3px;\n      position: absolute;\n      bottom: 0;\n      right: 0;\n    }\n    `,\n  ],\n}\n"
  },
  {
    "path": "packages/next/LESENCE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-present, Alibaba Group Holding Limited. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "packages/next/README.md",
    "content": "# @formily/next\n\n### Install\n\n```bash\nnpm install --save @formily/next\n```\n"
  },
  {
    "path": "packages/next/__tests__/moment.spec.ts",
    "content": "import { momentable, formatMomentValue } from '../src/__builtins__/moment'\nimport moment from 'moment'\n\ntest('momentable is usable', () => {\n  expect(moment.isMoment(momentable('2021-09-08'))).toBe(true)\n  expect(\n    momentable(['2021-09-08', '2021-12-29']).every((item) =>\n      moment.isMoment(item)\n    )\n  ).toBe(true)\n  expect(momentable(0)).toBe(0)\n})\n\ntest('formatMomentValue is usable', () => {\n  expect(formatMomentValue('', 'YYYY-MM-DD', '~')).toBe('~')\n  expect(formatMomentValue('2021-12-22 15:47:00', 'YYYY-MM-DD')).toBe(\n    '2021-12-22'\n  )\n  expect(formatMomentValue('2021-12-23 15:47:00', undefined)).toBe(\n    '2021-12-23 15:47:00'\n  )\n  expect(formatMomentValue('2021-12-21 15:47:00', (date: string) => date)).toBe(\n    '2021-12-21 15:47:00'\n  )\n  expect(formatMomentValue('12:11', 'HH:mm')).toBe('12:11')\n  expect(formatMomentValue('12:11:11', 'HH:mm:ss')).toBe('12:11:11')\n  expect(formatMomentValue(['12:11'], ['HH:mm'])).toEqual(['12:11'])\n  expect(formatMomentValue(['12:11:11'], ['HH:mm:ss'])).toEqual(['12:11:11'])\n  expect(formatMomentValue(1663155911097, 'YYYY-MM-DD HH:mm:ss')).toBe(\n    moment(1663155911097).format('YYYY-MM-DD HH:mm:ss')\n  )\n  expect(formatMomentValue([1663155911097], ['YYYY-MM-DD HH:mm:ss'])).toEqual([\n    moment(1663155911097).format('YYYY-MM-DD HH:mm:ss'),\n  ])\n  expect(\n    formatMomentValue('2022-09-15T09:56:26.000Z', 'YYYY-MM-DD HH:mm:ss')\n  ).toBe(moment('2022-09-15T09:56:26.000Z').format('YYYY-MM-DD HH:mm:ss'))\n  expect(\n    formatMomentValue(['2022-09-15T09:56:26.000Z'], ['YYYY-MM-DD HH:mm:ss'])\n  ).toEqual([moment('2022-09-15T09:56:26.000Z').format('YYYY-MM-DD HH:mm:ss')])\n  expect(formatMomentValue('2022-09-15 09:56:26', 'HH:mm:ss')).toBe('09:56:26')\n  expect(formatMomentValue(['2022-09-15 09:56:26'], ['HH:mm:ss'])).toEqual([\n    '09:56:26',\n  ])\n  expect(\n    formatMomentValue(\n      ['2021-12-21 15:47:00', '2021-12-29 15:47:00'],\n      'YYYY-MM-DD'\n    )\n  ).toEqual(['2021-12-21', '2021-12-29'])\n  expect(\n    formatMomentValue(\n      ['2021-12-21 16:47:00', '2021-12-29 18:47:00'],\n      (date: string) => date\n    )\n  ).toEqual(['2021-12-21 16:47:00', '2021-12-29 18:47:00'])\n  expect(\n    formatMomentValue(\n      ['2021-12-21 16:47:00', '2021-12-29 18:47:00'],\n      ['YYYY-MM-DD', (date: string) => date]\n    )\n  ).toEqual(['2021-12-21', '2021-12-29 18:47:00'])\n  expect(\n    formatMomentValue(\n      ['2021-12-21 16:47:00', '2021-12-29 18:47:00'],\n      ['YYYY-MM-DD', undefined]\n    )\n  ).toEqual(['2021-12-21', '2021-12-29 18:47:00'])\n})\n"
  },
  {
    "path": "packages/next/__tests__/sideEffects.spec.ts",
    "content": "import SideEffectsFlagPlugin from 'webpack/lib/optimize/SideEffectsFlagPlugin'\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { sideEffects, name: baseName } = require('../package.json')\n\ntest('sideEffects should be controlled manually', () => {\n  // if config in pkg.json changed, please ensure it is covered by jest.\n  expect(sideEffects).toStrictEqual([\n    'dist/*',\n    'esm/*.js',\n    'lib/*.js',\n    'src/*.ts',\n    '*.scss',\n    '**/*/style.js',\n  ])\n})\n\ntest('dist/*', () => {\n  // eg. import \"@formily/next/dist/next.css\"\n  expect(\n    SideEffectsFlagPlugin.moduleHasSideEffects('dist/next.css', 'dist/*')\n  ).toBeTruthy()\n  expect(\n    SideEffectsFlagPlugin.moduleHasSideEffects(\n      'dist/formily.next.umd.production.js',\n      'dist/*'\n    )\n  ).toBeTruthy()\n  expect(\n    SideEffectsFlagPlugin.moduleHasSideEffects(\n      'dist/formily.next.umd.production.js',\n      'dist/*'\n    )\n  ).toBeTruthy()\n})\n\ntest('esm/*.js & lib/*.js', () => {\n  // expected to be truthy\n  // eg. import Formilynext from \"@formily/next/esm/index\"\n  expect(\n    SideEffectsFlagPlugin.moduleHasSideEffects('esm/index.js', 'esm/*.js')\n  ).toBeTruthy()\n  expect(\n    SideEffectsFlagPlugin.moduleHasSideEffects('lib/index.js', 'lib/*.js')\n  ).toBeTruthy()\n\n  // expected to be falsy\n  // eg. import Input from \"@formily/next/esm/input/index\" => will be compiled to __webpack_require__(\"./node_modules/@formily/next/esm/input/index.js\")\n  // It should be removed by webpack if not used after imported.\n  expect(\n    SideEffectsFlagPlugin.moduleHasSideEffects('esm/input/index.js', 'esm/*.js')\n  ).toBeFalsy()\n  expect(\n    SideEffectsFlagPlugin.moduleHasSideEffects(\n      'esm/array-base/index.js',\n      'esm/*.js'\n    )\n  ).toBeFalsy()\n  expect(\n    SideEffectsFlagPlugin.moduleHasSideEffects('lib/input/index.js', 'lib/*.js')\n  ).toBeFalsy()\n})\n\ntest('*.scss', () => {\n  //  eg. import \"@formily/next/lib/input/style.scss\"\n  expect(\n    SideEffectsFlagPlugin.moduleHasSideEffects(\n      `${baseName}/lib/input/style.scss`,\n      '*.scss'\n    )\n  ).toBeTruthy()\n})\n\ntest('**/*/style.js', () => {\n  // eg. import \"@formily/next/lib/input/style\" will be compiled to  __webpack_require__(\"./node_modules/@formily/next/lib/input/style.js\")\n  // so we can match the `*style.js` only, not `**/*/style*` may be cause someting mismatch like `@formily/next/lib/xxx-style/index.js`\n  const modulePathArr = [\n    'lib/input/style.js',\n    `${baseName}/lib/input/style.js`,\n    `./node_modules/${baseName}/style.js`,\n  ]\n\n  modulePathArr.forEach((modulePath) => {\n    const hasSideEffects = SideEffectsFlagPlugin.moduleHasSideEffects(\n      modulePath,\n      '**/*/style.js'\n    )\n    expect(hasSideEffects).toBeTruthy()\n  })\n})\n"
  },
  {
    "path": "packages/next/build-style.ts",
    "content": "import { build } from '../../scripts/build-style'\n\nbuild({\n  esStr: '@alifd/next/es/',\n  libStr: '@alifd/next/lib/',\n  allStylesOutputFile: 'dist/next.css',\n})\n"
  },
  {
    "path": "packages/next/create-style.ts",
    "content": "import glob from 'glob'\nimport path from 'path'\nimport fs from 'fs-extra'\n\nglob(\n  './*/main.scss',\n  { cwd: path.resolve(__dirname, './src') },\n  (err, files) => {\n    if (err) return console.error(err)\n    fs.writeFile(\n      path.resolve(__dirname, './src/style.ts'),\n      `// auto generated code\n${files\n  .map((path) => {\n    return `import '${path}'\\n`\n  })\n  .join('')}`,\n      'utf8'\n    )\n    fs.writeFile(\n      path.resolve(__dirname, './src/main.scss'),\n      `// auto generated code\n${files\n  .map((path) => {\n    return `@import '${path}';\\n`\n  })\n  .join('')}`,\n      'utf8'\n    )\n  }\n)\n"
  },
  {
    "path": "packages/next/docs/components/ArrayCards.md",
    "content": "# ArrayCards\n\n> Card list, it is more suitable to use ArrayCards for scenarios with a large number of fields in each row and more linkages\n>\n> Note: This component is only applicable to Schema scenarios\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCards,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"string_array\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCards\"\n          x-component-props={{\n            title: 'String array',\n          }}\n        >\n          <SchemaField.Void>\n            <SchemaField.Void x-component=\"ArrayCards.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCards.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCards.Copy\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveDown\" />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"ArrayCards.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"array\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCards\"\n          x-component-props={{\n            title: 'Object array',\n          }}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void x-component=\"ArrayCards.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCards.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveDown\" />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayCards.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCards,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    string_array: {\n      type: 'array',\n      'x-component': 'ArrayCards',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      'x-component-props': {\n        title: 'String array',\n      },\n      items: {\n        type: 'void',\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCards.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCards.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayCards.Addition',\n        },\n      },\n    },\n    array: {\n      type: 'array',\n      'x-component': 'ArrayCards',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      'x-component-props': {\n        title: 'Object array',\n      },\n      items: {\n        type: 'object',\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCards.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCards.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayCards.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## Effects linkage case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCards,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nconst form = createForm({\n  effects: () => {\n    //Active linkage mode\n    onFieldChange('array.*.aa', ['value'], (field, form) => {\n      form.setFieldState(field.query('.bb'), (state) => {\n        state.visible = field.value != '123'\n      })\n    })\n    //Passive linkage mode\n    onFieldReact('array.*.dd', (field) => {\n      field.visible = field.query('.cc').get('value') != '123'\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"array\"\n          maxItems={3}\n          x-component=\"ArrayCards\"\n          x-decorator=\"FormItem\"\n          x-component-props={{\n            title: 'Object array',\n          }}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void x-component=\"ArrayCards.Index\" />\n            <SchemaField.String\n              name=\"aa\"\n              x-decorator=\"FormItem\"\n              title=\"AA\"\n              required\n              description=\"AA hide BB when entering 123\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"bb\"\n              x-decorator=\"FormItem\"\n              title=\"BB\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"cc\"\n              x-decorator=\"FormItem\"\n              title=\"CC\"\n              required\n              description=\"Hide DD when CC enters 123\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"dd\"\n              x-decorator=\"FormItem\"\n              title=\"DD\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCards.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveDown\" />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayCards.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema linkage case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCards,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    array: {\n      type: 'array',\n      'x-component': 'ArrayCards',\n      maxItems: 3,\n      title: 'Object array',\n      items: {\n        type: 'object',\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCards.Index',\n          },\n          aa: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'AA',\n            required: true,\n            'x-component': 'Input',\n            description: 'Enter 123',\n          },\n          bb: {\n            type: 'string',\n            title: 'BB',\n            required: true,\n            'x-decorator': 'FormItem',\n            'x-component': 'Input',\n            'x-reactions': [\n              {\n                dependencies: ['.aa'],\n                when: \"{{$deps[0] != '123'}}\",\n                fulfill: {\n                  schema: {\n                    title: 'BB',\n                    'x-disabled': true,\n                  },\n                },\n                otherwise: {\n                  schema: {\n                    title: 'Changed',\n                    'x-disabled': false,\n                  },\n                },\n              },\n            ],\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCards.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayCards.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### ArrayCards\n\nExtended attributes\n\n| Property name | Type                      | Description     | Default value |\n| ------------- | ------------------------- | --------------- | ------------- |\n| onAdd         | `(index: number) => void` | add method      |               |\n| onRemove      | `(index: number) => void` | remove method   |               |\n| onCopy        | `(index: number) => void` | copy method     |               |\n| onMoveUp      | `(index: number) => void` | moveUp method   |               |\n| onMoveDown    | `(index: number) => void` | moveDown method |               |\n\nOther Reference https://fusion.design/pc/component/basic/card\n\n### ArrayCards.Addition\n\n> Add button\n\nExtended attributes\n\n| Property name | Type                 | Description   | Default value |\n| ------------- | -------------------- | ------------- | ------------- |\n| title         | ReactText            | Copywriting   |               |\n| method        | `'push' \\|'unshift'` | add method    | `'push'`      |\n| defaultValue  | `any`                | Default value |               |\n\nOther references https://fusion.design/pc/component/basic/button\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\n### ArrayCards.Copy\n\n> Copy button\n\nExtended attributes\n\n| Property name | Type                 | Description | Default value |\n| ------------- | -------------------- | ----------- | ------------- |\n| title         | ReactText            | Copywriting |               |\n| method        | `'push' \\|'unshift'` | add method  | `'push'`      |\n\nOther references https://fusion.design/pc/component/basic/button\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\n### ArrayCards.Remove\n\n> Delete button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\n### ArrayCards.MoveDown\n\n> Move down button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\n### ArrayCards.MoveUp\n\n> Move up button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\n### ArrayCards.Index\n\n> Index Renderer\n\nNo attributes\n\n### ArrayCards.useIndex\n\n> Read the React Hook of the current rendering row index\n\n### ArrayCards.useRecord\n\n> Read the React Hook of the current rendering row\n"
  },
  {
    "path": "packages/next/docs/components/ArrayCards.zh-CN.md",
    "content": "# ArrayCards\n\n> 卡片列表，对于每行字段数量较多，联动较多的场景比较适合使用 ArrayCards\n>\n> 注意：该组件只适用于 Schema 场景\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCards,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"string_array\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCards\"\n          x-component-props={{\n            title: '字符串数组',\n          }}\n        >\n          <SchemaField.Void>\n            <SchemaField.Void x-component=\"ArrayCards.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCards.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCards.Copy\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveDown\" />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"ArrayCards.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"array\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCards\"\n          x-component-props={{\n            title: '对象数组',\n          }}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void x-component=\"ArrayCards.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCards.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveDown\" />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayCards.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCards,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    string_array: {\n      type: 'array',\n      'x-component': 'ArrayCards',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      'x-component-props': {\n        title: '字符串数组',\n      },\n      items: {\n        type: 'void',\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCards.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCards.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayCards.Addition',\n        },\n      },\n    },\n    array: {\n      type: 'array',\n      'x-component': 'ArrayCards',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      'x-component-props': {\n        title: '对象数组',\n      },\n      items: {\n        type: 'object',\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCards.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCards.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayCards.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## Effects 联动案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCards,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nconst form = createForm({\n  effects: () => {\n    //主动联动模式\n    onFieldChange('array.*.aa', ['value'], (field, form) => {\n      form.setFieldState(field.query('.bb'), (state) => {\n        state.visible = field.value != '123'\n      })\n    })\n    //被动联动模式\n    onFieldReact('array.*.dd', (field) => {\n      field.visible = field.query('.cc').get('value') != '123'\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"array\"\n          maxItems={3}\n          x-component=\"ArrayCards\"\n          x-decorator=\"FormItem\"\n          x-component-props={{\n            title: '对象数组',\n          }}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void x-component=\"ArrayCards.Index\" />\n            <SchemaField.String\n              name=\"aa\"\n              x-decorator=\"FormItem\"\n              title=\"AA\"\n              required\n              description=\"AA输入123时隐藏BB\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"bb\"\n              x-decorator=\"FormItem\"\n              title=\"BB\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"cc\"\n              x-decorator=\"FormItem\"\n              title=\"CC\"\n              required\n              description=\"CC输入123时隐藏DD\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"dd\"\n              x-decorator=\"FormItem\"\n              title=\"DD\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCards.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCards.MoveDown\" />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayCards.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 联动案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCards,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCards,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    array: {\n      type: 'array',\n      'x-component': 'ArrayCards',\n      maxItems: 3,\n      title: '对象数组',\n      items: {\n        type: 'object',\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCards.Index',\n          },\n          aa: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'AA',\n            required: true,\n            'x-component': 'Input',\n            description: '输入123',\n          },\n          bb: {\n            type: 'string',\n            title: 'BB',\n            required: true,\n            'x-decorator': 'FormItem',\n            'x-component': 'Input',\n            'x-reactions': [\n              {\n                dependencies: ['.aa'],\n                when: \"{{$deps[0] != '123'}}\",\n                fulfill: {\n                  schema: {\n                    title: 'BB',\n                    'x-disabled': true,\n                  },\n                },\n                otherwise: {\n                  schema: {\n                    title: 'Changed',\n                    'x-disabled': false,\n                  },\n                },\n              },\n            ],\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCards.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCards.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayCards.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### ArrayCards\n\n扩展属性\n\n| 属性名     | 类型                      | 描述         | 默认值 |\n| ---------- | ------------------------- | ------------ | ------ |\n| onAdd      | `(index: number) => void` | 增加方法     |        |\n| onRemove   | `(index: number) => void` | 删除方法     |        |\n| onCopy     | `(index: number) => void` | 复制方法     |        |\n| onMoveUp   | `(index: number) => void` | 向上移动方法 |        |\n| onMoveDown | `(index: number) => void` | 向下移动方法 |        |\n\n其余参考 https://fusion.design/pc/component/basic/card\n\n### ArrayCards.Addition\n\n> 添加按钮\n\n扩展属性\n\n| 属性名       | 类型                  | 描述     | 默认值   |\n| ------------ | --------------------- | -------- | -------- |\n| title        | ReactText             | 文案     |          |\n| method       | `'push' \\| 'unshift'` | 添加方式 | `'push'` |\n| defaultValue | `any`                 | 默认值   |          |\n\n其余参考 https://fusion.design/pc/component/basic/button\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayCards.Copy\n\n> 复制按钮\n\n扩展属性\n\n| 属性名 | 类型                  | 描述     | 默认值   |\n| ------ | --------------------- | -------- | -------- |\n| title  | ReactText             | 文案     |          |\n| method | `'push' \\| 'unshift'` | 添加方式 | `'push'` |\n\n其余参考 https://fusion.design/pc/component/basic/button\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayCards.Remove\n\n> 删除按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayCards.MoveDown\n\n> 下移按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayCards.MoveUp\n\n> 上移按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayCards.Index\n\n> 索引渲染器\n\n无属性\n\n### ArrayCards.useIndex\n\n> 读取当前渲染行索引的 React Hook\n\n### ArrayCards.useRecord\n\n> 读取当前渲染记录的 React Hook\n"
  },
  {
    "path": "packages/next/docs/components/ArrayCollapse.md",
    "content": "# ArrayCollapse\n\n> Folding panel, it is more suitable to use ArrayCollapse for scenes with more fields in each row and more linkage\n>\n> Note: This component is only applicable to Schema scenarios\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCollapse,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"string_array\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCollapse\"\n          x-component-props={{\n            accordion: true,\n            defaultOpenPanelCount: 3,\n          }}\n        >\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.CollapsePanel\"\n            x-component-props={{\n              title: 'String array',\n            }}\n          >\n            <SchemaField.Void x-component=\"ArrayCollapse.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCollapse.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveDown\" />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"array\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCollapse\"\n        >\n          <SchemaField.Object\n            x-component=\"ArrayCollapse.CollapsePanel\"\n            x-component-props={{\n              title: 'Object array',\n            }}\n          >\n            <SchemaField.Void x-component=\"ArrayCollapse.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCollapse.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveDown\" />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"string_array_unshift\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCollapse\"\n          x-component-props={{\n            defaultOpenPanelCount: 8,\n          }}\n        >\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.CollapsePanel\"\n            x-component-props={{\n              title: 'String array',\n            }}\n          >\n            <SchemaField.Void x-component=\"ArrayCollapse.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCollapse.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveDown\" />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.Addition\"\n            title=\"Add entry (unshift)\"\n            x-component-props={{\n              method: 'unshift',\n            }}\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Button\n          onClick={() => {\n            form.setInitialValues({\n              array: Array.from({ length: 10 }).map(() => ({\n                input: 'default value',\n              })),\n              string_array: Array.from({ length: 10 }).map(\n                () => 'default value'\n              ),\n              string_array_unshift: Array.from({ length: 10 }).map(\n                () => 'default value'\n              ),\n            })\n          }}\n        >\n          Load default data\n        </Button>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCollapse,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    string_array: {\n      type: 'array',\n      'x-component': 'ArrayCollapse',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      items: {\n        type: 'void',\n        'x-component': 'ArrayCollapse.CollapsePanel',\n        'x-component-props': {\n          title: 'String array',\n        },\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayCollapse.Addition',\n        },\n      },\n    },\n    array: {\n      type: 'array',\n      'x-component': 'ArrayCollapse',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      items: {\n        type: 'object',\n        'x-component': 'ArrayCollapse.CollapsePanel',\n        'x-component-props': {\n          title: 'Object array',\n        },\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayCollapse.Addition',\n        },\n      },\n    },\n    array_unshift: {\n      type: 'array',\n      'x-component': 'ArrayCollapse',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      items: {\n        type: 'object',\n        'x-component': 'ArrayCollapse.CollapsePanel',\n        'x-component-props': {\n          title: 'Object array',\n        },\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add entry (unshift)',\n          'x-component': 'ArrayCollapse.Addition',\n          'x-component-props': {\n            method: 'unshift',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## Effects linkage case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCollapse,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nconst form = createForm({\n  effects: () => {\n    //Active linkage mode\n    onFieldChange('array.*.aa', ['value'], (field, form) => {\n      form.setFieldState(field.query('.bb'), (state) => {\n        state.visible = field.value != '123'\n      })\n    })\n    //Passive linkage mode\n    onFieldReact('array.*.dd', (field) => {\n      field.visible = field.query('.cc').get('value') != '123'\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"array\"\n          maxItems={3}\n          x-component=\"ArrayCollapse\"\n          x-decorator=\"FormItem\"\n          x-component-props={{\n            title: 'Object array',\n          }}\n        >\n          <SchemaField.Object\n            x-component=\"ArrayCollapse.CollapsePanel\"\n            x-component-props={{\n              title: 'Object array',\n            }}\n          >\n            <SchemaField.Void x-component=\"ArrayCollapse.Index\" />\n            <SchemaField.String\n              name=\"aa\"\n              x-decorator=\"FormItem\"\n              title=\"AA\"\n              required\n              description=\"AA hide BB when entering 123\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"bb\"\n              x-decorator=\"FormItem\"\n              title=\"BB\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"cc\"\n              x-decorator=\"FormItem\"\n              title=\"CC\"\n              required\n              description=\"Hide DD when CC enters 123\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"dd\"\n              x-decorator=\"FormItem\"\n              title=\"DD\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCollapse.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveDown\" />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema linkage case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCollapse,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    array: {\n      type: 'array',\n      'x-component': 'ArrayCollapse',\n      maxItems: 3,\n      title: 'Object array',\n      items: {\n        type: 'object',\n        'x-component': 'ArrayCollapse.CollapsePanel',\n        'x-component-props': {\n          title: 'Object array',\n        },\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Index',\n          },\n          aa: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'AA',\n            required: true,\n            'x-component': 'Input',\n            description: 'Enter 123',\n          },\n          bb: {\n            type: 'string',\n            title: 'BB',\n            required: true,\n            'x-decorator': 'FormItem',\n            'x-component': 'Input',\n            'x-reactions': [\n              {\n                dependencies: ['.aa'],\n                when: \"{{$deps[0] != '123'}}\",\n                fulfill: {\n                  schema: {\n                    title: 'BB',\n                    'x-disabled': true,\n                  },\n                },\n                otherwise: {\n                  schema: {\n                    title: 'Changed',\n                    'x-disabled': false,\n                  },\n                },\n              },\n            ],\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayCollapse.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### ArrayCollapse\n\nReference https://fusion.design/pc/component/collapse\n\nExtended attributes\n\n| Property name         | Type   | Description                  | Default value |\n| --------------------- | ------ | ---------------------------- | ------------- |\n| defaultOpenPanelCount | number | Default expanded Panel count | 5             |\n\n### ArrayCollapse.CollapsePanel\n\nReference https://fusion.design/pc/component/collapse\n\n### ArrayCollapse.Addition\n\n> Add button\n\nExtended attributes\n\n| Property name | Type                 | Description   | Default value |\n| ------------- | -------------------- | ------------- | ------------- |\n| title         | ReactText            | Copywriting   |               |\n| method        | `'push' \\|'unshift'` | add method    | `'push'`      |\n| defaultValue  | `any`                | Default value |               |\n\nOther references https://fusion.design/pc/component/basic/button\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\n### ArrayCollapse.Remove\n\n> Delete button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\n### ArrayCollapse.MoveDown\n\n> Move down button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\n### ArrayCollapse.MoveUp\n\n> Move up button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\n### ArrayCollapse.Index\n\n> Index Renderer\n\nNo attributes\n\n### ArrayCollapse.useIndex\n\n> Read the React Hook of the current rendering row index\n\n### ArrayCollapse.useRecord\n\n> Read the React Hook of the current rendering row\n"
  },
  {
    "path": "packages/next/docs/components/ArrayCollapse.zh-CN.md",
    "content": "# ArrayCollapse\n\n> 折叠面板，对于每行字段数量较多，联动较多的场景比较适合使用 ArrayCollapse\n>\n> 注意：该组件只适用于 Schema 场景\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCollapse,\n  FormButtonGroup,\n  Radio,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Radio,\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"string_array\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCollapse\"\n          x-component-props={{\n            accordion: true,\n            defaultOpenPanelCount: 3,\n          }}\n        >\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.CollapsePanel\"\n            x-component-props={{\n              title: '字符串数组',\n            }}\n          >\n            <SchemaField.Void x-component=\"ArrayCollapse.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCollapse.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveDown\" />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"array\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCollapse\"\n        >\n          <SchemaField.Object\n            x-component=\"ArrayCollapse.CollapsePanel\"\n            x-component-props={{\n              title: '对象数组',\n            }}\n          >\n            <SchemaField.Void x-component=\"ArrayCollapse.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"radio\"\n              x-decorator=\"FormItem\"\n              title=\"Radio\"\n              enum={[1, 2]}\n              required\n              x-component=\"Radio.Group\"\n            />\n            <SchemaField.Void x-component=\"ArrayCollapse.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveDown\" />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"string_array_unshift\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayCollapse\"\n          x-component-props={{\n            defaultOpenPanelCount: 8,\n          }}\n        >\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.CollapsePanel\"\n            x-component-props={{\n              title: '字符串数组',\n            }}\n          >\n            <SchemaField.Void x-component=\"ArrayCollapse.Index\" />\n            <SchemaField.String\n              name=\"input\"\n              x-decorator=\"FormItem\"\n              title=\"Input\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCollapse.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveDown\" />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.Addition\"\n            title=\"添加条目（unshift）\"\n            x-component-props={{\n              method: 'unshift',\n            }}\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Button\n          onClick={() => {\n            form.setInitialValues({\n              array: Array.from({ length: 10 }).map(() => ({\n                input: 'default value',\n              })),\n              string_array: Array.from({ length: 10 }).map(\n                () => 'default value'\n              ),\n              string_array_unshift: Array.from({ length: 10 }).map(\n                () => 'default value'\n              ),\n            })\n          }}\n        >\n          加载默认数据\n        </Button>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCollapse,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    string_array: {\n      type: 'array',\n      'x-component': 'ArrayCollapse',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      items: {\n        type: 'void',\n        'x-component': 'ArrayCollapse.CollapsePanel',\n        'x-component-props': {\n          title: '字符串数组',\n        },\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayCollapse.Addition',\n        },\n      },\n    },\n    array: {\n      type: 'array',\n      'x-component': 'ArrayCollapse',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      items: {\n        type: 'object',\n        'x-component': 'ArrayCollapse.CollapsePanel',\n        'x-component-props': {\n          title: '对象数组',\n        },\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayCollapse.Addition',\n        },\n      },\n    },\n    array_unshift: {\n      type: 'array',\n      'x-component': 'ArrayCollapse',\n      maxItems: 3,\n      'x-decorator': 'FormItem',\n      items: {\n        type: 'object',\n        'x-component': 'ArrayCollapse.CollapsePanel',\n        'x-component-props': {\n          title: '对象数组',\n        },\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Index',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'Input',\n            required: true,\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '添加条目(unshift)',\n          'x-component': 'ArrayCollapse.Addition',\n          'x-component-props': {\n            method: 'unshift',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## Effects 联动案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCollapse,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nconst form = createForm({\n  effects: () => {\n    //主动联动模式\n    onFieldChange('array.*.aa', ['value'], (field, form) => {\n      form.setFieldState(field.query('.bb'), (state) => {\n        state.visible = field.value != '123'\n      })\n    })\n    //被动联动模式\n    onFieldReact('array.*.dd', (field) => {\n      field.visible = field.query('.cc').get('value') != '123'\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"array\"\n          maxItems={3}\n          x-component=\"ArrayCollapse\"\n          x-decorator=\"FormItem\"\n          x-component-props={{\n            title: '对象数组',\n          }}\n        >\n          <SchemaField.Object\n            x-component=\"ArrayCollapse.CollapsePanel\"\n            x-component-props={{\n              title: '对象数组',\n            }}\n          >\n            <SchemaField.Void x-component=\"ArrayCollapse.Index\" />\n            <SchemaField.String\n              name=\"aa\"\n              x-decorator=\"FormItem\"\n              title=\"AA\"\n              required\n              description=\"AA输入123时隐藏BB\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"bb\"\n              x-decorator=\"FormItem\"\n              title=\"BB\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"cc\"\n              x-decorator=\"FormItem\"\n              title=\"CC\"\n              required\n              description=\"CC输入123时隐藏DD\"\n              x-component=\"Input\"\n            />\n            <SchemaField.String\n              name=\"dd\"\n              x-decorator=\"FormItem\"\n              title=\"DD\"\n              required\n              x-component=\"Input\"\n            />\n            <SchemaField.Void x-component=\"ArrayCollapse.Remove\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveUp\" />\n            <SchemaField.Void x-component=\"ArrayCollapse.MoveDown\" />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayCollapse.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 联动案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayCollapse,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    ArrayCollapse,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    array: {\n      type: 'array',\n      'x-component': 'ArrayCollapse',\n      maxItems: 3,\n      title: '对象数组',\n      items: {\n        type: 'object',\n        'x-component': 'ArrayCollapse.CollapsePanel',\n        'x-component-props': {\n          title: '对象数组',\n        },\n        properties: {\n          index: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Index',\n          },\n          aa: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            title: 'AA',\n            required: true,\n            'x-component': 'Input',\n            description: '输入123',\n          },\n          bb: {\n            type: 'string',\n            title: 'BB',\n            required: true,\n            'x-decorator': 'FormItem',\n            'x-component': 'Input',\n            'x-reactions': [\n              {\n                dependencies: ['.aa'],\n                when: \"{{$deps[0] != '123'}}\",\n                fulfill: {\n                  schema: {\n                    title: 'BB',\n                    'x-disabled': true,\n                  },\n                },\n                otherwise: {\n                  schema: {\n                    title: 'Changed',\n                    'x-disabled': false,\n                  },\n                },\n              },\n            ],\n          },\n          remove: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.Remove',\n          },\n          moveUp: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveUp',\n          },\n          moveDown: {\n            type: 'void',\n            'x-component': 'ArrayCollapse.MoveDown',\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayCollapse.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### ArrayCollapse\n\n参考 https://fusion.design/pc/component/collapse\n\n扩展属性\n\n| 属性名                | 类型   | 描述                | 默认值 |\n| --------------------- | ------ | ------------------- | ------ |\n| defaultOpenPanelCount | number | 默认展开 Panel 数量 | 5      |\n\n### ArrayCollapse.CollapsePanel\n\n参考 https://fusion.design/pc/component/collapse\n\n### ArrayCollapse.Addition\n\n> 添加按钮\n\n扩展属性\n\n| 属性名       | 类型                  | 描述     | 默认值   |\n| ------------ | --------------------- | -------- | -------- |\n| title        | ReactText             | 文案     |          |\n| method       | `'push' \\| 'unshift'` | 添加方式 | `'push'` |\n| defaultValue | `any`                 | 默认值   |          |\n\n其余参考 https://fusion.design/pc/component/basic/button\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayCollapse.Remove\n\n> 删除按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayCollapse.MoveDown\n\n> 下移按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayCollapse.MoveUp\n\n> 上移按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayCollapse.Index\n\n> 索引渲染器\n\n无属性\n\n### ArrayCollapse.useIndex\n\n> 读取当前渲染行索引的 React Hook\n\n### ArrayCollapse.useRecord\n\n> 读取当前渲染记录的 React Hook\n"
  },
  {
    "path": "packages/next/docs/components/ArrayItems.md",
    "content": "# ArrayItems\n\n> Self-increment list, suitable for simple self-increment editing scenes, or for scenes with high space requirements\n>\n> Note: This component is only applicable to Schema scenarios\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  Editable,\n  Select,\n  DatePicker,\n  ArrayItems,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    DatePicker,\n    Editable,\n    Space,\n    Input,\n    Select,\n    ArrayItems,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"string_array\"\n          title=\"string array\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayItems\"\n        >\n          <SchemaField.Void x-component=\"Space\">\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.SortHandle\"\n            />\n            <SchemaField.String\n              x-decorator=\"FormItem\"\n              required\n              name=\"input\"\n              x-component=\"Input\"\n            />\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.Remove\"\n            />\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.Copy\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"ArrayItems.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"array\"\n          title=\"Object array\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayItems\"\n        >\n          <SchemaField.Object>\n            <SchemaField.Void x-component=\"Space\">\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.SortHandle\"\n              />\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"date\"\n                name=\"date\"\n                x-component=\"DatePicker.RangePicker\"\n                x-component-props={{\n                  style: {\n                    width: 160,\n                  },\n                }}\n              />\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"input box\"\n                name=\"input\"\n                x-component=\"Input\"\n              />\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"select box\"\n                name=\"select\"\n                enum={[\n                  { label: 'Option 1', value: 1 },\n                  { label: 'Option 2', value: 2 },\n                ]}\n                x-component=\"Select\"\n                x-component-props={{\n                  style: {\n                    width: 160,\n                  },\n                }}\n              />\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.Remove\"\n              />\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.Copy\"\n              />\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayItems.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"array2\"\n          title=\"Object array\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayItems\"\n          x-component-props={{ style: { width: 300 } }}\n        >\n          <SchemaField.Object x-decorator=\"ArrayItems.Item\">\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.SortHandle\"\n            />\n            <SchemaField.String\n              x-decorator=\"Editable\"\n              title=\"input box\"\n              name=\"input\"\n              x-component=\"Input\"\n            />\n            <SchemaField.Object\n              name=\"config\"\n              x-component=\"Editable.Popover\"\n              required\n              title=\"Configure complex data\"\n              x-reactions={(field) =>\n                (field.title = field.value?.input || field.title)\n              }\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"date\"\n                name=\"date\"\n                x-component=\"DatePicker.RangePicker\"\n                x-component-props={{\n                  style: { width: '100%' },\n                  followTrigger: true,\n                }}\n              />\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"input box\"\n                name=\"input\"\n                x-component=\"Input\"\n              />\n            </SchemaField.Object>\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.Remove\"\n            />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayItems.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Editable,\n  Input,\n  Select,\n  Radio,\n  DatePicker,\n  ArrayItems,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Editable,\n    DatePicker,\n    Space,\n    Radio,\n    Input,\n    Select,\n    ArrayItems,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    string_array: {\n      type: 'array',\n      'x-component': 'ArrayItems',\n      'x-decorator': 'FormItem',\n      title: 'String array',\n      items: {\n        type: 'void',\n        'x-component': 'Space',\n        properties: {\n          sort: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.SortHandle',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.Remove',\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n    array: {\n      type: 'array',\n      'x-component': 'ArrayItems',\n      'x-decorator': 'FormItem',\n      title: 'Object array',\n      items: {\n        type: 'object',\n        properties: {\n          space: {\n            type: 'void',\n            'x-component': 'Space',\n            properties: {\n              sort: {\n                type: 'void',\n                'x-decorator': 'FormItem',\n                'x-component': 'ArrayItems.SortHandle',\n              },\n              date: {\n                type: 'string',\n                title: 'Date',\n                'x-decorator': 'FormItem',\n                'x-component': 'DatePicker.RangePicker',\n                'x-component-props': {\n                  style: {\n                    width: 160,\n                  },\n                },\n              },\n              input: {\n                type: 'string',\n                title: 'input box',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n              select: {\n                type: 'string',\n                title: 'drop-down box',\n                enum: [\n                  { label: 'Option 1', value: 1 },\n                  { label: 'Option 2', value: 2 },\n                ],\n                'x-decorator': 'FormItem',\n                'x-component': 'Select',\n                'x-component-props': {\n                  style: {\n                    width: 160,\n                  },\n                },\n              },\n              remove: {\n                type: 'void',\n                'x-decorator': 'FormItem',\n                'x-component': 'ArrayItems.Remove',\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n    array2: {\n      type: 'array',\n      'x-component': 'ArrayItems',\n      'x-decorator': 'FormItem',\n      'x-component-props': { style: { width: 300 } },\n      title: 'Object array',\n      items: {\n        type: 'object',\n        'x-decorator': 'ArrayItems.Item',\n        properties: {\n          sort: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.SortHandle',\n          },\n\n          input: {\n            type: 'string',\n            title: 'input box',\n            'x-decorator': 'Editable',\n            'x-component': 'Input',\n          },\n          config: {\n            type: 'object',\n            title: 'Configure complex data',\n            'x-component': 'Editable.Popover',\n            'x-reactions':\n              '{{(field)=>field.title = field.value && field.value.input || field.title}}',\n            properties: {\n              date: {\n                type: 'string',\n                title: 'Date',\n                'x-decorator': 'FormItem',\n                'x-component': 'DatePicker.RangePicker',\n                'x-component-props': {\n                  style: {\n                    width: 160,\n                  },\n                  followTrigger: true,\n                },\n              },\n              input: {\n                type: 'string',\n                title: 'input box',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n              select: {\n                type: 'string',\n                title: 'drop-down box',\n                enum: [\n                  { label: 'Option 1', value: 1 },\n                  { label: 'Option 2', value: 2 },\n                ],\n                'x-decorator': 'FormItem',\n                'x-component': 'Select',\n                'x-component-props': {\n                  style: {\n                    width: 160,\n                  },\n                },\n              },\n            },\n          },\n          remove: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.Remove',\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## Effects linkage case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayItems,\n  Editable,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/next'\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Space,\n    Editable,\n    FormItem,\n    Input,\n    ArrayItems,\n  },\n})\n\nconst form = createForm({\n  effects: () => {\n    //Active linkage mode\n    onFieldChange('array.*.aa', ['value'], (field, form) => {\n      form.setFieldState(field.query('.bb'), (state) => {\n        state.visible = field.value != '123'\n      })\n    })\n    //Passive linkage mode\n    onFieldReact('array.*.dd', (field) => {\n      field.visible = field.query('.cc').get('value') != '123'\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"array\"\n          title=\"Object array\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayItems\"\n          x-component-props={{\n            style: {\n              width: 300,\n            },\n          }}\n        >\n          <SchemaField.Object x-decorator=\"ArrayItems.Item\">\n            <SchemaField.Void x-component=\"Space\">\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.SortHandle\"\n              />\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.Index\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"Editable.Popover\"\n              title=\"Configuration data\"\n            >\n              <SchemaField.String\n                name=\"aa\"\n                x-decorator=\"FormItem\"\n                title=\"AA\"\n                required\n                description=\"AA hide BB when entering 123\"\n                x-component=\"Input\"\n              />\n              <SchemaField.String\n                name=\"bb\"\n                x-decorator=\"FormItem\"\n                title=\"BB\"\n                required\n                x-component=\"Input\"\n              />\n              <SchemaField.String\n                name=\"cc\"\n                x-decorator=\"FormItem\"\n                title=\"CC\"\n                required\n                description=\"Hide DD when CC enters 123\"\n                x-component=\"Input\"\n              />\n              <SchemaField.String\n                name=\"dd\"\n                x-decorator=\"FormItem\"\n                title=\"DD\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void x-component=\"Space\">\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.Remove\"\n              />\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.MoveUp\"\n              />\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.MoveDown\"\n              />\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayItems.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema linkage case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayItems,\n  Editable,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Space,\n    Editable,\n    FormItem,\n    Input,\n    ArrayItems,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    array: {\n      type: 'array',\n      'x-component': 'ArrayItems',\n      'x-decorator': 'FormItem',\n      maxItems: 3,\n      title: 'Object array',\n      'x-component-props': { style: { width: 300 } },\n      items: {\n        type: 'object',\n        'x-decorator': 'ArrayItems.Item',\n        properties: {\n          left: {\n            type: 'void',\n            'x-component': 'Space',\n            properties: {\n              sort: {\n                type: 'void',\n                'x-decorator': 'FormItem',\n                'x-component': 'ArrayItems.SortHandle',\n              },\n              index: {\n                type: 'void',\n                'x-decorator': 'FormItem',\n                'x-component': 'ArrayItems.Index',\n              },\n            },\n          },\n          edit: {\n            type: 'void',\n            'x-component': 'Editable.Popover',\n            title: 'Configuration data',\n            properties: {\n              aa: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                title: 'AA',\n                required: true,\n                'x-component': 'Input',\n                description: 'Enter 123',\n              },\n              bb: {\n                type: 'string',\n                title: 'BB',\n                required: true,\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-reactions': [\n                  {\n                    dependencies: ['.aa'],\n                    when: \"{{$deps[0] != '123'}}\",\n                    fulfill: {\n                      schema: {\n                        title: 'BB',\n                        'x-disabled': true,\n                      },\n                    },\n                    otherwise: {\n                      schema: {\n                        title: 'Changed',\n                        'x-disabled': false,\n                      },\n                    },\n                  },\n                ],\n              },\n            },\n          },\n          right: {\n            type: 'void',\n            'x-component': 'Space',\n            properties: {\n              remove: {\n                type: 'void',\n                'x-component': 'ArrayItems.Remove',\n              },\n              moveUp: {\n                type: 'void',\n                'x-component': 'ArrayItems.MoveUp',\n              },\n              moveDown: {\n                type: 'void',\n                'x-component': 'ArrayItems.MoveDown',\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: 'Add entry',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### ArrayItems\n\nExtended attributes\n\n| Property name | Type                      | Description     | Default value |\n| ------------- | ------------------------- | --------------- | ------------- |\n| onAdd         | `(index: number) => void` | add method      |               |\n| onRemove      | `(index: number) => void` | remove method   |               |\n| onCopy        | `(index: number) => void` | copy method     |               |\n| onMoveUp      | `(index: number) => void` | moveUp method   |               |\n| onMoveDown    | `(index: number) => void` | moveDown method |               |\n\nOther Inherit HTMLDivElement Props\n\n### ArrayItems.Item\n\n> List block\n\nInherit HTMLDivElement Props\n\nExtended attributes\n\n| Property name | Type                | Description           | Default value |\n| ------------- | ------------------- | --------------------- | ------------- |\n| type          | `'card' \\|'divide'` | card or dividing line |               |\n\n### ArrayItems.SortHandle\n\n> Drag handle\n\nReference https://ant.design/components/icon-cn/\n\n### ArrayItems.Addition\n\n> Add button\n\nExtended attributes\n\n| Property name | Type                 | Description   | Default value |\n| ------------- | -------------------- | ------------- | ------------- |\n| title         | ReactText            | Copywriting   |               |\n| method        | `'push' \\|'unshift'` | add method    | `'push'`      |\n| defaultValue  | `any`                | Default value |               |\n\nOther references https://fusion.design/pc/component/basic/button\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\n### ArrayItems.Copy\n\n> Copy button\n\nExtended attributes\n\n| Property name | Type                 | Description | Default value |\n| ------------- | -------------------- | ----------- | ------------- |\n| title         | ReactText            | Copywriting |               |\n| method        | `'push' \\|'unshift'` | add method  | `'push'`      |\n\nOther references https://fusion.design/pc/component/basic/button\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\n### ArrayItems.Remove\n\n> Delete button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\n### ArrayItems.MoveDown\n\n> Move down button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\n### ArrayItems.MoveUp\n\n> Move up button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\n### ArrayItems.Index\n\n> Index Renderer\n\nNo attributes\n\n### ArrayItems.useIndex\n\n> Read the React Hook of the current rendering row index\n\n### ArrayItems.useRecord\n\n> Read the React Hook of the current rendering row\n"
  },
  {
    "path": "packages/next/docs/components/ArrayItems.zh-CN.md",
    "content": "# ArrayItems\n\n> 自增列表，对于简单的自增编辑场景比较适合，或者对于空间要求高的场景比较适合\n>\n> 注意：该组件只适用于 Schema 场景\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  Editable,\n  Select,\n  DatePicker,\n  ArrayItems,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    DatePicker,\n    Editable,\n    Space,\n    Input,\n    Select,\n    ArrayItems,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"string_array\"\n          title=\"字符串数组\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayItems\"\n        >\n          <SchemaField.Void x-component=\"Space\">\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.SortHandle\"\n            />\n            <SchemaField.String\n              x-decorator=\"FormItem\"\n              required\n              name=\"input\"\n              x-component=\"Input\"\n            />\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.Remove\"\n            />\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.Copy\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"ArrayItems.Addition\"\n            x-component-props={{ method: 'unshift' }}\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"array\"\n          title=\"对象数组\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayItems\"\n        >\n          <SchemaField.Object>\n            <SchemaField.Void x-component=\"Space\">\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.SortHandle\"\n              />\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"日期\"\n                name=\"date\"\n                x-component=\"DatePicker.RangePicker\"\n                x-component-props={{\n                  style: {\n                    width: 160,\n                  },\n                }}\n              />\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"输入框\"\n                name=\"input\"\n                x-component=\"Input\"\n              />\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"选择框\"\n                name=\"select\"\n                enum={[\n                  { label: '选项1', value: 1 },\n                  { label: '选项2', value: 2 },\n                ]}\n                x-component=\"Select\"\n                x-component-props={{\n                  style: {\n                    width: 160,\n                  },\n                }}\n              />\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.Remove\"\n              />\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayItems.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n        <SchemaField.Array\n          name=\"array2\"\n          title=\"对象数组\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayItems\"\n          x-component-props={{ style: { width: 300 } }}\n        >\n          <SchemaField.Object x-decorator=\"ArrayItems.Item\">\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.SortHandle\"\n            />\n            <SchemaField.String\n              x-decorator=\"Editable\"\n              title=\"输入框\"\n              name=\"input\"\n              x-component=\"Input\"\n            />\n            <SchemaField.Object\n              name=\"config\"\n              x-component=\"Editable.Popover\"\n              required\n              title=\"配置复杂数据\"\n              x-reactions={(field) =>\n                (field.title = field.value?.input || field.title)\n              }\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"日期\"\n                name=\"date\"\n                x-component=\"DatePicker.RangePicker\"\n                x-component-props={{\n                  style: { width: '100%' },\n                  followTrigger: true,\n                }}\n              />\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                title=\"输入框\"\n                name=\"input\"\n                x-component=\"Input\"\n              />\n            </SchemaField.Object>\n            <SchemaField.Void\n              x-decorator=\"FormItem\"\n              x-component=\"ArrayItems.Remove\"\n            />\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayItems.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Editable,\n  Input,\n  Select,\n  Radio,\n  DatePicker,\n  ArrayItems,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Editable,\n    DatePicker,\n    Space,\n    Radio,\n    Input,\n    Select,\n    ArrayItems,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    string_array: {\n      type: 'array',\n      'x-component': 'ArrayItems',\n      'x-decorator': 'FormItem',\n      title: '字符串数组',\n      items: {\n        type: 'void',\n        'x-component': 'Space',\n        properties: {\n          sort: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.SortHandle',\n          },\n          input: {\n            type: 'string',\n            'x-decorator': 'FormItem',\n            'x-component': 'Input',\n          },\n          remove: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.Remove',\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n    array: {\n      type: 'array',\n      'x-component': 'ArrayItems',\n      'x-decorator': 'FormItem',\n      title: '对象数组',\n      items: {\n        type: 'object',\n        properties: {\n          space: {\n            type: 'void',\n            'x-component': 'Space',\n            properties: {\n              sort: {\n                type: 'void',\n                'x-decorator': 'FormItem',\n                'x-component': 'ArrayItems.SortHandle',\n              },\n              date: {\n                type: 'string',\n                title: '日期',\n                'x-decorator': 'FormItem',\n                'x-component': 'DatePicker.RangePicker',\n                'x-component-props': {\n                  style: {\n                    width: 160,\n                  },\n                },\n              },\n              input: {\n                type: 'string',\n                title: '输入框',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n              select: {\n                type: 'string',\n                title: '下拉框',\n                enum: [\n                  { label: '选项1', value: 1 },\n                  { label: '选项2', value: 2 },\n                ],\n                'x-decorator': 'FormItem',\n                'x-component': 'Select',\n                'x-component-props': {\n                  style: {\n                    width: 160,\n                  },\n                },\n              },\n              remove: {\n                type: 'void',\n                'x-decorator': 'FormItem',\n                'x-component': 'ArrayItems.Remove',\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n    array2: {\n      type: 'array',\n      'x-component': 'ArrayItems',\n      'x-decorator': 'FormItem',\n      'x-component-props': { style: { width: 300 } },\n      title: '对象数组',\n      items: {\n        type: 'object',\n        'x-decorator': 'ArrayItems.Item',\n        properties: {\n          sort: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.SortHandle',\n          },\n\n          input: {\n            type: 'string',\n            title: '输入框',\n            'x-decorator': 'Editable',\n            'x-component': 'Input',\n          },\n          config: {\n            type: 'object',\n            title: '配置复杂数据',\n            'x-component': 'Editable.Popover',\n            'x-reactions':\n              '{{(field)=>field.title = field.value && field.value.input || field.title}}',\n            properties: {\n              date: {\n                type: 'string',\n                title: '日期',\n                'x-decorator': 'FormItem',\n                'x-component': 'DatePicker.RangePicker',\n                'x-component-props': {\n                  style: {\n                    width: 160,\n                  },\n                  followTrigger: true,\n                },\n              },\n              input: {\n                type: 'string',\n                title: '输入框',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n              select: {\n                type: 'string',\n                title: '下拉框',\n                enum: [\n                  { label: '选项1', value: 1 },\n                  { label: '选项2', value: 2 },\n                ],\n                'x-decorator': 'FormItem',\n                'x-component': 'Select',\n                'x-component-props': {\n                  style: {\n                    width: 160,\n                  },\n                },\n              },\n            },\n          },\n          remove: {\n            type: 'void',\n            'x-decorator': 'FormItem',\n            'x-component': 'ArrayItems.Remove',\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## Effects 联动案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayItems,\n  Editable,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/next'\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Space,\n    Editable,\n    FormItem,\n    Input,\n    ArrayItems,\n  },\n})\n\nconst form = createForm({\n  effects: () => {\n    //主动联动模式\n    onFieldChange('array.*.aa', ['value'], (field, form) => {\n      form.setFieldState(field.query('.bb'), (state) => {\n        state.visible = field.value != '123'\n      })\n    })\n    //被动联动模式\n    onFieldReact('array.*.dd', (field) => {\n      field.visible = field.query('.cc').get('value') != '123'\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"array\"\n          title=\"对象数组\"\n          maxItems={3}\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayItems\"\n          x-component-props={{\n            style: {\n              width: 300,\n            },\n          }}\n        >\n          <SchemaField.Object x-decorator=\"ArrayItems.Item\">\n            <SchemaField.Void x-component=\"Space\">\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.SortHandle\"\n              />\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.Index\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void x-component=\"Editable.Popover\" title=\"配置数据\">\n              <SchemaField.String\n                name=\"aa\"\n                x-decorator=\"FormItem\"\n                title=\"AA\"\n                required\n                description=\"AA输入123时隐藏BB\"\n                x-component=\"Input\"\n              />\n              <SchemaField.String\n                name=\"bb\"\n                x-decorator=\"FormItem\"\n                title=\"BB\"\n                required\n                x-component=\"Input\"\n              />\n              <SchemaField.String\n                name=\"cc\"\n                x-decorator=\"FormItem\"\n                title=\"CC\"\n                required\n                description=\"CC输入123时隐藏DD\"\n                x-component=\"Input\"\n              />\n              <SchemaField.String\n                name=\"dd\"\n                x-decorator=\"FormItem\"\n                title=\"DD\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void x-component=\"Space\">\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.Remove\"\n              />\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.MoveUp\"\n              />\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                x-component=\"ArrayItems.MoveDown\"\n              />\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayItems.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 联动案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayItems,\n  Editable,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Space,\n    Editable,\n    FormItem,\n    Input,\n    ArrayItems,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    array: {\n      type: 'array',\n      'x-component': 'ArrayItems',\n      'x-decorator': 'FormItem',\n      maxItems: 3,\n      title: '对象数组',\n      'x-component-props': { style: { width: 300 } },\n      items: {\n        type: 'object',\n        'x-decorator': 'ArrayItems.Item',\n        properties: {\n          left: {\n            type: 'void',\n            'x-component': 'Space',\n            properties: {\n              sort: {\n                type: 'void',\n                'x-decorator': 'FormItem',\n                'x-component': 'ArrayItems.SortHandle',\n              },\n              index: {\n                type: 'void',\n                'x-decorator': 'FormItem',\n                'x-component': 'ArrayItems.Index',\n              },\n            },\n          },\n          edit: {\n            type: 'void',\n            'x-component': 'Editable.Popover',\n            title: '配置数据',\n            properties: {\n              aa: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                title: 'AA',\n                required: true,\n                'x-component': 'Input',\n                description: '输入123',\n              },\n              bb: {\n                type: 'string',\n                title: 'BB',\n                required: true,\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                'x-reactions': [\n                  {\n                    dependencies: ['.aa'],\n                    when: \"{{$deps[0] != '123'}}\",\n                    fulfill: {\n                      schema: {\n                        title: 'BB',\n                        'x-disabled': true,\n                      },\n                    },\n                    otherwise: {\n                      schema: {\n                        title: 'Changed',\n                        'x-disabled': false,\n                      },\n                    },\n                  },\n                ],\n              },\n            },\n          },\n          right: {\n            type: 'void',\n            'x-component': 'Space',\n            properties: {\n              remove: {\n                type: 'void',\n                'x-component': 'ArrayItems.Remove',\n              },\n              moveUp: {\n                type: 'void',\n                'x-component': 'ArrayItems.MoveUp',\n              },\n              moveDown: {\n                type: 'void',\n                'x-component': 'ArrayItems.MoveDown',\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        addition: {\n          type: 'void',\n          title: '添加条目',\n          'x-component': 'ArrayItems.Addition',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### ArrayItems\n\n扩展属性\n\n| 属性名     | 类型                      | 描述         | 默认值 |\n| ---------- | ------------------------- | ------------ | ------ |\n| onAdd      | `(index: number) => void` | 增加方法     |        |\n| onRemove   | `(index: number) => void` | 删除方法     |        |\n| onCopy     | `(index: number) => void` | 复制方法     |        |\n| onMoveUp   | `(index: number) => void` | 向上移动方法 |        |\n| onMoveDown | `(index: number) => void` | 向下移动方法 |        |\n\n其余继承 HTMLDivElement Props\n\n### ArrayItems.Item\n\n> 列表区块\n\n继承 HTMLDivElement Props\n\n扩展属性\n\n| 属性名 | 类型                 | 描述           | 默认值 |\n| ------ | -------------------- | -------------- | ------ |\n| type   | `'card' \\| 'divide'` | 卡片或者分割线 |        |\n\n### ArrayItems.SortHandle\n\n> 拖拽手柄\n\n参考 https://ant.design/components/icon-cn/\n\n### ArrayItems.Addition\n\n> 添加按钮\n\n扩展属性\n\n| 属性名       | 类型                  | 描述     | 默认值   |\n| ------------ | --------------------- | -------- | -------- |\n| title        | ReactText             | 文案     |          |\n| method       | `'push' \\| 'unshift'` | 添加方式 | `'push'` |\n| defaultValue | `any`                 | 默认值   |          |\n\n其余参考 https://fusion.design/pc/component/basic/button\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayItems.Copy\n\n> 复制按钮\n\n扩展属性\n\n| 属性名 | 类型                  | 描述     | 默认值   |\n| ------ | --------------------- | -------- | -------- |\n| title  | ReactText             | 文案     |          |\n| method | `'push' \\| 'unshift'` | 添加方式 | `'push'` |\n\n其余参考 https://fusion.design/pc/component/basic/button\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayItems.Remove\n\n> 删除按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayItems.MoveDown\n\n> 下移按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayItems.MoveUp\n\n> 上移按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayItems.Index\n\n> 索引渲染器\n\n无属性\n\n### ArrayItems.useIndex\n\n> 读取当前渲染行索引的 React Hook\n\n### ArrayItems.useRecord\n\n> 读取当前渲染记录的 React Hook\n"
  },
  {
    "path": "packages/next/docs/components/ArrayTable.md",
    "content": "# ArrayTable\n\n> Self-increasing table, it is more suitable to use this component for scenes with a large amount of data. Although the amount of data is large to a certain extent, it will be a little bit stuck, but it will not affect the basic operation\n>\n> Note: This component is only applicable to Schema scenarios and can only be an array of objects\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  Editable,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button, Message } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Editable,\n    Input,\n    ArrayTable,\n  },\n})\n\nconst form = createForm()\n\nconst range = (count: number) =>\n  Array.from(new Array(count)).map((_, key) => ({\n    aaa: key,\n  }))\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"array\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayTable\"\n          x-component-props={{\n            pagination: { pageSize: 10 },\n            style: { width: '100%' },\n          }}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ width: 80, title: 'Sort', align: 'center' }}\n            >\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"ArrayTable.SortHandle\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{\n                width: 120,\n                title: 'Index',\n                align: 'center',\n              }}\n            >\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"ArrayTable.Index\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'A1', dataIndex: 'a1', width: 200 }}\n            >\n              <SchemaField.String\n                name=\"a1\"\n                x-decorator=\"Editable\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'A2', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a2\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'A3', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a3\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{\n                title: 'Operations',\n                dataIndex: 'operations',\n                width: 200,\n                fixed: 'right',\n              }}\n            >\n              <SchemaField.Void x-component=\"FormItem\">\n                <SchemaField.Void x-component=\"ArrayTable.Remove\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveDown\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveUp\" />\n              </SchemaField.Void>\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayTable.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n        <Button\n          onClick={() => {\n            form.setInitialValues({\n              array: range(100000),\n            })\n          }}\n        >\n          Load 10W pieces of large data\n        </Button>\n      </FormButtonGroup>\n      <Message style={{ marginTop: 10 }} type=\"warning\">\n        Note: Open the formily plug-in page, because there is data communication\n        in the background, which will occupy the browser's computing power, it\n        is best to test in the incognito mode (without the formily plug-in)\n      </Message>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  Editable,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Editable,\n    Input,\n    ArrayTable,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    array: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'ArrayTable',\n      'x-component-props': {\n        pagination: { pageSize: 10 },\n        style: { width: '100%' },\n      },\n      items: {\n        type: 'object',\n        properties: {\n          column1: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 80, title: 'Sort', align: 'center' },\n            properties: {\n              sort: {\n                type: 'void',\n                'x-component': 'ArrayTable.SortHandle',\n              },\n            },\n          },\n          column2: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              width: 120,\n              title: 'Index',\n              align: 'center',\n            },\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayTable.Index',\n              },\n            },\n          },\n          column3: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A1' },\n            properties: {\n              a1: {\n                type: 'string',\n                'x-decorator': 'Editable',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column4: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A2' },\n            properties: {\n              a2: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column5: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A3' },\n            properties: {\n              a3: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column6: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              title: 'Operations',\n              dataIndex: 'operations',\n              width: 200,\n              fixed: 'right',\n            },\n            properties: {\n              item: {\n                type: 'void',\n                'x-component': 'FormItem',\n                properties: {\n                  remove: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.Remove',\n                  },\n                  moveDown: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveDown',\n                  },\n                  moveUp: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveUp',\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          'x-component': 'ArrayTable.Addition',\n          title: 'Add entry',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## Effects linkage case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  Switch,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Switch,\n    Input,\n    Button,\n    ArrayTable,\n  },\n})\n\nconst form = createForm({\n  effects: () => {\n    //Active linkage mode\n    onFieldChange('hideFirstColumn', ['value'], (field) => {\n      field.query('array.column4').take((target) => {\n        target.visible = !field.value\n      })\n      field.query('array.*.a2').take((target) => {\n        target.visible = !field.value\n      })\n    })\n    //Passive linkage mode\n    onFieldReact('array.*.a2', (field) => {\n      field.visible = !field.query('.a1').get('value')\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Boolean\n          name=\"hideFirstColumn\"\n          x-decorator=\"FormItem\"\n          x-component=\"Switch\"\n          title=\"Hide A2\"\n        />\n        <SchemaField.Array\n          name=\"array\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayTable\"\n          x-component-props={{\n            pagination: { pageSize: 10 },\n            style: { width: '100%' },\n          }}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column1\"\n              x-component-props={{ width: 80, title: 'Sort', align: 'center' }}\n            >\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"ArrayTable.SortHandle\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column2\"\n              x-component-props={{\n                width: 120,\n                title: 'Index',\n                align: 'center',\n              }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"ArrayTable.Index\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column3\"\n              x-component-props={{\n                title: 'Explicitly hidden->A2',\n                dataIndex: 'a1',\n                width: 100,\n              }}\n            >\n              <SchemaField.Boolean\n                name=\"a1\"\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"Switch\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column4\"\n              x-component-props={{ title: 'A2', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a2\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column5\"\n              x-component-props={{ title: 'A3', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a3\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column6\"\n              x-component-props={{\n                title: 'Operations',\n                dataIndex: 'operations',\n                width: 200,\n                fixed: 'right',\n              }}\n            >\n              <SchemaField.Void x-component=\"FormItem\">\n                <SchemaField.Void x-component=\"ArrayTable.Remove\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveDown\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveUp\" />\n              </SchemaField.Void>\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayTable.Addition\"\n            title=\"Add entry\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema linkage case\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  Switch,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Switch,\n    Input,\n    ArrayTable,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    hideFirstColumn: {\n      type: 'boolean',\n      title: 'Hide A2',\n      'x-decorator': 'FormItem',\n      'x-component': 'Switch',\n    },\n    array: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'ArrayTable',\n      'x-component-props': {\n        pagination: { pageSize: 10 },\n        style: { width: '100%' },\n      },\n      items: {\n        type: 'object',\n        properties: {\n          column1: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 80, title: 'Sort', align: 'center' },\n\n            properties: {\n              sort: {\n                type: 'void',\n                'x-component': 'ArrayTable.SortHandle',\n              },\n            },\n          },\n          column2: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              width: 120,\n              title: 'Index',\n              align: 'center',\n            },\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayTable.Index',\n              },\n            },\n          },\n          column3: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 100, title: 'Explicitly hidden->A2' },\n            properties: {\n              a1: {\n                type: 'boolean',\n                'x-decorator': 'FormItem',\n                'x-component': 'Switch',\n              },\n            },\n          },\n          column4: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A2' },\n            'x-reactions': [\n              {\n                dependencies: ['hideFirstColumn'],\n                when: '{{$deps[0]}}',\n                fulfill: {\n                  schema: {\n                    'x-visible': false,\n                  },\n                },\n                otherwise: {\n                  schema: {\n                    'x-visible': true,\n                  },\n                },\n              },\n            ],\n            properties: {\n              a2: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                required: true,\n                'x-reactions': [\n                  {\n                    dependencies: ['.a1', 'hideFirstColumn'],\n                    when: '{{$deps[1] || $deps[0]}}',\n                    fulfill: {\n                      schema: {\n                        'x-visible': false,\n                      },\n                    },\n                    otherwise: {\n                      schema: {\n                        'x-visible': true,\n                      },\n                    },\n                  },\n                ],\n              },\n            },\n          },\n          column5: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A3' },\n            properties: {\n              a3: {\n                type: 'string',\n                required: true,\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column6: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              title: 'Operations',\n              dataIndex: 'operations',\n              width: 200,\n              fixed: 'right',\n            },\n            properties: {\n              item: {\n                type: 'void',\n                'x-component': 'FormItem',\n                properties: {\n                  remove: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.Remove',\n                  },\n                  moveDown: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveDown',\n                  },\n                  moveUp: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveUp',\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          'x-component': 'ArrayTable.Addition',\n          title: 'Add entry',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### ArrayTable\n\n> Form Components\n\nExtended attributes\n\n| Property name | Type                      | Description     | Default value |\n| ------------- | ------------------------- | --------------- | ------------- |\n| onAdd         | `(index: number) => void` | add method      |               |\n| onRemove      | `(index: number) => void` | remove method   |               |\n| onCopy        | `(index: number) => void` | copy method     |               |\n| onMoveUp      | `(index: number) => void` | moveUp method   |               |\n| onMoveDown    | `(index: number) => void` | moveDown method |               |\n\nOther Reference https://fusion.design/pc/component/basic/table\n\n### ArrayTable.Column\n\n> Table Column\n\nReference https://fusion.design/pc/component/basic/table\n\n### ArrayTable.SortHandle\n\n> Drag handle\n\nReference https://ant.design/components/icon-cn/\n\n### ArrayTable.Addition\n\n> Add button\n\nExtended attributes\n\n| Property name | Type                 | Description   | Default value |\n| ------------- | -------------------- | ------------- | ------------- |\n| title         | ReactText            | Copywriting   |               |\n| method        | `'push' \\|'unshift'` | add method    | `'push'`      |\n| defaultValue  | `any`                | Default value |               |\n\nOther references https://fusion.design/pc/component/basic/button\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\n### ArrayTable.Remove\n\n> Delete button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\n### ArrayTable.MoveDown\n\n> Move down button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\n### ArrayTable.MoveUp\n\n> Move up button\n\n| Property name | Type      | Description | Default value |\n| ------------- | --------- | ----------- | ------------- |\n| title         | ReactText | Copywriting |               |\n\nOther references https://ant.design/components/icon-cn/\n\nNote: The title attribute can receive the title mapping in the Field model, that is, uploading the title in the Field is also effective\n\n### ArrayTable.Index\n\n> Index Renderer\n\nNo attributes\n\n### ArrayTable.useIndex\n\n> Read the React Hook of the current rendering row index\n\n### ArrayTable.useRecord\n\n> Read the React Hook of the current rendering row\n"
  },
  {
    "path": "packages/next/docs/components/ArrayTable.zh-CN.md",
    "content": "# ArrayTable\n\n> 自增表格，对于数据量超大的场景比较适合使用该组件，虽然数据量大到一定程度会有些许卡顿，但是不会影响基本操作\n>\n> 注意：该组件只适用于 Schema 场景，且只能是对象数组\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  Editable,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button, Message } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Editable,\n    Input,\n    ArrayTable,\n  },\n})\n\nconst form = createForm()\n\nconst range = (count: number) =>\n  Array.from(new Array(count)).map((_, key) => ({\n    aaa: key,\n  }))\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"array\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayTable\"\n          x-component-props={{\n            pagination: { pageSize: 10 },\n            style: { width: '100%' },\n          }}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ width: 80, title: 'Sort', align: 'center' }}\n            >\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"ArrayTable.SortHandle\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{\n                width: 120,\n                title: 'Index',\n                align: 'center',\n              }}\n            >\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"ArrayTable.Index\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'A1', dataIndex: 'a1', width: 200 }}\n            >\n              <SchemaField.String\n                name=\"a1\"\n                x-decorator=\"Editable\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'A2', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a2\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{ title: 'A3', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a3\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              x-component-props={{\n                title: 'Operations',\n                dataIndex: 'operations',\n                width: 200,\n                fixed: 'right',\n              }}\n            >\n              <SchemaField.Void x-component=\"FormItem\">\n                <SchemaField.Void x-component=\"ArrayTable.Remove\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveDown\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveUp\" />\n              </SchemaField.Void>\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayTable.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n        <Button\n          onClick={() => {\n            form.setInitialValues({\n              array: range(100000),\n            })\n          }}\n        >\n          加载10W条超大数据\n        </Button>\n      </FormButtonGroup>\n      <Message style={{ marginTop: 10 }} type=\"warning\">\n        注意：开启formily插件的页面，因为后台有数据通信，会占用浏览器算力，最好在无痕模式(无formily插件)下测试\n      </Message>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  Editable,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Editable,\n    Input,\n    ArrayTable,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    array: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'ArrayTable',\n      'x-component-props': {\n        pagination: { pageSize: 10 },\n        style: { width: '100%' },\n      },\n      items: {\n        type: 'object',\n        properties: {\n          column1: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 80, title: 'Sort', align: 'center' },\n            properties: {\n              sort: {\n                type: 'void',\n                'x-component': 'ArrayTable.SortHandle',\n              },\n            },\n          },\n          column2: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              width: 120,\n              title: 'Index',\n              align: 'center',\n            },\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayTable.Index',\n              },\n            },\n          },\n          column3: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A1' },\n            properties: {\n              a1: {\n                type: 'string',\n                'x-decorator': 'Editable',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column4: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A2' },\n            properties: {\n              a2: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column5: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A3' },\n            properties: {\n              a3: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column6: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              title: 'Operations',\n              dataIndex: 'operations',\n              width: 200,\n              fixed: 'right',\n            },\n            properties: {\n              item: {\n                type: 'void',\n                'x-component': 'FormItem',\n                properties: {\n                  remove: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.Remove',\n                  },\n                  moveDown: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveDown',\n                  },\n                  moveUp: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveUp',\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          'x-component': 'ArrayTable.Addition',\n          title: '添加条目',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## Effects 联动案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  Switch,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm, onFieldChange, onFieldReact } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Switch,\n    Input,\n    Button,\n    ArrayTable,\n  },\n})\n\nconst form = createForm({\n  effects: () => {\n    //主动联动模式\n    onFieldChange('hideFirstColumn', ['value'], (field) => {\n      field.query('array.column4').take((target) => {\n        target.visible = !field.value\n      })\n      field.query('array.*.a2').take((target) => {\n        target.visible = !field.value\n      })\n    })\n    //被动联动模式\n    onFieldReact('array.*.a2', (field) => {\n      field.visible = !field.query('.a1').get('value')\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Boolean\n          name=\"hideFirstColumn\"\n          x-decorator=\"FormItem\"\n          x-component=\"Switch\"\n          title=\"隐藏A2\"\n        />\n        <SchemaField.Array\n          name=\"array\"\n          x-decorator=\"FormItem\"\n          x-component=\"ArrayTable\"\n          x-component-props={{\n            pagination: { pageSize: 10 },\n            style: { width: '100%' },\n          }}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column1\"\n              x-component-props={{ width: 80, title: 'Sort', align: 'center' }}\n            >\n              <SchemaField.Void\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"ArrayTable.SortHandle\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column2\"\n              x-component-props={{\n                width: 120,\n                title: 'Index',\n                align: 'center',\n              }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"ArrayTable.Index\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column3\"\n              x-component-props={{\n                title: '显隐->A2',\n                dataIndex: 'a1',\n                width: 100,\n              }}\n            >\n              <SchemaField.Boolean\n                name=\"a1\"\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"Switch\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column4\"\n              x-component-props={{ title: 'A2', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a2\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column5\"\n              x-component-props={{ title: 'A3', width: 200 }}\n            >\n              <SchemaField.String\n                x-decorator=\"FormItem\"\n                name=\"a3\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              x-component=\"ArrayTable.Column\"\n              name=\"column6\"\n              x-component-props={{\n                title: 'Operations',\n                dataIndex: 'operations',\n                width: 200,\n                fixed: 'right',\n              }}\n            >\n              <SchemaField.Void x-component=\"FormItem\">\n                <SchemaField.Void x-component=\"ArrayTable.Remove\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveDown\" />\n                <SchemaField.Void x-component=\"ArrayTable.MoveUp\" />\n              </SchemaField.Void>\n            </SchemaField.Void>\n          </SchemaField.Object>\n          <SchemaField.Void\n            x-component=\"ArrayTable.Addition\"\n            title=\"添加条目\"\n          />\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 联动案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormItem,\n  Input,\n  ArrayTable,\n  Switch,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Switch,\n    Input,\n    ArrayTable,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    hideFirstColumn: {\n      type: 'boolean',\n      title: '隐藏A2',\n      'x-decorator': 'FormItem',\n      'x-component': 'Switch',\n    },\n    array: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'ArrayTable',\n      'x-component-props': {\n        pagination: { pageSize: 10 },\n        style: { width: '100%' },\n      },\n      items: {\n        type: 'object',\n        properties: {\n          column1: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 80, title: 'Sort', align: 'center' },\n\n            properties: {\n              sort: {\n                type: 'void',\n                'x-component': 'ArrayTable.SortHandle',\n              },\n            },\n          },\n          column2: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              width: 120,\n              title: 'Index',\n              align: 'center',\n            },\n            properties: {\n              index: {\n                type: 'void',\n                'x-component': 'ArrayTable.Index',\n              },\n            },\n          },\n          column3: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 100, title: '显隐->A2' },\n            properties: {\n              a1: {\n                type: 'boolean',\n                'x-decorator': 'FormItem',\n                'x-component': 'Switch',\n              },\n            },\n          },\n          column4: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A2' },\n            'x-reactions': [\n              {\n                dependencies: ['hideFirstColumn'],\n                when: '{{$deps[0]}}',\n                fulfill: {\n                  schema: {\n                    'x-visible': false,\n                  },\n                },\n                otherwise: {\n                  schema: {\n                    'x-visible': true,\n                  },\n                },\n              },\n            ],\n            properties: {\n              a2: {\n                type: 'string',\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n                required: true,\n                'x-reactions': [\n                  {\n                    dependencies: ['.a1', 'hideFirstColumn'],\n                    when: '{{$deps[1] || $deps[0]}}',\n                    fulfill: {\n                      schema: {\n                        'x-visible': false,\n                      },\n                    },\n                    otherwise: {\n                      schema: {\n                        'x-visible': true,\n                      },\n                    },\n                  },\n                ],\n              },\n            },\n          },\n          column5: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': { width: 200, title: 'A3' },\n            properties: {\n              a3: {\n                type: 'string',\n                required: true,\n                'x-decorator': 'FormItem',\n                'x-component': 'Input',\n              },\n            },\n          },\n          column6: {\n            type: 'void',\n            'x-component': 'ArrayTable.Column',\n            'x-component-props': {\n              title: 'Operations',\n              dataIndex: 'operations',\n              width: 200,\n              fixed: 'right',\n            },\n            properties: {\n              item: {\n                type: 'void',\n                'x-component': 'FormItem',\n                properties: {\n                  remove: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.Remove',\n                  },\n                  moveDown: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveDown',\n                  },\n                  moveUp: {\n                    type: 'void',\n                    'x-component': 'ArrayTable.MoveUp',\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n      properties: {\n        add: {\n          type: 'void',\n          'x-component': 'ArrayTable.Addition',\n          title: '添加条目',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### ArrayTable\n\n> 表格组件\n\n扩展属性\n\n| 属性名     | 类型                      | 描述         | 默认值 |\n| ---------- | ------------------------- | ------------ | ------ |\n| onAdd      | `(index: number) => void` | 增加方法     |        |\n| onRemove   | `(index: number) => void` | 删除方法     |        |\n| onCopy     | `(index: number) => void` | 复制方法     |        |\n| onMoveUp   | `(index: number) => void` | 向上移动方法 |        |\n| onMoveDown | `(index: number) => void` | 向下移动方法 |        |\n\n其余参考 https://fusion.design/pc/component/basic/table\n\n### ArrayTable.Column\n\n> 表格列\n\n参考 https://fusion.design/pc/component/basic/table\n\n### ArrayTable.SortHandle\n\n> 拖拽手柄\n\n参考 https://ant.design/components/icon-cn/\n\n### ArrayTable.Addition\n\n> 添加按钮\n\n扩展属性\n\n| 属性名       | 类型                  | 描述     | 默认值   |\n| ------------ | --------------------- | -------- | -------- |\n| title        | ReactText             | 文案     |          |\n| method       | `'push' \\| 'unshift'` | 添加方式 | `'push'` |\n| defaultValue | `any`                 | 默认值   |          |\n\n其余参考 https://fusion.design/pc/component/basic/button\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayTable.Remove\n\n> 删除按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayTable.MoveDown\n\n> 下移按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayTable.MoveUp\n\n> 上移按钮\n\n| 属性名 | 类型      | 描述 | 默认值 |\n| ------ | --------- | ---- | ------ |\n| title  | ReactText | 文案 |        |\n\n其余参考 https://ant.design/components/icon-cn/\n\n注意：title 属性可以接收 Field 模型中的 title 映射，也就是在 Field 上传 title 也是生效的\n\n### ArrayTable.Index\n\n> 索引渲染器\n\n无属性\n\n### ArrayTable.useIndex\n\n> 读取当前渲染行索引的 React Hook\n\n### ArrayTable.useRecord\n\n> 读取当前渲染记录的 React Hook\n"
  },
  {
    "path": "packages/next/docs/components/Cascader.md",
    "content": "# Cascader\n\n> Cascade selector\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm, onFieldReact, FormPathPattern } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Cascader,\n    FormItem,\n  },\n})\n\nconst useAddress = (pattern: FormPathPattern) => {\n  const transform = (data = {}) => {\n    return Object.entries(data).reduce((buf, [key, value]) => {\n      if (typeof value === 'string')\n        return buf.concat({\n          label: value,\n          value: key,\n        })\n      const { name, code, cities, districts } = value\n      const _cities = transform(cities)\n      const _districts = transform(districts)\n      return buf.concat({\n        label: name,\n        value: code,\n        children: _cities.length\n          ? _cities\n          : _districts.length\n          ? _districts\n          : undefined,\n      })\n    }, [])\n  }\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    fetch('//unpkg.com/china-location/dist/location.json')\n      .then((res) => res.json())\n      .then(\n        action.bound((data) => {\n          field.dataSource = transform(data)\n          field.loading = false\n        })\n      )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAddress('address')\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"address\"\n        title=\"Address Selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"Cascader\"\n        x-component-props={{\n          style: {\n            width: 240,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Cascader,\n    FormItem,\n  },\n})\n\nconst transformAddress = (data = {}) => {\n  return Object.entries(data).reduce((buf, [key, value]) => {\n    if (typeof value === 'string')\n      return buf.concat({\n        label: value,\n        value: key,\n      })\n    const { name, code, cities, districts } = value\n    const _cities = transformAddress(cities)\n    const _districts = transformAddress(districts)\n    return buf.concat({\n      label: name,\n      value: code,\n      children: _cities.length\n        ? _cities\n        : _districts.length\n        ? _districts\n        : undefined,\n    })\n  }, [])\n}\n\nconst useAsyncDataSource =\n  (url: string, transform: (data: any) => any) => (field) => {\n    field.loading = true\n    fetch(url)\n      .then((res) => res.json())\n      .then(\n        action.bound((data) => {\n          field.dataSource = transform(data)\n          field.loading = false\n        })\n      )\n  }\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    address: {\n      type: 'string',\n      title: 'Address Selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'Cascader',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n      'x-reactions': [\n        '{{useAsyncDataSource(\"//unpkg.com/china-location/dist/location.json\",transformAddress)}}',\n      ],\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField\n      schema={schema}\n      scope={{ useAsyncDataSource, transformAddress }}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm, onFieldReact, FormPathPattern } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst useAddress = (pattern: FormPathPattern) => {\n  const transform = (data = {}) => {\n    return Object.entries(data).reduce((buf, [key, value]) => {\n      if (typeof value === 'string')\n        return buf.concat({\n          label: value,\n          value: key,\n        })\n      const { name, code, cities, districts } = value\n      const _cities = transform(cities)\n      const _districts = transform(districts)\n      return buf.concat({\n        label: name,\n        value: code,\n        children: _cities.length\n          ? _cities\n          : _districts.length\n          ? _districts\n          : undefined,\n      })\n    }, [])\n  }\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    fetch('//unpkg.com/china-location/dist/location.json')\n      .then((res) => res.json())\n      .then(\n        action.bound((data) => {\n          field.dataSource = transform(data)\n          field.loading = false\n        })\n      )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAddress('address')\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"address\"\n      title=\"Address Selection\"\n      decorator={[FormItem]}\n      component={[\n        Cascader,\n        {\n          style: {\n            width: 240,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://fusion.design/pc/component/basic/cascader-select\n"
  },
  {
    "path": "packages/next/docs/components/Cascader.zh-CN.md",
    "content": "# Cascader\n\n> 联级选择器\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm, onFieldReact, FormPathPattern } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Cascader,\n    FormItem,\n  },\n})\n\nconst useAddress = (pattern: FormPathPattern) => {\n  const transform = (data = {}) => {\n    return Object.entries(data).reduce((buf, [key, value]) => {\n      if (typeof value === 'string')\n        return buf.concat({\n          label: value,\n          value: key,\n        })\n      const { name, code, cities, districts } = value\n      const _cities = transform(cities)\n      const _districts = transform(districts)\n      return buf.concat({\n        label: name,\n        value: code,\n        children: _cities.length\n          ? _cities\n          : _districts.length\n          ? _districts\n          : undefined,\n      })\n    }, [])\n  }\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    fetch('//unpkg.com/china-location/dist/location.json')\n      .then((res) => res.json())\n      .then(\n        action.bound((data) => {\n          field.dataSource = transform(data)\n          field.loading = false\n        })\n      )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAddress('address')\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"address\"\n        title=\"地址选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"Cascader\"\n        x-component-props={{\n          style: {\n            width: 240,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Cascader,\n    FormItem,\n  },\n})\n\nconst transformAddress = (data = {}) => {\n  return Object.entries(data).reduce((buf, [key, value]) => {\n    if (typeof value === 'string')\n      return buf.concat({\n        label: value,\n        value: key,\n      })\n    const { name, code, cities, districts } = value\n    const _cities = transformAddress(cities)\n    const _districts = transformAddress(districts)\n    return buf.concat({\n      label: name,\n      value: code,\n      children: _cities.length\n        ? _cities\n        : _districts.length\n        ? _districts\n        : undefined,\n    })\n  }, [])\n}\n\nconst useAsyncDataSource =\n  (url: string, transform: (data: any) => any) => (field) => {\n    field.loading = true\n    fetch(url)\n      .then((res) => res.json())\n      .then(\n        action.bound((data) => {\n          field.dataSource = transform(data)\n          field.loading = false\n        })\n      )\n  }\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    address: {\n      type: 'string',\n      title: '地址选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'Cascader',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n      'x-reactions': [\n        '{{useAsyncDataSource(\"//unpkg.com/china-location/dist/location.json\",transformAddress)}}',\n      ],\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField\n      schema={schema}\n      scope={{ useAsyncDataSource, transformAddress }}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { Cascader, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm, onFieldReact, FormPathPattern } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst useAddress = (pattern: FormPathPattern) => {\n  const transform = (data = {}) => {\n    return Object.entries(data).reduce((buf, [key, value]) => {\n      if (typeof value === 'string')\n        return buf.concat({\n          label: value,\n          value: key,\n        })\n      const { name, code, cities, districts } = value\n      const _cities = transform(cities)\n      const _districts = transform(districts)\n      return buf.concat({\n        label: name,\n        value: code,\n        children: _cities.length\n          ? _cities\n          : _districts.length\n          ? _districts\n          : undefined,\n      })\n    }, [])\n  }\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    fetch('//unpkg.com/china-location/dist/location.json')\n      .then((res) => res.json())\n      .then(\n        action.bound((data) => {\n          field.dataSource = transform(data)\n          field.loading = false\n        })\n      )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAddress('address')\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"address\"\n      title=\"地址选择\"\n      decorator={[FormItem]}\n      component={[\n        Cascader,\n        {\n          style: {\n            width: 240,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://fusion.design/pc/component/basic/cascader-select\n"
  },
  {
    "path": "packages/next/docs/components/Checkbox.md",
    "content": "# Checkbox\n\n> Checkbox\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Checkbox,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Boolean\n        name=\"single\"\n        title=\"Are you sure\"\n        x-decorator=\"FormItem\"\n        x-component=\"Checkbox\"\n      />\n      <SchemaField.String\n        name=\"multiple\"\n        title=\"Check\"\n        enum={[\n          {\n            label: 'Option 1',\n            value: 1,\n          },\n          {\n            label: 'Option 2',\n            value: 2,\n          },\n        ]}\n        x-decorator=\"FormItem\"\n        x-component=\"Checkbox.Group\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Checkbox,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    single: {\n      type: 'boolean',\n      title: 'Are you sure?',\n      'x-decorator': 'FormItem',\n      'x-component': 'Checkbox',\n    },\n    multiple: {\n      type: 'array',\n      title: 'Check',\n      enum: [\n        {\n          label: 'Option 1',\n          value: 1,\n        },\n        {\n          label: 'Option 2',\n          value: 2,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Checkbox.Group',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"single\"\n      title=\"Are you sure\"\n      decorator={[FormItem]}\n      component={[Checkbox]}\n    />\n    <Field\n      name=\"multiple\"\n      title=\"Check\"\n      dataSource={[\n        {\n          label: 'Option 1',\n          value: 1,\n        },\n        {\n          label: 'Option 2',\n          value: 2,\n        },\n      ]}\n      decorator={[FormItem]}\n      component={[Checkbox.Group]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://fusion.design/pc/component/basic/checkbox\n"
  },
  {
    "path": "packages/next/docs/components/Checkbox.zh-CN.md",
    "content": "# Checkbox\n\n> 复选框\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Checkbox,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Boolean\n        name=\"single\"\n        title=\"是否确认\"\n        x-decorator=\"FormItem\"\n        x-component=\"Checkbox\"\n      />\n      <SchemaField.String\n        name=\"multiple\"\n        title=\"复选\"\n        enum={[\n          {\n            label: '选项1',\n            value: 1,\n          },\n          {\n            label: '选项2',\n            value: 2,\n          },\n        ]}\n        x-decorator=\"FormItem\"\n        x-component=\"Checkbox.Group\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Checkbox,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    single: {\n      type: 'boolean',\n      title: '是否确认',\n      'x-decorator': 'FormItem',\n      'x-component': 'Checkbox',\n    },\n    multiple: {\n      type: 'array',\n      title: '复选',\n      enum: [\n        {\n          label: '选项1',\n          value: 1,\n        },\n        {\n          label: '选项2',\n          value: 2,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Checkbox.Group',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { Checkbox, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"single\"\n      title=\"是否确认\"\n      decorator={[FormItem]}\n      component={[Checkbox]}\n    />\n    <Field\n      name=\"multiple\"\n      title=\"复选\"\n      dataSource={[\n        {\n          label: '选项1',\n          value: 1,\n        },\n        {\n          label: '选项2',\n          value: 2,\n        },\n      ]}\n      decorator={[FormItem]}\n      component={[Checkbox.Group]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://fusion.design/pc/component/basic/checkbox\n"
  },
  {
    "path": "packages/next/docs/components/DatePicker.md",
    "content": "# DatePicker\n\n> Date Picker\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { DatePicker, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"date\"\n        title=\"normal date\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n      />\n      <SchemaField.String\n        name=\"week\"\n        title=\"Week Selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.WeekPicker\"\n      />\n      <SchemaField.String\n        name=\"month\"\n        title=\"Month Selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.MonthPicker\"\n      />\n      <SchemaField.String\n        name=\"year\"\n        title=\"Year selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.YearPicker\"\n      />\n      <SchemaField.String\n        name=\"[startDate,endDate]\"\n        title=\"Date Range\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.RangePicker\"\n        x-component-props={{\n          showTime: true,\n        }}\n      />\n      <SchemaField.String\n        name=\"range_month\"\n        title=\"Month Range Selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.RangePicker\"\n        x-component-props={{\n          type: 'month',\n        }}\n      />\n      <SchemaField.String\n        name=\"range_year\"\n        title=\"Year range selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.RangePicker\"\n        x-component-props={{\n          type: 'year',\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { DatePicker, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    date: {\n      title: 'Normal date',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      type: 'string',\n    },\n    week: {\n      title: 'Week Selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.WeekPicker',\n      type: 'string',\n    },\n    month: {\n      title: 'Month Selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.MonthPicker',\n      type: 'string',\n    },\n    year: {\n      title: 'Year selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.YearPicker',\n      type: 'string',\n    },\n    '[startDate,endDate]': {\n      title: 'Date range',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n      'x-component-props': {\n        showTime: true,\n      },\n      type: 'string',\n    },\n    range_month: {\n      title: 'Month Range Selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n      'x-component-props': {\n        type: 'month',\n      },\n      type: 'string',\n    },\n    range_year: {\n      name: 'range_year',\n      title: 'Year range selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n      'x-component-props': {\n        type: 'year',\n      },\n      type: 'string',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { DatePicker, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"date\"\n      title=\"date selection\"\n      decorator={[FormItem]}\n      component={[DatePicker]}\n    />\n    <Field\n      name=\"week\"\n      title=\"Week Selection\"\n      decorator={[FormItem]}\n      component={[DatePicker.WeekPicker]}\n    />\n    <Field\n      name=\"quarter\"\n      title=\"Financial Year Selection\"\n      decorator={[FormItem]}\n      component={[DatePicker.MonthPicker]}\n    />\n    <Field\n      name=\"year\"\n      title=\"Year selection\"\n      decorator={[FormItem]}\n      component={[DatePicker.YearPicker]}\n    />\n    <Field\n      name=\"[startDate,endDate]\"\n      title=\"Date range selection\"\n      decorator={[FormItem]}\n      component={[DatePicker.RangePicker]}\n    />\n    <Field\n      name=\"range_month\"\n      title=\"Month Range Selection\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker.RangePicker,\n        {\n          type: 'month',\n        },\n      ]}\n    />\n    <Field\n      name=\"range_year\"\n      title=\"Year range selection\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker.RangePicker,\n        {\n          type: 'year',\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://fusion.design/pc/component/basic/date-picker\n"
  },
  {
    "path": "packages/next/docs/components/DatePicker.zh-CN.md",
    "content": "# DatePicker\n\n> 日期选择器\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { DatePicker, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"date\"\n        title=\"普通日期\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker\"\n      />\n      <SchemaField.String\n        name=\"week\"\n        title=\"周选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.WeekPicker\"\n      />\n      <SchemaField.String\n        name=\"month\"\n        title=\"月选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.MonthPicker\"\n      />\n      <SchemaField.String\n        name=\"year\"\n        title=\"年选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.YearPicker\"\n      />\n      <SchemaField.String\n        name=\"[startDate,endDate]\"\n        title=\"日期范围\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.RangePicker\"\n        x-component-props={{\n          showTime: true,\n        }}\n      />\n      <SchemaField.String\n        name=\"range_month\"\n        title=\"月范围选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.RangePicker\"\n        x-component-props={{\n          type: 'month',\n        }}\n      />\n      <SchemaField.String\n        name=\"range_year\"\n        title=\"年范围选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker.RangePicker\"\n        x-component-props={{\n          type: 'year',\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { DatePicker, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    date: {\n      title: '普通日期',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker',\n      type: 'string',\n    },\n    week: {\n      title: '周选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.WeekPicker',\n      type: 'string',\n    },\n    month: {\n      title: '月选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.MonthPicker',\n      type: 'string',\n    },\n    year: {\n      title: '年选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.YearPicker',\n      type: 'string',\n    },\n    '[startDate,endDate]': {\n      title: '日期范围',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n      'x-component-props': {\n        showTime: true,\n      },\n      type: 'string',\n    },\n    range_month: {\n      title: '月范围选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n      'x-component-props': {\n        type: 'month',\n      },\n      type: 'string',\n    },\n    range_year: {\n      name: 'range_year',\n      title: '年范围选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker.RangePicker',\n      'x-component-props': {\n        type: 'year',\n      },\n      type: 'string',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { DatePicker, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"date\"\n      title=\"日期选择\"\n      decorator={[FormItem]}\n      component={[DatePicker]}\n    />\n    <Field\n      name=\"week\"\n      title=\"周选择\"\n      decorator={[FormItem]}\n      component={[DatePicker.WeekPicker]}\n    />\n    <Field\n      name=\"quarter\"\n      title=\"财年选择\"\n      decorator={[FormItem]}\n      component={[DatePicker.MonthPicker]}\n    />\n    <Field\n      name=\"year\"\n      title=\"年选择\"\n      decorator={[FormItem]}\n      component={[DatePicker.YearPicker]}\n    />\n    <Field\n      name=\"[startDate,endDate]\"\n      title=\"日期范围选择\"\n      decorator={[FormItem]}\n      component={[DatePicker.RangePicker]}\n    />\n    <Field\n      name=\"range_month\"\n      title=\"月范围选择\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker.RangePicker,\n        {\n          type: 'month',\n        },\n      ]}\n    />\n    <Field\n      name=\"range_year\"\n      title=\"年范围选择\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker.RangePicker,\n        {\n          type: 'year',\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://fusion.design/pc/component/basic/date-picker\n"
  },
  {
    "path": "packages/next/docs/components/DatePicker2.md",
    "content": "# DatePicker2\n\n> Date Picker\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { DatePicker2, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker2,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"date\"\n        title=\"normal date\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker2\"\n      />\n      <SchemaField.String\n        name=\"week\"\n        title=\"Week Selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker2.WeekPicker\"\n      />\n      <SchemaField.String\n        name=\"month\"\n        title=\"Month Selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker2.MonthPicker\"\n      />\n      <SchemaField.String\n        name=\"year\"\n        title=\"Year selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker2.YearPicker\"\n      />\n      <SchemaField.String\n        name=\"[startDate,endDate]\"\n        title=\"Date Range\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker2.RangePicker\"\n        x-component-props={{\n          showTime: true,\n        }}\n      />\n      <SchemaField.String\n        name=\"range_month\"\n        title=\"Month Range Selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker2.RangePicker\"\n        x-component-props={{\n          mode: 'month',\n        }}\n      />\n      <SchemaField.String\n        name=\"range_year\"\n        title=\"Year range selection\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker2.RangePicker\"\n        x-component-props={{\n          mode: 'year',\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { DatePicker2, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker2,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    date: {\n      title: 'Normal date',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker2',\n      type: 'string',\n    },\n    week: {\n      title: 'Week Selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker2.WeekPicker',\n      type: 'string',\n    },\n    month: {\n      title: 'Month Selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker2.MonthPicker',\n      type: 'string',\n    },\n    year: {\n      title: 'Year selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker2.YearPicker',\n      type: 'string',\n    },\n    '[startDate,endDate]': {\n      title: 'Date range',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker2.RangePicker',\n      'x-component-props': {\n        showTime: true,\n      },\n      type: 'string',\n    },\n    range_month: {\n      title: 'Month Range Selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker2.RangePicker',\n      'x-component-props': {\n        mode: 'month',\n      },\n      type: 'string',\n    },\n    range_year: {\n      name: 'range_year',\n      title: 'Year range selection',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker2.RangePicker',\n      'x-component-props': {\n        mode: 'year',\n      },\n      type: 'string',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { DatePicker2, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"date\"\n      title=\"date selection\"\n      decorator={[FormItem]}\n      component={[DatePicker2]}\n    />\n    <Field\n      name=\"week\"\n      title=\"Week Selection\"\n      decorator={[FormItem]}\n      component={[DatePicker2.WeekPicker]}\n    />\n    <Field\n      name=\"quarter\"\n      title=\"Financial Year Selection\"\n      decorator={[FormItem]}\n      component={[DatePicker2.MonthPicker]}\n    />\n    <Field\n      name=\"year\"\n      title=\"Year selection\"\n      decorator={[FormItem]}\n      component={[DatePicker2.YearPicker]}\n    />\n    <Field\n      name=\"[startDate,endDate]\"\n      title=\"Date range selection\"\n      decorator={[FormItem]}\n      component={[DatePicker2.RangePicker]}\n    />\n    <Field\n      name=\"range_month\"\n      title=\"Month Range Selection\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker2.RangePicker,\n        {\n          mode: 'month',\n        },\n      ]}\n    />\n    <Field\n      name=\"range_year\"\n      title=\"Year range selection\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker2.RangePicker,\n        {\n          mode: 'year',\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://fusion.design/pc/component/basic/date-picker2\n"
  },
  {
    "path": "packages/next/docs/components/DatePicker2.zh-CN.md",
    "content": "# DatePicker2\n\n> 日期选择器\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { DatePicker2, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker2,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"date\"\n        title=\"普通日期\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker2\"\n      />\n      <SchemaField.String\n        name=\"week\"\n        title=\"周选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker2.WeekPicker\"\n      />\n      <SchemaField.String\n        name=\"month\"\n        title=\"月选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker2.MonthPicker\"\n      />\n      <SchemaField.String\n        name=\"year\"\n        title=\"年选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker2.YearPicker\"\n      />\n      <SchemaField.String\n        name=\"[startDate,endDate]\"\n        title=\"日期范围\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker2.RangePicker\"\n        x-component-props={{\n          showTime: true,\n        }}\n      />\n      <SchemaField.String\n        name=\"range_month\"\n        title=\"月范围选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker2.RangePicker\"\n        x-component-props={{\n          mode: 'month',\n        }}\n      />\n      <SchemaField.String\n        name=\"range_year\"\n        title=\"年范围选择\"\n        x-decorator=\"FormItem\"\n        x-component=\"DatePicker2.RangePicker\"\n        x-component-props={{\n          mode: 'year',\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { DatePicker2, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker2,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    date: {\n      title: '普通日期',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker2',\n      type: 'string',\n    },\n    week: {\n      title: '周选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker2.WeekPicker',\n      type: 'string',\n    },\n    month: {\n      title: '月选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker2.MonthPicker',\n      type: 'string',\n    },\n    year: {\n      title: '年选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker2.YearPicker',\n      type: 'string',\n    },\n    '[startDate,endDate]': {\n      title: '日期范围',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker2.RangePicker',\n      'x-component-props': {\n        showTime: true,\n      },\n      type: 'string',\n    },\n    range_month: {\n      title: '月范围选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker2.RangePicker',\n      'x-component-props': {\n        mode: 'month',\n      },\n      type: 'string',\n    },\n    range_year: {\n      name: 'range_year',\n      title: '年范围选择',\n      'x-decorator': 'FormItem',\n      'x-component': 'DatePicker2.RangePicker',\n      'x-component-props': {\n        mode: 'year',\n      },\n      type: 'string',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { DatePicker2, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"date\"\n      title=\"日期选择\"\n      decorator={[FormItem]}\n      component={[DatePicker2]}\n    />\n    <Field\n      name=\"week\"\n      title=\"周选择\"\n      decorator={[FormItem]}\n      component={[DatePicker2.WeekPicker]}\n    />\n    <Field\n      name=\"quarter\"\n      title=\"财年选择\"\n      decorator={[FormItem]}\n      component={[DatePicker2.MonthPicker]}\n    />\n    <Field\n      name=\"year\"\n      title=\"年选择\"\n      decorator={[FormItem]}\n      component={[DatePicker2.YearPicker]}\n    />\n    <Field\n      name=\"[startDate,endDate]\"\n      title=\"日期范围选择\"\n      decorator={[FormItem]}\n      component={[DatePicker2.RangePicker]}\n    />\n    <Field\n      name=\"range_month\"\n      title=\"月范围选择\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker2.RangePicker,\n        {\n          mode: 'month',\n        },\n      ]}\n    />\n    <Field\n      name=\"range_year\"\n      title=\"年范围选择\"\n      decorator={[FormItem]}\n      component={[\n        DatePicker2.RangePicker,\n        {\n          mode: 'year',\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://fusion.design/pc/component/basic/date-picker2\n"
  },
  {
    "path": "packages/next/docs/components/Editable.md",
    "content": "# Editable\n\n> Partial editor, you can use this component for some form areas with high space requirements\n>\n> Editable component is equivalent to a variant of FormItem component, so it is usually placed in decorator\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  DatePicker,\n  Editable,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker,\n    Editable,\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"date\"\n        title=\"date\"\n        x-decorator=\"Editable\"\n        x-component=\"DatePicker\"\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        x-decorator=\"Editable\"\n        x-component=\"Input\"\n      />\n      <SchemaField.Void\n        name=\"void\"\n        title=\"Virtual Node Container\"\n        x-component=\"Editable.Popover\"\n        x-reactions={(field) => {\n          field.title = field.query('.void.date2').get('value') || field.title\n        }}\n      >\n        <SchemaField.String\n          name=\"date2\"\n          title=\"date\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          x-component-props={{\n            followTrigger: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"input2\"\n          title=\"input box\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n      </SchemaField.Void>\n      <SchemaField.Object\n        name=\"iobject\"\n        title=\"Object node container\"\n        x-component=\"Editable.Popover\"\n        x-reactions={(field) => {\n          field.title = field.value?.date || field.title\n        }}\n      >\n        <SchemaField.String\n          name=\"date\"\n          title=\"date\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          x-component-props={{\n            followTrigger: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"input\"\n          title=\"input box\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n      </SchemaField.Object>\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  DatePicker,\n  Editable,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker,\n    Editable,\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    date: {\n      type: 'string',\n      title: 'Date',\n      'x-decorator': 'Editable',\n      'x-component': 'DatePicker',\n    },\n    input: {\n      type: 'string',\n      title: 'input box',\n      'x-decorator': 'Editable',\n      'x-component': 'Input',\n    },\n    void: {\n      type: 'void',\n      title: 'Virtual Node Container',\n      'x-component': 'Editable.Popover',\n      'x-reactions':\n        \"{{(field) => field.title = field.query('.void.date2').get('value') || field.title}}\",\n      properties: {\n        date2: {\n          type: 'string',\n          title: 'Date',\n          'x-decorator': 'FormItem',\n          'x-component': 'DatePicker',\n          'x-component-props': {\n            followTrigger: true,\n          },\n        },\n        input2: {\n          type: 'string',\n          title: 'input box',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n      },\n    },\n    iobject: {\n      type: 'object',\n      title: 'Object node container',\n      'x-component': 'Editable.Popover',\n      'x-reactions':\n        '{{(field) => field.title = field.value && field.value.date || field.title}}',\n      properties: {\n        date: {\n          type: 'string',\n          title: 'Date',\n          'x-decorator': 'FormItem',\n          'x-component': 'DatePicker',\n          'x-component-props': {\n            followTrigger: true,\n          },\n        },\n        input: {\n          type: 'string',\n          title: 'input box',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  DatePicker,\n  Editable,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, VoidField, ObjectField } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"date\"\n      title=\"date\"\n      decorator={[Editable]}\n      component={[DatePicker]}\n    />\n    <Field\n      name=\"input\"\n      title=\"input box\"\n      decorator={[Editable]}\n      component={[Input]}\n    />\n    <VoidField\n      name=\"void\"\n      title=\"Virtual Node Container\"\n      reactions={(field) => {\n        field.title = field.query('.void.date2').get('value') || field.title\n      }}\n      component={[Editable.Popover]}\n    >\n      <Field\n        name=\"date2\"\n        title=\"date\"\n        decorator={[FormItem]}\n        component={[\n          DatePicker,\n          {\n            followTrigger: true,\n          },\n        ]}\n      />\n      <Field\n        name=\"input2\"\n        title=\"input box\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n    </VoidField>\n    <ObjectField\n      name=\"iobject\"\n      title=\"Object node container\"\n      component={[\n        Editable.Popover,\n        {\n          renderPreview: (field) => {\n            return field.value?.date\n          },\n        },\n      ]}\n    >\n      <Field\n        name=\"date\"\n        title=\"date\"\n        decorator={[FormItem]}\n        component={[\n          DatePicker,\n          {\n            followTrigger: true,\n          },\n        ]}\n      />\n      <Field\n        name=\"input\"\n        title=\"input box\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n    </ObjectField>\n\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n### Editable\n\n> Inline editing\n\nRefer to the FormItem property in https://fusion.design/pc/component/basic/form\n\n### Editable.Popover\n\n> Floating layer editing\n\n| Property name | Type                              | Description      | Default value |\n| ------------- | --------------------------------- | ---------------- | ------------- |\n| renderPreview | `(field:GeneralField)=>ReactNode` | Preview renderer |               |\n\nNote: If there is a floating layer component such as Select/DatePicker inside the Popover, followTrigger=true needs to be configured on the floating layer component\n\nOther references https://fusion.design/pc/component/basic/balloon\n"
  },
  {
    "path": "packages/next/docs/components/Editable.zh-CN.md",
    "content": "# Editable\n\n> 局部编辑器，对于一些空间要求较高的表单区域可以使用该组件\n>\n> Editable 组件相当于是 FormItem 组件的变体，所以通常放在 decorator 中\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  DatePicker,\n  Editable,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker,\n    Editable,\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"date\"\n        title=\"日期\"\n        x-decorator=\"Editable\"\n        x-component=\"DatePicker\"\n      />\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        x-decorator=\"Editable\"\n        x-component=\"Input\"\n      />\n      <SchemaField.Void\n        name=\"void\"\n        title=\"虚拟节点容器\"\n        x-component=\"Editable.Popover\"\n        x-reactions={(field) => {\n          field.title = field.query('.void.date2').get('value') || field.title\n        }}\n      >\n        <SchemaField.String\n          name=\"date2\"\n          title=\"日期\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          x-component-props={{\n            followTrigger: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"input2\"\n          title=\"输入框\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n      </SchemaField.Void>\n      <SchemaField.Object\n        name=\"iobject\"\n        title=\"对象节点容器\"\n        x-component=\"Editable.Popover\"\n        x-reactions={(field) => {\n          field.title = field.value?.date || field.title\n        }}\n      >\n        <SchemaField.String\n          name=\"date\"\n          title=\"日期\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          x-component-props={{\n            followTrigger: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"input\"\n          title=\"输入框\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n      </SchemaField.Object>\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  DatePicker,\n  Editable,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    DatePicker,\n    Editable,\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    date: {\n      type: 'string',\n      title: '日期',\n      'x-decorator': 'Editable',\n      'x-component': 'DatePicker',\n    },\n    input: {\n      type: 'string',\n      title: '输入框',\n      'x-decorator': 'Editable',\n      'x-component': 'Input',\n    },\n    void: {\n      type: 'void',\n      title: '虚拟节点容器',\n      'x-component': 'Editable.Popover',\n      'x-reactions':\n        \"{{(field) => field.title = field.query('.void.date2').get('value') || field.title}}\",\n      properties: {\n        date2: {\n          type: 'string',\n          title: '日期',\n          'x-decorator': 'FormItem',\n          'x-component': 'DatePicker',\n          'x-component-props': {\n            followTrigger: true,\n          },\n        },\n        input2: {\n          type: 'string',\n          title: '输入框',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n      },\n    },\n    iobject: {\n      type: 'object',\n      title: '对象节点容器',\n      'x-component': 'Editable.Popover',\n      'x-reactions':\n        '{{(field) => field.title = field.value && field.value.date || field.title}}',\n      properties: {\n        date: {\n          type: 'string',\n          title: '日期',\n          'x-decorator': 'FormItem',\n          'x-component': 'DatePicker',\n          'x-component-props': {\n            followTrigger: true,\n          },\n        },\n        input: {\n          type: 'string',\n          title: '输入框',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  DatePicker,\n  Editable,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, VoidField, ObjectField } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"date\"\n      title=\"日期\"\n      decorator={[Editable]}\n      component={[DatePicker]}\n    />\n    <Field\n      name=\"input\"\n      title=\"输入框\"\n      decorator={[Editable]}\n      component={[Input]}\n    />\n    <VoidField\n      name=\"void\"\n      title=\"虚拟节点容器\"\n      reactions={(field) => {\n        field.title = field.query('.void.date2').get('value') || field.title\n      }}\n      component={[Editable.Popover]}\n    >\n      <Field\n        name=\"date2\"\n        title=\"日期\"\n        decorator={[FormItem]}\n        component={[\n          DatePicker,\n          {\n            followTrigger: true,\n          },\n        ]}\n      />\n      <Field\n        name=\"input2\"\n        title=\"输入框\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n    </VoidField>\n    <ObjectField\n      name=\"iobject\"\n      title=\"对象节点容器\"\n      component={[\n        Editable.Popover,\n        {\n          renderPreview: (field) => {\n            return field.value?.date\n          },\n        },\n      ]}\n    >\n      <Field\n        name=\"date\"\n        title=\"日期\"\n        decorator={[FormItem]}\n        component={[\n          DatePicker,\n          {\n            followTrigger: true,\n          },\n        ]}\n      />\n      <Field\n        name=\"input\"\n        title=\"输入框\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n    </ObjectField>\n\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n### Editable\n\n> 内联编辑\n\n参考 https://fusion.design/pc/component/basic/form 中的 FormItem 属性\n\n### Editable.Popover\n\n> 浮层编辑\n\n| 属性名        | 类型                              | 描述       | 默认值 |\n| ------------- | --------------------------------- | ---------- | ------ |\n| renderPreview | `(field:GeneralField)=>ReactNode` | 预览渲染器 |        |\n\n注意：如果在 Popover 内部有 Select/DatePicker 之类的浮层组件，需要在浮层组件上配置 followTrigger=true\n\n其余参考 https://fusion.design/pc/component/basic/balloon\n"
  },
  {
    "path": "packages/next/docs/components/Form.md",
    "content": "# Form\n\n> The combination of FormProvider + FormLayout + form tags can help us quickly implement forms that are submitted with carriage return and can be laid out in batches\n\n## Use Cases\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Select,\n  Form,\n  FormItem,\n  FormGrid,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <Form\n    form={form}\n    layout=\"vertical\"\n    feedbackLayout=\"terse\"\n    onAutoSubmit={console.log}\n    onAutoSubmitFailed={console.log}\n  >\n    <FormGrid maxColumns={4}>\n      <Field\n        name=\"aa\"\n        title=\"select box\"\n        decorator={[FormItem]}\n        component={[Select]}\n        dataSource={[\n          {\n            label: 'Option 1',\n            value: 1,\n          },\n          {\n            label: 'Option 2',\n            value: 2,\n          },\n        ]}\n      />\n      <Field\n        name=\"bb\"\n        title=\"input box\"\n        required\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <Field\n        name=\"cc\"\n        title=\"input box\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <Field\n        name=\"dd\"\n        title=\"input box\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <Field\n        name=\"ee\"\n        title=\"input box\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <FormButtonGroup.FormItem>\n        <Submit>Query</Submit>\n      </FormButtonGroup.FormItem>\n    </FormGrid>\n  </Form>\n)\n```\n\n## Fusion Multilingual\n\n```tsx\nimport React from 'react'\nimport { Input, Form, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/react'\nimport { ConfigProvider } from '@alifd/next'\nimport enUS from '@alifd/next/lib/locale/en-us'\n\nconst form = createForm()\n\nexport default () => (\n  <ConfigProvider locale={enUS}>\n    <Form\n      form={form}\n      layout=\"vertical\"\n      feedbackLayout=\"terse\"\n      onAutoSubmit={console.log}\n    >\n      <Field\n        name=\"bb\"\n        title=\"User Name\"\n        required\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n\n      <FormButtonGroup.FormItem>\n        <Submit>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </Form>\n  </ConfigProvider>\n)\n```\n\n<Alert style=\"margin-top:20px\">\nNote: 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.\n</Alert>\n\n## API\n\nFor layout-related API properties, we can refer to [FormLayout](./form-layout), and the rest are the unique API properties of the Form component\n\n| Property name          | Type                                                                                             | Description                                                         | Default value |\n| ---------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------- | ------------- |\n| form                   | [Form](https://core.formilyjs.org/api/models/form)                                               | Form example                                                        | -             |\n| component              | string                                                                                           | Rendering component, can be specified as custom component rendering | `form`        |\n| previewTextPlaceholder | ReactNode                                                                                        | Preview State Placeholder                                           | `N/A`         |\n| onAutoSubmit           | `(values:any)=>any`                                                                              | Carriage return submit event callback                               | -             |\n| onAutoSubmitFailed     | (feedbacks: [IFormFeedback](https://core.formilyjs.org/api/models/form#iformfeedback)[]) => void | Carriage return submission verification failure event callback      | -             |\n"
  },
  {
    "path": "packages/next/docs/components/Form.zh-CN.md",
    "content": "# Form\n\n> FormProvider + FormLayout + form 标签的组合组件，可以帮助我们快速实现带回车提交的且能批量布局的表单\n\n## 使用案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Select,\n  Form,\n  FormItem,\n  FormGrid,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <Form\n    form={form}\n    layout=\"vertical\"\n    feedbackLayout=\"terse\"\n    onAutoSubmit={console.log}\n    onAutoSubmitFailed={console.log}\n  >\n    <FormGrid maxColumns={4}>\n      <Field\n        name=\"aa\"\n        title=\"选择框\"\n        decorator={[FormItem]}\n        component={[Select]}\n        dataSource={[\n          {\n            label: '选项1',\n            value: 1,\n          },\n          {\n            label: '选项2',\n            value: 2,\n          },\n        ]}\n      />\n      <Field\n        name=\"bb\"\n        title=\"输入框\"\n        required\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <Field\n        name=\"cc\"\n        title=\"输入框\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <Field\n        name=\"dd\"\n        title=\"输入框\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <Field\n        name=\"ee\"\n        title=\"输入框\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <FormButtonGroup.FormItem>\n        <Submit>查询</Submit>\n      </FormButtonGroup.FormItem>\n    </FormGrid>\n  </Form>\n)\n```\n\n## Fusion 多语言\n\n```tsx\nimport React from 'react'\nimport { Input, Form, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { Field } from '@formily/react'\nimport { ConfigProvider } from '@alifd/next'\nimport enUS from '@alifd/next/lib/locale/en-us'\n\nconst form = createForm()\n\nexport default () => (\n  <ConfigProvider locale={enUS}>\n    <Form\n      form={form}\n      layout=\"vertical\"\n      feedbackLayout=\"terse\"\n      onAutoSubmit={console.log}\n    >\n      <Field\n        name=\"bb\"\n        title=\"User Name\"\n        required\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n\n      <FormButtonGroup.FormItem>\n        <Submit>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </Form>\n  </ConfigProvider>\n)\n```\n\n<Alert style=\"margin-top:20px\">\n注意：想要实现回车提交，我们在使用Submit组件的时候不能给其传onSubmit事件，否则回车提交会失效，这样做的目的是为了防止用户同时在多处写onSubmit事件监听器，处理逻辑不一致的话，提交时很难定位问题。\n</Alert>\n\n## API\n\n布局相关的 API 属性，我们参考 [FormLayout](./form-layout)即可，剩下是 Form 组件独有的 API 属性\n\n| 属性名                 | 类型                                                                                                   | 描述                               | 默认值 |\n| ---------------------- | ------------------------------------------------------------------------------------------------------ | ---------------------------------- | ------ |\n| form                   | [Form](https://core.formilyjs.org/zh-CN/api/models/form)                                               | Form 实例                          | -      |\n| component              | string                                                                                                 | 渲染组件，可以指定为自定义组件渲染 | `form` |\n| previewTextPlaceholder | ReactNode                                                                                              | 预览态占位符                       | `N/A`  |\n| onAutoSubmit           | `(values:any)=>any`                                                                                    | 回车提交事件回调                   | -      |\n| onAutoSubmitFailed     | (feedbacks: [IFormFeedback](https://core.formilyjs.org/zh-CN/api/models/form#iformfeedback)[]) => void | 回车提交校验失败事件回调           | -      |\n"
  },
  {
    "path": "packages/next/docs/components/FormButtonGroup.md",
    "content": "# FormButtonGroup\n\n> Form button group layout component\n\n## Common case\n\n```tsx\nimport React from 'react'\nimport {\n  FormButtonGroup,\n  Submit,\n  Reset,\n  FormItem,\n  Input,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField>\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaField>\n        <FormButtonGroup.FormItem>\n          <Submit onSubmit={console.log}>Submit</Submit>\n          <Reset>Reset</Reset>\n        </FormButtonGroup.FormItem>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## Suction bottom case\n\n```tsx\nimport React from 'react'\nimport {\n  FormButtonGroup,\n  Submit,\n  Reset,\n  FormItem,\n  FormLayout,\n  Input,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField>\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaField>\n        <FormButtonGroup.Sticky>\n          <FormButtonGroup.FormItem>\n            <Submit onSubmit={console.log}>Submit</Submit>\n            <Reset>Reset</Reset>\n          </FormButtonGroup.FormItem>\n        </FormButtonGroup.Sticky>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## Suction bottom centering case\n\n```tsx\nimport React from 'react'\nimport {\n  FormButtonGroup,\n  Submit,\n  Reset,\n  FormItem,\n  FormLayout,\n  Input,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField>\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"input box\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaField>\n        <FormButtonGroup.Sticky align=\"center\">\n          <FormButtonGroup>\n            <Submit onSubmit={console.log}>Submit</Submit>\n            <Reset>Reset</Reset>\n          </FormButtonGroup>\n        </FormButtonGroup.Sticky>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormButtonGroup\n\n> This component is mainly used to handle the button group gap\n\n| Property name | Type                        | Description | Default value |\n| ------------- | --------------------------- | ----------- | ------------- |\n| gutter        | number                      | Gap size    | 8px           |\n| align         | `'left'\\|'center'\\|'right'` | Alignment   | `'left'`      |\n\n### FormButtonGroup.FormItem\n\n> This component is mainly used to deal with the alignment of the button group and the main form FormItem\n\nRefer to [FormItem](/components/form-item) property\n\n### FormButtonGroup.Sticky\n\n> This component is mainly used to deal with the floating positioning problem of the button group\n\n| Property name | Type                        | Description | Default value |\n| ------------- | --------------------------- | ----------- | ------------- |\n| align         | `'left'\\|'center'\\|'right'` | Alignment   | `'left'`      |\n"
  },
  {
    "path": "packages/next/docs/components/FormButtonGroup.zh-CN.md",
    "content": "# FormButtonGroup\n\n> 表单按钮组布局组件\n\n## 普通案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormButtonGroup,\n  Submit,\n  Reset,\n  FormItem,\n  Input,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField>\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaField>\n        <FormButtonGroup.FormItem>\n          <Submit onSubmit={console.log}>提交</Submit>\n          <Reset>重置</Reset>\n        </FormButtonGroup.FormItem>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## 吸底案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormButtonGroup,\n  Submit,\n  Reset,\n  FormItem,\n  FormLayout,\n  Input,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField>\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaField>\n        <FormButtonGroup.Sticky>\n          <FormButtonGroup.FormItem>\n            <Submit onSubmit={console.log}>提交</Submit>\n            <Reset>重置</Reset>\n          </FormButtonGroup.FormItem>\n        </FormButtonGroup.Sticky>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## 吸底居中案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormButtonGroup,\n  Submit,\n  Reset,\n  FormItem,\n  FormLayout,\n  Input,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField>\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            title=\"输入框\"\n            x-decorator=\"FormItem\"\n            required\n            x-component=\"Input\"\n          />\n        </SchemaField>\n        <FormButtonGroup.Sticky align=\"center\">\n          <FormButtonGroup>\n            <Submit onSubmit={console.log}>提交</Submit>\n            <Reset>重置</Reset>\n          </FormButtonGroup>\n        </FormButtonGroup.Sticky>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormButtonGroup\n\n> 该组件主要用来处理按钮组间隙\n\n| 属性名 | 类型                        | 描述     | 默认值   |\n| ------ | --------------------------- | -------- | -------- |\n| gutter | number                      | 间隙大小 | 8px      |\n| align  | `'left'\\|'center'\\|'right'` | 对齐方式 | `'left'` |\n\n### FormButtonGroup.FormItem\n\n> 该组件主要用来处理按钮组与主表单 FormItem 对齐问题\n\n参考 [FormItem](/components/form-item) 属性\n\n### FormButtonGroup.Sticky\n\n> 该组件主要用来处理按钮组浮动定位问题\n\n| 属性名 | 类型                        | 描述     | 默认值   |\n| ------ | --------------------------- | -------- | -------- |\n| align  | `'left'\\|'center'\\|'right'` | 对齐方式 | `'left'` |\n"
  },
  {
    "path": "packages/next/docs/components/FormCollapse.md",
    "content": "# FormCollapse\n\n> Folding panel, usually used in form scenes with high layout space requirements\n>\n> Note: Can only be used in Schema scenarios\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  FormCollapse,\n  FormItem,\n  Input,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormCollapse,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formCollapse = FormCollapse.createFormCollapse()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField>\n          <SchemaField.Void\n            title=\"Folding Panel\"\n            x-decorator=\"FormItem\"\n            x-component=\"FormCollapse\"\n            x-component-props={{\n              formCollapse,\n            }}\n          >\n            <SchemaField.Void\n              name=\"panel1\"\n              x-component=\"FormCollapse.CollapsePanel\"\n              x-component-props={{ title: 'A1' }}\n            >\n              <SchemaField.String\n                name=\"aaa\"\n                title=\"AAA\"\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              name=\"panel2\"\n              x-component=\"FormCollapse.CollapsePanel\"\n              x-component-props={{ title: 'A2' }}\n            >\n              <SchemaField.String\n                name=\"bbb\"\n                title=\"BBB\"\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              name=\"panel3\"\n              x-component=\"FormCollapse.CollapsePanel\"\n              x-component-props={{ title: 'A3' }}\n            >\n              <SchemaField.String\n                name=\"ccc\"\n                title=\"CCC\"\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n          </SchemaField.Void>\n        </SchemaField>\n        <FormButtonGroup.FormItem>\n          <Button\n            onClick={() => {\n              form.query('panel3').take((field) => {\n                field.visible = !field.visible\n              })\n            }}\n          >\n            Show/hide the last tab\n          </Button>\n          <Button\n            onClick={() => {\n              formCollapse.toggleActiveKey('panel2')\n            }}\n          >\n            Switch to the second Tab\n          </Button>\n          <Submit onSubmit={console.log}>Submit</Submit>\n        </FormButtonGroup.FormItem>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  FormCollapse,\n  FormItem,\n  Input,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormCollapse,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formCollapse = FormCollapse.createFormCollapse()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    collapse: {\n      type: 'void',\n      title: 'Folding Panel',\n      'x-decorator': 'FormItem',\n      'x-component': 'FormCollapse',\n      'x-component-props': {\n        formCollapse: '{{formCollapse}}',\n      },\n      properties: {\n        panel1: {\n          type: 'void',\n          'x-component': 'FormCollapse.CollapsePanel',\n          'x-component-props': {\n            title: 'A1',\n          },\n          properties: {\n            aaa: {\n              type: 'string',\n              title: 'AAA',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        panel2: {\n          type: 'void',\n          'x-component': 'FormCollapse.CollapsePanel',\n          'x-component-props': {\n            title: 'A2',\n          },\n          properties: {\n            bbb: {\n              type: 'string',\n              title: 'BBB',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        panel3: {\n          type: 'void',\n          'x-component': 'FormCollapse.CollapsePanel',\n          'x-component-props': {\n            title: 'A3',\n          },\n          properties: {\n            ccc: {\n              type: 'string',\n              title: 'CCC',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField schema={schema} scope={{ formCollapse }} />\n        <FormButtonGroup.FormItem>\n          <Button\n            onClick={() => {\n              form.query('panel3').take((field) => {\n                field.visible = !field.visible\n              })\n            }}\n          >\n            Show/hide the last tab\n          </Button>\n          <Button\n            onClick={() => {\n              formCollapse.toggleActiveKey('panel2')\n            }}\n          >\n            Switch to the second Tab\n          </Button>\n          <Submit onSubmit={console.log}>Submit</Submit>\n        </FormButtonGroup.FormItem>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormCollapse\n\n| Property name | Type          | Description                                                     | Default value |\n| ------------- | ------------- | --------------------------------------------------------------- | ------------- |\n| formCollapse  | IFormCollapse | Pass in the model created by createFormCollapse/useFormCollapse |               |\n\nOther references https://fusion.design/pc/component/basic/collapse\n\n### FormCollapse.CollapsePanel\n\nReference https://fusion.design/pc/component/basic/collapse\n\n### FormCollapse.createFormCollapse\n\n```ts pure\ntype ActiveKey = string | number\ntype ActiveKeys = string | number | Array<string | number>\n\ninterface createFormCollapse {\n  (defaultActiveKeys?: ActiveKeys): IFormCollpase\n}\n\ninterface IFormCollapse {\n  //Activate the primary key list\n  activeKeys: ActiveKeys\n  //Does the activation key exist?\n  hasActiveKey(key: ActiveKey): boolean\n  //Set the list of active primary keys\n  setActiveKeys(keys: ActiveKeys): void\n  //Add activation key\n  addActiveKey(key: ActiveKey): void\n  //Delete the active primary key\n  removeActiveKey(key: ActiveKey): void\n  //Switch to activate the main key\n  toggleActiveKey(key: ActiveKey): void\n}\n```\n"
  },
  {
    "path": "packages/next/docs/components/FormCollapse.zh-CN.md",
    "content": "# FormCollapse\n\n> 折叠面板，通常用在布局空间要求较高的表单场景\n>\n> 注意：只能用在 Schema 场景\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormCollapse,\n  FormItem,\n  Input,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormCollapse,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formCollapse = FormCollapse.createFormCollapse()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField>\n          <SchemaField.Void\n            title=\"折叠面板\"\n            x-decorator=\"FormItem\"\n            x-component=\"FormCollapse\"\n            x-component-props={{\n              formCollapse,\n            }}\n          >\n            <SchemaField.Void\n              name=\"panel1\"\n              x-component=\"FormCollapse.CollapsePanel\"\n              x-component-props={{ title: 'A1' }}\n            >\n              <SchemaField.String\n                name=\"aaa\"\n                title=\"AAA\"\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              name=\"panel2\"\n              x-component=\"FormCollapse.CollapsePanel\"\n              x-component-props={{ title: 'A2' }}\n            >\n              <SchemaField.String\n                name=\"bbb\"\n                title=\"BBB\"\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n            <SchemaField.Void\n              name=\"panel3\"\n              x-component=\"FormCollapse.CollapsePanel\"\n              x-component-props={{ title: 'A3' }}\n            >\n              <SchemaField.String\n                name=\"ccc\"\n                title=\"CCC\"\n                x-decorator=\"FormItem\"\n                required\n                x-component=\"Input\"\n              />\n            </SchemaField.Void>\n          </SchemaField.Void>\n        </SchemaField>\n        <FormButtonGroup.FormItem>\n          <Button\n            onClick={() => {\n              form.query('panel3').take((field) => {\n                field.visible = !field.visible\n              })\n            }}\n          >\n            显示/隐藏最后一个Tab\n          </Button>\n          <Button\n            onClick={() => {\n              formCollapse.toggleActiveKey('panel2')\n            }}\n          >\n            切换第二个Tab\n          </Button>\n          <Submit onSubmit={console.log}>提交</Submit>\n        </FormButtonGroup.FormItem>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormCollapse,\n  FormItem,\n  Input,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormCollapse,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formCollapse = FormCollapse.createFormCollapse()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    collapse: {\n      type: 'void',\n      title: '折叠面板',\n      'x-decorator': 'FormItem',\n      'x-component': 'FormCollapse',\n      'x-component-props': {\n        formCollapse: '{{formCollapse}}',\n      },\n      properties: {\n        panel1: {\n          type: 'void',\n          'x-component': 'FormCollapse.CollapsePanel',\n          'x-component-props': {\n            title: 'A1',\n          },\n          properties: {\n            aaa: {\n              type: 'string',\n              title: 'AAA',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        panel2: {\n          type: 'void',\n          'x-component': 'FormCollapse.CollapsePanel',\n          'x-component-props': {\n            title: 'A2',\n          },\n          properties: {\n            bbb: {\n              type: 'string',\n              title: 'BBB',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        panel3: {\n          type: 'void',\n          'x-component': 'FormCollapse.CollapsePanel',\n          'x-component-props': {\n            title: 'A3',\n          },\n          properties: {\n            ccc: {\n              type: 'string',\n              title: 'CCC',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <FormLayout labelCol={6} wrapperCol={10}>\n        <SchemaField schema={schema} scope={{ formCollapse }} />\n        <FormButtonGroup.FormItem>\n          <Button\n            onClick={() => {\n              form.query('panel3').take((field) => {\n                field.visible = !field.visible\n              })\n            }}\n          >\n            显示/隐藏最后一个Tab\n          </Button>\n          <Button\n            onClick={() => {\n              formCollapse.toggleActiveKey('panel2')\n            }}\n          >\n            切换第二个Tab\n          </Button>\n          <Submit onSubmit={console.log}>提交</Submit>\n        </FormButtonGroup.FormItem>\n      </FormLayout>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormCollapse\n\n| 属性名       | 类型          | 描述                                                       | 默认值 |\n| ------------ | ------------- | ---------------------------------------------------------- | ------ |\n| formCollapse | IFormCollapse | 传入通过 createFormCollapse/useFormCollapse 创建出来的模型 |        |\n\n其余参考 https://fusion.design/pc/component/basic/collapse\n\n### FormCollapse.CollapsePanel\n\n参考 https://fusion.design/pc/component/basic/collapse\n\n### FormCollapse.createFormCollapse\n\n```ts pure\ntype ActiveKey = string | number\ntype ActiveKeys = string | number | Array<string | number>\n\ninterface createFormCollapse {\n  (defaultActiveKeys?: ActiveKeys): IFormCollpase\n}\n\ninterface IFormCollapse {\n  //激活主键列表\n  activeKeys: ActiveKeys\n  //是否存在该激活主键\n  hasActiveKey(key: ActiveKey): boolean\n  //设置激活主键列表\n  setActiveKeys(keys: ActiveKeys): void\n  //添加激活主键\n  addActiveKey(key: ActiveKey): void\n  //删除激活主键\n  removeActiveKey(key: ActiveKey): void\n  //开关切换激活主键\n  toggleActiveKey(key: ActiveKey): void\n}\n```\n"
  },
  {
    "path": "packages/next/docs/components/FormDialog.md",
    "content": "# FormDialog\n\n> Pop-up form, mainly used in simple event to open the form scene\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { FormDialog, FormItem, Input, FormLayout } from '@formily/next'\nimport { createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        FormDialog('Pop-up form', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={14}>\n              <SchemaField>\n                <SchemaField.String\n                  name=\"aaa\"\n                  required\n                  title=\"input box 1\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"bbb\"\n                  required\n                  title=\"input box 2\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"ccc\"\n                  required\n                  title=\"input box 3\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"ddd\"\n                  required\n                  title=\"input box 4\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n              </SchemaField>\n              <FormDialog.Footer>\n                <span style={{ marginLeft: 4 }}>Extended copywriting</span>\n              </FormDialog.Footer>\n            </FormLayout>\n          )\n        })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      Click me to open the form\n    </Button>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { FormDialog, FormItem, Input, FormLayout } from '@formily/next'\nimport { createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    aaa: {\n      type: 'string',\n      title: 'input box 1',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    bbb: {\n      type: 'string',\n      title: 'input box 2',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    ccc: {\n      type: 'string',\n      title: 'input box 3',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    ddd: {\n      type: 'string',\n      title: 'input box 4',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        FormDialog('Pop-up form', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={14}>\n              <SchemaField schema={schema} />\n              <FormDialog.Footer>\n                <span style={{ marginLeft: 4 }}>Extended copywriting</span>\n              </FormDialog.Footer>\n            </FormLayout>\n          )\n        })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      Click me to open the form\n    </Button>\n  )\n}\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { FormDialog, FormItem, Input, FormLayout } from '@formily/next'\nimport { Field } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        FormDialog('Pop-up form', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={14}>\n              <Field\n                name=\"aaa\"\n                required\n                title=\"input box 1\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"bbb\"\n                required\n                title=\"input box 2\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"ccc\"\n                required\n                title=\"input box 3\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"ddd\"\n                required\n                title=\"input box 4\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <FormDialog.Footer>\n                <span style={{ marginLeft: 4 }}>Extended copywriting</span>\n              </FormDialog.Footer>\n            </FormLayout>\n          )\n        })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      Click me to open the form\n    </Button>\n  )\n}\n```\n\n## Use Fusion Context\n\n```tsx\nimport React from 'react'\nimport { FormDialog, FormItem, Input, FormLayout } from '@formily/next'\nimport { Field } from '@formily/react'\nimport { Button, ConfigProvider } from '@alifd/next'\n\nexport default () => {\n  return (\n    <ConfigProvider\n      locale={{\n        Dialog: {\n          ok: 'OK',\n          cancel: 'Cancel',\n        },\n      }}\n      defaultPropsConfig={{\n        Dialog: {\n          isFullScreen: true,\n          footerActions: ['cancel', 'ok'],\n        },\n      }}\n    >\n      <Button\n        onClick={() => {\n          FormDialog('Pop-up form', () => {\n            return (\n              <FormLayout labelCol={6} wrapperCol={14}>\n                <Field\n                  name=\"aaa\"\n                  required\n                  title=\"input box 1\"\n                  decorator={[FormItem]}\n                  component={[Input]}\n                />\n                <Field\n                  name=\"bbb\"\n                  required\n                  title=\"input box 2\"\n                  decorator={[FormItem]}\n                  component={[Input]}\n                />\n                <Field\n                  name=\"ccc\"\n                  required\n                  title=\"input box 3\"\n                  decorator={[FormItem]}\n                  component={[Input]}\n                />\n                <Field\n                  name=\"ddd\"\n                  required\n                  title=\"input box 4\"\n                  decorator={[FormItem]}\n                  component={[Input]}\n                />\n                <FormDialog.Footer>\n                  <span style={{ marginLeft: 4 }}>Extended copywriting</span>\n                </FormDialog.Footer>\n              </FormLayout>\n            )\n          })\n            .open({\n              initialValues: {\n                aaa: '123',\n              },\n            })\n            .then(console.log)\n        }}\n      >\n        Click me to open the form\n      </Button>\n    </ConfigProvider>\n  )\n}\n```\n\n## API\n\n### FormDialog\n\n```ts pure\nimport { IFormProps, Form } from '@formily/core'\n\ntype FormDialogRenderer =\n  | React.ReactElement\n  | ((form: Form) => React.ReactElement)\n\ninterface IFormDialog {\n  forOpen(\n    middleware: (\n      props: IFormProps,\n      next: (props?: IFormProps) => Promise<any>\n    ) => any\n  ): any //Middleware interceptor, can intercept Dialog to open\n  forConfirm(\n    middleware: (props: Form, next: (props?: Form) => Promise<any>) => any\n  ): any //Middleware interceptor, which can intercept Dialog confirmation\n  forCancel(\n    middleware: (props: Form, next: (props?: Form) => Promise<any>) => any\n  ): any //Middleware interceptor, can intercept Dialog to cancel\n  //Open the pop-up window to receive form attributes, you can pass in initialValues/values/effects etc.\n  open(props: IFormProps): Promise<any> //return form data\n  //Close the pop-up window\n  close(): void\n}\n\ninterface IDialogProps extends DialogProps {\n  onOk?: (event: React.MouseEvent) => void | boolean // return false can prevent onOk\n  onCancel?: (event: React.MouseEvent) => void | boolean // return false can prevent onCancel\n  loadingText?: React.ReactText\n}\n\ninterface FormDialog {\n  (title: IDialogProps, id: string, renderer: FormDialogRenderer): IFormDialog\n  (title: IDialogProps, renderer: FormDialogRenderer): IFormDialog\n  (title: ModalTitle, id: string, renderer: FormDialogRenderer): IFormDialog\n  (title: ModalTitle, renderer: FormDialogRenderer): IFormDialog\n}\n```\n\n`DialogProps` type definition reference fusion [Dialog API](https://fusion.design/pc/component/dialog?themeid=2#API)\n\n### FormDialog.Footer\n\nNo attributes, only child nodes are received\n\n### FormDialog.Portal\n\nReceive the optional id attribute, the default value is `form-dialog`, if there are multiple prefixCls in an application, and the prefixCls in the pop-up window of different regions are different, then it is recommended to specify the id as the region-level id\n"
  },
  {
    "path": "packages/next/docs/components/FormDialog.zh-CN.md",
    "content": "# FormDialog\n\n> 弹窗表单，主要用在简单的事件打开表单场景\n\n## Markup Schema 案例\n\n```tsx\nimport React, { createContext, useContext } from 'react'\nimport { FormDialog, FormItem, Input, FormLayout } from '@formily/next'\nimport { createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst Context = createContext()\n\nconst PortalId = '可以传，也可以不传的ID，默认是form-dialog'\n\nexport default () => {\n  return (\n    <Context.Provider value=\"自定义上下文可以直接传到弹窗内部，只需要ID一致即可\">\n      <FormDialog.Portal id={PortalId}>\n        <Button\n          onClick={() => {\n            FormDialog('弹窗表单', PortalId, (form) => {\n              console.log(useContext(Context))\n              return (\n                <FormLayout labelCol={6} wrapperCol={10}>\n                  <SchemaField>\n                    <SchemaField.String\n                      name=\"aaa\"\n                      required\n                      title=\"输入框1\"\n                      x-decorator=\"FormItem\"\n                      x-component=\"Input\"\n                    />\n                    <SchemaField.String\n                      name=\"bbb\"\n                      required\n                      title=\"输入框2\"\n                      x-decorator=\"FormItem\"\n                      x-component=\"Input\"\n                    />\n                    <SchemaField.String\n                      name=\"ccc\"\n                      required\n                      title=\"输入框3\"\n                      x-decorator=\"FormItem\"\n                      x-component=\"Input\"\n                    />\n                    <SchemaField.String\n                      name=\"ddd\"\n                      required\n                      title=\"输入框4\"\n                      x-decorator=\"FormItem\"\n                      x-component=\"Input\"\n                    />\n                  </SchemaField>\n                  <FormDialog.Footer>\n                    <span style={{ marginLeft: 4 }}>\n                      扩展文案：{form.values.aaa}\n                    </span>\n                  </FormDialog.Footer>\n                </FormLayout>\n              )\n            })\n              .forOpen((payload, next) => {\n                setTimeout(() => {\n                  next({\n                    initialValues: {\n                      aaa: '123',\n                    },\n                  })\n                }, 1000)\n              })\n              .forConfirm((payload, next) => {\n                setTimeout(() => {\n                  console.log(payload)\n                  next(payload)\n                }, 1000)\n              })\n              .forCancel((payload, next) => {\n                setTimeout(() => {\n                  console.log(payload)\n                  next(payload)\n                }, 1000)\n              })\n              .open()\n              .then(console.log)\n              .catch(console.error)\n          }}\n        >\n          点我打开表单\n        </Button>\n      </FormDialog.Portal>\n    </Context.Provider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { FormDialog, FormItem, Input, FormLayout } from '@formily/next'\nimport { createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    aaa: {\n      type: 'string',\n      title: '输入框1',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    bbb: {\n      type: 'string',\n      title: '输入框2',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    ccc: {\n      type: 'string',\n      title: '输入框3',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    ddd: {\n      type: 'string',\n      title: '输入框4',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        FormDialog('弹窗表单', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={14}>\n              <SchemaField schema={schema} />\n              <FormDialog.Footer>\n                <span style={{ marginLeft: 4 }}>扩展文案</span>\n              </FormDialog.Footer>\n            </FormLayout>\n          )\n        })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      点我打开表单\n    </Button>\n  )\n}\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { FormDialog, FormItem, Input, FormLayout } from '@formily/next'\nimport { Field } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        FormDialog('弹窗表单', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={14}>\n              <Field\n                name=\"aaa\"\n                required\n                title=\"输入框1\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"bbb\"\n                required\n                title=\"输入框2\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"ccc\"\n                required\n                title=\"输入框3\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"ddd\"\n                required\n                title=\"输入框4\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <FormDialog.Footer>\n                <span style={{ marginLeft: 4 }}>扩展文案</span>\n              </FormDialog.Footer>\n            </FormLayout>\n          )\n        })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      点我打开表单\n    </Button>\n  )\n}\n```\n\n## 使用 Fusion Context\n\n```tsx\nimport React from 'react'\nimport { FormDialog, FormItem, Input, FormLayout } from '@formily/next'\nimport { Field } from '@formily/react'\nimport { Button, ConfigProvider } from '@alifd/next'\n\nexport default () => {\n  return (\n    <ConfigProvider\n      locale={{\n        Dialog: {\n          ok: 'OK',\n          cancel: 'Cancel',\n        },\n      }}\n      defaultPropsConfig={{\n        Dialog: {\n          isFullScreen: true,\n          footerActions: ['cancel', 'ok'],\n        },\n      }}\n    >\n      <Button\n        onClick={() => {\n          FormDialog('弹窗表单', () => {\n            return (\n              <FormLayout labelCol={6} wrapperCol={14}>\n                <Field\n                  name=\"aaa\"\n                  required\n                  title=\"输入框1\"\n                  decorator={[FormItem]}\n                  component={[Input]}\n                />\n                <Field\n                  name=\"bbb\"\n                  required\n                  title=\"输入框2\"\n                  decorator={[FormItem]}\n                  component={[Input]}\n                />\n                <Field\n                  name=\"ccc\"\n                  required\n                  title=\"输入框3\"\n                  decorator={[FormItem]}\n                  component={[Input]}\n                />\n                <Field\n                  name=\"ddd\"\n                  required\n                  title=\"输入框4\"\n                  decorator={[FormItem]}\n                  component={[Input]}\n                />\n                <FormDialog.Footer>\n                  <span style={{ marginLeft: 4 }}>扩展文案</span>\n                </FormDialog.Footer>\n              </FormLayout>\n            )\n          })\n            .open({\n              initialValues: {\n                aaa: '123',\n              },\n            })\n            .then(console.log)\n        }}\n      >\n        点我打开表单\n      </Button>\n    </ConfigProvider>\n  )\n}\n```\n\n## API\n\n### FormDialog\n\n```ts pure\nimport { IFormProps, Form } from '@formily/core'\n\ntype FormDialogRenderer =\n  | React.ReactElement\n  | ((form: Form) => React.ReactElement)\n\ninterface IFormDialog {\n  forOpen(\n    middleware: (\n      props: IFormProps,\n      next: (props?: IFormProps) => Promise<any>\n    ) => any\n  ): any //中间件拦截器，可以拦截Dialog打开\n  forConfirm(\n    middleware: (props: Form, next: (props?: Form) => Promise<any>) => any\n  ): any //中间件拦截器，可以拦截Dialog确认\n  forCancel(\n    middleware: (props: Form, next: (props?: Form) => Promise<any>) => any\n  ): any //中间件拦截器，可以拦截Dialog取消\n  //打开弹窗，接收表单属性，可以传入initialValues/values/effects etc.\n  open(props: IFormProps): Promise<any> //返回表单数据\n  //关闭弹窗\n  close(): void\n}\n\ninterface IDialogProps extends DialogProps {\n  onOk?: (event: React.MouseEvent) => void | boolean // return false can prevent onOk\n  onCancel?: (event: React.MouseEvent) => void | boolean // return false can prevent onCancel\n  loadingText?: React.ReactText\n}\n\ninterface FormDialog {\n  (title: IDialogProps, id: string, renderer: FormDialogRenderer): IFormDialog\n  (title: IDialogProps, renderer: FormDialogRenderer): IFormDialog\n  (title: ModalTitle, id: string, renderer: FormDialogRenderer): IFormDialog\n  (title: ModalTitle, renderer: FormDialogRenderer): IFormDialog\n}\n```\n\n`DialogProps` 类型定义参考 fusion [Dialog API](https://fusion.design/pc/component/dialog?themeid=2#API)\n\n### FormDialog.Footer\n\n无属性，只接收子节点\n\n### FormDialog.Portal\n\n接收可选的 id 属性，默认值为`form-dialog`，如果一个应用存在多个 prefixCls，不同区域的弹窗内部 prefixCls 不一样，那推荐指定 id 为区域级 id\n"
  },
  {
    "path": "packages/next/docs/components/FormDrawer.md",
    "content": "# FormDrawer\n\n> Drawer form, mainly used in simple event to open form scene\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  FormDrawer,\n  FormItem,\n  Input,\n  Submit,\n  Reset,\n  FormButtonGroup,\n  FormLayout,\n} from '@formily/next'\nimport { createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        FormDrawer('Drawer Form', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={14}>\n              <SchemaField>\n                <SchemaField.String\n                  name=\"aaa\"\n                  required\n                  title=\"input box 1\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"bbb\"\n                  required\n                  title=\"input box 2\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"ccc\"\n                  required\n                  title=\"input box 3\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"ddd\"\n                  required\n                  title=\"input box 4\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n              </SchemaField>\n              <FormDrawer.Footer>\n                <FormButtonGroup align=\"right\">\n                  <Submit\n                    onSubmit={() => {\n                      return new Promise((resolve) => {\n                        setTimeout(resolve, 1000)\n                      })\n                    }}\n                  >\n                    Submit\n                  </Submit>\n                  <Reset>Reset</Reset>\n                </FormButtonGroup>\n              </FormDrawer.Footer>\n            </FormLayout>\n          )\n        })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      Click me to open the form\n    </Button>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  FormDrawer,\n  FormItem,\n  Input,\n  Submit,\n  Reset,\n  FormButtonGroup,\n  FormLayout,\n} from '@formily/next'\nimport { createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    aaa: {\n      type: 'string',\n      title: 'input box 1',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    bbb: {\n      type: 'string',\n      title: 'input box 2',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    ccc: {\n      type: 'string',\n      title: 'input box 3',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    ddd: {\n      type: 'string',\n      title: 'input box 4',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        FormDrawer('Pop-up form', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={14}>\n              <SchemaField schema={schema} />\n              <FormDrawer.Footer>\n                <FormButtonGroup align=\"right\">\n                  <Submit\n                    onSubmit={() => {\n                      return new Promise((resolve) => {\n                        setTimeout(resolve, 1000)\n                      })\n                    }}\n                  >\n                    Submit\n                  </Submit>\n                  <Reset>Reset</Reset>\n                </FormButtonGroup>\n              </FormDrawer.Footer>\n            </FormLayout>\n          )\n        })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      Click me to open the form\n    </Button>\n  )\n}\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport {\n  FormDrawer,\n  FormItem,\n  Input,\n  Submit,\n  Reset,\n  FormButtonGroup,\n  FormLayout,\n} from '@formily/next'\nimport { Field } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        FormDrawer('Pop-up form', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={14}>\n              <Field\n                name=\"aaa\"\n                required\n                title=\"input box 1\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"bbb\"\n                required\n                title=\"input box 2\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"ccc\"\n                required\n                title=\"input box 3\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"ddd\"\n                required\n                title=\"input box 4\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <FormDrawer.Footer>\n                <FormButtonGroup align=\"right\">\n                  <Submit\n                    onSubmit={() => {\n                      return new Promise((resolve) => {\n                        setTimeout(resolve, 1000)\n                      })\n                    }}\n                  >\n                    Submit\n                  </Submit>\n                  <Reset>Reset</Reset>\n                </FormButtonGroup>\n              </FormDrawer.Footer>\n            </FormLayout>\n          )\n        })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      Click me to open the form\n    </Button>\n  )\n}\n```\n\n## Use Fusion Context\n\n```tsx\nimport React from 'react'\nimport {\n  FormDrawer,\n  FormItem,\n  Input,\n  Submit,\n  Reset,\n  FormButtonGroup,\n  FormLayout,\n} from '@formily/next'\nimport { Field } from '@formily/react'\nimport { Button, ConfigProvider } from '@alifd/next'\n\nexport default () => {\n  return (\n    <ConfigProvider\n      defaultPropsConfig={{\n        Drawer: {},\n      }}\n    >\n      <Button\n        onClick={() => {\n          FormDrawer('Pop-up form', () => {\n            return (\n              <FormLayout labelCol={6} wrapperCol={14}>\n                <Field\n                  name=\"aaa\"\n                  required\n                  title=\"input box 1\"\n                  decorator={[FormItem]}\n                  component={[Input]}\n                />\n                <Field\n                  name=\"bbb\"\n                  required\n                  title=\"input box 2\"\n                  decorator={[FormItem]}\n                  component={[Input]}\n                />\n                <Field\n                  name=\"ccc\"\n                  required\n                  title=\"input box 3\"\n                  decorator={[FormItem]}\n                  component={[Input]}\n                />\n                <Field\n                  name=\"ddd\"\n                  required\n                  title=\"input box 4\"\n                  decorator={[FormItem]}\n                  component={[Input]}\n                />\n                <FormDrawer.Footer>\n                  <FormButtonGroup align=\"right\">\n                    <Submit\n                      onSubmit={() => {\n                        return new Promise((resolve) => {\n                          setTimeout(resolve, 1000)\n                        })\n                      }}\n                    >\n                      Submit\n                    </Submit>\n                    <Reset>Reset</Reset>\n                  </FormButtonGroup>\n                </FormDrawer.Footer>\n              </FormLayout>\n            )\n          })\n            .open({\n              initialValues: {\n                aaa: '123',\n              },\n            })\n            .then(console.log)\n        }}\n      >\n        Click me to open the form\n      </Button>\n    </ConfigProvider>\n  )\n}\n```\n\n## API\n\n### FormDrawer\n\n```ts pure\nimport { IFormProps, Form } from '@formily/core'\n\ntype FormDrawerRenderer =\n  | React.ReactElement\n  | ((form: Form) => React.ReactElement)\n\ninterface IFormDrawer {\n  forOpen(\n    middleware: (\n      props: IFormProps,\n      next: (props?: IFormProps) => Promise<any>\n    ) => any\n  ): any //Middleware interceptor, can intercept Drawer to open\n  //Open the pop-up window to receive form attributes, you can pass in initialValues/values/effects etc.\n  open(props: IFormProps): Promise<any> //return form data\n  //Close the pop-up window\n  close(): void\n}\n\ninterface IDrawerProps extends DrawerProps {\n  onClose?: (reason: string, e: React.MouseEvent) => void | boolean // return false can prevent onClose\n  loadingText?: React.ReactNode\n}\n\ninterface FormDrawer {\n  (title: IDrawerProps, id: string, renderer: FormDrawerRenderer): IFormDrawer\n  (title: IDrawerProps, renderer: FormDrawerRenderer): IFormDrawer\n  (title: ModalTitle, id: string, renderer: FormDrawerRenderer): IFormDrawer\n  (title: ModalTitle, renderer: FormDrawerRenderer): IFormDrawer\n}\n```\n\n`DrawerProps` type definition reference ant design [Drawer API](https://fusion.design/pc/component/drawer?themeid=2#API)\n\n### FormDrawer.Footer\n\nNo attributes, only child nodes are received\n\n### FormDrawer.Portal\n\nReceive an optional id attribute, the default value is `form-drawer`, if there are multiple prefixCls in an application, and the prefixCls in the pop-up window of different regions are different, then it is recommended to specify the id as the region-level id\n"
  },
  {
    "path": "packages/next/docs/components/FormDrawer.zh-CN.md",
    "content": "# FormDrawer\n\n> 抽屉表单，主要用在简单的事件打开表单场景\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormDrawer,\n  FormItem,\n  Input,\n  Submit,\n  Reset,\n  FormButtonGroup,\n  FormLayout,\n} from '@formily/next'\nimport { createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        FormDrawer('抽屉表单', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={10}>\n              <SchemaField>\n                <SchemaField.String\n                  name=\"aaa\"\n                  required\n                  title=\"输入框1\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"bbb\"\n                  required\n                  title=\"输入框2\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"ccc\"\n                  required\n                  title=\"输入框3\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n                <SchemaField.String\n                  name=\"ddd\"\n                  required\n                  title=\"输入框4\"\n                  x-decorator=\"FormItem\"\n                  x-component=\"Input\"\n                />\n              </SchemaField>\n              <FormDrawer.Footer>\n                <FormButtonGroup align=\"right\">\n                  <Submit\n                    onSubmit={() => {\n                      return new Promise((resolve) => {\n                        setTimeout(resolve, 1000)\n                      })\n                    }}\n                  >\n                    提交\n                  </Submit>\n                  <Reset>重置</Reset>\n                </FormButtonGroup>\n              </FormDrawer.Footer>\n            </FormLayout>\n          )\n        })\n          .forOpen((props, next) => {\n            setTimeout(() => {\n              next()\n            }, 1000)\n          })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      点我打开表单\n    </Button>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormDrawer,\n  FormItem,\n  Input,\n  Submit,\n  Reset,\n  FormButtonGroup,\n  FormLayout,\n} from '@formily/next'\nimport { createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    aaa: {\n      type: 'string',\n      title: '输入框1',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    bbb: {\n      type: 'string',\n      title: '输入框2',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    ccc: {\n      type: 'string',\n      title: '输入框3',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n    ddd: {\n      type: 'string',\n      title: '输入框4',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        FormDrawer('弹窗表单', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={14}>\n              <SchemaField schema={schema} />\n              <FormDrawer.Footer>\n                <FormButtonGroup align=\"right\">\n                  <Submit\n                    onSubmit={() => {\n                      return new Promise((resolve) => {\n                        setTimeout(resolve, 1000)\n                      })\n                    }}\n                  >\n                    提交\n                  </Submit>\n                  <Reset>重置</Reset>\n                </FormButtonGroup>\n              </FormDrawer.Footer>\n            </FormLayout>\n          )\n        })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      点我打开表单\n    </Button>\n  )\n}\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormDrawer,\n  FormItem,\n  Input,\n  Submit,\n  Reset,\n  FormButtonGroup,\n  FormLayout,\n} from '@formily/next'\nimport { Field } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nexport default () => {\n  return (\n    <Button\n      onClick={() => {\n        FormDrawer('弹窗表单', () => {\n          return (\n            <FormLayout labelCol={6} wrapperCol={14}>\n              <Field\n                name=\"aaa\"\n                required\n                title=\"输入框1\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"bbb\"\n                required\n                title=\"输入框2\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"ccc\"\n                required\n                title=\"输入框3\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <Field\n                name=\"ddd\"\n                required\n                title=\"输入框4\"\n                decorator={[FormItem]}\n                component={[Input]}\n              />\n              <FormDrawer.Footer>\n                <FormButtonGroup align=\"right\">\n                  <Submit\n                    onSubmit={() => {\n                      return new Promise((resolve) => {\n                        setTimeout(resolve, 1000)\n                      })\n                    }}\n                  >\n                    提交\n                  </Submit>\n                  <Reset>重置</Reset>\n                </FormButtonGroup>\n              </FormDrawer.Footer>\n            </FormLayout>\n          )\n        })\n          .open({\n            initialValues: {\n              aaa: '123',\n            },\n          })\n          .then(console.log)\n      }}\n    >\n      点我打开表单\n    </Button>\n  )\n}\n```\n\n## 使用 Fusion Context\n\n```tsx\nimport React from 'react'\nimport {\n  FormDrawer,\n  FormItem,\n  Input,\n  Submit,\n  Reset,\n  FormButtonGroup,\n  FormLayout,\n} from '@formily/next'\nimport { Field } from '@formily/react'\nimport { Button, ConfigProvider } from '@alifd/next'\n\nexport default () => {\n  return (\n    <ConfigProvider\n      defaultPropsConfig={{\n        Drawer: {},\n      }}\n    >\n      <Button\n        onClick={() => {\n          FormDrawer('弹窗表单', () => {\n            return (\n              <FormLayout labelCol={6} wrapperCol={14}>\n                <Field\n                  name=\"aaa\"\n                  required\n                  title=\"输入框1\"\n                  decorator={[FormItem]}\n                  component={[Input]}\n                />\n                <Field\n                  name=\"bbb\"\n                  required\n                  title=\"输入框2\"\n                  decorator={[FormItem]}\n                  component={[Input]}\n                />\n                <Field\n                  name=\"ccc\"\n                  required\n                  title=\"输入框3\"\n                  decorator={[FormItem]}\n                  component={[Input]}\n                />\n                <Field\n                  name=\"ddd\"\n                  required\n                  title=\"输入框4\"\n                  decorator={[FormItem]}\n                  component={[Input]}\n                />\n                <FormDrawer.Footer>\n                  <FormButtonGroup align=\"right\">\n                    <Submit\n                      onSubmit={() => {\n                        return new Promise((resolve) => {\n                          setTimeout(resolve, 1000)\n                        })\n                      }}\n                    >\n                      提交\n                    </Submit>\n                    <Reset>重置</Reset>\n                  </FormButtonGroup>\n                </FormDrawer.Footer>\n              </FormLayout>\n            )\n          })\n            .open({\n              initialValues: {\n                aaa: '123',\n              },\n            })\n            .then(console.log)\n        }}\n      >\n        点我打开表单\n      </Button>\n    </ConfigProvider>\n  )\n}\n```\n\n## API\n\n### FormDrawer\n\n## API\n\n### FormDrawer\n\n```ts pure\nimport { IFormProps, Form } from '@formily/core'\n\ntype FormDrawerRenderer =\n  | React.ReactElement\n  | ((form: Form) => React.ReactElement)\n\ninterface IFormDrawer {\n  forOpen(\n    middleware: (\n      props: IFormProps,\n      next: (props?: IFormProps) => Promise<any>\n    ) => any\n  ): any //中间件拦截器，可以拦截Drawer打开\n  //打开弹窗，接收表单属性，可以传入initialValues/values/effects etc.\n  open(props: IFormProps): Promise<any> //返回表单数据\n  //关闭弹窗\n  close(): void\n}\n\ninterface IDrawerProps extends DrawerProps {\n  onClose?: (reason: string, e: React.MouseEvent) => void | boolean // return false can prevent onClose\n  loadingText?: React.ReactNode\n}\n\ninterface FormDrawer {\n  (title: IDrawerProps, id: string, renderer: FormDrawerRenderer): IFormDrawer\n  (title: IDrawerProps, renderer: FormDrawerRenderer): IFormDrawer\n  (title: ModalTitle, id: string, renderer: FormDrawerRenderer): IFormDrawer\n  (title: ModalTitle, renderer: FormDrawerRenderer): IFormDrawer\n}\n```\n\n`DrawerProps` 类型定义参考 fusion [Drawer API](https://fusion.design/pc/component/drawer?themeid=2#API)\n\n### FormDrawer.Footer\n\n无属性，只接收子节点\n\n### FormDrawer.Portal\n\n接收可选的 id 属性，默认值为`form-drawer`，如果一个应用存在多个 prefixCls，不同区域的弹窗内部 prefixCls 不一样，那推荐指定 id 为区域级 id\n"
  },
  {
    "path": "packages/next/docs/components/FormGrid.md",
    "content": "# FormGrid\n\n> FormGrid component\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { FormItem, Input, FormGrid } from '@formily/next'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { createForm } from '@formily/core'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    FormGrid,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Void\n          x-component=\"FormGrid\"\n          x-component-props={{\n            maxColumns: 3,\n            minColumns: 2,\n          }}\n        >\n          <SchemaField.String\n            name=\"aaa\"\n            title=\"aaa\"\n            x-decorator=\"FormItem\"\n            x-decorator-props={{ gridSpan: 2 }}\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"bbb\"\n            title=\"bbb\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"ccc\"\n            title=\"ccc\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"ddd\"\n            title=\"ddd\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"eee\"\n            title=\"eee\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"fff\"\n            title=\"fff\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"ggg\"\n            title=\"ggg\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n        </SchemaField.Void>\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { FormItem, Input, FormGrid } from '@formily/next'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { createForm } from '@formily/core'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    FormGrid,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    grid: {\n      type: 'void',\n      'x-component': 'FormGrid',\n      'x-component-props': {\n        minColumns: [4, 6, 10],\n      },\n      properties: {\n        aaa: {\n          type: 'string',\n          title: 'AAA',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        bbb: {\n          type: 'string',\n          title: 'BBB',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ccc: {\n          type: 'string',\n          title: 'CCC',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ddd: {\n          type: 'string',\n          title: 'DDD',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        eee: {\n          type: 'string',\n          title: 'EEE',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        fff: {\n          type: 'string',\n          title: 'FFF',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ggg: {\n          type: 'string',\n          title: 'GGG',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n    </FormProvider>\n  )\n}\n```\n\n## Native case\n\n```tsx\nimport React from 'react'\nimport { FormGrid } from '@formily/next'\n\nconst { GridColumn } = FormGrid\nconst Cell = ({ children }) => {\n  return (\n    <div\n      style={{\n        backgroundColor: '#AAA',\n        color: '#FFF',\n        height: 30,\n        display: 'flex',\n        alignItems: 'center',\n        padding: '0 10px',\n      }}\n    >\n      {children}\n    </div>\n  )\n}\nexport default () => {\n  return (\n    <React.Fragment>\n      <p>maxColumns 3 + minColumns 2</p>\n      <FormGrid maxColumns={3} minColumns={2} columnGap={4}>\n        <GridColumn gridSpan={4}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>maxColumns 3</p>\n      <FormGrid maxColumns={3} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>minColumns 2</p>\n      <FormGrid minColumns={2} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>Null</p>\n      <FormGrid columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>minWidth 150 +maxColumns 3</p>\n      <FormGrid minWidth={150} maxColumns={3} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>maxWidth 120+minColumns 2</p>\n      <FormGrid maxWidth={120} minColumns={2} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>maxWidth 120 + gridSpan -1</p>\n      <FormGrid maxWidth={120} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn gridSpan={-1}>\n          <Cell>3</Cell>\n        </GridColumn>\n      </FormGrid>\n    </React.Fragment>\n  )\n}\n```\n\n## Query Form case\n\n```tsx\nimport React, { useMemo, Fragment } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider, observer } from '@formily/react'\nimport {\n  Form,\n  Input,\n  Select,\n  DatePicker,\n  FormItem,\n  FormGrid,\n  Submit,\n  Reset,\n  FormButtonGroup,\n} from '@formily/next'\n\nconst useCollapseGrid = (maxRows: number) => {\n  const grid = useMemo(\n    () =>\n      FormGrid.createFormGrid({\n        maxColumns: 4,\n        maxWidth: 240,\n        maxRows: maxRows,\n        shouldVisible: (node, grid) => {\n          if (node.index === grid.childSize - 1) return true\n          if (grid.maxRows === Infinity) return true\n          return node.shadowRow < maxRows + 1\n        },\n      }),\n    []\n  )\n  const expanded = grid.maxRows === Infinity\n  const realRows = grid.shadowRows\n  const computeRows = grid.fullnessLastColumn\n    ? grid.shadowRows - 1\n    : grid.shadowRows\n\n  const toggle = () => {\n    if (grid.maxRows === Infinity) {\n      grid.maxRows = maxRows\n    } else {\n      grid.maxRows = Infinity\n    }\n  }\n  const takeType = () => {\n    if (realRows < maxRows + 1) return 'incomplete-wrap'\n    if (computeRows > maxRows) return 'collapsible'\n    return 'complete-wrap'\n  }\n  return {\n    grid,\n    expanded,\n    toggle,\n    type: takeType(),\n  }\n}\n\nconst QueryForm: React.FC = observer((props) => {\n  const { grid, expanded, toggle, type } = useCollapseGrid(1)\n\n  const renderActions = () => {\n    return (\n      <Fragment>\n        <Submit onSubmit={console.log}>Query</Submit>\n        <Reset>Reset</Reset>\n      </Fragment>\n    )\n  }\n\n  const renderButtonGroup = () => {\n    if (type === 'incomplete-wrap') {\n      return (\n        <FormButtonGroup.FormItem>\n          <FormButtonGroup>{renderActions()}</FormButtonGroup>\n        </FormButtonGroup.FormItem>\n      )\n    }\n    if (type === 'collapsible') {\n      return (\n        <Fragment>\n          <FormButtonGroup>\n            <a\n              href=\"\"\n              onClick={(e) => {\n                e.preventDefault()\n                toggle()\n              }}\n            >\n              {expanded ? 'Fold' : 'UnFold'}\n            </a>\n          </FormButtonGroup>\n          <FormButtonGroup align=\"right\">{renderActions()}</FormButtonGroup>\n        </Fragment>\n      )\n    }\n    return (\n      <FormButtonGroup align=\"right\" style={{ display: 'flex', width: '100%' }}>\n        {renderActions()}\n      </FormButtonGroup>\n    )\n  }\n\n  return (\n    <Form {...props} layout=\"vertical\" feedbackLayout=\"terse\">\n      <FormGrid grid={grid}>\n        {props.children}\n        <FormGrid.GridColumn\n          gridSpan={-1}\n          style={{ display: 'flex', justifyContent: 'space-between' }}\n        >\n          {renderButtonGroup()}\n        </FormGrid.GridColumn>\n      </FormGrid>\n    </Form>\n  )\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    QueryForm,\n    Input,\n    Select,\n    DatePicker,\n    FormItem,\n  },\n})\n\nexport default () => {\n  const form = useMemo(() => createForm(), [])\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Object x-component=\"QueryForm\">\n          <SchemaField.String\n            name=\"input1\"\n            title=\"Input 1\"\n            x-component=\"Input\"\n            x-decorator=\"FormItem\"\n          />\n          <SchemaField.String\n            name=\"input2\"\n            title=\"Input 2\"\n            x-component=\"Input\"\n            x-decorator=\"FormItem\"\n          />\n\n          <SchemaField.String\n            name=\"select1\"\n            title=\"Select 1\"\n            x-component=\"Select\"\n            x-decorator=\"FormItem\"\n          />\n          <SchemaField.String\n            name=\"select2\"\n            title=\"Select 2\"\n            x-component=\"Select\"\n            x-decorator=\"FormItem\"\n          />\n          <SchemaField.String\n            name=\"date\"\n            title=\"DatePicker\"\n            x-component=\"DatePicker\"\n            x-decorator=\"FormItem\"\n          />\n          <SchemaField.String\n            name=\"dateRange\"\n            title=\"DatePicker.RangePicker\"\n            x-component=\"DatePicker.RangePicker\"\n            x-decorator=\"FormItem\"\n            x-decorator-props={{\n              gridSpan: 2,\n            }}\n          />\n          <SchemaField.String\n            name=\"select3\"\n            title=\"Select 3\"\n            x-component=\"Select\"\n            x-decorator=\"FormItem\"\n          />\n        </SchemaField.Object>\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormGrid\n\n| Property name | Type                   | Description                                                                       | Default value     |\n| ------------- | ---------------------- | --------------------------------------------------------------------------------- | ----------------- |\n| minWidth      | `number \\| number[]`   | Minimum element width                                                             | 100               |\n| maxWidth      | `number \\| number[]`   | Maximum element width                                                             | -                 |\n| minColumns    | `number \\| number[]`   | Minimum number of columns                                                         | 0                 |\n| maxColumns    | `number \\| number[]`   | Maximum number of columns                                                         | -                 |\n| breakpoints   | number[]               | Container size breakpoints                                                        | `[720,1280,1920]` |\n| columnGap     | number                 | Column spacing                                                                    | 8                 |\n| rowGap        | number                 | Row spacing                                                                       | 4                 |\n| colWrap       | boolean                | Wrap                                                                              | true              |\n| strictAutoFit | boolean                | Is width strictly limited by maxWidth                                             | false             |\n| shouldVisible | `(node,grid)=>boolean` | Whether to show the current node                                                  | `()=>true`        |\n| grid          | `Grid`                 | Grid instance passed in from outside, used to implement more complex layout logic | -                 |\n\nnote:\n\n- minWidth takes priority over minColumn\n- maxWidth has priority over maxColumn\n- The array format of minWidth/maxWidth/minColumns/maxColumns represents the mapping with the breakpoint array\n\n### FormGrid.GridColumn\n\n| Property name | Type   | Description                                                                                                              | Default value |\n| ------------- | ------ | ------------------------------------------------------------------------------------------------------------------------ | ------------- |\n| gridSpan      | number | The number of columns spanned by the element, if it is -1, it will automatically fill the cell across columns in reverse | 1             |\n\n### FormGrid.createFormGrid\n\nRead the Grid instance from the context\n\n```ts\ninterface createFormGrid {\n  (props: IGridProps): Grid\n}\n```\n\n- IGridProps reference FormGrid properties\n- Grid instance attribute method reference https://github.com/alibaba/formily/tree/formily_next/packages/grid\n\n### FormGrid.useFormGrid\n\nRead the Grid instance from the context\n\n```ts\ninterface useFormGrid {\n  (): Grid\n}\n```\n\n- Grid instance attribute method reference https://github.com/alibaba/formily/tree/formily_next/packages/grid\n"
  },
  {
    "path": "packages/next/docs/components/FormGrid.zh-CN.md",
    "content": "# FormGrid\n\n> FormGrid 组件\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { FormItem, Input, FormGrid } from '@formily/next'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { createForm } from '@formily/core'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    FormGrid,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Void\n          x-component=\"FormGrid\"\n          x-component-props={{\n            maxColumns: 3,\n            minColumns: 2,\n          }}\n        >\n          <SchemaField.String\n            name=\"aaa\"\n            title=\"aaa\"\n            x-decorator=\"FormItem\"\n            x-decorator-props={{ gridSpan: 2 }}\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"bbb\"\n            title=\"bbb\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"ccc\"\n            title=\"ccc\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"ddd\"\n            title=\"ddd\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"eee\"\n            title=\"eee\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"fff\"\n            title=\"fff\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n          <SchemaField.String\n            name=\"ggg\"\n            title=\"ggg\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n          />\n        </SchemaField.Void>\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { FormItem, Input, FormGrid } from '@formily/next'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { createForm } from '@formily/core'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    Input,\n    FormGrid,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    grid: {\n      type: 'void',\n      'x-component': 'FormGrid',\n      'x-component-props': {\n        minColumns: [4, 6, 10],\n      },\n      properties: {\n        aaa: {\n          type: 'string',\n          title: 'AAA',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        bbb: {\n          type: 'string',\n          title: 'BBB',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ccc: {\n          type: 'string',\n          title: 'CCC',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ddd: {\n          type: 'string',\n          title: 'DDD',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        eee: {\n          type: 'string',\n          title: 'EEE',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        fff: {\n          type: 'string',\n          title: 'FFF',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n        ggg: {\n          type: 'string',\n          title: 'GGG',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} />\n    </FormProvider>\n  )\n}\n```\n\n## 原生 案例\n\n```tsx\nimport React from 'react'\nimport { FormGrid } from '@formily/next'\n\nconst { GridColumn } = FormGrid\nconst Cell = ({ children }) => {\n  return (\n    <div\n      style={{\n        backgroundColor: '#AAA',\n        color: '#FFF',\n        height: 30,\n        display: 'flex',\n        alignItems: 'center',\n        padding: '0 10px',\n      }}\n    >\n      {children}\n    </div>\n  )\n}\nexport default () => {\n  return (\n    <React.Fragment>\n      <p>maxColumns 3 + minColumns 2</p>\n      <FormGrid maxColumns={3} minColumns={2} columnGap={4}>\n        <GridColumn gridSpan={4}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>maxColumns 3</p>\n      <FormGrid maxColumns={3} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>minColumns 2</p>\n      <FormGrid minColumns={2} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>Null</p>\n      <FormGrid columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>minWidth 150 +maxColumns 3</p>\n      <FormGrid minWidth={150} maxColumns={3} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>maxWidth 120+minColumns 2</p>\n      <FormGrid maxWidth={120} minColumns={2} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>3</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>4</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>5</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>6</Cell>\n        </GridColumn>\n      </FormGrid>\n      <p>maxWidth 120 + gridSpan -1</p>\n      <FormGrid maxWidth={120} columnGap={4}>\n        <GridColumn gridSpan={2}>\n          <Cell>1</Cell>\n        </GridColumn>\n        <GridColumn>\n          <Cell>2</Cell>\n        </GridColumn>\n        <GridColumn gridSpan={-1}>\n          <Cell>3</Cell>\n        </GridColumn>\n      </FormGrid>\n    </React.Fragment>\n  )\n}\n```\n\n## 查询表单实现案例\n\n```tsx\nimport React, { useMemo, Fragment } from 'react'\nimport { createForm } from '@formily/core'\nimport { createSchemaField, FormProvider, observer } from '@formily/react'\nimport {\n  Form,\n  Input,\n  Select,\n  DatePicker,\n  FormItem,\n  FormGrid,\n  Submit,\n  Reset,\n  FormButtonGroup,\n} from '@formily/next'\n\nconst useCollapseGrid = (maxRows: number) => {\n  const grid = useMemo(\n    () =>\n      FormGrid.createFormGrid({\n        maxColumns: 4,\n        maxWidth: 240,\n        maxRows: maxRows,\n        shouldVisible: (node, grid) => {\n          if (node.index === grid.childSize - 1) return true\n          if (grid.maxRows === Infinity) return true\n          return node.shadowRow < maxRows + 1\n        },\n      }),\n    []\n  )\n  const expanded = grid.maxRows === Infinity\n  const realRows = grid.shadowRows\n  const computeRows = grid.fullnessLastColumn\n    ? grid.shadowRows - 1\n    : grid.shadowRows\n\n  const toggle = () => {\n    if (grid.maxRows === Infinity) {\n      grid.maxRows = maxRows\n    } else {\n      grid.maxRows = Infinity\n    }\n  }\n  const takeType = () => {\n    if (realRows < maxRows + 1) return 'incomplete-wrap'\n    if (computeRows > maxRows) return 'collapsible'\n    return 'complete-wrap'\n  }\n  return {\n    grid,\n    expanded,\n    toggle,\n    type: takeType(),\n  }\n}\n\nconst QueryForm: React.FC = observer((props) => {\n  const { grid, expanded, toggle, type } = useCollapseGrid(1)\n\n  const renderActions = () => {\n    return (\n      <Fragment>\n        <Submit onSubmit={console.log}>查询</Submit>\n        <Reset>重置</Reset>\n      </Fragment>\n    )\n  }\n\n  const renderButtonGroup = () => {\n    if (type === 'incomplete-wrap') {\n      return (\n        <FormButtonGroup.FormItem>\n          <FormButtonGroup>{renderActions()}</FormButtonGroup>\n        </FormButtonGroup.FormItem>\n      )\n    }\n    if (type === 'collapsible') {\n      return (\n        <Fragment>\n          <FormButtonGroup>\n            <a\n              href=\"\"\n              onClick={(e) => {\n                e.preventDefault()\n                toggle()\n              }}\n            >\n              {expanded ? '收起' : '展开'}\n            </a>\n          </FormButtonGroup>\n          <FormButtonGroup align=\"right\">{renderActions()}</FormButtonGroup>\n        </Fragment>\n      )\n    }\n    return (\n      <FormButtonGroup align=\"right\" style={{ display: 'flex', width: '100%' }}>\n        {renderActions()}\n      </FormButtonGroup>\n    )\n  }\n\n  return (\n    <Form {...props} layout=\"vertical\" feedbackLayout=\"terse\">\n      <FormGrid grid={grid}>\n        {props.children}\n        <FormGrid.GridColumn\n          gridSpan={-1}\n          style={{ display: 'flex', justifyContent: 'space-between' }}\n        >\n          {renderButtonGroup()}\n        </FormGrid.GridColumn>\n      </FormGrid>\n    </Form>\n  )\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    QueryForm,\n    Input,\n    Select,\n    DatePicker,\n    FormItem,\n  },\n})\n\nexport default () => {\n  const form = useMemo(() => createForm(), [])\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Object x-component=\"QueryForm\">\n          <SchemaField.String\n            name=\"input1\"\n            title=\"Input 1\"\n            x-component=\"Input\"\n            x-decorator=\"FormItem\"\n          />\n          <SchemaField.String\n            name=\"input2\"\n            title=\"Input 2\"\n            x-component=\"Input\"\n            x-decorator=\"FormItem\"\n          />\n\n          <SchemaField.String\n            name=\"select1\"\n            title=\"Select 1\"\n            x-component=\"Select\"\n            x-decorator=\"FormItem\"\n          />\n          <SchemaField.String\n            name=\"select2\"\n            title=\"Select 2\"\n            x-component=\"Select\"\n            x-decorator=\"FormItem\"\n          />\n          <SchemaField.String\n            name=\"date\"\n            title=\"DatePicker\"\n            x-component=\"DatePicker\"\n            x-decorator=\"FormItem\"\n          />\n          <SchemaField.String\n            name=\"dateRange\"\n            title=\"DatePicker.RangePicker\"\n            x-component=\"DatePicker.RangePicker\"\n            x-decorator=\"FormItem\"\n            x-decorator-props={{\n              gridSpan: 2,\n            }}\n          />\n          <SchemaField.String\n            name=\"select3\"\n            title=\"Select 3\"\n            x-component=\"Select\"\n            x-decorator=\"FormItem\"\n          />\n        </SchemaField.Object>\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormGrid\n\n| 属性名        | 类型                   | 描述                                                           | 默认值            |\n| ------------- | ---------------------- | -------------------------------------------------------------- | ----------------- |\n| minWidth      | `number \\| number[]`   | 元素最小宽度                                                   | 100               |\n| maxWidth      | `number \\| number[]`   | 元素最大宽度                                                   | -                 |\n| minColumns    | `number \\| number[]`   | 最小列数                                                       | 0                 |\n| maxColumns    | `number \\| number[]`   | 最大列数                                                       | -                 |\n| breakpoints   | number[]               | 容器尺寸断点                                                   | `[720,1280,1920]` |\n| columnGap     | number                 | 列间距                                                         | 8                 |\n| rowGap        | number                 | 行间距                                                         | 4                 |\n| colWrap       | boolean                | 自动换行                                                       | true              |\n| strictAutoFit | boolean                | GridItem 宽度是否严格受限于 maxWidth，不受限的话会自动占满容器 | false             |\n| shouldVisible | `(node,grid)=>boolean` | 是否需要显示当前节点                                           | `()=>true`        |\n| grid          | `Grid`                 | 外部传入 Grid 实例，用于实现更复杂的布局逻辑                   | -                 |\n\n注意：\n\n- minWidth 生效优先级高于 minColumn\n- maxWidth 优先级高于 maxColumn\n- minWidth/maxWidth/minColumns/maxColumns 的数组格式代表与断点数组映射\n\n### FormGrid.GridColumn\n\n| 属性名   | 类型   | 描述                                                 | 默认值 |\n| -------- | ------ | ---------------------------------------------------- | ------ |\n| gridSpan | number | 元素所跨列数，如果为-1，那么会自动反向跨列填补单元格 | 1      |\n\n### FormGrid.createFormGrid\n\n从上下文中读取 Grid 实例\n\n```ts\ninterface createFormGrid {\n  (props: IGridProps): Grid\n}\n```\n\n- IGridProps 参考 FormGrid 属性\n- Grid 实例属性方法参考 https://github.com/alibaba/formily/tree/formily_next/packages/grid\n\n### FormGrid.useFormGrid\n\n从上下文中读取 Grid 实例\n\n```ts\ninterface useFormGrid {\n  (): Grid\n}\n```\n\n- Grid 实例属性方法参考 https://github.com/alibaba/formily/tree/formily_next/packages/grid\n"
  },
  {
    "path": "packages/next/docs/components/FormItem.md",
    "content": "# FormItem\n\n> The brand new FormItem component, compared to Fusion Next’s FormItem, it supports more functions. At the same time, it is positioned as a pure style component and does not manage form status, so it will be lighter and more convenient for customization\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { Input, Select, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        required\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JOSN Schema case\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      title: 'input box',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"input\"\n      title=\"input box\"\n      required\n      decorator={[FormItem]}\n      component={[\n        Input,\n        {\n          style: {\n            width: 240,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Commonly used attribute cases\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  FormItem,\n  NumberPicker,\n  Switch,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst Title = (props) => <h3>{props.text}</h3>\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Title,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: 'Display when label is empty' }}\n        />\n        <SchemaField.String\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n          }}\n        />\n        <SchemaField.String\n          title=\"\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n          }}\n        />\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: 'colon' }}\n        />\n        <SchemaField.String\n          title=\"default\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n        <SchemaField.String\n          title=\"no colon (colon=false)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            colon: false,\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: 'Fixed width settings' }}\n        />\n        <SchemaField.String\n          title=\"Fixed label width (labelWidth)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n          }}\n        />\n        <SchemaField.String\n          title=\"Fixed label width (labelWidth) overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow overflow\"\n          description=\"description description\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            tooltip: 'Prompt Tip',\n            tooltipLayout: 'text',\n          }}\n        />\n        <SchemaField.String\n          title=\"Fixed label width (labelWidth) newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline newline\"\n          description=\"description description\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            labelWrap: true,\n            tooltip: 'Prompt Tip',\n          }}\n        />\n        <SchemaField.String\n          title=\"fixed content width (wrapperWidth)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            wrapperWidth: 300,\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: 'Alignment settings' }}\n        />\n        <SchemaField.String\n          title=\"labelLeft Alignment(labelAlign=left)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            labelAlign: 'left',\n          }}\n        />\n        <SchemaField.String\n          title=\"label right alignment (labelAlign=right default)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            labelAlign: 'right',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Content left aligned (wrapperAlign=left default)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            wrapperWidth: 240,\n            wrapperAlign: 'left',\n          }}\n        />\n        <SchemaField.String\n          title=\"Content align right (wrapperAlign=right)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            wrapperWidth: 240,\n            wrapperAlign: 'right',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"tooltip\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            tooltip: 'tooltip',\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: 'Is it full?' }}\n        />\n\n        <SchemaField.String\n          title=\"The default is fullness(fullness=true)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n        />\n        <SchemaField.String\n          title=\"Not fullness(fullness=false)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          x-decorator-props={{\n            fullness: false,\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: 'auxiliary information' }}\n        />\n\n        <SchemaField.String\n          title=\"Required asterisk\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            asterisk: true,\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n\n        <SchemaField.String\n          title=\"prefix\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            addonBefore: 'addonBefore',\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n        <SchemaField.String\n          title=\"suffix\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            addonAfter: 'addonAfter',\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Help information feedbackText\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackText: 'feedbackText',\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n\n        <SchemaField.String\n          title=\"extra information extra\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackText: 'feedbackText',\n            extra: 'extra',\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## Borderless case\n\nSet to remove the component border\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  FormItem,\n  NumberPicker,\n  Switch,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst Title = (props) => <h3>{props.text}</h3>\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Title,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"input\"\n          title=\"Input\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"Select\"\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"Select\"\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"Cascader\"\n          title=\"Cascader\"\n          x-decorator=\"FormItem\"\n          x-component=\"Cascader\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"DatePicker\"\n          title=\"DatePicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"NumberPicker\"\n          title=\"NumberPicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"NumberPicker\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"TreeSelect\"\n          title=\"TreeSelect\"\n          x-decorator=\"FormItem\"\n          x-component=\"TreeSelect\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.Boolean\n          name=\"Switch\"\n          title=\"Switch\"\n          x-decorator=\"FormItem\"\n          x-component=\"Switch\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## Embedded mode case\n\nSet the form component to inline mode\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  FormItem,\n  NumberPicker,\n  Switch,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst Title = (props) => <h3>{props.text}</h3>\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Title,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"input\"\n          title=\"Input\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"Select\"\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"Select\"\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"Cascader\"\n          title=\"Cascader\"\n          x-decorator=\"FormItem\"\n          x-component=\"Cascader\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"DatePicker\"\n          title=\"DatePicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"NumberPicker\"\n          title=\"NumberPicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"NumberPicker\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"TreeSelect\"\n          title=\"TreeSelect\"\n          x-decorator=\"FormItem\"\n          x-component=\"TreeSelect\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.Boolean\n          name=\"Switch\"\n          title=\"Switch\"\n          x-decorator=\"FormItem\"\n          x-component=\"Switch\"\n          required\n          x-decorator-props={{\n            inset: false,\n          }}\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## Feedback Customization Case\n\nThe button for specifying feedback can be passed in through `feedbackIcon`\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  TimePicker,\n  FormItem,\n  FormLayout,\n  NumberPicker,\n  Switch,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { CheckCircleFilled, LoadingOutlined } from '@ant-design/icons'\nconst Title = (props) => <h3>{props.text}</h3>\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    TimePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Title,\n    FormLayout,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          title=\"error status (feedbackStatus=error)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          description=\"description\"\n          x-decorator-props={{\n            feedbackStatus: 'error',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Warning Status(feedbackStatus=warning)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          description=\"description\"\n          x-decorator-props={{\n            feedbackStatus: 'warning',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Success Status (feedbackStatus=success)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          description=\"description\"\n          x-decorator-props={{\n            feedbackStatus: 'success',\n            feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Loading Status(feedbackStatus=pending)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          description=\"description\"\n          x-decorator-props={{\n            feedbackStatus: 'pending',\n            feedbackIcon: <LoadingOutlined style={{ color: '#1890ff' }} />,\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: 'Layout of feedback information' }}\n        />\n\n        <SchemaField.String\n          title=\"Compact mode required\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          required\n          x-decorator-props={{\n            feedbackLayout: 'terse',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Compact mode has feedback(feedbackLayout=terse)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'error',\n            feedbackText: 'error message',\n            feedbackLayout: 'terse',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Compact mode without feedback(feedbackLayout=terse)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackLayout: 'terse',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"loose mode (feedbackLayout=loose)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'error',\n            feedbackText: 'error message',\n            feedbackLayout: 'loose',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Popup Mode (feedbackLayout=popover)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'warning',\n            feedbackText: 'warning message',\n            feedbackLayout: 'popover',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"Popup Mode (feedbackLayout=popover)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'error',\n            feedbackText: 'error message',\n            feedbackLayout: 'popover',\n          }}\n        />\n        <SchemaField.String\n          title=\"Popup Mode (feedbackLayout=popover)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'success',\n            feedbackText: 'success message',\n            feedbackLayout: 'popover',\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: 'Component adaptation' }}\n        />\n        <SchemaField.Void\n          x-component=\"FormLayout\"\n          x-component-props={{ layout: 'vertical' }}\n        >\n          <SchemaField.String\n            title=\"Select\"\n            x-decorator=\"FormItem\"\n            x-component=\"Select\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n\n          <SchemaField.String\n            title=\"DatePicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"DatePicker.RangePicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker.RangePicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"DatePicker.YearPicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker.YearPicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"DatePicker.MonthPicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker.MonthPicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"DatePicker.TimePicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"TimePicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"NumberPicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"NumberPicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n\n          <SchemaField.String\n            title=\"TreeSelect\"\n            x-decorator=\"FormItem\"\n            x-component=\"TreeSelect\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n\n          <SchemaField.String\n            title=\"Cascader\"\n            x-decorator=\"FormItem\"\n            x-component=\"Cascader\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n        </SchemaField.Void>\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## Size control case\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  FormItem,\n  NumberPicker,\n  Switch,\n} from '@formily/next'\nimport { createForm, onFieldChange } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst Div = (props) => <div {...props} />\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Div,\n  },\n})\n\nconst form = createForm({\n  values: {\n    size: 'default',\n  },\n  effects: () => {\n    onFieldChange('size', ['value'], (field, form) => {\n      form.setFieldState('sizeWrap.*', (state) => {\n        if (state.decorator[1]) {\n          state.decorator[1].size = field.value\n        }\n      })\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"size\"\n          title=\"Radio.Group\"\n          x-decorator=\"FormItem\"\n          x-component=\"Radio.Group\"\n          enum={[\n            { value: 'small', label: 'Small' },\n            { value: 'default', label: 'Default' },\n            { value: 'large', label: 'Large' },\n          ]}\n        />\n        <SchemaField.Void name=\"sizeWrap\" x-component=\"Div\">\n          <SchemaField.String\n            name=\"input\"\n            title=\"Input\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            required\n          />\n          <SchemaField.String\n            name=\"Select\"\n            title=\"Select\"\n            x-decorator=\"FormItem\"\n            x-component=\"Select\"\n            required\n          />\n          <SchemaField.String\n            name=\"Select\"\n            title=\"Select\"\n            x-decorator=\"FormItem\"\n            x-component=\"Select\"\n            enum={[\n              {\n                label: 'Option 1',\n                value: 1,\n              },\n              {\n                label: 'Option 2',\n                value: 2,\n              },\n            ]}\n            required\n          />\n          <SchemaField.String\n            name=\"Cascader\"\n            title=\"Cascader\"\n            x-decorator=\"FormItem\"\n            x-component=\"Cascader\"\n            required\n          />\n          <SchemaField.String\n            name=\"DatePicker\"\n            title=\"DatePicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker\"\n            required\n          />\n          <SchemaField.String\n            name=\"NumberPicker\"\n            title=\"NumberPicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"NumberPicker\"\n            required\n          />\n          <SchemaField.String\n            name=\"TreeSelect\"\n            title=\"TreeSelect\"\n            x-decorator=\"FormItem\"\n            x-component=\"TreeSelect\"\n            required\n          />\n          <SchemaField.Boolean\n            name=\"Switch\"\n            title=\"Switch\"\n            x-decorator=\"FormItem\"\n            x-component=\"Switch\"\n            required\n          />\n        </SchemaField.Void>\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormItem\n\n| Property name  | Type                                                   | Description                                                                                      | Default value |\n| -------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | ------------- |\n| label          | ReactNode                                              | label                                                                                            | -             |\n| style          | CSSProperties                                          | Style                                                                                            | -             |\n| labelStyle     | CSSProperties                                          | Label style                                                                                      | -             |\n| wrapperStyle   | CSSProperties                                          | Component container style                                                                        | -             |\n| className      | string                                                 | Component style class name                                                                       | -             |\n| colon          | boolean                                                | colon                                                                                            | true          |\n| tooltip        | ReactNode                                              | Question mark prompt                                                                             | -             |\n| tooltipLayout  | `\"icon\" \\| \"text\"`                                     | Ask the prompt layout                                                                            | `\"icon\"`      |\n| tooltipIcon    | ReactNode                                              | Ask the prompt icon                                                                              | `?`           |\n| labelAlign     | `\"left\"` \\| `\"right\"`                                  | Label text alignment                                                                             | `\"right\"`     |\n| labelWrap      | boolean                                                | Label change, otherwise an ellipsis appears, hover has tooltip                                   | false         |\n| labelWidth     | `number \\| string`                                     | Label fixed width                                                                                | -             |\n| wrapperWidth   | `number \\| string`                                     | Content fixed width                                                                              | -             |\n| labelCol       | number                                                 | The number of columns occupied by the label grid, and the number of content columns add up to 24 | -             |\n| wrapperCol     | number                                                 | The number of columns occupied by the content grid, and the number of label columns add up to 24 | -             |\n| wrapperAlign   | `\"left\"` \\| `\"right\"`                                  | Content text alignment ⻬                                                                        | `\"left\"`      |\n| wrapperWrap    | boolean                                                | Change the content, otherwise an ellipsis appears, and hover has tooltip                         | false         |\n| fullness       | boolean                                                | fullness                                                                                         | true          |\n| addonBefore    | ReactNode                                              | Prefix content                                                                                   | -             |\n| addonAfter     | ReactNode                                              | Suffix content                                                                                   | -             |\n| size           | `\"small\"` \\| `\"default\"` \\| `\"large\"`                  | 尺⼨                                                                                             | -             |\n| inset          | boolean                                                | Is it an inline layout                                                                           | false         |\n| extra          | ReactNode                                              | Extended description script                                                                      | -             |\n| feedbackText   | ReactNode                                              | Feedback Case                                                                                    | -             |\n| feedbackLayout | `\"loose\"` \\| `\"terse\"` \\| `\"popover\" \\| \"none\"`        | Feedback layout                                                                                  | -             |\n| feedbackStatus | `\"error\"` \\| `\"warning\"` \\| `\"success\"` \\| `\"pending\"` | Feedback layout                                                                                  | -             |\n| feedbackIcon   | ReactNode                                              | Feedback icon                                                                                    | -             |\n| asterisk       | boolean                                                | Asterisk reminder                                                                                | -             |\n| gridSpan       | number                                                 | Grid layout occupies width                                                                       | -             |\n| bordered       | boolean                                                | Is there a border                                                                                | -             |\n\n### FormItem.BaseItem\n\nPure style components, the properties are the same as FormItem, and Formily Core does not do state bridging. It is mainly used for scenarios that need to rely on the style layout capabilities of FormItem but do not want to access the Field state.\n"
  },
  {
    "path": "packages/next/docs/components/FormItem.zh-CN.md",
    "content": "# FormItem\n\n> 全新的 FormItem 组件，相比于 Fusion Next 的 FormItem，它支持的功能更多，同时它的定位是纯样式组件，不管理表单状态，所以也会更轻量，更方便定制\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Input, Select, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        required\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JOSN Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      title: '输入框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"input\"\n      title=\"输入框\"\n      required\n      decorator={[FormItem]}\n      component={[\n        Input,\n        {\n          style: {\n            width: 240,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 常用属性案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  FormItem,\n  NumberPicker,\n  Switch,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst Title = (props) => <h3>{props.text}</h3>\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Title,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: 'label为空时的展示' }}\n        />\n        <SchemaField.String\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n          }}\n        />\n        <SchemaField.String\n          title=\"\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n          }}\n        />\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: '冒号' }}\n        />\n        <SchemaField.String\n          title=\"默认\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n        />\n        <SchemaField.String\n          title=\"无冒号(colon=false)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            colon: false,\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: '固定宽度设置' }}\n        />\n        <SchemaField.String\n          title=\"固定label宽度(labelWidth)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n          }}\n        />\n        <SchemaField.String\n          title=\"固定label宽度(labelWidth)溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出溢出\"\n          description=\"描述描述\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            tooltip: '提示提示',\n            tooltipLayout: 'text',\n          }}\n        />\n        <SchemaField.String\n          title=\"固定label宽度(labelWidth)换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行换行\"\n          description=\"描述描述\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            labelWrap: true,\n            tooltip: '提示提示',\n          }}\n        />\n        <SchemaField.String\n          title=\"固定内容宽度(wrapperWidth)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            wrapperWidth: 300,\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: '对齐方式设置' }}\n        />\n        <SchemaField.String\n          title=\"label左对齐(labelAlign=left)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            labelAlign: 'left',\n          }}\n        />\n        <SchemaField.String\n          title=\"label右对齐(labelAlign=right默认)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            labelAlign: 'right',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"内容左对齐(wrapperAlign=left默认)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            wrapperWidth: 240,\n            wrapperAlign: 'left',\n          }}\n        />\n        <SchemaField.String\n          title=\"内容右对齐(wrapperAlign=right)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            labelWidth: 300,\n            wrapperWidth: 240,\n            wrapperAlign: 'right',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"tooltip\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            tooltip: 'tooltip',\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: '是否撑满' }}\n        />\n\n        <SchemaField.String\n          title=\"默认撑满(fullness=true)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n        />\n        <SchemaField.String\n          title=\"不撑满(fullness=false)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          x-decorator-props={{\n            fullness: false,\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: '辅助信息' }}\n        />\n\n        <SchemaField.String\n          title=\"必填星号\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            asterisk: true,\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n\n        <SchemaField.String\n          title=\"前缀\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            addonBefore: 'addonBefore',\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n        <SchemaField.String\n          title=\"后缀\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            addonAfter: 'addonAfter',\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n\n        <SchemaField.String\n          title=\"帮助信息feedbackText\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackText: 'feedbackText',\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n\n        <SchemaField.String\n          title=\"额外信息extra\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackText: 'feedbackText',\n            extra: 'extra',\n            labelCol: 6,\n            wrapperCol: 10,\n          }}\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## 无边框案例\n\n设置去除组件边框\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  FormItem,\n  NumberPicker,\n  Switch,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst Title = (props) => <h3>{props.text}</h3>\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Title,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"input\"\n          title=\"Input\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"Select\"\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"Select\"\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"Cascader\"\n          title=\"Cascader\"\n          x-decorator=\"FormItem\"\n          x-component=\"Cascader\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"DatePicker\"\n          title=\"DatePicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"NumberPicker\"\n          title=\"NumberPicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"NumberPicker\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.String\n          name=\"TreeSelect\"\n          title=\"TreeSelect\"\n          x-decorator=\"FormItem\"\n          x-component=\"TreeSelect\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n        <SchemaField.Boolean\n          name=\"Switch\"\n          title=\"Switch\"\n          x-decorator=\"FormItem\"\n          x-component=\"Switch\"\n          required\n          x-decorator-props={{\n            bordered: false,\n          }}\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## 内嵌模式案例\n\n设置表单组件为内嵌模式\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  FormItem,\n  NumberPicker,\n  Switch,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst Title = (props) => <h3>{props.text}</h3>\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Title,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"input\"\n          title=\"Input\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"Select\"\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"Select\"\n          title=\"Select\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"Cascader\"\n          title=\"Cascader\"\n          x-decorator=\"FormItem\"\n          x-component=\"Cascader\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"DatePicker\"\n          title=\"DatePicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"DatePicker\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"NumberPicker\"\n          title=\"NumberPicker\"\n          x-decorator=\"FormItem\"\n          x-component=\"NumberPicker\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.String\n          name=\"TreeSelect\"\n          title=\"TreeSelect\"\n          x-decorator=\"FormItem\"\n          x-component=\"TreeSelect\"\n          required\n          x-decorator-props={{\n            inset: true,\n          }}\n        />\n        <SchemaField.Boolean\n          name=\"Switch\"\n          title=\"Switch\"\n          x-decorator=\"FormItem\"\n          x-component=\"Switch\"\n          required\n          x-decorator-props={{\n            inset: false,\n          }}\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## 反馈信息定制案例\n\n可通过 `feedbackIcon` 传入指定反馈的按钮\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  TimePicker,\n  FormItem,\n  FormLayout,\n  NumberPicker,\n  Switch,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { CheckCircleFilled, LoadingOutlined } from '@ant-design/icons'\nconst Title = (props) => <h3>{props.text}</h3>\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    TimePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Title,\n    FormLayout,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          title=\"错误状态(feedbackStatus=error)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          description=\"description\"\n          x-decorator-props={{\n            feedbackStatus: 'error',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"警告状态(feedbackStatus=warning)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          description=\"description\"\n          x-decorator-props={{\n            feedbackStatus: 'warning',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"成功状态(feedbackStatus=success)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          description=\"description\"\n          x-decorator-props={{\n            feedbackStatus: 'success',\n            feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n          }}\n        />\n\n        <SchemaField.String\n          title=\"加载状态(feedbackStatus=pending)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          description=\"description\"\n          x-decorator-props={{\n            feedbackStatus: 'pending',\n            feedbackIcon: <LoadingOutlined style={{ color: '#1890ff' }} />,\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: '反馈信息的布局' }}\n        />\n\n        <SchemaField.String\n          title=\"紧凑模式required\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          required\n          x-decorator-props={{\n            feedbackLayout: 'terse',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"紧凑模式有feedback(feedbackLayout=terse)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'error',\n            feedbackText: 'error message',\n            feedbackLayout: 'terse',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"紧凑模式无feedback(feedbackLayout=terse)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackLayout: 'terse',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"松散模式(feedbackLayout=loose)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'error',\n            feedbackText: 'error message',\n            feedbackLayout: 'loose',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"弹出模式(feedbackLayout=popover)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'warning',\n            feedbackText: 'warning message',\n            feedbackLayout: 'popover',\n          }}\n        />\n\n        <SchemaField.String\n          title=\"弹出模式(feedbackLayout=popover)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'error',\n            feedbackText: 'error message',\n            feedbackLayout: 'popover',\n          }}\n        />\n        <SchemaField.String\n          title=\"弹出模式(feedbackLayout=popover)\"\n          x-decorator=\"FormItem\"\n          x-component=\"Input\"\n          x-decorator-props={{\n            feedbackStatus: 'success',\n            feedbackText: 'success message',\n            feedbackLayout: 'popover',\n          }}\n        />\n\n        <SchemaField.Void\n          x-component=\"Title\"\n          x-component-props={{ text: '组件的适配情况' }}\n        />\n        <SchemaField.Void\n          x-component=\"FormLayout\"\n          x-component-props={{ layout: 'vertical' }}\n        >\n          <SchemaField.String\n            title=\"Select\"\n            x-decorator=\"FormItem\"\n            x-component=\"Select\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n\n          <SchemaField.String\n            title=\"DatePicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"DatePicker.RangePicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker.RangePicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"DatePicker.YearPicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker.YearPicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"DatePicker.MonthPicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker.MonthPicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"DatePicker.TimePicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"TimePicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n          <SchemaField.String\n            title=\"NumberPicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"NumberPicker\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n\n          <SchemaField.String\n            title=\"TreeSelect\"\n            x-decorator=\"FormItem\"\n            x-component=\"TreeSelect\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n\n          <SchemaField.String\n            title=\"Cascader\"\n            x-decorator=\"FormItem\"\n            x-component=\"Cascader\"\n            x-decorator-props={{\n              feedbackStatus: 'success',\n              feedbackIcon: <CheckCircleFilled style={{ color: '#52c41a' }} />,\n            }}\n          />\n        </SchemaField.Void>\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## 尺寸控制案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Radio,\n  TreeSelect,\n  Cascader,\n  Select,\n  DatePicker,\n  FormItem,\n  NumberPicker,\n  Switch,\n} from '@formily/next'\nimport { createForm, onFieldChange } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst Div = (props) => <div {...props} />\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    Cascader,\n    TreeSelect,\n    DatePicker,\n    NumberPicker,\n    Switch,\n    Radio,\n    FormItem,\n    Div,\n  },\n})\n\nconst form = createForm({\n  values: {\n    size: 'default',\n  },\n  effects: () => {\n    onFieldChange('size', ['value'], (field, form) => {\n      form.setFieldState('sizeWrap.*', (state) => {\n        if (state.decorator[1]) {\n          state.decorator[1].size = field.value\n        }\n      })\n    })\n  },\n})\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"size\"\n          title=\"Radio.Group\"\n          x-decorator=\"FormItem\"\n          x-component=\"Radio.Group\"\n          enum={[\n            { value: 'small', label: 'Small' },\n            { value: 'default', label: 'Default' },\n            { value: 'large', label: 'Large' },\n          ]}\n        />\n        <SchemaField.Void name=\"sizeWrap\" x-component=\"Div\">\n          <SchemaField.String\n            name=\"input\"\n            title=\"Input\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            required\n          />\n          <SchemaField.String\n            name=\"Select\"\n            title=\"Select\"\n            x-decorator=\"FormItem\"\n            x-component=\"Select\"\n            required\n          />\n          <SchemaField.String\n            name=\"Select\"\n            title=\"Select\"\n            x-decorator=\"FormItem\"\n            x-component=\"Select\"\n            enum={[\n              {\n                label: '选项1',\n                value: 1,\n              },\n              {\n                label: '选项2',\n                value: 2,\n              },\n            ]}\n            required\n          />\n          <SchemaField.String\n            name=\"Cascader\"\n            title=\"Cascader\"\n            x-decorator=\"FormItem\"\n            x-component=\"Cascader\"\n            required\n          />\n          <SchemaField.String\n            name=\"DatePicker\"\n            title=\"DatePicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"DatePicker\"\n            required\n          />\n          <SchemaField.String\n            name=\"NumberPicker\"\n            title=\"NumberPicker\"\n            x-decorator=\"FormItem\"\n            x-component=\"NumberPicker\"\n            required\n          />\n          <SchemaField.String\n            name=\"TreeSelect\"\n            title=\"TreeSelect\"\n            x-decorator=\"FormItem\"\n            x-component=\"TreeSelect\"\n            required\n          />\n          <SchemaField.Boolean\n            name=\"Switch\"\n            title=\"Switch\"\n            x-decorator=\"FormItem\"\n            x-component=\"Switch\"\n            required\n          />\n        </SchemaField.Void>\n      </SchemaField>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormItem\n\n| 属性名         | 类型                                                   | 描述                                        | 默认值    |\n| -------------- | ------------------------------------------------------ | ------------------------------------------- | --------- |\n| label          | ReactNode                                              | 标签                                        | -         |\n| style          | CSSProperties                                          | 样式                                        | -         |\n| labelStyle     | CSSProperties                                          | 标签样式                                    | -         |\n| wrapperStyle   | CSSProperties                                          | 组件容器样式                                | -         |\n| className      | string                                                 | 组件样式类名                                | -         |\n| colon          | boolean                                                | 冒号                                        | true      |\n| tooltip        | ReactNode                                              | 问号提示                                    | -         |\n| tooltipLayout  | `\"icon\" \\| \"text\"`                                     | 问号提示布局                                | `\"icon\"`  |\n| tooltipIcon    | ReactNode                                              | 问号提示图标                                | `?`       |\n| labelAlign     | `\"left\"` \\| `\"right\"`                                  | 标签文本对齐方式                            | `\"right\"` |\n| labelWrap      | boolean                                                | 标签换⾏，否则出现省略号，hover 有 tooltip  | false     |\n| labelWidth     | `number \\| string`                                     | 标签固定宽度                                | -         |\n| wrapperWidth   | `number \\| string`                                     | 内容固定宽度                                | -         |\n| labelCol       | number                                                 | 标签⽹格所占列数，和内容列数加起来总和为 24 | -         |\n| wrapperCol     | number                                                 | 内容⽹格所占列数，和标签列数加起来总和为 24 | -         |\n| wrapperAlign   | `\"left\"` \\| `\"right\"`                                  | 内容文本对齐方式⻬                          | `\"left\"`  |\n| wrapperWrap    | boolean                                                | 内容换⾏，否则出现省略号，hover 有 tooltip  | false     |\n| fullness       | boolean                                                | 内容撑满                                    | true      |\n| addonBefore    | ReactNode                                              | 前缀内容                                    | -         |\n| addonAfter     | ReactNode                                              | 后缀内容                                    | -         |\n| size           | `\"small\"` \\| `\"default\"` \\| `\"large\"`                  | 尺⼨                                        | -         |\n| inset          | boolean                                                | 是否是内嵌布局                              | false     |\n| extra          | ReactNode                                              | 扩展描述⽂案                                | -         |\n| feedbackText   | ReactNode                                              | 反馈⽂案                                    | -         |\n| feedbackLayout | `\"loose\"` \\| `\"terse\"` \\| `\"popover\" \\| \"none\"`        | 反馈布局                                    | -         |\n| feedbackStatus | `\"error\"` \\| `\"warning\"` \\| `\"success\"` \\| `\"pending\"` | 反馈布局                                    | -         |\n| feedbackIcon   | ReactNode                                              | 反馈图标                                    | -         |\n| asterisk       | boolean                                                | 星号提醒                                    | -         |\n| gridSpan       | number                                                 | ⽹格布局占宽                                | -         |\n| bordered       | boolean                                                | 是否有边框                                  | -         |\n\n### FormItem.BaseItem\n\n纯样式组件，属性与 FormItem 一样，与 Formily Core 不做状态桥接，主要用于一些需要依赖 FormItem 的样式布局能力，但不希望接入 Field 状态的场景\n"
  },
  {
    "path": "packages/next/docs/components/FormLayout.md",
    "content": "# FormLayout\n\n> Block-level layout batch control component, with the help of this component, we can easily control the layout mode of all FormItem components enclosed by FormLayout\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { Input, Select, FormItem, FormLayout } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    FormItem,\n    FormLayout,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Void\n        x-component=\"FormLayout\"\n        x-component-props={{\n          labelCol: 6,\n          wrapperCol: 10,\n        }}\n      >\n        <SchemaField.String\n          name=\"input\"\n          title=\"input box\"\n          x-decorator=\"FormItem\"\n          x-decorator-props={{\n            tooltip: <div>123</div>,\n          }}\n          x-component=\"Input\"\n          required\n        />\n        <SchemaField.String\n          name=\"select\"\n          title=\"select box\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n        />\n      </SchemaField.Void>\n    </SchemaField>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { Input, Select, FormItem, FormLayout } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    FormItem,\n    FormLayout,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    layout: {\n      type: 'void',\n      'x-component': 'FormLayout',\n      'x-component-props': {\n        labelCol: 6,\n        wrapperCol: 10,\n        layout: 'vertical',\n      },\n      properties: {\n        input: {\n          type: 'string',\n          title: 'input box',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            tooltip: <div>123</div>,\n          },\n          'x-component': 'Input',\n        },\n        select: {\n          type: 'string',\n          title: 'Select box',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Select',\n        },\n      },\n    },\n  },\n}\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Select,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <Field\n        name=\"input\"\n        required\n        title=\"input box\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <Field\n        name=\"select\"\n        required\n        title=\"select box\"\n        decorator={[FormItem]}\n        component={[Select]}\n      />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## API\n\n| Property name  | Type                                                                                   | Description                           | Default value |\n| -------------- | -------------------------------------------------------------------------------------- | ------------------------------------- | ------------- |\n| style          | CSSProperties                                                                          | Style                                 | -             |\n| className      | string                                                                                 | class name                            | -             |\n| colon          | boolean                                                                                | Is there a colon                      | true          |\n| labelAlign     | `'right' \\| 'left' \\| ('right' \\| 'left')[]`                                           | Label content alignment               | -             |\n| wrapperAlign   | `'right' \\| 'left' \\| ('right' \\| 'left')[]`                                           | Component container content alignment | -             |\n| labelWrap      | boolean                                                                                | Wrap label content                    | false         |\n| labelWidth     | number                                                                                 | Label width (px)                      | -             |\n| wrapperWidth   | number                                                                                 | Component container width (px)        | -             |\n| wrapperWrap    | boolean                                                                                | Component container wrap              | false         |\n| labelCol       | `number \\| number[]`                                                                   | Label width (24 column)               | -             |\n| wrapperCol     | `number \\| number[]`                                                                   | Component container width (24 column) | -             |\n| fullness       | boolean                                                                                | Component container width 100%        | false         |\n| size           | `'small' \\|'default' \\|'large'`                                                        | component size                        | default       |\n| layout         | `'vertical' \\| 'horizontal' \\| 'inline' \\| ('vertical' \\| 'horizontal' \\| 'inline')[]` | layout mode                           | horizontal    |\n| direction      | `'rtl' \\|'ltr'`                                                                        | direction (not supported yet)         | ltr           |\n| inset          | boolean                                                                                | Inline layout                         | false         |\n| shallow        | boolean                                                                                | shallow context transfer              | true          |\n| feedbackLayout | `'loose' \\|'terse' \\|'popover' \\|'none'`                                               | feedback layout                       | true          |\n| tooltipLayout  | `\"icon\" \\| \"text\"`                                                                     | Ask the prompt layout                 | `\"icon\"`      |\n| tooltipIcon    | ReactNode                                                                              | Ask the prompt icon                   | -             |\n| bordered       | boolean                                                                                | Is there a border                     | true          |\n| breakpoints    | number[]                                                                               | Container size breakpoints            | -             |\n| gridColumnGap  | number                                                                                 | Grid Column Gap                       | 8             |\n| gridRowGap     | number                                                                                 | Grid Row Gap                          | 4             |\n| spaceGap       | number                                                                                 | Space Gap                             | 8             |\n"
  },
  {
    "path": "packages/next/docs/components/FormLayout.zh-CN.md",
    "content": "# FormLayout\n\n> 区块级布局批量控制组件，借助该组件，我们可以轻松的控制被 FormLayout 圈住的所有 FormItem 组件的布局模式\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Input, Select, FormItem, FormLayout } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    FormItem,\n    FormLayout,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Void\n        x-component=\"FormLayout\"\n        x-component-props={{\n          labelCol: 6,\n          wrapperCol: 10,\n        }}\n      >\n        <SchemaField.String\n          name=\"input\"\n          title=\"输入框\"\n          x-decorator=\"FormItem\"\n          x-decorator-props={{\n            tooltip: <div>123</div>,\n          }}\n          x-component=\"Input\"\n          required\n        />\n        <SchemaField.String\n          name=\"select\"\n          title=\"选择框\"\n          x-decorator=\"FormItem\"\n          x-component=\"Select\"\n          required\n        />\n      </SchemaField.Void>\n    </SchemaField>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Input, Select, FormItem, FormLayout } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    Select,\n    FormItem,\n    FormLayout,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    layout: {\n      type: 'void',\n      'x-component': 'FormLayout',\n      'x-component-props': {\n        labelCol: 6,\n        wrapperCol: 10,\n        layout: 'vertical',\n      },\n      properties: {\n        input: {\n          type: 'string',\n          title: '输入框',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            tooltip: <div>123</div>,\n          },\n          'x-component': 'Input',\n        },\n        select: {\n          type: 'string',\n          title: '选择框',\n          required: true,\n          'x-decorator': 'FormItem',\n          'x-component': 'Select',\n        },\n      },\n    },\n  },\n}\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  Select,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout\n      breakpoints={[680]}\n      layout={['vertical', 'horizontal']}\n      labelAlign={['left', 'right']}\n      labelCol={[24, 6]}\n      wrapperCol={[24, 10]}\n    >\n      <Field\n        name=\"input\"\n        required\n        title=\"输入框\"\n        decorator={[FormItem]}\n        component={[Input]}\n      />\n      <Field\n        name=\"select\"\n        required\n        title=\"选择框\"\n        decorator={[FormItem]}\n        component={[Select]}\n      />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## API\n\n| 属性名         | 类型                                                                                  | 描述                    | 默认值     |\n| -------------- | ------------------------------------------------------------------------------------- | ----------------------- | ---------- |\n| style          | CSSProperties                                                                         | 样式                    | -          |\n| className      | string                                                                                | 类名                    | -          |\n| colon          | boolean                                                                               | 是否有冒号              | true       |\n| labelAlign     | `'right' \\| 'left' \\| ('right' \\| 'left')[]`                                          | 标签内容对齐            | -          |\n| wrapperAlign   | `'right' \\| 'left' \\| ('right' \\| 'left')[]`                                          | 组件容器内容对齐        | -          |\n| labelWrap      | boolean                                                                               | 标签内容换行            | false      |\n| labelWidth     | number                                                                                | 标签宽度(px)            | -          |\n| wrapperWidth   | number                                                                                | 组件容器宽度(px)        | -          |\n| wrapperWrap    | boolean                                                                               | 组件容器换行            | false      |\n| labelCol       | `number \\| number[]`                                                                  | 标签宽度(24 column)     | -          |\n| wrapperCol     | `number \\| number[]`                                                                  | 组件容器宽度(24 column) | -          |\n| fullness       | boolean                                                                               | 组件容器宽度 100%       | false      |\n| size           | `'small' \\| 'default' \\| 'large'`                                                     | 组件尺寸                | default    |\n| layout         | `'vertical' \\| 'horizontal' \\| 'inline' \\|('vertical' \\| 'horizontal' \\| 'inline')[]` | 布局模式                | horizontal |\n| direction      | `'rtl' \\| 'ltr'`                                                                      | 方向(暂不支持)          | ltr        |\n| inset          | boolean                                                                               | 内联布局                | false      |\n| shallow        | boolean                                                                               | 上下文浅层传递          | true       |\n| feedbackLayout | `'loose' \\| 'terse' \\| 'popover' \\| 'none'`                                           | 反馈布局                | true       |\n| tooltipLayout  | `\"icon\" \\| \"text\"`                                                                    | 问号提示布局            | `\"icon\"`   |\n| tooltipIcon    | ReactNode                                                                             | 问号提示图标            | -          |\n| bordered       | boolean                                                                               | 是否有边框              | true       |\n| breakpoints    | number[]                                                                              | 容器尺寸断点            | -          |\n| gridColumnGap  | number                                                                                | 网格布局列间距          | 8          |\n| gridRowGap     | number                                                                                | 网格布局行间距          | 4          |\n| spaceGap       | number                                                                                | 弹性间距                | 8          |\n"
  },
  {
    "path": "packages/next/docs/components/FormStep.md",
    "content": "# FormStep\n\n> Step-by-step form components\n>\n> Note: This component can only be used in Schema scenarios\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { FormStep, FormItem, Input, FormButtonGroup } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormStep,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formStep = FormStep.createFormStep()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Void\n          x-component=\"FormStep\"\n          x-component-props={{ formStep }}\n        >\n          <SchemaField.Void\n            x-component=\"FormStep.StepPane\"\n            x-component-props={{ title: 'First Step' }}\n          >\n            <SchemaField.String\n              name=\"aaa\"\n              x-decorator=\"FormItem\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"FormStep.StepPane\"\n            x-component-props={{ title: 'Second Step' }}\n          >\n            <SchemaField.String\n              name=\"bbb\"\n              x-decorator=\"FormItem\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            type=\"void\"\n            x-component=\"FormStep.StepPane\"\n            x-component-props={{ title: 'Step 3' }}\n          >\n            <SchemaField.String\n              name=\"ccc\"\n              x-decorator=\"FormItem\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n        </SchemaField.Void>\n      </SchemaField>\n      <FormConsumer>\n        {() => (\n          <FormButtonGroup>\n            <Button\n              disabled={!formStep.allowBack}\n              onClick={() => {\n                formStep.back()\n              }}\n            >\n              Previous\n            </Button>\n            <Button\n              disabled={!formStep.allowNext}\n              onClick={() => {\n                formStep.next()\n              }}\n            >\n              Next step\n            </Button>\n            <Button\n              disabled={formStep.allowNext}\n              onClick={() => {\n                formStep.submit(console.log)\n              }}\n            >\n              submit\n            </Button>\n          </FormButtonGroup>\n        )}\n      </FormConsumer>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { FormStep, FormItem, Input, FormButtonGroup } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormStep,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formStep = FormStep.createFormStep()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    step: {\n      type: 'void',\n      'x-component': 'FormStep',\n      'x-component-props': {\n        formStep: '{{formStep}}',\n      },\n      properties: {\n        step1: {\n          type: 'void',\n          'x-component': 'FormStep.StepPane',\n          'x-component-props': {\n            title: 'First Step',\n          },\n          properties: {\n            aaa: {\n              type: 'string',\n              title: 'AAA',\n              required: true,\n              'x-decorator': 'FormItem',\n              'x-component': 'Input',\n            },\n          },\n        },\n        step2: {\n          type: 'void',\n          'x-component': 'FormStep.StepPane',\n          'x-component-props': {\n            title: 'Second Step',\n          },\n          properties: {\n            bbb: {\n              type: 'string',\n              title: 'AAA',\n              required: true,\n              'x-decorator': 'FormItem',\n              'x-component': 'Input',\n            },\n          },\n        },\n        step3: {\n          type: 'void',\n          'x-component': 'FormStep.StepPane',\n          'x-component-props': {\n            title: 'The third step',\n          },\n          properties: {\n            ccc: {\n              type: 'string',\n              title: 'AAA',\n              required: true,\n              'x-decorator': 'FormItem',\n              'x-component': 'Input',\n            },\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} scope={{ formStep }} />\n      <FormConsumer>\n        {() => (\n          <FormButtonGroup>\n            <Button\n              disabled={!formStep.allowBack}\n              onClick={() => {\n                formStep.back()\n              }}\n            >\n              Previous\n            </Button>\n            <Button\n              disabled={!formStep.allowNext}\n              onClick={() => {\n                formStep.next()\n              }}\n            >\n              Next step\n            </Button>\n            <Button\n              disabled={formStep.allowNext}\n              onClick={() => {\n                formStep.submit(console.log)\n              }}\n            >\n              submit\n            </Button>\n          </FormButtonGroup>\n        )}\n      </FormConsumer>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormStep\n\n| Property name | Type      | Description                                             | Default value |\n| ------------- | --------- | ------------------------------------------------------- | ------------- |\n| formStep      | IFormStep | Pass in the model created by createFormStep/useFormStep |               |\n\nOther references https://fusion.design/pc/component/basic/step\n\n### FormStep.StepPane\n\nRefer to https://fusion.design/pc/component/basic/step Steps.Step properties\n\n### FormStep.createFormStep\n\n```ts pure\nimport { Form } from '@formily/core'\n\ninterface createFormStep {\n  (current?: number): IFormStep\n}\n\ninterface IFormTab {\n  //Current index\n  current: number\n  //Whether to allow backwards\n  allowNext: boolean\n  //Whether to allow forward\n  allowBack: boolean\n  //Set the current index\n  setCurrent(key: number): void\n  //submit Form\n  submit: Form['submit']\n  //backward\n  next(): void\n  //forward\n  back(): void\n}\n```\n"
  },
  {
    "path": "packages/next/docs/components/FormStep.zh-CN.md",
    "content": "# FormStep\n\n> 分步表单组件\n>\n> 注意：该组件只能用在 Schema 场景\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { FormStep, FormItem, Input, FormButtonGroup } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormStep,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formStep = FormStep.createFormStep()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Void\n          x-component=\"FormStep\"\n          x-component-props={{ formStep }}\n        >\n          <SchemaField.Void\n            x-component=\"FormStep.StepPane\"\n            x-component-props={{ title: '第一步' }}\n          >\n            <SchemaField.String\n              name=\"aaa\"\n              x-decorator=\"FormItem\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            x-component=\"FormStep.StepPane\"\n            x-component-props={{ title: '第二步' }}\n          >\n            <SchemaField.String\n              name=\"bbb\"\n              x-decorator=\"FormItem\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            type=\"void\"\n            x-component=\"FormStep.StepPane\"\n            x-component-props={{ title: '第三步' }}\n          >\n            <SchemaField.String\n              name=\"ccc\"\n              x-decorator=\"FormItem\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n        </SchemaField.Void>\n      </SchemaField>\n      <FormConsumer>\n        {() => (\n          <FormButtonGroup>\n            <Button\n              disabled={!formStep.allowBack}\n              onClick={() => {\n                formStep.back()\n              }}\n            >\n              上一步\n            </Button>\n            <Button\n              disabled={!formStep.allowNext}\n              onClick={() => {\n                formStep.next()\n              }}\n            >\n              下一步\n            </Button>\n            <Button\n              disabled={formStep.allowNext}\n              onClick={() => {\n                formStep.submit(console.log)\n              }}\n            >\n              提交\n            </Button>\n          </FormButtonGroup>\n        )}\n      </FormConsumer>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { FormStep, FormItem, Input, FormButtonGroup } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormStep,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formStep = FormStep.createFormStep()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    step: {\n      type: 'void',\n      'x-component': 'FormStep',\n      'x-component-props': {\n        formStep: '{{formStep}}',\n      },\n      properties: {\n        step1: {\n          type: 'void',\n          'x-component': 'FormStep.StepPane',\n          'x-component-props': {\n            title: '第一步',\n          },\n          properties: {\n            aaa: {\n              type: 'string',\n              title: 'AAA',\n              required: true,\n              'x-decorator': 'FormItem',\n              'x-component': 'Input',\n            },\n          },\n        },\n        step2: {\n          type: 'void',\n          'x-component': 'FormStep.StepPane',\n          'x-component-props': {\n            title: '第二步',\n          },\n          properties: {\n            bbb: {\n              type: 'string',\n              title: 'AAA',\n              required: true,\n              'x-decorator': 'FormItem',\n              'x-component': 'Input',\n            },\n          },\n        },\n        step3: {\n          type: 'void',\n          'x-component': 'FormStep.StepPane',\n          'x-component-props': {\n            title: '第三步',\n          },\n          properties: {\n            ccc: {\n              type: 'string',\n              title: 'AAA',\n              required: true,\n              'x-decorator': 'FormItem',\n              'x-component': 'Input',\n            },\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} scope={{ formStep }} />\n      <FormConsumer>\n        {() => (\n          <FormButtonGroup>\n            <Button\n              disabled={!formStep.allowBack}\n              onClick={() => {\n                formStep.back()\n              }}\n            >\n              上一步\n            </Button>\n            <Button\n              disabled={!formStep.allowNext}\n              onClick={() => {\n                formStep.next()\n              }}\n            >\n              下一步\n            </Button>\n            <Button\n              disabled={formStep.allowNext}\n              onClick={() => {\n                formStep.submit(console.log)\n              }}\n            >\n              提交\n            </Button>\n          </FormButtonGroup>\n        )}\n      </FormConsumer>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormStep\n\n| 属性名   | 类型      | 描述                                               | 默认值 |\n| -------- | --------- | -------------------------------------------------- | ------ |\n| formStep | IFormStep | 传入通过 createFormStep/useFormStep 创建出来的模型 |        |\n\n其余参考 https://fusion.design/pc/component/basic/step\n\n### FormStep.StepPane\n\n参考 https://fusion.design/pc/component/basic/step Steps.Step 属性\n\n### FormStep.createFormStep\n\n```ts pure\nimport { Form } from '@formily/core'\n\ninterface createFormStep {\n  (current?: number): IFormStep\n}\n\ninterface IFormTab {\n  //当前索引\n  current: number\n  //是否允许向后\n  allowNext: boolean\n  //是否允许向前\n  allowBack: boolean\n  //设置当前索引\n  setCurrent(key: number): void\n  //提交表单\n  submit: Form['submit']\n  //向后\n  next(): void\n  //向前\n  back(): void\n}\n```\n"
  },
  {
    "path": "packages/next/docs/components/FormTab.md",
    "content": "# FormTab\n\n> Tab form\n>\n> Note: This component is only applicable to Schema scenarios\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  FormTab,\n  FormItem,\n  Input,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormTab,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formTab = FormTab.createFormTab()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Void\n          type=\"void\"\n          x-component=\"FormTab\"\n          x-component-props={{ formTab }}\n        >\n          <SchemaField.Void\n            type=\"void\"\n            name=\"tab1\"\n            x-component=\"FormTab.TabPane\"\n            x-component-props={{ tab: 'A1' }}\n          >\n            <SchemaField.String\n              name=\"aaa\"\n              x-decorator=\"FormItem\"\n              title=\"AAA\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            name=\"tab2\"\n            x-component=\"FormTab.TabPane\"\n            x-component-props={{ tab: 'A2' }}\n          >\n            <SchemaField.String\n              name=\"bbb\"\n              x-decorator=\"FormItem\"\n              title=\"BBB\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            name=\"tab3\"\n            x-component=\"FormTab.TabPane\"\n            x-component-props={{ tab: 'A3' }}\n          >\n            <SchemaField.String\n              name=\"ccc\"\n              x-decorator=\"FormItem\"\n              title=\"CCC\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n        </SchemaField.Void>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Button\n          onClick={() => {\n            form.query('tab3').take((field) => {\n              field.visible = !field.visible\n            })\n          }}\n        >\n          Show/hide the last tab\n        </Button>\n        <Button\n          onClick={() => {\n            formTab.setActiveKey('tab2')\n          }}\n        >\n          Switch to the second Tab\n        </Button>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  FormTab,\n  FormItem,\n  Input,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormTab,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formTab = FormTab.createFormTab()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    collapse: {\n      type: 'void',\n      'x-component': 'FormTab',\n      'x-component-props': {\n        formTab: '{{formTab}}',\n      },\n      properties: {\n        tab1: {\n          type: 'void',\n          'x-component': 'FormTab.TabPane',\n          'x-component-props': {\n            tab: 'A1',\n          },\n          properties: {\n            aaa: {\n              type: 'string',\n              title: 'AAA',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        tab2: {\n          type: 'void',\n          'x-component': 'FormTab.TabPane',\n          'x-component-props': {\n            tab: 'A2',\n          },\n          properties: {\n            bbb: {\n              type: 'string',\n              title: 'BBB',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        tab3: {\n          type: 'void',\n          'x-component': 'FormTab.TabPane',\n          'x-component-props': {\n            tab: 'A3',\n          },\n          properties: {\n            ccc: {\n              type: 'string',\n              title: 'CCC',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} scope={{ formTab }} />\n      <FormButtonGroup.FormItem>\n        <Button\n          onClick={() => {\n            form.query('tab3').take((field) => {\n              field.visible = !field.visible\n            })\n          }}\n        >\n          Show/hide the last tab\n        </Button>\n        <Button\n          onClick={() => {\n            formTab.setActiveKey('tab2')\n          }}\n        >\n          Switch to the second Tab\n        </Button>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormTab\n\n| Property name | Type     | Description                                           | Default value |\n| ------------- | -------- | ----------------------------------------------------- | ------------- |\n| formTab       | IFormTab | Pass in the model created by createFormTab/useFormTab |               |\n\nOther references https://fusion.design/pc/component/basic/tab\n\n### FormTab.TabPane\n\nRefer to the Item property of https://fusion.design/pc/component/basic/tab\n\n### FormTab.createFormTab\n\n```ts pure\ntype ActiveKey = string | number\n\ninterface createFormTab {\n  (defaultActiveKey?: ActiveKey): IFormTab\n}\n\ninterface IFormTab {\n  //Activate the primary key\n  activeKey: ActiveKey\n  //Set the activation key\n  setActiveKey(key: ActiveKey): void\n}\n```\n"
  },
  {
    "path": "packages/next/docs/components/FormTab.zh-CN.md",
    "content": "# FormTab\n\n> 选项卡表单\n>\n> 注意：该组件只适用于 Schema 场景\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormTab,\n  FormItem,\n  Input,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormTab,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formTab = FormTab.createFormTab()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Void\n          type=\"void\"\n          x-component=\"FormTab\"\n          x-component-props={{ formTab }}\n        >\n          <SchemaField.Void\n            type=\"void\"\n            name=\"tab1\"\n            x-component=\"FormTab.TabPane\"\n            x-component-props={{ tab: 'A1' }}\n          >\n            <SchemaField.String\n              name=\"aaa\"\n              x-decorator=\"FormItem\"\n              title=\"AAA\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            name=\"tab2\"\n            x-component=\"FormTab.TabPane\"\n            x-component-props={{ tab: 'A2' }}\n          >\n            <SchemaField.String\n              name=\"bbb\"\n              x-decorator=\"FormItem\"\n              title=\"BBB\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n          <SchemaField.Void\n            name=\"tab3\"\n            x-component=\"FormTab.TabPane\"\n            x-component-props={{ tab: 'A3' }}\n          >\n            <SchemaField.String\n              name=\"ccc\"\n              x-decorator=\"FormItem\"\n              title=\"CCC\"\n              required\n              x-component=\"Input\"\n            />\n          </SchemaField.Void>\n        </SchemaField.Void>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Button\n          onClick={() => {\n            form.query('tab3').take((field) => {\n              field.visible = !field.visible\n            })\n          }}\n        >\n          显示/隐藏最后一个Tab\n        </Button>\n        <Button\n          onClick={() => {\n            formTab.setActiveKey('tab2')\n          }}\n        >\n          切换第二个Tab\n        </Button>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  FormTab,\n  FormItem,\n  Input,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    FormTab,\n    Input,\n  },\n})\n\nconst form = createForm()\nconst formTab = FormTab.createFormTab()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    collapse: {\n      type: 'void',\n      'x-component': 'FormTab',\n      'x-component-props': {\n        formTab: '{{formTab}}',\n      },\n      properties: {\n        tab1: {\n          type: 'void',\n          'x-component': 'FormTab.TabPane',\n          'x-component-props': {\n            tab: 'A1',\n          },\n          properties: {\n            aaa: {\n              type: 'string',\n              title: 'AAA',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        tab2: {\n          type: 'void',\n          'x-component': 'FormTab.TabPane',\n          'x-component-props': {\n            tab: 'A2',\n          },\n          properties: {\n            bbb: {\n              type: 'string',\n              title: 'BBB',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n        tab3: {\n          type: 'void',\n          'x-component': 'FormTab.TabPane',\n          'x-component-props': {\n            tab: 'A3',\n          },\n          properties: {\n            ccc: {\n              type: 'string',\n              title: 'CCC',\n              'x-decorator': 'FormItem',\n              required: true,\n              'x-component': 'Input',\n            },\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField schema={schema} scope={{ formTab }} />\n      <FormButtonGroup.FormItem>\n        <Button\n          onClick={() => {\n            form.query('tab3').take((field) => {\n              field.visible = !field.visible\n            })\n          }}\n        >\n          显示/隐藏最后一个Tab\n        </Button>\n        <Button\n          onClick={() => {\n            formTab.setActiveKey('tab2')\n          }}\n        >\n          切换第二个Tab\n        </Button>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## API\n\n### FormTab\n\n| 属性名  | 类型     | 描述                                             | 默认值 |\n| ------- | -------- | ------------------------------------------------ | ------ |\n| formTab | IFormTab | 传入通过 createFormTab/useFormTab 创建出来的模型 |        |\n\n其余参考 https://fusion.design/pc/component/basic/tab\n\n### FormTab.TabPane\n\n参考 https://fusion.design/pc/component/basic/tab 的 Item 属性\n\n### FormTab.createFormTab\n\n```ts pure\ntype ActiveKey = string | number\n\ninterface createFormTab {\n  (defaultActiveKey?: ActiveKey): IFormTab\n}\n\ninterface IFormTab {\n  //激活主键\n  activeKey: ActiveKey\n  //设置激活主键\n  setActiveKey(key: ActiveKey): void\n}\n```\n"
  },
  {
    "path": "packages/next/docs/components/Input.md",
    "content": "# Input\n\n> Text input box\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        required\n        x-component-props={{\n          style: {\n            width: 240,\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"textarea\"\n        title=\"text box\"\n        x-decorator=\"FormItem\"\n        required\n        x-component=\"Input.TextArea\"\n        x-component-props={{\n          style: {\n            width: 400,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      title: 'input box',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n    },\n    textarea: {\n      type: 'string',\n      title: 'input box',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input.TextArea',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"input\"\n      title=\"input box\"\n      required\n      decorator={[FormItem]}\n      component={[\n        Input,\n        {\n          style: {\n            width: 240,\n          },\n        },\n      ]}\n    />\n    <Field\n      name=\"textarea\"\n      title=\"text box\"\n      required\n      decorator={[FormItem]}\n      component={[\n        Input.TextArea,\n        {\n          style: {\n            width: 400,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://fusion.design/pc/component/basic/input\n"
  },
  {
    "path": "packages/next/docs/components/Input.zh-CN.md",
    "content": "# Input\n\n> 文本输入框\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n        required\n        x-component-props={{\n          style: {\n            width: 240,\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"textarea\"\n        title=\"文本框\"\n        x-decorator=\"FormItem\"\n        required\n        x-component=\"Input.TextArea\"\n        x-component-props={{\n          style: {\n            width: 400,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      title: '输入框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n    },\n    textarea: {\n      type: 'string',\n      title: '输入框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input.TextArea',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"input\"\n      title=\"输入框\"\n      required\n      decorator={[FormItem]}\n      component={[\n        Input,\n        {\n          style: {\n            width: 240,\n          },\n        },\n      ]}\n    />\n    <Field\n      name=\"textarea\"\n      title=\"文本框\"\n      required\n      decorator={[FormItem]}\n      component={[\n        Input.TextArea,\n        {\n          style: {\n            width: 400,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://fusion.design/pc/component/basic/input\n"
  },
  {
    "path": "packages/next/docs/components/NumberPicker.md",
    "content": "# NumberPicker\n\n> Number input box\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { NumberPicker, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    NumberPicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        x-decorator=\"FormItem\"\n        x-component=\"NumberPicker\"\n        required\n        x-component-props={{\n          style: {\n            width: 240,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { NumberPicker, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    NumberPicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      title: 'input box',\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { NumberPicker, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"input\"\n      title=\"input box\"\n      required\n      decorator={[FormItem]}\n      component={[\n        NumberPicker,\n        {\n          style: {\n            width: 240,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://fusion.design/pc/component/basic/number-picker\n"
  },
  {
    "path": "packages/next/docs/components/NumberPicker.zh-CN.md",
    "content": "# NumberPicker\n\n> 数字输入框\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { NumberPicker, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    NumberPicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        x-decorator=\"FormItem\"\n        x-component=\"NumberPicker\"\n        required\n        x-component-props={{\n          style: {\n            width: 240,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { NumberPicker, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    NumberPicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      title: '输入框',\n      'x-decorator': 'FormItem',\n      'x-component': 'NumberPicker',\n      'x-component-props': {\n        style: {\n          width: 240,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { NumberPicker, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"input\"\n      title=\"输入框\"\n      required\n      decorator={[FormItem]}\n      component={[\n        NumberPicker,\n        {\n          style: {\n            width: 240,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://fusion.design/pc/component/basic/number-picker\n"
  },
  {
    "path": "packages/next/docs/components/Password.md",
    "content": "# Password\n\n> Password input box\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  Password,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Password,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"input\"\n          title=\"input box\"\n          x-decorator=\"FormItem\"\n          x-component=\"Password\"\n          required\n          x-component-props={{\n            checkStrength: true,\n          }}\n        />\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  Password,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nconst SchemaField = createSchemaField({\n  components: {\n    Password,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      title: 'input box',\n      'x-decorator': 'FormItem',\n      'x-component': 'Password',\n      'x-component-props': {\n        checkStrength: true,\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport {\n  Password,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <Field\n        name=\"input\"\n        title=\"input box\"\n        required\n        decorator={[FormItem]}\n        component={[\n          Password,\n          {\n            checkStrength: true,\n          },\n        ]}\n      />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://fusion.design/pc/component/basic/input\n"
  },
  {
    "path": "packages/next/docs/components/Password.zh-CN.md",
    "content": "# Password\n\n> 密码输入框\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Password,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Password,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"input\"\n          title=\"输入框\"\n          x-decorator=\"FormItem\"\n          x-component=\"Password\"\n          required\n          x-component-props={{\n            checkStrength: true,\n          }}\n        />\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Password,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nconst SchemaField = createSchemaField({\n  components: {\n    Password,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      title: '输入框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Password',\n      'x-component-props': {\n        checkStrength: true,\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Password,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={10}>\n      <Field\n        name=\"input\"\n        title=\"输入框\"\n        required\n        decorator={[FormItem]}\n        component={[\n          Password,\n          {\n            checkStrength: true,\n          },\n        ]}\n      />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://fusion.design/pc/component/basic/input\n"
  },
  {
    "path": "packages/next/docs/components/PreviewText.md",
    "content": "# PreviewText\n\n> Reading state components, mainly used to implement the reading state of these components of class Input and DatePicker\n\n## Simple use case\n\n```tsx\nimport React from 'react'\nimport { PreviewText, FormItem, FormLayout } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    PreviewText,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormLayout labelCol={8} wrapperCol={16}>\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"text preview\"\n            x-component=\"PreviewText.Input\"\n            default={'Hello world'}\n          />\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"Select item preview\"\n            x-component=\"PreviewText.Select\"\n            x-component-props={{\n              mode: 'multiple',\n            }}\n            default={['123', '222']}\n            enum={[\n              { label: 'A111', value: '123' },\n              { label: 'A222', value: '222' },\n            ]}\n          />\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"date preview\"\n            x-component=\"PreviewText.DatePicker\"\n            default={'2020-11-23 22:15:20'}\n          />\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"Cascader Preview\"\n            x-component=\"PreviewText.Cascader\"\n            default={'yuhang'}\n            enum={[\n              {\n                label: 'Hangzhou',\n                value: 'hangzhou',\n                children: [\n                  {\n                    label: 'Yuhang',\n                    value: 'yuhang',\n                  },\n                ],\n              },\n            ]}\n          />\n        </SchemaField>\n      </FormProvider>\n    </FormLayout>\n  )\n}\n```\n\n## Extended reading mode\n\n```tsx\nimport React from 'react'\nimport {\n  PreviewText,\n  FormItem,\n  FormButtonGroup,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  mapReadPretty,\n  connect,\n  createSchemaField,\n} from '@formily/react'\nimport { Button, Input as NextInput } from '@alifd/next'\n\nconst Input = connect(NextInput, mapReadPretty(PreviewText.Input))\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    PreviewText,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <PreviewText.Placeholder value=\"No data currently available\">\n      <FormLayout labelCol={8} wrapperCol={16}>\n        <FormProvider form={form}>\n          <SchemaField>\n            <SchemaField.Markup\n              type=\"string\"\n              x-decorator=\"FormItem\"\n              title=\"text preview\"\n              required\n              x-component=\"Input\"\n              default={'Hello world'}\n            />\n            <SchemaField.Markup\n              type=\"string\"\n              x-decorator=\"FormItem\"\n              title=\"Select item preview\"\n              x-component=\"PreviewText.Select\"\n              x-component-props={{\n                mode: 'multiple',\n              }}\n              default={['123']}\n              enum={[\n                { label: 'A111', value: '123' },\n                { label: 'A222', value: '222' },\n              ]}\n            />\n            <SchemaField.Markup\n              type=\"string\"\n              x-decorator=\"FormItem\"\n              title=\"date preview\"\n              x-component=\"PreviewText.DatePicker\"\n            />\n            <SchemaField.Markup\n              type=\"string\"\n              x-decorator=\"FormItem\"\n              title=\"Cascader Preview\"\n              x-component=\"PreviewText.Cascader\"\n              default={'yuhang'}\n              enum={[\n                {\n                  label: 'Hangzhou',\n                  value: 'hangzhou',\n                  children: [\n                    {\n                      label: 'Yuhang',\n                      value: 'yuhang',\n                    },\n                  ],\n                },\n              ]}\n            />\n          </SchemaField>\n          <FormButtonGroup.FormItem>\n            <Button\n              onClick={() => {\n                form.setState((state) => {\n                  state.editable = !state.editable\n                })\n              }}\n            >\n              Switch reading mode\n            </Button>\n          </FormButtonGroup.FormItem>\n        </FormProvider>\n      </FormLayout>\n    </PreviewText.Placeholder>\n  )\n}\n```\n\n## API\n\n### PreviewText.Input\n\nReference https://fusion.design/pc/component/basic/input\n\n### PreviewText.Select\n\nReference https://fusion.design/pc/component/basic/select\n\n### PreviewText.TreeSelect\n\nReference https://fusion.design/pc/component/basic/tree-select\n\n### PreviewText.Cascader\n\nReference https://fusion.design/pc/component/basic/cascader-select\n\n### PreviewText.DatePicker\n\nReference https://fusion.design/pc/component/basic/date-picker\n\n### PreviewText.DateRangePicker\n\nReference https://fusion.design/pc/component/basic/date-picker\n\n### PreviewText.TimePicker\n\nReference https://fusion.design/pc/component/basic/time-picker\n\n### PreviewText.NumberPicker\n\nReference https://fusion.design/pc/component/basic/number-picker\n\n### PreviewText.Placeholder\n\n| Property name | Type   | Description         | Default value |\n| ------------- | ------ | ------------------- | ------------- |\n| value         | stirng | Default placeholder | N/A           |\n\n### PreviewText.usePlaceholder\n\n```ts pure\ninterface usePlaceholder {\n  (): string\n}\n```\n"
  },
  {
    "path": "packages/next/docs/components/PreviewText.zh-CN.md",
    "content": "# PreviewText\n\n> 阅读态组件，主要用来实现类 Input，类 DatePicker 这些组件的阅读态\n\n## 简单用例\n\n```tsx\nimport React from 'react'\nimport { PreviewText, FormItem, FormLayout } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    PreviewText,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormLayout labelCol={8} wrapperCol={16}>\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"文本预览\"\n            x-component=\"PreviewText.Input\"\n            default={'Hello world'}\n          />\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"选择项预览\"\n            x-component=\"PreviewText.Select\"\n            x-component-props={{\n              mode: 'multiple',\n            }}\n            default={['123', '222']}\n            enum={[\n              { label: 'A111', value: '123' },\n              { label: 'A222', value: '222' },\n            ]}\n          />\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"日期预览\"\n            x-component=\"PreviewText.DatePicker\"\n            default={'2020-11-23 22:15:20'}\n          />\n          <SchemaField.String\n            x-decorator=\"FormItem\"\n            title=\"Cascader预览\"\n            x-component=\"PreviewText.Cascader\"\n            default={'yuhang'}\n            enum={[\n              {\n                label: '杭州',\n                value: 'hangzhou',\n                children: [\n                  {\n                    label: '余杭',\n                    value: 'yuhang',\n                  },\n                ],\n              },\n            ]}\n          />\n        </SchemaField>\n      </FormProvider>\n    </FormLayout>\n  )\n}\n```\n\n## 扩展阅读态\n\n```tsx\nimport React from 'react'\nimport {\n  PreviewText,\n  FormItem,\n  FormButtonGroup,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  mapReadPretty,\n  connect,\n  createSchemaField,\n} from '@formily/react'\nimport { Button, Input as NextInput } from '@alifd/next'\n\nconst Input = connect(NextInput, mapReadPretty(PreviewText.Input))\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    PreviewText,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <PreviewText.Placeholder value=\"暂无数据\">\n      <FormLayout labelCol={8} wrapperCol={16}>\n        <FormProvider form={form}>\n          <SchemaField>\n            <SchemaField.Markup\n              type=\"string\"\n              x-decorator=\"FormItem\"\n              title=\"文本预览\"\n              required\n              x-component=\"Input\"\n              default={'Hello world'}\n            />\n            <SchemaField.Markup\n              type=\"string\"\n              x-decorator=\"FormItem\"\n              title=\"选择项预览\"\n              x-component=\"PreviewText.Select\"\n              x-component-props={{\n                mode: 'multiple',\n              }}\n              default={['123']}\n              enum={[\n                { label: 'A111', value: '123' },\n                { label: 'A222', value: '222' },\n              ]}\n            />\n            <SchemaField.Markup\n              type=\"string\"\n              x-decorator=\"FormItem\"\n              title=\"日期预览\"\n              x-component=\"PreviewText.DatePicker\"\n            />\n            <SchemaField.Markup\n              type=\"string\"\n              x-decorator=\"FormItem\"\n              title=\"Cascader预览\"\n              x-component=\"PreviewText.Cascader\"\n              default={'yuhang'}\n              enum={[\n                {\n                  label: '杭州',\n                  value: 'hangzhou',\n                  children: [\n                    {\n                      label: '余杭',\n                      value: 'yuhang',\n                    },\n                  ],\n                },\n              ]}\n            />\n          </SchemaField>\n          <FormButtonGroup.FormItem>\n            <Button\n              onClick={() => {\n                form.setState((state) => {\n                  state.editable = !state.editable\n                })\n              }}\n            >\n              切换阅读态\n            </Button>\n          </FormButtonGroup.FormItem>\n        </FormProvider>\n      </FormLayout>\n    </PreviewText.Placeholder>\n  )\n}\n```\n\n## API\n\n### PreviewText.Input\n\n参考 https://fusion.design/pc/component/basic/input\n\n### PreviewText.Select\n\n参考 https://fusion.design/pc/component/basic/select\n\n### PreviewText.TreeSelect\n\n参考 https://fusion.design/pc/component/basic/tree-select\n\n### PreviewText.Cascader\n\n参考 https://fusion.design/pc/component/basic/cascader-select\n\n### PreviewText.DatePicker\n\n参考 https://fusion.design/pc/component/basic/date-picker\n\n### PreviewText.DateRangePicker\n\n参考 https://fusion.design/pc/component/basic/date-picker\n\n### PreviewText.TimePicker\n\n参考 https://fusion.design/pc/component/basic/time-picker\n\n### PreviewText.NumberPicker\n\n参考 https://fusion.design/pc/component/basic/number-picker\n\n### PreviewText.Placeholder\n\n| 属性名 | 类型   | 描述       | 默认值 |\n| ------ | ------ | ---------- | ------ |\n| value  | stirng | 缺省占位符 | N/A    |\n\n### PreviewText.usePlaceholder\n\n```ts pure\ninterface usePlaceholder {\n  (): string\n}\n```\n"
  },
  {
    "path": "packages/next/docs/components/Radio.md",
    "content": "# Radio\n\n> Single selection box\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { Radio, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Radio,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"radio\"\n        title=\"single choice\"\n        enum={[\n          {\n            label: 'Option 1',\n            value: 1,\n          },\n          {\n            label: 'Option 2',\n            value: 2,\n          },\n        ]}\n        x-decorator=\"FormItem\"\n        x-component=\"Radio.Group\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { Radio, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Radio,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    radio: {\n      type: 'number',\n      title: 'Single selection',\n      enum: [\n        {\n          label: 'Option 1',\n          value: 1,\n        },\n        {\n          label: 'Option 2',\n          value: 2,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Radio.Group',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { Radio, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"radio\"\n      title=\"single choice\"\n      dataSource={[\n        {\n          label: 'Option 1',\n          value: 1,\n        },\n        {\n          label: 'Option 2',\n          value: 2,\n        },\n      ]}\n      decorator={FormItem}\n      component={Radio.Group}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://fusion.design/pc/component/basic/radio\n"
  },
  {
    "path": "packages/next/docs/components/Radio.zh-CN.md",
    "content": "# Radio\n\n> 单选框\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Radio, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Radio,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"radio\"\n        title=\"单选\"\n        enum={[\n          {\n            label: '选项1',\n            value: 1,\n          },\n          {\n            label: '选项2',\n            value: 2,\n          },\n        ]}\n        x-decorator=\"FormItem\"\n        x-component=\"Radio.Group\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Radio, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Radio,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    radio: {\n      type: 'number',\n      title: '单选',\n      enum: [\n        {\n          label: '选项1',\n          value: 1,\n        },\n        {\n          label: '选项2',\n          value: 2,\n        },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Radio.Group',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { Radio, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"radio\"\n      title=\"单选\"\n      dataSource={[\n        {\n          label: '选项1',\n          value: 1,\n        },\n        {\n          label: '选项2',\n          value: 2,\n        },\n      ]}\n      decorator={FormItem}\n      component={Radio.Group}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://fusion.design/pc/component/basic/radio\n"
  },
  {
    "path": "packages/next/docs/components/Reset.md",
    "content": "# Reset\n\n> Reset button\n\n## Normal reset\n\n> Controls with default values cannot be cleared\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Reset } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"input box\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Reset>Reset</Reset>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Force empty reset\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Reset } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"input box\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Reset forceClear>Reset</Reset>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Reset and verify\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Reset } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"input box\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Reset validate>Reset</Reset>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Force empty reset and verify\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Reset } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"input box\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Reset forceClear validate>\n        Reset\n      </Reset>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n### Reset\n\nOther API reference https://fusion.design/pc/component/basic/button\n\n| Property name          | Type                                                                                             | Description                                              | Default value |\n| ---------------------- | ------------------------------------------------------------------------------------------------ | -------------------------------------------------------- | ------------- |\n| onClick                | `(event: MouseEvent) => void \\| boolean`                                                         | Click event, if it returns false, it can block resetting | -             |\n| onResetValidateSuccess | (payload: any) => void                                                                           | Reset validation success event                           | -             |\n| onResetValidateFailed  | (feedbacks: [IFormFeedback](https://core.formilyjs.org/api/models/form#iformfeedback)[]) => void | Reset validation failure event                           | -             |\n"
  },
  {
    "path": "packages/next/docs/components/Reset.zh-CN.md",
    "content": "# Reset\n\n> 重置按钮\n\n## 普通重置\n\n> 有默认值的控件无法被清空\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Reset } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"输入框\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Reset>重置</Reset>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 强制清空重置\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Reset } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"输入框\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Reset forceClear>重置</Reset>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 重置并校验\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Reset } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"输入框\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Reset validate>重置</Reset>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 强制清空重置并校验\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Reset } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"输入框\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Reset forceClear validate>\n        重置\n      </Reset>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n### Reset\n\n其余 API 参考 https://fusion.design/pc/component/basic/button\n\n| 属性名                 | 类型                                                                                                   | 描述                                  | 默认值 |\n| ---------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------- | ------ |\n| onClick                | `(event: MouseEvent) => void \\| boolean`                                                               | 点击事件，如果返回 false 可以阻塞重置 | -      |\n| onResetValidateSuccess | (payload: any) => void                                                                                 | 重置校验成功事件                      | -      |\n| onResetValidateFailed  | (feedbacks: [IFormFeedback](https://core.formilyjs.org/zh-CN/api/models/form#iformfeedback)[]) => void | 重置校验失败事件                      | -      |\n"
  },
  {
    "path": "packages/next/docs/components/Select.md",
    "content": "# Select\n\n> Drop-down box components\n\n## Markup Schema synchronization data source case\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"select\"\n        title=\"select box\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        enum={[\n          { label: 'Option 1', value: 1 },\n          { label: 'Option 2', value: 2 },\n        ]}\n        x-component-props={{\n          style: {\n            width: 120,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Markup Schema Asynchronous Linkage Data Source Case\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm, onFieldReact, FormPathPattern, Field } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    FormItem,\n  },\n})\n\nconst useAsyncDataSource = (\n  pattern: FormPathPattern,\n  service: (field: Field) => Promise<{ label: string; value: any }[]>\n) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service(field).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async (field) => {\n      const linkage = field.query('linkage').get('value')\n      if (!linkage) return []\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          if (linkage === 1) {\n            resolve([\n              {\n                label: 'AAA',\n                value: 'aaa',\n              },\n              {\n                label: 'BBB',\n                value: 'ccc',\n              },\n            ])\n          } else if (linkage === 2) {\n            resolve([\n              {\n                label: 'CCC',\n                value: 'ccc',\n              },\n              {\n                label: 'DDD',\n                value: 'ddd',\n              },\n            ])\n          }\n        }, 1500)\n      })\n    })\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"linkage\"\n        title=\"Linkage selection box\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        enum={[\n          { label: 'Request 1', value: 1 },\n          { label: 'Request 2', value: 2 },\n        ]}\n        x-component-props={{\n          style: {\n            width: 120,\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"select\"\n        title=\"Asynchronous select box\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        x-component-props={{\n          style: {\n            width: 120,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema synchronization data source case\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    select: {\n      type: 'string',\n      title: 'Select box',\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      enum: [\n        { label: 'Option 1', value: 1 },\n        { label: 'Option 2', value: 2 },\n      ],\n      'x-component-props': {\n        style: {\n          width: 120,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema asynchronous linkage data source case\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    FormItem,\n  },\n})\n\nconst loadData = async (field) => {\n  const linkage = field.query('linkage').get('value')\n  if (!linkage) return []\n  return new Promise((resolve) => {\n    setTimeout(() => {\n      if (linkage === 1) {\n        resolve([\n          {\n            label: 'AAA',\n            value: 'aaa',\n          },\n          {\n            label: 'BBB',\n            value: 'ccc',\n          },\n        ])\n      } else if (linkage === 2) {\n        resolve([\n          {\n            label: 'CCC',\n            value: 'ccc',\n          },\n          {\n            label: 'DDD',\n            value: 'ddd',\n          },\n        ])\n      }\n    }, 1500)\n  })\n}\n\nconst useAsyncDataSource = (service) => (field) => {\n  field.loading = true\n  service(field).then(\n    action.bound((data) => {\n      field.dataSource = data\n      field.loading = false\n    })\n  )\n}\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    linkage: {\n      type: 'string',\n      title: 'Linkage selection box',\n      enum: [\n        { label: 'Request 1', value: 1 },\n        { label: 'Request 2', value: 2 },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      'x-component-props': {\n        style: {\n          width: 120,\n        },\n      },\n    },\n    select: {\n      type: 'string',\n      title: 'Asynchronous selection box',\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      'x-component-props': {\n        style: {\n          width: 120,\n        },\n      },\n      'x-reactions': ['{{useAsyncDataSource(loadData)}}'],\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} scope={{ useAsyncDataSource, loadData }} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX synchronization data source case\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"select\"\n      title=\"select box\"\n      dataSource={[\n        { label: 'Option 1', value: 1 },\n        { label: 'Option 2', value: 2 },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        Select,\n        {\n          style: {\n            width: 120,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX asynchronous linkage data source case\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport {\n  createForm,\n  onFieldReact,\n  FormPathPattern,\n  FieldType,\n} from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst useAsyncDataSource = (\n  pattern: FormPathPattern,\n  service: (field: FieldType) => Promise<{ label: string; value: any }[]>\n) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service(field).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async (field) => {\n      const linkage = field.query('linkage').get('value')\n      if (!linkage) return []\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          if (linkage === 1) {\n            resolve([\n              {\n                label: 'AAA',\n                value: 'aaa',\n              },\n              {\n                label: 'BBB',\n                value: 'ccc',\n              },\n            ])\n          } else if (linkage === 2) {\n            resolve([\n              {\n                label: 'CCC',\n                value: 'ccc',\n              },\n              {\n                label: 'DDD',\n                value: 'ddd',\n              },\n            ])\n          }\n        }, 1500)\n      })\n    })\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"linkage\"\n      title=\"Linkage selection box\"\n      dataSource={[\n        { label: 'Request 1', value: 1 },\n        { label: 'Request 2', value: 2 },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        Select,\n        {\n          style: {\n            width: 120,\n          },\n        },\n      ]}\n    />\n    <Field\n      name=\"select\"\n      title=\"Asynchronous select box\"\n      decorator={[FormItem]}\n      component={[\n        Select,\n        {\n          style: {\n            width: 120,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://fusion.design/pc/component/basic/select\n"
  },
  {
    "path": "packages/next/docs/components/Select.zh-CN.md",
    "content": "# Select\n\n> 下拉框组件\n\n## Markup Schema 同步数据源案例\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"select\"\n        title=\"选择框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        enum={[\n          { label: '选项1', value: 1 },\n          { label: '选项2', value: 2 },\n        ]}\n        x-component-props={{\n          style: {\n            width: 120,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Markup Schema 异步联动数据源案例\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm, onFieldReact, FormPathPattern, Field } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    FormItem,\n  },\n})\n\nconst useAsyncDataSource = (\n  pattern: FormPathPattern,\n  service: (field: Field) => Promise<{ label: string; value: any }[]>\n) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service(field).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async (field) => {\n      const linkage = field.query('linkage').get('value')\n      if (!linkage) return []\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          if (linkage === 1) {\n            resolve([\n              {\n                label: 'AAA',\n                value: 'aaa',\n              },\n              {\n                label: 'BBB',\n                value: 'ccc',\n              },\n            ])\n          } else if (linkage === 2) {\n            resolve([\n              {\n                label: 'CCC',\n                value: 'ccc',\n              },\n              {\n                label: 'DDD',\n                value: 'ddd',\n              },\n            ])\n          }\n        }, 1500)\n      })\n    })\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"linkage\"\n        title=\"联动选择框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        enum={[\n          { label: '发请求1', value: 1 },\n          { label: '发请求2', value: 2 },\n        ]}\n        x-component-props={{\n          style: {\n            width: 120,\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"select\"\n        title=\"异步选择框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        x-component-props={{\n          style: {\n            width: 120,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 同步数据源案例\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    select: {\n      type: 'string',\n      title: '选择框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      enum: [\n        { label: '选项1', value: 1 },\n        { label: '选项2', value: 2 },\n      ],\n      'x-component-props': {\n        style: {\n          width: 120,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 异步联动数据源案例\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    FormItem,\n  },\n})\n\nconst loadData = async (field) => {\n  const linkage = field.query('linkage').get('value')\n  if (!linkage) return []\n  return new Promise((resolve) => {\n    setTimeout(() => {\n      if (linkage === 1) {\n        resolve([\n          {\n            label: 'AAA',\n            value: 'aaa',\n          },\n          {\n            label: 'BBB',\n            value: 'ccc',\n          },\n        ])\n      } else if (linkage === 2) {\n        resolve([\n          {\n            label: 'CCC',\n            value: 'ccc',\n          },\n          {\n            label: 'DDD',\n            value: 'ddd',\n          },\n        ])\n      }\n    }, 1500)\n  })\n}\n\nconst useAsyncDataSource = (service) => (field) => {\n  field.loading = true\n  service(field).then(\n    action.bound((data) => {\n      field.dataSource = data\n      field.loading = false\n    })\n  )\n}\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    linkage: {\n      type: 'string',\n      title: '联动选择框',\n      enum: [\n        { label: '发请求1', value: 1 },\n        { label: '发请求2', value: 2 },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      'x-component-props': {\n        style: {\n          width: 120,\n        },\n      },\n    },\n    select: {\n      type: 'string',\n      title: '异步选择框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      'x-component-props': {\n        style: {\n          width: 120,\n        },\n      },\n      'x-reactions': ['{{useAsyncDataSource(loadData)}}'],\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} scope={{ useAsyncDataSource, loadData }} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 同步数据源案例\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"select\"\n      title=\"选择框\"\n      dataSource={[\n        { label: '选项1', value: 1 },\n        { label: '选项2', value: 2 },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        Select,\n        {\n          style: {\n            width: 120,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 异步联动数据源案例\n\n```tsx\nimport React from 'react'\nimport { Select, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport {\n  createForm,\n  onFieldReact,\n  FormPathPattern,\n  FieldType,\n} from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst useAsyncDataSource = (\n  pattern: FormPathPattern,\n  service: (field: FieldType) => Promise<{ label: string; value: any }[]>\n) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service(field).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async (field) => {\n      const linkage = field.query('linkage').get('value')\n      if (!linkage) return []\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          if (linkage === 1) {\n            resolve([\n              {\n                label: 'AAA',\n                value: 'aaa',\n              },\n              {\n                label: 'BBB',\n                value: 'ccc',\n              },\n            ])\n          } else if (linkage === 2) {\n            resolve([\n              {\n                label: 'CCC',\n                value: 'ccc',\n              },\n              {\n                label: 'DDD',\n                value: 'ddd',\n              },\n            ])\n          }\n        }, 1500)\n      })\n    })\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"linkage\"\n      title=\"联动选择框\"\n      dataSource={[\n        { label: '发请求1', value: 1 },\n        { label: '发请求2', value: 2 },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        Select,\n        {\n          style: {\n            width: 120,\n          },\n        },\n      ]}\n    />\n    <Field\n      name=\"select\"\n      title=\"异步选择框\"\n      decorator={[FormItem]}\n      component={[\n        Select,\n        {\n          style: {\n            width: 120,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://fusion.design/pc/component/basic/select\n"
  },
  {
    "path": "packages/next/docs/components/SelectTable.md",
    "content": "# SelectTable\n\n> Optional table components\n\n## Markup Schema single case\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    SelectTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Object\n          type=\"string\"\n          name=\"selectTable\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            hasBorder: false,\n            mode: 'single',\n          }}\n          enum={[\n            { key: '1', name: 'title-1', description: 'description-1' },\n            { key: '2', name: 'Title-2', description: 'description-2' },\n          ]}\n        >\n          <SchemaField.Void\n            name=\"name\"\n            title=\"Title\"\n            x-component=\"SelectTable.Column\"\n          />\n          <SchemaField.Void\n            name=\"description\"\n            title=\"Description\"\n            x-component=\"SelectTable.Column\"\n          />\n        </SchemaField.Object>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## Markup Schema filter case\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    SelectTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          type=\"array\"\n          name=\"selectTable\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            hasBorder: false,\n            showSearch: true,\n            optionAsValue: true,\n          }}\n          enum={[\n            { key: '1', name: 'title-1', description: 'description-1' },\n            { key: '2', name: 'Title-2', description: 'description-2' },\n          ]}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              name=\"name\"\n              title=\"Title\"\n              x-component=\"SelectTable.Column\"\n            />\n            <SchemaField.Void\n              name=\"description\"\n              title=\"Description\"\n              x-component=\"SelectTable.Column\"\n            />\n          </SchemaField.Object>\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## Markup Schema async data source case\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    SelectTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  const onSearch = (value) => {\n    const field = form.query('selectTable').take()\n    field.loading = true\n    setTimeout(() => {\n      field.setState({\n        dataSource: [\n          {\n            key: '3',\n            name: 'AAA' + value,\n            description: 'aaa',\n          },\n          {\n            key: '4',\n            name: 'BBB' + value,\n            description: 'bbb',\n          },\n        ],\n        loading: false,\n      })\n    }, 1500)\n  }\n\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Object\n          type=\"object\"\n          name=\"selectTable\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            hasBorder: false,\n            showSearch: true,\n            filterOption: false,\n            onSearch,\n          }}\n          enum={[\n            { key: '1', name: 'title-1', description: 'description-1' },\n            { key: '2', name: 'title-2', description: 'description-2' },\n          ]}\n        >\n          <SchemaField.Void\n            name=\"name\"\n            title=\"Title\"\n            x-component=\"SelectTable.Column\"\n          />\n          <SchemaField.Void\n            name=\"description\"\n            title=\"Description\"\n            x-component=\"SelectTable.Column\"\n          />\n        </SchemaField.Object>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## Markup Schema read-pretty case\n\n```tsx\nimport React from 'react'\nimport {\n  Form,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  SelectTable,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    SelectTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <Form form={form} layout=\"vertical\">\n      <SchemaField>\n        <SchemaField.Object\n          title=\"single\"\n          type=\"string\"\n          name=\"selectTable1\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            hasBorder: false,\n            mode: 'single',\n          }}\n          default=\"1\"\n          enum={[\n            { key: '1', name: 'title-1', description: 'description-1' },\n            { key: '2', name: 'Title-2', description: 'description-2' },\n          ]}\n          x-read-pretty={true}\n        >\n          <SchemaField.Void\n            name=\"name\"\n            title=\"Title\"\n            x-component=\"SelectTable.Column\"\n          />\n          <SchemaField.Void\n            name=\"description\"\n            title=\"Description\"\n            x-component=\"SelectTable.Column\"\n          />\n        </SchemaField.Object>\n        <SchemaField.Object\n          title=\"single + optionAsValue\"\n          type=\"string\"\n          name=\"selectTable2\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            hasBorder: false,\n            mode: 'single',\n            optionAsValue: true,\n          }}\n          default={{ key: '1', name: 'Title1', description: 'Description1' }}\n          enum={[\n            { key: '1', name: 'title-1', description: 'description-1' },\n            { key: '2', name: 'Title-2', description: 'description-2' },\n          ]}\n          x-read-pretty={true}\n        >\n          <SchemaField.Void\n            name=\"name\"\n            title=\"Title\"\n            x-component=\"SelectTable.Column\"\n          />\n          <SchemaField.Void\n            name=\"description\"\n            title=\"Description\"\n            x-component=\"SelectTable.Column\"\n          />\n        </SchemaField.Object>\n        <SchemaField.Array\n          title=\"multiple\"\n          type=\"array\"\n          name=\"selectTable3\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            hasBorder: false,\n          }}\n          default={['1', '3']}\n          enum={[\n            { key: '1', name: 'title-1', description: 'description-1' },\n            { key: '2', name: 'Title-2', description: 'description-2' },\n            { key: '3', name: 'title-3', description: 'description-3' },\n          ]}\n          x-read-pretty={true}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              name=\"name\"\n              title=\"Title\"\n              x-component=\"SelectTable.Column\"\n            />\n            <SchemaField.Void\n              name=\"description\"\n              title=\"Description\"\n              x-component=\"SelectTable.Column\"\n            />\n          </SchemaField.Object>\n        </SchemaField.Array>\n        <SchemaField.Array\n          title=\"multiple + optionAsValue\"\n          type=\"array\"\n          name=\"selectTable4\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            hasBorder: false,\n            optionAsValue: true,\n          }}\n          default={[\n            { key: '1', name: 'title-1', description: 'description-1' },\n            { key: '3', name: 'title-3', description: 'description-3' },\n          ]}\n          enum={[\n            { key: '1', name: 'title-1', description: 'description-1' },\n            { key: '2', name: 'Title-2', description: 'description-2' },\n            { key: '3', name: 'title-3', description: 'description-3' },\n          ]}\n          x-read-pretty={true}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              name=\"name\"\n              title=\"Title\"\n              x-component=\"SelectTable.Column\"\n            />\n            <SchemaField.Void\n              name=\"description\"\n              title=\"Description\"\n              x-component=\"SelectTable.Column\"\n            />\n          </SchemaField.Object>\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </Form>\n  )\n}\n```\n\n## JSON Schema multiple case\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    SelectTable,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    selectTable: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'SelectTable',\n      'x-component-props': {\n        hasBorder: false,\n        mode: 'multiple',\n      },\n      enum: [\n        { key: '1', name: 'title-1', description: 'description-1' },\n        { key: '2', name: 'Title-2', description: 'description-2' },\n      ],\n      properties: {\n        name: {\n          title: 'Title',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '40%',\n          },\n        },\n        description: {\n          title: 'Description',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '60%',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema custom filter case\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    SelectTable,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    selectTable: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'SelectTable',\n      'x-component-props': {\n        hasBorder: false,\n        showSearch: true,\n        primaryKey: 'key',\n        isTree: true,\n        filterOption: (input, option) =>\n          option.description.toLowerCase().indexOf(input.toLowerCase()) >= 0,\n        filterSort: (optionA, optionB) =>\n          optionA.description\n            .toLowerCase()\n            .localeCompare(optionB.description.toLowerCase()),\n        optionAsValue: true,\n        rowSelection: {\n          checkStrictly: false,\n        },\n      },\n      enum: [\n        { key: '1', name: 'title-1', description: 'A-description' },\n        {\n          key: '2',\n          name: 'title-2',\n          description: 'X-description',\n          children: [\n            {\n              key: '2-1',\n              name: 'title2-1',\n              description: 'Y-description',\n              children: [\n                {\n                  key: '2-1-1',\n                  name: 'title-2-1-1',\n                  description: 'Z-description',\n                },\n              ],\n            },\n            {\n              key: '2-2',\n              name: 'title2-2',\n              description: 'YY-description',\n            },\n          ],\n        },\n        { key: '3', name: 'title-3', description: 'C-description' },\n      ],\n      properties: {\n        name: {\n          title: 'Title',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '40%',\n          },\n        },\n        description: {\n          title: 'Description',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '60%',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema async data source case\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    SelectTable,\n    FormItem,\n  },\n})\n\nconst loadData = async (value) => {\n  return new Promise((resolve) => {\n    setTimeout(() => {\n      resolve([\n        { key: '3', name: 'AAA' + value, description: 'aaa' },\n        { key: '4', name: 'BBB' + value, description: 'bbb' },\n      ])\n    }, 1500)\n  })\n}\n\nconst useAsyncDataSource = (service, field) => (value) => {\n  field.loading = true\n  service(value).then((data) => {\n    field.setState({\n      dataSource: data,\n      loading: false,\n    })\n  })\n}\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    selectTable: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'SelectTable',\n      'x-component-props': {\n        hasBorder: false,\n        showSearch: true,\n        filterOption: false,\n        onSearch: '{{useAsyncDataSource(loadData,$self)}}',\n      },\n      enum: [\n        { key: '1', name: 'title-1', description: 'description-1' },\n        { key: '2', name: 'title-2', description: 'description-2' },\n      ],\n      properties: {\n        name: {\n          title: 'Title',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '40%',\n          },\n        },\n        description: {\n          title: 'Description',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '60%',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} scope={{ useAsyncDataSource, loadData }} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"SelectTable\"\n      dataSource={[\n        { key: '1', name: 'title-1', description: 'description-1' },\n        { key: '2', name: 'title-2', description: 'description-2' },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        SelectTable,\n        {\n          hasBorder: false,\n          columns: [\n            { dataIndex: 'name', title: 'Title' },\n            { dataIndex: 'description', title: 'Description' },\n          ],\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n### SelectTable\n\n| Property name | Type                                               | Description                                                                                                                                                                                                                                                 | Default value |\n| ------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |\n| mode          | `'multiple' \\| 'single'`                           | Set mode of SelectTable                                                                                                                                                                                                                                     | `'multiple'`  |\n| valueType     | `'all' \\| 'parent' \\| 'child' \\| 'path'`           | value type, Only applies when checkStrictly is set to `false`                                                                                                                                                                                               | `'all'`       |\n| optionAsValue | boolean                                            | use `option` as value, Only applies when valueType is not set to `'path'`                                                                                                                                                                                   | false         |\n| showSearch    | boolean                                            | show `Search` component                                                                                                                                                                                                                                     | false         |\n| searchProps   | object                                             | `Search` component props                                                                                                                                                                                                                                    | -             |\n| primaryKey    | `string \\| (record) => string`                     | Row's unique key                                                                                                                                                                                                                                            | `'key'`       |\n| filterOption  | `boolean \\| (inputValue, option) => boolean`       | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns true, the option will be included in the filtered set; Otherwise, it will be excluded |\n| filterSort    | (optionA, optionB) => number                       | Sort function for search options sorting, see Array.sort's compareFunction                                                                                                                                                                                  | -             |\n| onSearch      | Callback function that is fired when input changed | (inputValue) => void                                                                                                                                                                                                                                        | -             |\n\n`TableProps` type definition reference fusion https://fusion.design/pc/component/basic/table\n\n### rowSelection\n\n| Property name | Type    | Description                                                                | Default value |\n| ------------- | ------- | -------------------------------------------------------------------------- | ------------- |\n| checkStrictly | boolean | Check table row precisely; parent row and children rows are not associated | true          |\n\n`rowSelectionProps` type definition reference fusion https://fusion.design/pc/component/basic/table rowSelection\n\n### SelectTable.Column\n\n`ColumnProps` type definition reference fusion https://fusion.design/pc/component/basic/table Table.Column\n"
  },
  {
    "path": "packages/next/docs/components/SelectTable.zh-CN.md",
    "content": "# SelectTable\n\n> 表格选择组件\n\n## Markup Schema 单选案例\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    SelectTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Object\n          type=\"string\"\n          name=\"selectTable\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            hasBorder: false,\n            mode: 'single',\n          }}\n          enum={[\n            { key: '1', name: '标题1', description: '描述1' },\n            { key: '2', name: '标题2', description: '描述2' },\n          ]}\n        >\n          <SchemaField.Void\n            name=\"name\"\n            title=\"标题\"\n            x-component=\"SelectTable.Column\"\n          />\n          <SchemaField.Void\n            name=\"description\"\n            title=\"描述\"\n            x-component=\"SelectTable.Column\"\n          />\n        </SchemaField.Object>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## Markup Schema 筛选案例\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    SelectTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Array\n          type=\"array\"\n          name=\"selectTable\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            hasBorder: false,\n            showSearch: true,\n            optionAsValue: true,\n          }}\n          enum={[\n            { key: '1', name: '标题1', description: '描述1' },\n            { key: '2', name: '标题2', description: '描述2' },\n          ]}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              name=\"name\"\n              title=\"标题\"\n              x-component=\"SelectTable.Column\"\n            />\n            <SchemaField.Void\n              name=\"description\"\n              title=\"描述\"\n              x-component=\"SelectTable.Column\"\n            />\n          </SchemaField.Object>\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## Markup Schema 异步数据源案例\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    SelectTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  const onSearch = (value) => {\n    const field = form.query('selectTable').take()\n    field.loading = true\n    setTimeout(() => {\n      field.setState({\n        dataSource: [\n          {\n            key: '3',\n            name: 'AAA' + value,\n            description: 'aaa',\n          },\n          {\n            key: '4',\n            name: 'BBB' + value,\n            description: 'bbb',\n          },\n        ],\n        loading: false,\n      })\n    }, 1500)\n  }\n\n  return (\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Object\n          type=\"object\"\n          name=\"selectTable\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            hasBorder: false,\n            showSearch: true,\n            filterOption: false,\n            onSearch,\n          }}\n          enum={[\n            { key: '1', name: '标题1', description: '描述1' },\n            { key: '2', name: '标题2', description: '描述2' },\n          ]}\n        >\n          <SchemaField.Void\n            name=\"name\"\n            title=\"标题\"\n            x-component=\"SelectTable.Column\"\n          />\n          <SchemaField.Void\n            name=\"description\"\n            title=\"描述\"\n            x-component=\"SelectTable.Column\"\n          />\n        </SchemaField.Object>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormProvider>\n  )\n}\n```\n\n## Markup Schema 阅读态案例\n\n```tsx\nimport React from 'react'\nimport {\n  Form,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  SelectTable,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    FormItem,\n    SelectTable,\n  },\n})\n\nconst form = createForm()\n\nexport default () => {\n  return (\n    <Form form={form} layout=\"vertical\">\n      <SchemaField>\n        <SchemaField.Object\n          title=\"单选\"\n          type=\"string\"\n          name=\"selectTable1\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            hasBorder: false,\n            mode: 'single',\n          }}\n          default=\"1\"\n          enum={[\n            { key: '1', name: '标题1', description: '描述1' },\n            { key: '2', name: '标题2', description: '描述2' },\n          ]}\n          x-read-pretty={true}\n        >\n          <SchemaField.Void\n            name=\"name\"\n            title=\"标题\"\n            x-component=\"SelectTable.Column\"\n          />\n          <SchemaField.Void\n            name=\"description\"\n            title=\"描述\"\n            x-component=\"SelectTable.Column\"\n          />\n        </SchemaField.Object>\n        <SchemaField.Object\n          title=\"单选 + optionAsValue\"\n          type=\"string\"\n          name=\"selectTable2\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            hasBorder: false,\n            mode: 'single',\n            optionAsValue: true,\n          }}\n          default={{ key: '1', name: '标题1', description: '描述1' }}\n          enum={[\n            { key: '1', name: '标题1', description: '描述1' },\n            { key: '2', name: '标题2', description: '描述2' },\n          ]}\n          x-read-pretty={true}\n        >\n          <SchemaField.Void\n            name=\"name\"\n            title=\"标题\"\n            x-component=\"SelectTable.Column\"\n          />\n          <SchemaField.Void\n            name=\"description\"\n            title=\"描述\"\n            x-component=\"SelectTable.Column\"\n          />\n        </SchemaField.Object>\n        <SchemaField.Array\n          title=\"多选\"\n          type=\"array\"\n          name=\"selectTable3\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            hasBorder: false,\n          }}\n          default={['1', '3']}\n          enum={[\n            { key: '1', name: '标题1', description: '描述1' },\n            { key: '2', name: '标题2', description: '描述2' },\n            { key: '3', name: '标题3', description: '描述3' },\n          ]}\n          x-read-pretty={true}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              name=\"name\"\n              title=\"标题\"\n              x-component=\"SelectTable.Column\"\n            />\n            <SchemaField.Void\n              name=\"description\"\n              title=\"描述\"\n              x-component=\"SelectTable.Column\"\n            />\n          </SchemaField.Object>\n        </SchemaField.Array>\n        <SchemaField.Array\n          title=\"多选 + optionAsValue\"\n          type=\"array\"\n          name=\"selectTable4\"\n          x-decorator=\"FormItem\"\n          x-component=\"SelectTable\"\n          x-component-props={{\n            hasBorder: false,\n            optionAsValue: true,\n          }}\n          default={[\n            { key: '1', name: '标题1', description: '描述1' },\n            { key: '3', name: '标题3', description: '描述3' },\n          ]}\n          enum={[\n            { key: '1', name: '标题1', description: '描述1' },\n            { key: '2', name: '标题2', description: '描述2' },\n            { key: '3', name: '标题3', description: '描述3' },\n          ]}\n          x-read-pretty={true}\n        >\n          <SchemaField.Object>\n            <SchemaField.Void\n              name=\"name\"\n              title=\"标题\"\n              x-component=\"SelectTable.Column\"\n            />\n            <SchemaField.Void\n              name=\"description\"\n              title=\"描述\"\n              x-component=\"SelectTable.Column\"\n            />\n          </SchemaField.Object>\n        </SchemaField.Array>\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </Form>\n  )\n}\n```\n\n## JSON Schema 多选案例\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    SelectTable,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    selectTable: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'SelectTable',\n      'x-component-props': {\n        hasBorder: false,\n        mode: 'multiple',\n      },\n      enum: [\n        { key: '1', name: '标题1', description: '描述1' },\n        { key: '2', name: '标题2', description: '描述2' },\n      ],\n      properties: {\n        name: {\n          title: '标题',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '40%',\n          },\n        },\n        description: {\n          title: '描述',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '60%',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 自定义筛选案例\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    SelectTable,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    selectTable: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'SelectTable',\n      'x-component-props': {\n        hasBorder: false,\n        showSearch: true,\n        primaryKey: 'key',\n        isTree: true,\n        filterOption: (input, option) =>\n          option.description.toLowerCase().indexOf(input.toLowerCase()) >= 0,\n        filterSort: (optionA, optionB) =>\n          optionA.description\n            .toLowerCase()\n            .localeCompare(optionB.description.toLowerCase()),\n        optionAsValue: true,\n        rowSelection: {\n          checkStrictly: false,\n        },\n      },\n      enum: [\n        { key: '1', name: '标题1', description: 'A-描述' },\n        {\n          key: '2',\n          name: '标题2',\n          description: 'X-描述',\n          children: [\n            {\n              key: '2-1',\n              name: '标题2-1',\n              description: 'Y-描述',\n              children: [\n                { key: '2-1-1', name: '标题2-1-1', description: 'Z-描述' },\n              ],\n            },\n            {\n              key: '2-2',\n              name: '标题2-2',\n              description: 'YY-描述',\n            },\n          ],\n        },\n        { key: '3', name: '标题3', description: 'C-描述' },\n      ],\n      properties: {\n        name: {\n          title: '标题',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '40%',\n          },\n        },\n        description: {\n          title: '描述',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '60%',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 异步数据源案例\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    SelectTable,\n    FormItem,\n  },\n})\n\nconst loadData = async (value) => {\n  return new Promise((resolve) => {\n    setTimeout(() => {\n      resolve([\n        { key: '3', name: 'AAA' + value, description: 'aaa' },\n        { key: '4', name: 'BBB' + value, description: 'bbb' },\n      ])\n    }, 1500)\n  })\n}\n\nconst useAsyncDataSource = (service, field) => (value) => {\n  field.loading = true\n  service(value).then((data) => {\n    field.setState({\n      dataSource: data,\n      loading: false,\n    })\n  })\n}\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    selectTable: {\n      type: 'array',\n      'x-decorator': 'FormItem',\n      'x-component': 'SelectTable',\n      'x-component-props': {\n        hasBorder: false,\n        showSearch: true,\n        filterOption: false,\n        onSearch: '{{useAsyncDataSource(loadData,$self)}}',\n      },\n      enum: [\n        { key: '1', name: '标题1', description: '描述1' },\n        { key: '2', name: '标题2', description: '描述2' },\n      ],\n      properties: {\n        name: {\n          title: '标题',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '40%',\n          },\n        },\n        description: {\n          title: '描述',\n          type: 'string',\n          'x-component': 'SelectTable.Column',\n          'x-component-props': {\n            width: '60%',\n          },\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} scope={{ useAsyncDataSource, loadData }} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { FormItem, FormButtonGroup, Submit, SelectTable } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"SelectTable\"\n      dataSource={[\n        { key: '1', name: '标题1', description: '描述1' },\n        { key: '2', name: '标题2', description: '描述2' },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        SelectTable,\n        {\n          hasBorder: false,\n          columns: [\n            { dataIndex: 'name', title: '标题' },\n            { dataIndex: 'description', title: '描述' },\n          ],\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n### SelectTable\n\n| 属性名        | 类型                                         | 描述                                                                                                                                 | 默认值       |\n| ------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ------------ |\n| mode          | `'multiple' \\| 'single'`                     | 设置 SelectTable 模式为单选或多选                                                                                                    | `'multiple'` |\n| valueType     | `'all' \\| 'parent' \\| 'child' \\| 'path'`     | 返回值类型，checkStrictly 设置为 `false` 时有效                                                                                      | `'all'`      |\n| optionAsValue | boolean                                      | 使用表格行数据作为值，valueType 值为 `'path'` 时无效                                                                                 | false        |\n| showSearch    | boolean                                      | 是否显示搜索组件                                                                                                                     | false        |\n| searchProps   | object                                       | Search 组件属性                                                                                                                      | -            |\n| primaryKey    | `string \\| (record) => string`               | 表格行 key 的取值                                                                                                                    | `'key'`      |\n| filterOption  | `boolean \\| (inputValue, option) => boolean` | 是否根据输入项进行筛选。当其为一个函数时，会接收 inputValue option 两个参数，当 option 符合筛选条件时，应返回 true，反之则返回 false | true         |\n| filterSort    | (optionA, optionB) => number                 | 搜索时对筛选结果项的排序函数, 类似 Array.sort 里的 compareFunction                                                                   | -            |\n| onSearch      | 文本框值变化时回调                           | (inputValue) => void                                                                                                                 | -            |\n\n参考 https://fusion.design/pc/component/basic/table\n\n### rowSelection\n\n| 属性名        | 类型    | 描述                                                         | 默认值 |\n| ------------- | ------- | ------------------------------------------------------------ | ------ |\n| checkStrictly | boolean | checkable 状态下节点选择完全受控（父子数据选中状态不再关联） | true   |\n\n参考 https://fusion.design/pc/component/basic/table rowSelection\n\n### SelectTable.Column\n\n参考 https://fusion.design/pc/component/basic/table Table.Column 属性\n"
  },
  {
    "path": "packages/next/docs/components/Space.md",
    "content": "# Space\n\n> Super convenient Flex layout component, can help users quickly realize the layout of any element side by side next to each other\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    Space,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={16}>\n      <SchemaField>\n        <SchemaField.Void\n          title=\"name\"\n          x-decorator=\"FormItem\"\n          x-decorator-props={{\n            asterisk: true,\n            feedbackLayout: 'none',\n          }}\n          x-component=\"Space\"\n        >\n          <SchemaField.String\n            name=\"firstName\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            required\n          />\n          <SchemaField.String\n            name=\"lastName\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            x-visible=\"{{$values.firstName === '123'}}\"\n            required\n          />\n          <SchemaField.String\n            name=\"kk\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            x-decorator-props={{\n              addonAfter: 'Unit',\n            }}\n            required\n          />\n        </SchemaField.Void>\n        <SchemaField.Void\n          title=\"Text concatenation\"\n          x-decorator=\"FormItem\"\n          x-decorator-props={{\n            asterisk: true,\n            feedbackLayout: 'none',\n          }}\n          x-component=\"Space\"\n        >\n          <SchemaField.String\n            name=\"aa\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            x-decorator-props={{\n              addonAfter: 'Unit',\n            }}\n            required\n          />\n          <SchemaField.String\n            name=\"bb\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            x-decorator-props={{\n              addonAfter: 'Unit',\n            }}\n            required\n          />\n          <SchemaField.String\n            name=\"cc\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            x-decorator-props={{\n              addonAfter: 'Unit',\n            }}\n            required\n          />\n        </SchemaField.Void>\n        <SchemaField.String\n          name=\"textarea\"\n          title=\"text box\"\n          x-decorator=\"FormItem\"\n          required\n          x-component=\"Input.TextArea\"\n          x-component-props={{\n            style: {\n              width: 400,\n            },\n          }}\n        />\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    Space,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    name: {\n      type: 'void',\n      title: 'Name',\n      'x-decorator': 'FormItem',\n      'x-decorator-props': {\n        asterisk: true,\n        feedbackLayout: 'none',\n      },\n      'x-component': 'Space',\n      properties: {\n        firstName: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          required: true,\n        },\n        lastName: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          required: true,\n        },\n      },\n    },\n    texts: {\n      type: 'void',\n      title: 'Text concatenation',\n      'x-decorator': 'FormItem',\n      'x-decorator-props': {\n        asterisk: true,\n        feedbackLayout: 'none',\n      },\n      'x-component': 'Space',\n      properties: {\n        aa: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            addonAfter: 'Unit',\n          },\n          'x-component': 'Input',\n          required: true,\n        },\n        bb: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            addonAfter: 'Unit',\n          },\n          'x-component': 'Input',\n          required: true,\n        },\n        cc: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            addonAfter: 'Unit',\n          },\n          'x-component': 'Input',\n          required: true,\n        },\n      },\n    },\n\n    textarea: {\n      type: 'string',\n      title: 'Text box',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input.TextArea',\n      'x-component-props': {\n        style: {\n          width: 400,\n        },\n      },\n      required: true,\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={16}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, VoidField } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={16}>\n      <VoidField\n        name=\"name\"\n        title=\"name\"\n        decorator={[\n          FormItem,\n          {\n            asterisk: true,\n            feedbackLayout: 'none',\n          },\n        ]}\n        component={[Space]}\n      >\n        <Field\n          name=\"firstName\"\n          decorator={[FormItem]}\n          component={[Input]}\n          required\n        />\n        <Field\n          name=\"lastName\"\n          decorator={[FormItem]}\n          component={[Input]}\n          required\n        />\n      </VoidField>\n      <VoidField\n        name=\"texts\"\n        title=\"Text concatenation\"\n        decorator={[\n          FormItem,\n          {\n            asterisk: true,\n            feedbackLayout: 'none',\n          },\n        ]}\n        component={[Space]}\n      >\n        <Field\n          name=\"aa\"\n          decorator={[\n            FormItem,\n            {\n              addonAfter: 'Unit',\n            },\n          ]}\n          component={[Input]}\n          required\n        />\n        <Field\n          name=\"bb\"\n          decorator={[\n            FormItem,\n            {\n              addonAfter: 'Unit',\n            },\n          ]}\n          component={[Input]}\n          required\n        />\n        <Field\n          name=\"cc\"\n          decorator={[\n            FormItem,\n            {\n              addonAfter: 'Unit',\n            },\n          ]}\n          component={[Input]}\n          required\n        />\n      </VoidField>\n      <Field\n        name=\"textarea\"\n        title=\"text box\"\n        decorator={[FormItem]}\n        component={[\n          Input.TextArea,\n          {\n            style: {\n              width: 400,\n            },\n          },\n        ]}\n        required\n      />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## API\n\n| Property name | Type                                      | Description     | Default value |\n| ------------- | ----------------------------------------- | --------------- | ------------- |\n| style         | CSSProperties                             | Style           | -             |\n| className     | string                                    | class name      | -             |\n| prefix        | string                                    | style prefix    | true          |\n| size          | `number \\|'small' \\|'large' \\|'middle'`   | interval size   | 8px           |\n| direction     | `'horizontal' \\|'vertical'`               | direction       | -             |\n| align         | `'start' \\|'end' \\|'center' \\|'baseline'` | align           | `'start'`     |\n| wrap          | boolean                                   | Whether to wrap | false         |\n"
  },
  {
    "path": "packages/next/docs/components/Space.zh-CN.md",
    "content": "# Space\n\n> 超级便捷的 Flex 布局组件，可以帮助用户快速实现任何元素的并排紧挨布局\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    Space,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={16}>\n      <SchemaField>\n        <SchemaField.Void\n          title=\"姓名\"\n          x-decorator=\"FormItem\"\n          x-decorator-props={{\n            asterisk: true,\n            feedbackLayout: 'none',\n          }}\n          x-component=\"Space\"\n        >\n          <SchemaField.String\n            name=\"firstName\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            required\n          />\n          <SchemaField.String\n            name=\"lastName\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            required\n          />\n        </SchemaField.Void>\n        <SchemaField.Void\n          title=\"文本串联\"\n          x-decorator=\"FormItem\"\n          x-decorator-props={{\n            asterisk: true,\n            feedbackLayout: 'none',\n          }}\n          x-component=\"Space\"\n        >\n          <SchemaField.String\n            name=\"aa\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            x-decorator-props={{\n              addonAfter: '单位',\n            }}\n            required\n          />\n          <SchemaField.String\n            name=\"bb\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            x-decorator-props={{\n              addonAfter: '单位',\n            }}\n            required\n          />\n          <SchemaField.String\n            name=\"cc\"\n            x-decorator=\"FormItem\"\n            x-component=\"Input\"\n            x-decorator-props={{\n              addonAfter: '单位',\n            }}\n            required\n          />\n        </SchemaField.Void>\n        <SchemaField.String\n          name=\"textarea\"\n          title=\"文本框\"\n          x-decorator=\"FormItem\"\n          required\n          x-component=\"Input.TextArea\"\n          x-component-props={{\n            style: {\n              width: 400,\n            },\n          }}\n        />\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n    Space,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    name: {\n      type: 'void',\n      title: '姓名',\n      'x-decorator': 'FormItem',\n      'x-decorator-props': {\n        asterisk: true,\n        feedbackLayout: 'none',\n      },\n      'x-component': 'Space',\n      properties: {\n        firstName: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          required: true,\n        },\n        lastName: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-component': 'Input',\n          required: true,\n        },\n      },\n    },\n    texts: {\n      type: 'void',\n      title: '文本串联',\n      'x-decorator': 'FormItem',\n      'x-decorator-props': {\n        asterisk: true,\n        feedbackLayout: 'none',\n      },\n      'x-component': 'Space',\n      properties: {\n        aa: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            addonAfter: '单位',\n          },\n          'x-component': 'Input',\n          required: true,\n        },\n        bb: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            addonAfter: '单位',\n          },\n          'x-component': 'Input',\n          required: true,\n        },\n        cc: {\n          type: 'string',\n          'x-decorator': 'FormItem',\n          'x-decorator-props': {\n            addonAfter: '单位',\n          },\n          'x-component': 'Input',\n          required: true,\n        },\n      },\n    },\n\n    textarea: {\n      type: 'string',\n      title: '文本框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Input.TextArea',\n      'x-component-props': {\n        style: {\n          width: 400,\n        },\n      },\n      required: true,\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={16}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Input,\n  FormItem,\n  FormLayout,\n  FormButtonGroup,\n  Submit,\n  Space,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, VoidField } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={16}>\n      <VoidField\n        name=\"name\"\n        title=\"姓名\"\n        decorator={[\n          FormItem,\n          {\n            asterisk: true,\n            feedbackLayout: 'none',\n          },\n        ]}\n        component={[Space]}\n      >\n        <Field\n          name=\"firstName\"\n          decorator={[FormItem]}\n          component={[Input]}\n          required\n        />\n        <Field\n          name=\"lastName\"\n          decorator={[FormItem]}\n          component={[Input]}\n          required\n        />\n      </VoidField>\n      <VoidField\n        name=\"texts\"\n        title=\"文本串联\"\n        decorator={[\n          FormItem,\n          {\n            asterisk: true,\n            feedbackLayout: 'none',\n          },\n        ]}\n        component={[Space]}\n      >\n        <Field\n          name=\"aa\"\n          decorator={[\n            FormItem,\n            {\n              addonAfter: '单位',\n            },\n          ]}\n          component={[Input]}\n          required\n        />\n        <Field\n          name=\"bb\"\n          decorator={[\n            FormItem,\n            {\n              addonAfter: '单位',\n            },\n          ]}\n          component={[Input]}\n          required\n        />\n        <Field\n          name=\"cc\"\n          decorator={[\n            FormItem,\n            {\n              addonAfter: '单位',\n            },\n          ]}\n          component={[Input]}\n          required\n        />\n      </VoidField>\n      <Field\n        name=\"textarea\"\n        title=\"文本框\"\n        decorator={[FormItem]}\n        component={[\n          Input.TextArea,\n          {\n            style: {\n              width: 400,\n            },\n          },\n        ]}\n        required\n      />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## API\n\n| 属性名    | 类型                                         | 描述     | 默认值    |\n| --------- | -------------------------------------------- | -------- | --------- |\n| style     | CSSProperties                                | 样式     | -         |\n| className | string                                       | 类名     | -         |\n| prefix    | string                                       | 样式前缀 | true      |\n| size      | `number \\| 'small' \\| 'large' \\| 'middle'`   | 间隔尺寸 | 8px       |\n| direction | `'horizontal' \\| 'vertical'`                 | 方向     | -         |\n| align     | `'start' \\| 'end' \\| 'center' \\| 'baseline'` | 对齐     | `'start'` |\n| wrap      | boolean                                      | 是否换行 | false     |\n"
  },
  {
    "path": "packages/next/docs/components/Submit.md",
    "content": "# Submit\n\n> Submit button\n\n## Ordinary submission\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"input box\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Prevent Duplicate Submission (Loading)\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"input box\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"input box\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit\n        onSubmit={(values) => {\n          return new Promise((resolve) => {\n            setTimeout(() => {\n              console.log(values)\n              resolve()\n            }, 2000)\n          })\n        }}\n        onSubmitFailed={console.log}\n      >\n        submit\n      </Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nFor button-related API properties, we can refer to https://fusion.design/pc/component/basic/button, and the rest are the unique API properties of the Submit component\n\n| Property name   | Type                                                                                             | Description                                               | Default value |\n| --------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------- | ------------- |\n| onClick         | `(event: MouseEvent) => void \\| boolean`                                                         | Click event, if it returns false, it can block submission | -             |\n| onSubmit        | `(values: any) => Promise<any> \\| any`                                                           | Submit event callback                                     | -             |\n| onSubmitSuccess | (payload: any) => void                                                                           | Submit successful response event                          | -             |\n| onSubmitFailed  | (feedbacks: [IFormFeedback](https://core.formilyjs.org/api/models/form#iformfeedback)[]) => void | Submit verification failure event callback                | -             |\n"
  },
  {
    "path": "packages/next/docs/components/Submit.zh-CN.md",
    "content": "# Submit\n\n> 提交按钮\n\n## 普通提交\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"输入框\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 防重复提交(Loading)\n\n```tsx\nimport React from 'react'\nimport { Input, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"input\"\n        title=\"输入框\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n      <SchemaField.String\n        name=\"input2\"\n        title=\"输入框\"\n        default=\"123\"\n        required\n        x-decorator=\"FormItem\"\n        x-component=\"Input\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit\n        onSubmit={(values) => {\n          return new Promise((resolve) => {\n            setTimeout(() => {\n              console.log(values)\n              resolve()\n            }, 2000)\n          })\n        }}\n        onSubmitFailed={console.log}\n      >\n        提交\n      </Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n按钮相关的 API 属性，我们参考 https://fusion.design/pc/component/basic/button 即可，剩下是 Submit 组件独有的 API 属性\n\n| 属性名          | 类型                                                                                                   | 描述                                  | 默认值 |\n| --------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------- | ------ |\n| onClick         | `(event: MouseEvent) => void \\| boolean`                                                               | 点击事件，如果返回 false 可以阻塞提交 | -      |\n| onSubmit        | `(values: any) => Promise<any> \\| any`                                                                 | 提交事件回调                          | -      |\n| onSubmitSuccess | (payload: any) => void                                                                                 | 提交成功响应事件                      | -      |\n| onSubmitFailed  | (feedbacks: [IFormFeedback](https://core.formilyjs.org/zh-CN/api/models/form#iformfeedback)[]) => void | 提交校验失败事件回调                  | -      |\n"
  },
  {
    "path": "packages/next/docs/components/Switch.md",
    "content": "# Switch\n\n> Switch Components\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { Switch, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Switch,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Boolean\n        name=\"switch\"\n        title=\"Switch\"\n        x-decorator=\"FormItem\"\n        x-component=\"Switch\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { Switch, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Switch,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    switch: {\n      type: 'boolean',\n      title: 'Switch',\n      'x-decorator': 'FormItem',\n      'x-component': 'Switch',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { Switch, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"switch\"\n      title=\"Switch\"\n      decorator={[FormItem]}\n      component={[Switch]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://fusion.design/pc/component/basic/switch\n"
  },
  {
    "path": "packages/next/docs/components/Switch.zh-CN.md",
    "content": "# Switch\n\n> 开关组件\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Switch, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Switch,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Boolean\n        name=\"switch\"\n        title=\"开关\"\n        x-decorator=\"FormItem\"\n        x-component=\"Switch\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Switch, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Switch,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    switch: {\n      type: 'boolean',\n      title: '开关',\n      'x-decorator': 'FormItem',\n      'x-component': 'Switch',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { Switch, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"switch\"\n      title=\"开关\"\n      decorator={[FormItem]}\n      component={[Switch]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://fusion.design/pc/component/basic/switch\n"
  },
  {
    "path": "packages/next/docs/components/TimePicker.md",
    "content": "# TimePicker\n\n> Time Picker\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TimePicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"time\"\n        title=\"time\"\n        x-decorator=\"FormItem\"\n        x-component=\"TimePicker\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TimePicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    time: {\n      title: 'Time',\n      'x-decorator': 'FormItem',\n      'x-component': 'TimePicker',\n      type: 'string',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"time\"\n      title=\"time\"\n      decorator={[FormItem]}\n      component={[TimePicker]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://fusion.design/pc/component/basic/time-picker\n"
  },
  {
    "path": "packages/next/docs/components/TimePicker.zh-CN.md",
    "content": "# TimePicker\n\n> 时间选择器\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TimePicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"time\"\n        title=\"时间\"\n        x-decorator=\"FormItem\"\n        x-component=\"TimePicker\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TimePicker,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    time: {\n      title: '时间',\n      'x-decorator': 'FormItem',\n      'x-component': 'TimePicker',\n      type: 'string',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { TimePicker, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"time\"\n      title=\"时间\"\n      decorator={[FormItem]}\n      component={[TimePicker]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://fusion.design/pc/component/basic/time-picker\n"
  },
  {
    "path": "packages/next/docs/components/TimePicker2.md",
    "content": "# TimePicker2\n\n> Time 选择器\n\n## Markup Schema Example\n\n```tsx\nimport React from 'react'\nimport { TimePicker2, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TimePicker2,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"time\"\n        title=\"time\"\n        x-decorator=\"FormItem\"\n        x-component=\"TimePicker2\"\n      />\n      <SchemaField.String\n        name=\"[startTime,endTime]\"\n        title=\"Time Range\"\n        x-decorator=\"FormItem\"\n        x-component=\"TimePicker2.RangePicker\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema Case\n\n```tsx\nimport React from 'react'\nimport { TimePicker2, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TimePicker2,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    time: {\n      title: 'Time',\n      'x-decorator': 'FormItem',\n      'x-component': 'TimePicker2',\n      type: 'string',\n    },\n    '[startTime,endTime]': {\n      title: 'Time Range',\n      'x-decorator': 'FormItem',\n      'x-component': 'TimePicker2.RangePicker',\n      type: 'string',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { TimePicker2, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"time\"\n      title=\"Time\"\n      decorator={[FormItem]}\n      component={[TimePicker2]}\n    />\n    <Field\n      name=\"[startTime,endTime]\"\n      title=\"Time Range\"\n      decorator={[FormItem]}\n      component={[TimePicker2.RangePicker]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://fusion.design/pc/component/basic/time-picker2\n"
  },
  {
    "path": "packages/next/docs/components/TimePicker2.zh-CN.md",
    "content": "# TimePicker2\n\n> 时间选择器\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { TimePicker2, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TimePicker2,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        name=\"time\"\n        title=\"时间\"\n        x-decorator=\"FormItem\"\n        x-component=\"TimePicker2\"\n      />\n      <SchemaField.String\n        name=\"[startTime,endTime]\"\n        title=\"时间范围\"\n        x-decorator=\"FormItem\"\n        x-component=\"TimePicker2.RangePicker\"\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { TimePicker2, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TimePicker2,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    time: {\n      title: '时间',\n      'x-decorator': 'FormItem',\n      'x-component': 'TimePicker2',\n      type: 'string',\n    },\n    '[startTime,endTime]': {\n      title: '时间范围',\n      'x-decorator': 'FormItem',\n      'x-component': 'TimePicker2.RangePicker',\n      type: 'string',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { TimePicker2, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"time\"\n      title=\"时间\"\n      decorator={[FormItem]}\n      component={[TimePicker2]}\n    />\n    <Field\n      name=\"[startTime,endTime]\"\n      title=\"时间范围\"\n      decorator={[FormItem]}\n      component={[TimePicker2.RangePicker]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://fusion.design/pc/component/basic/time-picker2\n"
  },
  {
    "path": "packages/next/docs/components/Transfer.md",
    "content": "# Transfer\n\n> Shuttle Box\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Transfer,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Array\n        name=\"transfer\"\n        title=\"shuttle box\"\n        x-decorator=\"FormItem\"\n        x-component=\"Transfer\"\n        enum={[\n          { label: 'Option 1', value: 'aaa' },\n          { label: 'Option 2', value: 'bbb' },\n        ]}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Transfer,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    transfer: {\n      type: 'array',\n      title: 'shuttle box',\n      'x-decorator': 'FormItem',\n      'x-component': 'Transfer',\n      enum: [\n        { label: 'Option 1', value: 'aaa' },\n        { label: 'Option 2', value: 'bbb' },\n      ],\n    },\n  },\n}\n\nconst renderTitle = (item) => item.title\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} scope={{ renderTitle }} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"transfer\"\n      title=\"shuttle box\"\n      dataSource={[\n        { label: 'Option 1', value: 'aaa' },\n        { label: 'Option 2', value: 'bbb' },\n      ]}\n      decorator={[FormItem]}\n      component={[Transfer]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://fusion.design/pc/component/basic/transfer\n"
  },
  {
    "path": "packages/next/docs/components/Transfer.zh-CN.md",
    "content": "# Transfer\n\n> 穿梭框\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Transfer,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Array\n        name=\"transfer\"\n        title=\"穿梭框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Transfer\"\n        enum={[\n          { label: '选项1', value: 'aaa' },\n          { label: '选项2', value: 'bbb' },\n        ]}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Transfer,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    transfer: {\n      type: 'array',\n      title: '穿梭框',\n      'x-decorator': 'FormItem',\n      'x-component': 'Transfer',\n      enum: [\n        { label: '选项1', value: 'aaa' },\n        { label: '选项2', value: 'bbb' },\n      ],\n    },\n  },\n}\n\nconst renderTitle = (item) => item.title\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} scope={{ renderTitle }} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport { Transfer, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"transfer\"\n      title=\"穿梭框\"\n      dataSource={[\n        { label: '选项1', value: 'aaa' },\n        { label: '选项2', value: 'bbb' },\n      ]}\n      decorator={[FormItem]}\n      component={[Transfer]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://fusion.design/pc/component/basic/transfer\n"
  },
  {
    "path": "packages/next/docs/components/TreeSelect.md",
    "content": "# TreeSelect\n\n> Tree selector\n\n## Markup Schema synchronization data source case\n\n```tsx\nimport React from 'react'\nimport { TreeSelect, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TreeSelect,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"select\"\n        label=\"select box\"\n        x-decorator=\"FormItem\"\n        x-component=\"TreeSelect\"\n        enum={[\n          {\n            label: 'Option 1',\n            value: 1,\n            children: [\n              {\n                label: 'Child Node1',\n                value: '0-0-0',\n                key: '0-0-0',\n              },\n              {\n                label: 'Child Node2',\n                value: '0-0-1',\n                key: '0-0-1',\n              },\n              {\n                label: 'Child Node3',\n                value: '0-0-2',\n                key: '0-0-2',\n              },\n            ],\n          },\n          {\n            label: 'Option 2',\n            value: 2,\n            children: [\n              {\n                label: 'Child Node3',\n                value: '0-1-0',\n                key: '0-1-0',\n              },\n              {\n                label: 'Child Node4',\n                value: '0-1-1',\n                key: '0-1-1',\n              },\n              {\n                label: 'Child Node5',\n                value: '0-1-2',\n                key: '0-1-2',\n              },\n            ],\n          },\n        ]}\n        x-component-props={{\n          style: {\n            width: 200,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Markup Schema Asynchronous Linkage Data Source Case\n\n```tsx\nimport React from 'react'\nimport {\n  TreeSelect,\n  Select,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm, onFieldReact, FormPathPattern, Field } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    TreeSelect,\n    FormItem,\n  },\n})\n\nconst useAsyncDataSource = (\n  pattern: FormPathPattern,\n  service: (field: Field) => Promise<{ label: string; value: any }[]>\n) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service(field).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async (field) => {\n      const linkage = field.query('linkage').get('value')\n      if (!linkage) return []\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          if (linkage === 1) {\n            resolve([\n              {\n                label: 'AAA',\n                value: 'aaa',\n                children: [\n                  {\n                    label: 'Child Node1',\n                    value: '0-0-0',\n                    key: '0-0-0',\n                  },\n                  {\n                    label: 'Child Node2',\n                    value: '0-0-1',\n                    key: '0-0-1',\n                  },\n                  {\n                    label: 'Child Node3',\n                    value: '0-0-2',\n                    key: '0-0-2',\n                  },\n                ],\n              },\n              {\n                label: 'BBB',\n                value: 'ccc',\n                children: [\n                  {\n                    label: 'Child Node1',\n                    value: '0-1-0',\n                    key: '0-1-0',\n                  },\n                  {\n                    label: 'Child Node2',\n                    value: '0-1-1',\n                    key: '0-1-1',\n                  },\n                  {\n                    label: 'Child Node3',\n                    value: '0-1-2',\n                    key: '0-1-2',\n                  },\n                ],\n              },\n            ])\n          } else if (linkage === 2) {\n            resolve([\n              {\n                label: 'CCC',\n                value: 'ccc',\n                children: [\n                  {\n                    label: 'Child Node1',\n                    value: '0-0-0',\n                    key: '0-0-0',\n                  },\n                  {\n                    label: 'Child Node2',\n                    value: '0-0-1',\n                    key: '0-0-1',\n                  },\n                  {\n                    label: 'Child Node3',\n                    value: '0-0-2',\n                    key: '0-0-2',\n                  },\n                ],\n              },\n              {\n                label: 'DDD',\n                value: 'ddd',\n                children: [\n                  {\n                    label: 'Child Node1',\n                    value: '0-1-0',\n                    key: '0-1-0',\n                  },\n                  {\n                    label: 'Child Node2',\n                    value: '0-1-1',\n                    key: '0-1-1',\n                  },\n                  {\n                    label: 'Child Node3',\n                    value: '0-1-2',\n                    key: '0-1-2',\n                  },\n                ],\n              },\n            ])\n          }\n        }, 1500)\n      })\n    })\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"linkage\"\n        label=\"Linkage selection box\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        enum={[\n          { label: 'Request 1', value: 1 },\n          { label: 'Request 2', value: 2 },\n        ]}\n        x-component-props={{\n          style: {\n            width: 200,\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"select\"\n        label=\"Asynchronous selection box\"\n        x-decorator=\"FormItem\"\n        x-component=\"TreeSelect\"\n        x-component-props={{\n          style: {\n            width: 200,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema synchronization data source case\n\n```tsx\nimport React from 'react'\nimport { TreeSelect, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TreeSelect,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    select: {\n      type: 'string',\n      label: 'Select box',\n      'x-decorator': 'FormItem',\n      'x-component': 'TreeSelect',\n      enum: [\n        {\n          label: 'Option 1',\n          value: 1,\n          children: [\n            {\n              label: 'Child Node1',\n              value: '0-0-0',\n              key: '0-0-0',\n            },\n            {\n              label: 'Child Node2',\n              value: '0-0-1',\n              key: '0-0-1',\n            },\n            {\n              label: 'Child Node3',\n              value: '0-0-2',\n              key: '0-0-2',\n            },\n          ],\n        },\n        {\n          label: 'Option 2',\n          value: 2,\n          children: [\n            {\n              label: 'Child Node1',\n              value: '0-1-0',\n              key: '0-1-0',\n            },\n            {\n              label: 'Child Node2',\n              value: '0-1-1',\n              key: '0-1-1',\n            },\n            {\n              label: 'Child Node3',\n              value: '0-1-2',\n              key: '0-1-2',\n            },\n          ],\n        },\n      ],\n      'x-component-props': {\n        style: {\n          width: 200,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema asynchronous linkage data source case\n\n```tsx\nimport React from 'react'\nimport {\n  TreeSelect,\n  Select,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    TreeSelect,\n    FormItem,\n  },\n})\n\nconst loadData = async (field) => {\n  const linkage = field.query('linkage').get('value')\n  if (!linkage) return []\n  return new Promise((resolve) => {\n    setTimeout(() => {\n      if (linkage === 1) {\n        resolve([\n          {\n            label: 'AAA',\n            value: 'aaa',\n            children: [\n              {\n                label: 'Child Node1',\n                value: '0-0-0',\n                key: '0-0-0',\n              },\n              {\n                label: 'Child Node2',\n                value: '0-0-1',\n                key: '0-0-1',\n              },\n              {\n                label: 'Child Node3',\n                value: '0-0-2',\n                key: '0-0-2',\n              },\n            ],\n          },\n          {\n            label: 'BBB',\n            value: 'ccc',\n            children: [\n              {\n                label: 'Child Node1',\n                value: '0-1-0',\n                key: '0-1-0',\n              },\n              {\n                label: 'Child Node2',\n                value: '0-1-1',\n                key: '0-1-1',\n              },\n              {\n                label: 'Child Node3',\n                value: '0-1-2',\n                key: '0-1-2',\n              },\n            ],\n          },\n        ])\n      } else if (linkage === 2) {\n        resolve([\n          {\n            label: 'CCC',\n            value: 'ccc',\n            children: [\n              {\n                label: 'Child Node1',\n                value: '0-0-0',\n                key: '0-0-0',\n              },\n              {\n                label: 'Child Node2',\n                value: '0-0-1',\n                key: '0-0-1',\n              },\n              {\n                label: 'Child Node3',\n                value: '0-0-2',\n                key: '0-0-2',\n              },\n            ],\n          },\n          {\n            label: 'DDD',\n            value: 'ddd',\n            children: [\n              {\n                label: 'Child Node1',\n                value: '0-1-0',\n                key: '0-1-0',\n              },\n              {\n                label: 'Child Node2',\n                value: '0-1-1',\n                key: '0-1-1',\n              },\n              {\n                label: 'Child Node3',\n                value: '0-1-2',\n                key: '0-1-2',\n              },\n            ],\n          },\n        ])\n      }\n    }, 1500)\n  })\n}\n\nconst useAsyncDataSource = (service) => (field) => {\n  field.loading = true\n  service(field).then(\n    action.bound((data) => {\n      field.dataSource = data\n      field.loading = false\n    })\n  )\n}\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    linkage: {\n      type: 'string',\n      label: 'Linkage selection box',\n      enum: [\n        { label: 'Request 1', value: 1 },\n        { label: 'Request 2', value: 2 },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      'x-component-props': {\n        style: {\n          width: 200,\n        },\n      },\n    },\n    select: {\n      type: 'string',\n      label: 'Asynchronous selection box',\n      'x-decorator': 'FormItem',\n      'x-component': 'TreeSelect',\n      'x-component-props': {\n        style: {\n          width: 200,\n        },\n      },\n      'x-reactions': ['{{useAsyncDataSource(loadData)}}'],\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} scope={{ useAsyncDataSource, loadData }} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX synchronization data source case\n\n```tsx\nimport React from 'react'\nimport { TreeSelect, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"select\"\n      label=\"select box\"\n      dataSource={[\n        {\n          label: 'Option 1',\n          value: 1,\n          children: [\n            {\n              label: 'Child Node1',\n              value: '0-0-0',\n              key: '0-0-0',\n            },\n            {\n              label: 'Child Node2',\n              value: '0-0-1',\n              key: '0-0-1',\n            },\n            {\n              label: 'Child Node3',\n              value: '0-0-2',\n              key: '0-0-2',\n            },\n          ],\n        },\n        {\n          label: 'Option 2',\n          value: 2,\n          children: [\n            {\n              label: 'Child Node3',\n              value: '0-1-0',\n              key: '0-1-0',\n            },\n            {\n              label: 'Child Node4',\n              value: '0-1-1',\n              key: '0-1-1',\n            },\n            {\n              label: 'Child Node5',\n              value: '0-1-2',\n              key: '0-1-2',\n            },\n          ],\n        },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        TreeSelect,\n        {\n          style: {\n            width: 200,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Pure JSX asynchronous linkage data source case\n\n```tsx\nimport React from 'react'\nimport {\n  TreeSelect,\n  Select,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport {\n  createForm,\n  onFieldReact,\n  FormPathPattern,\n  FieldType,\n} from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst useAsyncDataSource = (\n  pattern: FormPathPattern,\n  service: (field: FieldType) => Promise<{ label: string; value: any }[]>\n) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service(field).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async (field) => {\n      const linkage = field.query('linkage').get('value')\n      if (!linkage) return []\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          if (linkage === 1) {\n            resolve([\n              {\n                label: 'AAA',\n                value: 'aaa',\n                children: [\n                  {\n                    label: 'Child Node1',\n                    value: '0-0-0',\n                    key: '0-0-0',\n                  },\n                  {\n                    label: 'Child Node2',\n                    value: '0-0-1',\n                    key: '0-0-1',\n                  },\n                  {\n                    label: 'Child Node3',\n                    value: '0-0-2',\n                    key: '0-0-2',\n                  },\n                ],\n              },\n              {\n                label: 'BBB',\n                value: 'ccc',\n                children: [\n                  {\n                    label: 'Child Node1',\n                    value: '0-1-0',\n                    key: '0-1-0',\n                  },\n                  {\n                    label: 'Child Node2',\n                    value: '0-1-1',\n                    key: '0-1-1',\n                  },\n                  {\n                    label: 'Child Node3',\n                    value: '0-1-2',\n                    key: '0-1-2',\n                  },\n                ],\n              },\n            ])\n          } else if (linkage === 2) {\n            resolve([\n              {\n                label: 'CCC',\n                value: 'ccc',\n                children: [\n                  {\n                    label: 'Child Node1',\n                    value: '0-0-0',\n                    key: '0-0-0',\n                  },\n                  {\n                    label: 'Child Node2',\n                    value: '0-0-1',\n                    key: '0-0-1',\n                  },\n                  {\n                    label: 'Child Node3',\n                    value: '0-0-2',\n                    key: '0-0-2',\n                  },\n                ],\n              },\n              {\n                label: 'DDD',\n                value: 'ddd',\n                children: [\n                  {\n                    label: 'Child Node1',\n                    value: '0-1-0',\n                    key: '0-1-0',\n                  },\n                  {\n                    label: 'Child Node2',\n                    value: '0-1-1',\n                    key: '0-1-1',\n                  },\n                  {\n                    label: 'Child Node3',\n                    value: '0-1-2',\n                    key: '0-1-2',\n                  },\n                ],\n              },\n            ])\n          }\n        }, 1500)\n      })\n    })\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"linkage\"\n      label=\"Linkage selection box\"\n      dataSource={[\n        { label: 'Request 1', value: 1 },\n        { label: 'Request 2', value: 2 },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        Select,\n        {\n          style: {\n            width: 200,\n          },\n        },\n      ]}\n    />\n    <Field\n      name=\"select\"\n      label=\"Asynchronous selection box\"\n      decorator={[FormItem]}\n      component={[\n        TreeSelect,\n        {\n          style: {\n            width: 200,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>Submit</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://fusion.design/pc/component/basic/tree-select\n"
  },
  {
    "path": "packages/next/docs/components/TreeSelect.zh-CN.md",
    "content": "# TreeSelect\n\n> 树选择器\n\n## Markup Schema 同步数据源案例\n\n```tsx\nimport React from 'react'\nimport { TreeSelect, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TreeSelect,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"select\"\n        label=\"选择框\"\n        x-decorator=\"FormItem\"\n        x-component=\"TreeSelect\"\n        enum={[\n          {\n            label: '选项1',\n            value: 1,\n            children: [\n              {\n                label: 'Child Node1',\n                value: '0-0-0',\n                key: '0-0-0',\n              },\n              {\n                label: 'Child Node2',\n                value: '0-0-1',\n                key: '0-0-1',\n              },\n              {\n                label: 'Child Node3',\n                value: '0-0-2',\n                key: '0-0-2',\n              },\n            ],\n          },\n          {\n            label: '选项2',\n            value: 2,\n            children: [\n              {\n                label: 'Child Node3',\n                value: '0-1-0',\n                key: '0-1-0',\n              },\n              {\n                label: 'Child Node4',\n                value: '0-1-1',\n                key: '0-1-1',\n              },\n              {\n                label: 'Child Node5',\n                value: '0-1-2',\n                key: '0-1-2',\n              },\n            ],\n          },\n        ]}\n        x-component-props={{\n          style: {\n            width: 200,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## Markup Schema 异步联动数据源案例\n\n```tsx\nimport React from 'react'\nimport {\n  TreeSelect,\n  Select,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm, onFieldReact, FormPathPattern, Field } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    TreeSelect,\n    FormItem,\n  },\n})\n\nconst useAsyncDataSource = (\n  pattern: FormPathPattern,\n  service: (field: Field) => Promise<{ label: string; value: any }[]>\n) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service(field).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async (field) => {\n      const linkage = field.query('linkage').get('value')\n      if (!linkage) return []\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          if (linkage === 1) {\n            resolve([\n              {\n                label: 'AAA',\n                value: 'aaa',\n                children: [\n                  {\n                    label: 'Child Node1',\n                    value: '0-0-0',\n                    key: '0-0-0',\n                  },\n                  {\n                    label: 'Child Node2',\n                    value: '0-0-1',\n                    key: '0-0-1',\n                  },\n                  {\n                    label: 'Child Node3',\n                    value: '0-0-2',\n                    key: '0-0-2',\n                  },\n                ],\n              },\n              {\n                label: 'BBB',\n                value: 'ccc',\n                children: [\n                  {\n                    label: 'Child Node1',\n                    value: '0-1-0',\n                    key: '0-1-0',\n                  },\n                  {\n                    label: 'Child Node2',\n                    value: '0-1-1',\n                    key: '0-1-1',\n                  },\n                  {\n                    label: 'Child Node3',\n                    value: '0-1-2',\n                    key: '0-1-2',\n                  },\n                ],\n              },\n            ])\n          } else if (linkage === 2) {\n            resolve([\n              {\n                label: 'CCC',\n                value: 'ccc',\n                children: [\n                  {\n                    label: 'Child Node1',\n                    value: '0-0-0',\n                    key: '0-0-0',\n                  },\n                  {\n                    label: 'Child Node2',\n                    value: '0-0-1',\n                    key: '0-0-1',\n                  },\n                  {\n                    label: 'Child Node3',\n                    value: '0-0-2',\n                    key: '0-0-2',\n                  },\n                ],\n              },\n              {\n                label: 'DDD',\n                value: 'ddd',\n                children: [\n                  {\n                    label: 'Child Node1',\n                    value: '0-1-0',\n                    key: '0-1-0',\n                  },\n                  {\n                    label: 'Child Node2',\n                    value: '0-1-1',\n                    key: '0-1-1',\n                  },\n                  {\n                    label: 'Child Node3',\n                    value: '0-1-2',\n                    key: '0-1-2',\n                  },\n                ],\n              },\n            ])\n          }\n        }, 1500)\n      })\n    })\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Number\n        name=\"linkage\"\n        label=\"联动选择框\"\n        x-decorator=\"FormItem\"\n        x-component=\"Select\"\n        enum={[\n          { label: '发请求1', value: 1 },\n          { label: '发请求2', value: 2 },\n        ]}\n        x-component-props={{\n          style: {\n            width: 200,\n          },\n        }}\n      />\n      <SchemaField.String\n        name=\"select\"\n        label=\"异步选择框\"\n        x-decorator=\"FormItem\"\n        x-component=\"TreeSelect\"\n        x-component-props={{\n          style: {\n            width: 200,\n          },\n        }}\n      />\n    </SchemaField>\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 同步数据源案例\n\n```tsx\nimport React from 'react'\nimport { TreeSelect, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\n\nconst SchemaField = createSchemaField({\n  components: {\n    TreeSelect,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    select: {\n      type: 'string',\n      label: '选择框',\n      'x-decorator': 'FormItem',\n      'x-component': 'TreeSelect',\n      enum: [\n        {\n          label: '选项1',\n          value: 1,\n          children: [\n            {\n              label: 'Child Node1',\n              value: '0-0-0',\n              key: '0-0-0',\n            },\n            {\n              label: 'Child Node2',\n              value: '0-0-1',\n              key: '0-0-1',\n            },\n            {\n              label: 'Child Node3',\n              value: '0-0-2',\n              key: '0-0-2',\n            },\n          ],\n        },\n        {\n          label: '选项2',\n          value: 2,\n          children: [\n            {\n              label: 'Child Node1',\n              value: '0-1-0',\n              key: '0-1-0',\n            },\n            {\n              label: 'Child Node2',\n              value: '0-1-1',\n              key: '0-1-1',\n            },\n            {\n              label: 'Child Node3',\n              value: '0-1-2',\n              key: '0-1-2',\n            },\n          ],\n        },\n      ],\n      'x-component-props': {\n        style: {\n          width: 200,\n        },\n      },\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## JSON Schema 异步联动数据源案例\n\n```tsx\nimport React from 'react'\nimport {\n  TreeSelect,\n  Select,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst SchemaField = createSchemaField({\n  components: {\n    Select,\n    TreeSelect,\n    FormItem,\n  },\n})\n\nconst loadData = async (field) => {\n  const linkage = field.query('linkage').get('value')\n  if (!linkage) return []\n  return new Promise((resolve) => {\n    setTimeout(() => {\n      if (linkage === 1) {\n        resolve([\n          {\n            label: 'AAA',\n            value: 'aaa',\n            children: [\n              {\n                label: 'Child Node1',\n                value: '0-0-0',\n                key: '0-0-0',\n              },\n              {\n                label: 'Child Node2',\n                value: '0-0-1',\n                key: '0-0-1',\n              },\n              {\n                label: 'Child Node3',\n                value: '0-0-2',\n                key: '0-0-2',\n              },\n            ],\n          },\n          {\n            label: 'BBB',\n            value: 'ccc',\n            children: [\n              {\n                label: 'Child Node1',\n                value: '0-1-0',\n                key: '0-1-0',\n              },\n              {\n                label: 'Child Node2',\n                value: '0-1-1',\n                key: '0-1-1',\n              },\n              {\n                label: 'Child Node3',\n                value: '0-1-2',\n                key: '0-1-2',\n              },\n            ],\n          },\n        ])\n      } else if (linkage === 2) {\n        resolve([\n          {\n            label: 'CCC',\n            value: 'ccc',\n            children: [\n              {\n                label: 'Child Node1',\n                value: '0-0-0',\n                key: '0-0-0',\n              },\n              {\n                label: 'Child Node2',\n                value: '0-0-1',\n                key: '0-0-1',\n              },\n              {\n                label: 'Child Node3',\n                value: '0-0-2',\n                key: '0-0-2',\n              },\n            ],\n          },\n          {\n            label: 'DDD',\n            value: 'ddd',\n            children: [\n              {\n                label: 'Child Node1',\n                value: '0-1-0',\n                key: '0-1-0',\n              },\n              {\n                label: 'Child Node2',\n                value: '0-1-1',\n                key: '0-1-1',\n              },\n              {\n                label: 'Child Node3',\n                value: '0-1-2',\n                key: '0-1-2',\n              },\n            ],\n          },\n        ])\n      }\n    }, 1500)\n  })\n}\n\nconst useAsyncDataSource = (service) => (field) => {\n  field.loading = true\n  service(field).then(\n    action.bound((data) => {\n      field.dataSource = data\n      field.loading = false\n    })\n  )\n}\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    linkage: {\n      type: 'string',\n      label: '联动选择框',\n      enum: [\n        { label: '发请求1', value: 1 },\n        { label: '发请求2', value: 2 },\n      ],\n      'x-decorator': 'FormItem',\n      'x-component': 'Select',\n      'x-component-props': {\n        style: {\n          width: 200,\n        },\n      },\n    },\n    select: {\n      type: 'string',\n      label: '异步选择框',\n      'x-decorator': 'FormItem',\n      'x-component': 'TreeSelect',\n      'x-component-props': {\n        style: {\n          width: 200,\n        },\n      },\n      'x-reactions': ['{{useAsyncDataSource(loadData)}}'],\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField schema={schema} scope={{ useAsyncDataSource, loadData }} />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 同步数据源案例\n\n```tsx\nimport React from 'react'\nimport { TreeSelect, FormItem, FormButtonGroup, Submit } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"select\"\n      label=\"选择框\"\n      dataSource={[\n        {\n          label: '选项1',\n          value: 1,\n          children: [\n            {\n              label: 'Child Node1',\n              value: '0-0-0',\n              key: '0-0-0',\n            },\n            {\n              label: 'Child Node2',\n              value: '0-0-1',\n              key: '0-0-1',\n            },\n            {\n              label: 'Child Node3',\n              value: '0-0-2',\n              key: '0-0-2',\n            },\n          ],\n        },\n        {\n          label: '选项2',\n          value: 2,\n          children: [\n            {\n              label: 'Child Node3',\n              value: '0-1-0',\n              key: '0-1-0',\n            },\n            {\n              label: 'Child Node4',\n              value: '0-1-1',\n              key: '0-1-1',\n            },\n            {\n              label: 'Child Node5',\n              value: '0-1-2',\n              key: '0-1-2',\n            },\n          ],\n        },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        TreeSelect,\n        {\n          style: {\n            width: 200,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 异步联动数据源案例\n\n```tsx\nimport React from 'react'\nimport {\n  TreeSelect,\n  Select,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n} from '@formily/next'\nimport {\n  createForm,\n  onFieldReact,\n  FormPathPattern,\n  FieldType,\n} from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { action } from '@formily/reactive'\n\nconst useAsyncDataSource = (\n  pattern: FormPathPattern,\n  service: (field: FieldType) => Promise<{ label: string; value: any }[]>\n) => {\n  onFieldReact(pattern, (field) => {\n    field.loading = true\n    service(field).then(\n      action.bound((data) => {\n        field.dataSource = data\n        field.loading = false\n      })\n    )\n  })\n}\n\nconst form = createForm({\n  effects: () => {\n    useAsyncDataSource('select', async (field) => {\n      const linkage = field.query('linkage').get('value')\n      if (!linkage) return []\n      return new Promise((resolve) => {\n        setTimeout(() => {\n          if (linkage === 1) {\n            resolve([\n              {\n                label: 'AAA',\n                value: 'aaa',\n                children: [\n                  {\n                    label: 'Child Node1',\n                    value: '0-0-0',\n                    key: '0-0-0',\n                  },\n                  {\n                    label: 'Child Node2',\n                    value: '0-0-1',\n                    key: '0-0-1',\n                  },\n                  {\n                    label: 'Child Node3',\n                    value: '0-0-2',\n                    key: '0-0-2',\n                  },\n                ],\n              },\n              {\n                label: 'BBB',\n                value: 'ccc',\n                children: [\n                  {\n                    label: 'Child Node1',\n                    value: '0-1-0',\n                    key: '0-1-0',\n                  },\n                  {\n                    label: 'Child Node2',\n                    value: '0-1-1',\n                    key: '0-1-1',\n                  },\n                  {\n                    label: 'Child Node3',\n                    value: '0-1-2',\n                    key: '0-1-2',\n                  },\n                ],\n              },\n            ])\n          } else if (linkage === 2) {\n            resolve([\n              {\n                label: 'CCC',\n                value: 'ccc',\n                children: [\n                  {\n                    label: 'Child Node1',\n                    value: '0-0-0',\n                    key: '0-0-0',\n                  },\n                  {\n                    label: 'Child Node2',\n                    value: '0-0-1',\n                    key: '0-0-1',\n                  },\n                  {\n                    label: 'Child Node3',\n                    value: '0-0-2',\n                    key: '0-0-2',\n                  },\n                ],\n              },\n              {\n                label: 'DDD',\n                value: 'ddd',\n                children: [\n                  {\n                    label: 'Child Node1',\n                    value: '0-1-0',\n                    key: '0-1-0',\n                  },\n                  {\n                    label: 'Child Node2',\n                    value: '0-1-1',\n                    key: '0-1-1',\n                  },\n                  {\n                    label: 'Child Node3',\n                    value: '0-1-2',\n                    key: '0-1-2',\n                  },\n                ],\n              },\n            ])\n          }\n        }, 1500)\n      })\n    })\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field\n      name=\"linkage\"\n      label=\"联动选择框\"\n      dataSource={[\n        { label: '发请求1', value: 1 },\n        { label: '发请求2', value: 2 },\n      ]}\n      decorator={[FormItem]}\n      component={[\n        Select,\n        {\n          style: {\n            width: 200,\n          },\n        },\n      ]}\n    />\n    <Field\n      name=\"select\"\n      label=\"异步选择框\"\n      decorator={[FormItem]}\n      component={[\n        TreeSelect,\n        {\n          style: {\n            width: 200,\n          },\n        },\n      ]}\n    />\n    <FormButtonGroup>\n      <Submit onSubmit={console.log}>提交</Submit>\n    </FormButtonGroup>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://fusion.design/pc/component/basic/tree-select\n"
  },
  {
    "path": "packages/next/docs/components/Upload.md",
    "content": "# Upload\n\n> Upload components\n>\n> Note: Using the upload component, it is recommended that users perform secondary packaging. Users do not need to care about the data communication between the upload component and Formily, only the style and basic upload configuration are required.\n\n## Markup Schema example\n\n```tsx\nimport React from 'react'\nimport {\n  Upload,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\nimport { UploadOutlined, InboxOutlined } from '@ant-design/icons'\n\nconst NormalUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      withCredentials={false}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button>\n        <UploadOutlined />\n        upload files\n      </Button>\n    </Upload>\n  )\n}\n\nconst CardUpload = (props) => {\n  return (\n    <Upload.Card\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      withCredentials={false}\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    />\n  )\n}\n\nconst DraggerUpload = (props) => {\n  return (\n    <Upload.Dragger\n      {...props}\n      withCredentials={false}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n    >\n      <div className=\"next-upload-drag\">\n        <p className=\"next-upload-drag-icon\" style={{ fontSize: 50 }}>\n          <InboxOutlined />\n        </p>\n        <p className=\"next-upload-drag-text\">\n          click to <Button text>download template</Button> or drag file here\n        </p>\n        <p className=\"next-upload-drag-hint\">supports docx, xls, PDF </p>\n      </div>\n    </Upload.Dragger>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    NormalUpload,\n    CardUpload,\n    DraggerUpload,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={14}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"upload\"\n          title=\"Upload\"\n          x-decorator=\"FormItem\"\n          x-component=\"NormalUpload\"\n          required\n        />\n        <SchemaField.Array\n          name=\"upload2\"\n          title=\"Card upload\"\n          x-decorator=\"FormItem\"\n          x-component=\"CardUpload\"\n          required\n        />\n        <SchemaField.Array\n          name=\"upload3\"\n          title=\"Drag and drop upload\"\n          x-decorator=\"FormItem\"\n          x-component=\"DraggerUpload\"\n          required\n        />\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## JSON Schema case\n\n```tsx\nimport React from 'react'\nimport {\n  Upload,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\nimport { UploadOutlined, InboxOutlined } from '@ant-design/icons'\n\nconst NormalUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      withCredentials={false}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button>\n        <UploadOutlined />\n        upload files\n      </Button>\n    </Upload>\n  )\n}\n\nconst CardUpload = (props) => {\n  return (\n    <Upload.Card\n      {...props}\n      withCredentials={false}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    />\n  )\n}\n\nconst DraggerUpload = (props) => {\n  return (\n    <Upload.Dragger\n      {...props}\n      withCredentials={false}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n    >\n      <div className=\"next-upload-drag\">\n        <p className=\"next-upload-drag-icon\" style={{ fontSize: 50 }}>\n          <InboxOutlined />\n        </p>\n        <p className=\"next-upload-drag-text\">\n          click to <Button text>download template</Button> or drag file here\n        </p>\n        <p className=\"next-upload-drag-hint\">supports docx, xls, PDF </p>\n      </div>\n    </Upload.Dragger>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    NormalUpload,\n    CardUpload,\n    DraggerUpload,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    upload: {\n      type: 'array',\n      title: 'Upload',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'NormalUpload',\n    },\n    upload2: {\n      type: 'array',\n      title: 'Card upload',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'CardUpload',\n    },\n    upload3: {\n      type: 'array',\n      title: 'Drag and drop upload',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'DraggerUpload',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={14}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## Pure JSX case\n\n```tsx\nimport React from 'react'\nimport {\n  Upload,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { Button } from '@alifd/next'\nimport { UploadOutlined, InboxOutlined } from '@ant-design/icons'\n\nconst NormalUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      withCredentials={false}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button>\n        <UploadOutlined />\n        upload files\n      </Button>\n    </Upload>\n  )\n}\n\nconst CardUpload = (props) => {\n  return (\n    <Upload.Card\n      {...props}\n      withCredentials={false}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    />\n  )\n}\n\nconst DraggerUpload = (props) => {\n  return (\n    <Upload.Dragger\n      {...props}\n      withCredentials={false}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n    >\n      <div className=\"next-upload-drag\">\n        <p className=\"next-upload-drag-icon\" style={{ fontSize: 50 }}>\n          <InboxOutlined />\n        </p>\n        <p className=\"next-upload-drag-text\">\n          click to <Button text>download template</Button> or drag file here\n        </p>\n        <p className=\"next-upload-drag-hint\">supports docx, xls, PDF </p>\n      </div>\n    </Upload.Dragger>\n  )\n}\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={14}>\n      <Field\n        name=\"upload\"\n        title=\"Upload\"\n        required\n        decorator={[FormItem]}\n        component={[NormalUpload]}\n      />\n      <Field\n        name=\"upload2\"\n        title=\"Card upload\"\n        required\n        decorator={[FormItem]}\n        component={[CardUpload]}\n      />\n      <Field\n        name=\"upload3\"\n        title=\"Drag and drop upload\"\n        required\n        decorator={[FormItem]}\n        component={[DraggerUpload]}\n      />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>Submit</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## API\n\nReference https://fusion.design/pc/component/basic/upload\n"
  },
  {
    "path": "packages/next/docs/components/Upload.zh-CN.md",
    "content": "# Upload\n\n> 上传组件\n>\n> 注意：使用上传组件，推荐用户进行二次封装，用户无需关心上传组件与 Formily 的数据通信，只需要处理样式与基本上传配置即可。\n\n## Markup Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Upload,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\nimport { UploadOutlined, InboxOutlined } from '@ant-design/icons'\n\nconst NormalUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      withCredentials={false}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button>\n        <UploadOutlined />\n        上传文件\n      </Button>\n    </Upload>\n  )\n}\n\nconst CardUpload = (props) => {\n  return (\n    <Upload.Card\n      {...props}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      withCredentials={false}\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    />\n  )\n}\n\nconst DraggerUpload = (props) => {\n  return (\n    <Upload.Dragger\n      {...props}\n      withCredentials={false}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n    >\n      <div className=\"next-upload-drag\">\n        <p className=\"next-upload-drag-icon\" style={{ fontSize: 50 }}>\n          <InboxOutlined />\n        </p>\n        <p className=\"next-upload-drag-text\">\n          click to <Button text>download template</Button> or drag file here\n        </p>\n        <p className=\"next-upload-drag-hint\">supports docx, xls, PDF </p>\n      </div>\n    </Upload.Dragger>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    NormalUpload,\n    CardUpload,\n    DraggerUpload,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={14}>\n      <SchemaField>\n        <SchemaField.Array\n          name=\"upload\"\n          title=\"上传\"\n          x-decorator=\"FormItem\"\n          x-component=\"NormalUpload\"\n          required\n        />\n        <SchemaField.Array\n          name=\"upload2\"\n          title=\"卡片上传\"\n          x-decorator=\"FormItem\"\n          x-component=\"CardUpload\"\n          required\n        />\n        <SchemaField.Array\n          name=\"upload3\"\n          title=\"拖拽上传\"\n          x-decorator=\"FormItem\"\n          x-component=\"DraggerUpload\"\n          required\n        />\n      </SchemaField>\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## JSON Schema 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Upload,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Button } from '@alifd/next'\nimport { UploadOutlined, InboxOutlined } from '@ant-design/icons'\n\nconst NormalUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      withCredentials={false}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button>\n        <UploadOutlined />\n        上传文件\n      </Button>\n    </Upload>\n  )\n}\n\nconst CardUpload = (props) => {\n  return (\n    <Upload.Card\n      {...props}\n      withCredentials={false}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    />\n  )\n}\n\nconst DraggerUpload = (props) => {\n  return (\n    <Upload.Dragger\n      {...props}\n      withCredentials={false}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n    >\n      <div className=\"next-upload-drag\">\n        <p className=\"next-upload-drag-icon\" style={{ fontSize: 50 }}>\n          <InboxOutlined />\n        </p>\n        <p className=\"next-upload-drag-text\">\n          click to <Button text>download template</Button> or drag file here\n        </p>\n        <p className=\"next-upload-drag-hint\">supports docx, xls, PDF </p>\n      </div>\n    </Upload.Dragger>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    NormalUpload,\n    CardUpload,\n    DraggerUpload,\n    FormItem,\n  },\n})\n\nconst form = createForm()\n\nconst schema = {\n  type: 'object',\n  properties: {\n    upload: {\n      type: 'array',\n      title: '上传',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'NormalUpload',\n    },\n    upload2: {\n      type: 'array',\n      title: '卡片上传',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'CardUpload',\n    },\n    upload3: {\n      type: 'array',\n      title: '拖拽上传',\n      required: true,\n      'x-decorator': 'FormItem',\n      'x-component': 'DraggerUpload',\n    },\n  },\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={14}>\n      <SchemaField schema={schema} />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## 纯 JSX 案例\n\n```tsx\nimport React from 'react'\nimport {\n  Upload,\n  FormItem,\n  FormButtonGroup,\n  Submit,\n  FormLayout,\n} from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { Button } from '@alifd/next'\nimport { UploadOutlined, InboxOutlined } from '@ant-design/icons'\n\nconst NormalUpload = (props) => {\n  return (\n    <Upload\n      {...props}\n      withCredentials={false}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    >\n      <Button>\n        <UploadOutlined />\n        上传文件\n      </Button>\n    </Upload>\n  )\n}\n\nconst CardUpload = (props) => {\n  return (\n    <Upload.Card\n      {...props}\n      withCredentials={false}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n      headers={{\n        authorization: 'authorization-text',\n      }}\n    />\n  )\n}\n\nconst DraggerUpload = (props) => {\n  return (\n    <Upload.Dragger\n      {...props}\n      withCredentials={false}\n      action=\"https://www.mocky.io/v2/5cc8019d300000980a055e76\"\n    >\n      <div className=\"next-upload-drag\">\n        <p className=\"next-upload-drag-icon\" style={{ fontSize: 50 }}>\n          <InboxOutlined />\n        </p>\n        <p className=\"next-upload-drag-text\">\n          click to <Button text>download template</Button> or drag file here\n        </p>\n        <p className=\"next-upload-drag-hint\">supports docx, xls, PDF </p>\n      </div>\n    </Upload.Dragger>\n  )\n}\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <FormLayout labelCol={6} wrapperCol={14}>\n      <Field\n        name=\"upload\"\n        title=\"上传\"\n        required\n        decorator={[FormItem]}\n        component={[NormalUpload]}\n      />\n      <Field\n        name=\"upload2\"\n        title=\"卡片上传\"\n        required\n        decorator={[FormItem]}\n        component={[CardUpload]}\n      />\n      <Field\n        name=\"upload3\"\n        title=\"拖拽上传\"\n        required\n        decorator={[FormItem]}\n        component={[DraggerUpload]}\n      />\n      <FormButtonGroup.FormItem>\n        <Submit onSubmit={console.log}>提交</Submit>\n      </FormButtonGroup.FormItem>\n    </FormLayout>\n  </FormProvider>\n)\n```\n\n## API\n\n参考 https://fusion.design/pc/component/basic/upload\n"
  },
  {
    "path": "packages/next/docs/components/index.md",
    "content": "# Alibaba Fusion\n\n## Introduction\n\n@formily/next is a professional component library for form scenarios based on Fusion Design encapsulation. It has the following characteristics:\n\n- Only Formily 2.x is supported\n  - Most components are not backward compatible\n  - Unfortunately, many components of 1.x have inherent flaws in the API design. This is also because the form scheme has been explored, so there will be version breaks.\n- Richer component system\n  - Layout components\n    - FormLayout\n    - FormItem\n    - FormGrid\n    - FormButtonGroup\n    - Space\n    - Submit\n    - Reset\n  - Input controls\n    - Input\n    - Password\n    - Select\n    - TreeSelect\n    - DatePicker\n    - TimePicker\n    - NumberPicker\n    - Transfer\n    - Cascader\n    - Radio\n    - Checkbox\n    - Upload\n    - Switch\n  - Scene components\n    - ArrayCards\n    - ArrayItems\n    - ArrayTable\n    - FormCollapse\n    - FormStep\n    - FormTab\n    - FormDialog\n    - FormDrawer\n    - Editable\n    - LogicDiagram\n  - Reading state component\n    - PreviewText\n- Theme customization ability\n  - Completely abandon the 1.x styled-components solution, follow the style system of the component library, it is more convenient to customize the theme\n- Support secondary packaging\n  - All components can be repackaged, and the 1.x component system cannot be repackaged, so providing this capability makes it more convenient for users to do business customization\n- Support reading mode\n  - Although 1.x also supports reading mode, 2.x provides a separate PreviewText component, users can make reading mode encapsulation based on it, which is more flexible\n- Type is more friendly\n  - Each component has an extremely complete type definition, and users can feel an unprecedented intelligent reminder experience during the actual development process\n- More complete layout control capabilities\n  - 1.x's layout capabilities have basically converged to FormMegaLayout. This time, we directly removed Mega. Mega is a standard component and is completely internalized into FormLayout and FormItem components. At the same time, MegaLayout's grid layout capabilities are placed in FormGrid components. In, it also provides smarter layout capabilities.\n- More elegant and easy-to-use APIs, such as:\n  - FormStep in the past has many problems. First, the type is not friendly. Second, the API is too hidden. To control the forward and backwards, you need to understand a bunch of private events. In the new version of FormStep, users only need to pay attention to the FormStep Reactive Model. You can create a Reactive Model through createFormStep and pass it to the FormStep component to quickly communicate. Similarly, FormTab/FormCollapse is the same communication mode.\n  - Pop-up forms, drawer forms, presumably in the past, users had to write a lot of code on these two scenarios almost every time. This time, an extremely simple API is directly provided for users to use, which maximizes development efficiency.\n\n## Note\n\nBecause Fusion is built on Sass, if you use Webpack configuration, please use the following two Sass tools\n\n```\n\"sass\": \"^1.32.11\",\n\"sass-loader\": \"^8.0.2\"\n```\n\n## Installation\n\n```bash\n$ npm install --save @alifd/next moment\n$ npm install --save @formily/next @formily/react\n\n```\n\n## Q/A\n\nQ: I want to package a set of component libraries by myself, what should I do?\n\nAnswer: If it is an open source component library, you can directly participate in the project co-construction and provide PR. If it is a private component library in the enterprise, you can refer to the source code. The source code does not have too much complicated logic.\n\nQuestion: Why do components such as ArrayCards/ArrayTable/FormStep only support Schema mode and not pure JSX mode?\n\nAnswer: This is the core advantage of Schema mode. With the help of protocols, we can do scene-based abstraction. On the contrary, pure JSX mode is limited by the unparseability of JSX. It is difficult for us to achieve UI-level scene-based abstraction. It's just an abstract hook.\n\nQ: Why is there no ArrayTabs component?\n\nAnswer: Because Fusion's Tab component does not support the ability to add Tabs, the ArrayTabs component is temporarily not supported.\n"
  },
  {
    "path": "packages/next/docs/components/index.zh-CN.md",
    "content": "# Alibaba Fusion\n\n## 介绍\n\n@formily/next 是基于 Fusion Design 封装的针对表单场景专业级(Professional)组件库，它主要有以下几个特点：\n\n- 仅支持 Formily2.x\n  - 大部分组件无法向后兼容\n  - 很遗憾，1.x 的很多组件在 API 设计上存在本质上的缺陷，这也是因为表单方案一直在探索之中，所以才会出现版本断裂。\n- 更丰富的组件体系\n  - 布局组件\n    - FormLayout\n    - FormItem\n    - FormGrid\n    - FormButtonGroup\n    - Space\n    - Submit\n    - Reset\n  - 输入控件\n    - Input\n    - Password\n    - Select\n    - TreeSelect\n    - DatePicker\n    - TimePicker\n    - NumberPicker\n    - Transfer\n    - Cascader\n    - Radio\n    - Checkbox\n    - Upload\n    - Switch\n  - 场景组件\n    - ArrayCards\n    - ArrayItems\n    - ArrayTable\n    - FormCollapse\n    - FormStep\n    - FormTab\n    - FormDialog\n    - FormDrawer\n    - Editable\n    - LogicDiagram\n  - 阅读态组件\n    - PreviewText\n- 主题定制能力\n  - 完全放弃了 1.x styled-components 方案，follow 组件库的样式体系，更方便定制主题\n- 支持二次封装\n  - 所有组件都能二次封装，1.x 的组件体系是不能二次封装的，所以提供了这个能力则更方便用户做业务定制\n- 支持阅读态\n  - 虽然 1.x 同样支持阅读态，但是 2.x 单独提供了 PreviewText 组件，用户可以基于它自己做阅读态封装，灵活性更强\n- 类型更加友好\n  - 每个组件都有着极其完整的类型定义，用户在实际开发过程中，可以感受到前所未有的智能提示体验\n- 更完备的布局控制能力\n  - 1.x 的布局能力基本上都收敛到了 FormMegaLayout 上，这次，我们直接去掉 Mega，Mega 就是标准组件，完全内化到 FormLayout 和 FormItem 组件中，同时将 MegaLayout 的网格布局能力放到了 FormGrid 组件中，也提供了更智能的布局能力。\n- 更优雅易用的 API，比如：\n  - 过去的 FormStep，有很多问题，第一，类型不友好，第二，API 隐藏太深，想要控制前进后退需要理解一堆的私有事件。新版 FormStep，用户只需要关注 FormStep Reactive Model 即可，通过 createFormStep 就可以创建出 Reactive Model，传给 FormStep 组件即可快速通讯。同理，FormTab/FormCollapse 也是一样的通讯模式。\n  - 弹窗表单，抽屉表单，想必过去，用户几乎每次都得在这两个场景上写大量的代码，这次直接提供了极其简易的 API 让用户使用，最大化提升开发效率。\n\n## 注意\n\n因为 Fusion 是基于 Sass 构建的，如果你用 Webpack 配置请使用以下两个 Sass 工具\n\n```\n\"sass\": \"^1.32.11\",\n\"sass-loader\": \"^8.0.2\"\n```\n\n## 安装\n\n```bash\n$ npm install --save @alifd/next moment\n$ npm install --save @formily/next @formily/react\n\n```\n\n## Q/A\n\n问：我想自己封装一套组件库，该怎么做？\n\n答：如果是开源组件库，可以直接参与项目共建，提供 PR，如果是企业内私有组件库，参考源码即可，源码并没有太多复杂逻辑。\n\n问：为什么 ArrayCards/ArrayTable/FormStep 这类组件只支持 Schema 模式，不支持纯 JSX 模式？\n\n答：这就是 Schema 模式的核心优势，借助协议，我们可以做场景化抽象，相反，纯 JSX 模式，受限于 JSX 的不可解析性，我们很难做到 UI 级别的场景化抽象，更多的只是抽象 Hook。\n\n问：为什么没有 ArrayTabs 组件？\n\n答：因为 Fusion 的 Tab 组件并不支持新增 Tab 能力，所以暂时不支持 ArrayTabs 组件。\n"
  },
  {
    "path": "packages/next/docs/index.md",
    "content": "---\ntitle: Formily-Alibaba unified front-end form solution\norder: 10\nhero:\n  title: Formily Fusion\n  desc: Formily Component System Based on Alibaba Fusion Encapsulation\n  actions:\n    - text: Home Site\n      link: //formilyjs.org\n    - text: Document\n      link: /components\nfeatures:\n  - icon: https://img.alicdn.com/imgextra/i2/O1CN016i72sH1c5wh1kyy9U_!!6000000003550-55-tps-800-800.svg\n    title: Easier To Use\n    desc: Out of the box, rich cases\n  - icon: https://img.alicdn.com/imgextra/i1/O1CN01bHdrZJ1rEOESvXEi5_!!6000000005599-55-tps-800-800.svg\n    title: More Efficient\n    desc: Stupid writing, super high performance\n  - icon: https://img.alicdn.com/imgextra/i3/O1CN01xlETZk1G0WSQT6Xii_!!6000000000560-55-tps-800-800.svg\n    title: More Professional\n    desc: complete, flexible, elegant\nfooter: Open-source MIT Licensed | Copyright © 2019-present<br />Powered by self\n---\n\n## Installation\n\n```bash\n$ npm install --save @alifd/next moment\n$ npm install --save @formily/core @formily/react @formily/next\n\n```\n\n## Quick start\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React from 'react'\nimport { NumberPicker, FormItem, Space } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Space>\n      <Field\n        name=\"price\"\n        title=\"price\"\n        initialValue={5.2}\n        decorator={[FormItem]}\n        component={[\n          NumberPicker,\n          {\n            placeholder: 'Please enter',\n            style: {\n              width: 100,\n            },\n          },\n        ]}\n      />\n      <FormItem>×</FormItem>\n      <Field\n        name=\"count\"\n        title=\"quantity\"\n        initialValue={100}\n        decorator={[FormItem]}\n        component={[\n          NumberPicker,\n          {\n            placeholder: 'Please enter',\n            style: {\n              width: 100,\n            },\n          },\n        ]}\n      />\n      <FormConsumer>\n        {(form) => (\n          <FormItem>={` ${form.values.price * form.values.count}元`}</FormItem>\n        )}\n      </FormConsumer>\n    </Space>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/next/docs/index.zh-CN.md",
    "content": "---\ntitle: Formily - 阿里巴巴统一前端表单解决方案\norder: 10\nhero:\n  title: Formily Fusion\n  desc: 基于Alibaba Fusion封装的优雅且易用的Formily2.x组件体系\n  actions:\n    - text: 主站文档\n      link: //formilyjs.org\n    - text: 组件文档\n      link: /zh-CN/components\nfeatures:\n  - icon: https://img.alicdn.com/imgextra/i2/O1CN016i72sH1c5wh1kyy9U_!!6000000003550-55-tps-800-800.svg\n    title: 更易用\n    desc: 开箱即用，案例丰富\n  - icon: https://img.alicdn.com/imgextra/i1/O1CN01bHdrZJ1rEOESvXEi5_!!6000000005599-55-tps-800-800.svg\n    title: 更高效\n    desc: 傻瓜写法，超高性能\n  - icon: https://img.alicdn.com/imgextra/i3/O1CN01xlETZk1G0WSQT6Xii_!!6000000000560-55-tps-800-800.svg\n    title: 更专业\n    desc: 完备，灵活，优雅\nfooter: Open-source MIT Licensed | Copyright © 2019-present<br />Powered by self\n---\n\n## 安装\n\n```bash\n$ npm install --save @alifd/next moment\n$ npm install --save @formily/core @formily/react @formily/next\n\n```\n\n## 快速开始\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React from 'react'\nimport { NumberPicker, FormItem, Space } from '@formily/next'\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, Field } from '@formily/react'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Space>\n      <Field\n        name=\"price\"\n        title=\"价格\"\n        initialValue={5.2}\n        decorator={[FormItem]}\n        component={[\n          NumberPicker,\n          {\n            placeholder: '请输入',\n            style: {\n              width: 100,\n            },\n          },\n        ]}\n      />\n      <FormItem>×</FormItem>\n      <Field\n        name=\"count\"\n        title=\"数量\"\n        initialValue={100}\n        decorator={[FormItem]}\n        component={[\n          NumberPicker,\n          {\n            placeholder: '请输入',\n            style: {\n              width: 100,\n            },\n          },\n        ]}\n      />\n      <FormConsumer>\n        {(form) => (\n          <FormItem>={` ${form.values.price * form.values.count} 元`}</FormItem>\n        )}\n      </FormConsumer>\n    </Space>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/next/package.json",
    "content": "{\n  \"name\": \"@formily/next\",\n  \"version\": \"2.3.7\",\n  \"license\": \"MIT\",\n  \"main\": \"lib\",\n  \"umd:main\": \"dist/formily.next.umd.production.js\",\n  \"unpkg\": \"dist/formily.next.umd.production.js\",\n  \"jsdelivr\": \"dist/formily.next.umd.production.js\",\n  \"jsnext:main\": \"esm\",\n  \"module\": \"esm\",\n  \"sideEffects\": [\n    \"dist/*\",\n    \"esm/*.js\",\n    \"lib/*.js\",\n    \"src/*.ts\",\n    \"*.scss\",\n    \"**/*/style.js\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/alibaba/formily.git\"\n  },\n  \"types\": \"esm/index.d.ts\",\n  \"bugs\": {\n    \"url\": \"https://github.com/alibaba/formily/issues\"\n  },\n  \"homepage\": \"https://github.com/alibaba/formily#readme\",\n  \"engines\": {\n    \"npm\": \">=3.0.0\"\n  },\n  \"scripts\": {\n    \"start\": \"dumi dev\",\n    \"build\": \"rimraf -rf lib esm dist && npm run create:style && npm run build:cjs && npm run build:esm && npm run build:umd && npm run build:style\",\n    \"create:style\": \"ts-node create-style\",\n    \"build:style\": \"ts-node build-style\",\n    \"build:cjs\": \"tsc --project tsconfig.build.json\",\n    \"build:esm\": \"tsc --project tsconfig.build.json --module es2015 --outDir esm\",\n    \"build:umd\": \"rollup --config\",\n    \"build:docs\": \"dumi build\"\n  },\n  \"peerDependencies\": {\n    \"@alifd/next\": \"^1.19.0\",\n    \"@types/react\": \">=16.8.0\",\n    \"@types/react-dom\": \">=16.8.0\",\n    \"react\": \">=16.8.0\",\n    \"react-dom\": \">=16.8.0\",\n    \"react-is\": \">=16.8.0\"\n  },\n  \"peerDependenciesMeta\": {\n    \"@types/react\": {\n      \"optional\": true\n    },\n    \"@types/react-dom\": {\n      \"optional\": true\n    }\n  },\n  \"devDependencies\": {\n    \"@umijs/plugin-sass\": \"^1.1.1\",\n    \"dumi\": \"^1.1.0-rc.8\"\n  },\n  \"dependencies\": {\n    \"@formily/core\": \"2.3.7\",\n    \"@formily/grid\": \"2.3.7\",\n    \"@formily/json-schema\": \"2.3.7\",\n    \"@formily/react\": \"2.3.7\",\n    \"@formily/reactive\": \"2.3.7\",\n    \"@formily/reactive-react\": \"2.3.7\",\n    \"@formily/shared\": \"2.3.7\",\n    \"classnames\": \"^2.2.6\",\n    \"react-sortable-hoc\": \"^1.11.0\",\n    \"react-sticky-box\": \"^0.9.3\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"gitHead\": \"ac79c196ae9324889aca5e0501146f9b37b04283\"\n}\n"
  },
  {
    "path": "packages/next/rollup.config.js",
    "content": "import baseConfig, {\n  removeImportStyleFromInputFilePlugin,\n} from '../../scripts/rollup.base.js'\n\nexport default baseConfig(\n  'formily.next',\n  'Formily.Next',\n  removeImportStyleFromInputFilePlugin()\n)\n"
  },
  {
    "path": "packages/next/src/__builtins__/empty.tsx",
    "content": "import React from 'react'\n\nexport const Empty = () => {\n  return (\n    <div className=\"next-empty\">\n      <div className=\"next-empty-image\">\n        <svg\n          className=\"ant-empty-img-default\"\n          width=\"184\"\n          height=\"120\"\n          viewBox=\"0 0 184 152\"\n          xmlns=\"http://www.w3.org/2000/svg\"\n        >\n          <g fill=\"none\" fillRule=\"evenodd\">\n            <g transform=\"translate(24 31.67)\">\n              <ellipse\n                className=\"ant-empty-img-default-ellipse\"\n                cx=\"67.797\"\n                cy=\"106.89\"\n                rx=\"67.797\"\n                ry=\"12.668\"\n              ></ellipse>\n              <path\n                className=\"ant-empty-img-default-path-1\"\n                d=\"M122.034 69.674L98.109 40.229c-1.148-1.386-2.826-2.225-4.593-2.225h-51.44c-1.766 0-3.444.839-4.592 2.225L13.56 69.674v15.383h108.475V69.674z\"\n              ></path>\n              <path\n                className=\"ant-empty-img-default-path-2\"\n                d=\"M101.537 86.214L80.63 61.102c-1.001-1.207-2.507-1.867-4.048-1.867H31.724c-1.54 0-3.047.66-4.048 1.867L6.769 86.214v13.792h94.768V86.214z\"\n                transform=\"translate(13.56)\"\n              ></path>\n              <path\n                className=\"ant-empty-img-default-path-3\"\n                d=\"M33.83 0h67.933a4 4 0 0 1 4 4v93.344a4 4 0 0 1-4 4H33.83a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4z\"\n              ></path>\n              <path\n                className=\"ant-empty-img-default-path-4\"\n                d=\"M42.678 9.953h50.237a2 2 0 0 1 2 2V36.91a2 2 0 0 1-2 2H42.678a2 2 0 0 1-2-2V11.953a2 2 0 0 1 2-2zM42.94 49.767h49.713a2.262 2.262 0 1 1 0 4.524H42.94a2.262 2.262 0 0 1 0-4.524zM42.94 61.53h49.713a2.262 2.262 0 1 1 0 4.525H42.94a2.262 2.262 0 0 1 0-4.525zM121.813 105.032c-.775 3.071-3.497 5.36-6.735 5.36H20.515c-3.238 0-5.96-2.29-6.734-5.36a7.309 7.309 0 0 1-.222-1.79V69.675h26.318c2.907 0 5.25 2.448 5.25 5.42v.04c0 2.971 2.37 5.37 5.277 5.37h34.785c2.907 0 5.277-2.421 5.277-5.393V75.1c0-2.972 2.343-5.426 5.25-5.426h26.318v33.569c0 .617-.077 1.216-.221 1.789z\"\n              ></path>\n            </g>\n            <path\n              className=\"ant-empty-img-default-path-5\"\n              d=\"M149.121 33.292l-6.83 2.65a1 1 0 0 1-1.317-1.23l1.937-6.207c-2.589-2.944-4.109-6.534-4.109-10.408C138.802 8.102 148.92 0 161.402 0 173.881 0 184 8.102 184 18.097c0 9.995-10.118 18.097-22.599 18.097-4.528 0-8.744-1.066-12.28-2.902z\"\n            ></path>\n            <g\n              className=\"ant-empty-img-default-g\"\n              transform=\"translate(149.65 15.383)\"\n            >\n              <ellipse cx=\"20.654\" cy=\"3.167\" rx=\"2.849\" ry=\"2.815\"></ellipse>\n              <path d=\"M5.698 5.63H0L2.898.704zM9.259.704h4.985V5.63H9.259z\"></path>\n            </g>\n          </g>\n        </svg>\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "packages/next/src/__builtins__/hooks/index.ts",
    "content": "export * from './useClickAway'\nexport * from './usePrefixCls'\n"
  },
  {
    "path": "packages/next/src/__builtins__/hooks/useClickAway.ts",
    "content": "import { useRef, useEffect, MutableRefObject } from 'react'\n\nconst defaultEvent = 'click'\n\ntype EventType = MouseEvent | TouchEvent\n\ntype BasicTarget<T = HTMLElement> =\n  | (() => T | null)\n  | T\n  | null\n  | MutableRefObject<T | null | undefined>\n\ntype TargetElement = HTMLElement | Element | Document | Window\n\nfunction getTargetElement(\n  target?: BasicTarget<TargetElement>,\n  defaultElement?: TargetElement\n): TargetElement | undefined | null {\n  if (!target) {\n    return defaultElement\n  }\n\n  let targetElement: TargetElement | undefined | null\n\n  if (typeof target === 'function') {\n    targetElement = target()\n  } else if ('current' in target) {\n    targetElement = target.current\n  } else {\n    targetElement = target\n  }\n\n  return targetElement\n}\n\nexport const useClickAway = (\n  onClickAway: (event: EventType) => void,\n  target: BasicTarget | BasicTarget[],\n  eventName: string = defaultEvent\n) => {\n  const onClickAwayRef = useRef(onClickAway)\n  onClickAwayRef.current = onClickAway\n\n  useEffect(() => {\n    const handler = (event: any) => {\n      const targets = Array.isArray(target) ? target : [target]\n      if (\n        targets.some((targetItem) => {\n          const targetElement = getTargetElement(targetItem) as HTMLElement\n          return !targetElement || targetElement?.contains(event.target)\n        })\n      ) {\n        return\n      }\n      onClickAwayRef.current(event)\n    }\n\n    document.addEventListener(eventName, handler)\n\n    return () => {\n      document.removeEventListener(eventName, handler)\n    }\n  }, [target, eventName])\n}\n"
  },
  {
    "path": "packages/next/src/__builtins__/hooks/usePrefixCls.ts",
    "content": "import { ConfigProvider } from '@alifd/next'\n\nexport const usePrefixCls = (\n  tag?: string,\n  props?: {\n    prefix?: string\n  }\n) => {\n  const getContext = ConfigProvider['getContext']\n  const prefix = props?.prefix ?? getContext()?.prefix ?? 'next-'\n  return `${prefix}${tag ?? ''}`\n}\n"
  },
  {
    "path": "packages/next/src/__builtins__/icons.tsx",
    "content": "import React from 'react'\nimport cls from 'classnames'\nimport { usePrefixCls } from './hooks/usePrefixCls'\nexport type IconProps = React.HTMLAttributes<SVGSVGElement> & {\n  ref?: React.ForwardedRef<SVGSVGElement>\n}\n\nexport type IconType = React.ForwardRefExoticComponent<IconProps>\n\nexport const Icon: IconType = React.forwardRef((props, ref) => {\n  const prefix = usePrefixCls('formily-icon')\n  return (\n    <svg\n      {...props}\n      ref={ref}\n      className={cls(prefix, props.className)}\n      style={{\n        ...props.style,\n        cursor: props.onClick ? 'pointer' : '',\n        display: 'inline-block',\n        verticalAlign: 'middle',\n      }}\n      viewBox=\"64 64 896 896\"\n      fill=\"currentColor\"\n      width=\"1em\"\n      height=\"1em\"\n      focusable=\"false\"\n      aria-hidden=\"true\"\n    >\n      {props.children}\n    </svg>\n  )\n})\n\nexport const MenuOutlinedIcon: IconType = React.forwardRef((props, ref) => (\n  <Icon {...props} ref={ref}>\n    <path d=\"M904 160H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0 624H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8zm0-312H120c-4.4 0-8 3.6-8 8v64c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-64c0-4.4-3.6-8-8-8z\"></path>\n  </Icon>\n))\n\nexport const PlusOutlinedIcon: IconType = React.forwardRef((props, ref) => (\n  <Icon {...props} ref={ref}>\n    <path d=\"M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z\"></path>\n    <path d=\"M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z\"></path>\n  </Icon>\n))\n\nexport const UpOutlinedIcon: IconType = React.forwardRef((props, ref) => (\n  <Icon {...props} ref={ref}>\n    <path d=\"M890.5 755.3L537.9 269.2c-12.8-17.6-39-17.6-51.7 0L133.5 755.3A8 8 0 00140 768h75c5.1 0 9.9-2.5 12.9-6.6L512 369.8l284.1 391.6c3 4.1 7.8 6.6 12.9 6.6h75c6.5 0 10.3-7.4 6.5-12.7z\"></path>\n  </Icon>\n))\n\nexport const DownOutlinedIcon: IconType = React.forwardRef((props, ref) => (\n  <Icon {...props} ref={ref}>\n    <path d=\"M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z\"></path>\n  </Icon>\n))\n\nexport const DeleteOutlinedIcon: IconType = React.forwardRef((props, ref) => (\n  <Icon {...props} ref={ref}>\n    <path d=\"M360 184h-8c4.4 0 8-3.6 8-8v8h304v-8c0 4.4 3.6 8 8 8h-8v72h72v-80c0-35.3-28.7-64-64-64H352c-35.3 0-64 28.7-64 64v80h72v-72zm504 72H160c-17.7 0-32 14.3-32 32v32c0 4.4 3.6 8 8 8h60.4l24.7 523c1.6 34.1 29.8 61 63.9 61h454c34.2 0 62.3-26.8 63.9-61l24.7-523H888c4.4 0 8-3.6 8-8v-32c0-17.7-14.3-32-32-32zM731.3 840H292.7l-24.2-512h487l-24.2 512z\"></path>\n  </Icon>\n))\n\nexport const CopyOutlinedIcon: IconType = React.forwardRef((props, ref) => (\n  <Icon {...props} ref={ref}>\n    <path d=\"M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32zM704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c2.2 2.2 4.7 4 7.4 5.5v1.9h4.2c3.5 1.3 7.2 2 11 2H704c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM350 856.2L263.9 770H350v86.2zM664 888H414V746c0-22.1-17.9-40-40-40H232V264h432v624z\"></path>\n  </Icon>\n))\n\nexport const QuestionCircleOutlinedIcon: IconType = React.forwardRef(\n  (props, ref) => (\n    <Icon {...props} ref={ref}>\n      <path d=\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z\"></path>\n      <path d=\"M623.6 316.7C593.6 290.4 554 276 512 276s-81.6 14.5-111.6 40.7C369.2 344 352 380.7 352 420v7.6c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V420c0-44.1 43.1-80 96-80s96 35.9 96 80c0 31.1-22 59.6-56.1 72.7-21.2 8.1-39.2 22.3-52.1 40.9-13.1 19-19.9 41.8-19.9 64.9V620c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-22.7a48.3 48.3 0 0130.9-44.8c59-22.7 97.1-74.7 97.1-132.5.1-39.3-17.1-76-48.3-103.3zM472 732a40 40 0 1080 0 40 40 0 10-80 0z\"></path>\n    </Icon>\n  )\n)\nexport const CloseCircleOutlinedIcon: IconType = React.forwardRef(\n  (props, ref) => (\n    <Icon {...props} ref={ref}>\n      <path d=\"M685.4 354.8c0-4.4-3.6-8-8-8l-66 .3L512 465.6l-99.3-118.4-66.1-.3c-4.4 0-8 3.5-8 8 0 1.9.7 3.7 1.9 5.2l130.1 155L340.5 670a8.32 8.32 0 00-1.9 5.2c0 4.4 3.6 8 8 8l66.1-.3L512 564.4l99.3 118.4 66 .3c4.4 0 8-3.5 8-8 0-1.9-.7-3.7-1.9-5.2L553.5 515l130.1-155c1.2-1.4 1.8-3.3 1.8-5.2z\"></path>\n      <path d=\"M512 65C264.6 65 64 265.6 64 513s200.6 448 448 448 448-200.6 448-448S759.4 65 512 65zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z\"></path>\n    </Icon>\n  )\n)\nexport const CheckCircleOutlinedIcon: IconType = React.forwardRef(\n  (props, ref) => (\n    <Icon {...props} ref={ref}>\n      <path d=\"M699 353h-46.9c-10.2 0-19.9 4.9-25.9 13.3L469 584.3l-71.2-98.8c-6-8.3-15.6-13.3-25.9-13.3H325c-6.5 0-10.3 7.4-6.5 12.7l124.6 172.8a31.8 31.8 0 0051.7 0l210.6-292c3.9-5.3.1-12.7-6.4-12.7z\"></path>\n      <path d=\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z\"></path>\n    </Icon>\n  )\n)\nexport const ExclamationCircleOutlinedIcon: IconType = React.forwardRef(\n  (props, ref) => (\n    <Icon {...props} ref={ref}>\n      <path d=\"M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z\"></path>\n      <path d=\"M464 688a48 48 0 1096 0 48 48 0 10-96 0zm24-112h48c4.4 0 8-3.6 8-8V296c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8z\"></path>\n    </Icon>\n  )\n)\n\nexport const EditOutlinedIcon: IconType = React.forwardRef((props, ref) => (\n  <Icon {...props} ref={ref}>\n    <path d=\"M257.7 752c2 0 4-.2 6-.5L431.9 722c2-.4 3.9-1.3 5.3-2.8l423.9-423.9a9.96 9.96 0 000-14.1L694.9 114.9c-1.9-1.9-4.4-2.9-7.1-2.9s-5.2 1-7.1 2.9L256.8 538.8c-1.5 1.5-2.4 3.3-2.8 5.3l-29.5 168.2a33.5 33.5 0 009.4 29.8c6.6 6.4 14.9 9.9 23.8 9.9zm67.4-174.4L687.8 215l73.3 73.3-362.7 362.6-88.9 15.7 15.6-89zM880 836H144c-17.7 0-32 14.3-32 32v36c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-36c0-17.7-14.3-32-32-32z\"></path>{' '}\n  </Icon>\n))\nexport const CloseOutlinedIcon: IconType = React.forwardRef((props, ref) => (\n  <Icon {...props} ref={ref}>\n    <path d=\"M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z\"></path>\n  </Icon>\n))\nexport const MessageOutlinedIcon: IconType = React.forwardRef((props, ref) => (\n  <Icon {...props} ref={ref}>\n    <path d=\"M464 512a48 48 0 1096 0 48 48 0 10-96 0zm200 0a48 48 0 1096 0 48 48 0 10-96 0zm-400 0a48 48 0 1096 0 48 48 0 10-96 0zm661.2-173.6c-22.6-53.7-55-101.9-96.3-143.3a444.35 444.35 0 00-143.3-96.3C630.6 75.7 572.2 64 512 64h-2c-60.6.3-119.3 12.3-174.5 35.9a445.35 445.35 0 00-142 96.5c-40.9 41.3-73 89.3-95.2 142.8-23 55.4-34.6 114.3-34.3 174.9A449.4 449.4 0 00112 714v152a46 46 0 0046 46h152.1A449.4 449.4 0 00510 960h2.1c59.9 0 118-11.6 172.7-34.3a444.48 444.48 0 00142.8-95.2c41.3-40.9 73.8-88.7 96.5-142 23.6-55.2 35.6-113.9 35.9-174.5.3-60.9-11.5-120-34.8-175.6zm-151.1 438C704 845.8 611 884 512 884h-1.7c-60.3-.3-120.2-15.3-173.1-43.5l-8.4-4.5H188V695.2l-4.5-8.4C155.3 633.9 140.3 574 140 513.7c-.4-99.7 37.7-193.3 107.6-263.8 69.8-70.5 163.1-109.5 262.8-109.9h1.7c50 0 98.5 9.7 144.2 28.9 44.6 18.7 84.6 45.6 119 80 34.3 34.3 61.3 74.4 80 119 19.4 46.2 29.1 95.2 28.9 145.8-.6 99.6-39.7 192.9-110.1 262.7z\"></path>\n  </Icon>\n))\n"
  },
  {
    "path": "packages/next/src/__builtins__/index.ts",
    "content": "export * from './moment'\nexport * from './hooks'\nexport * from './toArray'\nexport * from './mapStatus'\nexport * from './mapSize'\nexport * from './empty'\nexport * from './loading'\nexport * from './portal'\nexport * from './pickDataProps'\nexport * from './icons'\n"
  },
  {
    "path": "packages/next/src/__builtins__/loading.ts",
    "content": "import { Message } from '@alifd/next'\n\nexport const loading = async (\n  title: React.ReactNode = 'Loading...',\n  processor: () => Promise<any>\n) => {\n  let loading = setTimeout(() => {\n    Message.loading(title as any)\n  }, 100)\n  try {\n    return await processor()\n  } finally {\n    Message.hide()\n    clearTimeout(loading)\n  }\n}\n"
  },
  {
    "path": "packages/next/src/__builtins__/mapSize.ts",
    "content": "import { useFormLayout, useFormShallowLayout } from '../form-layout'\n\nexport const mapSize = (props: any) => {\n  const layout = { ...useFormShallowLayout(), ...useFormLayout() }\n  const takeSize = () => {\n    return layout.size === 'default' ? 'medium' : layout.size\n  }\n  return {\n    ...props,\n    size: props.size || takeSize(),\n  }\n}\n"
  },
  {
    "path": "packages/next/src/__builtins__/mapStatus.ts",
    "content": "import { Field } from '@formily/core'\n\nexport const mapStatus = (props: any, field: Field) => {\n  const takeStatus = () => {\n    if (!field) return\n    if (field.loading || field.validating) return 'loading'\n    if (field.selfErrors?.length) return 'error'\n    if (field.selfWarnings?.length) return 'warning'\n    return field.decoratorProps?.feedbackStatus\n  }\n  const takeState = (state: string) => {\n    if (state === 'validating' || state === 'pending') return 'loading'\n    return state\n  }\n  return {\n    ...props,\n    state: takeState(props.state) || takeStatus(),\n  }\n}\n"
  },
  {
    "path": "packages/next/src/__builtins__/moment.ts",
    "content": "import { isArr, isEmpty, isFn } from '@formily/shared'\nimport Moment from 'moment'\n\nconst moment = (date: any, format?: string) => {\n  return Moment(date?.toDate ? date.toDate() : date, format)\n}\n\nexport const momentable = (value: any, format?: string) => {\n  return Array.isArray(value)\n    ? value.map((val) => moment(val, format))\n    : value\n    ? moment(value, format)\n    : value\n}\n\nexport const formatMomentValue = (\n  value: any,\n  format: any,\n  placeholder?: string\n): string | string[] => {\n  const formatDate = (date: any, format: any, i = 0) => {\n    if (!date) return placeholder\n    const TIME_REG = /^(?:[01]\\d|2[0-3]):[0-5]\\d(:[0-5]\\d)?$/\n    let _format = format\n    if (isArr(format)) {\n      _format = format[i]\n    }\n    if (isFn(_format)) {\n      return _format(date)\n    }\n    if (isEmpty(_format)) {\n      return date\n    }\n    // moment '19:55:22' 下需要传入第二个参数\n    if (TIME_REG.test(date)) {\n      return moment(date, _format).format(_format)\n    }\n    return moment(date).format(_format)\n  }\n  if (isArr(value)) {\n    return value.map((val, index) => {\n      return formatDate(val, format, index)\n    })\n  } else {\n    return value ? formatDate(value, format) : value || placeholder\n  }\n}\n"
  },
  {
    "path": "packages/next/src/__builtins__/pickDataProps.ts",
    "content": "export const pickDataProps = (props: any = {}) => {\n  return Object.keys(props).reduce((buf, key) => {\n    if (key.includes('data-')) {\n      buf[key] = props[key]\n    }\n    return buf\n  }, {})\n}\n"
  },
  {
    "path": "packages/next/src/__builtins__/portal.tsx",
    "content": "import React, { Fragment } from 'react'\nimport { createPortal } from 'react-dom'\nimport { observable } from '@formily/reactive'\nimport { Observer } from '@formily/react'\nimport { render as reactRender, unmount as reactUnmount } from './render'\nexport interface IPortalProps {\n  id?: string | symbol\n}\n\nconst PortalMap = observable(new Map<string | symbol, React.ReactNode>())\n\nexport const createPortalProvider = (id: string | symbol) => {\n  const Portal = (props: React.PropsWithChildren<IPortalProps>) => {\n    const portalId = props.id ?? id\n    if (portalId && !PortalMap.has(portalId)) {\n      PortalMap.set(portalId, null)\n    }\n\n    return (\n      <Fragment>\n        {props.children}\n        <Observer>\n          {() => {\n            if (!portalId) return null\n            const portal = PortalMap.get(portalId)\n            if (portal) return createPortal(portal, document.body)\n            return null\n          }}\n        </Observer>\n      </Fragment>\n    )\n  }\n  return Portal\n}\n\nexport function createPortalRoot<T extends React.ReactNode>(\n  host: HTMLElement,\n  id: string\n) {\n  function render(renderer?: () => T) {\n    if (PortalMap.has(id)) {\n      PortalMap.set(id, renderer?.())\n    } else if (host) {\n      reactRender(<Fragment>{renderer?.()}</Fragment>, host)\n    }\n  }\n\n  function unmount() {\n    if (PortalMap.has(id)) {\n      PortalMap.set(id, null)\n    }\n    if (host) {\n      const unmountResult = reactUnmount(host)\n      if (unmountResult && host.parentNode) {\n        host.parentNode?.removeChild(host)\n      }\n    }\n  }\n\n  return {\n    render,\n    unmount,\n  }\n}\n"
  },
  {
    "path": "packages/next/src/__builtins__/render.ts",
    "content": "import { ReactElement } from 'react'\nimport * as ReactDOM from 'react-dom'\nimport type { Root } from 'react-dom/client'\n\n// 移植自rc-util: https://github.com/react-component/util/blob/master/src/React/render.ts\n\ntype CreateRoot = (container: ContainerType) => Root\n\n// Let compiler not to search module usage\nconst fullClone = {\n  ...ReactDOM,\n} as typeof ReactDOM & {\n  __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED?: {\n    usingClientEntryPoint?: boolean\n  }\n  createRoot?: CreateRoot\n}\n\nconst { version, render: reactRender, unmountComponentAtNode } = fullClone\n\nlet createRoot: CreateRoot\ntry {\n  const mainVersion = Number((version || '').split('.')[0])\n  if (mainVersion >= 18 && fullClone.createRoot) {\n    // eslint-disable-next-line @typescript-eslint/no-var-requires\n    createRoot = fullClone.createRoot\n  }\n} catch (e) {\n  // Do nothing;\n}\n\nfunction toggleWarning(skip: boolean) {\n  const { __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED } = fullClone\n\n  if (\n    __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED &&\n    typeof __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED === 'object'\n  ) {\n    __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.usingClientEntryPoint =\n      skip\n  }\n}\n\nconst MARK = '__antd_mobile_root__'\n\n// ========================== Render ==========================\ntype ContainerType = (Element | DocumentFragment) & {\n  [MARK]?: Root\n}\n\nfunction legacyRender(node: ReactElement, container: ContainerType) {\n  reactRender(node, container)\n}\n\nfunction concurrentRender(node: ReactElement, container: ContainerType) {\n  toggleWarning(true)\n  const root = container[MARK] || createRoot(container)\n  toggleWarning(false)\n  root.render(node)\n  container[MARK] = root\n}\n\nexport function render(node: ReactElement, container: ContainerType) {\n  if (createRoot as unknown) {\n    concurrentRender(node, container)\n    return\n  }\n  legacyRender(node, container)\n}\n\n// ========================== Unmount =========================\nfunction legacyUnmount(container: ContainerType) {\n  return unmountComponentAtNode(container)\n}\n\nasync function concurrentUnmount(container: ContainerType) {\n  // Delay to unmount to avoid React 18 sync warning\n  return Promise.resolve().then(() => {\n    container[MARK]?.unmount()\n    delete container[MARK]\n  })\n}\n\nexport function unmount(container: ContainerType) {\n  if (createRoot as unknown) {\n    return concurrentUnmount(container)\n  }\n\n  return legacyUnmount(container)\n}"
  },
  {
    "path": "packages/next/src/__builtins__/toArray.ts",
    "content": "import React from 'react'\nimport { isFragment } from 'react-is'\n\nexport interface toArrayOption {\n  keepEmpty?: boolean\n}\n\nexport function toArray(\n  children: React.ReactNode,\n  option: toArrayOption = {}\n): React.ReactElement[] {\n  let ret: React.ReactElement[] = []\n\n  React.Children.forEach(children, (child: any) => {\n    if ((child === undefined || child === null) && !option.keepEmpty) {\n      return\n    }\n\n    if (Array.isArray(child)) {\n      ret = ret.concat(toArray(child))\n    } else if (isFragment(child) && child.props) {\n      ret = ret.concat(toArray(child.props.children, option))\n    } else {\n      ret.push(child)\n    }\n  })\n\n  return ret\n}\n"
  },
  {
    "path": "packages/next/src/array-base/index.tsx",
    "content": "import React, { createContext, useContext } from 'react'\nimport { Button } from '@alifd/next'\nimport { isValid, isUndef, clone } from '@formily/shared'\nimport { ButtonProps } from '@alifd/next/lib/button'\nimport { ArrayField } from '@formily/core'\nimport { useField, useFieldSchema, Schema, JSXComponent } from '@formily/react'\nimport { SortableHandle } from 'react-sortable-hoc'\nimport {\n  usePrefixCls,\n  PlusOutlinedIcon,\n  DeleteOutlinedIcon,\n  DownOutlinedIcon,\n  UpOutlinedIcon,\n  MenuOutlinedIcon,\n  CopyOutlinedIcon,\n} from '../__builtins__'\nimport cls from 'classnames'\n\nexport interface IArrayBaseAdditionProps extends ButtonProps {\n  title?: string\n  method?: 'push' | 'unshift'\n  defaultValue?: any\n  icon?: React.ReactNode\n}\n\nexport interface IArrayBaseOperationProps extends ButtonProps {\n  title?: string\n  index?: number\n  ref?: React.Ref<Button>\n  icon?: React.ReactNode\n}\n\nexport interface IArrayBaseContext {\n  props: IArrayBaseProps\n  field: ArrayField\n  schema: Schema\n}\n\nexport interface IArrayBaseItemProps {\n  index: number\n  record: ((index: number) => Record<string, any>) | Record<string, any>\n}\n\nexport type ArrayBaseMixins = {\n  Addition?: React.FC<React.PropsWithChildren<IArrayBaseAdditionProps>>\n  Remove?: React.FC<\n    React.PropsWithChildren<IArrayBaseOperationProps & { index?: number }>\n  >\n  Copy?: React.FC<\n    React.PropsWithChildren<\n      IArrayBaseAdditionProps & IArrayBaseOperationProps & { index?: number }\n    >\n  >\n  MoveUp?: React.FC<\n    React.PropsWithChildren<IArrayBaseOperationProps & { index?: number }>\n  >\n  MoveDown?: React.FC<\n    React.PropsWithChildren<IArrayBaseOperationProps & { index?: number }>\n  >\n  SortHandle?: React.FC<\n    React.PropsWithChildren<IArrayBaseOperationProps & { index?: number }>\n  >\n  Index?: React.FC\n  useArray?: () => IArrayBaseContext\n  useIndex?: (index?: number) => number\n  useRecord?: (record?: number) => any\n}\n\nexport interface IArrayBaseProps {\n  disabled?: boolean\n  onCopy?: (index: number) => void\n  onAdd?: (index: number) => void\n  onRemove?: (index: number) => void\n  onMoveDown?: (index: number) => void\n  onMoveUp?: (index: number) => void\n}\n\ntype ComposedArrayBase = React.FC<React.PropsWithChildren<IArrayBaseProps>> &\n  ArrayBaseMixins & {\n    Item?: React.FC<React.PropsWithChildren<IArrayBaseItemProps>>\n    mixin?: <T extends JSXComponent>(target: T) => T & ArrayBaseMixins\n  }\n\nconst ArrayBaseContext = createContext<IArrayBaseContext>(null)\n\nconst ItemContext = createContext<IArrayBaseItemProps>(null)\n\nconst takeRecord = (val: any, index?: number) =>\n  typeof val === 'function' ? val(index) : val\n\nconst useArray = () => {\n  return useContext(ArrayBaseContext)\n}\n\nconst useIndex = (index?: number) => {\n  const ctx = useContext(ItemContext)\n  return ctx ? ctx.index : index\n}\n\nconst useRecord = (record?: number) => {\n  const ctx = useContext(ItemContext)\n  return takeRecord(ctx ? ctx.record : record, ctx?.index)\n}\n\nconst getSchemaDefaultValue = (schema: Schema) => {\n  if (schema?.type === 'array') return []\n  if (schema?.type === 'object') return {}\n  if (schema?.type === 'void') {\n    for (let key in schema.properties) {\n      const value = getSchemaDefaultValue(schema.properties[key])\n      if (isValid(value)) return value\n    }\n  }\n}\n\nconst getDefaultValue = (defaultValue: any, schema: Schema) => {\n  if (isValid(defaultValue)) return clone(defaultValue)\n  if (Array.isArray(schema?.items))\n    return getSchemaDefaultValue(schema?.items[0])\n  return getSchemaDefaultValue(schema?.items)\n}\n\nexport const ArrayBase: ComposedArrayBase = (props) => {\n  const field = useField<ArrayField>()\n  const schema = useFieldSchema()\n  return (\n    <ArrayBaseContext.Provider value={{ field, schema, props }}>\n      {props.children}\n    </ArrayBaseContext.Provider>\n  )\n}\n\nArrayBase.Item = ({ children, ...props }) => {\n  return <ItemContext.Provider value={props}>{children}</ItemContext.Provider>\n}\n\nconst SortHandle = SortableHandle((props: any) => {\n  const prefixCls = usePrefixCls('formily-array-base')\n  return (\n    <MenuOutlinedIcon\n      {...props}\n      className={cls(`${prefixCls}-sort-handle`, props.className)}\n      style={{ ...props.style }}\n    />\n  )\n}) as any\n\nArrayBase.SortHandle = () => {\n  const array = useArray()\n  if (!array) return null\n  if (array.field?.pattern !== 'editable') return null\n  return <SortHandle />\n}\n\nArrayBase.Index = (props) => {\n  const index = useIndex()\n  const prefixCls = usePrefixCls('formily-array-base')\n  return (\n    <span {...props} className={`${prefixCls}-index`}>\n      #{index + 1}.\n    </span>\n  )\n}\n\nArrayBase.Addition = (props) => {\n  const self = useField()\n  const array = useArray()\n  const prefixCls = usePrefixCls('formily-array-base')\n  if (!array) return null\n  if (\n    array.field?.pattern !== 'editable' &&\n    array.field?.pattern !== 'disabled'\n  )\n    return null\n  return (\n    <Button\n      {...props}\n      disabled={self?.disabled}\n      className={cls(`${prefixCls}-addition`, props.className)}\n      style={{ display: 'block', width: '100%', ...props.style }}\n      onClick={(e) => {\n        if (array.props?.disabled) return\n        e.stopPropagation()\n        const defaultValue = getDefaultValue(props.defaultValue, array.schema)\n        if (props.method === 'unshift') {\n          array.field?.unshift?.(defaultValue)\n          array.props?.onAdd?.(0)\n        } else {\n          array.field?.push?.(defaultValue)\n          array.props?.onAdd?.(array?.field?.value?.length - 1)\n        }\n        if (props.onClick) {\n          props.onClick(e)\n        }\n      }}\n    >\n      {isUndef(props.icon) ? <PlusOutlinedIcon /> : props.icon}\n      {props.title || self.title}\n    </Button>\n  )\n}\n\nArrayBase.Remove = React.forwardRef((props, ref) => {\n  const index = useIndex(props.index)\n  const self = useField()\n  const array = useArray()\n  const prefixCls = usePrefixCls('formily-array-base')\n  if (!array) return null\n  if (array.field?.pattern !== 'editable') return null\n  return (\n    <Button\n      text\n      {...props}\n      disabled={self?.disabled}\n      className={cls(\n        `${prefixCls}-remove`,\n        self?.disabled ? `${prefixCls}-remove-disabled` : '',\n        props.className\n      )}\n      ref={ref}\n      onClick={(e) => {\n        if (self?.disabled) return\n        e.stopPropagation()\n        array.field?.remove?.(index)\n        array.props?.onRemove?.(index)\n        if (props.onClick) {\n          props.onClick(e)\n        }\n      }}\n    >\n      {isUndef(props.icon) ? <DeleteOutlinedIcon /> : props.icon}\n      {props.title || self.title}\n    </Button>\n  )\n})\n\nArrayBase.Copy = React.forwardRef((props, ref) => {\n  const index = useIndex(props.index)\n  const self = useField()\n  const array = useArray()\n  const prefixCls = usePrefixCls('formily-array-base')\n  if (!array) return null\n  if (array.field?.pattern !== 'editable') return null\n  return (\n    <Button\n      text\n      {...props}\n      disabled={self?.disabled}\n      className={cls(\n        `${prefixCls}-copy`,\n        self?.disabled ? `${prefixCls}-copy-disabled` : '',\n        props.className\n      )}\n      ref={ref}\n      onClick={(e) => {\n        if (self?.disabled) return\n        e.stopPropagation()\n        if (array.props?.disabled) return\n        const value = clone(array?.field?.value[index])\n        const distIndex = index + 1\n        array.field?.insert?.(distIndex, value)\n        array.props?.onCopy?.(distIndex)\n        if (props.onClick) {\n          props.onClick(e)\n        }\n      }}\n    >\n      {isUndef(props.icon) ? <CopyOutlinedIcon /> : props.icon}\n      {props.title || self.title}\n    </Button>\n  )\n})\n\nArrayBase.MoveDown = React.forwardRef((props, ref) => {\n  const index = useIndex(props.index)\n  const self = useField()\n  const array = useArray()\n  const prefixCls = usePrefixCls('formily-array-base')\n  if (!array) return null\n  if (array.field?.pattern !== 'editable') return null\n  return (\n    <Button\n      text\n      {...props}\n      disabled={self?.disabled}\n      className={cls(\n        `${prefixCls}-move-down`,\n        self?.disabled ? `${prefixCls}-move-down-disabled` : '',\n        props.className\n      )}\n      ref={ref}\n      onClick={(e) => {\n        if (self?.disabled) return\n        e.stopPropagation()\n        array.field?.moveDown?.(index)\n        array.props?.onMoveDown?.(index)\n        if (props.onClick) {\n          props.onClick(e)\n        }\n      }}\n    >\n      {isUndef(props.icon) ? <DownOutlinedIcon /> : props.icon}\n      {props.title || self.title}\n    </Button>\n  )\n})\n\nArrayBase.MoveUp = React.forwardRef((props, ref) => {\n  const index = useIndex(props.index)\n  const self = useField()\n  const array = useArray()\n  const prefixCls = usePrefixCls('formily-array-base')\n  if (!array) return null\n  if (array.field?.pattern !== 'editable') return null\n  return (\n    <Button\n      text\n      {...props}\n      disabled={self?.disabled}\n      className={cls(\n        `${prefixCls}-move-up`,\n        self?.disabled ? `${prefixCls}-move-up-disabled` : '',\n        props.className\n      )}\n      ref={ref}\n      onClick={(e) => {\n        if (self?.disabled) return\n        e.stopPropagation()\n        array?.field?.moveUp(index)\n        array?.props?.onMoveUp?.(index)\n        if (props.onClick) {\n          props.onClick(e)\n        }\n      }}\n    >\n      {isUndef(props.icon) ? <UpOutlinedIcon /> : props.icon}\n      {props.title || self.title}\n    </Button>\n  )\n})\n\nArrayBase.useArray = useArray\nArrayBase.useIndex = useIndex\nArrayBase.useRecord = useRecord\nArrayBase.mixin = (target: any) => {\n  target.Index = ArrayBase.Index\n  target.SortHandle = ArrayBase.SortHandle\n  target.Addition = ArrayBase.Addition\n  target.Copy = ArrayBase.Copy\n  target.Remove = ArrayBase.Remove\n  target.MoveDown = ArrayBase.MoveDown\n  target.MoveUp = ArrayBase.MoveUp\n  target.useArray = ArrayBase.useArray\n  target.useIndex = ArrayBase.useIndex\n  target.useRecord = ArrayBase.useRecord\n  return target\n}\n\nexport default ArrayBase\n"
  },
  {
    "path": "packages/next/src/array-base/main.scss",
    "content": "@import '~@alifd/next/lib/core/index-noreset.scss';\n\n$array-base-prefix-cls: '#{$css-prefix}formily-array-base';\n\n.#{$array-base-prefix-cls}-remove,\n.#{$array-base-prefix-cls}-copy {\n  transition: all 0.25s ease-in-out;\n  color: $color-text1-3;\n  font-size: 16px;\n\n  &:hover {\n    color: $color-text1-1;\n  }\n\n  &-disabled {\n    color: $color-text1-1;\n    cursor: not-allowed !important;\n    &:hover {\n      color: $color-text1-1;\n    }\n  }\n\n  .#{$css-prefix}formily-icon {\n    font-size: 16px;\n  }\n}\n\n.#{$array-base-prefix-cls}-addition {\n  transition: all 0.25s ease-in-out;\n}\n\n.#{$array-base-prefix-cls}-move-down {\n  transition: all 0.25s ease-in-out;\n  color: $color-text1-3;\n  font-size: 16px;\n\n  &:hover {\n    color: $color-text1-1;\n  }\n\n  &-disabled {\n    color: $color-text1-1;\n    cursor: not-allowed !important;\n    &:hover {\n      color: $color-text1-1;\n    }\n  }\n\n  .#{$css-prefix}formily-icon {\n    font-size: 16px;\n  }\n}\n\n.#{$array-base-prefix-cls}-move-up {\n  transition: all 0.25s ease-in-out;\n  color: $color-text1-3;\n  font-size: 16px;\n\n  &:hover {\n    color: $color-text1-1;\n  }\n\n  &-disabled {\n    color: $color-text1-1;\n    cursor: not-allowed !important;\n    &:hover {\n      color: $color-text1-1;\n    }\n  }\n\n  .#{$css-prefix}formily-icon {\n    font-size: 16px;\n  }\n}\n\n.#{$array-base-prefix-cls}-sort-handle {\n  cursor: move;\n  color: #888 !important;\n}\n"
  },
  {
    "path": "packages/next/src/array-base/style.ts",
    "content": "import '@alifd/next/lib/button/style'\nimport './main.scss'\n"
  },
  {
    "path": "packages/next/src/array-cards/index.tsx",
    "content": "import React from 'react'\nimport { Card } from '@alifd/next'\nimport { CardProps } from '@alifd/next/lib/card'\nimport { ArrayField } from '@formily/core'\nimport {\n  useField,\n  observer,\n  useFieldSchema,\n  RecursionField,\n} from '@formily/react'\nimport { ISchema } from '@formily/json-schema'\nimport { usePrefixCls } from '../__builtins__'\nimport { ArrayBase, ArrayBaseMixins, IArrayBaseProps } from '../array-base'\nimport cls from 'classnames'\n\ntype ComposedArrayCards = React.FC<\n  React.PropsWithChildren<CardProps & IArrayBaseProps>\n> &\n  ArrayBaseMixins\n\nconst isAdditionComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Addition') > -1\n}\n\nconst isIndexComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Index') > -1\n}\n\nconst isRemoveComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Remove') > -1\n}\n\nconst isCopyComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Copy') > -1\n}\n\nconst isMoveUpComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('MoveUp') > -1\n}\n\nconst isMoveDownComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('MoveDown') > -1\n}\n\nconst isOperationComponent = (schema: ISchema) => {\n  return (\n    isAdditionComponent(schema) ||\n    isRemoveComponent(schema) ||\n    isCopyComponent(schema) ||\n    isMoveDownComponent(schema) ||\n    isMoveUpComponent(schema)\n  )\n}\n\nconst Empty = () => {\n  return (\n    <div className=\"next-empty\">\n      <div className=\"next-empty-image\">\n        <svg\n          className=\"ant-empty-img-default\"\n          width=\"184\"\n          height=\"152\"\n          viewBox=\"0 0 184 152\"\n          xmlns=\"http://www.w3.org/2000/svg\"\n        >\n          <g fill=\"none\" fillRule=\"evenodd\">\n            <g transform=\"translate(24 31.67)\">\n              <ellipse\n                className=\"ant-empty-img-default-ellipse\"\n                cx=\"67.797\"\n                cy=\"106.89\"\n                rx=\"67.797\"\n                ry=\"12.668\"\n              ></ellipse>\n              <path\n                className=\"ant-empty-img-default-path-1\"\n                d=\"M122.034 69.674L98.109 40.229c-1.148-1.386-2.826-2.225-4.593-2.225h-51.44c-1.766 0-3.444.839-4.592 2.225L13.56 69.674v15.383h108.475V69.674z\"\n              ></path>\n              <path\n                className=\"ant-empty-img-default-path-2\"\n                d=\"M101.537 86.214L80.63 61.102c-1.001-1.207-2.507-1.867-4.048-1.867H31.724c-1.54 0-3.047.66-4.048 1.867L6.769 86.214v13.792h94.768V86.214z\"\n                transform=\"translate(13.56)\"\n              ></path>\n              <path\n                className=\"ant-empty-img-default-path-3\"\n                d=\"M33.83 0h67.933a4 4 0 0 1 4 4v93.344a4 4 0 0 1-4 4H33.83a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4z\"\n              ></path>\n              <path\n                className=\"ant-empty-img-default-path-4\"\n                d=\"M42.678 9.953h50.237a2 2 0 0 1 2 2V36.91a2 2 0 0 1-2 2H42.678a2 2 0 0 1-2-2V11.953a2 2 0 0 1 2-2zM42.94 49.767h49.713a2.262 2.262 0 1 1 0 4.524H42.94a2.262 2.262 0 0 1 0-4.524zM42.94 61.53h49.713a2.262 2.262 0 1 1 0 4.525H42.94a2.262 2.262 0 0 1 0-4.525zM121.813 105.032c-.775 3.071-3.497 5.36-6.735 5.36H20.515c-3.238 0-5.96-2.29-6.734-5.36a7.309 7.309 0 0 1-.222-1.79V69.675h26.318c2.907 0 5.25 2.448 5.25 5.42v.04c0 2.971 2.37 5.37 5.277 5.37h34.785c2.907 0 5.277-2.421 5.277-5.393V75.1c0-2.972 2.343-5.426 5.25-5.426h26.318v33.569c0 .617-.077 1.216-.221 1.789z\"\n              ></path>\n            </g>\n            <path\n              className=\"ant-empty-img-default-path-5\"\n              d=\"M149.121 33.292l-6.83 2.65a1 1 0 0 1-1.317-1.23l1.937-6.207c-2.589-2.944-4.109-6.534-4.109-10.408C138.802 8.102 148.92 0 161.402 0 173.881 0 184 8.102 184 18.097c0 9.995-10.118 18.097-22.599 18.097-4.528 0-8.744-1.066-12.28-2.902z\"\n            ></path>\n            <g\n              className=\"ant-empty-img-default-g\"\n              transform=\"translate(149.65 15.383)\"\n            >\n              <ellipse cx=\"20.654\" cy=\"3.167\" rx=\"2.849\" ry=\"2.815\"></ellipse>\n              <path d=\"M5.698 5.63H0L2.898.704zM9.259.704h4.985V5.63H9.259z\"></path>\n            </g>\n          </g>\n        </svg>\n      </div>\n    </div>\n  )\n}\n\nexport const ArrayCards: ComposedArrayCards = observer((props) => {\n  const field = useField<ArrayField>()\n  const schema = useFieldSchema()\n  const dataSource = Array.isArray(field.value) ? field.value : []\n  const prefixCls = usePrefixCls('formily-array-cards', props)\n  const { onAdd, onCopy, onRemove, onMoveDown, onMoveUp } = props\n  const renderItems = () => {\n    return dataSource?.map((item, index) => {\n      const items = Array.isArray(schema.items)\n        ? schema.items[index] || schema.items[0]\n        : schema.items\n      const title = (\n        <span>\n          <RecursionField\n            schema={items}\n            name={index}\n            filterProperties={(schema) => {\n              if (!isIndexComponent(schema)) return false\n              return true\n            }}\n            onlyRenderProperties\n          />\n          {props.title || field.title}\n        </span>\n      )\n      const extra = (\n        <span>\n          <RecursionField\n            schema={items}\n            name={index}\n            filterProperties={(schema) => {\n              if (!isOperationComponent(schema)) return false\n              return true\n            }}\n            onlyRenderProperties\n          />\n          {props.extra}\n        </span>\n      )\n      const content = (\n        <RecursionField\n          schema={items}\n          name={index}\n          filterProperties={(schema) => {\n            if (isIndexComponent(schema)) return false\n            if (isOperationComponent(schema)) return false\n            return true\n          }}\n        />\n      )\n      return (\n        <ArrayBase.Item\n          key={index}\n          index={index}\n          record={() => field.value?.[index]}\n        >\n          <Card\n            contentHeight=\"auto\"\n            {...props}\n            onChange={() => {}}\n            className={cls(`${prefixCls}-item`, props.className)}\n            title={title}\n            extra={extra}\n          >\n            {content}\n          </Card>\n        </ArrayBase.Item>\n      )\n    })\n  }\n\n  const renderAddition = () => {\n    return schema.reduceProperties((addition, schema, key) => {\n      if (isAdditionComponent(schema)) {\n        return <RecursionField schema={schema} name={key} />\n      }\n      return addition\n    }, null)\n  }\n\n  const renderEmpty = () => {\n    if (dataSource?.length) return\n    return (\n      <Card\n        contentHeight=\"auto\"\n        {...props}\n        className={cls(`${prefixCls}-item`, props.className)}\n        title={props.title || field.title}\n        onChange={() => {}}\n      >\n        <Empty />\n      </Card>\n    )\n  }\n\n  return (\n    <ArrayBase\n      onAdd={onAdd}\n      onCopy={onCopy}\n      onRemove={onRemove}\n      onMoveUp={onMoveUp}\n      onMoveDown={onMoveDown}\n    >\n      {renderEmpty()}\n      {renderItems()}\n      {renderAddition()}\n    </ArrayBase>\n  )\n})\n\nArrayCards.displayName = 'ArrayCards'\n\nArrayBase.mixin(ArrayCards)\n\nexport default ArrayCards\n"
  },
  {
    "path": "packages/next/src/array-cards/main.scss",
    "content": "@import '~@alifd/next/lib/core/index-noreset.scss';\n\n$array-cards-prefix-cls: '#{$css-prefix}formily-array-cards';\n\n.#{$css-prefix}empty {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n\n  &-image {\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    transform: scale(0.8);\n\n    .ant-empty-img-default-ellipse {\n      fill-opacity: 0.8;\n      fill: #f5f5f5;\n    }\n\n    .ant-empty-img-default-path-1 {\n      fill: #aeb8c2;\n    }\n\n    .ant-empty-img-default-path-2 {\n      fill: url(#linearGradient-1);\n    }\n\n    .ant-empty-img-default-path-3 {\n      fill: #f5f5f7;\n    }\n\n    .ant-empty-img-default-path-4,\n    .ant-empty-img-default-path-5 {\n      fill: #dce0e6;\n    }\n\n    .ant-empty-img-default-g {\n      fill: #fff;\n    }\n\n    .ant-empty-img-simple-ellipse {\n      fill: #f5f5f5;\n    }\n\n    .ant-empty-img-simple-g {\n      stroke: #d9d9d9;\n    }\n\n    .ant-empty-img-simple-path {\n      fill: #fafafa;\n    }\n\n    .ant-empty-rtl {\n      direction: rtl;\n    }\n  }\n}\n\n.#{$array-cards-prefix-cls}-remove {\n  transition: all 0.25s ease-in-out;\n  color: $color-text1-3;\n  font-size: 16px;\n  margin-left: 6px;\n\n  &:hover {\n    color: $color-text1-1;\n  }\n}\n\n.#{$array-cards-prefix-cls}-addition {\n  transition: all 0.25s ease-in-out;\n}\n\n.#{$array-cards-prefix-cls}-move-down {\n  transition: all 0.25s ease-in-out;\n  color: $color-text1-3;\n  font-size: 16px;\n  margin-left: 6px;\n\n  &:hover {\n    color: $color-text1-1;\n  }\n}\n\n.#{$array-cards-prefix-cls}-move-up {\n  transition: all 0.25s ease-in-out;\n  color: $color-text1-3;\n  font-size: 16px;\n  margin-left: 6px;\n\n  &:hover {\n    color: $color-text1-1;\n  }\n}\n\n.#{$array-cards-prefix-cls}-item {\n  margin-bottom: 10px !important;\n}\n\n.next-card-extra {\n  svg {\n    margin-right: 6px;\n    &:last-of-type {\n      margin-right: 0;\n    }\n  }\n}\n"
  },
  {
    "path": "packages/next/src/array-cards/style.ts",
    "content": "import '@alifd/next/lib/button/style'\nimport '@alifd/next/lib/card/style'\nimport './main.scss'\n"
  },
  {
    "path": "packages/next/src/array-collapse/index.tsx",
    "content": "import React, { Fragment, useState, useEffect } from 'react'\nimport { Badge, Card, Collapse } from '@alifd/next'\nimport { ArrayField } from '@formily/core'\nimport {\n  RecursionField,\n  useField,\n  useFieldSchema,\n  observer,\n  ISchema,\n} from '@formily/react'\nimport { toArr } from '@formily/shared'\nimport cls from 'classnames'\nimport ArrayBase, { ArrayBaseMixins, IArrayBaseProps } from '../array-base'\nimport { usePrefixCls, Empty } from '../__builtins__'\nimport { CollapseProps, PanelProps } from '@alifd/next/lib/collapse'\n\nexport interface IArrayCollapseProps extends CollapseProps {\n  defaultOpenPanelCount?: number\n}\ntype ComposedArrayCollapse = React.FC<\n  React.PropsWithChildren<IArrayCollapseProps & IArrayBaseProps>\n> &\n  ArrayBaseMixins & {\n    CollapsePanel?: React.FC<React.PropsWithChildren<PanelProps>>\n  }\n\nconst isAdditionComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Addition') > -1\n}\n\nconst isIndexComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Index') > -1\n}\n\nconst isRemoveComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('Remove') > -1\n}\n\nconst isMoveUpComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('MoveUp') > -1\n}\n\nconst isMoveDownComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf?.('MoveDown') > -1\n}\n\nconst isOperationComponent = (schema: ISchema) => {\n  return (\n    isAdditionComponent(schema) ||\n    isRemoveComponent(schema) ||\n    isMoveDownComponent(schema) ||\n    isMoveUpComponent(schema)\n  )\n}\n\nconst range = (count: number) => Array.from({ length: count }).map((_, i) => i)\n\nconst takeDefaultExpandedKeys = (\n  dataSourceLength: number,\n  defaultOpenPanelCount: number\n) => {\n  if (dataSourceLength < defaultOpenPanelCount) return range(dataSourceLength)\n  return range(defaultOpenPanelCount)\n}\n\nconst insertExpandedKeys = (expandedKeys: number[], index: number) => {\n  if (expandedKeys.length <= index) return expandedKeys.concat(index)\n  return expandedKeys.reduce((buf, key) => {\n    if (key < index) return buf.concat(key)\n    if (key === index) return buf.concat([key, key + 1])\n    return buf.concat(key + 1)\n  }, [])\n}\n\nexport const ArrayCollapse: ComposedArrayCollapse = observer(\n  ({ defaultOpenPanelCount = 5, ...props }) => {\n    const field = useField<ArrayField>()\n    const dataSource = Array.isArray(field.value) ? field.value : []\n\n    const [expandKeys, setExpandKeys] = useState<number[]>(\n      takeDefaultExpandedKeys(dataSource.length, defaultOpenPanelCount)\n    )\n    const schema = useFieldSchema()\n    const prefixCls = usePrefixCls('formily-array-collapse', props)\n    useEffect(() => {\n      if (!field.modified && dataSource.length) {\n        setExpandKeys(\n          takeDefaultExpandedKeys(dataSource.length, defaultOpenPanelCount)\n        )\n      }\n    }, [dataSource.length, field])\n    if (!schema) throw new Error('can not found schema object')\n    const { onAdd, onCopy, onRemove, onMoveDown, onMoveUp } = props\n\n    const renderAddition = () => {\n      return schema.reduceProperties((addition, schema, key) => {\n        if (isAdditionComponent(schema)) {\n          return <RecursionField schema={schema} name={key} />\n        }\n        return addition\n      }, null)\n    }\n    const renderEmpty = () => {\n      if (dataSource.length) return\n      return (\n        <Card className={cls(`${prefixCls}-item`, props.className)}>\n          <Empty />\n        </Card>\n      )\n    }\n\n    const renderItems = () => {\n      return (\n        <Collapse\n          {...props}\n          onChange={() => {}}\n          expandedKeys={expandKeys.map(String)}\n          onExpand={(keys: string[]) => setExpandKeys(toArr(keys).map(Number))}\n          className={cls(`${prefixCls}-item`, props.className)}\n        >\n          {dataSource.map((item, index) => {\n            const items = Array.isArray(schema.items)\n              ? schema.items[index] || schema.items[0]\n              : schema.items\n            const panelProps = field\n              .query(`${field.address}.${index}`)\n              .get('componentProps')\n            const props: PanelProps = items['x-component-props']\n            const title = () => {\n              const title = `${\n                panelProps?.title || props?.title || field.title\n              }`\n              const path = field.address.concat(index)\n              const errors = field.form.queryFeedbacks({\n                type: 'error',\n                address: `${path}.**`,\n              })\n              return (\n                <ArrayBase.Item index={index} record={item}>\n                  <div\n                    className={cls(`${prefixCls}-item-title`, props.className)}\n                  >\n                    <div>\n                      <RecursionField\n                        schema={items}\n                        name={index}\n                        filterProperties={(schema) => {\n                          if (!isIndexComponent(schema)) return false\n                          return true\n                        }}\n                        onlyRenderProperties\n                      />\n                      {errors.length ? (\n                        <Badge className=\"errors-badge\" count={errors.length}>\n                          {title}\n                        </Badge>\n                      ) : (\n                        title\n                      )}\n                    </div>\n                    <div>\n                      <RecursionField\n                        schema={items}\n                        name={index}\n                        filterProperties={(schema) => {\n                          if (!isOperationComponent(schema)) return false\n                          return true\n                        }}\n                        onlyRenderProperties\n                      />\n                    </div>\n                  </div>\n                </ArrayBase.Item>\n              )\n            }\n\n            const content = (\n              <RecursionField\n                schema={items}\n                name={index}\n                filterProperties={(schema) => {\n                  if (isIndexComponent(schema)) return false\n                  if (isOperationComponent(schema)) return false\n                  return true\n                }}\n              />\n            )\n            return (\n              <Collapse.Panel\n                {...props}\n                {...panelProps}\n                onChange={() => {}}\n                key={index}\n                title={title()}\n              >\n                <ArrayBase.Item\n                  index={index}\n                  key={index}\n                  record={() => field.value?.[index]}\n                >\n                  {content}\n                </ArrayBase.Item>\n              </Collapse.Panel>\n            )\n          })}\n        </Collapse>\n      )\n    }\n    return (\n      <ArrayBase\n        onAdd={(index) => {\n          onAdd?.(index)\n          setExpandKeys(insertExpandedKeys(expandKeys, index))\n        }}\n        onCopy={onCopy}\n        onRemove={onRemove}\n        onMoveUp={onMoveUp}\n        onMoveDown={onMoveDown}\n      >\n        {renderEmpty()}\n        {renderItems()}\n        {renderAddition()}\n      </ArrayBase>\n    )\n  }\n)\n\nconst CollapsePanel: React.FC<React.PropsWithChildren<PanelProps>> = ({\n  children,\n}) => {\n  return <Fragment>{children}</Fragment>\n}\n\nCollapsePanel.displayName = 'CollapsePanel'\n\nArrayCollapse.displayName = 'ArrayCollapse'\nArrayCollapse.CollapsePanel = CollapsePanel\n\nArrayBase.mixin(ArrayCollapse)\n\nexport default ArrayCollapse\n"
  },
  {
    "path": "packages/next/src/array-collapse/main.scss",
    "content": "@import '~@alifd/next/lib/core/index-noreset.scss';\n\n$array-collapse-prefix-cls: '#{$css-prefix}formily-array-collapse';\n\n.#{$css-prefix}empty {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n\n  &-image {\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    transform: scale(0.8);\n\n    .ant-empty-img-default-ellipse {\n      fill-opacity: 0.8;\n      fill: #f5f5f5;\n    }\n\n    .ant-empty-img-default-path-1 {\n      fill: #aeb8c2;\n    }\n\n    .ant-empty-img-default-path-2 {\n      fill: url(#linearGradient-1);\n    }\n\n    .ant-empty-img-default-path-3 {\n      fill: #f5f5f7;\n    }\n\n    .ant-empty-img-default-path-4,\n    .ant-empty-img-default-path-5 {\n      fill: #dce0e6;\n    }\n\n    .ant-empty-img-default-g {\n      fill: #fff;\n    }\n\n    .ant-empty-img-simple-ellipse {\n      fill: #f5f5f5;\n    }\n\n    .ant-empty-img-simple-g {\n      stroke: #d9d9d9;\n    }\n\n    .ant-empty-img-simple-path {\n      fill: #fafafa;\n    }\n\n    .ant-empty-rtl {\n      direction: rtl;\n    }\n  }\n}\n\n.#{$array-collapse-prefix-cls}-remove {\n  transition: all 0.25s ease-in-out;\n  color: $color-text1-3;\n  font-size: 16px;\n  margin-left: 6px;\n\n  &:hover {\n    color: $color-text1-1;\n  }\n}\n\n.#{$array-collapse-prefix-cls}-addition {\n  transition: all 0.25s ease-in-out;\n}\n\n.#{$array-collapse-prefix-cls}-move-down {\n  transition: all 0.25s ease-in-out;\n  color: $color-text1-3;\n  font-size: 16px;\n  margin-left: 6px;\n\n  &:hover {\n    color: $color-text1-1;\n  }\n}\n\n.#{$array-collapse-prefix-cls}-move-up {\n  transition: all 0.25s ease-in-out;\n  color: $color-text1-3;\n  font-size: 16px;\n  margin-left: 6px;\n\n  &:hover {\n    color: $color-text1-1;\n  }\n}\n\n.#{$array-collapse-prefix-cls}-item {\n  margin-bottom: 10px !important;\n  .#{$array-collapse-prefix-cls}-item-title {\n    display: flex;\n    justify-content: space-between;\n  }\n}\n"
  },
  {
    "path": "packages/next/src/array-collapse/style.ts",
    "content": "import '@alifd/next/lib/collapse/style'\nimport '@alifd/next/lib/card/style'\nimport './main.scss'\n"
  },
  {
    "path": "packages/next/src/array-items/index.tsx",
    "content": "import React from 'react'\nimport { ArrayField } from '@formily/core'\nimport {\n  useField,\n  observer,\n  useFieldSchema,\n  RecursionField,\n} from '@formily/react'\nimport cls from 'classnames'\nimport {\n  SortableContainer,\n  SortableElement,\n  SortableContainerProps,\n  SortableElementProps,\n} from 'react-sortable-hoc'\nimport { ISchema } from '@formily/json-schema'\nimport { usePrefixCls } from '../__builtins__'\nimport { ArrayBase, ArrayBaseMixins, IArrayBaseProps } from '../array-base'\n\ntype ComposedArrayItems = React.FC<\n  React.PropsWithChildren<\n    React.HTMLAttributes<HTMLDivElement> & IArrayBaseProps\n  >\n> &\n  ArrayBaseMixins & {\n    Item?: React.FC<\n      React.HTMLAttributes<HTMLDivElement> & {\n        type?: 'card' | 'divide'\n      }\n    >\n  }\n\nconst SortableItem: React.FC<\n  React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>> &\n    SortableElementProps\n> = SortableElement(\n  (props: React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>) => {\n    const prefixCls = usePrefixCls('formily-array-items')\n    return (\n      <div {...props} className={cls(`${prefixCls}-item`, props.className)}>\n        {props.children}\n      </div>\n    )\n  }\n) as any\n\nconst SortableList: React.FC<\n  React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>> &\n    SortableContainerProps\n> = SortableContainer(\n  (props: React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>) => {\n    const prefixCls = usePrefixCls('formily-array-items')\n    return (\n      <div {...props} className={cls(`${prefixCls}-list`, props.className)}>\n        {props.children}\n      </div>\n    )\n  }\n) as any\n\nconst isAdditionComponent = (schema: ISchema) => {\n  return schema['x-component']?.indexOf('Addition') > -1\n}\n\nconst useAddition = () => {\n  const schema = useFieldSchema()\n  return schema.reduceProperties((addition, schema, key) => {\n    if (isAdditionComponent(schema)) {\n      return <RecursionField schema={schema} name={key} />\n    }\n    return addition\n  }, null)\n}\n\nexport const ArrayItems: ComposedArrayItems = observer((props) => {\n  const field = useField<ArrayField>()\n  const prefixCls = usePrefixCls('formily-array-items')\n  const schema = useFieldSchema()\n  const addition = useAddition()\n  const { onAdd, onCopy, onRemove, onMoveDown, onMoveUp } = props\n  const dataSource = Array.isArray(field.value) ? field.value : []\n  return (\n    <ArrayBase\n      onAdd={onAdd}\n      onCopy={onCopy}\n      onRemove={onRemove}\n      onMoveUp={onMoveUp}\n      onMoveDown={onMoveDown}\n    >\n      <div\n        {...props}\n        onChange={() => {}}\n        className={cls(prefixCls, props.className)}\n      >\n        <SortableList\n          useDragHandle\n          lockAxis=\"y\"\n          helperClass={`${prefixCls}-sort-helper`}\n          onSortEnd={({ oldIndex, newIndex }) => {\n            field.move(oldIndex, newIndex)\n          }}\n        >\n          {dataSource?.map((item, index) => {\n            const items = Array.isArray(schema.items)\n              ? schema.items[index] || schema.items[0]\n              : schema.items\n            return (\n              <ArrayBase.Item\n                key={index}\n                index={index}\n                record={() => field.value?.[index]}\n              >\n                <SortableItem key={`item-${index}`} index={index}>\n                  <div className={`${prefixCls}-item-inner`}>\n                    <RecursionField schema={items} name={index} />\n                  </div>\n                </SortableItem>\n              </ArrayBase.Item>\n            )\n          })}\n        </SortableList>\n        {addition}\n      </div>\n    </ArrayBase>\n  )\n})\n\nArrayItems.displayName = 'ArrayItems'\n\nArrayItems.Item = (props) => {\n  const prefixCls = usePrefixCls('formily-array-items')\n  return (\n    <div\n      {...props}\n      onChange={() => {}}\n      className={cls(`${prefixCls}-${props.type || 'card'}`, props.className)}\n    >\n      {props.children}\n    </div>\n  )\n}\n\nArrayBase.mixin(ArrayItems)\n\nexport default ArrayItems\n"
  },
  {
    "path": "packages/next/src/array-items/main.scss",
    "content": "@import '~@alifd/next/lib/core/index-noreset.scss';\n\n$array-items-prefix-cls: '#{$css-prefix}formily-array-items';\n\n.#{$array-items-prefix-cls} {\n  .#{$css-prefix}form-item {\n    margin-bottom: 0;\n  }\n}\n\n// fix https://github.com/alibaba/formily/issues/2891\n.#{$array-items-prefix-cls}-item {\n  z-index: 100000;\n}\n\n.#{$array-items-prefix-cls}-sort-handler {\n  cursor: move;\n  color: #888 !important;\n}\n\n.#{$array-items-prefix-cls}-item-inner {\n  margin-bottom: 10px;\n  visibility: visible;\n}\n\n.#{$array-items-prefix-cls}-card {\n  display: flex;\n  border: 1px solid #eee;\n  margin-bottom: 10px;\n  padding: 3px 6px;\n  background: #fff;\n  justify-content: space-between;\n  align-items: center;\n\n  transition: all 0.35s;\n\n  .#{$css-prefix}formily-item:not(.#{$css-prefix}formily-item-feedback-layout-popover) {\n    margin-bottom: 0 !important;\n    position: relative;\n\n    .#{$css-prefix}formily-item-help {\n      position: absolute;\n      font-size: 12px;\n      top: 100%;\n      background: #fff;\n      width: 100%;\n      margin-top: 3px;\n      padding: 3px;\n      z-index: 1;\n      border-radius: 3px;\n      box-shadow: 0 0 10px #eee;\n    }\n  }\n}\n\n.#{$array-items-prefix-cls}-divide {\n  display: flex;\n  border-bottom: 1px solid #eee;\n  margin-bottom: 10px;\n  padding: 10px 0;\n  background: #fff;\n  justify-content: space-between;\n  align-items: center;\n\n  .#{$css-prefix}formily-item:not(.#{$css-prefix}formily-item-feedback-layout-popover) {\n    margin-bottom: 0 !important;\n    position: relative;\n\n    .#{$css-prefix}formily-item-help {\n      position: absolute;\n      font-size: 12px;\n      top: 100%;\n      background: #fff;\n      width: 100%;\n      margin-top: 3px;\n      padding: 3px;\n      z-index: 1;\n      border-radius: 3px;\n      box-shadow: 0 0 10px #eee;\n    }\n  }\n}\n"
  },
  {
    "path": "packages/next/src/array-items/style.ts",
    "content": "import '@alifd/next/lib/button/style'\nimport './main.scss'\n"
  },
  {
    "path": "packages/next/src/array-table/index.tsx",
    "content": "import React, {\n  Fragment,\n  useState,\n  useRef,\n  useEffect,\n  createContext,\n  useContext,\n} from 'react'\nimport { Table, Pagination, Select, Badge } from '@alifd/next'\nimport { PaginationProps } from '@alifd/next/lib/pagination'\nimport { TableProps, ColumnProps } from '@alifd/next/lib/table'\nimport { SelectProps } from '@alifd/next/lib/select'\nimport cls from 'classnames'\nimport { GeneralField, FieldDisplayTypes, ArrayField } from '@formily/core'\nimport {\n  useField,\n  observer,\n  useFieldSchema,\n  RecursionField,\n  ReactFC,\n} from '@formily/react'\nimport { isArr, isBool, isFn } from '@formily/shared'\nimport { Schema } from '@formily/json-schema'\nimport { usePrefixCls } from '../__builtins__'\nimport { ArrayBase, ArrayBaseMixins, IArrayBaseProps } from '../array-base'\n\ninterface ObservableColumnSource {\n  field: GeneralField\n  columnProps: ColumnProps\n  schema: Schema\n  display: FieldDisplayTypes\n  name: string\n}\n\ninterface IArrayTablePaginationProps extends Omit<PaginationProps, 'children'> {\n  dataSource?: any[]\n  children?: (\n    dataSource: any[],\n    pagination: React.ReactNode\n  ) => React.ReactElement\n}\n\ninterface IStatusSelectProps extends SelectProps {\n  pageSize?: number\n}\n\nexport type ExtendTableProps = {\n  pagination?: PaginationProps\n} & IArrayBaseProps &\n  TableProps\n\ntype ComposedArrayTable = ReactFC<ExtendTableProps> &\n  ArrayBaseMixins & {\n    Column?: ReactFC<ColumnProps>\n  }\n\ninterface PaginationAction {\n  totalPage?: number\n  pageSize?: number\n  changePage?: (page: number) => void\n}\n\nconst isColumnComponent = (schema: Schema) => {\n  return schema['x-component']?.indexOf('Column') > -1\n}\n\nconst isOperationsComponent = (schema: Schema) => {\n  return schema['x-component']?.indexOf('Operations') > -1\n}\n\nconst isAdditionComponent = (schema: Schema) => {\n  return schema['x-component']?.indexOf('Addition') > -1\n}\n\nconst useArrayTableSources = () => {\n  const arrayField = useField()\n  const schema = useFieldSchema()\n  const parseSources = (schema: Schema): ObservableColumnSource[] => {\n    if (\n      isColumnComponent(schema) ||\n      isOperationsComponent(schema) ||\n      isAdditionComponent(schema)\n    ) {\n      if (!schema['x-component-props']?.['dataIndex'] && !schema['name'])\n        return []\n      const name = schema['x-component-props']?.['dataIndex'] || schema['name']\n      const field = arrayField.query(arrayField.address.concat(name)).take()\n      const columnProps =\n        field?.component?.[1] || schema['x-component-props'] || {}\n      const display = field?.display || schema['x-display'] || 'visible'\n      return [\n        {\n          name,\n          display,\n          field,\n          schema,\n          columnProps,\n        },\n      ]\n    } else if (schema.properties) {\n      return schema.reduceProperties((buf, schema) => {\n        return buf.concat(parseSources(schema))\n      }, [])\n    }\n  }\n\n  const parseArrayItems = (schema: Schema['items']) => {\n    if (!schema) return []\n    const sources: ObservableColumnSource[] = []\n    const items = isArr(schema) ? schema : [schema]\n    return items.reduce((columns, schema) => {\n      const item = parseSources(schema)\n      if (item) {\n        return columns.concat(item)\n      }\n      return columns\n    }, sources)\n  }\n\n  return parseArrayItems(schema.items)\n}\n\nconst useArrayTableColumns = (\n  dataSource: any[],\n  field: ArrayField,\n  sources: ObservableColumnSource[]\n): TableProps['columns'] => {\n  return sources.reduce((buf, { name, columnProps, schema, display }, key) => {\n    if (display !== 'visible') return buf\n    if (!isColumnComponent(schema)) return buf\n    return buf.concat({\n      ...columnProps,\n      key,\n      dataIndex: name,\n      cell: (value: any, _: number, record: any) => {\n        const index = dataSource?.indexOf(record)\n        const children = (\n          <ArrayBase.Item\n            key={index}\n            index={index}\n            record={() => field.value?.[index]}\n          >\n            <RecursionField schema={schema} name={index} onlyRenderProperties />\n          </ArrayBase.Item>\n        )\n        return children\n      },\n    })\n  }, [])\n}\n\nconst useAddition = () => {\n  const schema = useFieldSchema()\n  return schema.reduceProperties((addition, schema, key) => {\n    if (isAdditionComponent(schema)) {\n      return <RecursionField schema={schema} name={key} />\n    }\n    return addition\n  }, null)\n}\n\nconst schedulerRequest = {\n  request: null,\n}\n\nconst StatusSelect: ReactFC<IStatusSelectProps> = observer(\n  ({ pageSize, ...props }) => {\n    const field = useField<ArrayField>()\n    const prefixCls = usePrefixCls('formily-array-table')\n    const errors = field.errors\n    const parseIndex = (address: string) => {\n      return Number(\n        address\n          .slice(address.indexOf(field.address.toString()) + 1)\n          .match(/(\\d+)/)?.[1]\n      )\n    }\n    const options = props.dataSource?.map(({ label, value }) => {\n      const hasError = errors.some(({ address }) => {\n        const currentIndex = parseIndex(address)\n        const startIndex = (value - 1) * pageSize\n        const endIndex = value * pageSize\n        return currentIndex >= startIndex && currentIndex <= endIndex\n      })\n      return {\n        label: hasError ? <Badge dot>{label}</Badge> : label,\n        value,\n      }\n    })\n\n    return (\n      <Select\n        {...props}\n        value={props.value}\n        onChange={props.onChange}\n        dataSource={options}\n        useVirtual\n        className={cls(`${prefixCls}-status-select`, {\n          'has-error': errors?.length,\n        })}\n      />\n    )\n  },\n  {\n    scheduler: (update) => {\n      clearTimeout(schedulerRequest.request)\n      schedulerRequest.request = setTimeout(() => {\n        update()\n      }, 100)\n    },\n  }\n)\n\nconst PaginationContext = createContext<PaginationAction>({})\nconst usePagination = () => {\n  return useContext(PaginationContext)\n}\n\nconst ArrayTablePagination: ReactFC<IArrayTablePaginationProps> = ({\n  children,\n  dataSource,\n  ...props\n}) => {\n  const [current, setCurrent] = useState(1)\n  const prefixCls = usePrefixCls('formily-array-table')\n  const pageSize = props.pageSize || 10\n  const size = props.size || 'medium'\n  const sources = dataSource || []\n  const startIndex = (current - 1) * pageSize\n  const endIndex = startIndex + pageSize - 1\n  const total = sources?.length || 0\n  const totalPage = Math.ceil(total / pageSize)\n  const pages = Array.from(new Array(totalPage)).map((_, index) => {\n    const page = index + 1\n    return {\n      label: page,\n      value: page,\n    }\n  })\n  const handleChange = (current: number) => {\n    setCurrent(current)\n  }\n\n  useEffect(() => {\n    if (totalPage > 0 && totalPage < current) {\n      handleChange(totalPage)\n    }\n  }, [totalPage, current])\n\n  const renderPagination = () => {\n    if (totalPage <= 1) return\n    return (\n      <div className={`${prefixCls}-pagination`}>\n        <StatusSelect\n          value={current}\n          pageSize={pageSize}\n          onChange={handleChange}\n          dataSource={pages}\n          notFoundContent={false}\n        />\n        <Pagination\n          {...props}\n          pageSize={pageSize}\n          current={current}\n          total={dataSource.length}\n          size={size}\n          pageSizeSelector={false}\n          onChange={handleChange}\n        />\n      </div>\n    )\n  }\n\n  return (\n    <Fragment>\n      <PaginationContext.Provider\n        value={{ totalPage, pageSize, changePage: handleChange }}\n      >\n        {children?.(\n          dataSource?.slice(startIndex, endIndex + 1),\n          renderPagination()\n        )}\n      </PaginationContext.Provider>\n    </Fragment>\n  )\n}\n\nconst omit = (props: any, keys?: string[]) => {\n  return Object.keys(props)\n    .filter((key) => !keys?.includes(key))\n    .reduce((buf, key) => {\n      buf[key] = props[key]\n      return buf\n    }, {})\n}\n\nexport const ArrayTable: ComposedArrayTable = observer(\n  (props: ExtendTableProps) => {\n    const ref = useRef<HTMLDivElement>()\n    const field = useField<ArrayField>()\n    const prefixCls = usePrefixCls('formily-array-table')\n    const dataSource = Array.isArray(field.value) ? field.value.slice() : []\n    const sources = useArrayTableSources()\n    const columns = useArrayTableColumns(dataSource, field, sources)\n    const pagination = isBool(props.pagination) ? {} : props.pagination\n    const { onAdd, onCopy, onRemove, onMoveDown, onMoveUp } = props\n    const addition = useAddition()\n\n    return (\n      <ArrayTablePagination {...pagination} dataSource={dataSource}>\n        {(dataSource, pager) => (\n          <div ref={ref} className={prefixCls}>\n            <ArrayBase\n              onAdd={onAdd}\n              onCopy={onCopy}\n              onRemove={onRemove}\n              onMoveUp={onMoveUp}\n              onMoveDown={onMoveDown}\n            >\n              <Table\n                size=\"small\"\n                {...omit(props, ['value', 'onChange', 'pagination'])}\n                columns={columns}\n                dataSource={dataSource}\n              />\n              <div style={{ marginTop: 5, marginBottom: 5 }}>{pager}</div>\n              {sources.map((column, key) => {\n                //专门用来承接对Column的状态管理\n                if (!isColumnComponent(column.schema)) return\n                return React.createElement(RecursionField, {\n                  name: column.name,\n                  schema: column.schema,\n                  onlyRenderSelf: true,\n                  key,\n                })\n              })}\n              {addition}\n            </ArrayBase>\n          </div>\n        )}\n      </ArrayTablePagination>\n    )\n  }\n)\n\nArrayTable.displayName = 'ArrayTable'\n\nArrayTable.Column = () => {\n  return <Fragment />\n}\n\nArrayBase.mixin(ArrayTable)\n\nconst Addition: ArrayBaseMixins['Addition'] = (props) => {\n  const array = ArrayBase.useArray()\n  const { totalPage = 0, pageSize = 10, changePage } = usePagination()\n  return (\n    <ArrayBase.Addition\n      {...props}\n      onClick={(e) => {\n        // 如果添加数据后将超过当前页，则自动切换到下一页\n        const total = array?.field?.value.length || 0\n        if (total === totalPage * pageSize + 1 && isFn(changePage)) {\n          changePage(totalPage + 1)\n        }\n        props.onClick?.(e)\n      }}\n    />\n  )\n}\nArrayTable.Addition = Addition\n\nexport default ArrayTable\n"
  },
  {
    "path": "packages/next/src/array-table/main.scss",
    "content": "@import '~@alifd/next/lib/core/index-noreset.scss';\n@import '~@alifd/next/lib/form/scss/variable.scss';\n\n$array-table-prefix-cls: '#{$css-prefix}formily-array-table';\n\n.#{$array-table-prefix-cls} {\n  .#{$array-table-prefix-cls}-pagination {\n    display: flex;\n    justify-content: center;\n    margin: 10px 0;\n\n    .#{$array-table-prefix-cls}-status-select {\n      min-width: 60px;\n      margin-right: 6px;\n      width: auto !important;\n\n      .#{$css-prefix}input {\n        min-width: 60px;\n      }\n\n      &.has-error {\n        .#{$css-prefix}input {\n          border-color: red !important;\n        }\n      }\n    }\n  }\n\n  .#{$css-prefix}table {\n    .#{$css-prefix}table-cell-wrapper {\n      overflow: visible;\n      word-break: normal;\n    }\n\n    td {\n      visibility: visible;\n\n      .#{$css-prefix}formily-item:not(.#{$css-prefix}formily-item-feedback-layout-popover) {\n        margin-bottom: 0 !important;\n        position: relative;\n\n        .#{$css-prefix}formily-item-help {\n          &.#{$css-prefix}formily-item-error-help {\n            color: $form-error-color;\n          }\n\n          &.#{$css-prefix}formily-item-warning-help {\n            color: $form-warning-color;\n          }\n\n          & {\n            min-width: 30px;\n            position: absolute;\n            font-size: 12px;\n            top: 100%;\n            width: 100%;\n            z-index: 1;\n            border-radius: 3px;\n            background-color: #fff;\n            border: 1px solid #eee;\n            padding: 6px 8px;\n            margin-top: 6px;\n            transform: translateY(0);\n            opacity: 1;\n          }\n          &:after {\n            content: ' ';\n            background-color: #fff;\n            position: absolute;\n            display: block;\n            width: 5px;\n            height: 5px;\n            pointer-events: none;\n            -webkit-transform: rotate(45deg);\n            top: -4px;\n            transform: rotate(45deg);\n            box-sizing: content-box !important;\n            border-left: 1px solid #eee;\n            border-top: 1px solid #eee;\n            z-index: -1;\n          }\n        }\n      }\n    }\n  }\n\n  .#{$array-table-prefix-cls}-sort-helper {\n    background: #fff;\n    border: 1px solid #eee;\n    z-index: 10;\n  }\n}\n"
  },
  {
    "path": "packages/next/src/array-table/style.ts",
    "content": "import '@alifd/next/lib/button/style'\nimport '@alifd/next/lib/badge/style'\nimport '@alifd/next/lib/pagination/style'\nimport '@alifd/next/lib/select/style'\nimport '@alifd/next/lib/table/style'\nimport './main.scss'\n"
  },
  {
    "path": "packages/next/src/cascader/index.tsx",
    "content": "import { connect, mapReadPretty, mapProps } from '@formily/react'\nimport { CascaderSelect } from '@alifd/next'\nimport { PreviewText } from '../preview-text'\nimport { mapSize, mapStatus } from '../__builtins__'\nexport const Cascader = connect(\n  CascaderSelect,\n  mapProps(\n    {\n      dataSource: true,\n    },\n    mapSize,\n    mapStatus\n  ),\n  mapReadPretty(PreviewText.Cascader)\n)\n\nexport default Cascader\n"
  },
  {
    "path": "packages/next/src/cascader/style.ts",
    "content": "import '@alifd/next/lib/cascader/style'\n"
  },
  {
    "path": "packages/next/src/checkbox/index.tsx",
    "content": "import { connect, mapProps, mapReadPretty } from '@formily/react'\nimport { Checkbox as NextCheckbox } from '@alifd/next'\nimport {\n  CheckboxProps,\n  GroupProps as CheckboxGroupProps,\n} from '@alifd/next/lib/checkbox'\nimport { PreviewText } from '../preview-text'\nimport { mapSize } from '../__builtins__'\n\ntype ComposedCheckbox = React.FC<React.PropsWithChildren<CheckboxProps>> & {\n  Group?: React.FC<React.PropsWithChildren<CheckboxGroupProps>>\n}\n\nexport const Checkbox: ComposedCheckbox = connect(\n  NextCheckbox,\n  mapProps(\n    {\n      value: 'checked',\n    },\n    mapSize\n  )\n)\n\nCheckbox.Group = connect(\n  NextCheckbox.Group,\n  mapProps(\n    {\n      dataSource: true,\n    },\n    mapSize\n  ),\n  mapReadPretty(PreviewText.Select, {\n    mode: 'multiple',\n  })\n)\n\nexport default Checkbox\n"
  },
  {
    "path": "packages/next/src/checkbox/style.ts",
    "content": "import '@alifd/next/lib/checkbox/style'\n"
  },
  {
    "path": "packages/next/src/date-picker/index.tsx",
    "content": "import moment from 'moment'\nimport { connect, mapProps, mapReadPretty } from '@formily/react'\nimport { DatePicker as NextDatePicker } from '@alifd/next'\nimport {\n  DatePickerProps as NextDatePickerProps,\n  MonthPickerProps,\n  YearPickerProps,\n  RangePickerProps,\n} from '@alifd/next/lib/date-picker'\nimport { PreviewText } from '../preview-text'\nimport {\n  formatMomentValue,\n  momentable,\n  mapSize,\n  mapStatus,\n} from '../__builtins__'\n\ntype DatePickerProps<PickerProps> = Exclude<\n  PickerProps,\n  'value' | 'onChange'\n> & {\n  value: string\n  onChange: (value: string | string[]) => void\n}\n\ntype ComposedDatePicker = React.FC<\n  React.PropsWithChildren<NextDatePickerProps>\n> & {\n  RangePicker?: React.FC<React.PropsWithChildren<RangePickerProps>>\n  MonthPicker?: React.FC<React.PropsWithChildren<MonthPickerProps>>\n  YearPicker?: React.FC<React.PropsWithChildren<YearPickerProps>>\n  WeekPicker?: React.FC<React.PropsWithChildren<NextDatePickerProps>>\n}\n\nconst mapDateFormat = function (type?: 'month' | 'year' | 'week') {\n  const getDefaultFormat = (props: DatePickerProps<NextDatePickerProps>) => {\n    const _type = props['type'] || type\n    if (_type === 'month') {\n      return 'YYYY-MM'\n    } else if (_type === 'year') {\n      return 'YYYY'\n    } else if (_type === 'week') {\n      return 'YYYY-wo'\n    }\n    return 'YYYY-MM-DD'\n  }\n\n  return (props: any) => {\n    const dateFormat = props['format'] || getDefaultFormat(props)\n\n    let valueFormat = dateFormat\n    if (props.showTime) {\n      const timeFormat = props.showTime.format || 'HH:mm:ss'\n      valueFormat = `${valueFormat} ${timeFormat}`\n    }\n\n    const onChange = props.onChange\n    return {\n      ...props,\n      format: dateFormat,\n      value: momentable(\n        props.value,\n        valueFormat === 'YYYY-wo' ? 'YYYY-w' : valueFormat\n      ),\n      onChange: (value: moment.Moment | moment.Moment[]) => {\n        if (onChange) {\n          onChange(formatMomentValue(value, valueFormat))\n        }\n      },\n    }\n  }\n}\n\nexport const DatePicker: ComposedDatePicker = connect(\n  NextDatePicker,\n  mapProps(mapDateFormat(), mapSize, mapStatus),\n  mapReadPretty(PreviewText.DatePicker)\n)\n\nDatePicker.RangePicker = connect(\n  NextDatePicker.RangePicker,\n  mapProps(mapDateFormat(), mapSize, mapStatus),\n  mapReadPretty(PreviewText.DateRangePicker)\n)\n\nDatePicker.YearPicker = connect(\n  NextDatePicker.YearPicker,\n  mapProps(mapDateFormat('year'), mapSize, mapStatus),\n  mapReadPretty(PreviewText.DatePicker)\n)\n\nDatePicker.MonthPicker = connect(\n  NextDatePicker.MonthPicker,\n  mapProps(mapDateFormat('month'), mapSize, mapStatus),\n  mapReadPretty(PreviewText.DatePicker)\n)\n\nDatePicker.WeekPicker = connect(\n  NextDatePicker.WeekPicker,\n  mapProps(mapDateFormat('week'), mapSize, mapStatus),\n  mapReadPretty(PreviewText.DatePicker)\n)\n\nexport default DatePicker\n"
  },
  {
    "path": "packages/next/src/date-picker/style.ts",
    "content": "import '@alifd/next/lib/date-picker/style'\n"
  },
  {
    "path": "packages/next/src/date-picker2/index.tsx",
    "content": "import moment from 'moment'\nimport { connect, mapProps, mapReadPretty } from '@formily/react'\nimport { DatePicker2 as NextDatePicker } from '@alifd/next'\nimport {\n  DatePickerProps as NextDatePickerProps,\n  RangePickerProps,\n} from '@alifd/next/lib/date-picker2'\nimport { PreviewText } from '../preview-text'\nimport {\n  formatMomentValue,\n  momentable,\n  mapSize,\n  mapStatus,\n} from '../__builtins__'\n\ntype DatePickerProps<PickerProps> = Exclude<\n  PickerProps,\n  'value' | 'onChange'\n> & {\n  value: string\n  onChange: (value: string | string[]) => void\n}\n\ntype ComposedDatePicker = React.FC<\n  React.PropsWithChildren<NextDatePickerProps>\n> & {\n  RangePicker?: React.FC<React.PropsWithChildren<RangePickerProps>>\n  MonthPicker?: React.FC<React.PropsWithChildren<NextDatePickerProps>>\n  YearPicker?: React.FC<React.PropsWithChildren<NextDatePickerProps>>\n  WeekPicker?: React.FC<React.PropsWithChildren<NextDatePickerProps>>\n  QuarterPicker?: React.FC<React.PropsWithChildren<NextDatePickerProps>>\n}\n\nconst mapDateFormat = function (type?: 'month' | 'year' | 'week' | 'quarter') {\n  const getDefaultFormat = (props: DatePickerProps<NextDatePickerProps>) => {\n    const _type = props['type'] || type\n    if (_type === 'month') {\n      return 'YYYY-MM'\n    } else if (_type === 'quarter') {\n      return 'YYYY-\\\\QQ'\n    } else if (_type === 'year') {\n      return 'YYYY'\n    } else if (_type === 'week') {\n      return 'YYYY-wo'\n    }\n    return props['showTime'] ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'\n  }\n\n  return (props: any) => {\n    const format = props['format'] || getDefaultFormat(props)\n    const onChange = props.onChange\n    return {\n      ...props,\n      format,\n      value: momentable(props.value, format === 'YYYY-wo' ? 'YYYY-w' : format),\n      onChange: (value: moment.Moment | moment.Moment[]) => {\n        if (onChange) {\n          onChange(formatMomentValue(value, format))\n        }\n      },\n    }\n  }\n}\n\nexport const DatePicker2: ComposedDatePicker = connect(\n  NextDatePicker,\n  mapProps(mapDateFormat(), mapSize, mapStatus),\n  mapReadPretty(PreviewText.DatePicker)\n)\n\nDatePicker2.RangePicker = connect(\n  NextDatePicker.RangePicker,\n  mapProps(mapDateFormat(), mapSize, mapStatus),\n  mapReadPretty(PreviewText.DateRangePicker)\n)\n\nDatePicker2.YearPicker = connect(\n  NextDatePicker.YearPicker,\n  mapProps(mapDateFormat('year'), mapSize, mapStatus),\n  mapReadPretty(PreviewText.DatePicker)\n)\n\nDatePicker2.MonthPicker = connect(\n  NextDatePicker.MonthPicker,\n  mapProps(mapDateFormat('month'), mapSize, mapStatus),\n  mapReadPretty(PreviewText.DatePicker)\n)\n\nDatePicker2.WeekPicker = connect(\n  NextDatePicker.WeekPicker,\n  mapProps(mapDateFormat('week'), mapSize, mapStatus),\n  mapReadPretty(PreviewText.DatePicker)\n)\n\nDatePicker2.QuarterPicker = connect(\n  NextDatePicker.QuarterPicker,\n  mapProps(mapDateFormat('quarter'), mapSize, mapStatus),\n  mapReadPretty(PreviewText.DatePicker)\n)\n\nexport default DatePicker2\n"
  },
  {
    "path": "packages/next/src/date-picker2/main.scss",
    "content": "@import '~@alifd/next/lib/core/index-noreset.scss';\n\n.#{$css-prefix}date-picker2 {\n  & > * {\n    width: 100%;\n  }\n}\n"
  },
  {
    "path": "packages/next/src/date-picker2/style.ts",
    "content": "import '@alifd/next/lib/date-picker2/style'\nimport './main.scss'\n"
  },
  {
    "path": "packages/next/src/editable/index.tsx",
    "content": "import React, { useLayoutEffect, useRef, useState } from 'react'\nimport { isVoidField, Field } from '@formily/core'\nimport { useField, observer } from '@formily/react'\nimport { Balloon } from '@alifd/next'\nimport { BalloonProps as PopoverProps } from '@alifd/next/lib/balloon'\nimport { BaseItem, IFormItemProps } from '../form-item'\nimport {\n  useClickAway,\n  usePrefixCls,\n  EditOutlinedIcon,\n  CloseOutlinedIcon,\n  MessageOutlinedIcon,\n} from '../__builtins__'\n/**\n * 默认Inline展示\n */\n\ntype IPopoverProps = PopoverProps\n\ntype ComposedEditable = React.FC<React.PropsWithChildren<IFormItemProps>> & {\n  Popover?: React.FC<\n    React.PropsWithChildren<IPopoverProps & { title?: React.ReactNode }>\n  >\n}\n\nconst useParentPattern = () => {\n  const field = useField<Field>()\n  return field?.parent?.pattern || field?.form?.pattern\n}\n\nconst useEditable = (): [boolean, (payload: boolean) => void] => {\n  const pattern = useParentPattern()\n  const field = useField<Field>()\n  useLayoutEffect(() => {\n    if (pattern === 'editable') {\n      field.setPattern('readPretty')\n    }\n  }, [pattern])\n  return [\n    field.pattern === 'editable',\n    (pyaload: boolean) => {\n      if (pattern !== 'editable') return\n      field.setPattern(pyaload ? 'editable' : 'readPretty')\n    },\n  ]\n}\n\nconst useFormItemProps = (): IFormItemProps => {\n  const field = useField()\n  if (isVoidField(field)) return {}\n  if (!field) return {}\n  const takeMessage = () => {\n    if (field.selfErrors.length) return field.selfErrors\n    if (field.selfWarnings.length) return field.selfWarnings\n    if (field.selfSuccesses.length) return field.selfSuccesses\n  }\n\n  return {\n    feedbackStatus:\n      field.validateStatus === 'validating' ? 'pending' : field.validateStatus,\n    feedbackText: takeMessage(),\n    extra: field.description,\n  }\n}\n\nexport const Editable: ComposedEditable = observer((props) => {\n  const [editable, setEditable] = useEditable()\n  const pattern = useParentPattern()\n  const itemProps = useFormItemProps()\n  const field = useField<Field>()\n  const basePrefixCls = usePrefixCls()\n  const prefixCls = usePrefixCls('formily-editable')\n  const ref = useRef<boolean>()\n  const innerRef = useRef<HTMLDivElement>()\n  const recover = () => {\n    if (ref.current && !field?.errors?.length) {\n      setEditable(false)\n    }\n  }\n  const renderEditHelper = () => {\n    if (editable) return\n    return (\n      <BaseItem {...props} {...itemProps}>\n        {pattern === 'editable' && (\n          <EditOutlinedIcon className={`${prefixCls}-edit-btn`} />\n        )}\n        {pattern !== 'editable' && (\n          <MessageOutlinedIcon className={`${prefixCls}-edit-btn`} />\n        )}\n      </BaseItem>\n    )\n  }\n\n  const renderCloseHelper = () => {\n    if (!editable) return\n    return (\n      <BaseItem {...props}>\n        <CloseOutlinedIcon className={`${prefixCls}-close-btn`} />\n      </BaseItem>\n    )\n  }\n\n  useClickAway((e) => {\n    const target = e.target as HTMLElement\n    if (target?.closest(`.${basePrefixCls}-overlay-wrapper`)) return\n    recover()\n  }, innerRef)\n\n  const onClick = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {\n    const target = e.target as HTMLElement\n    const close = innerRef.current.querySelector(`.${prefixCls}-close-btn`)\n    if (target?.contains(close) || close?.contains(target)) {\n      recover()\n    } else if (!ref.current) {\n      setTimeout(() => {\n        setEditable(true)\n        setTimeout(() => {\n          innerRef.current.querySelector('input')?.focus()\n        })\n      })\n    }\n  }\n\n  ref.current = editable\n\n  return (\n    <div className={prefixCls} ref={innerRef} onClick={onClick}>\n      <div className={`${prefixCls}-content`}>\n        <BaseItem {...props} {...itemProps}>\n          {props.children}\n        </BaseItem>\n        {renderEditHelper()}\n        {renderCloseHelper()}\n      </div>\n    </div>\n  )\n})\n\nEditable.Popover = observer((props) => {\n  const field = useField<Field>()\n  const pattern = useParentPattern()\n  const [visible, setVisible] = useState(false)\n  const prefixCls = usePrefixCls('formily-editable')\n  const closePopover = async () => {\n    try {\n      await field.form.validate(`${field.address}.*`)\n    } finally {\n      const errors = field.form.queryFeedbacks({\n        type: 'error',\n        address: `${field.address}.*`,\n      })\n      if (errors?.length) return\n      setVisible(false)\n    }\n  }\n  const openPopover = () => {\n    setVisible(true)\n  }\n  return (\n    <Balloon\n      {...props}\n      title={field.title}\n      visible={visible}\n      className={props.className}\n      onVisibleChange={(visible) => {\n        if (visible) {\n          openPopover()\n        } else {\n          closePopover()\n        }\n      }}\n      align=\"t\"\n      triggerType=\"click\"\n      closable={false}\n      trigger={\n        <div style={{ display: 'inline-flex' }}>\n          <BaseItem className={`${prefixCls}-trigger`}>\n            <div className={`${prefixCls}-content`}>\n              <span className={`${prefixCls}-preview`}>\n                {props.title || field.title}\n              </span>\n              {pattern === 'editable' && (\n                <EditOutlinedIcon className={`${prefixCls}-edit-btn`} />\n              )}\n              {pattern !== 'editable' && (\n                <MessageOutlinedIcon className={`${prefixCls}-edit-btn`} />\n              )}\n            </div>\n          </BaseItem>\n        </div>\n      }\n    >\n      {props.children}\n    </Balloon>\n  )\n})\n\nexport default Editable\n"
  },
  {
    "path": "packages/next/src/editable/main.scss",
    "content": "@import '~@alifd/next/lib/core/index-noreset.scss';\n\n$editable-prefix-cls: '#{$css-prefix}formily-editable';\n$editable-popover-prefix-cls: '#{$css-prefix}formily-editable-popover';\n\n.#{$editable-prefix-cls} {\n  cursor: pointer;\n  display: inline-flex;\n  align-items: center;\n\n  .#{$css-prefix}form-text {\n    .#{$css-prefix}tag {\n      transition: none !important;\n    }\n\n    .#{$css-prefix}tag:last-child {\n      margin-right: 0 !important;\n    }\n  }\n\n  &-content {\n    display: flex;\n    align-items: center;\n\n    > * {\n      margin-right: 3px;\n\n      &:last-child {\n        margin-right: 0;\n      }\n    }\n  }\n\n  .#{$editable-prefix-cls}-edit-btn,\n  .#{$editable-prefix-cls}-close-btn {\n    transition: all 0.25s ease-in-out;\n    color: #aaa;\n    font-size: 12px;\n\n    &:hover {\n      color: $color-text1-1;\n    }\n  }\n\n  .#{$css-prefix}form-text {\n    display: flex;\n    align-items: center;\n  }\n\n  .#{$editable-prefix-cls}-preview {\n    white-space: nowrap;\n    text-overflow: ellipsis;\n    overflow: hidden;\n    word-break: break-all;\n    max-width: 100px;\n    display: block;\n  }\n}\n\n.#{$editable-prefix-cls} {\n  &-trigger {\n    cursor: pointer;\n    display: inline-flex !important;\n    outline: none;\n  }\n\n  &-edit-btn {\n    color: #aaa;\n  }\n}\n"
  },
  {
    "path": "packages/next/src/editable/style.ts",
    "content": "import '@alifd/next/lib/form/style'\nimport '@alifd/next/lib/balloon/style'\nimport './main.scss'\n"
  },
  {
    "path": "packages/next/src/form/index.tsx",
    "content": "import React, { useMemo } from 'react'\nimport { FormProvider, JSXComponent, useParentForm } from '@formily/react'\nimport { FormLayout, IFormLayoutProps } from '../form-layout'\nimport { ConfigProvider } from '@alifd/next'\nimport {\n  getValidateLocaleIOSCode,\n  setValidateLanguage,\n  Form as FormType,\n  ObjectField,\n  IFormFeedback,\n} from '@formily/core'\nimport { PreviewText } from '../preview-text'\nexport interface FormProps extends IFormLayoutProps {\n  form?: FormType\n  component?: JSXComponent\n  onAutoSubmit?: (values: any) => any\n  onAutoSubmitFailed?: (feedbacks: IFormFeedback[]) => void\n  previewTextPlaceholder?: React.ReactNode\n}\n\nexport const Form: React.FC<React.PropsWithChildren<FormProps>> = ({\n  form,\n  component = 'form',\n  onAutoSubmit,\n  onAutoSubmitFailed,\n  previewTextPlaceholder,\n  ...props\n}) => {\n  const top = useParentForm()\n  const lang =\n    (ConfigProvider as any).getContext()?.locale?.momentLocale ?? 'zh-CN'\n  useMemo(() => {\n    const validateLanguage = getValidateLocaleIOSCode(lang)\n    setValidateLanguage(validateLanguage)\n  }, [lang])\n\n  const renderContent = (form: FormType | ObjectField) => (\n    <PreviewText.Placeholder value={previewTextPlaceholder}>\n      <FormLayout {...props}>\n        {React.createElement(\n          component,\n          {\n            onSubmit(e: React.FormEvent) {\n              e?.stopPropagation?.()\n              e?.preventDefault?.()\n              form.submit(onAutoSubmit).catch(onAutoSubmitFailed)\n            },\n          },\n          props.children\n        )}\n      </FormLayout>\n    </PreviewText.Placeholder>\n  )\n\n  if (form)\n    return <FormProvider form={form}>{renderContent(form)}</FormProvider>\n  if (!top) throw new Error('must pass form instance by createForm')\n  return renderContent(top)\n}\n\nexport default Form\n"
  },
  {
    "path": "packages/next/src/form/main.scss",
    "content": ""
  },
  {
    "path": "packages/next/src/form/style.ts",
    "content": "// @ts-ignore\n"
  },
  {
    "path": "packages/next/src/form-button-group/index.tsx",
    "content": "/**\n * 1. FormItem网格布局\n * 2. 居中，居右，居左布局\n * 3. 行内布局\n * 4. 吸底布局\n */\nimport React, { useRef, useLayoutEffect, useState } from 'react'\nimport StickyBox from 'react-sticky-box'\nimport { ReactFC } from '@formily/react'\nimport { Space, ISpaceProps } from '../space'\nimport { BaseItem, IFormItemProps } from '../form-item'\nimport { usePrefixCls } from '../__builtins__'\nimport cls from 'classnames'\ninterface IStickyProps extends React.ComponentProps<typeof StickyBox> {\n  align?: React.CSSProperties['textAlign']\n}\n\ntype IFormButtonGroupProps = Omit<ISpaceProps, 'align' | 'size'> & {\n  align?: React.CSSProperties['textAlign']\n  gutter?: number\n}\n\ntype ComposedButtonGroup = ReactFC<IFormButtonGroupProps> & {\n  Sticky: ReactFC<IStickyProps>\n  FormItem: ReactFC<\n    IFormItemProps & {\n      gutter?: number\n    }\n  >\n}\n\nfunction getInheritedBackgroundColor(el: HTMLElement) {\n  // get default style for current browser\n  let defaultStyle = getDefaultBackground() // typically \"rgba(0, 0, 0, 0)\"\n\n  // get computed color for el\n  let backgroundColor = window.getComputedStyle(el).backgroundColor\n\n  // if we got a real value, return it\n  if (backgroundColor != defaultStyle) return backgroundColor\n\n  // if we've reached the top parent el without getting an explicit color, return default\n  if (!el.parentElement) return defaultStyle\n\n  // otherwise, recurse and try again on parent element\n  return getInheritedBackgroundColor(el.parentElement)\n}\n\nfunction getDefaultBackground() {\n  // have to add to the document in order to use getComputedStyle\n  let div = document.createElement('div')\n  document.head.appendChild(div)\n  let bg = window.getComputedStyle(div).backgroundColor\n  document.head.removeChild(div)\n  return bg\n}\n\nexport const FormButtonGroup: ComposedButtonGroup = ({\n  align = 'left',\n  gutter,\n  ...props\n}) => {\n  const prefixCls = usePrefixCls('formily-button-group')\n  return (\n    <Space\n      {...props}\n      size={gutter}\n      className={cls(prefixCls, props.className)}\n      style={{\n        ...props.style,\n        justifyContent:\n          align === 'left'\n            ? 'flex-start'\n            : align === 'right'\n            ? 'flex-end'\n            : 'center',\n        display: 'flex',\n      }}\n    >\n      {props.children}\n    </Space>\n  )\n}\n\nFormButtonGroup.FormItem = ({ gutter, ...props }) => {\n  return (\n    <BaseItem\n      {...props}\n      label=\" \"\n      style={{\n        margin: 0,\n        padding: 0,\n        ...props.style,\n        width: '100%',\n      }}\n      colon={false}\n    >\n      {props.children?.['length'] ? (\n        <Space size={gutter}>{props.children}</Space>\n      ) : (\n        props.children\n      )}\n    </BaseItem>\n  )\n}\n\nFormButtonGroup.Sticky = ({ align = 'left', ...props }) => {\n  const ref = useRef()\n  const [color, setColor] = useState('transparent')\n  const prefixCls = usePrefixCls('formily-button-group')\n\n  useLayoutEffect(() => {\n    if (ref.current) {\n      const computed = getInheritedBackgroundColor(ref.current)\n      if (computed !== color) {\n        setColor(computed)\n      }\n    }\n  })\n  return (\n    <StickyBox\n      {...props}\n      className={cls(`${prefixCls}-sticky`, props.className)}\n      style={{\n        backgroundColor: color,\n        ...props.style,\n      }}\n      bottom\n    >\n      <div\n        ref={ref}\n        className={`${prefixCls}-sticky-inner`}\n        style={{\n          ...props.style,\n          justifyContent:\n            align === 'left'\n              ? 'flex-start'\n              : align === 'right'\n              ? 'flex-end'\n              : 'center',\n        }}\n      >\n        {props.children}\n      </div>\n    </StickyBox>\n  )\n}\n\nexport default FormButtonGroup\n"
  },
  {
    "path": "packages/next/src/form-button-group/main.scss",
    "content": "@import '~@alifd/next/lib/core/index-noreset.scss';\n\n$btn-group-prefix-cls: '#{$css-prefix}formily-button-group';\n\n.#{$btn-group-prefix-cls}-sticky {\n  padding: 10px 0;\n  border-top: 1px solid #eee;\n  z-index: 999;\n\n  &-inner {\n    display: flex;\n\n    .#{$css-prefix}formily-item {\n      flex: 2;\n    }\n  }\n}\n"
  },
  {
    "path": "packages/next/src/form-button-group/style.ts",
    "content": "import '@alifd/next/lib/form/style'\nimport './main.scss'\n"
  },
  {
    "path": "packages/next/src/form-collapse/index.tsx",
    "content": "import React, { Fragment, useMemo } from 'react'\nimport { Collapse, Badge } from '@alifd/next'\nimport { model, markRaw } from '@formily/reactive'\nimport {\n  CollapseProps,\n  PanelProps as CollapsePanelProps,\n} from '@alifd/next/lib/collapse'\nimport {\n  useField,\n  observer,\n  useFieldSchema,\n  RecursionField,\n} from '@formily/react'\nimport { Schema, SchemaKey } from '@formily/json-schema'\nimport { toArr } from '@formily/shared'\nimport cls from 'classnames'\nimport { usePrefixCls } from '../__builtins__'\n\ntype ActiveKeys = string | number | Array<string | number>\n\ntype ActiveKey = string | number\n\nexport interface IFormCollapse {\n  activeKeys: ActiveKeys\n  hasActiveKey(key: ActiveKey): boolean\n  setActiveKeys(key: ActiveKeys): void\n  addActiveKey(key: ActiveKey): void\n  removeActiveKey(key: ActiveKey): void\n  toggleActiveKey(key: ActiveKey): void\n}\n\nexport interface IFormCollapseProps extends CollapseProps {\n  formCollapse?: IFormCollapse\n}\n\ntype ComposedFormCollapse = React.FC<\n  React.PropsWithChildren<IFormCollapseProps>\n> & {\n  CollapsePanel?: React.FC<React.PropsWithChildren<CollapsePanelProps>>\n  createFormCollapse?: (\n    defaultActiveKeys?: CollapseProps['expandedKeys']\n  ) => IFormCollapse\n}\n\nconst usePanels = () => {\n  const collapseField = useField()\n  const schema = useFieldSchema()\n  const panels: { name: SchemaKey; props: any; schema: Schema }[] = []\n  schema.mapProperties((schema, name) => {\n    const field = collapseField.query(collapseField.address.concat(name)).take()\n    if (field?.display === 'none' || field?.display === 'hidden') return\n    if (schema['x-component']?.indexOf('CollapsePanel') > -1) {\n      panels.push({\n        name,\n        props: {\n          ...schema?.['x-component-props'],\n          title: schema?.['x-component-props']?.title || schema?.title,\n          key: schema?.['x-component-props']?.key || name,\n        },\n        schema,\n      })\n    }\n  })\n  return panels\n}\n\nconst createFormCollapse = (defaultActiveKeys?: ActiveKeys) => {\n  const formCollapse = model({\n    activeKeys: defaultActiveKeys,\n    setActiveKeys(keys: ActiveKeys) {\n      formCollapse.activeKeys = keys\n    },\n    hasActiveKey(key: ActiveKey) {\n      if (Array.isArray(formCollapse.activeKeys)) {\n        if (formCollapse.activeKeys.includes(key)) {\n          return true\n        }\n      } else if (formCollapse.activeKeys == key) {\n        return true\n      }\n      return false\n    },\n    addActiveKey(key: ActiveKey) {\n      if (formCollapse.hasActiveKey(key)) return\n      formCollapse.activeKeys = toArr(formCollapse.activeKeys).concat(key)\n    },\n    removeActiveKey(key: ActiveKey) {\n      if (Array.isArray(formCollapse.activeKeys)) {\n        formCollapse.activeKeys = formCollapse.activeKeys.filter(\n          (item) => item != key\n        )\n      } else {\n        formCollapse.activeKeys = []\n      }\n    },\n    toggleActiveKey(key: ActiveKey) {\n      if (formCollapse.hasActiveKey(key)) {\n        formCollapse.removeActiveKey(key)\n      } else {\n        formCollapse.addActiveKey(key)\n      }\n    },\n  })\n  return markRaw(formCollapse)\n}\n\nexport const FormCollapse: ComposedFormCollapse = observer(\n  ({ formCollapse, ...props }) => {\n    const field = useField()\n    const panels = usePanels()\n    const prefixCls = usePrefixCls('formily-collapse', props)\n    const _formCollapse = useMemo(() => {\n      return formCollapse\n        ? formCollapse\n        : createFormCollapse(props.defaultExpandedKeys)\n    }, [])\n\n    const takeExpandedKeys = () => {\n      if (props.expandedKeys) return props.expandedKeys\n      if (_formCollapse?.activeKeys) return _formCollapse?.activeKeys\n      if (props.accordion) return panels[0]?.name\n      return panels.map((item) => item.name)\n    }\n\n    const badgedHeader = (key: SchemaKey, props: any) => {\n      const errors = field.form.queryFeedbacks({\n        type: 'error',\n        address: `${field.address.concat(key)}.*`,\n      })\n      if (errors.length) {\n        return (\n          <Badge className=\"errors-badge\" count={errors.length}>\n            {props.title}\n          </Badge>\n        )\n      }\n      return props.title\n    }\n    return (\n      <Collapse\n        {...props}\n        className={cls(prefixCls, props.className)}\n        expandedKeys={takeExpandedKeys() as any}\n        onExpand={(keys) => {\n          props?.onExpand?.(keys)\n          _formCollapse?.setActiveKeys?.(keys)\n        }}\n      >\n        {panels.map(({ props, schema, name }, index) => (\n          <Collapse.Panel\n            key={index}\n            {...props}\n            title={badgedHeader(name, props)}\n          >\n            <RecursionField schema={schema} name={name} />\n          </Collapse.Panel>\n        ))}\n      </Collapse>\n    )\n  }\n)\n\nconst CollapsePanel: React.FC<React.PropsWithChildren<CollapsePanelProps>> = ({\n  children,\n}) => {\n  return <Fragment>{children}</Fragment>\n}\n\nFormCollapse.CollapsePanel = CollapsePanel\nFormCollapse.createFormCollapse = createFormCollapse\n\nexport default FormCollapse\n"
  },
  {
    "path": "packages/next/src/form-collapse/style.ts",
    "content": "import '@alifd/next/lib/collapse/style'\nimport '@alifd/next/lib/badge/style'\n"
  },
  {
    "path": "packages/next/src/form-dialog/index.tsx",
    "content": "import React, { Fragment, useRef, useLayoutEffect, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport { createForm, IFormProps, Form } from '@formily/core'\nimport { toJS } from '@formily/reactive'\nimport { FormProvider, Observer, observer, ReactFC } from '@formily/react'\nimport {\n  isNum,\n  isStr,\n  isBool,\n  isFn,\n  applyMiddleware,\n  IMiddleware,\n} from '@formily/shared'\nimport { Dialog, ConfigProvider, Button } from '@alifd/next'\nimport { DialogProps } from '@alifd/next/lib/dialog'\nimport {\n  usePrefixCls,\n  loading,\n  createPortalProvider,\n  createPortalRoot,\n} from '../__builtins__'\n\ntype FormDialogRenderer =\n  | React.ReactElement\n  | ((form: Form) => React.ReactElement)\n\ntype ModalTitle = string | number | React.ReactElement\n\nconst getContext: () => any = ConfigProvider['getContext']\n\nconst isModalTitle = (props: any): props is ModalTitle => {\n  return (\n    isNum(props) || isStr(props) || isBool(props) || React.isValidElement(props)\n  )\n}\n\nconst getModelProps = (props: any): IDialogProps => {\n  if (isModalTitle(props)) {\n    return {\n      title: props,\n    }\n  } else {\n    return props\n  }\n}\n\nexport interface IDialogProps extends DialogProps {\n  onOk?: (event: React.MouseEvent) => void | boolean\n  onCancel?: (event: React.MouseEvent) => void | boolean\n  loadingText?: React.ReactText\n}\n\nexport interface IFormDialog {\n  forOpen(middleware: IMiddleware<IFormProps>): IFormDialog\n  forConfirm(middleware: IMiddleware<Form>): IFormDialog\n  forCancel(middleware: IMiddleware<Form>): IFormDialog\n  open(props?: IFormProps): Promise<any>\n  close(): void\n}\n\nexport function FormDialog(\n  title: IDialogProps,\n  id: string,\n  renderer: FormDialogRenderer\n): IFormDialog\nexport function FormDialog(\n  title: IDialogProps,\n  renderer: FormDialogRenderer\n): IFormDialog\nexport function FormDialog(\n  title: ModalTitle,\n  id: string,\n  renderer: FormDialogRenderer\n): IFormDialog\nexport function FormDialog(\n  title: ModalTitle,\n  renderer: FormDialogRenderer\n): IFormDialog\nexport function FormDialog(title: any, id: any, renderer?: any): IFormDialog {\n  if (isFn(id) || React.isValidElement(id)) {\n    renderer = id\n    id = 'form-dialog'\n  }\n  const env = {\n    host: document.createElement('div'),\n    form: null,\n    promise: null,\n    openMiddlewares: [],\n    confirmMiddlewares: [],\n    cancelMiddlewares: [],\n  }\n  const root = createPortalRoot(env.host, id)\n  const props = getModelProps(title)\n  const modal = {\n    ...props,\n    style: {\n      width: '40%',\n      ...props.style,\n    },\n    afterClose: () => {\n      props?.afterClose?.()\n      root.unmount()\n    },\n  }\n  const DialogContent = observer(() => {\n    return <Fragment>{isFn(renderer) ? renderer(env.form) : renderer}</Fragment>\n  })\n  const renderDialog = (\n    visible = true,\n    resolve?: () => any,\n    reject?: () => any\n  ) => {\n    const ctx = getContext()\n    const prefix = modal.prefix || ctx.prefix || 'next'\n    const okProps = {\n      children: ctx?.locale?.Dialog?.ok || '确定',\n      ...(ctx?.defaultPropsConfig?.Dialog?.okProps || {}),\n      ...(modal.okProps || {}),\n    }\n    const cancelProps = {\n      children: ctx?.locale?.Dialog?.cancel || '取消',\n      ...(ctx?.defaultPropsConfig?.Dialog?.cancelProps || {}),\n      ...(modal.cancelProps || {}),\n    }\n    const buttonMap = {\n      ok: (\n        <Button\n          key=\"ok\"\n          type=\"primary\"\n          className={prefix + '-dialog-btn'}\n          loading={env.form.submitting}\n          onClick={(e) => {\n            if (modal?.onOk?.(e) !== false) {\n              resolve()\n            }\n          }}\n          {...okProps}\n        />\n      ),\n      cancel: (\n        <Button\n          key=\"cancel\"\n          className={prefix + '-dialog-btn'}\n          onClick={(e) => {\n            if (modal?.onCancel?.(e) !== false) {\n              reject()\n            }\n          }}\n          {...cancelProps}\n        />\n      ),\n    }\n    const footerActions = ctx?.defaultPropsConfig?.Dialog?.footerActions ||\n      modal.footerActions || ['cancel', 'ok']\n\n    return (\n      <ConfigProvider {...ctx}>\n        <Observer>\n          {() => (\n            <Dialog\n              {...modal}\n              visible={visible}\n              footer={\n                <Fragment>\n                  {footerActions.map((item) => buttonMap[item])}\n                </Fragment>\n              }\n              onClose={(trigger, e) => {\n                modal?.onClose?.(trigger, e)\n                reject()\n              }}\n            >\n              <FormProvider form={env.form}>\n                <DialogContent />\n              </FormProvider>\n            </Dialog>\n          )}\n        </Observer>\n      </ConfigProvider>\n    )\n  }\n  document.body.appendChild(env.host)\n  const formDialog = {\n    forOpen: (middleware: IMiddleware<IFormProps>) => {\n      if (isFn(middleware)) {\n        env.openMiddlewares.push(middleware)\n      }\n      return formDialog\n    },\n    forConfirm: (middleware: IMiddleware<Form>) => {\n      if (isFn(middleware)) {\n        env.confirmMiddlewares.push(middleware)\n      }\n      return formDialog\n    },\n    forCancel: (middleware: IMiddleware<Form>) => {\n      if (isFn(middleware)) {\n        env.cancelMiddlewares.push(middleware)\n      }\n      return formDialog\n    },\n    open: async (props: IFormProps) => {\n      if (env.promise) return env.promise\n      env.promise = new Promise(async (resolve, reject) => {\n        try {\n          props = await loading(modal.loadingText, () =>\n            applyMiddleware(props, env.openMiddlewares)\n          )\n          env.form = env.form || createForm(props)\n        } catch (e) {\n          reject(e)\n        }\n        root.render(() =>\n          renderDialog(\n            true,\n            () => {\n              env.form\n                .submit(async () => {\n                  await applyMiddleware(env.form, env.confirmMiddlewares)\n                  resolve(toJS(env.form.values))\n                  formDialog.close()\n                })\n                .catch(() => {})\n            },\n            async () => {\n              await loading(modal.loadingText, () =>\n                applyMiddleware(env.form, env.cancelMiddlewares)\n              )\n              formDialog.close()\n            }\n          )\n        )\n      })\n      return env.promise\n    },\n    close: () => {\n      if (!env.host) return\n      root.render(() => renderDialog(false))\n    },\n  }\n  return formDialog\n}\n\nconst DialogFooter: ReactFC = (props) => {\n  const ref = useRef<HTMLDivElement>()\n  const [footer, setFooter] = useState<HTMLDivElement>()\n  const footerRef = useRef<HTMLDivElement>()\n  const prefixCls = usePrefixCls('dialog')\n  useLayoutEffect(() => {\n    const content = ref.current?.closest(`.${prefixCls}`)\n    if (content) {\n      if (!footerRef.current) {\n        footerRef.current = content.querySelector(`.${prefixCls}-footer`)\n        if (!footerRef.current) {\n          footerRef.current = document.createElement('div')\n          footerRef.current.classList.add(`${prefixCls}-footer`)\n          content.appendChild(footerRef.current)\n        }\n      }\n      setFooter(footerRef.current)\n    }\n  })\n\n  footerRef.current = footer\n\n  return (\n    <div ref={ref} style={{ display: 'none' }}>\n      {footer && createPortal(props.children, footer)}\n    </div>\n  )\n}\n\nFormDialog.Footer = DialogFooter\n\nFormDialog.Portal = createPortalProvider('form-dialog')\n\nexport default FormDialog\n"
  },
  {
    "path": "packages/next/src/form-dialog/style.ts",
    "content": "import '@alifd/next/lib/dialog/style'\n"
  },
  {
    "path": "packages/next/src/form-drawer/index.tsx",
    "content": "import React, { Fragment, useLayoutEffect, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport {\n  createForm,\n  onFormSubmitSuccess,\n  IFormProps,\n  Form,\n} from '@formily/core'\nimport { toJS } from '@formily/reactive'\nimport { FormProvider, observer, Observer, ReactFC } from '@formily/react'\nimport {\n  isNum,\n  isStr,\n  isBool,\n  isFn,\n  applyMiddleware,\n  IMiddleware,\n} from '@formily/shared'\nimport { ConfigProvider, Drawer } from '@alifd/next'\nimport { DrawerProps } from '@alifd/next/lib/drawer'\nimport {\n  usePrefixCls,\n  loading,\n  createPortalProvider,\n  createPortalRoot,\n} from '../__builtins__'\n\ntype FormDrawerRenderer =\n  | React.ReactElement\n  | ((form: Form) => React.ReactElement)\n\ntype DrawerTitle = string | number | React.ReactElement\n\nconst getContext: () => any = ConfigProvider['getContext']\n\nconst isDrawerTitle = (props: any): props is DrawerTitle => {\n  return (\n    isNum(props) || isStr(props) || isBool(props) || React.isValidElement(props)\n  )\n}\n\nconst getDrawerProps = (props: any): IDrawerProps => {\n  if (isDrawerTitle(props)) {\n    return {\n      title: props,\n    }\n  } else {\n    return props\n  }\n}\n\nexport interface IDrawerProps extends DrawerProps {\n  onClose?: (reason: string, e: React.MouseEvent) => void | boolean\n  loadingText?: React.ReactNode\n}\n\nexport interface IFormDrawer {\n  forOpen(middleware: IMiddleware<IFormProps>): IFormDrawer\n  open(props?: IFormProps): Promise<any>\n  close(): void\n}\n\nexport function FormDrawer(\n  title: IDrawerProps,\n  id: string,\n  renderer: FormDrawerRenderer\n): IFormDrawer\nexport function FormDrawer(\n  title: IDrawerProps,\n  renderer: FormDrawerRenderer\n): IFormDrawer\nexport function FormDrawer(\n  title: DrawerTitle,\n  id: string,\n  renderer: FormDrawerRenderer\n): IFormDrawer\nexport function FormDrawer(\n  title: DrawerTitle,\n  renderer: FormDrawerRenderer\n): IFormDrawer\nexport function FormDrawer(title: any, id: any, renderer?: any): IFormDrawer {\n  if (isFn(id) || React.isValidElement(id)) {\n    renderer = id\n    id = 'form-drawer'\n  }\n  const env = {\n    host: document.createElement('div'),\n    form: null,\n    promise: null,\n    openMiddlewares: [],\n  }\n  const root = createPortalRoot(env.host, id)\n  const props = getDrawerProps(title)\n  const drawer = {\n    width: '40%',\n    ...props,\n    onClose: (reason: string, e: any) => {\n      if (props?.onClose?.(reason, e) !== false) {\n        formDrawer.close()\n      }\n    },\n    afterClose() {\n      props?.afterClose?.()\n      root.unmount()\n    },\n  }\n  const DrawerContent = observer(() => {\n    return <Fragment>{isFn(renderer) ? renderer(env.form) : renderer}</Fragment>\n  })\n  const renderDrawer = (visible = true) => {\n    return (\n      <ConfigProvider {...getContext()}>\n        <Observer>\n          {() => (\n            <Drawer {...drawer} visible={visible}>\n              <FormProvider form={env.form}>\n                <DrawerContent />\n              </FormProvider>\n            </Drawer>\n          )}\n        </Observer>\n      </ConfigProvider>\n    )\n  }\n  document.body.appendChild(env.host)\n  const formDrawer = {\n    forOpen: (middleware: IMiddleware<IFormProps>) => {\n      if (isFn(middleware)) {\n        env.openMiddlewares.push(middleware)\n      }\n      return formDrawer\n    },\n    open: (props: IFormProps) => {\n      if (env.promise) return env.promise\n      env.promise = new Promise(async (resolve, reject) => {\n        try {\n          props = await loading(drawer.loadingText, () =>\n            applyMiddleware(props, env.openMiddlewares)\n          )\n          env.form =\n            env.form ||\n            createForm({\n              ...props,\n              effects(form) {\n                onFormSubmitSuccess(() => {\n                  resolve(toJS(form.values))\n                  formDrawer.close()\n                })\n                props?.effects?.(form)\n              },\n            })\n        } catch (e) {\n          reject(e)\n        }\n        root.render(() => renderDrawer(false))\n        setTimeout(() => {\n          root.render(() => renderDrawer(true))\n        }, 16)\n      })\n      return env.promise\n    },\n    close: () => {\n      if (!env.host) return\n      root.render(() => renderDrawer(false))\n    },\n  }\n  return formDrawer\n}\n\nconst DrawerFooter: ReactFC = (props) => {\n  const ref = useRef<HTMLDivElement>()\n  const [footer, setFooter] = useState<HTMLDivElement>()\n  const footerRef = useRef<HTMLDivElement>()\n  const prefixCls = usePrefixCls('drawer')\n  useLayoutEffect(() => {\n    const content = ref.current?.closest(`.${prefixCls}`)\n    if (content) {\n      if (!footerRef.current) {\n        footerRef.current = content.querySelector(`.${prefixCls}-footer`)\n        const body = content.querySelector(`.${prefixCls}-body`)\n        if (!footerRef.current && body) {\n          footerRef.current = document.createElement('div')\n          footerRef.current.classList.add(`${prefixCls}-footer`)\n          footerRef.current.style.padding = '20px'\n          footerRef.current.style.borderTop = '1px solid #eee'\n          body.after(footerRef.current)\n        }\n      }\n      setFooter(footerRef.current)\n    }\n  })\n\n  footerRef.current = footer\n\n  return (\n    <div ref={ref} style={{ display: 'none' }}>\n      {footer && createPortal(props.children, footer)}\n    </div>\n  )\n}\n\nFormDrawer.Footer = DrawerFooter\n\nFormDrawer.Portal = createPortalProvider('form-drawer')\n\nexport default FormDrawer\n"
  },
  {
    "path": "packages/next/src/form-drawer/style.ts",
    "content": "import '@alifd/next/lib/drawer/style'\n"
  },
  {
    "path": "packages/next/src/form-grid/index.tsx",
    "content": "import React, { useLayoutEffect, useRef, useMemo, useContext } from 'react'\nimport { markRaw } from '@formily/reactive'\nimport { observer } from '@formily/react'\nimport { Grid, IGridOptions } from '@formily/grid'\nimport { usePrefixCls, pickDataProps } from '../__builtins__'\nimport { useFormLayout } from '../form-layout'\nimport cls from 'classnames'\n\nconst FormGridContext = React.createContext<Grid<HTMLElement>>(null)\n\nexport interface IFormGridProps extends IGridOptions {\n  grid?: Grid<HTMLElement>\n  prefix?: string\n  className?: string\n  style?: React.CSSProperties\n}\n\nexport interface IGridColumnProps {\n  gridSpan?: number\n  style?: React.CSSProperties\n  className?: string\n}\n\ntype ComposedFormGrid = React.FC<React.PropsWithChildren<IFormGridProps>> & {\n  GridColumn: React.FC<React.PropsWithChildren<IGridColumnProps>>\n  useFormGrid: () => Grid<HTMLElement>\n  createFormGrid: (props: IFormGridProps) => Grid<HTMLElement>\n  /**\n   * @deprecated\n   */\n  useGridSpan: (gridSpan: number) => number\n  /**\n   * @deprecated\n   */\n  useGridColumn: (gridSpan: number) => number\n}\n\nexport const createFormGrid = (props: IFormGridProps) => {\n  return markRaw(new Grid(props))\n}\n\nexport const useFormGrid = () => useContext(FormGridContext)\n\n/**\n * @deprecated\n */\nexport const useGridSpan = (gridSpan = 1) => {\n  return gridSpan\n}\n/**\n * @deprecated\n */\nexport const useGridColumn = (gridSpan = 1) => {\n  return gridSpan\n}\n\nexport const FormGrid: ComposedFormGrid = observer(\n  ({\n    children,\n    className,\n    style,\n    ...props\n  }: React.PropsWithChildren<IFormGridProps>) => {\n    const layout = useFormLayout()\n    const options = {\n      columnGap: layout?.gridColumnGap ?? 8,\n      rowGap: layout?.gridRowGap ?? 4,\n      ...props,\n    }\n    const grid = useMemo(\n      () => markRaw(options?.grid ? options.grid : new Grid(options)),\n      [Grid.id(options)]\n    )\n    const ref = useRef<HTMLDivElement>()\n    const prefixCls = usePrefixCls('formily-grid', props)\n    const dataProps = pickDataProps(props)\n    useLayoutEffect(() => {\n      return grid.connect(ref.current)\n    }, [grid])\n    return (\n      <FormGridContext.Provider value={grid}>\n        <div\n          {...dataProps}\n          className={cls(`${prefixCls}-layout`, className)}\n          style={{\n            ...style,\n            gridTemplateColumns: grid.templateColumns,\n            gap: grid.gap,\n          }}\n          ref={ref}\n        >\n          {children}\n        </div>\n      </FormGridContext.Provider>\n    )\n  },\n  {\n    forwardRef: true,\n  }\n) as any\n\nexport const GridColumn: React.FC<React.PropsWithChildren<IGridColumnProps>> =\n  observer(({ gridSpan = 1, children, ...props }) => {\n    return (\n      <div {...props} data-grid-span={gridSpan}>\n        {children}\n      </div>\n    )\n  })\n\nFormGrid.createFormGrid = createFormGrid\nFormGrid.useFormGrid = useFormGrid\nFormGrid.useGridSpan = useGridSpan\nFormGrid.useGridColumn = useGridColumn\nFormGrid.GridColumn = GridColumn\n\nexport default FormGrid\n"
  },
  {
    "path": "packages/next/src/form-grid/main.scss",
    "content": "@import '~@alifd/next/lib/core/index-noreset.scss';\n\n$form-grid-prefix-cls: '#{$css-prefix}formily-grid';\n\n.#{$form-grid-prefix-cls}-layout {\n  display: grid;\n}\n"
  },
  {
    "path": "packages/next/src/form-grid/style.ts",
    "content": "import './main.scss'\n"
  },
  {
    "path": "packages/next/src/form-item/animation.scss",
    "content": "@-webkit-keyframes antShowHelpIn {\n  0% {\n    -webkit-transform: translateY(-5px);\n    transform: translateY(-5px);\n    opacity: 0;\n  }\n\n  to {\n    -webkit-transform: translateY(0);\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n\n.#{$form-item-cls}-help-appear,\n.#{$form-item-cls}-help-enter {\n  -webkit-animation-duration: 0.3s;\n  animation-duration: 0.3s;\n  -webkit-animation-fill-mode: both;\n  animation-fill-mode: both;\n  -webkit-animation-play-state: paused;\n  animation-play-state: paused;\n}\n\n.#{$form-item-cls}-help-appear.#{$form-item-cls}-help-appear-active,\n.#{$form-item-cls}-help-enter.#{$form-item-cls}-help-enter-active {\n  -webkit-animation-name: antShowHelpIn;\n  animation-name: antShowHelpIn;\n  -webkit-animation-play-state: running;\n  animation-play-state: running;\n}\n\n.#{$form-item-cls}-help-appear,\n.#{$form-item-cls}-help-enter {\n  opacity: 0;\n}\n\n.#{$form-item-cls}-help-appear,\n.#{$form-item-cls}-help-enter {\n  -webkit-animation-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);\n  animation-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1);\n}\n\n@keyframes antShowHelpIn {\n  0% {\n    -webkit-transform: translateY(-5px);\n    transform: translateY(-5px);\n    opacity: 0;\n  }\n\n  to {\n    -webkit-transform: translateY(0);\n    transform: translateY(0);\n    opacity: 1;\n  }\n}\n\n@-webkit-keyframes antShowHelpOut {\n  to {\n    -webkit-transform: translateY(-5px);\n    transform: translateY(-5px);\n    opacity: 0;\n  }\n}\n\n@keyframes antShowHelpOut {\n  to {\n    -webkit-transform: translateY(-5px);\n    transform: translateY(-5px);\n    opacity: 0;\n  }\n}\n"
  },
  {
    "path": "packages/next/src/form-item/grid.scss",
    "content": ".#{$form-item-cls} {\n  .#{$form-item-cls}-item-col-24 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 100%;\n    flex: 0 0 100%;\n    max-width: 100%;\n  }\n\n  .#{$form-item-cls}-item-col-23 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 95.83333333%;\n    flex: 0 0 95.83333333%;\n    max-width: 95.83333333%;\n  }\n\n  .#{$form-item-cls}-item-col-22 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 91.66666667%;\n    flex: 0 0 91.66666667%;\n    max-width: 91.66666667%;\n  }\n\n  .#{$form-item-cls}-item-col-21 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 87.5%;\n    flex: 0 0 87.5%;\n    max-width: 87.5%;\n  }\n\n  .#{$form-item-cls}-item-col-20 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 83.33333333%;\n    flex: 0 0 83.33333333%;\n    max-width: 83.33333333%;\n  }\n\n  .#{$form-item-cls}-item-col-19 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 79.16666667%;\n    flex: 0 0 79.16666667%;\n    max-width: 79.16666667%;\n  }\n\n  .#{$form-item-cls}-item-col-18 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 75%;\n    flex: 0 0 75%;\n    max-width: 75%;\n  }\n\n  .#{$form-item-cls}-item-col-17 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 70.83333333%;\n    flex: 0 0 70.83333333%;\n    max-width: 70.83333333%;\n  }\n\n  .#{$form-item-cls}-item-col-16 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 66.66666667%;\n    flex: 0 0 66.66666667%;\n    max-width: 66.66666667%;\n  }\n\n  .#{$form-item-cls}-item-col-15 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 62.5%;\n    flex: 0 0 62.5%;\n    max-width: 62.5%;\n  }\n\n  .#{$form-item-cls}-item-col-14 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 58.33333333%;\n    flex: 0 0 58.33333333%;\n    max-width: 58.33333333%;\n  }\n\n  .#{$form-item-cls}-item-col-13 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 54.16666667%;\n    flex: 0 0 54.16666667%;\n    max-width: 54.16666667%;\n  }\n\n  .#{$form-item-cls}-item-col-12 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 50%;\n    flex: 0 0 50%;\n    max-width: 50%;\n  }\n\n  .#{$form-item-cls}-item-col-11 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 45.83333333%;\n    flex: 0 0 45.83333333%;\n    max-width: 45.83333333%;\n  }\n\n  .#{$form-item-cls}-item-col-10 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 41.66666667%;\n    flex: 0 0 41.66666667%;\n    max-width: 41.66666667%;\n  }\n\n  .#{$form-item-cls}-item-col-9 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 37.5%;\n    flex: 0 0 37.5%;\n    max-width: 37.5%;\n  }\n\n  .#{$form-item-cls}-item-col-8 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 33.33333333%;\n    flex: 0 0 33.33333333%;\n    max-width: 33.33333333%;\n  }\n\n  .#{$form-item-cls}-item-col-7 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 29.16666667%;\n    flex: 0 0 29.16666667%;\n    max-width: 29.16666667%;\n  }\n\n  .#{$form-item-cls}-item-col-6 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 25%;\n    flex: 0 0 25%;\n    max-width: 25%;\n  }\n\n  .#{$form-item-cls}-item-col-5 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 20.83333333%;\n    flex: 0 0 20.83333333%;\n    max-width: 20.83333333%;\n  }\n\n  .#{$form-item-cls}-item-col-4 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 16.66666667%;\n    flex: 0 0 16.66666667%;\n    max-width: 16.66666667%;\n  }\n\n  .#{$form-item-cls}-item-col-3 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 12.5%;\n    flex: 0 0 12.5%;\n    max-width: 12.5%;\n  }\n\n  .#{$form-item-cls}-item-col-2 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 8.33333333%;\n    flex: 0 0 8.33333333%;\n    max-width: 8.33333333%;\n  }\n\n  .#{$form-item-cls}-item-col-1 {\n    -webkit-box-flex: 0;\n    -ms-flex: 0 0 4.16666667%;\n    flex: 0 0 4.16666667%;\n    max-width: 4.16666667%;\n  }\n\n  .#{$form-item-cls}-item-col-0 {\n    display: none;\n  }\n}\n"
  },
  {
    "path": "packages/next/src/form-item/index.tsx",
    "content": "import React, { useState, useRef, useEffect } from 'react'\nimport cls from 'classnames'\nimport {\n  usePrefixCls,\n  pickDataProps,\n  QuestionCircleOutlinedIcon,\n  CloseCircleOutlinedIcon,\n  CheckCircleOutlinedIcon,\n  ExclamationCircleOutlinedIcon,\n} from '../__builtins__'\nimport { isVoidField } from '@formily/core'\nimport { connect, mapProps } from '@formily/react'\nimport { useFormLayout, FormLayoutShallowContext } from '../form-layout'\nimport { Balloon } from '@alifd/next'\n\nexport interface IFormItemProps {\n  className?: string\n  style?: React.CSSProperties\n  prefix?: string\n  label?: React.ReactNode\n  colon?: boolean\n  layout?: 'vertical' | 'horizontal' | 'inline'\n  tooltip?: React.ReactNode\n  tooltipLayout?: 'icon' | 'text'\n  tooltipIcon?: React.ReactNode\n  labelFor?: string\n  labelStyle?: React.CSSProperties\n  labelAlign?: 'left' | 'right'\n  labelWrap?: boolean\n  labelWidth?: number | string\n  wrapperWidth?: number | string\n  labelCol?: number\n  wrapperCol?: number\n  wrapperAlign?: 'left' | 'right'\n  wrapperWrap?: boolean\n  wrapperStyle?: React.CSSProperties\n  fullness?: boolean\n  addonBefore?: React.ReactNode\n  addonAfter?: React.ReactNode\n  size?: 'small' | 'default' | 'large'\n  inset?: boolean\n  extra?: React.ReactNode\n  feedbackText?: React.ReactNode\n  feedbackLayout?: 'loose' | 'terse' | 'popover' | 'none' | (string & {})\n  feedbackStatus?: 'error' | 'warning' | 'success' | 'pending' | (string & {})\n  feedbackIcon?: React.ReactNode\n  asterisk?: boolean\n  gridSpan?: number\n  bordered?: boolean\n}\n\ntype ComposeFormItem = React.FC<React.PropsWithChildren<IFormItemProps>> & {\n  BaseItem?: React.FC<React.PropsWithChildren<IFormItemProps>>\n}\n\nconst useFormItemLayout = (props: IFormItemProps) => {\n  const layout = useFormLayout()\n  const layoutType = props.layout ?? layout.layout ?? 'horizontal'\n  return {\n    ...props,\n    layout: layoutType,\n    colon: props.colon ?? layout.colon,\n    labelAlign:\n      layoutType === 'vertical'\n        ? props.labelAlign ?? 'left'\n        : props.labelAlign ?? layout.labelAlign ?? 'right',\n    labelWrap: props.labelWrap ?? layout.labelWrap,\n    labelWidth: props.labelWidth ?? layout.labelWidth,\n    wrapperWidth: props.wrapperWidth ?? layout.wrapperWidth,\n    labelCol: props.labelCol ?? layout.labelCol,\n    wrapperCol: props.wrapperCol ?? layout.wrapperCol,\n    wrapperAlign: props.wrapperAlign ?? layout.wrapperAlign,\n    wrapperWrap: props.wrapperWrap ?? layout.wrapperWrap,\n    fullness: props.fullness ?? layout.fullness,\n    size: props.size ?? layout.size,\n    inset: props.inset ?? layout.inset,\n    asterisk: props.asterisk,\n    bordered: props.bordered ?? layout.bordered,\n    feedbackIcon: props.feedbackIcon,\n    feedbackLayout: props.feedbackLayout ?? layout.feedbackLayout ?? 'loose',\n    tooltipLayout: props.tooltipLayout ?? layout.tooltipLayout ?? 'icon',\n    tooltipIcon: props.tooltipIcon ?? layout.tooltipIcon ?? (\n      <QuestionCircleOutlinedIcon />\n    ),\n  }\n}\n\nfunction useOverflow<\n  Container extends HTMLElement,\n  Content extends HTMLElement\n>() {\n  const [overflow, setOverflow] = useState(false)\n  const containerRef = useRef<Container>()\n  const contentRef = useRef<Content>()\n  const layout = useFormLayout()\n  const labelCol = JSON.stringify(layout.labelCol)\n\n  useEffect(() => {\n    requestAnimationFrame(() => {\n      if (containerRef.current && contentRef.current) {\n        const contentWidth = contentRef.current.getBoundingClientRect().width\n        const containerWidth =\n          containerRef.current.getBoundingClientRect().width\n        if (contentWidth && containerWidth && containerWidth < contentWidth) {\n          if (!overflow) setOverflow(true)\n        } else {\n          if (overflow) setOverflow(false)\n        }\n      }\n    })\n  }, [labelCol])\n\n  return {\n    overflow,\n    containerRef,\n    contentRef,\n  }\n}\n\nconst ICON_MAP = {\n  error: <CloseCircleOutlinedIcon />,\n  success: <CheckCircleOutlinedIcon />,\n  warning: <ExclamationCircleOutlinedIcon />,\n}\n\nexport const BaseItem: React.FC<React.PropsWithChildren<IFormItemProps>> = (\n  props\n) => {\n  const { children, ...others } = props\n  const [active, setActive] = useState(false)\n  const formLayout = useFormItemLayout(others)\n  const { containerRef, contentRef, overflow } = useOverflow<\n    HTMLDivElement,\n    HTMLSpanElement\n  >()\n  const {\n    label,\n    style,\n    layout,\n    colon = true,\n    addonBefore,\n    addonAfter,\n    asterisk,\n    feedbackStatus,\n    extra,\n    feedbackText,\n    fullness = true,\n    feedbackLayout,\n    feedbackIcon,\n    inset,\n    bordered = true,\n    labelWidth,\n    wrapperWidth,\n    labelCol,\n    wrapperCol,\n    labelAlign,\n    wrapperAlign = 'left',\n    size,\n    labelWrap,\n    wrapperWrap,\n    tooltip,\n    tooltipLayout,\n    tooltipIcon,\n  } = formLayout\n  const labelStyle = { ...formLayout.labelStyle }\n  const wrapperStyle = { ...formLayout.wrapperStyle }\n  // 固定宽度\n  let enableCol = false\n  if (labelWidth || wrapperWidth) {\n    if (labelWidth) {\n      labelStyle.width = labelWidth === 'auto' ? undefined : labelWidth\n      labelStyle.maxWidth = labelWidth === 'auto' ? undefined : labelWidth\n    }\n    if (wrapperWidth) {\n      wrapperStyle.width = wrapperWidth === 'auto' ? undefined : wrapperWidth\n      wrapperStyle.maxWidth = wrapperWidth === 'auto' ? undefined : wrapperWidth\n    }\n    // 栅格模式\n  }\n  if (labelCol || wrapperCol) {\n    if (!labelStyle.width && !wrapperStyle.width && layout !== 'vertical') {\n      enableCol = true\n    }\n  }\n  const prefixCls = usePrefixCls('formily-item', props)\n  const prefix = usePrefixCls()\n  const formatChildren =\n    feedbackLayout === 'popover' ? (\n      <Balloon\n        needAdjust\n        align=\"t\"\n        closable={false}\n        trigger={children}\n        visible={!!feedbackText}\n      >\n        <div\n          className={cls({\n            [`${prefixCls}-${feedbackStatus}-help`]: !!feedbackStatus,\n            [`${prefixCls}-help`]: true,\n          })}\n        >\n          {ICON_MAP[feedbackStatus]} {feedbackText}\n        </div>\n      </Balloon>\n    ) : (\n      children\n    )\n\n  const gridStyles: React.CSSProperties = {}\n\n  const getOverflowTooltip = () => {\n    if (overflow) {\n      return (\n        <div>\n          <div>{label}</div>\n          <div>{tooltip}</div>\n        </div>\n      )\n    }\n    return tooltip\n  }\n\n  const renderLabelText = () => {\n    const labelChildren = (\n      <div className={cls(`${prefixCls}-label-content`)} ref={containerRef}>\n        <span ref={contentRef}>\n          {asterisk && (\n            <span className={cls(`${prefixCls}-asterisk`)}>{'*'}</span>\n          )}\n          <label htmlFor={props.labelFor}>{label}</label>\n        </span>\n      </div>\n    )\n\n    if ((tooltipLayout === 'text' && tooltip) || overflow) {\n      return (\n        <Balloon.Tooltip align=\"t\" trigger={labelChildren}>\n          {getOverflowTooltip()}\n        </Balloon.Tooltip>\n      )\n    }\n    return labelChildren\n  }\n\n  const renderTooltipIcon = () => {\n    if (tooltip && tooltipLayout === 'icon' && !overflow) {\n      return (\n        <span className={cls(`${prefixCls}-label-tooltip-icon`)}>\n          <Balloon.Tooltip align=\"t\" trigger={tooltipIcon}>\n            {tooltip}\n          </Balloon.Tooltip>\n        </span>\n      )\n    }\n  }\n\n  const renderLabel = () => {\n    if (!label) return null\n    return (\n      <div\n        className={cls({\n          [`${prefixCls}-label`]: true,\n          [`${prefixCls}-label-tooltip`]:\n            (tooltip && tooltipLayout === 'text') || overflow,\n          [`${prefixCls}-item-col-${labelCol}`]: enableCol && !!labelCol,\n        })}\n        style={labelStyle}\n      >\n        {renderLabelText()}\n        {renderTooltipIcon()}\n        {label !== ' ' && (\n          <span className={cls(`${prefixCls}-colon`)}>{colon ? ':' : ''}</span>\n        )}\n      </div>\n    )\n  }\n\n  return (\n    <div\n      {...pickDataProps(props)}\n      style={{\n        ...style,\n        ...gridStyles,\n      }}\n      data-grid-span={props.gridSpan}\n      className={cls({\n        [`${prefixCls}`]: true,\n        [`${prefixCls}-layout-${layout}`]: true,\n        [`${prefixCls}-${feedbackStatus}`]: !!feedbackStatus,\n        [`${prefixCls}-feedback-has-text`]: !!feedbackText,\n        [`${prefixCls}-size-${size}`]: !!size,\n        [`${prefixCls}-feedback-layout-${feedbackLayout}`]: !!feedbackLayout,\n        [`${prefixCls}-fullness`]: !!fullness || !!inset || !!feedbackIcon,\n        [`${prefixCls}-inset`]: !!inset,\n        [`${prefix}input`]: !!inset,\n        [`${prefixCls}-active`]: active,\n        [`${prefix}focus`]: active,\n        [`${prefixCls}-inset-active`]: !!inset && active,\n        [`${prefixCls}-label-align-${labelAlign}`]: true,\n        [`${prefixCls}-control-align-${wrapperAlign}`]: true,\n        [`${prefixCls}-label-wrap`]: !!labelWrap,\n        [`${prefixCls}-control-wrap`]: !!wrapperWrap,\n        [`${prefixCls}-bordered-none`]: bordered === false,\n        [props.className]: !!props.className,\n      })}\n      onFocus={() => {\n        if (feedbackIcon || inset) {\n          setActive(true)\n        }\n      }}\n      onBlur={() => {\n        if (feedbackIcon || inset) {\n          setActive(false)\n        }\n      }}\n    >\n      {renderLabel()}\n      <div\n        className={cls({\n          [`${prefixCls}-control`]: true,\n          [`${prefixCls}-item-col-${wrapperCol}`]:\n            enableCol && !!wrapperCol && label,\n        })}\n      >\n        <div className={cls(`${prefixCls}-control-content`)}>\n          {addonBefore && (\n            <div className={cls(`${prefixCls}-addon-before`)}>\n              {addonBefore}\n            </div>\n          )}\n          <div\n            style={wrapperStyle}\n            className={cls({\n              [`${prefixCls}-control-content-component`]: true,\n              [`${prefixCls}-control-content-component-has-feedback-icon`]:\n                !!feedbackIcon,\n              [`${prefix}input`]: !!feedbackIcon,\n              [`${prefixCls}-active`]: active,\n              [`${prefix}focus`]: active,\n            })}\n          >\n            <FormLayoutShallowContext.Provider value={{ size }}>\n              {formatChildren}\n            </FormLayoutShallowContext.Provider>\n            {feedbackIcon && (\n              <div className={cls(`${prefixCls}-feedback-icon`)}>\n                {feedbackIcon}\n              </div>\n            )}\n          </div>\n          {addonAfter && (\n            <div className={cls(`${prefixCls}-addon-after`)}>{addonAfter}</div>\n          )}\n        </div>\n        {!!feedbackText &&\n          feedbackLayout !== 'popover' &&\n          feedbackLayout !== 'none' && (\n            <div\n              className={cls({\n                [`${prefixCls}-${feedbackStatus}-help`]: !!feedbackStatus,\n                [`${prefixCls}-help`]: true,\n                [`${prefixCls}-help-enter`]: true,\n                [`${prefixCls}-help-enter-active`]: true,\n              })}\n            >\n              {feedbackText}\n            </div>\n          )}\n        {extra && <div className={cls(`${prefixCls}-extra`)}>{extra}</div>}\n      </div>\n    </div>\n  )\n}\n\n// 适配\nexport const FormItem: ComposeFormItem = connect(\n  BaseItem,\n  mapProps((props, field) => {\n    if (isVoidField(field))\n      return {\n        label: field.title || props.label,\n        asterisk: props.asterisk,\n        extra: props.extra || field.description,\n      }\n    if (!field) return props\n    const takeFeedbackStatus = () => {\n      if (field.validating) return 'pending'\n      return field.decoratorProps.feedbackStatus || field.validateStatus\n    }\n    const takeMessage = () => {\n      const split = (messages: any[]) => {\n        return messages.reduce((buf, text, index) => {\n          if (!text) return buf\n          return index < messages.length - 1\n            ? buf.concat([text, ', '])\n            : buf.concat([text])\n        }, [])\n      }\n      if (field.validating) return\n      if (props.feedbackText) return props.feedbackText\n      if (field.selfErrors.length) return split(field.selfErrors)\n      if (field.selfWarnings.length) return split(field.selfWarnings)\n      if (field.selfSuccesses.length) return split(field.selfSuccesses)\n    }\n    const takeAsterisk = () => {\n      if (field.required && field.pattern !== 'readPretty') {\n        return true\n      }\n      if ('asterisk' in props) {\n        return props.asterisk\n      }\n      return false\n    }\n    return {\n      label: props.label || field.title,\n      feedbackStatus: takeFeedbackStatus(),\n      feedbackText: takeMessage(),\n      asterisk: takeAsterisk(),\n      extra: props.extra || field.description,\n    }\n  })\n)\n\nFormItem.BaseItem = BaseItem\n\nexport default FormItem\n"
  },
  {
    "path": "packages/next/src/form-item/main.scss",
    "content": "@import '~@alifd/next/lib/core/index-noreset.scss';\n@import './scss/variable.scss';\n@import './grid.scss';\n@import './animation.scss';\n\n.#{$form-item-cls} {\n  display: flex;\n  margin-bottom: $form-item-m-margin-b + 2;\n  position: relative;\n  line-height: $form-element-medium-height;\n  font-size: $form-element-medium-font-size;\n\n  &-layout-vertical {\n    display: block;\n  }\n\n  &-label-content {\n    min-height: $form-element-medium-height;\n  }\n\n  &-control-content-component {\n    line-height: $form-element-medium-height;\n  }\n\n  &-inset {\n    padding: 0 8px;\n    border: 1px solid $input-border-color;\n    border-radius: $form-element-medium-corner;\n    width: 100%;\n\n    .#{$css-prefix}input {\n      border: none !important;\n      box-shadow: none !important;\n      outline: none;\n    }\n  }\n\n  &-bordered-none:not(.#{$form-item-cls}-inset) {\n    .#{$css-prefix}input {\n      border: none !important;\n      box-shadow: none !important;\n      outline: none;\n    }\n  }\n}\n\n.#{$form-item-cls}-label {\n  position: relative;\n  display: flex;\n  &-content {\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n\n  &-tooltip {\n    cursor: help;\n\n    .#{$form-item-cls}-colon {\n      display: flex;\n    }\n\n    * {\n      cursor: help;\n    }\n\n    &-colon {\n      cursor: help;\n    }\n\n    label {\n      border-bottom: 1px dashed currentColor;\n    }\n  }\n}\n\n.#{$form-item-cls}-label label {\n  cursor: text;\n  color: rgba(0, 0, 0, 0.85);\n}\n\n.#{$form-item-cls}-label-align-left {\n  > .#{$form-item-cls}-label {\n    justify-content: flex-start;\n  }\n}\n\n.#{$form-item-cls}-label-align-right {\n  > .#{$form-item-cls}-label {\n    justify-content: flex-end;\n  }\n}\n\n.#{$form-item-cls}-label-wrap {\n  .#{$form-item-cls}-label {\n    label {\n      white-space: pre-line;\n      word-break: break-all;\n    }\n  }\n}\n\n.#{$form-item-cls}-feedback-layout-terse {\n  margin-bottom: 8px;\n\n  &.#{$form-item-cls}-feedback-has-text:not(.#{$form-item-cls}-inset) {\n    margin-bottom: 0;\n  }\n}\n\n.#{$form-item-cls}-feedback-layout-loose {\n  margin-bottom: $form-item-m-margin-b + 4;\n\n  &.#{$form-item-cls}-feedback-has-text:not(.#{$form-item-cls}-inset) {\n    margin-bottom: 0;\n  }\n}\n\n.#{$form-item-cls}-feedback-layout-none {\n  margin-bottom: 0px;\n\n  &.#{$form-item-cls}-feedback-has-text:not(.#{$form-item-cls}-inset) {\n    margin-bottom: 0;\n  }\n}\n\n.#{$form-item-cls}-control {\n  flex: 1;\n  max-width: 100%;\n\n  .#{$form-item-cls}-control-content {\n    display: flex;\n\n    .#{$form-item-cls}-control-content-component {\n      width: 100%;\n      min-height: $form-element-medium-height;\n      line-height: $form-element-medium-height;\n\n      &-has-feedback-icon {\n        flex: 1;\n        position: relative;\n        display: flex;\n        align-items: center;\n\n        .#{$css-prefix}input {\n          height: 100%;\n          border: none !important;\n          box-shadow: none !important;\n          outline: none;\n\n          .#{$css-prefix}input-control {\n            margin-right: 0;\n            padding-right: 0;\n\n            .#{$css-prefix}icon {\n              display: none;\n            }\n\n            .#{$css-prefix}input-hint-wrap {\n              .#{$css-prefix}icon {\n                display: block;\n              }\n            }\n          }\n        }\n      }\n\n      .#{$css-prefix}range {\n        height: 100%;\n        padding-left: 2px;\n      }\n\n      .#{$css-prefix}transfer {\n        display: flex;\n        align-items: center;\n      }\n    }\n\n    .#{$form-item-cls}-addon-before {\n      margin-right: 8px;\n      display: inline-flex;\n      align-items: center;\n      min-height: $form-element-medium-height;\n      flex-shrink: 0;\n    }\n\n    .#{$form-item-cls}-addon-after {\n      margin-left: 8px;\n      display: inline-flex;\n      align-items: center;\n      min-height: $form-element-medium-height;\n      flex-shrink: 0;\n    }\n  }\n}\n\n.#{$form-item-cls}-size-small {\n  font-size: $form-element-small-font-size;\n  line-height: $form-element-small-height;\n\n  .#{$form-item-cls}-label-content {\n    min-height: $form-element-small-height;\n  }\n\n  .#{$form-item-cls}-control-content {\n    .#{$form-item-cls}-control-content-component {\n      line-height: $form-element-small-height;\n      min-height: $form-element-small-height;\n    }\n\n    .#{$form-item-cls}-addon-before {\n      min-height: $form-element-small-height;\n    }\n\n    .#{$form-item-cls}-addon-after {\n      min-height: $form-element-small-height;\n    }\n  }\n\n  &-inset {\n    border-radius: $form-element-small-corner;\n  }\n\n  &.#{$form-item-cls}-feedback-layout-terse {\n    margin-bottom: 8px;\n\n    &.#{$form-item-cls}-feedback-has-text:not(.#{$form-item-cls}-inset) {\n      margin-bottom: 0;\n    }\n  }\n\n  &.#{$form-item-cls}-feedback-layout-loose {\n    margin-bottom: $form-item-s-margin-b + 8;\n\n    &.#{$form-item-cls}-feedback-has-text:not(.#{$form-item-cls}-inset) {\n      margin-bottom: 0;\n    }\n  }\n\n  .#{$form-item-cls}-help,\n  .#{$form-item-cls}-extra {\n    min-height: $form-element-small-font-size + 2;\n  }\n\n  .#{$form-item-cls}-control-content {\n    min-height: $form-element-small-height;\n  }\n\n  .#{$form-item-cls}-label > label {\n    height: $form-element-small-height;\n  }\n}\n\n.#{$form-item-cls}-size-large {\n  font-size: $form-element-large-font-size;\n  line-height: $form-element-large-height;\n\n  .#{$form-item-cls}-label-content {\n    min-height: $form-element-large-height;\n  }\n\n  .#{$form-item-cls}-control-content {\n    .#{$form-item-cls}-control-content-component {\n      line-height: $form-element-large-height;\n      min-height: $form-element-large-height;\n    }\n\n    .#{$form-item-cls}-addon-before {\n      min-height: $form-element-large-height;\n    }\n\n    .#{$form-item-cls}-addon-after {\n      min-height: $form-element-large-height;\n    }\n  }\n\n  &-inset {\n    border-radius: $form-element-large-corner;\n  }\n\n  .#{$form-item-cls}-help,\n  .#{$form-item-cls}-extra {\n    min-height: $form-element-large-font-size + 2;\n  }\n\n  &.#{$form-item-cls}-feedback-layout-loose {\n    margin-bottom: $form-item-l-margin-b;\n\n    &.#{$form-item-cls}-feedback-has-text:not(.#{$form-item-cls}-inset) {\n      margin-bottom: 0;\n    }\n  }\n\n  .#{$form-item-cls}-control-content {\n    min-height: $form-element-large-height;\n  }\n\n  .#{$form-item-cls}-label > label {\n    height: $form-element-large-height;\n  }\n}\n\n.#{$form-item-cls}-feedback-layout-popover {\n  margin-bottom: 8px;\n}\n\n.#{$form-item-cls}-label-tooltip-icon {\n  margin-left: 4px;\n  color: #00000073;\n  cursor: pointer;\n  max-height: $form-element-medium-height;\n}\n\n.#{$form-item-cls}-control-align-left {\n  .#{$form-item-cls}-control-content {\n    justify-content: flex-start;\n  }\n}\n\n.#{$form-item-cls}-control-align-right {\n  .#{$form-item-cls}-control-content {\n    justify-content: flex-end;\n  }\n}\n\n.#{$form-item-cls}-control-wrap {\n  .#{$form-item-cls}-control {\n    white-space: pre-line;\n  }\n}\n\n.#{$form-item-cls}-asterisk {\n  color: $form-error-color;\n  margin-right: 4px;\n  display: inline-block;\n  font-family: SimSun, sans-serif;\n}\n\n.#{$form-item-cls}-colon {\n  margin-left: 2px;\n  margin-right: 8px;\n}\n\n.#{$form-item-cls}-help,\n.#{$form-item-cls}-extra {\n  clear: both;\n  line-height: $form-item-m-margin-b + 4;\n  min-height: $form-item-m-margin-b;\n  color: rgba(0, 0, 0, 0.45);\n  transition: color 0.3s cubic-bezier(0.215, 0.61, 0.355, 1);\n  padding-top: 0px;\n}\n\n.#{$form-item-cls}-fullness {\n  > .#{$form-item-cls}-control {\n    > .#{$form-item-cls}-control-content {\n      > .#{$form-item-cls}-control-content-component {\n        > *:first-child:not(.#{$css-prefix}switch):not(.#{$css-prefix}icon):not(.#{$css-prefix}formily-icon):not(.anticon):not(.#{$css-prefix}btn-text) {\n          width: 100%;\n        }\n      }\n    }\n  }\n}\n\n.#{$form-item-cls}-control-content-component-has-feedback-icon {\n  border-radius: 2px;\n  border: 1px solid $input-border-color;\n  transition: all 0.3s;\n  touch-action: manipulation;\n  outline: none;\n  padding-right: 8px;\n\n  .#{$css-prefix}input {\n    border: none !important;\n  }\n\n  .#{$css-prefix}range-picker-trigger {\n    border: none !important;\n  }\n\n  .#{$form-item-cls}-feedback-icon {\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    margin-right: -2px;\n    padding-left: 2px;\n\n    .anticon {\n      display: inline-block;\n      color: inherit;\n      font-style: normal;\n      font-size: $form-element-medium-font-size;\n      line-height: 0;\n      text-align: center;\n      text-transform: none;\n      vertical-align: -0.125em;\n      text-rendering: optimizeLegibility;\n    }\n  }\n}\n\n.#{$form-item-cls}-error-help {\n  color: $form-error-color;\n}\n\n.#{$form-item-cls}-warning-help {\n  color: $form-warning-color;\n}\n\n.#{$form-item-cls}-success-help {\n  color: $form-success-color;\n}\n"
  },
  {
    "path": "packages/next/src/form-item/scss/variable.scss",
    "content": "////\n/// @module form: 表单\n/// @tag Form\n/// @category component\n/// @family data-entry\n/// @varPrefix $form-\n/// @classPrefix {prefix}-form\n/// @order {\"size/bounding\":10,\"size/item\":11,\"size/label\":12,\"size/help\":13,\"size/border\":14,\"statement/help\":10,\"statement/label\":11,\"statement/normal\":12,\"statement/border\":13}\n////\n\n@charset \"UTF-8\";\n\n// form variables\n// --------------------------------------------------\n\n$form-item-cls: '#{$css-prefix}formily-item';\n\n$input-border-color: $color-line1-3 !default;\n/// label padding (r)\n/// @namespace size/bounding\n$form-label-padding-r: $s-3 !default;\n\n/// margin (b)\n/// @namespace size/item\n$form-item-m-margin-b: $s-4 !default;\n\n/// margin (b)\n/// @namespace size/item\n$form-item-l-margin-b: $s-5 !default;\n\n/// margin (b)\n/// @namespace size/item\n$form-item-s-margin-b: $s-3 !default;\n\n/// margin (r)\n/// @namespace size/item\n$form-inline-l-item-margin-r: $s-6 !default;\n\n/// margin (r)\n/// @namespace size/item\n$form-inline-m-item-margin-r: $s-5 !default;\n\n/// margin (r)\n/// @namespace size/item\n$form-inline-s-item-margin-r: $s-4 !default;\n\n/// margin (t)\n/// @namespace size/help\n$form-help-margin-top: $s-1 !default;\n\n/// text\n/// @namespace size/help\n$form-help-font-size: $font-size-caption !default;\n\n/// text\n/// @namespace statement/help\n$form-help-color: $color-text1-2 !default;\n\n/// error text\n/// @namespace statement/help\n$form-error-color: $color-error-3 !default;\n\n/// warning text\n/// @namespace statement/help\n$form-warning-color: $color-warning-3 !default;\n\n$form-success-color: $color-success-3 !default;\n\n/// margin (b)\n/// @type length\n/// @namespace size/label\n$form-top-label-margin-b: 2px !default;\n\n/// text\n/// @namespace statement/label\n$form-label-color: $color-text1-3 !default;\n\n/// padding\n/// @namespace size/bounding\n$input-l-padding: $s-3 !default;\n\n/// padding(l)\n/// @namespace size/label\n$input-l-label-padding-left: $s-3 !default;\n\n/// padding(r)\n/// @namespace size/label\n$input-l-icon-padding-right: $s-2 !default;\n\n// medium\n// --------------------------------------------------\n\n/// padding\n/// @namespace size/bounding\n$input-m-padding: $s-2 !default;\n\n/// padding(l)\n/// @namespace size/label\n$input-m-label-padding-left: $s-2 !default;\n\n/// padding(r)\n/// @namespace size/label\n$input-m-icon-padding-right: $s-2 !default;\n\n// small\n// --------------------------------------------------\n\n/// padding\n/// @namespace size/bounding\n$input-s-padding: $s-1 !default;\n\n/// padding(l)\n/// @namespace size/label\n$input-s-label-padding-left: $s-2 !default;\n\n/// padding(r)\n/// @namespace size/label\n$input-s-icon-padding-right: $s-1 !default;\n"
  },
  {
    "path": "packages/next/src/form-item/style.ts",
    "content": "import '@alifd/next/lib/form/style'\nimport './main.scss'\n"
  },
  {
    "path": "packages/next/src/form-layout/index.tsx",
    "content": "import React, { createContext, useContext } from 'react'\nimport { useResponsiveFormLayout } from './useResponsiveFormLayout'\nimport { usePrefixCls } from '../__builtins__'\nimport cls from 'classnames'\n\nexport interface IFormLayoutProps {\n  prefix?: string\n  className?: string\n  style?: React.CSSProperties\n  colon?: boolean\n  labelAlign?: 'right' | 'left' | ('right' | 'left')[]\n  wrapperAlign?: 'right' | 'left' | ('right' | 'left')[]\n  labelWrap?: boolean\n  labelWidth?: number\n  wrapperWidth?: number\n  wrapperWrap?: boolean\n  labelCol?: number | number[]\n  wrapperCol?: number | number[]\n  fullness?: boolean\n  size?: 'small' | 'default' | 'large'\n  layout?:\n    | 'vertical'\n    | 'horizontal'\n    | 'inline'\n    | ('vertical' | 'horizontal' | 'inline')[]\n  direction?: 'rtl' | 'ltr'\n  inset?: boolean\n  shallow?: boolean\n  tooltipLayout?: 'icon' | 'text'\n  tooltipIcon?: React.ReactNode\n  feedbackLayout?: 'loose' | 'terse' | 'popover' | 'none'\n  bordered?: boolean\n  breakpoints?: number[]\n  gridColumnGap?: number\n  gridRowGap?: number\n  spaceGap?: number\n}\n\nexport interface IFormLayoutContext\n  extends Omit<\n    IFormLayoutProps,\n    'labelAlign' | 'wrapperAlign' | 'layout' | 'labelCol' | 'wrapperCol'\n  > {\n  labelAlign?: 'right' | 'left'\n  wrapperAlign?: 'right' | 'left'\n  layout?: 'vertical' | 'horizontal' | 'inline'\n  labelCol?: number\n  wrapperCol?: number\n}\n\nexport const FormLayoutDeepContext = createContext<IFormLayoutContext>(null)\n\nexport const FormLayoutShallowContext = createContext<IFormLayoutContext>(null)\n\nexport const useFormDeepLayout = () => useContext(FormLayoutDeepContext)\n\nexport const useFormShallowLayout = () => useContext(FormLayoutShallowContext)\n\nexport const useFormLayout = () => ({\n  ...useFormDeepLayout(),\n  ...useFormShallowLayout(),\n})\n\nexport const FormLayout: React.FC<React.PropsWithChildren<IFormLayoutProps>> & {\n  useFormLayout: () => IFormLayoutContext\n  useFormDeepLayout: () => IFormLayoutContext\n  useFormShallowLayout: () => IFormLayoutContext\n} = ({ shallow = true, children, prefix, className, style, ...otherProps }) => {\n  const { ref, props } = useResponsiveFormLayout(otherProps)\n  const deepLayout = useFormDeepLayout()\n  const formPrefixCls = usePrefixCls('form', { prefix })\n  const layoutPrefixCls = usePrefixCls('formily-layout', { prefix })\n  const layoutClassName = cls(\n    layoutPrefixCls,\n    {\n      [`${formPrefixCls}-${props.layout}`]: true,\n      [`${formPrefixCls}-rtl`]: props.direction === 'rtl',\n      [`${formPrefixCls}-${props.size}`]: props.size,\n    },\n    className\n  )\n  const renderChildren = () => {\n    const newDeepLayout = {\n      ...deepLayout,\n    }\n    if (!shallow) {\n      Object.assign(newDeepLayout, props)\n    } else {\n      if (props.size) {\n        newDeepLayout.size = props.size\n      }\n      if (props.colon) {\n        newDeepLayout.colon = props.colon\n      }\n    }\n    return (\n      <FormLayoutDeepContext.Provider value={newDeepLayout}>\n        <FormLayoutShallowContext.Provider value={shallow ? props : undefined}>\n          {children}\n        </FormLayoutShallowContext.Provider>\n      </FormLayoutDeepContext.Provider>\n    )\n  }\n  return (\n    <div ref={ref} className={layoutClassName} style={style}>\n      {renderChildren()}\n    </div>\n  )\n}\n\nFormLayout.useFormDeepLayout = useFormDeepLayout\nFormLayout.useFormShallowLayout = useFormShallowLayout\nFormLayout.useFormLayout = useFormLayout\n\nexport default FormLayout\n"
  },
  {
    "path": "packages/next/src/form-layout/main.scss",
    "content": ""
  },
  {
    "path": "packages/next/src/form-layout/style.ts",
    "content": "// @ts-ignore\n"
  },
  {
    "path": "packages/next/src/form-layout/useResponsiveFormLayout.ts",
    "content": "import { useRef, useState, useEffect } from 'react'\nimport { isArr, isValid } from '@formily/shared'\n\ninterface IProps {\n  breakpoints?: number[]\n  layout?:\n    | 'vertical'\n    | 'horizontal'\n    | 'inline'\n    | ('vertical' | 'horizontal' | 'inline')[]\n  labelCol?: number | number[]\n  wrapperCol?: number | number[]\n  labelAlign?: 'right' | 'left' | ('right' | 'left')[]\n  wrapperAlign?: 'right' | 'left' | ('right' | 'left')[]\n  [props: string]: any\n}\n\ninterface ICalcBreakpointIndex {\n  (originalBreakpoints: number[], width: number): number\n}\n\ninterface ICalculateProps {\n  (target: HTMLElement, props: IProps): IProps\n}\n\ninterface IUseResponsiveFormLayout {\n  (props: IProps): {\n    ref: React.MutableRefObject<HTMLDivElement>\n    props: any\n  }\n}\n\nconst calcBreakpointIndex: ICalcBreakpointIndex = (breakpoints, width) => {\n  for (let i = 0; i < breakpoints.length; i++) {\n    if (width <= breakpoints[i]) {\n      return i\n    }\n  }\n}\n\nconst calcFactor = <T>(value: T | T[], breakpointIndex: number): T => {\n  if (Array.isArray(value)) {\n    if (breakpointIndex === -1) return value[0]\n    return value[breakpointIndex] ?? value[value.length - 1]\n  } else {\n    return value\n  }\n}\n\nconst factor = <T>(value: T | T[], breakpointIndex: number): T =>\n  isValid(value) ? calcFactor(value as any, breakpointIndex) : value\n\nconst calculateProps: ICalculateProps = (target, props) => {\n  const { clientWidth } = target\n  const {\n    breakpoints,\n    layout,\n    labelAlign,\n    wrapperAlign,\n    labelCol,\n    wrapperCol,\n    ...otherProps\n  } = props\n  const breakpointIndex = calcBreakpointIndex(breakpoints, clientWidth)\n\n  return {\n    layout: factor(layout, breakpointIndex),\n    labelAlign: factor(labelAlign, breakpointIndex),\n    wrapperAlign: factor(wrapperAlign, breakpointIndex),\n    labelCol: factor(labelCol, breakpointIndex),\n    wrapperCol: factor(wrapperCol, breakpointIndex),\n    ...otherProps,\n  }\n}\n\nexport const useResponsiveFormLayout: IUseResponsiveFormLayout = (props) => {\n  const ref = useRef<HTMLDivElement>(null)\n  const { breakpoints } = props\n  if (!isArr(breakpoints)) {\n    return { ref, props }\n  }\n  const [layoutProps, setLayout] = useState<IProps>(props)\n\n  const updateUI = () => {\n    if (ref.current) {\n      setLayout(calculateProps(ref.current, props))\n    }\n  }\n\n  useEffect(() => {\n    const observer = () => {\n      updateUI()\n    }\n    const resizeObserver = new ResizeObserver(observer)\n    if (ref.current) {\n      resizeObserver.observe(ref.current)\n    }\n    updateUI()\n    return () => {\n      resizeObserver.disconnect()\n    }\n  }, [])\n\n  return {\n    ref,\n    props: layoutProps,\n  }\n}\n"
  },
  {
    "path": "packages/next/src/form-step/index.tsx",
    "content": "import React, { Fragment } from 'react'\nimport { define, observable, model, markRaw, action } from '@formily/reactive'\nimport cls from 'classnames'\nimport {\n  StepProps as StepsProps,\n  ItemProps as StepProps,\n} from '@alifd/next/lib/step'\nimport { Form, VoidField } from '@formily/core'\nimport {\n  connect,\n  useField,\n  observer,\n  useFieldSchema,\n  RecursionField,\n} from '@formily/react'\nimport { Schema, SchemaKey } from '@formily/json-schema'\nimport { Step as Steps } from '@alifd/next'\nimport { usePrefixCls } from '../__builtins__'\n\nexport interface IFormStep {\n  connect: (steps: SchemaStep[], field: VoidField) => void\n  current: number\n  allowNext: boolean\n  allowBack: boolean\n  setCurrent(key: number): void\n  submit: Form['submit']\n  next(): void\n  back(): void\n}\n\nexport interface IFormStepProps extends StepsProps {\n  formStep?: IFormStep\n}\n\ntype ComposedFormTab = React.FC<React.PropsWithChildren<IFormStepProps>> & {\n  StepPane?: React.FC<React.PropsWithChildren<StepProps>>\n  createFormStep?: (defaultCurrent?: number) => IFormStep\n}\n\ntype SchemaStep = {\n  name: SchemaKey\n  props: any\n  schema: Schema\n}\n\ntype FormStepEnv = {\n  form: Form\n  field: VoidField\n  steps: SchemaStep[]\n}\n\nconst parseSteps = (schema: Schema) => {\n  const steps: SchemaStep[] = []\n  schema.mapProperties((schema, name) => {\n    if (schema['x-component']?.indexOf('StepPane') > -1) {\n      steps.push({\n        name,\n        props: schema['x-component-props'],\n        schema,\n      })\n    }\n  })\n  return steps\n}\n\nconst createFormStep = (defaultCurrent = 0): IFormStep => {\n  const env: FormStepEnv = define(\n    {\n      form: null,\n      field: null,\n      steps: [],\n    },\n    {\n      form: observable.ref,\n      field: observable.ref,\n      steps: observable.shallow,\n    }\n  )\n\n  const setDisplay = action.bound((target: number) => {\n    const currentStep = env.steps[target]\n    env.steps.forEach(({ name }) => {\n      env.form.query(`${env.field.address}.${name}`).take((field) => {\n        if (name === currentStep.name) {\n          field.setDisplay('visible')\n        } else {\n          field.setDisplay('hidden')\n        }\n      })\n    })\n  })\n\n  const next = () => {\n    if (formStep.allowNext) {\n      formStep.setCurrent(formStep.current + 1)\n    }\n  }\n\n  const back = () => {\n    if (formStep.allowBack) {\n      formStep.setCurrent(formStep.current - 1)\n    }\n  }\n\n  const formStep: IFormStep = model({\n    connect(steps, field) {\n      env.steps = steps\n      env.form = field?.form\n      env.field = field\n    },\n    current: defaultCurrent,\n    setCurrent(key: number) {\n      setDisplay(key)\n      formStep.current = key\n    },\n    get allowNext() {\n      return formStep.current < env.steps.length - 1\n    },\n    get allowBack() {\n      return formStep.current > 0\n    },\n    async next() {\n      try {\n        await env.form.validate()\n        if (env.form.valid) {\n          next()\n        }\n      } catch {}\n    },\n    async back() {\n      back()\n    },\n    async submit(onSubmit) {\n      return env.form?.submit?.(onSubmit)\n    },\n  })\n  return markRaw(formStep)\n}\n\nexport const FormStep: ComposedFormTab = connect(\n  observer(({ formStep, className, ...props }: IFormStepProps) => {\n    const field = useField<VoidField>()\n    const prefixCls = usePrefixCls('formily-step', props)\n    const schema = useFieldSchema()\n    const steps = parseSteps(schema)\n    const current = props.current || formStep?.current || 0\n    formStep?.connect?.(steps, field)\n    return (\n      <div className={cls(prefixCls, className)}>\n        <Steps\n          {...props}\n          style={{ marginBottom: 10, ...props.style }}\n          current={current}\n        >\n          {steps.map(({ props }, key) => {\n            return <Steps.Item {...props} key={key} />\n          })}\n        </Steps>\n        {steps.map(({ name, schema }, key) => {\n          if (key !== current) return\n          return <RecursionField key={key} name={name} schema={schema} />\n        })}\n      </div>\n    )\n  })\n)\n\nconst StepPane: React.FC<React.PropsWithChildren<StepProps>> = ({\n  children,\n}) => {\n  return <Fragment>{children}</Fragment>\n}\n\nFormStep.StepPane = StepPane\nFormStep.createFormStep = createFormStep\n\nexport default FormStep\n"
  },
  {
    "path": "packages/next/src/form-step/style.ts",
    "content": "import '@alifd/next/lib/step/style'\n"
  },
  {
    "path": "packages/next/src/form-tab/index.tsx",
    "content": "import React, { Fragment, useMemo } from 'react'\nimport { Tab as Tabs, Badge } from '@alifd/next'\nimport { model, markRaw } from '@formily/reactive'\nimport { isValid } from '@formily/shared'\nimport {\n  ItemProps as TabPaneProps,\n  TabProps as TabsProps,\n} from '@alifd/next/lib/tab'\nimport {\n  useField,\n  observer,\n  ReactFC,\n  useFieldSchema,\n  RecursionField,\n} from '@formily/react'\nimport { Schema, SchemaKey } from '@formily/json-schema'\nimport cls from 'classnames'\nimport { usePrefixCls } from '../__builtins__'\nexport interface IFormTab {\n  activeKey: SchemaKey\n  setActiveKey(key: SchemaKey): void\n}\n\nexport interface IFormTabProps extends TabsProps {\n  formTab?: IFormTab\n}\n\nexport interface IFormTabPaneProps extends TabPaneProps {\n  key: SchemaKey\n}\n\ninterface IFeedbackBadgeProps {\n  name: SchemaKey\n  tab: React.ReactNode\n}\n\ntype ComposedFormTab = React.FC<React.PropsWithChildren<IFormTabProps>> & {\n  TabPane: React.FC<React.PropsWithChildren<IFormTabPaneProps>>\n  createFormTab: (defaultActiveKey?: React.ReactText) => IFormTab\n}\n\nconst useTabs = () => {\n  const tabsField = useField()\n  const schema = useFieldSchema()\n  const tabs: { name: SchemaKey; props: any; schema: Schema }[] = []\n  schema.mapProperties((schema, name) => {\n    const field = tabsField.query(tabsField.address.concat(name)).take()\n    if (field?.display === 'none' || field?.display === 'hidden') return\n    if (schema['x-component']?.indexOf('TabPane') > -1) {\n      tabs.push({\n        name,\n        props: {\n          key: schema?.['x-component-props']?.key || name,\n          ...schema?.['x-component-props'],\n        },\n        schema,\n      })\n    }\n  })\n  return tabs\n}\n\nconst createFormTab = (defaultActiveKey?: string) => {\n  const formTab = model({\n    activeKey: defaultActiveKey,\n    setActiveKey(key: string) {\n      formTab.activeKey = key\n    },\n  })\n  return markRaw(formTab)\n}\n\nconst FeedbackBadge: ReactFC<IFeedbackBadgeProps> = observer((props) => {\n  const field = useField()\n  const errors = field.form.queryFeedbacks({\n    type: 'error',\n    address: `${field.address.concat(props.name)}.*`,\n  })\n  if (errors.length) {\n    return (\n      <Badge className=\"errors-badge\" count={errors.length}>\n        {props.tab}\n      </Badge>\n    )\n  }\n  return <Fragment>{props.tab}</Fragment>\n})\n\nexport const FormTab: ComposedFormTab = observer(\n  ({ formTab, ...props }: IFormTabProps) => {\n    const tabs = useTabs()\n    const _formTab = useMemo(() => {\n      return formTab ? formTab : createFormTab()\n    }, [])\n    const prefixCls = usePrefixCls('formily-tab', props)\n    const activeKey = props.activeKey || _formTab?.activeKey\n\n    return (\n      <Tabs\n        {...props}\n        {...(isValid(activeKey) && { activeKey })}\n        className={cls(prefixCls, props.className)}\n        onChange={(key) => {\n          props.onChange?.(key)\n          _formTab?.setActiveKey?.(key)\n        }}\n        lazyLoad={false}\n      >\n        {tabs.map(({ props, schema, name }, key) => (\n          <Tabs.Item\n            key={key}\n            {...props}\n            tab={<FeedbackBadge name={name} tab={props.tab} />}\n          >\n            <RecursionField schema={schema} name={name} />\n          </Tabs.Item>\n        ))}\n      </Tabs>\n    )\n  }\n) as unknown as ComposedFormTab\n\nconst TabPane: React.FC<React.PropsWithChildren<IFormTabPaneProps>> = ({\n  children,\n}) => {\n  return <Fragment>{children}</Fragment>\n}\n\nFormTab.TabPane = TabPane\nFormTab.createFormTab = createFormTab\n\nexport default FormTab\n"
  },
  {
    "path": "packages/next/src/form-tab/style.ts",
    "content": "import '@alifd/next/lib/tab/style'\nimport '@alifd/next/lib/badge/style'\n"
  },
  {
    "path": "packages/next/src/index.ts",
    "content": "import './style'\nexport * from './array-base'\nexport * from './array-table'\nexport * from './array-cards'\nexport * from './array-collapse'\nexport * from './array-items'\nexport * from './form-dialog'\nexport * from './form-drawer'\nexport * from './form-grid'\nexport * from './form-item'\nexport * from './form'\nexport * from './form-layout'\nexport * from './form-step'\nexport * from './form-tab'\nexport * from './form-collapse'\nexport * from './form-button-group'\nexport * from './input'\nexport * from './password'\nexport * from './preview-text'\nexport * from './radio'\nexport * from './checkbox'\nexport * from './select'\nexport * from './cascader'\nexport * from './space'\nexport * from './tree-select'\nexport * from './transfer'\nexport * from './date-picker'\nexport * from './date-picker2'\nexport * from './time-picker'\nexport * from './time-picker2'\nexport * from './number-picker'\nexport * from './switch'\nexport * from './upload'\nexport * from './submit'\nexport * from './reset'\nexport * from './editable'\nexport * from './select-table'\n"
  },
  {
    "path": "packages/next/src/input/index.tsx",
    "content": "import { connect, mapReadPretty, mapProps } from '@formily/react'\nimport { Input as NextInput } from '@alifd/next'\nimport { InputProps, TextAreaProps } from '@alifd/next/lib/input'\nimport { PreviewText } from '../preview-text'\nimport { mapSize, mapStatus } from '../__builtins__'\n\ntype ComposedInput = React.FC<React.PropsWithChildren<InputProps>> & {\n  TextArea?: React.FC<React.PropsWithChildren<TextAreaProps>>\n}\n\nexport const Input: ComposedInput = connect(\n  NextInput,\n  mapProps(mapSize, mapStatus),\n  mapReadPretty(PreviewText.Input)\n)\n\nInput.TextArea = connect(\n  NextInput.TextArea,\n  mapProps(mapSize, mapStatus),\n  mapReadPretty(PreviewText.Input)\n)\n\nexport default Input\n"
  },
  {
    "path": "packages/next/src/input/style.ts",
    "content": "import '@alifd/next/lib/input/style'\n"
  },
  {
    "path": "packages/next/src/main.scss",
    "content": "// auto generated code\n@import './array-base/main.scss';\n@import './array-cards/main.scss';\n@import './array-collapse/main.scss';\n@import './array-items/main.scss';\n@import './array-table/main.scss';\n@import './date-picker2/main.scss';\n@import './editable/main.scss';\n@import './form-button-group/main.scss';\n@import './form-grid/main.scss';\n@import './form-item/main.scss';\n@import './form-layout/main.scss';\n@import './form/main.scss';\n@import './preview-text/main.scss';\n@import './select-table/main.scss';\n@import './space/main.scss';\n@import './upload/main.scss';\n"
  },
  {
    "path": "packages/next/src/number-picker/index.tsx",
    "content": "import { connect, mapProps, mapReadPretty } from '@formily/react'\nimport { NumberPicker as InputNumber } from '@alifd/next'\nimport { PreviewText } from '../preview-text'\nimport { mapSize, mapStatus } from '../__builtins__'\nexport const NumberPicker = connect(\n  InputNumber,\n  mapProps(mapSize, mapStatus),\n  mapReadPretty(PreviewText.NumberPicker)\n)\n\nexport default NumberPicker\n"
  },
  {
    "path": "packages/next/src/number-picker/style.ts",
    "content": "import '@alifd/next/lib/number-picker/style'\n"
  },
  {
    "path": "packages/next/src/password/PasswordStrength.tsx",
    "content": "import React, { Fragment } from 'react'\nimport { ReactFC } from '@formily/react'\nimport { isFn } from '@formily/shared'\n\ntype ReactRenderPropsChildren<T = any> =\n  | React.ReactNode\n  | ((props: T) => React.ReactElement)\n\ninterface IPasswordStrengthProps {\n  value?: React.ReactText\n  children?: ReactRenderPropsChildren<number>\n}\n\nconst isNum = function (c) {\n  return c >= 48 && c <= 57\n}\nconst isLower = function (c) {\n  return c >= 97 && c <= 122\n}\nconst isUpper = function (c) {\n  return c >= 65 && c <= 90\n}\nconst isSymbol = function (c) {\n  return !(isLower(c) || isUpper(c) || isNum(c))\n}\nconst isLetter = function (c) {\n  return isLower(c) || isUpper(c)\n}\n\nconst getStrength = (val) => {\n  if (!val) return 0\n  let num = 0\n  let lower = 0\n  let upper = 0\n  let symbol = 0\n  let MNS = 0\n  let rep = 0\n  let repC = 0\n  let consecutive = 0\n  let sequential = 0\n  const len = () => num + lower + upper + symbol\n  const callme = () => {\n    let re = num > 0 ? 1 : 0\n    re += lower > 0 ? 1 : 0\n    re += upper > 0 ? 1 : 0\n    re += symbol > 0 ? 1 : 0\n    if (re > 2 && len() >= 8) {\n      return re + 1\n    } else {\n      return 0\n    }\n  }\n  for (let i = 0; i < val.length; i++) {\n    const c = val.charCodeAt(i)\n    if (isNum(c)) {\n      num++\n      if (i !== 0 && i !== val.length - 1) {\n        MNS++\n      }\n      if (i > 0 && isNum(val.charCodeAt(i - 1))) {\n        consecutive++\n      }\n    } else if (isLower(c)) {\n      lower++\n      if (i > 0 && isLower(val.charCodeAt(i - 1))) {\n        consecutive++\n      }\n    } else if (isUpper(c)) {\n      upper++\n      if (i > 0 && isUpper(val.charCodeAt(i - 1))) {\n        consecutive++\n      }\n    } else {\n      symbol++\n      if (i !== 0 && i !== val.length - 1) {\n        MNS++\n      }\n    }\n    let exists = false\n    for (let j = 0; j < val.length; j++) {\n      if (val[i] === val[j] && i !== j) {\n        exists = true\n        repC += Math.abs(val.length / (j - i))\n      }\n    }\n    if (exists) {\n      rep++\n      const unique = val.length - rep\n      repC = unique ? Math.ceil(repC / unique) : Math.ceil(repC)\n    }\n    if (i > 1) {\n      const last1 = val.charCodeAt(i - 1)\n      const last2 = val.charCodeAt(i - 2)\n      if (isLetter(c)) {\n        if (isLetter(last1) && isLetter(last2)) {\n          const v = val.toLowerCase()\n          const vi = v.charCodeAt(i)\n          const vi1 = v.charCodeAt(i - 1)\n          const vi2 = v.charCodeAt(i - 2)\n          if (vi - vi1 === vi1 - vi2 && Math.abs(vi - vi1) === 1) {\n            sequential++\n          }\n        }\n      } else if (isNum(c)) {\n        if (isNum(last1) && isNum(last2)) {\n          if (c - last1 === last1 - last2 && Math.abs(c - last1) === 1) {\n            sequential++\n          }\n        }\n      } else {\n        if (isSymbol(last1) && isSymbol(last2)) {\n          if (c - last1 === last1 - last2 && Math.abs(c - last1) === 1) {\n            sequential++\n          }\n        }\n      }\n    }\n  }\n  let sum = 0\n  const length = len()\n  sum += 4 * length\n  if (lower > 0) {\n    sum += 2 * (length - lower)\n  }\n  if (upper > 0) {\n    sum += 2 * (length - upper)\n  }\n  if (num !== length) {\n    sum += 4 * num\n  }\n  sum += 6 * symbol\n  sum += 2 * MNS\n  sum += 2 * callme()\n  if (length === lower + upper) {\n    sum -= length\n  }\n  if (length === num) {\n    sum -= num\n  }\n  sum -= repC\n  sum -= 2 * consecutive\n  sum -= 3 * sequential\n  sum = sum < 0 ? 0 : sum\n  sum = sum > 100 ? 100 : sum\n\n  if (sum >= 80) {\n    return 100\n  } else if (sum >= 60) {\n    return 80\n  } else if (sum >= 40) {\n    return 60\n  } else if (sum >= 20) {\n    return 40\n  } else {\n    return 20\n  }\n}\n\nexport const PasswordStrength: ReactFC<IPasswordStrengthProps> = (props) => {\n  if (isFn(props.children)) {\n    return props.children(getStrength(String(props.value)))\n  } else {\n    return <Fragment>{props.children}</Fragment>\n  }\n}\n"
  },
  {
    "path": "packages/next/src/password/index.tsx",
    "content": "import React from 'react'\nimport { connect, mapProps, mapReadPretty } from '@formily/react'\nimport { Input } from '@alifd/next'\nimport { PasswordProps } from '@alifd/next/lib/input'\nimport { PasswordStrength } from './PasswordStrength'\nimport { PreviewText } from '../preview-text'\nimport { mapStatus, mapSize } from '../__builtins__'\nexport interface IPasswordProps extends PasswordProps {\n  checkStrength: boolean\n}\n\nexport const Password = connect(\n  (props: IPasswordProps) => {\n    const { value, className, checkStrength, ...others } = props\n    const blockStyle: React.CSSProperties = {\n      position: 'absolute',\n      zIndex: 1,\n      height: 8,\n      top: 0,\n      background: '#fff',\n      width: 1,\n      transform: 'translate(-50%, 0)',\n    }\n    return (\n      <span className={className}>\n        <Input.Password\n          {...others}\n          style={{ ...others.style, width: '100%' }}\n          value={value}\n        />\n        {checkStrength && (\n          <PasswordStrength value={String(value)}>\n            {(score) => {\n              return (\n                <div\n                  style={{\n                    background: '#e0e0e0',\n                    marginBottom: 3,\n                    position: 'relative',\n                  }}\n                >\n                  <div style={{ ...blockStyle, left: '20%' }} />\n                  <div style={{ ...blockStyle, left: '40%' }} />\n                  <div style={{ ...blockStyle, left: '60%' }} />\n                  <div style={{ ...blockStyle, left: '80%' }} />\n                  <div\n                    style={{\n                      position: 'relative',\n                      backgroundImage:\n                        '-webkit-linear-gradient(left, #ff5500, #ff9300)',\n                      transition: 'all 0.35s ease-in-out',\n                      height: 8,\n                      width: '100%',\n                      marginTop: 5,\n                      clipPath: `polygon(0 0,${score}% 0,${score}% 100%,0 100%)`,\n                    }}\n                  />\n                </div>\n              )\n            }}\n          </PasswordStrength>\n        )}\n      </span>\n    )\n  },\n  mapProps(mapSize, mapStatus),\n  mapReadPretty(PreviewText.Input)\n)\n\nexport default Password\n"
  },
  {
    "path": "packages/next/src/password/style.ts",
    "content": "import '@alifd/next/lib/input/style'\n"
  },
  {
    "path": "packages/next/src/preview-text/index.tsx",
    "content": "import React, { createContext, useContext } from 'react'\nimport { isArr, isEmpty, isValid } from '@formily/shared'\nimport { Field } from '@formily/core'\nimport { useField, observer } from '@formily/react'\nimport { InputProps } from '@alifd/next/lib/input'\nimport { NumberPickerProps } from '@alifd/next/lib/number-picker'\nimport { SelectProps } from '@alifd/next/lib/select'\nimport { TreeSelectProps } from '@alifd/next/lib/tree-select'\nimport { CascaderSelectProps } from '@alifd/next/lib/cascader-select'\nimport {\n  DatePickerProps,\n  RangePickerProps as DateRangePickerProps,\n} from '@alifd/next/lib/date-picker'\nimport { TimePickerProps } from '@alifd/next/lib/time-picker'\nimport {\n  TimePickerProps as TimePicker2Props,\n  RangePickerProps as TimeRangePicker2Props,\n} from '@alifd/next/types/time-picker2'\nimport {\n  Tag,\n  Input as NextInput,\n  NumberPicker as NextNumberPicker,\n  CascaderSelect as NextCascader,\n} from '@alifd/next'\nimport cls from 'classnames'\nimport { formatMomentValue, usePrefixCls } from '../__builtins__'\n\nconst PlaceholderContext = createContext<React.ReactNode>('N/A')\n\nconst Placeholder = PlaceholderContext.Provider\n\nconst usePlaceholder = (value?: any) => {\n  const placeholder = useContext(PlaceholderContext) || 'N/A'\n  return !isEmpty(value) ? value : placeholder\n}\n\nconst Input: React.FC<React.PropsWithChildren<InputProps>> = (props) => {\n  return <NextInput {...props} isPreview />\n}\n\nconst NumberPicker: React.FC<React.PropsWithChildren<NumberPickerProps>> = (\n  props\n) => {\n  return <NextNumberPicker {...props} isPreview />\n}\n\nconst Select: React.FC<React.PropsWithChildren<SelectProps>> = observer(\n  (props) => {\n    const field = useField<Field>()\n    const prefixCls = usePrefixCls('form-preview', props)\n    const dataSource: any[] = field?.dataSource?.length\n      ? field.dataSource\n      : props?.dataSource?.length\n      ? props.dataSource\n      : []\n    const placeholder = usePlaceholder()\n    const getSelected = () => {\n      const value = props.value\n      if (props.mode === 'multiple' || props.mode === 'tag') {\n        if (props.useDetailValue) {\n          return isArr(value) ? value : []\n        } else {\n          return isArr(value)\n            ? value.map((val) => ({ label: val, value: val }))\n            : []\n        }\n      } else {\n        if (props.useDetailValue) {\n          return isValid(value) ? [value] : []\n        } else {\n          return isValid(value) ? [{ label: value, value }] : []\n        }\n      }\n    }\n\n    const getLabel = (target: any) => {\n      return (\n        dataSource?.find((item) => item.value == target?.value)?.label ||\n        target.label ||\n        placeholder\n      )\n    }\n\n    const getLabels = () => {\n      const selected = getSelected()\n      if (!selected.length) return placeholder\n      if (selected.length === 1) return getLabel(selected[0])\n      return selected.map((item, key) => {\n        return (\n          <Tag type=\"primary\" size=\"small\" key={key}>\n            {getLabel(item)}\n          </Tag>\n        )\n      })\n    }\n\n    return <div className={cls(prefixCls, props.className)}>{getLabels()}</div>\n  }\n)\n\nconst TreeSelect: React.FC<React.PropsWithChildren<TreeSelectProps>> = observer(\n  (props) => {\n    const field = useField<Field>()\n    const placeholder = usePlaceholder()\n    const prefixCls = usePrefixCls('form-preview', props)\n    const dataSource = field?.dataSource?.length\n      ? field.dataSource\n      : props?.dataSource?.length\n      ? props.dataSource\n      : []\n    const getSelected = () => {\n      const value = props.value\n      if (props.multiple) {\n        if (props['useDetailValue']) {\n          return isArr(value) ? value : []\n        } else {\n          return isArr(value)\n            ? value.map((val) => ({ label: val, value: val }))\n            : []\n        }\n      } else {\n        if (props['useDetailValue']) {\n          return value ? [value] : []\n        } else {\n          return value ? [{ label: value, value }] : []\n        }\n      }\n    }\n\n    const findLabel = (value: any, dataSource: any[]) => {\n      for (let i = 0; i < dataSource?.length; i++) {\n        const item = dataSource[i]\n        if (item?.value === value) {\n          return item?.label\n        } else {\n          const childLabel = findLabel(value, item?.children)\n          if (childLabel) return childLabel\n        }\n      }\n    }\n\n    const getLabels = () => {\n      const selected = getSelected()\n      if (!selected?.length)\n        return (\n          <Tag type=\"primary\" size=\"small\">\n            {placeholder}\n          </Tag>\n        )\n      return selected.map(({ value, label }, key) => {\n        return (\n          <Tag type=\"primary\" size=\"small\" key={key}>\n            {findLabel(value, dataSource) || label || placeholder}\n          </Tag>\n        )\n      })\n    }\n    return <div className={cls(prefixCls, props.className)}>{getLabels()}</div>\n  }\n)\n\nconst Cascader: React.FC<React.PropsWithChildren<CascaderSelectProps>> =\n  observer((props) => {\n    const field = useField<Field>()\n    const prefixCls = usePrefixCls('form-preview', props)\n    return (\n      <NextCascader\n        {...props}\n        className={prefixCls}\n        dataSource={field.dataSource}\n        isPreview\n      />\n    )\n  })\n\nconst DatePicker: React.FC<React.PropsWithChildren<DatePickerProps>> = (\n  props\n) => {\n  const placeholder = usePlaceholder()\n  const prefixCls = usePrefixCls('form-preview', props)\n  const getLabels = () => {\n    const labels = formatMomentValue(props.value, props.format, placeholder)\n    return isArr(labels) ? labels.join('~') : labels\n  }\n  return <div className={cls(prefixCls, props.className)}>{getLabels()}</div>\n}\n\nconst DateRangePicker: React.FC<\n  React.PropsWithChildren<DateRangePickerProps>\n> = (props) => {\n  const placeholder = usePlaceholder()\n  const prefixCls = usePrefixCls('form-preview', props)\n  const getLabels = () => {\n    const labels = formatMomentValue(props.value, props.format, placeholder)\n    return isArr(labels) ? labels.join('~') : labels\n  }\n  return <div className={cls(prefixCls, props.className)}>{getLabels()}</div>\n}\n\nconst TimePicker: React.FC<React.PropsWithChildren<TimePickerProps>> = (\n  props\n) => {\n  const placeholder = usePlaceholder()\n  const prefixCls = usePrefixCls('form-preview', props)\n  const getLabels = () => {\n    const labels = formatMomentValue(props.value, props.format, placeholder)\n    return isArr(labels) ? labels.join('~') : labels\n  }\n  return <div className={cls(prefixCls, props.className)}>{getLabels()}</div>\n}\n\nconst TimePicker2: React.FC<React.PropsWithChildren<TimePicker2Props>> = (\n  props\n) => {\n  const placeholder = usePlaceholder()\n  const prefixCls = usePrefixCls('form-preview', props)\n  const getLabels = () => {\n    const labels = formatMomentValue(props.value, props.format, placeholder)\n    return isArr(labels) ? labels.join('~') : labels\n  }\n  return <div className={cls(prefixCls, props.className)}>{getLabels()}</div>\n}\n\nconst TimeRangePicker2: React.FC<\n  React.PropsWithChildren<TimeRangePicker2Props>\n> = (props) => {\n  const placeholder = usePlaceholder()\n  const prefixCls = usePrefixCls('form-preview', props)\n  const getLabels = () => {\n    const labels = formatMomentValue(props.value, props.format, placeholder)\n    return isArr(labels) ? labels.join('~') : labels\n  }\n  return <div className={cls(prefixCls, props.className)}>{getLabels()}</div>\n}\n\nconst Text = (props: React.PropsWithChildren<any>) => {\n  const prefixCls = usePrefixCls('form-preview', props)\n\n  return (\n    <div className={cls(prefixCls, props.className)} style={props.style}>\n      {usePlaceholder(props.value)}\n    </div>\n  )\n}\n\nText.Input = Input\nText.NumberPicker = NumberPicker\nText.Select = Select\nText.TreeSelect = TreeSelect\nText.Cascader = Cascader\nText.DatePicker = DatePicker\nText.DateRangePicker = DateRangePicker\nText.TimePicker = TimePicker\nText.TimePicker2 = TimePicker2\nText.TimeRangePicker2 = TimeRangePicker2\nText.Placeholder = Placeholder\nText.usePlaceholder = usePlaceholder\n\nexport const PreviewText = Text\n\nexport default PreviewText\n"
  },
  {
    "path": "packages/next/src/preview-text/main.scss",
    "content": "@import '~@alifd/next/lib/core/index-noreset.scss';\n\n$form-preview-prefix-cls: '#{$css-prefix}form-preview';\n\n.#{$form-preview-prefix-cls} {\n  font-weight: 400;\n  word-break: break-all;\n\n  .#{$css-prefix}tag {\n    margin-right: 4px;\n  }\n\n  .#{$css-prefix}tag:last-child {\n    margin-right: 0;\n  }\n}\n\np.#{$form-preview-prefix-cls} {\n  margin: 0;\n  font-size: inherit;\n  line-height: inherit;\n}\n"
  },
  {
    "path": "packages/next/src/preview-text/style.ts",
    "content": "import '@alifd/next/lib/tag/style'\nimport './main.scss'\n"
  },
  {
    "path": "packages/next/src/radio/index.tsx",
    "content": "import { connect, mapProps, mapReadPretty } from '@formily/react'\nimport { Radio as NextRadio } from '@alifd/next'\nimport {\n  RadioProps,\n  GroupProps as RadioGroupProps,\n} from '@alifd/next/lib/radio'\nimport { PreviewText } from '../preview-text'\nimport { mapSize } from '../__builtins__'\n\ntype ComposedRadio = React.FC<React.PropsWithChildren<RadioProps>> & {\n  Group?: React.FC<React.PropsWithChildren<RadioGroupProps>>\n}\n\nexport const Radio: ComposedRadio = connect(\n  NextRadio,\n  mapProps(\n    {\n      value: 'checked',\n    },\n    mapSize\n  )\n)\n\nRadio.Group = connect(\n  NextRadio.Group,\n  mapProps(\n    {\n      dataSource: true,\n    },\n    mapSize\n  ),\n  mapReadPretty(PreviewText.Select)\n)\n\nexport default Radio\n"
  },
  {
    "path": "packages/next/src/radio/style.ts",
    "content": "import '@alifd/next/lib/radio/style'\n"
  },
  {
    "path": "packages/next/src/reset/index.tsx",
    "content": "import React from 'react'\nimport { Button } from '@alifd/next'\nimport { ButtonProps } from '@alifd/next/lib/button'\nimport { IFormFeedback, IFieldResetOptions } from '@formily/core'\nimport { useParentForm } from '@formily/react'\n\nexport interface IResetProps extends IFieldResetOptions, ButtonProps {\n  onClick?: (e: React.MouseEvent<Element, MouseEvent>) => any\n  onResetValidateSuccess?: (payload: any) => void\n  onResetValidateFailed?: (feedbacks: IFormFeedback[]) => void\n}\n\nexport const Reset: React.FC<React.PropsWithChildren<IResetProps>> = ({\n  forceClear,\n  validate,\n  onResetValidateFailed,\n  onResetValidateSuccess,\n  ...props\n}: IResetProps) => {\n  const form = useParentForm()\n  return (\n    <Button\n      {...props}\n      onClick={(e) => {\n        if (props.onClick) {\n          if (props.onClick(e) === false) return\n        }\n        form\n          .reset('*', {\n            forceClear,\n            validate,\n          })\n          .then(onResetValidateSuccess)\n          .catch(onResetValidateFailed)\n      }}\n    >\n      {props.children}\n    </Button>\n  )\n}\n\nexport default Reset\n"
  },
  {
    "path": "packages/next/src/reset/style.ts",
    "content": "import '@alifd/next/lib/button/style'\n"
  },
  {
    "path": "packages/next/src/select/index.tsx",
    "content": "import { connect, mapReadPretty, mapProps } from '@formily/react'\nimport { isVoidField } from '@formily/core'\nimport { Select as NextSelect } from '@alifd/next'\nimport { PreviewText } from '../preview-text'\nimport { mapSize, mapStatus } from '../__builtins__'\n\nconst patchDataSource = (dataSource: any = []) => {\n  const removeEmptyChildren = (data: any) => {\n    const result = { ...data }\n    if (!result.children || result.children.length === 0) {\n      delete result.children\n    } else {\n      result.children = result.children.map(removeEmptyChildren)\n    }\n    return result\n  }\n  return dataSource.map(removeEmptyChildren)\n}\n\nexport const Select = connect(\n  NextSelect,\n  mapProps(\n    (props, field) => {\n      if (isVoidField(field)) {\n        return props\n      }\n      return {\n        ...props,\n        dataSource: patchDataSource(props.dataSource ?? field?.dataSource),\n      }\n    },\n    mapSize,\n    mapStatus\n  ),\n  mapReadPretty(PreviewText.Select)\n)\n\nexport default Select\n"
  },
  {
    "path": "packages/next/src/select/style.ts",
    "content": "import '@alifd/next/lib/select/style'\n"
  },
  {
    "path": "packages/next/src/select-table/index.tsx",
    "content": "import React, { useState, useMemo } from 'react'\nimport {\n  observer,\n  useFieldSchema,\n  useField,\n  Schema,\n  RecursionField,\n} from '@formily/react'\nimport cls from 'classnames'\nimport { GeneralField, FieldDisplayTypes } from '@formily/core'\nimport { isArr, isBool, isFn } from '@formily/shared'\nimport { Search, Table } from '@alifd/next'\nimport { TableProps, ColumnProps } from '@alifd/next/types/table'\nimport { SearchProps } from '@alifd/next/types/search'\nimport { useFilterOptions } from './useFilterOptions'\nimport { useFlatOptions } from './useFlatOptions'\nimport { useSize } from './useSize'\nimport { useTitleAddon } from './useTitleAddon'\nimport { useCheckSlackly, getIndeterminate } from './useCheckSlackly'\nimport { getUISelected, getOutputData } from './utils'\nimport { usePrefixCls } from '../__builtins__'\n\ninterface ObservableColumnSource {\n  field: GeneralField\n  columnProps: ColumnProps\n  schema: Schema\n  display: FieldDisplayTypes\n  name: string\n}\n\ntype IFilterOption = boolean | ((option: any, keyword: string) => boolean)\n\ntype IFilterSort = (optionA: any, optionB: any) => number\n\nexport interface ISelectTableColumnProps extends ColumnProps {\n  key: React.ReactText\n}\n\nexport interface ISelectTableProps\n  extends Omit<TableProps, 'primaryKey' | 'onChange'> {\n  mode?: 'multiple' | 'single'\n  dataSource?: any[]\n  optionAsValue?: boolean\n  valueType?: 'all' | 'parent' | 'child' | 'path'\n  showSearch?: boolean\n  searchProps?: SearchProps\n  primaryKey?: string | ((record: any) => string)\n  filterOption?: IFilterOption\n  filterSort?: IFilterSort\n  onSearch?: (keyword: string) => void\n  onChange?: (value: any, options: any) => void\n  value?: any\n  rowSelection?: TableProps['rowSelection'] & {\n    checkStrictly?: boolean\n  }\n}\n\ntype ComposedSelectTable = React.FC<\n  React.PropsWithChildren<ISelectTableProps>\n> & {\n  Column?: React.FC<React.PropsWithChildren<ISelectTableColumnProps>>\n}\n\nconst isColumnComponent = (schema: Schema) => {\n  return schema['x-component']?.indexOf('Column') > -1\n}\n\nconst useSources = () => {\n  const arrayField = useField()\n  const schema = useFieldSchema()\n  const parseSources = (schema: Schema): ObservableColumnSource[] => {\n    if (isColumnComponent(schema)) {\n      if (!schema['x-component-props']?.['dataIndex'] && !schema['name'])\n        return []\n      const name = schema['x-component-props']?.['dataIndex'] || schema['name']\n      const field = arrayField.query(arrayField.address.concat(name)).take()\n      const columnProps =\n        field?.component?.[1] || schema['x-component-props'] || {}\n      const display = field?.display || schema['x-display']\n      return [\n        {\n          name,\n          display,\n          field,\n          schema,\n          columnProps: {\n            title: field?.title || columnProps.title,\n            ...columnProps,\n          },\n        },\n      ]\n    } else if (schema.properties) {\n      return schema.reduceProperties((buf, schema) => {\n        return buf.concat(parseSources(schema))\n      }, [])\n    }\n  }\n\n  const parseArrayItems = (schema: Schema['items']) => {\n    if (!schema) return []\n    const sources: ObservableColumnSource[] = []\n    const items = isArr(schema) ? schema : [schema]\n    return items.reduce((columns, schema) => {\n      const item = parseSources(schema)\n      if (item) {\n        return columns.concat(item)\n      }\n      return columns\n    }, sources)\n  }\n\n  const validSchema = (\n    schema?.type === 'array' && schema?.items ? schema.items : schema\n  ) as Schema\n\n  return parseArrayItems(validSchema)\n}\n\nconst useColumns = (\n  sources: ObservableColumnSource[]\n): TableProps['columns'] => {\n  return sources.reduce((buf, { name, columnProps, schema, display }, key) => {\n    if (display !== 'visible') return buf\n    if (!isColumnComponent(schema)) return buf\n    return buf.concat({\n      ...columnProps,\n      key,\n      dataIndex: name,\n    })\n  }, [])\n}\n\nconst addPrimaryKey = (dataSource, rowKey, primaryKey) =>\n  dataSource.map((item) => {\n    const children = isArr(item.children)\n      ? addPrimaryKey(item.children, rowKey, primaryKey)\n      : {}\n    return {\n      ...item,\n      ...children,\n      [primaryKey]: rowKey(item),\n    }\n  })\n\nexport const SelectTable: ComposedSelectTable = observer((props) => {\n  const {\n    mode = 'multiple',\n    dataSource: propsDataSource,\n    optionAsValue,\n    valueType = 'all',\n    showSearch = false,\n    filterOption,\n    filterSort,\n    onSearch,\n    searchProps,\n    className,\n    value,\n    onChange,\n    rowSelection,\n    primaryKey: rowKey = 'key',\n    ...otherTableProps\n  } = props\n  const prefixCls = usePrefixCls('formily-select-table', props)\n  const [searchValue, setSearchValue] = useState<string>()\n  const field = useField() as any\n  const loading = isBool(props.loading) ? props.loading : field.loading\n  const disabled = field.disabled\n  const readOnly = field.readOnly\n  const readPretty = field.readPretty\n  const { searchSize, tableSize } = useSize(\n    field.decoratorProps?.size,\n    searchProps?.size,\n    props?.size\n  )\n  const primaryKey = isFn(rowKey) ? '__formily_key__' : rowKey\n  const sources = useSources()\n  const columns = useColumns(sources)\n\n  // dataSource\n  let dataSource = isArr(propsDataSource) ? propsDataSource : field.dataSource\n  dataSource = isFn(rowKey)\n    ? addPrimaryKey(dataSource, rowKey, primaryKey)\n    : dataSource\n\n  // Filter dataSource By Search\n  const filteredDataSource = useFilterOptions(\n    dataSource,\n    searchValue,\n    filterOption,\n    rowSelection?.checkStrictly\n  )\n\n  // Order dataSource By filterSort\n  const orderedFilteredDataSource = useMemo(() => {\n    if (!filterSort) {\n      return filteredDataSource\n    }\n    return [...filteredDataSource].sort((a, b) => filterSort(a, b))\n  }, [filteredDataSource, filterSort])\n\n  const flatDataSource = useFlatOptions(dataSource)\n  const flatFilteredDataSource = useFlatOptions(filteredDataSource)\n\n  // 分页或异步查询时，dataSource会丢失已选数据，配置optionAsValue则无法获取已选数据，需要进行合并\n  const getWholeDataSource = () => {\n    if (optionAsValue && mode === 'multiple' && value?.length) {\n      const map = new Map()\n      const arr = [...flatDataSource, ...value]\n      arr.forEach((item) => {\n        if (!map.has(item[primaryKey])) {\n          map.set(item[primaryKey], item)\n        }\n      })\n      return [...map.values()]\n    }\n    return flatDataSource\n  }\n\n  // selected keys for Table UI\n  const selected = getUISelected(\n    value,\n    flatDataSource,\n    primaryKey,\n    valueType,\n    optionAsValue,\n    mode,\n    rowSelection?.checkStrictly,\n    rowKey\n  )\n\n  // readPretty Value\n  const readPrettyDataSource = useFilterOptions(\n    orderedFilteredDataSource,\n    selected,\n    (value, item) => value.includes(item[primaryKey])\n  )\n\n  const onInnerSearch = (searchText) => {\n    const formatted = (searchText || '').trim()\n    setSearchValue(searchText)\n    onSearch?.(formatted)\n  }\n\n  const onInnerChange = (selectedRowKeys: any[]) => {\n    if (readOnly) {\n      return\n    }\n    // 筛选后onChange默认的records数据不完整，此处需使用完整数据过滤\n    const wholeRecords = getWholeDataSource().filter((item) =>\n      selectedRowKeys.includes(item?.[primaryKey])\n    )\n\n    const { outputValue, outputOptions } = getOutputData(\n      selectedRowKeys,\n      wholeRecords,\n      dataSource,\n      primaryKey,\n      valueType,\n      optionAsValue,\n      mode,\n      rowSelection?.checkStrictly\n    )\n\n    onChange?.(outputValue, outputOptions)\n  }\n\n  const onRowClick = (record) => {\n    if (readPretty || disabled || readOnly || record?.disabled) {\n      return\n    }\n    const selectedRowKey = record?.[primaryKey]\n    const isSelected = selected?.includes(selectedRowKey)\n    let selectedRowKeys = []\n    if (mode === 'single') {\n      selectedRowKeys = [selectedRowKey]\n    } else {\n      if (isSelected) {\n        selectedRowKeys = selected.filter((item) => item !== selectedRowKey)\n      } else {\n        selectedRowKeys = [...selected, selectedRowKey]\n      }\n    }\n    if (rowSelection?.checkStrictly !== false) {\n      onInnerChange(selectedRowKeys)\n    } else {\n      onSlacklyChange(selectedRowKeys)\n    }\n  }\n\n  // TreeData SlacklyChange\n  const onSlacklyChange = (currentSelected: any[]) => {\n    let { selectedRowKeys } = useCheckSlackly(\n      currentSelected,\n      selected,\n      flatDataSource,\n      flatFilteredDataSource,\n      primaryKey,\n      rowSelection?.checkStrictly\n    )\n    onInnerChange(selectedRowKeys)\n  }\n\n  // Table All Checkbox\n  const titleAddon = useTitleAddon(\n    selected,\n    flatDataSource,\n    flatFilteredDataSource,\n    primaryKey,\n    mode,\n    disabled,\n    readOnly,\n    rowSelection?.checkStrictly,\n    onInnerChange\n  )\n\n  return (\n    <div className={prefixCls}>\n      {showSearch ? (\n        <Search\n          {...searchProps}\n          className={cls(`${prefixCls}-search`, searchProps?.className)}\n          style={{ width: '100%', ...searchProps?.style }}\n          onSearch={onInnerSearch}\n          onChange={onInnerSearch}\n          disabled={disabled}\n          readOnly={readOnly}\n          size={searchSize}\n          buttonProps={{ ...searchProps?.buttonProps, loading }} // fusion\n        />\n      ) : null}\n      <Table\n        {...otherTableProps}\n        className={cls(`${prefixCls}-table`, className)}\n        dataSource={\n          readPretty ? readPrettyDataSource : orderedFilteredDataSource\n        }\n        rowSelection={\n          readPretty\n            ? undefined\n            : {\n                ...rowSelection,\n                ...titleAddon,\n                getProps: (record, index) => ({\n                  ...(rowSelection?.getProps?.(record, index) as any),\n                  ...(rowSelection?.checkStrictly !== false\n                    ? {}\n                    : {\n                        indeterminate: getIndeterminate(\n                          record,\n                          flatDataSource,\n                          selected,\n                          primaryKey\n                        ),\n                      }), // 父子关联模式indeterminate值\n                  disabled: disabled || record?.disabled,\n                }), // fusion\n                selectedRowKeys: selected,\n                onChange:\n                  rowSelection?.checkStrictly !== false\n                    ? onInnerChange\n                    : onSlacklyChange,\n                mode,\n              }\n        }\n        columns={props.columns || columns}\n        primaryKey={primaryKey}\n        loading={loading}\n        size={tableSize}\n        onRowClick={(record, index, e) => {\n          // fusion\n          onRowClick(record)\n          props.onRowClick?.(record, index, e)\n        }}\n      >\n        {''}\n      </Table>\n      {sources.map((column, key) => {\n        //专门用来承接对Column的状态管理\n        if (!isColumnComponent(column.schema)) return\n        return React.createElement(RecursionField, {\n          name: column.name,\n          schema: column.schema,\n          onlyRenderSelf: true,\n          key,\n        })\n      })}\n    </div>\n  )\n})\n\nconst TableColumn: React.FC<\n  React.PropsWithChildren<ISelectTableColumnProps>\n> = () => <></>\n\nSelectTable.Column = TableColumn\n\nexport default SelectTable\n"
  },
  {
    "path": "packages/next/src/select-table/main.scss",
    "content": "@import '~@alifd/next/lib/core/index-noreset.scss';\n@import '~@alifd/next/lib/form/scss/variable.scss';\n\n$select-table-prefix-cls: '#{$css-prefix}formily-select-table';\n\n.#{$select-table-prefix-cls} {\n  .#{$select-table-prefix-cls}-search {\n    margin-bottom: 8px;\n  }\n}\n"
  },
  {
    "path": "packages/next/src/select-table/style.ts",
    "content": "import '@alifd/next/lib/select/style'\nimport './main.scss'\n"
  },
  {
    "path": "packages/next/src/select-table/useCheckSlackly.tsx",
    "content": "import {\n  getTreeKeys,\n  hasSelectedKey,\n  completedKeys,\n  getCompatibleAllSelected,\n} from './utils'\n\n/**\n * 判断该字段的 indeterminate 属性\n * @param record 当前字段\n * @param flatDataSource 完整平铺数据\n * @param selected 已选中的字段值集合\n * @param primaryKey 键名称\n * @returns indeterminate 属性值\n */\nconst getIndeterminate = (\n  record: any,\n  flatDataSource: any,\n  selected: any[],\n  primaryKey: string\n) => {\n  if (selected?.includes(record[primaryKey])) {\n    return undefined\n  }\n  const wholeRecord = flatDataSource.find(\n    (item) => item[primaryKey] === record[primaryKey]\n  )\n  return hasSelectedKey(wholeRecord.children, selected, primaryKey) || undefined\n}\n\ninterface ICheckSlackly {\n  (\n    currentSelected: any[],\n    selected: any[],\n    flatDataSource: any[],\n    flatFilteredDataSource: any[],\n    primaryKey: string,\n    checkStrictly: boolean\n  ): { selectedRowKeys: any[] }\n}\n\n// 父子节点（节点状态按全完整数据计算，节点操作按筛选数据计算）\nconst useCheckSlackly: ICheckSlackly = (\n  currentSelected, // onChange 返回的 keys\n  selected, // Table UI 展示的 keys\n  flatDataSource,\n  flatFilteredDataSource,\n  primaryKey,\n  checkStrictly\n) => {\n  let isSelected = currentSelected.length > selected.length // 判断是选中还是取消\n\n  const currentKey = [...currentSelected, ...selected].find(\n    (key) => !(currentSelected.includes(key) && selected.includes(key)) // 当前变化key不同时存在于两个selected\n  )\n  // 从过滤后的数据中获取当前record\n  const currentRecord = flatFilteredDataSource.find(\n    (item) => item[primaryKey] === currentKey\n  )\n  const currentTreeKeys = getTreeKeys(currentRecord.children, primaryKey)\n\n  // 在筛选状态下（按钮的indeterminate状态处于异常）需要通过数据对比判断是否处于全选中状态\n  if (\n    getCompatibleAllSelected(\n      selected,\n      currentRecord.children,\n      currentTreeKeys,\n      checkStrictly,\n      primaryKey\n    )\n  ) {\n    isSelected = false\n  }\n\n  let newSelected = []\n  if (isSelected) {\n    // 选中当前key及其子keys\n    newSelected = [...new Set([...selected, currentKey, ...currentTreeKeys])]\n  } else {\n    // 移除当前key及其子keys\n    newSelected = selected.filter(\n      (key) => ![currentKey, ...currentTreeKeys].includes(key)\n    )\n  }\n\n  newSelected = completedKeys(flatDataSource, newSelected, primaryKey)\n\n  return { selectedRowKeys: newSelected }\n}\n\nexport { useCheckSlackly, getIndeterminate }\n"
  },
  {
    "path": "packages/next/src/select-table/useFilterOptions.tsx",
    "content": "import * as React from 'react'\nimport { isFn, isArr } from '@formily/shared'\n\ntype IFilterOption = boolean | ((option: any, keyword: string) => boolean)\n\nfunction includes(test: React.ReactNode, search: string) {\n  return toArray(test).join('').toUpperCase().includes(search)\n}\n\nfunction includesOption(option: any, search: string) {\n  const searched = new Set()\n  const _includesOption = (option: any) => {\n    const keys = Object.keys(option || {})\n    return keys.some((key) => {\n      if (key === '__level') {\n        return false\n      }\n      const value = option[key]\n      if (React.isValidElement(value)) return false\n      if (key !== 'children' && !searched.has(value)) {\n        if (typeof value === 'object') {\n          searched.add(value)\n          return _includesOption(value)\n        }\n        return includes(value, search)\n      }\n      return false\n    })\n  }\n  return _includesOption(option)\n}\n\nfunction toArray<T>(value: T | T[]): T[] {\n  if (isArr(value)) {\n    return value\n  }\n  return value !== undefined ? [value] : []\n}\n\nconst useFilterOptions = (\n  options: any[],\n  searchValue?: string | string[],\n  filterOption?: IFilterOption,\n  checkStrictly?: boolean\n) =>\n  React.useMemo(() => {\n    if (!searchValue || filterOption === false) {\n      return options\n    }\n    const filterFunc = isFn(filterOption)\n      ? filterOption\n      : (value: any, option: any) => includesOption(option, value.toUpperCase())\n\n    const doFilter = (arr: any[]) => {\n      const filterArr: any[] = []\n      arr?.forEach((item) => {\n        if (item?.children?.length) {\n          const filterChildren = doFilter(item.children)\n          if (filterChildren.length) {\n            filterArr.push({ ...item, children: filterChildren })\n          } else if (filterFunc(searchValue, item) && checkStrictly !== false) {\n            // 父子关系启用时，没有可用子元素，不添加父元素\n            filterArr.push({ ...item, children: [] })\n          }\n        } else if (filterFunc(searchValue, item)) {\n          filterArr.push(item)\n        }\n      })\n      return filterArr\n    }\n\n    return doFilter(options)\n  }, [options, searchValue, filterOption])\n\nexport { useFilterOptions }\n"
  },
  {
    "path": "packages/next/src/select-table/useFlatOptions.tsx",
    "content": "const useFlatOptions = (tree: any[]) => {\n  const flatData = (data) => {\n    let list = []\n    data?.forEach((item) => {\n      list = [...list, item]\n      if (item?.children?.length) {\n        list = [...list, ...flatData(item.children)]\n      }\n    })\n    return list\n  }\n  return flatData(tree)\n}\n\nexport { useFlatOptions }\n"
  },
  {
    "path": "packages/next/src/select-table/useSize.tsx",
    "content": "interface ISize {\n  (\n    fieldSize: 'large' | 'default' | 'small',\n    searchSize: 'large' | 'medium',\n    tableSize: 'small' | 'medium'\n  ): {\n    searchSize: 'large' | 'medium'\n    tableSize: 'small' | 'medium'\n  }\n}\n\nconst useSize: ISize = (fieldSize = 'default', searchSize, tableSize) => {\n  const fieldSizeMap: any = {\n    small: {\n      searchSize: 'medium',\n      tableSize: 'small',\n    },\n    default: {\n      searchSize: 'medium',\n      tableSize: 'medium',\n    },\n    large: {\n      searchSize: 'large',\n      tableSize: 'medium',\n    },\n  }\n  const { searchSize: fieldSearchSize, tableSize: fieldTableSize } =\n    fieldSizeMap[fieldSize]\n\n  return {\n    searchSize: searchSize || fieldSearchSize,\n    tableSize: tableSize || fieldTableSize,\n  }\n}\n\nexport { useSize }\n"
  },
  {
    "path": "packages/next/src/select-table/useTitleAddon.tsx",
    "content": "import React from 'react'\nimport { Checkbox } from '@alifd/next'\nimport { completedKeys, getCompatibleAllSelected } from './utils'\n\n// 重写表格表头Checkbox（节点状态按全完整数据计算，节点操作按筛选数据计算）\nconst newCheckbox =\n  (\n    selected,\n    flatDataSource,\n    flatFilteredDataSource,\n    primaryKey,\n    disabled,\n    readOnly,\n    checkStrictly,\n    onChange\n  ) =>\n  () => {\n    // 全选框是否选中\n    const checked = Boolean(\n      selected?.length &&\n        selected?.length ===\n          flatDataSource.filter((item) => !item.disabled).length\n    )\n    // 全选框是否未完全选中\n    const indeterminate = Boolean(selected?.length && !checked)\n\n    const onInnerChange = (checked) => {\n      if (!readOnly) {\n        let isSelected = checked\n        // 当前可执行全选的keys\n        const usableKeys = flatFilteredDataSource\n          .filter((item) => !item.disabled)\n          .map((item) => item?.[primaryKey])\n        // 在筛选状态下（按钮的indeterminate状态处于异常）需要通过数据对比判断是否处于全选中状态\n        if (\n          getCompatibleAllSelected(\n            selected,\n            flatFilteredDataSource,\n            usableKeys,\n            checkStrictly,\n            primaryKey\n          )\n        ) {\n          isSelected = false\n        }\n\n        let newSelected = []\n        if (isSelected) {\n          // 执行全选\n          newSelected = [...new Set([...selected, ...usableKeys])]\n        } else {\n          // 执行取消全选\n          newSelected = selected.filter((key) => !usableKeys.includes(key))\n        }\n        newSelected = completedKeys(flatDataSource, newSelected, primaryKey)\n        onChange?.(newSelected)\n      }\n    }\n\n    return (\n      <Checkbox\n        key=\"titleAddons\"\n        disabled={disabled}\n        checked={checked}\n        indeterminate={indeterminate}\n        onChange={onInnerChange}\n      />\n    )\n  }\n\nconst useTitleAddon = (\n  selected: any[],\n  flatDataSource: any[],\n  flatFilteredDataSource: any[],\n  primaryKey: string,\n  mode: string,\n  disabled: boolean,\n  readOnly: boolean,\n  checkStrictly: boolean,\n  onChange: (selectedRowKeys: any[], record: any[]) => any\n) => {\n  if (mode === 'single') {\n    return {}\n  }\n  return {\n    titleProps: () => ({\n      style: { display: 'none' },\n    }),\n    titleAddons: newCheckbox(\n      selected,\n      flatDataSource,\n      flatFilteredDataSource,\n      primaryKey,\n      disabled,\n      readOnly,\n      checkStrictly,\n      onChange\n    ),\n  }\n}\n\nexport { useTitleAddon }\n"
  },
  {
    "path": "packages/next/src/select-table/utils.ts",
    "content": "import { isArr, isFn } from '@formily/shared'\nimport { useFlatOptions } from './useFlatOptions'\n\n/**\n * 获取树列表某个键值的集合\n * @param tree 树列表\n * @param primaryKey 键名称\n * @returns 键值数组集合\n */\nconst getTreeKeys = (tree: any[], primaryKey: string) =>\n  isArr(tree)\n    ? tree.reduce((prev, current) => {\n        if (current?.disabled) {\n          return prev\n        }\n        return [\n          ...prev,\n          current[primaryKey],\n          ...getTreeKeys(current?.children, primaryKey),\n        ]\n      }, [])\n    : []\n\n/**\n * 判断树列表中是否有任一 key 被选中\n * @param tree 树列表\n * @param selected 已选中的 keys\n * @param primaryKey 键名\n * @returns\n */\nconst hasSelectedKey = (tree: any[], selected: any[], primaryKey: string) => {\n  const keys = getTreeKeys(tree, primaryKey)\n  const mergedKeys = [...keys, ...selected]\n  const validKeys = [...new Set(mergedKeys)]\n  return validKeys.length !== mergedKeys.length\n}\n\n/**\n * 判断列表项是否全部被选中\n * @param list 一阶列表\n * @param selected 当前选中的字段值集合\n * @param primaryKey 键名称\n * @returns 是否全部被选中\n */\nconst isAllSelected = (list: any[], selected: any[], primaryKey: string) => {\n  const validList = list.filter((item) => !item?.disabled)\n  const selectedList = validList.filter((item) =>\n    selected?.includes(item[primaryKey])\n  )\n  return selectedList.length === validList.length\n}\n\n/**\n * 完善TableUI Keys（添加选中所有子元素的父元素，或移除未选中所有子元素的父元素）\n * @param flatDataSource 完整数据平铺列表\n * @param selected 当前选中的字段值集合\n * @param primaryKey 键名称\n * @returns 完整的字段值集合\n */\nconst completedKeys = (\n  flatDataSource: any[] = [],\n  selected: any[],\n  primaryKey: string\n) => {\n  let allSelectedKeys = [...selected]\n  flatDataSource.forEach((item) => {\n    if (item.children?.length) {\n      // 优先递归子元素\n      allSelectedKeys = completedKeys(\n        item.children,\n        allSelectedKeys,\n        primaryKey\n      )\n      if (isAllSelected(item.children, allSelectedKeys, primaryKey)) {\n        // 如果该元素的子元素全部选中，且该元素未禁用，则也选中该项（即包含全选子元素的父元素）\n        if (!item?.disabled) {\n          allSelectedKeys = [...new Set([...allSelectedKeys, item[primaryKey]])]\n        }\n      } else {\n        // 如果该元素的子元素未全部选中，则移除该项\n        allSelectedKeys = allSelectedKeys.filter(\n          (key) => key !== item[primaryKey]\n        )\n      }\n    }\n  })\n  return allSelectedKeys\n}\n\n/**\n * 获取数列表中被选中的有效路径\n * @param tree 数列表\n * @param selected 当前选中的字段值集合\n * @param primaryKey 键名称\n * @returns 有效的树路径\n */\nconst getSelectedPath = (tree = [], selected, primaryKey) => {\n  const pathData = []\n\n  tree.forEach((item) => {\n    const validChildren = getSelectedPath(item.children, selected, primaryKey)\n    if (validChildren.length || selected?.includes(item[primaryKey])) {\n      pathData.push({\n        ...item,\n        ...(validChildren.length ? { children: validChildren } : {}),\n      })\n    }\n  })\n\n  return pathData\n}\n\n/**\n * 删除树列表的某个 key/value 键值对\n * @param tree\n * @param key\n * @returns\n */\nconst deleteTreeItem = (tree: any[], key: string) =>\n  tree.map((item) => {\n    const validItem = { ...item }\n    delete validItem[key]\n    if (validItem.children?.length) {\n      validItem.children = deleteTreeItem(validItem.children, key)\n    }\n    return validItem\n  })\n\n/**\n * 根据 valueType 获取最终输出值\n * @param keys 当前选中的 key 集合（all完整类型）\n * @param records 当前选中的 option 集合\n * @param dataSource 数据源集合\n * @param primaryKey 键名\n * @param originalValueType 值输出类型\n * @param originalOptionAsValue\n * @param mode\n * @param checkStrictly\n * @returns 最终输出的 keys 和 options\n */\nconst getOutputData = (\n  keys, // selected\n  options,\n  dataSource,\n  primaryKey,\n  originalValueType,\n  originalOptionAsValue,\n  mode,\n  checkStrictly\n) => {\n  const valueType = checkStrictly !== false ? 'all' : originalValueType // valueType 在 Strictly 为 false 时生效\n  const optionAsValue = valueType === 'path' ? false : originalOptionAsValue // optionAsValue 在 path 模式不生效\n  let outputValue = []\n  let outputOptions = []\n\n  if (valueType === 'parent') {\n    // 移除所有选中值的子值\n    let childrenKeys = []\n    options.forEach((option) => {\n      childrenKeys = [\n        ...childrenKeys,\n        ...getTreeKeys(option.children, primaryKey),\n      ]\n    })\n    outputValue = keys.filter((key) => !childrenKeys.includes(key))\n    outputOptions = options.filter((options) =>\n      outputValue.includes(options[primaryKey])\n    )\n  } else if (valueType === 'child') {\n    outputValue = [...keys]\n    outputOptions = [...options]\n    outputOptions.forEach((option) => {\n      // 移除当前有子值被选中的父值\n      if (hasSelectedKey(option.children, keys, primaryKey)) {\n        outputValue = outputValue.filter((key) => key !== option[primaryKey])\n        outputOptions = outputOptions.filter(\n          (options) => options[primaryKey] !== option[primaryKey]\n        )\n      }\n    })\n  } else if (valueType === 'path') {\n    outputValue = getSelectedPath(dataSource, keys, primaryKey)\n    outputOptions = [...options]\n  } else {\n    // valueType === 'all'\n    outputValue = [...keys]\n    outputOptions = [...options]\n  }\n\n  outputOptions = deleteTreeItem(outputOptions, '__formily_key__')\n  outputValue =\n    optionAsValue && valueType !== 'path' ? outputOptions : outputValue\n  if (mode === 'single') {\n    outputValue = outputValue[0]\n    outputOptions = outputOptions[0]\n  }\n\n  return { outputValue, outputOptions }\n}\n\n/**\n * 根据 valueType 获取 TableUI 显示值\n * @param keys 回填的数据（输出的）keys 集合\n * @param flatDataSource 平铺的数据源集合\n * @param primaryKey 键名称\n * @param originalValueType 值输出类型\n * @param originalOptionAsValue\n * @param mode\n * @param checkStrictly\n * @param rowKey\n * @returns [] TableUI keys 集合\n */\nconst getUISelected = (\n  value,\n  flatDataSource,\n  primaryKey,\n  originalValueType,\n  originalOptionAsValue,\n  mode,\n  checkStrictly,\n  rowKey\n) => {\n  const valueType = checkStrictly !== false ? 'all' : originalValueType // valueType 在 Strictly 为 false 时生效\n  const optionAsValue = valueType === 'path' ? false : originalOptionAsValue // optionAsValue 在 path 模式不生效\n\n  let keys = mode === 'single' ? [value] : isArr(value) ? value : []\n  keys =\n    optionAsValue && valueType !== 'path'\n      ? keys.map((record: any) =>\n          isFn(rowKey) ? rowKey(record) : record?.[primaryKey]\n        )\n      : keys\n\n  let newKeys = []\n  if (valueType === 'parent') {\n    const options = flatDataSource.filter((item) =>\n      keys.includes(item[primaryKey])\n    )\n    let childrenKeys = []\n    options.forEach((option) => {\n      childrenKeys = [\n        ...childrenKeys,\n        ...getTreeKeys(option.children, primaryKey),\n      ]\n    })\n    newKeys = [...new Set([...keys, ...childrenKeys])]\n  } else if (valueType === 'child') {\n    newKeys = completedKeys(flatDataSource, keys, primaryKey)\n  } else if (valueType === 'path') {\n    const pathKeys = useFlatOptions(keys).map((item) => item[primaryKey])\n    newKeys = completedKeys(flatDataSource, pathKeys, primaryKey)\n  } else {\n    // valueType === 'all'\n    newKeys = [...keys]\n  }\n\n  return newKeys\n}\n\n/**\n * 获取兼容筛选模式下是否全部选中子元素\n * @param selected 已选中项\n * @param dataSource 当前数据结构\n * @param usableKeys 当前数据结构的可执行项\n * @param checkStrictly\n * @param primaryKey\n * @returns 是否全部选中\n */\nconst getCompatibleAllSelected = (\n  selected,\n  dataSource,\n  usableKeys,\n  checkStrictly,\n  primaryKey\n) => {\n  if (!usableKeys.length) {\n    return false\n  }\n  // 当前模式下已选中的项\n  const currentSelected = selected.filter((item) => usableKeys.includes(item))\n  // 获取有效选中（父子模式或非父子模式）\n  const validSelected =\n    checkStrictly !== false\n      ? currentSelected // 非父子模式选中项\n      : completedKeys(dataSource, currentSelected, primaryKey) // 父子模式选中项\n  // 有效选中项数量等于可执行项数量则全部选中子元素\n  return validSelected.length === usableKeys.length\n}\n\nexport {\n  hasSelectedKey,\n  getTreeKeys,\n  deleteTreeItem,\n  isAllSelected,\n  getUISelected,\n  getOutputData,\n  completedKeys,\n  getCompatibleAllSelected,\n}\n"
  },
  {
    "path": "packages/next/src/space/index.tsx",
    "content": "import React from 'react'\nimport { Box } from '@alifd/next'\nimport { isNumberLike } from '@formily/shared'\nimport { toArray, usePrefixCls } from '../__builtins__'\nimport { useFormLayout } from '../form-layout'\nexport interface ISpaceProps {\n  prefix?: string\n  className?: string\n  style?: React.CSSProperties\n  size?: number | 'small' | 'large' | 'middle'\n  direction?: 'horizontal' | 'vertical'\n  // No `stretch` since many components do not support that.\n  align?: 'start' | 'end' | 'center' | 'baseline'\n  wrap?: boolean\n}\n\nconst spaceSize = {\n  small: 8,\n  middle: 16,\n  large: 24,\n}\n\nexport const Space: React.FC<React.PropsWithChildren<ISpaceProps>> = ({\n  direction = 'horizontal',\n  size,\n  align = 'start',\n  ...props\n}) => {\n  const layout = useFormLayout()\n  const prefix = usePrefixCls('space', props)\n  const getDirection = () => {\n    if (direction === 'horizontal') {\n      return 'row'\n    } else {\n      return 'column'\n    }\n  }\n  const getAlign = () => {\n    if (align === 'start') {\n      return 'flex-start'\n    } else if (align === 'end') {\n      return 'flex-end'\n    } else {\n      return 'center'\n    }\n  }\n  const _size = size ?? layout?.spaceGap ?? 8\n  const _align = getAlign()\n  return (\n    <Box\n      {...props}\n      spacing={isNumberLike(_size) ? _size : spaceSize[_size] || 8}\n      style={{\n        alignItems: _align,\n        display: 'inline-flex',\n        ...props.style,\n      }}\n      align={_align}\n      direction={getDirection()}\n    >\n      {toArray(props.children, { keepEmpty: true }).map((child, index) => (\n        <div className={`${prefix}-item`} key={index}>\n          {child}\n        </div>\n      ))}\n    </Box>\n  )\n}\n\nexport default Space\n"
  },
  {
    "path": "packages/next/src/space/main.scss",
    "content": "@import '~@alifd/next/lib/core/index-noreset.scss';\n@import '~@alifd/next/lib/form/scss/variable.scss';\n\n$space-prefix-cls: '#{$css-prefix}space';\n\n.#{$space-prefix-cls}-item:empty {\n  display: none !important;\n}\n"
  },
  {
    "path": "packages/next/src/space/style.ts",
    "content": "import '@alifd/next/lib/box/style'\nimport './main.scss'\n"
  },
  {
    "path": "packages/next/src/style.ts",
    "content": "// auto generated code\nimport './array-base/main.scss'\nimport './array-cards/main.scss'\nimport './array-collapse/main.scss'\nimport './array-items/main.scss'\nimport './array-table/main.scss'\nimport './date-picker2/main.scss'\nimport './editable/main.scss'\nimport './form-button-group/main.scss'\nimport './form-grid/main.scss'\nimport './form-item/main.scss'\nimport './form-layout/main.scss'\nimport './form/main.scss'\nimport './preview-text/main.scss'\nimport './select-table/main.scss'\nimport './space/main.scss'\nimport './upload/main.scss'\n"
  },
  {
    "path": "packages/next/src/submit/index.tsx",
    "content": "import React from 'react'\nimport { Button } from '@alifd/next'\nimport { ButtonProps } from '@alifd/next/lib/button'\nimport { IFormFeedback } from '@formily/core'\nimport { useParentForm, observer } from '@formily/react'\n\ninterface ISubmitProps extends ButtonProps {\n  onClick?: (e: React.MouseEvent<Element, MouseEvent>) => any\n  onSubmit?: (values: any) => any\n  onSubmitSuccess?: (payload: any) => void\n  onSubmitFailed?: (feedbacks: IFormFeedback[]) => void\n}\n\nexport const Submit: React.FC<React.PropsWithChildren<ISubmitProps>> = observer(\n  ({ onSubmit, onSubmitFailed, onSubmitSuccess, ...props }: ISubmitProps) => {\n    const form = useParentForm()\n    return (\n      <Button\n        htmlType={onSubmit ? 'button' : 'submit'}\n        type=\"primary\"\n        {...props}\n        loading={props.loading !== undefined ? props.loading : form.submitting}\n        onClick={(e) => {\n          if (props.onClick) {\n            if (props.onClick(e) === false) return\n          }\n          if (onSubmit) {\n            form.submit(onSubmit).then(onSubmitSuccess).catch(onSubmitFailed)\n          }\n        }}\n      >\n        {props.children}\n      </Button>\n    )\n  },\n  {\n    forwardRef: true,\n  }\n)\n\nexport default Submit\n"
  },
  {
    "path": "packages/next/src/submit/style.ts",
    "content": "import '@alifd/next/lib/button/style'\n"
  },
  {
    "path": "packages/next/src/switch/index.tsx",
    "content": "import { Switch as NextSwitch } from '@alifd/next'\nimport { connect, mapProps } from '@formily/react'\nimport { mapSize, mapStatus } from '../__builtins__'\nexport const Switch = connect(\n  NextSwitch,\n  mapProps(\n    {\n      value: 'checked',\n    },\n    mapSize,\n    mapStatus\n  )\n)\n\nexport default Switch\n"
  },
  {
    "path": "packages/next/src/switch/style.ts",
    "content": "import '@alifd/next/lib/switch/style'\n"
  },
  {
    "path": "packages/next/src/time-picker/index.tsx",
    "content": "import moment from 'moment'\nimport { connect, mapProps, mapReadPretty } from '@formily/react'\nimport { TimePicker as NextTimePicker } from '@alifd/next'\nimport { TimePickerProps } from '@alifd/next/lib/time-picker'\nimport { PreviewText } from '../preview-text'\nimport {\n  formatMomentValue,\n  momentable,\n  mapSize,\n  mapStatus,\n} from '../__builtins__'\n\nconst mapTimeFormat = function () {\n  return (props: any) => {\n    const format = props['format'] || 'HH:mm:ss'\n    const onChange = props.onChange\n    return {\n      ...props,\n      format,\n      value: momentable(props.value, format),\n      onChange: (value: moment.Moment | moment.Moment[]) => {\n        if (onChange) {\n          onChange(formatMomentValue(value, format))\n        }\n      },\n    }\n  }\n}\n\nexport const TimePicker: React.FC<React.PropsWithChildren<TimePickerProps>> =\n  connect(\n    NextTimePicker,\n    mapProps(mapTimeFormat(), mapSize, mapStatus),\n    mapReadPretty(PreviewText.TimePicker)\n  )\n\nexport default TimePicker\n"
  },
  {
    "path": "packages/next/src/time-picker/style.ts",
    "content": "import '@alifd/next/lib/time-picker/style'\n"
  },
  {
    "path": "packages/next/src/time-picker2/index.tsx",
    "content": "import moment from 'moment'\nimport { connect, mapProps, mapReadPretty } from '@formily/react'\nimport { TimePicker2 as NextTimePicker2 } from '@alifd/next'\nimport {\n  TimePickerProps,\n  RangePickerProps,\n} from '@alifd/next/types/time-picker2'\nimport { PreviewText } from '../preview-text'\nimport {\n  formatMomentValue,\n  momentable,\n  mapSize,\n  mapStatus,\n} from '../__builtins__'\n\ntype ComposedTimePicker = React.FC<React.PropsWithChildren<TimePickerProps>> & {\n  RangePicker?: React.FC<React.PropsWithChildren<RangePickerProps>>\n}\n\nconst mapTimeFormat = function () {\n  return (props: any) => {\n    const format = props['format'] || 'HH:mm:ss'\n    const onChange = props.onChange\n    return {\n      ...props,\n      format,\n      value: momentable(props.value, format),\n      onChange: (value: moment.Moment | moment.Moment[]) => {\n        if (onChange) {\n          onChange(formatMomentValue(value, format))\n        }\n      },\n    }\n  }\n}\n\nexport const TimePicker2: ComposedTimePicker = connect(\n  NextTimePicker2,\n  mapProps(mapTimeFormat(), mapSize, mapStatus),\n  mapReadPretty(PreviewText.TimePicker2)\n)\n\nTimePicker2.RangePicker = connect(\n  NextTimePicker2.RangePicker,\n  mapProps(mapTimeFormat(), mapSize, mapStatus),\n  mapReadPretty(PreviewText.TimeRangePicker2)\n)\n\nexport default TimePicker2\n"
  },
  {
    "path": "packages/next/src/time-picker2/style.ts",
    "content": "import '@alifd/next/lib/time-picker2/style'\n"
  },
  {
    "path": "packages/next/src/transfer/index.tsx",
    "content": "import { connect, mapProps } from '@formily/react'\nimport { Transfer as NextTransfer } from '@alifd/next'\n\nexport const Transfer = connect(\n  NextTransfer,\n  mapProps({\n    dataSource: true,\n  })\n)\n\nexport default Transfer\n"
  },
  {
    "path": "packages/next/src/transfer/style.ts",
    "content": "import '@alifd/next/lib/transfer/style'\n"
  },
  {
    "path": "packages/next/src/tree-select/index.tsx",
    "content": "import { connect, mapReadPretty, mapProps } from '@formily/react'\nimport { TreeSelect as NextTreeSelect } from '@alifd/next'\nimport { PreviewText } from '../preview-text'\nimport { mapSize, mapStatus } from '../__builtins__'\n\nexport const TreeSelect = connect(\n  NextTreeSelect,\n  mapProps(\n    {\n      dataSource: true,\n    },\n    mapSize,\n    mapStatus\n  ),\n  mapReadPretty(PreviewText.TreeSelect)\n)\n\nexport default TreeSelect\n"
  },
  {
    "path": "packages/next/src/tree-select/style.ts",
    "content": "import '@alifd/next/lib/tree-select/style'\n"
  },
  {
    "path": "packages/next/src/upload/index.tsx",
    "content": "import React, { useEffect } from 'react'\nimport { Field } from '@formily/core'\nimport { useField } from '@formily/react'\nimport { reaction } from '@formily/reactive'\nimport { Upload as NextUpload, Button, Icon } from '@alifd/next'\nimport {\n  UploadProps as NextUploadProps,\n  CardProps,\n} from '@alifd/next/lib/upload'\nimport { isArr, toArr } from '@formily/shared'\nimport { UPLOAD_PLACEHOLDER } from './placeholder'\n\ntype ExtendsUploadProps = NextUploadProps & {\n  textContent?: React.ReactNode\n  serviceErrorMessage?: string\n}\n\ntype FileList = Parameters<ExtendsUploadProps['onChange']>[0]\n\ntype ComposedUpload = React.FC<React.PropsWithChildren<IUploadProps>> & {\n  Card?: React.FC<React.PropsWithChildren<ICardUploadProps>>\n  Dragger?: React.FC<React.PropsWithChildren<IUploadProps>>\n}\n\ntype IExtendsUploadProps = {\n  value?: any[]\n  serviceErrorMessage?: string\n  onChange?: (...args: any) => void\n  formatter?: (...args: any) => any\n}\n\nexport type IUploadProps = ExtendsUploadProps & { serviceErrorMessage?: string }\n\nexport type ICardUploadProps = CardProps & { serviceErrorMessage?: string }\n\nconst testOpts = (\n  ext: RegExp,\n  options: { exclude?: string[]; include?: string[] }\n) => {\n  if (options && isArr(options.include)) {\n    return options.include.some((url) => ext.test(url))\n  }\n\n  if (options && isArr(options.exclude)) {\n    return !options.exclude.some((url) => ext.test(url))\n  }\n\n  return true\n}\n\nconst getImageByUrl = (url: string, options: any) => {\n  for (let i = 0; i < UPLOAD_PLACEHOLDER.length; i++) {\n    if (\n      UPLOAD_PLACEHOLDER[i].ext.test(url) &&\n      testOpts(UPLOAD_PLACEHOLDER[i].ext, options)\n    ) {\n      return UPLOAD_PLACEHOLDER[i].icon || url\n    }\n  }\n\n  return url\n}\n\nconst getURL = (target: any) => {\n  return target?.['url'] || target?.['downloadURL'] || target?.['imgURL']\n}\n\nconst getThumbURL = (target: any) => {\n  return (\n    target?.['thumbUrl'] ||\n    target?.['url'] ||\n    target?.['downloadURL'] ||\n    target?.['imgURL']\n  )\n}\n\nconst getSuccess = (target: any) => {\n  return (\n    target?.success ||\n    target?.status === 'done' ||\n    target?.status === 'success' ||\n    target?.state === 'done' ||\n    target?.state === 'success'\n  )\n}\n\nconst getErrorMessage = (target: any) => {\n  return (\n    target?.errorMessage ||\n    target?.errMsg ||\n    target?.errorMsg ||\n    target?.message ||\n    (typeof target?.error === 'string' ? target.error : '')\n  )\n}\n\nconst getState = (target: any) => {\n  if (target?.success === false) return 'error'\n  if (target?.failed === true) return 'error'\n  if (target?.error) return 'error'\n  return target?.state || target?.status\n}\n\nconst normalizeFileList = (fileList: IUploadProps['value']) => {\n  if (fileList && fileList.length) {\n    return fileList.map(({ ...file }, index) => {\n      delete file['originFileObj']\n      return {\n        ...file,\n        uid: file.uid || index,\n        state: getState(file?.response) || getState(file),\n        downloadURL: getURL(file) || getURL(file?.response),\n        imgURL: getImageByUrl(\n          getThumbURL(file) || getThumbURL(file?.response),\n          {\n            exclude: ['.png', '.jpg', '.jpeg', '.gif'],\n          }\n        ),\n      }\n    })\n  }\n  return []\n}\n\nconst useValidator = (validator: (value: any) => string) => {\n  const field = useField<Field>()\n  useEffect(() => {\n    const dispose = reaction(\n      () => field.value,\n      (value) => {\n        const message = validator(value)\n        field.setFeedback({\n          type: 'error',\n          code: 'UploadError',\n          messages: message ? [message] : [],\n        })\n      }\n    )\n    return () => {\n      dispose()\n    }\n  }, [])\n}\n\nconst useUploadValidator = (serviceErrorMessage = 'Upload Service Error') => {\n  useValidator((value) => {\n    const list = toArr(value)\n    for (let i = 0; i < list.length; i++) {\n      if (list[i]?.state === 'error') {\n        return (\n          getErrorMessage(list[i]?.response) ||\n          getErrorMessage(list[i]) ||\n          serviceErrorMessage\n        )\n      }\n    }\n  })\n}\n\nfunction useUploadProps<T extends IExtendsUploadProps = IUploadProps>({\n  serviceErrorMessage,\n  ...props\n}: T) {\n  useUploadValidator(serviceErrorMessage)\n  const onChange = (fileList: FileList) => {\n    props.onChange?.(normalizeFileList([...fileList]))\n  }\n\n  const formatter = (res: any, file: any) => {\n    const response = props?.formatter?.(res, file) as any\n    return {\n      ...res,\n      success: getSuccess(res),\n      ...response,\n    }\n  }\n  return {\n    ...props,\n    value: normalizeFileList(props.value),\n    onChange,\n    formatter,\n  }\n}\n\nconst getPlaceholder = (props: IUploadProps) => {\n  if (props.shape !== 'card') {\n    return (\n      <Button>\n        <Icon type=\"upload\" />\n        {props.textContent}\n      </Button>\n    )\n  }\n  return <Icon type=\"upload\" style={{ fontSize: 20 }} />\n}\n\nexport const Upload: ComposedUpload = (props) => {\n  return (\n    <NextUpload listType=\"text\" {...useUploadProps(props)}>\n      {props.children || getPlaceholder(props)}\n    </NextUpload>\n  )\n}\n\nUpload.Dragger = (props) => {\n  return <NextUpload.Dragger listType=\"text\" {...useUploadProps(props)} />\n}\n\nUpload.Card = (props) => {\n  return <NextUpload.Card listType=\"card\" {...useUploadProps(props)} />\n}\n\nexport default Upload\n"
  },
  {
    "path": "packages/next/src/upload/main.scss",
    "content": "@import '~@alifd/next/lib/core/index-noreset.scss';\n\n$upload-prefix-cls: '#{$css-prefix}upload';\n\n.#{$upload-prefix-cls}-list {\n  margin-top: 4px;\n}\n"
  },
  {
    "path": "packages/next/src/upload/placeholder.ts",
    "content": "export const UPLOAD_PLACEHOLDER = [\n  {\n    ext: /\\.docx/i,\n    icon: '//img.alicdn.com/tfs/TB1n8jfr1uSBuNjy1XcXXcYjFXa-200-200.png',\n  },\n  {\n    ext: /\\.pptx/i,\n    icon: '//img.alicdn.com/tfs/TB1ItgWr_tYBeNjy1XdXXXXyVXa-200-200.png',\n  },\n  {\n    ext: /\\.jpe?g/i,\n    icon: '//img.alicdn.com/tfs/TB1wrT5r9BYBeNjy0FeXXbnmFXa-200-200.png',\n  },\n  {\n    ext: /\\.pdf/i,\n    icon: '//img.alicdn.com/tfs/TB1GwD8r9BYBeNjy0FeXXbnmFXa-200-200.png',\n  },\n  {\n    ext: /\\.png/i,\n    icon: '//img.alicdn.com/tfs/TB1BHT5r9BYBeNjy0FeXXbnmFXa-200-200.png',\n  },\n  {\n    ext: /\\.eps/i,\n    icon: '//img.alicdn.com/tfs/TB1G_iGrVOWBuNjy0FiXXXFxVXa-200-200.png',\n  },\n  {\n    ext: /\\.ai/i,\n    icon: '//img.alicdn.com/tfs/TB1B2cVr_tYBeNjy1XdXXXXyVXa-200-200.png',\n  },\n  {\n    ext: /\\.gif/i,\n    icon: '//img.alicdn.com/tfs/TB1DTiGrVOWBuNjy0FiXXXFxVXa-200-200.png',\n  },\n  {\n    ext: /\\.svg/i,\n    icon: '//img.alicdn.com/tfs/TB1uUm9rY9YBuNjy0FgXXcxcXXa-200-200.png',\n  },\n  {\n    ext: /\\.xlsx?/i,\n    icon: '//img.alicdn.com/tfs/TB1any1r1OSBuNjy0FdXXbDnVXa-200-200.png',\n  },\n  {\n    ext: /\\.psd?/i,\n    icon: '//img.alicdn.com/tfs/TB1_nu1r1OSBuNjy0FdXXbDnVXa-200-200.png',\n  },\n  {\n    ext: /\\.(wav|aif|aiff|au|mp1|mp2|mp3|ra|rm|ram|mid|rmi)/i,\n    icon: '//img.alicdn.com/tfs/TB1jPvwr49YBuNjy0FfXXXIsVXa-200-200.png',\n  },\n  {\n    ext: /\\.(avi|wmv|mpg|mpeg|vob|dat|3gp|mp4|mkv|rm|rmvb|mov|flv)/i,\n    icon: '//img.alicdn.com/tfs/TB1FrT5r9BYBeNjy0FeXXbnmFXa-200-200.png',\n  },\n  {\n    ext: /\\.(zip|rar|arj|z|gz|iso|jar|ace|tar|uue|dmg|pkg|lzh|cab)/i,\n    icon: '//img.alicdn.com/tfs/TB10jmfr29TBuNjy0FcXXbeiFXa-200-200.png',\n  },\n  {\n    ext: /\\.[^.]+/i,\n    icon: '//img.alicdn.com/tfs/TB10.R4r3mTBuNjy1XbXXaMrVXa-200-200.png',\n  },\n]\n"
  },
  {
    "path": "packages/next/src/upload/style.ts",
    "content": "import '@alifd/next/lib/upload/style'\nimport './main.scss'\n"
  },
  {
    "path": "packages/next/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*\", \"devtools/*\"]\n    },\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/next/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"include\": [\"./src/**/*.js\", \"./src/**/*.ts\", \"./src/**/*.tsx\"],\n  \"exclude\": [\"./src/__tests__/*\"],\n  \"compilerOptions\": {\n    \"lib\": [\"ESNext\", \"DOM\"]\n  }\n}\n"
  },
  {
    "path": "packages/path/.npmignore",
    "content": "node_modules\n*.log\nbuild\ndocs\ndoc-site\n__tests__\n.eslintrc\njest.config.js\ntsconfig.json\n.umi\nsrc"
  },
  {
    "path": "packages/path/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-present, Alibaba Group Holding Limited. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/path/README.md",
    "content": "# @formily/path\n\n> Path System\n"
  },
  {
    "path": "packages/path/benchmark.ts",
    "content": "import b from 'benny'\nimport _ from 'lodash'\nimport { Parser } from './src/parser'\n\nconst str =\n  'aakkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk.bbmmmmmmmmmmmmmmmmmmmmmmmmmmm.cceeeeeeeeeeeeeeeeeee'\n\nb.suite(\n  'Path benchmark',\n  b.add('Path parse', () => {\n    _.times(1e3, () => {\n      new Parser(str).parse()\n    })\n  }),\n  b.add('Normal foreach', () => {\n    _.times(1e3, () => {\n      if (!/[()*\\[\\]]/.test(str)) {\n        str.replace(/\\s+/g, '').split('.')\n      }\n    })\n  }),\n  b.add('charCodeAt foreach', () => {\n    _.times(1e3, () => {\n      const res = []\n      for (let i = 0; i < str.length; i++) {\n        res.push(str.charCodeAt(i))\n      }\n    })\n  }),\n  b.cycle(),\n  b.complete()\n)\n"
  },
  {
    "path": "packages/path/package.json",
    "content": "{\n  \"name\": \"@formily/path\",\n  \"version\": \"2.3.7\",\n  \"license\": \"MIT\",\n  \"main\": \"lib\",\n  \"module\": \"esm\",\n  \"umd:main\": \"dist/formily.path.umd.production.js\",\n  \"unpkg\": \"dist/formily.path.umd.production.js\",\n  \"jsdelivr\": \"dist/formily.path.umd.production.js\",\n  \"jsnext:main\": \"esm\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/alibaba/formily.git\"\n  },\n  \"types\": \"esm/index.d.ts\",\n  \"bugs\": {\n    \"url\": \"https://github.com/alibaba/formily/issues\"\n  },\n  \"homepage\": \"https://github.com/alibaba/formily#readme\",\n  \"engines\": {\n    \"npm\": \">=3.0.0\"\n  },\n  \"scripts\": {\n    \"start\": \"dumi dev\",\n    \"build\": \"rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm && npm run build:umd\",\n    \"build:cjs\": \"tsc --project tsconfig.build.json\",\n    \"build:esm\": \"tsc --project tsconfig.build.json --module es2015 --outDir esm\",\n    \"build:umd\": \"rollup --config\",\n    \"build:docs\": \"dumi build\",\n    \"benchmark\": \"ts-node ./benchmark\"\n  },\n  \"devDependencies\": {\n    \"benny\": \"^3.6.15\",\n    \"dumi\": \"^1.1.0-rc.8\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"gitHead\": \"ac79c196ae9324889aca5e0501146f9b37b04283\"\n}\n"
  },
  {
    "path": "packages/path/rollup.config.js",
    "content": "import baseConfig from '../../scripts/rollup.base.js'\n\nexport default baseConfig('formily.path', 'Formily.Path')\n"
  },
  {
    "path": "packages/path/src/__tests__/accessor.spec.ts",
    "content": "import { Path } from '../'\n\nconst { getIn, setIn } = Path\n\ntest('test getIn null parent', () => {\n  const value = { aa: null }\n  expect(getIn(value, 'aa')).toEqual(null)\n  expect(getIn(value, 'aa.bb.cc')).toEqual(undefined)\n})\n\ntest('test getIn and setIn', () => {\n  const value = { a: { b: { c: 2, d: 333 } } }\n  expect(getIn(value, 'a.b.c')).toEqual(2)\n  setIn(value, 'a.b.c', 1111)\n  expect(getIn(value, 'a.b.c')).toEqual(1111)\n})\n\ntest('test getIn with destructor', () => {\n  const value = { array: [{ aa: 123, bb: 321 }] }\n  expect(getIn(value, 'array.0.[aa,bb]')).toEqual([123, 321])\n})\n\ntest('test setIn auto create array', () => {\n  const value = { array: null }\n  setIn(value, 'array[0].bb[2]', 'hello world')\n  expect(value).toEqual({\n    array: [\n      {\n        bb: [undefined, undefined, 'hello world'],\n      },\n    ],\n  })\n  expect(getIn(undefined, 'aa.bb.cc')).toEqual(undefined)\n  setIn(undefined, 'aa.bb.cc', 123)\n})\n\ntest('map', () => {\n  const value = { map: new Map() }\n  setIn(value, 'map.aa.bb.cc', 123)\n  expect(getIn(value, 'map.aa.bb.cc')).toEqual(123)\n})\n\ntest('test setIn array properties', () => {\n  const value = { array: [] }\n  setIn(value, 'array.xxx', 'hello world')\n  expect(value).toEqual({ array: [] })\n})\n\ntest('test setIn dose not affect other items', () => {\n  const value = {\n    aa: [\n      {\n        dd: [\n          {\n            ee: '是',\n          },\n        ],\n        cc: '1111',\n      },\n    ],\n  }\n\n  setIn(value, 'aa.1.dd.0.ee', '否')\n  expect(value.aa[0]).toEqual({\n    dd: [\n      {\n        ee: '是',\n      },\n    ],\n    cc: '1111',\n  })\n})\n\ntest('destruct getIn', () => {\n  // getIn 通过解构表达式从扁平数据转为复合嵌套数据\n  const value = { a: { b: { c: 2, d: 333 } } }\n  expect(getIn({ a: { b: { kk: 2, mm: 333 } } }, 'a.b.{c:kk,d:mm}')).toEqual({\n    c: 2,\n    d: 333,\n  })\n\n  expect(\n    getIn(\n      { kk: 2, mm: 333 },\n      `{\n        a : {\n          b : {\n            c : kk,\n            d : mm\n          }\n        }\n      }`\n    )\n  ).toEqual(value)\n  expect(getIn({ bb: undefined, dd: undefined }, `[{aa:bb,cc:dd}]`)).toEqual([])\n  expect(\n    getIn(\n      { kk: undefined, mm: undefined },\n      `{\n        a : {\n          b : {\n            c : kk,\n            d : mm\n          }\n        }\n      }`\n    )\n  ).toEqual({})\n})\n\ntest('destruct setIn', () => {\n  const value = { a: { b: { c: 2, d: 333 } } }\n  // setIn 从复杂嵌套结构中解构数据出来对其做赋值处理\n  expect(\n    setIn(\n      {},\n      `{\n        a : {\n          b : {\n            c,\n            d\n          }\n        }\n      }`,\n      value\n    )\n  ).toEqual({ c: 2, d: 333 })\n\n  expect(\n    setIn(\n      {},\n      `\n      [aa,bb]\n      `,\n      [123, 444]\n    )\n  ).toEqual({ aa: 123, bb: 444 })\n  expect(setIn({}, 'aa.bb.ddd.[aa,bb]', [123, 444])).toEqual({\n    aa: { bb: { ddd: { aa: 123, bb: 444 } } },\n  })\n\n  expect(setIn({}, 'aa.bb.ddd.[{cc:aa,bb}]', [{ cc: 123, bb: 444 }])).toEqual({\n    aa: { bb: { ddd: { aa: 123, bb: 444 } } },\n  })\n})\n\ntest('setIn with a.b.c.{aaa,bbb}', () => {\n  expect(Path.setIn({}, 'a.b.c.{aaa,bbb}', { aaa: 123, bbb: 321 })).toEqual({\n    a: { b: { c: { aaa: 123, bbb: 321 } } },\n  })\n})\n\ntest('getIn with a.b.c.{aaa,bbb}', () => {\n  expect(\n    Path.getIn({ a: { b: { c: { aaa: 123, bbb: 321 } } } }, 'a.b.c.{aaa,bbb}')\n  ).toEqual({ aaa: 123, bbb: 321 })\n})\n\ntest('setIn with a.b.c.{aaa,bbb} source has extra property', () => {\n  expect(\n    Path.setIn({ a: { b: { c: { kkk: 'ddd' } } } }, 'a.b.c.{aaa,bbb}', {\n      aaa: 123,\n      bbb: 321,\n    })\n  ).toEqual({ a: { b: { c: { aaa: 123, bbb: 321, kkk: 'ddd' } } } })\n})\n\ntest('getIn with a.b.c.{aaa,bbb} source has extra property', () => {\n  expect(\n    Path.getIn(\n      { a: { b: { c: { aaa: 123, bbb: 321, kkk: 'ddd' } } } },\n      'a.b.c.{aaa,bbb}'\n    )\n  ).toEqual({ aaa: 123, bbb: 321 })\n})\n\ntest('setIn with a.b.c.{aaa:ooo,bbb}', () => {\n  expect(\n    Path.setIn({ a: { b: { c: { kkk: 'ddd' } } } }, 'a.b.c.{aaa:ooo,bbb}', {\n      aaa: 123,\n      bbb: 321,\n    })\n  ).toEqual({ a: { b: { c: { ooo: 123, bbb: 321, kkk: 'ddd' } } } })\n})\n\ntest('getIn with a.b.c.{aaa:ooo,bbb}', () => {\n  expect(\n    Path.getIn(\n      { a: { b: { c: { ooo: 123, bbb: 321, kkk: 'ddd' } } } },\n      'a.b.c.{aaa:ooo,bbb}'\n    )\n  ).toEqual({ aaa: 123, bbb: 321 })\n})\n\ntest('setIn with a.b.c.[aaa,bbb]', () => {\n  expect(Path.setIn({}, 'a.b.c.[aaa,bbb]', [123, 321])).toEqual({\n    a: { b: { c: { aaa: 123, bbb: 321 } } },\n  })\n})\n\ntest('getIn with a.b.c.[aaa,bbb]', () => {\n  expect(\n    Path.getIn({ a: { b: { c: { aaa: 123, bbb: 321 } } } }, 'a.b.c.[aaa,bbb]')\n  ).toEqual([123, 321])\n})\n\ntest('setIn with a.b.c.[aaa,bbb] source has extra property', () => {\n  expect(\n    Path.setIn(\n      { a: { b: { c: { kkk: 'ddd' } } } },\n      'a.b.c.[aaa,bbb]',\n      [123, 321]\n    )\n  ).toEqual({ a: { b: { c: { aaa: 123, bbb: 321, kkk: 'ddd' } } } })\n})\n\ntest('getIn with a.b.c.[aaa,bbb] source has extra property', () => {\n  expect(\n    Path.getIn(\n      { a: { b: { c: { aaa: 123, bbb: 321, kkk: 'ddd' } } } },\n      'a.b.c.[aaa,bbb]'\n    )\n  ).toEqual([123, 321])\n})\n\ntest('setIn with a.b.c.[{ddd,kkk:mmm},bbb]', () => {\n  expect(\n    Path.setIn({}, 'a.b.c.[{ddd,kkk:mmm},bbb]', [{ ddd: 123, kkk: 'hhh' }, 321])\n  ).toEqual({ a: { b: { c: { ddd: 123, bbb: 321, mmm: 'hhh' } } } })\n})\n\ntest('getIn with a.b.c.[{ddd,kkk:mmm},bbb]', () => {\n  expect(\n    Path.getIn(\n      { a: { b: { c: { ddd: 123, bbb: 321, mmm: 'hhh' } } } },\n      'a.b.c.[{ddd,kkk:mmm},bbb]'\n    )\n  ).toEqual([{ ddd: 123, kkk: 'hhh' }, 321])\n})\n\ntest('setIn with a.b.c.{aaa:ooo,bbb:[ccc,ddd]}', () => {\n  expect(\n    Path.setIn(\n      { a: { b: { c: { kkk: 'ddd' } } } },\n      'a.b.c.{aaa:ooo,bbb:[ccc,ddd]}',\n      { aaa: 123, bbb: [123, 321] }\n    )\n  ).toEqual({ a: { b: { c: { ooo: 123, ccc: 123, ddd: 321, kkk: 'ddd' } } } })\n})\n\ntest('getIn with a.b.c.{aaa:ooo,bbb:[ccc,ddd]}', () => {\n  expect(\n    Path.getIn(\n      { a: { b: { c: { ooo: 123, ccc: 123, ddd: 321, kkk: 'ddd' } } } },\n      'a.b.c.{aaa:ooo,bbb:[ccc,ddd]}'\n    )\n  ).toEqual({ aaa: 123, bbb: [123, 321] })\n})\n\ntest('existIn with a.b.c', () => {\n  expect(Path.existIn({ a: { b: { c: 123123 } } }, 'a.b.c')).toEqual(true)\n  expect(Path.existIn({ a: { b: { c: 123123 } } }, 'a.b.c.d')).toEqual(false)\n  expect(Path.existIn({ a: 123 }, 'a.b.c.d')).toEqual(false)\n  expect(\n    Path.existIn(\n      { a: { b: { c: { ooo: 123, ccc: 123, ddd: 321, kkk: 'ddd' } } } },\n      'a.b.c.{aaa:ooo,bbb:[ccc,ddd]}'\n    )\n  ).toEqual(true)\n  expect(\n    Path.existIn(\n      { a: { b: { c: { ooo: 123, ccc: 123, kkk: 'ddd' } } } },\n      'a.b.c.{aaa:ooo,bbb:[ccc,ddd]}'\n    )\n  ).toEqual(false)\n  expect(Path.existIn({ a: [{}] }, 'a.0')).toEqual(true)\n})\n\ntest('existIn with start Path', () => {\n  expect(Path.existIn({ a: [{}] }, 'a.0', Path.parse('a'))).toEqual(false)\n  expect(Path.existIn({ a: [{}] }, 'b.a.0', Path.parse('b'))).toEqual(true)\n})\n\ntest('deleteIn', () => {\n  expect(\n    Path.deleteIn({ a: { b: { c: { ooo: 123, ccc: 234 } } } }, 'a.b.c.ccc')\n  ).toEqual({ a: { b: { c: { ooo: 123 } } } })\n\n  expect(\n    Path.deleteIn({ a: { b: { c: { ooo: 123, ccc: 234 } } } }, null)\n  ).toEqual({ a: { b: { c: { ooo: 123, ccc: 234 } } } })\n\n  expect(\n    Path.deleteIn({ a: { b: { c: { ooo: 123, ccc: 234 } } } }, [])\n  ).toEqual({ a: { b: { c: { ooo: 123, ccc: 234 } } } })\n\n  expect(Path.deleteIn({ a: { b: { c: 'c' } } }, 'a.b.c.ccc')).toEqual({\n    a: { b: { c: 'c' } },\n  })\n\n  expect(Path.deleteIn({ a: 1, b: 2 }, '{ a }')).toEqual({ b: 2 })\n  expect(Path.deleteIn([1, 2], '[0]')).toEqual([undefined, 2])\n})\n\ntest('ensureIn', () => {\n  expect(Path.parse('a.b').ensureIn({}, 'default')).toEqual('default')\n  expect(Path.parse('a.b').ensureIn({ a: { b: 'value' } }, 'default')).toEqual(\n    'value'\n  )\n  expect(Path.ensureIn({}, 'a.b.c', 'default')).toEqual('default')\n})\n\ntest('complex destructing', () => {\n  expect(\n    Path.setIn(\n      {},\n      '{aa:{bb:{cc:destructor1,dd:[destructor2,destructor3],ee}}}',\n      {\n        aa: {\n          bb: {\n            cc: 123,\n            dd: [333, 444],\n            ee: 'abcde',\n          },\n        },\n      }\n    )\n  ).toEqual({\n    destructor1: 123,\n    destructor2: 333,\n    destructor3: 444,\n    ee: 'abcde',\n  })\n  expect(\n    Path.getIn(\n      {\n        destructor1: 123,\n        destructor2: 333,\n        destructor3: 444,\n        ee: 'abcde',\n      },\n      '{aa:{bb:{cc:destructor1,dd:[destructor2,destructor3],ee}}}'\n    )\n  ).toEqual({\n    aa: {\n      bb: {\n        cc: 123,\n        dd: [333, 444],\n        ee: 'abcde',\n      },\n    },\n  })\n})\n\ntest('test getIn with invalid value', () => {\n  const value = {\n    array: [null, undefined, { nil: null, undef: undefined }],\n    nil: null,\n    undef: undefined,\n  }\n  expect(getIn(value, 'array.0')).toBeNull()\n  expect(getIn(value, 'array.1')).toBeUndefined()\n  expect(getIn(value, 'array.2.nil')).toBeNull()\n  expect(getIn(value, 'array.2.undef')).toBeUndefined()\n  expect(getIn(value, 'nil')).toBeNull()\n  expect(getIn(value, 'undef')).toBeUndefined()\n})\n\ntest('test setIn with invalid value', () => {\n  const value = {\n    a: 1,\n    b: 2,\n    array: [null, undefined, { nil: null, undef: undefined }],\n    nil: null,\n    undef: undefined,\n  }\n  setIn(value, 'a', null)\n  setIn(value, 'b', undefined)\n  // undefined 与 null 互转\n  setIn(value, 'array.0', undefined)\n  setIn(value, 'array.1', null)\n  setIn(value, 'array.2.nil', undefined)\n  setIn(value, 'array.2.undef', null)\n  setIn(value, 'nil', undefined)\n  setIn(value, 'undef', null)\n\n  expect(getIn(value, 'a')).toBeNull()\n  expect(getIn(value, 'b')).toBeUndefined()\n  expect(getIn(value, 'array.0')).toBeUndefined()\n  expect(getIn(value, 'array.1')).toBeNull()\n  expect(getIn(value, 'array.2.nil')).toBeUndefined()\n  expect(getIn(value, 'array.2.undef')).toBeNull()\n  expect(getIn(value, 'nil')).toBeUndefined()\n  expect(getIn(value, 'undef')).toBeNull()\n})\n\ntest('path arguments', () => {\n  const path = new Path('a.b.c')\n  expect(new Path(path).segments).toEqual(['a', 'b', 'c'])\n\n  const matchPath = Path.match('a.b.c')\n  expect(new Path(matchPath).segments).toEqual(['a', 'b', 'c'])\n\n  expect(new Path(undefined).segments).toEqual([])\n})\n\ntest('path methods', () => {\n  const path = Path.parse('a.b.c')\n\n  expect(path.concat(Path.parse('d.e')).segments).toEqual([\n    'a',\n    'b',\n    'c',\n    'd',\n    'e',\n  ])\n\n  expect(Path.parse(['a', 'b', 'c']).toString()).toEqual('a.b.c')\n  expect(Path.parse(['a', 'b', 'c']).length).toEqual(3)\n\n  const matchPath = Path.parse('*')\n  const regexPath = Path.parse(/.+/)\n  expect(() => matchPath.concat('a')).toThrowError()\n  expect(() => regexPath.concat('a')).toThrowError()\n  expect(() => matchPath.slice()).toThrowError()\n  expect(() => regexPath.slice()).toThrowError()\n  expect(() => matchPath.pop()).toThrowError()\n  expect(() => regexPath.pop()).toThrowError()\n  expect(() => matchPath.splice(0, 1)).toThrowError()\n  expect(() => regexPath.splice(0, 1)).toThrowError()\n  expect(() => matchPath.forEach(() => {})).toThrowError()\n  expect(() => regexPath.forEach(() => {})).toThrowError()\n  expect(() => matchPath.map(() => {})).toThrowError()\n  expect(() => regexPath.map(() => {})).toThrowError()\n  expect(() => matchPath.reduce((p) => p, '')).toThrowError()\n  expect(() => regexPath.reduce((p) => p, '')).toThrowError()\n\n  expect(path.slice().segments).toEqual(['a', 'b', 'c'])\n  expect(path.push('d').segments).toEqual(['a', 'b', 'c', 'd'])\n  expect(path.pop().segments).toEqual(['a', 'b'])\n  expect(path.splice(0, 1).segments).toEqual(['b', 'c'])\n\n  let key = ''\n  path.forEach((p) => (key += p + '_'))\n  expect(key).toEqual('a_b_c_')\n  expect(path.map((p) => p)).toEqual(['a', 'b', 'c'])\n  expect(path.reduce((str, p) => str + p, '')).toEqual('abc')\n  expect(path.parent().segments).toEqual(['a', 'b'])\n\n  expect(() => Path.parse('*').includes('*')).toThrowError()\n  expect(() => Path.parse('*').includes('*')).toThrowError()\n  expect(() => Path.parse('a.b').includes('*')).toThrowError()\n  expect(Path.parse('*').includes('a.b')).toBeTruthy()\n  expect(Path.parse('a.b').includes('a.b')).toBeTruthy()\n  expect(Path.parse('a.b').includes('a.c')).toBeFalsy()\n  expect(Path.parse('a.b').includes('a.b.c')).toBeFalsy()\n\n  expect(Path.parse('a.b.c').transform(/[a-z]/, (...result) => result)).toEqual(\n    ['a', 'b', 'c']\n  )\n  expect(Path.parse('a.b.c').transform(/[a-b]/, (...result) => result)).toEqual(\n    ['a', 'b']\n  )\n  expect(Path.parse('a.b.c').transform('', null)).toEqual('')\n  expect(() => Path.parse('*').transform('', () => {})).toThrowError()\n  expect(Path.transform('a.b.c', /[a-z]/, (...result) => result)).toEqual([\n    'a',\n    'b',\n    'c',\n  ])\n\n  expect(Path.parse('a.b.c').match('*')).toBeTruthy()\n  expect(() => Path.parse('*').match('*')).toThrowError()\n  expect(Path.match('*')('a.b.c')).toBeTruthy()\n  expect(Path.match('a.b')('a.b.c')).toBeFalsy()\n\n  const matcher = Path.match('a.b.c')\n  expect(Path.parse(matcher).segments).toEqual(['a', 'b', 'c'])\n})\n"
  },
  {
    "path": "packages/path/src/__tests__/basic.spec.ts",
    "content": "import { Path } from '../'\n\nconst { isPathPattern, match } = Path\n\ntest('isPathPattern', () => {\n  expect(isPathPattern('obj')).toBeTruthy()\n  expect(isPathPattern(['obj', 'aa'])).toBeTruthy()\n  expect(isPathPattern(/^obj/)).toBeTruthy()\n\n  const matcher = match('obj.aa')\n  expect(isPathPattern(matcher)).toBeTruthy()\n})\n"
  },
  {
    "path": "packages/path/src/__tests__/match.spec.ts",
    "content": "import expect from 'expect'\nimport { Path } from '../'\nimport { Matcher } from '../matcher'\n\nconst match = (obj) => {\n  for (let name in obj) {\n    test('test match ' + name, () => {\n      const path = new Path(name)\n      if (Array.isArray(obj[name]) && Array.isArray(obj[name][0])) {\n        obj[name].forEach((_path) => {\n          expect(path.match(_path)).toBeTruthy()\n        })\n      } else {\n        expect(path.match(obj[name])).toBeTruthy()\n      }\n    })\n  }\n}\n\nconst unmatch = (obj) => {\n  for (let name in obj) {\n    test('test unmatch ' + name, () => {\n      const path = new Path(name)\n      if (Array.isArray(obj[name]) && Array.isArray(obj[name][0])) {\n        obj[name].forEach((_path) => {\n          expect(path.match(_path)).toBeFalsy()\n        })\n      } else {\n        expect(path.match(obj[name])).toBeFalsy()\n      }\n    })\n  }\n}\n\ntest('basic match', () => {\n  expect(Path.parse('xxx').match('')).toBeFalsy()\n  expect(Path.parse('xxx').match('aaa')).toBeFalsy()\n  expect(Path.parse('xxx.eee').match('xxx')).toBeFalsy()\n  expect(Path.parse('*(xxx.eee~)').match('xxx')).toBeFalsy()\n  expect(Path.parse('xxx.eee~').match('xxx.eee')).toBeTruthy()\n  expect(Path.parse('*(!xxx.eee,yyy)').match('xxx')).toBeFalsy()\n  expect(Path.parse('*(!xxx.eee,yyy)').match('xxx.ooo.ppp')).toBeTruthy()\n  expect(Path.parse('*(!xxx.eee,yyy)').match('xxx.eee')).toBeFalsy()\n  expect(Path.parse('*(!xxx.eee~,yyy)').match('xxx.eee')).toBeFalsy()\n  expect(Path.parse('~.aa').match('xxx.aa')).toBeTruthy()\n})\n\ntest('not expect match not', () => {\n  expect(new Matcher({}).match(['']).matched).toBeFalsy()\n})\n\ntest('test matchGroup', () => {\n  const pattern = new Path('*(aa,bb,cc)')\n  expect(pattern.matchAliasGroup('aa', 'bb')).toEqual(true)\n  const excludePattern = new Path('aa.bb.*(11,22,33).*(!aa,bb,cc)')\n  expect(\n    excludePattern.matchAliasGroup('aa.bb.11.mm', 'aa.cc.dd.bb.11.mm')\n  ).toEqual(true)\n  expect(excludePattern.matchAliasGroup('aa.cc', 'aa.kk.cc')).toEqual(false)\n  expect(new Path('aa.*(!bb)').matchAliasGroup('kk.mm.aa.bb', 'aa.bb')).toEqual(\n    false\n  )\n  expect(\n    new Path('aa.*(!bb)').matchAliasGroup('kk.mm.aa.bb.cc', 'kk.mm.aa')\n  ).toEqual(false)\n  expect(new Path('aa.*(!bb,oo)').matchAliasGroup('kk.mm', 'aa')).toEqual(false)\n  expect(new Path('aa.*(!bb.*)').matchAliasGroup('kk.mm', 'aa')).toEqual(false)\n  expect(new Path('aa.*(!bb)').matchAliasGroup('kk.mm.aa.cc', 'aa.cc')).toEqual(\n    true\n  )\n  const patttern2 = Path.parse('*(array)')\n  expect(patttern2.matchAliasGroup(['array', 0], ['array', 0])).toEqual(false)\n})\n\ntest('exclude match', () => {\n  //路径长度相等\n  expect(Path.parse('*(!aaa)').match('ggg')).toBeTruthy()\n  expect(Path.parse('*(!aaa)').match('aaa')).toBeFalsy()\n  expect(Path.parse('*(!aaa.bbb)').match('ggg.ddd')).toBeTruthy()\n  expect(Path.parse('*(!aaa.ccc)').match('aaa.ccc')).toBeFalsy()\n  //长路径匹配短路径\n  expect(Path.parse('*(!aaa.bbb)').match('ggg')).toBeTruthy()\n  expect(Path.parse('*(!aaa.bbb)').match('aaa')).toBeFalsy()\n  //短路径匹配长路径\n  expect(Path.parse('*(!aaa)').match('aaa.bbb')).toBeTruthy()\n  expect(Path.parse('*(!aaa)').match('aaa.ccc')).toBeTruthy()\n  expect(Path.parse('*(!aaa)').match('bbb.ccc')).toBeTruthy()\n\n  expect(Path.parse('*(!aaa,bbb)').match('bbb')).toBeFalsy()\n  expect(Path.parse('*(!aaa.bbb)').match('aaa.ccc')).toBeTruthy()\n  expect(Path.parse('*(!basic.name,versionTag)').match('basic.id')).toBeTruthy()\n  expect(Path.parse('*(!basic.name,versionTag)').match('basic')).toBeFalsy()\n  expect(\n    Path.parse('*(!basic.name,versionTag)').match('isExecutable')\n  ).toBeTruthy()\n  expect(\n    Path.parse('*(!basic.name,versionTag)').match('versionTag')\n  ).toBeFalsy()\n  expect(\n    Path.parse('*(!basic.name,basic.name.*,versionTag)').match('basic.name')\n  ).toBeFalsy()\n  expect(\n    Path.parse('*(!basic.name,basic.name.*,versionTag)').match('basic.name.kkk')\n  ).toBeFalsy()\n  expect(Path.parse('aa.*(!bb)').match('kk.mm.aa.bb.cc')).toBeFalsy()\n  expect(Path.parse('aa.*(!bb)').match('aa')).toBeFalsy()\n  expect(Path.parse('aa.*(!bb.*)').match('aa')).toBeFalsy()\n  expect(Path.parse('aa.*(!bb,cc)').match('aa')).toBeFalsy()\n  expect(Path.parse('aa.*(!bb,cc)').match('aa.dd')).toBeTruthy()\n  expect(Path.parse('aa.*(!bb,cc)').match('aa.kk')).toBeTruthy()\n})\n\ntest('match regexp', () => {\n  expect(Path.parse(/^\\d+$/).match('212')).toBeTruthy()\n  expect(Path.parse(/^\\d+$/).match('212dd')).toBeFalsy()\n})\n\ntest('test zero', () => {\n  expect(Path.parse('t.0.value~').match(['t', 0, 'value_list'])).toEqual(true)\n})\n\ntest('test optional wild match', () => {\n  expect(Path.parse('aa.**').match(['aa'])).toEqual(true)\n  expect(Path.parse('aa.**').match(['aa', 'bb', 'cc'])).toEqual(true)\n  expect(Path.parse('aa.*').match(['aa'])).toEqual(false)\n  expect(Path.parse('aa.\\\\*\\\\*\\\\.aa').match(['aa', '**.aa'])).toEqual(true)\n  expect(Path.parse('aa.[[**.aa]]').match(['aa', '**.aa'])).toEqual(true)\n  expect(() => Path.parse('aa.**.aa').match(['aa'])).toThrowError()\n  expect(() => Path.parse('aa.**(bb)').match(['aa'])).toThrowError()\n  expect(Path.parse('*(aa.**)').match(['aa'])).toEqual(true)\n  expect(Path.parse('*(aa.**,bb.**)').match(['aa'])).toEqual(true)\n  expect(Path.parse('*(aa.**,bb.**)').match(['aa', 'bb', 'cc'])).toEqual(true)\n  expect(Path.parse('*(aa.**,bb.**)').match(['bb'])).toEqual(true)\n  expect(Path.parse('*(aa.**,bb.**)').match(['bb', 'cc', 'dd'])).toEqual(true)\n  expect(Path.parse('*(aa.**,bb.**)').match(['cc'])).toEqual(false)\n  expect(Path.parse('*(aa.**,bb.**).bb').match(['aa', 'oo'])).toEqual(true)\n  expect(Path.parse('*(aa.**,bb.**).bb').match(['bb', 'oo'])).toEqual(true)\n  expect(Path.parse('*(aa.**,bb.**).bb').match(['aa', 'oo', 'bb'])).toEqual(\n    true\n  )\n  expect(Path.parse('*(aa.**,bb.**).bb').match(['bb', 'oo', 'bb'])).toEqual(\n    true\n  )\n  expect(\n    Path.parse('*(aa.**,bb.**).bb').match(['aa', 'oo', 'kk', 'dd', 'bb'])\n  ).toEqual(true)\n  expect(\n    Path.parse('*(aa.**,bb.**).bb').match(['cc', 'oo', 'kk', 'dd', 'bb'])\n  ).toEqual(false)\n  expect(\n    Path.parse('*(aa.**,bb.**).bb').match(['bb', 'oo', 'kk', 'dd', 'bb'])\n  ).toEqual(true)\n  expect(\n    Path.parse('*(aa.**,bb.**).bb').match(['kk', 'oo', 'kk', 'dd', 'bb'])\n  ).toEqual(false)\n})\n\ntest('test expand', () => {\n  expect(\n    Path.parse('t.0.value~').match(['t', 0, 'value_list', 'hello'])\n  ).toEqual(false)\n})\n\ntest('test multi expand', () => {\n  expect(Path.parse('*(aa~,bb~).*').match(['aa12323', 'asdasd'])).toEqual(true)\n})\n\ntest('test group', () => {\n  const node = Path.parse('*(phases.*.type,phases.*.steps.*.type)')\n  expect(node.match('phases.0.steps.1.type')).toBeTruthy()\n})\n\ntest('test segments', () => {\n  const node = Path.parse('a.0.b')\n  expect(node.match(['a', 0, 'b'])).toEqual(true)\n})\n\ntest('nested group match', () => {\n  expect(\n    Path.parse('aa.*.*(bb,cc).dd.*(kk,oo).ee').match('aa.0.cc.dd.kk.ee')\n  ).toEqual(true)\n})\n\ntest('group match with destructor', () => {\n  expect(Path.parse('*([startDate,endDate],date,weak)').match('date')).toEqual(\n    true\n  )\n  expect(Path.parse('*({startDate,endDate},date,weak)').match('date')).toEqual(\n    true\n  )\n  expect(Path.parse('*([startDate,endDate],date,weak)').match('xxx')).toEqual(\n    false\n  )\n  expect(Path.parse('*({startDate,endDate},date,weak)').match('xxx')).toEqual(\n    false\n  )\n  expect(\n    Path.parse('*([startDate,endDate],date,weak)').match('[startDate,endDate]')\n  ).toEqual(true)\n  expect(\n    Path.parse('*({startDate,endDate},date,weak)').match('{startDate,endDate}')\n  ).toEqual(true)\n})\n\ntest('all range match', () => {\n  expect(\n    Path.parse('array.*[:].*[:].*[:].bb').match('array.0.0.0.aa')\n  ).toBeFalsy()\n})\n\nmatch({\n  '*': [[], ['aa'], ['aa', 'bb', 'cc'], ['aa', 'dd', 'gg']],\n  '*.a.b': [\n    ['c', 'a', 'b'],\n    ['k', 'a', 'b'],\n    ['m', 'a', 'b'],\n  ],\n  'a.*.k': [\n    ['a', 'b', 'k'],\n    ['a', 'd', 'k'],\n    ['a', 'c', 'k'],\n  ],\n  'a.*(b,d,m).k': [\n    ['a', 'b', 'k'],\n    ['a', 'd', 'k'],\n    ['a', 'm', 'k'],\n  ],\n  'a.*(!b,d,m).*(!a,b)': [\n    ['a', 'o', 'k'],\n    ['a', 'q', 'k'],\n    ['a', 'c', 'k'],\n  ],\n  'a.*(b.c.d,d,m).k': [\n    ['a', 'b', 'c', 'd', 'k'],\n    ['a', 'd', 'k'],\n    ['a', 'm', 'k'],\n  ],\n  'a.*(b.*(c,k).d,d,m).k': [\n    ['a', 'b', 'c', 'd', 'k'],\n    ['a', 'b', 'k', 'd', 'k'],\n    ['a', 'd', 'k'],\n    ['a', 'm', 'k'],\n  ],\n  'a.b.*': [\n    ['a', 'b', 'c', 'd'],\n    ['a', 'b', 'c'],\n    ['a', 'b', 2, 'aaa', 3, 'bbb'],\n  ],\n  '*(step1,step2).*': [\n    ['step1', 'aa', 'bb'],\n    ['step1', 'aa', 'bb', 'ccc', 'ddd'],\n  ],\n  'dyanmic.*(!dynamic-1)': [\n    ['dyanmic', 'dynamic-2'],\n    ['dyanmic', 'dynamic-3'],\n  ],\n  't.0.value~': [['t', '0', 'value']],\n  'a.*[10:50].*(!a,b)': [\n    ['a', 49, 's'],\n    ['a', 10, 's'],\n    ['a', 50, 's'],\n  ],\n  'a.*[10:].*(!a,b)': [\n    ['a', 49, 's'],\n    ['a', 10, 's'],\n    ['a', 50, 's'],\n  ],\n  'a.*[].*(!a,b)': [\n    ['a', 49, 's'],\n    ['a', 10, 's'],\n    ['a', 50, 's'],\n  ],\n  'a.*[:50].*(!a,b)': [\n    ['a', 49, 's'],\n    ['a', 10, 's'],\n    ['a', 50, 's'],\n  ],\n  'a.*([[a.b.c]],[[c.b.d~]])': [\n    ['a', '[[a.b.c]]'],\n    ['a', 'c.b.d~'],\n  ],\n  'a.*(!k,d,m).k': [\n    ['a', 'u', 'k'],\n    ['a', 'o', 'k'],\n    ['a', 'p', 'k'],\n  ],\n  'a\\\\.\\\\*\\\\[1\\\\]': [['a.*[1]']],\n  '[[\\\\[aa,bb\\\\]]]': [['[aa,bb]']],\n  '[[\\\\[aa,bb\\\\]   ]]': [['[aa,bb]   ']],\n  '[[   \\\\[aa,bb~\\\\]   ]]': [['   [aa,bb~]   ']],\n  'aa.bb.*': [['aa', 'bb', 'ccc']],\n  'a.*': [\n    ['a', 'b'],\n    ['a', 'b', 'c'],\n  ],\n  'aa.*.*(bb,cc).dd': [['aa', '0', 'cc', 'dd']],\n  'aaa.products.0.*': [['aaa', 'products', '0', 'aaa']],\n  'aa~.ccc': [\n    ['aa', 'ccc'],\n    ['aa12', 'ccc'],\n  ],\n  '*(aa~,bb~).*': [\n    ['aa12323', 'asdasd'],\n    ['bb12222', 'asd'],\n  ],\n  '*(aa,bb,bb.aa)': [['bb', 'aa']],\n  '*(!aa,bb,bb.aa)': [['xx'], ['yyy']],\n  '*(!aaa)': [['bbb']],\n  '*(!aaa,bbb)': [['ccc'], ['ggg']],\n  '*([startDate,endDate],date,weak)': [['date']],\n})\n\nunmatch({\n  'a.*': [['a'], ['b']],\n  '*(array)': [['array', '0']],\n  'aa.bb.*': [['aa', 'bb']],\n  'a.*.b': [['a', 'k', 'b', 'd']],\n  '*(!aaa)': [['aaa']],\n  'dyanmic.*(!dynamic-1)': [['dyanmic', 'dynamic-1']],\n  'dyanmic.*(!dynamic-1.*)': [['dyanmic', 'dynamic-1', 'ccc']],\n  a: [['c', 'b']],\n  'aa~.ccc': [['a', 'ccc'], ['aa'], ['aaasdd']],\n  bb: [['bb', 'cc']],\n  'aa.*(cc,bb).*.aa': [['aa', 'cc', '0', 'bb']],\n})\n"
  },
  {
    "path": "packages/path/src/__tests__/parser.spec.ts",
    "content": "import expect from 'expect'\nimport { Parser } from '../parser'\nimport { Path } from '../'\nconst parse = (string: string, json: any, index: number) => {\n  test('test ' + string + ` : ${index}`, () => {\n    const parser = new Parser(string)\n    expect(parser.parse()).toEqual(json)\n  })\n}\n\nconst batchTest = (obj) => {\n  let i = 0\n  for (let key in obj) {\n    i++\n    parse(key, obj[key], i)\n  }\n}\n\ntest('relative', () => {\n  const parser = new Parser('..[ + 1 ].dd.bb', new Path(['aa', '1', 'cc']))\n  const parser2 = new Parser('.ee', new Path(['aa', '1', 'cc']))\n  const parser3 = new Parser('.', new Path(['aa', '1', 'cc']))\n  const parser4 = new Parser('..', new Path(['aa', '1', 'cc']))\n  const parser5 = new Parser('.[].dd', new Path(['aa', '1']))\n  const parser6 = new Parser('.[].[]', new Path(['aa', '1']))\n  const parser7 = new Parser('.[].[aa]', new Path(['aa', '1']))\n  parser2.parse()\n  parser3.parse()\n  parser4.parse()\n  parser5.parse()\n  parser6.parse()\n  parser7.parse()\n  expect(parser.parse()).toEqual({\n    type: 'Identifier',\n    value: 'aa',\n    after: {\n      type: 'DotOperator',\n      after: {\n        type: 'DestructorExpression',\n        value: {\n          type: 'ArrayPattern',\n          elements: [\n            {\n              type: 'Identifier',\n              value: '+',\n              after: {\n                type: 'Identifier',\n                value: '1',\n              },\n            },\n          ],\n        },\n        source: '2',\n        after: {\n          type: 'DotOperator',\n          after: {\n            type: 'Identifier',\n            value: 'dd',\n            after: {\n              type: 'DotOperator',\n              after: {\n                type: 'Identifier',\n                value: 'bb',\n              },\n            },\n          },\n        },\n      },\n    },\n  })\n  expect(parser.data.segments).toEqual(['aa', '2', 'dd', 'bb'])\n  expect(parser2.data.segments).toEqual(['aa', '1', 'ee'])\n  expect(parser3.data.segments).toEqual(['aa', '1'])\n  expect(parser4.data.segments).toEqual(['aa'])\n  expect(parser5.data.segments).toEqual(['aa', '1', 'dd'])\n  expect(parser6.data.segments).toEqual(['aa', '1', '[]'])\n  expect(parser7.data.segments).toEqual(['aa', '1', '[aa]'])\n})\n\ntest('calculate', () => {\n  const parser0 = new Parser('..[+].dd.bb', new Path(['aa', '1', 'cc']))\n  parser0.parse()\n  expect(parser0.data.segments).toEqual(['aa', '2', 'dd', 'bb'])\n\n  const parser = new Parser('..[ -1 ].dd.bb', new Path(['aa', '1', 'cc']))\n  parser.parse()\n  expect(parser.data.segments).toEqual(['aa', '0', 'dd', 'bb'])\n\n  // TODO support\n  // const parser2 = new Parser('..[ *2 ].dd.bb', new Path(['aa', '2', 'cc']))\n  // parser2.parse()\n  // expect(parser2.data.segments).toEqual(['aa', '4', 'dd', 'bb'])\n\n  const parser3 = new Parser('..[ /2 ].dd.bb', new Path(['aa', '2', 'cc']))\n  parser3.parse()\n  expect(parser3.data.segments).toEqual(['aa', '1', 'dd', 'bb'])\n\n  const parser4 = new Parser('..[ +1 ].dd.bb', new Path(['aa', 'a', 'cc']))\n  parser4.parse()\n  expect(parser4.data.segments).toEqual(['aa', 'a1', 'dd', 'bb'])\n\n  const parser5 = new Parser('..[ -1 ].dd.bb', new Path(['aa', 'a', 'cc']))\n  parser5.parse()\n  expect(parser5.data.segments).toEqual(['aa', 'NaN', 'dd', 'bb'])\n\n  // TODO support\n  // const parser6 = new Parser('..[ *1 ].dd.bb', new Path(['aa', 'a', 'cc']))\n  // parser6.parse()\n  // expect(parser6.data.segments).toEqual(['aa', 'NaN', 'dd', 'bb'])\n\n  const parser7 = new Parser('..[ /1 ].dd.bb', new Path(['aa', 'a', 'cc']))\n  parser7.parse()\n  expect(parser7.data.segments).toEqual(['aa', 'NaN', 'dd', 'bb'])\n\n  const parser8 = new Parser('..[1].dd.bb', new Path(['aa', '1', 'cc']))\n  parser8.parse()\n  expect(parser8.data.segments).toEqual(['aa', '2', 'dd', 'bb'])\n  const parser9 = new Parser('')\n  parser9.next()\n  expect(parser9.parseObjectProperties()).toEqual([])\n})\n\ntest('parser unexpected', () => {\n  const parser = new Parser('array[]')\n  expect(() => parser.parse()).toThrowError()\n\n  const parser2 = new Parser('array[0.')\n  expect(() => parser2.parse()).toThrowError()\n\n  const parser3 = new Parser('.[+]', new Path('*.1.cc'))\n  expect(() => parser3.parse()).toThrowError()\n\n  const parser4 = new Parser('[:,4]')\n  expect(() => parser4.parse()).toThrowError()\n})\n\ntest('tokenizer', () => {\n  const originFromCharCode = String.fromCharCode\n  String.fromCharCode = null\n\n  const parser = new Parser('aa.bb')\n  parser.parse()\n  expect(parser.data.segments).toEqual(['aa', 'bb'])\n\n  const parser2 = new Parser('array.0.[aa,bb]')\n  parser2.parse()\n  expect(parser2.data.segments).toEqual(['array', '0', '[aa,bb]'])\n\n  String.fromCharCode = originFromCharCode\n\n  const char13 = String.fromCharCode(13)\n  const parser3 = new Parser(`${char13} aa.bb`)\n  parser3.parse()\n\n  const char11 = String.fromCharCode(11)\n  const parser4 = new Parser(`${char11} aa.bb`)\n  parser4.parse()\n\n  const parser5 = new Parser('')\n  parser5.next()\n  parser5.parse()\n  expect(parser5.data.segments).toEqual([])\n\n  const char10 = String.fromCharCode(10)\n  const parser6 = new Parser(`{\n                c${char13}${char10}: kk,\n                d : mm\n          }`)\n  parser6.parse()\n  expect(parser6.data.segments).toEqual(['{c:kk,d:mm}'])\n\n  const parser7 = new Parser(`{\n                c${char13}${char11}: kk,\n                d : mm\n          }`)\n  parser7.parse()\n  expect(parser7.data.segments).toEqual(['{c:kk,d:mm}'])\n\n  const parser8 = new Parser(`\\\\name`)\n  parser8.state.pos++\n  parser8.parse()\n  expect(parser8.data.segments).toEqual(['name'])\n\n  const parser9 = new Parser(`[a,{b}]`)\n  parser9.parse()\n  expect(parser9.data.segments).toEqual(['[a,{b}]'])\n\n  const parser10 = new Parser(`*(a.b.c.*(aa,bb))`)\n  parser10.parse()\n  expect(parser10.data.segments).toEqual([])\n\n  const parser11 = new Parser(`{a,[b,{c}]. }`)\n  expect(() => parser11.parse()).toThrowError()\n\n  const parser12 = new Parser(`*(a.*[1:3])`)\n  parser12.parse()\n  expect(parser12.data.segments).toEqual([])\n\n  const parser13 = new Parser(`*(a.*[1:3]])`)\n  expect(() => parser13.parse()).toThrowError()\n})\n\nbatchTest({\n  '*': {\n    type: 'WildcardOperator',\n  },\n  'a.b.c': {\n    type: 'Identifier',\n    value: 'a',\n    after: {\n      type: 'DotOperator',\n      after: {\n        type: 'Identifier',\n        value: 'b',\n        after: {\n          type: 'DotOperator',\n          after: {\n            type: 'Identifier',\n            value: 'c',\n          },\n        },\n      },\n    },\n  },\n  'a.b.*': {\n    type: 'Identifier',\n    value: 'a',\n    after: {\n      type: 'DotOperator',\n      after: {\n        type: 'Identifier',\n        value: 'b',\n        after: {\n          type: 'DotOperator',\n          after: {\n            type: 'WildcardOperator',\n          },\n        },\n      },\n    },\n  },\n  'a.b.*(111,222,aaa)': {\n    type: 'Identifier',\n    value: 'a',\n    after: {\n      type: 'DotOperator',\n      after: {\n        type: 'Identifier',\n        value: 'b',\n        after: {\n          type: 'DotOperator',\n          after: {\n            type: 'WildcardOperator',\n            filter: {\n              type: 'GroupExpression',\n              value: [\n                {\n                  type: 'Identifier',\n                  value: '111',\n                },\n                {\n                  type: 'Identifier',\n                  value: '222',\n                },\n                {\n                  type: 'Identifier',\n                  value: 'aaa',\n                },\n              ],\n            },\n          },\n        },\n      },\n    },\n  },\n  'a.b.*(!111,222,aaa)': {\n    type: 'Identifier',\n    value: 'a',\n    after: {\n      type: 'DotOperator',\n      after: {\n        type: 'Identifier',\n        value: 'b',\n        after: {\n          type: 'DotOperator',\n          after: {\n            type: 'WildcardOperator',\n            filter: {\n              type: 'GroupExpression',\n              isExclude: true,\n              value: [\n                {\n                  type: 'Identifier',\n                  value: '111',\n                },\n                {\n                  type: 'Identifier',\n                  value: '222',\n                },\n                {\n                  type: 'Identifier',\n                  value: 'aaa',\n                },\n              ],\n            },\n          },\n        },\n      },\n    },\n  },\n  'a.b. * [  11 :  22  ]': {\n    type: 'Identifier',\n    value: 'a',\n    after: {\n      type: 'DotOperator',\n      after: {\n        type: 'Identifier',\n        value: 'b',\n        after: {\n          type: 'DotOperator',\n          after: {\n            type: 'WildcardOperator',\n            filter: {\n              type: 'RangeExpression',\n              start: {\n                type: 'Identifier',\n                value: '11',\n              },\n              end: {\n                type: 'Identifier',\n                value: '22',\n              },\n            },\n          },\n        },\n      },\n    },\n  },\n  'a.b.*([[123123!,()]],[[aaa]])': {\n    type: 'Identifier',\n    value: 'a',\n    after: {\n      type: 'DotOperator',\n      after: {\n        type: 'Identifier',\n        value: 'b',\n        after: {\n          type: 'DotOperator',\n          after: {\n            type: 'WildcardOperator',\n            filter: {\n              type: 'GroupExpression',\n              value: [\n                {\n                  type: 'IgnoreExpression',\n                  value: '123123!,()',\n                },\n                {\n                  type: 'IgnoreExpression',\n                  value: 'aaa',\n                },\n              ],\n            },\n          },\n        },\n      },\n    },\n  },\n  'a.b.*([[123123!,()]],aaa)': {\n    type: 'Identifier',\n    value: 'a',\n    after: {\n      type: 'DotOperator',\n      after: {\n        type: 'Identifier',\n        value: 'b',\n        after: {\n          type: 'DotOperator',\n          after: {\n            type: 'WildcardOperator',\n            filter: {\n              type: 'GroupExpression',\n              value: [\n                {\n                  type: 'IgnoreExpression',\n                  value: '123123!,()',\n                },\n                {\n                  type: 'Identifier',\n                  value: 'aaa',\n                },\n              ],\n            },\n          },\n        },\n      },\n    },\n  },\n  'a.b.*(![[123123!,()]],aaa)': {\n    type: 'Identifier',\n    value: 'a',\n    after: {\n      type: 'DotOperator',\n      after: {\n        type: 'Identifier',\n        value: 'b',\n        after: {\n          type: 'DotOperator',\n          after: {\n            type: 'WildcardOperator',\n            filter: {\n              type: 'GroupExpression',\n              value: [\n                {\n                  type: 'IgnoreExpression',\n                  value: '123123!,()',\n                },\n                {\n                  type: 'Identifier',\n                  value: 'aaa',\n                },\n              ],\n              isExclude: true,\n            },\n          },\n        },\n      },\n    },\n  },\n  'a.b  . *   (![[123123!,()]],aaa,bbb)': {\n    type: 'Identifier',\n    value: 'a',\n    after: {\n      type: 'DotOperator',\n      after: {\n        type: 'Identifier',\n        value: 'b',\n        after: {\n          type: 'DotOperator',\n          after: {\n            type: 'WildcardOperator',\n            filter: {\n              type: 'GroupExpression',\n              value: [\n                {\n                  type: 'IgnoreExpression',\n                  value: '123123!,()',\n                },\n                {\n                  type: 'Identifier',\n                  value: 'aaa',\n                },\n                {\n                  type: 'Identifier',\n                  value: 'bbb',\n                },\n              ],\n              isExclude: true,\n            },\n          },\n        },\n      },\n    },\n  },\n  'a.b.[[123123!,()]]   ': {\n    type: 'Identifier',\n    value: 'a',\n    after: {\n      type: 'DotOperator',\n      after: {\n        type: 'Identifier',\n        value: 'b',\n        after: {\n          type: 'DotOperator',\n          after: {\n            type: 'IgnoreExpression',\n            value: '123123!,()',\n          },\n        },\n      },\n    },\n  },\n  [`a .  \n     b .  \n       [[123123!,()]]\n    \n    .aaaa`]: {\n    type: 'Identifier',\n    value: 'a',\n    after: {\n      type: 'DotOperator',\n      after: {\n        type: 'Identifier',\n        value: 'b',\n        after: {\n          type: 'DotOperator',\n          after: {\n            type: 'IgnoreExpression',\n            value: '123123!,()',\n            after: {\n              type: 'DotOperator',\n              after: {\n                type: 'Identifier',\n                value: 'aaaa',\n              },\n            },\n          },\n        },\n      },\n    },\n  },\n  'a.*(aaa.d.*(!sss),ddd,bbb).c.b': {\n    type: 'Identifier',\n    value: 'a',\n    after: {\n      type: 'DotOperator',\n      after: {\n        type: 'WildcardOperator',\n        filter: {\n          type: 'GroupExpression',\n          value: [\n            {\n              type: 'Identifier',\n              value: 'aaa',\n              after: {\n                type: 'DotOperator',\n                after: {\n                  type: 'Identifier',\n                  value: 'd',\n                  after: {\n                    type: 'DotOperator',\n                    after: {\n                      type: 'WildcardOperator',\n                      filter: {\n                        type: 'GroupExpression',\n                        isExclude: true,\n                        value: [\n                          {\n                            type: 'Identifier',\n                            value: 'sss',\n                          },\n                        ],\n                      },\n                    },\n                  },\n                },\n              },\n            },\n            {\n              type: 'Identifier',\n              value: 'ddd',\n            },\n            {\n              type: 'Identifier',\n              value: 'bbb',\n            },\n          ],\n        },\n        after: {\n          type: 'DotOperator',\n          after: {\n            type: 'Identifier',\n            value: 'c',\n            after: {\n              type: 'DotOperator',\n              after: {\n                type: 'Identifier',\n                value: 'b',\n              },\n            },\n          },\n        },\n      },\n    },\n  },\n  'aa.bb.cc.{aa,bb,cc:kk}': {\n    type: 'Identifier',\n    value: 'aa',\n    after: {\n      type: 'DotOperator',\n      after: {\n        type: 'Identifier',\n        value: 'bb',\n        after: {\n          type: 'DotOperator',\n          after: {\n            type: 'Identifier',\n            value: 'cc',\n            after: {\n              type: 'DotOperator',\n              after: {\n                type: 'DestructorExpression',\n                value: {\n                  type: 'ObjectPattern',\n                  properties: [\n                    {\n                      type: 'ObjectPatternProperty',\n                      key: { type: 'Identifier', value: 'aa' },\n                    },\n                    {\n                      type: 'ObjectPatternProperty',\n                      key: { type: 'Identifier', value: 'bb' },\n                    },\n                    {\n                      type: 'ObjectPatternProperty',\n                      key: { type: 'Identifier', value: 'cc' },\n                      value: { type: 'Identifier', value: 'kk' },\n                    },\n                  ],\n                },\n                source: '{aa,bb,cc:kk}',\n              },\n            },\n          },\n        },\n      },\n    },\n  },\n  'aa.bb.cc.[ [aa,bb,cc,[ [{aa:bb}] ]] ]': {\n    type: 'Identifier',\n    value: 'aa',\n    after: {\n      type: 'DotOperator',\n      after: {\n        type: 'Identifier',\n        value: 'bb',\n        after: {\n          type: 'DotOperator',\n          after: {\n            type: 'Identifier',\n            value: 'cc',\n            after: {\n              type: 'DotOperator',\n              after: {\n                type: 'DestructorExpression',\n                value: {\n                  type: 'ArrayPattern',\n                  elements: [\n                    {\n                      type: 'ArrayPattern',\n                      elements: [\n                        {\n                          type: 'Identifier',\n                          value: 'aa',\n                        },\n                        {\n                          type: 'Identifier',\n                          value: 'bb',\n                        },\n                        {\n                          type: 'Identifier',\n                          value: 'cc',\n                        },\n                        {\n                          type: 'ArrayPattern',\n                          elements: [\n                            {\n                              type: 'ArrayPattern',\n                              elements: [\n                                {\n                                  type: 'ObjectPattern',\n                                  properties: [\n                                    {\n                                      type: 'ObjectPatternProperty',\n                                      key: {\n                                        type: 'Identifier',\n                                        value: 'aa',\n                                      },\n                                      value: {\n                                        type: 'Identifier',\n                                        value: 'bb',\n                                      },\n                                    },\n                                  ],\n                                },\n                              ],\n                            },\n                          ],\n                        },\n                      ],\n                    },\n                  ],\n                },\n                source: '[[aa,bb,cc,[[{aa:bb}]]]]',\n              },\n            },\n          },\n        },\n      },\n    },\n  },\n})\n"
  },
  {
    "path": "packages/path/src/__tests__/share.spec.ts",
    "content": "import { isAssignable, isEqual } from '../shared'\n\ntest('isAssignable', () => {\n  expect(isAssignable({})).toBeTruthy()\n  expect(isAssignable(() => {})).toBeTruthy()\n\n  expect(isAssignable(1)).toBeFalsy()\n  expect(isAssignable('str')).toBeFalsy()\n})\n\ntest('isEqual', () => {\n  const sameObj = {}\n  const sameArray = []\n  expect(isEqual('string', 'string')).toBeTruthy()\n  expect(isEqual(123, 123)).toBeTruthy()\n  expect(isEqual(undefined, undefined)).toBeTruthy()\n  expect(isEqual(null, null)).toBeTruthy()\n\n  expect(isEqual(sameObj, sameObj)).toBeTruthy()\n  expect(isEqual(sameArray, sameArray)).toBeTruthy()\n\n  expect(isEqual([1, '123'], [1, '123'])).toBeTruthy()\n  expect(\n    isEqual([1, '123', { a: 1, b: 2 }], [1, '123', { a: 1, b: 2 }])\n  ).toBeTruthy()\n  expect(\n    isEqual([1, '123', { a: 1, b: 2 }], [1, '123', { a: 1, b: 3 }])\n  ).toBeFalsy()\n  expect(isEqual([1, '123'], [1, '234'])).toBeFalsy()\n  expect(isEqual([], [1])).toBeFalsy()\n  expect(isEqual([], {})).toBeFalsy()\n\n  expect(isEqual({ a: [1, 2, 3] }, { a: [1, 2, 3] })).toBeTruthy()\n  expect(isEqual({ a: [1, 2, 3] }, { a: [1, 2, 4] })).toBeFalsy()\n  expect(isEqual({ a: 1 }, { a: 11 })).toBeFalsy()\n  expect(isEqual({ a: 1 }, { a: 1, b: 2 })).toBeFalsy()\n\n  const b = { age: '234' }\n  // @ts-ignore\n  Object.prototype.name = '123'\n  expect(isEqual({ name: '123' }, b)).toBeFalsy()\n\n  expect(isEqual(NaN, NaN)).toBeTruthy()\n})\n"
  },
  {
    "path": "packages/path/src/contexts.ts",
    "content": "export type Context = {\n  flag: string\n  [key: string]: any\n}\n\nconst ContextType = (flag: string, props?: any): Context => {\n  return {\n    flag,\n    ...props,\n  }\n}\n\nexport const bracketContext = ContextType('[]')\n\nexport const bracketArrayContext = ContextType('[\\\\d]')\n\nexport const bracketDContext = ContextType('[[]]')\n\nexport const parenContext = ContextType('()')\n\nexport const braceContext = ContextType('{}')\n\nexport const destructorContext = ContextType('{x}')\n"
  },
  {
    "path": "packages/path/src/destructor.ts",
    "content": "import {\n  Segments,\n  Node,\n  DestructorRules,\n  isArrayPattern,\n  isObjectPattern,\n  isIdentifier,\n  isDestructorExpression,\n} from './types'\nimport { isNum } from './shared'\n\ntype Mutators = {\n  getIn: (segments: Segments, source: any) => any\n  setIn: (segments: Segments, source: any, value: any) => void\n  deleteIn?: (segments: Segments, source: any) => any\n  existIn?: (segments: Segments, source: any, start: number) => boolean\n}\n\nconst DestructorCache = new Map()\n\nconst isValid = (val: any) => val !== undefined && val !== null\n\nexport const getDestructor = (source: string) => {\n  return DestructorCache.get(source)\n}\n\nexport const setDestructor = (source: string, rules: DestructorRules) => {\n  DestructorCache.set(source, rules)\n}\n\nexport const parseDestructorRules = (node: Node): DestructorRules => {\n  const rules = []\n  if (isObjectPattern(node)) {\n    let index = 0\n    node.properties.forEach((child) => {\n      rules[index] = {\n        path: [],\n      }\n      rules[index].key = child.key.value\n      rules[index].path.push(child.key.value)\n      if (isIdentifier(child.value)) {\n        rules[index].key = child.value.value\n      }\n      const basePath = rules[index].path\n      const childRules = parseDestructorRules(child.value as Node)\n      let k = index\n      childRules.forEach((rule) => {\n        if (rules[k]) {\n          rules[k].key = rule.key\n          rules[k].path = basePath.concat(rule.path)\n        } else {\n          rules[k] = {\n            key: rule.key,\n            path: basePath.concat(rule.path),\n          }\n        }\n        k++\n      })\n      if (k > index) {\n        index = k\n      } else {\n        index++\n      }\n    })\n    return rules\n  } else if (isArrayPattern(node)) {\n    let index = 0\n    node.elements.forEach((child, key) => {\n      rules[index] = {\n        path: [],\n      }\n      rules[index].key = key\n      rules[index].path.push(key)\n      if (isIdentifier(child)) {\n        rules[index].key = child.value\n      }\n      const basePath = rules[index].path\n      const childRules = parseDestructorRules(child as Node)\n      let k = index\n      childRules.forEach((rule) => {\n        if (rules[k]) {\n          rules[k].key = rule.key\n          rules[k].path = basePath.concat(rule.path)\n        } else {\n          rules[k] = {\n            key: rule.key,\n            path: basePath.concat(rule.path),\n          }\n        }\n        k++\n      })\n      if (k > index) {\n        index = k\n      } else {\n        index++\n      }\n    })\n    return rules\n  }\n  if (isDestructorExpression(node)) {\n    return parseDestructorRules(node.value)\n  }\n  return rules\n}\n\nexport const setInByDestructor = (\n  source: any,\n  rules: DestructorRules,\n  value: any,\n  mutators: Mutators\n) => {\n  rules.forEach(({ key, path }) => {\n    mutators.setIn([key], source, mutators.getIn(path, value))\n  })\n}\n\nexport const getInByDestructor = (\n  source: any,\n  rules: DestructorRules,\n  mutators: Mutators\n) => {\n  let response = {}\n  if (rules.length) {\n    if (isNum(rules[0].path[0])) {\n      response = []\n    }\n  }\n  source = isValid(source) ? source : {}\n  rules.forEach(({ key, path }) => {\n    mutators.setIn(path, response, source[key])\n  })\n  return response\n}\n\nexport const deleteInByDestructor = (\n  source: any,\n  rules: DestructorRules,\n  mutators: Mutators\n) => {\n  rules.forEach(({ key }) => {\n    mutators.deleteIn([key], source)\n  })\n}\n\nexport const existInByDestructor = (\n  source: any,\n  rules: DestructorRules,\n  start: number,\n  mutators: Mutators\n) => {\n  return rules.every(({ key }) => {\n    return mutators.existIn([key], source, start)\n  })\n}\n"
  },
  {
    "path": "packages/path/src/index.ts",
    "content": "import { Parser } from './parser'\nimport { isStr, isArr, isFn, isEqual, isObj, isNum, isRegExp } from './shared'\nimport {\n  getDestructor,\n  getInByDestructor,\n  setInByDestructor,\n  deleteInByDestructor,\n  existInByDestructor,\n} from './destructor'\nimport { Segments, Node, Pattern } from './types'\nimport { Matcher } from './matcher'\n\nconst pathCache = new Map()\n\nconst isMatcher = Symbol('PATH_MATCHER')\n\nconst isValid = (val: any) => val !== undefined && val !== null\n\nconst isSimplePath = (val: string) =>\n  val.indexOf('*') === -1 &&\n  val.indexOf('~') === -1 &&\n  val.indexOf('[') === -1 &&\n  val.indexOf(']') === -1 &&\n  val.indexOf(',') === -1 &&\n  val.indexOf(':') === -1 &&\n  val.indexOf(' ') === -1 &&\n  val[0] !== '.'\n\nconst isAssignable = (val: any) =>\n  typeof val === 'object' || typeof val === 'function'\n\nconst isNumberIndex = (val: any) =>\n  isStr(val) ? /^\\d+$/.test(val) : isNum(val)\n\nconst getIn = (segments: Segments, source: any) => {\n  for (let i = 0; i < segments.length; i++) {\n    const index = segments[i]\n    const rules = getDestructor(index as string)\n    if (!rules) {\n      if (!isValid(source)) return\n      source = source[index]\n    } else {\n      source = getInByDestructor(source, rules, { setIn, getIn })\n      break\n    }\n  }\n  return source\n}\n\nconst setIn = (segments: Segments, source: any, value: any) => {\n  for (let i = 0; i < segments.length; i++) {\n    const index = segments[i]\n    const rules = getDestructor(index as string)\n    if (!rules) {\n      if (!isValid(source) || !isAssignable(source)) return\n      if (isArr(source) && !isNumberIndex(index)) {\n        return\n      }\n      if (!isValid(source[index])) {\n        if (value === undefined) {\n          if (source[index] === null) source[index] = value\n          return\n        }\n        if (i < segments.length - 1) {\n          source[index] = isNum(segments[i + 1]) ? [] : {}\n        }\n      }\n      if (i === segments.length - 1) {\n        source[index] = value\n      }\n      source = source[index]\n    } else {\n      setInByDestructor(source, rules, value, { setIn, getIn })\n      break\n    }\n  }\n}\n\nconst deleteIn = (segments: Segments, source: any) => {\n  for (let i = 0; i < segments.length; i++) {\n    const index = segments[i]\n    const rules = getDestructor(index as string)\n    if (!rules) {\n      if (i === segments.length - 1 && isValid(source)) {\n        delete source[index]\n        return\n      }\n\n      if (!isValid(source) || !isAssignable(source)) return\n      source = source[index]\n      if (!isObj(source)) {\n        return\n      }\n    } else {\n      deleteInByDestructor(source, rules, {\n        setIn,\n        getIn,\n        deleteIn,\n      })\n      break\n    }\n  }\n}\n\nconst hasOwnProperty = Object.prototype.hasOwnProperty\n\nconst existIn = (segments: Segments, source: any, start: number | Path) => {\n  if (start instanceof Path) {\n    start = start.length\n  }\n  for (let i = start; i < segments.length; i++) {\n    const index = segments[i]\n    const rules = getDestructor(index as string)\n    if (!rules) {\n      if (i === segments.length - 1) {\n        return hasOwnProperty.call(source, index)\n      }\n\n      if (!isValid(source) || !isAssignable(source)) return false\n      source = source[index]\n\n      if (!isObj(source)) {\n        return false\n      }\n    } else {\n      return existInByDestructor(source, rules, start, {\n        setIn,\n        getIn,\n        deleteIn,\n        existIn,\n      })\n    }\n  }\n}\n\nconst parse = (pattern: Pattern, base?: Pattern) => {\n  if (pattern instanceof Path) {\n    return {\n      entire: pattern.entire,\n      segments: pattern.segments.slice(),\n      isRegExp: false,\n      haveRelativePattern: pattern.haveRelativePattern,\n      isWildMatchPattern: pattern.isWildMatchPattern,\n      isMatchPattern: pattern.isMatchPattern,\n      haveExcludePattern: pattern.haveExcludePattern,\n      tree: pattern.tree,\n    }\n  } else if (isStr(pattern)) {\n    if (!pattern) {\n      return {\n        entire: '',\n        segments: [],\n        isRegExp: false,\n        isWildMatchPattern: false,\n        haveExcludePattern: false,\n        isMatchPattern: false,\n      }\n    }\n    if (isSimplePath(pattern)) {\n      return {\n        entire: pattern,\n        segments: pattern.split('.'),\n        isRegExp: false,\n        isWildMatchPattern: false,\n        haveExcludePattern: false,\n        isMatchPattern: false,\n      }\n    }\n    const parser = new Parser(pattern, Path.parse(base))\n    const tree = parser.parse()\n    if (!parser.isMatchPattern) {\n      const segments = parser.data.segments\n      return {\n        entire: segments.join('.'),\n        segments,\n        tree,\n        isRegExp: false,\n        haveRelativePattern: parser.haveRelativePattern,\n        isWildMatchPattern: false,\n        haveExcludePattern: false,\n        isMatchPattern: false,\n      }\n    } else {\n      return {\n        entire: pattern,\n        segments: [],\n        isRegExp: false,\n        haveRelativePattern: false,\n        isWildMatchPattern: parser.isWildMatchPattern,\n        haveExcludePattern: parser.haveExcludePattern,\n        isMatchPattern: true,\n        tree,\n      }\n    }\n  } else if (isFn(pattern) && pattern[isMatcher]) {\n    return parse(pattern['path'])\n  } else if (isArr(pattern)) {\n    return {\n      entire: pattern.join('.'),\n      segments: pattern.reduce((buf, key) => {\n        return buf.concat(parseString(key))\n      }, []),\n      isRegExp: false,\n      haveRelativePattern: false,\n      isWildMatchPattern: false,\n      haveExcludePattern: false,\n      isMatchPattern: false,\n    }\n  } else if (isRegExp(pattern)) {\n    return {\n      entire: pattern,\n      segments: [],\n      isRegExp: true,\n      haveRelativePattern: false,\n      isWildMatchPattern: false,\n      haveExcludePattern: false,\n      isMatchPattern: true,\n    }\n  } else {\n    return {\n      entire: '',\n      isRegExp: false,\n      segments: pattern !== undefined ? [pattern] : [],\n      haveRelativePattern: false,\n      isWildMatchPattern: false,\n      haveExcludePattern: false,\n      isMatchPattern: false,\n    }\n  }\n}\n\nconst parseString = (source: any) => {\n  if (isStr(source)) {\n    source = source.replace(/\\s*/g, '')\n    try {\n      const { segments, isMatchPattern } = parse(source)\n      return !isMatchPattern ? segments : source\n    } catch (e) {\n      return source\n    }\n  } else if (source instanceof Path) {\n    return source.segments\n  }\n  return source\n}\n\nexport class Path {\n  public entire: string | RegExp\n  public segments: Segments\n  public isMatchPattern: boolean\n  public isWildMatchPattern: boolean\n  public isRegExp: boolean\n  public haveRelativePattern: boolean\n  public haveExcludePattern: boolean\n  public matchScore: number\n  public tree: Node\n  private matchCache: any\n  private includesCache: any\n\n  constructor(input: Pattern, base?: Pattern) {\n    const {\n      tree,\n      segments,\n      entire,\n      isRegExp,\n      isMatchPattern,\n      isWildMatchPattern,\n      haveRelativePattern,\n      haveExcludePattern,\n    } = parse(input, base)\n    this.entire = entire\n    this.segments = segments\n    this.isMatchPattern = isMatchPattern\n    this.isWildMatchPattern = isWildMatchPattern\n    this.haveRelativePattern = haveRelativePattern\n    this.isRegExp = isRegExp\n    this.haveExcludePattern = haveExcludePattern\n    this.tree = tree as Node\n    this.matchCache = new Map()\n    this.includesCache = new Map()\n  }\n\n  toString() {\n    return this.entire?.toString()\n  }\n\n  toArr() {\n    return this.segments?.slice()\n  }\n\n  get length() {\n    return this.segments.length\n  }\n\n  concat = (...args: Pattern[]) => {\n    if (this.isMatchPattern || this.isRegExp) {\n      throw new Error(`${this.entire} cannot be concat`)\n    }\n    const path = new Path('')\n    path.segments = this.segments.concat(...args.map((s) => parseString(s)))\n    path.entire = path.segments.join('.')\n    return path\n  }\n\n  slice = (start?: number, end?: number) => {\n    if (this.isMatchPattern || this.isRegExp) {\n      throw new Error(`${this.entire} cannot be slice`)\n    }\n    const path = new Path('')\n    path.segments = this.segments.slice(start, end)\n    path.entire = path.segments.join('.')\n    return path\n  }\n\n  push = (...items: Pattern[]) => {\n    return this.concat(...items)\n  }\n\n  pop = () => {\n    if (this.isMatchPattern || this.isRegExp) {\n      throw new Error(`${this.entire} cannot be pop`)\n    }\n    return new Path(this.segments.slice(0, this.segments.length - 1))\n  }\n\n  splice = (\n    start: number,\n    deleteCount?: number,\n    ...items: Array<string | number>\n  ) => {\n    if (this.isMatchPattern || this.isRegExp) {\n      throw new Error(`${this.entire} cannot be splice`)\n    }\n    items = items.reduce((buf, item) => buf.concat(parseString(item)), [])\n    const segments_ = this.segments.slice()\n    segments_.splice(start, deleteCount, ...items)\n    return new Path(segments_)\n  }\n\n  forEach = (callback: (key: string | number) => any) => {\n    if (this.isMatchPattern || this.isRegExp) {\n      throw new Error(`${this.entire} cannot be each`)\n    }\n    this.segments.forEach(callback)\n  }\n\n  map = (callback: (key: string | number) => any) => {\n    if (this.isMatchPattern || this.isRegExp) {\n      throw new Error(`${this.entire} cannot be map`)\n    }\n    return this.segments.map(callback)\n  }\n\n  reduce = <T>(\n    callback: (buf: T, item: string | number, index: number) => T,\n    initial: T\n  ): T => {\n    if (this.isMatchPattern || this.isRegExp) {\n      throw new Error(`${this.entire} cannot be reduce`)\n    }\n    return this.segments.reduce(callback, initial)\n  }\n\n  parent = () => {\n    return this.slice(0, this.length - 1)\n  }\n\n  includes = (pattern: Pattern) => {\n    const { entire, segments, isMatchPattern } = Path.parse(pattern)\n    const cache = this.includesCache.get(entire)\n    if (cache !== undefined) return cache\n    const cacheWith = (value: boolean): boolean => {\n      this.includesCache.set(entire, value)\n      return value\n    }\n    if (this.isMatchPattern) {\n      if (!isMatchPattern) {\n        return cacheWith(this.match(segments))\n      } else {\n        throw new Error(`${this.entire} cannot be used to match ${entire}`)\n      }\n    }\n    if (isMatchPattern) {\n      throw new Error(`${this.entire} cannot be used to match ${entire}`)\n    }\n    if (segments.length > this.segments.length) return cacheWith(false)\n    for (let i = 0; i < segments.length; i++) {\n      if (!isEqual(String(segments[i]), String(this.segments[i]))) {\n        return cacheWith(false)\n      }\n    }\n    return cacheWith(true)\n  }\n\n  transform = <T>(\n    regexp: string | RegExp,\n    callback: (...args: string[]) => T\n  ): T | string => {\n    if (!isFn(callback)) return ''\n    if (this.isMatchPattern) {\n      throw new Error(`${this.entire} cannot be transformed`)\n    }\n    const reg = new RegExp(regexp)\n    const args = this.segments.filter((key) =>\n      reg.test(key as string)\n    ) as string[]\n    return callback(...args)\n  }\n\n  match = (pattern: Pattern): boolean => {\n    const path = Path.parse(pattern)\n    const cache = this.matchCache.get(path.entire)\n    if (cache !== undefined) {\n      if (cache.record && cache.record.score !== undefined) {\n        this.matchScore = cache.record.score\n      }\n      return cache.matched\n    }\n    const cacheWith = (value: any) => {\n      this.matchCache.set(path.entire, value)\n      return value\n    }\n    if (path.isMatchPattern) {\n      if (this.isMatchPattern) {\n        throw new Error(`${path.entire} cannot match ${this.entire}`)\n      } else {\n        this.matchScore = 0\n        return cacheWith(path.match(this.segments))\n      }\n    } else {\n      if (this.isMatchPattern) {\n        if (this.isRegExp) {\n          try {\n            return this['entire']?.['test']?.(path.entire)\n          } finally {\n            ;(this.entire as RegExp).lastIndex = 0\n          }\n        }\n        const record = {\n          score: 0,\n        }\n        const result = cacheWith(\n          new Matcher(this.tree, record).match(path.segments)\n        )\n        this.matchScore = record.score\n        return result.matched\n      } else {\n        const record = {\n          score: 0,\n        }\n        const result = cacheWith(\n          Matcher.matchSegments(this.segments, path.segments, record)\n        )\n        this.matchScore = record.score\n        return result.matched\n      }\n    }\n  }\n\n  //别名组匹配\n  matchAliasGroup = (name: Pattern, alias: Pattern) => {\n    const namePath = Path.parse(name)\n    const aliasPath = Path.parse(alias)\n    const nameMatched = this.match(namePath)\n    const nameMatchedScore = this.matchScore\n    const aliasMatched = this.match(aliasPath)\n    const aliasMatchedScore = this.matchScore\n    if (this.haveExcludePattern) {\n      if (nameMatchedScore >= aliasMatchedScore) {\n        return nameMatched\n      } else {\n        return aliasMatched\n      }\n    } else {\n      return nameMatched || aliasMatched\n    }\n  }\n\n  existIn = (source?: any, start: number | Path = 0) => {\n    return existIn(this.segments, source, start)\n  }\n\n  getIn = (source?: any) => {\n    return getIn(this.segments, source)\n  }\n\n  setIn = (source?: any, value?: any) => {\n    setIn(this.segments, source, value)\n    return source\n  }\n\n  deleteIn = (source?: any) => {\n    deleteIn(this.segments, source)\n    return source\n  }\n\n  ensureIn = (source?: any, defaults?: any) => {\n    const results = this.getIn(source)\n    if (results === undefined) {\n      this.setIn(source, defaults)\n      return this.getIn(source)\n    }\n    return results\n  }\n\n  static match(pattern: Pattern) {\n    const path = Path.parse(pattern)\n    const matcher = (target) => {\n      return path.match(target)\n    }\n    matcher[isMatcher] = true\n    matcher.path = path\n    return matcher\n  }\n\n  static isPathPattern(target: any): target is Pattern {\n    return !!(\n      isStr(target) ||\n      isArr(target) ||\n      isRegExp(target) ||\n      (isFn(target) && target[isMatcher])\n    )\n  }\n\n  static transform<T>(\n    pattern: Pattern,\n    regexp: string | RegExp,\n    callback: (...args: string[]) => T\n  ): any {\n    return Path.parse(pattern).transform(regexp, callback)\n  }\n\n  static parse(path: Pattern = '', base?: Pattern): Path {\n    if (path instanceof Path) {\n      const found = pathCache.get(path.entire)\n      if (found) {\n        return found\n      } else {\n        pathCache.set(path.entire, path)\n        return path\n      }\n    } else if (path && path[isMatcher]) {\n      return Path.parse(path['path'])\n    } else {\n      const key_ = base ? Path.parse(base) : ''\n      const key = `${path}:${key_}`\n      const found = pathCache.get(key)\n      if (found) {\n        return found\n      } else {\n        path = new Path(path, base)\n        pathCache.set(key, path)\n        return path\n      }\n    }\n  }\n\n  static getIn = (source: any, pattern: Pattern) => {\n    const path = Path.parse(pattern)\n    return path.getIn(source)\n  }\n\n  static setIn = (source: any, pattern: Pattern, value: any) => {\n    const path = Path.parse(pattern)\n    return path.setIn(source, value)\n  }\n\n  static deleteIn = (source: any, pattern: Pattern) => {\n    const path = Path.parse(pattern)\n    return path.deleteIn(source)\n  }\n\n  static existIn = (source: any, pattern: Pattern, start?: number | Path) => {\n    const path = Path.parse(pattern)\n    return path.existIn(source, start)\n  }\n\n  static ensureIn = (source: any, pattern: Pattern, defaultValue?: any) => {\n    const path = Path.parse(pattern)\n    return path.ensureIn(source, defaultValue)\n  }\n}\n\nexport { Pattern }\n"
  },
  {
    "path": "packages/path/src/matcher.ts",
    "content": "import {\n  Segments,\n  Node,\n  isIdentifier,\n  isExpandOperator,\n  isWildcardOperator,\n  isGroupExpression,\n  isRangeExpression,\n  isIgnoreExpression,\n  isDotOperator,\n  isDestructorExpression,\n  IdentifierNode,\n  IgnoreExpressionNode,\n  DestructorExpressionNode,\n  ExpandOperatorNode,\n  WildcardOperatorNode,\n  GroupExpressionNode,\n  RangeExpressionNode,\n} from './types'\nimport { isEqual, toArr, isSegmentEqual } from './shared'\nexport interface IRecord {\n  score: number\n}\n\nexport class Matcher {\n  private tree: Node\n\n  private stack: Node[]\n\n  private record: IRecord\n\n  private excluding: boolean\n\n  private wildcards: WildcardOperatorNode[]\n\n  private path: Segments\n\n  constructor(tree: Node, record?: any) {\n    this.tree = tree\n    this.stack = []\n    this.excluding = false\n    this.wildcards = []\n    this.record = record\n  }\n\n  next(node: Node, pos: number) {\n    //  const isOverToken = pos > this.path.length\n    if (node.after) {\n      // if (isOverToken) {\n      //   return false\n      // }\n      return this.matchNode(node.after, pos)\n    }\n\n    if (isWildcardOperator(node) && !node.filter) {\n      if (this.excluding) {\n        return false\n      } else {\n        if (pos === 0 || node.optional) return true\n        return !!this.take(pos)\n      }\n    }\n\n    const isLastToken = pos === this.path.length - 1\n    if (isLastToken) {\n      return !!this.take(pos)\n    } else {\n      const wildcard = this.wildcards.pop()\n      if (wildcard && wildcard.after) {\n        return this.next(wildcard, pos)\n      }\n    }\n\n    return false\n  }\n\n  shot() {\n    if (this.record?.score >= 0) {\n      this.record.score++\n    }\n  }\n\n  take(pos: number) {\n    return String(this.path[pos] ?? '')\n  }\n\n  matchExcludeIdentifier(matched: boolean, node: Node, pos: number) {\n    const isLastToken = pos === this.path.length - 1\n    const isContainToken = pos < this.path.length\n    if (!node.after) {\n      this.excluding = false\n    }\n    if (matched) {\n      if (node.after) {\n        return this.next(node, pos)\n      }\n      if (isLastToken) {\n        return false\n      }\n    }\n    if (isLastToken) {\n      return true\n    }\n    return isContainToken\n  }\n\n  matchIdentifier(node: IdentifierNode, pos: number) {\n    const current = this.take(pos)\n    let matched = false\n    if (isExpandOperator(node.after)) {\n      if (current.indexOf(node.value) === 0) {\n        this.shot()\n        matched = true\n      }\n      if (this.excluding) {\n        return this.matchExcludeIdentifier(matched, node.after, pos)\n      } else {\n        return matched && this.next(node.after, pos)\n      }\n    } else if (current === node.value) {\n      this.shot()\n      matched = true\n    }\n    if (this.excluding) {\n      return this.matchExcludeIdentifier(matched, node, pos)\n    } else {\n      return matched && this.next(node, pos)\n    }\n  }\n\n  matchIgnoreExpression(node: IgnoreExpressionNode, pos: number) {\n    return isEqual(node.value, this.take(pos)) && this.next(node, pos)\n  }\n\n  matchDestructorExpression(node: DestructorExpressionNode, pos: number) {\n    return isEqual(node.source, this.take(pos)) && this.next(node, pos)\n  }\n\n  matchExpandOperator(node: ExpandOperatorNode, pos: number) {\n    return this.next(node, pos)\n  }\n\n  matchWildcardOperator(node: WildcardOperatorNode, pos: number) {\n    let matched = false\n    if (node.filter) {\n      this.stack.push(node)\n      matched = this.matchNode(node.filter, pos)\n      this.stack.pop()\n    } else {\n      matched = this.next(node, pos)\n    }\n    return matched\n  }\n\n  matchGroupExpression(node: GroupExpressionNode, pos: number) {\n    let excluding = false\n    if (node.isExclude) {\n      excluding = !this.excluding\n    }\n    return toArr(node.value)[excluding ? 'every' : 'some']((item) => {\n      this.wildcards = this.stack.slice() as WildcardOperatorNode[]\n      this.excluding = excluding\n      return this.matchNode(item, pos)\n    })\n  }\n\n  matchRangeExpression(node: RangeExpressionNode, pos: number) {\n    const current = Number(this.take(pos))\n    if (node.start) {\n      if (node.end) {\n        return (\n          current >= Number(node.start.value) &&\n          current <= Number(node.end.value)\n        )\n      } else {\n        return current >= Number(node.start.value)\n      }\n    } else {\n      if (node.end) {\n        return current <= Number(node.end.value)\n      } else {\n        this.wildcards = this.stack.slice() as WildcardOperatorNode[]\n        return this.next(node, pos)\n      }\n    }\n  }\n\n  matchNode(node: Node, pos = 0) {\n    if (isDotOperator(node)) {\n      return this.next(node, pos + 1)\n    } else if (isIdentifier(node)) {\n      return this.matchIdentifier(node, pos)\n    } else if (isIgnoreExpression(node)) {\n      return this.matchIgnoreExpression(node, pos)\n    } else if (isDestructorExpression(node)) {\n      return this.matchDestructorExpression(node, pos)\n    } else if (isExpandOperator(node)) {\n      return this.matchExpandOperator(node, pos)\n    } else if (isWildcardOperator(node)) {\n      return this.matchWildcardOperator(node, pos)\n    } else if (isGroupExpression(node)) {\n      return this.matchGroupExpression(node, pos)\n    } else if (isRangeExpression(node)) {\n      return this.matchRangeExpression(node, pos)\n    }\n    return false\n  }\n\n  match(path: Segments) {\n    this.path = path\n    return { matched: this.matchNode(this.tree), record: this.record }\n  }\n\n  static matchSegments(source: Segments, target: Segments, record?: any) {\n    if (source.length !== target.length) return { matched: false, record }\n    const match = (pos = 0) => {\n      const current = isSegmentEqual(source[pos], target[pos])\n      if (record?.score >= 0) {\n        record.score++\n      }\n      return current && (pos < source.length - 1 ? match(pos + 1) : true)\n    }\n    return { matched: match(), record }\n  }\n}\n"
  },
  {
    "path": "packages/path/src/parser.ts",
    "content": "import { Tokenizer } from './tokenizer'\nimport {\n  Token,\n  nameTok,\n  colonTok,\n  dotTok,\n  starTok,\n  bangTok,\n  bracketLTok,\n  bracketRTok,\n  braceLTok,\n  braceRTok,\n  bracketDLTok,\n  parenLTok,\n  parenRTok,\n  commaTok,\n  expandTok,\n  eofTok,\n  dbStarTok,\n} from './tokens'\nimport { bracketArrayContext, destructorContext } from './contexts'\nimport {\n  IdentifierNode,\n  ExpandOperatorNode,\n  WildcardOperatorNode,\n  RangeExpressionNode,\n  GroupExpressionNode,\n  DotOperatorNode,\n  IgnoreExpressionNode,\n  DestructorExpressionNode,\n  ObjectPatternNode,\n  ObjectPatternPropertyNode,\n  ArrayPatternNode,\n  Node,\n  Segments,\n} from './types'\nimport { parseDestructorRules, setDestructor } from './destructor'\nimport { isNumberLike } from './shared'\nimport { Path } from './index'\n\nconst createTreeBySegments = (segments: Segments = [], afterNode?: Node) => {\n  const segLen = segments.length\n  const build = (start = 0) => {\n    const after = start < segLen - 1 ? build(start + 1) : afterNode\n    const dot = after && {\n      type: 'DotOperator',\n      after,\n    }\n    return {\n      type: 'Identifier',\n      value: segments[start],\n      after: dot,\n    }\n  }\n  return build()\n}\n\nconst calculate = (\n  a: string | number,\n  b: string | number,\n  operator: string\n) => {\n  if (isNumberLike(a) && isNumberLike(b)) {\n    if (operator === '+') return String(Number(a) + Number(b))\n    if (operator === '-') return String(Number(a) - Number(b))\n    if (operator === '*') return String(Number(a) * Number(b))\n    if (operator === '/') return String(Number(a) / Number(b))\n  } else {\n    if (operator === '+') return String(a) + String(b)\n    if (operator === '-') return 'NaN'\n    if (operator === '*') return 'NaN'\n    if (operator === '/') return 'NaN'\n  }\n  return String(Number(b))\n}\n\nexport class Parser extends Tokenizer {\n  public isMatchPattern = false\n\n  public isWildMatchPattern = false\n\n  public haveExcludePattern = false\n\n  public haveRelativePattern = false\n\n  public base: Path\n\n  public relative: string | number\n\n  public data: {\n    segments: Segments\n    tree?: Node\n  }\n\n  constructor(input: string, base?: Path) {\n    super(input)\n    this.base = base\n  }\n\n  parse() {\n    let node: Node\n    this.data = {\n      segments: [],\n    }\n    if (!this.eat(eofTok)) {\n      this.next()\n      node = this.parseAtom(this.state.type)\n    }\n    this.data.tree = node\n\n    return node\n  }\n\n  append(parent: Node, node: Node) {\n    if (parent && node) {\n      parent.after = node\n    }\n  }\n\n  parseAtom(type: Token): Node {\n    switch (type) {\n      case braceLTok:\n      case bracketLTok:\n        if (this.includesContext(destructorContext)) {\n          if (type === braceLTok) {\n            return this.parseObjectPattern()\n          } else {\n            return this.parseArrayPattern()\n          }\n        }\n        return this.parseDestructorExpression()\n      case nameTok:\n        return this.parseIdentifier()\n      case expandTok:\n        return this.parseExpandOperator()\n      case dbStarTok:\n      case starTok:\n        return this.parseWildcardOperator()\n      case bracketDLTok:\n        return this.parseIgnoreExpression()\n      case dotTok:\n        return this.parseDotOperator()\n    }\n  }\n\n  pushSegments(key: string | number) {\n    this.data.segments.push(key)\n  }\n\n  parseIdentifier() {\n    const node: IdentifierNode = {\n      type: 'Identifier',\n      value: this.state.value,\n    }\n    const hasNotInDestructor =\n      !this.includesContext(destructorContext) &&\n      !this.isMatchPattern &&\n      !this.isWildMatchPattern\n\n    this.next()\n    if (this.includesContext(bracketArrayContext)) {\n      if (this.state.type !== bracketRTok) {\n        throw this.unexpect()\n      } else {\n        this.state.context.pop()\n        this.next()\n      }\n    } else if (hasNotInDestructor) {\n      this.pushSegments(node.value)\n    }\n    if (this.state.type === bracketLTok) {\n      this.next()\n      if (this.state.type !== nameTok) {\n        throw this.unexpect()\n      }\n      this.state.context.push(bracketArrayContext)\n      let isNumberKey = false\n      if (/^\\d+$/.test(this.state.value)) {\n        isNumberKey = true\n      }\n      const value = this.state.value\n      this.pushSegments(isNumberKey ? Number(value) : value)\n      const after = this.parseAtom(this.state.type) as IdentifierNode\n      if (isNumberKey) {\n        after.arrayIndex = true\n      }\n      this.append(node, after)\n    } else {\n      this.append(node, this.parseAtom(this.state.type))\n    }\n\n    return node\n  }\n\n  parseExpandOperator() {\n    const node: ExpandOperatorNode = {\n      type: 'ExpandOperator',\n    }\n\n    this.isMatchPattern = true\n    this.isWildMatchPattern = true\n    this.data.segments = []\n\n    this.next()\n\n    this.append(node, this.parseAtom(this.state.type))\n\n    return node\n  }\n\n  parseWildcardOperator(): WildcardOperatorNode {\n    const node: WildcardOperatorNode = {\n      type: 'WildcardOperator',\n    }\n\n    if (this.state.type === dbStarTok) {\n      node.optional = true\n    }\n\n    this.isMatchPattern = true\n    this.isWildMatchPattern = true\n    this.data.segments = []\n\n    this.next()\n\n    if (this.state.type === parenLTok) {\n      node.filter = this.parseGroupExpression(node)\n    } else if (this.state.type === bracketLTok) {\n      node.filter = this.parseRangeExpression(node)\n    }\n\n    this.append(node, this.parseAtom(this.state.type))\n\n    return node\n  }\n\n  parseDestructorExpression(): DestructorExpressionNode {\n    const node: DestructorExpressionNode = {\n      type: 'DestructorExpression',\n    }\n    this.state.context.push(destructorContext)\n    const startPos = this.state.pos - 1\n    node.value =\n      this.state.type === braceLTok\n        ? this.parseObjectPattern()\n        : this.parseArrayPattern()\n    const endPos = this.state.pos\n    this.state.context.pop()\n    node.source = this.input\n      .substring(startPos, endPos)\n      .replace(\n        /\\[\\s*([\\+\\-\\*\\/])?\\s*([^,\\]\\s]*)\\s*\\]/,\n        (match, operator, target) => {\n          if (this.relative !== undefined) {\n            if (operator) {\n              if (target) {\n                return calculate(this.relative, target, operator)\n              } else {\n                return calculate(this.relative, 1, operator)\n              }\n            } else {\n              if (target) {\n                return calculate(this.relative, target, '+')\n              } else {\n                return String(this.relative)\n              }\n            }\n          }\n          return match\n        }\n      )\n      .replace(/\\s*\\.\\s*/g, '')\n      .replace(/\\s*/g, '')\n    if (this.relative === undefined) {\n      setDestructor(node.source, parseDestructorRules(node))\n    }\n    this.relative = undefined\n    this.pushSegments(node.source)\n    this.next()\n    this.append(node, this.parseAtom(this.state.type))\n    return node\n  }\n\n  parseArrayPattern(): ArrayPatternNode {\n    const node: ArrayPatternNode = {\n      type: 'ArrayPattern',\n      elements: [],\n    }\n    this.next()\n    node.elements = this.parseArrayPatternElements()\n    return node\n  }\n\n  parseArrayPatternElements() {\n    const nodes = []\n    while (this.state.type !== bracketRTok && this.state.type !== eofTok) {\n      nodes.push(this.parseAtom(this.state.type))\n      if (this.state.type === bracketRTok) {\n        if (this.includesContext(destructorContext)) {\n          this.next()\n        }\n        return nodes\n      }\n      this.next()\n    }\n    return nodes\n  }\n\n  parseObjectPattern(): ObjectPatternNode {\n    const node: ObjectPatternNode = {\n      type: 'ObjectPattern',\n      properties: [],\n    }\n    this.next()\n    node.properties = this.parseObjectProperties()\n    return node\n  }\n\n  parseObjectProperties(): ObjectPatternPropertyNode[] {\n    const nodes = []\n    while (this.state.type !== braceRTok && this.state.type !== eofTok) {\n      const node: ObjectPatternPropertyNode = {\n        type: 'ObjectPatternProperty',\n        key: this.parseAtom(this.state.type) as IdentifierNode,\n      }\n      nodes.push(node)\n      if (this.state.type === colonTok) {\n        this.next()\n        node.value = this.parseAtom(this.state.type) as\n          | IdentifierNode\n          | ObjectPatternNode[]\n          | ArrayPatternNode[]\n      }\n      if (this.state.type === braceRTok) {\n        if (this.includesContext(destructorContext)) {\n          this.next()\n        }\n        return nodes\n      }\n      this.next()\n    }\n    return nodes\n  }\n\n  parseDotOperator(): Node {\n    const node: DotOperatorNode = {\n      type: 'DotOperator',\n    }\n\n    const prevToken = this.type_\n    if (!prevToken && this.base) {\n      if (this.base.isMatchPattern) {\n        throw new Error('Base path must be an absolute path.')\n      }\n      this.data.segments = this.base.toArr()\n      while (this.state.type === dotTok) {\n        this.relative = this.data.segments.pop()\n        this.haveRelativePattern = true\n        this.next()\n      }\n      return createTreeBySegments(\n        this.data.segments.slice(),\n        this.parseAtom(this.state.type)\n      )\n    } else {\n      this.next()\n    }\n\n    this.append(node, this.parseAtom(this.state.type))\n\n    return node\n  }\n\n  parseIgnoreExpression() {\n    this.next()\n\n    const value = String(this.state.value).replace(/\\s*/g, '')\n\n    const node: IgnoreExpressionNode = {\n      type: 'IgnoreExpression',\n      value: value,\n    }\n\n    this.pushSegments(value)\n\n    this.next()\n\n    this.append(node, this.parseAtom(this.state.type))\n\n    this.next()\n\n    return node\n  }\n\n  parseGroupExpression(parent: Node) {\n    const node: GroupExpressionNode = {\n      type: 'GroupExpression',\n      value: [],\n    }\n\n    this.isMatchPattern = true\n    this.data.segments = []\n\n    this.next()\n\n    loop: while (true) {\n      switch (this.state.type) {\n        case commaTok:\n          this.next()\n          break\n        case bangTok:\n          node.isExclude = true\n          this.haveExcludePattern = true\n          this.next()\n          break\n        case eofTok:\n          break loop\n        case parenRTok:\n          break loop\n        default:\n          node.value.push(this.parseAtom(this.state.type))\n      }\n    }\n\n    this.next()\n\n    this.append(parent, this.parseAtom(this.state.type))\n\n    return node\n  }\n\n  parseRangeExpression(parent: Node) {\n    const node: RangeExpressionNode = {\n      type: 'RangeExpression',\n    }\n\n    this.next()\n\n    this.isMatchPattern = true\n    this.data.segments = []\n\n    let start = false,\n      hasColon = false\n\n    loop: while (true) {\n      switch (this.state.type) {\n        case colonTok:\n          hasColon = true\n          start = true\n          this.next()\n          break\n        case bracketRTok:\n          if (!hasColon && !node.end) {\n            node.end = node.start\n          }\n          break loop\n        case commaTok:\n          // never reach\n          throw this.unexpect()\n        case eofTok:\n          // never reach\n          break loop\n        default:\n          if (!start) {\n            node.start = this.parseAtom(this.state.type) as IdentifierNode\n          } else {\n            node.end = this.parseAtom(this.state.type) as IdentifierNode\n          }\n      }\n    }\n\n    this.next()\n\n    this.append(parent, this.parseAtom(this.state.type))\n\n    return node\n  }\n}\n"
  },
  {
    "path": "packages/path/src/shared.ts",
    "content": "const toString = Object.prototype.toString\nconst isType =\n  <T>(type: string) =>\n  (obj: unknown): obj is T =>\n    toString.call(obj) === `[object ${type}]`\nexport const isFn = isType<(...args: any[]) => any>('Function')\nexport const isArr = Array.isArray || isType<unknown[]>('Array')\nexport const isPlainObj = isType<object>('Object')\nexport const isStr = isType<string>('String')\nexport const isBool = isType<boolean>('Boolean')\nexport const isNum = isType<number>('Number')\nexport const isObj = (val: unknown): val is object => typeof val === 'object'\nexport const isRegExp = isType<RegExp>('RegExp')\nexport const isNumberLike = (t: any) => {\n  return isNum(t) || /^(\\d+)(\\.\\d+)?$/.test(t)\n}\nconst isArray = isArr\nconst keyList = Object.keys\nconst hasProp = Object.prototype.hasOwnProperty\n\nexport const toArr = <T>(val: T | T[]): T[] =>\n  Array.isArray(val) ? val : val !== undefined ? [val] : []\nexport const isAssignable = (val: any) => {\n  return typeof val === 'object' || typeof val === 'function'\n}\nexport const isEqual = (a: any, b: any) => {\n  if (a === b) {\n    return true\n  }\n  if (a && b && typeof a === 'object' && typeof b === 'object') {\n    const arrA = isArray(a)\n    const arrB = isArray(b)\n    let i\n    let length\n    let key\n\n    if (arrA && arrB) {\n      length = a.length\n      if (length !== b.length) {\n        return false\n      }\n      for (i = length; i-- !== 0; ) {\n        if (!isEqual(a[i], b[i])) {\n          return false\n        }\n      }\n      return true\n    }\n\n    if (arrA !== arrB) {\n      return false\n    }\n\n    const keys = keyList(a)\n    length = keys.length\n\n    if (length !== keyList(b).length) {\n      return false\n    }\n\n    for (i = length; i-- !== 0; ) {\n      if (!hasProp.call(b, keys[i])) {\n        return false\n      }\n    }\n    for (i = length; i-- !== 0; ) {\n      key = keys[i]\n      if (!isEqual(a[key], b[key])) {\n        return false\n      }\n    }\n\n    return true\n  }\n  return a !== a && b !== b\n}\nexport const isSegmentEqual = (a: any, b: any) => {\n  a = typeof a === 'symbol' ? a : `${a}`\n  b = typeof b === 'symbol' ? b : `${b}`\n  return a === b\n}\n"
  },
  {
    "path": "packages/path/src/tokenizer.ts",
    "content": "import {\n  Token,\n  nameTok,\n  colonTok,\n  dotTok,\n  starTok,\n  dbStarTok,\n  bangTok,\n  bracketLTok,\n  bracketRTok,\n  bracketDRTok,\n  expandTok,\n  parenLTok,\n  parenRTok,\n  commaTok,\n  eofTok,\n  ignoreTok,\n  braceLTok,\n  braceRTok,\n  bracketDLTok,\n} from './tokens'\nimport { bracketDContext, Context } from './contexts'\n\nconst nonASCIIWhitespace = /[\\u1680\\u180e\\u2000-\\u200a\\u202f\\u205f\\u3000\\ufeff]/\n\nconst fullCharCodeAtPos = (input: string, pos: number) => {\n  if (String.fromCharCode) return input.codePointAt(pos)\n  const code = input.charCodeAt(pos)\n  if (code <= 0xd7ff || code >= 0xe000) return code\n\n  const next = input.charCodeAt(pos + 1)\n  return (code << 10) + next - 0x35fdc00\n}\n\nconst isRewordCode = (code: number) =>\n  code === 42 ||\n  code === 46 ||\n  code === 33 ||\n  code === 91 ||\n  code === 93 ||\n  code === 40 ||\n  code === 41 ||\n  code === 44 ||\n  code === 58 ||\n  code === 126 ||\n  code === 123 ||\n  code === 125\n\nconst getError = (message?: string, props?: any) => {\n  const err = new Error(message)\n  Object.assign(err, props)\n  return err\n}\n\nconst slice = (string: string, start: number, end: number) => {\n  let str = ''\n  for (let i = start; i < end; i++) {\n    const ch = string.charAt(i)\n    if (ch !== '\\\\') {\n      str += ch\n    }\n  }\n  return str\n}\n\nexport class Tokenizer {\n  public input: string\n  public state: {\n    context: Context[]\n    type: Token\n    pos: number\n    value?: any\n  }\n  public type_: Token\n  constructor(input: string) {\n    this.input = input\n    this.state = {\n      context: [],\n      type: null,\n      pos: 0,\n    }\n    this.type_ = null\n  }\n\n  curContext() {\n    return this.state.context[this.state.context.length - 1]\n  }\n\n  includesContext(context: Context) {\n    for (let len = this.state.context.length - 1; len >= 0; len--) {\n      if (this.state.context[len] === context) {\n        return true\n      }\n    }\n    return false\n  }\n\n  unexpect(type?: Token) {\n    type = type || this.state.type\n    return getError(\n      `Unexpect token \"${type.flag}\" in ${this.state.pos} char.`,\n      {\n        pos: this.state.pos,\n      }\n    )\n  }\n\n  expectNext(type?: Token, next?: Token) {\n    if (type && type.expectNext) {\n      if (next && !type.expectNext.call(this, next)) {\n        throw getError(\n          `Unexpect token \"${next.flag}\" token should not be behind \"${type.flag}\" token.(${this.state.pos}th char)`,\n          {\n            pos: this.state.pos,\n          }\n        )\n      }\n    }\n  }\n\n  expectPrev(type?: Token, prev?: Token) {\n    if (type && type.expectPrev) {\n      if (prev && !type.expectPrev.call(this, prev)) {\n        throw getError(\n          `Unexpect token \"${type.flag}\" should not be behind \"${prev.flag}\"(${this.state.pos}th char).`,\n          {\n            pos: this.state.pos,\n          }\n        )\n      }\n    }\n  }\n\n  match(type?: Token) {\n    return this.state.type === type\n  }\n\n  skipSpace() {\n    if (this.curContext() === bracketDContext) return\n    loop: while (this.state.pos < this.input.length) {\n      const ch = this.input.charCodeAt(this.state.pos)\n      switch (ch) {\n        case 32:\n        case 160:\n          ++this.state.pos\n          break\n\n        case 13:\n          if (this.input.charCodeAt(this.state.pos + 1) === 10) {\n            ++this.state.pos\n          }\n\n        case 10:\n        case 8232:\n        case 8233:\n          ++this.state.pos\n          break\n        default:\n          if (\n            (ch > 8 && ch < 14) ||\n            (ch >= 5760 && nonASCIIWhitespace.test(String.fromCharCode(ch)))\n          ) {\n            ++this.state.pos\n          } else {\n            break loop\n          }\n      }\n    }\n  }\n\n  next() {\n    this.type_ = this.state.type\n    if (this.input.length <= this.state.pos) {\n      return this.finishToken(eofTok)\n    }\n    this.skipSpace()\n    this.readToken(\n      this.getCode(),\n      this.state.pos > 0 ? this.getCode(this.state.pos - 1) : -Infinity\n    )\n  }\n\n  getCode(pos = this.state.pos) {\n    return fullCharCodeAtPos(this.input, pos)\n  }\n\n  eat(type) {\n    if (this.match(type)) {\n      this.next()\n      return true\n    } else {\n      return false\n    }\n  }\n\n  readKeyWord() {\n    let startPos = this.state.pos,\n      string = ''\n    while (true) {\n      const code = this.getCode()\n      const prevCode = this.getCode(this.state.pos - 1)\n      if (this.input.length === this.state.pos) {\n        string = slice(this.input, startPos, this.state.pos + 1)\n        break\n      }\n      if (!isRewordCode(code) || prevCode === 92) {\n        if (\n          code === 32 ||\n          code === 160 ||\n          code === 10 ||\n          code === 8232 ||\n          code === 8233\n        ) {\n          string = slice(this.input, startPos, this.state.pos)\n          break\n        }\n        if (code === 13 && this.input.charCodeAt(this.state.pos + 1) === 10) {\n          string = slice(this.input, startPos, this.state.pos)\n          break\n        }\n        if (\n          (code > 8 && code < 14) ||\n          (code >= 5760 && nonASCIIWhitespace.test(String.fromCharCode(code)))\n        ) {\n          string = slice(this.input, startPos, this.state.pos)\n          break\n        }\n        this.state.pos++\n      } else {\n        string = slice(this.input, startPos, this.state.pos)\n        break\n      }\n    }\n\n    this.finishToken(nameTok, string)\n  }\n\n  readIgnoreString() {\n    let startPos = this.state.pos,\n      prevCode,\n      string = ''\n    while (true) {\n      const code = this.getCode()\n      if (this.state.pos >= this.input.length) break\n      if ((code === 91 || code === 93) && prevCode === 92) {\n        this.state.pos++\n        prevCode = ''\n      } else if (code == 93 && prevCode === 93) {\n        string = this.input\n          .slice(startPos, this.state.pos - 1)\n          .replace(/\\\\([\\[\\]])/g, '$1')\n        this.state.pos++\n        break\n      } else {\n        this.state.pos++\n        prevCode = code\n      }\n    }\n\n    this.finishToken(ignoreTok, string)\n    this.finishToken(bracketDRTok)\n  }\n\n  finishToken(type: Token, value?: any) {\n    const preType = this.state.type\n    this.state.type = type\n    if (value !== undefined) this.state.value = value\n    this.expectNext(preType, type)\n    this.expectPrev(type, preType)\n    if (type.updateContext) {\n      type.updateContext.call(this, preType)\n    }\n  }\n\n  readToken(code: number, prevCode: number) {\n    if (prevCode === 92) {\n      return this.readKeyWord()\n    }\n    if (this.input.length <= this.state.pos) {\n      this.finishToken(eofTok)\n    } else if (this.curContext() === bracketDContext) {\n      this.readIgnoreString()\n    } else if (code === 123) {\n      this.state.pos++\n      this.finishToken(braceLTok)\n    } else if (code === 125) {\n      this.state.pos++\n      this.finishToken(braceRTok)\n    } else if (code === 42) {\n      this.state.pos++\n      if (this.getCode() === 42) {\n        this.state.pos++\n        return this.finishToken(dbStarTok)\n      }\n      this.finishToken(starTok)\n    } else if (code === 33) {\n      this.state.pos++\n      this.finishToken(bangTok)\n    } else if (code === 46) {\n      this.state.pos++\n      this.finishToken(dotTok)\n    } else if (code === 91) {\n      this.state.pos++\n      if (this.getCode() === 91) {\n        this.state.pos++\n        return this.finishToken(bracketDLTok)\n      }\n      this.finishToken(bracketLTok)\n    } else if (code === 126) {\n      this.state.pos++\n      this.finishToken(expandTok)\n    } else if (code === 93) {\n      this.state.pos++\n      this.finishToken(bracketRTok)\n    } else if (code === 40) {\n      this.state.pos++\n      this.finishToken(parenLTok)\n    } else if (code === 41) {\n      this.state.pos++\n      this.finishToken(parenRTok)\n    } else if (code === 44) {\n      this.state.pos++\n      this.finishToken(commaTok)\n    } else if (code === 58) {\n      this.state.pos++\n      this.finishToken(colonTok)\n    } else {\n      this.readKeyWord()\n    }\n  }\n}\n"
  },
  {
    "path": "packages/path/src/tokens.ts",
    "content": "import {\n  bracketContext,\n  parenContext,\n  bracketArrayContext,\n  bracketDContext,\n  braceContext,\n  destructorContext,\n} from './contexts'\n\ninterface ITokenProps {\n  expectNext?: (next?: Token) => boolean\n  expectPrev?: (prev?: Token) => boolean\n  updateContext?: (prev?: Token) => void\n}\n\nexport type Token = ITokenProps & {\n  flag: string\n}\n\nconst TokenType = (flag: string, props?: ITokenProps): Token => {\n  return {\n    flag,\n    ...props,\n  }\n}\n\nexport const nameTok = TokenType('name', {\n  expectNext(next) {\n    if (this.includesContext(destructorContext)) {\n      return (\n        next === nameTok ||\n        next === commaTok ||\n        next === bracketRTok ||\n        next === braceRTok ||\n        next === colonTok\n      )\n    }\n    return (\n      next === dotTok ||\n      next === commaTok ||\n      next === eofTok ||\n      next === bracketRTok ||\n      next === parenRTok ||\n      next === colonTok ||\n      next === expandTok ||\n      next === bracketLTok\n    )\n  },\n})\nexport const starTok = TokenType('*', {\n  expectNext(next) {\n    return (\n      next === dotTok ||\n      next === parenLTok ||\n      next === bracketLTok ||\n      next === eofTok ||\n      next === commaTok ||\n      next === parenRTok\n    )\n  },\n})\nexport const dbStarTok = TokenType('**', {\n  expectNext(next) {\n    return (\n      next === dotTok ||\n      next === bracketLTok ||\n      next === eofTok ||\n      next === commaTok ||\n      next === parenRTok\n    )\n  },\n})\nexport const dotTok = TokenType('.', {\n  expectNext(next) {\n    return (\n      next === dotTok ||\n      next === nameTok ||\n      next === bracketDLTok ||\n      next === starTok ||\n      next === dbStarTok ||\n      next === bracketLTok ||\n      next === braceLTok ||\n      next === eofTok\n    )\n  },\n  expectPrev(prev) {\n    return (\n      prev === dotTok ||\n      prev === nameTok ||\n      prev === bracketDRTok ||\n      prev === starTok ||\n      prev === parenRTok ||\n      prev === bracketRTok ||\n      prev === expandTok ||\n      prev === braceRTok\n    )\n  },\n})\nexport const bangTok = TokenType('!', {\n  expectNext(next) {\n    return next === nameTok || next === bracketDLTok\n  },\n})\nexport const colonTok = TokenType(':', {\n  expectNext(next) {\n    if (this.includesContext(destructorContext)) {\n      return next === nameTok || next === braceLTok || next === bracketLTok\n    }\n    return next === nameTok || next === bracketDLTok || next === bracketRTok\n  },\n})\n\nexport const braceLTok = TokenType('{', {\n  expectNext(next) {\n    return next === nameTok\n  },\n  expectPrev(prev) {\n    if (this.includesContext(destructorContext)) {\n      return prev === colonTok || prev === commaTok || prev === bracketLTok\n    }\n    return prev === dotTok || prev === colonTok || prev === parenLTok\n  },\n  updateContext() {\n    this.state.context.push(braceContext)\n  },\n})\n\nexport const braceRTok = TokenType('}', {\n  expectNext(next) {\n    if (this.includesContext(destructorContext)) {\n      return (\n        next === commaTok ||\n        next === braceRTok ||\n        next === eofTok ||\n        next === bracketRTok\n      )\n    }\n    return next === dotTok || next === eofTok || next === commaTok\n  },\n  expectPrev(prev) {\n    return prev === nameTok || prev === braceRTok || prev === bracketRTok\n  },\n  updateContext() {\n    this.state.context.pop(braceContext)\n  },\n})\n\nexport const bracketLTok = TokenType('[', {\n  expectNext(next) {\n    if (this.includesContext(destructorContext)) {\n      return (\n        next === nameTok ||\n        next === bracketLTok ||\n        next === braceLTok ||\n        next === bracketRTok\n      )\n    }\n    return (\n      next === nameTok ||\n      next === bracketDLTok ||\n      next === colonTok ||\n      next === bracketLTok ||\n      next === ignoreTok ||\n      next === bracketRTok\n    )\n  },\n  expectPrev(prev) {\n    if (this.includesContext(destructorContext)) {\n      return prev === colonTok || prev === commaTok || prev === bracketLTok\n    }\n    return (\n      prev === starTok ||\n      prev === bracketLTok ||\n      prev === dotTok ||\n      prev === nameTok ||\n      prev === parenLTok ||\n      // never reach\n      prev == commaTok\n    )\n  },\n  updateContext() {\n    this.state.context.push(bracketContext)\n  },\n})\n\nexport const bracketRTok = TokenType(']', {\n  expectNext(next) {\n    if (this.includesContext(destructorContext)) {\n      return (\n        next === commaTok ||\n        next === braceRTok ||\n        next === bracketRTok ||\n        next === eofTok\n      )\n    }\n    return (\n      next === dotTok ||\n      next === eofTok ||\n      next === commaTok ||\n      next === parenRTok ||\n      next === bracketRTok\n    )\n  },\n  updateContext() {\n    if (this.includesContext(bracketArrayContext)) return\n    if (!this.includesContext(bracketContext)) throw this.unexpect()\n    this.state.context.pop()\n  },\n})\n\nexport const bracketDLTok = TokenType('[[', {\n  updateContext() {\n    this.state.context.push(bracketDContext)\n  },\n})\n\nexport const bracketDRTok = TokenType(']]', {\n  updateContext() {\n    if (this.curContext() !== bracketDContext) throw this.unexpect()\n    this.state.context.pop()\n  },\n})\n\nexport const parenLTok = TokenType('(', {\n  expectNext(next) {\n    return (\n      next === nameTok ||\n      next === bracketDLTok ||\n      next === braceLTok ||\n      next === bangTok ||\n      next === bracketLTok\n    )\n  },\n  expectPrev(prev) {\n    return prev === starTok\n  },\n  updateContext() {\n    this.state.context.push(parenContext)\n  },\n})\nexport const parenRTok = TokenType(')', {\n  expectNext(next) {\n    return (\n      next === dotTok ||\n      next === eofTok ||\n      next === commaTok ||\n      next === parenRTok\n    )\n  },\n  updateContext() {\n    if (this.curContext() !== parenContext) throw this.unexpect()\n    this.state.context.pop()\n  },\n})\n\nexport const commaTok = TokenType(',', {\n  expectNext(next) {\n    return (\n      next === nameTok ||\n      next === bracketDLTok ||\n      next === bracketLTok ||\n      next === braceLTok\n    )\n  },\n})\nexport const ignoreTok = TokenType('ignore', {\n  expectNext(next) {\n    return next === bracketDRTok\n  },\n  expectPrev(prev) {\n    return prev == bracketDLTok\n  },\n})\n\nexport const expandTok = TokenType('expandTok', {\n  expectNext(next) {\n    return (\n      next === dotTok ||\n      next === eofTok ||\n      next === commaTok ||\n      next === parenRTok\n    )\n  },\n})\n\nexport const eofTok = TokenType('eof')\n"
  },
  {
    "path": "packages/path/src/types.ts",
    "content": "import { Path } from './index'\ninterface INode {\n  type?: string\n  after?: Node\n  depth?: number\n}\n\nexport type Node =\n  | IdentifierNode\n  | WildcardOperatorNode\n  | GroupExpressionNode\n  | RangeExpressionNode\n  | DestructorExpressionNode\n  | ObjectPatternNode\n  | ArrayPatternNode\n  | DotOperatorNode\n  | ExpandOperatorNode\n  | INode\n\nexport type IdentifierNode = {\n  type: 'Identifier'\n  value: string\n  arrayIndex?: boolean\n} & INode\n\nexport type IgnoreExpressionNode = {\n  type: 'IgnoreExpression'\n  value: string\n} & INode\n\nexport type DotOperatorNode = {\n  type: 'DotOperator'\n} & INode\n\nexport type WildcardOperatorNode = {\n  type: 'WildcardOperator'\n  filter?: GroupExpressionNode | RangeExpressionNode\n  optional?: boolean\n} & INode\n\nexport type ExpandOperatorNode = {\n  type: 'ExpandOperator'\n} & INode\n\nexport type GroupExpressionNode = {\n  type: 'GroupExpression'\n  value: Node[]\n  isExclude?: boolean\n} & INode\n\nexport type RangeExpressionNode = {\n  type: 'RangeExpression'\n  start?: IdentifierNode\n  end?: IdentifierNode\n} & INode\n\nexport type DestructorExpressionNode = {\n  type: 'DestructorExpression'\n  value?: ObjectPatternNode | ArrayPatternNode\n  source?: string\n} & INode\n\nexport type ObjectPatternNode = {\n  type: 'ObjectPattern'\n  properties: ObjectPatternPropertyNode[]\n} & INode\n\nexport type ObjectPatternPropertyNode = {\n  type: 'ObjectPatternProperty'\n  key: IdentifierNode\n  value?: ObjectPatternNode[] | ArrayPatternNode[] | IdentifierNode\n} & INode\n\nexport type ArrayPatternNode = {\n  type: 'ArrayPattern'\n  elements: ObjectPatternNode[] | ArrayPatternNode[] | IdentifierNode[]\n} & INode\n\nexport type DestructorRule = {\n  key?: string | number\n  path?: Array<number | string>\n}\n\nexport type MatcherFunction = ((path: Segments) => boolean) & {\n  path: Path\n}\n\nexport type Pattern =\n  | string\n  | number\n  | Path\n  | Segments\n  | MatcherFunction\n  | RegExp\n\nexport type DestructorRules = DestructorRule[]\n\nexport type Segments = Array<string | number>\n\nexport const isType =\n  <T>(type: string) =>\n  (obj: any): obj is T => {\n    return obj && obj.type === type\n  }\n\nexport const isIdentifier = isType<IdentifierNode>('Identifier')\n\nexport const isIgnoreExpression =\n  isType<IgnoreExpressionNode>('IgnoreExpression')\n\nexport const isDotOperator = isType<DotOperatorNode>('DotOperator')\n\nexport const isWildcardOperator =\n  isType<WildcardOperatorNode>('WildcardOperator')\n\nexport const isExpandOperator = isType<ExpandOperatorNode>('ExpandOperator')\n\nexport const isGroupExpression = isType<GroupExpressionNode>('GroupExpression')\n\nexport const isRangeExpression = isType<RangeExpressionNode>('RangeExpression')\n\nexport const isDestructorExpression = isType<DestructorExpressionNode>(\n  'DestructorExpression'\n)\n\nexport const isObjectPattern = isType<ObjectPatternNode>('ObjectPattern')\n\nexport const isObjectPatternProperty = isType<ObjectPatternPropertyNode>(\n  'ObjectPatternProperty'\n)\n\nexport const isArrayPattern = isType<ArrayPatternNode>('ArrayPattern')\n\nexport type KeyType = string | number | symbol\n\nexport type IAccessors = {\n  get?: (source: any, key: KeyType) => any\n  set?: (source: any, key: KeyType, value: any) => any\n  has?: (source: any, key: KeyType) => boolean\n  delete?: (source: any, key: KeyType) => any\n}\n\nexport type IRegistry = {\n  accessors?: IAccessors\n}\n"
  },
  {
    "path": "packages/path/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*\", \"devtools/*\"]\n    },\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/path/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"include\": [\"./src/**/*.ts\", \"./src/**/*.tsx\"],\n  \"exclude\": [\"./src/__tests__/*\", \"./esm/*\", \"./lib/*\"]\n}\n"
  },
  {
    "path": "packages/react/.npmignore",
    "content": "node_modules\n*.log\nbuild\ndocs\ndoc-site\n__tests__\n.eslintrc\njest.config.js\ntsconfig.json\n.umi\nsrc"
  },
  {
    "path": "packages/react/.umirc.js",
    "content": "import { resolve } from 'path'\nexport default {\n  mode: 'site',\n  logo: '//img.alicdn.com/imgextra/i2/O1CN01Kq3OHU1fph6LGqjIz_!!6000000004056-55-tps-1141-150.svg',\n  title: 'React',\n  hash: true,\n  favicon:\n    '//img.alicdn.com/imgextra/i3/O1CN01XtT3Tv1Wd1b5hNVKy_!!6000000002810-55-tps-360-360.svg',\n  outputPath: './doc-site',\n  navs: {\n    'en-US': [\n      {\n        title: 'Guide',\n        path: '/guide',\n      },\n      {\n        title: 'API',\n        path: '/api',\n      },\n      {\n        title: 'Home Site',\n        path: 'https://formilyjs.org',\n      },\n      {\n        title: 'GITHUB',\n        path: 'https://github.com/alibaba/formily',\n      },\n    ],\n    'zh-CN': [\n      {\n        title: '指南',\n        path: '/zh-CN/guide',\n      },\n      {\n        title: 'API',\n        path: '/zh-CN/api',\n      },\n      {\n        title: '主站',\n        path: 'https://formilyjs.org',\n      },\n      {\n        title: 'GITHUB',\n        path: 'https://github.com/alibaba/formily',\n      },\n    ],\n  },\n  links: [\n    {\n      rel: 'stylesheet',\n      href: 'https://esm.sh/antd@4.x/dist/antd.css',\n    },\n  ],\n  headScripts: [\n    `\n    function loadAd(){\n      var header = document.querySelector('.__dumi-default-layout-content .markdown h1')\n      if(header && !header.querySelector('#_carbonads_js')){\n        var script = document.createElement('script')\n        script.src = '//cdn.carbonads.com/carbon.js?serve=CEAICK3M&placement=formilyjsorg'\n        script.id = '_carbonads_js'\n        script.classList.add('head-ad')\n        header.appendChild(script)\n      }\n    }\n    var request = null\n    var observer = new MutationObserver(function(){\n      cancelIdleCallback(request)\n      request = requestIdleCallback(loadAd)\n    })\n    document.addEventListener('DOMContentLoaded',function(){\n      loadAd()\n      observer.observe(\n        document.body,\n        {\n          childList:true,\n          subtree:true\n        }\n      )\n    })\n    `,\n  ],\n  styles: [\n    `.__dumi-default-navbar-logo{\n      background-size: 140px!important;\n      background-position: center left!important;\n      background-repeat: no-repeat!important;\n      padding-left: 150px!important;/*可根据title的宽度调整*/\n      font-size: 22px!important;\n      color: #000!important;\n      font-weight: lighter!important;\n    }\n    .__dumi-default-navbar{\n      padding: 0 28px !important;\n    }\n    .__dumi-default-layout-hero{\n      background-image: url(//img.alicdn.com/imgextra/i4/O1CN01ZcvS4e26XMsdsCkf9_!!6000000007671-2-tps-6001-4001.png);\n      background-size: cover;\n      background-repeat: no-repeat;\n      padding: 120px 0 !important;\n    }\n    .__dumi-default-layout-hero h1{\n      color:#45124e !important;\n      font-size:80px !important;\n      padding-bottom: 30px !important;\n    }\n    .__dumi-default-dark-switch {\n      display:none\n    }\n    nav a{\n      text-decoration: none !important;\n    }\n    #carbonads * {\n      margin: initial;\n      padding: initial;\n    }\n    #carbonads {\n      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,\n        Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Helvetica, Arial,\n        sans-serif;\n    }\n    #carbonads {\n      display: flex;\n      max-width: 330px;\n      background-color: hsl(0, 0%, 98%);\n      box-shadow: 0 1px 4px 1px hsla(0, 0%, 0%, 0.1);\n      z-index: 100;\n      float:right;\n    }\n    #carbonads a {\n      color: inherit;\n      text-decoration: none;\n    }\n    #carbonads a:hover {\n      color: inherit;\n    }\n    #carbonads span {\n      position: relative;\n      display: block;\n      overflow: hidden;\n    }\n    #carbonads .carbon-wrap {\n      display: flex;\n    }\n    #carbonads .carbon-img {\n      display: block;\n      margin: 0;\n      line-height: 1;\n    }\n    #carbonads .carbon-img img {\n      display: block;\n    }\n    #carbonads .carbon-text {\n      font-size: 13px;\n      padding: 10px;\n      margin-bottom: 16px;\n      line-height: 1.5;\n      text-align: left;\n    }\n    #carbonads .carbon-poweredby {\n      display: block;\n      padding: 6px 8px;\n      background: #f1f1f2;\n      text-align: center;\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n      font-weight: 600;\n      font-size: 8px;\n      line-height: 1;\n      border-top-left-radius: 3px;\n      position: absolute;\n      bottom: 0;\n      right: 0;\n    }\n    `,\n  ],\n  menus: {\n    '/guide': [\n      {\n        title: 'Introduction',\n        path: '/guide',\n      },\n      { title: 'Architecture', path: '/guide/architecture' },\n      { title: 'Concept', path: '/guide/concept' },\n    ],\n    '/zh-CN/guide': [\n      {\n        title: '介绍',\n        path: '/guide',\n      },\n      { title: '核心架构', path: '/zh-CN/guide/architecture' },\n      { title: '核心概念', path: '/zh-CN/guide/concept' },\n    ],\n  },\n}\n"
  },
  {
    "path": "packages/react/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-present, Alibaba Group Holding Limited. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "packages/react/README.md",
    "content": "# @formily/react\n"
  },
  {
    "path": "packages/react/docs/api/components/ArrayField.md",
    "content": "---\norder: 1\n---\n\n# ArrayField\n\n## Description\n\nAs @formily/core's [createArrayField](https://core.formilyjs.org/api/models/form#createarrayfield) React implementation, it is a bridge component specifically used to bind ViewModel and input controls, ArrayField component Property reference [IFieldFactoryProps](https://core.formilyjs.org/api/models/form#ifieldfactoryprops)\n\n<Alert>\nWhen we use the ArrayField component, we must remember to pass the name attribute. At the same time, use render props to organize sub-components\n</Alert>\n\n## Signature\n\n```ts\ntype ArrayField = React.FC<React.PropsWithChildren<IFieldFactoryProps>>\n```\n\n## Custom component use case\n\n```tsx\nimport React from 'react'\nimport { createForm, ArrayField as ArrayFieldType } from '@formily/core'\nimport {\n  FormProvider,\n  Field,\n  ArrayField,\n  useField,\n  observer,\n} from '@formily/react'\nimport { Input, Button, Space } from 'antd'\n\nconst form = createForm()\n\nconst ArrayComponent = observer(() => {\n  const field = useField<ArrayFieldType>()\n  return (\n    <>\n      <div>\n        {field.value?.map((item, index) => (\n          <div key={index} style={{ display: 'flex-block', marginBottom: 10 }}>\n            <Space>\n              <Field name={index} component={[Input]} />\n              <Button\n                onClick={() => {\n                  field.remove(index)\n                }}\n              >\n                Remove\n              </Button>\n              <Button\n                onClick={() => {\n                  field.moveUp(index)\n                }}\n              >\n                Move Up\n              </Button>\n              <Button\n                onClick={() => {\n                  field.moveDown(index)\n                }}\n              >\n                Move Down\n              </Button>\n            </Space>\n          </div>\n        ))}\n      </div>\n      <Button\n        onClick={() => {\n          field.push('')\n        }}\n      >\n        Add\n      </Button>\n    </>\n  )\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <ArrayField name=\"array\" component={[ArrayComponent]} />\n  </FormProvider>\n)\n```\n\n## RenderProps use cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, ArrayField } from '@formily/react'\nimport { Input, Button, Space } from 'antd'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <ArrayField name=\"array\">\n      {(field) => {\n        return (\n          <>\n            <div>\n              {field.value?.map((item, index) => (\n                <div\n                  key={index}\n                  style={{ display: 'flex-block', marginBottom: 10 }}\n                >\n                  <Space>\n                    <Field name={index} component={[Input]} />\n                    <Button\n                      onClick={() => {\n                        field.remove(index)\n                      }}\n                    >\n                      Remove\n                    </Button>\n                    <Button\n                      onClick={() => {\n                        field.moveUp(index)\n                      }}\n                    >\n                      Move Up\n                    </Button>\n                    <Button\n                      onClick={() => {\n                        field.moveDown(index)\n                      }}\n                    >\n                      Move Down\n                    </Button>\n                  </Space>\n                </div>\n              ))}\n            </div>\n            <Button onClick={() => field.push('')}>Add</Button>\n          </>\n        )\n      }}\n    </ArrayField>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/components/ArrayField.zh-CN.md",
    "content": "---\norder: 1\n---\n\n# ArrayField\n\n## 描述\n\n作为@formily/core 的 [createArrayField](https://core.formilyjs.org/zh-CN/api/models/form#createarrayfield) React 实现，它是专门用于将 ViewModel 与输入控件做绑定的桥接组件，ArrayField 组件属性参考[IFieldFactoryProps](https://core.formilyjs.org/zh-CN/api/models/form#ifieldfactoryprops)\n\n<Alert>\n我们在使用 ArrayField 组件的时候，一定要记得传name属性。同时要使用render props形式来组织子组件\n</Alert>\n\n## 签名\n\n```ts\ntype ArrayField = React.FC<React.PropsWithChildren<IFieldFactoryProps>>\n```\n\n## 自定义组件用例\n\n```tsx\nimport React from 'react'\nimport { createForm, ArrayField as ArrayFieldType } from '@formily/core'\nimport {\n  FormProvider,\n  Field,\n  ArrayField,\n  useField,\n  observer,\n} from '@formily/react'\nimport { Input, Button, Space } from 'antd'\n\nconst form = createForm()\n\nconst ArrayComponent = observer(() => {\n  const field = useField<ArrayFieldType>()\n  return (\n    <>\n      <div>\n        {field.value?.map((item, index) => (\n          <div key={index} style={{ display: 'flex-block', marginBottom: 10 }}>\n            <Space>\n              <Field name={index} component={[Input]} />\n              <Button\n                onClick={() => {\n                  field.remove(index)\n                }}\n              >\n                Remove\n              </Button>\n              <Button\n                onClick={() => {\n                  field.moveUp(index)\n                }}\n              >\n                Move Up\n              </Button>\n              <Button\n                onClick={() => {\n                  field.moveDown(index)\n                }}\n              >\n                Move Down\n              </Button>\n            </Space>\n          </div>\n        ))}\n      </div>\n      <Button\n        onClick={() => {\n          field.push('')\n        }}\n      >\n        Add\n      </Button>\n    </>\n  )\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <ArrayField name=\"array\" component={[ArrayComponent]} />\n  </FormProvider>\n)\n```\n\n## RenderProps 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, ArrayField } from '@formily/react'\nimport { Input, Button, Space } from 'antd'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <ArrayField name=\"array\">\n      {(field) => {\n        return (\n          <>\n            <div>\n              {field.value?.map((item, index) => (\n                <div\n                  key={index}\n                  style={{ display: 'flex-block', marginBottom: 10 }}\n                >\n                  <Space>\n                    <Field name={index} component={[Input]} />\n                    <Button\n                      onClick={() => {\n                        field.remove(index)\n                      }}\n                    >\n                      Remove\n                    </Button>\n                    <Button\n                      onClick={() => {\n                        field.moveUp(index)\n                      }}\n                    >\n                      Move Up\n                    </Button>\n                    <Button\n                      onClick={() => {\n                        field.moveDown(index)\n                      }}\n                    >\n                      Move Down\n                    </Button>\n                  </Space>\n                </div>\n              ))}\n            </div>\n            <Button onClick={() => field.push('')}>Add</Button>\n          </>\n        )\n      }}\n    </ArrayField>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/components/ExpressionScope.md",
    "content": "---\norder: 8\n---\n\n# ExpressionScope\n\n## Description\n\nUsed to pass local scopes to json-schema expressions inside custom components\n\n## Signature\n\n```ts\ninterface IExpressionScopeProps {\n  value?: any\n}\ntype ExpressionScope = React.FC<React.PropsWithChildren<IExpressionScopeProps>>\n```\n\n## Example\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  createSchemaField,\n  ExpressionScope,\n} from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nconst Container = (props) => {\n  return (\n    <ExpressionScope value={{ $innerScope: 'this inner scope value' }}>\n      {props.children}\n    </ExpressionScope>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    Container,\n    Input,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Void x-component=\"Container\">\n        <SchemaField.String\n          name=\"input\"\n          x-component=\"Input\"\n          x-value=\"{{$innerScope}}\"\n        />\n      </SchemaField.Void>\n    </SchemaField>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/components/ExpressionScope.zh-CN.md",
    "content": "---\norder: 8\n---\n\n# ExpressionScope\n\n## 描述\n\n用于自定义组件内部给 json-schema 表达式传递局部作用域\n\n## 签名\n\n```ts\ninterface IExpressionScopeProps {\n  value?: any\n}\ntype ExpressionScope = React.FC<React.PropsWithChildren<IExpressionScopeProps>>\n```\n\n## 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  createSchemaField,\n  ExpressionScope,\n} from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nconst Container = (props) => {\n  return (\n    <ExpressionScope value={{ $innerScope: 'this inner scope value' }}>\n      {props.children}\n    </ExpressionScope>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    Container,\n    Input,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Void x-component=\"Container\">\n        <SchemaField.String\n          name=\"input\"\n          x-component=\"Input\"\n          x-value=\"{{$innerScope}}\"\n        />\n      </SchemaField.Void>\n    </SchemaField>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/components/Field.md",
    "content": "---\norder: 0\n---\n\n# Field\n\n## Description\n\nAs @formily/core's [createField](https://core.formilyjs.org/api/models/form#createfield) React implementation, it is a bridge component specifically used to bind ViewModel and input controls, the Field component Property reference [IFieldFactoryProps](https://core.formilyjs.org/api/models/form#ifieldfactoryprops)\n\n<Alert>\nWhen we use the Field component, we must remember to pass the name attribute.\n</Alert>\n\n## Signature\n\n```ts\ntype Field = React.FC<React.PropsWithChildren<IFieldFactoryProps>>\n```\n\n## Example\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field name=\"input\" component={[Input, { placeholder: 'Please Input' }]} />\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/components/Field.zh-CN.md",
    "content": "---\norder: 0\n---\n\n# Field\n\n## 描述\n\n作为@formily/core 的 [createField](https://core.formilyjs.org/zh-CN/api/models/form#createfield) React 实现，它是专门用于将 ViewModel 与输入控件做绑定的桥接组件，Field 组件属性参考[IFieldFactoryProps](https://core.formilyjs.org/zh-CN/api/models/form#ifieldfactoryprops)\n\n<Alert>\n我们在使用 Field 组件的时候，一定要记得传name属性。\n</Alert>\n\n## 签名\n\n```ts\ntype Field = React.FC<React.PropsWithChildren<IFieldFactoryProps>>\n```\n\n## 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field name=\"input\" component={[Input, { placeholder: 'Please Input' }]} />\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/components/FormConsumer.md",
    "content": "---\norder: 7\n---\n\n# FormConsumer\n\n## Description\n\nThe form response consumer is specifically used to monitor the data changes of the form model to implement various UI response components. The use method is render props.\n\nWhen the dependent data in the callback function changes, the callback function will be re-rendered\n\n## Signature\n\n```ts\ntype FormConsumer = React.FC<{ children: (form: Form) => React.ReactNode }>\n```\n\nForm reference [Form](https://core.formilyjs.org/api/models/form)\n\n## Example\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, Field } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field name=\"input\" component={[Input]} />\n    <FormConsumer>{(form) => form.values.input}</FormConsumer>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/components/FormConsumer.zh-CN.md",
    "content": "---\norder: 7\n---\n\n# FormConsumer\n\n## 描述\n\n表单响应消费者，专门用于监听表单模型数据变化而实现各种 UI 响应的组件，使用方式为 render props.\n\n当回调函数内依赖的数据发生变化时就会重新渲染回调函数\n\n## 签名\n\n```ts\ntype FormConsumer = React.FC<{ children: (form: Form) => React.ReactNode }>\n```\n\nForm 参考[Form](https://core.formilyjs.org/zh-CN/api/models/form)\n\n## 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, Field } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field name=\"input\" component={[Input]} />\n    <FormConsumer>{(form) => form.values.input}</FormConsumer>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/components/FormProvider.md",
    "content": "---\norder: 6\n---\n\n# FormProvider\n\n## Description\n\nThe entry component is used to place the order context to the field component and is responsible for the communication of the entire form state. It is equivalent to a communication hub.\n\n## Signature\n\n```ts\ntype FormProvider = React.FC<{\n  form: Form // form instance created by createForm\n}>\n```\n\nForm reference [Form](https://core.formilyjs.org/api/models/form)\n\n## Example\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field name=\"input\" component={[Input]} />\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/components/FormProvider.zh-CN.md",
    "content": "---\norder: 6\n---\n\n# FormProvider\n\n## 描述\n\n入口组件，用于下发表单上下文给字段组件，负责整个表单状态的通讯，它相当于是一个通讯枢纽。\n\n## 签名\n\n```ts\ntype FormProvider = React.FC<{\n  form: Form //通过createForm创建的form实例\n}>\n```\n\nForm 参考[Form](https://core.formilyjs.org/zh-CN/api/models/form)\n\n## 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field name=\"input\" component={[Input]} />\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/components/ObjectField.md",
    "content": "---\norder: 2\n---\n\n# ObjectField\n\n## Description\n\nAs @formily/core's [createObjectField](https://core.formilyjs.org/api/models/form#createobjectfield) React implementation, it is a bridge component specifically used to bind ViewModel and input controls, ObjectField component Property reference [IFieldFactoryProps](https://core.formilyjs.org/api/models/form#ifieldfactoryprops)\n\n<Alert>\nWhen we use the ObjectField component, we must remember to pass the name attribute. At the same time, use render props to organize sub-components\n</Alert>\n\n## Signature\n\n```ts\ntype ObjectField = React.FC<React.PropsWithChildren<IFieldFactoryProps>>\n```\n\n## Custom component use case\n\n```tsx\nimport React from 'react'\nimport { createForm, ObjectField as ObjectFieldType } from '@formily/core'\nimport {\n  FormProvider,\n  Field,\n  ObjectField,\n  useField,\n  observer,\n} from '@formily/react'\nimport { Input, Button, Space } from 'antd'\n\nconst form = createForm()\n\nconst ObjectComponent = observer(() => {\n  const field = useField<ObjectFieldType>()\n  return (\n    <>\n      <div>\n        {Object.keys(field.value || {}).map((key) => (\n          <div key={key} style={{ display: 'flex-block', marginBottom: 10 }}>\n            <Space>\n              <Field name={key} component={[Input, { placeholder: key }]} />\n              <Button\n                onClick={() => {\n                  field.removeProperty(key)\n                }}\n              >\n                Remove\n              </Button>\n            </Space>\n          </div>\n        ))}\n      </div>\n      <Space>\n        <Field\n          name=\"propertyName\"\n          basePath={''}\n          required\n          component={[Input, { placeholder: 'Property Name' }]}\n        />\n        <Button\n          onClick={() => {\n            const name = form.values.propertyName\n            if (name && !form.existValuesIn(`${field.path}.${name}`)) {\n              field.addProperty(name, '')\n              form.deleteValuesIn('propertyName')\n            }\n          }}\n        >\n          Add\n        </Button>\n      </Space>\n    </>\n  )\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <ObjectField name=\"object\" component={[ObjectComponent]} />\n  </FormProvider>\n)\n```\n\n## RenderProps use cases\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, ObjectField } from '@formily/react'\nimport { Input, Button, Space } from 'antd'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <ObjectField name=\"object\">\n      {(field) => {\n        return (\n          <>\n            <div>\n              {Object.keys(field.value || {}).map((key) => (\n                <div\n                  key={key}\n                  style={{ display: 'flex-block', marginBottom: 10 }}\n                >\n                  <Space>\n                    <Field\n                      name={key}\n                      component={[Input, { placeholder: key }]}\n                    />\n                    <Button\n                      onClick={() => {\n                        field.removeProperty(key)\n                      }}\n                    >\n                      Remove\n                    </Button>\n                  </Space>\n                </div>\n              ))}\n            </div>\n            <Space>\n              <Field\n                name=\"propertyName\"\n                basePath={''}\n                required\n                component={[Input, { placeholder: 'Property Name' }]}\n              />\n              <Button\n                onClick={() => {\n                  const name = form.values.propertyName\n                  if (name && !form.existValuesIn(`${field.path}.${name}`)) {\n                    field.addProperty(name, '')\n                    form.deleteValuesIn('propertyName')\n                  }\n                }}\n              >\n                Add\n              </Button>\n            </Space>\n          </>\n        )\n      }}\n    </ObjectField>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/components/ObjectField.zh-CN.md",
    "content": "---\norder: 2\n---\n\n# ObjectField\n\n## 描述\n\n作为@formily/core 的 [createObjectField](https://core.formilyjs.org/zh-CN/api/models/form#createobjectfield) React 实现，它是专门用于将 ViewModel 与输入控件做绑定的桥接组件，ObjectField 组件属性参考[IFieldFactoryProps](https://core.formilyjs.org/zh-CN/api/models/form#ifieldfactoryprops)\n\n<Alert>\n我们在使用 ObjectField 组件的时候，一定要记得传name属性。同时要使用render props形式来组织子组件\n</Alert>\n\n## 签名\n\n```ts\ntype ObjectField = React.FC<React.PropsWithChildren<IFieldFactoryProps>>\n```\n\n## 自定义组件用例\n\n```tsx\nimport React from 'react'\nimport { createForm, ObjectField as ObjectFieldType } from '@formily/core'\nimport {\n  FormProvider,\n  Field,\n  ObjectField,\n  useField,\n  observer,\n} from '@formily/react'\nimport { Input, Button, Space } from 'antd'\n\nconst form = createForm()\n\nconst ObjectComponent = observer(() => {\n  const field = useField<ObjectFieldType>()\n  return (\n    <>\n      <div>\n        {Object.keys(field.value || {}).map((key) => (\n          <div key={key} style={{ display: 'flex-block', marginBottom: 10 }}>\n            <Space>\n              <Field name={key} component={[Input, { placeholder: key }]} />\n              <Button\n                onClick={() => {\n                  field.removeProperty(key)\n                }}\n              >\n                Remove\n              </Button>\n            </Space>\n          </div>\n        ))}\n      </div>\n      <Space>\n        <Field\n          name=\"propertyName\"\n          basePath={''}\n          required\n          component={[Input, { placeholder: 'Property Name' }]}\n        />\n        <Button\n          onClick={() => {\n            const name = form.values.propertyName\n            if (name && !form.existValuesIn(`${field.path}.${name}`)) {\n              field.addProperty(name, '')\n              form.deleteValuesIn('propertyName')\n            }\n          }}\n        >\n          Add\n        </Button>\n      </Space>\n    </>\n  )\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <ObjectField name=\"object\" component={[ObjectComponent]} />\n  </FormProvider>\n)\n```\n\n## RenderProps 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, ObjectField } from '@formily/react'\nimport { Input, Button, Space } from 'antd'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <ObjectField name=\"object\">\n      {(field) => {\n        return (\n          <>\n            <div>\n              {Object.keys(field.value || {}).map((key) => (\n                <div\n                  key={key}\n                  style={{ display: 'flex-block', marginBottom: 10 }}\n                >\n                  <Space>\n                    <Field\n                      name={key}\n                      component={[Input, { placeholder: key }]}\n                    />\n                    <Button\n                      onClick={() => {\n                        field.removeProperty(key)\n                      }}\n                    >\n                      Remove\n                    </Button>\n                  </Space>\n                </div>\n              ))}\n            </div>\n            <Space>\n              <Field\n                name=\"propertyName\"\n                basePath={''}\n                required\n                component={[Input, { placeholder: 'Property Name' }]}\n              />\n              <Button\n                onClick={() => {\n                  const name = form.values.propertyName\n                  if (name && !form.existValuesIn(`${field.path}.${name}`)) {\n                    field.addProperty(name, '')\n                    form.deleteValuesIn('propertyName')\n                  }\n                }}\n              >\n                Add\n              </Button>\n            </Space>\n          </>\n        )\n      }}\n    </ObjectField>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/components/RecordScope.md",
    "content": "---\norder: 9\n---\n\n# RecordScope\n\n## Description\n\nStandard scoped injection component for injecting the following built-in variables:\n\n- `$record` current record data\n- `$record.$lookup` The parent record of the current record, you can always look up\n- `$record.$index` the index of the current record\n- `$index` The current record index, equivalent to `$record.$index`, considering that if the record data is not an object, it needs to be read independently\n- `$lookup` The parent record of the current record, equivalent to `$record.$lookup`, considering that if the record data is not an object, it needs to be read independently\n\n## Signature\n\n```ts\ninterface IRecordScopeProps {\n  getRecord(): any\n  getIndex?(): number\n}\n\ntype RecordScope = React.FC<React.PropsWithChildren<IRecordScopeProps>>\n```\n\n## Usage\n\nAny auto-increment list extension component should use RecordScope internally to pass record scope variables. Components that have implemented this convention include:\nAll components of the ArrayX family in @formily/antd and @formily/next\n\n## Custom component extension use case\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField, RecordScope } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nconst MyCustomComponent = (props) => {\n  return (\n    <RecordScope getRecord={() => props.record} getIndex={() => props.index}>\n      {props.children}\n    </RecordScope>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    MyCustomComponent,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField\n      schema={{\n        type: 'object',\n        properties: {\n          lookup: {\n            type: 'void',\n            'x-component': 'MyCustomComponent',\n            'x-component-props': {\n              record: {\n                name: 'Lookup Name',\n                code: 'Lookup Code',\n              },\n              index: 1,\n            },\n            properties: {\n              record: {\n                type: 'void',\n                'x-component': 'MyCustomComponent',\n                'x-component-props': {\n                  record: {\n                    name: 'Name',\n                    code: 'Code',\n                  },\n                  index: 0,\n                },\n                properties: {\n                  input: {\n                    type: 'string',\n                    'x-component': 'Input',\n                    'x-value':\n                      '{{`' +\n                      '${$record.name} ' +\n                      '${$record.code} ' +\n                      '${$record.$index} ' +\n                      '${$record.$lookup.name} ' +\n                      '${$record.$lookup.code} ' +\n                      '${$index} ' +\n                      '${$lookup.name} ' +\n                      '${$lookup.code} ' +\n                      '`}}',\n                  },\n                },\n              },\n            },\n          },\n        },\n      }}\n    ></SchemaField>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/components/RecordScope.zh-CN.md",
    "content": "---\norder: 9\n---\n\n# RecordScope\n\n## 描述\n\n标准作用域注入组件，用于注入以下内置变量：\n\n- `$record` 当前记录数据\n- `$record.$lookup` 当前记录的父级记录，可以一直往上查找\n- `$record.$index` 当前记录的索引\n- `$index` 当前记录索引，等同于`$record.$index`，考虑到记录数据如果不是对象，则需要独立读取\n- `$lookup` 当前记录的父级记录，等同于`$record.$lookup`，考虑到记录数据如果不是对象，则需要独立读取\n\n## 签名\n\n```ts\ninterface IRecordScopeProps {\n  getRecord(): any\n  getIndex?(): number\n}\n\ntype RecordScope = React.FC<React.PropsWithChildren<IRecordScopeProps>>\n```\n\n## 使用约定\n\n任何自增列表扩展组件，内部都应该使用 RecordScope，用于传递记录作用域变量，目前已实现该约定的组件包括：\n@formily/antd 和 @formily/next 中的 ArrayX 系列的所有组件\n\n## 自定义组件扩展用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField, RecordScope } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nconst MyCustomComponent = (props) => {\n  return (\n    <RecordScope getRecord={() => props.record} getIndex={() => props.index}>\n      {props.children}\n    </RecordScope>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    MyCustomComponent,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField\n      schema={{\n        type: 'object',\n        properties: {\n          lookup: {\n            type: 'void',\n            'x-component': 'MyCustomComponent',\n            'x-component-props': {\n              record: {\n                name: 'Lookup Name',\n                code: 'Lookup Code',\n              },\n              index: 1,\n            },\n            properties: {\n              record: {\n                type: 'void',\n                'x-component': 'MyCustomComponent',\n                'x-component-props': {\n                  record: {\n                    name: 'Name',\n                    code: 'Code',\n                  },\n                  index: 0,\n                },\n                properties: {\n                  input: {\n                    type: 'string',\n                    'x-component': 'Input',\n                    'x-value':\n                      '{{`' +\n                      '${$record.name} ' +\n                      '${$record.code} ' +\n                      '${$record.$index} ' +\n                      '${$record.$lookup.name} ' +\n                      '${$record.$lookup.code} ' +\n                      '${$index} ' +\n                      '${$lookup.name} ' +\n                      '${$lookup.code} ' +\n                      '`}}',\n                  },\n                },\n              },\n            },\n          },\n        },\n      }}\n    ></SchemaField>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/components/RecordsScope.md",
    "content": "---\norder: 10\n---\n\n# RecordsScope\n\n## Description\n\nStandard scoped injection component for injecting the following built-in variables:\n\n- `$records` current record list data\n\n## Signature\n\n```ts\ninterface IRecordsScopeProps {\n  getRecords(): any[]\n}\n\ntype RecordsScope = React.FC<React.PropsWithChildren<IRecordsScopeProps>>\n```\n\n## Usage\n\nAny auto-incrementing list extension component should use RecordsScope internally to pass record scope variables. Components that have implemented this convention include:\nAll components of the ArrayX family in @formily/antd and @formily/next\n\n## Custom component extension use case\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField, RecordsScope } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nconst MyCustomComponent = (props) => {\n  return (\n    <RecordsScope getRecords={() => props.records}>\n      {props.children}\n    </RecordsScope>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    MyCustomComponent,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField\n      schema={{\n        type: 'object',\n        properties: {\n          records: {\n            type: 'void',\n            'x-component': 'MyCustomComponent',\n            'x-component-props': {\n              records: [\n                {\n                  name: 'Name',\n                  code: 'Code',\n                },\n              ],\n            },\n            properties: {\n              input: {\n                type: 'string',\n                'x-component': 'Input',\n                'x-value':\n                  '{{`' +\n                  '${$records[0].name} ' +\n                  '${$records[0].code}' +\n                  '`}}',\n              },\n            },\n          },\n        },\n      }}\n    ></SchemaField>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/components/RecordsScope.zh-CN.md",
    "content": "---\norder: 10\n---\n\n# RecordsScope\n\n## 描述\n\n标准作用域注入组件，用于注入以下内置变量：\n\n- `$records` 当前记录列表数据\n\n## 签名\n\n```ts\ninterface IRecordsScopeProps {\n  getRecords(): any[]\n}\n\ntype RecordsScope = React.FC<React.PropsWithChildren<IRecordsScopeProps>>\n```\n\n## 使用约定\n\n任何自增列表扩展组件，内部都应该使用 RecordsScope，用于传递记录作用域变量，目前已实现该约定的组件包括：\n@formily/antd 和 @formily/next 中的 ArrayX 系列的所有组件\n\n## 自定义组件扩展用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField, RecordsScope } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nconst MyCustomComponent = (props) => {\n  return (\n    <RecordsScope getRecords={() => props.records}>\n      {props.children}\n    </RecordsScope>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    MyCustomComponent,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField\n      schema={{\n        type: 'object',\n        properties: {\n          records: {\n            type: 'void',\n            'x-component': 'MyCustomComponent',\n            'x-component-props': {\n              records: [\n                {\n                  name: 'Name',\n                  code: 'Code',\n                },\n              ],\n            },\n            properties: {\n              input: {\n                type: 'string',\n                'x-component': 'Input',\n                'x-value':\n                  '{{`' +\n                  '${$records[0].name} ' +\n                  '${$records[0].code} ' +\n                  '`}}',\n              },\n            },\n          },\n        },\n      }}\n    ></SchemaField>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/components/RecursionField.md",
    "content": "---\norder: 5\n---\n\n# RecursionField\n\n## Description\n\nThe recursive rendering component is mainly based on [JSON-Schema](/api/shared/schema) for recursive rendering. It is the core rendering component inside the [SchemaField](/api/components/schema-field) component. Of course, it can It is used separately from SchemaField. When we use it, it is mainly used in custom components to implement custom components with recursive rendering capabilities.\n\n## Signature\n\n```ts\ninterface IRecursionFieldProps {\n  schema: ISchema //Field schema\n  name?: string //Path name\n  basePath?: FormPathPattern //base path\n  propsRecursion?: boolean //Whether to recursiveliy pass mapProperties and filterProperties\n  onlyRenderProperties?: boolean //Whether to only render properties\n  onlyRenderSelf?: boolean //Whether to only render itself without rendering properties\n  mapProperties?: (schema: Schema, name: string) => Schema //schema properties mapper, mainly used to rewrite the schema\n  filterProperties?: (schema: Schema, name: string) => boolean //schema properties filter, the filtered schema nodes will not be rendered\n}\n\ntype RecursionField = React.FC<React.PropsWithChildren<IRecursionFieldProps>>\n```\n\n## Example\n\n### Simple recursion\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField, RecursionField } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nconst Custom = (props) => {\n  return <RecursionField schema={props.schema} onlyRenderProperties />\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    Custom,\n    Input,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Object\n        name=\"custom\"\n        x-component=\"Custom\"\n        x-component-props={{\n          schema: {\n            type: 'object',\n            properties: {\n              input: {\n                type: 'string',\n                'x-component': 'Input',\n              },\n            },\n          },\n        }}\n      />\n    </SchemaField>\n  </FormProvider>\n)\n```\n\nWe can read independent schema objects from component properties and pass them to RecursionField for rendering\n\n### Incremental list recursion\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  createSchemaField,\n  RecursionField,\n  useField,\n  useFieldSchema,\n  observer,\n} from '@formily/react'\nimport { Input, Space, Button } from 'antd'\n\nconst form = createForm()\n\nconst ArrayItems = observer((props) => {\n  const field = useField()\n  const schema = useFieldSchema()\n  return (\n    <div>\n      {props.value?.map((item, index) => {\n        return (\n          <div key={index} style={{ marginBottom: 10 }}>\n            <Space>\n              <RecursionField schema={schema.items} name={index} />\n              <Button\n                onClick={() => {\n                  field.remove(index)\n                }}\n              >\n                Remove\n              </Button>\n            </Space>\n          </div>\n        )\n      })}\n      <Button\n        onClick={() => {\n          field.push({})\n        }}\n      >\n        Add\n      </Button>\n    </div>\n  )\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    ArrayItems,\n    Input,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Array name=\"custom\" x-component=\"ArrayItems\">\n        <SchemaField.Object>\n          <SchemaField.String name=\"input\" x-component=\"Input\" />\n        </SchemaField.Object>\n      </SchemaField.Array>\n    </SchemaField>\n  </FormProvider>\n)\n```\n\nUse [useField](/api/hooks/useField) and [useFieldSchema](/api/shared/use-field-schema) to get the field instance and field schema in the current field context\n"
  },
  {
    "path": "packages/react/docs/api/components/RecursionField.zh-CN.md",
    "content": "---\norder: 5\n---\n\n# RecursionField\n\n## 描述\n\n递归渲染组件，主要基于[JSON-Schema](/api/shared/schema)做递归渲染，它是[SchemaField](/api/components/schema-field)组件内部的核心渲染组件，当然，它是可以独立于 SchemaField 单独使用的，我们使用的时候主要是在自定义组件中使用，用于实现具有递归渲染能力的自定义组件\n\n## 签名\n\n```ts\ninterface IRecursionFieldProps {\n  schema: ISchema //字段schema\n  name?: string //路径名称\n  basePath?: FormPathPattern //基础路径\n  propsRecursion?: boolean //是否递归传递 mapProperties 和 filterProperties\n  onlyRenderProperties?: boolean //是否只渲染properties\n  onlyRenderSelf?: boolean //是否只渲染自身，不渲染properties\n  mapProperties?: (schema: Schema, name: string) => Schema //schema properties映射器，主要用于改写schema\n  filterProperties?: (schema: Schema, name: string) => boolean //schema properties过滤器，被过滤掉的schema节点不会被渲染\n}\n\ntype RecursionField = React.FC<React.PropsWithChildren<IRecursionFieldProps>>\n```\n\n## 用例\n\n### 简单递归\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField, RecursionField } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nconst Custom = (props) => {\n  return <RecursionField schema={props.schema} onlyRenderProperties />\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    Custom,\n    Input,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Object\n        name=\"custom\"\n        x-component=\"Custom\"\n        x-component-props={{\n          schema: {\n            type: 'object',\n            properties: {\n              input: {\n                type: 'string',\n                'x-component': 'Input',\n              },\n            },\n          },\n        }}\n      />\n    </SchemaField>\n  </FormProvider>\n)\n```\n\n我们可以从组件属性中读取独立的 schema 对象，传给 RecursionField 渲染\n\n### 自增列表递归\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  createSchemaField,\n  RecursionField,\n  useField,\n  useFieldSchema,\n  observer,\n} from '@formily/react'\nimport { Input, Space, Button } from 'antd'\n\nconst form = createForm()\n\nconst ArrayItems = observer((props) => {\n  const field = useField()\n  const schema = useFieldSchema()\n  return (\n    <div>\n      {props.value?.map((item, index) => {\n        return (\n          <div key={index} style={{ marginBottom: 10 }}>\n            <Space>\n              <RecursionField schema={schema.items} name={index} />\n              <Button\n                onClick={() => {\n                  field.remove(index)\n                }}\n              >\n                Remove\n              </Button>\n            </Space>\n          </div>\n        )\n      })}\n      <Button\n        onClick={() => {\n          field.push({})\n        }}\n      >\n        Add\n      </Button>\n    </div>\n  )\n})\n\nconst SchemaField = createSchemaField({\n  components: {\n    ArrayItems,\n    Input,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Array name=\"custom\" x-component=\"ArrayItems\">\n        <SchemaField.Object>\n          <SchemaField.String name=\"input\" x-component=\"Input\" />\n        </SchemaField.Object>\n      </SchemaField.Array>\n    </SchemaField>\n  </FormProvider>\n)\n```\n\n使用[useField](/api/hooks/useField)和[useFieldSchema](/api/shared/use-field-schema)来获取当前字段上下文中的字段实例和字段 schema\n"
  },
  {
    "path": "packages/react/docs/api/components/SchemaField.md",
    "content": "---\norder: 4\n---\n\n# SchemaField\n\n## Description\n\nThe SchemaField component is a component specially used to parse [JSON-Schema](/api/shared/schema) dynamically rendering forms.\nWhen using the SchemaField component, you need to create a SchemaField component through the createSchemaField factory function.\n\n## Signature\n\n```ts\n//SchemaField component and its static properties\ntype ComposeSchemaField = React.FC<\n  React.PropsWithChildren<ISchemaFieldProps>\n> & {\n  Markup: React.FC<React.PropsWithChildren<ISchema>>\n  String: React.FC<React.PropsWithChildren<Omit<ISchema, 'type'>>>\n  Object: React.FC<React.PropsWithChildren<Omit<ISchema, 'type'>>>\n  Array: React.FC<React.PropsWithChildren<Omit<ISchema, 'type'>>>\n  Date: React.FC<React.PropsWithChildren<Omit<ISchema, 'type'>>>\n  DateTime: React.FC<React.PropsWithChildren<Omit<ISchema, 'type'>>>\n  Boolean: React.FC<React.PropsWithChildren<Omit<ISchema, 'type'>>>\n  Number: React.FC<React.PropsWithChildren<Omit<ISchema, 'type'>>>\n  Void: React.FC<React.PropsWithChildren<Omit<ISchema, 'type'>>>\n}\n\n//Factory function parameter attributes\ninterface ISchemaFieldFactoryProps {\n  components?: {\n    [key: string]: React.FC //Component list\n  }\n  scope?: any //Global scope, used to implement protocol expression variable injection\n}\n\n//SchemaField attribute\ninterface ISchemaFieldProps extends IFieldFactoryProps {\n  schema?: ISchema //Field schema\n  scope?: any //Protocol expression scope\n  name?: string //Field name\n  components?: {\n    [key: string]: React.FC //Partial component list, note: the components passed here cannot enjoy smart prompts\n  }\n}\n\n//Factory function\ninterface createSchemaField {\n  (props: ISchemaFieldFactoryProps): ComposeSchemaField\n}\n```\n\nIFieldFactoryProps reference [IFieldFactoryProps](https://core.formilyjs.org/api/models/form#ifieldfactoryprops)\n\nISchema Reference [ISchema](/api/shared/schema#ischema)\n\n## Markup Schema Use Case\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Input, Select } from 'antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField\n      components={{\n        Select,\n      }}\n    >\n      <SchemaField.String name=\"input\" x-component=\"Input\" />\n      <SchemaField.String\n        name=\"select\"\n        x-component=\"Select\"\n        x-component-props={{\n          style: {\n            width: 200,\n            marginTop: 20,\n          },\n        }}\n      />\n    </SchemaField>\n  </FormProvider>\n)\n```\n\n## JSON Schema Use Case\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Input, Select } from 'antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField\n      components={{\n        Select,\n      }}\n      schema={{\n        type: 'object',\n        properties: {\n          input: {\n            type: 'string',\n            'x-component': 'Input',\n          },\n          select: {\n            type: 'string',\n            'x-component': 'Select',\n            'x-component-props': {\n              style: {\n                width: 200,\n                marginTop: 20,\n              },\n            },\n          },\n        },\n      }}\n    ></SchemaField>\n  </FormProvider>\n)\n```\n\n## JSON Schema ReactNode Prop Use Case （x-slot-node）\n\nReference [Slot](https://react.formilyjs.org/api/shared/schema#slot)\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Input, Tag } from 'antd'\nimport { CheckCircleTwoTone, CloseCircleOutlined } from '@ant-design/icons'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    CheckCircleTwoTone,\n    CloseCircleOutlined,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField\n      components={{\n        Tag,\n      }}\n      schema={{\n        type: 'object',\n        properties: {\n          tag: {\n            'x-slot-node': {\n              target: 'input.x-component-props.prefix',\n            },\n            'x-component': 'Tag',\n            'x-component-props': {\n              children: 'www.',\n            },\n          },\n          tag2: {\n            'x-slot-node': {\n              target: 'input.x-component-props.suffix',\n            },\n            'x-component': 'Tag',\n            'x-component-props': {\n              children: '.com',\n            },\n          },\n          icon: {\n            'x-slot-node': {\n              target: 'input.x-component-props.addonAfter',\n            },\n            'x-component':\n              '{{$form.values.input?.length > 5 ? \"CheckCircleTwoTone\" : \"CloseCircleOutlined\"}}',\n          },\n          input: {\n            type: 'string',\n            'x-component': 'Input',\n            'x-component-props': {},\n          },\n        },\n      }}\n    ></SchemaField>\n  </FormProvider>\n)\n```\n\n## JSON Schema Render Prop Use Case （x-slot-node & isRenderProp）\n\nReference [Slot](https://react.formilyjs.org/api/shared/schema#slot)\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Rate } from 'antd'\nimport { DollarOutlined } from '@ant-design/icons'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    DollarOutlined,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField\n      components={{\n        Rate,\n      }}\n      schema={{\n        type: 'object',\n        properties: {\n          icon: {\n            'x-slot-node': {\n              target: 'rate.x-component-props.character',\n              isRenderProp: true,\n            },\n            'x-component': 'DollarOutlined',\n            'x-component-props': {\n              rotate: '{{ $slotArgs[0].value * 45 }}',\n              style: {\n                fontSize: '50px',\n              },\n            },\n          },\n          rate: {\n            'x-component': 'Rate',\n            'x-component-props': {\n              defaultValue: 3,\n            },\n          },\n        },\n      }}\n    ></SchemaField>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/components/SchemaField.zh-CN.md",
    "content": "---\norder: 4\n---\n\n# SchemaField\n\n## 描述\n\nSchemaField 组件是专门用于解析[JSON-Schema](/api/shared/schema)动态渲染表单的组件。\n在使用 SchemaField 组件的时候，需要通过 createSchemaField 工厂函数创建一个 SchemaField 组件。\n\n## 签名\n\n```ts\n//SchemaField组件与其静态属性\ntype ComposeSchemaField = React.FC<\n  React.PropsWithChildren<ISchemaFieldProps>\n> & {\n  Markup: React.FC<React.PropsWithChildren<ISchema>>\n  String: React.FC<React.PropsWithChildren<Omit<ISchema, 'type'>>>\n  Object: React.FC<React.PropsWithChildren<Omit<ISchema, 'type'>>>\n  Array: React.FC<React.PropsWithChildren<Omit<ISchema, 'type'>>>\n  Date: React.FC<React.PropsWithChildren<Omit<ISchema, 'type'>>>\n  DateTime: React.FC<React.PropsWithChildren<Omit<ISchema, 'type'>>>\n  Boolean: React.FC<React.PropsWithChildren<Omit<ISchema, 'type'>>>\n  Number: React.FC<React.PropsWithChildren<Omit<ISchema, 'type'>>>\n  Void: React.FC<React.PropsWithChildren<Omit<ISchema, 'type'>>>\n}\n\n//工厂函数参数属性\ninterface ISchemaFieldFactoryProps {\n  components?: {\n    [key: string]: React.FC //组件列表\n  }\n  scope?: any //全局作用域，用于实现协议表达式变量注入\n}\n\n//SchemaField属性\ninterface ISchemaFieldProps extends IFieldFactoryProps {\n  schema?: ISchema //字段schema\n  scope?: any //协议表达式作用域\n  name?: string //字段名称\n  components?: {\n    [key: string]: React.FC //局部组件列表，注意：这里传的组件是享受不到智能提示的\n  }\n}\n\n//工厂函数\ninterface createSchemaField {\n  (props: ISchemaFieldFactoryProps): ComposeSchemaField\n}\n```\n\nIFieldFactoryProps 参考 [IFieldFactoryProps](https://core.formilyjs.org/zh-CN/api/models/form#ifieldfactoryprops)\n\nISchema 参考 [ISchema](/api/shared/schema#ischema)\n\n## Markup Schema 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Input, Select } from 'antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField\n      components={{\n        Select,\n      }}\n    >\n      <SchemaField.String name=\"input\" x-component=\"Input\" />\n      <SchemaField.String\n        name=\"select\"\n        x-component=\"Select\"\n        x-component-props={{\n          style: {\n            width: 200,\n            marginTop: 20,\n          },\n        }}\n      />\n    </SchemaField>\n  </FormProvider>\n)\n```\n\n## JSON Schema 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Input, Select } from 'antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField\n      components={{\n        Select,\n      }}\n      schema={{\n        type: 'object',\n        properties: {\n          input: {\n            type: 'string',\n            'x-component': 'Input',\n          },\n          select: {\n            type: 'string',\n            'x-component': 'Select',\n            'x-component-props': {\n              style: {\n                width: 200,\n                marginTop: 20,\n              },\n            },\n          },\n        },\n      }}\n    ></SchemaField>\n  </FormProvider>\n)\n```\n\n## JSON Schema ReactNode Prop 用例 （x-slot-node）\n\n参考[Slot](https://react.formilyjs.org/zh-CN/api/shared/schema#slot)\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Input, Tag } from 'antd'\nimport { CheckCircleTwoTone } from '@ant-design/icons'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n    CheckCircleTwoTone,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField\n      components={{\n        Tag,\n      }}\n      schema={{\n        type: 'object',\n        properties: {\n          tag: {\n            'x-slot-node': {\n              target: 'input.x-component-props.prefix',\n            },\n            'x-component': 'Tag',\n            'x-component-props': {\n              children: 'www.',\n            },\n          },\n          tag2: {\n            'x-slot-node': {\n              target: 'input.x-component-props.suffix',\n            },\n            'x-component': 'Tag',\n            'x-component-props': {\n              children: '.com',\n            },\n          },\n          icon: {\n            'x-slot-node': {\n              target: 'input.x-component-props.addonAfter',\n            },\n            'x-component':\n              '{{$form.values.input?.length > 5 ? \"CheckCircleTwoTone\" : \"CloseCircleOutlined\"}}',\n          },\n          input: {\n            type: 'string',\n            'x-component': 'Input',\n            'x-component-props': {},\n          },\n        },\n      }}\n    ></SchemaField>\n  </FormProvider>\n)\n```\n\n## JSON Schema Render Prop 用例 （x-slot-node & isRenderProp）\n\n参考[Slot](https://react.formilyjs.org/zh-CN/api/shared/schema#slot)\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Rate } from 'antd'\nimport { DollarOutlined } from '@ant-design/icons'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    DollarOutlined,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField\n      components={{\n        Rate,\n      }}\n      schema={{\n        type: 'object',\n        properties: {\n          icon: {\n            'x-slot-node': {\n              target: 'rate.x-component-props.character',\n              isRenderProp: true,\n            },\n            'x-component': 'DollarOutlined',\n            'x-component-props': {\n              rotate: '{{ $slotArgs[0].value * 45 }}',\n              style: {\n                fontSize: '50px',\n              },\n            },\n          },\n          rate: {\n            'x-component': 'Rate',\n            'x-component-props': {\n              defaultValue: 3,\n            },\n          },\n        },\n      }}\n    ></SchemaField>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/components/VoidField.md",
    "content": "---\norder: 3\n---\n\n# VoidField\n\n## Description\n\nAs @formily/core's [createVoidField](https://core.formilyjs.org/api/models/form#createvoidfield) React implementation, it is a bridge component specifically used to bind ViewModel and virtual layout controls. Used to control the display and hide of data type fields, interactive mode, etc., VoidField component properties refer to [IVoidFieldFactoryProps](https://core.formilyjs.org/api/models/form#ivoidfieldfactoryprops)\n\n<Alert>\nWhen we use the VoidField component, we must remember to pass the name attribute.\n</Alert>\n\n## Signature\n\n```ts\ntype VoidField = React.FC<React.PropsWithChildren<IVoidFieldFactoryProps>>\n```\n\n## Example\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, Field, VoidField } from '@formily/react'\nimport { Input, Button, Space } from 'antd'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Space>\n      <VoidField name=\"layout\">\n        <Field name=\"input\" component={[Input]} />\n      </VoidField>\n      <FormConsumer>\n        {() => (\n          <Space>\n            <Button\n              onClick={() => {\n                form\n                  .query('layout')\n                  .take()\n                  .setState((state) => {\n                    state.visible = !state.visible\n                  })\n              }}\n            >\n              {form.query('layout').get('visible') ? 'Hide' : 'Show'}\n            </Button>\n            <div>{JSON.stringify(form.values, null, 2)}</div>\n          </Space>\n        )}\n      </FormConsumer>\n    </Space>\n  </FormProvider>\n)\n```\n\nThis example demonstrates how to use VoidField to control the display and hiding of child nodes. Observe that when the VoidField is hidden, the data of the child nodes will be cleared at the same time, because visible is false, which means display is none. This kind of hiding does not retain the field value.\n\nBut when it is displayed again, the scene will be restored again. This is the internal feature of Formily Core, which supports the ability to completely restore the scene.\n"
  },
  {
    "path": "packages/react/docs/api/components/VoidField.zh-CN.md",
    "content": "---\norder: 3\n---\n\n# VoidField\n\n## 描述\n\n作为@formily/core 的 [createVoidField](https://core.formilyjs.org/zh-CN/api/models/form#createvoidfield) React 实现，它是专门用于将 ViewModel 与虚拟布局控件做绑定的桥接组件，可以用来控制数据型字段的显示隐藏，交互模式等，VoidField 组件属性参考[IVoidFieldFactoryProps](https://core.formilyjs.org/zh-CN/api/models/form#ivoidfieldfactoryprops)\n\n<Alert>\n我们在使用 VoidField 组件的时候，一定要记得传name属性。\n</Alert>\n\n## 签名\n\n```ts\ntype VoidField = React.FC<React.PropsWithChildren<IVoidFieldFactoryProps>>\n```\n\n## 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, FormConsumer, Field, VoidField } from '@formily/react'\nimport { Input, Button, Space } from 'antd'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Space>\n      <VoidField name=\"layout\">\n        <Field name=\"input\" component={[Input]} />\n      </VoidField>\n      <FormConsumer>\n        {() => (\n          <Space>\n            <Button\n              onClick={() => {\n                form\n                  .query('layout')\n                  .take()\n                  .setState((state) => {\n                    state.visible = !state.visible\n                  })\n              }}\n            >\n              {form.query('layout').get('visible') ? 'Hide' : 'Show'}\n            </Button>\n            <div>{JSON.stringify(form.values, null, 2)}</div>\n          </Space>\n        )}\n      </FormConsumer>\n    </Space>\n  </FormProvider>\n)\n```\n\n该例子演示了如何用 VoidField 控制子节点显示隐藏，注意观察，VoidField 隐藏的时候，子节点的数据会同时被清空，因为 visible 为 false 代表 display 为 none，这种隐藏是不会保留字段值的。\n\n但是再次显示的时候，又会恢复现场，这里是 Formily Core 内部的特性，支持完全恢复现场的能力。\n"
  },
  {
    "path": "packages/react/docs/api/hooks/useExpressionScope.md",
    "content": "# useExpressionScope\n\n## Description\n\nThe expression scope is mainly read in the custom component. The sources of the expression scope are:\n\n- createSchemaField top-level delivery\n- SchemaField component attribute delivery\n- ExpressionScope/RecordScope/RecordsScope are issued inside custom components\n\n## Signature\n\n```ts\ninterface useExpressionScope {\n  (): any\n}\n```\n\n## Example\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  createSchemaField,\n  useExpressionScope,\n  RecordScope,\n} from '@formily/react'\n\nconst form = createForm()\n\nconst Custom = () => {\n  const scope = useExpressionScope()\n  return (\n    <code>\n      <pre>{JSON.stringify(scope, null, 2)}</pre>\n    </code>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    Custom,\n  },\n  scope: {\n    topScope: {\n      aa: 123,\n    },\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <RecordScope\n      getRecord={() => ({ name: 'Record Name', code: 'Record Code' })}\n      getIndex={() => 2}\n    >\n      <SchemaField scope={{ propsScope: { bb: 321 } }}>\n        <SchemaField.String name=\"custom\" x-component=\"Custom\" />\n      </SchemaField>\n    </RecordScope>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/hooks/useExpressionScope.zh-CN.md",
    "content": "# useExpressionScope\n\n## 描述\n\n主要在自定义组件中读取表达式作用域，表达式作用域的来源主要有：\n\n- createSchemaField 顶层下发\n- SchemaField 组件属性下发\n- ExpressionScope/RecordScope/RecordsScope 自定义组件内部下发\n\n## 签名\n\n```ts\ninterface useExpressionScope {\n  (): any\n}\n```\n\n## 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  createSchemaField,\n  useExpressionScope,\n  RecordScope,\n} from '@formily/react'\n\nconst form = createForm()\n\nconst Custom = () => {\n  const scope = useExpressionScope()\n  return (\n    <code>\n      <pre>{JSON.stringify(scope, null, 2)}</pre>\n    </code>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    Custom,\n  },\n  scope: {\n    topScope: {\n      aa: 123,\n    },\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <RecordScope\n      getRecord={() => ({ name: 'Record Name', code: 'Record Code' })}\n      getIndex={() => 2}\n    >\n      <SchemaField scope={{ propsScope: { bb: 321 } }}>\n        <SchemaField.String name=\"custom\" x-component=\"Custom\" />\n      </SchemaField>\n    </RecordScope>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/hooks/useField.md",
    "content": "# useField\n\n## Description\n\nMainly used in custom components to read current field properties, manipulate field status, etc. It can be used in the subtree of all Field components. Note that the one you get is [GeneralField](https://core.formilyjs.org/ api/models/field#generalfield), if you need to process different types of fields, please use [Type Checker](https://core.formilyjs.org/api/entry/form-checker)\n\n<Alert>\nNote: If you want to use useField in a custom component and respond to changes in the field model, you need to wrap the observer for the custom component\n</Alert>\n\n## Signature\n\n```ts\ninterface useField {\n  (): Field\n}\n```\n\n## Example\n\n```tsx\nimport React, { useMemo } from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  FormConsumer,\n  Field,\n  useField,\n  observer,\n} from '@formily/react'\nimport { Input, Form, Button } from 'antd'\n\n// FormItem UI component\nconst FormItem = observer(({ children }) => {\n  const field = useField()\n  return (\n    <Form.Item\n      label={field.title}\n      help={field.selfErrors?.length ? field.selfErrors : undefined}\n      extra={field.description}\n      validateStatus={field.validateStatus}\n    >\n      {children}\n    </Form.Item>\n  )\n})\n\nexport default () => {\n  const form = useMemo(() => createForm({ validateFirst: true }))\n  return (\n    <FormProvider form={form}>\n      <Form layout=\"vertical\">\n        <Field\n          name=\"name\"\n          title=\"Name\"\n          required\n          decorator={[FormItem]}\n          component={[Input, { placeholder: 'Please Input' }]}\n        />\n        <code>\n          <pre>\n            <FormConsumer>\n              {(form) => JSON.stringify(form.values, null, 2)}\n            </FormConsumer>\n          </pre>\n        </code>\n        <Button\n          type=\"primary\"\n          onClick={() => {\n            form.submit(console.log)\n          }}\n        >\n          Submit\n        </Button>\n      </Form>\n    </FormProvider>\n  )\n}\n```\n"
  },
  {
    "path": "packages/react/docs/api/hooks/useField.zh-CN.md",
    "content": "# useField\n\n## 描述\n\n主要用在自定义组件内读取当前字段属性，操作字段状态等，在所有 Field 组件的子树内都能使用，注意，拿到的是[GeneralField](https://core.formilyjs.org/zh-CN/api/models/field#generalfield)，如果需要对不同类型的字段做处理，请使用[Type Checker](https://core.formilyjs.org/zh-CN/api/entry/form-checker)\n\n<Alert>\n注意：如果要在自定义组件内使用useField，并响应字段模型变化，那需要给自定义组件包装observer\n</Alert>\n\n## 签名\n\n```ts\ninterface useField {\n  (): Field\n}\n```\n\n## 用例\n\n```tsx\nimport React, { useMemo } from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  FormConsumer,\n  Field,\n  useField,\n  observer,\n} from '@formily/react'\nimport { Input, Form, Button } from 'antd'\n\n// FormItem UI组件\nconst FormItem = observer(({ children }) => {\n  const field = useField()\n  return (\n    <Form.Item\n      label={field.title}\n      help={field.selfErrors?.length ? field.selfErrors : undefined}\n      extra={field.description}\n      validateStatus={field.validateStatus}\n    >\n      {children}\n    </Form.Item>\n  )\n})\n\nexport default () => {\n  const form = useMemo(() => createForm({ validateFirst: true }))\n  return (\n    <FormProvider form={form}>\n      <Form layout=\"vertical\">\n        <Field\n          name=\"name\"\n          title=\"Name\"\n          required\n          decorator={[FormItem]}\n          component={[Input, { placeholder: 'Please Input' }]}\n        />\n        <code>\n          <pre>\n            <FormConsumer>\n              {(form) => JSON.stringify(form.values, null, 2)}\n            </FormConsumer>\n          </pre>\n        </code>\n        <Button\n          type=\"primary\"\n          onClick={() => {\n            form.submit(console.log)\n          }}\n        >\n          Submit\n        </Button>\n      </Form>\n    </FormProvider>\n  )\n}\n```\n"
  },
  {
    "path": "packages/react/docs/api/hooks/useFieldSchema.md",
    "content": "# useFieldSchema\n\n## Description\n\nMainly read the Schema information of the current field in the custom component, this hook can only be used in the subtree of SchemaField or RecursionField\n\n## Signature\n\n```ts\ninterface useFieldSchema {\n  (): Schema\n}\n```\n\nSchema Reference [Schema](/api/shared/schema)\n\n## Example\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField, useFieldSchema } from '@formily/react'\n\nconst form = createForm()\n\nconst Custom = () => {\n  const schema = useFieldSchema()\n  return (\n    <code>\n      <pre>{JSON.stringify(schema.toJSON(), null, 2)}</pre>\n    </code>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    Custom,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Object\n        name=\"custom\"\n        x-component=\"Custom\"\n        x-component-props={{\n          schema: {\n            type: 'object',\n            properties: {\n              input: {\n                type: 'string',\n                'x-component': 'Custom',\n              },\n            },\n          },\n        }}\n      />\n    </SchemaField>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/hooks/useFieldSchema.zh-CN.md",
    "content": "# useFieldSchema\n\n## 描述\n\n主要在自定义组件中读取当前字段的 Schema 信息，该 hook 只能用在 SchemaField 或者 RecursionField 的子树中使用\n\n## 签名\n\n```ts\ninterface useFieldSchema {\n  (): Schema\n}\n```\n\nSchema 参考[Schema](/api/shared/schema)\n\n## 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField, useFieldSchema } from '@formily/react'\n\nconst form = createForm()\n\nconst Custom = () => {\n  const schema = useFieldSchema()\n  return (\n    <code>\n      <pre>{JSON.stringify(schema.toJSON(), null, 2)}</pre>\n    </code>\n  )\n}\n\nconst SchemaField = createSchemaField({\n  components: {\n    Custom,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.Object\n        name=\"custom\"\n        x-component=\"Custom\"\n        x-component-props={{\n          schema: {\n            type: 'object',\n            properties: {\n              input: {\n                type: 'string',\n                'x-component': 'Custom',\n              },\n            },\n          },\n        }}\n      />\n    </SchemaField>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/hooks/useForm.md",
    "content": "# useForm\n\n## Description\n\nMainly read the current [Form](https://core.formilyjs.org/api/models/form) instance in the custom component to implement some side-effect dependencies, such as relying on the errors information of the Form, for Implement some more complex scenario-based components\n\n## Signature\n\n```ts\ninterface useForm {\n  (): Form\n}\n```\n\n## Example\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, useForm, observer } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nconst Custom = observer(() => {\n  const form = useForm()\n  return <div>{form.values.input}</div>\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field name=\"input\" component={[Input]} />\n    <Field name=\"custom\" component={[Custom]} />\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/hooks/useForm.zh-CN.md",
    "content": "# useForm\n\n## 描述\n\n主要在自定义组件中读取当前[Form](https://core.formilyjs.org/zh-CN/api/models/form)实例，用于实现一些副作用依赖，比如依赖 Form 的 errors 信息之类的，用于实现一些较为复杂的场景化组件\n\n## 签名\n\n```ts\ninterface useForm {\n  (): Form\n}\n```\n\n## 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, useForm, observer } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nconst Custom = observer(() => {\n  const form = useForm()\n  return <div>{form.values.input}</div>\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field name=\"input\" component={[Input]} />\n    <Field name=\"custom\" component={[Custom]} />\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/hooks/useFormEffects.md",
    "content": "# useFormEffects\n\n## Description\n\nMainly inject side-effect logic into the current [Form](https://core.formilyjs.org/api/models/form) instance in the custom component to implement some more complex scenario-based components\n\n<Alert>\nNote: It is invalid to monitor onFormInit in the effects function, because the Form has already been initialized when rendering to the current component, and the effects function will only be executed once, so if you want to rely on the data of useState, please use the reference data of useRef.\n</Alert>\n\n## Signature\n\n```ts\ninterface useFormEffects {\n  (form: Form): void\n}\n```\n\n## Example\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { FormProvider, Field, useFormEffects } from '@formily/react'\nimport { Input, Form } from 'antd'\n\nconst form = createForm({\n  effects() {\n    onFieldReact('custom.aa', (field) => {\n      field.value = field.query('input').get('value')\n    })\n  },\n})\n\nconst Custom = () => {\n  useFormEffects(() => {\n    onFieldReact('custom.bb', (field) => {\n      field.value = field.query('.aa').get('value')\n    })\n  })\n  return (\n    <div>\n      <Field name=\"aa\" decorator={[Form.Item]} component={[Input]} />\n      <Field name=\"bb\" decorator={[Form.Item]} component={[Input]} />\n    </div>\n  )\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field name=\"input\" decorator={[Form.Item]} component={[Input]} />\n    <Field name=\"custom\" decorator={[Form.Item]} component={[Custom]} />\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/hooks/useFormEffects.zh-CN.md",
    "content": "# useFormEffects\n\n## 描述\n\n主要在自定义组件中往当前[Form](https://core.formilyjs.org/zh-CN/api/models/form)实例注入副作用逻辑，用于实现一些较为复杂的场景化组件\n\n<Alert>\n注意：在effects函数内监听onFormInit是无效的，因为渲染到当前组件，Form早已初始化，同时effects函数是只会执行一次，所以想要依赖useState的数据，请使用useRef的引用数据\n</Alert>\n\n## 签名\n\n```ts\ninterface useFormEffects {\n  (form: Form): void\n}\n```\n\n## 用例\n\n```tsx\nimport React from 'react'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { FormProvider, Field, useFormEffects } from '@formily/react'\nimport { Input, Form } from 'antd'\n\nconst form = createForm({\n  effects() {\n    onFieldReact('custom.aa', (field) => {\n      field.value = field.query('input').get('value')\n    })\n  },\n})\n\nconst Custom = () => {\n  useFormEffects(() => {\n    onFieldReact('custom.bb', (field) => {\n      field.value = field.query('.aa').get('value')\n    })\n  })\n  return (\n    <div>\n      <Field name=\"aa\" decorator={[Form.Item]} component={[Input]} />\n      <Field name=\"bb\" decorator={[Form.Item]} component={[Input]} />\n    </div>\n  )\n}\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field name=\"input\" decorator={[Form.Item]} component={[Input]} />\n    <Field name=\"custom\" decorator={[Form.Item]} component={[Custom]} />\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/hooks/useParentForm.md",
    "content": "# useParentForm\n\n## Description\n\nUsed to read the most recent Form or ObjectField instance, which is mainly convenient for calling the submit/validate of the subform\n\n## Signature\n\n```ts\ninterface useParentForm {\n  (): Form | ObjectField\n}\n```\n\n## Example\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  ObjectField,\n  VoidField,\n  observer,\n  useParentForm,\n} from '@formily/react'\n\nconst form = createForm()\n\nconst Custom = observer(() => {\n  const form = useParentForm()\n  return <div>{form.displayName}</div>\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <ObjectField name=\"object\">\n      <Custom />\n    </ObjectField>\n    <Custom />\n    <VoidField name=\"void\">\n      <Custom />\n    </VoidField>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/hooks/useParentForm.zh-CN.md",
    "content": "# useParentForm\n\n## 描述\n\n用于读取最近的 Form 或者 ObjectField 实例，主要方便于调用子表单的 submit/validate\n\n## 签名\n\n```ts\ninterface useParentForm {\n  (): Form | ObjectField\n}\n```\n\n## 用例\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  ObjectField,\n  VoidField,\n  observer,\n  useParentForm,\n} from '@formily/react'\n\nconst form = createForm()\n\nconst Custom = observer(() => {\n  const form = useParentForm()\n  return <div>{form.displayName}</div>\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <ObjectField name=\"object\">\n      <Custom />\n    </ObjectField>\n    <Custom />\n    <VoidField name=\"void\">\n      <Custom />\n    </VoidField>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/api/shared/Schema.md",
    "content": "# Schema\n\n## Description\n\nThe core part of the @formily/react protocol driver. Schema is a general class in which users can use it by themselves. At the same time, both SchemaField and RecursionField rely on it. It has several core capabilities:\n\n- Ability to parse json-schema\n- The ability to convert json-schema to Field Model\n- The ability to compile json-schema expressions\n\nYou can export the Schema Class from @formily/react, but if you don’t want to use @formily/react, you can rely on the @formily/json-schema package alone\n\n## Constructor\n\n```ts\nclass Schema {\n  constructor(json: ISchema, parent?: ISchema)\n}\n```\n\nCreate a Schema Tree based on a piece of json schema data to ensure that each schema node contains the corresponding method\n\n## Attributes\n\n| Property             | Description                                                                     | Type                                                                               | Field Model Mapping                                                      |\n| -------------------- | ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |\n| type                 | Type                                                                            | [SchemaTypes](#schematypes)                                                        | [GeneralField](https://core.formilyjs.org/api/models/field#generalfield) |\n| title                | Title                                                                           | React.ReactNode                                                                    | `title`                                                                  |\n| description          | Description                                                                     | React.ReactNode                                                                    | `description`                                                            |\n| default              | Default value                                                                   | Any                                                                                | `initialValue`                                                           |\n| readOnly             | Is it read-only                                                                 | Boolean                                                                            | `readOnly`                                                               |\n| writeOnly            | Whether to write only                                                           | Boolean                                                                            | `editable`                                                               |\n| enum                 | Enumeration                                                                     | [SchemaEnum](#schemaenum)                                                          | `dataSource`                                                             |\n| const                | Check whether the field value is equal to the value of const                    | Any                                                                                | `validator`                                                              |\n| multipleOf           | Check whether the field value is divisible by the value of multipleOf           | Number                                                                             | `validator`                                                              |\n| maximum              | Check the maximum value (greater than)                                          | Number                                                                             | `validator`                                                              |\n| exclusiveMaximum     | Check the maximum value (greater than or equal to                               | Number                                                                             | `validator`                                                              |\n| minimum              | Validation minimum value (less than)                                            | Number                                                                             | `validator`                                                              |\n| exclusiveMinimum     | Minimum value (less than or equal to)                                           | Number                                                                             | `validator`                                                              |\n| maxLength            | Maximum length of verification                                                  | Number                                                                             | `validator`                                                              |\n| minLength            | Check minimum length                                                            | Number                                                                             | `validator`                                                              |\n| pattern              | Regular verification rules                                                      | RegExpString                                                                       | `validator`                                                              |\n| maxItems             | Maximum number of items                                                         | Number                                                                             | `validator`                                                              |\n| minItems             | Minimum number of items                                                         | Number                                                                             | `validator`                                                              |\n| uniqueItems          | Whether to verify duplicates                                                    | Boolean                                                                            | `validator`                                                              |\n| maxProperties        | Maximum number of properties                                                    | Number                                                                             | `validator`                                                              |\n| minProperties        | Minimum number of properties                                                    | Number                                                                             | `validator`                                                              |\n| required             | required                                                                        | Boolean                                                                            | `validator`                                                              |\n| format               | Regular verification format                                                     | [ValidatorFormats](https://core.formilyjs.org/api/models/field#fieldvalidator)     | `validator`                                                              |\n| properties           | Property description                                                            | [SchemaProperties](#schemaproperties)                                              | -                                                                        |\n| items                | Array description                                                               | [SchemaItems](#schemaitems)                                                        | -                                                                        |\n| additionalItems      | Additional array element description                                            | Schema                                                                             | -                                                                        |\n| patternProperties    | Schema of a certain property of the dynamic matching object                     | [SchemaProperties](#schemaproperties)                                              | -                                                                        |\n| additionalProperties | Schema of matching object additional properties                                 | Schema                                                                             | -                                                                        |\n| x-index              | UI display order                                                                | Number                                                                             | -                                                                        |\n| x-pattern            | UI interaction mode                                                             | [FieldPatternTypes](https://core.formilyjs.org/api/models/field#fieldpatterntypes) | `pattern`                                                                |\n| x-display            | UI display                                                                      | [FieldDisplayTypes](https://core.formilyjs.org/api/models/field#fielddisplaytypes) | `display`                                                                |\n| x-validator          | Field Validator                                                                 | [FieldValidator](https://core.formilyjs.org/api/models/field#fieldvalidator)       | `validator`                                                              |\n| x-decorator          | Field UI wrapper component                                                      | `String \\| React.FC`                                                               | `decorator`                                                              |\n| x-decorator-props    | Field UI wrapper component properties                                           | Any                                                                                | `decorator`                                                              |\n| x-component          | Field UI component                                                              | `String \\| React.FC`                                                               | `component`                                                              |\n| x-component-props    | Field UI component properties                                                   | Any                                                                                | `component`                                                              |\n| x-reactions          | Field linkage agreement                                                         | [SchemaReactions](#schemareactions)                                                | `reactions`                                                              |\n| x-content            | Field content, used to pass in the child nodes of a component                   | React.ReactNode                                                                    | `content`                                                                |\n| x-visible            | Field display hidden                                                            | Boolean                                                                            | `visible`                                                                |\n| x-hidden             | Field UI hidden (data retention)                                                | Boolean                                                                            | `hidden`                                                                 |\n| x-disabled           | Field disabled                                                                  | Boolean                                                                            | `disabled`                                                               |\n| x-editable           | Editable field                                                                  | Boolean                                                                            | `editable`                                                               |\n| x-read-only          | Field read-only                                                                 | Boolean                                                                            | `readOnly`                                                               |\n| x-read-pretty        | Field Reading State                                                             | Boolean                                                                            | `readPretty`                                                             |\n| definitions          | Schema predefined                                                               | [SchemaProperties](#schemaproperties)                                              | -                                                                        |\n| $ref                 | Read the Schema from the Schema predefined and merge it into the current Schema | String                                                                             | -                                                                        |\n| x-data               | Extends Data                                                                    | Object                                                                             | `data`                                                                   |\n| x-compile-omitted    | list of attributes to ignore compiled expressions                               | string[]                                                                           | `[]`                                                                     |\n| x-slot-node          | Slot node mark                                                                  | [Slot](#slot)                                                                      | -                                                                        |\n\n#### Detailed description\n\n- The component ID of x-component matches the key of the component collection passed in [createSchemaField](/api/components/schema-field#signature)\n- The component ID of x-decorator matches the key of the component collection passed in [createSchemaField](/api/components/schema-field#signature)\n- Every attribute of Schema can use string expression `{{expression}}`, expression variables can be passed in from createSchemaField or from SchemaField component\n- The predefined format of $ref specified Schema must be `#/definitions/address` this format, loading remote JSON Schema is not supported\n\n## Method\n\n### addProperty\n\n#### Description\n\nAdd attribute description\n\n#### Signature\n\n```ts\ninterface addProperty {\n  (key: string | number, schema: ISchema): Schema //Return the added Schema object\n}\n```\n\n### removeProperty\n\n#### Description\n\nRemove attribute description\n\n#### Signature\n\n```ts\ninterface removeProperty {\n  (key: string | number): Schema //Return the removed Schema object\n}\n```\n\n### setProperties\n\n#### Description\n\nOverwrite update attribute description\n\n#### Signature\n\n```ts\ninterface setProperties {\n  (properties: SchemaProperties): Schema //Return the current Schema object\n}\n```\n\nSchemaProperties Reference [SchemaProperties](#schemaproperties)\n\n### addPatternProperty\n\n#### Description\n\nAdd regular attribute description\n\n#### Signature\n\n```ts\ninterface addPatternProperty {\n  (regexp: string, schema: ISchema): Schema //Return the added Schema object\n}\n```\n\n### removePatternProperty\n\n#### Description\n\nRemove regular attribute description\n\n#### Signature\n\n```ts\ninterface removePatternProperty {\n  (regexp: string): Schema //Return the removed Schema object\n}\n```\n\n### setPatternProperties\n\n#### Description\n\nOverride update regular attribute description\n\n#### Signature\n\n```ts\ninterface setPatternProperties {\n  (properties: SchemaProperties): Schema //Return the current Schema object\n}\n```\n\nSchemaProperties Reference [SchemaProperties](#schemaproperties)\n\n### setAdditionalProperties\n\n#### Description\n\nOverwrite update extended attribute description\n\n#### Signature\n\n```ts\ninterface setAdditionalProperties {\n  (properties: ISchema): Schema //Returns the extended properties Schema object\n}\n```\n\n### setItems\n\n#### Description\n\nOverride to update the array item description\n\n#### Signature\n\n```ts\ninterface setItems {\n  (items: SchemaItems): SchemaItems //Return the updated SchemaItems object\n}\n```\n\nSchemaItems Reference [SchemaItems](#schemaitems)\n\n### setAdditionalItems\n\n#### Description\n\nOverride to update the array extension item description\n\n#### Signature\n\n```ts\ninterface setAdditionalItems {\n  (items: ISchema): Schema //Return the updated Schema object\n}\n```\n\nSchemaItems Reference [SchemaItems](#schemaitems)\n\n### mapProperties\n\n#### Description\n\nTraverse and map the properties of the current Schema, and traverse based on the x-index order\n\n#### Signature\n\n```ts\ninterface mapProperties<T> {\n  (mapper: (property: Schema, key: string | number) => T): T[]\n}\n```\n\n### mapPatternProperties\n\n#### Description\n\nTraverse and map the patternProperties attribute of the current Schema, and traverse based on the x-index order\n\n#### Signature\n\n```ts\ninterface mapPatternProperties<T> {\n  (mapper: (property: Schema, key: string | number) => T): T[]\n}\n```\n\n### reduceProperties\n\n#### Description\n\nreduce the properties of the current Schema, and it will be traversed based on the x-index order\n\n#### Signature\n\n```ts\ninterface reduceProperties<T> {\n  (\n    reducer: (value: T, property: Schema, key: string | number) => T,\n    initialValue?: T\n  ): T\n}\n```\n\n### reducePatternProperties\n\n#### Description\n\nreduce the patternProperties attribute of the current Schema, and it will be traversed based on the x-index order\n\n#### Signature\n\n```ts\ninterface reducePatternProperties<T> {\n  (\n    reducer: (value: T, property: Schema, key: string | number) => T,\n    initialValue?: T\n  ): T\n}\n```\n\n### compile\n\n#### Description\n\nDeeply recurse the expression fragments in the current Schema object, compile the expression, and return the Schema. We can pass in the scope object, and then consume the scope variable in the expression\n\nExpression fragment convention: a string ending with `{{`beginning with `}}` represents an expression fragment\n\n#### Signature\n\n```ts\ninterface compile {\n  (scope: any): Schema\n}\n```\n\n### fromJSON\n\n#### Description\n\nConvert ordinary json data into Schema objects\n\n#### Signature\n\n```ts\ninterface fromJSON {\n  (json: ISchema): Schema\n}\n```\n\n### toJSON\n\n#### Description\n\nConvert the current Schema object into ordinary json data\n\n#### Signature\n\n```ts\ninterface toJSON {\n  (): ISchema\n}\n```\n\n### toFieldProps\n\n#### Description\n\nConvert the current Schema object into a Formily field model attribute, refer to the mapping relationship [attribute](#attributes)\n\n#### Signature\n\n```ts\nimport { IFieldFactoryProps } from '@formily/core'\n\ninterface toFieldProps {\n  (): IFieldFactoryProps\n}\n```\n\nIFieldFactoryProps reference [IFieldFactoryProps](https://core.formilyjs.org/api/models/form#ifieldfactoryprops)\n\n## Static method\n\n### getOrderProperties\n\n#### Description\n\nGet the sorted properties from the Schema\n\n#### Signature\n\n```ts\ninterface getOrderProperties {\n  (schema: ISchema = {}, propertiesName: keyof ISchema = 'properties'): ISchema\n}\n```\n\n### compile\n\n#### Description\n\nIn-depth traversal of expression fragments in any object, expression fragment convention: a string ending with `{{`beginning`}}` represents an expression fragment\n\n#### Signature\n\n```ts\ninterface compile {\n  (target: any, scope: any): any\n}\n```\n\n### shallowCompile\n\n#### Description\n\nShallow traversal of expression fragments in any object, expression fragment convention: a string ending with `{{`beginning with `}}` represents an expression fragment\n\n#### Signature\n\n```ts\ninterface shallowCompile {\n  (target: any, scope: any): any\n}\n```\n\n### silent\n\n#### Description\n\nWhether to compile silently, if it is, there will be no reminder if the expression error is reported\n\n#### Signature\n\n```ts\ninterface silent {\n  (value?: boolean): void\n}\n```\n\n### isSchemaInstance\n\n#### Description\n\nDetermine whether an object is an instance of Schema Class\n\n#### Signature\n\n```ts\ninterface isSchemaInstance {\n  (target: any): target is Schema\n}\n```\n\n### registerCompiler\n\n#### Description\n\nRegister the expression compiler\n\n#### Signature\n\n```ts\ninterface registerCompiler {\n  (compiler: (expression: string, scope: any) => any): void\n}\n```\n\n### registerPatches\n\n#### Description\n\nRegister Schema patch to facilitate compatibility of different versions of Schema protocol\n\n#### Signature\n\n```ts\ntype SchemaPatch = (schema: ISchema) => ISchema\n\ninterface registerPatches {\n  (...args: SchemaPatch[]): void\n}\n```\n\n### registerVoidComponents\n\n#### Description\n\nMark the field component to indicate that the component is a virtual component and is compatible with formily1.x\n\n#### Signature\n\n```ts\ninterface registerVoidComponents {\n  (components: string[]): void\n}\n```\n\n#### Example\n\n```ts\nimport { Schema } from '@formily/react'\n\nSchema.registerVoidComponents(['card', 'tab', 'step'])\n```\n\n<Alert type=\"warning\">\n  Note that this api needs to be used with <code>enablePolyfills(['1.0'])</code>\n</Alert>\n\n### registerTypeDefaultComponents\n\n#### Description\n\nIdentify the default component type for the Schema type\n\n#### Signature\n\n```ts\ninterface registerTypeDefaultComponents {\n  (maps: Record<string, string>): void\n}\n```\n\n#### Example\n\n```ts\nimport { Schema } from '@formily/react'\n\nSchema.registerTypeDefaultComponents({\n  string: 'Input',\n  number: 'NumberPicker',\n  array: 'ArrayTable',\n})\n```\n\n<Alert type=\"warning\">\n  Note that this api needs to be used with <code>enablePolyfills(['1.0'])</code>\n</Alert>\n\n### registerPolyfills\n\n#### Description\n\nRegistration agreement compatible gasket\n\n#### Signature\n\n```ts\ntype SchemaPatch = (schema: ISchema) => ISchema\n\ninterface registerPolyfills {\n  (version: string, patch: SchemaPatch): void\n}\n```\n\n#### Example\n\n```ts\nimport { Schema } from '@formily/react'\n\nSchema.registerPolyfills('1.0', (schema) => {\n  schema['x-decorator'] = 'FormItem'\n  return schema\n})\n```\n\n### enablePolyfills\n\n#### Description\n\nTurn on the protocol gasket, the 1.0 version protocol compatible gasket is built in by default, and the main compatibility features are:\n\n- x-decorator does not declare, it is automatically used as FormItem\n- x-linkages converted to x-reactions\n- x-props is automatically converted to x-decorator-props\n- x-rules converted to x-validator\n- convert editable to x-editable\n- Convert visible to x-visible\n- x-component is automatically converted to VoidField for card/block/grid-row/grid-col/grid/layout/step/tab/text-box,\n\n#### Signature\n\n```ts\ninterface enablePolyfills {\n  (versions: string[]): void\n}\n```\n\n#### Example\n\n```ts\nimport { Schema } from '@formily/react'\n\nSchema.enablePolyfills(['1.0'])\n```\n\n## Types of\n\n### ISchema\n\n#### Description\n\nISchema is a normal JSON data, and at the same time it is JSON data following the Schema [Attribute](#attributes) specification\n\n### SchemaTypes\n\n#### Description\n\nSchema description type\n\n#### Signature\n\n```ts\ntype SchemaTypes =\n  | 'string'\n  | 'object'\n  | 'array'\n  | 'number'\n  | 'boolean'\n  | 'void'\n  | 'date'\n  | 'datetime'\n  | (string & {})\n```\n\n### SchemaProperties\n\n#### Description\n\nSchema attribute description\n\n#### Signature\n\n```ts\ntype SchemaProperties = Record<string, ISchema>\n```\n\n### SchemaItems\n\n#### Description\n\nSchema array item description\n\n#### Signature\n\n```ts\ntype SchemaItems = ISchema | ISchema[]\n```\n\n### SchemaEnum\n\n#### Description\n\nSchema enum\n\n#### Signature\n\n```ts\ntype SchemaEnum<Message> = Array<\n  | string\n  | number\n  | { label: Message; value: any; [key: string]: any }\n  | { key: any; title: Message; [key: string]: any }\n>\n```\n\n### SchemaReactions\n\n#### Description\n\nSchema linkage protocol, if the reaction object contains target, it represents active linkage mode, otherwise it represents passive linkage mode  \nIf you want to achieve more complex linkage, you can pass in the reaction responder function through the scope for processing  \nFormPathPattern path syntax documentation is [here](https://core.formilyjs.org/api/entry/form-path#formpathpattern)\n\n#### Signature\n\n```ts\nimport { IGeneralFieldState } from '@formily/core'\n\ntype SchemaReactionEffect =\n  | 'onFieldInit'\n  | 'onFieldMount'\n  | 'onFieldUnmount'\n  | 'onFieldValueChange'\n  | 'onFieldInputValueChange'\n  | 'onFieldInitialValueChange'\n  | 'onFieldValidateStart'\n  | 'onFieldValidateEnd'\n  | 'onFieldValidateFailed'\n  | 'onFieldValidateSuccess'\n\ntype SchemaReaction<Field = any> =\n  | {\n      dependencies?: //The list of dependent field paths can only describe dependencies in dot paths, and supports relative paths\n      | Array<\n            | string //If it is an array contains string format, then it is also an array format when reading\n            | {\n                //If it is an array contains object format, then it is an object format when reading, but the name field is equivalent to an alias\n                name?: string\n                type?: string\n                source?: string\n                property?: string\n              }\n          >\n        | Record<string, string> //If it is an object format, It is also an object format when reading, but the key for object is equivalent to an alias\n      when?: string | boolean //Linkage condition\n      target?: string //The field path to be operated, supports FormPathPattern path syntax, note: relative path is not supported! !\n      effects?: SchemaReactionEffect[] //Independent life cycle hook in active mode\n      fulfill?: {\n        //To meet the conditions\n        state?: IGeneralFieldState //Update state\n        schema?: ISchema //Update Schema\n        run?: string //Execute statement\n      }\n      otherwise?: {\n        //Does not meet the conditions\n        state?: IGeneralFieldState //Update state\n        schema?: ISchema //Update Schema\n        run?: string //Execute statement\n      }\n    }\n  | ((field: Field) => void) //Can be complex linkage\n\ntype SchemaReactions<Field = any> =\n  | SchemaReaction<Field>\n  | SchemaReaction<Field>[]\n```\n\n#### Example\n\n**Active linkage**\n\nWriting method one, standard initiative linkage\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"target\": \"target\",\n        \"when\": \"{{$self.value === '123'}}\",\n        \"fulfill\": {\n          \"state\": {\n            \"visible\": false\n          }\n        },\n        \"otherwise\": {\n          \"state\": {\n            \"visible\": true\n          }\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\nWriting method two, local expression distribution linkage\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"target\": \"target\",\n        \"fulfill\": {\n          \"state\": {\n            \"visible\": \"{{$self.value === '123'}}\" //Any level of attributes supports expressions\n          }\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\nWriting method three, based on Schema protocol linkage\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"target\": \"target\",\n        \"fulfill\": {\n          \"schema\": {\n            \"x-visible\": \"{{$self.value === '123'}}\" //Any level of attributes supports expressions\n          }\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\nWriting method four, based on run statement linkage\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"fulfill\": {\n          \"run\": \"$form.setFieldState('target',state=>{state.visible = $self.value === '123'})\"\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\nWriting method five, based on the linkage of life cycle hooks\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"target\": \"target\",\n        \"effects\": [\"onFieldInputValueChange\"],\n        \"fulfill\": {\n          \"state\": {\n            \"visible\": \"{{$self.value === '123'}}\" //Any level of attributes supports expressions\n          }\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\n**Passive linkage**\n\nWriting method one, standard passive linkage\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"dependencies\": [\"source\"], //Dependency path is written by default to take value. If you rely on other attributes of the field, you can use source#modified, and use # to split to get detailed attributes\n        // \"dependencies\":{ aliasName:\"source\" }, //alias form\n        \"fulfill\": {\n          \"schema\": {\n            \"x-visible\": \"{{$deps[0] === '123'}}\" //Any level of attributes supports expressions\n          }\n        }\n      }\n    }\n  }\n}\n```\n\nWriting method two, linkage of adjacent elements\n\n```json\n{\n  \"type\": \"array\",\n  \"x-component\": \"ArrayTable\",\n  \"items\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"source\": {\n        \"type\": \"string\",\n        \"x-component\": \"Input\"\n      },\n      \"target\": {\n        \"type\": \"string\",\n        \"x-component\": \"Input\",\n        \"x-reactions\": {\n          \"dependencies\": [\".source\"],\n          \"fulfill\": {\n            \"schema\": {\n              \"x-visible\": \"{{$deps[0] === '123'}}\"\n            }\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n**Complex linkage**\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": \"{{myReaction}}\" //For externally passed functions, more complex linkages can be realized within the function\n    }\n  }\n}\n```\n\n**Component attribute linkage**\n\nWriting one, operating status\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"target\": \"target\",\n        \"fulfill\": {\n          \"state\": {\n            \"component[1].style.color\": \"{{$self.value === '123'?'red':'blue'}}\" //Any level attribute supports expressions, and the key is a support path Expression, can achieve precise manipulation of attributes\n          }\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\nWriting method two, operating the Schema protocol\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"target\": \"target\",\n        \"fulfill\": {\n          \"schema\": {\n            \"x-component-props.style.color\": \"{{$self.value === '123'?'red':'blue'}}\" //Any level of property supports expressions, and the key is supported Path expression, can achieve precise operation properties\n          }\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\n### Slot\n\n#### Description\n\nMark this node as a Slot node, which will be skipped in the normal rendering process.  \nUse `target` to specify the target property for rendering this node, which must be a sibling property at the same level.  \nYou can use `isRenderProp` to specify that this node is passed in the form of the renderProp function.  \nWhen `isRenderProp` is `true`, the renderProp function’s argument list can be accessed within the Slot through `$slotArgs`.\n\n#### Signature\n\n```ts\ntype Slot = {\n  //Slot target: Specify the target property for rendering this node, which must be a sibling property at the same level.\n  target: string // 'some-sibling-node.x-component-props.xxx' or 'some-sibling-node.x-decorator-props.xxx'\n  //whether it is a renderProp Slot\n  isRenderProp?: boolean\n}\n```\n\n#### Example\n\n**ReactNode Prop**  \nReference [SchemaField](https://react.formilyjs.org/api/components/schema-field#json-schema-reactnode-prop-use-case-x-slot-node)\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"search_icon\": {\n      \"x-slot-node\": {\n        \"target\": \"button.x-component-props.icon\" //Specify to render the search_icon node as a slot into the icon prop of the Button component.\n      },\n      \"x-component\": \"SearchOutlined\",\n      \"x-component-props\": {\n        \"data-testid\": \"icon\"\n      }\n    },\n    \"button\": {\n      \"type\": \"string\",\n      \"x-component\": \"Button\",\n      \"x-component-props\": {\n        \"data-testid\": \"button\"\n      }\n    }\n  }\n}\n```\n\n**RenderProp**  \nReference [SchemaField](https://react.formilyjs.org/api/components/schema-field#json-schema-render-prop-use-case-x-slot-node--isrenderprop)\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"dollar_icon\": {\n      \"x-slot-node\": {\n        \"target\": \"rate.x-component-props.character\", //Specify to render the dollar_icon node as a slot into the character prop of the Rate component.\n        \"isRenderProp\": true //The character prop accepts a renderProp function. Specify the Slot as a renderProp to take control of the rendering of the rating icons.\n      },\n      \"x-component\": \"DollarOutlined\",\n      \"x-component-props\": {\n        \"data-testid\": \"icon\",\n        \"rotate\": \"{{$slotArgs[0].value * 45}}\", //When isRenderProp is true, the renderProp function’s argument list can be accessed within the Slot through $slotArgs.\n        \"style\": {\n          \"fontSize\": \"50px\"\n        }\n      }\n    },\n    \"rate\": {\n      \"x-component\": \"Rate\"\n    }\n  }\n}\n```\n\n## Built-in expression scope\n\nBuilt-in expression scope is mainly used to realize various linkage relationships in expressions\n\n### $self\n\nRepresents the current field instance, can be used in ordinary attribute expressions, and can also be used in x-reactions\n\n### $values\n\nRepresents the top-level form data, which can be used in ordinary attribute expressions, and can also be used in x-reactions\n\n### $form\n\nRepresents the current Form instance, which can be used in ordinary attribute expressions, and can also be used in x-reactions\n\n### $observable\n\nIt is used to create reactive objects in the same way as observable\n\n### $memo\n\nUsed to create persistent reference data in the same way as autorun.memo\n\n### $effect\n\nThe timing of the next microtask in response to autorun's first execution and the dispose in response to autorun are used in the same way as autorun.effect\n\n### $dependencies\n\nIt can only be consumed by expressions in x-reactions, corresponding to the dependencies defined by x-reactions, and the sequence of the array is the same\n\n### $deps\n\nIt can only be consumed by expressions in x-reactions, corresponding to the dependencies defined by x-reactions, and the sequence of the array is the same\n\n### $target\n\nCan only be consumed in expressions in x-reactions, representing the target field of active mode\n\n### $slotArgs\n\nCan only be consumed in slot node. When slot used as render prop, $slotArgs can access render function arguments array\n"
  },
  {
    "path": "packages/react/docs/api/shared/Schema.zh-CN.md",
    "content": "# Schema\n\n## 描述\n\n@formily/react 协议驱动最核心的部分，Schema 在其中是一个通用 Class，用户可以自行使用，同时在 SchemaField 和 RecursionField 中都有依赖它，它主要有几个核心能力：\n\n- 解析 json-schema 的能力\n- 将 json-schema 转换成 Field Model 的能力\n- 编译 json-schema 表达式的能力\n\n从@formily/react 中可以导出 Schema 这个 Class，但是如果你不希望使用@formily/react，你可以单独依赖@formily/json-schema 这个包\n\n## 构造器\n\n```ts\nclass Schema {\n  constructor(json: ISchema, parent?: ISchema)\n}\n```\n\n基于一份 json schema 数据创建一棵 Schema Tree，保证每个 schema 节点都是包含对应方法的\n\n## 属性\n\n| 属性                 | 描述                                              | 类型                                                                                     | 字段模型映射                                                                   |\n| -------------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |\n| type                 | 类型                                              | [SchemaTypes](#schematypes)                                                              | [GeneralField](https://core.formilyjs.org/zh-CN/api/models/field#generalfield) |\n| title                | 标题                                              | React.ReactNode                                                                          | `title`                                                                        |\n| description          | 描述                                              | React.ReactNode                                                                          | `description`                                                                  |\n| default              | 默认值                                            | Any                                                                                      | `initialValue`                                                                 |\n| readOnly             | 是否只读                                          | Boolean                                                                                  | `readOnly`                                                                     |\n| writeOnly            | 是否只写                                          | Boolean                                                                                  | `editable`                                                                     |\n| enum                 | 枚举                                              | [SchemaEnum](#schemaenum)                                                                | `dataSource`                                                                   |\n| const                | 校验字段值是否与 const 的值相等                   | Any                                                                                      | `validator`                                                                    |\n| multipleOf           | 校验字段值是否可被 multipleOf 的值整除            | Number                                                                                   | `validator`                                                                    |\n| maximum              | 校验最大值(大于)                                  | Number                                                                                   | `validator`                                                                    |\n| exclusiveMaximum     | 校验最大值（大于等于                              | Number                                                                                   | `validator`                                                                    |\n| minimum              | 校验最小值(小于)                                  | Number                                                                                   | `validator`                                                                    |\n| exclusiveMinimum     | 最小值（小于等于）                                | Number                                                                                   | `validator`                                                                    |\n| maxLength            | 校验最大长度                                      | Number                                                                                   | `validator`                                                                    |\n| minLength            | 校验最小长度                                      | Number                                                                                   | `validator`                                                                    |\n| pattern              | 正则校验规则                                      | RegExpString                                                                             | `validator`                                                                    |\n| maxItems             | 最大条目数                                        | Number                                                                                   | `validator`                                                                    |\n| minItems             | 最小条目数                                        | Number                                                                                   | `validator`                                                                    |\n| uniqueItems          | 是否校验重复                                      | Boolean                                                                                  | `validator`                                                                    |\n| maxProperties        | 最大属性数量                                      | Number                                                                                   | `validator`                                                                    |\n| minProperties        | 最小属性数量                                      | Number                                                                                   | `validator`                                                                    |\n| required             | 必填                                              | Boolean                                                                                  | `validator`                                                                    |\n| format               | 正则校验格式                                      | [ValidatorFormats](https://core.formilyjs.org/zh-CN/api/models/field#fieldvalidator)     | `validator`                                                                    |\n| properties           | 属性描述                                          | [SchemaProperties](#schemaproperties)                                                    | -                                                                              |\n| items                | 数组描述                                          | [SchemaItems](#schemaitems)                                                              | -                                                                              |\n| additionalItems      | 额外数组元素描述                                  | Schema                                                                                   | -                                                                              |\n| patternProperties    | 动态匹配对象的某个属性的 Schema                   | [SchemaProperties](#schemaproperties)                                                    | -                                                                              |\n| additionalProperties | 匹配对象额外属性的 Schema                         | Schema                                                                                   | -                                                                              |\n| x-index              | UI 展示顺序                                       | Number                                                                                   | -                                                                              |\n| x-pattern            | UI 交互模式                                       | [FieldPatternTypes](https://core.formilyjs.org/zh-CN/api/models/field#fieldpatterntypes) | `pattern`                                                                      |\n| x-display            | UI 展示                                           | [FieldDisplayTypes](https://core.formilyjs.org/zh-CN/api/models/field#fielddisplaytypes) | `display`                                                                      |\n| x-validator          | 字段校验器                                        | [FieldValidator](https://core.formilyjs.org/zh-CN/api/models/field#fieldvalidator)       | `validator`                                                                    |\n| x-decorator          | 字段 UI 包装器组件                                | `String \\| React.FC`                                                                     | `decorator`                                                                    |\n| x-decorator-props    | 字段 UI 包装器组件属性                            | Any                                                                                      | `decorator`                                                                    |\n| x-component          | 字段 UI 组件                                      | `String \\| React.FC`                                                                     | `component`                                                                    |\n| x-component-props    | 字段 UI 组件属性                                  | Any                                                                                      | `component`                                                                    |\n| x-reactions          | 字段联动协议                                      | [SchemaReactions](#schemareactions)                                                      | `reactions`                                                                    |\n| x-content            | 字段内容，用来传入某个组件的子节点                | React.ReactNode                                                                          | `content`                                                                      |\n| x-visible            | 字段显示隐藏                                      | Boolean                                                                                  | `visible`                                                                      |\n| x-hidden             | 字段 UI 隐藏(保留数据)                            | Boolean                                                                                  | `hidden`                                                                       |\n| x-disabled           | 字段禁用                                          | Boolean                                                                                  | `disabled`                                                                     |\n| x-editable           | 字段可编辑                                        | Boolean                                                                                  | `editable`                                                                     |\n| x-read-only          | 字段只读                                          | Boolean                                                                                  | `readOnly`                                                                     |\n| x-read-pretty        | 字段阅读态                                        | Boolean                                                                                  | `readPretty`                                                                   |\n| definitions          | Schema 预定义                                     | [SchemaProperties](#schemaproperties)                                                    | -                                                                              |\n| $ref                 | 从 Schema 预定义中读取 Schema 并合并至当前 Schema | String                                                                                   | -                                                                              |\n| x-data               | 扩展属性                                          | Object                                                                                   | `data`                                                                         |\n| x-compile-omitted    | 忽略编译表达式的属性列表                          | string[]                                                                                 | `[]`                                                                           |\n| x-slot-node          | Slot 节点标记                                     | [Slot](#slot)                                                                            | -                                                                              |\n\n#### 详细说明\n\n- x-component 的组件标识与[createSchemaField](/api/components/schema-field#签名)传入的组件集合的 Key 匹配\n- x-decorator 的组件标识与[createSchemaField](/api/components/schema-field#签名)传入的组件集合的 Key 匹配\n- Schema 的每个属性都能使用字符串表达式`{{expression}}`，表达式变量可以从 createSchemaField 中传入，也可以从 SchemaField 组件中传入\n- $ref 指定 Schema 预定义的格式必须是`#/definitions/address`这种格式，不支持加载远程 JSON Schema\n\n## 方法\n\n### addProperty\n\n#### 描述\n\n添加属性描述\n\n#### 签名\n\n```ts\ninterface addProperty {\n  (key: string | number, schema: ISchema): Schema //返回添加后的Schema对象\n}\n```\n\n### removeProperty\n\n#### 描述\n\n移除属性描述\n\n#### 签名\n\n```ts\ninterface removeProperty {\n  (key: string | number): Schema //返回被移除的Schema对象\n}\n```\n\n### setProperties\n\n#### 描述\n\n覆盖式更新属性描述\n\n#### 签名\n\n```ts\ninterface setProperties {\n  (properties: SchemaProperties): Schema //返回当前Schema对象\n}\n```\n\nSchemaProperties 参考 [SchemaProperties](#schemaproperties)\n\n### addPatternProperty\n\n#### 描述\n\n添加正则属性描述\n\n#### 签名\n\n```ts\ninterface addPatternProperty {\n  (regexp: string, schema: ISchema): Schema //返回添加后的Schema对象\n}\n```\n\n### removePatternProperty\n\n#### 描述\n\n移除正则属性描述\n\n#### 签名\n\n```ts\ninterface removePatternProperty {\n  (regexp: string): Schema //返回移除后的Schema对象\n}\n```\n\n### setPatternProperties\n\n#### 描述\n\n覆盖式更新正则属性描述\n\n#### 签名\n\n```ts\ninterface setPatternProperties {\n  (properties: SchemaProperties): Schema //返回当前Schema对象\n}\n```\n\nSchemaProperties 参考 [SchemaProperties](#schemaproperties)\n\n### setAdditionalProperties\n\n#### 描述\n\n覆盖式更新扩展属性描述\n\n#### 签名\n\n```ts\ninterface setAdditionalProperties {\n  (properties: ISchema): Schema //返回扩展属性Schema对象\n}\n```\n\n### setItems\n\n#### 描述\n\n覆盖式更新数组项描述\n\n#### 签名\n\n```ts\ninterface setItems {\n  (items: SchemaItems): SchemaItems //返回更新后的SchemaItems对象\n}\n```\n\nSchemaItems 参考 [SchemaItems](#schemaitems)\n\n### setAdditionalItems\n\n#### 描述\n\n覆盖式更新数组扩展项描述\n\n#### 签名\n\n```ts\ninterface setAdditionalItems {\n  (items: ISchema): Schema //返回更新后的Schema对象\n}\n```\n\nSchemaItems 参考 [SchemaItems](#schemaitems)\n\n### mapProperties\n\n#### 描述\n\n遍历并映射当前 Schema 的 properties 属性，同时会基于 x-index 顺序来遍历\n\n#### 签名\n\n```ts\ninterface mapProperties<T> {\n  (mapper: (property: Schema, key: string | number) => T): T[]\n}\n```\n\n### mapPatternProperties\n\n#### 描述\n\n遍历并映射当前 Schema 的 patternProperties 属性，同时会基于 x-index 顺序来遍历\n\n#### 签名\n\n```ts\ninterface mapPatternProperties<T> {\n  (mapper: (property: Schema, key: string | number) => T): T[]\n}\n```\n\n### reduceProperties\n\n#### 描述\n\nreduce 当前 Schema 的 properties 属性，同时会基于 x-index 顺序来遍历\n\n#### 签名\n\n```ts\ninterface reduceProperties<T> {\n  (\n    reducer: (value: T, property: Schema, key: string | number) => T,\n    initialValue?: T\n  ): T\n}\n```\n\n### reducePatternProperties\n\n#### 描述\n\nreduce 当前 Schema 的 patternProperties 属性，同时会基于 x-index 顺序来遍历\n\n#### 签名\n\n```ts\ninterface reducePatternProperties<T> {\n  (\n    reducer: (value: T, property: Schema, key: string | number) => T,\n    initialValue?: T\n  ): T\n}\n```\n\n### compile\n\n#### 描述\n\n深度递归当前 Schema 对象中的表达式片段，编译表达式，并返回 Schema，我们可以传入作用域对象，在表达式中即可消费作用域变量\n\n表达式片段约定：以`{{`开头`}}`结尾的字符串代表一个表达式片段\n\n#### 签名\n\n```ts\ninterface compile {\n  (scope: any): Schema\n}\n```\n\n### fromJSON\n\n#### 描述\n\n将普通 json 数据转换成 Schema 对象\n\n#### 签名\n\n```ts\ninterface fromJSON {\n  (json: ISchema): Schema\n}\n```\n\n### toJSON\n\n#### 描述\n\n将当前 Schema 对象转换成普通 json 数据\n\n#### 签名\n\n```ts\ninterface toJSON {\n  (): ISchema\n}\n```\n\n### toFieldProps\n\n#### 描述\n\n将当前 Schema 对象转换成 Formily 字段模型属性，映射关系参考 [属性](#属性)\n\n#### 签名\n\n```ts\nimport { IFieldFactoryProps } from '@formily/core'\n\ninterface toFieldProps {\n  (): IFieldFactoryProps\n}\n```\n\nIFieldFactoryProps 参考 [IFieldFactoryProps](https://core.formilyjs.org/zh-CN/api/models/form#ifieldfactoryprops)\n\n## 静态方法\n\n### getOrderProperties\n\n#### 描述\n\n从 Schema 中获取排序后的 properties\n\n#### 签名\n\n```ts\ninterface getOrderProperties {\n  (schema: ISchema = {}, propertiesName: keyof ISchema = 'properties'): ISchema\n}\n```\n\n### compile\n\n#### 描述\n\n深度遍历任意对象中的表达式片段，表达式片段约定：以`{{`开头`}}`结尾的字符串代表一个表达式片段\n\n#### 签名\n\n```ts\ninterface compile {\n  (target: any, scope: any): any\n}\n```\n\n### shallowCompile\n\n#### 描述\n\n浅层遍历任意对象中的表达式片段，表达式片段约定：以`{{`开头`}}`结尾的字符串代表一个表达式片段\n\n#### 签名\n\n```ts\ninterface shallowCompile {\n  (target: any, scope: any): any\n}\n```\n\n### silent\n\n#### 描述\n\n是否静默编译，如果是，则表达式报错不会有任何提醒\n\n#### 签名\n\n```ts\ninterface silent {\n  (value?: boolean): void\n}\n```\n\n### isSchemaInstance\n\n#### 描述\n\n判断某个对象是否为 Schema Class 的实例对象\n\n#### 签名\n\n```ts\ninterface isSchemaInstance {\n  (target: any): target is Schema\n}\n```\n\n### registerCompiler\n\n#### 描述\n\n注册表达式编译器\n\n#### 签名\n\n```ts\ninterface registerCompiler {\n  (compiler: (expression: string, scope: any) => any): void\n}\n```\n\n### registerPatches\n\n#### 描述\n\n注册 Schema 补丁，方便做不同版本的 Schema 协议兼容\n\n#### 签名\n\n```ts\ntype SchemaPatch = (schema: ISchema) => ISchema\n\ninterface registerPatches {\n  (...args: SchemaPatch[]): void\n}\n```\n\n### registerVoidComponents\n\n#### 描述\n\n给字段组件打上标识，标识该组件是虚拟组件，与 formily1.x 做兼容\n\n#### 签名\n\n```ts\ninterface registerVoidComponents {\n  (components: string[]): void\n}\n```\n\n#### 用例\n\n```ts\nimport { Schema } from '@formily/react'\n\nSchema.registerVoidComponents(['card', 'tab', 'step'])\n```\n\n<Alert type=\"warning\">\n  注意，该 api 需要配合 <code>enablePolyfills(['1.0'])</code> 使用\n</Alert>\n\n### registerTypeDefaultComponents\n\n#### 描述\n\n给 Schema 类型标识默认组件类型\n\n#### 签名\n\n```ts\ninterface registerTypeDefaultComponents {\n  (maps: Record<string, string>): void\n}\n```\n\n#### 用例\n\n```ts\nimport { Schema } from '@formily/react'\n\nSchema.registerTypeDefaultComponents({\n  string: 'Input',\n  number: 'NumberPicker',\n  array: 'ArrayTable',\n})\n```\n\n<Alert type=\"warning\">\n  注意，该 api 需要配合 <code>enablePolyfills(['1.0'])</code> 使用\n</Alert>\n\n### registerPolyfills\n\n#### 描述\n\n注册协议兼容垫片\n\n#### 签名\n\n```ts\ntype SchemaPatch = (schema: ISchema) => ISchema\n\ninterface registerPolyfills {\n  (version: string, patch: SchemaPatch): void\n}\n```\n\n#### 用例\n\n```ts\nimport { Schema } from '@formily/react'\n\nSchema.registerPolyfills('1.0', (schema) => {\n  schema['x-decorator'] = 'FormItem'\n  return schema\n})\n```\n\n### enablePolyfills\n\n#### 描述\n\n开启协议垫片，默认内置 1.0 版本协议兼容垫片，主要兼容特性：\n\n- x-decorator 不声明，自动作为 FormItem\n- x-linkages 转换为 x-reactions\n- x-props 自动转换为 x-decorator-props\n- x-rules 转换为 x-validator\n- editable 转换为 x-editable\n- visible 转换为 x-visible\n- x-component 为 card/block/grid-row/grid-col/grid/layout/step/tab/text-box 自动转换 VoidField，\n\n#### 签名\n\n```ts\ninterface enablePolyfills {\n  (versions: string[]): void\n}\n```\n\n#### 用例\n\n```ts\nimport { Schema } from '@formily/react'\n\nSchema.enablePolyfills(['1.0'])\n```\n\n## 类型\n\n### ISchema\n\n#### 描述\n\nISchema 就是一份普通 JSON 数据，同时它是遵循 Schema [属性](#属性) 规范的 JSON 数据\n\n### SchemaTypes\n\n#### 描述\n\nSchema 描述的类型\n\n#### 签名\n\n```ts\ntype SchemaTypes =\n  | 'string'\n  | 'object'\n  | 'array'\n  | 'number'\n  | 'boolean'\n  | 'void'\n  | 'date'\n  | 'datetime'\n  | (string & {})\n```\n\n### SchemaProperties\n\n#### 描述\n\nSchema 属性描述\n\n#### 签名\n\n```ts\ntype SchemaProperties = Record<string, ISchema>\n```\n\n### SchemaItems\n\n#### 描述\n\nSchema 数组项描述\n\n#### 签名\n\n```ts\ntype SchemaItems = ISchema | ISchema[]\n```\n\n### SchemaEnum\n\n#### 描述\n\nSchema 枚举\n\n#### 签名\n\n```ts\ntype SchemaEnum<Message> = Array<\n  | string\n  | number\n  | { label: Message; value: any; [key: string]: any }\n  | { key: any; title: Message; [key: string]: any }\n>\n```\n\n### SchemaReactions\n\n#### 描述\n\nSchema 联动协议，如果 reaction 对象里包含 target，则代表主动联动模式，否则代表被动联动模式  \n如果想实现更复杂的联动，可以通过作用域传入 reaction 响应器函数进行处理  \nFormPathPattern 路径语法文档看[这里](https://core.formilyjs.org/zh-CN/api/entry/form-path#formpathpattern)\n\n#### 签名\n\n```ts\nimport { IGeneralFieldState } from '@formily/core'\n\ntype SchemaReactionEffect =\n  | 'onFieldInit'\n  | 'onFieldMount'\n  | 'onFieldUnmount'\n  | 'onFieldValueChange'\n  | 'onFieldInputValueChange'\n  | 'onFieldInitialValueChange'\n  | 'onFieldValidateStart'\n  | 'onFieldValidateEnd'\n  | 'onFieldValidateFailed'\n  | 'onFieldValidateSuccess'\n\ntype SchemaReaction<Field = any> =\n  | {\n      dependencies?: //依赖的字段路径列表，支持FormPathPattern数据路径语法, 只能以点路径描述依赖，支持相对路径\n      | Array<\n            | string //如果数组里是string，那么读的时候也是数组格式\n            | {\n                //如果数组里是对象, 那么读的时候通过name从$deps获取\n                name?: string //从$deps读取时的别名\n                type?: string //字段类型\n                source?: string //字段路径\n                property?: string //依赖属性, 默认为value\n              }\n          >\n        | Record<string, string> //如果是对象格式，读的时候也是对象格式，只是对象的key相当于别名\n      when?: string | boolean //联动条件\n      target?: string //要操作的字段路径，支持FormPathPattern匹配路径语法，注意：不支持相对路径！！\n      effects?: SchemaReactionEffect[] //主动模式下的独立生命周期钩子\n      fulfill?: {\n        //满足条件\n        state?: IGeneralFieldState //更新状态\n        schema?: ISchema //更新Schema\n        run?: string //执行语句\n      }\n      otherwise?: {\n        //不满足条件\n        state?: IGeneralFieldState //更新状态\n        schema?: ISchema //更新Schema\n        run?: string //执行语句\n      }\n    }\n  | ((field: Field) => void) //支持函数, 可以复杂联动\n\ntype SchemaReactions<Field = any> =\n  | SchemaReaction<Field>\n  | SchemaReaction<Field>[] //支持传入数组\n```\n\n#### 用例\n\n**主动联动**\n\n写法一，标准主动联动\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"target\": \"target\",\n        \"when\": \"{{$self.value === '123'}}\",\n        \"fulfill\": {\n          \"state\": {\n            \"visible\": false\n          }\n        },\n        \"otherwise\": {\n          \"state\": {\n            \"visible\": true\n          }\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\n写法二，局部表达式分发联动\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"target\": \"target\",\n        \"fulfill\": {\n          \"state\": {\n            \"visible\": \"{{$self.value === '123'}}\" //任意层次属性都支持表达式\n          }\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\n写法三，基于 Schema 协议联动\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"target\": \"target\",\n        \"fulfill\": {\n          \"schema\": {\n            \"x-visible\": \"{{$self.value === '123'}}\" //任意层次属性都支持表达式\n          }\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\n写法四，基于 run 语句联动\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"fulfill\": {\n          \"run\": \"$form.setFieldState('target',state=>{state.visible = $self.value === '123'})\"\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\n写法五，基于生命周期钩子联动\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"target\": \"target\",\n        \"effects\": [\"onFieldInputValueChange\"],\n        \"fulfill\": {\n          \"state\": {\n            \"visible\": \"{{$self.value === '123'}}\" //任意层次属性都支持表达式\n          }\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\n**被动联动**\n\n写法一，标准被动联动\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"dependencies\": [\"source\"], //依赖路径写法默认是取value，如果依赖的是字段的其他属性，可以使用 source#modified，用#分割取详细属性\n        // \"dependencies\":{ aliasName:\"source\" }, //别名形式\n        \"fulfill\": {\n          \"schema\": {\n            \"x-visible\": \"{{$deps[0] === '123'}}\" //任意层次属性都支持表达式\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n写法二，相邻元素联动\n\n```json\n{\n  \"type\": \"array\",\n  \"x-component\": \"ArrayTable\",\n  \"items\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"source\": {\n        \"type\": \"string\",\n        \"x-component\": \"Input\"\n      },\n      \"target\": {\n        \"type\": \"string\",\n        \"x-component\": \"Input\",\n        \"x-reactions\": {\n          \"dependencies\": [\".source\"],\n          \"fulfill\": {\n            \"schema\": {\n              \"x-visible\": \"{{$deps[0] === '123'}}\"\n            }\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n**复杂联动**\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": \"{{myReaction}}\" //外部传入的函数，在函数内可以实现更复杂的联动\n    }\n  }\n}\n```\n\n**组件属性联动**\n\n写法一，操作状态\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"target\": \"target\",\n        \"fulfill\": {\n          \"state\": {\n            \"component[1].style.color\": \"{{$self.value === '123' ? 'red' : 'blue'}}\" //任意层次属性都支持表达式，同时key是支持路径表达式的，可以实现精确操作属性\n          }\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\n写法二，操作 Schema 协议\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"target\": \"target\",\n        \"fulfill\": {\n          \"schema\": {\n            \"x-component-props.style.color\": \"{{$self.value === '123' ? 'red' : 'blue'}}\" //任意层次属性都支持表达式，同时key是支持路径表达式的，可以实现精确操作属性\n          }\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\n### Slot\n\n#### 描述\n\n标记该节点为 Slot 节点，会在常规渲染流程中被跳过  \n通过 `target` 指定此节点渲染的目标属性，必须为同级兄弟节点属性  \n可以通过 `isRenderProp` 来指定该节点以 renderProp 函数形式传入  \n当`isRenderProp`为`true`时，在 Slot 中可以通过`$slotArgs`访问到 renderProp 函数入参参数列表\n\n#### 签名\n\n```ts\ntype Slot = {\n  //Slot目标，指定此节点渲染的目标属性，必须为同级兄弟节点属性\n  target: string // 'some-sibling-node.x-component-props.xxx' 或 'some-sibling-node.x-decorator-props.xxx'\n  //Slot是否为render prop\n  isRenderProp?: boolean\n}\n```\n\n#### 用例\n\n**ReactNode Prop**  \n参考 [SchemaField](https://react.formilyjs.org/zh-CN/api/components/schema-field#json-schema-reactnode-prop-%E7%94%A8%E4%BE%8B-x-slot-node)\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"search_icon\": {\n      \"x-slot-node\": {\n        \"target\": \"button.x-component-props.icon\" //指定将search_icon节点作为slot渲染到Button组件的icon prop中\n      },\n      \"x-component\": \"SearchOutlined\",\n      \"x-component-props\": {\n        \"data-testid\": \"icon\"\n      }\n    },\n    \"button\": {\n      \"type\": \"string\",\n      \"x-component\": \"Button\",\n      \"x-component-props\": {\n        \"data-testid\": \"button\"\n      }\n    }\n  }\n}\n```\n\n**RenderProp**  \n参考 [SchemaField](https://react.formilyjs.org/zh-CN/api/components/schema-field#json-schema-render-prop-%E7%94%A8%E4%BE%8B-x-slot-node--isrenderprop)\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"dollar_icon\": {\n      \"x-slot-node\": {\n        \"target\": \"rate.x-component-props.character\", //指定将dollar_icon节点作为slot渲染到Rate组件的character prop中\n        \"isRenderProp\": true //character prop接受一个renderProp函数，指定Slot作为renderProp传入，接管评分图标渲染\n      },\n      \"x-component\": \"DollarOutlined\",\n      \"x-component-props\": {\n        \"data-testid\": \"icon\",\n        \"rotate\": \"{{$slotArgs[0].value * 45}}\", //当isRenderProp为true时，在Slot中可以通过$slotArgs访问到renderProp函数入参参数列表\n        \"style\": {\n          \"fontSize\": \"50px\"\n        }\n      }\n    },\n    \"rate\": {\n      \"x-component\": \"Rate\"\n    }\n  }\n}\n```\n\n## 内置表达式作用域\n\n内置表达式作用域主要用于在表达式中实现各种联动关系\n\n### $self\n\n代表当前字段实例，可以在普通属性表达式中使用，也能在 x-reactions 中使用\n\n### $values\n\n代表顶层表单数据，可以在普通属性表达式中使用，也能在 x-reactions 中使用\n\n### $form\n\n代表当前 Form 实例，可以在普通属性表达式中使用，也能在 x-reactions 中使用\n\n### $observable\n\n用于创建响应式对象，使用方式与 observable 一致\n\n### $memo\n\n用于创建持久引用数据，使用方式与 autorun.memo 一致\n\n### $effect\n\n用于响应 autorun 第一次执行的下一个微任务时机与响应 autorun 的 dispose，使用方式与 autorun.effect 一致\n\n### $dependencies\n\n只能在 x-reactions 中的表达式消费，与 x-reactions 定义的 dependencies 对应，数组顺序一致\n\n### $deps\n\n只能在 x-reactions 中的表达式消费，与 x-reactions 定义的 dependencies 对应，数组顺序一致\n\n### $target\n\n只能在 x-reactions 中的表达式消费，代表主动模式的 target 字段\n\n### $slotArgs\n\n只能在 Slot 节点中消费。当为 render prop slot 时，可以通过$slotArgs 获取渲染函数入参数组\n"
  },
  {
    "path": "packages/react/docs/api/shared/connect.md",
    "content": "# connect\n\n## Description\n\nMainly used for non-intrusive access to third-party component libraries Formily\n\n## Signature\n\n```ts\ninterface IComponentMapper<T extends React.FC> {\n  (target: T): React.FC\n}\ninterface connect<T extends React.FC> {\n  (target: T, ...args: IComponentMapper<T>[]): React.FC\n}\n```\n\nThe first parameter passed in is the component to be connected, the following parameters are component mappers, each mapper is a function, usually we will use the built-in [mapProps](/api/shared/map- props) and [mapReadPretty](/api/shared/map-read-pretty) mapper\n\n## Example\n\n```tsx\nimport React, { useMemo } from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  FormConsumer,\n  Field,\n  connect,\n  mapProps,\n} from '@formily/react'\nimport { Input, Form, Button } from 'antd'\n\n// FormItem UI component\nconst FormItem = connect(\n  Form.Item,\n  mapProps(\n    {\n      title: 'label',\n      description: 'extra',\n      required: true,\n      validateStatus: true,\n    },\n    (props, field) => {\n      return {\n        ...props,\n        help: field.selfErrors?.length ? field.selfErrors : undefined,\n      }\n    }\n  )\n)\n\nexport default () => {\n  const form = useMemo(() => createForm({ validateFirst: true }))\n  return (\n    <FormProvider form={form}>\n      <Form layout=\"vertical\">\n        <Field\n          name=\"name\"\n          title=\"Name\"\n          required\n          decorator={[FormItem]}\n          component={[Input, { placeholder: 'Please Input' }]}\n        />\n        <code>\n          <pre>\n            <FormConsumer>\n              {(form) => JSON.stringify(form.values, null, 2)}\n            </FormConsumer>\n          </pre>\n        </code>\n        <Button\n          type=\"primary\"\n          onClick={() => {\n            form.submit(console.log)\n          }}\n        >\n          Submit\n        </Button>\n      </Form>\n    </FormProvider>\n  )\n}\n```\n"
  },
  {
    "path": "packages/react/docs/api/shared/connect.zh-CN.md",
    "content": "# connect\n\n## 描述\n\n主要用于对第三方组件库的无侵入接入 Formily\n\n## 签名\n\n```ts\ninterface IComponentMapper<T extends React.FC> {\n  (target: T): React.FC\n}\ninterface connect<T extends React.FC> {\n  (target: T, ...args: IComponentMapper<T>[]): React.FC\n}\n```\n\n入参传入第一个参数是要接入的组件，后面的参数都是组件映射器，每个映射器都是一个函数，通常我们会使用内置的[mapProps](/api/shared/map-props)和[mapReadPretty](/api/shared/map-read-pretty)映射器\n\n## 用例\n\n```tsx\nimport React, { useMemo } from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  FormConsumer,\n  Field,\n  connect,\n  mapProps,\n} from '@formily/react'\nimport { Input, Form, Button } from 'antd'\n\n// FormItem UI组件\nconst FormItem = connect(\n  Form.Item,\n  mapProps(\n    {\n      title: 'label',\n      description: 'extra',\n      required: true,\n      validateStatus: true,\n    },\n    (props, field) => {\n      return {\n        ...props,\n        help: field.selfErrors?.length ? field.selfErrors : undefined,\n      }\n    }\n  )\n)\n\nexport default () => {\n  const form = useMemo(() => createForm({ validateFirst: true }))\n  return (\n    <FormProvider form={form}>\n      <Form layout=\"vertical\">\n        <Field\n          name=\"name\"\n          title=\"Name\"\n          required\n          decorator={[FormItem]}\n          component={[Input, { placeholder: 'Please Input' }]}\n        />\n        <code>\n          <pre>\n            <FormConsumer>\n              {(form) => JSON.stringify(form.values, null, 2)}\n            </FormConsumer>\n          </pre>\n        </code>\n        <Button\n          type=\"primary\"\n          onClick={() => {\n            form.submit(console.log)\n          }}\n        >\n          Submit\n        </Button>\n      </Form>\n    </FormProvider>\n  )\n}\n```\n"
  },
  {
    "path": "packages/react/docs/api/shared/context.md",
    "content": "# context\n\n## Description\n\nAll React Context of @formily/react is convenient for users to do more complex personalized customization. We can consume these contexts through useContext\n\n## FormContext\n\n#### Description\n\nForm context, you can get the current Form instance\n\n#### Signature\n\n```ts\nimport { Form } from '@formily/core'\n\nconst FormContext = createContext<Form>(null)\n```\n\n## FieldContext\n\n#### Description\n\nField context, you can get the current field instance\n\n#### Signature\n\n```ts\nimport { GeneralField } from '@formily/core'\n\nconst FieldContext = createContext<GeneralField>(null)\n```\n\n## SchemaMarkupContext\n\n#### Description\n\nSchema tag context, mainly used to collect Schema tags written in JSX Markup, and then convert them into standard JSON Schema\n\n#### Signature\n\n```ts\nSchemaMarkupContext = createContext<Schema>(null)\n```\n\n## SchemaContext\n\n#### Description\n\nField Schema context, mainly used to obtain the Schema information of the current field\n\n#### Signature\n\n```ts\nconst SchemaContext = createContext<Schema>(null)\n```\n\n## SchemaExpressionScopeContext\n\n#### Description\n\nSchema expression scope context\n\n#### Signature\n\n```ts\nexport const SchemaExpressionScopeContext = createContext<any>(null)\n```\n\n## SchemaOptionsContext\n\n#### Description\n\nSchema global parameter context, mainly used to obtain the parameters passed in from createSchemaField\n\n#### Signature\n\n```ts\nconst SchemaOptionsContext = createContext<ISchemaFieldFactoryOptions>(null)\n```\n"
  },
  {
    "path": "packages/react/docs/api/shared/context.zh-CN.md",
    "content": "# context\n\n## 描述\n\n@formily/react 的所有 React Context，方便用户做更复杂的个性化定制，我们可以通过 useContext 来消费这些上下文\n\n## FormContext\n\n#### 描述\n\nForm 上下文，可以获取当前 Form 实例\n\n#### 签名\n\n```ts\nimport { Form } from '@formily/core'\n\nconst FormContext = createContext<Form>(null)\n```\n\n## FieldContext\n\n#### 描述\n\n字段上下文，可以获取当前字段实例\n\n#### 签名\n\n```ts\nimport { GeneralField } from '@formily/core'\n\nconst FieldContext = createContext<GeneralField>(null)\n```\n\n## SchemaMarkupContext\n\n#### 描述\n\nSchema 标签上下文，主要用于收集 JSX Markup 写法的 Schema 标签，然后转换成标准 JSON Schema\n\n#### 签名\n\n```ts\nSchemaMarkupContext = createContext<Schema>(null)\n```\n\n## SchemaContext\n\n#### 描述\n\n字段 Schema 上下文，主要用于获取当前字段的 Schema 信息\n\n#### 签名\n\n```ts\nconst SchemaContext = createContext<Schema>(null)\n```\n\n## SchemaExpressionScopeContext\n\n#### 描述\n\nSchema 表达式作用域上下文\n\n#### 签名\n\n```ts\nexport const SchemaExpressionScopeContext = createContext<any>(null)\n```\n\n## SchemaOptionsContext\n\n#### 描述\n\nSchema 全局参数上下文，主要用于获取从 createSchemaField 传入的参数\n\n#### 签名\n\n```ts\nconst SchemaOptionsContext = createContext<ISchemaFieldFactoryOptions>(null)\n```\n"
  },
  {
    "path": "packages/react/docs/api/shared/mapProps.md",
    "content": "# mapProps\n\n## Description\n\nAdapter function that maps [Field](https://core.formilyjs.org/api/models/field) attributes and component attributes, mainly used in conjunction with the connect function\n\n## Signature\n\n```ts\nimport { Field, GeneralField } from '@formily/core'\ntype IStateMapper<Props> =\n  | {\n      [key in keyof Field]?: keyof Props | boolean\n    }\n  | ((props: Props, field: GeneralField) => Props)\n\ninterface mapProps<T extends React.FC> {\n  (...args: IStateMapper<React.ComponentProps<T>>[]): React.FC\n}\n```\n\n- Parameters can be passed objects (key is the attribute of the field, value is the attribute of the component, if the value is true, the mapped attribute name is the same)\n- Parameters can be passed to functions, and functions can directly do more complex mappings to attributes\n\n## Example\n\n```tsx\nimport React, { useMemo } from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  FormConsumer,\n  Field,\n  connect,\n  mapProps,\n} from '@formily/react'\nimport { Input, Form, Button } from 'antd'\n\n// FormItem UI component\nconst FormItem = connect(\n  Form.Item,\n  mapProps(\n    {\n      title: 'label',\n      description: 'extra',\n      required: true,\n      validateStatus: true,\n    },\n    (props, field) => {\n      return {\n        ...props,\n        help: field.selfErrors?.length ? field.selfErrors : undefined,\n      }\n    }\n  )\n)\n\nexport default () => {\n  const form = useMemo(() => createForm({ validateFirst: true }))\n  return (\n    <FormProvider form={form}>\n      <Form layout=\"vertical\">\n        <Field\n          name=\"name\"\n          title=\"Name\"\n          required\n          decorator={[FormItem]}\n          component={[Input, { placeholder: 'Please Input' }]}\n        />\n        <code>\n          <pre>\n            <FormConsumer>\n              {(form) => JSON.stringify(form.values, null, 2)}\n            </FormConsumer>\n          </pre>\n        </code>\n        <Button\n          type=\"primary\"\n          onClick={() => {\n            form.submit(console.log)\n          }}\n        >\n          Submit\n        </Button>\n      </Form>\n    </FormProvider>\n  )\n}\n```\n"
  },
  {
    "path": "packages/react/docs/api/shared/mapProps.zh-CN.md",
    "content": "# mapProps\n\n## 描述\n\n将[Field](https://core.formilyjs.org/zh-CN/api/models/field)属性与组件属性映射的适配器函数，主要与 connect 函数搭配使用\n\n## 签名\n\n```ts\nimport { Field, GeneralField } from '@formily/core'\ntype IStateMapper<Props> =\n  | {\n      [key in keyof Field]?: keyof Props | boolean\n    }\n  | ((props: Props, field: GeneralField) => Props)\n\ninterface mapProps<T extends React.FC> {\n  (...args: IStateMapper<React.ComponentProps<T>>[]): React.FC\n}\n```\n\n- 参数可以传对象(key 是 field 的属性，value 是组件的属性，如果 value 为 true，代表映射的属性名相同)\n- 参数可以传函数，函数可以直接对属性做更复杂的映射\n\n## 用例\n\n```tsx\nimport React, { useMemo } from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  FormConsumer,\n  Field,\n  connect,\n  mapProps,\n} from '@formily/react'\nimport { Input, Form, Button } from 'antd'\n\n// FormItem UI组件\nconst FormItem = connect(\n  Form.Item,\n  mapProps(\n    {\n      title: 'label',\n      description: 'extra',\n      required: true,\n      validateStatus: true,\n    },\n    (props, field) => {\n      return {\n        ...props,\n        help: field.selfErrors?.length ? field.selfErrors : undefined,\n      }\n    }\n  )\n)\n\nexport default () => {\n  const form = useMemo(() => createForm({ validateFirst: true }))\n  return (\n    <FormProvider form={form}>\n      <Form layout=\"vertical\">\n        <Field\n          name=\"name\"\n          title=\"Name\"\n          required\n          decorator={[FormItem]}\n          component={[Input, { placeholder: 'Please Input' }]}\n        />\n        <code>\n          <pre>\n            <FormConsumer>\n              {(form) => JSON.stringify(form.values, null, 2)}\n            </FormConsumer>\n          </pre>\n        </code>\n        <Button\n          type=\"primary\"\n          onClick={() => {\n            form.submit(console.log)\n          }}\n        >\n          Submit\n        </Button>\n      </Form>\n    </FormProvider>\n  )\n}\n```\n"
  },
  {
    "path": "packages/react/docs/api/shared/mapReadPretty.md",
    "content": "# mapReadPretty\n\n## Description\n\nBecause most third-party components do not support the reading state, if you want to quickly support the reading state, you can use the mapReadPretty function to map a reading state component\n\n## Signature\n\n```ts\ninterface mapReadPretty<Target extends React.FC> {\n  (component: Target, readPrettyProps?: React.ComponentProps<Target>): React.FC\n}\n```\n\n## Example\n\n```tsx\nimport React, { useMemo } from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  Field,\n  connect,\n  mapProps,\n  mapReadPretty,\n} from '@formily/react'\nimport { Input as AntdInput, Form } from 'antd'\n\n// FormItem UI component\nconst FormItem = connect(\n  Form.Item,\n  mapProps(\n    {\n      title: 'label',\n      description: 'extra',\n      required: true,\n      validateStatus: true,\n    },\n    (props, field) => {\n      return {\n        ...props,\n        help: field.selfErrors?.length ? field.selfErrors : undefined,\n      }\n    }\n  )\n)\n\nconst Input = connect(\n  AntdInput,\n  mapReadPretty(({ value }) => <div>{value}</div>)\n)\n\nexport default () => {\n  const form = useMemo(() =>\n    createForm({ validateFirst: true, readPretty: true })\n  )\n  return (\n    <FormProvider form={form}>\n      <Form layout=\"vertical\">\n        <Field\n          name=\"name\"\n          title=\"Name\"\n          required\n          initialValue=\"Hello world\"\n          decorator={[FormItem]}\n          component={[Input, { placeholder: 'Please Input' }]}\n        />\n      </Form>\n    </FormProvider>\n  )\n}\n```\n"
  },
  {
    "path": "packages/react/docs/api/shared/mapReadPretty.zh-CN.md",
    "content": "# mapReadPretty\n\n## 描述\n\n因为大多数第三方组件都不支持阅读态，如果想要快速支持阅读态的话，即可使用 mapReadPretty 函数来映射一个阅读态组件\n\n## 签名\n\n```ts\ninterface mapReadPretty<Target extends React.FC> {\n  (component: Target, readPrettyProps?: React.ComponentProps<Target>): React.FC\n}\n```\n\n## 用例\n\n```tsx\nimport React, { useMemo } from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  Field,\n  connect,\n  mapProps,\n  mapReadPretty,\n} from '@formily/react'\nimport { Input as AntdInput, Form } from 'antd'\n\n// FormItem UI组件\nconst FormItem = connect(\n  Form.Item,\n  mapProps(\n    {\n      title: 'label',\n      description: 'extra',\n      required: true,\n      validateStatus: true,\n    },\n    (props, field) => {\n      return {\n        ...props,\n        help: field.selfErrors?.length ? field.selfErrors : undefined,\n      }\n    }\n  )\n)\n\nconst Input = connect(\n  AntdInput,\n  mapReadPretty(({ value }) => <div>{value}</div>)\n)\n\nexport default () => {\n  const form = useMemo(() =>\n    createForm({ validateFirst: true, readPretty: true })\n  )\n  return (\n    <FormProvider form={form}>\n      <Form layout=\"vertical\">\n        <Field\n          name=\"name\"\n          title=\"Name\"\n          required\n          initialValue=\"Hello world\"\n          decorator={[FormItem]}\n          component={[Input, { placeholder: 'Please Input' }]}\n        />\n      </Form>\n    </FormProvider>\n  )\n}\n```\n"
  },
  {
    "path": "packages/react/docs/api/shared/observer.md",
    "content": "# observer\n\n## observer\n\n### Description\n\nThe observer is a [HOC](https://reactjs.bootcss.com/docs/higher-order-components.html), which is used to add reactive features to react functional components.\n\n### When to use\n\nWhen a component uses an [observable](https://reactive.formilyjs.org/api/observable) object inside, and you want the component to respond to changes in the observable object.\n\n### API definition\n\n```ts\ninterface IObserverOptions {\n  // Do you need observers to use forwardRef to pass ref attributes\n  forwardRef?: boolean\n  scheduler?: (updater: () => void) => void\n  displayName?: string\n}\n\nfunction observer<P, Options extends IObserverOptions>(\n  component: React.FunctionComponent<P>,\n  options?: Options\n): React.MemoExoticComponent<\n  React.FunctionComponent<\n    Options extends { forwardRef: true }\n      ? React.PropsWithRef<P>\n      : React.PropsWithoutRef<P>\n  >\n>\n```\n\n### Example\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React from 'react'\nimport { observable } from '@formily/reactive'\nimport { observer } from '@formily/reactive-react'\n\nconst obs = observable({\n  value: 'Hello world',\n})\n\nexport default observer(() => {\n  return (\n    <div>\n      <div>\n        <input\n          style={{\n            height: 28,\n            padding: '0 8px',\n            border: '2px solid #888',\n            borderRadius: 3,\n          }}\n          value={obs.value}\n          onChange={(e) => {\n            obs.value = e.target.value\n          }}\n        />\n      </div>\n      <div>{obs.value}</div>\n    </div>\n  )\n})\n```\n\n### Note\n\n`observer` can only receive callable function components, and does not support packaged components such as `React.forwardRef` | `React.memo`.\n\n## Observer\n\n### Description\n\nSimilar to Vue's responsive slot, it receives a Function RenderProps, as long as any responsive data consumed inside the Function, it will be automatically re-rendered as the data changes, and it is easier to achieve local accurate rendering\n\nIn fact, the function of this API is basically the same as that of FormConsumer, except that FormConsumer reveals the form instance of the current context in the RenderProps parameter.\n\n### Signature\n\n```ts\ninterface IObserverProps {\n  children?: () => React.ReactElement\n}\n\ntype Observer = React.FC<React.PropsWithChildren<IObserverProps>>\n```\n\n### Example\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React from 'react'\nimport { observable } from '@formily/reactive'\nimport { Observer } from '@formily/react'\n\nconst obs = observable({\n  value: 'Hello world',\n})\n\nexport default () => {\n  return (\n    <div>\n      <div>\n        <Observer>\n          {() => (\n            <input\n              style={{\n                height: 28,\n                padding: '0 8px',\n                border: '2px solid #888',\n                borderRadius: 3,\n              }}\n              value={obs.value}\n              onChange={(e) => {\n                obs.value = e.target.value\n              }}\n            />\n          )}\n        </Observer>\n      </div>\n      <Observer>{() => <div>{obs.value}</div>}</Observer>\n    </div>\n  )\n}\n```\n"
  },
  {
    "path": "packages/react/docs/api/shared/observer.zh-CN.md",
    "content": "# observer\n\n## observer\n\n### 描述\n\nobserver 是一个 [HOC](https://reactjs.bootcss.com/docs/higher-order-components.html)，用于为 react 函数组件添加 reactive 特性。\n\n### 什么时候使用\n\n当一个组件内部使用了 [observable](https://reactive.formilyjs.org/zh-CN/api/observable) 对象，而你希望组件响应 observable 对象的变化时。\n\n### API 定义\n\n```ts\ninterface IObserverOptions {\n  // 是否需要 observer 使用 forwardRef 传递 ref 属性\n  forwardRef?: boolean\n  scheduler?: (updater: () => void) => void\n  displayName?: string\n}\n\nfunction observer<P, Options extends IObserverOptions>(\n  component: React.FunctionComponent<P>,\n  options?: Options\n): React.MemoExoticComponent<\n  React.FunctionComponent<\n    Options extends { forwardRef: true }\n      ? React.PropsWithRef<P>\n      : React.PropsWithoutRef<P>\n  >\n>\n```\n\n### 用例\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React from 'react'\nimport { observable } from '@formily/reactive'\nimport { observer } from '@formily/reactive-react'\n\nconst obs = observable({\n  value: 'Hello world',\n})\n\nexport default observer(() => {\n  return (\n    <div>\n      <div>\n        <input\n          style={{\n            height: 28,\n            padding: '0 8px',\n            border: '2px solid #888',\n            borderRadius: 3,\n          }}\n          value={obs.value}\n          onChange={(e) => {\n            obs.value = e.target.value\n          }}\n        />\n      </div>\n      <div>{obs.value}</div>\n    </div>\n  )\n})\n```\n\n### 注意\n\n`observer` 只能接收 callable 函数组件，不支持 `React.forwardRef` | `React.memo` 等包裹的组件。\n\n## Observer\n\n### 描述\n\n类似于 Vue 的响应式 Slot，它接收一个 Function RenderProps，只要在 Function 内部消费到的任何响应式数据，都会随数据变化而自动重新渲染，也更容易实现局部精确渲染\n\n其实该 API 与 FormConsumer 的作用基本一致，只是 FormConsumer 在 RenderProps 参数中透出了当前上下文的 form 实例\n\n### 签名\n\n```ts\ninterface IObserverProps {\n  children?: () => React.ReactElement\n}\n\ntype Observer = React.FC<React.PropsWithChildren<IObserverProps>>\n```\n\n### 用例\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React from 'react'\nimport { observable } from '@formily/reactive'\nimport { Observer } from '@formily/react'\n\nconst obs = observable({\n  value: 'Hello world',\n})\n\nexport default () => {\n  return (\n    <div>\n      <div>\n        <Observer>\n          {() => (\n            <input\n              style={{\n                height: 28,\n                padding: '0 8px',\n                border: '2px solid #888',\n                borderRadius: 3,\n              }}\n              value={obs.value}\n              onChange={(e) => {\n                obs.value = e.target.value\n              }}\n            />\n          )}\n        </Observer>\n      </div>\n      <Observer>{() => <div>{obs.value}</div>}</Observer>\n    </div>\n  )\n}\n```\n"
  },
  {
    "path": "packages/react/docs/guide/architecture.md",
    "content": "# Core Architecture\n\nThe architecture of @formily/react is not complicated compared to @formily/core. First look at the architecture diagram:\n\n![](https://img.alicdn.com/imgextra/i1/O1CN013jbRfk1l5n6N7jYH8_!!6000000004768-55-tps-2200-1637.svg)\n\nFrom this architecture diagram, we can see that @formily/react supports two types of users, one is pure source code development users, they only need to use the Field/ArrayField/ObjectField/VoidField component. The other type is users who do dynamic development based on JSON-Schema. They mainly rely on the SchemaField component. However, both types of users need to use a FormProvider component to uniformly deliver the context. Then there is the SchemaField component, which is actually the dependent Field/ArrayField/ObjectField/VoidField component inside.\n"
  },
  {
    "path": "packages/react/docs/guide/architecture.zh-CN.md",
    "content": "# 核心架构\n\n@formily/react 的架构相比于@formily/core 并不复杂，先看架构图：\n\n![](https://img.alicdn.com/imgextra/i1/O1CN013jbRfk1l5n6N7jYH8_!!6000000004768-55-tps-2200-1637.svg)\n\n从这张架构图中我们可以看到，@formily/react 支持了两类用户，一类就是纯源码开发用户，他们只需要使用 Field/ArrayField/ObjectField/VoidField 组件。另一类就是基于 JSON-Schema 做动态开发的用户，他们依赖的主要是 SchemaField 组件，但是，这两类用户都需要使用一个 FormProvider 的组件来统一下发上下文。然后是 SchemaField 组件，它内部其实是依赖的 Field/ArrayField/ObjectField/VoidField 组件。\n"
  },
  {
    "path": "packages/react/docs/guide/concept.md",
    "content": "# Core idea\n\nThe architecture of @formily/react itself is not complicated, because it only provides a series of components and Hooks for users to use, but we still need to understand the following concepts:\n\n- Form context\n- Field context\n- Protocol context\n- Model binding\n- Protocol driven\n- Three development modes\n\n## Form context\n\nFrom the [architecture diagram](/guide/architecture) we can see that FormProvider exists as a unified context for forms, and its position is very important. It is mainly used to create [Form](//core. formilyjs.org/api/models/form) instances are distributed to all sub-components, whether in built-in components or user-extended components, can be read through [useForm](/api/hooks/use-form) [ Form](//core.formilyjs.org/api/models/form) instance\n\n## Field context\n\nFrom the [architecture diagram](/guide/architecture) we can see that whether it is Field/ArrayField/ObjectField/VoidField, a FieldContext will be issued to the subtree. We can read the current field model in the custom component, mainly Use [useField](/api/hooks/use-field) to read, which is very convenient for model mapping\n\n## Protocol context\n\nFrom the [architecture diagram](/guide/architecture) we can see that [RecursionField](/api/components/recursion-field) will send a FieldSchemaContext to the subtree, and we can read the current field in the custom component The Schema description is mainly read using [useFieldSchema](/api/hooks/useFieldSchema). Note that this Hook can only be used in the [SchemaField](/api/components/SchemaField) and [RecursionField](/api/components/recursion-field) subtrees\n\n## Model binding\n\nTo understand model binding, you need to understand what [MVVM](//core.formilyjs.org/guide/mvvm) is. After understanding, let’s take a look at this picture:\n\n![](https://img.alicdn.com/imgextra/i1/O1CN01A03C191KwT1raxnDg_!!6000000001228-55-tps-2200-869.svg)\n\nIn Formily, @formily/core is ViewModel, Component and Decorator are View, @formily/react is the glue layer that binds ViewModel and View, and the binding of ViewModel and View is called model binding, which implements model binding. The main methods are [useField](/api/hooks/use-field), and [connect](/api/shared/connect) and [mapProps](/api/shared/map-props) can also be used. Note that Component only needs to support the value/onChange property to automatically realize the two-way binding of the data layer.\n\n## JSON Schema Driver\n\nProtocol-driven rendering is the most expensive part of @formily/react, but after learning it, the benefits it brings to the business are also very high. A total of 4 core concepts need to be understood:\n\n- Schema\n- Recursive rendering\n- Protocol binding\n- Three development modes\n\n### Schema\n\nFormily’s protocol driver is mainly based on the standard JSON Schema to drive rendering. At the same time, we have extended some `x-*` attributes to express the UI on top of the standard, so that the entire protocol can fully describe a complex form. Schema protocol, refer to [Schema](/api/shared/schema) API document\n\n### Recursive rendering\n\nWhat is recursive rendering? Recursive rendering means that component A will continue to use component A to render content under certain conditions. Take a look at the following pseudo code:\n\n```json\n{<---- RecursionField (condition: object; rendering right: RecursionField)\n  \"type\":\"object\",\n  \"properties\":{\n    \"username\":{ <---- RecursionField (condition: string; rendering right: RecursionField)\n      \"type\":\"string\",\n      \"x-component\":\"Input\"\n    },\n    \"phone\":{ <---- RecursionField (condition: string; rendering right: RecursionField)\n      \"type\":\"string\",\n      \"x-component\":\"Input\",\n      \"x-validator\":\"phone\"\n    },\n    \"email\":{ <---- RecursionField (condition: string; rendering right: RecursionField)\n      \"type\":\"string\",\n      \"x-component\":\"Input\",\n      \"x-validator\":\"email\"\n    },\n    \"contacts\":{ <---- RecursionField (condition: array; rendering right: RecursionField)\n      \"type\":\"array\",\n      \"x-component\":\"ArrayTable\",\n      \"items\":{ <---- RecursionField (condition: object; rendering rights: ArrayTable component)\n        \"type\":\"object\",\n        \"properties\":{\n          \"username\":{ <---- RecursionField (condition: string; rendering right: RecursionField)\n            \"type\":\"string\",\n            \"x-component\":\"Input\"\n          },\n          \"phone\":{ <---- RecursionField (condition: string; rendering right: RecursionField)\n            \"type\":\"string\",\n            \"x-component\":\"Input\",\n            \"x-validator\":\"phone\"\n          },\n          \"email\":{ <---- RecursionField (condition: string; rendering right: RecursionField)\n            \"type\":\"string\",\n            \"x-component\":\"Input\",\n            \"x-validator\":\"email\"\n          },\n        }\n      }\n    }\n  }\n}\n```\n\n@formily/react The entry point for recursive rendering is [SchemaField](/api/components/schema-field), but it actually uses [RecursionField](/api/components/recursion-field) to render internally, because of JSON-Schema It is a recursive structure, so [RecursionField](/api/components/recursion-field) will be parsed from the top-level Schema node when rendering. If it is a non-object and array type, it will directly render the specific component. If it is an object, it will traverse. properties Continue to use [RecursionField](/api/components/recursion-field) to render child Schema nodes.\n\nA special case here is the rendering of the array type auto-increment list, which requires the user to use [RecursionField](/api/components/recursion-field) in the custom component for recursive rendering, because the UI of the auto-increment list is very customized High, so the recursive rendering rights are handed over to the user to render, so the design can also make protocol-driven rendering more flexible.\n\nWhat is the difference between SchemaField and RecursionField? There are two main points:\n\n- SchemaField supports Markup grammar, it will parse Markup grammar in advance to generate [JSON Schema](/api/shared/schema) and transfer it to RecursionField for rendering, so RecursionField can only be rendered based on [JSON Schema](/api/shared/schema)\n- SchemaField renders the overall Schema protocol, while RecursionField renders the partial Schema protocol\n\n### Protocol binding\n\nI talked about model binding, and protocol binding is the process of converting Schema protocol into model binding, because JSON-Schema protocol is a JSON string and can be stored offline, while model binding is a binding between memory The relationship is at the Runtime layer. For example, `x-component` is the string identifier of the component in the Schema, but the component in the model requires component reference, so the JSON string and the Runtime layer need to be converted. Then we can continue to improve the above model binding diagram:\n\n![](https://img.alicdn.com/imgextra/i3/O1CN01jLCRxH1aa3V0x6nw4_!!6000000003345-55-tps-2200-1147.svg)\n\nTo sum up, in @formily/react, there are mainly two layers of binding relationships, Schema binding model, model binding component, the glue layer that realizes the binding is @formily/react, it should be noted that Schema binds the field model After that, the Schema is not perceptible in the field model. For example, if you want to modify the `enum`, you need to modify the `dataSource` attribute in the field model. In short, if you want to update the field model, refer to [Field](//core.formilyjs. org/api/models/field), you can refer to [Schema](/api/shared/schema) document if you want to understand the mapping relationship between Schema and field model\n\n## Three development models\n\nFrom the [architecture diagram](/guide/architecture), we have actually seen that the entire @formily/react has three development modes, corresponding to different users:\n\n- JSX development model\n- JSON Schema development mode\n- Markup Schema development mode\n\nWe can look at specific examples\n\n#### JSX development model\n\nThis mode mainly uses Field/ArrayField/ObjectField/VoidField components\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field name=\"input\" component={[Input, { placeholder: 'Please enter' }]} />\n  </FormProvider>\n)\n```\n\n#### JSON Schema Development Mode\n\nThis mode is to pass JSON Schema to the schema attribute of SchemaField\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField\n      schema={{\n        type: 'object',\n        properties: {\n          input: {\n            type: 'string',\n            'x-component': 'Input',\n            'x-component-props': {\n              placeholder: 'Please enter',\n            },\n          },\n        },\n      }}\n    />\n  </FormProvider>\n)\n```\n\n#### Markup Schema Development Mode\n\nThis mode can be regarded as a Schema development mode that is more friendly to source code development, and it also uses the SchemaField component.\n\nBecause it is difficult to get the best smart prompt experience in the JSX environment with JSON Schema, and it is inconvenient to maintain, the maintainability in the form of tags will be better, and the smart prompt is also very strong.\n\nMarkup Schema mode mainly has the following characteristics:\n\n- Mainly rely on description tags such as SchemaField.String/SchemaField.Array/SchemaField.Object... to express Schema\n- Each description tag represents a Schema node, which is equivalent to JSON-Schema\n- SchemaField child nodes cannot insert UI elements at will, because SchemaField will only parse all the Schema description tags of the child nodes, and then convert them into JSON Schema, and finally give it to [RecursionField](/api/components/recursion-field) for rendering, if you want Insert UI elements, you can upload the `x-content` attribute in VoidDield to insert UI elements\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        x-component=\"Input\"\n        x-component-props={{ placeholder: 'Please enter' }}\n      />\n      <div>I will not be rendered</div>\n      <SchemaField.Void x-content={<div>I will be rendered</div>} />\n    </SchemaField>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/guide/concept.zh-CN.md",
    "content": "# 核心概念\n\n@formily/react 本身架构不复杂，因为它只是提供了一系列的组件和 Hooks 给用户使用，但是我们还是需要理解以下几个概念：\n\n- 表单上下文\n- 字段上下文\n- 协议上下文\n- 模型绑定\n- 协议驱动\n- 三种开发模式\n\n## 表单上下文\n\n从[架构图](/guide/architecture)中我们可以看到 FormProvider 是作为表单统一上下文而存在，它的地位非常重要，主要用于将@formily/core 创建出来的[Form](//core.formilyjs.org/zh-CN/api/models/form)实例下发到所有子组件中，不管是在内置组件还是用户扩展的组件，都能通过[useForm](/api/hooks/use-form)读取到[Form](//core.formilyjs.org/zh-CN/api/models/form)实例\n\n## 字段上下文\n\n从[架构图](/guide/architecture)中我们可以看到不管是 Field/ArrayField/ObjectField/VoidField，会给子树下发一个 FieldContext，我们可以在自定义组件中读取到当前字段模型，主要是使用[useField](/api/hooks/use-field)来读取，这样非常方便于做模型映射\n\n## 协议上下文\n\n从[架构图](/guide/architecture)中我们可以看到[RecursionField](/api/components/recursion-field)会给子树下发一个 FieldSchemaContext，我们可以在自定义组件中读取到当前字段的 Schema 描述，主要是使用[useFieldSchema](/api/hooks/useFieldSchema)来读取。注意，该 Hook 只能用在[SchemaField](/api/components/SchemaField)和[RecursionField](/api/components/recursion-field)子树中使用\n\n## 模型绑定\n\n想要理解模型绑定，需要先理解什么是[MVVM](//core.formilyjs.org/zh-CN/guide/mvvm)，理解了之后我们再看看这张图：\n\n![](https://img.alicdn.com/imgextra/i1/O1CN01A03C191KwT1raxnDg_!!6000000001228-55-tps-2200-869.svg)\n\n在 Formily 中，@formily/core 就是 ViewModel，Component 和 Decorator 就是 View，@formily/react 就是将 ViewModel 和 View 绑定起来的胶水层，ViewModel 和 View 的绑定就叫做模型绑定，实现模型绑定的手段主要有[useField](/api/hooks/use-field)，也能使用[connect](/api/shared/connect)和[mapProps](/api/shared/map-props)，需要注意的是，Component 只需要支持 value/onChange 属性即可自动实现数据层的双向绑定。\n\n## 协议驱动\n\n协议驱动渲染算是@formily/react 中学习成本最高的部分了，但是学会了之后，它给业务带来的收益也是很高，总共需要理解 4 个核心概念：\n\n- Schema\n- 递归渲染\n- 协议绑定\n- 三种开发模式\n\n### Schema\n\nformily 的协议驱动主要是基于标准 JSON Schema 来进行驱动渲染的，同时我们在标准之上又扩展了一些`x-*`属性来表达 UI，使得整个协议可以具备完整描述一个复杂表单的能力，具体 Schema 协议，参考[Schema](/api/shared/schema) API 文档\n\n### 递归渲染\n\n何为递归渲染？递归渲染就是组件 A 在某些条件下会继续用组件 A 来渲染内容，看看以下伪代码：\n\n```json\n{ <---- RecursionField(条件：object；渲染权：RecursionField)\n  \"type\":\"object\",\n  \"properties\":{\n    \"username\":{ <---- RecursionField(条件：string；渲染权：RecursionField)\n      \"type\":\"string\",\n      \"x-component\":\"Input\"\n    },\n    \"phone\":{ <---- RecursionField(条件：string；渲染权：RecursionField)\n      \"type\":\"string\",\n      \"x-component\":\"Input\",\n      \"x-validator\":\"phone\"\n    },\n    \"email\":{ <---- RecursionField(条件：string；渲染权：RecursionField)\n      \"type\":\"string\",\n      \"x-component\":\"Input\",\n      \"x-validator\":\"email\"\n    },\n    \"contacts\":{ <---- RecursionField(条件：array；渲染权：RecursionField)\n      \"type\":\"array\",\n      \"x-component\":\"ArrayTable\",\n      \"items\":{ <---- RecursionField(条件：object；渲染权：ArrayTable组件)\n        \"type\":\"object\",\n        \"properties\":{\n          \"username\":{ <---- RecursionField(条件：string；渲染权：RecursionField)\n            \"type\":\"string\",\n            \"x-component\":\"Input\"\n          },\n          \"phone\":{ <---- RecursionField(条件：string；渲染权：RecursionField)\n            \"type\":\"string\",\n            \"x-component\":\"Input\",\n            \"x-validator\":\"phone\"\n          },\n          \"email\":{ <---- RecursionField(条件：string；渲染权：RecursionField)\n            \"type\":\"string\",\n            \"x-component\":\"Input\",\n            \"x-validator\":\"email\"\n          },\n        }\n      }\n    }\n  }\n}\n```\n\n@formily/react 递归渲染的入口是[SchemaField](/api/components/schema-field)，但它内部实际是使用 [RecursionField](/api/components/recursion-field) 来渲染的，因为 JSON-Schema 就是一个递归型结构，所以 [RecursionField](/api/components/recursion-field) 在渲染的时候会从顶层 Schema 节点解析，如果是非 object 和 array 类型则直接渲染具体组件，如果是 object，则会遍历 properties 继续用 [RecursionField](/api/components/recursion-field) 渲染子级 Schema 节点。\n\n这里有点特殊的情况是 array 类型的自增列表渲染，需要用户在自定义组件内使用[RecursionField](/api/components/recursion-field)进行递归渲染，因为自增列表的 UI 个性化定制程度很高，所以就把递归渲染权交给用户来渲染了，这样设计也能让协议驱动渲染变得更加灵活。\n\n那 SchemaField 和 RecursionField 有啥差别呢？主要有两点：\n\n- SchemaField 是支持 Markup 语法的，它会提前解析 Markup 语法生成[JSON Schema](/api/shared/schema)移交给 RecursionField 渲染，所以 RecursionField 只能基于 [JSON Schema](/api/shared/schema) 渲染\n- SchemaField 渲染的是整体的 Schema 协议，而 RecursionField 渲染的是局部 Schema 协议\n\n### 协议绑定\n\n前面讲了模型绑定，而协议绑定则是将 Schema 协议转换成模型绑定的过程，因为 JSON-Schema 协议是 JSON 字符串，可离线存储的，而模型绑定则是内存间的绑定关系，是 Runtime 层的，比如`x-component`在 Schema 中是组件的字符串标识，但是在模型中的 component 则是需要组件引用，所以 JSON 字符串与 Runtime 层是需要转换的。然后我们就可以继续完善一下以上模型绑定的图：\n\n![](https://img.alicdn.com/imgextra/i3/O1CN01jLCRxH1aa3V0x6nw4_!!6000000003345-55-tps-2200-1147.svg)\n\n总结下来，在@formily/react 中，主要有 2 层绑定关系，Schema 绑定模型，模型绑定组件，实现绑定的胶水层就是@formily/react，需要注意的是，Schema 绑定字段模型之后，字段模型中是感知不到 Schema 的，比如要修改`enum`，就是修改字段模型中的`dataSource`属性了，总之，想要更新字段模型，参考[Field](//core.formilyjs.org/zh-CN/api/models/field)，想要理解 Schema 与字段模型的映射关系可以参考[Schema](/api/shared/schema)文档\n\n## 三种开发模式\n\n从[架构图](/guide/architecture)中我们其实已经看到整个@formily/react 是有三种开发模式的，对应不同用户：\n\n- JSX 开发模式\n- JSON Schema 开发模式\n- Markup Schema 开发模式\n\n我们可以看看具体例子\n\n#### JSX 开发模式\n\n该模式主要是使用 Field/ArrayField/ObjectField/VoidField 组件\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nexport default () => (\n  <FormProvider form={form}>\n    <Field name=\"input\" component={[Input, { placeholder: '请输入' }]} />\n  </FormProvider>\n)\n```\n\n#### JSON Schema 开发模式\n\n该模式是给 SchemaField 的 schema 属性传递 JSON Schema 即可\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField\n      schema={{\n        type: 'object',\n        properties: {\n          input: {\n            type: 'string',\n            'x-component': 'Input',\n            'x-component-props': {\n              placeholder: '请输入',\n            },\n          },\n        },\n      }}\n    />\n  </FormProvider>\n)\n```\n\n#### Markup Schema 开发模式\n\n该模式算是一个对源码开发比较友好的 Schema 开发模式，同样是使用 SchemaField 组件。\n\n因为用 JSON Schema 在 JSX 环境下很难得到最好的智能提示体验，而且也不方便维护，用标签的形式可维护性会更好，智能提示也很强。\n\nMarkup Schema 模式主要有以下几个特点：\n\n- 主要依赖 SchemaField.String/SchemaField.Array/SchemaField.Object...这类描述标签来表达 Schema\n- 每个描述标签都代表一个 Schema 节点，与 JSON-Schema 等价\n- SchemaField 子节点不能随意插 UI 元素，因为 SchemaField 只会解析子节点的所有 Schema 描述标签，然后转换成 JSON Schema，最终交给[RecursionField](/api/components/recursion-field)渲染，如果想要插入 UI 元素，可以在 VoidField 上传`x-content`属性来插入 UI 元素\n\n```tsx\nimport React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/react'\nimport { Input } from 'antd'\n\nconst form = createForm()\n\nconst SchemaField = createSchemaField({\n  components: {\n    Input,\n  },\n})\n\nexport default () => (\n  <FormProvider form={form}>\n    <SchemaField>\n      <SchemaField.String\n        x-component=\"Input\"\n        x-component-props={{ placeholder: '请输入' }}\n      />\n      <div>我不会被渲染</div>\n      <SchemaField.Void x-content={<div>我会被渲染</div>} />\n    </SchemaField>\n  </FormProvider>\n)\n```\n"
  },
  {
    "path": "packages/react/docs/guide/index.md",
    "content": "# Introduction\n\nThe core positioning of @formily/react is to realize a state binding relationship between ViewModel ([@formily/core](//core.formilyjs.org)) and components. It is not responsible for managing form data and form verification. It is only A rendering glue layer, but such a layer of glue is not dirty, it will elegantly decouple a lot of dirty logic and become maintainable.\n\n## Ultra high performance\n\nWith the responsive model of [@formily/core](//core.formilyjs.org), @formily/react can obtain super high performance advantages without any optimization, relying on tracking, accurate updates, on-demand rendering, let us The form of really does only need to focus on business logic, without considering performance issues.\n\n## Out of the box\n\n@formily/react provides a series of React components, such as Field/ArrayField/ObjectField/VoidField. When using it, users only need to pass the component property to the Field component (supporting two-way binding conventions such as value/onChange). Quick access to @formily/react, the access cost is extremely low.\n\n## JSON Schema Driver\n\n@formily/react provides protocol-driven components such as SchemaField. It is also driven by the standard JSON-Schema, so that form development can become more dynamic and configurable. What's more, we can achieve a protocol that allows multiple terminals Render the form.\n\n## Scene Reuse\n\nWith the help of protocol-driven capabilities, we can abstract a protocol fragment carrying business logic into a scene component to help users develop efficiently in certain scenes, such as scene components such as FormTab and FormStep.\n\n## Smart tips\n\nBecause formily is a complete Typescript project, users can develop on VSCode or WebStorm to get the maximum intelligent prompt experience\n\n![img](https://img.alicdn.com/imgextra/i2/O1CN01yiREHk1X95KJPPz1c_!!6000000002880-2-tps-2014-868.png)\n\n## Status observable\n\nInstall [FormilyDevtools](https://chrome.google.com/webstore/detail/formily-devtools/kkocalmbfnplecdmbadaapgapdioecfm?hl=zh-CN) to observe the model status changes in real time and troubleshoot problems\n\n![img](https://img.alicdn.com/imgextra/i4/O1CN01DSci5h1rAGfRafpXw_!!6000000005590-2-tps-2882-1642.png)\n"
  },
  {
    "path": "packages/react/docs/guide/index.zh-CN.md",
    "content": "# 介绍\n\n@formily/react 的核心定位是将 ViewModel([@formily/core](//core.formilyjs.org))与组件实现一个状态绑定关系，它不负责管理表单数据，表单校验，它仅仅是一个渲染胶水层，但是这样一层胶水，并不脏，它会把很多脏逻辑优雅的解耦，变得可维护。\n\n## 超高性能\n\n借助 [@formily/core](//core.formilyjs.org) 的响应式模型，@formily/react 无需做任何优化即可获得超高的性能优势，依赖追踪，精确更新，按需渲染，让我们的表单真正做到了只需关注业务逻辑，无需考虑性能问题。\n\n## 开箱即用\n\n@formily/react 提供了一系列的 React 组件，比如 Field/ArrayField/ObjectField/VoidField，用户在使用的时候，只需要给 Field 组件传入 component 属性(支持 value/onChange 这样的双向绑定约定)即可快速接入@formily/react，接入成本极低。\n\n## 协议驱动\n\n@formily/react 提供了 SchemaField 这样的协议驱动组件，同时是基于标准 JSON-Schema 的驱动，让表单开发可以变得更加动态化，可配置化，更甚，我们可以做到一份协议，让多端渲染表单。\n\n## 场景复用\n\n借助协议驱动的能力，我们可以将一个携带业务逻辑的协议片段抽象成一个场景组件，帮助用户在某些场景上高效开发，比如 FormTab、FormStep 这类场景组件。\n\n## 智能提示\n\n因为 formily 是完全的 Typescript 项目，所以用户在 VSCode 或 WebStorm 等上开发可以获得最大化的智能提示体验\n\n![img](https://img.alicdn.com/imgextra/i2/O1CN01yiREHk1X95KJPPz1c_!!6000000002880-2-tps-2014-868.png)\n\n## 状态可观测\n\n安装 [FormilyDevtools](https://chrome.google.com/webstore/detail/formily-devtools/kkocalmbfnplecdmbadaapgapdioecfm?hl=zh-CN) 可以实时观测模型状态变化，排查问题\n\n![img](https://img.alicdn.com/imgextra/i4/O1CN01DSci5h1rAGfRafpXw_!!6000000005590-2-tps-2882-1642.png)\n"
  },
  {
    "path": "packages/react/docs/index.md",
    "content": "---\ntitle: Formily-Alibaba unified front-end form solution\norder: 10\nhero:\n  title: React Library\n  desc: Alibaba Unified Form Solution\n  actions:\n    - text: Home Site\n      link: //formilyjs.org\n    - text: Development Guide\n      link: /guide\nfeatures:\n  - icon: https://img.alicdn.com/imgextra/i1/O1CN01bHdrZJ1rEOESvXEi5_!!6000000005599-55-tps-800-800.svg\n    title: Ultra High Performance\n    desc: Dependency tracking, efficient update, on-demand rendering\n  - icon: https://img.alicdn.com/imgextra/i2/O1CN016i72sH1c5wh1kyy9U_!!6000000003550-55-tps-800-800.svg\n    title: Out Of The Box\n    desc: The component status is automatically bound, and the access cost is extremely low\n  - icon: https://img.alicdn.com/imgextra/i3/O1CN01JHzg8U1FZV5Mvt012_!!6000000000501-55-tps-800-800.svg\n    title: JSON Schema Driver\n    desc: Standard JSON-Schema\n  - icon: https://img.alicdn.com/imgextra/i3/O1CN0194OqFF1ui6mMT4g7O_!!6000000006070-55-tps-800-800.svg\n    title: Scene Reuse\n    desc: Based on protocol-driven, abstract scene components\n  - icon: https://img.alicdn.com/imgextra/i4/O1CN018vDmpl2186xdLu6KI_!!6000000006939-55-tps-800-800.svg\n    title: Debugging Friendly\n    desc: Natural docking with Formily DevTools\n  - icon: https://img.alicdn.com/imgextra/i4/O1CN01u6jHgs1ZMwXpjAYnh_!!6000000003181-55-tps-800-800.svg\n    title: Smart Tips\n    desc: Embrace Typescript\nfooter: Open-source MIT Licensed | Copyright © 2019-present<br />Powered by self\n---\n\n## Installation\n\n```bash\n$ npm install --save @formily/core @formily/react\n\n```\n\n## Quick start\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React, { useMemo } from 'react'\nimport { createForm, setValidateLanguage } from '@formily/core'\nimport {\n  FormProvider,\n  FormConsumer,\n  Field,\n  useField,\n  observer,\n} from '@formily/react'\nimport { Input, Form } from 'antd'\n\n// FormItem UI component\nconst FormItem = observer(({ children }) => {\n  const field = useField()\n  return (\n    <Form.Item\n      label={field.title}\n      help={field.selfErrors?.length ? field.selfErrors : undefined}\n      extra={field.description}\n      validateStatus={field.validateStatus}\n    >\n      {children}\n    </Form.Item>\n  )\n})\n\n/*\n * The above logic has been implemented in @formily/antd, and there is no need to rewrite it in actual use\n */\n\n//Switch the built-in check internationalization copy to English\nsetValidateLanguage('en')\n\nexport default () => {\n  const form = useMemo(() => createForm({ validateFirst: true }))\n\n  const createPasswordEqualValidate = (equalName) => (field) => {\n    if (\n      form.values.confirm_password &&\n      field.value &&\n      form.values[equalName] !== field.value\n    ) {\n      field.selfErrors = ['Password does not match Confirm Password.']\n    } else {\n      field.selfErrors = []\n    }\n  }\n\n  return (\n    <FormProvider form={form}>\n      <Form layout=\"vertical\">\n        <Field\n          name=\"name\"\n          title=\"Name\"\n          required\n          decorator={[FormItem]}\n          component={[Input, { placeholder: 'Please Input' }]}\n        />\n        <Field\n          name=\"password\"\n          title=\"Password\"\n          required\n          decorator={[FormItem]}\n          component={[Input, { type: 'password', placeholder: 'Please Input' }]}\n          reactions={createPasswordEqualValidate('confirm_password')}\n        />\n        <Field\n          name=\"confirm_password\"\n          title=\"Confirm Password\"\n          required\n          decorator={[FormItem]}\n          component={[Input, { type: 'password', placeholder: 'Please Input' }]}\n          reactions={createPasswordEqualValidate('password')}\n        />\n        <code>\n          <pre>\n            <FormConsumer>\n              {(form) => JSON.stringify(form.values, null, 2)}\n            </FormConsumer>\n          </pre>\n        </code>\n      </Form>\n    </FormProvider>\n  )\n}\n```\n"
  },
  {
    "path": "packages/react/docs/index.zh-CN.md",
    "content": "---\ntitle: Formily - 阿里巴巴统一前端表单解决方案\norder: 10\nhero:\n  title: React Library\n  desc: 阿里巴巴统一前端表单解决方案\n  actions:\n    - text: 主站文档\n      link: //formilyjs.org\n    - text: 开发指南\n      link: /zh-CN/guide\nfeatures:\n  - icon: https://img.alicdn.com/imgextra/i1/O1CN01bHdrZJ1rEOESvXEi5_!!6000000005599-55-tps-800-800.svg\n    title: 超高性能\n    desc: 依赖追踪，高效更新，按需渲染\n  - icon: https://img.alicdn.com/imgextra/i2/O1CN016i72sH1c5wh1kyy9U_!!6000000003550-55-tps-800-800.svg\n    title: 开箱即用\n    desc: 组件状态自动绑定，接入成本极低\n  - icon: https://img.alicdn.com/imgextra/i3/O1CN01JHzg8U1FZV5Mvt012_!!6000000000501-55-tps-800-800.svg\n    title: 协议驱动\n    desc: 标准JSON-Schema\n  - icon: https://img.alicdn.com/imgextra/i3/O1CN0194OqFF1ui6mMT4g7O_!!6000000006070-55-tps-800-800.svg\n    title: 场景复用\n    desc: 基于协议驱动，抽象场景组件\n  - icon: https://img.alicdn.com/imgextra/i4/O1CN018vDmpl2186xdLu6KI_!!6000000006939-55-tps-800-800.svg\n    title: 调试友好\n    desc: 天然对接Formily DevTools\n  - icon: https://img.alicdn.com/imgextra/i4/O1CN01u6jHgs1ZMwXpjAYnh_!!6000000003181-55-tps-800-800.svg\n    title: 智能提示\n    desc: 拥抱Typescript\nfooter: Open-source MIT Licensed | Copyright © 2019-present<br />Powered by self\n---\n\n## 安装\n\n```bash\n$ npm install --save @formily/core @formily/react\n\n```\n\n## 快速开始\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React, { useMemo } from 'react'\nimport { createForm, setValidateLanguage } from '@formily/core'\nimport {\n  FormProvider,\n  FormConsumer,\n  Field,\n  useField,\n  observer,\n} from '@formily/react'\nimport { Input, Form } from 'antd'\n\n// FormItem UI组件\nconst FormItem = observer(({ children }) => {\n  const field = useField()\n  return (\n    <Form.Item\n      label={field.title}\n      help={field.selfErrors?.length ? field.selfErrors : undefined}\n      extra={field.description}\n      validateStatus={field.validateStatus}\n    >\n      {children}\n    </Form.Item>\n  )\n})\n\n/*\n * 以上逻辑都已经在 @formily/antd 中实现，实际使用无需重复编写\n */\n\n//切换内置校验国际化文案为英文\nsetValidateLanguage('en')\n\nexport default () => {\n  const form = useMemo(() => createForm({ validateFirst: true }))\n\n  const createPasswordEqualValidate = (equalName) => (field) => {\n    if (\n      form.values.confirm_password &&\n      field.value &&\n      form.values[equalName] !== field.value\n    ) {\n      field.selfErrors = ['Password does not match Confirm Password.']\n    } else {\n      field.selfErrors = []\n    }\n  }\n\n  return (\n    <FormProvider form={form}>\n      <Form layout=\"vertical\">\n        <Field\n          name=\"name\"\n          title=\"Name\"\n          required\n          decorator={[FormItem]}\n          component={[Input, { placeholder: 'Please Input' }]}\n        />\n        <Field\n          name=\"password\"\n          title=\"Password\"\n          required\n          decorator={[FormItem]}\n          component={[Input, { type: 'password', placeholder: 'Please Input' }]}\n          reactions={createPasswordEqualValidate('confirm_password')}\n        />\n        <Field\n          name=\"confirm_password\"\n          title=\"Confirm Password\"\n          required\n          decorator={[FormItem]}\n          component={[Input, { type: 'password', placeholder: 'Please Input' }]}\n          reactions={createPasswordEqualValidate('password')}\n        />\n        <code>\n          <pre>\n            <FormConsumer>\n              {(form) => JSON.stringify(form.values, null, 2)}\n            </FormConsumer>\n          </pre>\n        </code>\n      </Form>\n    </FormProvider>\n  )\n}\n```\n"
  },
  {
    "path": "packages/react/package.json",
    "content": "{\n  \"name\": \"@formily/react\",\n  \"version\": \"2.3.7\",\n  \"license\": \"MIT\",\n  \"main\": \"lib\",\n  \"module\": \"esm\",\n  \"umd:main\": \"dist/formily.react.umd.production.js\",\n  \"unpkg\": \"dist/formily.react.umd.production.js\",\n  \"jsdelivr\": \"dist/formily.react.umd.production.js\",\n  \"jsnext:main\": \"esm\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/alibaba/formily.git\"\n  },\n  \"types\": \"esm/index.d.ts\",\n  \"bugs\": {\n    \"url\": \"https://github.com/alibaba/formily/issues\"\n  },\n  \"homepage\": \"https://github.com/alibaba/formily#readme\",\n  \"engines\": {\n    \"npm\": \">=3.0.0\"\n  },\n  \"scripts\": {\n    \"start\": \"dumi dev\",\n    \"build\": \"rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm && npm run build:umd\",\n    \"build:cjs\": \"tsc --project tsconfig.build.json\",\n    \"build:esm\": \"tsc --project tsconfig.build.json --module es2015 --outDir esm\",\n    \"build:umd\": \"rollup --config\",\n    \"build:docs\": \"dumi build\"\n  },\n  \"peerDependencies\": {\n    \"@types/react\": \">=16.8.0\",\n    \"@types/react-dom\": \">=16.8.0\",\n    \"react\": \">=16.8.0\",\n    \"react-dom\": \">=16.8.0\",\n    \"react-is\": \">=16.8.0\"\n  },\n  \"peerDependenciesMeta\": {\n    \"@types/react\": {\n      \"optional\": true\n    },\n    \"@types/react-dom\": {\n      \"optional\": true\n    }\n  },\n  \"devDependencies\": {\n    \"dumi\": \"^1.1.0-rc.8\"\n  },\n  \"dependencies\": {\n    \"@formily/core\": \"2.3.7\",\n    \"@formily/json-schema\": \"2.3.7\",\n    \"@formily/reactive\": \"2.3.7\",\n    \"@formily/reactive-react\": \"2.3.7\",\n    \"@formily/shared\": \"2.3.7\",\n    \"@formily/validator\": \"2.3.7\",\n    \"hoist-non-react-statics\": \"^3.3.2\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"gitHead\": \"ac79c196ae9324889aca5e0501146f9b37b04283\"\n}\n"
  },
  {
    "path": "packages/react/rollup.config.js",
    "content": "import baseConfig from '../../scripts/rollup.base.js'\n\nexport default baseConfig('formily.react', 'Formily.React')\n"
  },
  {
    "path": "packages/react/src/__tests__/expression.spec.tsx",
    "content": "import React from 'react'\nimport { render, waitFor } from '@testing-library/react'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  ExpressionScope,\n  createSchemaField,\n  useField,\n  Field,\n} from '..'\n\ntest('expression scope', async () => {\n  const Container = (props) => {\n    return (\n      <ExpressionScope value={{ $innerScope: 'this is inner scope value' }}>\n        {props.children}\n      </ExpressionScope>\n    )\n  }\n  const Input = (props) => <div data-testid=\"test-input\">{props.value}</div>\n  const SchemaField = createSchemaField({\n    components: {\n      Container,\n      Input,\n    },\n  })\n  const form = createForm()\n  const { getByTestId } = render(\n    <FormProvider form={form}>\n      <SchemaField scope={{ $outerScope: 'this is outer scope value' }}>\n        <SchemaField.Void x-component=\"Container\">\n          <SchemaField.String\n            name=\"input\"\n            x-component=\"Input\"\n            x-value=\"{{$innerScope + ' ' + $outerScope}}\"\n          />\n        </SchemaField.Void>\n      </SchemaField>\n    </FormProvider>\n  )\n\n  expect(getByTestId('test-input').textContent).toBe(\n    'this is inner scope value this is outer scope value'\n  )\n})\n\ntest('x-compile-omitted', async () => {\n  const form = createForm()\n  const SchemaField = createSchemaField({\n    components: {\n      Input: (props) => (\n        <div data-testid=\"input\">\n          {props.aa}\n          {useField().title}\n          {props.extra}\n        </div>\n      ),\n    },\n  })\n\n  const { queryByTestId } = render(\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"target\"\n          x-compile-omitted={['x-component-props']}\n          title=\"{{123 + '321'}}\"\n          x-component-props={{\n            aa: '{{fake}}',\n            extra: 'extra',\n          }}\n          x-component=\"Input\"\n        />\n        <SchemaField.String name=\"btn\" x-component=\"Button\" />\n      </SchemaField>\n    </FormProvider>\n  )\n  await waitFor(() => {\n    expect(queryByTestId('input')?.textContent).toBe('{{fake}}123321extra')\n  })\n})\n\ntest('field hidden & visible', async () => {\n  const form = createForm({ initialValues: { empty: null } })\n  const { findByTestId } = render(\n    <FormProvider form={form}>\n      <div data-testid=\"testid\">\n        <Field name=\"empty\" component={['input']} />\n      </div>\n    </FormProvider>\n  )\n  await findByTestId('testid')\n  //\n  expect(form.fields.empty.hidden).toBe(false)\n  expect(form.fields.empty.value).toBe(null)\n  form.fields.empty.hidden = true\n  expect(form.fields.empty.hidden).toBe(true)\n  expect(form.fields.empty.value).toBe(null)\n  form.fields.empty.hidden = false\n  expect(form.fields.empty.hidden).toBe(false)\n  expect(form.fields.empty.value).toBe(null)\n  //\n  expect(form.fields.empty.visible).toBe(true)\n  expect(form.fields.empty.value).toBe(null)\n  form.fields.empty.visible = false\n  expect(form.fields.empty.visible).toBe(false)\n  expect(form.fields.empty.value).toBe(undefined)\n  form.fields.empty.visible = true\n  expect(form.fields.empty.visible).toBe(true)\n  expect(form.fields.empty.value).toBe(null)\n})\n"
  },
  {
    "path": "packages/react/src/__tests__/field.spec.tsx",
    "content": "import React from 'react'\nimport { act } from 'react-dom/test-utils'\nimport { render, fireEvent, waitFor } from '@testing-library/react'\nimport { createForm, onFieldUnmount, isArrayField } from '@formily/core'\nimport {\n  isField,\n  Field as FieldType,\n  isVoidField,\n  onFieldChange,\n} from '@formily/core'\nimport {\n  FormProvider,\n  ArrayField,\n  ObjectField,\n  VoidField,\n  Field,\n  useField,\n  useFormEffects,\n  observer,\n  connect,\n  mapProps,\n  mapReadPretty,\n} from '..'\nimport { ReactiveField } from '../components/ReactiveField'\nimport { expectThrowError } from './shared'\n\ntype InputProps = {\n  value?: string\n  onChange?: (...args: any) => void\n}\n\ntype CustomProps = {\n  list?: string[]\n}\n\nconst Decorator = (props) => <div>{props.children}</div>\nconst Input: React.FC<React.PropsWithChildren<InputProps>> = (props) => (\n  <input\n    {...props}\n    value={props.value || ''}\n    data-testid={useField().path.toString()}\n  />\n)\n\nconst Normal = () => <div></div>\n\ntest('render field', async () => {\n  const form = createForm()\n  const onChange = jest.fn()\n  const { getByTestId, queryByTestId, unmount } = render(\n    <FormProvider form={form}>\n      <Field\n        name=\"aa\"\n        decorator={[Decorator]}\n        component={[Input, { onChange }]}\n      />\n      <ArrayField name=\"bb\" decorator={[Decorator]}>\n        <div data-testid=\"bb-children\"></div>\n      </ArrayField>\n      <ObjectField name=\"cc\" decorator={[Decorator]}>\n        <Field name=\"mm\" decorator={[Decorator]} component={[Input]} />\n        <ObjectField name=\"pp\" decorator={[Decorator]} />\n        <ArrayField name=\"tt\" decorator={[Decorator]} />\n        <VoidField name=\"ww\" />\n      </ObjectField>\n      <VoidField name=\"dd\" decorator={[Decorator]}>\n        {() => (\n          <div data-testid=\"dd-children\">\n            <Field name=\"oo\" decorator={[Decorator]} component={[Input]} />\n          </div>\n        )}\n      </VoidField>\n      <VoidField name=\"xx\" decorator={[Decorator]} component={[Normal]} />\n      <Field\n        name=\"ee\"\n        visible={false}\n        decorator={[Decorator]}\n        component={[Input]}\n      />\n      <Field name=\"ff\" decorator={[]} component={[]} />\n      <Field name=\"gg\" decorator={null} component={null} />\n      <Field name=\"hh\" decorator={[null]} component={[null, null]} />\n      <Field\n        name=\"kk\"\n        decorator={[Decorator]}\n        component={[Input, { onChange: null }]}\n      />\n    </FormProvider>\n  )\n  expect(form.mounted).toBeTruthy()\n  expect(form.query('aa').take().mounted).toBeTruthy()\n  expect(form.query('bb').take().mounted).toBeTruthy()\n  expect(form.query('cc').take().mounted).toBeTruthy()\n  expect(form.query('dd').take().mounted).toBeTruthy()\n  fireEvent.change(getByTestId('aa'), {\n    target: {\n      value: '123',\n    },\n  })\n  fireEvent.change(getByTestId('kk'), {\n    target: {\n      value: '123',\n    },\n  })\n  expect(onChange).toBeCalledTimes(1)\n  expect(getByTestId('bb-children')).not.toBeUndefined()\n  expect(getByTestId('dd-children')).not.toBeUndefined()\n  expect(queryByTestId('ee')).toBeNull()\n  expect(form.query('aa').get('value')).toEqual('123')\n  expect(form.query('kk').get('value')).toEqual('123')\n  unmount()\n})\n\ntest('render field no context', () => {\n  expectThrowError(() => {\n    return (\n      <>\n        <Field name=\"aa\">{() => <div></div>}</Field>\n        <ArrayField name=\"bb\">\n          <div></div>\n        </ArrayField>\n        <ObjectField name=\"cc\" />\n        <VoidField name=\"dd\" />\n      </>\n    )\n  })\n})\n\ntest('ReactiveField', () => {\n  render(<ReactiveField field={null} />)\n  render(<ReactiveField field={null}>{() => <div></div>}</ReactiveField>)\n})\n\ntest('useAttach basic', async () => {\n  const form = createForm()\n  const MyComponent = (props: any) => {\n    return (\n      <FormProvider form={form}>\n        <Field name={props.name} decorator={[Decorator]} component={[Input]} />\n      </FormProvider>\n    )\n  }\n  const { rerender } = render(<MyComponent name=\"aa\" />)\n  expect(form.query('aa').take().mounted).toBeTruthy()\n  rerender(<MyComponent name=\"bb\" />)\n  await waitFor(() => {\n    expect(form.query('aa').take().mounted).toBeFalsy()\n    expect(form.query('bb').take().mounted).toBeTruthy()\n  })\n})\n\ntest('useAttach with array field', async () => {\n  const form = createForm()\n  const MyComponent = () => {\n    return (\n      <FormProvider form={form}>\n        <ArrayField\n          name=\"array\"\n          initialValue={[{ input: '11' }, { input: '22' }]}\n        >\n          {(field) => {\n            return field.value.map((val, index) => {\n              return (\n                <Field\n                  key={index}\n                  name={index + '.input'}\n                  decorator={[Decorator]}\n                  component={[Input]}\n                />\n              )\n            })\n          }}\n        </ArrayField>\n      </FormProvider>\n    )\n  }\n  render(<MyComponent />)\n  await waitFor(() => {\n    expect(form.query('array.0.input').take().mounted).toBeTruthy()\n    expect(form.query('array.1.input').take().mounted).toBeTruthy()\n  })\n  form.query('array').take((field) => {\n    if (isArrayField(field)) {\n      field.moveDown(0)\n    }\n  })\n  await waitFor(() => {\n    expect(form.query('array.0.input').take().mounted).toBeTruthy()\n    expect(form.query('array.1.input').take().mounted).toBeTruthy()\n  })\n})\n\ntest('useFormEffects', async () => {\n  const form = createForm()\n  const CustomField = observer(() => {\n    const field = useField<FieldType>()\n    useFormEffects(() => {\n      onFieldChange('aa', ['value'], (target) => {\n        if (isVoidField(target)) return\n        field.setValue(target.value)\n      })\n    })\n    return <div data-testid=\"custom-value\">{field.value}</div>\n  })\n  act(async () => {\n    const { queryByTestId, rerender } = render(\n      <FormProvider form={form}>\n        <Field name=\"aa\" decorator={[Decorator]} component={[Input]} />\n        <Field name=\"bb\" component={[CustomField, { tag: 'xxx' }]} />\n      </FormProvider>\n    )\n\n    expect(queryByTestId('custom-value')?.textContent).toEqual('')\n    form.query('aa').take((aa) => {\n      if (isField(aa)) {\n        aa.setValue('123')\n      }\n    })\n    await waitFor(() => {\n      expect(queryByTestId('custom-value')?.textContent).toEqual('123')\n    })\n    rerender(\n      <FormProvider form={form}>\n        <Field name=\"aa\" decorator={[Decorator]} component={[Input]} />\n        <Field name=\"bb\" component={[CustomField, { tag: 'yyy' }]} />\n      </FormProvider>\n    )\n  })\n})\n\ntest('connect', async () => {\n  const CustomField = connect(\n    (props: CustomProps) => {\n      return <div>{props.list}</div>\n    },\n    mapProps({ value: 'list', loading: true }, (props, field) => {\n      return {\n        ...props,\n        mounted: field.mounted ? 1 : 2,\n      }\n    }),\n    mapReadPretty(() => <div>read pretty</div>)\n  )\n  const BaseComponent = (props: any) => {\n    return <div>{props.value}</div>\n  }\n  BaseComponent.displayName = 'BaseComponent'\n  const CustomField2 = connect(\n    BaseComponent,\n    mapProps({ value: true, loading: true }),\n    mapReadPretty(() => <div>read pretty</div>)\n  )\n  const form = createForm()\n  const MyComponent = () => {\n    return (\n      <FormProvider form={form}>\n        <Field name=\"aa\" decorator={[Decorator]} component={[CustomField]} />\n        <Field name=\"bb\" decorator={[Decorator]} component={[CustomField2]} />\n      </FormProvider>\n    )\n  }\n  const { queryByText } = render(<MyComponent />)\n  form.query('aa').take((field) => {\n    field.setState((state) => {\n      state.value = '123'\n    })\n  })\n  await waitFor(() => {\n    expect(queryByText('123')).toBeVisible()\n  })\n\n  form.query('aa').take((field) => {\n    if (!isField(field)) return\n    field.readPretty = true\n  })\n  await waitFor(() => {\n    expect(queryByText('123')).toBeNull()\n    expect(queryByText('read pretty')).toBeVisible()\n  })\n})\n\ntest('fields unmount and validate', async () => {\n  const fn = jest.fn()\n  const form = createForm({\n    initialValues: {\n      parent: {\n        type: 'mounted',\n      },\n    },\n    effects: () => {\n      onFieldUnmount('parent.child', () => {\n        fn()\n      })\n    },\n  })\n  const Parent = observer(() => {\n    const field = useField<FieldType>()\n    if (field.value.type === 'mounted') {\n      return (\n        <Field\n          name=\"child\"\n          component={[Input]}\n          validator={{ required: true }}\n        />\n      )\n    }\n    return <div data-testid=\"unmounted\"></div>\n  })\n\n  const MyComponent = () => {\n    return (\n      <FormProvider form={form}>\n        <Field name=\"parent\" component={[Parent]} />\n      </FormProvider>\n    )\n  }\n  render(<MyComponent />)\n\n  try {\n    await form.validate()\n  } catch {}\n\n  expect(form.invalid).toBeTruthy()\n\n  form.query('parent').take((field) => {\n    field.setState((state) => {\n      state.value.type = 'unmounted'\n    })\n  })\n\n  await waitFor(() => {\n    expect(fn.mock.calls.length).toBe(1)\n  })\n\n  try {\n    await form.validate()\n  } catch {}\n  expect(form.invalid).toBeTruthy()\n})\n"
  },
  {
    "path": "packages/react/src/__tests__/form.spec.tsx",
    "content": "import React from 'react'\nimport { render } from '@testing-library/react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, ObjectField, VoidField, Field } from '../'\nimport { FormConsumer } from '../components'\nimport { useParentForm } from '../hooks'\n\ntest('render form', () => {\n  const form = createForm()\n  render(\n    <FormProvider form={form}>\n      <FormConsumer>{(form) => `${form.mounted}`}</FormConsumer>\n      <FormConsumer />\n    </FormProvider>\n  )\n  expect(form.mounted).toBeTruthy()\n})\n\nconst DisplayParentForm: React.FC<\n  React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>\n> = (props) => {\n  return <div {...props}>{useParentForm()?.displayName}</div>\n}\n\ntest('useParentForm', () => {\n  const form = createForm()\n  const { queryByTestId } = render(\n    <FormProvider form={form}>\n      <ObjectField name=\"aa\">\n        <Field name=\"bb\">\n          <DisplayParentForm data-testid=\"111\" />\n        </Field>\n      </ObjectField>\n      <VoidField name=\"cc\">\n        <Field name=\"dd\">\n          <DisplayParentForm data-testid=\"222\" />\n        </Field>\n      </VoidField>\n      <DisplayParentForm data-testid=\"333\" />\n    </FormProvider>\n  )\n\n  expect(queryByTestId('111').textContent).toBe('ObjectField')\n  expect(queryByTestId('222').textContent).toBe('Form')\n  expect(queryByTestId('333').textContent).toBe('Form')\n})\n"
  },
  {
    "path": "packages/react/src/__tests__/schema.json.spec.tsx",
    "content": "import React from 'react'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '../index'\nimport { Schema } from '@formily/json-schema'\nimport { render } from '@testing-library/react'\n\nconst Input = ({ value, onChange }) => {\n  return <input data-testid=\"input\" value={value || ''} onChange={onChange} />\n}\n\nimport { Button, Rate } from 'antd'\nimport { SearchOutlined, DollarOutlined } from '@ant-design/icons'\n\ndescribe('json schema field', () => {\n  test('string field', () => {\n    const form = createForm()\n    const SchemaField = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    const { queryByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField\n          name=\"string\"\n          schema={\n            new Schema({\n              type: 'string',\n              default: '123',\n              'x-component': 'Input',\n            })\n          }\n        />\n      </FormProvider>\n    )\n    expect(queryByTestId('input')).toBeVisible()\n    expect(queryByTestId('input')?.getAttribute('value')).toEqual('123')\n  })\n  test('object field', () => {\n    const form = createForm()\n    const SchemaField = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    const { queryByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField\n          name=\"object\"\n          schema={{\n            type: 'object',\n            properties: {\n              string: {\n                type: 'string',\n                'x-component': 'Input',\n              },\n            },\n          }}\n        />\n      </FormProvider>\n    )\n    expect(queryByTestId('input')).toBeVisible()\n  })\n  test('x-component-props children', () => {\n    const form = createForm()\n    const Text: React.FC = ({ children }) => {\n      return <div data-testid=\"children-test\">{children}</div>\n    }\n    const SchemaField = createSchemaField({\n      components: {\n        Text,\n      },\n    })\n    const { queryByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField\n          name=\"object\"\n          schema={{\n            type: 'object',\n            properties: {\n              string: {\n                type: 'string',\n                'x-component': 'Text',\n                'x-component-props': {\n                  children: 'children',\n                },\n              },\n            },\n          }}\n        />\n      </FormProvider>\n    )\n    expect(queryByTestId('children-test')).toBeVisible()\n    expect(queryByTestId('children-test')?.innerHTML).toEqual('children')\n  })\n  test('x-content', async () => {\n    const form = createForm()\n    const Text: React.FC = ({ children }) => {\n      return <div data-testid=\"content-test\">{children}</div>\n    }\n    const SchemaField = createSchemaField({\n      components: {\n        Text,\n      },\n    })\n    const { queryByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField\n          name=\"object\"\n          schema={{\n            type: 'object',\n            properties: {\n              string: {\n                type: 'string',\n                'x-component': 'Text',\n                'x-content': 'content',\n              },\n            },\n          }}\n        />\n      </FormProvider>\n    )\n    expect(queryByTestId('content-test')).toBeVisible()\n    expect(queryByTestId('content-test')?.innerHTML).toEqual('content')\n  })\n  test('x-slot-node', () => {\n    const form = createForm()\n    const SchemaField = createSchemaField({\n      components: {\n        SearchOutlined,\n        Button,\n      },\n    })\n    const { queryByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField\n          name=\"object\"\n          schema={{\n            type: 'object',\n            properties: {\n              icon: {\n                'x-slot-node': {\n                  target: 'button.x-component-props.icon',\n                },\n                'x-component': 'SearchOutlined',\n                'x-component-props': {\n                  'data-testid': 'icon',\n                },\n              },\n              button: {\n                type: 'string',\n                'x-component': 'Button',\n                'x-component-props': {\n                  'data-testid': 'button',\n                },\n              },\n            },\n          }}\n        />\n      </FormProvider>\n    )\n    const button = queryByTestId('button')\n    const icon = queryByTestId('icon')\n\n    expect(button).toContainElement(icon)\n  })\n  test('x-slot-node render prop', async () => {\n    const form = createForm()\n    const SchemaField = createSchemaField({\n      components: {\n        Rate,\n        DollarOutlined,\n      },\n    })\n    const { queryByRole, queryAllByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField\n          name=\"object\"\n          schema={{\n            type: 'object',\n            properties: {\n              icon: {\n                'x-slot-node': {\n                  target: 'rate.x-component-props.character',\n                  isRenderProp: true,\n                },\n                'x-component': 'DollarOutlined',\n                'x-component-props': {\n                  'data-testid': 'icon',\n                  rotate: '{{$slotArgs[0].value * 45}}',\n                  style: {\n                    fontSize: '{{`${$slotArgs[0].value * 10}px`}}',\n                  },\n                },\n              },\n              rate: {\n                'x-component': 'Rate',\n                'x-component-props': {\n                  defaultValue: 2,\n                },\n              },\n            },\n          }}\n        />\n      </FormProvider>\n    )\n\n    const rate = queryByRole('radiogroup')\n    expect(rate).toBeVisible()\n    const icons = queryAllByTestId('icon')\n    expect(icons).toHaveLength(10)\n    icons.forEach((icon) => {\n      expect(rate).toContainElement(icon)\n    })\n\n    const style = window.getComputedStyle(icons[0])\n    const fontSize = style.fontSize\n    expect(fontSize).toBe('20px')\n  })\n})\n"
  },
  {
    "path": "packages/react/src/__tests__/schema.markup.spec.tsx",
    "content": "import React from 'react'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  createSchemaField,\n  useFieldSchema,\n  useField,\n  RecursionField,\n  RecordScope,\n  RecordsScope,\n} from '../index'\nimport { render, fireEvent, waitFor, act } from '@testing-library/react'\n\nconst Input: React.FC<{\n  value?: string\n  onChange?: (...args: any) => void\n  [key: string]: any\n}> = ({ value, onChange, ...others }) => {\n  return (\n    <input\n      data-testid=\"input\"\n      {...others}\n      value={value || ''}\n      onChange={onChange}\n    />\n  )\n}\n\ndescribe('markup schema field', () => {\n  test('string', () => {\n    const form = createForm()\n    const SchemaField = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    const { queryByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.String x-component=\"Input\" />\n        </SchemaField>\n      </FormProvider>\n    )\n    expect(queryByTestId('input')).toBeVisible()\n  })\n  test('boolean', () => {\n    const form = createForm()\n    const SchemaField = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    const { queryByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.Boolean x-component=\"Input\" />\n        </SchemaField>\n      </FormProvider>\n    )\n    expect(queryByTestId('input')).toBeVisible()\n  })\n  test('number', () => {\n    const form = createForm()\n    const SchemaField = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    const { queryByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.Number x-component=\"Input\" />\n        </SchemaField>\n      </FormProvider>\n    )\n    expect(queryByTestId('input')).toBeVisible()\n  })\n  test('date', () => {\n    const form = createForm()\n    const SchemaField = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    const { queryByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.Date x-component=\"Input\" />\n        </SchemaField>\n      </FormProvider>\n    )\n    expect(queryByTestId('input')).toBeVisible()\n  })\n  test('datetime', () => {\n    const form = createForm()\n    const SchemaField = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    const { queryByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.DateTime x-component=\"Input\" />\n        </SchemaField>\n      </FormProvider>\n    )\n    expect(queryByTestId('input')).toBeVisible()\n  })\n  test('void', () => {\n    const form = createForm()\n    const VoidComponent = (props) => {\n      return <div data-testid=\"void-component\">{props.children}</div>\n    }\n    const SchemaField = createSchemaField({\n      components: {\n        VoidComponent,\n      },\n    })\n    const { queryByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.Void x-component=\"VoidComponent\" />\n        </SchemaField>\n      </FormProvider>\n    )\n    expect(queryByTestId('void-component')).toBeVisible()\n  })\n  test('array', () => {\n    const form = createForm()\n    const SchemaField = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    render(\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.Array>\n            <SchemaField.Object>\n              <SchemaField.String x-component=\"Input\" />\n            </SchemaField.Object>\n            <SchemaField.Void />\n          </SchemaField.Array>\n        </SchemaField>\n      </FormProvider>\n    )\n  })\n  test('other', () => {\n    const form = createForm()\n    const SchemaField = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    render(\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.Markup type=\"other\">\n            <SchemaField.Markup />\n          </SchemaField.Markup>\n        </SchemaField>\n      </FormProvider>\n    )\n  })\n  test('no parent', () => {\n    const form = createForm()\n    const SchemaField = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    render(\n      <FormProvider form={form}>\n        <SchemaField.Markup type=\"other\">\n          <SchemaField.Markup />\n        </SchemaField.Markup>\n      </FormProvider>\n    )\n  })\n  test('props children', () => {\n    const form = createForm()\n    const Text = (props) => {\n      return <div data-testid=\"children-test\">{props.children}</div>\n    }\n    const SchemaField = createSchemaField({\n      components: {\n        Text,\n      },\n    })\n    const { queryByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.Void\n            x-component=\"Text\"\n            x-component-props={{ children: 'props' }}\n          />\n        </SchemaField>\n      </FormProvider>\n    )\n    expect(queryByTestId('children-test')).toBeVisible()\n    expect(queryByTestId('children-test').innerHTML).toEqual('props')\n  })\n  test('x-content', () => {\n    const form = createForm()\n    const Text = (props) => {\n      return <div data-testid=\"content-test\">{props.children}</div>\n    }\n    const SchemaField = createSchemaField({\n      components: {\n        Text,\n      },\n    })\n    const { queryByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.Void x-component=\"Text\" x-content=\"content\" />\n        </SchemaField>\n      </FormProvider>\n    )\n    expect(queryByTestId('content-test')).toBeVisible()\n    expect(queryByTestId('content-test').innerHTML).toEqual('content')\n  })\n})\n\ndescribe('recursion field', () => {\n  test('onlyRenderProperties', () => {\n    const form = createForm()\n    const CustomObject: React.FC = () => {\n      const schema = useFieldSchema()\n      return (\n        <div data-testid=\"object\">\n          <RecursionField schema={schema} />\n        </div>\n      )\n    }\n    const CustomObject2: React.FC = () => {\n      const field = useField()\n      const schema = useFieldSchema()\n      return (\n        <div data-testid=\"only-properties\">\n          <RecursionField\n            name={schema.name}\n            basePath={field.address}\n            schema={schema}\n            onlyRenderProperties\n          />\n        </div>\n      )\n    }\n    const SchemaField = createSchemaField({\n      components: {\n        Input,\n        CustomObject,\n        CustomObject2,\n      },\n    })\n    const { queryAllByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.Object x-component=\"CustomObject\">\n            <SchemaField.String x-component=\"Input\" />\n          </SchemaField.Object>\n          <SchemaField.Object x-component=\"CustomObject2\">\n            <SchemaField.String x-component=\"Input\" />\n          </SchemaField.Object>\n          <SchemaField.Void x-component=\"CustomObject2\">\n            <SchemaField.String x-component=\"Input\" />\n          </SchemaField.Void>\n        </SchemaField>\n      </FormProvider>\n    )\n    expect(queryAllByTestId('input').length).toEqual(3)\n    expect(queryAllByTestId('object').length).toEqual(1)\n    expect(queryAllByTestId('only-properties').length).toEqual(2)\n  })\n\n  test('mapProperties', () => {\n    const form = createForm()\n    const CustomObject: React.FC = () => {\n      const schema = useFieldSchema()\n      return (\n        <div data-testid=\"object\">\n          <RecursionField\n            schema={schema}\n            mapProperties={(schema) => {\n              schema.default = '123'\n              return schema\n            }}\n          />\n        </div>\n      )\n    }\n    const CustomObject2: React.FC = () => {\n      const schema = useFieldSchema()\n      return (\n        <div data-testid=\"object\">\n          <RecursionField\n            schema={schema}\n            mapProperties={() => {\n              return null\n            }}\n          />\n        </div>\n      )\n    }\n    const SchemaField = createSchemaField({\n      components: {\n        Input,\n        CustomObject,\n        CustomObject2,\n      },\n    })\n    const { queryAllByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.Object x-component=\"CustomObject\">\n            <SchemaField.String x-component=\"Input\" />\n          </SchemaField.Object>\n          <SchemaField.Object x-component=\"CustomObject2\">\n            <SchemaField.String x-component=\"Input\" />\n          </SchemaField.Object>\n        </SchemaField>\n      </FormProvider>\n    )\n    expect(queryAllByTestId('input').length).toEqual(2)\n    expect(queryAllByTestId('input')[0].getAttribute('value')).toEqual('123')\n    expect(queryAllByTestId('input')[1].getAttribute('value')).toEqual('')\n  })\n\n  test('filterProperties', () => {\n    const form = createForm()\n    const CustomObject: React.FC = () => {\n      const schema = useFieldSchema()\n      return (\n        <div data-testid=\"object\">\n          <RecursionField\n            schema={schema}\n            filterProperties={(schema) => {\n              if (schema['x-component'] === 'Input') return false\n              return true\n            }}\n          />\n        </div>\n      )\n    }\n    const CustomObject2: React.FC = () => {\n      const schema = useFieldSchema()\n      return (\n        <div data-testid=\"object\">\n          <RecursionField\n            schema={schema}\n            filterProperties={(schema) => {\n              if (schema['x-component'] === 'Input') return true\n              return false\n            }}\n          />\n        </div>\n      )\n    }\n    const SchemaField = createSchemaField({\n      components: {\n        Input,\n        CustomObject,\n        CustomObject2,\n      },\n    })\n    const { queryAllByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.Object x-component=\"CustomObject\">\n            <SchemaField.String x-component=\"Input\" />\n          </SchemaField.Object>\n          <SchemaField.Object x-component=\"CustomObject2\">\n            <SchemaField.String x-component=\"Input\" />\n          </SchemaField.Object>\n        </SchemaField>\n      </FormProvider>\n    )\n    expect(queryAllByTestId('input').length).toEqual(1)\n    expect(queryAllByTestId('object').length).toEqual(2)\n  })\n\n  test('onlyRenderSelf', () => {\n    const form = createForm()\n    const CustomObject: React.FC = () => {\n      const schema = useFieldSchema()\n      return (\n        <div data-testid=\"object\">\n          <RecursionField schema={schema} onlyRenderSelf />\n        </div>\n      )\n    }\n    const SchemaField = createSchemaField({\n      components: {\n        Input,\n        CustomObject,\n      },\n    })\n    const { queryAllByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.Object x-component=\"CustomObject\">\n            <SchemaField.String x-component=\"Input\" />\n          </SchemaField.Object>\n        </SchemaField>\n      </FormProvider>\n    )\n    expect(queryAllByTestId('input').length).toEqual(0)\n    expect(queryAllByTestId('object').length).toEqual(1)\n  })\n\n  test('illegal schema', () => {\n    const form = createForm()\n    const CustomObject: React.FC = () => {\n      return (\n        <div data-testid=\"object\">\n          <RecursionField schema={null} />\n        </div>\n      )\n    }\n    const CustomObject2: React.FC = () => {\n      return (\n        <div data-testid=\"object\">\n          <RecursionField schema={{} as any} />\n        </div>\n      )\n    }\n    const SchemaField = createSchemaField({\n      components: {\n        Input,\n        CustomObject,\n        CustomObject2,\n      },\n    })\n    const { queryByTestId } = render(\n      <FormProvider form={form}>\n        <SchemaField>\n          <SchemaField.Object x-component=\"CustomObject\">\n            <SchemaField.String x-component=\"Input\" />\n          </SchemaField.Object>\n          <SchemaField.Object x-component=\"CustomObject2\">\n            <SchemaField.String x-component=\"Input\" />\n          </SchemaField.Object>\n        </SchemaField>\n      </FormProvider>\n    )\n    expect(queryByTestId('input')).toBeNull()\n  })\n})\n\ntest('schema reactions', async () => {\n  const form = createForm()\n  const SchemaField = createSchemaField({\n    components: {\n      Input,\n    },\n  })\n  const { queryByTestId } = render(\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"aaa\"\n          x-component=\"Input\"\n          x-component-props={{\n            'data-testid': 'aaa',\n          }}\n        />\n        <SchemaField.String\n          name=\"bbb\"\n          x-component=\"Input\"\n          x-component-props={{\n            'data-testid': 'bbb',\n          }}\n          x-reactions={[\n            {\n              when: '{{$form.values.aaa === \"123\"}}',\n              fulfill: {\n                state: {\n                  visible: true,\n                },\n              },\n              otherwise: {\n                state: {\n                  visible: false,\n                },\n              },\n            },\n            {\n              when: '{{$self.value === \"123\"}}',\n              target: 'ccc',\n              fulfill: {\n                schema: {\n                  'x-visible': true,\n                },\n              },\n              otherwise: {\n                schema: {\n                  'x-visible': false,\n                },\n              },\n            },\n          ]}\n        />\n        <SchemaField.String\n          name=\"ccc\"\n          x-component=\"Input\"\n          x-component-props={{\n            'data-testid': 'ccc',\n          }}\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n  expect(queryByTestId('bbb')).toBeNull()\n  fireEvent.change(queryByTestId('aaa'), {\n    target: {\n      value: '123',\n    },\n  })\n  await waitFor(() => {\n    expect(queryByTestId('bbb')).toBeVisible()\n  })\n  expect(queryByTestId('ccc')).toBeNull()\n  fireEvent.change(queryByTestId('bbb'), {\n    target: {\n      value: '123',\n    },\n  })\n  await waitFor(() => {\n    expect(queryByTestId('ccc')).toBeVisible()\n  })\n})\n\ntest('expression scope', async () => {\n  let aa = false\n  let bb = false\n  let cc = false\n  const form = createForm()\n  const SchemaField = createSchemaField({\n    components: {\n      Input,\n    },\n    scope: {\n      aa() {\n        aa = true\n      },\n    },\n  })\n\n  const scope = {\n    bb() {\n      bb = true\n    },\n    cc() {\n      cc = true\n    },\n  }\n\n  const schema = {\n    type: 'object',\n    properties: {\n      aa: {\n        type: 'string',\n        'x-component': 'Input',\n        'x-reactions': '{{ aa }}',\n      },\n      bb: {\n        type: 'string',\n        'x-component': 'Input',\n        'x-reactions': '{{ bb }}',\n      },\n      cc: {\n        type: 'string',\n        'x-component': 'Input',\n        'x-reactions': {\n          dependencies: ['aa'],\n          fulfill: {\n            run: 'cc()',\n          },\n        },\n      },\n    },\n  }\n\n  const { queryByTestId } = render(\n    <FormProvider form={form}>\n      <SchemaField schema={schema} scope={scope} />\n    </FormProvider>\n  )\n\n  await waitFor(() => queryByTestId('aa'))\n  expect(aa).toBeTruthy()\n\n  await waitFor(() => queryByTestId('bb'))\n  expect(bb).toBeTruthy()\n\n  await waitFor(() => queryByTestId('cc'))\n  expect(cc).toBeTruthy()\n})\n\ntest('expression x-content', async () => {\n  const form = createForm()\n  const SchemaField = createSchemaField({\n    components: {\n      Wrapper: (props) => props.children,\n    },\n    scope: {\n      child: <div data-testid=\"child\"></div>,\n    },\n  })\n\n  const { queryByTestId } = render(\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"aaa\"\n          x-component=\"Wrapper\"\n          x-content=\"{{child}}\"\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n\n  await waitFor(() => {\n    expect(queryByTestId('child')).not.toBeUndefined()\n  })\n})\n\ntest('expression x-visible', async () => {\n  const form = createForm()\n  const SchemaField = createSchemaField({\n    components: {\n      AAA: () => <div>AAA</div>,\n      BBB: () => <div>BBB</div>,\n    },\n  })\n\n  const { queryByText } = render(\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String name=\"aaa\" x-component=\"AAA\" />\n        <SchemaField.String\n          name=\"bbb\"\n          x-component=\"BBB\"\n          x-visible=\"{{$form.values.aaa === 123}}\"\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n\n  await waitFor(() => {\n    expect(queryByText('BBB')).toBeNull()\n  })\n  act(() => {\n    form.values.aaa = 123\n  })\n  await waitFor(() => {\n    expect(queryByText('BBB')).not.toBeNull()\n  })\n})\n\ntest('expression x-value', async () => {\n  const form = createForm({\n    values: {\n      aaa: 1,\n    },\n  })\n  const SchemaField = createSchemaField({\n    components: {\n      Text: (props) => <div>{props.value}</div>,\n    },\n  })\n\n  const { queryByText } = render(\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String name=\"aaa\" x-component=\"Text\" />\n        <SchemaField.String\n          name=\"bbb\"\n          x-component=\"Text\"\n          x-value=\"{{$form.values.aaa * 10}}\"\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n\n  await waitFor(() => {\n    expect(queryByText('10')).not.toBeNull()\n  })\n  act(() => {\n    form.values.aaa = 10\n  })\n  await waitFor(() => {\n    expect(queryByText('100')).not.toBeNull()\n  })\n})\n\ntest('nested update component props with expression', async () => {\n  const form = createForm({\n    values: {\n      aaa: 'xxx',\n    },\n  })\n  const SchemaField = createSchemaField({\n    components: {\n      Text: (props) => <div>{props.aa?.bb?.cc}</div>,\n    },\n  })\n\n  const { queryByText } = render(\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String name=\"aaa\" x-component=\"Text\" />\n        <SchemaField.String\n          name=\"bbb\"\n          x-component=\"Text\"\n          x-component-props={{ aa: { bb: { cc: '{{$form.values.aaa}}' } } }}\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n  await waitFor(() => {\n    expect(queryByText('xxx')).not.toBeNull()\n  })\n  act(() => {\n    form.values.aaa = '10'\n  })\n  await waitFor(() => {\n    expect(queryByText('10')).not.toBeNull()\n  })\n})\n\ntest('nested update component props with x-reactions', async () => {\n  const form = createForm({\n    values: {\n      aaa: 'xxx',\n    },\n  })\n  const SchemaField = createSchemaField({\n    components: {\n      Text: (props) => <div>{props.aa?.bb?.cc}</div>,\n    },\n  })\n\n  const { queryByText } = render(\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String name=\"aaa\" x-component=\"Text\" />\n        <SchemaField.String\n          name=\"bbb\"\n          x-component=\"Text\"\n          x-reactions={{\n            fulfill: {\n              schema: {\n                'x-component-props.aa.bb.cc': '{{$form.values.aaa}}',\n              } as any,\n            },\n          }}\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n  await waitFor(() => {\n    expect(queryByText('xxx')).not.toBeNull()\n  })\n  act(() => {\n    form.values.aaa = '10'\n  })\n  await waitFor(() => {\n    expect(queryByText('10')).not.toBeNull()\n  })\n})\n\ntest('schema x-validator/required', async () => {\n  const form = createForm({\n    values: {\n      aaa: 'xxx',\n    },\n  })\n  const SchemaField = createSchemaField({\n    components: {\n      Input: () => <div></div>,\n    },\n  })\n\n  render(\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"input\"\n          required\n          x-validator=\"email\"\n          x-component=\"Input\"\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n  await waitFor(() => {\n    expect(form.query('input').get('required')).toBeTruthy()\n    expect(form.query('input').get('validator')).toEqual([\n      { required: true },\n      { format: 'email' },\n    ])\n  })\n})\n\ntest('schema x-reactions when undefined', async () => {\n  const form = createForm({\n    values: {\n      aaa: 'xxx',\n    },\n  })\n  const SchemaField = createSchemaField({\n    components: {\n      Input: () => <div data-testid=\"input\"></div>,\n      Select: () => <div data-testid=\"select\"></div>,\n    },\n  })\n\n  const { queryByTestId } = render(\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String name=\"input\" required x-component=\"Input\" />\n        <SchemaField.String\n          name=\"select\"\n          required\n          x-component=\"Select\"\n          x-reactions={{\n            when: '{{$values.input}}',\n            fulfill: {\n              state: {\n                visible: true,\n              },\n            },\n            otherwise: {\n              state: {\n                visible: false,\n              },\n            },\n          }}\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n  await waitFor(() => {\n    expect(queryByTestId('input')).not.toBeNull()\n    expect(queryByTestId('select')).toBeNull()\n  })\n})\n\ntest('void field children', async () => {\n  const form = createForm()\n  const SchemaField = createSchemaField({\n    components: {\n      Button: (props) => (\n        <div data-testid=\"btn\">{props.children || 'placeholder'}</div>\n      ),\n    },\n  })\n\n  const { queryByTestId } = render(\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Void x-component=\"Button\" />\n      </SchemaField>\n    </FormProvider>\n  )\n  await waitFor(() => {\n    expect(queryByTestId('btn')?.textContent).toBe('placeholder')\n  })\n})\n\ntest('x-reactions runner for target', async () => {\n  const form = createForm()\n  const getTarget = jest.fn()\n  const SchemaField = createSchemaField({\n    components: {\n      Input: () => <div></div>,\n      Button: (props) => (\n        <button\n          data-testid=\"btn\"\n          onClick={(e) => {\n            e.preventDefault()\n            props.onChange('123')\n          }}\n        >\n          Click {props.value}\n        </button>\n      ),\n    },\n    scope: {\n      getTarget,\n    },\n  })\n\n  const { getByTestId } = render(\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String name=\"target\" default=\"333\" x-component=\"Input\" />\n        <SchemaField.String\n          x-component=\"Button\"\n          x-reactions={{\n            target: 'target',\n            effects: ['onFieldInputValueChange'],\n            fulfill: {\n              run: 'getTarget($target.value)',\n            },\n          }}\n        />\n      </SchemaField>\n    </FormProvider>\n  )\n  fireEvent.click(getByTestId('btn'))\n  await waitFor(() => {\n    expect(getByTestId('btn').textContent).toBe('Click 123')\n    expect(getTarget).toBeCalledWith('333')\n    expect(getTarget).toBeCalledTimes(1)\n  })\n})\n\ntest('multi x-reactions isolate effect', async () => {\n  const form = createForm()\n  const otherEffect = jest.fn()\n  const SchemaField = createSchemaField({\n    components: {\n      Input: () => <div data-testid=\"input\"></div>,\n      Button: (props) => (\n        <button\n          data-testid=\"btn\"\n          onClick={(e) => {\n            e.preventDefault()\n            props.onChange('123')\n          }}\n        >\n          Click {props.value}\n        </button>\n      ),\n    },\n  })\n\n  const { getByTestId, queryByTestId } = render(\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.String\n          name=\"target\"\n          x-reactions={[\n            otherEffect,\n            {\n              dependencies: ['btn'],\n              fulfill: {\n                state: {\n                  visible: '{{$deps[0] === \"123\"}}',\n                },\n              },\n            },\n          ]}\n          x-component=\"Input\"\n        />\n        <SchemaField.String name=\"btn\" x-component=\"Button\" />\n      </SchemaField>\n    </FormProvider>\n  )\n  await waitFor(() => {\n    expect(queryByTestId('input')).toBeNull()\n  })\n  fireEvent.click(getByTestId('btn'))\n  await waitFor(() => {\n    expect(getByTestId('btn').textContent).toBe('Click 123')\n    expect(getByTestId('input')).not.toBeNull()\n    expect(otherEffect).toBeCalledTimes(1)\n  })\n})\n\ntest('nested record scope', async () => {\n  const form = createForm()\n  const SchemaField = createSchemaField({\n    components: {\n      Text: (props) => <div data-testid=\"text\">{props.text}</div>,\n    },\n  })\n\n  const { queryByTestId } = render(\n    <FormProvider form={form}>\n      <RecordScope getRecord={() => ({ bb: '321' })} getIndex={() => 1}>\n        <RecordScope getRecord={() => ({ aa: '123' })} getIndex={() => 2}>\n          <SchemaField>\n            <SchemaField.Void\n              x-component=\"Text\"\n              x-component-props={{\n                text: '{{$record.aa + $record.$lookup.bb + $index + $lookup.$index}}',\n              }}\n            />\n          </SchemaField>\n        </RecordScope>\n      </RecordScope>\n    </FormProvider>\n  )\n  await waitFor(() => {\n    expect(queryByTestId('text')?.textContent).toBe('12332121')\n  })\n})\n\ntest('literal record scope', async () => {\n  const form = createForm()\n  const SchemaField = createSchemaField({\n    components: {\n      Text: (props) => <div data-testid=\"text\">{props.text}</div>,\n    },\n  })\n\n  const { queryByTestId } = render(\n    <FormProvider form={form}>\n      <RecordScope getRecord={() => '123'} getIndex={() => 2}>\n        <SchemaField>\n          <SchemaField.Void\n            x-component=\"Text\"\n            x-component-props={{\n              text: '{{$record + $index}}',\n            }}\n          />\n        </SchemaField>\n      </RecordScope>\n    </FormProvider>\n  )\n  await waitFor(() => {\n    expect(queryByTestId('text')?.textContent).toBe('1232')\n  })\n})\n\ntest('records scope', async () => {\n  const form = createForm()\n  const SchemaField = createSchemaField({\n    components: {\n      Text: (props) => <div data-testid=\"text\">{props.text}</div>,\n    },\n  })\n\n  const { queryByTestId } = render(\n    <FormProvider form={form}>\n      <RecordsScope getRecords={() => [1, 2, 3]}>\n        <SchemaField>\n          <SchemaField.Void\n            x-component=\"Text\"\n            x-component-props={{\n              text: '{{$records[2]}}',\n            }}\n          />\n        </SchemaField>\n      </RecordsScope>\n    </FormProvider>\n  )\n  await waitFor(() => {\n    expect(queryByTestId('text')?.textContent).toBe('3')\n  })\n})\n\ntest('propsRecursion as true', () => {\n  const form = createForm()\n  const CustomObject: React.FC = () => {\n    const schema = useFieldSchema()\n    return (\n      <div data-testid=\"object\">\n        <RecursionField\n          schema={schema}\n          propsRecursion={true}\n          filterProperties={(schema) => {\n            if (schema['x-component'] === 'Input') {\n              return false\n            }\n            return true\n          }}\n        />\n      </div>\n    )\n  }\n\n  const SchemaField = createSchemaField({\n    components: {\n      Input,\n      CustomObject,\n    },\n  })\n  const { queryAllByTestId } = render(\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Object x-component=\"CustomObject\">\n          <SchemaField.String x-component=\"Input\" />\n          <SchemaField.Object>\n            <SchemaField.String x-component=\"Input\" />\n          </SchemaField.Object>\n        </SchemaField.Object>\n      </SchemaField>\n    </FormProvider>\n  )\n  expect(queryAllByTestId('input').length).toEqual(0)\n  expect(queryAllByTestId('object').length).toEqual(1)\n})\n\ntest('propsRecursion as empty', () => {\n  const form = createForm()\n  const CustomObject: React.FC = () => {\n    const schema = useFieldSchema()\n    return (\n      <div data-testid=\"object\">\n        <RecursionField\n          schema={schema}\n          filterProperties={(schema) => {\n            if (schema['x-component'] === 'Input') {\n              return false\n            }\n            return true\n          }}\n        />\n      </div>\n    )\n  }\n\n  const SchemaField = createSchemaField({\n    components: {\n      Input,\n      CustomObject,\n    },\n  })\n  const { queryAllByTestId } = render(\n    <FormProvider form={form}>\n      <SchemaField>\n        <SchemaField.Object x-component=\"CustomObject\">\n          <SchemaField.String x-component=\"Input\" />\n          <SchemaField.Object>\n            <SchemaField.String x-component=\"Input\" />\n          </SchemaField.Object>\n        </SchemaField.Object>\n      </SchemaField>\n    </FormProvider>\n  )\n  expect(queryAllByTestId('input').length).toEqual(1)\n  expect(queryAllByTestId('object').length).toEqual(1)\n})\n"
  },
  {
    "path": "packages/react/src/__tests__/shared.tsx",
    "content": "import React, { Component, Fragment } from 'react'\nimport { render } from '@testing-library/react'\nexport class ErrorBoundary extends Component {\n  state = {\n    error: null,\n  }\n\n  componentDidCatch(error: Error) {\n    this.setState({\n      error,\n    })\n  }\n\n  render() {\n    if (this.state.error) {\n      return (\n        <div data-testid=\"error-boundary-message\">\n          {this.state.error.message}\n        </div>\n      )\n    }\n    return <Fragment>{this.props.children}</Fragment>\n  }\n}\n\nexport const expectThrowError = (callback: () => React.ReactElement) => {\n  const { queryByTestId } = render(<ErrorBoundary>{callback()}</ErrorBoundary>)\n  expect(queryByTestId('error-boundary-message')).toBeVisible()\n}\n"
  },
  {
    "path": "packages/react/src/components/ArrayField.tsx",
    "content": "import React from 'react'\nimport { ArrayField as ArrayFieldType } from '@formily/core'\nimport { useForm, useField } from '../hooks'\nimport { useAttach } from '../hooks/useAttach'\nimport { FieldContext } from '../shared'\nimport { JSXComponent, IFieldProps } from '../types'\nimport { ReactiveField } from './ReactiveField'\n\nexport const ArrayField = <D extends JSXComponent, C extends JSXComponent>(\n  props: IFieldProps<D, C, ArrayFieldType>\n) => {\n  const form = useForm()\n  const parent = useField()\n  const field = useAttach(\n    form.createArrayField({\n      basePath: parent?.address,\n      ...props,\n    })\n  )\n  return (\n    <FieldContext.Provider value={field}>\n      <ReactiveField field={field}>{props.children}</ReactiveField>\n    </FieldContext.Provider>\n  )\n}\n\nArrayField.displayName = 'ArrayField'\n"
  },
  {
    "path": "packages/react/src/components/ExpressionScope.tsx",
    "content": "import React, { useContext } from 'react'\nimport { lazyMerge } from '@formily/shared'\nimport { SchemaExpressionScopeContext } from '../shared'\nimport { IExpressionScopeProps, ReactFC } from '../types'\n\nexport const ExpressionScope: ReactFC<IExpressionScopeProps> = (props) => {\n  const scope = useContext(SchemaExpressionScopeContext)\n  return (\n    <SchemaExpressionScopeContext.Provider\n      value={lazyMerge(scope, props.value)}\n    >\n      {props.children}\n    </SchemaExpressionScopeContext.Provider>\n  )\n}\n"
  },
  {
    "path": "packages/react/src/components/Field.tsx",
    "content": "import React, { useEffect } from 'react'\nimport { useField, useForm } from '../hooks'\nimport { ReactiveField } from './ReactiveField'\nimport { FieldContext } from '../shared'\nimport { JSXComponent, IFieldProps } from '../types'\n\nexport const Field = <D extends JSXComponent, C extends JSXComponent>(\n  props: IFieldProps<D, C>\n) => {\n  const form = useForm()\n  const parent = useField()\n  const field = form.createField({ basePath: parent?.address, ...props })\n  useEffect(() => {\n    field?.onMount()\n    return () => {\n      field?.onUnmount()\n    }\n  }, [field])\n  return (\n    <FieldContext.Provider value={field}>\n      <ReactiveField field={field}>{props.children}</ReactiveField>\n    </FieldContext.Provider>\n  )\n}\n\nField.displayName = 'Field'\n"
  },
  {
    "path": "packages/react/src/components/FormConsumer.tsx",
    "content": "import React, { Fragment } from 'react'\nimport { isFn } from '@formily/shared'\nimport { observer } from '@formily/reactive-react'\nimport { useForm } from '../hooks'\nimport { IFormSpyProps, ReactFC } from '../types'\n\nexport const FormConsumer: ReactFC<IFormSpyProps> = observer((props) => {\n  const children = isFn(props.children) ? props.children(useForm()) : null\n  return <Fragment>{children}</Fragment>\n})\n\nFormConsumer.displayName = 'FormConsumer'\n"
  },
  {
    "path": "packages/react/src/components/FormProvider.tsx",
    "content": "import React from 'react'\nimport { useAttach } from '../hooks/useAttach'\nimport { FormContext, ContextCleaner } from '../shared'\nimport { IProviderProps, ReactFC } from '../types'\n\nexport const FormProvider: ReactFC<IProviderProps> = (props) => {\n  const form = useAttach(props.form)\n  return (\n    <ContextCleaner>\n      <FormContext.Provider value={form}>{props.children}</FormContext.Provider>\n    </ContextCleaner>\n  )\n}\n\nFormProvider.displayName = 'FormProvider'\n"
  },
  {
    "path": "packages/react/src/components/ObjectField.tsx",
    "content": "import React from 'react'\nimport { ObjectField as ObjectFieldType } from '@formily/core'\nimport { useForm, useField } from '../hooks'\nimport { useAttach } from '../hooks/useAttach'\nimport { ReactiveField } from './ReactiveField'\nimport { FieldContext } from '../shared'\nimport { JSXComponent, IFieldProps } from '../types'\n\nexport const ObjectField = <D extends JSXComponent, C extends JSXComponent>(\n  props: IFieldProps<D, C, ObjectFieldType>\n) => {\n  const form = useForm()\n  const parent = useField()\n  const field = useAttach(\n    form.createObjectField({ basePath: parent?.address, ...props })\n  )\n  return (\n    <FieldContext.Provider value={field}>\n      <ReactiveField field={field}>{props.children}</ReactiveField>\n    </FieldContext.Provider>\n  )\n}\n\nObjectField.displayName = 'ObjectField'\n"
  },
  {
    "path": "packages/react/src/components/ReactiveField.tsx",
    "content": "import React, { Fragment, useContext } from 'react'\nimport { toJS } from '@formily/reactive'\nimport { observer } from '@formily/reactive-react'\nimport { FormPath, isFn } from '@formily/shared'\nimport { isVoidField, GeneralField, Form } from '@formily/core'\nimport { SchemaComponentsContext } from '../shared'\nimport { RenderPropsChildren } from '../types'\ninterface IReactiveFieldProps {\n  field: GeneralField\n  children?: RenderPropsChildren<GeneralField>\n}\n\nconst mergeChildren = (\n  children: RenderPropsChildren<GeneralField>,\n  content: React.ReactNode\n) => {\n  if (!children && !content) return\n  if (isFn(children)) return\n  return (\n    <Fragment>\n      {children}\n      {content}\n    </Fragment>\n  )\n}\n\nconst isValidComponent = (target: any) =>\n  target && (typeof target === 'object' || typeof target === 'function')\n\nconst renderChildren = (\n  children: RenderPropsChildren<GeneralField>,\n  field?: GeneralField,\n  form?: Form\n) => (isFn(children) ? children(field, form) : children)\n\nconst ReactiveInternal: React.FC<IReactiveFieldProps> = (props) => {\n  const components = useContext(SchemaComponentsContext)\n  if (!props.field) {\n    return <Fragment>{renderChildren(props.children)}</Fragment>\n  }\n  const field = props.field\n  const content = mergeChildren(\n    renderChildren(props.children, field, field.form),\n    field.content ?? field.componentProps.children\n  )\n  if (field.display !== 'visible') return null\n\n  const getComponent = (target: any) => {\n    return isValidComponent(target)\n      ? target\n      : FormPath.getIn(components, target) ?? target\n  }\n\n  const renderDecorator = (children: React.ReactNode) => {\n    if (!field.decoratorType) {\n      return <Fragment>{children}</Fragment>\n    }\n\n    return React.createElement(\n      getComponent(field.decoratorType),\n      toJS(field.decoratorProps),\n      children\n    )\n  }\n\n  const renderComponent = () => {\n    if (!field.componentType) return content\n    const value = !isVoidField(field) ? field.value : undefined\n    const onChange = !isVoidField(field)\n      ? (...args: any[]) => {\n          field.onInput(...args)\n          field.componentProps?.onChange?.(...args)\n        }\n      : field.componentProps?.onChange\n    const onFocus = !isVoidField(field)\n      ? (...args: any[]) => {\n          field.onFocus(...args)\n          field.componentProps?.onFocus?.(...args)\n        }\n      : field.componentProps?.onFocus\n    const onBlur = !isVoidField(field)\n      ? (...args: any[]) => {\n          field.onBlur(...args)\n          field.componentProps?.onBlur?.(...args)\n        }\n      : field.componentProps?.onBlur\n    const disabled = !isVoidField(field)\n      ? field.pattern === 'disabled' || field.pattern === 'readPretty'\n      : undefined\n    const readOnly = !isVoidField(field)\n      ? field.pattern === 'readOnly'\n      : undefined\n    return React.createElement(\n      getComponent(field.componentType),\n      {\n        disabled,\n        readOnly,\n        ...toJS(field.componentProps),\n        value,\n        onChange,\n        onFocus,\n        onBlur,\n      },\n      content\n    )\n  }\n\n  return renderDecorator(renderComponent())\n}\n\nReactiveInternal.displayName = 'ReactiveField'\n\nexport const ReactiveField = observer(ReactiveInternal, {\n  forwardRef: true,\n})\n"
  },
  {
    "path": "packages/react/src/components/RecordScope.tsx",
    "content": "import React from 'react'\nimport { lazyMerge } from '@formily/shared'\nimport { ExpressionScope } from './ExpressionScope'\nimport { ReactFC, IRecordScopeProps } from '../types'\nimport { useExpressionScope } from '../hooks'\n\nexport const RecordScope: ReactFC<IRecordScopeProps> = (props) => {\n  const scope = useExpressionScope()\n  return (\n    <ExpressionScope\n      value={{\n        get $lookup() {\n          return scope?.$record\n        },\n        get $record() {\n          const record = props.getRecord?.()\n          if (typeof record === 'object') {\n            return lazyMerge(record, {\n              get $lookup() {\n                return scope?.$record\n              },\n              get $index() {\n                return props.getIndex?.()\n              },\n            })\n          }\n          return record\n        },\n        get $index() {\n          return props.getIndex?.()\n        },\n      }}\n    >\n      {props.children}\n    </ExpressionScope>\n  )\n}\n"
  },
  {
    "path": "packages/react/src/components/RecordsScope.tsx",
    "content": "import React from 'react'\nimport { ExpressionScope } from './ExpressionScope'\nimport { ReactFC, IRecordsScopeProps } from '../types'\n\nexport const RecordsScope: ReactFC<IRecordsScopeProps> = (props) => {\n  return (\n    <ExpressionScope\n      value={{\n        get $records() {\n          return props.getRecords?.() ?? []\n        },\n      }}\n    >\n      {props.children}\n    </ExpressionScope>\n  )\n}\n"
  },
  {
    "path": "packages/react/src/components/RecursionField.tsx",
    "content": "import React, { Fragment, useMemo } from 'react'\nimport { FormPath, isBool, isFn, isValid } from '@formily/shared'\nimport { GeneralField } from '@formily/core'\nimport { Schema } from '@formily/json-schema'\nimport { SchemaContext } from '../shared'\nimport { IRecursionFieldProps, ReactFC } from '../types'\nimport { useField, useExpressionScope } from '../hooks'\nimport { ObjectField } from './ObjectField'\nimport { ArrayField } from './ArrayField'\nimport { Field } from './Field'\nimport { VoidField } from './VoidField'\nimport { ExpressionScope } from './ExpressionScope'\nimport { observable } from '@formily/reactive'\n\nconst useFieldProps = (schema: Schema) => {\n  const scope = useExpressionScope()\n  return schema.toFieldProps({\n    scope,\n  }) as any\n}\n\nconst useBasePath = (props: IRecursionFieldProps) => {\n  const parent = useField()\n  if (props.onlyRenderProperties) {\n    return props.basePath || parent?.address.concat(props.name)\n  }\n  return props.basePath || parent?.address\n}\n\nexport const RecursionField: ReactFC<IRecursionFieldProps> = (props) => {\n  const basePath = useBasePath(props)\n  const fieldSchema = useMemo(() => new Schema(props.schema), [props.schema])\n  const fieldProps = useFieldProps(fieldSchema)\n\n  const renderSlots = (innerSchema, key) => {\n    const slot = innerSchema['x-slot-node']\n    const { target, isRenderProp } = slot\n    if (isRenderProp) {\n      const args = observable({ $slotArgs: [] })\n      FormPath.setIn(fieldSchema.properties, target, (..._args: any) => {\n        args.$slotArgs = _args\n        return (\n          <ExpressionScope value={args}>\n            <RecursionField schema={innerSchema} name={key} />\n          </ExpressionScope>\n        )\n      })\n    } else {\n      FormPath.setIn(\n        fieldSchema.properties,\n        target,\n        <RecursionField schema={innerSchema} name={key} />\n      )\n    }\n  }\n\n  const renderProperties = (field?: GeneralField) => {\n    if (props.onlyRenderSelf) return\n    const properties = Schema.getOrderProperties(fieldSchema)\n    if (!properties.length) return\n    return (\n      <Fragment>\n        {properties.map(({ schema: item, key: name }, index) => {\n          const base = field?.address || basePath\n          let schema: Schema = item\n          if (schema['x-slot-node']) {\n            renderSlots(schema, name)\n            return null\n          }\n\n          if (isFn(props.mapProperties)) {\n            const mapped = props.mapProperties(item, name)\n            if (mapped) {\n              schema = mapped\n            }\n          }\n          if (isFn(props.filterProperties)) {\n            if (props.filterProperties(schema, name) === false) {\n              return null\n            }\n          }\n          if (isBool(props.propsRecursion) && props.propsRecursion) {\n            return (\n              <RecursionField\n                propsRecursion={true}\n                filterProperties={props.filterProperties}\n                mapProperties={props.mapProperties}\n                schema={schema}\n                key={`${index}-${name}`}\n                name={name}\n                basePath={base}\n              />\n            )\n          }\n          return (\n            <RecursionField\n              schema={schema}\n              key={`${index}-${name}`}\n              name={name}\n              basePath={base}\n            />\n          )\n        })}\n      </Fragment>\n    )\n  }\n\n  const render = () => {\n    if (!isValid(props.name)) return renderProperties()\n    if (fieldSchema.type === 'object') {\n      if (props.onlyRenderProperties) return renderProperties()\n      return (\n        <ObjectField {...fieldProps} name={props.name} basePath={basePath}>\n          {renderProperties}\n        </ObjectField>\n      )\n    } else if (fieldSchema.type === 'array') {\n      return (\n        <ArrayField {...fieldProps} name={props.name} basePath={basePath} />\n      )\n    } else if (fieldSchema.type === 'void') {\n      if (props.onlyRenderProperties) return renderProperties()\n      return (\n        <VoidField {...fieldProps} name={props.name} basePath={basePath}>\n          {renderProperties}\n        </VoidField>\n      )\n    }\n    return <Field {...fieldProps} name={props.name} basePath={basePath} />\n  }\n\n  if (!fieldSchema) return <Fragment />\n\n  return (\n    <SchemaContext.Provider value={fieldSchema}>\n      {render()}\n    </SchemaContext.Provider>\n  )\n}\n"
  },
  {
    "path": "packages/react/src/components/SchemaField.tsx",
    "content": "import React, { useContext, Fragment } from 'react'\nimport { ISchema, Schema } from '@formily/json-schema'\nimport { RecursionField } from './RecursionField'\nimport { render } from '../shared/render'\nimport {\n  SchemaMarkupContext,\n  SchemaOptionsContext,\n  SchemaComponentsContext,\n} from '../shared'\nimport {\n  ReactComponentPath,\n  JSXComponent,\n  ISchemaFieldReactFactoryOptions,\n  SchemaReactComponents,\n  ISchemaFieldProps,\n  ISchemaMarkupFieldProps,\n  ISchemaTypeFieldProps,\n} from '../types'\nimport { lazyMerge } from '@formily/shared'\nimport { ExpressionScope } from './ExpressionScope'\nconst env = {\n  nonameId: 0,\n}\n\nconst getRandomName = () => {\n  return `NO_NAME_FIELD_$${env.nonameId++}`\n}\n\nexport function createSchemaField<Components extends SchemaReactComponents>(\n  options: ISchemaFieldReactFactoryOptions<Components> = {}\n) {\n  function SchemaField<\n    Decorator extends JSXComponent,\n    Component extends JSXComponent\n  >(props: ISchemaFieldProps<Decorator, Component>) {\n    const schema = Schema.isSchemaInstance(props.schema)\n      ? props.schema\n      : new Schema({\n          type: 'object',\n          ...props.schema,\n        })\n    const renderMarkup = () => {\n      env.nonameId = 0\n      if (props.schema) return null\n      return render(\n        <SchemaMarkupContext.Provider value={schema}>\n          {props.children}\n        </SchemaMarkupContext.Provider>\n      )\n    }\n\n    const renderChildren = () => {\n      return <RecursionField {...props} schema={schema} />\n    }\n\n    return (\n      <SchemaOptionsContext.Provider value={options}>\n        <SchemaComponentsContext.Provider\n          value={lazyMerge(options.components, props.components)}\n        >\n          <ExpressionScope value={lazyMerge(options.scope, props.scope)}>\n            {renderMarkup()}\n            {renderChildren()}\n          </ExpressionScope>\n        </SchemaComponentsContext.Provider>\n      </SchemaOptionsContext.Provider>\n    )\n  }\n\n  SchemaField.displayName = 'SchemaField'\n\n  function MarkupRender(props: any) {\n    const parent = useContext(SchemaMarkupContext)\n    if (!parent) return <Fragment />\n    const renderChildren = () => {\n      return <React.Fragment>{props.children}</React.Fragment>\n    }\n    const appendArraySchema = (schema: ISchema) => {\n      const items = parent.items as Schema\n      if (items && items.name !== props.name) {\n        return parent.addProperty(props.name, schema)\n      } else {\n        return parent.setItems(schema)\n      }\n    }\n    if (parent.type === 'object' || parent.type === 'void') {\n      const schema = parent.addProperty(props.name, props)\n      return (\n        <SchemaMarkupContext.Provider value={schema}>\n          {renderChildren()}\n        </SchemaMarkupContext.Provider>\n      )\n    } else if (parent.type === 'array') {\n      const schema = appendArraySchema(props)\n      return (\n        <SchemaMarkupContext.Provider\n          value={Array.isArray(schema) ? schema[0] : schema}\n        >\n          {props.children}\n        </SchemaMarkupContext.Provider>\n      )\n    } else {\n      return renderChildren()\n    }\n  }\n\n  function MarkupField<\n    Decorator extends ReactComponentPath<Components>,\n    Component extends ReactComponentPath<Components>\n  >(props: ISchemaMarkupFieldProps<Components, Component, Decorator>) {\n    return <MarkupRender {...props} name={props.name || getRandomName()} />\n  }\n\n  MarkupField.displayName = 'MarkupField'\n\n  function StringField<\n    Decorator extends ReactComponentPath<Components>,\n    Component extends ReactComponentPath<Components>\n  >(props: ISchemaTypeFieldProps<Components, Component, Decorator>) {\n    return <MarkupField {...props} type=\"string\" />\n  }\n\n  StringField.displayName = 'StringField'\n\n  function ObjectField<\n    Decorator extends ReactComponentPath<Components>,\n    Component extends ReactComponentPath<Components>\n  >(props: ISchemaTypeFieldProps<Components, Component, Decorator>) {\n    return <MarkupField {...props} type=\"object\" />\n  }\n\n  ObjectField.displayName = 'ObjectField'\n\n  function ArrayField<\n    Decorator extends ReactComponentPath<Components>,\n    Component extends ReactComponentPath<Components>\n  >(props: ISchemaTypeFieldProps<Components, Component, Decorator>) {\n    return <MarkupField {...props} type=\"array\" />\n  }\n\n  ArrayField.displayName = 'ArrayField'\n  function BooleanField<\n    Decorator extends ReactComponentPath<Components>,\n    Component extends ReactComponentPath<Components>\n  >(props: ISchemaTypeFieldProps<Components, Component, Decorator>) {\n    return <MarkupField {...props} type=\"boolean\" />\n  }\n\n  BooleanField.displayName = 'BooleanField'\n\n  function NumberField<\n    Decorator extends ReactComponentPath<Components>,\n    Component extends ReactComponentPath<Components>\n  >(props: ISchemaTypeFieldProps<Components, Component, Decorator>) {\n    return <MarkupField {...props} type=\"number\" />\n  }\n\n  NumberField.displayName = 'NumberField'\n\n  function DateField<\n    Decorator extends ReactComponentPath<Components>,\n    Component extends ReactComponentPath<Components>\n  >(props: ISchemaTypeFieldProps<Components, Component, Decorator>) {\n    return <MarkupField {...props} type=\"date\" />\n  }\n\n  DateField.displayName = 'DateField'\n\n  function DateTimeField<\n    Decorator extends ReactComponentPath<Components>,\n    Component extends ReactComponentPath<Components>\n  >(props: ISchemaTypeFieldProps<Components, Component, Decorator>) {\n    return <MarkupField {...props} type=\"datetime\" />\n  }\n\n  DateTimeField.displayName = 'DateTimeField'\n\n  function VoidField<\n    Decorator extends ReactComponentPath<Components>,\n    Component extends ReactComponentPath<Components>\n  >(props: ISchemaTypeFieldProps<Components, Component, Decorator>) {\n    return <MarkupField {...props} type=\"void\" />\n  }\n\n  VoidField.displayName = 'VoidField'\n\n  SchemaField.Markup = MarkupField\n  SchemaField.String = StringField\n  SchemaField.Object = ObjectField\n  SchemaField.Array = ArrayField\n  SchemaField.Boolean = BooleanField\n  SchemaField.Date = DateField\n  SchemaField.DateTime = DateTimeField\n  SchemaField.Void = VoidField\n  SchemaField.Number = NumberField\n\n  return SchemaField\n}\n"
  },
  {
    "path": "packages/react/src/components/VoidField.tsx",
    "content": "import React from 'react'\nimport { useForm, useField } from '../hooks'\nimport { useAttach } from '../hooks/useAttach'\nimport { ReactiveField } from './ReactiveField'\nimport { FieldContext } from '../shared'\nimport { JSXComponent, IVoidFieldProps } from '../types'\n\nexport const VoidField = <D extends JSXComponent, C extends JSXComponent>(\n  props: IVoidFieldProps<D, C>\n) => {\n  const form = useForm()\n  const parent = useField()\n  const field = useAttach(\n    form.createVoidField({ basePath: parent?.address, ...props })\n  )\n  return (\n    <FieldContext.Provider value={field}>\n      <ReactiveField field={field}>{props.children}</ReactiveField>\n    </FieldContext.Provider>\n  )\n}\n\nVoidField.displayName = 'VoidField'\n"
  },
  {
    "path": "packages/react/src/components/index.ts",
    "content": "export * from './FormProvider'\nexport * from './FormConsumer'\nexport * from './ArrayField'\nexport * from './ObjectField'\nexport * from './VoidField'\nexport * from './RecursionField'\nexport * from './ExpressionScope'\nexport * from './RecordsScope'\nexport * from './RecordScope'\nexport * from './SchemaField'\nexport * from './Field'\n"
  },
  {
    "path": "packages/react/src/global.d.ts",
    "content": "/// <reference types=\"@formily/core\" />\n/// <reference types=\"@formily/json-schema\" />\nimport * as Types from './types'\ndeclare global {\n  namespace Formily.React {\n    export { Types }\n  }\n}\n"
  },
  {
    "path": "packages/react/src/hooks/index.ts",
    "content": "export * from './useForm'\nexport * from './useField'\nexport * from './useParentForm'\nexport * from './useFieldSchema'\nexport * from './useFormEffects'\nexport * from './useExpressionScope'\n"
  },
  {
    "path": "packages/react/src/hooks/useAttach.ts",
    "content": "import { unstable_useCompatEffect } from '@formily/reactive-react'\ninterface IRecycleTarget {\n  onMount: () => void\n  onUnmount: () => void\n}\n\nexport const useAttach = <T extends IRecycleTarget>(target: T): T => {\n  unstable_useCompatEffect(() => {\n    target.onMount()\n    return () => target.onUnmount()\n  }, [target])\n  return target\n}\n"
  },
  {
    "path": "packages/react/src/hooks/useExpressionScope.ts",
    "content": "import { useContext } from 'react'\nimport { SchemaExpressionScopeContext } from '../shared/context'\n\nexport const useExpressionScope = () => useContext(SchemaExpressionScopeContext)\n"
  },
  {
    "path": "packages/react/src/hooks/useField.ts",
    "content": "import { useContext } from 'react'\nimport { GeneralField } from '@formily/core'\nimport { FieldContext } from '../shared'\n\nexport const useField = <T = GeneralField>(): T => {\n  return useContext(FieldContext) as any\n}\n"
  },
  {
    "path": "packages/react/src/hooks/useFieldSchema.ts",
    "content": "import { useContext } from 'react'\nimport { SchemaContext } from '../shared'\nimport { Schema } from '@formily/json-schema'\n\nexport const useFieldSchema = (): Schema => {\n  return useContext(SchemaContext)\n}\n"
  },
  {
    "path": "packages/react/src/hooks/useForm.ts",
    "content": "import { useContext } from 'react'\nimport { Form } from '@formily/core'\nimport { FormContext } from '../shared'\n\nexport const useForm = <T extends object = any>(): Form<T> => {\n  return useContext(FormContext)\n}\n"
  },
  {
    "path": "packages/react/src/hooks/useFormEffects.ts",
    "content": "import { unstable_useCompatFactory } from '@formily/reactive-react'\nimport { Form } from '@formily/core'\nimport { uid } from '@formily/shared'\nimport { useForm } from './useForm'\n\nexport const useFormEffects = (effects?: (form: Form) => void) => {\n  const form = useForm()\n  unstable_useCompatFactory(() => {\n    const id = uid()\n    form.addEffects(id, effects)\n    return {\n      dispose() {\n        form.removeEffects(id)\n      },\n    }\n  })\n}\n"
  },
  {
    "path": "packages/react/src/hooks/useParentForm.ts",
    "content": "import { isObjectField, GeneralField, Form, ObjectField } from '@formily/core'\nimport { useField } from './useField'\nimport { useForm } from './useForm'\n\nexport const useParentForm = (): Form | ObjectField => {\n  const field = useField()\n  const form = useForm()\n  const findObjectParent = (field: GeneralField) => {\n    if (!field) return form\n    if (isObjectField(field)) return field\n    return findObjectParent(field?.parent)\n  }\n  return findObjectParent(field)\n}\n"
  },
  {
    "path": "packages/react/src/index.ts",
    "content": "export * from '@formily/json-schema'\nexport * from './components'\nexport * from './shared'\nexport * from './hooks'\nexport * from './types'\n"
  },
  {
    "path": "packages/react/src/shared/connect.ts",
    "content": "import React from 'react'\nimport { isFn, isStr, FormPath, each, isValid } from '@formily/shared'\nimport { isVoidField } from '@formily/core'\nimport { observer, Observer } from '@formily/reactive-react'\nimport { JSXComponent, IComponentMapper, IStateMapper } from '../types'\nimport { useField } from '../hooks'\nimport hoistNonReactStatics from 'hoist-non-react-statics'\n\nexport function mapProps<T extends JSXComponent>(\n  ...args: IStateMapper<React.ComponentProps<T>>[]\n) {\n  return (target: T) => {\n    return observer(\n      (props: any) => {\n        const field = useField()\n        const results = args.reduce(\n          (props, mapper) => {\n            if (isFn(mapper)) {\n              props = Object.assign(props, mapper(props, field))\n            } else {\n              each(mapper, (to, extract) => {\n                const extractValue = FormPath.getIn(field, extract)\n                const targetValue = isStr(to) ? to : (extract as any)\n                const originalValue = FormPath.getIn(props, targetValue)\n                if (extract === 'value') {\n                  if (to !== extract) {\n                    delete props.value\n                  }\n                }\n                if (isValid(originalValue) && !isValid(extractValue)) return\n                FormPath.setIn(props, targetValue, extractValue)\n              })\n            }\n            return props\n          },\n          { ...props }\n        )\n        return React.createElement(target, results)\n      },\n      {\n        forwardRef: true,\n      }\n    )\n  }\n}\n\nexport function mapReadPretty<T extends JSXComponent, C extends JSXComponent>(\n  component: C,\n  readPrettyProps?: React.ComponentProps<C>\n) {\n  return (target: T) => {\n    return observer(\n      (props) => {\n        const field = useField()\n        if (!isVoidField(field) && field?.pattern === 'readPretty') {\n          return React.createElement(component, {\n            ...readPrettyProps,\n            ...props,\n          })\n        }\n        return React.createElement(target, props)\n      },\n      {\n        forwardRef: true,\n      }\n    )\n  }\n}\n\nexport function connect<T extends JSXComponent>(\n  target: T,\n  ...args: IComponentMapper<T>[]\n) {\n  const Target = args.reduce((target, mapper) => {\n    return mapper(target)\n  }, target)\n\n  const Destination = React.forwardRef(\n    (props: Partial<React.ComponentProps<T>>, ref) => {\n      return React.createElement(Target, { ...props, ref })\n    }\n  )\n\n  if (target) hoistNonReactStatics(Destination, target as any)\n\n  return Destination\n}\n\nexport { observer, Observer }\n"
  },
  {
    "path": "packages/react/src/shared/context.ts",
    "content": "import React, { createContext } from 'react'\nimport { Form, GeneralField } from '@formily/core'\nimport { Schema } from '@formily/json-schema'\nimport {\n  ISchemaFieldReactFactoryOptions,\n  SchemaReactComponents,\n} from '../types'\n\nconst createContextCleaner = <T>(...contexts: React.Context<T>[]) => {\n  return ({ children }) => {\n    return contexts.reduce((buf, ctx) => {\n      return React.createElement(ctx.Provider, { value: undefined }, buf)\n    }, children)\n  }\n}\n\nexport const FormContext = createContext<Form>(null)\nexport const FieldContext = createContext<GeneralField>(null)\nexport const SchemaMarkupContext = createContext<Schema>(null)\nexport const SchemaContext = createContext<Schema>(null)\nexport const SchemaExpressionScopeContext = createContext<any>(null)\nexport const SchemaComponentsContext =\n  createContext<SchemaReactComponents>(null)\nexport const SchemaOptionsContext =\n  createContext<ISchemaFieldReactFactoryOptions>(null)\n\nexport const ContextCleaner = createContextCleaner(\n  FieldContext,\n  SchemaMarkupContext,\n  SchemaContext,\n  SchemaExpressionScopeContext,\n  SchemaComponentsContext,\n  SchemaOptionsContext\n)\n"
  },
  {
    "path": "packages/react/src/shared/index.ts",
    "content": "export * from './context'\nexport * from './connect'\n"
  },
  {
    "path": "packages/react/src/shared/render.ts",
    "content": "import React, { ReactNode, ReactPortal } from 'react'\nimport { globalThisPolyfill } from '@formily/shared'\n\ninterface Env {\n  portalDOM?: HTMLDivElement\n  createPortal?: (children: ReactNode, container: Element) => ReactPortal\n}\n\nconst env: Env = {\n  portalDOM: globalThisPolyfill?.document?.createElement?.('div'),\n  createPortal: globalThisPolyfill?.['ReactDOM']?.createPortal,\n}\n\n/* istanbul ignore next */\nconst loadCreatePortal = () => {\n  if (!env.createPortal) {\n    try {\n      // eslint-disable-next-line @typescript-eslint/no-var-requires\n      env.createPortal ??= require('react-dom')?.createPortal\n    } catch {}\n  }\n  if (!env.createPortal) {\n    try {\n      // @ts-ignore\n      import('react-dom')\n        .then((module) => (env.createPortal ??= module?.createPortal))\n        .catch()\n    } catch {}\n  }\n}\n\nexport const render = (element: React.ReactElement) => {\n  if (globalThisPolyfill.navigator?.product === 'ReactNative') return null\n  if (env.portalDOM && env.createPortal) {\n    return env.createPortal(element, env.portalDOM)\n  } else {\n    return React.createElement('template', {}, element)\n  }\n}\n\nloadCreatePortal()\n"
  },
  {
    "path": "packages/react/src/types.ts",
    "content": "import React from 'react'\nimport {\n  Form,\n  Field as FieldType,\n  VoidField,\n  ObjectField,\n  GeneralField,\n  IFieldFactoryProps,\n  IVoidFieldFactoryProps,\n  FormPatternTypes,\n  FieldDisplayTypes,\n  FieldValidator,\n} from '@formily/core'\nimport { ReactFC } from '@formily/reactive-react'\nimport { ISchema, Schema, SchemaKey } from '@formily/json-schema'\nimport { FormPathPattern } from '@formily/shared'\n\nexport type JSXComponent =\n  | keyof JSX.IntrinsicElements\n  | React.JSXElementConstructor<any>\n\nexport type IProviderProps = {\n  form: Form\n}\n\nexport interface IFormSpyProps {\n  children?: (form: Form) => ReactChild\n}\n\nexport type RenderPropsChildren<Payload> =\n  | ((field: Payload, form: Form) => React.ReactNode)\n  | React.ReactNode\n\nexport interface IFieldProps<\n  D extends JSXComponent,\n  C extends JSXComponent,\n  Field = FieldType\n> extends IFieldFactoryProps<D, C> {\n  children?: RenderPropsChildren<Field>\n  decorator?: [] | [D] | [D, React.ComponentProps<D>] | any[]\n  component?: [] | [C] | [C, React.ComponentProps<C>] | any[]\n}\n\nexport interface IVoidFieldProps<\n  D extends JSXComponent,\n  C extends JSXComponent,\n  Field = VoidField\n> extends IVoidFieldFactoryProps<D, C> {\n  children?: RenderPropsChildren<Field>\n  decorator?: [] | [D] | [D, React.ComponentProps<D>] | any[]\n  component?: [] | [C] | [C, React.ComponentProps<C>] | any[]\n}\n\nexport interface IComponentMapper<T extends JSXComponent> {\n  (target: T): JSXComponent\n}\n\nexport type IStateMapper<Props> =\n  | {\n      [key in keyof FieldType]?: keyof Props | boolean\n    }\n  | ((props: Props, field: GeneralField) => Props)\n\nexport type SchemaReactComponents = Record<string, JSXComponent>\n\nexport interface ISchemaFieldReactFactoryOptions<\n  Components extends SchemaReactComponents = any\n> {\n  components?: Components\n  scope?: any\n}\n\nexport interface ISchemaFieldOptionContext {\n  components: SchemaReactComponents\n}\n\nexport interface ISchemaFieldProps<\n  Decorator extends JSXComponent = any,\n  Component extends JSXComponent = any,\n  InnerField = ObjectField<Decorator, Component>\n> extends Omit<IFieldFactoryProps<Decorator, Component, InnerField>, 'name'> {\n  schema?: ISchema\n  components?: {\n    [key: string]: JSXComponent\n  }\n  scope?: any\n  name?: SchemaKey\n  children?: React.ReactNode\n}\n\nexport interface ISchemaMapper {\n  (schema: Schema, name: SchemaKey): Schema\n}\n\nexport interface ISchemaFilter {\n  (schema: Schema, name: SchemaKey): boolean\n}\nexport interface IRecursionFieldProps {\n  schema: ISchema\n  name?: SchemaKey\n  basePath?: FormPathPattern\n  propsRecursion?: boolean\n  onlyRenderProperties?: boolean\n  onlyRenderSelf?: boolean\n  mapProperties?: ISchemaMapper\n  filterProperties?: ISchemaFilter\n}\n\nexport type ObjectKey = string | number | boolean | symbol\n\nexport type Path<T, Key extends keyof T = keyof T> = Key extends string\n  ? T[Key] extends Record<string, any>\n    ?\n        | `${Key}.${Path<T[Key], Exclude<keyof T[Key], keyof Array<any>>> &\n            string}`\n        | `${Key}.${Exclude<keyof T[Key], keyof Array<any>> & string}`\n        | Key\n    : Key\n  : never\n\nexport type PathValue<\n  T,\n  P extends Path<T>\n> = P extends `${infer Key}.${infer Rest}`\n  ? Key extends keyof T\n    ? Rest extends Path<T[Key]>\n      ? PathValue<T[Key], Rest>\n      : never\n    : never\n  : P extends keyof T\n  ? T[P]\n  : never\n\nexport type KeyOfReactComponent<T> = Exclude<\n  keyof T,\n  'contextTypes' | 'displayName' | 'propTypes' | 'defaultProps'\n>\n\nexport type ReactComponentPath<\n  T,\n  Key extends KeyOfReactComponent<T> = KeyOfReactComponent<T>\n> = Key extends string\n  ? T[Key] extends Record<string, any>\n    ?\n        | `${Key}.${Exclude<KeyOfReactComponent<T[Key]>, keyof Array<any>> &\n            string}`\n        | Key\n    : Key\n  : never\n\nexport type ReactComponentPropsByPathValue<\n  T extends Record<string, any>,\n  P extends ReactComponentPath<T>\n> = P extends `${infer Key}.${infer Rest}`\n  ? Key extends keyof T\n    ? Rest extends ReactComponentPath<T[Key]>\n      ? ReactComponentPropsByPathValue<T[Key], Rest>\n      : never\n    : React.ComponentProps<T[P]>\n  : P extends keyof T\n  ? React.ComponentProps<T[P]>\n  : never\nexport interface ISchemaMarkupFieldProps<\n  Components extends SchemaReactComponents,\n  Decorator extends ReactComponentPath<Components>,\n  Component extends ReactComponentPath<Components>\n> extends ISchema<\n    Decorator,\n    Component,\n    ReactComponentPropsByPathValue<Components, Decorator>,\n    ReactComponentPropsByPathValue<Components, Component>,\n    FormPatternTypes,\n    FieldDisplayTypes,\n    FieldValidator,\n    React.ReactNode,\n    GeneralField\n  > {\n  children?: React.ReactNode\n}\n\nexport type ISchemaTypeFieldProps<\n  Components extends SchemaReactComponents,\n  Decorator extends ReactComponentPath<Components>,\n  Component extends ReactComponentPath<Components>\n> = ISchemaMarkupFieldProps<Components, Decorator, Component>\n\nexport interface IExpressionScopeProps {\n  value?: any\n}\n\nexport interface IRecordScopeProps {\n  getIndex?(): number\n  getRecord(): any\n}\n\nexport interface IRecordsScopeProps {\n  getRecords(): any[]\n}\n\nexport type ReactChild = React.ReactElement | string | number\n\nexport { ReactFC }\n"
  },
  {
    "path": "packages/react/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*\", \"devtools/*\"]\n    },\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/react/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"include\": [\"./src/**/*.ts\", \"./src/**/*.tsx\"],\n  \"exclude\": [\"./src/__tests__/*\", \"./esm/*\", \"./lib/*\"],\n  \"compilerOptions\": {\n    \"lib\": [\"ESNext\", \"DOM\"]\n  }\n}\n"
  },
  {
    "path": "packages/reactive/.npmignore",
    "content": "node_modules\n*.log\nbuild\ndocs\ndoc-site\n__tests__\n.eslintrc\njest.config.js\ntsconfig.json\n.umi\nsrc"
  },
  {
    "path": "packages/reactive/.umirc.js",
    "content": "import { resolve } from 'path'\nexport default {\n  mode: 'site',\n  logo: '//img.alicdn.com/imgextra/i2/O1CN01Kq3OHU1fph6LGqjIz_!!6000000004056-55-tps-1141-150.svg',\n  title: 'Reactive',\n  hash: true,\n  favicon:\n    '//img.alicdn.com/imgextra/i3/O1CN01XtT3Tv1Wd1b5hNVKy_!!6000000002810-55-tps-360-360.svg',\n  outputPath: './doc-site',\n  navs: {\n    'en-US': [\n      {\n        title: 'Guide',\n        path: '/guide',\n      },\n      {\n        title: 'API',\n        path: '/api',\n      },\n      {\n        title: 'Home Site',\n        path: 'https://formilyjs.org',\n      },\n      {\n        title: 'GITHUB',\n        path: 'https://github.com/alibaba/formily',\n      },\n    ],\n    'zh-CN': [\n      {\n        title: '指南',\n        path: '/zh-CN/guide',\n      },\n      {\n        title: 'API',\n        path: '/zh-CN/api',\n      },\n      {\n        title: '主站',\n        path: 'https://formilyjs.org',\n      },\n      {\n        title: 'GITHUB',\n        path: 'https://github.com/alibaba/formily',\n      },\n    ],\n  },\n  headScripts: [\n    `\n    function loadAd(){\n      var header = document.querySelector('.__dumi-default-layout-content .markdown h1')\n      if(header && !header.querySelector('#_carbonads_js')){\n        var script = document.createElement('script')\n        script.src = '//cdn.carbonads.com/carbon.js?serve=CEAICK3M&placement=formilyjsorg'\n        script.id = '_carbonads_js'\n        script.classList.add('head-ad')\n        header.appendChild(script)\n      }\n    }\n    var request = null\n    var observer = new MutationObserver(function(){\n      cancelIdleCallback(request)\n      request = requestIdleCallback(loadAd)\n    })\n    document.addEventListener('DOMContentLoaded',function(){\n      loadAd()\n      observer.observe(\n        document.body,\n        {\n          childList:true,\n          subtree:true\n        }\n      )\n    })\n    `,\n  ],\n  styles: [\n    `.__dumi-default-navbar-logo{\n      background-size: 140px!important;\n      background-position: center left!important;\n      background-repeat: no-repeat!important;\n      padding-left: 150px!important;/*可根据title的宽度调整*/\n      font-size: 22px!important;\n      color: #000!important;\n      font-weight: lighter!important;\n    }\n    .__dumi-default-navbar{\n      padding: 0 28px !important;\n    }\n    .__dumi-default-layout-hero{\n      background-image: url(//img.alicdn.com/imgextra/i4/O1CN01ZcvS4e26XMsdsCkf9_!!6000000007671-2-tps-6001-4001.png);\n      background-size: cover;\n      background-repeat: no-repeat;\n      padding: 120px 0 !important;\n    }\n    .__dumi-default-layout-hero h1{\n      color:#45124e !important;\n      font-size:80px !important;\n      padding-bottom: 30px !important;\n    }\n    .__dumi-default-dark-switch {\n      display:none\n    }\n    nav a{\n      text-decoration: none !important;\n    }\n    #carbonads * {\n      margin: initial;\n      padding: initial;\n    }\n    #carbonads {\n      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,\n        Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Helvetica, Arial,\n        sans-serif;\n    }\n    #carbonads {\n      display: flex;\n      max-width: 330px;\n      background-color: hsl(0, 0%, 98%);\n      box-shadow: 0 1px 4px 1px hsla(0, 0%, 0%, 0.1);\n      z-index: 100;\n      float:right;\n    }\n    #carbonads a {\n      color: inherit;\n      text-decoration: none;\n    }\n    #carbonads a:hover {\n      color: inherit;\n    }\n    #carbonads span {\n      position: relative;\n      display: block;\n      overflow: hidden;\n    }\n    #carbonads .carbon-wrap {\n      display: flex;\n    }\n    #carbonads .carbon-img {\n      display: block;\n      margin: 0;\n      line-height: 1;\n    }\n    #carbonads .carbon-img img {\n      display: block;\n    }\n    #carbonads .carbon-text {\n      font-size: 13px;\n      padding: 10px;\n      margin-bottom: 16px;\n      line-height: 1.5;\n      text-align: left;\n    }\n    #carbonads .carbon-poweredby {\n      display: block;\n      padding: 6px 8px;\n      background: #f1f1f2;\n      text-align: center;\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n      font-weight: 600;\n      font-size: 8px;\n      line-height: 1;\n      border-top-left-radius: 3px;\n      position: absolute;\n      bottom: 0;\n      right: 0;\n    }\n    `,\n  ],\n  menus: {\n    '/guide': [\n      {\n        title: 'Introduction',\n        path: '/guide',\n      },\n      { title: 'Concept', path: '/guide/concept' },\n      {\n        title: 'Best Practice',\n        path: '/guide/best-practice',\n      },\n    ],\n    '/api': [\n      {\n        title: '@formily/reactive',\n        children: [\n          {\n            title: 'observable',\n            path: '/api/observable',\n          },\n          {\n            title: 'autorun',\n            path: '/api/autorun',\n          },\n          {\n            title: 'reaction',\n            path: '/api/reaction',\n          },\n\n          {\n            title: 'batch',\n            path: '/api/batch',\n          },\n          {\n            title: 'action',\n            path: '/api/action',\n          },\n          {\n            title: 'define',\n            path: '/api/define',\n          },\n          {\n            title: 'model',\n            path: '/api/model',\n          },\n          {\n            title: 'observe',\n            path: '/api/observe',\n          },\n          {\n            title: 'markRaw',\n            path: '/api/mark-raw',\n          },\n          {\n            title: 'markObservable',\n            path: '/api/mark-observable',\n          },\n          {\n            title: 'raw',\n            path: '/api/raw',\n          },\n          {\n            title: 'toJS',\n            path: '/api/to-js',\n          },\n          {\n            title: 'untracked',\n            path: '/api/untracked',\n          },\n          {\n            title: 'hasCollected',\n            path: '/api/has-collected',\n          },\n          {\n            title: 'Tracker',\n            path: '/api/tracker',\n          },\n          {\n            title: 'Type Chekcer',\n            path: '/api/type-checker',\n          },\n        ],\n      },\n      {\n        title: '@formily/reactive-react',\n        children: [\n          {\n            title: 'observer',\n            path: '/api/react/observer',\n          },\n        ],\n      },\n      {\n        title: '@formily/reactive-vue',\n        children: [\n          {\n            title: 'observer',\n            path: '/api/vue/observer',\n          },\n        ],\n      },\n    ],\n    '/zh-CN/guide': [\n      {\n        title: '介绍',\n        path: '/zh-CN/guide',\n      },\n      { title: '核心概念', path: '/zh-CN/guide/concept' },\n      {\n        title: '最佳实践',\n        path: '/zh-CN/guide/best-practice',\n      },\n    ],\n    '/zh-CN/api': [\n      {\n        title: '@formily/reactive',\n        children: [\n          {\n            title: 'observable',\n            path: '/zh-CN/api/observable',\n          },\n          {\n            title: 'autorun',\n            path: '/zh-CN/api/autorun',\n          },\n          {\n            title: 'reaction',\n            path: '/zh-CN/api/reaction',\n          },\n\n          {\n            title: 'batch',\n            path: '/zh-CN/api/batch',\n          },\n          {\n            title: 'action',\n            path: '/zh-CN/api/action',\n          },\n          {\n            title: 'define',\n            path: '/zh-CN/api/define',\n          },\n          {\n            title: 'model',\n            path: '/zh-CN/api/model',\n          },\n          {\n            title: 'observe',\n            path: '/zh-CN/api/observe',\n          },\n          {\n            title: 'markRaw',\n            path: '/zh-CN/api/mark-raw',\n          },\n          {\n            title: 'markObservable',\n            path: '/zh-CN/api/mark-observable',\n          },\n          {\n            title: 'raw',\n            path: '/zh-CN/api/raw',\n          },\n          {\n            title: 'toJS',\n            path: '/zh-CN/api/to-js',\n          },\n          {\n            title: 'untracked',\n            path: '/zh-CN/api/untracked',\n          },\n          {\n            title: 'hasCollected',\n            path: '/zh-CN/api/has-collected',\n          },\n          {\n            title: 'Tracker',\n            path: '/zh-CN/api/tracker',\n          },\n          {\n            title: 'Type Chekcer',\n            path: '/zh-CN/api/type-checker',\n          },\n        ],\n      },\n      {\n        title: '@formily/reactive-react',\n        children: [\n          {\n            title: 'observer',\n            path: '/zh-CN/api/react/observer',\n          },\n        ],\n      },\n      {\n        title: '@formily/reactive-vue',\n        children: [\n          {\n            title: 'observer',\n            path: '/zh-CN/api/vue/observer',\n          },\n        ],\n      },\n    ],\n  },\n}\n"
  },
  {
    "path": "packages/reactive/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-present, Alibaba Group Holding Limited. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/reactive/README.md",
    "content": "# @formily/reactive\n\n> Web Reactive Library Like Mobx\n\n## QuikStart\n"
  },
  {
    "path": "packages/reactive/benchmark.ts",
    "content": "import b from 'benny'\nimport _ from 'lodash'\nimport * as mobx from 'mobx'\nimport * as vueReactivity from '@vue/reactivity'\nimport * as formilyReactive from './src'\n\nfunction func(obs, times) {\n  obs.arr = []\n  obs.obj = {}\n  _.times(times, (v) => {\n    obs.num = v\n    obs.str = `${v}`\n    obs.arr.push(v)\n    obs.obj[`${v}`] = v\n  })\n}\n\nb.suite(\n  'Reactive Observable',\n\n  b.add('Case MobX', () => {\n    const obs = mobx.observable({})\n    func(obs, 1e3)\n  }),\n\n  b.add('Case @vue/reactivity', () => {\n    const obs = vueReactivity.reactive({})\n    func(obs, 1e3)\n  }),\n\n  b.add('Case @formily/reactive', () => {\n    const obs = formilyReactive.observable({})\n    func(obs, 1e3)\n  }),\n\n  b.cycle(),\n  b.complete()\n)\n"
  },
  {
    "path": "packages/reactive/docs/api/action.md",
    "content": "# action\n\n## Description\n\nDefine a batch action. The only difference with batch is that dependencies cannot be collected inside an action\n\n## Signature\n\n```ts\ninterface action {\n  <T>(callback?: () => T): T //In-situ action\n  scope<T>(callback?: () => T): T //In-situ local action\n  bound<T extends (...args: any[]) => any>(callback: T, context?: any): T //High-level binding\n}\n```\n\n## Example\n\n```ts\nimport { observable, action } from '@formily/reactive'\n\nconst obs = observable({})\n\nconst method = action.bound(() => {\n  obs.aa = 123\n  obs.bb = 321\n})\n\nmethod()\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/action.zh-CN.md",
    "content": "# action\n\n## 描述\n\n定义一个批量动作。与 batch 的唯一差别就是 action 内部是无法收集依赖的\n\n## 签名\n\n```ts\ninterface action {\n  <T>(callback?: () => T): T //原地action\n  scope<T>(callback?: () => T): T //原地局部action\n  bound<T extends (...args: any[]) => any>(callback: T, context?: any): T //高阶绑定\n}\n```\n\n## 用例\n\n```ts\nimport { observable, action } from '@formily/reactive'\n\nconst obs = observable({})\n\nconst method = action.bound(() => {\n  obs.aa = 123\n  obs.bb = 321\n})\n\nmethod()\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/autorun.md",
    "content": "# autorun\n\n## Description\n\nReceive a tracker function, if there is observable data in the function, the tracker function will be executed repeatedly when the data changes\n\n## Signature\n\n```ts\ninterface autorun {\n  (tracker: () => void, name?: string): void\n}\n```\n\n## Example\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\n\nconst obs = observable({})\n\nconst dispose = autorun(() => {\n  console.log(obs.aa)\n})\n\nobs.aa = 123\n\ndispose()\n```\n\n## autorun.memo\n\n### Description\n\nUsed in autorun to create persistent reference data, only re-execute memo internal functions due to dependency changes\n\nNote: Please do not use it in If/For statements, because it depends on the execution order to bind the current autorun\n\n### Signature\n\n```ts\ninterface memo<T> {\n  (callback: () => T, dependencies: any[] = []): T\n}\n```\n\nNote: The default dependency is `[]`, that is, if the dependency is not passed, it means that the second time will never be executed\n\n### Example\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\n\nconst obs1 = observable({\n  aa: 0,\n})\n\nconst dispose = autorun(() => {\n  const obs2 = autorun.memo(() =>\n    observable({\n      bb: 0,\n    })\n  )\n  console.log(obs1.aa, obs2.bb++)\n})\n\nobs1.aa++\nobs1.aa++\nobs1.aa++\n//Execute four times, the output result is\n/**\n * 0 0\n * 1 1\n * twenty two\n * 3 3\n */\n\ndispose()\n```\n\n## autorun.effect\n\n### Description\n\nIn autorun, it is used to respond to the next micro task timing of autorun's first execution and the dispose of responding to autorun\n\nNote: Please do not use it in If/For statements, because it depends on the execution order to bind the current autorun\n\n### Signature\n\n```ts\ninterface effect {\n  (callback: () => void | (() => void), dependencies: any[] = [{}]): void\n}\n```\n\nNote: The default dependency is `[{}]`, that is, if the dependency is not passed, the representative will continue to execute, because the internal dirty check is a shallow comparison\n\n### Example\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\n\nconst obs1 = observable({\n  aa: 0,\n})\nconst dispose = autorun(() => {\n  const obs2 = autorun.memo(() =>\n    observable({\n      bb: 0,\n    })\n  )\n  console.log(obs1.aa, obs2.bb++)\n  autorun.effect(() => {\n    obs2.bb++\n  }, [])\n})\nobs1.aa++\nobs1.aa++\nobs1.aa++\n//Execute five times, the output result is\n/**\n * 0 0\n * 1 1\n * twenty two\n * 3 3\n * 3 5\n */\n\ndispose()\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/autorun.zh-CN.md",
    "content": "# autorun\n\n## 描述\n\n接收一个 tracker 函数，如果函数内部有消费 observable 数据，数据发生变化时，tracker 函数会重复执行\n\n## 签名\n\n```ts\ninterface autorun {\n  (tracker: () => void, name?: string): void\n}\n```\n\n## 用例\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\n\nconst obs = observable({})\n\nconst dispose = autorun(() => {\n  console.log(obs.aa)\n})\n\nobs.aa = 123\n\ndispose()\n```\n\n## autorun.memo\n\n### 描述\n\n在 autorun 中用于创建持久引用数据，仅仅只会受依赖变化而重新执行 memo 内部函数\n\n注意：请不要在 If/For 这类语句中使用，因为它内部是依赖执行顺序来绑定当前 autorun 的\n\n### 签名\n\n```ts\ninterface memo<T> {\n  (callback: () => T, dependencies: any[] = []): T\n}\n```\n\n注意：依赖默认为`[]`，也就是如果不传依赖，代表永远不会执行第二次\n\n### 用例\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\n\nconst obs1 = observable({\n  aa: 0,\n})\n\nconst dispose = autorun(() => {\n  const obs2 = autorun.memo(() =>\n    observable({\n      bb: 0,\n    })\n  )\n  console.log(obs1.aa, obs2.bb++)\n})\n\nobs1.aa++\nobs1.aa++\nobs1.aa++\n//执行四次，输出结果为\n/**\n * 0 0\n * 1 1\n * 2 2\n * 3 3\n */\n\ndispose()\n```\n\n## autorun.effect\n\n### 描述\n\n在 autorun 中用于响应 autorun 第一次执行的下一个微任务时机与响应 autorun 的 dispose\n\n注意：请不要在 If/For 这类语句中使用，因为它内部是依赖执行顺序来绑定当前 autorun 的\n\n### 签名\n\n```ts\ninterface effect {\n  (callback: () => void | (() => void), dependencies: any[] = [{}]): void\n}\n```\n\n注意：依赖默认为`[{}]`，也就是如果不传依赖，代表会持续执行，因为内部脏检查是浅比较\n\n### 用例\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\n\nconst obs1 = observable({\n  aa: 0,\n})\nconst dispose = autorun(() => {\n  const obs2 = autorun.memo(() =>\n    observable({\n      bb: 0,\n    })\n  )\n  console.log(obs1.aa, obs2.bb++)\n  autorun.effect(() => {\n    obs2.bb++\n  }, [])\n})\nobs1.aa++\nobs1.aa++\nobs1.aa++\n//执行五次，输出结果为\n/**\n * 0 0\n * 1 1\n * 2 2\n * 3 3\n * 3 5\n */\n\ndispose()\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/batch.md",
    "content": "# batch\n\n## Description\n\nDefine batch operations, internal dependencies can be collected\n\n## Signature\n\n```ts\ninterface batch {\n  <T>(callback?: () => T): T //In-place batch\n  scope<T>(callback?: () => T): T //In-situ local batch\n  bound<T extends (...args: any[]) => any>(callback: T, context?: any): T //High-level binding\n  endpoint(callback?: () => void): void //Register batch endpoint callback\n}\n```\n\n## Example\n\n```ts\nimport { observable, autorun, batch } from '@formily/reactive'\n\nconst obs = observable({})\n\nautorun(() => {\n  console.log(obs.aa, obs.bb, obs.cc, obs.dd)\n})\n\nbatch(() => {\n  batch.scope(() => {\n    obs.aa = 123\n  })\n  batch.scope(() => {\n    obs.cc = 'ccccc'\n  })\n  obs.bb = 321\n  obs.dd = 'dddd'\n})\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/batch.zh-CN.md",
    "content": "# batch\n\n## 描述\n\n定义批量操作，内部可以收集依赖\n\n## 签名\n\n```ts\ninterface batch {\n  <T>(callback?: () => T): T //原地batch\n  scope<T>(callback?: () => T): T //原地局部batch\n  bound<T extends (...args: any[]) => any>(callback: T, context?: any): T //高阶绑定\n  endpoint(callback?: () => void): void //注册批量执行结束回调\n}\n```\n\n## 用例\n\n```ts\nimport { observable, autorun, batch } from '@formily/reactive'\n\nconst obs = observable({})\n\nautorun(() => {\n  console.log(obs.aa, obs.bb, obs.cc, obs.dd)\n})\n\nbatch(() => {\n  batch.scope(() => {\n    obs.aa = 123\n  })\n  batch.scope(() => {\n    obs.cc = 'ccccc'\n  })\n  obs.bb = 321\n  obs.dd = 'dddd'\n})\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/define.md",
    "content": "# define\n\n## Description\n\nManually define the domain model, you can specify the responsive behavior of specific attributes, or you can specify a method as batch mode\n\n## Signature\n\n```ts\ninterface define<Target extends object> {\n  (\n    target: Target,\n    annotations?: {\n      [key: string]: (...args: any[]) => any\n    }\n  ): Target\n}\n```\n\n## Annotations\n\nAll Annotations currently supported are:\n\n- observable/observable.deep defines deep hijacking responsive properties\n- observable.box defines get/set container\n- observable.computed defines calculated properties\n- observable.ref defines reference hijacking responsive attributes\n- observable.shallow defines shallow hijacking responsive properties\n- action/batch defines the batch processing method\n\n## Example\n\n```ts\nimport { define, observable, action, autorun } from '@formily/reactive'\n\nclass DomainModel {\n  deep = { aa: 1 }\n  shallow = {}\n  box = 0\n  ref = ''\n\n  constructor() {\n    define(this, {\n      deep: observable,\n      shallow: observable.shallow,\n      box: observable.box,\n      ref: observable.ref,\n      computed: observable.computed,\n      action,\n    })\n  }\n\n  get computed() {\n    return this.deep.aa + this.box.get()\n  }\n  action(aa, box) {\n    this.deep.aa = aa\n    this.box.set(box)\n  }\n}\n\nconst model = new DomainModel()\n\nautorun(() => {\n  console.log(model.computed)\n})\n\nmodel.action(1, 2)\nmodel.action(1, 2) //Repeat calls will not respond repeatedly\nmodel.action(3, 4)\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/define.zh-CN.md",
    "content": "# define\n\n## 描述\n\n手动定义领域模型，可以指定具体属性的响应式行为，也可以指定某个方法为 batch 模式\n\n## 签名\n\n```ts\ninterface define<Target extends object> {\n  (\n    target: Target,\n    annotations?: {\n      [key: string]: (...args: any[]) => any\n    }\n  ): Target\n}\n```\n\n## Annotations\n\n目前支持的所有 Annotation 有：\n\n- observable/observable.deep 定义深度劫持响应式属性\n- observable.box 定义 get/set 容器\n- observable.computed 定义计算属性\n- observable.ref 定义引用劫持响应式属性\n- observable.shallow 定义浅劫持响应式属性\n- action/batch 定义批处理方法\n\n## 用例\n\n```ts\nimport { define, observable, action, autorun } from '@formily/reactive'\n\nclass DomainModel {\n  deep = { aa: 1 }\n  shallow = {}\n  box = 0\n  ref = ''\n\n  constructor() {\n    define(this, {\n      deep: observable,\n      shallow: observable.shallow,\n      box: observable.box,\n      ref: observable.ref,\n      computed: observable.computed,\n      action,\n    })\n  }\n\n  get computed() {\n    return this.deep.aa + this.box.get()\n  }\n  action(aa, box) {\n    this.deep.aa = aa\n    this.box.set(box)\n  }\n}\n\nconst model = new DomainModel()\n\nautorun(() => {\n  console.log(model.computed)\n})\n\nmodel.action(1, 2)\nmodel.action(1, 2) //重复调用不会重复响应\nmodel.action(3, 4)\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/hasCollected.md",
    "content": "# hasCollected\n\n## describe\n\nUsed to detect whether a certain piece of execution logic has dependent collection\n\n## Signature\n\n```ts\ninterface hasCollected {\n  (callback?: () => void): boolean\n}\n```\n\n## Example\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\n\nconst obs = observable({\n  aa: 11,\n})\n\nautorun(() => {\n  console.log(\n    hasCollected(() => {\n      obs.aa\n    })\n  ) //return true\n  console.log(\n    hasCollected(() => {\n      11 + 22\n    })\n  ) //return false\n})\n\nobs.aa = 22\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/hasCollected.zh-CN.md",
    "content": "# hasCollected\n\n## 描述\n\n用于检测某段执行逻辑是否存在依赖收集\n\n## 签名\n\n```ts\ninterface hasCollected {\n  (callback?: () => void): boolean\n}\n```\n\n## 用例\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\n\nconst obs = observable({\n  aa: 11,\n})\n\nautorun(() => {\n  console.log(\n    hasCollected(() => {\n      obs.aa\n    })\n  ) //return true\n  console.log(\n    hasCollected(() => {\n      11 + 22\n    })\n  ) //return false\n})\n\nobs.aa = 22\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/markObservable.md",
    "content": "# markObservable\n\n## Description\n\nMark any object or class prototype as being hijacked by observable. React Node and objects with toJSON/toJS methods will be automatically bypassed in @formily/reactive. In special scenarios, we may hope that the object should be hijacked, so you can use it markObservable mark\n\n## Signature\n\n```ts\ninterface markObservable<T> {\n  (target: T): T\n}\n```\n\n## Example\n\n```ts\nimport { observable, autorun, markObservable } from '@formily/reactive'\n\nclass A {\n  property = ''\n\n  toJSON() {}\n}\n\nconst a = observable(new A())\n\nautorun(() => {\n  console.log(a.property) //will not be triggered when the property changes, because there is a toJSON method in the A instance\n})\n\na.property = 123\n\n//--------------------------------------------\n\nconst b = observable(markObservable(new A())) //instance-level mark, only valid for the current instance\n\nautorun(() => {\n  console.log(b.property) //Can be triggered when the property changes, because it has been marked as observable\n})\n\nb.property = 123\n\n//--------------------------------------------\n\nmarkObservable(A) //Class-level mark, then all instances will take effect\n\nconst c = observable(new A())\n\nautorun(() => {\n  console.log(c.property) //Can be triggered when the property changes, because it has been marked as observable\n})\n\nc.property = 123\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/markObservable.zh-CN.md",
    "content": "# markObservable\n\n## 描述\n\n标记任意一个对象或者类原型为可被 observable 劫持，在@formily/reactive 中会自动绕过 React Node 与带有 toJSON/toJS 方法的对象，特殊场景，我们可能希望该对象应该被劫持，所以可以使用 markObservable 标记\n\n## 签名\n\n```ts\ninterface markObservable<T> {\n  (target: T): T\n}\n```\n\n## 用例\n\n```ts\nimport { observable, autorun, markObservable } from '@formily/reactive'\n\nclass A {\n  property = ''\n\n  toJSON() {}\n}\n\nconst a = observable(new A())\n\nautorun(() => {\n  console.log(a.property) //property变化时不会被触发，因为A实例中有toJSON方法\n})\n\na.property = 123\n\n//--------------------------------------------\n\nconst b = observable(markObservable(new A())) //实例级标记，只对当前实例生效\n\nautorun(() => {\n  console.log(b.property) //property变化时可以被触发，因为已被标记observable\n})\n\nb.property = 123\n\n//--------------------------------------------\n\nmarkObservable(A) //类级标记，那么所有实例都会生效\n\nconst c = observable(new A())\n\nautorun(() => {\n  console.log(c.property) //property变化时可以被触发，因为已被标记observable\n})\n\nc.property = 123\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/markRaw.md",
    "content": "# markRaw\n\n## Description\n\nMark any object or class prototype as never being hijacked by observable, priority is higher than markObservable\n\nNote: If you mark an object that is already observable with markRaw, then toJS will not convert it into a normal object\n\n## Signature\n\n```ts\ninterface markRaw<T> {\n  (target: T): T\n}\n```\n\n## Example\n\n```ts\nimport { observable, autorun, markRaw } from '@formily/reactive'\n\nclass A {\n  property = ''\n}\n\nconst a = observable(new A())\n\nautorun(() => {\n  console.log(a.property) //It will be triggered when the property changes, because the A instance is a normal object\n})\n\na.property = 123\n\n//--------------------------------------------\n\nconst b = observable(markRaw(new A())) //instance-level mark, only valid for the current instance\n\nautorun(() => {\n  console.log(b.property) //will not be triggered when the property changes, because it has been marked raw\n})\n\nb.property = 123\n\n//--------------------------------------------\n\nmarkRaw(A) //Class-level mark, then all instances will take effect\n\nconst c = observable(new A())\n\nautorun(() => {\n  console.log(c.property) //will not be triggered when the property changes, because it has been marked raw\n})\n\nc.property = 123\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/markRaw.zh-CN.md",
    "content": "# markRaw\n\n## 描述\n\n标记任意一个对象或者类原型为永远不可被 observable 劫持，优先级比 markObservable 高\n\n注意：如果对一个已经是 observable 的对象标记 markRaw，那么 toJS，是不会将它转换成普通对象的\n\n## 签名\n\n```ts\ninterface markRaw<T> {\n  (target: T): T\n}\n```\n\n## 用例\n\n```ts\nimport { observable, autorun, markRaw } from '@formily/reactive'\n\nclass A {\n  property = ''\n}\n\nconst a = observable(new A())\n\nautorun(() => {\n  console.log(a.property) //property变化时会被触发，因为A实例是普通对象\n})\n\na.property = 123\n\n//--------------------------------------------\n\nconst b = observable(markRaw(new A())) //实例级标记，只对当前实例生效\n\nautorun(() => {\n  console.log(b.property) //property变化时不会被触发，因为已被标记raw\n})\n\nb.property = 123\n\n//--------------------------------------------\n\nmarkRaw(A) //类级标记，那么所有实例都会生效\n\nconst c = observable(new A())\n\nautorun(() => {\n  console.log(c.property) //property变化时不会被触发，因为已被标记raw\n})\n\nc.property = 123\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/model.md",
    "content": "# model\n\n## Description\n\nQuickly define the domain model, and automatically declare the model attributes:\n\n- Automatic declaration of getter/setter properties computed\n- Function automatically declare action\n- Common attributes are automatically declared observable\n\n## Signature\n\n```ts\ninterface model<Target extends object> {\n  (target: Target): Target\n}\n```\n\n## Example\n\n```ts\nimport { model, autorun } from '@formily/reactive'\n\nconst obs = model({\n  aa: 1,\n  bb: 2,\n  get cc() {\n    return this.aa + this.bb\n  },\n  update(aa, bb) {\n    this.aa=aa\n    this.bb=bb\n  },\n})\n\nautorun(() => {\n  console.log(obs.cc)\n})\n\nobs.aa = 3\n\nobs.update(4, 6)\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/model.zh-CN.md",
    "content": "# model\n\n## 描述\n\n快速定义领域模型，会对模型属性做自动声明：\n\n- getter/setter 属性自动声明 computed\n- 函数自动声明 action\n- 普通属性自动声明 observable\n\n## 签名\n\n```ts\ninterface model<Target extends object> {\n  (target: Target): Target\n}\n```\n\n## 用例\n\n```ts\nimport { model, autorun } from '@formily/reactive'\n\nconst obs = model({\n  aa: 1,\n  bb: 2,\n  get cc() {\n    return this.aa + this.bb\n  },\n  update(aa, bb) {\n    this.aa=aa\n    this.bb=bb\n  },\n})\n\nautorun(() => {\n  console.log(obs.cc)\n})\n\nobs.aa = 3\n\nobs.update(4, 6)\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/observable.md",
    "content": "# observable\n\n> Mainly used to create observable objects with different responsive behaviors, and can be used as an annotation to define to mark responsive attributes\n\n## observable/observable.deep\n\n### Description\n\nCreate deep hijacking responsive objects\n\n### Signature\n\n```ts\ninterface observable<T extends object> {\n  (target: T): T\n}\n\ninterface deep<T extends object> {\n  (target: T): T\n}\n```\n\n### Example\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\n\nconst obs = observable({\n  aa: {\n    bb: 123,\n  },\n})\n\nautorun(() => {\n  console.log(obs.aa.bb)\n})\n\nobs.aa.bb = 321\n```\n\n## observable.shallow\n\n### Description\n\nCreate shallow hijacking responsive objects, that is, only respond to the first-level attribute operations of the target object\n\n### Signature\n\n```ts\ninterface shallow<T extends object> {\n  (target: T): T\n}\n```\n\n### Example\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\n\nconst obs = observable.shallow({\n  aa: {\n    bb: 111,\n  },\n})\n\nautorun(() => {\n  console.log(obs.aa.bb)\n})\n\nobs.aa.bb = 222 // will not respond\nobs.aa = { bb: 333 } // can respond\n```\n\n## observable.computed\n\n### Description\n\nCreate a calculation buffer\n\n### Signature\n\n```ts\ninterface computed {\n  <T extends () => any>(target: T): { value: ReturnType<T> }\n  <T extends { get?: () => any; set?: (value: any) => void }>(target: T): {\n    value: ReturnType<T['get']>\n  }\n}\n```\n\n### Example\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\n\nconst obs = observable({\n  aa: 11,\n  bb: 22,\n})\n\nconst computed = observable.computed(() => obs.aa + obs.bb)\n\nautorun(() => {\n  console.log(computed.value)\n})\n\nobs.aa = 33\n```\n\n## observable.ref\n\n### Description\n\nCreate reference hijacking responsive objects\n\n### Signature\n\n```ts\ninterface ref<T extends object> {\n  (target: T): { value: T }\n}\n```\n\n### Example\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\n\nconst ref = observable.ref(1)\n\nautorun(() => {\n  console.log(ref.value)\n})\n\nref.value = 2\n```\n\n## observable.box\n\n### Description\n\nSimilar to ref, except that the data is read and written through the get/set method\n\n### Signature\n\n```ts\ninterface box<T extends object> {\n  (target: T): { get: () => T; set: (value: T) => void }\n}\n```\n\n### Example\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\n\nconst box = observable.box(1)\n\nautorun(() => {\n  console.log(box.get())\n})\n\nbox.set(2)\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/observable.zh-CN.md",
    "content": "# observable\n\n> 主要用于创建不同响应式行为的 observable 对象，同时可以作为 annotation 给 define 用于标记响应式属性\n\n## observable/observable.deep\n\n### 描述\n\n创建深度劫持响应式对象\n\n### 签名\n\n```ts\ninterface observable<T extends object> {\n  (target: T): T\n}\n\ninterface deep<T extends object> {\n  (target: T): T\n}\n```\n\n### 用例\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\n\nconst obs = observable({\n  aa: {\n    bb: 123,\n  },\n})\n\nautorun(() => {\n  console.log(obs.aa.bb)\n})\n\nobs.aa.bb = 321\n```\n\n## observable.shallow\n\n### 描述\n\n创建浅劫持响应式对象，也就是只会对目标对象的第一级属性操作响应\n\n### 签名\n\n```ts\ninterface shallow<T extends object> {\n  (target: T): T\n}\n```\n\n### 用例\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\n\nconst obs = observable.shallow({\n  aa: {\n    bb: 111,\n  },\n})\n\nautorun(() => {\n  console.log(obs.aa.bb)\n})\n\nobs.aa.bb = 222 // 不会响应\nobs.aa = { bb: 333 } // 可以响应\n```\n\n## observable.computed\n\n### 描述\n\n创建一个计算缓存器\n\n### 签名\n\n```ts\ninterface computed {\n  <T extends () => any>(target: T): { value: ReturnType<T> }\n  <T extends { get?: () => any; set?: (value: any) => void }>(target: T): {\n    value: ReturnType<T['get']>\n  }\n}\n```\n\n### 用例\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\n\nconst obs = observable({\n  aa: 11,\n  bb: 22,\n})\n\nconst computed = observable.computed(() => obs.aa + obs.bb)\n\nautorun(() => {\n  console.log(computed.value)\n})\n\nobs.aa = 33\n```\n\n## observable.ref\n\n### 描述\n\n创建引用劫持响应式对象\n\n### 签名\n\n```ts\ninterface ref<T extends object> {\n  (target: T): { value: T }\n}\n```\n\n### 用例\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\n\nconst ref = observable.ref(1)\n\nautorun(() => {\n  console.log(ref.value)\n})\n\nref.value = 2\n```\n\n## observable.box\n\n### 描述\n\n与 ref 相似，只是读写数据是通过 get/set 方法\n\n### 签名\n\n```ts\ninterface box<T extends object> {\n  (target: T): { get: () => T; set: (value: T) => void }\n}\n```\n\n### 用例\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\n\nconst box = observable.box(1)\n\nautorun(() => {\n  console.log(box.get())\n})\n\nbox.set(2)\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/observe.md",
    "content": "# observe\n\n## Description\n\nVery different from autorun/reaction/Tracker, using observe will monitor all operations of observable objects, support deep monitoring and shallow monitoring\n\n<Alert>\nNote: The read operation will not be monitored\n</Alert>\n\n## Signature\n\n```ts\ntype PropertyKey = string | number | symbol\n\ntype ObservablePath = Array<string | number>\n\ntype OperationType =\n  | 'add'\n  | 'delete'\n  | 'clear'\n  | 'set'\n  | 'get'\n  | 'iterate'\n  | 'has'\n\ninterface IChange {\n  key?: PropertyKey\n  path?: ObservablePath\n  object?: object\n  value?: any\n  oldValue?: any\n  type?: OperationType\n}\n\ninterface IDispose {\n  (): void\n}\n\ninterface observe {\n  (\n    target: object,\n    observer?: (change: IChange) => void,\n    deep?: boolean //default is true\n  ): IDispose //Release the monitor\n}\n```\n\n## Example\n\n```ts\nimport { observable, observe } from '@formily/reactive'\n\nconst obs = observable({\n  aa: 11,\n})\n\nconst dispose = observe(obs, (change) => {\n  console.log(change)\n})\n\nobs.aa = 22\n\ndispose()\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/observe.zh-CN.md",
    "content": "# observe\n\n## 描述\n\n与 autorun/reaction/Tracker 非常不一样，使用 observe 会监听 observable 对象的所有操作，支持深度监听也支持浅监听\n\n<Alert>\n注意：读取操作是不会被监听到的\n</Alert>\n\n## 签名\n\n```ts\ntype PropertyKey = string | number | symbol\n\ntype ObservablePath = Array<string | number>\n\ntype OperationType =\n  | 'add'\n  | 'delete'\n  | 'clear'\n  | 'set'\n  | 'get'\n  | 'iterate'\n  | 'has'\n\ninterface IChange {\n  key?: PropertyKey\n  path?: ObservablePath\n  object?: object\n  value?: any\n  oldValue?: any\n  type?: OperationType\n}\n\ninterface IDispose {\n  (): void\n}\n\ninterface observe {\n  (\n    target: object,\n    observer?: (change: IChange) => void,\n    deep?: boolean //默认为true\n  ): IDispose //释放监听\n}\n```\n\n## 用例\n\n```ts\nimport { observable, observe } from '@formily/reactive'\n\nconst obs = observable({\n  aa: 11,\n})\n\nconst dispose = observe(obs, (change) => {\n  console.log(change)\n})\n\nobs.aa = 22\n\ndispose()\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/raw.md",
    "content": "# raw\n\n## Description\n\nObtain the source data from the observable object. Generally, this API is not recommended\n\n<Alert>\nNote: Only the source data of the current object can be obtained, excluding deep object properties\n</Alert>\n\n## Signature\n\n```ts\ninterface raw<T extends object> {\n  (target: T): T\n}\n```\n\n## Example\n\n```ts\nimport { raw, observable } from '@formily/reactive'\n\nconst obs = observable({})\n\nobs.aa = { bb: 123 }\n\nconsole.log(raw(obs))\nconsole.log(raw(obs.aa))\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/raw.zh-CN.md",
    "content": "# raw\n\n## 描述\n\n从 observable 对象中获取源数据，通常情况下并不推荐使用该 API\n\n<Alert>\n注意：只能获取当前对象的源数据，不包括深层对象属性\n</Alert>\n\n## 签名\n\n```ts\ninterface raw<T extends object> {\n  (target: T): T\n}\n```\n\n## 用例\n\n```ts\nimport { raw, observable } from '@formily/reactive'\n\nconst obs = observable({})\n\nobs.aa = { bb: 123 }\n\nconsole.log(raw(obs))\nconsole.log(raw(obs.aa))\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/react/observer.md",
    "content": "# observer\n\n## observer\n\n### Description\n\nIn React, turn Function Component into Reaction, and dependencies will be collected every time the view is re-rendered, and dependency updates will be automatically re-rendered\n\n<Alert>\nNote: Only Function Component is supported\n</Alert>\n\n### Signature\n\n```ts\ninterface IObserverOptions {\n  forwardRef?: boolean //Whether to pass the reference transparently\n  scheduler?: (updater: () => void) => void //The scheduler, you can manually control the timing of the update\n  displayName?: string //displayName of the packaged component\n}\n\ninterface observer<T extends React.FC> {\n  (component: T, options?: IObserverOptions): T\n}\n```\n\n### Example\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React from 'react'\nimport { observable } from '@formily/reactive'\nimport { observer } from '@formily/reactive-react'\n\nconst obs = observable({\n  value: 'Hello world',\n})\n\nexport default observer(() => {\n  return (\n    <div>\n      <div>\n        <input\n          style={{\n            height: 28,\n            padding: '0 8px',\n            border: '2px solid #888',\n            borderRadius: 3,\n          }}\n          value={obs.value}\n          onChange={(e) => {\n            obs.value = e.target.value\n          }}\n        />\n      </div>\n      <div>{obs.value}</div>\n    </div>\n  )\n})\n```\n\n## Observer\n\n### Description\n\nSimilar to Vue's responsive slot, it receives a Function RenderProps, as long as any responsive data consumed inside the Function, it will be automatically re-rendered as the data changes, and it is easier to achieve local accurate rendering\n\n### Signature\n\n```ts\ninterface IObserverProps {\n  children?: () => React.ReactElement\n}\n\ntype Observer = React.FC<React.PropsWithChildren<IObserverProps>>\n```\n\n### Example\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React from 'react'\nimport { observable } from '@formily/reactive'\nimport { Observer } from '@formily/reactive-react'\n\nconst obs = observable({\n  value: 'Hello world',\n})\n\nexport default () => {\n  return (\n    <div>\n      <div>\n        <Observer>\n          {() => (\n            <input\n              style={{\n                height: 28,\n                padding: '0 8px',\n                border: '2px solid #888',\n                borderRadius: 3,\n              }}\n              value={obs.value}\n              onChange={(e) => {\n                obs.value = e.target.value\n              }}\n            />\n          )}\n        </Observer>\n      </div>\n      <Observer>{() => <div>{obs.value}</div>}</Observer>\n    </div>\n  )\n}\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/react/observer.zh-CN.md",
    "content": "# observer\n\n## observer\n\n### 描述\n\n在 React 中，将 Function Component 变成 Reaction，每次视图重新渲染就会收集依赖，依赖更新会自动重渲染\n\n<Alert>\n注意：只支持Function Component\n</Alert>\n\n### 签名\n\n```ts\ninterface IObserverOptions {\n  forwardRef?: boolean //是否透传引用\n  scheduler?: (updater: () => void) => void //调度器，可以手动控制更新时机\n  displayName?: string //包装后的组件的displayName\n}\n\ninterface observer<T extends React.FC> {\n  (component: T, options?: IObserverOptions): T\n}\n```\n\n### 用例\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React from 'react'\nimport { observable } from '@formily/reactive'\nimport { observer } from '@formily/reactive-react'\n\nconst obs = observable({\n  value: 'Hello world',\n})\n\nexport default observer(() => {\n  return (\n    <div>\n      <div>\n        <input\n          style={{\n            height: 28,\n            padding: '0 8px',\n            border: '2px solid #888',\n            borderRadius: 3,\n          }}\n          value={obs.value}\n          onChange={(e) => {\n            obs.value = e.target.value\n          }}\n        />\n      </div>\n      <div>{obs.value}</div>\n    </div>\n  )\n})\n```\n\n## Observer\n\n### 描述\n\n类似于 Vue 的响应式 Slot，它接收一个 Function RenderProps，只要在 Function 内部消费到的任何响应式数据，都会随数据变化而自动重新渲染，也更容易实现局部精确渲染\n\n### 签名\n\n```ts\ninterface IObserverProps {\n  children?: () => React.ReactElement\n}\n\ntype Observer = React.FC<React.PropsWithChildren<IObserverProps>>\n```\n\n### 用例\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React from 'react'\nimport { observable } from '@formily/reactive'\nimport { Observer } from '@formily/reactive-react'\n\nconst obs = observable({\n  value: 'Hello world',\n})\n\nexport default () => {\n  return (\n    <div>\n      <div>\n        <Observer>\n          {() => (\n            <input\n              style={{\n                height: 28,\n                padding: '0 8px',\n                border: '2px solid #888',\n                borderRadius: 3,\n              }}\n              value={obs.value}\n              onChange={(e) => {\n                obs.value = e.target.value\n              }}\n            />\n          )}\n        </Observer>\n      </div>\n      <Observer>{() => <div>{obs.value}</div>}</Observer>\n    </div>\n  )\n}\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/reaction.md",
    "content": "# reaction\n\n## Description\n\nReceive a tracker function and a callback response function. If there is observable data in the tracker, the tracker function will be executed repeatedly when the data changes, but the callback execution must be executed when the tracker function return value changes.\n\n## Signature\n\n```ts\ninterface IReactionOptions<T> {\n  name?: string\n  equals?: (oldValue: T, newValue: T) => boolean //Dirty check\n  fireImmediately?: boolean //Is it triggered by default for the first time, bypassing the dirty check\n}\n\ninterface reaction<T> {\n  (\n    tracker: () => T,\n    subscriber?: (newValue: T, oldValue: T) => void,\n    options?: IReactionOptions<T>\n  ): void\n}\n```\n\n## Example\n\n```ts\nimport { observable, reaction, batch } from '@formily/reactive'\n\nconst obs = observable({\n  aa: 1,\n  bb: 2,\n})\n\nconst dispose = reaction(() => {\n  return obs.aa + obs.bb\n}, console.log)\n\nbatch(() => {\n  //Won't trigger because the value of obs.aa + obs.bb has not changed\n  obs.aa = 2\n  obs.bb = 1\n})\n\nobs.aa = 4\n\ndispose()\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/reaction.zh-CN.md",
    "content": "# reaction\n\n## 描述\n\n接收一个 tracker 函数，与 callback 响应函数，如果 tracker 内部有消费 observable 数据，数据发生变化时，tracker 函数会重复执行，但是 callback 执行必须要求 tracker 函数返回值发生变化时才执行\n\n## 签名\n\n```ts\ninterface IReactionOptions<T> {\n  name?: string\n  equals?: (oldValue: T, newValue: T) => boolean //脏检查\n  fireImmediately?: boolean //是否第一次默认触发，绕过脏检查\n}\n\ninterface reaction<T> {\n  (\n    tracker: () => T,\n    subscriber?: (newValue: T, oldValue: T) => void,\n    options?: IReactionOptions<T>\n  ): void\n}\n```\n\n## 用例\n\n```ts\nimport { observable, reaction, batch } from '@formily/reactive'\n\nconst obs = observable({\n  aa: 1,\n  bb: 2,\n})\n\nconst dispose = reaction(() => {\n  return obs.aa + obs.bb\n}, console.log)\n\nbatch(() => {\n  //不会触发，因为obs.aa + obs.bb值没变\n  obs.aa = 2\n  obs.bb = 1\n})\n\nobs.aa = 4\n\ndispose()\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/toJS.md",
    "content": "# toJS\n\n## Description\n\nDeep recursion converts observable objects into ordinary JS objects\n\nNote: If you mark an object that is already observable with markRaw, then toJS will not convert it into a normal object\n\n## Signature\n\n```ts\ninterface toJS<T> {\n  (target: T): T\n}\n```\n\n## Example\n\n```ts\nimport { observable, autorun, toJS } from '@formily/reactive'\n\nconst obs = observable({\n  aa: {\n    bb: {\n      cc: 123,\n    },\n  },\n})\n\nconst js = toJS(obs)\n\nautorun(() => {\n  console.log(js.aa.bb.cc) // will not trigger when changes\n})\n\njs.aa.bb.cc = 321\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/toJS.zh-CN.md",
    "content": "# toJS\n\n## 描述\n\n深度递归将 observable 对象转换成普通 JS 对象\n\n注意：如果对一个已经是 observable 的对象标记 markRaw，那么 toJS，是不会将它转换成普通对象的\n\n## 签名\n\n```ts\ninterface toJS<T> {\n  (target: T): T\n}\n```\n\n## 用例\n\n```ts\nimport { observable, autorun, toJS } from '@formily/reactive'\n\nconst obs = observable({\n  aa: {\n    bb: {\n      cc: 123,\n    },\n  },\n})\n\nconst js = toJS(obs)\n\nautorun(() => {\n  console.log(js.aa.bb.cc) //变化时不会触发\n})\n\njs.aa.bb.cc = 321\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/tracker.md",
    "content": "# tracker\n\n## Description\n\nMainly used to access the manual tracking dependency tool of React/Vue. The tracker function will not be executed repeatedly when the dependency changes. It requires the user to manually execute it repeatedly, which will only trigger the scheduler\n\n## Signature\n\n```ts\nclass Tracker {\n  constructor(scheduler?: (reaction: this['track']) => void, name?: string)\n  track: <T>(tracker?: () => T) => T\n  dispose: () => void\n}\n```\n\n## Example\n\n```ts\nimport { observable, Tracker } from '@formily/reactive'\n\nconst obs = observable({\n  aa: 11,\n})\n\nconst view = () => {\n  console.log(obs.aa)\n}\n\nconst tracker = new Tracker(() => {\n  tracker.track(view)\n})\n\ntracker.track(view)\n\nobs.aa = 22\n\ntracker.dispose()\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/tracker.zh-CN.md",
    "content": "# tracker\n\n## 描述\n\n主要用于接入 React/Vue 的手动追踪依赖工具，在依赖发生变化时不会重复执行 tracker 函数，需要用户手动重复执行，只会触发 scheduler\n\n## 签名\n\n```ts\nclass Tracker {\n  constructor(scheduler?: (reaction: this['track']) => void, name?: string)\n  track: <T>(tracker?: () => T) => T\n  dispose: () => void\n}\n```\n\n## 用例\n\n```ts\nimport { observable, Tracker } from '@formily/reactive'\n\nconst obs = observable({\n  aa: 11,\n})\n\nconst view = () => {\n  console.log(obs.aa)\n}\n\nconst tracker = new Tracker(() => {\n  tracker.track(view)\n})\n\ntracker.track(view)\n\nobs.aa = 22\n\ntracker.dispose()\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/typeChecker.md",
    "content": "# Type Checker\n\n## isObservable\n\n#### Description\n\nDetermine whether an object is observable\n\n#### Signature\n\n```ts\ninterface isObservable {\n  (target: any): boolean\n}\n```\n\n## isAnnotation\n\n#### Description\n\nDetermine whether an object is Annotation\n\n#### Signature\n\n```ts\ninterface isAnnotation {\n  (target: any): boolean\n}\n```\n\n## isSupportObservable\n\n#### Description\n\nDetermine whether an object can be observable\n\n#### Signature\n\n```ts\ninterface isSupportObservable {\n  (target: any): boolean\n}\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/typeChecker.zh-CN.md",
    "content": "# Type Checker\n\n## isObservable\n\n#### 描述\n\n判断某个对象是否是 observable 对象\n\n#### 签名\n\n```ts\ninterface isObservable {\n  (target: any): boolean\n}\n```\n\n## isAnnotation\n\n#### 描述\n\n判断某个对象是否是 Annotation\n\n#### 签名\n\n```ts\ninterface isAnnotation {\n  (target: any): boolean\n}\n```\n\n## isSupportObservable\n\n#### 描述\n\n判断某个对象是否可以被 observable\n\n#### 签名\n\n```ts\ninterface isSupportObservable {\n  (target: any): boolean\n}\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/untracked.md",
    "content": "# untracked\n\n## Description\n\nUsage is similar to batch, and will never be collected by dependencies within a given untracker function\n\n## Signature\n\n```ts\ninterface untracked<T extends () => any> {\n  (untracker?: T): ReturnType<T>\n}\n```\n\n## Example\n\n```ts\nimport { observable, autorun, untracked } from '@formily/reactive'\n\nconst obs = observable({\n  aa: 11,\n})\n\nautorun(() => {\n  console.log(untracked(() => obs.aa)) // will not trigger when changes\n})\n\nobs.aa = 22\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/untracked.zh-CN.md",
    "content": "# untracked\n\n## 描述\n\n用法与 batch 相似，在给定的 untracker 函数内部永远不会被依赖收集\n\n## 签名\n\n```ts\ninterface untracked<T extends () => any> {\n  (untracker?: T): ReturnType<T>\n}\n```\n\n## 用例\n\n```ts\nimport { observable, autorun, untracked } from '@formily/reactive'\n\nconst obs = observable({\n  aa: 11,\n})\n\nautorun(() => {\n  console.log(untracked(() => obs.aa)) //变化时不会触发\n})\n\nobs.aa = 22\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/vue/observer.md",
    "content": "# observer\n\n## describe\n\nIn Vue, the component rendering method is changed to Reaction, and dependencies are collected every time the view is re-rendered, and dependencies are updated automatically to re-render.\n\n### Signature\n\n```ts\ninterface IObserverOptions {\n  scheduler?: (updater: () => void) => void //The scheduler, you can manually control the timing of the update\n  name?: string //name of the packaged component\n}\n\ninterface observer<T extends VueComponent> {\n  (component: T, options?: IObserverOptions): T\n}\n```\n\n## Example\n\n```html\n<template>\n  <div>\n    <div>\n      <input\n        :style=\"{\n           height: 28,\n           padding: '0 8px',\n           border: '2px solid #888',\n           borderRadius: 3,\n         }\"\n        :value=\"obs.value\"\n        @input=\"(e) => {\n           obs.value = e.target.value\n         }\"\n      />\n    </div>\n    <div>{{obs.value}}</div>\n  </div>\n</template>\n\n<script>\n  import { observable } from '@formily/reactive'\n  import { observer } from '@formily/reactive-vue'\n\n  export default observer({\n    data() {\n      // can coexist with vue's response system\n      const obs = observable({\n        value: 'Hello world',\n      })\n      return {\n        obs,\n      }\n    },\n  })\n</script>\n```\n"
  },
  {
    "path": "packages/reactive/docs/api/vue/observer.zh-CN.md",
    "content": "# observer\n\n## 描述\n\n在 Vue 中，将组件渲染方法变成 Reaction，每次视图重新渲染就会收集依赖，依赖更新会自动重渲染。\n\n### 签名\n\n```ts\ninterface IObserverOptions {\n  scheduler?: (updater: () => void) => void //调度器，可以手动控制更新时机\n  name?: string //包装后的组件的name\n}\n\ninterface observer<T extends VueComponent> {\n  (component: T, options?: IObserverOptions): T\n}\n```\n\n## 用例\n\n```html\n<template>\n  <div>\n    <div>\n      <input\n        :style=\"{\n          height: 28,\n          padding: '0 8px',\n          border: '2px solid #888',\n          borderRadius: 3,\n        }\"\n        :value=\"obs.value\"\n        @input=\"(e) => {\n          obs.value = e.target.value\n        }\"\n      />\n    </div>\n    <div>{{obs.value}}</div>\n  </div>\n</template>\n\n<script>\n  import { observable } from '@formily/reactive'\n  import { observer } from '@formily/reactive-vue'\n\n  export default observer({\n    data() {\n      // 能与 vue 的响应系统共存\n      const obs = observable({\n        value: 'Hello world',\n      })\n      return {\n        obs,\n      }\n    },\n  })\n</script>\n```\n"
  },
  {
    "path": "packages/reactive/docs/guide/best-practice.md",
    "content": "# Best Practices\n\nWhen using @formily/reactive, we only need to pay attention to the following points:\n\n- Minimize the use of observable/observable.deep for deep packaging, instead of using observable.ref/observable.shallow as a last resort, the performance will be better\n- Multi-use computed properties in the domain model, which can intelligently cache the calculation results\n- Although batch operation is not necessary, use batch mode as much as possible to reduce the number of executions of Reaction\n- When using autorun/reaction, you must remember to call the dispose release function (that is, the second-order function returned by the calling function), otherwise there will be memory leaks\n"
  },
  {
    "path": "packages/reactive/docs/guide/best-practice.zh-CN.md",
    "content": "# 最佳实践\n\n在使用@formily/reactive 的时候，我们只需要注意以下几点即可：\n\n- 尽量少用 observable/observable.deep 进行深度包装，不是非不得已就多用 observable.ref/observable.shallow，这样性能会更好\n- 领域模型中多用 computed 计算属性，它可以智能缓存计算结果\n- 虽然批量操作不是必须的，但是尽量多用 batch 模式，这样可以减少 Reaction 执行次数\n- 使用 autorun/reaction 的时候，一定记得调用 dispose 释放函数(也就是调用函数所返回的二阶函数)，否则会内存泄漏\n"
  },
  {
    "path": "packages/reactive/docs/guide/concept.md",
    "content": "# Core idea\n\n## Observable\n\nObservable is the most important part of the reactive programming model. Its core concepts are:\n\nAn observable object, literally means a subscribable object, **we create a subscribable object, each time we manipulate the attribute data of the object, we will automatically notify the subscriber**, @formily/reactive creates an observable object mainly It is created by ES Proxy, which can perfectly hijack data operations\n\nWe mainly use the following APIs to create observable objects in @formily/reactive:\n\n- The observable function creates a deep observable object\n  - The observable.deep function creates a deep hijacking observable object\n  - The observable.shallow function creates shallow hijacked observable objects\n  - The observable.computed function creates a cache calculator\n  - The observable.box function creates observable objects with get/set methods\n  - The observable.ref function creates a reference-level observable object\n- The define function defines the observable domain model, which can be combined with the observable function and its static attribute (such as observable.computed) function to complete the definition of the domain model\n- The model function defines an automatic observable domain model. It will wrap the getter setter attribute as a computed attribute, wrap the function as an action, and wrap other data attributes with observable (note that this is a deep hijacking)\n\n## Reaction\n\nIn the reactive programming model, reaction is equivalent to the subscriber of the subscribeable object. It receives a tracker function. When this function is executed, if there is a **read operation* on an attribute in the observable object inside the function. * (Dependency collection), then the current reaction will be bound to the attribute (dependency tracking), until the attribute has a **write operation\\*\\* in other places, it will trigger the tracker function to repeat execution, using a picture Means:\n\n![](https://img.alicdn.com/imgextra/i4/O1CN01DQMGUL22mFICDsKfY_!!6000000007162-2-tps-1234-614.png)\n\nYou can see that from subscribing to dispatching subscriptions, it is actually a closed loop state machine. Each time the tracker function is executed, the dependencies are re-collected, and the tracker execution is re-triggered when the dependencies change. So, if we don't want to subscribe to the reaction anymore, we must manually dispose, otherwise there will be memory leaks.\n\nIn @formily/reactive, we mainly use the following APIs to create reactions:\n\n- autorun creates an automatically executed responder\n- reaction creates a responder that can implement dirty checks\n- Tracker creates a dependency tracker that requires users to manually perform tracking\n\n## Computed\n\nComputed is also a relatively important concept in the reactive programming model. In one sentence, **computed is a Reaction that can cache calculation results**\n\nIts caching strategy is: as long as the observable data that the computed function relies on changes, the function will re-execute the calculation, otherwise the cached result will always be read\n\nThe requirement here is that the computed function must be a pure function. The internally dependent data is either observable data or external constant data. If it is external variable data (non-observable), then if the external variable data changes, the computed will not be re-executed computational.\n\n## Batch\n\nAs mentioned earlier, @formily/reactive is a reactive programming model based on Proxy hijacking. Therefore, any atomic operation will trigger the execution of Reaction, which is obviously a waste of computing resources. For example, we have a function for multiple observables. Property to operate:\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\nconst obs = observable({})\nconst handler = () => {\n  obs.aa = 123\n  obs.bb = 321\n}\n\nautorun(() => {\n  console.log(obs.aa, obs.bb)\n})\n\nhandler()\n```\n\nThis will execute 3 prints, autorun is executed once by default, plus the assignment of obs.aa is executed once, and the assignment of obs.bb is executed once. If there are more atomic operations, the number of executions will be more. Therefore, we recommend using batch mode To merge the updates:\n\n```ts\nimport { observable, autorun, batch } from '@formily/reactive'\nconst obs = observable({})\nconst handler = () => {\n  obs.aa = 123\n  obs.bb = 321\n}\n\nautorun(() => {\n  console.log(obs.aa, obs.bb)\n})\n\nbatch(() => {\n  handler()\n})\n```\n\nOf course, we can also use action for high-level packaging:\n\n```ts\nimport { observable, autorun, action } from '@formily/reactive'\nconst obs = observable({})\nconst handler = action.bound(() => {\n  obs.aa = 123\n  obs.bb = 321\n})\n\nautorun(() => {\n  console.log(obs.aa, obs.bb)\n})\n\nhandler()\n```\n\nThe final number of executions is 2 times, even if there are more operations inside the handler, it is still 2 times\n"
  },
  {
    "path": "packages/reactive/docs/guide/concept.zh-CN.md",
    "content": "# 核心概念\n\n## Observable\n\nobservable 是响应式编程模型中最重要的一块，它的核心概念就是：\n\n一个 observable 对象，字面意思是可订阅对象，**我们通过创建一个可订阅对象，在每次操作该对象的属性数据的过程中，会自动通知订阅者**，@formily/reactive 创建 observable 对象主要是通过 ES Proxy 来创建的，它可以做到完美劫持数据操作\n\n我们在@formily/reactive 中主要用以下几个 API 来创建 observable 对象：\n\n- observable 函数创建深度 observable 对象\n  - observable.deep 函数创建深劫持 observable 对象\n  - observable.shallow 函数创建浅劫持 observable 对象\n  - observable.computed 函数创建缓存计算器\n  - observable.box 函数创建带 get/set 方法的 observable 对象\n  - observable.ref 函数创建引用级 observable 对象\n- define 函数定义 observable 领域模型，可以组合 observable 函数与其静态属性(比如 observable.computed)函数完成领域模型的定义\n- model 函数定义自动 observable 领域模型，它会将 getter setter 属性包装为 computed 计算属性，将函数包装为 action，将其他数据属性用 observable 包装(注意这里是深劫持)\n\n## Reaction\n\nreaction 在响应式编程模型中，它就相当于是可订阅对象的订阅者，它接收一个 tracker 函数，这个函数在执行的时候，如果函数内部有对 observable 对象中的某个属性进行**读操作**(依赖收集)，那当前 reaction 就会与该属性进行一个绑定(依赖追踪)，直到该属性在其他地方发生了**写操作**，就会触发 tracker 函数重复执行，用一张图表示：\n\n![](https://img.alicdn.com/imgextra/i4/O1CN01DQMGUL22mFICDsKfY_!!6000000007162-2-tps-1234-614.png)\n\n可以看到从订阅到派发订阅，其实是一个封闭的循环状态机，每次 tracker 函数执行的时候都会重新收集依赖，依赖变化时又会重新触发 tracker 执行。所以，如果一旦我们不想再订阅 reaction 了，一定要手动 dispose，否则会内存泄漏。\n\n在@formily/reactive 中的我们主要是使用以下几个 API 来创建 reaction:\n\n- autorun 创建一个自动执行的响应器\n- reaction 创建一个可以实现脏检查的响应器\n- Tracker 创建一个依赖追踪器，需要用户手动执行追踪\n\n## Computed\n\ncomputed 在响应式编程模型中也是属于一个比较重要的概念，一句话表达的话，**computed 是一个可以缓存计算结果的 Reaction**\n\n它的缓存策略是：只要 computed 函数内部所依赖的 observable 数据发生变化，函数才会重新执行计算，否则永远读取缓存结果\n\n这里要求的就是 computed 函数必须是纯函数，内部依赖的数据要么是 observable 数据，要么是外部常量数据，如果是外部变量数据(非 observable)，那如果外部变量数据发生变化，computed 是不会重新执行计算的。\n\n## Batch\n\n前面有讲到@formily/reactive 是基于 Proxy 劫持来实现的响应式编程模型，所以任何一个原子操作都会触发 Reaction 执行，这样明显是浪费了计算资源的，比如我们有一个函数内部是对多个 observable 属性进行操作的：\n\n```ts\nimport { observable, autorun } from '@formily/reactive'\nconst obs = observable({})\nconst handler = () => {\n  obs.aa = 123\n  obs.bb = 321\n}\n\nautorun(() => {\n  console.log(obs.aa, obs.bb)\n})\n\nhandler()\n```\n\n这样就会执行 3 次打印，autorun 默认执行一次，加上 obs.aa 赋值执行一次，obs.bb 赋值执行一次，如果原子操作更多一些，那执行次数会更多，所以，我们推荐使用 batch 模式，将更新进行合并：\n\n```ts\nimport { observable, autorun, batch } from '@formily/reactive'\nconst obs = observable({})\nconst handler = () => {\n  obs.aa = 123\n  obs.bb = 321\n}\n\nautorun(() => {\n  console.log(obs.aa, obs.bb)\n})\n\nbatch(() => {\n  handler()\n})\n```\n\n当然，我们也可以使用 action 进行高阶包装：\n\n```ts\nimport { observable, autorun, action } from '@formily/reactive'\nconst obs = observable({})\nconst handler = action.bound(() => {\n  obs.aa = 123\n  obs.bb = 321\n})\n\nautorun(() => {\n  console.log(obs.aa, obs.bb)\n})\n\nhandler()\n```\n\n最终执行次数就是 2 次了，即便 handler 内部的操作再多也还是 2 次\n"
  },
  {
    "path": "packages/reactive/docs/guide/index.md",
    "content": "# Introduction\n\nThe core idea of @formily/reactive is to refer to [Mobx](https://mobx.js.org/), so why reinvent the wheel?\n\nThere are four main reasons:\n\n- mobx does not support dependency collection within actions\n- The observable function of mobx does not support filtering special objects such as react node, moment, and immutable\n- mobx's observable function will automatically turn the function into action\n- The observer of mobx-react-lite does not support React concurrent rendering\n\nFor the above reasons, Formily had to reinvent the wheel, but the wheel strongly relies on Proxy, that is, it does not support IE browser. Of course, reinventing the wheel also has its advantages:\n\n- More controllability, you can do more in-depth optimization and customization for formily scenes\n- Regardless of the historical burden of Mobx, the code can be cleaner\n- If the Mobx version is Break Change or there are security vulnerabilities, it will have no impact on Formily\n"
  },
  {
    "path": "packages/reactive/docs/guide/index.zh-CN.md",
    "content": "# 介绍\n\n@formily/reactive 的核心思想是参考 [Mobx](https://mobx.js.org/) 的，那为什么要重新造轮子呢？\n\n主要有 4 点原因：\n\n- mobx 不支持 action 内部进行依赖收集\n- mobx 的 observable 函数不支持过滤 react node,moment,immutable 之类的特殊对象\n- mobx 的 observable 函数会自动将函数变成 action\n- mobx-react-lite 的 observer 不支持 React 并发渲染\n\n基于以上原因，formily 不得不重新造轮子，不过该轮子是强依赖 Proxy 的，也就是不支持 IE 浏览器，当然，重新造轮子也有它的好处：\n\n- 把控性更强，可以为 formily 场景做更深的优化定制\n- 不用考虑 Mobx 的历史包袱，代码可以更干净\n- 如果 Mobx 版本 Break Change 或者存在安全漏洞，对 Formily 无影响\n"
  },
  {
    "path": "packages/reactive/docs/index.md",
    "content": "---\ntitle: Formily-Alibaba unified front-end form solution\norder: 10\nhero:\n  title: Reactive Library\n  desc: DDD-oriented Responsive State Management Solution\n  actions:\n    - text: Home Site\n      link: //formilyjs.org\n    - text: Document\n      link: /guide\nfeatures:\n  - icon: https://img.alicdn.com/imgextra/i1/O1CN01bHdrZJ1rEOESvXEi5_!!6000000005599-55-tps-800-800.svg\n    title: High Performance\n    desc: Efficient update, Demand rendering\n  - icon: https://img.alicdn.com/imgextra/i2/O1CN01YqmcpN1tDalwgyHBH_!!6000000005868-55-tps-800-800.svg\n    title: Zero Dependencies\n    desc: Cross Device,Cross Framework\n  - icon: https://img.alicdn.com/imgextra/i4/O1CN01u6jHgs1ZMwXpjAYnh_!!6000000003181-55-tps-800-800.svg\n    title: Smart Tips\n    desc: Embrace Typescript\nfooter: Open-source MIT Licensed | Copyright © 2019-present<br />Powered by self\n---\n\n## Installation\n\n```bash\n$ npm install --save @formily/reactive\n\n```\n\n## Quick start\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React from 'react'\nimport { observable } from '@formily/reactive'\nimport { observer } from '@formily/reactive-react'\n\nconst obs = observable({\n  value: 'Hello world',\n})\n\nexport default observer(() => {\n  return (\n    <div>\n      <div>\n        <input\n          style={{\n            height: 28,\n            padding: '0 8px',\n            border: '2px solid #888',\n            borderRadius: 3,\n          }}\n          value={obs.value}\n          onChange={(e) => {\n            obs.value = e.target.value\n          }}\n        />\n      </div>\n      <div>{obs.value}</div>\n    </div>\n  )\n})\n```\n"
  },
  {
    "path": "packages/reactive/docs/index.zh-CN.md",
    "content": "---\ntitle: Formily - 阿里巴巴统一前端表单解决方案\norder: 10\nhero:\n  title: Reactive Library\n  desc: 面向DDD的响应式状态管理方案\n  actions:\n    - text: 主站文档\n      link: //formilyjs.org\n    - text: 开发指南\n      link: /zh-CN/guide\nfeatures:\n  - icon: https://img.alicdn.com/imgextra/i1/O1CN01bHdrZJ1rEOESvXEi5_!!6000000005599-55-tps-800-800.svg\n    title: 超高性能\n    desc: 依赖追踪，高效更新，按需渲染\n  - icon: https://img.alicdn.com/imgextra/i2/O1CN01YqmcpN1tDalwgyHBH_!!6000000005868-55-tps-800-800.svg\n    title: 跨终端，跨框架\n    desc: UI无关，框架无关\n  - icon: https://img.alicdn.com/imgextra/i4/O1CN01u6jHgs1ZMwXpjAYnh_!!6000000003181-55-tps-800-800.svg\n    title: 智能提示\n    desc: 拥抱Typescript\nfooter: Open-source MIT Licensed | Copyright © 2019-present<br />Powered by self\n---\n\n## 安装\n\n```bash\n$ npm install --save @formily/reactive\n\n```\n\n## 快速开始\n\n```tsx\n/**\n * defaultShowCode: true\n */\nimport React from 'react'\nimport { observable } from '@formily/reactive'\nimport { observer } from '@formily/reactive-react'\n\nconst obs = observable({\n  value: 'Hello world',\n})\n\nexport default observer(() => {\n  return (\n    <div>\n      <div>\n        <input\n          style={{\n            height: 28,\n            padding: '0 8px',\n            border: '2px solid #888',\n            borderRadius: 3,\n          }}\n          value={obs.value}\n          onChange={(e) => {\n            obs.value = e.target.value\n          }}\n        />\n      </div>\n      <div>{obs.value}</div>\n    </div>\n  )\n})\n```\n"
  },
  {
    "path": "packages/reactive/package.json",
    "content": "{\n  \"name\": \"@formily/reactive\",\n  \"version\": \"2.3.7\",\n  \"license\": \"MIT\",\n  \"main\": \"lib\",\n  \"module\": \"esm\",\n  \"umd:main\": \"dist/formily.reactive.umd.production.js\",\n  \"unpkg\": \"dist/formily.reactive.umd.production.js\",\n  \"jsdelivr\": \"dist/formily.reactive.umd.production.js\",\n  \"jsnext:main\": \"esm\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/alibaba/formily.git\"\n  },\n  \"types\": \"esm/index.d.ts\",\n  \"bugs\": {\n    \"url\": \"https://github.com/alibaba/formily/issues\"\n  },\n  \"homepage\": \"https://github.com/alibaba/formily#readme\",\n  \"engines\": {\n    \"npm\": \">=3.0.0\"\n  },\n  \"scripts\": {\n    \"start\": \"dumi dev\",\n    \"build\": \"rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm && npm run build:umd\",\n    \"build:cjs\": \"tsc --project tsconfig.build.json\",\n    \"build:esm\": \"tsc --project tsconfig.build.json --module es2015 --outDir esm\",\n    \"build:umd\": \"rollup --config\",\n    \"build:docs\": \"dumi build\",\n    \"benchmark\": \"ts-node ./benchmark\"\n  },\n  \"devDependencies\": {\n    \"@vue/reactivity\": \"^3.0.11\",\n    \"benny\": \"^3.6.15\",\n    \"dumi\": \"^1.1.0-rc.8\",\n    \"lodash\": \"^4.17.21\",\n    \"mobx\": \"^6.3.0\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"gitHead\": \"ac79c196ae9324889aca5e0501146f9b37b04283\"\n}\n"
  },
  {
    "path": "packages/reactive/rollup.config.js",
    "content": "import baseConfig from '../../scripts/rollup.base.js'\n\nexport default baseConfig('formily.reactive', 'Formily.Reactive')\n"
  },
  {
    "path": "packages/reactive/src/__tests__/action.spec.ts",
    "content": "import { observable, action, autorun } from '..'\nimport { reaction } from '../autorun'\nimport { batch } from '../batch'\nimport { define } from '../model'\n\ndescribe('normal action', () => {\n  test('no action', () => {\n    const obs = observable({\n      aa: {\n        bb: 123,\n      },\n    })\n    const handler = jest.fn()\n    autorun(() => {\n      handler(obs.aa.bb)\n    })\n    obs.aa.bb = 111\n    obs.aa.bb = 222\n    expect(handler).toBeCalledTimes(3)\n\n    obs.aa.bb = 333\n    obs.aa.bb = 444\n\n    expect(handler).toBeCalledTimes(5)\n  })\n\n  test('action', () => {\n    const obs = observable({\n      aa: {\n        bb: 123,\n      },\n    })\n    const handler = jest.fn()\n    autorun(() => {\n      handler(obs.aa.bb)\n    })\n    obs.aa.bb = 111\n    obs.aa.bb = 222\n    expect(handler).toBeCalledTimes(3)\n    action(() => {\n      obs.aa.bb = 333\n      obs.aa.bb = 444\n    })\n    action(() => {})\n    action()\n    expect(handler).toBeCalledTimes(4)\n  })\n\n  test('action track', () => {\n    const obs = observable({\n      aa: {\n        bb: 123,\n      },\n      cc: 1,\n    })\n    const handler = jest.fn()\n    autorun(() => {\n      action(() => {\n        if (obs.cc > 0) {\n          handler(obs.aa.bb)\n          obs.cc = obs.cc + 20\n        }\n      })\n    })\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n    obs.aa.bb = 321\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n  })\n\n  test('action.bound', () => {\n    const obs = observable({\n      aa: {\n        bb: 123,\n      },\n    })\n    const handler = jest.fn()\n    const setData = action.bound(() => {\n      obs.aa.bb = 333\n      obs.aa.bb = 444\n    })\n    autorun(() => {\n      handler(obs.aa.bb)\n    })\n    obs.aa.bb = 111\n    obs.aa.bb = 222\n    expect(handler).toBeCalledTimes(3)\n    setData()\n    action.bound(() => {})\n    expect(handler).toBeCalledTimes(4)\n  })\n\n  test('action.bound track', () => {\n    const obs = observable({\n      aa: {\n        bb: 123,\n      },\n      cc: 1,\n    })\n    const handler = jest.fn()\n    autorun(() => {\n      action.bound(() => {\n        if (obs.cc > 0) {\n          handler(obs.aa.bb)\n          obs.cc = obs.cc + 20\n        }\n      })()\n    })\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n    obs.aa.bb = 321\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n  })\n\n  test('action.scope xxx', () => {\n    const obs = observable<any>({})\n\n    const handler = jest.fn()\n\n    autorun(() => {\n      handler(obs.aa, obs.bb, obs.cc, obs.dd)\n    })\n\n    action(() => {\n      action.scope(() => {\n        obs.aa = 123\n      })\n      action.scope(() => {\n        obs.cc = 'ccccc'\n      })\n      obs.bb = 321\n      obs.dd = 'ddddd'\n    })\n\n    expect(handler).toBeCalledTimes(4)\n  })\n\n  test('action.scope bound', () => {\n    const obs = observable<any>({})\n\n    const handler = jest.fn()\n\n    autorun(() => {\n      handler(obs.aa, obs.bb, obs.cc, obs.dd)\n    })\n\n    const scope1 = action.scope.bound(() => {\n      obs.aa = 123\n    })\n    action(() => {\n      scope1()\n      action.scope.bound(() => {\n        obs.cc = 'ccccc'\n      })()\n      obs.bb = 321\n      obs.dd = 'ddddd'\n    })\n\n    expect(handler).toBeCalledTimes(4)\n  })\n\n  test('action.scope track', () => {\n    const obs = observable({\n      aa: {\n        bb: 123,\n      },\n      cc: 1,\n    })\n    const handler = jest.fn()\n    autorun(() => {\n      action.scope(() => {\n        if (obs.cc > 0) {\n          handler(obs.aa.bb)\n          obs.cc = obs.cc + 20\n        }\n      })\n    })\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n    obs.aa.bb = 321\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n  })\n\n  test('action.scope bound track', () => {\n    const obs = observable({\n      aa: {\n        bb: 123,\n      },\n      cc: 1,\n    })\n    const handler = jest.fn()\n    autorun(() => {\n      action.scope.bound(() => {\n        if (obs.cc > 0) {\n          handler(obs.aa.bb)\n          obs.cc = obs.cc + 20\n        }\n      })()\n    })\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n    obs.aa.bb = 321\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n  })\n})\n\ndescribe('annotation action', () => {\n  test('action', () => {\n    const obs = define(\n      {\n        aa: {\n          bb: 123,\n        },\n        setData() {\n          this.aa.bb = 333\n          this.aa.bb = 444\n        },\n      },\n      {\n        aa: observable,\n        setData: action,\n      }\n    )\n    const handler = jest.fn()\n    autorun(() => {\n      handler(obs.aa.bb)\n    })\n    obs.aa.bb = 111\n    obs.aa.bb = 222\n    expect(handler).toBeCalledTimes(3)\n    obs.setData()\n    expect(handler).toBeCalledTimes(4)\n  })\n\n  test('action track', () => {\n    const obs = define(\n      {\n        aa: {\n          bb: 123,\n        },\n        cc: 1,\n        setData() {\n          if (obs.cc > 0) {\n            handler(obs.aa.bb)\n            obs.cc = obs.cc + 20\n          }\n        },\n      },\n      {\n        aa: observable,\n        setData: action,\n      }\n    )\n    const handler = jest.fn()\n    autorun(() => {\n      obs.setData()\n    })\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n    obs.aa.bb = 321\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n  })\n\n  test('action.bound', () => {\n    const obs = define(\n      {\n        aa: {\n          bb: 123,\n        },\n        setData() {\n          this.aa.bb = 333\n          this.aa.bb = 444\n        },\n      },\n      {\n        aa: observable,\n        setData: action.bound,\n      }\n    )\n    const handler = jest.fn()\n    autorun(() => {\n      handler(obs.aa.bb)\n    })\n    obs.aa.bb = 111\n    obs.aa.bb = 222\n    expect(handler).toBeCalledTimes(3)\n    obs.setData()\n    expect(handler).toBeCalledTimes(4)\n  })\n\n  test('action.bound track', () => {\n    const obs = define(\n      {\n        aa: {\n          bb: 123,\n        },\n        cc: 1,\n        setData() {\n          if (obs.cc > 0) {\n            handler(obs.aa.bb)\n            obs.cc = obs.cc + 20\n          }\n        },\n      },\n      {\n        aa: observable,\n        setData: action.bound,\n      }\n    )\n    const handler = jest.fn()\n    autorun(() => {\n      obs.setData()\n    })\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n    obs.aa.bb = 321\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n  })\n\n  test('action.scope', () => {\n    const obs = define(\n      {\n        aa: null,\n        bb: null,\n        cc: null,\n        dd: null,\n        scope1() {\n          this.aa = 123\n        },\n        scope2() {\n          this.cc = 'ccccc'\n        },\n      },\n      {\n        aa: observable,\n        bb: observable,\n        cc: observable,\n        dd: observable,\n        scope1: action.scope,\n        scope2: action.scope,\n      }\n    )\n\n    const handler = jest.fn()\n\n    autorun(() => {\n      handler(obs.aa, obs.bb, obs.cc, obs.dd)\n    })\n\n    action(() => {\n      obs.scope1()\n      obs.scope2()\n      obs.bb = 321\n      obs.dd = 'ddddd'\n    })\n\n    expect(handler).toBeCalledTimes(4)\n  })\n\n  test('action.scope bound', () => {\n    const obs = define(\n      {\n        aa: null,\n        bb: null,\n        cc: null,\n        dd: null,\n        scope1() {\n          this.aa = 123\n        },\n        scope2() {\n          this.cc = 'ccccc'\n        },\n      },\n      {\n        aa: observable,\n        bb: observable,\n        cc: observable,\n        dd: observable,\n        scope1: action.scope.bound,\n        scope2: action.scope.bound,\n      }\n    )\n\n    const handler = jest.fn()\n\n    autorun(() => {\n      handler(obs.aa, obs.bb, obs.cc, obs.dd)\n    })\n\n    action(() => {\n      obs.scope1()\n      obs.scope2()\n      obs.bb = 321\n      obs.dd = 'ddddd'\n    })\n\n    expect(handler).toBeCalledTimes(4)\n  })\n\n  test('action.scope track', () => {\n    const obs = define(\n      {\n        aa: {\n          bb: 123,\n        },\n        cc: 1,\n        scope() {\n          if (this.cc > 0) {\n            handler(this.aa.bb)\n            this.cc = this.cc + 20\n          }\n        },\n      },\n      {\n        aa: observable,\n        cc: observable,\n        scope: action.scope,\n      }\n    )\n    const handler = jest.fn()\n    autorun(() => {\n      obs.scope()\n    })\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n    obs.aa.bb = 321\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n  })\n\n  test('action.scope bound track', () => {\n    const obs = define(\n      {\n        aa: {\n          bb: 123,\n        },\n        cc: 1,\n        scope() {\n          if (this.cc > 0) {\n            handler(this.aa.bb)\n            this.cc = this.cc + 20\n          }\n        },\n      },\n      {\n        aa: observable,\n        cc: observable,\n        scope: action.scope.bound,\n      }\n    )\n    const handler = jest.fn()\n    autorun(() => {\n      obs.scope()\n    })\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n    obs.aa.bb = 321\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n  })\n})\n\ntest('nested action to reaction', () => {\n  const obs = observable({\n    aa: 0,\n  })\n  const handler = jest.fn()\n  reaction(\n    () => obs.aa,\n    (v) => handler(v)\n  )\n  action(() => {\n    obs.aa = 1\n    action(() => {\n      obs.aa = 2\n    })\n  })\n  action(() => {\n    obs.aa = 3\n    action(() => {\n      obs.aa = 4\n    })\n  })\n  expect(handler).nthCalledWith(1, 2)\n  expect(handler).nthCalledWith(2, 4)\n  expect(handler).toBeCalledTimes(2)\n})\n\ntest('nested action/batch to reaction', () => {\n  const obs = define(\n    {\n      bb: 0,\n      get aa() {\n        return this.bb\n      },\n      set aa(v) {\n        this.bb = v\n      },\n    },\n    {\n      aa: observable.computed,\n      bb: observable,\n    }\n  )\n  const handler = jest.fn()\n  reaction(\n    () => obs.aa,\n    (v) => handler(v)\n  )\n  action(() => {\n    obs.aa = 1\n    batch(() => {\n      obs.aa = 2\n    })\n  })\n  action(() => {\n    obs.aa = 3\n    batch(() => {\n      obs.aa = 4\n    })\n  })\n  expect(handler).nthCalledWith(1, 2)\n  expect(handler).nthCalledWith(2, 4)\n  expect(handler).toBeCalledTimes(2)\n})\n"
  },
  {
    "path": "packages/reactive/src/__tests__/annotations.spec.ts",
    "content": "import { observable, action, model, define } from '../'\nimport { autorun, reaction } from '../autorun'\nimport { observe } from '../observe'\nimport { isObservable } from '../externals'\nimport { untracked } from '../untracked'\nimport { getObservableMaker } from '../internals'\n\ntest('observable annotation', () => {\n  const obs = observable<any>({\n    aa: 111,\n  })\n  const handler = jest.fn()\n  const handler1 = jest.fn()\n  observe(obs, handler1)\n  reaction(() => {\n    handler(obs.aa)\n  })\n  obs.aa = { bb: { cc: 123 } }\n  obs.aa.bb = 333\n  expect(handler).toBeCalledTimes(2)\n  expect(handler1).toBeCalledTimes(2)\n\n  const handler2 = jest.fn()\n  const handler3 = jest.fn()\n  const obsAnno = getObservableMaker(observable)({ value: obs })\n\n  observe(obsAnno, handler2)\n  reaction(() => {\n    handler3(obsAnno.aa)\n  })\n  obsAnno.aa = { bb: { cc: 123 } }\n  obsAnno.aa.bb = 333\n  expect(handler2).toBeCalledTimes(2)\n  expect(handler3).toBeCalledTimes(2)\n})\n\ntest('shallow annotation', () => {\n  const obs = observable.shallow<any>({\n    aa: 111,\n  })\n  const handler = jest.fn()\n  const handler1 = jest.fn()\n  observe(obs, handler1)\n  reaction(() => {\n    handler(obs.aa)\n  })\n  obs.aa = { bb: { cc: 123 } }\n  expect(isObservable(obs)).toBe(true)\n  expect(isObservable(obs.aa)).toBe(false)\n  expect(isObservable(obs.aa.bb)).toBe(false)\n  obs.aa.bb = 333\n  obs.cc = 444\n  expect(handler).toBeCalledTimes(2)\n  expect(handler1).toBeCalledTimes(2)\n})\n\ntest('box annotation', () => {\n  const obs = observable.box(123)\n  const handler = jest.fn()\n  const handler1 = jest.fn()\n  observe(obs, handler1)\n  reaction(() => {\n    handler(obs.get())\n  })\n  const boxValue = 333\n  obs.set(boxValue)\n  expect(handler1).toBeCalledTimes(1)\n  expect(handler1.mock.calls[0][0]).toMatchObject({\n    value: boxValue,\n  })\n  expect(handler).toBeCalledTimes(2)\n  expect(handler.mock.calls[0][0]).toBe(123)\n  expect(handler.mock.calls[1][0]).toBe(boxValue)\n})\n\ntest('ref annotation', () => {\n  const obs = observable.ref(123)\n  const handler = jest.fn()\n  const handler1 = jest.fn()\n  observe(obs, handler1)\n  reaction(() => {\n    handler(obs.value)\n  })\n  obs.value = 333\n  expect(handler).nthCalledWith(1, 123)\n  expect(handler).nthCalledWith(2, 333)\n  expect(handler1).toBeCalledTimes(1)\n})\n\ntest('action annotation', () => {\n  const obs = observable<any>({})\n  const setData = action.bound(() => {\n    obs.aa = 123\n    obs.bb = 321\n  })\n  const handler = jest.fn()\n  reaction(() => {\n    return [obs.aa, obs.bb]\n  }, handler)\n  setData()\n  expect(handler).toBeCalledTimes(1)\n  expect(handler).toBeCalledWith([123, 321], [undefined, undefined])\n})\n\ntest('no action annotation', () => {\n  const obs = observable<any>({})\n  const setData = () => {\n    obs.aa = 123\n    obs.bb = 321\n  }\n  const handler = jest.fn()\n  reaction(() => {\n    return [obs.aa, obs.bb]\n  }, handler)\n  setData()\n  expect(handler).toBeCalledTimes(2)\n  expect(handler).nthCalledWith(1, [123, undefined], [undefined, undefined])\n  expect(handler).nthCalledWith(2, [123, 321], [123, undefined])\n})\n\ntest('computed annotation', () => {\n  const obs = observable({\n    aa: 11,\n    bb: 22,\n  })\n  const handler = jest.fn(() => obs.aa + obs.bb)\n  const runner1 = jest.fn()\n  const runner2 = jest.fn()\n  const runner3 = jest.fn()\n  const compu = observable.computed(handler)\n  expect(compu.value).toEqual(33)\n  expect(handler).toBeCalledTimes(1)\n  obs.aa = 22\n  expect(handler).toBeCalledTimes(1)\n  const dispose = autorun(() => {\n    compu.value\n    runner1()\n  })\n  const dispose2 = autorun(() => {\n    compu.value\n    runner2()\n  })\n  expect(compu.value).toEqual(44)\n  expect(handler).toBeCalledTimes(2)\n  obs.bb = 33\n  expect(runner1).toBeCalledTimes(2)\n  expect(runner2).toBeCalledTimes(2)\n  expect(handler).toBeCalledTimes(3)\n  expect(compu.value).toEqual(55)\n  expect(handler).toBeCalledTimes(3)\n  obs.aa = 11\n  expect(runner1).toBeCalledTimes(3)\n  expect(runner2).toBeCalledTimes(3)\n  expect(handler).toBeCalledTimes(4)\n  expect(compu.value).toEqual(44)\n  expect(handler).toBeCalledTimes(4)\n  dispose()\n  obs.aa = 22\n  expect(runner1).toBeCalledTimes(3)\n  expect(runner2).toBeCalledTimes(4)\n  expect(handler).toBeCalledTimes(5)\n  expect(compu.value).toEqual(55)\n  expect(handler).toBeCalledTimes(5)\n  dispose2()\n  obs.aa = 33\n  expect(runner1).toBeCalledTimes(3)\n  expect(runner2).toBeCalledTimes(4)\n  expect(handler).toBeCalledTimes(5)\n  expect(compu.value).toEqual(66)\n  expect(handler).toBeCalledTimes(6)\n  expect(compu.value).toEqual(66)\n  expect(handler).toBeCalledTimes(6)\n  autorun(() => {\n    compu.value\n    runner3()\n  })\n  expect(compu.value).toEqual(66)\n  expect(handler).toBeCalledTimes(6)\n  expect(compu.value).toEqual(66)\n  expect(handler).toBeCalledTimes(6)\n  obs.aa = 11\n  expect(handler).toBeCalledTimes(7)\n  expect(compu.value).toEqual(44)\n  expect(handler).toBeCalledTimes(7)\n})\n\ntest('computed chain annotation', () => {\n  const obs = observable({\n    aa: 11,\n    bb: 22,\n  })\n  const handler = jest.fn(() => obs.aa + obs.bb)\n  const compu1 = observable.computed(handler)\n  const handler1 = jest.fn(() => compu1.value + 33)\n  const compu2 = observable.computed(handler1)\n  const dispose = autorun(() => {\n    compu2.value\n  })\n  expect(handler).toBeCalledTimes(1)\n  expect(handler1).toBeCalledTimes(1)\n  expect(compu2.value).toEqual(66)\n  expect(handler).toBeCalledTimes(1)\n  expect(handler1).toBeCalledTimes(1)\n  obs.aa = 22\n  expect(handler).toBeCalledTimes(2)\n  expect(handler1).toBeCalledTimes(2)\n  expect(compu2.value).toEqual(77)\n  expect(handler).toBeCalledTimes(2)\n  expect(handler1).toBeCalledTimes(2)\n  dispose()\n  obs.aa = 11\n  expect(handler).toBeCalledTimes(2)\n  expect(handler1).toBeCalledTimes(2)\n  expect(compu2.value).toEqual(66)\n  expect(handler).toBeCalledTimes(3)\n  expect(handler1).toBeCalledTimes(3)\n})\n\ntest('computed with array length', () => {\n  const obs = model({\n    arr: [],\n    get isEmpty() {\n      return this.arr.length === 0\n    },\n    get isNotEmpty() {\n      return !this.isEmpty\n    },\n  })\n  const handler = jest.fn()\n  autorun(() => {\n    handler(obs.isEmpty)\n    handler(obs.isNotEmpty)\n  })\n  expect(handler).toBeCalledTimes(2)\n  obs.arr = ['1']\n  obs.arr = []\n  expect(handler).toBeCalledTimes(6)\n})\n\ntest('computed with computed array length', () => {\n  const obs = model({\n    arr: [],\n    get arr2() {\n      return this.arr.map((item: number) => item + 1)\n    },\n    get isEmpty() {\n      return this.arr2.length === 0\n    },\n    get isNotEmpty() {\n      return !this.isEmpty\n    },\n  })\n  const handler = jest.fn()\n  const handler2 = jest.fn()\n  autorun(() => {\n    handler(obs.isNotEmpty)\n    handler2(obs.arr2)\n  })\n  expect(handler).toBeCalledTimes(1)\n  expect(handler).lastCalledWith(false)\n  expect(handler2).toBeCalledTimes(1)\n  expect(handler2.mock.calls[0][0]).toEqual([])\n  obs.arr.push(1)\n  expect(handler).lastCalledWith(true)\n  expect(handler2.mock.calls[1][0]).toEqual([2])\n  obs.arr = []\n  expect(handler).lastCalledWith(false)\n  expect(handler2.mock.calls[2][0]).toEqual([])\n})\n\ntest('computed recollect dependencies', () => {\n  const computed = jest.fn()\n  const obs = model({\n    aa: 'aaa',\n    bb: 'bbb',\n    cc: 'ccc',\n    get compute() {\n      computed()\n      if (this.aa === 'aaa') {\n        return this.bb\n      }\n      return this.cc\n    },\n  })\n  const handler = jest.fn()\n  autorun(() => {\n    handler(obs.compute)\n  })\n  obs.aa = '111'\n  obs.bb = '222'\n  expect(computed).toBeCalledTimes(2)\n})\n\ntest('computed no params', () => {\n  observable.computed(null)\n})\n\ntest('computed object params', () => {\n  observable.computed({ get: () => {} })\n})\n\ntest('computed no track get', () => {\n  const obs = observable({ aa: 123 })\n  const compu = observable.computed({ get: () => obs.aa })\n  untracked(() => {\n    expect(compu.value).toBe(123)\n  })\n})\n\ntest('computed cache descriptor', () => {\n  class A {\n    _value = 0\n    constructor() {\n      define(this, {\n        _value: observable.ref,\n        value: observable.computed,\n      })\n    }\n\n    get value() {\n      return this._value\n    }\n  }\n  const obs1 = new A()\n  const obs2 = new A()\n  const handler1 = jest.fn()\n  const handler2 = jest.fn()\n  autorun(() => {\n    handler1(obs1.value)\n  })\n  autorun(() => {\n    handler2(obs2.value)\n  })\n  expect(handler1).toBeCalledTimes(1)\n  expect(handler2).toBeCalledTimes(1)\n  obs1._value = 123\n  obs2._value = 123\n  expect(handler1).toBeCalledTimes(2)\n  expect(handler2).toBeCalledTimes(2)\n})\n\ntest('computed normal object', () => {\n  const obs = define(\n    {\n      _value: 0,\n      get value() {\n        return this._value\n      },\n    },\n    {\n      _value: observable.ref,\n      value: observable.computed,\n    }\n  )\n  const handler = jest.fn()\n  autorun(() => {\n    handler(obs.value)\n  })\n  expect(handler).toBeCalledTimes(1)\n  obs._value = 123\n  expect(handler).toBeCalledTimes(2)\n})\n"
  },
  {
    "path": "packages/reactive/src/__tests__/array.spec.ts",
    "content": "import { toArray, ArraySet } from '../array'\n\ntest('toArray', () => {\n  expect(toArray([])).toEqual([])\n  expect(toArray(null)).toEqual([])\n  expect(toArray(undefined)).toEqual([])\n  expect(toArray(0)).toEqual([0])\n})\n\ntest('ArraySet', () => {\n  const set = new ArraySet()\n  set.add(11)\n  set.add(11)\n  set.add(22)\n  expect(set.value).toEqual([11, 22])\n\n  const handler = jest.fn()\n  set.forEach(handler)\n  expect(handler).toBeCalledTimes(2)\n  expect(handler).nthCalledWith(1, 11)\n  expect(handler).nthCalledWith(2, 22)\n  expect(set.value).toEqual([11, 22])\n\n  expect(set.has(11)).toBe(true)\n  set.delete(11)\n  expect(set.has(11)).toBe(false)\n  expect(set.value).toEqual([22])\n\n  set.clear()\n  expect(set.value).toEqual([])\n\n  const handler1 = jest.fn()\n  set.add(11)\n  set.add(22)\n  set.batchDelete(handler1)\n  expect(handler1).toBeCalledTimes(2)\n  expect(handler1).nthCalledWith(1, 11)\n  expect(handler1).nthCalledWith(2, 22)\n  expect(set.value).toEqual([])\n})\n"
  },
  {
    "path": "packages/reactive/src/__tests__/autorun.spec.ts",
    "content": "import { observable, reaction, autorun } from '../'\nimport { batch } from '../batch'\nimport { define } from '../model'\n\nconst sleep = (duration = 100) =>\n  new Promise((resolve) => setTimeout(resolve, duration))\n\ntest('autorun', () => {\n  const obs = observable({\n    aa: {\n      bb: 123,\n    },\n  })\n  const handler = jest.fn()\n  const dispose = autorun(() => {\n    handler(obs.aa.bb)\n  })\n  obs.aa.bb = 123\n  expect(handler).toBeCalledTimes(1)\n  obs.aa.bb = 111\n  expect(handler).toBeCalledTimes(2)\n  dispose()\n  obs.aa.bb = 222\n  expect(handler).toBeCalledTimes(2)\n})\n\ntest('reaction', () => {\n  const obs = observable({\n    aa: {\n      bb: 123,\n    },\n  })\n  const handler = jest.fn()\n  const dispose = reaction(() => {\n    return obs.aa.bb\n  }, handler)\n  obs.aa.bb = 123\n  expect(handler).toBeCalledTimes(0)\n  obs.aa.bb = 111\n  expect(handler).toBeCalledTimes(1)\n  dispose()\n  obs.aa.bb = 222\n  expect(handler).toBeCalledTimes(1)\n})\n\ntest('reaction fireImmediately', () => {\n  const obs = observable({\n    aa: {\n      bb: 123,\n    },\n  })\n  const handler = jest.fn()\n  const dispose = reaction(\n    () => {\n      return obs.aa.bb\n    },\n    handler,\n    {\n      fireImmediately: true,\n    }\n  )\n  expect(handler).toBeCalledTimes(1)\n  obs.aa.bb = 123\n  expect(handler).toBeCalledTimes(1)\n  obs.aa.bb = 111\n  expect(handler).toBeCalledTimes(2)\n  dispose()\n  obs.aa.bb = 222\n  expect(handler).toBeCalledTimes(2)\n})\n\ntest('reaction untrack handler', () => {\n  const obs = observable({\n    aa: {\n      bb: 123,\n      cc: 123,\n    },\n  })\n  const handler = jest.fn()\n  const dispose = reaction(\n    () => {\n      return obs.aa.bb\n    },\n    () => {\n      handler(obs.aa.cc)\n    }\n  )\n  obs.aa.bb = 222\n  obs.aa.cc = 222\n  expect(handler).toBeCalledTimes(1)\n  dispose()\n})\n\ntest('reaction dirty check', () => {\n  const obs: any = {\n    aa: 123,\n  }\n  define(obs, {\n    aa: observable.ref,\n  })\n  const handler = jest.fn()\n  reaction(() => {\n    return obs.aa\n  }, handler)\n  batch(() => {\n    obs.aa = 123\n    obs.aa = 123\n  })\n\n  expect(handler).toBeCalledTimes(0)\n})\n\ntest('reaction with shallow equals', () => {\n  const obs: any = {\n    aa: { bb: 123 },\n  }\n  define(obs, {\n    aa: observable.ref,\n  })\n  const handler = jest.fn()\n  reaction(() => {\n    return obs.aa\n  }, handler)\n  obs.aa = { bb: 123 }\n  expect(handler).toBeCalledTimes(1)\n  expect(handler.mock.calls[0][0]).toEqual({ bb: 123 })\n})\n\ntest('reaction with deep equals', () => {\n  const obs: any = {\n    aa: { bb: 123 },\n  }\n  define(obs, {\n    aa: observable.ref,\n  })\n  const handler = jest.fn()\n  reaction(\n    () => {\n      return obs.aa\n    },\n    handler,\n    {\n      equals: (a, b) => JSON.stringify(a) === JSON.stringify(b),\n    }\n  )\n  obs.aa = { bb: 123 }\n  expect(handler).toBeCalledTimes(0)\n})\n\ntest('autorun direct recursive react', () => {\n  const obs = observable<any>({ value: 1 })\n  autorun(() => {\n    obs.value++\n  })\n  expect(obs.value).toEqual(2)\n})\n\ntest('autorun direct recursive react with if', () => {\n  const obs1 = observable<any>({})\n  const obs2 = observable<any>({})\n  const fn = jest.fn()\n  autorun(() => {\n    if (!obs1.value) {\n      obs1.value = '111'\n      return\n    }\n    fn(obs1.value, obs2.value)\n  })\n  obs2.value = '222'\n  expect(fn).toBeCalledTimes(0)\n})\n\ntest('autorun indirect recursive react', () => {\n  const obs1 = observable<any>({})\n  const obs2 = observable<any>({})\n  const obs3 = observable<any>({})\n  autorun(() => {\n    obs1.value = obs2.value + 1\n  })\n  autorun(() => {\n    obs2.value = obs3.value + 1\n  })\n  autorun(() => {\n    if (obs1.value) {\n      obs3.value = obs1.value + 1\n    } else {\n      obs3.value = 0\n    }\n  })\n  expect(obs2.value).toEqual(1)\n  expect(obs1.value).toEqual(2)\n  obs3.value = 1\n  expect(obs2.value).toEqual(2)\n  expect(obs1.value).toEqual(3)\n})\n\ntest('autorun indirect alive recursive react', () => {\n  const aa = observable<any>({})\n  const bb = observable<any>({})\n  const cc = observable<any>({})\n\n  batch(() => {\n    autorun(() => {\n      if (aa.value) {\n        bb.value = aa.value + 1\n      }\n    })\n    autorun(() => {\n      if (aa.value && bb.value) {\n        cc.value = aa.value + bb.value\n      }\n    })\n    batch(() => {\n      aa.value = 1\n    })\n  })\n  expect(aa.value).toEqual(1)\n  expect(bb.value).toEqual(2)\n  expect(cc.value).toEqual(3)\n})\n\ntest('autorun direct recursive react with head track', () => {\n  const obs1 = observable<any>({})\n  const obs2 = observable<any>({})\n  const fn = jest.fn()\n  autorun(() => {\n    const obs2Value = obs2.value\n    if (!obs1.value) {\n      obs1.value = '111'\n      return\n    }\n    fn(obs1.value, obs2Value)\n  })\n  obs2.value = '222'\n  expect(fn).toBeCalledTimes(1)\n  expect(fn).lastCalledWith('111', '222')\n})\n\ntest('autorun.memo', () => {\n  const obs = observable<any>({\n    bb: 0,\n  })\n  const fn = jest.fn()\n  autorun(() => {\n    const value = autorun.memo(() => ({\n      aa: 0,\n    }))\n    fn(obs.bb, value.aa++)\n  })\n  obs.bb++\n  obs.bb++\n  obs.bb++\n  obs.bb++\n  expect(fn).toBeCalledTimes(5)\n  expect(fn).nthCalledWith(1, 0, 0)\n  expect(fn).nthCalledWith(2, 1, 1)\n  expect(fn).nthCalledWith(3, 2, 2)\n  expect(fn).nthCalledWith(4, 3, 3)\n  expect(fn).nthCalledWith(5, 4, 4)\n})\n\ntest('autorun.memo with observable', () => {\n  const obs1 = observable({\n    aa: 0,\n  })\n  const fn = jest.fn()\n  const dispose = autorun(() => {\n    const obs2 = autorun.memo(() =>\n      observable({\n        bb: 0,\n      })\n    )\n    fn(obs1.aa, obs2.bb++)\n  })\n  obs1.aa++\n  obs1.aa++\n  obs1.aa++\n  expect(fn).toBeCalledTimes(4)\n  expect(fn).nthCalledWith(1, 0, 0)\n  expect(fn).nthCalledWith(2, 1, 1)\n  expect(fn).nthCalledWith(3, 2, 2)\n  expect(fn).nthCalledWith(4, 3, 3)\n  dispose()\n  obs1.aa++\n  expect(fn).toBeCalledTimes(4)\n})\n\ntest('autorun.memo with observable and effect', async () => {\n  const obs1 = observable({\n    aa: 0,\n  })\n  const fn = jest.fn()\n  const dispose = autorun(() => {\n    const obs2 = autorun.memo(() =>\n      observable({\n        bb: 0,\n      })\n    )\n    fn(obs1.aa, obs2.bb++)\n    autorun.effect(() => {\n      obs2.bb++\n    }, [])\n  })\n  obs1.aa++\n  obs1.aa++\n  obs1.aa++\n  await sleep(0)\n  expect(fn).toBeCalledTimes(5)\n  expect(fn).nthCalledWith(1, 0, 0)\n  expect(fn).nthCalledWith(2, 1, 1)\n  expect(fn).nthCalledWith(3, 2, 2)\n  expect(fn).nthCalledWith(4, 3, 3)\n  expect(fn).nthCalledWith(5, 3, 5)\n  dispose()\n  obs1.aa++\n  expect(fn).toBeCalledTimes(5)\n})\n\ntest('autorun.memo with deps', () => {\n  const obs = observable<any>({\n    bb: 0,\n    cc: 0,\n  })\n  const fn = jest.fn()\n  autorun(() => {\n    const value = autorun.memo(\n      () => ({\n        aa: 0,\n      }),\n      [obs.cc]\n    )\n    fn(obs.bb, value.aa++)\n  })\n  obs.bb++\n  obs.bb++\n  obs.bb++\n  obs.bb++\n  expect(fn).toBeCalledTimes(5)\n  expect(fn).nthCalledWith(1, 0, 0)\n  expect(fn).nthCalledWith(2, 1, 1)\n  expect(fn).nthCalledWith(3, 2, 2)\n  expect(fn).nthCalledWith(4, 3, 3)\n  expect(fn).nthCalledWith(5, 4, 4)\n  obs.cc++\n  expect(fn).toBeCalledTimes(6)\n  expect(fn).nthCalledWith(6, 4, 0)\n})\n\ntest('autorun.memo with deps and dispose', () => {\n  const obs = observable<any>({\n    bb: 0,\n    cc: 0,\n  })\n  const fn = jest.fn()\n  const dispose = autorun(() => {\n    const value = autorun.memo(\n      () => ({\n        aa: 0,\n      }),\n      [obs.cc]\n    )\n    fn(obs.bb, value.aa++)\n  })\n  obs.bb++\n  obs.bb++\n  obs.bb++\n  obs.bb++\n  expect(fn).toBeCalledTimes(5)\n  expect(fn).lastCalledWith(4, 4)\n  obs.cc++\n  expect(fn).toBeCalledTimes(6)\n  expect(fn).lastCalledWith(4, 0)\n  dispose()\n  obs.bb++\n  obs.cc++\n  expect(fn).toBeCalledTimes(6)\n})\n\ntest('autorun.memo with invalid params', () => {\n  const obs = observable<any>({\n    bb: 0,\n  })\n  const fn = jest.fn()\n  autorun(() => {\n    const value = autorun.memo({ aa: 0 } as any)\n    fn(obs.bb, value)\n  })\n  obs.bb++\n  obs.bb++\n  obs.bb++\n  obs.bb++\n  expect(fn).toBeCalledTimes(5)\n  expect(fn).lastCalledWith(4, undefined)\n})\n\ntest('autorun.memo not in autorun', () => {\n  expect(() => autorun.memo(() => ({ aa: 0 }))).toThrow()\n})\n\ntest('autorun no memo', () => {\n  const obs = observable<any>({\n    bb: 0,\n  })\n  const fn = jest.fn()\n  autorun(() => {\n    const value = {\n      aa: 0,\n    }\n    fn(obs.bb, value.aa++)\n  })\n  obs.bb++\n  obs.bb++\n  obs.bb++\n  obs.bb++\n  expect(fn).toBeCalledTimes(5)\n  expect(fn).nthCalledWith(1, 0, 0)\n  expect(fn).nthCalledWith(2, 1, 0)\n  expect(fn).nthCalledWith(3, 2, 0)\n  expect(fn).nthCalledWith(4, 3, 0)\n  expect(fn).nthCalledWith(5, 4, 0)\n})\n\ntest('autorun.effect', async () => {\n  const obs = observable<any>({\n    bb: 0,\n  })\n  const fn = jest.fn()\n  const effect = jest.fn()\n  const disposer = jest.fn()\n  const dispose = autorun(() => {\n    autorun.effect(() => {\n      effect()\n      return disposer\n    }, [])\n    fn(obs.bb)\n  })\n  obs.bb++\n  obs.bb++\n  obs.bb++\n  obs.bb++\n\n  await sleep(0)\n  expect(fn).toBeCalledTimes(5)\n  expect(fn).lastCalledWith(4)\n  expect(effect).toBeCalledTimes(1)\n  expect(disposer).toBeCalledTimes(0)\n\n  dispose()\n  await sleep(0)\n  expect(effect).toBeCalledTimes(1)\n  expect(disposer).toBeCalledTimes(1)\n})\n\ntest('autorun.effect dispose when autorun dispose', async () => {\n  const obs = observable<any>({\n    bb: 0,\n  })\n  const fn = jest.fn()\n  const effect = jest.fn()\n  const disposer = jest.fn()\n  const dispose = autorun(() => {\n    autorun.effect(() => {\n      effect()\n      return disposer\n    }, [])\n    fn(obs.bb)\n  })\n  obs.bb++\n  obs.bb++\n  obs.bb++\n  obs.bb++\n\n  dispose()\n  await sleep(0)\n  expect(fn).toBeCalledTimes(5)\n  expect(fn).lastCalledWith(4)\n  expect(effect).toBeCalledTimes(0)\n  expect(disposer).toBeCalledTimes(0)\n})\n\ntest('autorun.effect with deps', async () => {\n  const obs = observable<any>({\n    bb: 0,\n    cc: 0,\n  })\n  const fn = jest.fn()\n  const effect = jest.fn()\n  const dispose = autorun(() => {\n    autorun.effect(() => {\n      effect()\n    }, [obs.cc])\n    fn(obs.bb)\n  })\n  obs.bb++\n  obs.bb++\n  obs.bb++\n  obs.bb++\n  expect(effect).toBeCalledTimes(0)\n  await sleep(0)\n  expect(fn).toBeCalledTimes(5)\n  expect(fn).lastCalledWith(4)\n  expect(effect).toBeCalledTimes(1)\n  obs.cc++\n  expect(effect).toBeCalledTimes(1)\n  await sleep(0)\n  expect(fn).toBeCalledTimes(6)\n  expect(fn).lastCalledWith(4)\n  expect(effect).toBeCalledTimes(2)\n  dispose()\n  await sleep(0)\n  expect(effect).toBeCalledTimes(2)\n})\n\ntest('autorun.effect with default deps', async () => {\n  const obs = observable<any>({\n    bb: 0,\n  })\n  const fn = jest.fn()\n  const effect = jest.fn()\n  const dispose = autorun(() => {\n    autorun.effect(() => {\n      effect()\n    })\n    fn(obs.bb)\n  })\n  obs.bb++\n  obs.bb++\n  obs.bb++\n  obs.bb++\n  expect(effect).toBeCalledTimes(0)\n  await sleep(0)\n  expect(fn).toBeCalledTimes(5)\n  expect(fn).lastCalledWith(4)\n  expect(effect).toBeCalledTimes(5)\n  dispose()\n  await sleep(0)\n  expect(effect).toBeCalledTimes(5)\n})\n\ntest('autorun.effect not in autorun', () => {\n  expect(() => autorun.effect(() => {})).toThrow()\n})\n\ntest('autorun.effect with invalid params', () => {\n  autorun.effect({} as any)\n})\n\ntest('autorun dispose in batch', () => {\n  const obs = observable({\n    value: 123,\n  })\n  const handler = jest.fn()\n  const dispose = autorun(() => {\n    handler(obs.value)\n  })\n\n  batch(() => {\n    obs.value = 321\n    dispose()\n  })\n  expect(handler).toBeCalledTimes(1)\n})\n\ntest('set value by computed depend', () => {\n  const obs = observable<any>({})\n  const comp1 = observable.computed(() => {\n    return obs.aa?.bb\n  })\n  const comp2 = observable.computed(() => {\n    return obs.aa?.cc\n  })\n  const handler = jest.fn()\n  autorun(() => {\n    handler(comp1.value, comp2.value)\n  })\n  obs.aa = {\n    bb: 123,\n    cc: 321,\n  }\n  expect(handler).toBeCalledTimes(2)\n  expect(handler).nthCalledWith(1, undefined, undefined)\n  expect(handler).nthCalledWith(2, 123, 321)\n})\n\ntest('delete value by computed depend', () => {\n  const handler = jest.fn()\n  const obs = observable({\n    a: {\n      b: 1,\n      c: 2,\n    },\n  })\n  const comp1 = observable.computed(() => {\n    return obs.a?.b\n  })\n  const comp2 = observable.computed(() => {\n    return obs.a?.c\n  })\n  autorun(() => {\n    handler(comp1.value, comp2.value)\n  })\n  delete obs.a\n  expect(handler).toBeCalledTimes(2)\n  expect(handler).nthCalledWith(1, 1, 2)\n  expect(handler).nthCalledWith(2, undefined, undefined)\n})\n\ntest('set Set value by computed depend', () => {\n  const handler = jest.fn()\n  const obs = observable({\n    set: new Set(),\n  })\n  const comp1 = observable.computed(() => {\n    return obs.set.has(1)\n  })\n  const comp2 = observable.computed(() => {\n    return obs.set.size\n  })\n  autorun(() => {\n    handler(comp1.value, comp2.value)\n  })\n  obs.set.add(1)\n  expect(handler).toBeCalledTimes(2)\n  expect(handler).nthCalledWith(1, false, 0)\n  expect(handler).nthCalledWith(2, true, 1)\n})\n\ntest('delete Set by computed depend', () => {\n  const handler = jest.fn()\n  const obs = observable({\n    set: new Set([1]),\n  })\n  const comp1 = observable.computed(() => {\n    return obs.set.has(1)\n  })\n  const comp2 = observable.computed(() => {\n    return obs.set.size\n  })\n  autorun(() => {\n    handler(comp1.value, comp2.value)\n  })\n  obs.set.delete(1)\n  expect(handler).toBeCalledTimes(2)\n  expect(handler).nthCalledWith(1, true, 1)\n  expect(handler).nthCalledWith(2, false, 0)\n})\n\ntest('set Map value by computed depend', () => {\n  const handler = jest.fn()\n  const obs = observable({\n    map: new Map(),\n  })\n  const comp1 = observable.computed(() => {\n    return obs.map.has(1)\n  })\n  const comp2 = observable.computed(() => {\n    return obs.map.size\n  })\n  autorun(() => {\n    handler(comp1.value, comp2.value)\n  })\n  obs.map.set(1, 1)\n  expect(handler).toBeCalledTimes(2)\n  expect(handler).nthCalledWith(1, false, 0)\n  expect(handler).nthCalledWith(2, true, 1)\n})\n\ntest('delete Map by computed depend', () => {\n  const handler = jest.fn()\n  const obs = observable({\n    map: new Map([[1, 1]]),\n  })\n  const comp1 = observable.computed(() => {\n    return obs.map.has(1)\n  })\n  const comp2 = observable.computed(() => {\n    return obs.map.size\n  })\n  autorun(() => {\n    handler(comp1.value, comp2.value)\n  })\n  obs.map.delete(1)\n  expect(handler).toBeCalledTimes(2)\n  expect(handler).nthCalledWith(1, true, 1)\n  expect(handler).nthCalledWith(2, false, 0)\n})\n\ntest('autorun recollect dependencies', () => {\n  const obs = observable<any>({\n    aa: 'aaa',\n    bb: 'bbb',\n    cc: 'ccc',\n  })\n  const fn = jest.fn()\n  autorun(() => {\n    fn()\n    if (obs.aa === 'aaa') {\n      return obs.bb\n    }\n    return obs.cc\n  })\n  obs.aa = '111'\n  obs.bb = '222'\n  expect(fn).toBeCalledTimes(2)\n})\n\ntest('reaction recollect dependencies', () => {\n  const obs = observable<any>({\n    aa: 'aaa',\n    bb: 'bbb',\n    cc: 'ccc',\n  })\n  const fn1 = jest.fn()\n  const fn2 = jest.fn()\n  const trigger1 = jest.fn()\n  const trigger2 = jest.fn()\n  reaction(() => {\n    fn1()\n    if (obs.aa === 'aaa') {\n      return obs.bb\n    }\n    return obs.cc\n  }, trigger1)\n  reaction(\n    () => {\n      fn2()\n      if (obs.aa === 'aaa') {\n        return obs.bb\n      }\n      return obs.cc\n    },\n    trigger2,\n    {\n      fireImmediately: true,\n    }\n  )\n  obs.aa = '111'\n  obs.bb = '222'\n  expect(fn1).toBeCalledTimes(2)\n  expect(trigger1).toBeCalledTimes(1)\n  expect(fn2).toBeCalledTimes(2)\n  expect(trigger2).toBeCalledTimes(2)\n})\n"
  },
  {
    "path": "packages/reactive/src/__tests__/batch.spec.ts",
    "content": "import { observable, batch, autorun, reaction } from '..'\nimport { define } from '../model'\n\ndescribe('normal batch', () => {\n  test('no batch', () => {\n    const obs = observable({\n      aa: {\n        bb: 123,\n      },\n    })\n    const handler = jest.fn()\n    autorun(() => {\n      handler(obs.aa.bb)\n    })\n    obs.aa.bb = 111\n    obs.aa.bb = 222\n    expect(handler).toBeCalledTimes(3)\n\n    obs.aa.bb = 333\n    obs.aa.bb = 444\n\n    expect(handler).toBeCalledTimes(5)\n  })\n\n  test('batch', () => {\n    const obs = observable({\n      aa: {\n        bb: 123,\n      },\n    })\n    const handler = jest.fn()\n    autorun(() => {\n      handler(obs.aa.bb)\n    })\n    obs.aa.bb = 111\n    obs.aa.bb = 222\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(222)\n    batch(() => {\n      obs.aa.bb = 333\n      obs.aa.bb = 444\n    })\n    batch(() => {})\n    batch()\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).lastCalledWith(444)\n  })\n\n  test('batch track', () => {\n    const obs = observable({\n      aa: {\n        bb: 123,\n      },\n      cc: 1,\n    })\n    const handler = jest.fn()\n    autorun(() => {\n      batch(() => {\n        if (obs.cc > 0) {\n          handler(obs.aa.bb)\n          obs.cc = obs.cc + 20\n        }\n      })\n    })\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n    obs.aa.bb = 321\n    expect(handler).toBeCalledTimes(2)\n    expect(obs.cc).toEqual(41)\n  })\n\n  test('batch.bound', () => {\n    const obs = observable({\n      aa: {\n        bb: 123,\n      },\n    })\n    const handler = jest.fn()\n    const setData = batch.bound(() => {\n      obs.aa.bb = 333\n      obs.aa.bb = 444\n    })\n    autorun(() => {\n      handler(obs.aa.bb)\n    })\n    obs.aa.bb = 111\n    obs.aa.bb = 222\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(222)\n    setData()\n    batch(() => {})\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).lastCalledWith(444)\n  })\n\n  test('batch.bound track', () => {\n    const obs = observable({\n      aa: {\n        bb: 123,\n      },\n      cc: 1,\n    })\n    const handler = jest.fn()\n    autorun(() => {\n      batch.bound(() => {\n        if (obs.cc > 0) {\n          handler(obs.aa.bb)\n          obs.cc = obs.cc + 20\n        }\n      })()\n    })\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n    obs.aa.bb = 321\n    expect(handler).toBeCalledTimes(2)\n    expect(obs.cc).toEqual(41)\n  })\n\n  test('batch.scope', () => {\n    const obs = observable<any>({})\n\n    const handler = jest.fn()\n\n    autorun(() => {\n      handler(obs.aa, obs.bb, obs.cc, obs.dd)\n    })\n\n    batch(() => {\n      batch.scope(() => {\n        obs.aa = 123\n      })\n      batch.scope(() => {\n        obs.cc = 'ccccc'\n      })\n      obs.bb = 321\n      obs.dd = 'ddddd'\n    })\n\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).nthCalledWith(1, undefined, undefined, undefined, undefined)\n    expect(handler).nthCalledWith(2, 123, undefined, undefined, undefined)\n    expect(handler).nthCalledWith(3, 123, undefined, 'ccccc', undefined)\n    expect(handler).nthCalledWith(4, 123, 321, 'ccccc', 'ddddd')\n  })\n\n  test('batch.scope bound', () => {\n    const obs = observable<any>({})\n\n    const handler = jest.fn()\n\n    autorun(() => {\n      handler(obs.aa, obs.bb, obs.cc, obs.dd)\n    })\n\n    const scope1 = batch.scope.bound(() => {\n      obs.aa = 123\n    })\n    batch(() => {\n      scope1()\n      batch.scope.bound(() => {\n        obs.cc = 'ccccc'\n      })()\n      obs.bb = 321\n      obs.dd = 'ddddd'\n    })\n\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).nthCalledWith(1, undefined, undefined, undefined, undefined)\n    expect(handler).nthCalledWith(2, 123, undefined, undefined, undefined)\n    expect(handler).nthCalledWith(3, 123, undefined, 'ccccc', undefined)\n    expect(handler).nthCalledWith(4, 123, 321, 'ccccc', 'ddddd')\n  })\n\n  test('batch.scope track', () => {\n    const obs = observable({\n      aa: {\n        bb: 123,\n      },\n      cc: 1,\n    })\n    const handler = jest.fn()\n    autorun(() => {\n      batch.scope(() => {\n        if (obs.cc > 0) {\n          handler(obs.aa.bb)\n          obs.cc = obs.cc + 20\n        }\n      })\n    })\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n    obs.aa.bb = 321\n    expect(handler).toBeCalledTimes(2)\n    expect(obs.cc).toEqual(41)\n  })\n\n  test('batch.scope bound track', () => {\n    const obs = observable({\n      aa: {\n        bb: 123,\n      },\n      cc: 1,\n    })\n    const handler = jest.fn()\n    autorun(() => {\n      batch.scope.bound(() => {\n        if (obs.cc > 0) {\n          handler(obs.aa.bb)\n          obs.cc = obs.cc + 20\n        }\n      })()\n    })\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n    obs.aa.bb = 321\n    expect(handler).toBeCalledTimes(2)\n    expect(obs.cc).toEqual(41)\n  })\n\n  test('batch error', () => {\n    let error = null\n    try {\n      batch(() => {\n        throw '123'\n      })\n    } catch (e) {\n      error = e\n    }\n    expect(error).toEqual('123')\n  })\n})\n\ndescribe('annotation batch', () => {\n  test('batch', () => {\n    const obs = define(\n      {\n        aa: {\n          bb: 123,\n        },\n        setData() {\n          this.aa.bb = 333\n          this.aa.bb = 444\n        },\n      },\n      {\n        aa: observable,\n        setData: batch,\n      }\n    )\n    const handler = jest.fn()\n    autorun(() => {\n      handler(obs.aa.bb)\n    })\n    obs.aa.bb = 111\n    obs.aa.bb = 222\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(222)\n    obs.setData()\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).lastCalledWith(444)\n  })\n\n  test('batch track', () => {\n    const obs = define(\n      {\n        aa: {\n          bb: 123,\n        },\n        cc: 1,\n        setData() {\n          if (obs.cc > 0) {\n            handler(obs.aa.bb)\n            obs.cc = obs.cc + 20\n          }\n        },\n      },\n      {\n        aa: observable,\n        setData: batch,\n      }\n    )\n    const handler = jest.fn()\n    autorun(() => {\n      obs.setData()\n    })\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n    obs.aa.bb = 321\n    expect(handler).toBeCalledTimes(2)\n    expect(obs.cc).toEqual(41)\n  })\n\n  test('batch.bound', () => {\n    const obs = define(\n      {\n        aa: {\n          bb: 123,\n        },\n        setData() {\n          this.aa.bb = 333\n          this.aa.bb = 444\n        },\n      },\n      {\n        aa: observable,\n        setData: batch.bound,\n      }\n    )\n    const handler = jest.fn()\n    autorun(() => {\n      handler(obs.aa.bb)\n    })\n    obs.aa.bb = 111\n    obs.aa.bb = 222\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(222)\n    obs.setData()\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).lastCalledWith(444)\n  })\n\n  test('batch.bound track', () => {\n    const obs = define(\n      {\n        aa: {\n          bb: 123,\n        },\n        cc: 1,\n        setData() {\n          if (obs.cc > 0) {\n            handler(obs.aa.bb)\n            obs.cc = obs.cc + 20\n          }\n        },\n      },\n      {\n        aa: observable,\n        setData: batch.bound,\n      }\n    )\n    const handler = jest.fn()\n    autorun(() => {\n      obs.setData()\n    })\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n    obs.aa.bb = 321\n    expect(handler).toBeCalledTimes(2)\n    expect(obs.cc).toEqual(41)\n  })\n\n  test('batch.scope', () => {\n    const obs = define(\n      {\n        aa: null,\n        bb: null,\n        cc: null,\n        dd: null,\n        scope1() {\n          this.aa = 123\n        },\n        scope2() {\n          this.cc = 'ccccc'\n        },\n      },\n      {\n        aa: observable,\n        bb: observable,\n        cc: observable,\n        dd: observable,\n        scope1: batch.scope,\n        scope2: batch.scope,\n      }\n    )\n\n    const handler = jest.fn()\n\n    autorun(() => {\n      handler(obs.aa, obs.bb, obs.cc, obs.dd)\n    })\n\n    batch(() => {\n      obs.scope1()\n      obs.scope2()\n      obs.bb = 321\n      obs.dd = 'ddddd'\n    })\n\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).nthCalledWith(1, null, null, null, null)\n    expect(handler).nthCalledWith(2, 123, null, null, null)\n    expect(handler).nthCalledWith(3, 123, null, 'ccccc', null)\n    expect(handler).nthCalledWith(4, 123, 321, 'ccccc', 'ddddd')\n  })\n\n  test('batch.scope bound', () => {\n    const obs = define(\n      {\n        aa: null,\n        bb: null,\n        cc: null,\n        dd: null,\n        scope1() {\n          this.aa = 123\n        },\n        scope2() {\n          this.cc = 'ccccc'\n        },\n      },\n      {\n        aa: observable,\n        bb: observable,\n        cc: observable,\n        dd: observable,\n        scope1: batch.scope.bound,\n        scope2: batch.scope.bound,\n      }\n    )\n\n    const handler = jest.fn()\n\n    autorun(() => {\n      handler(obs.aa, obs.bb, obs.cc, obs.dd)\n    })\n\n    batch(() => {\n      obs.scope1()\n      obs.scope2()\n      obs.bb = 321\n      obs.dd = 'ddddd'\n    })\n\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).nthCalledWith(1, null, null, null, null)\n    expect(handler).nthCalledWith(2, 123, null, null, null)\n    expect(handler).nthCalledWith(3, 123, null, 'ccccc', null)\n    expect(handler).nthCalledWith(4, 123, 321, 'ccccc', 'ddddd')\n  })\n\n  test('batch.scope track', () => {\n    const obs = define(\n      {\n        aa: {\n          bb: 123,\n        },\n        cc: 1,\n        scope() {\n          if (this.cc > 0) {\n            handler(this.aa.bb)\n            this.cc = this.cc + 20\n          }\n        },\n      },\n      {\n        aa: observable,\n        cc: observable,\n        scope: batch.scope,\n      }\n    )\n    const handler = jest.fn()\n    autorun(() => {\n      obs.scope()\n    })\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n    obs.aa.bb = 321\n    expect(handler).toBeCalledTimes(2)\n    expect(obs.cc).toEqual(41)\n  })\n\n  test('batch.scope bound track', () => {\n    const obs = define(\n      {\n        aa: {\n          bb: 123,\n        },\n        cc: 1,\n        scope() {\n          if (this.cc > 0) {\n            handler(this.aa.bb)\n            this.cc = this.cc + 20\n          }\n        },\n      },\n      {\n        aa: observable,\n        cc: observable,\n        scope: batch.scope.bound,\n      }\n    )\n    const handler = jest.fn()\n    autorun(() => {\n      obs.scope()\n    })\n    expect(handler).toBeCalledTimes(1)\n    expect(obs.cc).toEqual(21)\n    obs.aa.bb = 321\n    expect(handler).toBeCalledTimes(2)\n    expect(obs.cc).toEqual(41)\n  })\n})\n\ndescribe('batch endpoint', () => {\n  test('normal endpoint', () => {\n    const tokens = []\n    const inner = batch.bound(() => {\n      batch.endpoint(() => {\n        tokens.push('endpoint')\n      })\n      tokens.push('inner')\n    })\n    const wrapper = batch.bound(() => {\n      inner()\n      tokens.push('wrapper')\n    })\n    wrapper()\n    expect(tokens).toEqual(['inner', 'wrapper', 'endpoint'])\n  })\n\n  test('unexpect endpoint', () => {\n    const tokens = []\n    const inner = batch.bound(() => {\n      batch.endpoint()\n      tokens.push('inner')\n    })\n    const wrapper = batch.bound(() => {\n      inner()\n      tokens.push('wrapper')\n    })\n    wrapper()\n    expect(tokens).toEqual(['inner', 'wrapper'])\n  })\n\n  test('no wrapper endpoint', () => {\n    const tokens = []\n    batch.endpoint(() => {\n      tokens.push('endpoint')\n    })\n    expect(tokens).toEqual(['endpoint'])\n  })\n})\n\ntest('reaction collect in batch valid', () => {\n  const obs = observable({\n    aa: 11,\n    bb: 22,\n    cc: 33,\n  })\n  reaction(\n    () => obs.aa,\n    () => {\n      void obs.cc\n    }\n  )\n  const fn = jest.fn()\n\n  autorun(() => {\n    batch.scope(() => {\n      obs.aa = obs.bb\n    })\n    fn()\n  })\n\n  obs.bb = 44\n  expect(fn).toBeCalledTimes(2)\n})\n\ntest('reaction collect in batch invalid', () => {\n  const obs = observable({\n    aa: 11,\n    bb: 22,\n    cc: 33,\n  })\n  reaction(\n    () => obs.aa,\n    () => {\n      void obs.cc\n    }\n  )\n  const fn = jest.fn()\n\n  autorun(() => {\n    batch.scope(() => {\n      obs.aa = obs.bb\n    })\n    fn()\n  })\n\n  obs.bb = 44\n  obs.cc = 55\n  expect(fn).toBeCalledTimes(3)\n})\n"
  },
  {
    "path": "packages/reactive/src/__tests__/collections-map.spec.ts",
    "content": "import { observable, autorun, raw } from '..'\n\ndescribe('Map', () => {\n  test('should be a proper JS Map', () => {\n    const map = observable(new Map())\n    expect(map).toBeInstanceOf(Map)\n    expect(raw(map)).toBeInstanceOf(Map)\n  })\n\n  test('should autorun mutations', () => {\n    const handler = jest.fn()\n    const map = observable(new Map())\n    autorun(() => handler(map.get('key')))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(undefined)\n    map.set('key', 'value')\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith('value')\n    map.set('key', 'value2')\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith('value2')\n    map.delete('key')\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).lastCalledWith(undefined)\n  })\n\n  test('should autorun size mutations', () => {\n    const handler = jest.fn()\n    const map = observable(new Map())\n    autorun(() => handler(map.size))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(0)\n    map.set('key1', 'value')\n    map.set('key2', 'value2')\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(2)\n    map.delete('key1')\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).lastCalledWith(1)\n    map.clear()\n    expect(handler).toBeCalledTimes(5)\n    expect(handler).lastCalledWith(0)\n  })\n\n  test('should autorun for of iteration', () => {\n    const handler = jest.fn()\n    const map = observable(new Map())\n    autorun(() => {\n      let sum = 0\n      // eslint-disable-next-line no-unused-vars\n      for (let [, num] of map) {\n        sum += num\n      }\n      handler(sum)\n    })\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(0)\n    map.set('key0', 3)\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(3)\n    map.set('key1', 2)\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(5)\n    map.delete('key0')\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).lastCalledWith(2)\n    map.clear()\n    expect(handler).toBeCalledTimes(5)\n    expect(handler).lastCalledWith(0)\n  })\n\n  test('should autorun forEach iteration', () => {\n    const handler = jest.fn()\n    const map = observable(new Map())\n    autorun(() => {\n      let sum = 0\n      map.forEach((num) => (sum += num))\n      handler(sum)\n    })\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(0)\n    map.set('key0', 3)\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(3)\n    map.set('key1', 2)\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(5)\n    map.delete('key0')\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).lastCalledWith(2)\n    map.clear()\n    expect(handler).toBeCalledTimes(5)\n    expect(handler).lastCalledWith(0)\n  })\n\n  test('should autorun keys iteration', () => {\n    const handler = jest.fn()\n    const map = observable(new Map())\n    autorun(() => {\n      let sum = 0\n      for (let key of map.keys()) {\n        sum += key\n      }\n      handler(sum)\n    })\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(0)\n    map.set(3, 3)\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(3)\n    map.set(2, 2)\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(5)\n    map.delete(3)\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).lastCalledWith(2)\n    map.clear()\n    expect(handler).toBeCalledTimes(5)\n    expect(handler).lastCalledWith(0)\n  })\n\n  test('should autorun values iteration', () => {\n    const handler = jest.fn()\n    const map = observable(new Map())\n    autorun(() => {\n      let sum = 0\n      for (let num of map.values()) {\n        sum += num\n      }\n      handler(sum)\n    })\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(0)\n    map.set('key0', 3)\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(3)\n    map.set('key1', 2)\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(5)\n    map.delete('key0')\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).lastCalledWith(2)\n    map.clear()\n    expect(handler).toBeCalledTimes(5)\n    expect(handler).lastCalledWith(0)\n  })\n\n  test('should autorun entries iteration', () => {\n    const handler = jest.fn()\n    const map = observable(new Map())\n    autorun(() => {\n      let sum = 0\n      // eslint-disable-next-line no-unused-vars\n      for (let [, num] of map.entries()) {\n        sum += num\n      }\n      handler(sum)\n    })\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(0)\n    map.set('key0', 3)\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(3)\n    map.set('key1', 2)\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(5)\n    map.delete('key0')\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).lastCalledWith(2)\n    map.clear()\n    expect(handler).toBeCalledTimes(5)\n    expect(handler).lastCalledWith(0)\n  })\n\n  test('should be triggered by clearing', () => {\n    const handler = jest.fn()\n    const map = observable(new Map())\n    autorun(() => handler(map.get('key')))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(undefined)\n    map.set('key', 3)\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(3)\n    map.clear()\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(undefined)\n  })\n\n  test('should not autorun custom property mutations', () => {\n    const handler = jest.fn()\n    const map = observable(new Map())\n    autorun(() => handler(map['customProp']))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(undefined)\n    map['customProp'] = 'Hello World'\n    expect(handler).toBeCalledTimes(1)\n  })\n\n  test('should not autorun non value changing mutations', () => {\n    const handler = jest.fn()\n    const map = observable(new Map())\n    autorun(() => handler(map.get('key')))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(undefined)\n    map.set('key', 'value')\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith('value')\n    map.set('key', 'value')\n    expect(handler).toBeCalledTimes(2)\n    map.delete('key')\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(undefined)\n    map.delete('key')\n    expect(handler).toBeCalledTimes(3)\n    map.clear()\n    expect(handler).toBeCalledTimes(3)\n  })\n\n  test('should not autorun raw data', () => {\n    const handler = jest.fn()\n    const map = observable(new Map())\n    autorun(() => handler(raw(map).get('key')))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(undefined)\n    map.set('key', 'Hello')\n    expect(handler).toBeCalledTimes(1)\n    map.delete('key')\n    expect(handler).toBeCalledTimes(1)\n  })\n\n  test('should not autorun raw iterations', () => {\n    const handler = jest.fn()\n    const map = observable(new Map())\n    autorun(() => {\n      let sum = 0\n      // eslint-disable-next-line no-unused-vars\n      for (let [, num] of raw(map).entries()) {\n        sum += num\n      }\n      for (let key of raw(map).keys()) {\n        sum += raw(map).get(key)\n      }\n      for (let num of raw(map).values()) {\n        sum += num\n      }\n      raw(map).forEach((num) => {\n        sum += num\n      })\n      // eslint-disable-next-line no-unused-vars\n      for (let [, num] of raw(map)) {\n        sum += num\n      }\n      handler(sum)\n    })\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(0)\n    map.set('key1', 2)\n    map.set('key2', 3)\n    expect(handler).toBeCalledTimes(1)\n    map.delete('key1')\n    expect(handler).toBeCalledTimes(1)\n  })\n\n  test('should not be triggered by raw mutations', () => {\n    const handler = jest.fn()\n    const map = observable(new Map())\n    autorun(() => handler(map.get('key')))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(undefined)\n    raw(map).set('key', 'Hello')\n    expect(handler).toBeCalledTimes(1)\n    raw(map).delete('key')\n    expect(handler).toBeCalledTimes(1)\n    raw(map).clear()\n    expect(handler).toBeCalledTimes(1)\n  })\n\n  test('should not autorun raw size mutations', () => {\n    const handler = jest.fn()\n    const map = observable(new Map())\n    autorun(() => handler(raw(map).size))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(0)\n    map.set('key', 'value')\n    expect(handler).toBeCalledTimes(1)\n  })\n\n  test('should not be triggered by raw size mutations', () => {\n    const handler = jest.fn()\n    const map = observable(new Map())\n    autorun(() => handler(map.size))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(0)\n    raw(map).set('key', 'value')\n    expect(handler).toBeCalledTimes(1)\n  })\n\n  test('should support objects as key', () => {\n    const handler = jest.fn()\n    const key = {}\n    const map = observable(new Map())\n    autorun(() => handler(map.get(key)))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(undefined)\n\n    map.set(key, 1)\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(1)\n\n    map.set({}, 2)\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(1)\n  })\n\n  test('observer object', () => {\n    const handler = jest.fn()\n    const map = observable(new Map<string, Record<string, any>>([]))\n    map.set('key', {})\n    map.set('key2', observable({}))\n    autorun(() => {\n      const [obs1, obs2] = [...map.values()]\n\n      handler(obs1.aa, obs2.aa)\n    })\n\n    expect(handler).toBeCalledTimes(1)\n    const obs1 = map.get('key')\n    const obs2 = map.get('key2')\n    obs1.aa = '123'\n    obs2.aa = '234'\n    expect(handler).toBeCalledTimes(3)\n  })\n\n  test('shallow', () => {\n    const handler = jest.fn()\n    const map = observable.shallow(new Map<string, Record<string, any>>([]))\n    map.set('key', {})\n    autorun(() => {\n      const [obs] = [...map.values()]\n\n      handler(obs.aa)\n    })\n\n    expect(handler).toBeCalledTimes(1)\n    const obs = map.get('key')\n    obs.aa = '123'\n    expect(handler).toBeCalledTimes(1)\n  })\n})\n"
  },
  {
    "path": "packages/reactive/src/__tests__/collections-set.spec.ts",
    "content": "import { observable, autorun, raw } from '..'\n\ndescribe('Set', () => {\n  test('should be a proper JS Set', () => {\n    const set = observable(new Set())\n    expect(set).toBeInstanceOf(Set)\n    expect(raw(set)).toBeInstanceOf(Set)\n  })\n\n  test('should autorun mutations', () => {\n    const handler = jest.fn()\n    const set = observable(new Set())\n    autorun(() => handler(set.has('value')))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(false)\n    set.add('value')\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(true)\n    set.delete('value')\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(false)\n  })\n\n  test('should autorun size mutations', () => {\n    const handler = jest.fn()\n    const set = observable(new Set())\n    autorun(() => handler(set.size))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(0)\n    set.add('value')\n    set.add('value2')\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(2)\n    set.delete('value')\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).lastCalledWith(1)\n    set.clear()\n    expect(handler).toBeCalledTimes(5)\n    expect(handler).lastCalledWith(0)\n  })\n\n  test('should autorun for of iteration', () => {\n    const handler = jest.fn()\n    const set = observable(new Set<number>())\n    autorun(() => {\n      let sum = 0\n      // eslint-disable-next-line no-unused-vars\n      for (let num of set) {\n        sum += num\n      }\n      handler(sum)\n    })\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(0)\n    set.add(3)\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(3)\n    set.add(2)\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(5)\n    set.delete(3)\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).lastCalledWith(2)\n    set.clear()\n    expect(handler).toBeCalledTimes(5)\n    expect(handler).lastCalledWith(0)\n  })\n\n  test('should autorun forEach iteration', () => {\n    const handler = jest.fn()\n    const set = observable(new Set<number>())\n    autorun(() => {\n      let sum = 0\n      set.forEach((num) => (sum += num))\n      handler(sum)\n    })\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(0)\n    set.add(3)\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(3)\n    set.add(2)\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(5)\n    set.delete(3)\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).lastCalledWith(2)\n    set.clear()\n    expect(handler).toBeCalledTimes(5)\n    expect(handler).lastCalledWith(0)\n  })\n\n  test('should autorun keys iteration', () => {\n    const handler = jest.fn()\n    const set = observable(new Set<number>())\n    autorun(() => {\n      let sum = 0\n      for (let key of set.keys()) {\n        sum += key\n      }\n      handler(sum)\n    })\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(0)\n    set.add(3)\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(3)\n    set.add(2)\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(5)\n    set.delete(3)\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).lastCalledWith(2)\n    set.clear()\n    expect(handler).toBeCalledTimes(5)\n    expect(handler).lastCalledWith(0)\n  })\n\n  test('should autorun values iteration', () => {\n    const handler = jest.fn()\n    const set = observable(new Set<number>())\n    autorun(() => {\n      let sum = 0\n      for (let num of set.values()) {\n        sum += num\n      }\n      handler(sum)\n    })\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(0)\n    set.add(3)\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(3)\n    set.add(2)\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(5)\n    set.delete(3)\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).lastCalledWith(2)\n    set.clear()\n    expect(handler).toBeCalledTimes(5)\n    expect(handler).lastCalledWith(0)\n  })\n\n  test('should autorun entries iteration', () => {\n    const handler = jest.fn()\n    const set = observable(new Set<number>())\n    autorun(() => {\n      let sum = 0\n      // eslint-disable-next-line no-unused-vars\n      for (let [, num] of set.entries()) {\n        sum += num\n      }\n      handler(sum)\n    })\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(0)\n    set.add(3)\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(3)\n    set.add(2)\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(5)\n    set.delete(3)\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).lastCalledWith(2)\n    set.clear()\n    expect(handler).toBeCalledTimes(5)\n    expect(handler).lastCalledWith(0)\n  })\n\n  test('should not autorun custom property mutations', () => {\n    const handler = jest.fn()\n    const set = observable(new Set())\n    autorun(() => handler(set['customProp']))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(undefined)\n    set['customProp'] = 'Hello World'\n    expect(handler).toBeCalledTimes(1)\n  })\n\n  test('should not autorun non value changing mutations', () => {\n    const handler = jest.fn()\n    const set = observable(new Set())\n    autorun(() => handler(set.has('value')))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(false)\n    set.add('value')\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(true)\n    set.add('value')\n    expect(handler).toBeCalledTimes(2)\n    set.delete('value')\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(false)\n    set.delete('value')\n    expect(handler).toBeCalledTimes(3)\n    set.clear()\n    expect(handler).toBeCalledTimes(3)\n  })\n\n  test('should not autorun raw data', () => {\n    const handler = jest.fn()\n    const set = observable(new Set())\n    autorun(() => handler(raw(set).has('value')))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(false)\n    set.add('value')\n    expect(handler).toBeCalledTimes(1)\n    set.delete('value')\n    expect(handler).toBeCalledTimes(1)\n  })\n\n  test('should not autorun raw iterations', () => {\n    const handler = jest.fn()\n    const set = observable(new Set<number>())\n    autorun(() => {\n      let sum = 0\n      // eslint-disable-next-line no-unused-vars\n      for (let [, num] of raw(set).entries()) {\n        sum += num\n      }\n      for (let key of raw(set).keys()) {\n        sum += key\n      }\n      for (let num of raw(set).values()) {\n        sum += num\n      }\n      raw(set).forEach((num) => {\n        sum += num\n      })\n      // eslint-disable-next-line no-unused-vars\n      for (let num of raw(set)) {\n        sum += num\n      }\n      handler(sum)\n    })\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(0)\n    set.add(2)\n    set.add(3)\n    expect(handler).toBeCalledTimes(1)\n    set.delete(2)\n    expect(handler).toBeCalledTimes(1)\n  })\n\n  test('should not be triggered by raw mutations', () => {\n    const handler = jest.fn()\n    const set = observable(new Set())\n    autorun(() => handler(set.has('value')))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(false)\n    raw(set).add('value')\n    expect(handler).toBeCalledTimes(1)\n    raw(set).delete('value')\n    expect(handler).toBeCalledTimes(1)\n    raw(set).clear()\n    expect(handler).toBeCalledTimes(1)\n  })\n\n  test('should not autorun raw size mutations', () => {\n    const handler = jest.fn()\n    const set = observable(new Set())\n    autorun(() => handler(raw(set).size))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(0)\n    set.add('value')\n    expect(handler).toBeCalledTimes(1)\n  })\n\n  test('should not be triggered by raw size mutations', () => {\n    const handler = jest.fn()\n    const set = observable(new Set())\n    autorun(() => handler(set.size))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(0)\n    raw(set).add('value')\n    expect(handler).toBeCalledTimes(1)\n  })\n})\n"
  },
  {
    "path": "packages/reactive/src/__tests__/collections-weakmap.spec.ts",
    "content": "import { observable, autorun, raw } from '..'\n\ndescribe('WeakMap', () => {\n  test('should be a proper JS WeakMap', () => {\n    const weakMap = observable(new WeakMap())\n    expect(weakMap).toBeInstanceOf(WeakMap)\n    expect(raw(weakMap)).toBeInstanceOf(WeakMap)\n  })\n\n  test('should autorun mutations', () => {\n    const handler = jest.fn()\n    const key = {}\n    const weakMap = observable(new WeakMap())\n    autorun(() => handler(weakMap.get(key)))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(undefined)\n    weakMap.set(key, 'value')\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith('value')\n    weakMap.set(key, 'value2')\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith('value2')\n    weakMap.delete(key)\n    expect(handler).toBeCalledTimes(4)\n    expect(handler).lastCalledWith(undefined)\n  })\n\n  test('should not autorun custom property mutations', () => {\n    const handler = jest.fn()\n    const weakMap = observable(new WeakMap())\n    autorun(() => handler(weakMap['customProp']))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(undefined)\n    weakMap['customProp'] = 'Hello World'\n    expect(handler).toBeCalledTimes(1)\n  })\n\n  test('should not autorun non value changing mutations', () => {\n    const handler = jest.fn()\n    const key = {}\n    const weakMap = observable(new WeakMap())\n    autorun(() => handler(weakMap.get(key)))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(undefined)\n    weakMap.set(key, 'value')\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith('value')\n    weakMap.set(key, 'value')\n    expect(handler).toBeCalledTimes(2)\n    weakMap.delete(key)\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(undefined)\n    weakMap.delete(key)\n    expect(handler).toBeCalledTimes(3)\n  })\n\n  test('should not autorun raw data', () => {\n    const handler = jest.fn()\n    const key = {}\n    const weakMap = observable(new WeakMap())\n    autorun(() => handler(raw(weakMap).get(key)))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(undefined)\n    weakMap.set(key, 'Hello')\n    expect(handler).toBeCalledTimes(1)\n    weakMap.delete(key)\n    expect(handler).toBeCalledTimes(1)\n  })\n\n  test('should not be triggered by raw mutations', () => {\n    const handler = jest.fn()\n    const key = {}\n    const weakMap = observable(new WeakMap())\n    autorun(() => handler(weakMap.get(key)))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(undefined)\n    raw(weakMap).set(key, 'Hello')\n    expect(handler).toBeCalledTimes(1)\n    raw(weakMap).delete(key)\n    expect(handler).toBeCalledTimes(1)\n  })\n})\n"
  },
  {
    "path": "packages/reactive/src/__tests__/collections-weakset.spec.ts",
    "content": "import { observable, autorun, raw } from '..'\n\ndescribe('WeakSet', () => {\n  test('should be a proper JS WeakSet', () => {\n    const weakSet = observable(new WeakSet())\n    expect(weakSet).toBeInstanceOf(WeakSet)\n    expect(raw(weakSet)).toBeInstanceOf(WeakSet)\n  })\n\n  test('should autorun mutations', () => {\n    const handler = jest.fn()\n    const value = {}\n    const weakSet = observable(new WeakSet())\n    autorun(() => handler(weakSet.has(value)))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(false)\n    weakSet.add(value)\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(true)\n    weakSet.delete(value)\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(false)\n  })\n\n  test('should not autorun custom property mutations', () => {\n    const handler = jest.fn()\n    const weakSet = observable(new WeakSet())\n    autorun(() => handler(weakSet['customProp']))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(undefined)\n    weakSet['customProp'] = 'Hello World'\n    expect(handler).toBeCalledTimes(1)\n  })\n\n  test('should not autorun non value changing mutations', () => {\n    const handler = jest.fn()\n    const value = {}\n    const weakSet = observable(new WeakSet())\n    autorun(() => handler(weakSet.has(value)))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(false)\n    weakSet.add(value)\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(true)\n    weakSet.add(value)\n    expect(handler).toBeCalledTimes(2)\n    weakSet.delete(value)\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).lastCalledWith(false)\n    weakSet.delete(value)\n    expect(handler).toBeCalledTimes(3)\n  })\n\n  test('should not autorun raw data', () => {\n    const handler = jest.fn()\n    const value = {}\n    const weakSet = observable(new WeakSet())\n    autorun(() => handler(raw(weakSet).has(value)))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(false)\n    weakSet.add(value)\n    expect(handler).toBeCalledTimes(1)\n    weakSet.delete(value)\n    expect(handler).toBeCalledTimes(1)\n  })\n\n  test('should not be triggered by raw mutations', () => {\n    const handler = jest.fn()\n    const value = {}\n    const weakSet = observable(new WeakSet())\n    autorun(() => handler(weakSet.has(value)))\n\n    expect(handler).toBeCalledTimes(1)\n    expect(handler).lastCalledWith(false)\n    raw(weakSet).add(value)\n    expect(handler).toBeCalledTimes(1)\n    raw(weakSet).delete(value)\n    expect(handler).toBeCalledTimes(1)\n  })\n})\n"
  },
  {
    "path": "packages/reactive/src/__tests__/define.spec.ts",
    "content": "import { define, model, observable, autorun } from '..'\nimport { observe } from '../observe'\nimport { FormPath } from '@formily/shared'\nimport { batch } from '../batch'\n\ndescribe('makeObservable', () => {\n  test('observable annotation', () => {\n    const target: any = {\n      aa: {},\n    }\n    define(target, {\n      aa: observable,\n    })\n    const handler = jest.fn()\n    const handler1 = jest.fn()\n    const handler2 = jest.fn()\n    autorun(() => {\n      handler(FormPath.getIn(target, 'aa.bb.cc'))\n    })\n    observe(target, handler1)\n    observe(target.aa, handler2)\n    target.aa.bb = { cc: { dd: { ee: 123 } } }\n    target.aa = { hh: 123 }\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).nthCalledWith(1, undefined)\n    expect(handler).nthCalledWith(2, { dd: { ee: 123 } })\n    expect(handler).nthCalledWith(3, undefined)\n    expect(handler1).toBeCalledTimes(2)\n    expect(handler2).toBeCalledTimes(2)\n  })\n  test('shallow annotation', () => {\n    const target: any = {\n      aa: {},\n    }\n    define(target, {\n      aa: observable.shallow,\n    })\n    const handler = jest.fn()\n    const handler1 = jest.fn()\n    const handler2 = jest.fn()\n    autorun(() => {\n      handler(FormPath.getIn(target, 'aa.bb.cc'))\n    })\n    observe(target, handler1)\n    observe(target.aa, handler2)\n    target.aa.bb = { cc: { dd: { ee: 123 } } }\n    target.aa.bb.cc.kk = 333\n    target.aa = { hh: 123 }\n    expect(handler).toBeCalledTimes(3)\n    expect(handler).nthCalledWith(1, undefined)\n    expect(handler).nthCalledWith(2, { dd: { ee: 123 }, kk: 333 })\n    expect(handler).nthCalledWith(3, undefined)\n    expect(handler1).toBeCalledTimes(2)\n    expect(handler2).toBeCalledTimes(2)\n  })\n  test('box annotation', () => {\n    const target: any = {}\n    define(target, {\n      aa: observable.box,\n    })\n    const handler = jest.fn()\n    const handler1 = jest.fn()\n    const handler2 = jest.fn()\n    autorun(() => {\n      handler(target.aa.get())\n    })\n    observe(target, handler1)\n    observe(target.aa, handler2)\n\n    expect(handler).lastCalledWith(undefined)\n    target.aa.set(123)\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(123)\n    expect(handler1).toBeCalledTimes(1)\n    expect(handler2).toBeCalledTimes(1)\n  })\n  test('ref annotation', () => {\n    const target: any = {}\n    define(target, {\n      aa: observable.ref,\n    })\n    const handler = jest.fn()\n    const handler1 = jest.fn()\n    autorun(() => {\n      handler(target.aa)\n    })\n    observe(target, handler1)\n    expect(handler).lastCalledWith(undefined)\n    target.aa = 123\n    expect(handler).toBeCalledTimes(2)\n    expect(handler).lastCalledWith(123)\n    expect(handler1).toBeCalledTimes(1)\n  })\n  test('action annotation', () => {\n    const target = {\n      aa: {\n        bb: null,\n        cc: null,\n      },\n      setData() {\n        target.aa.bb = 123\n        target.aa.cc = 312\n      },\n    }\n    define(target, {\n      aa: observable,\n      setData: batch,\n    })\n    const handler = jest.fn()\n    autorun(() => {\n      handler([target.aa.bb, target.aa.cc])\n    })\n    expect(handler).toBeCalledTimes(1)\n    target.setData()\n    expect(handler).toBeCalledTimes(2)\n  })\n  test('computed annotation', () => {\n    const handler = jest.fn()\n    const target = {\n      aa: 11,\n      bb: 22,\n      get cc() {\n        handler()\n        return this.aa + this.bb\n      },\n    }\n    define(target, {\n      aa: observable,\n      bb: observable,\n      cc: observable.computed,\n    })\n    autorun(() => {\n      target.cc\n    })\n    expect(handler).toBeCalledTimes(1)\n    expect(target.cc).toEqual(33)\n    target.aa = 22\n    expect(handler).toBeCalledTimes(2)\n    expect(target.cc).toEqual(44)\n  })\n  test('unexpect target', () => {\n    const testFn = jest.fn()\n    const testArr = []\n    const obs1 = define(4 as any, {\n      value: observable.computed,\n    })\n    const obs2 = define('123' as any, {\n      value: observable.computed,\n    })\n    const obs3 = define(testFn as any, {\n      value: observable.computed,\n    })\n    const obs4 = define(testArr as any, {\n      value: observable.computed,\n    })\n    expect(obs1).toBe(4)\n    expect(obs2).toBe('123')\n    expect(obs3).toBe(testFn)\n    expect(obs4).toBe(testArr)\n  })\n})\n\ntest('define model', () => {\n  const obs = model({\n    aa: 1,\n    action() {\n      this.aa++\n    },\n  })\n  const { action } = obs\n  action()\n  expect(obs.aa).toEqual(2)\n})\n"
  },
  {
    "path": "packages/reactive/src/__tests__/externals.spec.ts",
    "content": "import {\n  isObservable,\n  isSupportObservable,\n  markObservable,\n  markRaw,\n  observable,\n  toJS,\n} from '..'\n\ntest('is support observable', () => {\n  const obs = observable<any>({ aa: 111 })\n  class Class {}\n\n  expect(isSupportObservable(obs)).toBe(true)\n  expect(isSupportObservable(new Class())).toBe(true)\n  expect(isSupportObservable(null)).toBe(false)\n  expect(isSupportObservable([])).toBe(true)\n  expect(isSupportObservable({})).toBe(true)\n  expect(isSupportObservable({ $$typeof: {}, _owner: {} })).toBe(false)\n  expect(isSupportObservable({ _isAMomentObject: {} })).toBe(false)\n  expect(isSupportObservable({ _isJSONSchemaObject: {} })).toBe(false)\n  expect(isSupportObservable({ toJS: () => {} })).toBe(false)\n  expect(isSupportObservable({ toJSON: () => {} })).toBe(false)\n  expect(isSupportObservable(new Map())).toBe(true)\n  expect(isSupportObservable(new WeakMap())).toBe(true)\n  expect(isSupportObservable(new Set())).toBe(true)\n  expect(isSupportObservable(new WeakSet())).toBe(true)\n})\n\ndescribe('mark operation', () => {\n  test('plain object should be observable', () => {\n    const obs = observable<any>({ aa: 111 })\n    expect(isObservable(obs)).toBe(true)\n  })\n\n  test('class instance should be observable', () => {\n    class Class {}\n    const obs = observable<any>(new Class())\n    const obs2 = observable<any>(new Class())\n    expect(isObservable(obs)).toBe(true)\n    expect(isObservable(obs2)).toBe(true)\n  })\n\n  test('object with toJS function should NOT be observable', () => {\n    const obs = observable<any>({ aa: 111, toJS: () => {} })\n    expect(isObservable(obs)).toBe(false)\n  })\n\n  test('plain object marked as raw should NOT be observable', () => {\n    const obs = observable<any>(markRaw({ aa: 111 }))\n    expect(isObservable(obs)).toBe(false)\n  })\n\n  test('class marked as raw instance should NOT be observable', () => {\n    class Class {}\n    markRaw(Class)\n    const obs = observable<any>(new Class())\n    const obs2 = observable<any>(new Class())\n    expect(isObservable(obs)).toBe(false)\n    expect(isObservable(obs2)).toBe(false)\n  })\n\n  test('object with toJS function marked as observable should be observable', () => {\n    const obs = observable<any>(markObservable({ aa: 111, toJS: () => {} }))\n    expect(isObservable(obs)).toBe(true)\n  })\n\n  test('plain object marked as raw and observable should NOT be observable', () => {\n    const obs = observable<any>(markRaw(markObservable({ aa: 111 })))\n    expect(isObservable(obs)).toBe(false)\n  })\n\n  test('plain object marked as observable and raw should NOT be observable', () => {\n    const obs = observable<any>(markObservable(markRaw({ aa: 111 })))\n    expect(isObservable(obs)).toBe(false)\n  })\n\n  test('function marked as observable should NOT be observable', () => {\n    const obs = observable<any>(markObservable(() => {}))\n    expect(isObservable(obs)).toBe(false)\n  })\n})\n\ntest('recursive references tojs', () => {\n  const obj: any = { aa: 111 }\n  obj.obj = obj\n  const obs = observable<any>(obj)\n  obs.obs = obs\n  expect(toJS(obs)).toBeTruthy()\n\n  const arrObs = observable([{ aa: 1 }, { bb: 2 }, { cc: 3 }])\n  expect(toJS(arrObs)).toEqual([{ aa: 1 }, { bb: 2 }, { cc: 3 }])\n})\n"
  },
  {
    "path": "packages/reactive/src/__tests__/hasCollected.spec.ts",
    "content": "import { observable, hasCollected, autorun } from '../'\n\ntest('hasCollected', () => {\n  const obs = observable({ value: '' })\n  autorun(() => {\n    expect(\n      hasCollected(() => {\n        obs.value\n      })\n    ).toBe(true)\n    expect(hasCollected(() => {})).toBe(false)\n    expect(hasCollected()).toBe(false)\n  })\n})\n"
  },
  {
    "path": "packages/reactive/src/__tests__/observable.spec.ts",
    "content": "import { observable } from '../'\nimport { contains } from '../externals'\n\ntest('array mutation', () => {\n  const arr = observable([1, 2, 3, 4])\n  arr.splice(2, 1)\n  expect(arr).toEqual([1, 2, 4])\n})\n\ntest('observable contains', () => {\n  const subElement = { cc: 333 }\n  const element = { aa: subElement }\n  const arr = observable<any[]>([element, 2, 3, 4])\n  expect(contains(arr, arr[0])).toBe(true)\n  expect(contains(arr, arr[0].aa)).toBe(true)\n  expect(contains(arr, element)).toBe(true)\n  expect(contains(arr, subElement)).toBe(true)\n  expect(contains(element, subElement)).toBe(true)\n  expect(contains(element, arr[0].aa)).toBe(true)\n  expect(contains(arr[0], subElement)).toBe(true)\n\n  const obj = observable<any>({})\n  const other = { bb: 321 }\n  expect(contains(obj, obj.other)).toBe(false)\n  obj.other = other\n  obj.arr = arr\n\n  expect(contains(obj, obj.other)).toBe(true)\n  expect(contains(obj, other)).toBe(true)\n\n  expect(contains(obj, obj.arr)).toBe(true)\n  expect(contains(obj, arr)).toBe(true)\n})\n\ntest('observable __proto__', () => {\n  const observableArr = observable([] as any[])\n  // @ts-ignore\n  observableArr.__proto__ = Object.create(Array.prototype)\n  observableArr[0] = {}\n  expect(observableArr).toEqual([{}])\n\n  const observableObj = observable({} as any)\n  // @ts-ignore\n  observableObj.__proto__ = Object.create(Object.prototype)\n  observableObj.aa = {}\n  expect(observableObj).toEqual({ aa: {} })\n})\n"
  },
  {
    "path": "packages/reactive/src/__tests__/observe.spec.ts",
    "content": "import { observable, observe } from '../'\n\ntest('deep observe', () => {\n  const obs = observable<any>({\n    aa: {\n      bb: {\n        cc: [11, 22, 33],\n      },\n    },\n    ee: observable([]),\n  })\n  const handler = jest.fn()\n  observe(obs, handler)\n  obs.dd = 123\n  obs.aa.bb.cc.push(44)\n  expect(obs.aa.bb.cc).toEqual([11, 22, 33, 44])\n  expect(handler).toHaveBeenCalledTimes(2)\n  delete obs.aa\n  expect(handler).toHaveBeenCalledTimes(3)\n\n  // Are these expected behaviors?\n  obs.ee.push(11)\n  expect(handler).toHaveBeenCalledTimes(3)\n  obs.ee = []\n  expect(handler).toHaveBeenCalledTimes(4)\n  obs.ee.push(11)\n  expect(handler).toHaveBeenCalledTimes(5)\n})\n\ntest('shallow observe', () => {\n  const obs = observable<any>({\n    aa: {\n      bb: {\n        cc: [11, 22, 33],\n      },\n    },\n  })\n  const handler = jest.fn()\n  observe(obs, handler, false)\n  obs.dd = 123\n  obs.aa.bb.cc.push(44)\n  expect(obs.aa.bb.cc).toEqual([11, 22, 33, 44])\n  expect(handler).toHaveBeenCalledTimes(1)\n  delete obs.aa\n  expect(handler).toHaveBeenCalledTimes(2)\n})\n\ntest('root replace observe', () => {\n  const obs = observable<any>({\n    aa: {\n      bb: {\n        cc: [11, 22, 33],\n      },\n    },\n  })\n  const handler1 = jest.fn()\n  const handler = jest.fn()\n  observe(obs, handler1)\n  observe(obs.aa, handler)\n  obs.aa = {\n    mm: 123,\n  }\n  expect(handler1).toBeCalledTimes(1)\n  expect(handler).toBeCalledTimes(1)\n  obs.aa = {\n    bb: {\n      cc: [11, 22, 33],\n    },\n  }\n  obs.aa.bb.cc.push(44)\n  expect(handler1).toBeCalledTimes(3)\n  expect(handler).toBeCalledTimes(3)\n})\n\ntest('dispose observe', () => {\n  const obs = observable<any>({\n    aa: {\n      bb: {\n        cc: [11, 22, 33],\n      },\n    },\n  })\n  const handler = jest.fn()\n  const dispose = observe(obs, handler)\n  obs.kk = 123\n  expect(handler).toBeCalledTimes(1)\n  dispose()\n  obs.aa = 123\n  expect(handler).toBeCalledTimes(1)\n})\n\ntest('dispose observe', () => {\n  const obs = observable<any>({\n    aa: {\n      bb: {\n        cc: [11, 22, 33],\n      },\n    },\n  })\n  const handler = jest.fn()\n  const dispose = observe(obs.aa, handler)\n  obs.kk = 111\n  expect(handler).toBeCalledTimes(0)\n  obs.aa = { mm: 222 }\n  expect(handler).toBeCalledTimes(1)\n  obs.aa = { mm: 222 }\n  expect(handler).toBeCalledTimes(2)\n  obs.aa = { mm: '111' }\n  expect(handler).toBeCalledTimes(3)\n  obs.aa = { mm: 333 }\n  expect(handler).toBeCalledTimes(4)\n  dispose()\n  obs.aa = { mm: 444 }\n  expect(handler).toBeCalledTimes(4)\n})\n\ntest('array delete', () => {\n  const array = observable([{ value: 1 }, { value: 2 }])\n\n  const fn = jest.fn()\n\n  const dispose = observe(array, (change) => {\n    if (change.type === 'set' && change.key === 'value') {\n      fn(change.path?.join('.'))\n    }\n  })\n\n  array[0].value = 3\n  expect(fn.mock.calls[0][0]).toBe('0.value')\n\n  array.splice(0, 1)\n\n  array[0].value = 3\n  expect(fn.mock.calls[1][0]).toBe('0.value')\n\n  dispose()\n})\n\ntest('observe dynamic tree', () => {\n  const handler = jest.fn()\n  const tree = observable<any>({})\n  const childTree = observable({})\n  tree.children = childTree\n  observe(tree, handler)\n  tree.children.aa = 123\n  expect(handler).toBeCalledTimes(1)\n})\n\ntest('invalid target', () => {\n  expect(() => observe(function () {})).toThrowError()\n})\n"
  },
  {
    "path": "packages/reactive/src/__tests__/tracker.spec.ts",
    "content": "import { Tracker, observable } from '../'\n\ntest('base tracker', () => {\n  const obs = observable<any>({})\n  const fn = jest.fn()\n  const view = () => {\n    fn(obs.value)\n  }\n  const scheduler = () => {\n    tracker.track(view)\n  }\n  const tracker = new Tracker(scheduler)\n\n  tracker.track(view)\n  obs.value = 123\n  expect(fn).nthCalledWith(1, undefined)\n  expect(fn).nthCalledWith(2, 123)\n  tracker.dispose()\n})\n\ntest('nested tracker', () => {\n  const obs = observable<any>({})\n  const fn = jest.fn()\n  const view = () => {\n    obs.value = obs.value || 321\n    fn(obs.value)\n  }\n  const scheduler = () => {\n    tracker.track(view)\n  }\n  const tracker = new Tracker(scheduler)\n\n  tracker.track(view)\n  expect(fn).toBeCalledTimes(1)\n  expect(fn).nthCalledWith(1, 321)\n  obs.value = 123\n  expect(fn).toBeCalledTimes(2)\n  expect(fn).nthCalledWith(2, 123)\n  tracker.dispose()\n})\n\ntest('tracker recollect dependencies', () => {\n  const obs = observable<any>({\n    aa: 'aaa',\n    bb: 'bbb',\n    cc: 'ccc',\n  })\n  const fn = jest.fn()\n  const view = () => {\n    fn()\n    if (obs.aa === 'aaa') {\n      return obs.bb\n    }\n    return obs.cc\n  }\n  const scheduler = () => {\n    tracker.track(view)\n  }\n  const tracker = new Tracker(scheduler)\n\n  tracker.track(view)\n  obs.aa = '111'\n  obs.bb = '222'\n  expect(fn).toBeCalledTimes(2)\n  tracker.dispose()\n})\n\ntest('shared scheduler with multi tracker(mock react strict mode)', () => {\n  const obs = observable<any>({})\n\n  const component = () => obs.value\n\n  const render = () => {\n    tracker1.track(component)\n    tracker2.track(component)\n  }\n\n  const scheduler1 = jest.fn(() => {\n    tracker2.track(component)\n  })\n  const scheduler2 = jest.fn(() => {\n    tracker1.track(component)\n  })\n  const tracker1 = new Tracker(scheduler1, 'tracker1')\n  const tracker2 = new Tracker(scheduler2, 'tracker2')\n\n  render()\n\n  obs.value = 123\n\n  expect(scheduler1).toBeCalledTimes(1)\n  expect(scheduler2).toBeCalledTimes(0)\n})\n"
  },
  {
    "path": "packages/reactive/src/__tests__/untracked.spec.ts",
    "content": "import { untracked, observable, autorun } from '../'\n\ntest('basic untracked', () => {\n  const obs = observable<any>({})\n  const fn = jest.fn()\n  autorun(() => {\n    untracked(() => {\n      fn(obs.value)\n    })\n  })\n\n  expect(fn).toBeCalledTimes(1)\n  obs.value = 123\n  expect(fn).toBeCalledTimes(1)\n})\n\ntest('no params untracked', () => {\n  untracked()\n})\n"
  },
  {
    "path": "packages/reactive/src/action.ts",
    "content": "import {\n  batchStart,\n  batchEnd,\n  batchScopeStart,\n  batchScopeEnd,\n  untrackStart,\n  untrackEnd,\n} from './reaction'\nimport { createBoundaryAnnotation } from './internals'\nimport { IAction } from './types'\n\nexport const action: IAction = createBoundaryAnnotation(\n  () => {\n    batchStart()\n    untrackStart()\n  },\n  () => {\n    untrackEnd()\n    batchEnd()\n  }\n)\n\naction.scope = createBoundaryAnnotation(\n  () => {\n    batchScopeStart()\n    untrackStart()\n  },\n  () => {\n    untrackEnd()\n    batchScopeEnd()\n  }\n)\n"
  },
  {
    "path": "packages/reactive/src/annotations/box.ts",
    "content": "import { ProxyRaw, RawProxy } from '../environment'\nimport { createAnnotation } from '../internals'\nimport { buildDataTree } from '../tree'\nimport {\n  bindTargetKeyWithCurrentReaction,\n  runReactionsFromTargetKey,\n} from '../reaction'\n\nexport interface IBox {\n  <T>(target: T): { get(): T; set(value: T): void }\n}\n\nexport const box: IBox = createAnnotation(({ target, key, value }) => {\n  const store = {\n    value: target ? target[key] : value,\n  }\n\n  const proxy = {\n    set,\n    get,\n  }\n\n  ProxyRaw.set(proxy, store)\n  RawProxy.set(store, proxy)\n\n  buildDataTree(target, key, store)\n\n  function get() {\n    bindTargetKeyWithCurrentReaction({\n      target: store,\n      key,\n      type: 'get',\n    })\n    return store.value\n  }\n\n  function set(value: any) {\n    const oldValue = store.value\n    store.value = value\n    if (oldValue !== value) {\n      runReactionsFromTargetKey({\n        target: store,\n        key,\n        type: 'set',\n        oldValue,\n        value,\n      })\n    }\n  }\n\n  if (target) {\n    Object.defineProperty(target, key, {\n      value: proxy,\n      enumerable: true,\n      configurable: false,\n      writable: false,\n    })\n    return target\n  }\n  return proxy\n})\n"
  },
  {
    "path": "packages/reactive/src/annotations/computed.ts",
    "content": "import { ObModelSymbol, ReactionStack } from '../environment'\nimport { createAnnotation } from '../internals'\nimport { buildDataTree } from '../tree'\nimport { isFn } from '../checkers'\nimport {\n  bindTargetKeyWithCurrentReaction,\n  runReactionsFromTargetKey,\n  bindComputedReactions,\n  hasRunningReaction,\n  isUntracking,\n  batchStart,\n  batchEnd,\n  releaseBindingReactions,\n} from '../reaction'\n\ninterface IValue<T = any> {\n  value?: T\n}\nexport interface IComputed {\n  <T>(compute: () => T): IValue<T>\n  <T>(compute: { get?: () => T; set?: (value: T) => void }): IValue<T>\n}\n\nconst getDescriptor = Object.getOwnPropertyDescriptor\n\nconst getProto = Object.getPrototypeOf\n\nconst ClassDescriptorSymbol = Symbol('ClassDescriptorSymbol')\n\nfunction getPropertyDescriptor(obj: any, key: PropertyKey) {\n  if (!obj) return\n  return getDescriptor(obj, key) || getPropertyDescriptor(getProto(obj), key)\n}\n\nfunction getPropertyDescriptorCache(obj: any, key: PropertyKey) {\n  const constructor = obj.constructor\n  if (constructor === Object || constructor === Array)\n    return getPropertyDescriptor(obj, key)\n  const cache = constructor[ClassDescriptorSymbol] || {}\n  const descriptor = cache[key]\n  if (descriptor) return descriptor\n  const newDesc = getPropertyDescriptor(obj, key)\n  constructor[ClassDescriptorSymbol] = cache\n  cache[key] = newDesc\n  return newDesc\n}\n\nfunction getPrototypeDescriptor(\n  target: any,\n  key: PropertyKey,\n  value: any\n): PropertyDescriptor {\n  if (!target) {\n    if (value) {\n      if (isFn(value)) {\n        return { get: value }\n      } else {\n        return value\n      }\n    }\n    return {}\n  }\n  const descriptor = getPropertyDescriptorCache(target, key)\n  if (descriptor) {\n    return descriptor\n  }\n  return {}\n}\n\nexport const computed: IComputed = createAnnotation(\n  ({ target, key, value }) => {\n    const store: IValue = {}\n\n    const proxy = {}\n\n    const context = target ? target : store\n    const property = target ? key : 'value'\n    const descriptor = getPrototypeDescriptor(target, property, value)\n\n    function compute() {\n      store.value = descriptor.get?.call(context)\n    }\n    function reaction() {\n      if (ReactionStack.indexOf(reaction) === -1) {\n        releaseBindingReactions(reaction)\n        try {\n          ReactionStack.push(reaction)\n          compute()\n        } finally {\n          ReactionStack.pop()\n        }\n      }\n    }\n    reaction._name = 'ComputedReaction'\n    reaction._scheduler = () => {\n      reaction._dirty = true\n      runReactionsFromTargetKey({\n        target: context,\n        key: property,\n        value: store.value,\n        type: 'set',\n      })\n    }\n    reaction._isComputed = true\n    reaction._dirty = true\n    reaction._context = context\n    reaction._property = property\n\n    function get() {\n      if (hasRunningReaction()) {\n        bindComputedReactions(reaction)\n      }\n      if (!isUntracking()) {\n        //如果允许untracked过程中收集依赖，那么永远不会存在绑定，因为_dirty已经设置为false\n        if (reaction._dirty) {\n          reaction()\n          reaction._dirty = false\n        }\n      } else {\n        compute()\n      }\n      bindTargetKeyWithCurrentReaction({\n        target: context,\n        key: property,\n        type: 'get',\n      })\n      return store.value\n    }\n\n    function set(value: any) {\n      try {\n        batchStart()\n        descriptor.set?.call(context, value)\n      } finally {\n        batchEnd()\n      }\n    }\n    if (target) {\n      Object.defineProperty(target, key, {\n        get,\n        set,\n        enumerable: true,\n      })\n      return target\n    } else {\n      Object.defineProperty(proxy, 'value', {\n        set,\n        get,\n      })\n      buildDataTree(target, key, store)\n      proxy[ObModelSymbol] = store\n    }\n    return proxy\n  }\n)\n"
  },
  {
    "path": "packages/reactive/src/annotations/index.ts",
    "content": "export * from './observable'\nexport * from './box'\nexport * from './ref'\nexport * from './shallow'\nexport * from './computed'\n"
  },
  {
    "path": "packages/reactive/src/annotations/observable.ts",
    "content": "import { createAnnotation, createObservable } from '../internals'\nimport {\n  bindTargetKeyWithCurrentReaction,\n  runReactionsFromTargetKey,\n} from '../reaction'\n\nexport interface IObservable {\n  <T>(target: T): T\n}\n\nexport const observable: IObservable = createAnnotation(\n  ({ target, key, value }) => {\n    const store = {\n      value: createObservable(target, key, target ? target[key] : value),\n    }\n\n    function get() {\n      bindTargetKeyWithCurrentReaction({\n        target: target,\n        key: key,\n        type: 'get',\n      })\n      return store.value\n    }\n\n    function set(value: any) {\n      const oldValue = store.value\n      value = createObservable(target, key, value)\n      store.value = value\n      if (oldValue === value) return\n      runReactionsFromTargetKey({\n        target: target,\n        key: key,\n        type: 'set',\n        oldValue,\n        value,\n      })\n    }\n    if (target) {\n      Object.defineProperty(target, key, {\n        set,\n        get,\n        enumerable: true,\n        configurable: false,\n      })\n      return target\n    }\n    return store.value\n  }\n)\n"
  },
  {
    "path": "packages/reactive/src/annotations/ref.ts",
    "content": "import { ObModelSymbol } from '../environment'\nimport { createAnnotation } from '../internals'\nimport { buildDataTree } from '../tree'\nimport {\n  bindTargetKeyWithCurrentReaction,\n  runReactionsFromTargetKey,\n} from '../reaction'\n\nexport interface IRef {\n  <T>(target: T): { value: T }\n}\n\nexport const ref: IRef = createAnnotation(({ target, key, value }) => {\n  const store = {\n    value: target ? target[key] : value,\n  }\n\n  const proxy = {}\n\n  const context = target ? target : store\n  const property = target ? key : 'value'\n\n  function get() {\n    bindTargetKeyWithCurrentReaction({\n      target: context,\n      key: property,\n      type: 'get',\n    })\n    return store.value\n  }\n\n  function set(value: any) {\n    const oldValue = store.value\n    store.value = value\n    if (oldValue !== value) {\n      runReactionsFromTargetKey({\n        target: context,\n        key: property,\n        type: 'set',\n        oldValue,\n        value,\n      })\n    }\n  }\n  if (target) {\n    Object.defineProperty(target, key, {\n      get,\n      set,\n      enumerable: true,\n    })\n    return target\n  } else {\n    Object.defineProperty(proxy, 'value', {\n      set,\n      get,\n    })\n    buildDataTree(target, key, store)\n    proxy[ObModelSymbol] = store\n  }\n  return proxy\n})\n"
  },
  {
    "path": "packages/reactive/src/annotations/shallow.ts",
    "content": "import { createAnnotation, createObservable } from '../internals'\nimport {\n  bindTargetKeyWithCurrentReaction,\n  runReactionsFromTargetKey,\n} from '../reaction'\nimport { IObservable } from './observable'\n\nexport const shallow: IObservable = createAnnotation(\n  ({ target, key, value }) => {\n    const store = {\n      value: createObservable(target, key, target ? target[key] : value, true),\n    }\n\n    function get() {\n      bindTargetKeyWithCurrentReaction({\n        target: target,\n        key: key,\n        type: 'get',\n      })\n      return store.value\n    }\n\n    function set(value: any) {\n      const oldValue = store.value\n      value = createObservable(target, key, value, true)\n      store.value = value\n      if (oldValue === value) return\n      runReactionsFromTargetKey({\n        target: target,\n        key: key,\n        type: 'set',\n        oldValue,\n        value,\n      })\n    }\n    if (target) {\n      Object.defineProperty(target, key, {\n        set,\n        get,\n        enumerable: true,\n        configurable: false,\n      })\n      return target\n    }\n    return store.value\n  }\n)\n"
  },
  {
    "path": "packages/reactive/src/array.ts",
    "content": "export const toArray = (value: any) => {\n  return Array.isArray(value)\n    ? value\n    : value !== undefined && value !== null\n    ? [value]\n    : []\n}\n\nexport class ArraySet<T> {\n  value: T[]\n  forEachIndex = 0\n  constructor(value: T[] = []) {\n    this.value = value\n  }\n\n  add(item: T) {\n    if (!this.has(item)) {\n      this.value.push(item)\n    }\n  }\n\n  has(item: T) {\n    return this.value.indexOf(item) > -1\n  }\n\n  delete(item: T) {\n    const len = this.value.length\n    if (len === 0) return\n    if (len === 1 && this.value[0] === item) {\n      this.value = []\n      return\n    }\n    const findIndex = this.value.indexOf(item)\n    if (findIndex > -1) {\n      this.value.splice(findIndex, 1)\n      if (findIndex <= this.forEachIndex) {\n        this.forEachIndex -= 1\n      }\n    }\n  }\n\n  forEach(callback: (value: T) => void) {\n    if (this.value.length === 0) return\n    this.forEachIndex = 0\n    for (; this.forEachIndex < this.value.length; this.forEachIndex++) {\n      callback(this.value[this.forEachIndex])\n    }\n  }\n\n  batchDelete(callback: (value: T) => void) {\n    if (this.value.length === 0) return\n    this.forEachIndex = 0\n    for (; this.forEachIndex < this.value.length; this.forEachIndex++) {\n      const value = this.value[this.forEachIndex]\n      this.value.splice(this.forEachIndex, 1)\n      this.forEachIndex--\n      callback(value)\n    }\n  }\n\n  clear() {\n    this.value.length = 0\n  }\n}\n"
  },
  {
    "path": "packages/reactive/src/autorun.ts",
    "content": "import {\n  batchEnd,\n  batchStart,\n  disposeBindingReactions,\n  releaseBindingReactions,\n  disposeEffects,\n  hasDepsChange,\n} from './reaction'\nimport { isFn } from './checkers'\nimport { ReactionStack } from './environment'\nimport { Reaction, IReactionOptions, Dispose } from './types'\nimport { toArray } from './array'\n\ninterface IValue {\n  currentValue?: any\n  oldValue?: any\n}\n\nexport const autorun = (tracker: Reaction, name = 'AutoRun') => {\n  const reaction: Reaction = () => {\n    if (!isFn(tracker)) return\n    if (reaction._boundary > 0) return\n    if (ReactionStack.indexOf(reaction) === -1) {\n      releaseBindingReactions(reaction)\n      try {\n        batchStart()\n        ReactionStack.push(reaction)\n        tracker()\n      } finally {\n        ReactionStack.pop()\n        reaction._boundary++\n        batchEnd()\n        reaction._boundary = 0\n        reaction._memos.cursor = 0\n        reaction._effects.cursor = 0\n      }\n    }\n  }\n  const cleanRefs = () => {\n    reaction._memos = {\n      queue: [],\n      cursor: 0,\n    }\n    reaction._effects = {\n      queue: [],\n      cursor: 0,\n    }\n  }\n  reaction._boundary = 0\n  reaction._name = name\n  cleanRefs()\n  reaction()\n  return () => {\n    disposeBindingReactions(reaction)\n    disposeEffects(reaction)\n    cleanRefs()\n  }\n}\n\nautorun.memo = <T>(callback: () => T, dependencies?: any[]): T => {\n  if (!isFn(callback)) return\n  const current = ReactionStack[ReactionStack.length - 1]\n  if (!current || !current._memos)\n    throw new Error('autorun.memo must used in autorun function body.')\n  const deps = toArray(dependencies || [])\n  const id = current._memos.cursor++\n  const old = current._memos.queue[id]\n  if (!old || hasDepsChange(deps, old.deps)) {\n    const value = callback()\n    current._memos.queue[id] = {\n      value,\n      deps,\n    }\n    return value\n  }\n  return old.value\n}\n\nautorun.effect = (callback: () => void | Dispose, dependencies?: any[]) => {\n  if (!isFn(callback)) return\n  const current = ReactionStack[ReactionStack.length - 1]\n  if (!current || !current._effects)\n    throw new Error('autorun.effect must used in autorun function body.')\n  const effects = current._effects\n  const deps = toArray(dependencies || [{}])\n  const id = effects.cursor++\n  const old = effects.queue[id]\n  if (!old || hasDepsChange(deps, old.deps)) {\n    Promise.resolve(0).then(() => {\n      if (current._disposed) return\n      const dispose = callback()\n      if (isFn(dispose)) {\n        effects.queue[id].dispose = dispose\n      }\n    })\n    effects.queue[id] = {\n      deps,\n    }\n  }\n}\n\nexport const reaction = <T>(\n  tracker: () => T,\n  subscriber?: (value: T, oldValue: T) => void,\n  options?: IReactionOptions<T>\n) => {\n  const realOptions = {\n    name: 'Reaction',\n    ...options,\n  }\n  const value: IValue = {}\n  const dirtyCheck = () => {\n    if (isFn(realOptions.equals))\n      return !realOptions.equals(value.oldValue, value.currentValue)\n    return value.oldValue !== value.currentValue\n  }\n\n  const fireAction = () => {\n    try {\n      //如果untrack的话，会导致用户如果在scheduler里同步调用setState影响下次React渲染的依赖收集\n      batchStart()\n      if (isFn(subscriber)) subscriber(value.currentValue, value.oldValue)\n    } finally {\n      batchEnd()\n    }\n  }\n\n  const reaction: Reaction = () => {\n    if (ReactionStack.indexOf(reaction) === -1) {\n      releaseBindingReactions(reaction)\n      try {\n        ReactionStack.push(reaction)\n        value.currentValue = tracker()\n      } finally {\n        ReactionStack.pop()\n      }\n    }\n  }\n  reaction._scheduler = (looping) => {\n    looping()\n    if (dirtyCheck()) fireAction()\n    value.oldValue = value.currentValue\n  }\n  reaction._name = realOptions.name\n  reaction()\n  value.oldValue = value.currentValue\n  if (realOptions.fireImmediately) {\n    fireAction()\n  }\n  return () => {\n    disposeBindingReactions(reaction)\n  }\n}\n"
  },
  {
    "path": "packages/reactive/src/batch.ts",
    "content": "import {\n  batchStart,\n  batchEnd,\n  batchScopeStart,\n  batchScopeEnd,\n} from './reaction'\nimport { BatchEndpoints, BatchCount } from './environment'\nimport { createBoundaryAnnotation } from './internals'\nimport { IBatch } from './types'\nimport { isFn } from './checkers'\n\nexport const batch: IBatch = createBoundaryAnnotation(batchStart, batchEnd)\nbatch.scope = createBoundaryAnnotation(batchScopeStart, batchScopeEnd)\nbatch.endpoint = (callback?: () => void) => {\n  if (!isFn(callback)) return\n  if (BatchCount.value === 0) {\n    callback()\n  } else {\n    BatchEndpoints.add(callback)\n  }\n}\n"
  },
  {
    "path": "packages/reactive/src/checkers.ts",
    "content": "const toString = Object.prototype.toString\nexport const isMap = (val: any): val is Map<any, any> =>\n  val && val instanceof Map\nexport const isSet = (val: any): val is Set<any> => val && val instanceof Set\nexport const isWeakMap = (val: any): val is WeakMap<any, any> =>\n  val && val instanceof WeakMap\nexport const isWeakSet = (val: any): val is WeakSet<any> =>\n  val && val instanceof WeakSet\nexport const isFn = (val: any): val is Function => typeof val === 'function'\nexport const isArr = Array.isArray\nexport const isPlainObj = (val: any): val is object =>\n  toString.call(val) === '[object Object]'\nexport const isValid = (val: any) => val !== null && val !== undefined\nexport const isCollectionType = (target: any) => {\n  return (\n    isMap(target) || isWeakMap(target) || isSet(target) || isWeakSet(target)\n  )\n}\nexport const isNormalType = (target: any) => {\n  return isPlainObj(target) || isArr(target)\n}\n"
  },
  {
    "path": "packages/reactive/src/environment.ts",
    "content": "import { ObservableListener, Reaction, ReactionsMap } from './types'\nimport { ArraySet } from './array'\nimport { DataNode } from './tree'\n\nexport const ProxyRaw = new WeakMap()\nexport const RawProxy = new WeakMap()\nexport const RawShallowProxy = new WeakMap()\nexport const RawNode = new WeakMap<object, DataNode>()\nexport const RawReactionsMap = new WeakMap<object, ReactionsMap>()\n\nexport const ReactionStack: Reaction[] = []\nexport const BatchCount = { value: 0 }\nexport const UntrackCount = { value: 0 }\nexport const BatchScope = { value: false }\nexport const DependencyCollected = { value: false }\nexport const PendingReactions = new ArraySet<Reaction>()\nexport const PendingScopeReactions = new ArraySet<Reaction>()\nexport const BatchEndpoints = new ArraySet<() => void>()\nexport const ObserverListeners = new ArraySet<ObservableListener>()\nexport const MakeObModelSymbol = Symbol('MakeObModelSymbol')\nexport const ObModelSymbol = Symbol('ObModelSymbol')\nexport const ObModelNodeSymbol = Symbol('ObModelNodeSymbol')\n"
  },
  {
    "path": "packages/reactive/src/externals.ts",
    "content": "import {\n  isValid,\n  isFn,\n  isMap,\n  isWeakMap,\n  isSet,\n  isWeakSet,\n  isPlainObj,\n  isArr,\n} from './checkers'\nimport {\n  ProxyRaw,\n  MakeObModelSymbol,\n  DependencyCollected,\n  ObModelSymbol,\n} from './environment'\nimport { getDataNode } from './tree'\nimport { Annotation } from './types'\n\nconst RAW_TYPE = Symbol('RAW_TYPE')\nconst OBSERVABLE_TYPE = Symbol('OBSERVABLE_TYPE')\nconst hasOwnProperty = Object.prototype.hasOwnProperty\n\nexport const isObservable = (target: any) => {\n  return ProxyRaw.has(target) || !!target?.[ObModelSymbol]\n}\n\nexport const isAnnotation = (target: any): target is Annotation => {\n  return target && !!target[MakeObModelSymbol]\n}\n\nexport const isSupportObservable = (target: any) => {\n  if (!isValid(target)) return false\n  if (isArr(target)) return true\n  if (isPlainObj(target)) {\n    if (target[RAW_TYPE]) {\n      return false\n    }\n    if (target[OBSERVABLE_TYPE]) {\n      return true\n    }\n    if ('$$typeof' in target && '_owner' in target) {\n      return false\n    }\n    if (target['_isAMomentObject']) {\n      return false\n    }\n    if (target['_isJSONSchemaObject']) {\n      return false\n    }\n    if (isFn(target['toJS'])) {\n      return false\n    }\n    if (isFn(target['toJSON'])) {\n      return false\n    }\n    return true\n  }\n  if (isMap(target) || isWeakMap(target) || isSet(target) || isWeakSet(target))\n    return true\n  return false\n}\n\nexport const markRaw = <T>(target: T): T => {\n  if (!target) return\n  if (isFn(target)) {\n    target.prototype[RAW_TYPE] = true\n  } else {\n    target[RAW_TYPE] = true\n  }\n  return target\n}\n\nexport const markObservable = <T>(target: T): T => {\n  if (!target) return\n  if (isFn(target)) {\n    target.prototype[OBSERVABLE_TYPE] = true\n  } else {\n    target[OBSERVABLE_TYPE] = true\n  }\n  return target\n}\n\nexport const raw = <T>(target: T): T => {\n  if (target?.[ObModelSymbol]) return target[ObModelSymbol]\n  return ProxyRaw.get(target as any) || target\n}\n\nexport const toJS = <T>(values: T): T => {\n  const visited = new WeakSet<any>()\n  const _toJS: typeof toJS = (values: any) => {\n    if (visited.has(values)) {\n      return values\n    }\n    if (values && values[RAW_TYPE]) return values\n    if (isArr(values)) {\n      if (isObservable(values)) {\n        visited.add(values)\n        const res: any = []\n        values.forEach((item: any) => {\n          res.push(_toJS(item))\n        })\n        visited.delete(values)\n        return res\n      }\n    } else if (isPlainObj(values)) {\n      if (isObservable(values)) {\n        visited.add(values)\n        const res: any = {}\n        for (const key in values) {\n          if (hasOwnProperty.call(values, key)) {\n            res[key] = _toJS(values[key])\n          }\n        }\n        visited.delete(values)\n        return res\n      }\n    }\n    return values\n  }\n\n  return _toJS(values)\n}\n\nexport const contains = (target: any, property: any) => {\n  const targetRaw = raw(target)\n  const propertyRaw = raw(property)\n  if (targetRaw === propertyRaw) return true\n  const targetNode = getDataNode(targetRaw)\n  const propertyNode = getDataNode(propertyRaw)\n  if (!targetNode) return false\n  if (!propertyNode) return false\n  return targetNode.contains(propertyNode)\n}\n\nexport const hasCollected = (callback?: () => void) => {\n  DependencyCollected.value = false\n  callback?.()\n  return DependencyCollected.value\n}\n"
  },
  {
    "path": "packages/reactive/src/global.d.ts",
    "content": "import * as Types from './types'\n\ndeclare global {\n  namespace Formily.Reactive {\n    export { Types }\n  }\n}\n"
  },
  {
    "path": "packages/reactive/src/handlers.ts",
    "content": "import {\n  bindTargetKeyWithCurrentReaction,\n  runReactionsFromTargetKey,\n} from './reaction'\nimport { ProxyRaw, RawProxy } from './environment'\nimport { isObservable, isSupportObservable } from './externals'\nimport { createObservable } from './internals'\n\nconst wellKnownSymbols = new Set(\n  Object.getOwnPropertyNames(Symbol).reduce((buf: Symbol[], key) => {\n    if (key === 'arguments' || key === 'caller') return buf\n    const value = Symbol[key]\n    if (typeof value === 'symbol') return buf.concat(value)\n    return buf\n  }, [])\n)\n\nconst hasOwnProperty = Object.prototype.hasOwnProperty\n\nfunction findObservable(target: any, key: PropertyKey, value: any) {\n  const observableObj = RawProxy.get(value)\n  if (observableObj) {\n    return observableObj\n  }\n  if (!isObservable(value) && isSupportObservable(value)) {\n    return createObservable(target, key, value)\n  }\n  return value\n}\n\nfunction patchIterator(\n  target: any,\n  key: PropertyKey,\n  iterator: IterableIterator<any>,\n  isEntries: boolean\n) {\n  const originalNext = iterator.next\n  iterator.next = () => {\n    let { done, value } = originalNext.call(iterator)\n    if (!done) {\n      if (isEntries) {\n        value[1] = findObservable(target, key, value[1])\n      } else {\n        value = findObservable(target, key, value)\n      }\n    }\n    return { done, value }\n  }\n  return iterator\n}\n\nconst instrumentations = {\n  has(key: PropertyKey) {\n    const target = ProxyRaw.get(this)\n    const proto = Reflect.getPrototypeOf(this) as any\n    bindTargetKeyWithCurrentReaction({ target, key, type: 'has' })\n    return proto.has.apply(target, arguments)\n  },\n  get(key: PropertyKey) {\n    const target = ProxyRaw.get(this)\n    const proto = Reflect.getPrototypeOf(this) as any\n    bindTargetKeyWithCurrentReaction({ target, key, type: 'get' })\n    return findObservable(target, key, proto.get.apply(target, arguments))\n  },\n  add(key: PropertyKey) {\n    const target = ProxyRaw.get(this)\n    const proto = Reflect.getPrototypeOf(this) as any\n    const hadKey = proto.has.call(target, key)\n    // forward the operation before queueing reactions\n    const result = proto.add.apply(target, arguments)\n    if (!hadKey) {\n      runReactionsFromTargetKey({ target, key, value: key, type: 'add' })\n    }\n    return result\n  },\n  set(key: PropertyKey, value: any) {\n    const target = ProxyRaw.get(this)\n    const proto = Reflect.getPrototypeOf(this) as any\n    const hadKey = proto.has.call(target, key)\n    const oldValue = proto.get.call(target, key)\n    // forward the operation before queueing reactions\n    const result = proto.set.apply(target, arguments)\n    if (!hadKey) {\n      runReactionsFromTargetKey({ target, key, value, type: 'add' })\n    } else if (value !== oldValue) {\n      runReactionsFromTargetKey({ target, key, value, oldValue, type: 'set' })\n    }\n    return result\n  },\n  delete(key: PropertyKey) {\n    const target = ProxyRaw.get(this)\n    const proto = Reflect.getPrototypeOf(this) as any\n    const hadKey = proto.has.call(target, key)\n    const oldValue = proto.get ? proto.get.call(target, key) : undefined\n    // forward the operation before queueing reactions\n    const result = proto.delete.apply(target, arguments)\n    if (hadKey) {\n      runReactionsFromTargetKey({ target, key, oldValue, type: 'delete' })\n    }\n    return result\n  },\n  clear() {\n    const target = ProxyRaw.get(this)\n    const proto = Reflect.getPrototypeOf(this) as any\n    const hadItems = target.size !== 0\n    const oldTarget = target instanceof Map ? new Map(target) : new Set(target)\n    // forward the operation before queueing reactions\n    const result = proto.clear.apply(target, arguments)\n    if (hadItems) {\n      runReactionsFromTargetKey({ target, oldTarget, type: 'clear' })\n    }\n    return result\n  },\n  forEach(cb: any, ...args: any[]) {\n    const target = ProxyRaw.get(this)\n    const proto = Reflect.getPrototypeOf(this) as any\n    bindTargetKeyWithCurrentReaction({ target, type: 'iterate' })\n    // swap out the raw values with their observable pairs\n    // before passing them to the callback\n    const wrappedCb = (value: any, key: PropertyKey, ...args: any) =>\n      cb(findObservable(target, key, value), key, ...args)\n    return proto.forEach.call(target, wrappedCb, ...args)\n  },\n  keys() {\n    const target = ProxyRaw.get(this)\n    const proto = Reflect.getPrototypeOf(this) as any\n    bindTargetKeyWithCurrentReaction({ target, type: 'iterate' })\n    return proto.keys.apply(target, arguments)\n  },\n  values() {\n    const target = ProxyRaw.get(this)\n    const proto = Reflect.getPrototypeOf(this) as any\n    bindTargetKeyWithCurrentReaction({ target, type: 'iterate' })\n    const iterator = proto.values.apply(target, arguments)\n    return patchIterator(target, '', iterator, false)\n  },\n  entries() {\n    const target = ProxyRaw.get(this)\n    const proto = Reflect.getPrototypeOf(this) as any\n    bindTargetKeyWithCurrentReaction({ target, type: 'iterate' })\n    const iterator = proto.entries.apply(target, arguments)\n    return patchIterator(target, '', iterator, true)\n  },\n  [Symbol.iterator]() {\n    const target = ProxyRaw.get(this)\n    const proto = Reflect.getPrototypeOf(this)\n    bindTargetKeyWithCurrentReaction({ target, type: 'iterate' })\n    const iterator = proto[Symbol.iterator].apply(target, arguments)\n    return patchIterator(target, '', iterator, target instanceof Map)\n  },\n  get size() {\n    const target = ProxyRaw.get(this)\n    const proto = Reflect.getPrototypeOf(this)\n    bindTargetKeyWithCurrentReaction({ target, type: 'iterate' })\n    return Reflect.get(proto, 'size', target)\n  },\n}\n\nexport const collectionHandlers = {\n  get(target: any, key: PropertyKey, receiver: any) {\n    // instrument methods and property accessors to be reactive\n    target = hasOwnProperty.call(instrumentations, key)\n      ? instrumentations\n      : target\n    return Reflect.get(target, key, receiver)\n  },\n}\n\nexport const baseHandlers: ProxyHandler<any> = {\n  get(target, key, receiver) {\n    if (!key) return\n    const result = target[key] // use Reflect.get is too slow\n    if (typeof key === 'symbol' && wellKnownSymbols.has(key)) {\n      return result\n    }\n    bindTargetKeyWithCurrentReaction({ target, key, receiver, type: 'get' })\n    const observableResult = RawProxy.get(result)\n    if (observableResult) {\n      return observableResult\n    }\n    if (!isObservable(result) && isSupportObservable(result)) {\n      const descriptor = Reflect.getOwnPropertyDescriptor(target, key)\n      if (\n        !descriptor ||\n        !(descriptor.writable === false && descriptor.configurable === false)\n      ) {\n        return createObservable(target, key, result)\n      }\n    }\n    return result\n  },\n  has(target, key) {\n    const result = Reflect.has(target, key)\n    bindTargetKeyWithCurrentReaction({ target, key, type: 'has' })\n    return result\n  },\n  ownKeys(target) {\n    const keys = Reflect.ownKeys(target)\n    bindTargetKeyWithCurrentReaction({ target, type: 'iterate' })\n    return keys\n  },\n  set(target, key, value, receiver) {\n    // vue2中有对数组原型重写，因此需去除此处proxy\n    if (key === '__proto__') {\n      target[key] = value\n      return true\n    }\n    const hadKey = hasOwnProperty.call(target, key)\n    const newValue = createObservable(target, key, value)\n    const oldValue = target[key]\n    target[key] = newValue // use Reflect.set is too slow\n    if (!hadKey) {\n      runReactionsFromTargetKey({\n        target,\n        key,\n        value: newValue,\n        oldValue,\n        receiver,\n        type: 'add',\n      })\n    } else if (value !== oldValue) {\n      runReactionsFromTargetKey({\n        target,\n        key,\n        value: newValue,\n        oldValue,\n        receiver,\n        type: 'set',\n      })\n    }\n    return true\n  },\n  deleteProperty(target, key) {\n    const oldValue = target[key]\n    delete target[key]\n    runReactionsFromTargetKey({\n      target,\n      key,\n      oldValue,\n      type: 'delete',\n    })\n    return true\n  },\n}\n"
  },
  {
    "path": "packages/reactive/src/index.ts",
    "content": "export * from './batch'\nexport * from './action'\nexport * from './untracked'\nexport * from './observable'\nexport * from './model'\nexport * from './autorun'\nexport * from './tracker'\nexport * from './observe'\nexport * from './externals'\nexport * from './types'\n"
  },
  {
    "path": "packages/reactive/src/internals.ts",
    "content": "import { isFn, isCollectionType, isNormalType } from './checkers'\nimport {\n  RawProxy,\n  ProxyRaw,\n  MakeObModelSymbol,\n  RawShallowProxy,\n} from './environment'\nimport { baseHandlers, collectionHandlers } from './handlers'\nimport { buildDataTree, getDataNode } from './tree'\nimport { isSupportObservable } from './externals'\nimport { PropertyKey, IVisitor, BoundaryFunction } from './types'\n\nconst createNormalProxy = (target: any, shallow?: boolean) => {\n  const proxy = new Proxy(target, baseHandlers)\n  ProxyRaw.set(proxy, target)\n  if (shallow) {\n    RawShallowProxy.set(target, proxy)\n  } else {\n    RawProxy.set(target, proxy)\n  }\n  return proxy\n}\n\nconst createCollectionProxy = (target: any, shallow?: boolean) => {\n  const proxy = new Proxy(target, collectionHandlers)\n  ProxyRaw.set(proxy, target)\n  if (shallow) {\n    RawShallowProxy.set(target, proxy)\n  } else {\n    RawProxy.set(target, proxy)\n  }\n  return proxy\n}\n\nconst createShallowProxy = (target: any) => {\n  if (isNormalType(target)) return createNormalProxy(target, true)\n  if (isCollectionType(target)) return createCollectionProxy(target, true)\n  // never reach\n  return target\n}\n\nexport const createObservable = (\n  target: any,\n  key?: PropertyKey,\n  value?: any,\n  shallow?: boolean\n) => {\n  if (typeof value !== 'object') return value\n  const raw = ProxyRaw.get(value)\n  if (!!raw) {\n    const node = getDataNode(raw)\n    if (!node.target) node.target = target\n    node.key = key\n    return value\n  }\n\n  if (!isSupportObservable(value)) return value\n\n  if (target) {\n    const parentRaw = ProxyRaw.get(target) || target\n    const isShallowParent = RawShallowProxy.get(parentRaw)\n    if (isShallowParent) return value\n  }\n\n  buildDataTree(target, key, value)\n  if (shallow) return createShallowProxy(value)\n  if (isNormalType(value)) return createNormalProxy(value)\n  if (isCollectionType(value)) return createCollectionProxy(value)\n  // never reach\n  return value\n}\n\nexport const createAnnotation = <T extends (visitor: IVisitor) => any>(\n  maker: T\n) => {\n  const annotation = (target: any): ReturnType<T> => {\n    return maker({ value: target })\n  }\n  if (isFn(maker)) {\n    annotation[MakeObModelSymbol] = maker\n  }\n  return annotation\n}\n\nexport const getObservableMaker = (target: any) => {\n  if (target[MakeObModelSymbol]) {\n    if (!target[MakeObModelSymbol][MakeObModelSymbol]) {\n      return target[MakeObModelSymbol]\n    }\n    return getObservableMaker(target[MakeObModelSymbol])\n  }\n}\n\nexport const createBoundaryFunction = (\n  start: (...args: any) => void,\n  end: (...args: any) => void\n) => {\n  function boundary<F extends (...args: any) => any>(fn?: F): ReturnType<F> {\n    let results: ReturnType<F>\n    try {\n      start()\n      if (isFn(fn)) {\n        results = fn()\n      }\n    } finally {\n      end()\n    }\n    return results\n  }\n\n  boundary.bound = createBindFunction(boundary)\n  return boundary\n}\n\nexport const createBindFunction = <Boundary extends BoundaryFunction>(\n  boundary: Boundary\n) => {\n  function bind<F extends (...args: any[]) => any>(\n    callback?: F,\n    context?: any\n  ): F {\n    return ((...args: any[]) =>\n      boundary(() => callback.apply(context, args))) as any\n  }\n  return bind\n}\n\nexport const createBoundaryAnnotation = (\n  start: (...args: any) => void,\n  end: (...args: any) => void\n) => {\n  const boundary = createBoundaryFunction(start, end)\n  const annotation = createAnnotation(({ target, key }) => {\n    target[key] = boundary.bound(target[key], target)\n    return target\n  })\n  boundary[MakeObModelSymbol] = annotation\n  boundary.bound[MakeObModelSymbol] = annotation\n  return boundary\n}\n"
  },
  {
    "path": "packages/reactive/src/model.ts",
    "content": "import { isFn } from './checkers'\nimport { buildDataTree } from './tree'\nimport { observable } from './observable'\nimport { getObservableMaker } from './internals'\nimport { isObservable, isAnnotation, isSupportObservable } from './externals'\nimport { Annotations } from './types'\nimport { action } from './action'\nimport { ObModelSymbol } from './environment'\n\nexport function define<Target extends object = any>(\n  target: Target,\n  annotations?: Annotations<Target>\n): Target {\n  if (isObservable(target)) return target\n  if (!isSupportObservable(target)) return target\n  target[ObModelSymbol] = target\n  buildDataTree(undefined, undefined, target)\n  for (const key in annotations) {\n    const annotation = annotations[key]\n    if (isAnnotation(annotation)) {\n      getObservableMaker(annotation)({\n        target,\n        key,\n      })\n    }\n  }\n  return target\n}\n\nexport function model<Target extends object = any>(target: Target): Target {\n  const annotations = Object.keys(target || {}).reduce((buf, key) => {\n    const descriptor = Object.getOwnPropertyDescriptor(target, key)\n    if (descriptor && descriptor.get) {\n      buf[key] = observable.computed\n    } else if (isFn(target[key])) {\n      buf[key] = action\n    } else {\n      buf[key] = observable\n    }\n    return buf\n  }, {})\n  return define(target, annotations)\n}\n"
  },
  {
    "path": "packages/reactive/src/observable.ts",
    "content": "import * as annotations from './annotations'\nimport { MakeObModelSymbol } from './environment'\nimport { createObservable } from './internals'\n\nexport function observable<T extends object>(target: T): T {\n  return createObservable(null, null, target)\n}\n\nobservable.box = annotations.box\nobservable.ref = annotations.ref\nobservable.deep = annotations.observable\nobservable.shallow = annotations.shallow\nobservable.computed = annotations.computed\nobservable[MakeObModelSymbol] = annotations.observable\n"
  },
  {
    "path": "packages/reactive/src/observe.ts",
    "content": "import { IOperation } from './types'\nimport { ObserverListeners } from './environment'\nimport { raw as getRaw } from './externals'\nimport { isFn } from './checkers'\nimport { DataChange, getDataNode } from './tree'\n\nexport const observe = (\n  target: object,\n  observer?: (change: DataChange) => void,\n  deep = true\n) => {\n  const addListener = (target: any) => {\n    const raw = getRaw(target)\n    const node = getDataNode(raw)\n\n    const listener = (operation: IOperation) => {\n      const targetRaw = getRaw(operation.target)\n      const targetNode = getDataNode(targetRaw)\n      if (deep) {\n        if (node.contains(targetNode)) {\n          observer(new DataChange(operation, targetNode))\n          return\n        }\n      }\n      if (\n        node === targetNode ||\n        (node.targetRaw === targetRaw && node.key === operation.key)\n      ) {\n        observer(new DataChange(operation, targetNode))\n      }\n    }\n\n    if (node && isFn(observer)) {\n      ObserverListeners.add(listener)\n    }\n    return () => {\n      ObserverListeners.delete(listener)\n    }\n  }\n  if (target && typeof target !== 'object')\n    throw Error(`Can not observe ${typeof target} type.`)\n  return addListener(target)\n}\n"
  },
  {
    "path": "packages/reactive/src/reaction.ts",
    "content": "import { isFn } from './checkers'\nimport { ArraySet } from './array'\nimport { IOperation, ReactionsMap, Reaction, PropertyKey } from './types'\nimport {\n  ReactionStack,\n  PendingScopeReactions,\n  BatchEndpoints,\n  DependencyCollected,\n  RawReactionsMap,\n  PendingReactions,\n  BatchCount,\n  UntrackCount,\n  BatchScope,\n  ObserverListeners,\n} from './environment'\n\nconst ITERATION_KEY = Symbol('iteration key')\n\nconst addRawReactionsMap = (\n  target: any,\n  key: PropertyKey,\n  reaction: Reaction\n) => {\n  const reactionsMap = RawReactionsMap.get(target)\n  if (reactionsMap) {\n    const reactions = reactionsMap.get(key)\n    if (reactions) {\n      reactions.add(reaction)\n    } else {\n      reactionsMap.set(key, new ArraySet([reaction]))\n    }\n    return reactionsMap\n  } else {\n    const reactionsMap: ReactionsMap = new Map([\n      [key, new ArraySet([reaction])],\n    ])\n    RawReactionsMap.set(target, reactionsMap)\n    return reactionsMap\n  }\n}\n\nconst addReactionsMapToReaction = (\n  reaction: Reaction,\n  reactionsMap: ReactionsMap\n) => {\n  const bindSet = reaction._reactionsSet\n  if (bindSet) {\n    bindSet.add(reactionsMap)\n  } else {\n    reaction._reactionsSet = new ArraySet([reactionsMap])\n  }\n  return bindSet\n}\n\nconst getReactionsFromTargetKey = (target: any, key: PropertyKey) => {\n  const reactionsMap = RawReactionsMap.get(target)\n  const reactions = []\n  if (reactionsMap) {\n    const map = reactionsMap.get(key)\n    if (map) {\n      map.forEach((reaction) => {\n        if (reactions.indexOf(reaction) === -1) {\n          reactions.push(reaction)\n        }\n      })\n    }\n  }\n  return reactions\n}\n\nconst runReactions = (target: any, key: PropertyKey) => {\n  const reactions = getReactionsFromTargetKey(target, key)\n  const prevUntrackCount = UntrackCount.value\n  UntrackCount.value = 0\n  for (let i = 0, len = reactions.length; i < len; i++) {\n    const reaction = reactions[i]\n    if (reaction._isComputed) {\n      reaction._scheduler(reaction)\n    } else if (isScopeBatching()) {\n      PendingScopeReactions.add(reaction)\n    } else if (isBatching()) {\n      PendingReactions.add(reaction)\n    } else {\n      // never reach\n      if (isFn(reaction._scheduler)) {\n        reaction._scheduler(reaction)\n      } else {\n        reaction()\n      }\n    }\n  }\n  UntrackCount.value = prevUntrackCount\n}\n\nconst notifyObservers = (operation: IOperation) => {\n  ObserverListeners.forEach((fn) => fn(operation))\n}\n\nexport const bindTargetKeyWithCurrentReaction = (operation: IOperation) => {\n  let { key, type, target } = operation\n  if (type === 'iterate') {\n    key = ITERATION_KEY\n  }\n  const reactionLen = ReactionStack.length\n  if (reactionLen === 0) return\n  const current = ReactionStack[reactionLen - 1]\n  if (isUntracking()) return\n  if (current) {\n    DependencyCollected.value = true\n    addReactionsMapToReaction(current, addRawReactionsMap(target, key, current))\n  }\n}\n\nexport const bindComputedReactions = (reaction: Reaction) => {\n  if (isFn(reaction)) {\n    const current = ReactionStack[ReactionStack.length - 1]\n    if (current) {\n      const computes = current._computesSet\n      if (computes) {\n        computes.add(reaction)\n      } else {\n        current._computesSet = new ArraySet([reaction])\n      }\n    }\n  }\n}\n\nexport const runReactionsFromTargetKey = (operation: IOperation) => {\n  let { key, type, target, oldTarget } = operation\n  batchStart()\n  notifyObservers(operation)\n  if (type === 'clear') {\n    oldTarget.forEach((_: any, key: PropertyKey) => {\n      runReactions(target, key)\n    })\n  } else {\n    runReactions(target, key)\n  }\n  if (type === 'add' || type === 'delete' || type === 'clear') {\n    const newKey = Array.isArray(target) ? 'length' : ITERATION_KEY\n    runReactions(target, newKey)\n  }\n  batchEnd()\n}\n\nexport const hasRunningReaction = () => {\n  return ReactionStack.length > 0\n}\n\nexport const releaseBindingReactions = (reaction: Reaction) => {\n  reaction._reactionsSet?.forEach((reactionsMap) => {\n    reactionsMap.forEach((reactions) => {\n      reactions.delete(reaction)\n    })\n  })\n  PendingReactions.delete(reaction)\n  PendingScopeReactions.delete(reaction)\n  delete reaction._reactionsSet\n}\n\nexport const suspendComputedReactions = (current: Reaction) => {\n  current._computesSet?.forEach((reaction) => {\n    const reactions = getReactionsFromTargetKey(\n      reaction._context,\n      reaction._property\n    )\n    if (reactions.length === 0) {\n      disposeBindingReactions(reaction)\n      reaction._dirty = true\n    }\n  })\n}\n\nexport const disposeBindingReactions = (reaction: Reaction) => {\n  reaction._disposed = true\n  releaseBindingReactions(reaction)\n  suspendComputedReactions(reaction)\n}\n\nexport const batchStart = () => {\n  BatchCount.value++\n}\n\nexport const batchEnd = () => {\n  BatchCount.value--\n  if (BatchCount.value === 0) {\n    const prevUntrackCount = UntrackCount.value\n    UntrackCount.value = 0\n    executePendingReactions()\n    executeBatchEndpoints()\n    UntrackCount.value = prevUntrackCount\n  }\n}\n\nexport const batchScopeStart = () => {\n  BatchScope.value = true\n}\n\nexport const batchScopeEnd = () => {\n  const prevUntrackCount = UntrackCount.value\n  BatchScope.value = false\n  UntrackCount.value = 0\n  PendingScopeReactions.batchDelete((reaction) => {\n    if (isFn(reaction._scheduler)) {\n      reaction._scheduler(reaction)\n    } else {\n      reaction()\n    }\n  })\n  UntrackCount.value = prevUntrackCount\n}\n\nexport const untrackStart = () => {\n  UntrackCount.value++\n}\n\nexport const untrackEnd = () => {\n  UntrackCount.value--\n}\n\nexport const isBatching = () => BatchCount.value > 0\n\nexport const isScopeBatching = () => BatchScope.value\n\nexport const isUntracking = () => UntrackCount.value > 0\n\nexport const executePendingReactions = () => {\n  PendingReactions.batchDelete((reaction) => {\n    if (isFn(reaction._scheduler)) {\n      reaction._scheduler(reaction)\n    } else {\n      reaction()\n    }\n  })\n}\n\nexport const executeBatchEndpoints = () => {\n  BatchEndpoints.batchDelete((callback) => {\n    callback()\n  })\n}\n\nexport const hasDepsChange = (newDeps: any[], oldDeps: any[]) => {\n  if (newDeps === oldDeps) return false\n  if (newDeps.length !== oldDeps.length) return true\n  if (newDeps.some((value, index) => value !== oldDeps[index])) return true\n  return false\n}\n\nexport const disposeEffects = (reaction: Reaction) => {\n  if (reaction._effects) {\n    try {\n      batchStart()\n      reaction._effects.queue.forEach((item) => {\n        if (!item || !item.dispose) return\n        item.dispose()\n      })\n    } finally {\n      batchEnd()\n    }\n  }\n}\n"
  },
  {
    "path": "packages/reactive/src/tracker.ts",
    "content": "import { ReactionStack } from './environment'\nimport { isFn } from './checkers'\nimport { Reaction } from './types'\nimport {\n  batchEnd,\n  batchStart,\n  disposeBindingReactions,\n  releaseBindingReactions,\n} from './reaction'\n\nexport class Tracker {\n  private results: any\n  constructor(\n    scheduler?: (reaction: Reaction) => void,\n    name = 'TrackerReaction'\n  ) {\n    this.track._scheduler = (callback) => {\n      if (this.track._boundary === 0) this.dispose()\n      if (isFn(callback)) scheduler(callback)\n    }\n    this.track._name = name\n    this.track._boundary = 0\n  }\n\n  track: Reaction = (tracker: Reaction) => {\n    if (!isFn(tracker)) return this.results\n    if (this.track._boundary > 0) return\n    if (ReactionStack.indexOf(this.track) === -1) {\n      releaseBindingReactions(this.track)\n      try {\n        batchStart()\n        ReactionStack.push(this.track)\n        this.results = tracker()\n      } finally {\n        ReactionStack.pop()\n        this.track._boundary++\n        batchEnd()\n        this.track._boundary = 0\n      }\n    }\n    return this.results\n  }\n\n  dispose = () => {\n    disposeBindingReactions(this.track)\n  }\n}\n"
  },
  {
    "path": "packages/reactive/src/tree.ts",
    "content": "import { ObModelSymbol, ObModelNodeSymbol, RawNode } from './environment'\nimport { raw as getRaw } from './externals'\nimport { PropertyKey, IOperation } from './types'\nexport class DataChange {\n  node: DataNode\n  key: PropertyKey\n  object: object\n  type: string\n  value: any\n  oldValue: any\n  constructor(operation: IOperation, node: DataNode) {\n    this.node = node\n    this.key = operation.key\n    this.type = operation.type\n    this.object = operation.target\n    this.value = operation.value\n    this.oldValue = operation.oldValue\n  }\n\n  get path() {\n    return this.node.path.concat(this.key)\n  }\n}\nexport class DataNode {\n  target: any\n\n  key: PropertyKey\n\n  value: any\n\n  constructor(target: any, key: PropertyKey, value: any) {\n    this.target = target\n    this.key = key\n    this.value = value\n  }\n\n  get path() {\n    if (!this.parent) return this.key ? [this.key] : []\n    return this.parent.path.concat(this.key)\n  }\n\n  get targetRaw() {\n    return getRaw(this.target)\n  }\n\n  get parent() {\n    if (!this.target) return\n    return getDataNode(this.targetRaw)\n  }\n\n  isEqual(node: DataNode) {\n    if (this.key) {\n      return node.targetRaw === this.targetRaw && node.key === this.key\n    }\n    return node.value === this.value\n  }\n\n  contains(node: DataNode) {\n    if (node === this) return true\n    let parent = node.parent\n    while (!!parent) {\n      if (this.isEqual(parent)) return true\n      parent = parent.parent\n    }\n    return false\n  }\n}\n\nexport const getDataNode = (raw: any) => {\n  if (raw?.[ObModelNodeSymbol]) {\n    return raw[ObModelNodeSymbol]\n  }\n  return RawNode.get(raw)\n}\n\nexport const setDataNode = (raw: any, node: DataNode) => {\n  if (raw?.[ObModelSymbol]) {\n    raw[ObModelNodeSymbol] = node\n    return\n  }\n  RawNode.set(raw, node)\n}\n\nexport const buildDataTree = (target: any, key: PropertyKey, value: any) => {\n  const raw = getRaw(value)\n  const currentNode = getDataNode(raw)\n  if (currentNode) return currentNode\n  setDataNode(raw, new DataNode(target, key, value))\n}\n"
  },
  {
    "path": "packages/reactive/src/types.ts",
    "content": "import { ArraySet } from './array'\n\nexport * from './tree'\n\nexport type PropertyKey = string | number | symbol\n\nexport type OperationType =\n  | 'add'\n  | 'delete'\n  | 'clear'\n  | 'set'\n  | 'get'\n  | 'iterate'\n  | 'has'\nexport interface IOperation {\n  target?: any\n  oldTarget?: any\n  key?: PropertyKey\n  value?: any\n  oldValue?: any\n  type?: OperationType\n  receiver?: any\n}\n\nexport interface IChange {\n  key?: PropertyKey\n  path?: ObservablePath\n  value?: any\n  oldValue?: any\n  type?: OperationType\n}\n\nexport interface IEffectQueueItem {\n  dispose?: void | Dispose\n  deps?: any[]\n}\n\nexport interface IMemoQueueItem {\n  value?: any\n  deps?: any[]\n}\n\nexport interface IVisitor<Value = any, Target = any> {\n  target?: Target\n  key?: PropertyKey\n  value?: Value\n}\n\nexport type Annotation = (...args: any[]) => any\n\nexport type Annotations<T = any> = {\n  [key in keyof T]?: Annotation\n}\n\nexport type ObservableListener = (operation: IOperation) => void\n\nexport type ObservablePath = Array<string | number>\n\nexport type Dispose = () => void\n\nexport type Effect = () => void | Dispose\n\nexport type Reaction = ((...args: any[]) => any) & {\n  _boundary?: number\n  _name?: string\n  _isComputed?: boolean\n  _dirty?: boolean\n  _context?: any\n  _disposed?: boolean\n  _property?: PropertyKey\n  _computesSet?: ArraySet<Reaction>\n  _reactionsSet?: ArraySet<ReactionsMap>\n  _scheduler?: (reaction: Reaction) => void\n  _memos?: {\n    queue: IMemoQueueItem[]\n    cursor: number\n  }\n  _effects?: {\n    queue: IEffectQueueItem[]\n    cursor: number\n  }\n}\n\nexport type ReactionsMap = Map<PropertyKey, ArraySet<Reaction>>\n\nexport interface IReactionOptions<T> {\n  name?: string\n  equals?: (oldValue: T, newValue: T) => boolean\n  fireImmediately?: boolean\n}\n\nexport type BindFunction<F = (...args: any[]) => any> = (\n  callback?: F,\n  context?: any\n) => F\n\nexport type BoundaryFunction = <F extends (...args: any) => any>(\n  fn?: F\n) => ReturnType<F>\n\nexport interface IBoundable {\n  bound?: <T extends (...args: any[]) => any>(callback: T, context?: any) => T //高阶绑定\n}\nexport interface IAction extends IBoundable {\n  <T>(callback?: () => T): T //原地action\n  scope?: (<T>(callback?: () => T) => T) & IBoundable //原地局部action\n}\n\nexport interface IBatch extends IAction {\n  endpoint?: (callback?: () => void) => void\n}\n"
  },
  {
    "path": "packages/reactive/src/untracked.ts",
    "content": "import { createBoundaryFunction } from './internals'\nimport { untrackStart, untrackEnd } from './reaction'\n\nexport const untracked = createBoundaryFunction(untrackStart, untrackEnd)\n"
  },
  {
    "path": "packages/reactive/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*\", \"devtools/*\"]\n    },\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/reactive/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"include\": [\"./src/**/*.ts\", \"./src/**/*.tsx\"],\n  \"exclude\": [\"./src/__tests__/*\", \"./esm/*\", \"./lib/*\"]\n}\n"
  },
  {
    "path": "packages/reactive-react/.npmignore",
    "content": "node_modules\n*.log\nbuild\ndocs\ndoc-site\n__tests__\n.eslintrc\njest.config.js\ntsconfig.json\n.umi\nsrc"
  },
  {
    "path": "packages/reactive-react/.umirc.js",
    "content": "import { resolve } from 'path'\nexport default {\n  mode: 'doc',\n  logo: 'https://img.alicdn.com/imgextra/i2/O1CN01Kq3OHU1fph6LGqjIz_!!6000000004056-55-tps-1141-150.svg',\n  title: 'Formily',\n  hash: true,\n  favicon:\n    '//img.alicdn.com/imgextra/i3/O1CN01XtT3Tv1Wd1b5hNVKy_!!6000000002810-55-tps-360-360.svg',\n  outputPath: './doc-site',\n  headScripts: [\n    `\n    function loadAd(){\n      var header = document.querySelector('.__dumi-default-layout-content .markdown h1')\n      if(header && !header.querySelector('#_carbonads_js')){\n        var script = document.createElement('script')\n        script.src = '//cdn.carbonads.com/carbon.js?serve=CEAICK3M&placement=formilyjsorg'\n        script.id = '_carbonads_js'\n        script.classList.add('head-ad')\n        header.appendChild(script)\n      }\n    }\n    var request = null\n    var observer = new MutationObserver(function(){\n      cancelIdleCallback(request)\n      request = requestIdleCallback(loadAd)\n    })\n    document.addEventListener('DOMContentLoaded',function(){\n      loadAd()\n      observer.observe(\n        document.body,\n        {\n          childList:true,\n          subtree:true\n        }\n      )\n    })\n    `,\n  ],\n  styles: [\n    `.__dumi-default-navbar-logo{\n      background-size: 140px!important;\n      background-position: center left!important;\n      background-repeat: no-repeat!important;\n      padding-left: 150px!important;/*可根据title的宽度调整*/\n      font-size: 22px!important;\n      color: #000!important;\n      font-weight: lighter!important;\n    }\n    .__dumi-default-navbar{\n      padding: 0 28px !important;\n    }\n    .__dumi-default-layout-hero{\n      background-image: url(//img.alicdn.com/imgextra/i4/O1CN01ZcvS4e26XMsdsCkf9_!!6000000007671-2-tps-6001-4001.png);\n      background-size: cover;\n      background-repeat: no-repeat;\n      padding: 120px 0 !important;\n    }\n    .__dumi-default-layout-hero h1{\n      color:#45124e !important;\n      font-size:80px !important;\n      padding-bottom: 30px !important;\n    }\n    .__dumi-default-dark-switch {\n      display:none\n    }\n    nav a{\n      text-decoration: none !important;\n    }\n    #carbonads * {\n      margin: initial;\n      padding: initial;\n    }\n    #carbonads {\n      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,\n        Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', Helvetica, Arial,\n        sans-serif;\n    }\n    #carbonads {\n      display: flex;\n      max-width: 330px;\n      background-color: hsl(0, 0%, 98%);\n      box-shadow: 0 1px 4px 1px hsla(0, 0%, 0%, 0.1);\n      z-index: 100;\n      float:right;\n    }\n    #carbonads a {\n      color: inherit;\n      text-decoration: none;\n    }\n    #carbonads a:hover {\n      color: inherit;\n    }\n    #carbonads span {\n      position: relative;\n      display: block;\n      overflow: hidden;\n    }\n    #carbonads .carbon-wrap {\n      display: flex;\n    }\n    #carbonads .carbon-img {\n      display: block;\n      margin: 0;\n      line-height: 1;\n    }\n    #carbonads .carbon-img img {\n      display: block;\n    }\n    #carbonads .carbon-text {\n      font-size: 13px;\n      padding: 10px;\n      margin-bottom: 16px;\n      line-height: 1.5;\n      text-align: left;\n    }\n    #carbonads .carbon-poweredby {\n      display: block;\n      padding: 6px 8px;\n      background: #f1f1f2;\n      text-align: center;\n      text-transform: uppercase;\n      letter-spacing: 0.5px;\n      font-weight: 600;\n      font-size: 8px;\n      line-height: 1;\n      border-top-left-radius: 3px;\n      position: absolute;\n      bottom: 0;\n      right: 0;\n    }\n    `,\n  ],\n}\n"
  },
  {
    "path": "packages/reactive-react/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-present, Alibaba Group Holding Limited. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/reactive-react/README.md",
    "content": "# @formily/reactive-react\n\n## QuikStart\n\n```tsx\nimport React from 'react'\nimport { observable } from '@formily/reactive'\nimport { observer } from '@formily/reactive-react'\n\nconst obs = observable({\n  count: 0,\n})\n\nexport default observer(() => {\n  return (\n    <div>\n      {obs.count}\n      <button\n        onClick={() => {\n          obs.count++\n        }}\n      >\n        Click\n      </button>\n    </div>\n  )\n})\n```\n"
  },
  {
    "path": "packages/reactive-react/package.json",
    "content": "{\n  \"name\": \"@formily/reactive-react\",\n  \"version\": \"2.3.7\",\n  \"license\": \"MIT\",\n  \"main\": \"lib\",\n  \"module\": \"esm\",\n  \"umd:main\": \"dist/formily.reactive-react.umd.production.js\",\n  \"unpkg\": \"dist/formily.reactive-react.umd.production.js\",\n  \"jsdelivr\": \"dist/formily.reactive-react.umd.production.js\",\n  \"jsnext:main\": \"esm\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/alibaba/formily.git\"\n  },\n  \"types\": \"esm/index.d.ts\",\n  \"bugs\": {\n    \"url\": \"https://github.com/alibaba/formily/issues\"\n  },\n  \"homepage\": \"https://github.com/alibaba/formily#readme\",\n  \"engines\": {\n    \"npm\": \">=3.0.0\"\n  },\n  \"scripts\": {\n    \"start\": \"dumi dev\",\n    \"build\": \"rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm && npm run build:umd\",\n    \"build:cjs\": \"tsc --project tsconfig.build.json\",\n    \"build:esm\": \"tsc --project tsconfig.build.json --module es2015 --outDir esm\",\n    \"build:umd\": \"rollup --config\",\n    \"build:docs\": \"dumi build\"\n  },\n  \"peerDependencies\": {\n    \"@types/react\": \">=16.8.0\",\n    \"@types/react-dom\": \">=16.8.0\",\n    \"react\": \">=16.8.0\",\n    \"react-dom\": \">=16.8.0\",\n    \"react-is\": \">=16.8.0\"\n  },\n  \"peerDependenciesMeta\": {\n    \"@types/react\": {\n      \"optional\": true\n    },\n    \"@types/react-dom\": {\n      \"optional\": true\n    }\n  },\n  \"devDependencies\": {\n    \"dumi\": \"^1.1.0-rc.8\"\n  },\n  \"dependencies\": {\n    \"@formily/reactive\": \"2.3.7\",\n    \"hoist-non-react-statics\": \"^3.3.2\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"gitHead\": \"ac79c196ae9324889aca5e0501146f9b37b04283\"\n}\n"
  },
  {
    "path": "packages/reactive-react/rollup.config.js",
    "content": "import baseConfig from '../../scripts/rollup.base.js'\n\nexport default baseConfig('formily.reactive-react', 'Formily.ReactiveReact')\n"
  },
  {
    "path": "packages/reactive-react/src/hooks/index.ts",
    "content": "import { useForceUpdate } from './useForceUpdate'\nimport { useCompatEffect } from './useCompatEffect'\nimport { useCompatFactory } from './useCompatFactory'\nimport { useDidUpdate } from './useDidUpdate'\nimport { useLayoutEffect } from './useLayoutEffect'\nimport { useObserver } from './useObserver'\n\nexport const unstable_useForceUpdate = useForceUpdate\nexport const unstable_useCompatEffect = useCompatEffect\nexport const unstable_useCompatFactory = useCompatFactory\nexport const unstable_useDidUpdate = useDidUpdate\nexport const unstable_useLayoutEffect = useLayoutEffect\nexport const unstable_useObserver = useObserver\n"
  },
  {
    "path": "packages/reactive-react/src/hooks/useCompatEffect.ts",
    "content": "import { useEffect, useRef, EffectCallback, DependencyList } from 'react'\nimport { immediate } from '../shared'\n\nconst isArr = Array.isArray\n\nconst isEqualDeps = (target: any, source: any) => {\n  const arrA = isArr(target)\n  const arrB = isArr(source)\n  if (arrA !== arrB) return false\n  if (arrA) {\n    if (target.length !== source.length) return false\n    return target.every((val, index) => val === source[index])\n  }\n  return target === source\n}\n\nexport const useCompatEffect = (\n  effect: EffectCallback,\n  deps?: DependencyList\n) => {\n  const depsRef = useRef<DependencyList>(null)\n  const mountedRef = useRef(false)\n  useEffect(() => {\n    mountedRef.current = true\n    const dispose = effect()\n    return () => {\n      mountedRef.current = false\n      if (!isEqualDeps(depsRef.current, deps)) {\n        if (dispose) dispose()\n        return\n      }\n      immediate(() => {\n        if (mountedRef.current) return\n        if (dispose) dispose()\n      })\n    }\n  }, deps)\n  depsRef.current = deps\n}\n"
  },
  {
    "path": "packages/reactive-react/src/hooks/useCompatFactory.ts",
    "content": "import React from 'react'\nimport { GarbageCollector } from '../shared'\nimport { useCompatEffect } from './useCompatEffect'\n\nclass ObjectToBeRetainedByReact {}\n\nfunction objectToBeRetainedByReactFactory() {\n  return new ObjectToBeRetainedByReact()\n}\n\nexport const useCompatFactory = <T extends { dispose: () => void }>(\n  factory: () => T\n): T => {\n  const instRef = React.useRef<T>(null)\n  const gcRef = React.useRef<GarbageCollector>()\n  const [objectRetainedByReact] = React.useState(\n    objectToBeRetainedByReactFactory\n  )\n  if (!instRef.current) {\n    instRef.current = factory()\n  }\n  //StrictMode/ConcurrentMode会导致组件无法正确触发UnMount，所以只能自己做垃圾回收\n  if (!gcRef.current) {\n    gcRef.current = new GarbageCollector(() => {\n      if (instRef.current) {\n        instRef.current.dispose()\n      }\n    })\n    gcRef.current.open(objectRetainedByReact)\n  }\n\n  useCompatEffect(() => {\n    gcRef.current.close()\n    return () => {\n      if (instRef.current) {\n        instRef.current.dispose()\n        instRef.current = null\n      }\n    }\n  }, [])\n  return instRef.current\n}\n"
  },
  {
    "path": "packages/reactive-react/src/hooks/useDidUpdate.ts",
    "content": "import { useRef } from 'react'\nimport { useLayoutEffect } from './useLayoutEffect'\nimport { immediate } from '../shared'\n\nexport const useDidUpdate = (callback?: () => void) => {\n  const request = useRef(null)\n  request.current = immediate(callback)\n  useLayoutEffect(() => {\n    request.current()\n    callback()\n  })\n}\n"
  },
  {
    "path": "packages/reactive-react/src/hooks/useForceUpdate.ts",
    "content": "import { useCallback, useRef, useState } from 'react'\nimport { useLayoutEffect } from './useLayoutEffect'\nimport { useDidUpdate } from './useDidUpdate'\n\nconst EMPTY_ARRAY: any[] = []\nconst RENDER_COUNT = { value: 0 }\nconst RENDER_QUEUE = new Set<() => void>()\n\nexport function useForceUpdate() {\n  const [, setState] = useState([])\n  const firstRenderedRef = useRef(false)\n  const needUpdateRef = useRef(false)\n  useLayoutEffect(() => {\n    firstRenderedRef.current = true\n    if (needUpdateRef.current) {\n      setState([])\n      needUpdateRef.current = false\n    }\n    return () => {\n      firstRenderedRef.current = false\n    }\n  }, EMPTY_ARRAY)\n\n  const update = useCallback(() => {\n    setState([])\n  }, EMPTY_ARRAY)\n\n  const scheduler = useCallback(() => {\n    if (!firstRenderedRef.current) {\n      // 针对StrictMode无法快速回收内存，只能考虑拦截第一次渲染函数的setState，\n      // 因为第一次渲染函数的setState会触发第二次渲染函数执行，从而清理掉第二次渲染函数内部的依赖\n      needUpdateRef.current = true\n      return\n    }\n    if (RENDER_COUNT.value === 0) {\n      update()\n    } else {\n      RENDER_QUEUE.add(update)\n    }\n  }, EMPTY_ARRAY)\n\n  RENDER_COUNT.value++\n\n  useDidUpdate(() => {\n    if (RENDER_COUNT.value > 0) {\n      RENDER_COUNT.value--\n    }\n    if (RENDER_COUNT.value === 0) {\n      RENDER_QUEUE.forEach((update) => {\n        RENDER_QUEUE.delete(update)\n        update()\n      })\n    }\n  })\n\n  return scheduler\n}\n"
  },
  {
    "path": "packages/reactive-react/src/hooks/useLayoutEffect.ts",
    "content": "import { useEffect, useLayoutEffect as _useLayoutEffect } from 'react'\n\nexport const useLayoutEffect =\n  typeof document !== 'undefined' ? _useLayoutEffect : useEffect\n"
  },
  {
    "path": "packages/reactive-react/src/hooks/useObserver.ts",
    "content": "import { Tracker } from '@formily/reactive'\nimport { IObserverOptions } from '../types'\nimport { useForceUpdate } from './useForceUpdate'\nimport { useCompatFactory } from './useCompatFactory'\n\nexport const useObserver = <T extends () => any>(\n  view: T,\n  options?: IObserverOptions\n): ReturnType<T> => {\n  const forceUpdate = useForceUpdate()\n  const tracker = useCompatFactory(\n    () =>\n      new Tracker(() => {\n        if (typeof options?.scheduler === 'function') {\n          options.scheduler(forceUpdate)\n        } else {\n          forceUpdate()\n        }\n      }, options?.displayName)\n  )\n  return tracker.track(view)\n}\n"
  },
  {
    "path": "packages/reactive-react/src/index.ts",
    "content": "export * from './observer'\nexport * from './hooks'\nexport * from './types'\n"
  },
  {
    "path": "packages/reactive-react/src/observer.ts",
    "content": "import React, { forwardRef, memo, Fragment } from 'react'\nimport hoistNonReactStatics from 'hoist-non-react-statics'\nimport { useObserver } from './hooks/useObserver'\nimport { IObserverOptions, IObserverProps, ReactFC } from './types'\n\nexport function observer<\n  P,\n  Options extends IObserverOptions = IObserverOptions\n>(\n  component: ReactFC<P>,\n  options?: Options\n): React.MemoExoticComponent<\n  ReactFC<\n    Options extends { forwardRef: true }\n      ? P & {\n          ref?: 'ref' extends keyof P ? P['ref'] : React.RefAttributes<any>\n        }\n      : React.PropsWithoutRef<P>\n  >\n> {\n  const realOptions = {\n    forwardRef: false,\n    ...options,\n  }\n\n  const wrappedComponent = realOptions.forwardRef\n    ? forwardRef((props: any, ref: any) => {\n        return useObserver(() => component({ ...props, ref }), realOptions)\n      })\n    : (props: any) => {\n        return useObserver(() => component(props), realOptions)\n      }\n\n  const memoComponent = memo(wrappedComponent)\n\n  hoistNonReactStatics(memoComponent, component)\n\n  if (realOptions.displayName) {\n    memoComponent.displayName = realOptions.displayName\n  }\n\n  return memoComponent\n}\n\nexport const Observer = observer((props: IObserverProps) => {\n  const children =\n    typeof props.children === 'function' ? props.children() : props.children\n  return React.createElement(Fragment, {}, children)\n})\n"
  },
  {
    "path": "packages/reactive-react/src/shared/gc.ts",
    "content": "import { globalThisPolyfill } from './global'\n\nconst registry: FinalizationRegistry<any> =\n  globalThisPolyfill['FinalizationRegistry'] &&\n  new globalThisPolyfill['FinalizationRegistry']((token: any) =>\n    token?.clean?.()\n  )\n\ntype Token = { clean: () => void }\nexport class GarbageCollector<T extends object = any> {\n  private expireTime: number\n  private request?: ReturnType<typeof setTimeout>;\n  private token: Token\n  constructor(clean?: () => void, expireTime = 10_000) {\n    this.token = {\n      clean,\n    }\n    this.expireTime = expireTime\n  }\n\n  open(target: T) {\n    if (registry) {\n      registry.register(target, this.token, this.token)\n    } else {\n      this.request = setTimeout(() => {\n        this.token?.clean?.()\n      }, this.expireTime)\n    }\n  }\n\n  close() {\n    if (registry) {\n      registry.unregister(this.token)\n    } else {\n      clearTimeout(this.request)\n    }\n  }\n}\n"
  },
  {
    "path": "packages/reactive-react/src/shared/global.ts",
    "content": "/* istanbul ignore next */\nfunction globalSelf() {\n  try {\n    if (typeof self !== 'undefined') {\n      return self\n    }\n  } catch (e) {}\n  try {\n    if (typeof window !== 'undefined') {\n      return window\n    }\n  } catch (e) {}\n  try {\n    if (typeof global !== 'undefined') {\n      return global\n    }\n  } catch (e) {}\n  return Function('return this')()\n}\n\nexport const globalThisPolyfill: Window = globalSelf()\n"
  },
  {
    "path": "packages/reactive-react/src/shared/immediate.ts",
    "content": "export const immediate = (callback?: () => void) => {\n  let disposed = false\n  Promise.resolve(0).then(() => {\n    if (disposed) {\n      disposed = false\n      return\n    }\n    callback()\n  })\n  return () => {\n    disposed = true\n  }\n}\n"
  },
  {
    "path": "packages/reactive-react/src/shared/index.ts",
    "content": "export * from './gc'\nexport * from './immediate'\n"
  },
  {
    "path": "packages/reactive-react/src/types.ts",
    "content": "import React from 'react'\n\nexport interface IObserverOptions {\n  forwardRef?: boolean\n  scheduler?: (updater: () => void) => void\n  displayName?: string\n}\n\nexport interface IObserverProps {\n  children?: (() => React.ReactElement) | React.ReactNode\n}\n\nexport type Modify<T, R> = Omit<T, keyof R> & R\n\nexport type ReactPropsWithChildren<P> = Modify<\n  { children?: React.ReactNode | undefined },\n  P\n>\n\nexport type ReactFC<P = {}> = React.FC<ReactPropsWithChildren<P>>\n"
  },
  {
    "path": "packages/reactive-react/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*\", \"devtools/*\"]\n    },\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/reactive-react/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"include\": [\"./src/**/*.ts\", \"./src/**/*.tsx\"],\n  \"exclude\": [\"./src/__tests__/*\", \"./esm/*\", \"./lib/*\"],\n  \"compilerOptions\": {\n    \"lib\": [\"ESNext\", \"DOM\"]\n  }\n}\n"
  },
  {
    "path": "packages/reactive-test-cases-for-react18/.npmignore",
    "content": "node_modules\n*.log\nbuild\ndocs\ndoc-site\n__tests__\n.eslintrc\njest.config.js\ntsconfig.json\n.umi\nsrc"
  },
  {
    "path": "packages/reactive-test-cases-for-react18/.umirc.js",
    "content": "import { resolve } from 'path'\nexport default {\n  mode: 'site',\n  logo: '//img.alicdn.com/imgextra/i2/O1CN01Kq3OHU1fph6LGqjIz_!!6000000004056-55-tps-1141-150.svg',\n  title: 'Formily',\n  hash: true,\n  favicon:\n    '//img.alicdn.com/imgextra/i3/O1CN01XtT3Tv1Wd1b5hNVKy_!!6000000002810-55-tps-360-360.svg',\n  outputPath: './doc-site',\n  navs: {\n    'en-US': [\n      {\n        title: 'Guide',\n        path: '/guide',\n      },\n      {\n        title: 'API',\n        path: '/api',\n      },\n      {\n        title: 'Home Site',\n        path: 'https://formilyjs.org',\n      },\n      {\n        title: 'GITHUB',\n        path: 'https://github.com/alibaba/formily',\n      },\n    ],\n    'zh-CN': [\n      {\n        title: '指南',\n        path: '/zh-CN/guide',\n      },\n      {\n        title: 'API',\n        path: '/zh-CN/api',\n      },\n      {\n        title: '主站',\n        path: 'https://formilyjs.org',\n      },\n      {\n        title: 'GITHUB',\n        path: 'https://github.com/alibaba/formily',\n      },\n    ],\n  },\n  links: [\n    {\n      rel: 'stylesheet',\n      href: 'https://esm.sh/antd@4.x/dist/antd.css',\n    },\n  ],\n  styles: [\n    `.__dumi-default-navbar-logo{\n      height: 60px !important;\n      width: 150px !important;\n      padding-left:0 !important;\n      color: transparent !important;\n    }\n    .__dumi-default-navbar{\n      padding: 0 28px !important;\n    }\n    .__dumi-default-layout-hero{\n      background-image: url(//img.alicdn.com/imgextra/i4/O1CN01ZcvS4e26XMsdsCkf9_!!6000000007671-2-tps-6001-4001.png);\n      background-size: cover;\n      background-repeat: no-repeat;\n    }\n    nav a{\n      text-decoration: none !important;\n    }\n    `,\n  ],\n  menus: {\n    '/guide': [\n      {\n        title: 'Introduction',\n        path: '/guide',\n      },\n      { title: 'Architecture', path: '/guide/architecture' },\n      { title: 'Concept', path: '/guide/concept' },\n    ],\n    '/zh-CN/guide': [\n      {\n        title: '介绍',\n        path: '/guide',\n      },\n      { title: '核心架构', path: '/zh-CN/guide/architecture' },\n      { title: '核心概念', path: '/zh-CN/guide/concept' },\n    ],\n  },\n}\n"
  },
  {
    "path": "packages/reactive-test-cases-for-react18/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-present, Alibaba Group Holding Limited. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/reactive-test-cases-for-react18/README.md",
    "content": "# @formily/reactive-test-cases-for-react18\n"
  },
  {
    "path": "packages/reactive-test-cases-for-react18/package.json",
    "content": "{\n  \"name\": \"@formily/reactive-test-cases-for-react18\",\n  \"version\": \"2.3.7\",\n  \"license\": \"MIT\",\n  \"private\": true,\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/alibaba/formily.git\"\n  },\n  \"types\": \"esm/index.d.ts\",\n  \"bugs\": {\n    \"url\": \"https://github.com/alibaba/formily/issues\"\n  },\n  \"homepage\": \"https://github.com/alibaba/formily#readme\",\n  \"engines\": {\n    \"npm\": \">=3.0.0\"\n  },\n  \"scripts\": {\n    \"start\": \"webpack-dev-server --config webpack.dev.ts\"\n  },\n  \"devDependencies\": {\n    \"file-loader\": \"^5.0.2\",\n    \"html-webpack-plugin\": \"^3.2.0\",\n    \"mini-css-extract-plugin\": \"^1.6.0\",\n    \"raw-loader\": \"^4.0.0\",\n    \"style-loader\": \"^1.1.3\",\n    \"ts-loader\": \"^7.0.4\",\n    \"webpack\": \"^4.41.5\",\n    \"webpack-bundle-analyzer\": \"^3.9.0\",\n    \"webpack-cli\": \"^3.3.10\",\n    \"webpack-dev-server\": \"^3.10.1\"\n  },\n  \"resolutions\": {\n    \"react\": \"next\",\n    \"react-dom\": \"next\",\n    \"react-is\": \"next\"\n  },\n  \"dependencies\": {\n    \"@formily/reactive\": \"2.3.7\",\n    \"@formily/reactive-react\": \"2.3.7\",\n    \"react\": \"next\",\n    \"react-dom\": \"next\",\n    \"react-is\": \"next\"\n  },\n  \"gitHead\": \"ac79c196ae9324889aca5e0501146f9b37b04283\"\n}\n"
  },
  {
    "path": "packages/reactive-test-cases-for-react18/src/MySlowList.js",
    "content": "import React from 'react'\nimport { observer } from '@formily/reactive-react'\n\n// Note: this file is exactly the same in both examples.\n\nfunction ListItem({ children }) {\n  let now = performance.now()\n  while (performance.now() - now < 10) {\n    // Note: this is an INTENTIONALLY EMPTY loop that\n    // DOES NOTHING for 3 milliseconds for EACH ITEM.\n    //\n    // It's meant to emulate what happens in a deep\n    // component tree with calculations and other\n    // work performed inside components that can't\n    // trivially be optimized or removed.\n  }\n  return <div className=\"ListItem\">{children}</div>\n}\n\nexport default observer(function MySlowList({ text }) {\n  let items = []\n  for (let i = 0; i < 50; i++) {\n    items.push(\n      <ListItem key={i}>{'Result ' + i + ' for ' + text.text}</ListItem>\n    )\n  }\n  return (\n    <>\n      <p>\n        <b>Results for \"{text.text}\":</b>\n      </p>\n      <ul className=\"List\">{items}</ul>\n    </>\n  )\n})\n"
  },
  {
    "path": "packages/reactive-test-cases-for-react18/src/index.js",
    "content": "import React, { startTransition, useState } from 'react'\nimport ReactDOM from 'react-dom'\nimport MySlowList from './MySlowList'\nimport { observable } from '@formily/reactive'\nimport { observer } from '@formily/reactive-react'\n\nconst App = observer(function App() {\n  const [text, setText] = useState('hello')\n  const [slowText] = useState(() =>\n    observable({\n      text,\n    })\n  )\n\n  function handleChange(e) {\n    setText(e.target.value)\n    startTransition(() => {\n      slowText.text = e.target.value\n    })\n  }\n\n  return (\n    <div className=\"App\">\n      <h1>Concurrent React</h1>\n      <label>\n        Type into the input: <input value={text} onChange={handleChange} />\n      </label>\n      <p>\n        You entered: <b>{text}</b>\n      </p>\n      <p\n        style={{\n          background: text !== slowText.text ? 'yellow' : '',\n        }}\n      >\n        But we are showing: <Indicator text={slowText} />\n      </p>\n      <p\n        style={{\n          background: text !== slowText.text ? 'yellow' : '',\n        }}\n      >\n        But we are showing: <Indicator text={slowText} />\n      </p>\n      <p\n        style={{\n          background: text !== slowText.text ? 'yellow' : '',\n        }}\n      >\n        But we are showing: <Indicator text={slowText} />\n      </p>\n      <p\n        style={{\n          background: text !== slowText.text ? 'yellow' : '',\n        }}\n      >\n        But we are showing: <Indicator text={slowText} />\n      </p>\n      <p>\n        Even though{' '}\n        <b>\n          each list item in this demo artificially blocks the main thread for 3\n          milliseconds\n        </b>\n        , the app is able to stay responsive.\n      </p>\n      <hr />\n      <MySlowList text={slowText} />\n    </div>\n  )\n})\n\nlet Indicator = observer(({ text }) => {\n  const [hover, setHover] = useState(false)\n  return (\n    <p\n      onMouseEnter={() => setHover(true)}\n      onMouseLeave={() => setHover(false)}\n      style={{\n        border: '1px solid black',\n        padding: 20,\n        background: hover ? 'yellow' : '',\n      }}\n    >\n      But we are showing: <b>{text.text}</b>\n    </p>\n  )\n})\n\nconst rootElement = document.getElementById('root')\nReactDOM.createRoot(rootElement).render(<App />)\n"
  },
  {
    "path": "packages/reactive-test-cases-for-react18/template.ejs",
    "content": "<!DOCTYPE html>\n\n<head>\n  <title>\n    React18 Demo\n  </title>\n  <style>\n    html,\n    body {\n      user-select: none;\n      -webkit-user-select: none;\n    }\n  </style>\n</head>\n\n<body>\n  <div id=\"root\">\n  </div>\n  <script src=\"https://esm.sh/react@next/umd/react.production.min.js\"></script>\n  <script src=\"https://esm.sh/react-dom@next/umd/react-dom.production.min.js\"></script>\n</body>"
  },
  {
    "path": "packages/reactive-test-cases-for-react18/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*\", \"devtools/*\"]\n    },\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/reactive-test-cases-for-react18/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"compilerOptions\": {\n    \"allowJs\": true\n  },\n  \"include\": [\"./src/**/*.js\"],\n  \"exclude\": [\"./src/__tests__/*\", \"./esm/*\", \"./lib/*\"]\n}\n"
  },
  {
    "path": "packages/reactive-test-cases-for-react18/webpack.base.ts",
    "content": "import path from 'path'\nimport fs from 'fs-extra'\nimport { GlobSync } from 'glob'\nimport MiniCssExtractPlugin from 'mini-css-extract-plugin'\n//import { getThemeVariables } from 'antd/dist/theme'\n\nconst getWorkspaceAlias = () => {\n  const basePath = path.resolve(__dirname, '../../')\n  const pkg = fs.readJSONSync(path.resolve(basePath, 'package.json')) || {}\n  const results = {}\n  const workspaces = pkg.workspaces\n  if (Array.isArray(workspaces)) {\n    workspaces.forEach((pattern) => {\n      const { found } = new GlobSync(pattern, { cwd: basePath })\n      found.forEach((name) => {\n        const pkg = fs.readJSONSync(\n          path.resolve(basePath, name, './package.json')\n        )\n        results[pkg.name] = path.resolve(basePath, name, './src')\n      })\n    })\n  }\n  return results\n}\n\nexport default {\n  mode: 'development',\n  devtool: 'inline-source-map', // 嵌入到源文件中\n  stats: {\n    entrypoints: false,\n    children: false,\n  },\n  entry: {\n    index: path.resolve(__dirname, './src/index'),\n  },\n  output: {\n    path: path.resolve(__dirname, '../build'),\n    filename: '[name].[hash].bundle.js',\n  },\n  resolve: {\n    modules: ['node_modules'],\n    extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],\n    alias: getWorkspaceAlias(),\n  },\n  externals: {\n    react: 'React',\n    'react-dom': 'ReactDOM',\n    moment: 'moment',\n    antd: 'antd',\n  },\n  module: {\n    rules: [\n      {\n        test: /\\.(tsx?|jsx?)$/,\n        use: [\n          {\n            loader: require.resolve('ts-loader'),\n            options: {\n              transpileOnly: true,\n            },\n          },\n        ],\n      },\n      {\n        test: /\\.css$/,\n        use: [MiniCssExtractPlugin.loader, require.resolve('css-loader')],\n      },\n      {\n        test: /\\.less$/,\n        use: [\n          MiniCssExtractPlugin.loader,\n          { loader: 'css-loader' },\n          {\n            loader: 'postcss-loader',\n          },\n          {\n            loader: 'less-loader',\n            options: {\n              // modifyVars: getThemeVariables({\n              //   dark: true // 开启暗黑模式\n              // }),\n              javascriptEnabled: true,\n            },\n          },\n        ],\n      },\n      {\n        test: /\\.(woff|woff2|ttf|eot|svg)(\\?v=\\d+\\.\\d+\\.\\d+)?$/,\n        use: ['url-loader'],\n      },\n      {\n        test: /\\.html?$/,\n        loader: require.resolve('file-loader'),\n        options: {\n          name: '[name].[ext]',\n        },\n      },\n    ],\n  },\n}\n"
  },
  {
    "path": "packages/reactive-test-cases-for-react18/webpack.dev.ts",
    "content": "import baseConfig from './webpack.base'\nimport HtmlWebpackPlugin from 'html-webpack-plugin'\nimport MiniCssExtractPlugin from 'mini-css-extract-plugin'\nimport webpack from 'webpack'\nimport path from 'path'\n\nconst PORT = 3000\n\nconst createPages = (pages) => {\n  return pages.map(({ filename, template, chunk }) => {\n    return new HtmlWebpackPlugin({\n      filename,\n      template,\n      inject: 'body',\n      chunks: chunk,\n    })\n  })\n}\n\nfor (const key in baseConfig.entry) {\n  if (Array.isArray(baseConfig.entry[key])) {\n    baseConfig.entry[key].push(\n      require.resolve('webpack/hot/dev-server'),\n      `${require.resolve('webpack-dev-server/client')}?http://localhost:${PORT}`\n    )\n  }\n}\n\nexport default {\n  ...baseConfig,\n  plugins: [\n    new MiniCssExtractPlugin({\n      filename: '[name].[hash].css',\n      chunkFilename: '[id].[hash].css',\n    }),\n    ...createPages([\n      {\n        filename: 'index.html',\n        template: path.resolve(__dirname, './template.ejs'),\n        chunk: ['index'],\n      },\n    ]),\n    new webpack.HotModuleReplacementPlugin(),\n    // new BundleAnalyzerPlugin()\n  ],\n  devServer: {\n    host: '127.0.0.1',\n    open: true,\n    port: PORT,\n  },\n}\n"
  },
  {
    "path": "packages/reactive-test-cases-for-react18/webpack.prod.ts",
    "content": "import baseConfig from './webpack.base'\nimport HtmlWebpackPlugin from 'html-webpack-plugin'\nimport MiniCssExtractPlugin from 'mini-css-extract-plugin'\nimport path from 'path'\n\nconst createPages = (pages) => {\n  return pages.map(({ filename, template, chunk }) => {\n    return new HtmlWebpackPlugin({\n      filename,\n      template,\n      inject: 'body',\n      chunks: chunk,\n    })\n  })\n}\n\nexport default {\n  ...baseConfig,\n  mode: 'production',\n  plugins: [\n    new MiniCssExtractPlugin({\n      filename: '[name].[hash].css',\n      chunkFilename: '[id].[hash].css',\n    }),\n    ...createPages([\n      {\n        filename: 'index.html',\n        template: path.resolve(__dirname, './template.ejs'),\n        chunk: ['index'],\n      },\n    ]),\n  ],\n  optimization: {\n    minimize: true,\n  },\n}\n"
  },
  {
    "path": "packages/reactive-vue/.npmignore",
    "content": "node_modules\n*.log\nbuild\ndocs\ndoc-site\n__tests__\n.eslintrc\njest.config.js\ntsconfig.json\n.umi\nsrc"
  },
  {
    "path": "packages/reactive-vue/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-present, Alibaba Group Holding Limited. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/reactive-vue/README.md",
    "content": "# @formily/reactive-vue\n"
  },
  {
    "path": "packages/reactive-vue/package.json",
    "content": "{\n  \"name\": \"@formily/reactive-vue\",\n  \"version\": \"2.3.7\",\n  \"license\": \"MIT\",\n  \"main\": \"lib\",\n  \"module\": \"esm\",\n  \"umd:main\": \"dist/formily.reactive-vue.umd.production.js\",\n  \"unpkg\": \"dist/formily.reactive-vue.umd.production.js\",\n  \"jsdelivr\": \"dist/formily.reactive-vue.umd.production.js\",\n  \"jsnext:main\": \"esm\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/alibaba/formily.git\"\n  },\n  \"types\": \"esm/index.d.ts\",\n  \"bugs\": {\n    \"url\": \"https://github.com/alibaba/formily/issues\"\n  },\n  \"homepage\": \"https://github.com/alibaba/formily#readme\",\n  \"engines\": {\n    \"npm\": \">=3.0.0\"\n  },\n  \"scripts\": {\n    \"build\": \"rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm && npm run build:umd\",\n    \"build:cjs\": \"tsc --project tsconfig.build.json\",\n    \"build:esm\": \"tsc --project tsconfig.build.json --module es2015 --outDir esm\",\n    \"build:umd\": \"rollup --config\"\n  },\n  \"devDependencies\": {\n    \"@vue/composition-api\": \"^1.0.0-rc.7\",\n    \"@vue/test-utils\": \"1.0.0-beta.22\",\n    \"core-js\": \"^2.4.0\",\n    \"vue\": \"^2.6.12\"\n  },\n  \"dependencies\": {\n    \"@formily/reactive\": \"2.3.7\",\n    \"vue-demi\": \">=0.13.6\"\n  },\n  \"peerDependencies\": {\n    \"@vue/composition-api\": \"^1.0.0-beta.1\",\n    \"vue\": \"^2.6.0 || >=3.0.0-rc.0\"\n  },\n  \"peerDependenciesMeta\": {\n    \"@vue/composition-api\": {\n      \"optional\": true\n    }\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"gitHead\": \"ac79c196ae9324889aca5e0501146f9b37b04283\"\n}\n"
  },
  {
    "path": "packages/reactive-vue/rollup.config.js",
    "content": "import baseConfig from '../../scripts/rollup.base.js'\n\nexport default baseConfig('formily.reactive-vue', 'Formily.ReactiveVue')\n"
  },
  {
    "path": "packages/reactive-vue/src/__tests__/observer.spec.ts",
    "content": "import { shallowMount, createLocalVue } from '@vue/test-utils'\nimport { observable, autorun } from '@formily/reactive'\nimport { CreateElement } from 'vue'\nimport CompositionAPI, { defineComponent, h } from '@vue/composition-api'\nimport { observer } from '../'\nimport collectData from '../observer/collectData'\nimport { observer as observerInVue2 } from '../observer/observerInVue2'\nimport expect from 'expect'\n\ntest('observer: component', async () => {\n  const model = observable<any>({\n    age: 10,\n    setAge() {\n      model.age++\n    },\n  })\n  const Component = observer({\n    data() {\n      return {\n        model,\n      }\n    },\n    render(this: any, h: CreateElement) {\n      return h('button', {\n        on: { click: this.model.setAge },\n        domProps: { textContent: this.model.age },\n      })\n    },\n  })\n  const wrapper = shallowMount(Component)\n  expect(wrapper.find('button').text()).toBe('10')\n  wrapper.find('button').trigger('click')\n  expect(wrapper.find('button').text()).toBe('11')\n  wrapper.destroy()\n})\n\ntest('observer: component with setup', async () => {\n  const Vue = createLocalVue()\n  Vue.use(CompositionAPI)\n  const model = observable<any>({\n    age: 30,\n    get sub10() {\n      return model.age - 10\n    },\n    get sub20() {\n      return model.sub10 - 10\n    },\n    setAge() {\n      model.age++\n    },\n  })\n  const Component = observer(\n    defineComponent({\n      setup() {\n        return () => {\n          return h('button', {\n            on: { click: model.setAge },\n            domProps: { textContent: model.sub20 },\n          })\n        }\n      },\n      // to fix 'Maximum call stack size exceeded' error of @vue/test-utils\n      render() {\n        return null\n      },\n    })\n  )\n  const wrapper = shallowMount(Component)\n  expect(wrapper.find('button').text()).toBe('10')\n  wrapper.find('button').trigger('click')\n  expect(wrapper.find('button').text()).toBe('11')\n  model.age++\n  expect(wrapper.find('button').text()).toBe('12')\n  wrapper.destroy()\n})\n\ntest('observer: component scheduler', async () => {\n  let schedulerRequest = null\n\n  const model = observable<any>({\n    age: 10,\n    setAge() {\n      model.age++\n    },\n  })\n  const Component = observer(\n    {\n      data() {\n        return {\n          model,\n        }\n      },\n      render(this: any, h: CreateElement) {\n        return h('button', {\n          on: { click: this.model.setAge },\n          domProps: { textContent: this.model.age },\n        })\n      },\n    },\n    {\n      scheduler: (update) => {\n        clearTimeout(schedulerRequest)\n        schedulerRequest = setTimeout(() => {\n          update()\n        }, 100)\n      },\n    }\n  )\n  const wrapper = shallowMount(Component)\n\n  expect(wrapper.find('button').text()).toBe('10')\n\n  wrapper.find('button').trigger('click')\n  await new Promise((r) => setTimeout(r, 150))\n  expect(wrapper.find('button').text()).toBe('11')\n\n  // test second render\n  wrapper.find('button').trigger('click')\n  await new Promise((r) => setTimeout(r, 150))\n  expect(wrapper.find('button').text()).toBe('12')\n\n  wrapper.destroy()\n})\n\ntest('observer: stop tracking if watcher is destroyed', async () => {\n  let count = 0\n  const model = observable<any>({\n    age: 10,\n    name: 'test',\n  })\n\n  const Component = observer({\n    name: 'test',\n    data() {\n      return {\n        model: model,\n      }\n    },\n    render() {\n      count++\n      return h('div', [this.model.name, this.model.age])\n    },\n  })\n\n  const wrapper = shallowMount(Component)\n\n  const childInst = wrapper.find({ name: 'test' })\n\n  expect(childInst.exists()).toBe(true)\n  ;(childInst.vm as any)._isDestroyed = true\n  model.age++\n  wrapper.destroy()\n  expect(count).toEqual(1) // 不触发 reactiveRender\n})\n\ntest('collectData', async () => {\n  const model = observable<any>({\n    age: 10,\n    name: 'test',\n  })\n\n  const target = {\n    value: 1,\n  }\n\n  const data = collectData(\n    {},\n    {\n      model,\n      target,\n    }\n  )\n\n  const fn1 = jest.fn()\n  const fn2 = jest.fn()\n\n  autorun(() => fn1(model.age))\n  autorun(() => fn2(data.target.value))\n\n  model.age++\n  expect(fn1).toBeCalledTimes(2)\n\n  target.value++\n  expect(fn2).toBeCalledTimes(1)\n})\n\ntest('observerInVue2', () => {\n  const componentObj = Object.create(null)\n\n  componentObj.data = () => {\n    return {}\n  }\n\n  const ExtendedComponent1 = observerInVue2(componentObj)\n  expect(ExtendedComponent1.name).toEqual('<component>')\n\n  function Component() {}\n  Component.options = {\n    data: () => {\n      return {}\n    },\n  }\n\n  const ExtendedComponent2 = observerInVue2(Component, { name: 'abc' })\n  expect(ExtendedComponent2.name).toEqual('abc')\n})\n"
  },
  {
    "path": "packages/reactive-vue/src/hooks/index.ts",
    "content": "export * from './useObserver'\n"
  },
  {
    "path": "packages/reactive-vue/src/hooks/useObserver.ts",
    "content": "import { Tracker } from '@formily/reactive'\nimport { getCurrentInstance, onBeforeUnmount, isVue3 } from 'vue-demi'\nimport { IObserverOptions } from '../types'\n\n/* istanbul ignore next */\nexport const useObserver = (options?: IObserverOptions) => {\n  if (isVue3) {\n    const vm = getCurrentInstance()\n    let tracker: Tracker = null\n    const disposeTracker = () => {\n      if (tracker) {\n        tracker.dispose()\n        tracker = null\n      }\n    }\n    const vmUpdate = () => {\n      vm?.proxy?.$forceUpdate()\n    }\n\n    onBeforeUnmount(disposeTracker)\n\n    Object.defineProperty(vm, 'effect', {\n      get() {\n        // https://github.com/alibaba/formily/issues/2655\n        return vm['_updateEffect'] || {}\n      },\n      set(newValue) {\n        vm['_updateEffectRun'] = newValue.run\n        disposeTracker()\n        const newTracker = () => {\n          tracker = new Tracker(() => {\n            if (options?.scheduler && typeof options.scheduler === 'function') {\n              options.scheduler(vmUpdate)\n            } else {\n              vmUpdate()\n            }\n          })\n        }\n\n        const update = function () {\n          let refn = null\n          tracker?.track(() => {\n            refn = vm['_updateEffectRun'].call(newValue)\n          })\n          return refn\n        }\n        newTracker()\n        newValue.run = update\n        vm['_updateEffect'] = newValue\n      },\n    })\n  }\n}\n"
  },
  {
    "path": "packages/reactive-vue/src/index.ts",
    "content": "export * from './observer'\nexport * from './hooks'\nexport * from './types'\n"
  },
  {
    "path": "packages/reactive-vue/src/observer/collectData.ts",
    "content": "// https://github.com/mobxjs/mobx-vue/blob/master/src/collectData.ts\n\n/**\n * @author Kuitos\n * @homepage https://github.com/kuitos/\n * @since 2018-06-08 10:16\n */\n\nimport { isObservable } from '@formily/reactive'\n\nexport default function collectData(vm: any, data?: any) {\n  const dataDefinition =\n    typeof data === 'function' ? data.call(vm, vm) : data || {}\n  const filteredData = Object.keys(dataDefinition).reduce(\n    (result: any, field) => {\n      const value = dataDefinition[field]\n\n      if (isObservable(value)) {\n        Object.defineProperty(vm, field, {\n          configurable: true,\n          get() {\n            return value\n          },\n        })\n      } else {\n        result[field] = value\n      }\n\n      return result\n    },\n    {}\n  )\n\n  return filteredData\n}\n"
  },
  {
    "path": "packages/reactive-vue/src/observer/index.ts",
    "content": "import { isVue2 } from 'vue-demi'\nimport { observer as observerV2 } from './observerInVue2'\nimport { observer as observerV3 } from './observerInVue3'\nimport collectData from './collectData'\nimport { IObserverOptions } from '../types'\n\nexport function observer<C>(baseComponent: C, options?: IObserverOptions): C {\n  /* istanbul ignore else */\n  if (isVue2) {\n    return observerV2(baseComponent, options)\n  } else {\n    return observerV3(baseComponent, options)\n  }\n}\n\nexport { collectData }\n"
  },
  {
    "path": "packages/reactive-vue/src/observer/observerInVue2.ts",
    "content": "// https://github.com/mobxjs/mobx-vue/blob/master/src/observer.ts\n\n/**\n * @author Kuitos\n * @homepage https://github.com/kuitos/\n * @since 2018-05-22 16:39\n */\nimport { Tracker, batch } from '@formily/reactive'\nimport collectDataForVue from './collectData'\nimport { Vue2 as Vue } from 'vue-demi'\nimport { IObserverOptions } from '../types'\n\nconst noop = () => {}\nconst disposerSymbol = Symbol('disposerSymbol')\n\nfunction observer(Component: any, observerOptions?: IObserverOptions): any {\n  const name =\n    observerOptions?.name ||\n    (Component as any).name ||\n    (Component as any)._componentTag ||\n    (Component.constructor && Component.constructor.name) ||\n    '<component>'\n\n  const originalOptions =\n    typeof Component === 'object' ? Component : (Component as any).options\n  // To not mutate the original component options, we need to construct a new one\n  const dataDefinition = originalOptions.data\n  const options = {\n    name,\n    ...originalOptions,\n    data(vm: any) {\n      return collectDataForVue(vm || this, dataDefinition)\n    },\n    // overrider the cached constructor to avoid extending skip\n    // @see https://github.com/vuejs/vue/blob/6cc070063bd211229dff5108c99f7d11b6778550/src/core/global-api/extend.js#L24\n    _Ctor: {},\n  }\n\n  // we couldn't use the Component as super class when Component was a VueClass, that will invoke the lifecycle twice after we called Component.extend\n  const superProto =\n    typeof Component === 'function' &&\n    Object.getPrototypeOf(Component.prototype)\n  const Super =\n    superProto instanceof (Vue as any) ? superProto.constructor : Vue\n  const ExtendedComponent = Super.extend(options)\n\n  const { $mount, $destroy } = ExtendedComponent.prototype\n\n  ExtendedComponent.prototype.$mount = function (this: any, ...args: any[]) {\n    let mounted = false\n    this[disposerSymbol] = noop\n\n    let nativeRenderOfVue: any\n\n    const reactiveRender = () => {\n      batch(() => {\n        tracker.track(() => {\n          if (!mounted) {\n            $mount.apply(this, args)\n            mounted = true\n            nativeRenderOfVue = this._watcher.getter\n            // rewrite the native render method of vue with our reactive tracker render\n            // thus if component updated by vue watcher, we could re track and collect dependencies by @formily/reactive\n            this._watcher.getter = reactiveRender\n          } else {\n            nativeRenderOfVue.call(this, this)\n          }\n        })\n      })\n\n      return this\n    }\n\n    reactiveRender.$vm = this\n\n    const tracker = new Tracker(() => {\n      if (\n        reactiveRender.$vm._isBeingDestroyed ||\n        reactiveRender.$vm._isDestroyed\n      ) {\n        return tracker.dispose()\n      }\n\n      if (\n        observerOptions?.scheduler &&\n        typeof observerOptions.scheduler === 'function'\n      ) {\n        observerOptions.scheduler(reactiveRender)\n      } else {\n        reactiveRender()\n      }\n    })\n\n    this[disposerSymbol] = tracker.dispose\n\n    return reactiveRender()\n  }\n\n  ExtendedComponent.prototype.$destroy = function (this: any) {\n    ;(this as any)[disposerSymbol]()\n    $destroy.apply(this)\n  }\n\n  const extendedComponentNamePropertyDescriptor =\n    Object.getOwnPropertyDescriptor(ExtendedComponent, 'name') || {}\n  if (extendedComponentNamePropertyDescriptor.configurable === true) {\n    Object.defineProperty(ExtendedComponent, 'name', {\n      writable: false,\n      value: name,\n      enumerable: false,\n      configurable: false,\n    })\n  }\n\n  return ExtendedComponent\n}\n\nexport { observer, observer as Observer }\n"
  },
  {
    "path": "packages/reactive-vue/src/observer/observerInVue3.ts",
    "content": "import { IObserverOptions } from '../types'\nimport { useObserver } from '../hooks/useObserver'\n\n/* istanbul ignore next */\nexport const observer = function (opts: any, options?: IObserverOptions): any {\n  const name = options?.name || opts.name || 'ObservableComponent'\n\n  return {\n    name,\n    ...opts,\n    setup(props: Record<string, any>, context: any) {\n      useObserver(options)\n      return opts?.setup?.(props, context)\n    },\n  }\n}\n"
  },
  {
    "path": "packages/reactive-vue/src/types.ts",
    "content": "export interface IObserverOptions {\n  name?: string\n  scheduler?: (updater: () => void) => void\n}\n"
  },
  {
    "path": "packages/reactive-vue/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*\", \"devtools/*\"]\n    },\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/reactive-vue/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"compilerOptions\": {\n    \"skipLibCheck\": true\n  },\n  \"include\": [\"./src/**/*.ts\", \"./src/**/*.tsx\"],\n  \"exclude\": [\"./src/__tests__/*\", \"./esm/*\", \"./lib/*\"]\n}\n"
  },
  {
    "path": "packages/shared/.npmignore",
    "content": "node_modules\n*.log\nbuild\ndocs\ndoc-site\n__tests__\n.eslintrc\njest.config.js\ntsconfig.json\n.umi\nsrc"
  },
  {
    "path": "packages/shared/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-present, Alibaba Group Holding Limited. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "packages/shared/README.md",
    "content": "# @formily/shared\n\n> Formily 工具函数集\n"
  },
  {
    "path": "packages/shared/package.json",
    "content": "{\n  \"name\": \"@formily/shared\",\n  \"version\": \"2.3.7\",\n  \"license\": \"MIT\",\n  \"main\": \"lib\",\n  \"module\": \"esm\",\n  \"umd:main\": \"dist/formily.shared.umd.production.js\",\n  \"unpkg\": \"dist/formily.shared.umd.production.js\",\n  \"jsdelivr\": \"dist/formily.shared.umd.production.js\",\n  \"jsnext:main\": \"esm\",\n  \"types\": \"esm/index.d.ts\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/alibaba/formily.git\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/alibaba/formily/issues\"\n  },\n  \"homepage\": \"https://github.com/alibaba/formily#readme\",\n  \"engines\": {\n    \"npm\": \">=3.0.0\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"gitHead\": \"ac79c196ae9324889aca5e0501146f9b37b04283\",\n  \"scripts\": {\n    \"build\": \"rimraf -rf lib esm dist && npm run build:cjs && npm run build:esm && npm run build:umd\",\n    \"build:cjs\": \"tsc --project tsconfig.build.json\",\n    \"build:esm\": \"tsc --project tsconfig.build.json --module es2015 --outDir esm\",\n    \"build:umd\": \"rollup --config\"\n  },\n  \"dependencies\": {\n    \"@formily/path\": \"2.3.7\",\n    \"camel-case\": \"^4.1.1\",\n    \"lower-case\": \"^2.0.1\",\n    \"no-case\": \"^3.0.4\",\n    \"param-case\": \"^3.0.4\",\n    \"pascal-case\": \"^3.1.1\",\n    \"upper-case\": \"^2.0.1\"\n  }\n}\n"
  },
  {
    "path": "packages/shared/rollup.config.js",
    "content": "import baseConfig from '../../scripts/rollup.base.js'\n\nexport default baseConfig('formily.shared', 'Formily.Shared')\n"
  },
  {
    "path": "packages/shared/src/__tests__/index.spec.ts",
    "content": "import moment from 'moment'\nimport { Map as ImmutableMap } from 'immutable'\nimport { isEqual } from '../compare'\nimport {\n  toArr,\n  every,\n  move,\n  some,\n  findIndex,\n  find,\n  includes,\n  map,\n  reduce,\n} from '../array'\nimport { clone, shallowClone } from '../clone'\nimport { lowerCase } from '../case'\nimport { deprecate } from '../deprecate'\nimport { globalThisPolyfill } from '../global'\nimport { isValid, isEmpty } from '../isEmpty'\nimport { stringLength } from '../string'\nimport { Subscribable } from '../subscribable'\nimport { lazyMerge, merge } from '../merge'\nimport { instOf } from '../instanceof'\nimport {\n  isFn,\n  isHTMLElement,\n  isNumberLike,\n  isReactElement,\n  isMap,\n  isWeakMap,\n  isWeakSet,\n  isSet,\n} from '../checkers'\nimport { defaults } from '../defaults'\nimport { applyMiddleware } from '../middleware'\n\nconst sleep = (d = 100) => new Promise((resolve) => setTimeout(resolve, d))\n\ndescribe('array', () => {\n  test('toArr', () => {\n    expect(isEqual(toArr([123]), [123])).toBeTruthy()\n    expect(isEqual(toArr(123), [123])).toBeTruthy()\n    expect(isEqual(toArr(null), [])).toBeTruthy()\n  })\n\n  test('some', () => {\n    const values1 = [1, 2, 3, 4, 5]\n    const values2 = []\n    const values3 = { a: 1, b: 2, c: 3 }\n    const values4 = {}\n    expect(some(values1, (item) => item === 3)).toBeTruthy()\n    expect(some(values1, (item) => item === 6)).toBeFalsy()\n    expect(some(values2, () => true)).toBeFalsy()\n    expect(some(values2, () => false)).toBeFalsy()\n    expect(some(values3, (item) => item === 3)).toBeTruthy()\n    expect(some(values3, (item) => item === 6)).toBeFalsy()\n    expect(some(values4, () => true)).toBeFalsy()\n    expect(some(values4, () => false)).toBeFalsy()\n  })\n\n  test('every', () => {\n    const values1 = [1, 2, 3, 4, 5]\n    const values2 = []\n    const values3 = { a: 1, b: 2, c: 3 }\n    const values4 = {}\n    expect(every(values1, (item) => item < 6)).toBeTruthy()\n    expect(every(values1, (item) => item < 3)).toBeFalsy()\n    expect(every(values2, () => true)).toBeTruthy()\n    expect(every(values2, () => false)).toBeTruthy()\n    expect(every(values2, () => false)).toBeTruthy()\n    expect(every(values3, (item) => item < 6)).toBeTruthy()\n    expect(every(values3, (item) => item < 3)).toBeFalsy()\n    expect(every(values4, () => false)).toBeTruthy()\n    expect(every(values4, () => false)).toBeTruthy()\n  })\n\n  test('findIndex', () => {\n    const value = [1, 2, 3, 4, 5]\n    expect(\n      isEqual(\n        findIndex(value, (item) => item > 3),\n        3\n      )\n    ).toBeTruthy()\n    expect(\n      isEqual(\n        findIndex(value, (item) => item < 3, true),\n        1\n      )\n    ).toBeTruthy()\n    expect(\n      isEqual(\n        findIndex(value, (item) => item > 6),\n        -1\n      )\n    ).toBeTruthy()\n  })\n\n  test('find', () => {\n    const value = [1, 2, 3, 4, 5]\n    expect(\n      isEqual(\n        find(value, (item) => item > 3),\n        4\n      )\n    ).toBeTruthy()\n    expect(\n      isEqual(\n        find(value, (item) => item < 3, true),\n        2\n      )\n    ).toBeTruthy()\n    expect(\n      isEqual(\n        find(value, (item) => item > 6),\n        void 0\n      )\n    ).toBeTruthy()\n  })\n\n  test('includes', () => {\n    const value = [1, 2, 3, 4, 5]\n    expect(includes(value, 3)).toBeTruthy()\n    expect(includes(value, 6)).toBeFalsy()\n    expect(includes('some test string', 'test')).toBeTruthy()\n    expect(includes('some test string', 'test2')).toBeFalsy()\n  })\n\n  test('map', () => {\n    const value = [1, 2, 3, 4, 5]\n    const stringVal = 'some test string'\n    const obj = { k1: 'v1', k2: 'v2' }\n    expect(\n      isEqual(\n        map(value, (item) => item + 1, true),\n        [6, 5, 4, 3, 2]\n      )\n    ).toBeTruthy()\n    expect(\n      isEqual(\n        map(stringVal, (item) => item),\n        stringVal.split('')\n      )\n    ).toBeTruthy()\n    expect(\n      isEqual(\n        map(obj, (item) => `${item}-copy`),\n        { k1: 'v1-copy', k2: 'v2-copy' }\n      )\n    ).toBeTruthy()\n  })\n\n  test('reduce', () => {\n    const value = [1, 2, 3, 4, 5]\n    expect(\n      isEqual(\n        reduce(value, (acc, item) => acc + item, 0, true),\n        15\n      )\n    ).toBeTruthy()\n  })\n})\n\ndescribe('case', () => {\n  test('lowercase', () => {\n    expect(lowerCase('SOME_UPPER_CASE_TEXT')).toEqual('some_upper_case_text')\n    expect(lowerCase('')).toEqual('')\n  })\n})\n\ndescribe('compare', () => {\n  // base\n  expect(isEqual('some test string', 'some test string')).toBeTruthy()\n\n  // array\n  expect(\n    isEqual([{ k1: 'v1' }, { k2: 'v2' }], [{ k1: 'v1' }, { k2: 'v2' }])\n  ).toBeTruthy()\n  expect(isEqual([{ k1: 'v1' }, { k2: 'v2' }], [{ k1: 'v1' }])).toBeFalsy()\n\n  // moment\n  const momentA = moment('2019-11-11', 'YYYY-MM-DD')\n  const momentB = moment('2019-11-10', 'YYYY-MM-DD')\n  expect(isEqual(momentA, {})).toBeFalsy()\n  expect(isEqual(momentA, moment('2019-11-11', 'YYYY-MM-DD'))).toBeTruthy()\n  expect(isEqual(momentA, momentB)).toBeFalsy()\n\n  // immutable\n  const immutableA = ImmutableMap({ key: 'val' })\n  const immutableB = ImmutableMap({ key1: 'val1' })\n  expect(isEqual(immutableA, {})).toBeFalsy()\n  expect(isEqual(immutableA, immutableB)).toBeFalsy()\n  // schema\n  // todo\n  // date\n  const dateA = new Date('2019-11-11')\n  const dateB = new Date('2019-11-10')\n  expect(isEqual(dateA, {})).toBeFalsy()\n  expect(isEqual(dateA, dateB)).toBeFalsy()\n  expect(isEqual(dateA, new Date('2019-11-11'))).toBeTruthy()\n  // regexp\n  const regexpA = new RegExp(/test/)\n  const regexpB = new RegExp(/test2/)\n  expect(isEqual(regexpA, {})).toBeFalsy()\n  expect(isEqual(regexpA, new RegExp(/test/))).toBeTruthy()\n  expect(isEqual(regexpA, regexpB)).toBeFalsy()\n  // URL\n  const urlA = new URL('https://formilyjs.org/')\n  const urlB = new URL('https://www.taobao.com')\n  const urlC = new URL('https://formilyjs.org/')\n  expect(isEqual(urlA, urlC)).toBeTruthy()\n  expect(isEqual(urlA, urlB)).toBeFalsy()\n  // object\n  const objA = { key: 'val' }\n  const objB = { key2: 'val2', key3: 'val3' }\n  const objC = { key2: 'val2' }\n  expect(isEqual(objA, { key: 'val' })).toBeTruthy()\n  expect(isEqual(objA, objB)).toBeFalsy()\n  expect(isEqual(objA, objC)).toBeFalsy()\n  expect(isEqual([11, 22], [33, 44])).toBeFalsy()\n  expect(isEqual([11, 22], {})).toBeFalsy()\n  expect(isEqual(new URL('https://aa.test'), {})).toBeFalsy()\n  expect(instOf(new URL('https://aa.test'), 'URL')).toBeTruthy()\n  expect(instOf(new Date(), 'Date')).toBeTruthy()\n  expect(\n    isEqual(new URL('https://aa.test'), new URL('https://aa.test'))\n  ).toBeTruthy()\n  expect(\n    isEqual(\n      {\n        $$typeof: true,\n        _owner: true,\n        aaa: 123,\n      },\n      {\n        $$typeof: true,\n        _owner: true,\n        aaa: 123,\n      }\n    )\n  ).toBeTruthy()\n  expect(\n    isEqual(\n      {\n        $$typeof: true,\n        _owner: true,\n        aaa: 123,\n      },\n      {\n        $$typeof: true,\n        _owner: true,\n        bbb: 123,\n      }\n    )\n  ).toBeFalsy()\n  expect(\n    isEqual(\n      {\n        $$typeof: true,\n        _owner: true,\n        aaa: 123,\n      },\n      {\n        $$typeof: true,\n        _owner: true,\n        aaa: 333,\n      }\n    )\n  ).toBeFalsy()\n})\n\ndescribe('clone and compare', () => {\n  test('clone form data', () => {\n    let dd = new Map()\n    dd.set('aaa', { bb: 123 })\n    let ee = new WeakMap()\n    ee.set({}, 1)\n    let ff = new WeakSet()\n    ff.add({})\n    let gg = new Set()\n    gg.add(3)\n\n    let a = {\n      aa: 123123,\n      bb: [{ bb: 111 }, { bb: 222 }],\n      cc: () => {\n        // eslint-disable-next-line no-console\n        console.log('123')\n      },\n      dd,\n      ee,\n      ff,\n      gg,\n    }\n    let cloned = clone(a)\n    expect(isEqual(cloned, a)).toBeTruthy()\n    expect(a === cloned).toBeFalsy()\n    expect(a.bb[0] === cloned.bb[0]).toBeFalsy()\n    expect(a.dd === cloned.dd).toBeTruthy()\n    expect(a.dd.get('aaa') === cloned.dd.get('aaa')).toBeTruthy()\n    expect(a.cc === cloned.cc).toBeTruthy()\n    expect(a.ee === cloned.ee).toBeTruthy()\n    expect(a.ff === cloned.ff).toBeTruthy()\n    expect(a.gg === cloned.gg).toBeTruthy()\n    expect(\n      clone({\n        aa: {\n          _isAMomentObject: true,\n        },\n        bb: {\n          _isJSONSchemaObject: true,\n        },\n        cc: {\n          $$typeof: true,\n          _owner: true,\n        },\n        dd: {\n          _isBigNumber: true,\n        },\n      })\n    ).toEqual({\n      aa: {\n        _isAMomentObject: true,\n      },\n      bb: {\n        _isJSONSchemaObject: true,\n      },\n      cc: {\n        $$typeof: true,\n        _owner: true,\n      },\n      dd: {\n        _isBigNumber: true,\n      },\n    })\n    expect(\n      clone({\n        toJS() {\n          return 123\n        },\n      })\n    ).toEqual(123)\n    expect(\n      clone({\n        toJSON() {\n          return 123\n        },\n      })\n    ).toEqual(123)\n  })\n\n  test('native clone', () => {\n    const map = new Map()\n    map.set('key', 123)\n    expect(clone(map) === map).toBeTruthy()\n    const weakMap = new WeakMap()\n    const key = {}\n    weakMap.set(key, 123)\n    expect(clone(weakMap) === weakMap).toBeTruthy()\n    const weakSet = new WeakSet()\n    const key2 = {}\n    weakMap.set(key2, 123)\n    expect(clone(weakSet) === weakSet).toBeTruthy()\n    const set = new Set()\n    expect(clone(set) === set).toBeTruthy()\n    const date = new Date()\n    expect(clone(date) === date).toBeTruthy()\n    // @ts-ignore\n    const file = new File([''], 'filename')\n    expect(clone(file) === file).toBeTruthy()\n    const url = new URL('https://test.com')\n    expect(clone(url) === url).toBeTruthy()\n    const regexp = /\\d+/\n    expect(clone(regexp) === regexp).toBeTruthy()\n    const promise = Promise.resolve(1)\n    expect(clone(promise) === promise).toBeTruthy()\n  })\n\n  test('shallowClone', () => {\n    expect(shallowClone({ aa: 123 })).toEqual({ aa: 123 })\n    expect(shallowClone([123])).toEqual([123])\n    expect(shallowClone(/\\d+/)).toEqual(/\\d+/)\n    expect(shallowClone({ _isAMomentObject: true })).toEqual({\n      _isAMomentObject: true,\n    })\n    expect(\n      shallowClone({\n        _isBigNumber: true,\n      })\n    ).toEqual({\n      _isBigNumber: true,\n    })\n    expect(\n      shallowClone({\n        _isJSONSchemaObject: true,\n      })\n    ).toEqual({\n      _isJSONSchemaObject: true,\n    })\n    expect(\n      shallowClone({\n        $$typeof: true,\n        _owner: true,\n      })\n    ).toEqual({\n      $$typeof: true,\n      _owner: true,\n    })\n    expect(\n      shallowClone({\n        toJS() {\n          return 123\n        },\n      }).toJS()\n    ).toEqual(123)\n    expect(\n      shallowClone({\n        toJSON() {\n          return 123\n        },\n      }).toJSON()\n    ).toEqual(123)\n    expect(shallowClone(1)).toEqual(1)\n  })\n})\n\ndescribe('deprecate', () => {\n  test('deprecate', () => {\n    const test = jest.fn(() => {\n      console.info('### deprecated function called ###')\n    })\n    const deprecatedFn = jest.fn(\n      deprecate(test, 'Some.Deprecated.Api', 'some deprecated error')\n    )\n\n    // arguments - function\n    deprecatedFn()\n    expect(deprecatedFn).toHaveBeenCalledTimes(1)\n    expect(test).toHaveBeenCalledTimes(1)\n\n    // arguments - string\n    const testDeprecatedFn = jest.fn(() =>\n      deprecate('Some.Deprecated.Api', 'some deprecated error')\n    )\n    testDeprecatedFn()\n    expect(testDeprecatedFn).toHaveBeenCalledTimes(1)\n\n    // arguments - empty string\n    const testDeprecatedFn2 = jest.fn(() => deprecate('Some.Deprecated.Api'))\n    testDeprecatedFn2()\n    expect(testDeprecatedFn2).toHaveBeenCalledTimes(1)\n  })\n})\n\ndescribe('isEmpty', () => {\n  test('isValid', () => {\n    // val - undefined\n    expect(isValid(undefined)).toBeFalsy()\n    // val - any\n    expect(isValid(!undefined)).toBeTruthy()\n  })\n\n  test('isEmpty', () => {\n    // val - null\n    expect(isEmpty(null)).toBeTruthy()\n\n    // val - boolean\n    expect(isEmpty(true)).toBeFalsy()\n\n    // val - number\n    expect(isEmpty(2422)).toBeFalsy()\n\n    // val - string\n    expect(isEmpty('some text')).toBeFalsy()\n    expect(isEmpty('')).toBeTruthy()\n\n    // val - function\n    const emptyFunc = function () {}\n    const nonEmptyFunc = function (payload) {\n      console.info(payload)\n    }\n    expect(isEmpty(emptyFunc)).toBeTruthy()\n    expect(isEmpty(nonEmptyFunc)).toBeFalsy()\n\n    // val - arrays\n    expect(isEmpty([])).toBeTruthy()\n    expect(isEmpty([0])).toBeTruthy()\n    expect(isEmpty([''])).toBeTruthy()\n    expect(isEmpty([''], true)).toBeFalsy()\n    expect(isEmpty([0], true)).toBeFalsy()\n    expect(isEmpty([1, 2, 3, 4, 5])).toBeFalsy()\n    expect(isEmpty([0, undefined, null, ''])).toBeTruthy()\n\n    // val - errors\n    expect(isEmpty(new Error())).toBeTruthy()\n    expect(isEmpty(new Error('some error'))).toBeFalsy()\n\n    // val - objects\n    // @ts-ignore\n    const file = new File(['foo'], 'filename.txt', { type: 'text/plain' })\n    // The toString and Object.prototype.toString of the File in the Jest environment are inconsistent\n    file.toString = Object.prototype.toString\n    expect(isEmpty(file)).toBeFalsy()\n    expect(isEmpty(new Map())).toBeTruthy()\n    expect(isEmpty(new Map().set('key', 'val'))).toBeFalsy()\n    expect(isEmpty(new Set())).toBeTruthy()\n    expect(isEmpty(new Set([1, 2]))).toBeFalsy()\n    expect(isEmpty({ key: 'val' })).toBeFalsy()\n    expect(isEmpty({})).toBeTruthy()\n\n    expect(isEmpty(Symbol())).toBeFalsy()\n  })\n})\n\ndescribe('string', () => {\n  test('stringLength', () => {\n    expect(stringLength('🦄some text')).toEqual(10)\n  })\n})\n\ndescribe('shared Subscribable', () => {\n  test('Subscribable', () => {\n    const cb = jest.fn((payload) => payload)\n\n    // defualt subscribable\n    const obj = new Subscribable()\n    const handlerIdx = obj.subscribe(cb)\n    expect(handlerIdx).toEqual(1)\n    obj.notify({ key: 'val' })\n    expect(cb).toHaveBeenCalledTimes(1)\n    expect(cb).toBeCalledWith({ key: 'val' })\n\n    obj.unsubscribe(handlerIdx)\n    obj.notify({ key: 'val' })\n    expect(cb).toHaveBeenCalledTimes(1)\n\n    // subscribable with custom filter\n    const objWithCustomFilter = new Subscribable()\n    const customFilter = (payload) => {\n      payload.key2 = 'val2'\n      return payload\n    }\n    objWithCustomFilter.subscription = {\n      filter: customFilter,\n    }\n    objWithCustomFilter.subscribe(cb)\n    const handlerIdx2 = objWithCustomFilter.subscribe(cb)\n    expect(handlerIdx2).toEqual(2)\n    objWithCustomFilter.notify({ key4: 'val4' })\n    expect(cb).toHaveBeenCalledTimes(3)\n    expect(cb).toBeCalledWith({ key4: 'val4', key2: 'val2' })\n\n    // subscribable with custom notify\n    const objWithCustomNotify = new Subscribable()\n    const customNotify = jest.fn((payload) => {\n      console.info(payload)\n      return false\n    })\n    objWithCustomNotify.subscription = {\n      notify: customNotify,\n    }\n    objWithCustomNotify.subscribe(cb)\n    objWithCustomNotify.notify({ key3: 'val3' })\n    expect(customNotify).toBeCalledTimes(1)\n    objWithCustomNotify.unsubscribe()\n  })\n})\n\ndescribe('types', () => {\n  test('isFn', () => {\n    const normalFunction = function normalFn() {}\n    const asyncFunction = async function asyncFn() {}\n    const generatorFunction = function* generatorFn() {}\n    expect(isFn(() => {})).toBeTruthy()\n    expect(isFn(normalFunction)).toBeTruthy()\n    expect(isFn(asyncFunction)).toBeTruthy()\n    expect(isFn(generatorFunction)).toBeTruthy()\n    expect(isFn('')).toBeFalsy()\n    expect(isFn(undefined)).toBeFalsy()\n    expect(isFn(['🦄'])).toBeFalsy()\n  })\n  test('isNumberLike', () => {\n    expect(isNumberLike(123)).toBeTruthy()\n    expect(isNumberLike('123')).toBeTruthy()\n    expect(isNumberLike('aa')).toBeFalsy()\n  })\n  test('isReactElement', () => {\n    expect(isReactElement({ $$typeof: true, _owner: true })).toBeTruthy()\n  })\n  test('isHTMLElement', () => {\n    // @ts-ignore\n    expect(isHTMLElement(document.createElement('div'))).toBeTruthy()\n  })\n  test('isMap', () => {\n    expect(isMap(new Map())).toBeTruthy()\n  })\n  test('isSet', () => {\n    expect(isSet(new Set())).toBeTruthy()\n  })\n  test('isWeakMap', () => {\n    expect(isWeakMap(new WeakMap())).toBeTruthy()\n    expect(isWeakMap(new Map())).toBeFalsy()\n  })\n  test('isWeakSet', () => {\n    expect(isWeakSet(new WeakSet())).toBeTruthy()\n    expect(isWeakSet(new Set())).toBeFalsy()\n  })\n})\n\ndescribe('merge', () => {\n  test('assign', () => {\n    const target = {\n      aa: {\n        bb: {\n          cc: {\n            dd: 123,\n          },\n        },\n      },\n    }\n    const source = {\n      aa: {\n        bb: {\n          cc: {\n            ee: '1234',\n          },\n        },\n      },\n    }\n\n    expect(\n      merge(target, source, {\n        assign: true,\n      })\n    ).toEqual({\n      aa: {\n        bb: {\n          cc: {\n            dd: 123,\n            ee: '1234',\n          },\n        },\n      },\n    })\n    expect(target).toEqual({\n      aa: {\n        bb: {\n          cc: {\n            dd: 123,\n            ee: '1234',\n          },\n        },\n      },\n    })\n    expect(\n      merge(\n        {\n          react: {\n            $$typeof: true,\n            _owner: true,\n            aa: 123,\n          },\n        },\n        {\n          react: {\n            $$typeof: true,\n            _owner: true,\n            bb: 321,\n          },\n        },\n        {\n          assign: true,\n        }\n      )\n    ).toEqual({\n      react: {\n        $$typeof: true,\n        _owner: true,\n        bb: 321,\n      },\n    })\n    expect(\n      merge(\n        {\n          react: {\n            _isAMomentObject: true,\n            aa: 123,\n          },\n        },\n        {\n          react: {\n            _isAMomentObject: true,\n            bb: 321,\n          },\n        },\n        {\n          assign: true,\n        }\n      )\n    ).toEqual({\n      react: {\n        _isAMomentObject: true,\n        bb: 321,\n      },\n    })\n    expect(\n      merge(\n        {\n          react: {\n            _isJSONSchemaObject: true,\n            aa: 123,\n          },\n        },\n        {\n          react: {\n            _isJSONSchemaObject: true,\n            bb: 321,\n          },\n        },\n        {\n          assign: true,\n        }\n      )\n    ).toEqual({\n      react: {\n        _isJSONSchemaObject: true,\n        bb: 321,\n      },\n    })\n    expect(\n      merge(\n        {\n          react: {\n            _isBigNumber: true,\n            c: [1, 234567890123],\n            e: 0,\n            s: 1,\n          },\n        },\n        {\n          react: {\n            _isBigNumber: true,\n            c: [2, 345678901234],\n            e: 1,\n            s: 0,\n          },\n        },\n        {\n          assign: true,\n        }\n      )\n    ).toEqual({\n      react: {\n        _isBigNumber: true,\n        c: [2, 345678901234],\n        e: 1,\n        s: 0,\n      },\n    })\n    const toJSObj = {\n      toJS: () => {},\n      bb: 321,\n    }\n    expect(\n      merge(\n        {\n          toJSObj: {\n            toJS: () => {},\n            aa: 123,\n          },\n        },\n        {\n          toJSObj,\n        },\n        {\n          assign: true,\n        }\n      )\n    ).toEqual({\n      toJSObj,\n    })\n    const toJSONObj = {\n      toJSON: () => {},\n      bb: 321,\n    }\n    expect(\n      merge(\n        {\n          toJSONObj: {\n            toJS: () => {},\n            aa: 123,\n          },\n        },\n        {\n          toJSONObj,\n        },\n        {\n          assign: true,\n        }\n      )\n    ).toEqual({\n      toJSONObj,\n    })\n  })\n\n  test('empty', () => {\n    expect(\n      merge(\n        {\n          aa: undefined,\n        },\n        {\n          aa: {},\n        }\n      )\n    ).toEqual({ aa: {} })\n  })\n\n  test('clone', () => {\n    const target = {\n      aa: {\n        bb: {\n          cc: {\n            dd: 123,\n          },\n        },\n      },\n    }\n    const source = {\n      aa: {\n        bb: {\n          cc: {\n            ee: '1234',\n          },\n        },\n      },\n    }\n\n    expect(merge(target, source)).toEqual({\n      aa: {\n        bb: {\n          cc: {\n            dd: 123,\n            ee: '1234',\n          },\n        },\n      },\n    })\n    expect(target).toEqual({\n      aa: {\n        bb: {\n          cc: {\n            dd: 123,\n          },\n        },\n      },\n    })\n  })\n  test('merge array', () => {\n    expect(merge([11, 22], [333])).toEqual([11, 22, 333])\n  })\n  test('merge custom', () => {\n    expect(\n      merge(\n        { aa: { cc: 123 } },\n        { aa: { bb: 321 } },\n        {\n          customMerge() {\n            return (a, b) => ({ ...a, ...b })\n          },\n        }\n      )\n    ).toEqual({ aa: { cc: 123, bb: 321 } })\n  })\n  test('merge symbols', () => {\n    const symbol = Symbol('xxx')\n    expect(merge({ [symbol]: 123 }, { aa: 321 })).toEqual({\n      [symbol]: 123,\n      aa: 321,\n    })\n\n    const getOwnPropertySymbols = Object.getOwnPropertySymbols\n    Object.getOwnPropertySymbols = null\n    const mergedObject = merge({ [symbol]: 123 }, { aa: 321 })\n    Object.getOwnPropertySymbols = getOwnPropertySymbols\n\n    expect(mergedObject).toEqual({\n      aa: 321,\n    })\n  })\n  test('merge unmatch', () => {\n    expect(merge({ aa: 123 }, [111])).toEqual([111])\n  })\n\n  test('lazy merge', () => {\n    const merge1 = lazyMerge<any>(1, 2)\n    expect(merge1).toBe(2)\n    const merge2 = lazyMerge<any>('123', '321')\n    expect(merge2).toBe('321')\n    const merge3 = lazyMerge<any>(1, undefined)\n    expect(merge3).toBe(1)\n    const merge4 = lazyMerge<any>('123', undefined)\n    expect(merge4).toBe('123')\n    const merge5 = lazyMerge<any>(undefined, '123')\n    expect(merge5).toBe('123')\n    const merge6 = lazyMerge([1, 2, 3], [3, 4])\n    expect(merge6[0]).toBe(3)\n    expect(merge6[1]).toBe(4)\n    expect(merge6[2]).toBe(3)\n    const merge7 = lazyMerge<any>(\n      {\n        get x() {\n          return 'x'\n        },\n      },\n      {\n        get y() {\n          return 'y'\n        },\n      }\n    )\n    expect(merge7.x).toBe('x')\n    expect(merge7.y).toBe('y')\n    const effects = {\n      a: 1,\n      b: 2,\n    }\n    const merge8 = lazyMerge<any>(\n      {\n        get x() {\n          return effects.a\n        },\n      },\n      {\n        get y() {\n          return effects.b\n        },\n      }\n    )\n    expect(merge8.x).toBe(1)\n    expect(merge8.y).toBe(2)\n    effects.a = 123\n    effects.b = 321\n    expect(merge8.x).toBe(123)\n    expect(merge8.y).toBe(321)\n    expect(Object.keys(merge8)).toEqual(['x', 'y'])\n    expect('x' in merge8).toBe(true)\n    expect('y' in merge8).toBe(true)\n    expect('z' in merge8).toBe(false)\n    const merge9Source = { a: 1 }\n    const merge9Target = { b: 2 }\n\n    const merge9 = lazyMerge<any>(merge9Target, merge9Source)\n\n    merge9.a = 2\n    merge9.b = 3\n    merge9.c = 4\n    expect(merge9Source).toEqual({ a: 2, c: 4 })\n    expect(merge9Target).toEqual({ b: 3 })\n  })\n})\n\ndescribe('globalThis', () => {\n  expect(globalThisPolyfill.requestAnimationFrame).not.toBeUndefined()\n})\n\ndescribe('instanceof', () => {\n  test('instOf', () => {\n    expect(instOf(123, 123)).toBeFalsy()\n    expect(instOf('123', '123')).toBeFalsy()\n  })\n})\n\ntest('defaults', () => {\n  const toJSON = () => {}\n  const toJS = () => {}\n  expect(\n    defaults(\n      {\n        aa: {\n          _isAMomentObject: true,\n        },\n        bb: {\n          _isJSONSchemaObject: true,\n        },\n        cc: {\n          $$typeof: true,\n          _owner: true,\n        },\n        dd: {\n          toJSON,\n        },\n        ee: {\n          toJS,\n        },\n        ff: {\n          _isBigNumber: true,\n          toJSON,\n        },\n      },\n      {\n        aa: { value: 111 },\n        bb: { value: 222 },\n        cc: { value: 333 },\n        dd: { value: 444 },\n        ee: { value: 555 },\n        mm: { value: 123 },\n        ff: {\n          value: {\n            c: [1, 234567890123],\n            e: 0,\n            s: 1,\n          },\n        },\n      }\n    )\n  ).toEqual({\n    aa: { value: 111 },\n    bb: { value: 222 },\n    cc: { value: 333 },\n    dd: { value: 444 },\n    ee: { value: 555 },\n    mm: { value: 123 },\n    ff: {\n      value: {\n        c: [1, 234567890123],\n        e: 0,\n        s: 1,\n      },\n    },\n  })\n\n  expect(defaults([1, 2, 3], [0, undefined])).toEqual([0, 2, 3])\n\n  const defaultDate = new RegExp('')\n  // @ts-ignore\n  defaultDate._name = 'name'\n  const date2 = new RegExp('')\n  expect(defaults(defaultDate, date2)._name).toEqual('name')\n})\n\ntest('applyMiddleware', async () => {\n  expect(await applyMiddleware(0)).toEqual(0)\n  expect(\n    await applyMiddleware(0, [\n      (num: number, next) => next(num + 1),\n      (num: number, next) => next(num + 1),\n      (num: number, next) => next(num + 1),\n    ])\n  ).toEqual(3)\n  expect(\n    await applyMiddleware(0, [\n      (num: number, next) => next(),\n      (num: number, next) => next(num + 1),\n      (num: number, next) => next(num + 1),\n    ])\n  ).toEqual(2)\n  const resolved = jest.fn()\n  applyMiddleware(0, [\n    (num: number, next) => next(num + 1),\n    () => '123',\n    (num: number, next) => next(num + 1),\n  ]).then(resolved)\n  await sleep(16)\n  expect(resolved).toBeCalledTimes(0)\n})\n\ntest('applyMiddleware with error', async () => {\n  try {\n    await applyMiddleware(0, [\n      () => {\n        throw 'this is error'\n      },\n    ])\n  } catch (e) {\n    expect(e).toEqual('this is error')\n  }\n})\n\ntest('move', () => {\n  const array1 = [1]\n  move(array1, 1, 0)\n  expect(array1).toEqual([1])\n  move(array1, 0, 1)\n  expect(array1).toEqual([1])\n  move(array1, -1, 1)\n  expect(array1).toEqual([1])\n  move(array1, 0, 3)\n  expect(array1).toEqual([1])\n\n  const array2 = [0, 1, 2]\n  move(array2, 0, 2)\n  expect(array2).toEqual([1, 2, 0])\n  move(array2, 1, 1)\n  expect(array2).toEqual([1, 2, 0])\n\n  const array3 = [0, 1, 2, 3]\n  move(array3, 3, 1)\n  expect(array3).toEqual([0, 3, 1, 2])\n})\n"
  },
  {
    "path": "packages/shared/src/array.ts",
    "content": "import { isArr, isObj, isStr } from './checkers'\n\ntype EachArrayIterator<T> = (currentValue: T, key: number) => void | boolean\ntype EachStringIterator = (currentValue: string, key: number) => void | boolean\ntype EachObjectIterator<T = any> = (\n  currentValue: T,\n  key: string\n) => void | boolean\ntype MapArrayIterator<TItem, TResult> = (\n  currentValue: TItem,\n  key: number\n) => TResult\ntype MapStringIterator<TResult> = (currentValue: string, key: number) => TResult\ntype MapObjectIterator<TItem, TResult> = (\n  currentValue: TItem,\n  key: string\n) => TResult\ntype MemoArrayIterator<T, U> = (\n  previousValue: U,\n  currentValue: T,\n  key: number\n) => U\ntype MemoStringIterator<T> = (\n  previousValue: T,\n  currentValue: string,\n  key: number\n) => T\ntype MemoObjectIterator<TValue, TResult> = (\n  previousValue: TResult,\n  currentValue: TValue,\n  key: string\n) => TResult\n\nexport const toArr = (val: any): any[] => (isArr(val) ? val : val ? [val] : [])\nexport function each(\n  val: string,\n  iterator: EachStringIterator,\n  revert?: boolean\n): void\nexport function each<T>(\n  val: T[],\n  iterator: EachArrayIterator<T>,\n  revert?: boolean\n): void\nexport function each<T extends {}, TValue extends T[keyof T]>(\n  val: T,\n  iterator: EachObjectIterator<TValue>,\n  revert?: boolean\n): void\nexport function each(val: any, iterator: any, revert?: boolean): void {\n  if (isArr(val) || isStr(val)) {\n    if (revert) {\n      for (let i: number = val.length - 1; i >= 0; i--) {\n        if (iterator(val[i], i) === false) {\n          return\n        }\n      }\n    } else {\n      for (let i = 0; i < val.length; i++) {\n        if (iterator(val[i], i) === false) {\n          return\n        }\n      }\n    }\n  } else if (isObj(val)) {\n    let key: string\n    for (key in val) {\n      if (Object.hasOwnProperty.call(val, key)) {\n        if (iterator(val[key], key) === false) {\n          return\n        }\n      }\n    }\n  }\n}\n\nexport function map<T>(\n  val: string,\n  iterator: MapStringIterator<T>,\n  revert?: boolean\n): T[]\nexport function map<TItem, TResult>(\n  val: TItem[],\n  iterator: MapArrayIterator<TItem, TResult>,\n  revert?: boolean\n): TResult[]\nexport function map<T extends {}, TResult>(\n  val: T,\n  iterator: MapObjectIterator<T[keyof T], TResult>,\n  revert?: boolean\n): Record<keyof T, TResult>\nexport function map(val: any, iterator: any, revert?: any): any {\n  const res = isArr(val) || isStr(val) ? [] : {}\n  each(\n    val,\n    (item, key) => {\n      const value = iterator(item, key)\n      if (isArr(res)) {\n        ;(res as any).push(value)\n      } else {\n        res[key] = value\n      }\n    },\n    revert\n  )\n  return res\n}\n\nexport function reduce<T, U>(\n  val: T[],\n  iterator: MemoArrayIterator<T, U>,\n  accumulator?: U,\n  revert?: boolean\n): U\nexport function reduce<T>(\n  val: string,\n  iterator: MemoStringIterator<T>,\n  accumulator?: T,\n  revert?: boolean\n): T\nexport function reduce<T extends {}, TValue extends T[keyof T], TResult = any>(\n  val: T,\n  iterator: MemoObjectIterator<TValue, TResult>,\n  accumulator?: TResult,\n  revert?: boolean\n): TResult\nexport function reduce(\n  val: any,\n  iterator: any,\n  accumulator?: any,\n  revert?: boolean\n): any {\n  let result = accumulator\n  each(\n    val,\n    (item, key) => {\n      result = iterator(result, item, key)\n    },\n    revert\n  )\n  return result\n}\n\nexport function every<T extends string>(\n  val: T,\n  iterator: EachStringIterator,\n  revert?: boolean\n): boolean\nexport function every<T>(\n  val: T[],\n  iterator: EachArrayIterator<T>,\n  revert?: boolean\n): boolean\nexport function every<T extends {}>(\n  val: T,\n  iterator: EachObjectIterator,\n  revert?: boolean\n): boolean\nexport function every(val: any, iterator: any, revert?: boolean): boolean {\n  let res = true\n  each(\n    val,\n    (item, key) => {\n      if (!iterator(item, key)) {\n        res = false\n        return false\n      }\n    },\n    revert\n  )\n  return res\n}\n\nexport function some<T extends string>(\n  val: T,\n  iterator: EachStringIterator,\n  revert?: boolean\n): boolean\nexport function some<T>(\n  val: T[],\n  iterator: EachArrayIterator<T>,\n  revert?: boolean\n): boolean\nexport function some<T extends {}>(\n  val: T,\n  iterator: EachObjectIterator,\n  revert?: boolean\n): boolean\nexport function some(val: any, iterator: any, revert?: boolean): boolean {\n  let res = false\n  each(\n    val,\n    (item, key) => {\n      if (iterator(item, key)) {\n        res = true\n        return false\n      }\n    },\n    revert\n  )\n  return res\n}\n\nexport function findIndex<T extends string>(\n  val: T,\n  iterator: EachStringIterator,\n  revert?: boolean\n): number\nexport function findIndex<T>(\n  val: T[],\n  iterator: EachArrayIterator<T>,\n  revert?: boolean\n): number\nexport function findIndex<T extends {}>(\n  val: T,\n  iterator: EachObjectIterator,\n  revert?: boolean\n): keyof T\nexport function findIndex(\n  val: any,\n  iterator: any,\n  revert?: boolean\n): string | number {\n  let res: number | string = -1\n  each(\n    val,\n    (item, key) => {\n      if (iterator(item, key)) {\n        res = key\n        return false\n      }\n    },\n    revert\n  )\n  return res\n}\n\nexport function find<T extends string>(\n  val: T,\n  iterator: EachStringIterator,\n  revert?: boolean\n): any\nexport function find<T>(\n  val: T[],\n  iterator: EachArrayIterator<T>,\n  revert?: boolean\n): T\nexport function find<T extends {}>(\n  val: T,\n  iterator: EachObjectIterator,\n  revert?: boolean\n): T[keyof T]\nexport function find(val: any, iterator: any, revert?: boolean): any {\n  let res: any\n  each(\n    val,\n    (item, key) => {\n      if (iterator(item, key)) {\n        res = item\n        return false\n      }\n    },\n    revert\n  )\n  return res\n}\n\nexport function includes<T extends string>(\n  val: T,\n  searchElement: string,\n  revert?: boolean\n): boolean\nexport function includes<T>(\n  val: T[],\n  searchElement: T,\n  revert?: boolean\n): boolean\nexport function includes(val: any, searchElement: any, revert?: boolean) {\n  if (isStr(val)) return val.includes(searchElement)\n  return some(val, (item) => item === searchElement, revert)\n}\n\nexport function move<T extends any>(\n  array: T[],\n  fromIndex: number,\n  toIndex: number\n) {\n  if (fromIndex === toIndex) return array\n\n  if (\n    toIndex < 0 ||\n    fromIndex < 0 ||\n    toIndex > array.length - 1 ||\n    fromIndex > array.length - 1\n  ) {\n    return array\n  }\n\n  if (fromIndex < toIndex) {\n    const fromItem = array[fromIndex]\n    for (let index = fromIndex; index < toIndex; index++) {\n      array[index] = array[index + 1]\n    }\n    array[toIndex] = fromItem\n  } else {\n    const fromItem = array[fromIndex]\n    for (let index = fromIndex; index > toIndex; index--) {\n      array[index] = array[index - 1]\n    }\n    array[toIndex] = fromItem\n  }\n  return array\n}\n"
  },
  {
    "path": "packages/shared/src/case.ts",
    "content": "import { camelCase } from 'camel-case'\nimport { pascalCase } from 'pascal-case'\nimport { lowerCase } from 'lower-case'\nimport { upperCase } from 'upper-case'\nimport { paramCase } from 'param-case'\n\nexport { lowerCase, upperCase, camelCase, pascalCase, paramCase }\n"
  },
  {
    "path": "packages/shared/src/checkers.ts",
    "content": "const toString = Object.prototype.toString\nconst isType =\n  <T>(type: string | string[]) =>\n  (obj: unknown): obj is T =>\n    getType(obj) === `[object ${type}]`\nexport const getType = (obj: any) => toString.call(obj)\nexport const isFn = (val: any): val is Function => typeof val === 'function'\nexport const isArr = Array.isArray\nexport const isPlainObj = isType<object>('Object')\nexport const isStr = isType<string>('String')\nexport const isBool = isType<boolean>('Boolean')\nexport const isNum = isType<number>('Number')\nexport const isMap = (val: any): val is Map<any, any> =>\n  val && val instanceof Map\nexport const isSet = (val: any): val is Set<any> => val && val instanceof Set\nexport const isWeakMap = (val: any): val is WeakMap<any, any> =>\n  val && val instanceof WeakMap\nexport const isWeakSet = (val: any): val is WeakSet<any> =>\n  val && val instanceof WeakSet\nexport const isNumberLike = (index: any): index is number =>\n  isNum(index) || /^\\d+$/.test(index)\nexport const isObj = (val: unknown): val is object => typeof val === 'object'\nexport const isRegExp = isType<RegExp>('RegExp')\nexport const isReactElement = (obj: any): boolean =>\n  obj && obj['$$typeof'] && obj['_owner']\nexport const isHTMLElement = (target: any): target is EventTarget => {\n  return Object.prototype.toString.call(target).indexOf('HTML') > -1\n}\n\nexport type Subscriber<S> = (payload: S) => void\n\nexport interface Subscription<S> {\n  notify?: (payload: S) => void | boolean\n  filter?: (payload: S) => any\n}\n"
  },
  {
    "path": "packages/shared/src/clone.ts",
    "content": "import { isFn, isPlainObj } from './checkers'\n\nexport const shallowClone = (values: any) => {\n  if (Array.isArray(values)) {\n    return values.slice(0)\n  } else if (isPlainObj(values)) {\n    if ('$$typeof' in values && '_owner' in values) {\n      return values\n    }\n    if (values['_isBigNumber']) {\n      return values\n    }\n    if (values['_isAMomentObject']) {\n      return values\n    }\n    if (values['_isJSONSchemaObject']) {\n      return values\n    }\n    if (isFn(values['toJS'])) {\n      return values\n    }\n    if (isFn(values['toJSON'])) {\n      return values\n    }\n    return {\n      ...values,\n    }\n  } else if (typeof values === 'object') {\n    return new values.constructor(values)\n  }\n  return values\n}\n\nexport const clone = (values: any) => {\n  if (Array.isArray(values)) {\n    const res = []\n    values.forEach((item) => {\n      res.push(clone(item))\n    })\n    return res\n  } else if (isPlainObj(values)) {\n    if ('$$typeof' in values && '_owner' in values) {\n      return values\n    }\n    if (values['_isBigNumber']) {\n      return values\n    }\n    if (values['_isAMomentObject']) {\n      return values\n    }\n    if (values['_isJSONSchemaObject']) {\n      return values\n    }\n    if (isFn(values['toJS'])) {\n      return values['toJS']()\n    }\n    if (isFn(values['toJSON'])) {\n      return values['toJSON']()\n    }\n    const res = {}\n    for (const key in values) {\n      if (Object.hasOwnProperty.call(values, key)) {\n        res[key] = clone(values[key])\n      }\n    }\n    return res\n  } else {\n    return values\n  }\n}\n"
  },
  {
    "path": "packages/shared/src/compare.ts",
    "content": "import { isArr } from './checkers'\nimport { instOf } from './instanceof'\nconst isArray = isArr\nconst keyList = Object.keys\nconst hasProp = Object.prototype.hasOwnProperty\n\n/* eslint-disable */\nfunction equal(a: any, b: any) {\n  // fast-deep-equal index.js 2.0.1\n  if (a === b) {\n    return true\n  }\n\n  if (a && b && typeof a === 'object' && typeof b === 'object') {\n    const arrA = isArray(a)\n    const arrB = isArray(b)\n    let i: number\n    let length: number\n    let key: string | number\n\n    if (arrA && arrB) {\n      length = a.length\n      if (length !== b.length) {\n        return false\n      }\n      for (i = length; i-- !== 0; ) {\n        if (!equal(a[i], b[i])) {\n          return false\n        }\n      }\n      return true\n    }\n\n    if (arrA !== arrB) {\n      return false\n    }\n    const momentA = a && a._isAMomentObject\n    const momentB = b && b._isAMomentObject\n    if (momentA !== momentB) return false\n    if (momentA && momentB) return a.isSame(b)\n    const immutableA = a && a.toJS\n    const immutableB = b && b.toJS\n    if (immutableA !== immutableB) return false\n    if (immutableA) return a.is ? a.is(b) : a === b\n    const dateA = instOf(a, 'Date')\n    const dateB = instOf(b, 'Date')\n    if (dateA !== dateB) {\n      return false\n    }\n    if (dateA && dateB) {\n      return a.getTime() === b.getTime()\n    }\n    const regexpA = instOf(a, 'RegExp')\n    const regexpB = instOf(b, 'RegExp')\n    if (regexpA !== regexpB) {\n      return false\n    }\n    if (regexpA && regexpB) {\n      return a.toString() === b.toString()\n    }\n    const urlA = instOf(a, 'URL')\n    const urlB = instOf(b, 'URL')\n\n    if (urlA !== urlB) {\n      return false\n    }\n\n    if (urlA && urlB) {\n      return a.href === b.href\n    }\n\n    const schemaA = a && a.toJSON\n    const schemaB = b && b.toJSON\n    if (schemaA !== schemaB) return false\n    if (schemaA && schemaB) return equal(a.toJSON(), b.toJSON())\n\n    const keys = keyList(a)\n    length = keys.length\n\n    if (length !== keyList(b).length) {\n      return false\n    }\n\n    for (i = length; i-- !== 0; ) {\n      if (!hasProp.call(b, keys[i])) {\n        return false\n      }\n    }\n    // end fast-deep-equal\n\n    // Custom handling for React\n    for (i = length; i-- !== 0; ) {\n      key = keys[i]\n\n      if (key === '_owner' && a.$$typeof) {\n        // React-specific: avoid traversing React elements' _owner.\n        //  _owner contains circular references\n        // and is not needed when comparing the actual elements (and not their owners)\n        // .$$typeof and ._store on just reasonable markers of a react element\n        continue\n      } else {\n        // all other properties should be traversed as usual\n        if (!equal(a[key], b[key])) {\n          return false\n        }\n      }\n    }\n\n    // fast-deep-equal index.js 2.0.1\n    return true\n  }\n\n  return a !== a && b !== b\n}\n// end fast-deep-equal\n\nexport const isEqual = function exportedEqual(a: any, b: any) {\n  try {\n    return equal(a, b)\n  } catch (error) {\n    /* istanbul ignore next */\n    if (\n      (error.message && error.message.match(/stack|recursion/i)) ||\n      error.number === -2146828260\n    ) {\n      // warn on circular references, don't crash\n      // browsers give this different errors name and messages:\n      // chrome/safari: \"RangeError\", \"Maximum call stack size exceeded\"\n      // firefox: \"InternalError\", too much recursion\"\n      // edge: \"Error\", \"Out of stack space\"\n      console.warn(\n        'Warning: react-fast-compare does not handle circular references.',\n        error.name,\n        error.message\n      )\n      return false\n    }\n    // some other error. we should definitely know about these\n    /* istanbul ignore next */\n    throw error\n  }\n}\n"
  },
  {
    "path": "packages/shared/src/defaults.ts",
    "content": "import { each } from './array'\nimport { isEmpty, isValid } from './isEmpty'\nimport { getType, isArr, isPlainObj } from './checkers'\n\nconst isUnNormalObject = (value: any) => {\n  if (value?._owner && value?.$$typeof) {\n    return true\n  }\n  if (value?._isAMomentObject || value?._isJSONSchemaObject) {\n    return true\n  }\n  if (value?.toJS || value?.toJSON) {\n    return true\n  }\n}\n\nconst isEnumerableObject = (val: any) => {\n  if (isUnNormalObject(val)) {\n    return false\n  }\n  return typeof val === 'object'\n}\n\n/**\n *\n * @param defaults\n * @param targets\n */\nexport const defaults = (defaults_: any, targets: any) => {\n  if (\n    getType(defaults_) !== getType(targets) ||\n    !isEnumerableObject(defaults_) ||\n    !isEnumerableObject(targets)\n  ) {\n    return !isEmpty(targets) ? targets : defaults_\n  } else {\n    const results = isArr(defaults_)\n      ? []\n      : isPlainObj(defaults_)\n      ? {}\n      : defaults_\n    each(targets, (value, key) => {\n      results[key] = defaults(defaults_[key], value)\n    })\n    each(defaults_, (value, key) => {\n      if (!isValid(results[key])) {\n        results[key] = value\n      }\n    })\n    return results\n  }\n}\n"
  },
  {
    "path": "packages/shared/src/deprecate.ts",
    "content": "import { isFn, isStr } from './checkers'\n\nconst caches = {}\n\nexport function deprecate<P1 = any, P2 = any, P3 = any, P4 = any, P5 = any>(\n  method: any,\n  message?: string,\n  help?: string\n) {\n  if (isFn(method)) {\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    return function (p1?: P1, p2?: P2, p3?: P3, p4?: P4, p5?: P5) {\n      deprecate(message, help)\n      return method.apply(this, arguments)\n    }\n  }\n  if (isStr(method) && !caches[method]) {\n    caches[method] = true\n    console.warn(\n      new Error(\n        `${method} has been deprecated. Do not continue to use this api.${\n          message || ''\n        }`\n      )\n    )\n  }\n}\n"
  },
  {
    "path": "packages/shared/src/global.ts",
    "content": "/* istanbul ignore next */\nfunction globalSelf() {\n  try {\n    if (typeof self !== 'undefined') {\n      return self\n    }\n  } catch (e) {}\n  try {\n    if (typeof window !== 'undefined') {\n      return window\n    }\n  } catch (e) {}\n  try {\n    if (typeof global !== 'undefined') {\n      return global\n    }\n  } catch (e) {}\n  return Function('return this')()\n}\nexport const globalThisPolyfill: Window = globalSelf()\n"
  },
  {
    "path": "packages/shared/src/index.ts",
    "content": "export * from './array'\nexport * from './compare'\nexport * from './checkers'\nexport * from './clone'\nexport * from './isEmpty'\nexport * from './case'\nexport * from './string'\nexport * from './global'\nexport * from './path'\nexport * from './deprecate'\nexport * from './subscribable'\nexport * from './middleware'\nexport * from './merge'\nexport * from './instanceof'\nexport * from './defaults'\nexport * from './uid'\n"
  },
  {
    "path": "packages/shared/src/instanceof.ts",
    "content": "import { globalThisPolyfill } from './global'\nimport { isStr, isFn } from './checkers'\nexport const instOf = (value: any, cls: any) => {\n  if (isFn(cls)) return value instanceof cls\n  if (isStr(cls)) {\n    return globalThisPolyfill[cls]\n      ? value instanceof globalThisPolyfill[cls]\n      : false\n  }\n  return false\n}\n"
  },
  {
    "path": "packages/shared/src/isEmpty.ts",
    "content": "import { instOf } from './instanceof'\nconst has = Object.prototype.hasOwnProperty\n\nconst toString = Object.prototype.toString\n\nexport const isUndef = (val: any) => val === undefined\n\nexport const isValid = (val: any) => val !== undefined && val !== null\n\nexport function isEmpty(val: any, strict = false): boolean {\n  // Null and Undefined...\n  if (val == null) {\n    return true\n  }\n\n  // Booleans...\n  if (typeof val === 'boolean') {\n    return false\n  }\n\n  // Numbers...\n  if (typeof val === 'number') {\n    return false\n  }\n\n  // Strings...\n  if (typeof val === 'string') {\n    return val.length === 0\n  }\n\n  // Functions...\n  if (typeof val === 'function') {\n    return val.length === 0\n  }\n\n  // Arrays...\n  if (Array.isArray(val)) {\n    if (val.length === 0) {\n      return true\n    }\n    for (let i = 0; i < val.length; i++) {\n      if (strict) {\n        if (val[i] !== undefined && val[i] !== null) {\n          return false\n        }\n      } else {\n        if (\n          val[i] !== undefined &&\n          val[i] !== null &&\n          val[i] !== '' &&\n          val[i] !== 0\n        ) {\n          return false\n        }\n      }\n    }\n    return true\n  }\n\n  // Errors...\n  if (instOf(val, 'Error')) {\n    return val.message === ''\n  }\n\n  // Objects...\n  if (val.toString === toString) {\n    switch (val.toString()) {\n      // Maps, Sets, Files and Errors...\n      case '[object File]':\n      case '[object Map]':\n      case '[object Set]': {\n        return val.size === 0\n      }\n\n      // Plain objects...\n      case '[object Object]': {\n        for (const key in val) {\n          if (has.call(val, key)) {\n            return false\n          }\n        }\n\n        return true\n      }\n    }\n  }\n\n  // Anything else...\n  return false\n}\n"
  },
  {
    "path": "packages/shared/src/merge.ts",
    "content": "import { isFn, isPlainObj } from './checkers'\nimport { isEmpty, isValid } from './isEmpty'\n\nfunction defaultIsMergeableObject(value: any) {\n  return isNonNullObject(value) && !isSpecial(value)\n}\n\nfunction isNonNullObject(value: any) {\n  // TODO: value !== null && typeof value === 'object'\n  return Boolean(value) && typeof value === 'object'\n}\n\nfunction isSpecial(value: any) {\n  // TODO: use isComplexObject()\n  if ('$$typeof' in value && '_owner' in value) {\n    return true\n  }\n  if (value._isAMomentObject) {\n    return true\n  }\n  if (value._isJSONSchemaObject) {\n    return true\n  }\n  if (isFn(value.toJS)) {\n    return true\n  }\n  if (isFn(value.toJSON)) {\n    return true\n  }\n  return !isPlainObj(value)\n}\n\nfunction emptyTarget(val: any) {\n  return Array.isArray(val) ? [] : {}\n}\n// @ts-ignore\nfunction cloneUnlessOtherwiseSpecified(value: any, options: Options) {\n  if (options.clone !== false && options.isMergeableObject?.(value)) {\n    return deepmerge(emptyTarget(value), value, options)\n  }\n  return value\n}\n\nfunction defaultArrayMerge(target: any, source: any, options: Options) {\n  return target.concat(source).map(function (element: any) {\n    return cloneUnlessOtherwiseSpecified(element, options)\n  })\n}\n\nfunction getMergeFunction(key: string, options: Options) {\n  if (!options.customMerge) {\n    return deepmerge\n  }\n  const customMerge = options.customMerge(key)\n  return typeof customMerge === 'function' ? customMerge : deepmerge\n}\n\nfunction getEnumerableOwnPropertySymbols(target: any): any {\n  return Object.getOwnPropertySymbols\n    ? Object.getOwnPropertySymbols(target).filter(function (symbol) {\n        return target.propertyIsEnumerable(symbol)\n      })\n    : []\n}\n\nfunction getKeys(target: any) {\n  if (!isValid(target)) return []\n  return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))\n}\n\nfunction propertyIsOnObject(object: any, property: any) {\n  /* istanbul ignore next */\n  try {\n    return property in object\n  } catch (_) {\n    return false\n  }\n}\n\n// Protects from prototype poisoning and unexpected merging up the prototype chain.\nfunction propertyIsUnsafe(target: any, key: PropertyKey) {\n  return (\n    propertyIsOnObject(target, key) && // Properties are safe to merge if they don't exist in the target yet,\n    !(\n      Object.hasOwnProperty.call(target, key) && // unsafe if they exist up the prototype chain,\n      Object.propertyIsEnumerable.call(target, key)\n    )\n  ) // and also unsafe if they're nonenumerable.\n}\n\nfunction mergeObject(target: any, source: any, options: Options) {\n  const destination = options.assign ? target || {} : {}\n  if (!options.isMergeableObject(target)) return target\n  if (!options.assign) {\n    getKeys(target).forEach(function (key) {\n      destination[key] = cloneUnlessOtherwiseSpecified(target[key], options)\n    })\n  }\n  getKeys(source).forEach(function (key) {\n    /* istanbul ignore next */\n    if (propertyIsUnsafe(target, key)) {\n      return\n    }\n    if (isEmpty(target[key])) {\n      destination[key] = source[key]\n    } else if (\n      propertyIsOnObject(target, key) &&\n      // @ts-ignore\n      options.isMergeableObject(source[key])\n    ) {\n      destination[key] = getMergeFunction(key, options)(\n        target[key],\n        source[key],\n        options\n      )\n    } else {\n      destination[key] = cloneUnlessOtherwiseSpecified(source[key], options)\n    }\n  })\n  return destination\n}\n\ninterface Options {\n  arrayMerge?(target: any[], source: any[], options?: Options): any[]\n  clone?: boolean\n  assign?: boolean\n  customMerge?: (\n    key: string,\n    options?: Options\n  ) => ((x: any, y: any) => any) | undefined\n  isMergeableObject?(value: object): boolean\n  cloneUnlessOtherwiseSpecified?: (value: any, options: Options) => any\n}\n\n// @ts-ignore\nfunction deepmerge(target: any, source: any, options?: Options) {\n  options = options || {}\n  options.arrayMerge = options.arrayMerge || defaultArrayMerge\n  options.isMergeableObject =\n    options.isMergeableObject || defaultIsMergeableObject\n  // cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()\n  // implementations can use it. The caller may not replace it.\n  options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified\n\n  const sourceIsArray = Array.isArray(source)\n  const targetIsArray = Array.isArray(target)\n  const sourceAndTargetTypesMatch = sourceIsArray === targetIsArray\n\n  if (!sourceAndTargetTypesMatch) {\n    return cloneUnlessOtherwiseSpecified(source, options)\n  } else if (sourceIsArray) {\n    return options.arrayMerge(target, source, options)\n  } else {\n    return mergeObject(target, source, options)\n  }\n}\n\nexport const lazyMerge = <T extends object | Function>(\n  target: T,\n  ...args: T[]\n): any => {\n  const _lazyMerge = <T extends object | Function>(\n    target: T,\n    source: T\n  ): {} => {\n    if (!isValid(source)) return target\n    if (!isValid(target)) return source\n    const isTargetObject = typeof target === 'object'\n    const isSourceObject = typeof source === 'object'\n    const isTargetFn = typeof target === 'function'\n    const isSourceFn = typeof source === 'function'\n    if (!isTargetObject && !isTargetFn) return source\n    if (!isSourceObject && !isSourceFn) return target\n    const getTarget = () => (isTargetFn ? target() : target)\n    const getSource = () => (isSourceFn ? source() : source)\n    const set = (_: object, key: PropertyKey, value: any) => {\n      const source = getSource()\n      const target = getTarget()\n      if (key in source) {\n        // @ts-ignore\n        source[key] = value\n      } else if (key in target) {\n        // @ts-ignore\n        target[key] = value\n      } else {\n        source[key] = value\n      }\n      return true\n    }\n    const get = (_: object, key: PropertyKey) => {\n      const source = getSource()\n      // @ts-ignore\n      if (key in source) {\n        return source[key]\n      }\n      // @ts-ignore\n      return getTarget()[key]\n    }\n    const ownKeys = () => {\n      const source = getSource()\n      const target = getTarget()\n      const keys = Object.keys(target)\n      for (const key in source) {\n        if (!(key in target)) {\n          keys.push(key)\n        }\n      }\n      return keys\n    }\n    const getOwnPropertyDescriptor = (_: object, key: PropertyKey) => ({\n      value: get(_, key),\n      enumerable: true,\n      configurable: true,\n    })\n    const has = (_: object, key: PropertyKey) => {\n      if (key in getSource() || key in getTarget()) return true\n      return false\n    }\n    const getPrototypeOf = () => Object.getPrototypeOf({})\n    return new Proxy(Object.create(null), {\n      set,\n      get,\n      ownKeys,\n      getPrototypeOf,\n      getOwnPropertyDescriptor,\n      has,\n    }) as any\n  }\n  return args.reduce<{}>((buf, arg) => _lazyMerge(buf, arg), target)\n}\n\nexport const merge = deepmerge\n"
  },
  {
    "path": "packages/shared/src/middleware.ts",
    "content": "export interface IMiddleware<Payload = any, Result = any> {\n  (payload: Payload, next: (payload?: Payload) => Result): Result\n}\n\nexport const applyMiddleware = (payload: any, fns: IMiddleware[] = []) => {\n  const compose = (payload: any, fns: IMiddleware[]): Promise<any> => {\n    const prevPayload = payload\n    return Promise.resolve(\n      fns[0](payload, (payload) =>\n        compose(payload ?? prevPayload, fns.slice(1))\n      )\n    )\n  }\n  return new Promise((resolve, reject) => {\n    compose(\n      payload,\n      fns.concat((payload) => {\n        resolve(payload)\n      })\n    ).catch(reject)\n  })\n}\n"
  },
  {
    "path": "packages/shared/src/path.ts",
    "content": "import { Path as FormPath, Pattern as FormPathPattern } from '@formily/path'\n\nexport { FormPath, FormPathPattern }\n"
  },
  {
    "path": "packages/shared/src/string.ts",
    "content": "// ansiRegex\nconst ansiRegex = () => {\n  const pattern = [\n    '[\\\\u001B\\\\u009B][[\\\\]()#;?]*(?:(?:(?:[a-zA-Z\\\\d]*(?:;[a-zA-Z\\\\d]*)*)?\\\\u0007)',\n    '(?:(?:\\\\d{1,4}(?:;\\\\d{0,4})*)?[\\\\dA-PRZcf-ntqry=><~]))',\n  ].join('|')\n\n  return new RegExp(pattern, 'g')\n}\n\n// astralRegex\nconst regex = '[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]'\n\nconst astralRegex = (opts?: { exact: boolean }) =>\n  opts && opts.exact ? new RegExp(`^${regex}$`) : new RegExp(regex, 'g')\n\n// stripAnsi\nconst stripAnsi = (input: any) =>\n  typeof input === 'string' ? input.replace(ansiRegex(), '') : input\n\nexport const stringLength = (input: string) =>\n  stripAnsi(input).replace(astralRegex(), ' ').length\n"
  },
  {
    "path": "packages/shared/src/subscribable.ts",
    "content": "import { isFn, Subscriber, Subscription } from './checkers'\nimport { each } from './array'\n\nexport class Subscribable<Payload = any> {\n  subscribers: {\n    index?: number\n    [key: number]: Subscriber<Payload>\n  } = {\n    index: 0,\n  }\n\n  subscription: Subscription<Payload>\n\n  subscribe = (callback?: Subscriber<Payload>): number => {\n    if (isFn(callback)) {\n      const index: number = this.subscribers.index + 1\n      this.subscribers[index] = callback\n      this.subscribers.index++\n      return index\n    }\n  }\n\n  unsubscribe = (index?: number) => {\n    if (this.subscribers[index]) {\n      delete this.subscribers[index]\n    } else if (!index) {\n      this.subscribers = {\n        index: 0,\n      }\n    }\n  }\n\n  notify = (payload?: Payload, silent?: boolean) => {\n    if (this.subscription) {\n      if (this.subscription && isFn(this.subscription.notify)) {\n        if (this.subscription.notify.call(this, payload) === false) {\n          return\n        }\n      }\n    }\n    if (silent) return\n    const filter = (payload: Payload) => {\n      if (this.subscription && isFn(this.subscription.filter)) {\n        return this.subscription.filter.call(this, payload)\n      }\n      return payload\n    }\n    each(this.subscribers, (callback: any) => {\n      if (isFn(callback)) callback(filter(payload))\n    })\n  }\n}\n"
  },
  {
    "path": "packages/shared/src/uid.ts",
    "content": "let IDX = 36,\n  HEX = ''\nwhile (IDX--) HEX += IDX.toString(36)\n\nexport function uid(len?: number) {\n  let str = '',\n    num = len || 11\n  while (num--) str += HEX[(Math.random() * 36) | 0]\n  return str\n}\n"
  },
  {
    "path": "packages/shared/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*\", \"devtools/*\"]\n    },\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/shared/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"include\": [\"./src/**/*.ts\", \"./src/**/*.tsx\"],\n  \"exclude\": [\"./src/__tests__/*\", \"./esm/*\", \"./lib/*\"],\n  \"compilerOptions\": {\n    \"lib\": [\"ESNext\", \"DOM\"]\n  }\n}\n"
  },
  {
    "path": "packages/validator/.npmignore",
    "content": "node_modules\n*.log\nbuild\ndocs\ndoc-site\n__tests__\n.eslintrc\njest.config.js\ntsconfig.json\n.umi\nsrc"
  },
  {
    "path": "packages/validator/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-present, Alibaba Group Holding Limited. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "packages/validator/README.md",
    "content": "# @formily/validator\n\n> Formily 数据校验工具\n"
  },
  {
    "path": "packages/validator/package.json",
    "content": "{\n  \"name\": \"@formily/validator\",\n  \"version\": \"2.3.7\",\n  \"license\": \"MIT\",\n  \"main\": \"lib\",\n  \"module\": \"esm\",\n  \"umd:main\": \"dist/formily.validator.umd.production.js\",\n  \"unpkg\": \"dist/formily.validator.umd.production.js\",\n  \"jsdelivr\": \"dist/formily.validator.umd.production.js\",\n  \"jsnext:main\": \"esm\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/alibaba/formily.git\"\n  },\n  \"types\": \"esm/index.d.ts\",\n  \"bugs\": {\n    \"url\": \"https://github.com/alibaba/formily/issues\"\n  },\n  \"homepage\": \"https://github.com/alibaba/formily#readme\",\n  \"engines\": {\n    \"npm\": \">=3.0.0\"\n  },\n  \"scripts\": {\n    \"build\": \"rimraf -rf lib esm dist lib && npm run build:cjs && npm run build:esm && npm run build:umd\",\n    \"build:cjs\": \"tsc --project tsconfig.build.json\",\n    \"build:esm\": \"tsc --project tsconfig.build.json --module es2015 --outDir esm\",\n    \"build:umd\": \"rollup --config\"\n  },\n  \"dependencies\": {\n    \"@formily/shared\": \"2.3.7\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"gitHead\": \"ac79c196ae9324889aca5e0501146f9b37b04283\"\n}\n"
  },
  {
    "path": "packages/validator/rollup.config.js",
    "content": "import baseConfig from '../../scripts/rollup.base.js'\n\nexport default baseConfig('formily.validator', 'Formily.Validator')\n"
  },
  {
    "path": "packages/validator/src/__tests__/parser.spec.ts",
    "content": "import { parseValidatorDescriptions } from '../parser'\n\ndescribe('parseValidatorDescriptions', () => {\n  test('basic', () => {\n    expect(parseValidatorDescriptions('date')).toEqual([{ format: 'date' }])\n    const validator = () => {\n      return ''\n    }\n    expect(parseValidatorDescriptions(validator)).toEqual([{ validator }])\n    expect(parseValidatorDescriptions(['date'])).toEqual([{ format: 'date' }])\n    expect(parseValidatorDescriptions([validator])).toEqual([{ validator }])\n    expect(parseValidatorDescriptions({ format: 'date' })).toEqual([\n      { format: 'date' },\n    ])\n    expect(parseValidatorDescriptions({ validator })).toEqual([{ validator }])\n  })\n})\n"
  },
  {
    "path": "packages/validator/src/__tests__/registry.spec.ts",
    "content": "import {\n  getValidateLocaleIOSCode,\n  getLocaleByPath,\n  getValidateLocale,\n  setValidateLanguage,\n} from '../'\nimport locale from '../locale'\n\ntest('getValidateLocaleIOSCode', () => {\n  expect(getValidateLocaleIOSCode('zh-CN')).toEqual('zh-CN')\n  expect(getValidateLocaleIOSCode('zh')).toEqual('zh')\n  expect(getValidateLocaleIOSCode('ZH')).toEqual('zh')\n  expect(getValidateLocaleIOSCode('cn')).toEqual('zh-CN')\n  expect(getValidateLocaleIOSCode('en')).toEqual('en')\n  expect(getValidateLocaleIOSCode('TW')).toEqual('zh-TW')\n})\n\ntest('getLocaleByPath', () => {\n  expect(getLocaleByPath('pattern', 'vi')).toEqual(locale.en.pattern)\n  expect(getLocaleByPath('pattern')).toEqual(locale.en.pattern)\n})\n\ntest('getValidateLocale', () => {\n  setValidateLanguage('vi')\n  expect(getValidateLocale('pattern')).toEqual(locale.en.pattern)\n})\n"
  },
  {
    "path": "packages/validator/src/__tests__/validator.spec.ts",
    "content": "import {\n  validate,\n  registerValidateRules,\n  registerValidateFormats,\n  setValidateLanguage,\n  registerValidateMessageTemplateEngine,\n} from '../index'\n\nregisterValidateRules({\n  custom: (value) => (value === '123' ? 'custom error' : ''),\n  customBool: () => false,\n  customBool2: () => true,\n})\n\nregisterValidateFormats({\n  custom: /^[\\u4e00-\\u9fa5]+$/,\n})\n\nconst hasError = (results: any, message?: string) => {\n  if (!message) {\n    return expect(results?.error?.[0]).not.toBeUndefined()\n  }\n  return expect(results?.error?.[0]).toEqual(message)\n}\n\nconst noError = (results: any) => {\n  return expect(results?.error?.[0]).toBeUndefined()\n}\n\ntest('empty string validate', async () => {\n  const results = await validate('', { required: true })\n  expect(results).toEqual({\n    error: ['The field value is required'],\n    success: [],\n    warning: [],\n  })\n})\n\ntest('empty array validate', async () => {\n  const results = await validate([], { required: true })\n  expect(results).toEqual({\n    error: ['The field value is required'],\n    success: [],\n    warning: [],\n  })\n  noError(await validate([''], { required: true }))\n})\n\ntest('empty object validate', async () => {\n  const results = await validate({}, { required: true })\n  expect(results).toEqual({\n    error: ['The field value is required'],\n    success: [],\n    warning: [],\n  })\n})\n\ntest('empty number validate', async () => {\n  const results = await validate(0, { required: true })\n  expect(results).toEqual({\n    error: [],\n    success: [],\n    warning: [],\n  })\n})\n\ntest('multi validate', async () => {\n  const results = await validate('', {\n    required: true,\n    validator() {\n      return 'validate error'\n    },\n  })\n  expect(results).toEqual({\n    error: ['The field value is required', 'validate error'],\n    success: [],\n    warning: [],\n  })\n})\n\ntest('message scope', async () => {\n  const results = await validate(\n    '',\n    {\n      required: true,\n      validator() {\n        return 'validate error {{name}}'\n      },\n    },\n    {\n      context: {\n        name: 'scopeName',\n      },\n    }\n  )\n  expect(results).toEqual({\n    error: ['The field value is required', 'validate error scopeName'],\n    success: [],\n    warning: [],\n  })\n})\n\ntest('first validate', async () => {\n  const results = await validate(\n    '',\n    {\n      required: true,\n      validator() {\n        return 'validate error'\n      },\n    },\n    {\n      validateFirst: true,\n    }\n  )\n  expect(results).toEqual({\n    error: ['The field value is required'],\n    success: [],\n    warning: [],\n  })\n})\n\ntest('custom validate results', async () => {\n  const results = await validate('', {\n    validator() {\n      return { type: 'error', message: 'validate error' }\n    },\n  })\n  expect(results).toEqual({\n    error: ['validate error'],\n    success: [],\n    warning: [],\n  })\n})\n\ntest('exception validate', async () => {\n  const results1 = await validate('', {\n    validator() {\n      throw new Error('validate error')\n    },\n  })\n  expect(results1).toEqual({\n    error: ['validate error'],\n    success: [],\n    warning: [],\n  })\n\n  const results2 = await validate('', {\n    validator() {\n      throw 'custom string'\n    },\n  })\n  expect(results2).toEqual({\n    error: ['custom string'],\n    success: [],\n    warning: [],\n  })\n})\n\ntest('max/maxItems/maxLength/minItems/minLength/min/maximum/exclusiveMaximum/minimum/exclusiveMinimum/len', async () => {\n  hasError(await validate(6, { max: 5 }))\n  hasError(await validate(6, { maxLength: 5 }))\n  hasError(await validate(6, { maxItems: 5 }))\n  noError(await validate(5, { max: 5 }))\n  noError(await validate(5, { maxLength: 5 }))\n  noError(await validate(5, { maxItems: 5 }))\n  hasError(await validate([1, 2, 3, 4, 5, 6], { max: 5 }))\n  hasError(await validate([1, 2, 3, 4, 5, 6], { maxLength: 5 }))\n  hasError(await validate([1, 2, 3, 4, 5, 6], { maxItems: 5 }))\n  noError(await validate([1, 2, 3, 4, 5], { max: 5 }))\n  noError(await validate([1, 2, 3, 4, 5], { maxLength: 5 }))\n  noError(await validate([1, 2, 3, 4, 5], { maxItems: 5 }))\n  hasError(await validate('123456', { max: 5 }))\n  hasError(await validate('123456', { maxLength: 5 }))\n  hasError(await validate('123456', { maxItems: 5 }))\n  noError(await validate('12345', { max: 5 }))\n  noError(await validate('12345', { maxLength: 5 }))\n  noError(await validate('12345', { maxItems: 5 }))\n  hasError(await validate(2, { min: 3 }))\n  hasError(await validate(2, { minLength: 3 }))\n  hasError(await validate(2, { minItems: 3 }))\n  noError(await validate(3, { min: 3 }))\n  noError(await validate(3, { minLength: 3 }))\n  noError(await validate(3, { minItems: 3 }))\n  hasError(await validate([1, 2], { min: 3 }))\n  hasError(await validate([1, 2], { minLength: 3 }))\n  hasError(await validate([1, 2], { minItems: 3 }))\n  noError(await validate([1, 2, 3], { min: 3 }))\n  noError(await validate([1, 2, 3], { minLength: 3 }))\n  noError(await validate([1, 2, 3], { minItems: 3 }))\n  hasError(await validate('12', { min: 3 }))\n  hasError(await validate('12', { minLength: 3 }))\n  hasError(await validate('12', { minItems: 3 }))\n  noError(await validate('123', { min: 3 }))\n  noError(await validate('123', { minLength: 3 }))\n  noError(await validate('123', { minItems: 3 }))\n\n  hasError(await validate(6, { maximum: 5 }))\n  noError(await validate(5, { maximum: 5 }))\n  hasError(await validate([1, 2, 3, 4, 5, 6], { maximum: 5 }))\n  noError(await validate([1, 2, 3, 4, 5], { maximum: 5 }))\n  hasError(await validate('123456', { maximum: 5 }))\n  noError(await validate('12345', { maximum: 5 }))\n  hasError(await validate(2, { minimum: 3 }))\n  noError(await validate(3, { minimum: 3 }))\n  hasError(await validate([1, 2], { minimum: 3 }))\n  noError(await validate([1, 2, 3], { minimum: 3 }))\n  hasError(await validate('12', { minimum: 3 }))\n  noError(await validate('123', { minimum: 3 }))\n\n  hasError(await validate(6, { exclusiveMaximum: 5 }))\n  hasError(await validate(5, { exclusiveMaximum: 5 }))\n  hasError(await validate([1, 2, 3, 4, 5, 6], { exclusiveMaximum: 5 }))\n  hasError(await validate([1, 2, 3, 4, 5], { exclusiveMaximum: 5 }))\n  hasError(await validate('123456', { exclusiveMaximum: 5 }))\n  hasError(await validate('12345', { exclusiveMaximum: 5 }))\n  hasError(await validate(2, { exclusiveMinimum: 3 }))\n  hasError(await validate(3, { exclusiveMinimum: 3 }))\n  hasError(await validate([1, 2], { exclusiveMinimum: 3 }))\n  hasError(await validate([1, 2, 3], { exclusiveMinimum: 3 }))\n  hasError(await validate('12', { exclusiveMinimum: 3 }))\n  hasError(await validate('123', { exclusiveMinimum: 3 }))\n\n  hasError(await validate('1234', { len: 3 }))\n  hasError(await validate({ aa: 1, bb: 2, cc: 3 }, { maxProperties: 2 }))\n  noError(await validate({ aa: 1, cc: 3 }, { maxProperties: 2 }))\n  hasError(await validate({ aa: 1 }, { minProperties: 2 }))\n  noError(await validate({ aa: 1, bb: 2, cc: 3 }, { minProperties: 2 }))\n  noError(await validate({ aa: 1, cc: 3 }, { maxProperties: 2 }))\n})\n\ntest('const', async () => {\n  noError(await validate('', { const: '123' }))\n  noError(await validate('123', { const: '123' }))\n  hasError(await validate('xxx', { const: '123' }))\n})\n\ntest('multipleOf', async () => {\n  noError(await validate('', { multipleOf: 2 }))\n  noError(await validate(4, { multipleOf: 2 }))\n  hasError(await validate(3, { multipleOf: 2 }))\n})\n\ntest('uniqueItems', async () => {\n  noError(await validate('', { uniqueItems: true }))\n  noError(await validate(4, { uniqueItems: true }))\n  hasError(await validate([1, 2], { uniqueItems: true }))\n  hasError(\n    await validate([{ label: '11', value: '11' }, { label: '11' }], {\n      uniqueItems: true,\n    })\n  )\n  noError(await validate([1, 1], { uniqueItems: true }))\n  noError(\n    await validate(\n      [\n        { label: '11', value: '11' },\n        { label: '11', value: '11' },\n      ],\n      { uniqueItems: true }\n    )\n  )\n})\n\ntest('pattern', async () => {\n  hasError(await validate('aaa', { pattern: /^\\d+$/ }))\n})\n\ntest('validator', async () => {\n  hasError(\n    await validate('aaa', {\n      validator() {\n        return false\n      },\n      message: 'error',\n    }),\n    'error'\n  )\n})\n\ntest('whitespace', async () => {\n  hasError(\n    await validate(' ', {\n      whitespace: true,\n    })\n  )\n})\n\ntest('enum', async () => {\n  hasError(\n    await validate('11', {\n      enum: ['22', '33'],\n    })\n  )\n  noError(\n    await validate('11', {\n      enum: ['22', '33', '11'],\n    })\n  )\n})\n\ntest('filter trigger type(unmatch)', async () => {\n  expect(\n    await validate(\n      '',\n      {\n        triggerType: 'onBlur',\n        required: true,\n        validator() {\n          return 'validate error'\n        },\n      },\n      {\n        validateFirst: true,\n        triggerType: 'onInput',\n      }\n    )\n  ).toEqual({\n    error: [],\n    success: [],\n    warning: [],\n  })\n})\n\ntest('filter trigger type(match first validate)', async () => {\n  expect(\n    await validate(\n      '',\n      {\n        triggerType: 'onBlur',\n        required: true,\n        validator() {\n          return 'validate error'\n        },\n      },\n      {\n        validateFirst: true,\n        triggerType: 'onBlur',\n      }\n    )\n  ).toEqual({\n    error: ['The field value is required'],\n    success: [],\n    warning: [],\n  })\n})\n\ntest('filter trigger type(match multi validate)', async () => {\n  expect(\n    await validate(\n      '',\n      {\n        triggerType: 'onBlur',\n        required: true,\n        validator() {\n          return 'validate error'\n        },\n      },\n      {\n        triggerType: 'onBlur',\n      }\n    )\n  ).toEqual({\n    error: ['The field value is required', 'validate error'],\n    success: [],\n    warning: [],\n  })\n})\n\ntest('validate formats(date)', async () => {\n  noError(await validate('', 'date'))\n  hasError(await validate('2020-1', 'date'))\n  hasError(await validate('2020-01- 11:23:33', 'date'))\n  hasError(await validate('12/01/', 'date'))\n  noError(await validate('2020-1-12', 'date'))\n  noError(await validate('2020/1/12', 'date'))\n  noError(await validate('2020-01-12', 'date'))\n  noError(await validate('2020/01/12', 'date'))\n  noError(await validate('12/01/2020', 'date'))\n  noError(await validate('2020-01-12 11:23:33', 'date'))\n  noError(await validate('2020/01/12 11:23:33', 'date'))\n  noError(await validate('12/01/2020 11:23:33', 'date'))\n  noError(await validate('12/1/2020 11:23:33', 'date'))\n})\n\ntest('validate formats(number)', async () => {\n  noError(await validate('', 'number'))\n  hasError(await validate('12323d', 'number'))\n  noError(await validate('12323', 'number'))\n  noError(await validate('12323.12', 'number'))\n  noError(await validate('-12323.12', 'number'))\n  noError(await validate('+12323.12', 'number'))\n})\n\ntest('validate formats(integer)', async () => {\n  noError(await validate('', 'integer'))\n  hasError(await validate('222.333', 'integer'))\n  noError(await validate('12323', 'integer'))\n})\n\ntest('validate formats(phone)', async () => {\n  noError(await validate('', 'phone'))\n  hasError(await validate('222333', 'phone'))\n  noError(await validate('15934567899', 'phone'))\n})\n\ntest('validate formats(money)', async () => {\n  noError(await validate('$12', 'money'))\n  hasError(await validate('$12.', 'money'))\n  noError(await validate('$12.3', 'money'))\n})\n\ntest('validate custom validator', async () => {\n  hasError(await validate('123', { custom: true }))\n  noError(await validate('', { custom: true }))\n})\n\ntest('validate custom formats', async () => {\n  hasError(await validate('aa asd', 'custom'))\n  hasError(await validate('aa asd 中文', 'custom'))\n  noError(await validate('中文', 'custom'))\n})\n\ntest('validate undefined format', async () => {\n  expect(\n    (\n      await validate('a', {\n        required: false,\n        pattern: '(\\\\d{3,4}-\\\\d{7,8}-\\\\d{4})|(4\\\\d{4,9})|(\\\\d{3,4}-\\\\d{7,8})',\n        format: undefined,\n        message: 'error',\n      })\n    ).error\n  ).toEqual(['error'])\n})\n\ntest('validator return boolean', async () => {\n  hasError(\n    await validate('123', {\n      customBool: true,\n      message: 'custom error',\n    }),\n    'custom error'\n  )\n  noError(\n    await validate('123', {\n      customBool2: true,\n      message: 'custom error',\n    })\n  )\n})\n\ntest('language', async () => {\n  setValidateLanguage('zh-CN')\n  hasError(\n    await validate('', {\n      required: true,\n    }),\n    '该字段是必填字段'\n  )\n  setValidateLanguage('en-US')\n  hasError(\n    await validate('', {\n      required: true,\n    }),\n    'The field value is required'\n  )\n})\n\ntest('validator template', async () => {\n  registerValidateMessageTemplateEngine((message) => {\n    if (typeof message !== 'string') return message\n    return message.replace(/\\<\\<\\s*([\\w.]+)\\s*\\>\\>/g, (_, $0) => {\n      return { aa: 123 }[$0]\n    })\n  })\n  hasError(\n    await validate('', () => {\n      return `<<aa>>=123`\n    }),\n    '123=123'\n  )\n})\n\ntest('validator template with format', async () => {\n  registerValidateMessageTemplateEngine((message) => {\n    if (typeof message !== 'string') return message\n    return message.replace(/\\<\\<\\s*([\\w.]+)\\s*\\>\\>/g, (_, $0) => {\n      return { aa: 123 }[$0]\n    })\n  })\n  hasError(\n    await validate('', (value, rules, ctx, format) => {\n      return `<<aa>>=123&${format('<<aa>>')}`\n    }),\n    '123=123&123'\n  )\n})\n\ntest('validator template with format and scope', async () => {\n  registerValidateMessageTemplateEngine((message) => {\n    if (typeof message !== 'string') return message\n    return message.replace(/\\<\\<\\s*([\\w.]+)\\s*\\>\\>/g, (_, $0) => {\n      return { aa: 123 }[$0]\n    })\n  })\n\n  const result = await validate(\n    '',\n    (value, rules, ctx, format) => {\n      return `<<aa>>=123&${format('<<aa>>{{name}}')}`\n    },\n    {\n      context: {\n        name: 'scopeName',\n      },\n    }\n  )\n\n  expect(result.error[0]).toEqual('123=123&123scopeName')\n})\n\ntest('validator order with format', async () => {\n  hasError(\n    await validate('', [\n      { required: true },\n      {\n        format: 'url',\n      },\n    ]),\n    'The field value is required'\n  )\n})\n"
  },
  {
    "path": "packages/validator/src/formats.ts",
    "content": "export default {\n  url: new RegExp(\n    // protocol identifier\n    '^(?:(?:(?:https?|ftp|rtmp):)?//)' +\n      // user:pass authentication\n      '(?:\\\\S+(?::\\\\S*)?@)?' +\n      '(?:' +\n      // IP address exclusion - private & local networks\n      // Reference: https://www.arin.net/knowledge/address_filters.html\n\n      // filter 10.*.*.* and 127.*.*.* addresses\n      '(?!(?:10|127)(?:\\\\.\\\\d{1,3}){3})' +\n      // filter 169.254.*.* and 192.168.*.*\n      '(?!(?:169\\\\.254|192\\\\.168)(?:\\\\.\\\\d{1,3}){2})' +\n      // filter 172.16.0.0 - 172.31.255.255\n      // TODO: add test to validate that it invalidates address in 16-31 range\n      '(?!172\\\\.(?:1[6-9]|2\\\\d|3[0-1])(?:\\\\.\\\\d{1,3}){2})' +\n      // IP address dotted notation octets\n      // excludes loopback network 0.0.0.0\n      // excludes reserved space >= 224.0.0.0\n      // excludes network & broadcast addresses\n      // (first & last IP address of each class)\n\n      // filter 1. part for 1-223\n      '(?:22[0-3]|2[01]\\\\d|[1-9]\\\\d?|1\\\\d\\\\d)' +\n      // filter 2. and 3. part for 0-255\n      '(?:\\\\.(?:25[0-5]|2[0-4]\\\\d|1?\\\\d{1,2})){2}' +\n      // filter 4. part for 1-254\n      '(?:\\\\.(?:25[0-4]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]\\\\d?))' +\n      '|' +\n      // host name\n      '(?:(?:[a-z\\\\u00a1-\\\\uffff0-9_]-*)*[a-z\\\\u00a1-\\\\uffff0-9_]+)' +\n      // domain name\n      '(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff0-9_]-*)*[a-z\\\\u00a1-\\\\uffff0-9_]+)*' +\n      // TLD identifier\n      '(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff_]{2,}))' +\n      ')' +\n      // port number\n      '(?::\\\\d{2,5})?' +\n      // resource path\n      '(?:/?\\\\S*)?$'\n  ),\n  email: /^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$/,\n\n  ipv6: /^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$/,\n\n  ipv4: /^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$/,\n\n  number: /^[+-]?\\d+(\\.\\d+)?$/,\n\n  integer: /^[+-]?\\d+$/,\n\n  qq: /^(\\+?[1-9]\\d*|0)$/,\n\n  phone: /^\\d{3}-\\d{8}$|^\\d{4}-\\d{7}$|^\\d{11}$/,\n\n  idcard: /^\\d{15}$|^\\d{17}(\\d|x|X)$/,\n\n  money:\n    /^([\\u0024\\u00A2\\u00A3\\u00A4\\u20AC\\u00A5\\u20B1\\u20B9\\uFFE5]\\s*)(\\d+,?)+(\\.\\d+)?\\s*$/,\n\n  zh: /^[\\u4e00-\\u9fa5]+$/,\n\n  date: /^[0-9]+[./-][0-9]+[./-][0-9]+\\s*(?:[0-9]+\\s*:\\s*[0-9]+\\s*:\\s*[0-9]+)?$/,\n\n  zip: /^[0-9]{6}$/,\n}\n"
  },
  {
    "path": "packages/validator/src/index.ts",
    "content": "export * from './validator'\nexport * from './parser'\nexport * from './registry'\nexport * from './types'\n"
  },
  {
    "path": "packages/validator/src/locale.ts",
    "content": "export default {\n  en: {\n    pattern: 'This field is invalid',\n    invalid: 'This field is invalid',\n    required: 'The field value is required',\n    number: 'The field value is not a number',\n    integer: 'The field value is not an integer number',\n    url: 'The field value is a invalid url',\n    email: 'The field value is not a email format',\n    ipv6: 'The field value is not a ipv6 format',\n    ipv4: 'The field value is not a ipv4 format',\n    idcard: 'The field value is not an idcard format',\n    qq: 'The field value is not a qq number format',\n    phone: 'The field value is not a phone number format',\n    money: 'The field value is not a currency format',\n    zh: 'The field value is not a chinese string',\n    date: 'The field value is not a valid date format',\n    zip: 'The field value is not a zip format',\n    len: 'The length or number of entries must be {{len}}',\n    min: 'The length or number of entries must be at least {{min}}',\n    minLength: 'The length or number of entries must be at least {{minLength}}',\n    minItems: 'The length or number of entries must be at least {{minItems}}',\n    maximum: 'The field value cannot be greater than {{maximum}}',\n    exclusiveMaximum: 'The field value must be less than {{exclusiveMaximum}}',\n    minimum: 'The field value cannot be less than {{minimum}}',\n    exclusiveMinimum:\n      'The field value must be greater than {{exclusiveMinimum}}',\n    max: 'The field length or number of entries must be at most {{max}}',\n    maxLength:\n      'The field length or number of entries must be at most {{maxLength}}',\n    maxItems:\n      'The field length or number of entries must be at most {{maxItems}}',\n    whitespace: 'This field value cannot be blank string.',\n    enum: 'The field value must be one of {{enum}}',\n\n    const: 'The field value must be equal to {{const}}',\n    multipleOf: 'The field value must be divisible by {{multipleOf}}',\n    maxProperties:\n      'The number of field properties cannot be greater than {{maxProperties}}',\n    minProperties:\n      'The number of field properties cannot be less than {{maxProperties}}',\n    uniqueItems: 'Array elements are not unique',\n  },\n  zh: {\n    pattern: '该字段不是一个合法的字段',\n    invalid: '该字段不是一个合法的字段',\n    required: '该字段是必填字段',\n    number: '该字段不是合法的数字',\n    integer: '该字段不是合法的整型数字',\n    url: '该字段不是合法的url',\n    email: '该字段不是合法的邮箱格式',\n    ipv6: '该字段不是合法的ipv6格式',\n    ipv4: '该字段不是合法的ipv4格式',\n    idcard: '该字段不是合法的身份证格式',\n    qq: '该字段不符合QQ号格式',\n    phone: '该字段不是有效的手机号',\n    money: '该字段不是有效货币格式',\n    zh: '该字段不是合法的中文字符串',\n    date: '该字段不是合法的日期格式',\n    zip: '该字段不是合法的邮编格式',\n    len: '长度或条目数必须为{{len}}',\n    min: '长度或条目数不能小于{{min}}',\n    minLength: '长度或条目数不能小于{{minLength}}',\n    minItems: '长度或条目数不能小于{{minItems}}',\n    max: '长度或条目数不能大于{{max}}',\n    maxLength: '长度或条目数不能大于{{maxLength}}',\n    maxItems: '长度或条目数不能大于{{maxItems}}',\n    maximum: '数值不能大于{{maximum}}',\n    exclusiveMaximum: '数值必须小于{{exclusiveMaximum}}',\n    minimum: '数值不能小于{{minimum}}',\n    exclusiveMinimum: '数值必须大于{{exclusiveMinimum}}',\n    whitespace: '不能为纯空白字符串',\n    enum: '字段值必须为{{enum}}其中一个',\n    const: '字段值必须等于{{const}}',\n    multipleOf: '字段值不能被{{multipleOf}}整除',\n    maxProperties: '字段属性数量不能大于{{maxProperties}}',\n    minProperties: '字段属性数量不能小于{{minProperties}}',\n    uniqueItems: '数组元素不唯一',\n  },\n  'en-US': {\n    pattern: 'This field is invalid',\n    invalid: 'This field is invalid',\n    required: 'The field value is required',\n    number: 'The field value is not a number',\n    integer: 'The field value is not an integer number',\n    url: 'The field value is a invalid url',\n    email: 'The field value is not a email format',\n    ipv6: 'The field value is not a ipv6 format',\n    ipv4: 'The field value is not a ipv4 format',\n    idcard: 'The field value is not an idcard format',\n    qq: 'The field value is not a qq number format',\n    phone: 'The field value is not a phone number format',\n    money: 'The field value is not a currency format',\n    zh: 'The field value is not a chinese string',\n    date: 'The field value is not a valid date format',\n    zip: 'The field value is not a zip format',\n    len: 'The length or number of entries must be {{len}}',\n    min: 'The length or number of entries must be at least {{min}}',\n    minLength: 'The length or number of entries must be at least {{minLength}}',\n    minItems: 'The length or number of entries must be at least {{minItems}}',\n    maximum: 'The field value cannot be greater than {{maximum}}',\n    exclusiveMaximum: 'The field value must be less than {{exclusiveMaximum}}',\n    minimum: 'The field value cannot be less than {{minimum}}',\n    exclusiveMinimum:\n      'The field value must be greater than {{exclusiveMinimum}}',\n    max: 'The field length or number of entries must be at most {{max}}',\n    maxLength:\n      'The field length or number of entries must be at most {{maxLength}}',\n    maxItems:\n      'The field length or number of entries must be at most {{maxItems}}',\n    whitespace: 'This field value cannot be blank string.',\n    enum: 'The field value must be one of {{enum}}',\n    const: 'The field value must be equal to {{const}}',\n    multipleOf: 'The field value must be divisible by {{multipleOf}}',\n    maxProperties:\n      'The number of field properties cannot be greater than {{maxProperties}}',\n    minProperties:\n      'The number of field properties cannot be less than {{maxProperties}}',\n    uniqueItems: 'Array elements are not unique',\n  },\n  'zh-CN': {\n    pattern: '该字段不是一个合法的字段',\n    invalid: '该字段不是一个合法的字段',\n    required: '该字段是必填字段',\n    number: '该字段不是合法的数字',\n    integer: '该字段不是合法的整型数字',\n    url: '该字段不是合法的url',\n    email: '该字段不是合法的邮箱格式',\n    ipv6: '该字段不是合法的ipv6格式',\n    ipv4: '该字段不是合法的ipv4格式',\n    idcard: '该字段不是合法的身份证格式',\n    qq: '该字段不符合QQ号格式',\n    phone: '该字段不是有效的手机号',\n    money: '该字段不是有效货币格式',\n    zh: '该字段不是合法的中文字符串',\n    date: '该字段不是合法的日期格式',\n    zip: '该字段不是合法的邮编格式',\n    len: '长度或条目数必须为{{len}}',\n    min: '长度或条目数不能小于{{min}}',\n    minLength: '长度或条目数不能小于{{minLength}}',\n    minItems: '长度或条目数不能小于{{minItems}}',\n    maxLength: '长度或条目数不能大于{{maxLength}}',\n    maxItems: '长度或条目数不能大于{{maxItems}}',\n    max: '长度或条目数不能大于{{max}}',\n    maximum: '数值不能大于{{maximum}}',\n    exclusiveMaximum: '数值必须小于{{exclusiveMaximum}}',\n    minimum: '数值不能小于{{minimum}}',\n    exclusiveMinimum: '数值必须大于{{exclusiveMinimum}}',\n    whitespace: '不能为纯空白字符串',\n    enum: '字段值必须为{{enum}}其中一个',\n    const: '字段值必须等于{{const}}',\n    multipleOf: '字段值不能被{{multipleOf}}整除',\n    maxProperties: '字段属性数量不能大于{{maxProperties}}',\n    minProperties: '字段属性数量不能小于{{minProperties}}',\n    uniqueItems: '数组元素不唯一',\n  },\n  'zh-TW': {\n    pattern: '該字段不是一個合法的字段',\n    invalid: '該字段不是一個合法的字段',\n    required: '該字段是必填字段',\n    number: '該字段不是合法的數字',\n    integer: '該字段不是合法的整型數字',\n    url: '該字段不是合法的url',\n    email: '該字段不是合法的郵箱格式',\n    ipv6: '該字段不是合法的ipv6格式',\n    ipv4: '該字段不是合法的ipv4格式',\n    idcard: '該字段不是合法的身份證格式',\n    qq: '該字段不符合QQ號格式',\n    phone: '該字段不是有效的手機號',\n    money: '該字段不是有效貨幣格式',\n    zh: '該字段不是合法的中文字符串',\n    date: '該字段不是合法的日期格式',\n    zip: '該字段不是合法的郵編格式',\n    len: '長度或條目數必須為{{len}}',\n    min: '長度或條目數不能小於{{min}}',\n    minItems: '長度或條目數不能小於{{minItems}}',\n    minLength: '長度或條目數不能小於{{minLength}}',\n    max: '長度或條目數不能大於{{max}}',\n    maxItems: '長度或條目數不能大於{{maxItems}}',\n    maxLength: '長度或條目數不能大於{{maxLength}}',\n    maximum: '數值不能大於{{maximum}}',\n    exclusiveMaximum: '數值必須小於{{exclusiveMaximum}}',\n    minimum: '數值不能小於{{minimum}}',\n    exclusiveMinimum: '數值必須大於{{exclusiveMinimum}}',\n    whitespace: '不能為純空白字符串',\n    enum: '字段值必須為{{enum}}其中一個',\n    const: '字段值必須等於{{const}}',\n    multipleOf: '字段值不能被{{multipleOf}}整除',\n    maxProperties: '字段屬性數量不能大於{{maxProperties}}',\n    minProperties: '字段屬性數量不能小於{{minProperties}}',\n    uniqueItems: '數組元素不唯一',\n  },\n  ja: {\n    url: 'このフィールドは無効なURLです',\n    whitespace: 'このフィールドを空の文字列にすることはできません。',\n    zh: 'このフィールドは中国語の文字列ではありません',\n    zip: 'このフィールドはzip形式ではありません',\n    date: 'このフィールドは有効な日付形式ではありません',\n    email: 'このフィールドはメール形式ではありません',\n    exclusiveMaximum: '値は{{exclusiveMaximum}}未満である必要があります',\n    exclusiveMinimum: '値は{{exclusiveMinimum}}より大きい必要があります',\n    idcard: 'このフィールドはIDカード形式ではありません',\n    integer: 'このフィールドは整数ではありません',\n    ipv4: 'このフィールドはIPv4形式ではありません',\n    ipv6: 'このフィールドはIPv6形式ではありません',\n    len: 'エントリの長さまたは数は{{len}}でなければなりません',\n    max: 'エントリの長さまたは数は最大{{max}}でなければなりません',\n    maxItems: 'エントリの長さまたは数は最大{{maxItems}}でなければなりません',\n    maxLength: 'エントリの長さまたは数は最大{{maxLength}}でなければなりません',\n    maximum: '値は{{最大}}を超えることはできません',\n    min: 'エントリの長さまたは数は、少なくとも{{min}}である必要があります',\n    minItems:\n      'エントリの長さまたは数は、少なくとも{{minItems}}である必要があります',\n    minLength:\n      'エントリの長さまたは数は、少なくとも{{minLength}}である必要があります',\n    minimum: '値は{{minimum}}以上にする必要があります',\n    money: 'このフィールドは通貨形式ではありません',\n    number: 'このフィールドは数値ではありません',\n    pattern: 'このフィールドはどのパターンとも一致しません',\n    invalid: 'このフィールドはどのパターンとも一致しません',\n    phone: 'このフィールドは電話番号の形式ではありません',\n    qq: 'このフィールドはqq数値形式ではありません',\n    required: 'この項目は必須です',\n    enum: 'フィールド値は{{enum}}のいずれかである必要があります',\n    cons: 'フィールド値は{{const}}と等しくなければなりません',\n    multipleOf: 'フィールド値を{{multipleOf}}で割り切れない',\n    maxProperties:\n      'フィールドプロパティの数は{{maxProperties}}を超えることはできません',\n    minProperties:\n      'フィールドプロパティの数は{{minProperties}}未満にすることはできません',\n    uniqueItems: '配列要素は一意ではありません',\n  },\n}\n"
  },
  {
    "path": "packages/validator/src/parser.ts",
    "content": "import { isArr, isBool, isFn, isStr } from '@formily/shared'\nimport {\n  ValidatorDescription,\n  ValidatorFunction,\n  ValidatorParsedFunction,\n  Validator,\n  IValidatorRules,\n  isValidateResult,\n  IValidatorOptions,\n} from './types'\nimport { getValidateRules, getValidateLocale } from './registry'\nimport { render } from './template'\n\nconst getRuleMessage = (rule: IValidatorRules, type: string) => {\n  if (rule.format) {\n    return rule.message || getValidateLocale(rule.format)\n  }\n  return rule.message || getValidateLocale(type)\n}\n\nexport const parseValidatorDescription = (\n  description: ValidatorDescription\n): IValidatorRules => {\n  if (!description) return {}\n  let rules: IValidatorRules = {}\n  if (isStr(description)) {\n    rules.format = description\n  } else if (isFn(description)) {\n    rules.validator = description\n  } else {\n    rules = Object.assign(rules, description)\n  }\n  return rules\n}\n\nexport const parseValidatorDescriptions = <Context = any>(\n  validator: Validator<Context>\n): IValidatorRules[] => {\n  if (!validator) return []\n  const array = isArr(validator) ? validator : [validator]\n  return array.map((description) => {\n    return parseValidatorDescription(description)\n  })\n}\n\nexport const parseValidatorRules = (\n  rules: IValidatorRules = {}\n): ValidatorParsedFunction[] => {\n  const getRulesKeys = (): string[] => {\n    const keys = []\n    if ('required' in rules) {\n      keys.push('required')\n    }\n    for (let key in rules) {\n      if (key === 'required' || key === 'validator') continue\n      keys.push(key)\n    }\n    if ('validator' in rules) {\n      keys.push('validator')\n    }\n    return keys\n  }\n  const getContext = (context: any, value: any) => {\n    return {\n      ...rules,\n      ...context,\n      value,\n    }\n  }\n  const createValidate =\n    (callback: ValidatorFunction, message: string) =>\n    async (value: any, context: any) => {\n      const context_ = getContext(context, value)\n      try {\n        const results = await callback(\n          value,\n          { ...rules, message },\n          context_,\n          (message: string, scope: any) => {\n            return render(\n              {\n                type: 'error',\n                message,\n              },\n              Object.assign(context_, scope)\n            )?.message\n          }\n        )\n        if (isBool(results)) {\n          if (!results) {\n            return render(\n              {\n                type: 'error',\n                message,\n              },\n              context_\n            )\n          }\n          return {\n            type: 'error',\n            message: undefined,\n          }\n        } else if (results) {\n          if (isValidateResult(results)) {\n            return render(results, context_)\n          }\n          return render(\n            {\n              type: 'error',\n              message: results,\n            },\n            context_\n          )\n        }\n\n        return {\n          type: 'error',\n          message: undefined,\n        }\n      } catch (e) {\n        return {\n          type: 'error',\n          message: e?.message || e,\n        }\n      }\n    }\n  return getRulesKeys().reduce((buf, key) => {\n    const callback = getValidateRules(key)\n    if (callback) {\n      const validator = createValidate(callback, getRuleMessage(rules, key))\n      return buf.concat(validator)\n    }\n    return buf\n  }, [])\n}\n\nexport const parseValidator = <Context = any>(\n  validator: Validator<Context>,\n  options: IValidatorOptions = {}\n) => {\n  if (!validator) return []\n  const array = isArr(validator) ? validator : [validator]\n  return array.reduce<ValidatorParsedFunction<Context>[]>(\n    (buf, description) => {\n      const rules = parseValidatorDescription(description)\n      const triggerType = rules.triggerType ?? 'onInput'\n      if (options?.triggerType && options.triggerType !== triggerType)\n        return buf\n      return rules ? buf.concat(parseValidatorRules(rules)) : buf\n    },\n    []\n  )\n}\n"
  },
  {
    "path": "packages/validator/src/registry.ts",
    "content": "import {\n  FormPath,\n  each,\n  lowerCase,\n  globalThisPolyfill,\n  merge as deepmerge,\n  isFn,\n  isStr,\n} from '@formily/shared'\nimport {\n  ValidatorFunctionResponse,\n  ValidatorFunction,\n  IRegistryFormats,\n  IRegistryLocaleMessages,\n  IRegistryLocales,\n  IRegistryRules,\n} from './types'\n\nconst getIn = FormPath.getIn\n\nconst self: any = globalThisPolyfill\n\nconst defaultLanguage = 'en'\n\nconst getBrowserlanguage = () => {\n  /* istanbul ignore next */\n  if (!self.navigator) {\n    return defaultLanguage\n  }\n  return (\n    self.navigator.browserlanguage || self.navigator.language || defaultLanguage\n  )\n}\n\nconst registry = {\n  locales: {\n    messages: {},\n    language: getBrowserlanguage(),\n  },\n  formats: {},\n  rules: {},\n  template: null,\n}\n\nconst getISOCode = (language: string) => {\n  let isoCode = registry.locales.language\n  if (registry.locales.messages[language]) {\n    return language\n  }\n  const lang = lowerCase(language)\n  each(\n    registry.locales.messages,\n    (messages: IRegistryLocaleMessages, key: string) => {\n      const target = lowerCase(key)\n      if (target.indexOf(lang) > -1 || lang.indexOf(target) > -1) {\n        isoCode = key\n        return false\n      }\n    }\n  )\n  return isoCode\n}\n\nexport const getValidateLocaleIOSCode = getISOCode\n\nexport const setValidateLanguage = (lang: string) => {\n  registry.locales.language = lang || defaultLanguage\n}\n\nexport const getValidateLanguage = () => registry.locales.language\n\nexport const getLocaleByPath = (\n  path: string,\n  lang: string = registry.locales.language\n) => getIn(registry.locales.messages, `${getISOCode(lang)}.${path}`)\n\nexport const getValidateLocale = (path: string) => {\n  const message = getLocaleByPath(path)\n  return (\n    message ||\n    getLocaleByPath('pattern') ||\n    getLocaleByPath('pattern', defaultLanguage)\n  )\n}\n\nexport const getValidateMessageTemplateEngine = () => registry.template\n\nexport const getValidateFormats = (key?: string) =>\n  key ? registry.formats[key] : registry.formats\n\nexport const getValidateRules = <T>(\n  key?: T\n): T extends string\n  ? ValidatorFunction\n  : { [key: string]: ValidatorFunction } =>\n  key ? registry.rules[key as any] : registry.rules\n\nexport const registerValidateLocale = (locale: IRegistryLocales) => {\n  registry.locales.messages = deepmerge(registry.locales.messages, locale)\n}\n\nexport const registerValidateRules = (rules: IRegistryRules) => {\n  each(rules, (rule, key) => {\n    if (isFn(rule)) {\n      registry.rules[key] = rule\n    }\n  })\n}\n\nexport const registerValidateFormats = (formats: IRegistryFormats) => {\n  each(formats, (pattern, key) => {\n    if (isStr(pattern) || pattern instanceof RegExp) {\n      registry.formats[key] = new RegExp(pattern)\n    }\n  })\n}\n\nexport const registerValidateMessageTemplateEngine = (\n  template: (message: ValidatorFunctionResponse, context: any) => any\n) => {\n  registry.template = template\n}\n"
  },
  {
    "path": "packages/validator/src/rules.ts",
    "content": "import {\n  isEmpty,\n  isValid,\n  stringLength,\n  isStr,\n  isArr,\n  isFn,\n  toArr,\n  isBool,\n  isNum,\n  isEqual,\n  each,\n} from '@formily/shared'\nimport { getValidateFormats } from './registry'\nimport { IRegistryRules } from './types'\n\nconst isValidateEmpty = (value: any) => {\n  if (isArr(value)) {\n    for (let i = 0; i < value.length; i++) {\n      if (isValid(value[i])) return false\n    }\n    return true\n  } else {\n    //compat to draft-js\n    if (value?.getCurrentContent) {\n      /* istanbul ignore next */\n      return !value.getCurrentContent()?.hasText()\n    }\n    return isEmpty(value)\n  }\n}\n\nconst getLength = (value: any) =>\n  isStr(value) ? stringLength(value) : value ? value.length : 0\n\nconst extendSameRules = (\n  rules: IRegistryRules,\n  names: Record<string, string>\n) => {\n  each(names, (realName, name) => {\n    rules[name] = (value, rule, ...args) =>\n      rules[realName](value, { ...rule, [realName]: rule[name] }, ...args)\n  })\n}\n\nconst RULES: IRegistryRules = {\n  format(value, rule) {\n    if (isValidateEmpty(value)) return ''\n    if (rule.format) {\n      const format = getValidateFormats(rule.format)\n      if (format) {\n        return !new RegExp(format).test(value) ? rule.message : ''\n      }\n    }\n    return ''\n  },\n  required(value, rule) {\n    if (rule.required !== true) return ''\n    return isValidateEmpty(value) ? rule.message : ''\n  },\n  max(value, rule) {\n    if (isValidateEmpty(value)) return ''\n    const length = isNum(value) ? value : getLength(value)\n    const max = Number(rule.max)\n    return length > max ? rule.message : ''\n  },\n  min(value, rule) {\n    if (isValidateEmpty(value)) return ''\n    const length = isNum(value) ? value : getLength(value)\n    const min = Number(rule.min)\n    return length < min ? rule.message : ''\n  },\n  exclusiveMaximum(value, rule) {\n    if (isValidateEmpty(value)) return ''\n    const length = isNum(value) ? value : getLength(value)\n    const max = Number(rule.exclusiveMaximum)\n    return length >= max ? rule.message : ''\n  },\n  exclusiveMinimum(value, rule) {\n    if (isValidateEmpty(value)) return ''\n    const length = isNum(value) ? value : getLength(value)\n    const min = Number(rule.exclusiveMinimum)\n    return length <= min ? rule.message : ''\n  },\n  len(value, rule) {\n    if (isValidateEmpty(value)) return ''\n    const length = getLength(value)\n    const len = Number(rule.len)\n    return length !== len ? rule.message : ''\n  },\n\n  pattern(value, rule) {\n    if (isValidateEmpty(value)) return ''\n    return !new RegExp(rule.pattern).test(value) ? rule.message : ''\n  },\n  async validator(value, rule, context, format) {\n    if (isFn(rule.validator)) {\n      const response = await Promise.resolve(\n        rule.validator(value, rule, context, format)\n      )\n      if (isBool(response)) {\n        return !response ? rule.message : ''\n      } else {\n        return response\n      }\n    }\n    /* istanbul ignore next */\n    throw new Error(\"The rule's validator property must be a function.\")\n  },\n  whitespace(value, rule) {\n    if (isValidateEmpty(value)) return ''\n    if (rule.whitespace) {\n      return /^\\s+$/.test(value) ? rule.message : ''\n    }\n  },\n  enum(value, rule) {\n    if (isValidateEmpty(value)) return ''\n    const enums = toArr(rule.enum)\n    return enums.indexOf(value) === -1 ? rule.message : ''\n  },\n  const(value, rule) {\n    if (isValidateEmpty(value)) return ''\n    return rule.const !== value ? rule.message : ''\n  },\n  multipleOf(value, rule) {\n    if (isValidateEmpty(value)) return ''\n    return Number(value) % Number(rule.multipleOf) !== 0 ? rule.message : ''\n  },\n  uniqueItems(value, rule) {\n    if (isValidateEmpty(value)) return ''\n    value = toArr(value)\n    return value.some((item: any, index: number) => {\n      for (let i = 0; i < value.length; i++) {\n        if (i !== index && !isEqual(value[i], item)) {\n          return false\n        }\n      }\n      return true\n    })\n      ? ''\n      : rule.message\n  },\n  maxProperties(value, rule) {\n    if (isValidateEmpty(value)) return ''\n    return Object.keys(value || {}).length <= Number(rule.maxProperties)\n      ? ''\n      : rule.message\n  },\n  minProperties(value, rule) {\n    if (isValidateEmpty(value)) return ''\n    return Object.keys(value || {}).length >= Number(rule.minProperties)\n      ? ''\n      : rule.message\n  },\n}\n\nextendSameRules(RULES, {\n  maximum: 'max',\n  minimum: 'min',\n  maxItems: 'max',\n  minItems: 'min',\n  maxLength: 'max',\n  minLength: 'min',\n})\n\nexport default RULES\n"
  },
  {
    "path": "packages/validator/src/template.ts",
    "content": "import { isFn, isStr, FormPath } from '@formily/shared'\nimport { IValidateResult, IValidatorRules } from './types'\nimport { getValidateMessageTemplateEngine } from './registry'\n\nexport const render = (\n  result: IValidateResult,\n  rules: IValidatorRules\n): IValidateResult => {\n  const { message } = result\n  if (isStr(message)) {\n    const template = getValidateMessageTemplateEngine()\n    if (isFn(template)) {\n      result.message = template(message, rules)\n    }\n    result.message = result.message.replace(\n      /\\{\\{\\s*([\\w.]+)\\s*\\}\\}/g,\n      (_, $0) => {\n        return FormPath.getIn(rules, $0)\n      }\n    )\n  }\n  return result\n}\n"
  },
  {
    "path": "packages/validator/src/types.ts",
    "content": "export type ValidatorFormats =\n  | 'url'\n  | 'email'\n  | 'ipv6'\n  | 'ipv4'\n  | 'number'\n  | 'integer'\n  | 'idcard'\n  | 'qq'\n  | 'phone'\n  | 'money'\n  | 'zh'\n  | 'date'\n  | 'zip'\n  | (string & {})\n\nexport interface IValidateResult {\n  type: 'error' | 'warning' | 'success' | (string & {})\n  message: string\n}\n\nexport interface IValidateResults {\n  error?: string[]\n  warning?: string[]\n  success?: string[]\n}\n\nexport const isValidateResult = (obj: any): obj is IValidateResult =>\n  !!obj['type'] && !!obj['message']\n\nexport type ValidatorFunctionResponse =\n  | null\n  | string\n  | boolean\n  | IValidateResult\n\nexport type ValidatorFunction<Context = any> = (\n  value: any,\n  rule: IValidatorRules<Context>,\n  ctx: Context,\n  render: (message: string, scope?: any) => string\n) => ValidatorFunctionResponse | Promise<ValidatorFunctionResponse> | null\n\nexport type ValidatorParsedFunction<Context = any> = (\n  value: any,\n  ctx: Context\n) => IValidateResult | Promise<IValidateResult> | null\n\nexport type ValidatorTriggerType =\n  | 'onInput'\n  | 'onFocus'\n  | 'onBlur'\n  | (string & {})\n\nexport interface IValidatorRules<Context = any> {\n  triggerType?: ValidatorTriggerType\n  format?: ValidatorFormats\n  validator?: ValidatorFunction<Context>\n  required?: boolean\n  pattern?: RegExp | string\n  max?: number\n  maximum?: number\n  maxItems?: number\n  minItems?: number\n  maxLength?: number\n  minLength?: number\n  exclusiveMaximum?: number\n  exclusiveMinimum?: number\n  minimum?: number\n  min?: number\n  len?: number\n  whitespace?: boolean\n  enum?: any[]\n  const?: any\n  multipleOf?: number\n  uniqueItems?: boolean\n  maxProperties?: number\n  minProperties?: number\n  message?: string\n  [key: string]: any\n}\n\nexport interface IRegistryLocaleMessages {\n  [key: string]: string | IRegistryLocaleMessages\n}\n\nexport interface IRegistryLocales {\n  [language: string]: IRegistryLocaleMessages\n}\n\nexport interface IRegistryRules<Context = any> {\n  [key: string]: ValidatorFunction<Context>\n}\n\nexport interface IRegistryFormats {\n  [key: string]: string | RegExp\n}\n\nexport type ValidatorDescription<Context = any> =\n  | ValidatorFormats\n  | ValidatorFunction<Context>\n  | IValidatorRules<Context>\n\nexport type MultiValidator<Context = any> = ValidatorDescription<Context>[]\n\nexport type Validator<Context = any> =\n  | ValidatorDescription<Context>\n  | MultiValidator<Context>\n\nexport interface IValidatorOptions<Context = any> {\n  validateFirst?: boolean\n  triggerType?: ValidatorTriggerType\n  context?: Context\n}\n"
  },
  {
    "path": "packages/validator/src/validator.ts",
    "content": "import { parseValidator } from './parser'\nimport { IValidateResults, Validator, IValidatorOptions } from './types'\nimport {\n  registerValidateFormats,\n  registerValidateLocale,\n  registerValidateRules,\n} from './registry'\nimport locales from './locale'\nimport formats from './formats'\nimport rules from './rules'\n\nregisterValidateRules(rules)\n\nregisterValidateLocale(locales)\n\nregisterValidateFormats(formats)\n\nexport const validate = async <Context = any>(\n  value: any,\n  validator: Validator<Context>,\n  options?: IValidatorOptions<Context>\n): Promise<IValidateResults> => {\n  const validates = parseValidator(validator, options)\n  const results: IValidateResults = {\n    error: [],\n    success: [],\n    warning: [],\n  }\n  for (let i = 0; i < validates.length; i++) {\n    const result = await validates[i](value, options?.context)\n    const { type, message } = result\n    results[type] = results[type] || []\n    if (message) {\n      results[type].push(message)\n      if (options?.validateFirst) break\n    }\n  }\n  return results\n}\n"
  },
  {
    "path": "packages/validator/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*\", \"devtools/*\"]\n    },\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/validator/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"include\": [\"./src/**/*.ts\", \"./src/**/*.tsx\"],\n  \"exclude\": [\"./src/__tests__/*\", \"./esm/*\", \"./lib/*\"]\n}\n"
  },
  {
    "path": "packages/vue/.npmignore",
    "content": "node_modules\n*.log\nbuild\ndocs\ndoc-site\n__tests__\n.eslintrc\njest.config.js\nvue.config.js\ntsconfig.json\n.umi\nsrc"
  },
  {
    "path": "packages/vue/README.md",
    "content": "## Usage\n\n### Requirement\n\nvue^2.6.0 + @vue/composition-api^1.0.0-beta.1\n\nOr\n\nvue>=3.0.0-rc.0\n"
  },
  {
    "path": "packages/vue/bin/formily-vue-fix.js",
    "content": "#!/usr/bin/env node\n'use strict'\nrequire('../scripts/postinstall')\n"
  },
  {
    "path": "packages/vue/bin/formily-vue-switch.js",
    "content": "#!/usr/bin/env node\n'use strict'\nrequire('../scripts/switch-cli')\n"
  },
  {
    "path": "packages/vue/docs/.vuepress/components/createCodeSandBox.js",
    "content": "import { getParameters } from 'codesandbox/lib/api/define'\n\nconst CodeSandBoxHTML = '<div id=\"app\"></div>'\nconst CodeSandBoxJS = `\nimport Vue from 'vue'\nimport Antd from 'ant-design-vue';\nimport 'ant-design-vue/dist/antd.css';\nimport App from './App.vue'\n\nVue.config.productionTip = false;\n\nVue.use(Antd);\n\n\nnew Vue({\n  render: h => h(App),\n}).$mount('#app')`\n\nconst createForm = ({ method, action, data }) => {\n  const form = document.createElement('form') // 构造 form\n  form.style.display = 'none' // 设置为不显示\n  form.target = '_blank' // 指向 iframe\n\n  // 构造 formdata\n  Object.keys(data).forEach((key) => {\n    const input = document.createElement('input') // 创建 input\n\n    input.name = key // 设置 name\n    input.value = data[key] // 设置 value\n\n    form.appendChild(input)\n  })\n\n  form.method = method // 设置方法\n  form.action = action // 设置地址\n\n  document.body.appendChild(form)\n\n  // 对该 form 执行提交\n  form.submit()\n\n  document.body.removeChild(form)\n}\n\nexport function createCodeSandBox(codeStr) {\n  const parameters = getParameters({\n    files: {\n      'sandbox.config.json': {\n        content: {\n          template: 'node',\n          infiniteLoopProtection: true,\n          hardReloadOnChange: false,\n          view: 'browser',\n          container: {\n            port: 8080,\n            node: '14',\n          },\n        },\n      },\n      'package.json': {\n        content: {\n          scripts: {\n            serve: 'vue-cli-service serve',\n            build: 'vue-cli-service build',\n            lint: 'vue-cli-service lint',\n          },\n          dependencies: {\n            '@formily/core': 'latest',\n            '@formily/vue': 'latest',\n            'core-js': '^3.6.5',\n            'ant-design-vue': 'latest',\n            'vue-demi': 'latest',\n            vue: '^2.6.11',\n          },\n          devDependencies: {\n            '@vue/cli-plugin-babel': '~4.5.0',\n            '@vue/cli-service': '~4.5.0',\n            '@vue/composition-api': 'latest',\n            'vue-template-compiler': '^2.6.11',\n          },\n          babel: {\n            presets: ['@vue/cli-plugin-babel/preset'],\n          },\n          vue: {\n            devServer: {\n              host: '0.0.0.0',\n              disableHostCheck: true, // 必须\n            },\n          },\n        },\n      },\n      'src/App.vue': {\n        content: codeStr,\n      },\n      'src/main.js': {\n        content: CodeSandBoxJS,\n      },\n      'public/index.html': {\n        content: CodeSandBoxHTML,\n      },\n    },\n  })\n\n  createForm({\n    method: 'post',\n    action: 'https://codesandbox.io/api/v1/sandboxes/define',\n    data: {\n      parameters,\n      query: 'file=/src/App.vue',\n    },\n  })\n}\n"
  },
  {
    "path": "packages/vue/docs/.vuepress/components/dumi-previewer.vue",
    "content": "<template>\n  <client-only>\n    <section class=\"dumi-previewer\">\n      <div class=\"dumi-previewer-demo\">\n        <template v-if=\"demoPath && demo\">\n          <component :is=\"demo\" />\n        </template>\n\n        <template v-else>\n          <slot name=\"demo\"></slot>\n        </template>\n      </div>\n\n      <div class=\"dumi-previewer-actions\">\n        <div>\n          <svg\n            xmlns=\"http://www.w3.org/2000/svg\"\n            xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n            class=\"dumi-previewer-actions__icon\"\n            viewBox=\"0 0 256 296\"\n            @click=\"openCodeSandBox\"\n          >\n            <path\n              d=\"M115.498 261.088v-106.61L23.814 101.73v60.773l41.996 24.347v45.7l49.688 28.54zm23.814.627l50.605-29.151V185.78l42.269-24.495v-60.011l-92.874 53.621v106.82zm80.66-180.887l-48.817-28.289l-42.863 24.872l-43.188-24.897l-49.252 28.667l91.914 52.882l92.206-53.235zM0 222.212V74.495L127.987 0L256 74.182v147.797l-128.016 73.744L0 222.212z\"\n              fill=\"#000\"\n            ></path>\n          </svg>\n        </div>\n\n        <div>\n          <svg\n            v-if=\"copied\"\n            class=\"dumi-previewer-actions__icon\"\n            style=\"fill: green\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n            viewBox=\"0 0 24 24\"\n            width=\"24\"\n            height=\"24\"\n          >\n            <path fill=\"none\" d=\"M0 0h24v24H0z\" />\n            <path\n              d=\"M10 15.172l9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z\"\n            />\n          </svg>\n\n          <svg\n            v-else\n            class=\"dumi-previewer-actions__icon\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n            viewBox=\"0 0 24 24\"\n            width=\"24\"\n            height=\"24\"\n            @click=\"handleCopy\"\n          >\n            <path fill=\"none\" d=\"M0 0h24v24H0z\" />\n            <path\n              d=\"M7 6V3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-3v3c0 .552-.45 1-1.007 1H4.007A1.001 1.001 0 0 1 3 21l.003-14c0-.552.45-1 1.007-1H7zM5.003 8L5 20h10V8H5.003zM9 6h8v10h2V4H9v2z\"\n            />\n          </svg>\n\n          <svg\n            class=\"dumi-previewer-actions__icon\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n            viewBox=\"0 0 24 24\"\n            width=\"24\"\n            height=\"24\"\n            @click=\"handleCollapse\"\n          >\n            <path fill=\"none\" d=\"M0 0h24v24H0z\" />\n            <path\n              d=\"M24 12l-5.657 5.657-1.414-1.414L21.172 12l-4.243-4.243 1.414-1.414L24 12zM2.828 12l4.243 4.243-1.414 1.414L0 12l5.657-5.657L7.07 7.757 2.828 12zm6.96 9H7.66l6.552-18h2.128L9.788 21z\"\n            />\n          </svg>\n        </div>\n      </div>\n\n      <div v-show=\"!collapsed\" class=\"dumi-previewer-source\">\n        <div v-html=\"highlightCode\" class=\"language-vue extra-class\" />\n      </div>\n    </section>\n  </client-only>\n</template>\n\n<script>\nimport copy from 'copy-to-clipboard'\nimport highlight from './highlight'\nimport { createCodeSandBox } from './createCodeSandBox'\n\nexport default {\n  name: 'dumi-previewer',\n\n  props: {\n    code: {\n      type: String,\n      default: '',\n    },\n\n    demoPath: {\n      type: String,\n      default: '',\n    },\n  },\n\n  data() {\n    return {\n      collapsed: false,\n      copied: false,\n      timerId: null,\n      demoStr: '',\n      /**\n       * take over VuePress render\n       * 接管VuePress渲染\n       */\n      demo: null,\n    }\n  },\n\n  computed: {\n    decodedCode() {\n      return decodeURIComponent(this.code || this.demoStr)\n    },\n\n    highlightCode() {\n      return highlight(this.decodedCode, 'vue')\n    },\n  },\n\n  created() {\n    if (this.demoPath) {\n      import(\n        /* webpackPrefetch: true */ `../../demos/${this.demoPath}.vue`\n      ).then((module) => {\n        this.demo = module.default\n      })\n      import(\n        /* webpackPrefetch: true */ `!raw-loader!../../demos/${this.demoPath}.vue`\n      ).then((module) => {\n        this.demoStr = module.default\n      })\n    }\n  },\n\n  beforeDestroy() {\n    clearTimeout(this.timerId)\n  },\n\n  methods: {\n    handleCollapse() {\n      this.collapsed = !this.collapsed\n    },\n\n    handleCopy() {\n      this.copied = true\n      copy(this.decodedCode)\n\n      clearTimeout(this.timer)\n      this.timerId = setTimeout(() => {\n        this.copied = false\n      }, 2000)\n    },\n\n    openCodeSandBox() {\n      createCodeSandBox(this.demoStr)\n    },\n  },\n}\n</script>\n\n<style lang=\"stylus\">\n.dumi-previewer {\n  background-color: #fff;\n  border: 1px solid #ebedf1;\n  border-radius: 1px;\n\n  .dumi-previewer-demo {\n    padding: 40px 24px;\n  }\n\n  .dumi-previewer-actions {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    border-top: 1px dashed #ebedf1;\n    height: 40px;\n    padding: 0 1em;\n\n    .dumi-previewer-actions__icon {\n      width: 16px;\n      height: 16px;\n      padding: 8px 4px;\n      opacity: 0.4;\n      cursor: pointer;\n      transition: opacity .3s;\n\n      &:hover {\n        opacity: 0.6;\n      }\n    }\n  }\n\n  .dumi-previewer-source {\n    border-top: 1px dashed #ebedf1;\n\n    div[class*=\"language-\"] {\n      background-color: #f9fafb;\n      border-radius: 0;\n    }\n\n    pre[class*=\"language-\"] {\n      margin: 0 !important;\n    }\n\n    pre[class*=\"language-\"] code {\n      color: #000 !important;\n    }\n\n    .token.cdata,.token.comment,.token.doctype,.token.prolog {\n      color: #708090\n    }\n\n    .token.punctuation {\n      color: #999\n    }\n\n    .token.namespace {\n      opacity: .7\n    }\n\n    .token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag {\n      color: #905\n    }\n\n    .token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string {\n      color: #690\n    }\n\n    .language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url {\n      color: #9a6e3a;\n      background: hsla(0,0%,100%,.5)\n    }\n\n    .token.atrule,.token.attr-value,.token.keyword {\n      color: #07a\n    }\n\n    .token.class-name,.token.function {\n      color: #dd4a68\n    }\n\n    .token.important,.token.regex,.token.variable {\n      color: #e90\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "packages/vue/docs/.vuepress/components/highlight.js",
    "content": "const prism = require('prismjs')\nconst escapeHtml = require('escape-html')\nconst loadLanguages = require('prismjs/components/index')\n\nfunction wrap(code, lang) {\n  if (lang === 'text') {\n    code = escapeHtml(code)\n  }\n  return `<pre v-pre class=\"language-${lang}\"><code>${code}</code></pre>`\n}\n\nfunction getLangCodeFromExtension(extension) {\n  const extensionMap = {\n    vue: 'markup',\n    html: 'markup',\n    md: 'markdown',\n    rb: 'ruby',\n    ts: 'typescript',\n    py: 'python',\n    sh: 'bash',\n    yml: 'yaml',\n    styl: 'stylus',\n    kt: 'kotlin',\n    rs: 'rust',\n  }\n\n  return extensionMap[extension] || extension\n}\n\nmodule.exports = (str, lang) => {\n  if (!lang) {\n    return wrap(str, 'text')\n  }\n  lang = lang.toLowerCase()\n  const rawLang = lang\n\n  lang = getLangCodeFromExtension(lang)\n\n  if (!prism.languages[lang]) {\n    try {\n      loadLanguages([lang])\n    } catch (e) {\n      console.warn(\n        `[vuepress] Syntax highlight for language \"${lang}\" is not supported.`\n      )\n    }\n  }\n  if (prism.languages[lang]) {\n    const code = prism.highlight(str, prism.languages[lang], lang)\n    return wrap(code, rawLang)\n  }\n  return wrap(str, 'text')\n}\n"
  },
  {
    "path": "packages/vue/docs/.vuepress/config.js",
    "content": "const path = require('path')\n\nmodule.exports = {\n  title: 'Formily Vue',\n  dest: './doc-site',\n  theme: '@vuepress-dumi/dumi',\n  head: [\n    [\n      'link',\n      {\n        rel: 'icon',\n        href: '//img.alicdn.com/imgextra/i3/O1CN01XtT3Tv1Wd1b5hNVKy_!!6000000002810-55-tps-360-360.svg',\n      },\n    ],\n  ],\n  themeConfig: {\n    logo: '//img.alicdn.com/imgextra/i2/O1CN01Kq3OHU1fph6LGqjIz_!!6000000004056-55-tps-1141-150.svg',\n    nav: [\n      {\n        text: '指南',\n        link: '/guide/',\n      },\n      {\n        text: 'API',\n        link: '/api/components/field',\n      },\n      {\n        text: 'Q&A',\n        link: '/questions/',\n      },\n      {\n        text: '主站',\n        link: 'https://formilyjs.org',\n      },\n      {\n        text: 'GITHUB',\n        link: 'https://github.com/alibaba/formily',\n      },\n    ],\n    sidebar: {\n      '/guide/': ['', 'architecture', 'concept'],\n      '/api/': [\n        {\n          title: 'Components',\n          children: [\n            '/api/components/field',\n            '/api/components/array-field',\n            '/api/components/object-field',\n            '/api/components/void-field',\n            '/api/components/schema-field',\n            '/api/components/schema-field-with-schema',\n            '/api/components/recursion-field',\n            '/api/components/recursion-field-with-component',\n            '/api/components/form-provider',\n            '/api/components/form-consumer',\n            '/api/components/expression-scope',\n          ],\n        },\n        {\n          title: 'Hooks',\n          children: [\n            '/api/hooks/use-field',\n            '/api/hooks/use-field-schema',\n            '/api/hooks/use-form',\n            '/api/hooks/use-form-effects',\n            '/api/hooks/use-parent-form',\n          ],\n        },\n        {\n          title: 'Shared',\n          children: [\n            '/api/shared/connect',\n            '/api/shared/injections',\n            '/api/shared/map-props',\n            '/api/shared/map-read-pretty',\n            '/api/shared/observer',\n            '/api/shared/schema',\n          ],\n        },\n      ],\n    },\n    lastUpdated: 'Last Updated',\n    smoothScroll: true,\n  },\n  plugins: [\n    'vuepress-plugin-typescript',\n    '@vuepress/back-to-top',\n    '@vuepress/last-updated',\n    '@vuepress-dumi/dumi-previewer',\n    [\n      '@vuepress/medium-zoom',\n      {\n        selector: '.content__default :not(a) > img',\n      },\n    ],\n  ],\n  configureWebpack: (config, isServer) => {\n    return {\n      resolve: {\n        alias: {\n          '@formily/vue': path.resolve(__dirname, '../../src'),\n          '@formily/json-schema': path.resolve(\n            __dirname,\n            '../../../json-schema/src'\n          ),\n          '@formily/path': path.resolve(__dirname, '../../../path/src'),\n          '@formily/reactive-vue': path.resolve(\n            __dirname,\n            '../../../reactive-vue/src'\n          ),\n          '@formily/element': path.resolve(__dirname, '../../../element/src'),\n          vue: path.resolve(\n            __dirname,\n            '../../../../node_modules/vue/dist/vue.runtime.esm.js'\n          ),\n        },\n      },\n    }\n  },\n}\n"
  },
  {
    "path": "packages/vue/docs/.vuepress/enhanceApp.js",
    "content": "import pageComponents from '@internal/page-components'\n\nexport default ({ Vue }) => {\n  for (const [name, component] of Object.entries(pageComponents)) {\n    Vue.component(name, component)\n  }\n}\n"
  },
  {
    "path": "packages/vue/docs/.vuepress/styles/index.styl",
    "content": ".navbar {\n  padding: 0 28px !important;\n}\n\n.navbar .logo {\n  height: auto !important;\n  width: 150px !important;\n}\n\n.navbar .site-name {\n  display: none;\n}\n\n.navbar .sidebar-button {\n  padding: 0;\n}\n\n.home .feature {\n  margin-bottom: 40px;\n  text-align: center;\n}\n\n.theme-dumi-content:not(.custom) {\n  max-width: 100%;\n}\n\n.page .page-nav {\n  max-width: 100%;\n}\n\n.dumi-previewer .dumi-previewer-actions .dumi-previewer-actions__icon {\n  padding: 0 !important;\n}\n\n.page .page-edit {\n  max-width 100%\n}\n\n.sidebar-group .sidebar-heading {\n  color: #454d64;\n  font-size: 16px;\n}\n\n.sidebar-group a.sidebar-link {\n  font-size: 0.9em;\n}\n\n.theme-dumi-content .custom-block.warning {\n  padding: 10px 20px;\n  border-color: #FFC11F;\n  box-shadow: 0 6px 16px -2px rgba(0,0,0,.06);\n  background: rgba(255,229,100,0.1);\n}\n.theme-dumi-content .custom-block.danger {\n  padding: 10px 20px;\n  p {\n    margin: 0;\n  }\n}\n\n.theme-dumi-content:not(.custom) > h1, .theme-dumi-content:not(.custom) > h2, .theme-dumi-content:not(.custom) > h3, .theme-dumi-content:not(.custom) > h4, .theme-dumi-content:not(.custom) > h5, .theme-dumi-content:not(.custom) > h6 {\n  margin-bottom: 18px;\n}\n\n.theme-dumi-content p {\n  margin: 1em 0;\n}\n\n.custom-block.warning p {\n  margin: 0;\n}\n\n// .theme-dumi-content div[class*=\"language-\"] {\n//   background-color: #f9fafb; \n// }\n\n// .theme-dumi-content pre[class*=\"language-\"] code {\n//   color: #000;\n// }\n\n.dumi-previewer .dumi-previewer-source,\n.dumi-previewer .dumi-previewer-demo {\n  overflow: auto;\n}\n\n@media (max-width: 719px) {\n  .sidebar-button + .home-link {\n    margin-left: 20px;\n  }\n}\n\n@media (max-width: 419px) {\n  .theme-dumi-content div[class*=\"language-\"] {\n    margin: 0;\n    border-radius: 0;\n  }\n}\n\n"
  },
  {
    "path": "packages/vue/docs/README.md",
    "content": "---\nhome: true\nheroText: Vue Library\ntagline: 阿里巴巴统一前端表单解决方案\nactionText: 开发指南\nactionLink: /guide/\nfeatures:\n  - title: 超高性能\n    details: 依赖追踪，高效更新，按需渲染\n  - title: 开箱即用\n    details: 组件状态自动绑定，接入成本极低\n  - title: 协议驱动\n    details: 标准JSON-Schema\n  - title: 场景复用\n    details: 基于协议驱动，抽象场景组件\n  - title: 调试友好\n    details: 天然对接Formily DevTools\n  - title: 智能提示\n    details: 拥抱Typescript\nfooter: Open-source MIT Licensed | Copyright © 2019-present\n---\n\n## 安装\n\nvue3:\n\n```bash\n$ npm install --save @formily/core @formily/vue\n```\n\nvue2:\n\n```bash\n$ npm install --save @formily/core @formily/vue @vue/composition-api\n```\n\n## 快速开始\n\n<dumi-previewer demoPath=\"index\" />\n"
  },
  {
    "path": "packages/vue/docs/api/components/array-field.md",
    "content": "---\norder: 1\n---\n\n# ArrayField\n\n## 描述\n\n作为@formily/core 的 [createArrayField](https://core.formilyjs.org/api/models/form#createarrayfield) Vue 实现，它是专门用于将 ViewModel 与输入控件做绑定的桥接组件，ArrayField 组件属性参考[IFieldFactoryProps](https://core.formilyjs.org/api/models/form#ifieldfactoryprops)\n\n::: warning\n我们在使用 ArrayField 组件的时候，一定要记得传 name 属性。同时要使用 scoped slots 形式来组织子组件\n:::\n\n## 签名\n\n```ts\ntype ArrayField = Vue.Component<any, any, any, IFieldFactoryProps>\n```\n\n## 用例\n\n<dumi-previewer demoPath=\"api/components/array-field\" />\n"
  },
  {
    "path": "packages/vue/docs/api/components/expression-scope.md",
    "content": "---\norder: 8\n---\n\n# ExpressionScope\n\n## 描述\n\n用于自定义组件内部给 json-schema 表达式传递局部作用域\n\n## 签名\n\n```ts\ninterface IExpressionScopeProps {\n  value?: any\n}\ntype ExpressionScope = Vue.Component<any, any, any, IExpressionScopeProps>\n```\n\n## 用例\n\n<dumi-previewer demoPath=\"api/components/expression-scope\" />\n"
  },
  {
    "path": "packages/vue/docs/api/components/field.md",
    "content": "---\norder: 0\n---\n\n# Field\n\n## 描述\n\n作为@formily/core 的 [createField](https://core.formilyjs.org/api/models/form#createfield) Vue 实现，它是专门用于将 ViewModel 与输入控件做绑定的桥接组件，Field 组件属性参考[IFieldFactoryProps](https://core.formilyjs.org/api/models/form#ifieldfactoryprops)\n\n::: warning\n我们在使用 Field 组件的时候，一定要记得传 name 属性。\n:::\n\n## 签名\n\n```ts\ntype Field = Vue.Component<any, any, any, IFieldFactoryProps>\n```\n\n## 用例\n\n<dumi-previewer demoPath=\"api/components/field\" />\n"
  },
  {
    "path": "packages/vue/docs/api/components/form-consumer.md",
    "content": "---\norder: 7\n---\n\n# FormConsumer\n\n## 描述\n\n表单响应消费者，专门用于监听表单模型数据变化而实现各种 UI 响应的组件，使用方式为 scoped slot.\n\n当回调函数内依赖的数据发生变化时就会重新渲染回调函数\n\nForm 参考[Form](https://core.formilyjs.org/api/models/form)\n\n## 用例\n\n<dumi-previewer demoPath=\"api/components/form-consumer\" />\n"
  },
  {
    "path": "packages/vue/docs/api/components/form-provider.md",
    "content": "---\norder: 6\n---\n\n# FormProvider\n\n## 描述\n\n入口组件，用于下发表单上下文给字段组件，负责整个表单状态的通讯，它相当于是一个通讯枢纽。\n\n## 签名\n\n```ts\ntype FormProvider = Vue.Component<\n  any,\n  any,\n  any,\n  {\n    form: Form //通过createForm创建的form实例\n  }\n>\n```\n\nForm 参考[Form](https://core.formilyjs.org/api/models/form)\n\n## 用例\n\n<dumi-previewer demoPath=\"api/components/form-provider\" />\n"
  },
  {
    "path": "packages/vue/docs/api/components/object-field.md",
    "content": "---\norder: 2\n---\n\n# ObjectField\n\n## 描述\n\n作为@formily/core 的 [createObjectField](https://core.formilyjs.org/api/models/form#createobjectfield) Vue 实现，它是专门用于将 ViewModel 与输入控件做绑定的桥接组件，ObjectField 组件属性参考[IFieldFactoryProps](https://core.formilyjs.org/api/models/form#ifieldfactoryprops)\n\n::: warning\n我们在使用 ObjectField 组件的时候，一定要记得传 name 属性。同时要使用 scoped slot 形式来组织子组件\n:::\n\n## 签名\n\n```ts\ntype ObjectField = Vue.Component<any, any, any, IFieldFactoryProps>\n```\n\n## 用例\n\n<dumi-previewer demoPath=\"api/components/object-field\" />\n"
  },
  {
    "path": "packages/vue/docs/api/components/recursion-field-with-component.md",
    "content": "---\norder: 5\n---\n\n# RecursionField (自增列表递归)\n\n## 用例\n\n<dumi-previewer demoPath=\"api/components/recursion-field-with-component\" />\n\n使用[useField](/api/hooks/use-field)和[useFieldSchema](/api/shared/use-field-schema)来获取当前字段上下文中的字段实例和字段 schema\n"
  },
  {
    "path": "packages/vue/docs/api/components/recursion-field.md",
    "content": "---\norder: 5\n---\n\n# RecursionField (简易递归)\n\n## 描述\n\n递归渲染组件，主要基于[JSON-Schema](/api/shared/schema)做递归渲染，它是[SchemaField](/api/components/schema-field)组件内部的核心渲染组件，当然，它是可以独立于 SchemaField 单独使用的，我们使用的时候主要是在自定义组件中使用，用于实现具有递归渲染能力的自定义组件\n\n## 签名\n\n```ts\ninterface IRecursionFieldProps {\n  schema: Schema //schema对象\n  name?: string //路径名称\n  basePath?: FormPathPattern //基础路径\n  onlyRenderProperties?: boolean //是否只渲染properties\n  onlyRenderSelf?: boolean //是否只渲染自身，不渲染properties\n  mapProperties?: (schema: Schema, name: string) => Schema //schema properties映射器，主要用于改写schema\n  filterProperties?: (schema: Schema, name: string) => boolean //schema properties过滤器，被过滤掉的schema节点不会被渲染\n}\n\ntype RecursionField = Vue.Component<IRecursionFieldProps>\n```\n\n## 用例\n\n<dumi-previewer demoPath=\"api/components/recursion-field\" />\n\n我们可以从组件属性中读取独立的 schema 对象，传给 RecursionField 渲染\n"
  },
  {
    "path": "packages/vue/docs/api/components/schema-field-with-schema.md",
    "content": "---\norder: 4\n---\n\n# SchemaField (JSON Schema)\n\n## 描述\n\nSchemaField 支持直接传入 [JSON-Schema](/api/shared/schema) 对象渲染表单。\n\n## 用例\n\n<dumi-previewer demoPath=\"api/components/schema-field-with-schema\" />\n"
  },
  {
    "path": "packages/vue/docs/api/components/schema-field.md",
    "content": "---\norder: 4\n---\n\n# SchemaField (Markup Schema)\n\n## 描述\n\nSchemaField 组件是专门用于解析[JSON-Schema](/api/shared/schema)动态渲染表单的组件。\n在使用 SchemaField 组件的时候，需要通过 createSchemaField 工厂函数创建一个 SchemaField 组件。\n\n## 签名\n\n```ts\ntype ComposeSchemaField = {\n  SchemaField: Vue.Component<any, any, any, ISchemaFieldProps>\n  SchemaMarkupField: Vue.Component<any, any, any, ISchema>\n  SchemaStringField: Vue.Component<any, any, any, Omit<ISchema, 'type'>>\n  SchemaObjectField: Vue.Component<any, any, any, Omit<ISchema, 'type'>>\n  SchemaArrayField: Vue.Component<any, any, any, Omit<ISchema, 'type'>>\n  SchemaBooleanField: Vue.Component<any, any, any, Omit<ISchema, 'type'>>\n  SchemaDateField: Vue.Component<any, any, any, Omit<ISchema, 'type'>>\n  SchemaDateTimeField: Vue.Component<any, any, any, Omit<ISchema, 'type'>>\n  SchemaVoidField: Vue.Component<any, any, any, Omit<ISchema, 'type'>>\n  SchemaNumberField: Vue.Component<any, any, any, Omit<ISchema, 'type'>>\n}\n\n//工厂函数参数属性\ninterface ISchemaFieldFactoryProps {\n  components?: {\n    [key: string]: Vue.Component //组件列表\n  }\n  scope?: any //全局作用域，用于实现协议表达式变量注入\n}\n\n//SchemaField属性\ninterface ISchemaFieldProps extends IFieldFactoryProps {\n  schema?: ISchema //字段schema\n  scope?: any //协议表达式作用域\n  name?: string //字段名称\n}\n\n//工厂函数\ninterface createSchemaField {\n  (props: ISchemaFieldFactoryProps): ComposeSchemaField\n}\n```\n\nIFieldFactoryProps 参考 [IFieldFactoryProps](https://core.formilyjs.org/api/models/form#ifieldfactoryprops)\n\nISchema 参考 [ISchema](/api/shared/schema#ischema)\n\n## 用例\n\n<dumi-previewer demoPath=\"api/components/schema-field\" />\n"
  },
  {
    "path": "packages/vue/docs/api/components/void-field.md",
    "content": "---\norder: 3\n---\n\n# VoidField\n\n## 描述\n\n作为@formily/core 的 [createVoidField](https://core.formilyjs.org/api/models/form#createvoidfield) Vue 实现，它是专门用于将 ViewModel 与虚拟布局控件做绑定的桥接组件，可以用来控制数据型字段的显示隐藏，交互模式等，VoidField 组件属性参考[IVoidFieldFactoryProps](https://core.formilyjs.org/api/models/form#ivoidfieldfactoryprops)\n\n::: warning\n我们在使用 VoidField 组件的时候，一定要记得传 name 属性。\n:::\n\n## 签名\n\n```ts\ntype VoidField = Vue.Component<any, any, any, IVoidFieldFactoryProps>\n```\n\n## 用例\n\n该例子演示了如何用 VoidField 控制子节点显示隐藏，注意观察，VoidField 隐藏的时候，子节点的数据会同时被清空，因为 visible 为 false 代表 display 为 none，这种隐藏是不会保留字段值的。\n\n但是再次显示的时候，又会恢复现场，这里是 Formily Core 内部的特性，支持完全恢复现场的能力。\n\n<dumi-previewer demoPath=\"api/components/void-field\" />\n"
  },
  {
    "path": "packages/vue/docs/api/hooks/use-field-schema.md",
    "content": "# useFieldSchema\n\n## 描述\n\n主要在自定义组件中读取当前字段的 Schema 信息，该 hook 只能用在 SchemaField 或者 RecursionField 的子树中使用\n\n## 签名\n\n```ts\ninterface useFieldSchema {\n  (): Ref<Schema>\n}\n```\n\nSchema 参考[Schema](/api/shared/schema)\n\n## 用例\n\n<dumi-previewer demoPath=\"api/hooks/use-field-schema\" />\n"
  },
  {
    "path": "packages/vue/docs/api/hooks/use-field.md",
    "content": "# useField\n\n## 描述\n\n主要用在自定义组件内读取当前字段属性，操作字段状态等，在所有 Field 组件的子树内都能使用，注意，拿到的是[GeneralField](https://core.formilyjs.org/api/models/field#generalfield)，如果需要对不同类型的字段做处理，请使用[Type Checker](https://core.formilyjs.org/api/entry/form-checker)\n\n::: warning\n注意：如果要在自定义组件内使用 useField，并响应字段模型变化，需要使用 [observer](/api/shared/observer) 包裹自定义组件\n:::\n\n## 签名\n\n```ts\ninterface useField {\n  (): Ref<Field>\n}\n```\n\n## 用例\n\n<dumi-previewer demoPath=\"api/hooks/use-field\" />\n"
  },
  {
    "path": "packages/vue/docs/api/hooks/use-form-effects.md",
    "content": "# useFormEffects\n\n## 描述\n\n主要在自定义组件中往当前[Form](https://core.formilyjs.org/api/models/form)实例注入副作用逻辑，用于实现一些较为复杂的场景化组件\n\n## 签名\n\n```ts\ninterface useFormEffects {\n  (form: Form): void\n}\n```\n\n## 用例\n\n<dumi-previewer demoPath=\"api/hooks/use-form-effects\" />\n"
  },
  {
    "path": "packages/vue/docs/api/hooks/use-form.md",
    "content": "# useForm\n\n## 描述\n\n主要在自定义组件中读取当前[Form](https://core.formilyjs.org/api/models/form)实例，用于实现一些副作用依赖，比如依赖 Form 的 errors 信息之类的，用于实现一些较为复杂的场景化组件\n\n## 签名\n\n```ts\ninterface useForm {\n  (): Form\n}\n```\n\n## 用例\n\n<dumi-previewer demoPath=\"api/hooks/use-form\" />\n"
  },
  {
    "path": "packages/vue/docs/api/hooks/use-parent-form.md",
    "content": "# useParentForm\n\n## 描述\n\n用于读取最近的 Form 或者 ObjectField 实例，主要方便于调用子表单的 submit/validate\n\n## 签名\n\n```ts\ninterface useParentForm {\n  (): Form | ObjectField\n}\n```\n\n## 用例\n\n<dumi-previewer demoPath=\"api/hooks/use-parent-form\" />\n"
  },
  {
    "path": "packages/vue/docs/api/shared/connect.md",
    "content": "# connect\n\n## 描述\n\n主要用于对第三方组件库的无侵入接入 Formily\n\n## 签名\n\n```ts\ninterface IComponentMapper<T extends Vue.Component> {\n  (target: T): Vue.Component\n}\ninterface connect<T extends Vue.Component> {\n  (target: T, ...args: IComponentMapper<T>[]): Vue.Component\n}\n```\n\n入参传入第一个参数是要接入的组件，后面的参数都是组件映射器，每个映射器都是一个函数，通常我们会使用内置的[mapProps](/api/shared/map-props)和[mapReadPretty](/api/shared/map-read-pretty)映射器\n\n## 用例\n\n<dumi-previewer demoPath=\"api/shared/connect\" />\n"
  },
  {
    "path": "packages/vue/docs/api/shared/injections.md",
    "content": "# injections\n\n## 描述\n\n@formily/vue 的所有 injections，方便用户做更复杂的个性化定制，我们可以通过 inject 来消费这些上下文\n\n## FormContext\n\n#### 描述\n\nForm 上下文，可以获取当前 Form 实例\n\n#### 签名\n\n```ts\nimport { Form } from '@formily/core'\n\nconst FormContext = inject<Form>(FormSymbol)\n```\n\n## FieldContext\n\n#### 描述\n\n字段上下文，可以获取当前字段实例\n\n#### 签名\n\n```ts\nimport { GeneralField } from '@formily/core'\n\nconst FieldContext = inject<GeneralField>(FieldSymbol)\n```\n\n## SchemaMarkupContext\n\n#### 描述\n\nSchema 标签上下文，主要用于收集 JSX Markup 写法的 Schema 标签，然后转换成标准 JSON Schema\n\n#### 签名\n\n```ts\nSchemaMarkupContext = inject<Schema>(SchemaMarkupSymbol)\n```\n\n## SchemaContext\n\n#### 描述\n\n字段 Schema 上下文，主要用于获取当前字段的 Schema 信息\n\n#### 签名\n\n```ts\nconst SchemaContext = inject<Schema>(SchemaSymbol)\n```\n\n## SchemaExpressionScopeContext\n\n#### 描述\n\nSchema 表达式作用域上下文\n\n#### 签名\n\n```ts\nconst SchemaExpressionScopeContext = inject<any>(SchemaExpressionScopeSymbol)\n```\n\n## SchemaOptionsContext\n\n#### 描述\n\nSchema 全局参数上下文，主要用于获取从 createSchemaField 传入的参数\n\n#### 签名\n\n```ts\nconst SchemaOptionsContext =\n  inject<ISchemaFieldFactoryOptions>(SchemaOptionsSymbol)\n```\n"
  },
  {
    "path": "packages/vue/docs/api/shared/map-props.md",
    "content": "# mapProps\n\n## 描述\n\n将[Field](https://core.formilyjs.org/api/models/field)属性与组件属性映射的适配器函数，主要与 connect 函数搭配使用\n\n## 签名\n\n```ts\nimport { Field, GeneralField } from '@formily/core'\n\ntype IStateMapper<Props> =\n  | {\n      [key in keyof Field]?: keyof Props | boolean\n    }\n  | ((props: Props, field: GeneralField) => Props)\n\ninterface mapProps<T extends Vue.Component> {\n  (...args: IStateMapper<VueComponentProps<T>>[]): Vue.Component\n}\n```\n\n- 参数可以传对象(key 是 field 的属性，value 是组件的属性，如果 value 为 true，代表映射的属性名相同)\n- 参数可以传函数，函数可以直接对属性做更复杂的映射\n\n## 用例\n\n<dumi-previewer demoPath=\"api/shared/map-props\" />\n"
  },
  {
    "path": "packages/vue/docs/api/shared/map-read-pretty.md",
    "content": "# mapReadPretty\n\n## 描述\n\n因为大多数第三方组件都不支持阅读态，如果想要快速支持阅读态的话，即可使用 mapReadPretty 函数来映射一个阅读态组件\n\n## 签名\n\n```ts\ninterface mapReadPretty {\n  (component: Vue.Component): Vue.Component\n}\n```\n\n## 用例\n\n<dumi-previewer demoPath=\"api/shared/map-read-pretty\" />\n"
  },
  {
    "path": "packages/vue/docs/api/shared/observer.md",
    "content": "# observer\n\n## 描述\n\nobserver 是从 [@formily/reactive-vue](https://reactive.formilyjs.org/api/vue/observer) 中导出的，API 完全一致，使用 observer 主要是将组件支持响应式更新能力。\n\n## 用例\n\n<dumi-previewer demoPath=\"api/shared/observer\" />\n"
  },
  {
    "path": "packages/vue/docs/api/shared/schema.md",
    "content": "# Schema\n\n## 描述\n\n@formily/vue 协议驱动最核心的部分，Schema 在其中是一个通用 Class，用户可以自行使用，同时在 SchemaField 和 RecursionField 中都有依赖它，它主要有几个核心能力：\n\n- 解析 json-schema 的能力\n- 将 json-schema 转换成 Field Model 的能力\n- 编译 json-schema 表达式的能力\n\n从@formily/vue 中可以导出 Schema 这个 Class，但是如果你不希望使用@formily/vue，你可以单独依赖@formily/json-schema 这个包\n\n## 构造器\n\n```ts\nclass Schema {\n  constructor(json: ISchema, parent?: ISchema)\n}\n```\n\n基于一份 json schema 数据创建一棵 Schema Tree，保证每个 schema 节点都是包含对应方法的\n\n## 属性\n\n| 属性                 | 描述                                              | 类型                                                                               | 字段模型映射                                                             |\n| -------------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |\n| type                 | 类型                                              | [SchemaTypes](#schematypes)                                                        | [GeneralField](https://core.formilyjs.org/api/models/field#generalfield) |\n| title                | 标题                                              | React.ReactNode                                                                    | `title`                                                                  |\n| description          | 描述                                              | React.ReactNode                                                                    | `description`                                                            |\n| default              | 默认值                                            | Any                                                                                | `initialValue`                                                           |\n| readOnly             | 是否只读                                          | Boolean                                                                            | `readOnly`                                                               |\n| writeOnly            | 是否只写                                          | Boolean                                                                            | `editable`                                                               |\n| enum                 | 枚举                                              | [SchemaEnum](#schemaenum)                                                          | `dataSource`                                                             |\n| const                | 校验字段值是否与 const 的值相等                   | Any                                                                                | `validator`                                                              |\n| multipleOf           | 校验字段值是否可被 multipleOf 的值整除            | Number                                                                             | `validator`                                                              |\n| maximum              | 校验最大值(大于)                                  | Number                                                                             | `validator`                                                              |\n| exclusiveMaximum     | 校验最大值（大于等于                              | Number                                                                             | `validator`                                                              |\n| minimum              | 校验最小值(小于)                                  | Number                                                                             | `validator`                                                              |\n| exclusiveMinimum     | 最小值（小于等于）                                | Number                                                                             | `validator`                                                              |\n| maxLength            | 校验最大长度                                      | Number                                                                             | `validator`                                                              |\n| minLength            | 校验最小长度                                      | Number                                                                             | `validator`                                                              |\n| pattern              | 正则校验规则                                      | RegExpString                                                                       | `validator`                                                              |\n| maxItems             | 最大条目数                                        | Number                                                                             | `validator`                                                              |\n| minItems             | 最小条目数                                        | Number                                                                             | `validator`                                                              |\n| uniqueItems          | 是否校验重复                                      | Boolean                                                                            | `validator`                                                              |\n| maxProperties        | 最大属性数量                                      | Number                                                                             | `validator`                                                              |\n| minProperties        | 最小属性数量                                      | Number                                                                             | `validator`                                                              |\n| required             | 必填                                              | Boolean                                                                            | `validator`                                                              |\n| format               | 正则校验格式                                      | [ValidatorFormats](https://core.formilyjs.org/api/models/field#fieldvalidator)     | `validator`                                                              |\n| properties           | 属性描述                                          | [SchemaProperties](#schemaproperties)                                              | -                                                                        |\n| items                | 数组描述                                          | [SchemaItems](#schemaitems)                                                        | -                                                                        |\n| additionalItems      | 额外数组元素描述                                  | Schema                                                                             | -                                                                        |\n| patternProperties    | 动态匹配对象的某个属性的 Schema                   | [SchemaProperties](#schemaproperties)                                              | -                                                                        |\n| additionalProperties | 匹配对象额外属性的 Schema                         | Schema                                                                             | -                                                                        |\n| x-index              | UI 展示顺序                                       | Number                                                                             | -                                                                        |\n| x-pattern            | UI 交互模式                                       | [FieldPatternTypes](https://core.formilyjs.org/api/models/field#fieldpatterntypes) | `pattern`                                                                |\n| x-display            | UI 展示                                           | [FieldDisplayTypes](https://core.formilyjs.org/api/models/field#fielddisplaytypes) | `display`                                                                |\n| x-validator          | 字段校验器                                        | [FieldValidator](https://core.formilyjs.org/api/models/field#fieldvalidator)       | `validator`                                                              |\n| x-decorator          | 字段 UI 包装器组件                                | `String \\| React.FC`                                                               | `decorator`                                                              |\n| x-decorator-props    | 字段 UI 包装器组件属性                            | Any                                                                                | `decorator`                                                              |\n| x-component          | 字段 UI 组件                                      | `String \\| React.FC`                                                               | `component`                                                              |\n| x-component-props    | 字段 UI 组件属性                                  | Any                                                                                | `component`                                                              |\n| x-reactions          | 字段联动协议                                      | [SchemaReactions](#schemareactions)                                                | `reactions`                                                              |\n| x-content            | 字段内容，用来传入某个组件的子节点                | React.ReactNode                                                                    | ReactChildren                                                            |\n| x-visible            | 字段显示隐藏                                      | Boolean                                                                            | `visible`                                                                |\n| x-hidden             | 字段 UI 隐藏(保留数据)                            | Boolean                                                                            | `hidden`                                                                 |\n| x-disabled           | 字段禁用                                          | Boolean                                                                            | `disabled`                                                               |\n| x-editable           | 字段可编辑                                        | Boolean                                                                            | `editable`                                                               |\n| x-read-only          | 字段只读                                          | Boolean                                                                            | `readOnly`                                                               |\n| x-read-pretty        | 字段阅读态                                        | Boolean                                                                            | `readPretty`                                                             |\n| definitions          | Schema 预定义                                     | [SchemaProperties](#schemaproperties)                                              | -                                                                        |\n| $ref                 | 从 Schema 预定义中读取 Schema 并合并至当前 Schema | String                                                                             | -                                                                        |\n| x-data               | 扩展属性                                          | Object                                                                             | data                                                                     |\n\n#### 详细说明\n\n- x-component 的组件标识与[createSchemaField](/api/components/schema-field#签名)传入的组件集合的 Key 匹配\n- x-decorator 的组件标识与[createSchemaField](/api/components/schema-field#签名)传入的组件集合的 Key 匹配\n- Schema 的每个属性都能使用字符串表达式<code v-pre>{{expression}}</code>，表达式变量可以从 createSchemaField 中传入，也可以从 SchemaField 组件中传入\n- $ref 指定 Schema 预定义的格式必须是<code v-pre>#/definitions/address</code>这种格式，不支持加载远程 JSON Schema\n\n## 方法\n\n### addProperty\n\n#### 描述\n\n添加属性描述\n\n#### 签名\n\n```ts\ninterface addProperty {\n  (key: string | number, schema: ISchema): Schema //返回添加后的Schema对象\n}\n```\n\n### removeProperty\n\n#### 描述\n\n移除属性描述\n\n#### 签名\n\n```ts\ninterface removeProperty {\n  (key: string | number): Schema //返回被移除的Schema对象\n}\n```\n\n### setProperties\n\n#### 描述\n\n覆盖式更新属性描述\n\n#### 签名\n\n```ts\ninterface setProperties {\n  (properties: SchemaProperties): Schema //返回当前Schema对象\n}\n```\n\nSchemaProperties 参考 [SchemaProperties](#schemaproperties)\n\n### addPatternProperty\n\n#### 描述\n\n添加正则属性描述\n\n#### 签名\n\n```ts\ninterface addPatternProperty {\n  (regexp: string, schema: ISchema): Schema //返回添加后的Schema对象\n}\n```\n\n### removePatternProperty\n\n#### 描述\n\n移除正则属性描述\n\n#### 签名\n\n```ts\ninterface removePatternProperty {\n  (regexp: string): Schema //返回移除后的Schema对象\n}\n```\n\n### setPatternProperties\n\n#### 描述\n\n覆盖式更新正则属性描述\n\n#### 签名\n\n```ts\ninterface setPatternProperties {\n  (properties: SchemaProperties): Schema //返回当前Schema对象\n}\n```\n\nSchemaProperties 参考 [SchemaProperties](#schemaproperties)\n\n### setAdditionalProperties\n\n#### 描述\n\n覆盖式更新扩展属性描述\n\n#### 签名\n\n```ts\ninterface setAdditionalProperties {\n  (properties: ISchema): Schema //返回扩展属性Schema对象\n}\n```\n\n### setItems\n\n#### 描述\n\n覆盖式更新数组项描述\n\n#### 签名\n\n```ts\ninterface setItems {\n  (items: SchemaItems): SchemaItems //返回更新后的SchemaItems对象\n}\n```\n\nSchemaItems 参考 [SchemaItems](#schemaitems)\n\n### setAdditionalItems\n\n#### 描述\n\n覆盖式更新数组扩展项描述\n\n#### 签名\n\n```ts\ninterface setAdditionalItems {\n  (items: ISchema): Schema //返回更新后的Schema对象\n}\n```\n\nSchemaItems 参考 [SchemaItems](#schemaitems)\n\n### mapProperties\n\n#### 描述\n\n遍历并映射当前 Schema 的 properties 属性，同时会基于 x-index 顺序来遍历\n\n#### 签名\n\n```ts\ninterface mapProperties<T> {\n  (mapper: (property: Schema, key: string | number) => T): T[]\n}\n```\n\n### mapPatternProperties\n\n#### 描述\n\n遍历并映射当前 Schema 的 patternProperties 属性，同时会基于 x-index 顺序来遍历\n\n#### 签名\n\n```ts\ninterface mapPatternProperties<T> {\n  (mapper: (property: Schema, key: string | number) => T): T[]\n}\n```\n\n### reduceProperties\n\n#### 描述\n\nreduce 当前 Schema 的 properties 属性，同时会基于 x-index 顺序来遍历\n\n#### 签名\n\n```ts\ninterface reduceProperties<T> {\n  (\n    reducer: (value: T, property: Schema, key: string | number) => T,\n    initialValue?: T\n  ): T\n}\n```\n\n### reducePatternProperties\n\n#### 描述\n\nreduce 当前 Schema 的 patternProperties 属性，同时会基于 x-index 顺序来遍历\n\n#### 签名\n\n```ts\ninterface reducePatternProperties<T> {\n  (\n    reducer: (value: T, property: Schema, key: string | number) => T,\n    initialValue?: T\n  ): T\n}\n```\n\n### compile\n\n#### 描述\n\n深度递归当前 Schema 对象中的表达式片段，编译表达式，并返回 Schema，我们可以传入作用域对象，在表达式中即可消费作用域变量\n\n表达式片段约定：以`{{`开头`}}`结尾的字符串代表一个表达式片段\n\n#### 签名\n\n```ts\ninterface compile {\n  (scope: any): Schema\n}\n```\n\n### fromJSON\n\n#### 描述\n\n将普通 json 数据转换成 Schema 对象\n\n#### 签名\n\n```ts\ninterface fromJSON {\n  (json: ISchema): Schema\n}\n```\n\n### toJSON\n\n#### 描述\n\n将当前 Schema 对象转换成普通 json 数据\n\n#### 签名\n\n```ts\ninterface toJSON {\n  (): ISchema\n}\n```\n\n### toFieldProps\n\n#### 描述\n\n将当前 Schema 对象转换成 Formily 字段模型属性，映射关系参考 [属性](#属性)\n\n#### 签名\n\n```ts\nimport { IFieldFactoryProps } from '@formily/core'\n\ninterface toFieldProps {\n  (): IFieldFactoryProps\n}\n```\n\nIFieldFactoryProps 参考 [IFieldFactoryProps](https://core.formilyjs.org/api/models/form#ifieldfactoryprops)\n\n## 静态方法\n\n### getOrderProperties\n\n#### 描述\n\n从 Schema 中获取排序后的 properties\n\n#### 签名\n\n```ts\ninterface getOrderProperties {\n  (schema: ISchema = {}, propertiesName: keyof ISchema = 'properties'): ISchema\n}\n```\n\n### compile\n\n#### 描述\n\n深度遍历任意对象中的表达式片段，表达式片段约定：以`{{`开头`}}`结尾的字符串代表一个表达式片段\n\n#### 签名\n\n```ts\ninterface compile {\n  (target: any, scope: any): any\n}\n```\n\n### shallowCompile\n\n#### 描述\n\n浅层遍历任意对象中的表达式片段，表达式片段约定：以`{{`开头`}}`结尾的字符串代表一个表达式片段\n\n#### 签名\n\n```ts\ninterface shallowCompile {\n  (target: any, scope: any): any\n}\n```\n\n### silent\n\n#### 描述\n\n是否静默编译，如果是，则表达式报错不会有任何提醒\n\n#### 签名\n\n```ts\ninterface silent {\n  (value?: boolean): void\n}\n```\n\n### isSchemaInstance\n\n#### 描述\n\n判断某个对象是否为 Schema Class 的实例对象\n\n#### 签名\n\n```ts\ninterface isSchemaInstance {\n  (target: any): target is Schema\n}\n```\n\n### registerCompiler\n\n#### 描述\n\n注册表达式编译器\n\n#### 签名\n\n```ts\ninterface registerCompiler {\n  (compiler: (expression: string, scope: any) => any): void\n}\n```\n\n### registerPatches\n\n#### 描述\n\n注册 Schema 补丁，方便做不同版本的 Schema 协议兼容\n\n#### 签名\n\n```ts\ntype SchemaPatch = (schema: ISchema) => ISchema\n\ninterface registerPatches {\n  (...args: SchemaPatch[]): void\n}\n```\n\n### registerVoidComponents\n\n#### 描述\n\n给字段组件打上标识，标识该组件是虚拟组件，与 formily1.x 做兼容\n\n#### 签名\n\n```ts\ninterface registerVoidComponents {\n  (components: string[]): void\n}\n```\n\n#### 用例\n\n```ts\nimport { Schema } from '@formily/react'\n\nSchema.registerVoidComponents(['card', 'tab', 'step'])\n```\n\n::: warning\n\n  <p>注意，该 api 需要配合 <code>enablePolyfills(['1.0'])</code> 使用</p>\n:::\n\n### registerTypeDefaultComponents\n\n#### 描述\n\n给 Schema 类型标识默认组件类型\n\n#### 签名\n\n```ts\ninterface registerTypeDefaultComponents {\n  (maps: Record<string, string>): void\n}\n```\n\n#### 用例\n\n```ts\nimport { Schema } from '@formily/vue'\n\nSchema.registerTypeDefaultComponents({\n  string: 'Input',\n  number: 'NumberPicker',\n  array: 'ArrayTable',\n})\n```\n\n注意，该 api 需要配合 <code>enablePolyfills(['1.0'])</code> 使用\n\n### registerPolyfills\n\n#### 描述\n\n注册协议兼容垫片\n\n#### 签名\n\n```ts\ntype SchemaPatch = (schema: ISchema) => ISchema\n\ninterface registerPolyfills {\n  (version: string, patch: SchemaPatch): void\n}\n```\n\n#### 用例\n\n```ts\nimport { Schema } from '@formily/react'\n\nSchema.registerPolyfills('1.0', (schema) => {\n  schema['x-decorator'] = 'FormItem'\n  return schema\n})\n```\n\n### enablePolyfills\n\n#### 描述\n\n开启协议垫片，默认内置 1.0 版本协议兼容垫片，主要兼容特性：\n\n- x-decorator 不声明，自动作为 FormItem\n- x-linkages 转换为 x-reactions\n- x-props 自动转换为 x-decorator-props\n- x-rules 转换为 x-validator\n- editable 转换为 x-editable\n- visible 转换为 x-visible\n- x-component 为 card/block/grid-row/grid-col/grid/layout/step/tab/text-box 自动转换 VoidField，\n\n#### 签名\n\n```ts\ninterface enablePolyfills {\n  (versions: string[]): void\n}\n```\n\n#### 用例\n\n```ts\nimport { Schema } from '@formily/vue'\n\nSchema.enablePolyfills(['1.0'])\n```\n\n## 类型\n\n### ISchema\n\n#### 描述\n\nISchema 就是一份普通 JSON 数据，同时它是遵循 Schema [属性](#属性) 规范的 JSON 数据\n\n### SchemaTypes\n\n#### 描述\n\nSchema 描述的类型\n\n#### 签名\n\n```ts\ntype SchemaTypes =\n  | 'string'\n  | 'object'\n  | 'array'\n  | 'number'\n  | 'boolean'\n  | 'void'\n  | 'date'\n  | 'datetime'\n  | (string & {})\n```\n\n### SchemaProperties\n\n#### 描述\n\nSchema 属性描述\n\n#### 签名\n\n```ts\ntype SchemaProperties = Record<string, ISchema>\n```\n\n### SchemaItems\n\n#### 描述\n\nSchema 数组项描述\n\n#### 签名\n\n```ts\ntype SchemaItems = ISchema | ISchema[]\n```\n\n### SchemaEnum\n\n#### 描述\n\nSchema 枚举\n\n#### 签名\n\n```ts\ntype SchemaEnum<Message> = Array<\n  | string\n  | number\n  | { label: Message; value: any; [key: string]: any }\n  | { key: any; title: Message; [key: string]: any }\n>\n```\n\n### SchemaReactions\n\n#### 描述\n\nSchema 联动协议，如果 reaction 对象里包含 target，则代表主动联动模式，否则代表被动联动模式  \n如果想实现更复杂的联动，可以通过作用域传入 reaction 响应器函数进行处理  \nFormPathPattern 路径语法文档看[这里](https://core.formilyjs.org/zh-CN/api/entry/form-path#formpathpattern)\n\n#### 签名\n\n```ts\nimport { IGeneralFieldState } from '@formily/core'\n\ntype SchemaReactionEffect =\n  | 'onFieldInit'\n  | 'onFieldMount'\n  | 'onFieldUnmount'\n  | 'onFieldValueChange'\n  | 'onFieldInputValueChange'\n  | 'onFieldInitialValueChange'\n  | 'onFieldValidateStart'\n  | 'onFieldValidateEnd'\n  | 'onFieldValidateFailed'\n  | 'onFieldValidateSuccess'\n\ntype SchemaReaction<Field = any> =\n  | {\n      dependencies?: //依赖的字段路径列表，支持FormPathPattern数据路径语法, 只能以点路径描述依赖，支持相对路径\n      | Array<\n            | string //如果数组里是string，那么读的时候也是数组格式\n            | {\n                //如果数组里是对象, 那么读的时候通过name从$deps获取\n                name?: string //从$deps读取时的别名\n                type?: string //字段类型\n                source?: string //字段路径\n                property?: string //依赖属性, 默认为value\n              }\n          >\n        | Record<string, string> //如果是对象格式，读的时候也是对象格式，只是对象的key相当于别名\n      when?: string | boolean //联动条件\n      target?: string //要操作的字段路径，支持FormPathPattern匹配路径语法，注意：不支持相对路径！！\n      effects?: SchemaReactionEffect[] //主动模式下的独立生命周期钩子\n      fulfill?: {\n        //满足条件\n        state?: IGeneralFieldState //更新状态\n        schema?: ISchema //更新Schema\n        run?: string //执行语句\n      }\n      otherwise?: {\n        //不满足条件\n        state?: IGeneralFieldState //更新状态\n        schema?: ISchema //更新Schema\n        run?: string //执行语句\n      }\n    }\n  | ((field: Field) => void) //支持函数, 可以复杂联动\n\ntype SchemaReactions<Field = any> =\n  | SchemaReaction<Field>\n  | SchemaReaction<Field>[] //支持传入数组\n```\n\n#### 用例\n\n**主动联动**\n\n写法一，标准主动联动\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"target\": \"target\",\n        \"when\": \"{{$self.value === '123'}}\",\n        \"fulfill\": {\n          \"state\": {\n            \"visible\": false\n          }\n        },\n        \"otherwise\": {\n          \"state\": {\n            \"visible\": true\n          }\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\n写法二，局部表达式分发联动\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"target\": \"target\",\n        \"fulfill\": {\n          \"state\": {\n            \"visible\": \"{{$self.value === '123'}}\" //任意层次属性都支持表达式\n          }\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\n写法三，相邻元素联动\n\n```json\n{\n  \"type\": \"array\",\n  \"x-component\": \"ArrayTable\",\n  \"items\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"source\": {\n        \"type\": \"string\",\n        \"x-component\": \"Input\",\n        \"x-reactions\": {\n          \"target\": \".target\",\n          \"fulfill\": {\n            \"state\": {\n              \"visible\": \"{{$self.value === '123'}}\" //任意层次属性都支持表达式\n            }\n          }\n        }\n      },\n      \"target\": {\n        \"type\": \"string\",\n        \"x-component\": \"Input\"\n      }\n    }\n  }\n}\n```\n\n写法四，基于 Schema 协议联动\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"target\": \"target\",\n        \"fulfill\": {\n          \"schema\": {\n            \"x-visible\": \"{{$self.value === '123'}}\" //任意层次属性都支持表达式\n          }\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\n写法五，基于 run 语句联动\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"fulfill\": {\n          \"run\": \"$form.setFieldState('target',state=>{state.visible = $self.value === '123'})\"\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\n写法六，基于生命周期钩子联动\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"target\": \"target\",\n        \"effects\": [\"onFieldInputValueChange\"],\n        \"fulfill\": {\n          \"state\": {\n            \"visible\": \"{{$self.value === '123'}}\" //任意层次属性都支持表达式\n          }\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\n**被动联动**\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"dependencies\": [\"source\"], //依赖路径写法默认是取value，如果依赖的是字段的其他属性，可以使用 source#modified，用#分割取详细属性\n        // \"dependencies\":{ aliasName:\"source\" }, //别名形式\n        \"fulfill\": {\n          \"schema\": {\n            \"x-visible\": \"{{$deps[0] === '123'}}\" //任意层次属性都支持表达式\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n**复杂联动**\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": \"{{myReaction}}\" //外部传入的函数，在函数内可以实现更复杂的联动\n    }\n  }\n}\n```\n\n**组件属性联动**\n\n写法一，操作状态\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"target\": \"target\",\n        \"fulfill\": {\n          \"state\": {\n            \"component[1].style.color\": \"{{$self.value === '123' ? 'red' : 'blue'}}\" //任意层次属性都支持表达式，同时key是支持路径表达式的，可以实现精确操作属性\n          }\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\n写法二，操作 Schema 协议\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"source\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\",\n      \"x-reactions\": {\n        \"target\": \"target\",\n        \"fulfill\": {\n          \"schema\": {\n            \"x-component-props.style.color\": \"{{$self.value === '123' ? 'red' : 'blue'}}\" //任意层次属性都支持表达式，同时key是支持路径表达式的，可以实现精确操作属性\n          }\n        }\n      }\n    },\n    \"target\": {\n      \"type\": \"string\",\n      \"x-component\": \"Input\"\n    }\n  }\n}\n```\n\n## 内置表达式作用域\n\n内置表达式作用域主要用于在表达式中实现各种联动关系\n\n### $self\n\n代表当前字段实例，可以在普通属性表达式中使用，也能在 x-reactions 中使用\n\n### $values\n\n代表顶层表单数据，可以在普通属性表达式中使用，也能在 x-reactions 中使用\n\n### $form\n\n代表当前 Form 实例，可以在普通属性表达式中使用，也能在 x-reactions 中使用\n\n### $observable\n\n用于创建响应式对象，使用方式与 observable 一致\n\n### $memo\n\n用于创建持久引用数据，使用方式与 autorun.memo 一致\n\n### $effect\n\n用于响应 autorun 第一次执行的下一个微任务时机与响应 autorun 的 dispose，使用方式与 autorun.effect 一致\n\n### $dependencies\n\n只能在 x-reactions 中的表达式消费，与 x-reactions 定义的 dependencies 对应，数组顺序一致\n\n### $deps\n\n只能在 x-reactions 中的表达式消费，与 x-reactions 定义的 dependencies 对应，数组顺序一致\n\n### $target\n\n只能在 x-reactions 中的表达式消费，代表主动模式的 target 字段\n"
  },
  {
    "path": "packages/vue/docs/demos/api/components/array-field.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <ArrayField name=\"array\">\n      <template #default=\"{ field }\">\n        <div\n          v-for=\"(item, index) in field.value || []\"\n          :key=\"`${item.id}-${index}`\"\n          :style=\"{ marginBottom: '10px' }\"\n        >\n          <Space>\n            <Field :name=\"`${index}.value`\" :component=\"[Input]\" />\n            <Button\n              @click=\"\n                () => {\n                  field.remove(index)\n                }\n              \"\n            >\n              Remove\n            </Button>\n            <Button\n              @click=\"\n                () => {\n                  field.moveUp(index)\n                }\n              \"\n            >\n              Move Up\n            </Button>\n            <Button\n              @click=\"\n                () => {\n                  field.moveDown(index)\n                }\n              \"\n            >\n              Move Down\n            </Button>\n          </Space>\n        </div>\n        <Button @click=\"() => field.push({ id: Date.now(), value: '' })\">\n          Add\n        </Button>\n      </template>\n    </ArrayField>\n  </FormProvider>\n</template>\n\n<script>\nimport { Input, Space, Button } from 'ant-design-vue'\nimport { createForm } from '@formily/core'\nimport { FormProvider, ArrayField, Field } from '@formily/vue'\nimport 'ant-design-vue/dist/antd.css'\n\nexport default {\n  components: { FormProvider, ArrayField, Field, Space, Button },\n  data() {\n    return {\n      Input,\n      form: createForm(),\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/components/expression-scope.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :scope=\"{ $outerScope: 'outer scope value' }\">\n      <SchemaVoidField x-component=\"Container\">\n        <SchemaVoidField\n          name=\"div\"\n          x-component=\"Text\"\n          :x-component-props=\"{ text: `{{$innerScope + ' ' + $outerScope}}` }\"\n        />\n      </SchemaVoidField>\n    </SchemaField>\n  </FormProvider>\n</template>\n\n<script>\nimport { defineComponent } from '@vue/composition-api'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  h,\n  createSchemaField,\n  ExpressionScope,\n} from '@formily/vue'\n\nconst Container = defineComponent({\n  setup(_props, { slots }) {\n    return () =>\n      h(\n        ExpressionScope,\n        {\n          props: { value: { $innerScope: 'inner scope value' } },\n        },\n        slots\n      )\n  },\n})\nconst Text = defineComponent({\n  props: ['text'],\n  setup(props) {\n    return () => h('div', {}, { default: () => props.text })\n  },\n})\nconst SchemaField = createSchemaField({\n  components: { Container, Text },\n})\n\nexport default {\n  components: { FormProvider, ...SchemaField },\n  data() {\n    return {\n      Text,\n      form: createForm(),\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/components/field.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Field name=\"input\" :component=\"[Input, { placeholder: '请输入' }]\" />\n  </FormProvider>\n</template>\n\n<script>\nimport { Input } from 'ant-design-vue'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/vue'\nimport 'ant-design-vue/dist/antd.css'\n\nexport default {\n  components: { FormProvider, Field },\n  data() {\n    return {\n      Input,\n      form: createForm(),\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/components/form-consumer.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Field name=\"input\" :component=\"[Input]\" />\n    <FormConsumer>\n      <template #default=\"{ form }\">\n        {{ form.values.input }}\n      </template>\n    </FormConsumer>\n  </FormProvider>\n</template>\n\n<script>\nimport { Input } from 'ant-design-vue'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, FormConsumer } from '@formily/vue'\nimport 'ant-design-vue/dist/antd.css'\n\nexport default {\n  components: { FormProvider, Field, FormConsumer },\n  data() {\n    return {\n      Input,\n      form: createForm(),\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/components/form-provider.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Field name=\"input\" :component=\"[Input]\" />\n  </FormProvider>\n</template>\n\n<script>\nimport { Input } from 'ant-design-vue'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field } from '@formily/vue'\nimport 'ant-design-vue/dist/antd.css'\n\nexport default {\n  components: { FormProvider, Field },\n  data() {\n    return {\n      Input,\n      form: createForm(),\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/components/object-field.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <ObjectField name=\"object\">\n      <template #default=\"{ field }\">\n        <div\n          v-for=\"key in Object.keys(field.value || {})\"\n          :key=\"key\"\n          :style=\"{ marginBottom: '10px' }\"\n        >\n          <Space>\n            <Field :name=\"key\" :component=\"[Input, { placeholder: key }]\" />\n            <Button @click=\"field.removeProperty(key)\"> Remove </Button>\n          </Space>\n        </div>\n        <Space>\n          <Field\n            name=\"propertyName\"\n            basePath=\"\"\n            required\n            :component=\"[Input, { placeholder: 'Property Name' }]\"\n          />\n          <Button @click=\"addPropertyToField(field)\"> Add </Button>\n        </Space>\n      </template>\n    </ObjectField>\n  </FormProvider>\n</template>\n\n<script>\nimport { Input, Space, Button } from 'ant-design-vue'\nimport { createForm } from '@formily/core'\nimport { FormProvider, ObjectField, Field } from '@formily/vue'\nimport 'ant-design-vue/dist/antd.css'\n\nexport default {\n  components: { FormProvider, ObjectField, Field, Space, Button },\n  data() {\n    return {\n      Input,\n      form: createForm(),\n    }\n  },\n  methods: {\n    addPropertyToField(field) {\n      const name = this.form.values.propertyName\n      if (name && !this.form.existValuesIn(`object.${name}`)) {\n        field.addProperty(name, '')\n        this.form.deleteValuesIn('propertyName')\n      }\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/components/recursion-field-with-component.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaArrayField name=\"custom\" x-component=\"ArrayItems\">\n        <SchemaObjectField>\n          <SchemaStringField name=\"input\" x-component=\"Input\" />\n        </SchemaObjectField>\n      </SchemaArrayField>\n    </SchemaField>\n  </FormProvider>\n</template>\n\n<script>\nimport { defineComponent, h } from '@vue/composition-api'\n// or \"import { defineComponent, h } from 'vue'\" if using vue3\nimport { Input, Button, Space } from 'ant-design-vue'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  createSchemaField,\n  RecursionField,\n  useField,\n  useFieldSchema,\n} from '@formily/vue'\nimport { observer } from '@formily/reactive-vue'\nimport 'ant-design-vue/dist/antd.css'\n\nconst ArrayItems = observer(\n  defineComponent({\n    setup() {\n      const fieldRef = useField()\n      const schemaRef = useFieldSchema()\n\n      return () => {\n        const field = fieldRef.value\n        const schema = schemaRef.value\n        const items = field.value?.map((item, index) => {\n          return h('div', { key: item.id, style: { marginBottom: '10px' } }, [\n            h(Space, [\n              // params of render function is different in vue3\n              h(RecursionField, {\n                props: { schema: schema.items, name: index },\n              }),\n              h(Button, { on: { click: () => field.remove(index) } }, [\n                'Remove',\n              ]),\n            ]),\n          ])\n        })\n        const button = h(\n          Button,\n          { on: { click: () => field.push({ id: Date.now() }) } },\n          ['Add']\n        )\n        return h('div', [items, button])\n      }\n    },\n  })\n)\n\nconst { SchemaField, SchemaStringField, SchemaArrayField, SchemaObjectField } =\n  createSchemaField({\n    components: {\n      ArrayItems,\n      Input,\n    },\n  })\n\nexport default {\n  components: {\n    FormProvider,\n    SchemaField,\n    SchemaStringField,\n    SchemaArrayField,\n    SchemaObjectField,\n  },\n  data() {\n    return {\n      form: createForm(),\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/components/recursion-field.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaObjectField\n        name=\"custom\"\n        x-component=\"Custom\"\n        :x-component-props=\"{\n          schema: {\n            type: 'object',\n            properties: {\n              input: {\n                type: 'string',\n                'x-component': 'Input',\n              },\n            },\n          },\n        }\"\n      />\n    </SchemaField>\n  </FormProvider>\n</template>\n\n<script>\nimport { Input } from 'ant-design-vue'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField, RecursionField } from '@formily/vue'\nimport 'ant-design-vue/dist/antd.css'\n\n// functional component in vue2\nconst Custom = {\n  functional: true,\n  render(h, { props }) {\n    return h(RecursionField, {\n      props: {\n        name: props.name,\n        schema: props.schema,\n        onlyRenderProperties: true,\n      },\n    })\n  },\n}\n\nconst { SchemaField, SchemaObjectField } = createSchemaField({\n  components: {\n    Custom,\n    Input,\n  },\n})\n\nexport default {\n  components: { FormProvider, SchemaField, SchemaObjectField },\n  data() {\n    return {\n      form: createForm(),\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/components/schema-field-with-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField\n      :schema=\"{\n        type: 'object',\n        properties: {\n          input: {\n            type: 'string',\n            'x-component': 'Input',\n          },\n        },\n      }\"\n    >\n    </SchemaField>\n  </FormProvider>\n</template>\n\n<script>\nimport { Input } from 'ant-design-vue'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport 'ant-design-vue/dist/antd.css'\n\nconst { SchemaField } = createSchemaField({\n  components: {\n    Input,\n  },\n})\n\nexport default {\n  components: { FormProvider, SchemaField },\n  data() {\n    return {\n      form: createForm(),\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/components/schema-field.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaStringField name=\"input\" x-component=\"Input\" />\n    </SchemaField>\n  </FormProvider>\n</template>\n\n<script>\nimport { Input } from 'ant-design-vue'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport 'ant-design-vue/dist/antd.css'\n\nconst { SchemaField, SchemaStringField } = createSchemaField({\n  components: {\n    Input,\n  },\n})\n\nexport default {\n  components: { FormProvider, SchemaField, SchemaStringField },\n  data() {\n    return {\n      form: createForm(),\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/components/void-field.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Space>\n      <VoidField name=\"layout\">\n        <Field name=\"input\" :component=\"[Input]\" />\n      </VoidField>\n      <FormConsumer>\n        <template #default=\"{ form }\">\n          <Space>\n            <Button\n              @click=\"\n                () => {\n                  form\n                    .query('layout')\n                    .take()\n                    .setState((state) => {\n                      state.visible = !state.visible\n                    })\n                }\n              \"\n            >\n              {{ form.query('layout').get('visible') ? 'Hide' : 'Show' }}\n            </Button>\n            <div>{{ JSON.stringify(form.values, null, 2) }}</div>\n          </Space>\n        </template>\n      </FormConsumer>\n    </Space>\n  </FormProvider>\n</template>\n\n<script>\nimport { Input, Space, Button } from 'ant-design-vue'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, FormConsumer, VoidField } from '@formily/vue'\nimport 'ant-design-vue/dist/antd.css'\n\nexport default {\n  components: { FormProvider, Field, FormConsumer, VoidField, Space, Button },\n  data() {\n    return {\n      Input,\n      form: createForm(),\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/hooks/use-field-schema.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaObjectField\n        name=\"custom\"\n        x-component=\"Custom\"\n        :x-component-props=\"{\n          schema: {\n            type: 'object',\n            properties: {\n              input: {\n                type: 'string',\n                'x-component': 'Custom',\n              },\n            },\n          },\n        }\"\n      />\n    </SchemaField>\n  </FormProvider>\n</template>\n\n<script>\nimport { defineComponent, h } from '@vue/composition-api'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField, useFieldSchema } from '@formily/vue'\nimport 'ant-design-vue/dist/antd.css'\n\nconst Custom = defineComponent({\n  setup() {\n    const schemaRef = useFieldSchema()\n    return () => {\n      const schema = schemaRef.value\n      return h(\n        'div',\n        {\n          style: { whiteSpace: 'pre' },\n        },\n        [JSON.stringify(schema.toJSON(), null, 4)]\n      )\n    }\n  },\n})\n\nconst { SchemaField, SchemaObjectField } = createSchemaField({\n  components: {\n    Custom,\n  },\n})\n\nexport default {\n  components: { FormProvider, SchemaField, SchemaObjectField },\n  data() {\n    const form = createForm({ validateFirst: true })\n    return {\n      form,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/hooks/use-field.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Form layout=\"vertical\">\n      <Field\n        name=\"name\"\n        title=\"Name\"\n        required\n        :decorator=\"[FormItem]\"\n        :component=\"[Input, { placeholder: 'Please Input' }]\"\n      />\n      <FormConsumer>\n        <template #default=\"{ form }\">\n          <div style=\"white-space: pre; margin-bottom: 16px\">\n            {{ JSON.stringify(form.values, null, 2) }}\n          </div>\n          <Button\n            type=\"primary\"\n            @click=\"\n              () => {\n                form.submit(log)\n              }\n            \"\n          >\n            Submit\n          </Button>\n        </template>\n      </FormConsumer>\n    </Form>\n  </FormProvider>\n</template>\n\n<script>\nimport { defineComponent, h } from '@vue/composition-api'\nimport { Form, Input, Button } from 'ant-design-vue'\nimport { createForm, setValidateLanguage } from '@formily/core'\nimport { FormProvider, FormConsumer, Field, useField } from '@formily/vue'\nimport { observer } from '@formily/reactive-vue'\nimport 'ant-design-vue/dist/antd.css'\n\nsetValidateLanguage('en')\n\nconst FormItem = observer(\n  defineComponent({\n    setup(props, { slots }) {\n      const fieldRef = useField()\n      return () => {\n        const field = fieldRef.value\n        return h(\n          Form.Item,\n          {\n            props: {\n              label: field.title,\n              required: field.required,\n              help: field.selfErrors?.length ? field.selfErrors : undefined,\n              extra: field.description,\n              validateStatus: field.validateStatus,\n            },\n          },\n          slots?.default()\n        )\n      }\n    },\n  })\n)\n\nexport default {\n  components: {\n    FormProvider,\n    FormConsumer,\n    Field,\n    Form,\n    Button,\n  },\n  data() {\n    const form = createForm({ validateFirst: true })\n    return {\n      FormItem,\n      Input,\n      form,\n    }\n  },\n  methods: {\n    log(...args) {\n      console.log(...args)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/hooks/use-form-effects.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Field\n      name=\"input\"\n      :decorator=\"[FormItem]\"\n      :component=\"[Input, { placeholder: 'input' }]\"\n    />\n    <Field name=\"custom\" :decorator=\"[FormItem]\" :component=\"[Custom]\" />\n  </FormProvider>\n</template>\n\n<script>\nimport { defineComponent, h } from '@vue/composition-api'\nimport { createForm, onFieldReact } from '@formily/core'\nimport { FormProvider, Field, useFormEffects } from '@formily/vue'\nimport { Form, Input } from 'ant-design-vue'\nimport 'ant-design-vue/dist/antd.css'\n\nconst Custom = defineComponent({\n  setup() {\n    useFormEffects(() => {\n      onFieldReact('custom.bb', (field) => {\n        field.value = field.query('.aa').get('value')\n      })\n    })\n    return () =>\n      h('div', {}, [\n        h(\n          Field,\n          {\n            props: {\n              name: 'aa',\n              decorator: [Form.Item],\n              component: [Input, { placeholder: 'aa' }],\n            },\n          },\n          {}\n        ),\n        h(\n          Field,\n          {\n            props: {\n              name: 'bb',\n              decorator: [Form.Item],\n              component: [Input, { placeholder: 'bb' }],\n            },\n          },\n          {}\n        ),\n      ])\n  },\n})\n\nexport default {\n  components: {\n    FormProvider,\n    Field,\n  },\n  data() {\n    const form = createForm({\n      effects() {\n        onFieldReact('custom.aa', (field) => {\n          field.value = field.query('input').get('value')\n        })\n      },\n    })\n    return {\n      FormItem: Form.Item,\n      Input,\n      Custom,\n      form,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/hooks/use-form.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Space>\n      <Field name=\"input\" :component=\"[Input]\" />\n      <Field name=\"custom\" :component=\"[Custom]\" />\n    </Space>\n  </FormProvider>\n</template>\n\n<script>\nimport { defineComponent, h } from '@vue/composition-api'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, useForm } from '@formily/vue'\nimport { observer } from '@formily/reactive-vue'\nimport { Input, Space } from 'ant-design-vue'\nimport 'ant-design-vue/dist/antd.css'\n\nconst Custom = observer(\n  defineComponent({\n    setup() {\n      const formRef = useForm()\n      return () => {\n        const form = formRef.value\n        return h('div', {}, [form.values.input])\n      }\n    },\n  })\n)\n\nexport default {\n  components: {\n    FormProvider,\n    Field,\n    Space,\n  },\n  data() {\n    const form = createForm({ validateFirst: true })\n    return {\n      Input,\n      Custom,\n      form,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/hooks/use-parent-form.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <ObjectField name=\"object\">\n      <Custom></Custom>\n    </ObjectField>\n    <Custom></Custom>\n    <VoidField name=\"void\">\n      <Custom></Custom>\n    </VoidField>\n  </FormProvider>\n</template>\n\n<script>\nimport { defineComponent, h } from '@vue/composition-api'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  ObjectField,\n  VoidField,\n  useParentForm,\n} from '@formily/vue'\nimport { observer } from '@formily/reactive-vue'\n\nconst Custom = observer(\n  defineComponent({\n    setup() {\n      const formRef = useParentForm()\n      return () => {\n        const form = formRef.value\n        return h('div', {}, [form.displayName])\n      }\n    },\n  })\n)\n\nexport default {\n  components: {\n    FormProvider,\n    ObjectField,\n    VoidField,\n    VoidField,\n    Custom,\n  },\n  data() {\n    const form = createForm()\n    return {\n      form,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/shared/connect.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Form layout=\"vertical\">\n      <Field\n        name=\"name\"\n        title=\"Name\"\n        required\n        :decorator=\"[FormItem]\"\n        :component=\"[Input, { placeholder: 'Please Input' }]\"\n      />\n      <FormConsumer>\n        <template #default=\"{ form }\">\n          <div style=\"white-space: pre; margin-bottom: 16px\">\n            {{ JSON.stringify(form.values, null, 2) }}\n          </div>\n          <Button\n            type=\"primary\"\n            @click=\"\n              () => {\n                form.submit(log)\n              }\n            \"\n          >\n            Submit\n          </Button>\n        </template>\n      </FormConsumer>\n    </Form>\n  </FormProvider>\n</template>\n\n<script>\nimport { Form, Input, Button } from 'ant-design-vue'\nimport { createForm, setValidateLanguage } from '@formily/core'\nimport {\n  FormProvider,\n  FormConsumer,\n  Field,\n  connect,\n  mapProps,\n} from '@formily/vue'\nimport 'ant-design-vue/dist/antd.css'\n\nsetValidateLanguage('en')\n\nconst FormItem = connect(\n  Form.Item,\n  mapProps(\n    {\n      title: 'label',\n      description: 'extra',\n      required: true,\n      validateStatus: true,\n    },\n    (props, field) => {\n      return {\n        ...props,\n        help: field.selfErrors?.length ? field.selfErrors : undefined,\n      }\n    }\n  )\n)\n\nexport default {\n  components: {\n    FormProvider,\n    FormConsumer,\n    Field,\n    Form,\n    Button,\n  },\n  data() {\n    const form = createForm({ validateFirst: true })\n    return {\n      FormItem,\n      Input,\n      form,\n    }\n  },\n  methods: {\n    log(...args) {\n      console.log(...args)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/shared/map-props.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Form layout=\"vertical\">\n      <Field\n        name=\"name\"\n        title=\"Name\"\n        required\n        :decorator=\"[FormItem]\"\n        :component=\"[Input, { placeholder: 'Please Input' }]\"\n      />\n      <FormConsumer>\n        <template #default=\"{ form }\">\n          <div style=\"white-space: pre; margin-bottom: 16px\">\n            {{ JSON.stringify(form.values, null, 2) }}\n          </div>\n          <Button\n            type=\"primary\"\n            @click=\"\n              () => {\n                form.submit(log)\n              }\n            \"\n          >\n            Submit\n          </Button>\n        </template>\n      </FormConsumer>\n    </Form>\n  </FormProvider>\n</template>\n\n<script>\nimport { Form, Input, Button } from 'ant-design-vue'\nimport { createForm, setValidateLanguage } from '@formily/core'\nimport {\n  FormProvider,\n  FormConsumer,\n  Field,\n  connect,\n  mapProps,\n} from '@formily/vue'\nimport 'ant-design-vue/dist/antd.css'\n\nsetValidateLanguage('en')\n\nconst FormItem = connect(\n  Form.Item,\n  mapProps(\n    {\n      title: 'label',\n      description: 'extra',\n      required: true,\n      validateStatus: true,\n    },\n    (props, field) => {\n      return {\n        ...props,\n        help: field.selfErrors?.length ? field.selfErrors : undefined,\n      }\n    }\n  )\n)\n\nexport default {\n  components: {\n    FormProvider,\n    FormConsumer,\n    Field,\n    Form,\n    Button,\n  },\n  data() {\n    const form = createForm({ validateFirst: true })\n    return {\n      FormItem,\n      Input,\n      form,\n    }\n  },\n  methods: {\n    log(...args) {\n      console.log(...args)\n    },\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/shared/map-read-pretty.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Form layout=\"vertical\">\n      <Field\n        name=\"name\"\n        title=\"Name\"\n        required\n        initialValue=\"Hello world\"\n        :decorator=\"[FormItem]\"\n        :component=\"[Input, { placeholder: 'Please Input' }]\"\n      />\n    </Form>\n  </FormProvider>\n</template>\n\n<script>\nimport { Form, Input as AntdInput } from 'ant-design-vue'\nimport { createForm, setValidateLanguage } from '@formily/core'\nimport {\n  FormProvider,\n  Field,\n  connect,\n  mapProps,\n  mapReadPretty,\n} from '@formily/vue'\nimport 'ant-design-vue/dist/antd.css'\n\nsetValidateLanguage('en')\n\nconst FormItem = connect(\n  Form.Item,\n  mapProps(\n    {\n      title: 'label',\n      description: 'extra',\n      required: true,\n      validateStatus: true,\n    },\n    (props, field) => {\n      return {\n        ...props,\n        help: field.selfErrors?.length ? field.selfErrors : undefined,\n      }\n    }\n  )\n)\n\nconst Input = connect(\n  AntdInput,\n  mapReadPretty({\n    props: ['value'],\n    // you need import \"h\" from \"vue\" in vue3\n    render(h) {\n      return h('div', [this.value])\n    },\n  })\n)\n\nexport default {\n  components: {\n    FormProvider,\n    Field,\n    Form,\n  },\n  data() {\n    const form = createForm({ validateFirst: true, readPretty: true })\n    return {\n      FormItem,\n      Input,\n      form,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/api/shared/observer.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Space>\n      <Field\n        name=\"name\"\n        title=\"Name\"\n        required\n        :component=\"[Input, { placeholder: 'Please Input' }]\"\n      />\n      <FormPreviewer />\n    </Space>\n  </FormProvider>\n</template>\n\n<script>\nimport { defineComponent, h } from '@vue/composition-api'\nimport { createForm } from '@formily/core'\nimport { FormProvider, Field, useForm } from '@formily/vue'\nimport { observer } from '@formily/reactive-vue'\nimport { Input, Space } from 'ant-design-vue'\nimport 'ant-design-vue/dist/antd.css'\n\nconst FormPreviewer = observer(\n  defineComponent({\n    name: 'FormPreviewer',\n    setup() {\n      const formRef = useForm()\n      return () => {\n        const form = formRef.value\n        return h('div', [JSON.stringify(form.values)])\n      }\n    },\n  })\n)\n\nexport default {\n  components: {\n    FormProvider,\n    Field,\n    FormPreviewer,\n    Space,\n  },\n  data() {\n    const form = createForm({ validateFirst: true })\n    return {\n      Input,\n      form,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/index.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <Field\n      name=\"name\"\n      title=\"Name\"\n      required\n      :decorator=\"[FormItem]\"\n      :component=\"[Input, { placeholder: 'Please Input' }]\"\n    />\n    <Field\n      name=\"password\"\n      title=\"Password\"\n      required\n      :decorator=\"[FormItem]\"\n      :component=\"[Input, { type: 'password', placeholder: 'Please Input' }]\"\n      :reactions=\"createPasswordEqualValidate('confirm_password')\"\n    />\n    <Field\n      name=\"confirm_password\"\n      title=\"Confirm Password\"\n      required\n      :decorator=\"[FormItem]\"\n      :component=\"[Input, { type: 'password', placeholder: 'Please Input' }]\"\n      :reactions=\"createPasswordEqualValidate('password')\"\n    />\n    <FormConsumer>\n      <template #default=\"{ form }\">\n        <div style=\"white-space: pre\">\n          {{ JSON.stringify(form.values, null, 2) }}\n        </div>\n      </template>\n    </FormConsumer>\n  </FormProvider>\n</template>\n\n<script>\nimport { Form, Input } from 'ant-design-vue'\nimport { createForm, isVoidField, setValidateLanguage } from '@formily/core'\nimport {\n  FormProvider,\n  FormConsumer,\n  Field,\n  connect,\n  mapProps,\n} from '@formily/vue'\nimport 'ant-design-vue/dist/antd.css'\n\nsetValidateLanguage('en')\n\nconst FormItem = connect(\n  Form.Item,\n  mapProps(\n    { validateStatus: true, title: 'label', required: true },\n    (props, field) => {\n      return {\n        help: !isVoidField(field)\n          ? field.selfErrors.length\n            ? field.selfErrors\n            : undefined\n          : undefined,\n        extra: field.description,\n      }\n    }\n  )\n)\n\nexport default {\n  components: {\n    FormProvider,\n    FormConsumer,\n    Field,\n  },\n  data() {\n    const form = createForm({ validateFirst: true })\n    const createPasswordEqualValidate = (equalName) => (field) => {\n      if (\n        form.values.confirm_password &&\n        field.value &&\n        form.values[equalName] !== field.value\n      ) {\n        field.selfErrors = ['Password does not match Confirm Password.']\n      } else {\n        field.selfErrors = []\n      }\n    }\n    return {\n      FormItem,\n      Input,\n      form,\n      createPasswordEqualValidate,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/questions/default-slot.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n  </FormProvider>\n</template>\n\n<script>\nimport { Button } from 'ant-design-vue'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport 'ant-design-vue/dist/antd.css'\n\nconst { SchemaField } = createSchemaField({\n  components: {\n    Button,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    button: {\n      type: 'void',\n      'x-component': 'Button',\n      'x-content': '一个普通的按钮',\n    },\n  },\n}\n\nexport default {\n  components: { FormProvider, SchemaField },\n  data() {\n    return {\n      form: createForm(),\n      schema,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/questions/events.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n  </FormProvider>\n</template>\n\n<script>\nimport { Input } from 'ant-design-vue'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport 'ant-design-vue/dist/antd.css'\n\nconst { SchemaField } = createSchemaField({\n  components: {\n    Input,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      'x-component': 'Input',\n      'x-component-props': {\n        '@change': (e) => console.log(e),\n        onFocus: (e) => console.log(e),\n      },\n    },\n  },\n}\n\nexport default {\n  components: { FormProvider, SchemaField },\n  data() {\n    return {\n      form: createForm(),\n      schema,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/questions/named-slot.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n  </FormProvider>\n</template>\n\n<script>\nimport { Input, Icon } from 'ant-design-vue'\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport 'ant-design-vue/dist/antd.css'\n\nconst { SchemaField } = createSchemaField({\n  components: {\n    Input,\n  },\n})\n\nconst PrefixIcon = {\n  functional: true,\n  render(h) {\n    return h(Icon, { props: { type: 'user' } })\n  },\n}\n\nconst schema = {\n  type: 'object',\n  properties: {\n    input: {\n      type: 'string',\n      'x-component': 'Input',\n      'x-content': {\n        prefix: PrefixIcon,\n      },\n    },\n  },\n}\n\nexport default {\n  components: { FormProvider, SchemaField },\n  data() {\n    return {\n      form: createForm(),\n      schema,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/demos/questions/scoped-slot.vue",
    "content": "<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n  </FormProvider>\n</template>\n\n<script>\nimport { createForm } from '@formily/core'\nimport { FormProvider, createSchemaField } from '@formily/vue'\nimport { observer } from '@formily/reactive-vue'\n\n// 带有作用域插槽的普通组件\nconst TextPreviewer = {\n  functional: true,\n  name: 'TextPreviewer',\n  render(h, context) {\n    return h('div', {}, [\n      context.scopedSlots.default({\n        slotProp: '有 default 作用域插槽组件的插槽属性值',\n        onScopedFunc: ($event) => {\n          alert($event)\n        },\n      }),\n    ])\n  },\n}\n\n// 响应式组件\nconst ObservedComponent = observer({\n  functional: true,\n  components: {\n    TextPreviewer,\n  },\n  render(h, context) {\n    return h(TextPreviewer, {\n      scopedSlots: {\n        default: (props) => context.scopedSlots.default(props),\n      },\n    })\n  },\n})\n\n// 作用域插槽组件\nconst ScopedSlotComponent = {\n  functional: true,\n  render(h, { props }) {\n    return h(\n      'div',\n      {\n        on: {\n          click: () => {\n            props.onScopedFunc('作用域插槽传递事件函数，事件发生后进行值的回传')\n          },\n        },\n      },\n      [props.slotProp]\n    )\n  },\n}\n\nconst { SchemaField } = createSchemaField({\n  components: {\n    ObservedComponent,\n  },\n})\n\nconst schema = {\n  type: 'object',\n  properties: {\n    textPreview: {\n      type: 'string',\n      'x-component': 'ObservedComponent',\n      'x-content': {\n        default: ScopedSlotComponent,\n      },\n    },\n  },\n}\nexport default {\n  components: { FormProvider, SchemaField },\n  data() {\n    return {\n      form: createForm(),\n      schema,\n    }\n  },\n}\n</script>\n"
  },
  {
    "path": "packages/vue/docs/guide/README.md",
    "content": "# 介绍\n\n@formily/vue 的核心定位是将 ViewModel([@formily/core](//core.formilyjs.org))与组件实现一个状态绑定关系，它不负责管理表单数据，表单校验，它仅仅是一个渲染胶水层，但是这样一层胶水，并不脏，它会把很多脏逻辑优雅的解耦，变得可维护。\n\n## 超高性能\n\n借助 [@formily/core](//core.formilyjs.org) 的响应式模型，@formily/vue 无需做任何优化即可获得超高的性能优势，依赖追踪，精确更新，按需渲染，让我们的表单真正做到了只需关注业务逻辑，无需考虑性能问题。\n\n## 开箱即用\n\n@formily/vue 提供了一系列的 Vue 组件，比如 Field/ArrayField/ObjectField/VoidField，用户在使用的时候，只需要给 Field 组件传入 component 属性(支持 value/@change 这样的双向绑定约定)即可快速接入@formily/vue，接入成本极低。\n\n## 协议驱动\n\n@formily/vue 提供了 SchemaField 这样的协议驱动组件，同时是基于标准 JSON-Schema 的驱动，让表单开发可以变得更加动态化，可配置化，更甚，我们可以做到一份协议，让多端渲染表单。\n\n## 场景复用\n\n借助协议驱动的能力，我们可以将一个携带业务逻辑的协议片段抽象成一个场景组件，帮助用户在某些场景上高效开发，比如 FormTab、FormStep 这类场景组件。\n\n## 智能提示\n\n因为 formily 是完全的 Typescript 项目，所以用户在 VSCode 或 WebStorm 等上开发可以获得最大化的智能提示体验\n\n![img](https://img.alicdn.com/imgextra/i2/O1CN01yiREHk1X95KJPPz1c_!!6000000002880-2-tps-2014-868.png)\n\n## 状态可观测\n\n安装 [FormilyDevtools](https://chrome.google.com/webstore/detail/formily-devtools/kkocalmbfnplecdmbadaapgapdioecfm?hl=zh-CN) 可以实时观测模型状态变化，排查问题\n\n![img](https://img.alicdn.com/imgextra/i4/O1CN01DSci5h1rAGfRafpXw_!!6000000005590-2-tps-2882-1642.png)\n"
  },
  {
    "path": "packages/vue/docs/guide/architecture.md",
    "content": "# 核心架构\n\n@formily/vue 的架构相比于@formily/core 并不复杂，先看架构图：\n\n![](https://img.alicdn.com/imgextra/i1/O1CN013jbRfk1l5n6N7jYH8_!!6000000004768-55-tps-2200-1637.svg)\n\n从这张架构图中我们可以看到，@formily/vue 支持了两类用户，一类就是纯源码开发用户，它们只需要使用 Field/ArrayField/ObjectField/VoidField 组件。另一类就是基于 JSON-Schema 做动态开发的用户，它们依赖的主要是 SchemaField 组件，但是，这两类用户都需要使用一个 FormProvider 的组件来统一下发上下文。然后是 SchemaField 组件，它内部其实是依赖的 Field/ArrayField/ObjectField/VoidField 组件。\n"
  },
  {
    "path": "packages/vue/docs/guide/concept.md",
    "content": "# 核心概念\n\n@formily/vue 本身架构不复杂，因为它只是提供了一系列的组件和 Hooks 给用户使用，但是我们还是需要理解以下几个概念：\n\n- 表单上下文\n- 字段上下文\n- 协议上下文\n- 模型绑定\n- 协议驱动\n- 三种开发模式\n\n## 表单上下文\n\n从[架构图](/guide/architecture)中我们可以看到 FormProvider 是作为表单统一上下文而存在，它的地位非常重要，主要用于将@formily/core 创建出来的[Form](//core.formilyjs.org/api/models/form)实例下发到所有子组件中，不管是在内置组件还是用户扩展的组件，都能通过[useForm](/api/hooks/use-form)读取到[Form](//core.formilyjs.org/api/models/form)实例\n\n## 字段上下文\n\n从[架构图](/guide/architecture)中我们可以看到不管是 Field/ArrayField/ObjectField/VoidField，会给子树下发一个 FieldContext，我们可以在自定义组件中读取到当前字段模型，主要是使用[useField](/api/hooks/use-field)来读取，这样非常方便于做模型映射\n\n## 协议上下文\n\n从[架构图](/guide/architecture)中我们可以看到[RecursionField](/api/components/recursion-field)会给子树下发一个 FieldSchemaContext，我们可以在自定义组件中读取到当前字段的 Schema 描述，主要是使用[useFieldSchema](/api/hooks/use-field-schema)来读取。注意，该 Hook 只能用在[SchemaField](/api/components/schema-field)和[RecursionField](/api/components/recursion-field)子树中使用\n\n## 模型绑定\n\n想要理解模型绑定，需要先理解什么是[MVVM](//core.formilyjs.org/guide/mvvm)，理解了之后我们再看看这张图：\n\n![](https://img.alicdn.com/imgextra/i1/O1CN01A03C191KwT1raxnDg_!!6000000001228-55-tps-2200-869.svg)\n\n在 Formily 中，@formily/core 就是 ViewModel，Component 和 Decorator 就是 View，@formily/vue 就是将 ViewModel 和 View 绑定起来的胶水层，ViewModel 和 View 的绑定就叫做模型绑定，实现模型绑定的手段主要有[useField](/api/hooks/use-field)，也能使用[connect](/api/shared/connect)和[mapProps](/api/shared/map-props)，需要注意的是，Component 只需要支持 value/onChange 属性即可自动实现数据层的双向绑定。\n\n## 协议驱动\n\n协议驱动渲染算是 @formily/vue 中学习成本最高的部分了，但是学会了之后，它给业务带来的收益也是很高，总共需要理解 4 个核心概念：\n\n- Schema\n- 递归渲染\n- 协议绑定\n- 三种开发模式\n\n### Schema\n\nformily 的协议驱动主要是基于标准 JSON Schema 来进行驱动渲染的，同时我们在标准之上又扩展了一些`x-*`属性来表达 UI，使得整个协议可以具备完整描述一个复杂表单的能力，具体 Schema 协议，参考[Schema](/api/shared/schema) API 文档\n\n### 递归渲染\n\n何为递归渲染？递归渲染就是组件 A 在某些条件下会继续用组件 A 来渲染内容，看看以下伪代码：\n\n```json\n{ <---- RecursionField(条件：object；渲染权：RecursionField)\n  \"type\":\"object\",\n  \"properties\":{\n    \"username\":{ <---- RecursionField(条件：string；渲染权：RecursionField)\n      \"type\":\"string\",\n      \"x-component\":\"Input\"\n    },\n    \"phone\":{ <---- RecursionField(条件：string；渲染权：RecursionField)\n      \"type\":\"string\",\n      \"x-component\":\"Input\",\n      \"x-validator\":\"phone\"\n    },\n    \"email\":{ <---- RecursionField(条件：string；渲染权：RecursionField)\n      \"type\":\"string\",\n      \"x-component\":\"Input\",\n      \"x-validator\":\"email\"\n    },\n    \"contacts\":{ <---- RecursionField(条件：array；渲染权：RecursionField)\n      \"type\":\"array\",\n      \"x-component\":\"ArrayTable\",\n      \"items\":{ <---- RecursionField(条件：object；渲染权：ArrayTable组件)\n        \"type\":\"object\",\n        \"properties\":{\n          \"username\":{ <---- RecursionField(条件：string；渲染权：RecursionField)\n            \"type\":\"string\",\n            \"x-component\":\"Input\"\n          },\n          \"phone\":{ <---- RecursionField(条件：string；渲染权：RecursionField)\n            \"type\":\"string\",\n            \"x-component\":\"Input\",\n            \"x-validator\":\"phone\"\n          },\n          \"email\":{ <---- RecursionField(条件：string；渲染权：RecursionField)\n            \"type\":\"string\",\n            \"x-component\":\"Input\",\n            \"x-validator\":\"email\"\n          },\n        }\n      }\n    }\n  }\n}\n```\n\n@formily/vue 递归渲染的入口是[SchemaField](/api/components/schema-field)，但它内部实际是使用 [RecursionField](/api/components/recursion-field) 来渲染的，因为 JSON-Schema 就是一个递归型结构，所以 [RecursionField](/api/components/recursion-field) 在渲染的时候会从顶层 Schema 节点解析，如果是非 object 和 array 类型则直接渲染具体组件，如果是 object，则会遍历 properties 继续用 [RecursionField](/api/components/recursion-field) 渲染子级 Schema 节点。\n\n这里有点特殊的情况是 array 类型的自增列表渲染，需要用户在自定义组件内使用[RecursionField](/api/components/recursion-field)进行递归渲染，因为自增列表的 UI 个性化定制程度很高，所以就把递归渲染权交给用户来渲染了，这样设计也能让协议驱动渲染变得更加灵活。\n\n那 SchemaField 和 RecursionField 有啥差别呢？主要有两点：\n\n- SchemaField 是支持 Markup 语法的，它会提前解析 Markup 语法生成[JSON Schema](/api/shared/schema)移交给 RecursionField 渲染，所以 RecursionField 只能基于 [JSON Schema](/api/shared/schema) 渲染\n- SchemaField 渲染的是整体的 Schema 协议，而 RecursionField 渲染的是局部 Schema 协议\n\n### 协议绑定\n\n前面讲了模型绑定，而协议绑定则是将 Schema 协议转换成模型绑定的过程，因为 JSON-Schema 协议是 JSON 字符串，可离线存储的，而模型绑定则是内存间的绑定关系，是 Runtime 层的，比如`x-component`在 Schema 中是组件的字符串标识，但是在模型中的 component 则是需要组件引用，所以 JSON 字符串与 Runtime 层是需要转换的。然后我们就可以继续完善一下以上模型绑定的图：\n\n![](https://img.alicdn.com/imgextra/i3/O1CN01jLCRxH1aa3V0x6nw4_!!6000000003345-55-tps-2200-1147.svg)\n\n总结下来，在 @formily/vue 中，主要有 2 层绑定关系，Schema 绑定模型，模型绑定组件，实现绑定的胶水层就是 @formily/vue，需要注意的是，Schema 绑定字段模型之后，字段模型中是感知不到 Schema 的，比如要修改`enum`，就是修改字段模型中的`dataSource`属性了，总之，想要更新字段模型，参考[Field](//core.formilyjs.org/models/field)，想要理解 Schema 与字段模型的映射关系可以参考[Schema](/api/shared/schema)文档\n\n## 三种开发模式\n\n从[架构图](/guide/architecture)中我们可以看到整个 @formily/vue 是有三种开发模式的，对应不同用户：\n\n- Template 开发模式\n- JSON Schema 开发模式\n- Markup Schema 开发模式\n\n#### Template 开发模式\n\n该模式主要是使用 Field/ArrayField/ObjectField/VoidField 组件\n\n```html\n<template>\n  <FormProvider :form=\"form\">\n    <Field name=\"input\" :component=\"[Input, { placeholder:'请输入' }]\" />\n  </FormProvider>\n</template>\n\n<script>\n  import { Input } from 'ant-design-vue'\n  import { createForm } from '@formily/core'\n  import { FormProvider, Field } from '@formily/vue'\n  import 'ant-design-vue/dist/antd.css'\n\n  export default {\n    components: { FormProvider, Field },\n    data() {\n      return {\n        Input,\n        form: createForm(),\n      }\n    },\n  }\n</script>\n```\n\n#### JSON Schema 开发模式\n\n该模式是给 SchemaField 的 schema 属性传递 JSON Schema 即可\n\n```html\n<template>\n  <FormProvider :form=\"form\">\n    <SchemaField :schema=\"schema\" />\n  </FormProvider>\n</template>\n\n<script>\n  import { Input } from 'ant-design-vue'\n  import { createForm } from '@formily/core'\n  import { FormProvider, createSchemaField } from '@formily/vue'\n  import 'ant-design-vue/dist/antd.css'\n\n  const { SchemaField } = createSchemaField({\n    components: {\n      Input,\n    },\n  })\n\n  export default {\n    components: { FormProvider, SchemaField },\n    data() {\n      return {\n        form: createForm(),\n        schema: {\n          type: 'object',\n          properties: {\n            input: {\n              type: 'string',\n              'x-component': 'Input',\n              'x-component-props': {\n                placeholder: '请输入',\n              },\n            },\n          },\n        },\n      }\n    },\n  }\n</script>\n```\n\n#### Markup Schema 开发模式\n\n该模式算是一个对源码开发比较友好的 Schema 开发模式，同样是使用 SchemaField 相关组件。\n\nMarkup Schema 模式主要有以下几个特点：\n\n- 主要依赖 SchemaStringField/SchemaArrayField/SchemaObjectField...这类描述标签来表达 Schema\n- 每个描述标签都代表一个 Schema 节点，与 JSON-Schema 等价\n- SchemaField 子节点不能随意插 UI 元素，因为 SchemaField 只会解析子节点的所有 Schema 描述标签，然后转换成 JSON Schema，最终交给[RecursionField](/api/components/recursion-field)渲染，如果想要插入 UI 元素，可以在 SchemaVoidField 上传`x-content`属性来插入 UI 元素\n\n```html\n<template>\n  <FormProvider :form=\"form\">\n    <SchemaField>\n      <SchemaStringField\n        x-component=\"Input\"\n        :x-component-props=\"{ placeholder: '请输入' }\"\n      />\n      <div>我不会被渲染</div>\n      <SchemaVoidField x-content=\"我会被渲染\" />\n      <SchemaVoidField :x-content=\"Comp\" />\n    </SchemaField>\n  </FormProvider>\n</template>\n\n<script>\n  import { Input } from 'ant-design-vue'\n  import { createForm } from '@formily/core'\n  import { FormProvider, createSchemaField } from '@formily/vue'\n  import 'ant-design-vue/dist/antd.css'\n\n  const SchemaComponents = createSchemaField({\n    components: {\n      Input,\n    },\n  })\n\n  const Comp = {\n    render(h) {\n      return h('div', ['我也会被渲染'])\n    },\n  }\n\n  export default {\n    components: { FormProvider, ...SchemaComponents },\n    data() {\n      return {\n        form: createForm(),\n        Comp,\n      }\n    },\n  }\n</script>\n```\n"
  },
  {
    "path": "packages/vue/docs/questions/README.md",
    "content": "---\nsidebar: auto\n---\n\n# 常见问题\n\n## 如何添加事件？\n\n`x-component-props` 中可以用 `@` 来标识事件，同时也支持 `onXxx` 这种方式来标识事件。两者区别在于使用 `@` 标识的内容不会再作为 prop 传入组件，而 `onXxx` 这种会。这是为了兼容某些组件具有 `onXxx` 的 prop，如 ElementUI 中的 [upload 组件](https://element.eleme.cn/#/zh-CN/component/upload#attribute)。\n\n::: warning\n事件名冲突时，`@` 的优先级更高。例如同时设置了 `@change` 和 `onChange`，只有 `@change` 会生效。\n:::\n\n<dumi-previewer demoPath=\"questions/events\" />\n\n## 如何使用插槽？\n\n使用 `x-content` 可以在组件的 `default` 插槽中插入内容。可以传入文本或组件。\n\n<dumi-previewer demoPath=\"questions/default-slot\" />\n\n## 如何使用具名插槽？\n\n`x-content` 中以键名来表示插槽名。\n\n::: danger\n注意键名不可包含 `template`、`render`、`setup` 三个关键字，否则整个 `x-content` 会被当做 vue 组件进行渲染。\n:::\n\n<dumi-previewer demoPath=\"questions/named-slot\" />\n\n## 如何使用作用域插槽？\n\n`x-content` 使用函数式组件时, 渲染函数增加第二个参数，通过其 `props` 成员访问作用域插槽传入属性，支持 observer() 和 connect() 接入组件。\n\n<dumi-previewer demoPath=\"questions/scoped-slot\" />\n"
  },
  {
    "path": "packages/vue/package.json",
    "content": "{\n  \"name\": \"@formily/vue\",\n  \"version\": \"2.3.7\",\n  \"license\": \"MIT\",\n  \"main\": \"lib\",\n  \"module\": \"esm\",\n  \"umd:main\": \"dist/formily.vue.umd.production.js\",\n  \"unpkg\": \"dist/formily.vue.umd.production.js\",\n  \"jsdelivr\": \"dist/formily.vue.umd.production.js\",\n  \"jsnext:main\": \"esm\",\n  \"types\": \"type-artefacts/cur/index.d.ts\",\n  \"engines\": {\n    \"npm\": \">=3.0.0\"\n  },\n  \"scripts\": {\n    \"postinstall\": \"node ./scripts/postinstall.js\",\n    \"start\": \"vuepress dev docs\",\n    \"build\": \"rimraf -rf lib esm dist type-artefacts && npm run build:cjs && npm run build:esm && npm run build:umd && npm run build:types\",\n    \"build:cjs\": \"tsc --project tsconfig.build.json\",\n    \"build:esm\": \"tsc --project tsconfig.build.json --module es2015 --outDir esm\",\n    \"build:umd\": \"rollup --config\",\n    \"build:types\": \"npm run build:types-vue2 && npm run build:types-vue3 && rimraf type-artefacts/**/*.js type-artefacts/**/**/*.js\",\n    \"build:types-vue2\": \"tsc --project tsconfig.types.json --outDir type-artefacts/v2\",\n    \"build:types-vue3\": \"npx vue-demi-switch 3 vue3 && tsc --project tsconfig.types.json --outDir type-artefacts/v3 && tsc --project tsconfig.types.json --outDir type-artefacts/cur && npx vue-demi-switch 2\",\n    \"build:docs\": \"vuepress build docs\"\n  },\n  \"bin\": {\n    \"formily-vue-fix\": \"bin/formily-vue-fix.js\",\n    \"formily-vue-switch\": \"bin/formily-vue-switch.js\"\n  },\n  \"devDependencies\": {\n    \"@ant-design/icons\": \"^2.1.1\",\n    \"@ant-design/icons-vue\": \"^2.0.0\",\n    \"@vue/composition-api\": \"^1.0.0-rc.7\",\n    \"@vuepress-dumi/vuepress-plugin-dumi-previewer\": \"0.3.3\",\n    \"@vuepress-dumi/vuepress-theme-dumi\": \"0.3.3\",\n    \"@vuepress/plugin-back-to-top\": \"^1.8.2\",\n    \"@vuepress/plugin-medium-zoom\": \"^1.8.2\",\n    \"ant-design-vue\": \"^1.7.3\",\n    \"codesandbox\": \"^2.2.3\",\n    \"core-js\": \"^2.4.0\",\n    \"vue\": \"^2.6.12\",\n    \"vue3\": \"npm:vue@3\",\n    \"vuepress\": \"^1.8.2\",\n    \"vuepress-plugin-typescript\": \"^0.3.1\"\n  },\n  \"dependencies\": {\n    \"@formily/core\": \"2.3.7\",\n    \"@formily/json-schema\": \"2.3.7\",\n    \"@formily/reactive\": \"2.3.7\",\n    \"@formily/reactive-vue\": \"2.3.7\",\n    \"@formily/shared\": \"2.3.7\",\n    \"@formily/validator\": \"2.3.7\",\n    \"fs-extra\": \"^10.0.0\",\n    \"vue-demi\": \">=0.13.6\",\n    \"vue-frag\": \"^1.1.4\"\n  },\n  \"peerDependencies\": {\n    \"@vue/composition-api\": \"^1.0.0-beta.1\",\n    \"vue\": \"^2.6.0 || >=3.0.0-rc.0\"\n  },\n  \"peerDependenciesMeta\": {\n    \"@vue/composition-api\": {\n      \"optional\": true\n    }\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"gitHead\": \"ac79c196ae9324889aca5e0501146f9b37b04283\"\n}\n"
  },
  {
    "path": "packages/vue/rollup.config.js",
    "content": "import baseConfig from '../../scripts/rollup.base'\n\nexport default baseConfig('formily.vue', 'Formily.Vue')\n"
  },
  {
    "path": "packages/vue/scripts/postinstall.js",
    "content": "const { switchVersion, loadModule } = require('./utils.js')\n\nconst Vue = loadModule('vue')\n\ntry {\n  if (Vue.version.startsWith('2.')) {\n    switchVersion(2)\n  } else if (Vue.version.startsWith('3.')) {\n    switchVersion(3)\n  }\n} catch (err) {\n  // nothing to do\n}\n"
  },
  {
    "path": "packages/vue/scripts/switch-cli.js",
    "content": "const { switchVersion } = require('./utils.js')\nconst { exec } = require('child_process')\n\nconst version = process.argv[2]\nconst vueEntry = process.argv[3] || 'vue'\n\nif (version == '2') {\n  switchVersion(2)\n  console.log(`[formily-vue] Switched types for Vue 2`)\n  exec(`npx vue-demi-switch 2 ${vueEntry}`)\n  console.log(`[vue-demi] Switched for Vue 2 (entry: \"${vueEntry}\")`)\n} else if (version == '3') {\n  switchVersion(3)\n  console.log(`[formily-vue] Switched types for Vue 3`)\n  exec(`npx vue-demi-switch 3 ${vueEntry}`)\n  console.log(`[vue-demi] Switched for Vue 3 (entry: \"${vueEntry}\")`)\n} else {\n  console.warn(\n    `[formily-vue] expecting version \"2\" or \"3\" but got \"${version}\"`\n  )\n  process.exit(1)\n}\n"
  },
  {
    "path": "packages/vue/scripts/utils.js",
    "content": "const fs = require('fs-extra')\nconst path = require('path')\n\nconst dir = path.resolve(__dirname, '..', 'type-artefacts')\n\nfunction switchVersion(version) {\n  fs.emptyDirSync(`${dir}/cur`)\n  fs.copySync(`${dir}/v${version}`, `${dir}/cur`)\n}\n\nfunction loadModule(name) {\n  try {\n    return require(name)\n  } catch (e) {\n    return undefined\n  }\n}\n\nmodule.exports.loadModule = loadModule\nmodule.exports.switchVersion = switchVersion\n"
  },
  {
    "path": "packages/vue/src/__tests__/expression.scope.spec.ts",
    "content": "import { render } from '@testing-library/vue'\nimport { createForm } from '@formily/core'\nimport { FormProvider, ExpressionScope, createSchemaField, h } from '..'\nimport { defineComponent } from '@vue/composition-api'\n\ntest('expression scope', async () => {\n  const Container = defineComponent({\n    setup(_props, { slots }) {\n      return () =>\n        h(\n          ExpressionScope,\n          {\n            props: { value: { $innerScope: 'inner scope value' } },\n          },\n          slots\n        )\n    },\n  })\n  const Input = defineComponent({\n    props: ['text'],\n    setup(props) {\n      return () =>\n        h(\n          'div',\n          { attrs: { 'data-testid': 'test-input' } },\n          { default: () => props.text }\n        )\n    },\n  })\n  const SchemaField = createSchemaField({\n    components: { Container, Input },\n  })\n  const form = createForm()\n  const { getByTestId } = render({\n    components: { ...SchemaField, FormProvider },\n    data() {\n      return { form }\n    },\n    template: `<FormProvider :form=\"form\">\n    <SchemaField :scope=\"{ $outerScope: 'outer scope value' }\">\n      <SchemaVoidField x-component=\"Container\">\n        <SchemaVoidField\n          name=\"div\"\n          x-component=\"Input\"\n          :x-component-props='{ text: \"{{$innerScope + $outerScope}}\"}'\n        />\n      </SchemaVoidField>\n    </SchemaField>\n  </FormProvider>`,\n  })\n\n  expect(getByTestId('test-input').textContent).toBe(\n    'inner scope valueouter scope value'\n  )\n})\n"
  },
  {
    "path": "packages/vue/src/__tests__/field.spec.ts",
    "content": "import Vue, { FunctionalComponentOptions } from 'vue'\nimport { render, fireEvent, waitFor } from '@testing-library/vue'\nimport { defineComponent, h, ref } from '@vue/composition-api'\nimport {\n  createForm,\n  Field as FieldType,\n  isField,\n  isVoidField,\n  onFieldChange,\n} from '@formily/core'\nimport { useField, useFormEffects, connect, mapProps, mapReadPretty } from '../'\nimport {\n  FormProvider,\n  ArrayField,\n  ObjectField,\n  VoidField,\n  Field,\n} from '../vue2-components'\nimport ReactiveField from '../components/ReactiveField'\n// import { expectThrowError } from './shared'\n\nVue.component('FormProvider', FormProvider)\nVue.component('ArrayField', ArrayField)\nVue.component('ObjectField', ObjectField)\nVue.component('VoidField', VoidField)\nVue.component('Field', Field)\nVue.component('ReactiveField', ReactiveField as unknown as Vue)\n\nconst Decorator = defineComponent({\n  props: ['label'],\n  render(h) {\n    return h(\n      'div',\n      {\n        attrs: this.$attrs,\n      },\n      [this.label, this.$slots.default]\n    )\n  },\n})\n\nconst Input = defineComponent({\n  props: ['value'],\n  setup(props, { attrs, listeners }) {\n    const fieldRef = useField()\n    return () => {\n      const field = fieldRef.value\n      return h('input', {\n        class: 'test-input',\n        attrs: {\n          ...attrs,\n          value: props.value,\n          'data-testid': field.path.toString(),\n        },\n        on: {\n          ...listeners,\n          input: listeners.change,\n        },\n      })\n    }\n  },\n})\n\nconst Normal: FunctionalComponentOptions = {\n  functional: true,\n  render(h) {\n    return h('div')\n  },\n}\n\ntest('render field', async () => {\n  const form = createForm()\n  const onChange = jest.fn()\n  const atChange = jest.fn()\n  const atBlur = jest.fn()\n  const atFocus = jest.fn()\n\n  const { getByTestId, queryByTestId, queryByText } = render(\n    defineComponent({\n      name: 'TestComponent',\n      setup() {\n        return {\n          form,\n          Normal,\n          Input,\n          Decorator,\n          onChange,\n          atChange,\n          atFocus,\n          atBlur,\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n      <Field\n        name=\"aa\"\n        :decorator=\"[Decorator, {label: 'aa-decorator'}]\"\n        :component=\"[Input, { onChange }]\"\n      />\n      <ArrayField name=\"bb\" :decorator=\"[Decorator]\">\n        <div data-testid=\"bb-children\"></div>\n      </ArrayField>\n      <ObjectField name=\"cc\" :decorator=\"[Decorator]\">\n        <Field name=\"mm\" :decorator=\"[Decorator]\" :component=\"[Input]\" />\n        <ObjectField name=\"pp\" :decorator=\"[Decorator]\" />\n        <ArrayField name=\"tt\" :decorator=\"[Decorator]\" />\n        <VoidField name=\"ww\" />\n      </ObjectField>\n      <VoidField name=\"dd\" :decorator=\"[Decorator]\">\n        <div data-testid=\"dd-children\">\n          <Field name=\"oo\" :decorator=\"[Decorator]\" :component=\"[Input]\" />\n        </div>\n      </VoidField>\n      <VoidField name=\"xx\" :decorator=\"[Decorator]\" :component=\"[Normal]\" />\n      <Field\n        name=\"ee\"\n        :visible=\"false\"\n        :decorator=\"[Decorator]\"\n        :component=\"[Input]\"\n      />\n      <Field name=\"ff\" :decorator=\"[]\" :component=\"[]\" />\n      <Field name=\"gg\" :decorator=\"null\" :component=\"null\" />\n      <Field name=\"hh\" :decorator=\"[null]\" :component=\"[null, null]\" />\n      <Field\n        name=\"kk\"\n        :decorator=\"[Decorator]\"\n        :component=\"[Input, { onChange: null }]\"\n      />\n      <Field\n        name=\"ll\"\n        :decorator=\"[Decorator]\"\n        :component=\"[Input, { '@change': atChange, '@focus': atFocus, '@blur': atBlur }]\"\n      />\n      <Field\n        name=\"mm\"\n        :decorator=\"[Decorator]\"\n      ><div data-testid=\"mm-children\"></div></Field>\n    </FormProvider>`,\n    })\n  )\n  expect(form.mounted).toBeTruthy()\n  expect(form.query('aa').take().mounted).toBeTruthy()\n  expect(form.query('bb').take().mounted).toBeTruthy()\n  expect(form.query('cc').take().mounted).toBeTruthy()\n  expect(form.query('dd').take().mounted).toBeTruthy()\n  await fireEvent.update(getByTestId('aa'), '123')\n  await fireEvent.update(getByTestId('kk'), '123')\n  await fireEvent.focus(getByTestId('ll'))\n  await fireEvent.blur(getByTestId('ll'))\n  await fireEvent.update(getByTestId('ll'), '123')\n  expect(onChange).toBeCalledTimes(1)\n  expect(atChange).toBeCalledTimes(1)\n  expect(atFocus).toBeCalledTimes(1)\n  expect(atBlur).toBeCalledTimes(1)\n  expect(getByTestId('bb-children')).not.toBeUndefined()\n  expect(getByTestId('dd-children')).not.toBeUndefined()\n  expect(queryByTestId('ee')).toBeNull()\n  expect(form.query('aa').get('value')).toEqual('123')\n  expect(form.query('kk').get('value')).toEqual('123')\n  expect(getByTestId('mm-children')).not.toBeUndefined()\n  expect(queryByText('aa-decorator')).not.toBeNull()\n})\n\nconst InputWithSlot = defineComponent({\n  props: ['value'],\n  setup(props, { attrs, listeners, slots }) {\n    const fieldRef = useField()\n    return () => {\n      const field = fieldRef.value\n      return h('div', {}, [\n        h('input', {\n          class: 'test-input',\n          attrs: {\n            ...attrs,\n            value: props.value,\n            'data-testid': field.path.toString(),\n          },\n          on: {\n            ...listeners,\n            input: listeners.change,\n          },\n        }),\n        [slots['append']?.({ path: field.path.toString() })],\n      ])\n    }\n  },\n})\n\ntest('render in nesting slots with (ObjectField/ArrayField) no decorator', async () => {\n  const form = createForm()\n\n  const { getByTestId } = render(\n    defineComponent({\n      name: 'TestComponent',\n      setup() {\n        return {\n          form,\n          Normal,\n          InputWithSlot,\n          Decorator,\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n      <ObjectField name=\"cc\" :component=\"['div']\">\n        <Field name=\"mm\" :decorator=\"[Decorator]\" :component=\"[InputWithSlot]\">\n          <template #append=\"{ path }\">\n            <span :data-testid=\"'slot-prop-' +path\"></span>\n          </template>\n        </Field>\n      </ObjectField>\n      <VoidField name=\"dd\" :component=\"['div']\">\n        <Field name=\"oo\" :decorator=\"[Decorator]\" :component=\"[InputWithSlot]\" />\n      </VoidField>\n      \n    </FormProvider>`,\n    })\n  )\n\n  expect(getByTestId('oo')).not.toBeUndefined()\n  expect(getByTestId('cc.mm')).not.toBeUndefined()\n  expect(getByTestId('slot-prop-cc.mm')).not.toBeUndefined()\n})\n\ntest('render field with html attrs', async () => {\n  const form = createForm()\n\n  const { getByTestId, container } = render(\n    defineComponent({\n      name: 'TestComponent',\n      setup() {\n        return {\n          form,\n          Input,\n          Decorator,\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n      <Field\n        name=\"aa\"\n        :decorator=\"[Decorator, {\n          'data-testid': 'decorator',\n          class: {\n            'test-class': true\n          },\n          style: {\n            marginRight: '10px'\n          }\n        }]\"\n        :component=\"[Input, {\n          class: {\n            'test-class': true\n          },\n          style: {\n            marginLeft: '10px'\n          }\n        }]\"\n      />\n    </FormProvider>`,\n    })\n  )\n  expect(form.mounted).toBeTruthy()\n  expect(form.query('aa').take().mounted).toBeTruthy()\n  expect(getByTestId('aa').className.indexOf('test-input') !== -1).toBeTruthy()\n  expect(getByTestId('aa').className.indexOf('test-class') !== -1).toBeTruthy()\n  expect(getByTestId('aa').style.marginLeft).toEqual('10px')\n  expect(\n    getByTestId('decorator').className.indexOf('test-class') !== -1\n  ).toBeTruthy()\n  expect(getByTestId('decorator').style.marginRight).toEqual('10px')\n})\n\ntest('ReactiveField', () => {\n  render({\n    template: `<ReactiveField />`,\n  })\n  render({\n    template: `<ReactiveField>\n      <div></div>\n    </ReactiveField>`,\n  })\n})\n\ntest('useAttch', async () => {\n  const form1 = createForm()\n  const MyComponent = defineComponent({\n    props: ['form', 'name1', 'name2', 'name3', 'name4'],\n    data() {\n      return { Input, Decorator }\n    },\n    template: `<FormProvider :form=\"form\">\n      <Field :name=\"name1\" :decorator=\"[Decorator]\" :component=\"[Input]\" />\n      <ArrayField :name=\"name2\" :decorator=\"[Decorator]\" :component=\"[Input]\" />\n      <ObjectField :name=\"name3\" :decorator=\"[Decorator]\" :component=\"[Input]\" />\n      <VoidField :name=\"name4\" :decorator=\"[Decorator]\" :component=\"[Input]\" />\n    </FormProvider>`,\n  })\n  const { updateProps } = render(MyComponent, {\n    props: {\n      form: form1,\n      name1: 'aa',\n      name2: 'bb',\n      name3: 'cc',\n      name4: 'dd',\n    },\n  })\n  expect(form1.mounted).toBeTruthy()\n  expect(form1.query('aa').take().mounted).toBeTruthy()\n  expect(form1.query('bb').take().mounted).toBeTruthy()\n  expect(form1.query('cc').take().mounted).toBeTruthy()\n  expect(form1.query('dd').take().mounted).toBeTruthy()\n  await updateProps({\n    name1: 'aaa',\n    name2: 'bbb',\n    name3: 'ccc',\n    name4: 'ddd',\n  })\n  await Vue.nextTick()\n  expect(form1.query('aa').take().mounted).toBeFalsy()\n  expect(form1.query('bb').take().mounted).toBeFalsy()\n  expect(form1.query('cc').take().mounted).toBeFalsy()\n  expect(form1.query('dd').take().mounted).toBeFalsy()\n  expect(form1.query('aaa').take().mounted).toBeTruthy()\n  expect(form1.query('bbb').take().mounted).toBeTruthy()\n  expect(form1.query('ccc').take().mounted).toBeTruthy()\n  expect(form1.query('ddd').take().mounted).toBeTruthy()\n  const form2 = createForm()\n  await updateProps({\n    form: form2,\n  })\n  await Vue.nextTick()\n  expect(form1.unmounted).toBeTruthy()\n  expect(form2.mounted).toBeTruthy()\n})\n\ntest('useFormEffects', async () => {\n  const form = createForm()\n  const CustomField = defineComponent({\n    props: ['value'],\n    setup(props) {\n      const fieldRef = useField<FieldType>()\n      useFormEffects(() => {\n        onFieldChange('aa', ['value'], (target) => {\n          if (isVoidField(target)) return\n          fieldRef.value.setValue(target.value)\n        })\n      })\n      return () => {\n        return h('div', { attrs: { 'data-testid': 'custom-value' } }, [\n          props.value,\n        ])\n      }\n    },\n  })\n  const { queryByTestId } = render({\n    data() {\n      return { form, Decorator, Input, CustomField }\n    },\n    template: `<FormProvider :form=\"form\">\n      <Field name=\"aa\" :decorator=\"[Decorator]\" :component=\"[Input]\" />\n      <Field name=\"bb\" :component=\"[CustomField]\" />\n    </FormProvider>`,\n  })\n  expect(queryByTestId('custom-value').textContent).toEqual('')\n  form.query('aa').take((aa) => {\n    if (isField(aa)) {\n      const value = '123' as any\n      aa.setValue(value)\n    }\n  })\n  await waitFor(() => {\n    expect(queryByTestId('custom-value').textContent).toEqual('123')\n  })\n})\n\ntest('useFormEffects: should be reregister when formRef change', async () => {\n  const CustomField = defineComponent({\n    setup() {\n      const reactiveText = ref()\n      useFormEffects(() => {\n        onFieldChange('aa', ['value'], (target) => {\n          if (isVoidField(target)) return\n          reactiveText.value = target.value\n        })\n      })\n      return () =>\n        h('div', { attrs: { 'data-testid': 'custom-value' } }, [\n          reactiveText.value,\n        ])\n    },\n  })\n\n  const { queryByTestId } = render({\n    setup() {\n      const formRef = ref(createForm())\n      return {\n        formRef,\n        Input,\n        CustomField,\n        changeForm() {\n          // form change\n          formRef.value = createForm()\n          formRef.value.setValues({ aa: 'text' })\n        },\n      }\n    },\n    template: `<FormProvider :form=\"formRef\">\n      <Field name=\"aa\" :decorator=\"[Decorator]\" :component=\"[Input]\" />\n      <VoidField name=\"bb\" :component=\"[CustomField]\" />\n      <button data-testid=\"btn\" @click=\"changeForm()\">Change</button>\n    </FormProvider>`,\n  })\n\n  expect(queryByTestId('custom-value').textContent).toEqual('')\n  queryByTestId('btn').click()\n  await waitFor(() => {\n    expect(queryByTestId('custom-value').textContent).toEqual('text')\n  })\n})\n\ntest('connect', async () => {\n  const CustomField = connect(\n    {\n      functional: true,\n      props: ['list'],\n      render(h, context) {\n        return h('div', [context.props.list])\n      },\n    },\n    mapProps({ value: 'list', loading: true }, (props, field) => {\n      return {\n        ...props,\n        mounted: field.mounted ? 1 : 2,\n      }\n    }),\n    mapReadPretty({\n      render(h) {\n        return h('div', 'read pretty')\n      },\n    })\n  )\n  const BaseComponent = {\n    functional: true,\n    name: 'BaseComponent',\n    render(h, context) {\n      return h('div', [context.props.value])\n    },\n  } as FunctionalComponentOptions\n  const CustomField2 = connect(\n    BaseComponent,\n    mapProps({ value: true, loading: true }),\n    mapReadPretty({\n      render(h) {\n        return h('div', 'read pretty')\n      },\n    })\n  )\n\n  const CustomField3 = connect(\n    Input,\n    mapProps(),\n    mapReadPretty({\n      render(h) {\n        return h('div', 'read pretty')\n      },\n    })\n  )\n\n  const CustomFormItem = connect(\n    {\n      functional: true,\n      render(h, context) {\n        return h('div', context.data, context.children)\n      },\n    },\n    mapProps(),\n    mapReadPretty({\n      render(h) {\n        return h('div', 'read pretty')\n      },\n    })\n  )\n\n  const form = createForm()\n  const { queryByText, getByTestId } = render({\n    data() {\n      return {\n        form,\n        Decorator,\n        CustomField,\n        CustomField2,\n        CustomField3,\n        CustomFormItem,\n      }\n    },\n    template: `<FormProvider :form=\"form\">\n      <Field name=\"aa\" :decorator=\"[Decorator]\" :component=\"[CustomField]\" />\n      <Field name=\"bb\" :decorator=\"[Decorator]\" :component=\"[CustomField2]\" />\n      <Field name=\"cc\" :decorator=\"[Decorator]\" :component=\"[CustomField3]\" />\n      <component :is=\"CustomFormItem\">dd</component>\n    </FormProvider>`,\n  })\n  form.query('aa').take((field) => {\n    field.setState((state) => {\n      state.value = '123'\n    })\n  })\n\n  expect(queryByText('dd')).toBeVisible()\n  await waitFor(() => {\n    expect(queryByText('123')).toBeVisible()\n  })\n\n  fireEvent.update(getByTestId('cc'), '123')\n  expect(queryByText('123')).toBeVisible()\n  expect(form.query('cc').get('value')).toEqual('123')\n\n  form.query('aa').take((field) => {\n    if (!isField(field)) return\n    field.readPretty = true\n  })\n  await waitFor(() => {\n    expect(queryByText('123')).toBeNull()\n    expect(queryByText('read pretty')).toBeVisible()\n  })\n})\n"
  },
  {
    "path": "packages/vue/src/__tests__/form.spec.ts",
    "content": "import Vue from 'vue'\nimport { render, fireEvent } from '@testing-library/vue'\nimport { mount } from '@vue/test-utils'\nimport { createForm } from '@formily/core'\nimport {\n  FormProvider,\n  FormConsumer,\n  Field,\n  ObjectField,\n  VoidField,\n} from '../vue2-components'\nimport { defineComponent } from 'vue-demi'\nimport { useParentForm, useField } from '../hooks'\nimport { h } from 'vue-demi'\n\nVue.component('FormProvider', FormProvider)\nVue.component('FormConsumer', FormConsumer)\nVue.component('ObjectField', ObjectField)\nVue.component('VoidField', VoidField)\nVue.component('Field', Field)\n\nconst Input = defineComponent({\n  props: ['value'],\n  setup(props, { attrs, listeners }) {\n    const fieldRef = useField()\n    return () => {\n      const field = fieldRef.value\n      return h('input', {\n        class: 'test-input',\n        attrs: {\n          ...attrs,\n          value: props.value,\n          'data-testid': field.path.toString(),\n        },\n        on: {\n          ...listeners,\n          input: listeners.change,\n        },\n      })\n    }\n  },\n})\n\ntest('render form', () => {\n  const form = createForm()\n  render({\n    data() {\n      return { form }\n    },\n    template: `<FormProvider :form=\"form\">\n      <FormConsumer>\n        <template #default=\"{ form }\">\n          {{ form.mounted }}\n        </template>\n      </FormConsumer>\n      <FormConsumer />\n    </FormProvider>`,\n  })\n\n  expect(form.mounted).toBeTruthy()\n})\n\nconst DisplayParentForm = defineComponent({\n  setup() {\n    const form = useParentForm()\n\n    return () => h('div', [form.value.displayName])\n  },\n})\n\ntest('useParentForm', () => {\n  const { queryByTestId } = render({\n    components: {\n      DisplayParentForm,\n    },\n    data() {\n      const form = createForm()\n      return { form }\n    },\n    template: `<FormProvider :form=\"form\">\n    <ObjectField name=\"aa\">\n      <Field name=\"bb\">\n        <DisplayParentForm data-testid=\"111\" />\n      </Field>\n    </ObjectField>\n    <VoidField name=\"cc\">\n      <Field name=\"dd\">\n        <DisplayParentForm data-testid=\"222\" />\n      </Field>\n    </VoidField>\n    <DisplayParentForm data-testid=\"333\" />\n  </FormProvider>`,\n  })\n  expect(queryByTestId('111').textContent).toBe('ObjectField')\n  expect(queryByTestId('222').textContent).toBe('Form')\n  expect(queryByTestId('333').textContent).toBe('Form')\n})\n\ntest('useInjectionCleaner', async () => {\n  const form = createForm()\n\n  const { getByTestId } = render({\n    name: 'TestComponent',\n    setup() {\n      return {\n        form,\n        Input,\n      }\n    },\n    template: `<FormProvider :form=\"form\">\n      <Field name=\"parent\">\n        <FormProvider :form=\"form\">\n          <Field name=\"inner\" :component=\"[Input]\" />\n        </FormProvider>\n        <Field name=\"outer\" :component=\"[Input]\" />\n      </Field>\n    </FormProvider>`,\n  })\n  expect(form.mounted).toBeTruthy()\n  expect(form.query('inner').take().mounted).toBeTruthy()\n  expect(form.query('parent.outer').take().mounted).toBeTruthy()\n  await fireEvent.update(getByTestId('parent.outer'), '123')\n  expect(form.getValuesIn('parent.outer')).toBe('123')\n  await fireEvent.update(getByTestId('inner'), '123')\n  expect(form.getValuesIn('inner')).toBe('123')\n})\n\ntest('FormConsumer', async () => {\n  const form = createForm({\n    values: {\n      a: 'abc',\n    },\n  })\n  const wrapper = mount({\n    data() {\n      return { form, Input }\n    },\n    template: `<FormProvider :form=\"form\">\n      <Field name=\"a\" :component=\"[Input]\" />\n      <FormConsumer ref=\"consumer\">\n        <template #default=\"{ form }\">\n          <div class=\"consumer\">{{JSON.stringify(form.values)}}</div>\n        </template>\n      </FormConsumer>\n    </FormProvider>`,\n  })\n  expect(form.getValuesIn('a')).toBe('abc')\n  expect(wrapper.find('.consumer').text()).toBe('{\"a\":\"abc\"}')\n  form.setDisplay('none')\n  expect(form.getValuesIn('a')).toBeUndefined()\n  const $consumer = wrapper.vm.$refs.consumer as Vue\n  $consumer.$forceUpdate()\n  expect(wrapper.find('.consumer').text()).toBe('{}')\n})\n"
  },
  {
    "path": "packages/vue/src/__tests__/schema.json.spec.ts",
    "content": "import { createForm, Field } from '@formily/core'\nimport { observer } from '@formily/reactive-vue'\nimport { Schema } from '@formily/json-schema'\nimport { fireEvent, render, waitFor } from '@testing-library/vue'\nimport { mount } from '@vue/test-utils'\nimport Vue, { FunctionalComponentOptions } from 'vue'\nimport {\n  FormProvider,\n  createSchemaField,\n  RecursionField,\n} from '../vue2-components'\nimport { connect, mapProps, mapReadPretty, useField, useFieldSchema } from '../'\nimport { defineComponent, h } from 'vue-demi'\n\nVue.component('FormProvider', FormProvider)\n\nconst Input: FunctionalComponentOptions = {\n  functional: true,\n  render(h, context) {\n    return h('input', {\n      class: 'input',\n      attrs: {\n        value: context.props.value,\n        'data-testid': 'input',\n      },\n      on: {\n        input: context.listeners.change,\n      },\n    })\n  },\n}\n\nconst Input2: FunctionalComponentOptions = {\n  functional: true,\n  render(h, context) {\n    return h('input', {\n      class: 'input2',\n      attrs: {\n        value: context.props.value,\n        'data-testid': 'input2',\n      },\n      on: {\n        input: context.listeners.change,\n      },\n    })\n  },\n}\n\nconst FormItem: FunctionalComponentOptions = {\n  functional: true,\n  render(h, { props, slots, data }) {\n    return h(\n      'div',\n      {\n        ...data,\n        style: {\n          width: '300px',\n          height: '30px',\n          background: 'yellow',\n        },\n        attrs: {\n          'data-testid': 'formitem',\n          ...data.attrs,\n        },\n      },\n      [props.label || 'unknown ', slots().default]\n    )\n  },\n}\n\nconst ArrayItems = observer(\n  defineComponent({\n    setup() {\n      const fieldRef = useField<Field>()\n      const schemaRef = useFieldSchema()\n\n      return () => {\n        const field = fieldRef.value\n        const schema = schemaRef.value\n        const items = field.value?.map?.((item, index) => {\n          return h(RecursionField, {\n            props: { schema: schema.items, name: index },\n          })\n        })\n        return h('div', { attrs: { 'data-testid': 'array-items' } }, [items])\n      }\n    },\n  })\n)\n\nconst Previewer: FunctionalComponentOptions = {\n  functional: true,\n  render(h, context) {\n    return h(\n      'div',\n      {\n        attrs: {\n          'data-testid': 'previewer',\n        },\n      },\n      context.children\n    )\n  },\n}\n\nconst Previewer2: FunctionalComponentOptions = {\n  functional: true,\n  render(h, context) {\n    return h(\n      'div',\n      {\n        attrs: {\n          'data-testid': 'previewer2',\n        },\n      },\n      [context.scopedSlots.content({})]\n    )\n  },\n}\n\nconst Previewer3: FunctionalComponentOptions = {\n  functional: true,\n  render(h, context) {\n    return h(\n      'div',\n      {\n        attrs: {\n          'data-testid': 'previewer3',\n        },\n      },\n      [\n        context.scopedSlots.default({\n          slotProp: '123',\n        }),\n      ]\n    )\n  },\n}\n\nconst Previewer4: FunctionalComponentOptions = {\n  functional: true,\n  render(h, context) {\n    return h(\n      'div',\n      {\n        attrs: {\n          'data-testid': 'previewer4',\n        },\n      },\n      [\n        context.scopedSlots.content({\n          slotProp: '123',\n        }),\n      ]\n    )\n  },\n}\n\nconst Previewer5: FunctionalComponentOptions = {\n  functional: true,\n  render(h, context) {\n    return h(\n      'div',\n      {\n        attrs: {\n          'data-testid': 'previewer5',\n        },\n      },\n      context.slots()?.append\n    )\n  },\n}\n\ndescribe('json schema field', () => {\n  test('string field', () => {\n    const form = createForm()\n    const { SchemaField } = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'string',\n            default: '123',\n            'x-component': 'Input',\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('input')).toBeVisible()\n    expect(queryByTestId('input').getAttribute('value')).toEqual('123')\n  })\n\n  test('object field', () => {\n    const form = createForm()\n    const { SchemaField } = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'object',\n            properties: {\n              string: {\n                type: 'string',\n                'x-component': 'Input',\n              },\n            },\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('input')).toBeVisible()\n  })\n})\n\ndescribe('x-content', () => {\n  test('default slot', () => {\n    const form = createForm()\n    const { SchemaField } = createSchemaField({\n      components: {\n        Previewer,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'string',\n            'x-component': 'Previewer',\n            'x-content': '123',\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('previewer')).toBeVisible()\n    expect(queryByTestId('previewer').textContent).toEqual('123')\n  })\n\n  test('default slot with component', () => {\n    const form = createForm()\n    const Content = {\n      render(h) {\n        return h('span', '123')\n      },\n    }\n    const { SchemaField } = createSchemaField({\n      components: {\n        Previewer,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'string',\n            'x-component': 'Previewer',\n            'x-content': Content,\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('previewer')).toBeVisible()\n    expect(queryByTestId('previewer').textContent).toEqual('123')\n  })\n\n  test('default slot with name default', () => {\n    const form = createForm()\n    const { SchemaField } = createSchemaField({\n      components: {\n        Previewer,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'string',\n            'x-component': 'Previewer',\n            'x-content': {\n              default: '123',\n            },\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('previewer')).toBeVisible()\n    expect(queryByTestId('previewer').textContent).toEqual('123')\n  })\n\n  test('default slot with name default and component', () => {\n    const form = createForm()\n    const Content = {\n      render(h) {\n        return h('span', '123')\n      },\n    }\n    const { SchemaField } = createSchemaField({\n      components: {\n        Previewer,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'string',\n            'x-component': 'Previewer',\n            'x-content': {\n              default: Content,\n            },\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('previewer')).toBeVisible()\n    expect(queryByTestId('previewer').textContent).toEqual('123')\n  })\n\n  test('named slot', () => {\n    const form = createForm()\n    const Content = {\n      render(h) {\n        return h('span', '123')\n      },\n    }\n    const { SchemaField } = createSchemaField({\n      components: {\n        Previewer2,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'string',\n            'x-component': 'Previewer2',\n            'x-content': {\n              content: Content,\n            },\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('previewer2')).toBeVisible()\n    expect(queryByTestId('previewer2').textContent).toEqual('123')\n  })\n\n  test('named slot with scope', () => {\n    const form = createForm()\n    const Content = {\n      render(h) {\n        return h('span', '123')\n      },\n    }\n    const { SchemaField } = createSchemaField({\n      components: {\n        Previewer2,\n      },\n      scope: {\n        Content,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'string',\n            'x-component': 'Previewer2',\n            'x-content': {\n              content: '{{Content}}',\n            },\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('previewer2')).toBeVisible()\n    expect(queryByTestId('previewer2').textContent).toEqual('123')\n  })\n\n  test('named slot in void field', () => {\n    const form = createForm()\n    const Content = {\n      render(h) {\n        return h('span', '123')\n      },\n    }\n    const { SchemaField } = createSchemaField({\n      components: {\n        Previewer2,\n      },\n      scope: {\n        Content,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'void',\n            'x-component': 'Previewer2',\n            'x-content': {\n              content: '{{Content}}',\n            },\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('previewer2')).toBeVisible()\n    expect(queryByTestId('previewer2').textContent).toEqual('123')\n  })\n\n  test('scoped slot', () => {\n    const form = createForm()\n    const Content = {\n      functional: true,\n      render(h, context) {\n        return h('span', context.props.slotProp)\n      },\n    }\n\n    const { SchemaField } = createSchemaField({\n      components: {\n        Previewer3,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'string',\n            'x-component': 'Previewer3',\n            'x-content': Content,\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('previewer3')).toBeVisible()\n    expect(queryByTestId('previewer3').textContent).toEqual('123')\n  })\n\n  test('scoped slot with scope', () => {\n    const form = createForm()\n    const Content = {\n      functional: true,\n      render(h, context) {\n        return h('span', context.props.slotProp)\n      },\n    }\n    const { SchemaField } = createSchemaField({\n      components: {\n        Previewer3,\n      },\n      scope: {\n        Content,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'string',\n            'x-component': 'Previewer3',\n            'x-content': '{{Content}}',\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('previewer3')).toBeVisible()\n    expect(queryByTestId('previewer3').textContent).toEqual('123')\n  })\n\n  test('scoped slot with name default', () => {\n    const form = createForm()\n    const Content = {\n      functional: true,\n      render(h, context) {\n        return h('span', context.props.slotProp)\n      },\n    }\n    const { SchemaField } = createSchemaField({\n      components: {\n        Previewer3,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'string',\n            'x-component': 'Previewer3',\n            'x-content': {\n              default: Content,\n            },\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('previewer3')).toBeVisible()\n    expect(queryByTestId('previewer3').textContent).toEqual('123')\n  })\n\n  test('scoped slot with name other', () => {\n    const form = createForm()\n    const Content = {\n      functional: true,\n      render(h, context) {\n        return h('span', context.props.slotProp)\n      },\n    }\n    const { SchemaField } = createSchemaField({\n      components: {\n        Previewer4,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'string',\n            'x-component': 'Previewer4',\n            'x-content': {\n              content: Content,\n            },\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('previewer4')).toBeVisible()\n    expect(queryByTestId('previewer4').textContent).toEqual('123')\n  })\n\n  test('scoped slot with connect', () => {\n    const form = createForm()\n    const ConnectedComponent = connect(\n      defineComponent({\n        render(h) {\n          return h(\n            'div',\n            {\n              attrs: {\n                'data-testid': 'ConnectedComponent',\n              },\n            },\n            [\n              this.$scopedSlots.default({\n                slotProp: '123',\n              }),\n            ]\n          )\n        },\n      }),\n      mapProps((props, field) => {\n        return {\n          ...props,\n        }\n      })\n    )\n\n    const scopeSlotComponent = {\n      functional: true,\n      render(h, context) {\n        return h('span', context.props.slotProp)\n      },\n    }\n    const { SchemaField } = createSchemaField({\n      components: {\n        ConnectedComponent,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'string',\n            name: 'ConnectedComponent',\n            'x-component': 'ConnectedComponent',\n            'x-content': {\n              default: scopeSlotComponent,\n            },\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('ConnectedComponent')).toBeVisible()\n    expect(queryByTestId('ConnectedComponent').textContent).toEqual('123')\n  })\n\n  test('scoped slot with connect and readPretty', () => {\n    const form = createForm()\n\n    const ConnectedWithMapReadPretty = connect(\n      defineComponent({\n        render(h) {\n          return h(\n            'div',\n            {\n              attrs: {\n                'data-testid': 'ConnectedWithMapReadPretty',\n              },\n            },\n            [\n              this.$scopedSlots.withMapReadPretty({\n                slotProp: '123',\n              }),\n            ]\n          )\n        },\n      }),\n      mapProps((props, field) => {\n        return {\n          ...props,\n        }\n      }),\n      mapReadPretty({\n        render(h) {\n          return h('div', 'read pretty')\n        },\n      })\n    )\n\n    const scopeSlotComponent = {\n      functional: true,\n      render(h, context) {\n        return h('span', context.props.slotProp)\n      },\n    }\n    const { SchemaField } = createSchemaField({\n      components: {\n        ConnectedWithMapReadPretty,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'string',\n            name: 'ConnectedWithMapReadPretty',\n            'x-component': 'ConnectedWithMapReadPretty',\n            'x-content': {\n              withMapReadPretty: scopeSlotComponent,\n            },\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('ConnectedWithMapReadPretty')).toBeVisible()\n    expect(queryByTestId('ConnectedWithMapReadPretty').textContent).toEqual(\n      '123'\n    )\n  })\n\n  test('slot compitible', () => {\n    const form = createForm()\n    const { SchemaField } = createSchemaField({\n      components: {\n        Previewer5,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'string',\n            'x-component': 'Previewer5',\n            'x-content': {\n              append: '123',\n            },\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('previewer5')).toBeVisible()\n    expect(queryByTestId('previewer5').textContent).toEqual('123')\n  })\n\n  test('wrong x-content will be ignore', () => {\n    const form = createForm()\n    const { SchemaField } = createSchemaField({\n      components: {\n        Previewer,\n      },\n    })\n    const { queryAllByTestId, container } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'object',\n            properties: {\n              input1: {\n                type: 'string',\n                'x-component': 'Previewer',\n                'x-content': {\n                  default: {\n                    someAttr: '123',\n                  },\n                },\n              },\n              input2: {\n                type: 'string',\n                'x-component': 'Previewer',\n                'x-content': {\n                  default: null,\n                },\n              },\n            },\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    queryAllByTestId('previewer').forEach((el) => expect(el).toBeVisible())\n    queryAllByTestId('previewer').forEach((el) =>\n      expect(el.textContent).toEqual('')\n    )\n  })\n})\n\ndescribe('x-slot', () => {\n  test('x-slot works in void field properties', () => {\n    const form = createForm()\n    const Content = {\n      render(h) {\n        return h('span', '123')\n      },\n    }\n    const { SchemaField } = createSchemaField({\n      components: {\n        Previewer4,\n        Content,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'void',\n            'x-component': 'Previewer4',\n            properties: {\n              content: {\n                type: 'void',\n                'x-component': 'Content',\n                'x-slot': 'content',\n              },\n            },\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('previewer4')).toBeVisible()\n    expect(queryByTestId('previewer4').textContent).toEqual('123')\n  })\n  test('x-slot works in object field properties', () => {\n    const form = createForm()\n    const Content = {\n      render(h) {\n        return h('span', '123')\n      },\n    }\n    const { SchemaField } = createSchemaField({\n      components: {\n        Previewer4,\n        Content,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'object',\n            'x-component': 'Previewer4',\n            properties: {\n              content: {\n                type: 'void',\n                'x-component': 'Content',\n                'x-slot': 'content',\n              },\n            },\n          }),\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          name=\"string\"\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('previewer4')).toBeVisible()\n    expect(queryByTestId('previewer4').textContent).toEqual('123')\n  })\n})\n\ndescribe('scope', () => {\n  test('scope in <SchemaField> prop', async () => {\n    const form = createForm()\n    const { SchemaField } = createSchemaField({\n      components: {\n        Input,\n        Input2,\n        Previewer,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: {\n            type: 'object',\n            properties: {\n              input1: {\n                type: 'string',\n                'x-component': 'Input',\n                'x-reactions': {\n                  target: 'input2',\n                  fulfill: {\n                    state: {\n                      value: '{{ test }}',\n                    },\n                  },\n                },\n              },\n              input2: {\n                type: 'string',\n                'x-component': 'Input2',\n              },\n            },\n          },\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          :schema=\"schema\"\n          :scope=\"{\n            test: '123'\n          }\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('input2').getAttribute('value')).toEqual('123')\n  })\n\n  test('scope in options of createSchemaField', async () => {\n    const form = createForm()\n    const { SchemaField } = createSchemaField({\n      components: {\n        Input,\n        Input2,\n        Previewer,\n      },\n      scope: {\n        test: '123',\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: {\n            type: 'object',\n            properties: {\n              input1: {\n                type: 'string',\n                'x-component': 'Input',\n                'x-reactions': {\n                  target: 'input2',\n                  fulfill: {\n                    state: {\n                      value: '{{ test }}',\n                    },\n                  },\n                },\n              },\n              input2: {\n                type: 'string',\n                'x-component': 'Input2',\n              },\n            },\n          },\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n    })\n    expect(queryByTestId('input2').getAttribute('value')).toEqual('123')\n  })\n})\n\ndescribe('expression', () => {\n  test('expression x-visible', async () => {\n    const form = createForm()\n    const { SchemaField } = createSchemaField({\n      components: {\n        Input,\n        Input2,\n        Previewer,\n      },\n    })\n\n    const wrapper = mount(\n      {\n        components: { SchemaField },\n        data() {\n          return {\n            form,\n            schema: {\n              type: 'object',\n              properties: {\n                input: {\n                  type: 'string',\n                  'x-component': 'Input',\n                },\n                input2: {\n                  type: 'string',\n                  'x-component': 'Input2',\n                  'x-visible': '{{$form.values.input === \"123\"}}',\n                },\n              },\n            },\n          }\n        },\n        template: `<FormProvider :form=\"form\">\n        <SchemaField\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n      },\n      {\n        attachToDocument: true,\n      }\n    )\n\n    expect(wrapper.find('.input').exists()).toBeTruthy()\n    expect(wrapper.find('.input2').exists()).not.toBeTruthy()\n\n    form.values.input = '123'\n    await waitFor(() => expect(wrapper.find('.input2').exists()).toBeTruthy())\n    wrapper.destroy()\n  })\n\n  test('expression x-value', async () => {\n    const form = createForm({\n      values: {\n        input: 1,\n      },\n    })\n    const { SchemaField } = createSchemaField({\n      components: {\n        Input,\n        Input2,\n        Previewer,\n      },\n    })\n\n    const wrapper = mount(\n      {\n        components: { SchemaField },\n        data() {\n          return {\n            form,\n            schema: {\n              type: 'object',\n              properties: {\n                input: {\n                  type: 'string',\n                  'x-component': 'Input',\n                },\n                input2: {\n                  type: 'string',\n                  'x-component': 'Input2',\n                  'x-value': '{{$form.values.input * 10}}',\n                },\n              },\n            },\n          }\n        },\n        template: `<FormProvider :form=\"form\">\n        <SchemaField\n          :schema=\"schema\"\n        />\n      </FormProvider>`,\n      },\n      { attachToDocument: true }\n    )\n\n    expect(wrapper.find('.input2').attributes().value).toEqual('10')\n    form.values.input = 10\n    await waitFor(() =>\n      expect(wrapper.find('.input2').attributes().value).toEqual('100')\n    )\n    wrapper.destroy()\n  })\n})\n\ndescribe('schema controlled', () => {\n  test('view update correctly when schema changed', async () => {\n    const form = createForm({})\n    const { SchemaField } = createSchemaField({\n      components: {\n        Input,\n        Input2,\n      },\n    })\n    const component = defineComponent({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: {\n            type: 'object',\n            properties: {\n              input: {\n                type: 'string',\n                'x-component': 'Input',\n              },\n              input2: {\n                type: 'string',\n                'x-component': 'Input2',\n              },\n            },\n          },\n        }\n      },\n      methods: {\n        changeSchema() {\n          this.schema = {\n            type: 'object',\n            properties: {\n              input2: {\n                type: 'string',\n                'x-component': 'Input2',\n              },\n            },\n          }\n        },\n      },\n      template: `<FormProvider :form=\"form\">\n          <SchemaField\n            :schema=\"schema\"\n          />\n          <button @click=\"changeSchema()\">changeSchema</button>\n        </FormProvider>`,\n    })\n    const { queryByTestId, getByText } = render(component)\n\n    expect(queryByTestId('input')).toBeVisible()\n    expect(queryByTestId('input2')).toBeVisible()\n    getByText('changeSchema').click()\n    await waitFor(() => {\n      expect(queryByTestId('input2')).toBeVisible()\n      expect(queryByTestId('input')).toBeNull()\n    })\n  })\n  test('view updated correctly with schema fragment changed', async () => {\n    const form = createForm({})\n    const { SchemaField } = createSchemaField({\n      components: {\n        Input,\n        Input2,\n        ArrayItems,\n      },\n    })\n    const frag1 = {\n      type: 'object',\n      properties: {\n        input1: {\n          type: 'string',\n          'x-component': 'Input',\n        },\n      },\n    }\n    const frag2 = {\n      type: 'array',\n      'x-component': 'ArrayItems',\n      items: {\n        type: 'object',\n        properties: {\n          input2: {\n            type: 'string',\n            'x-component': 'Input2',\n          },\n        },\n      },\n    }\n    const component = defineComponent({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: {\n            type: 'object',\n            properties: {\n              input: frag1,\n            },\n          },\n        }\n      },\n      methods: {\n        changeSchema() {\n          this.form.clearFormGraph('input')\n          this.form.deleteValuesIn('input')\n          this.schema = {\n            type: 'object',\n            properties: {\n              input: frag2,\n            },\n          }\n        },\n      },\n      template: `<FormProvider :form=\"form\">\n          <SchemaField\n            :schema=\"schema\"\n          />\n          <button @click=\"changeSchema()\">changeSchema</button>\n        </FormProvider>`,\n    })\n    const { queryByTestId, getByText } = render(component)\n\n    expect(queryByTestId('input')).toBeVisible()\n    expect(queryByTestId('array-items')).toBeNull()\n    getByText('changeSchema').click()\n    await waitFor(() => {\n      expect(queryByTestId('input')).toBeNull()\n      expect(queryByTestId('array-items')).toBeVisible()\n    })\n  })\n})\n\ndescribe('x-decorator', () => {\n  test('x-decorator-props', async () => {\n    const form = createForm()\n    const { SchemaField } = createSchemaField({\n      components: {\n        Input,\n        FormItem,\n      },\n    })\n\n    const atBlurFn = jest.fn()\n    const onClickFn = jest.fn()\n    const atClickFn = jest.fn()\n    const { queryByTestId, getByText } = render({\n      components: { SchemaField },\n      data() {\n        return {\n          form,\n          schema: new Schema({\n            type: 'string',\n            'x-component': 'Input',\n            'x-component-props': {\n              '@blur': function atBlur() {\n                atBlurFn()\n              },\n            },\n            'x-decorator': 'FormItem',\n            'x-decorator-props': {\n              label: 'Label ',\n              onClick: function onClick() {\n                onClickFn()\n              },\n              '@click': function atClick() {\n                atClickFn()\n              },\n            },\n          }),\n        }\n      },\n      template: `\n        <FormProvider :form=\"form\">\n          <SchemaField\n            name=\"string\"\n            :schema=\"schema\"\n          />\n        </FormProvider>`,\n    })\n    expect(queryByTestId('formitem')).toBeVisible()\n    await fireEvent.click(getByText('Label'))\n    expect(atClickFn).toBeCalledTimes(1)\n    expect(onClickFn).toBeCalledTimes(0)\n  })\n})\n"
  },
  {
    "path": "packages/vue/src/__tests__/schema.markup.spec.ts",
    "content": "import { createForm } from '@formily/core'\nimport { useFieldSchema, useField, Schema } from '../'\nimport {\n  FormProvider,\n  RecursionField,\n  createSchemaField,\n} from '../vue2-components'\nimport { render } from '@testing-library/vue'\nimport { mount, createLocalVue } from '@vue/test-utils'\nimport Vue, { CreateElement } from 'vue'\nimport { defineComponent, h } from '@vue/composition-api'\n\nVue.component('FormProvider', FormProvider)\nVue.component('RecursionField', RecursionField)\n\nconst Input = defineComponent({\n  props: ['value'],\n  setup(props, { attrs, listeners }) {\n    return () => {\n      return h('input', {\n        attrs: {\n          ...attrs,\n          value: props.value,\n          'data-testid': 'input',\n        },\n        on: {\n          ...listeners,\n          input: listeners.change,\n        },\n      })\n    }\n  },\n})\n\ndescribe('markup schema field', () => {\n  test('string', () => {\n    const form = createForm()\n    const { SchemaField, SchemaStringField } = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField, SchemaStringField },\n      data() {\n        return {\n          form,\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField>\n          <SchemaStringField x-component=\"Input\" />\n        </SchemaField>\n      </FormProvider>`,\n    })\n    expect(queryByTestId('input')).toBeVisible()\n  })\n\n  test('boolean', () => {\n    const form = createForm()\n    const { SchemaField, SchemaBooleanField } = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField, SchemaBooleanField },\n      data() {\n        return {\n          form,\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField>\n          <SchemaBooleanField x-component=\"Input\" />\n        </SchemaField>\n      </FormProvider>`,\n    })\n    expect(queryByTestId('input')).toBeVisible()\n  })\n\n  test('number', () => {\n    const form = createForm()\n    const { SchemaField, SchemaNumberField } = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField, SchemaNumberField },\n      data() {\n        return {\n          form,\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField>\n          <SchemaNumberField x-component=\"Input\" />\n        </SchemaField>\n      </FormProvider>`,\n    })\n    expect(queryByTestId('input')).toBeVisible()\n  })\n\n  test('date', () => {\n    const form = createForm()\n    const { SchemaField, SchemaDateField } = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField, SchemaDateField },\n      data() {\n        return {\n          form,\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField>\n          <SchemaDateField x-component=\"Input\" />\n        </SchemaField>\n      </FormProvider>`,\n    })\n    expect(queryByTestId('input')).toBeVisible()\n  })\n\n  test('datetime', () => {\n    const form = createForm()\n    const { SchemaField, SchemaDateTimeField } = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField, SchemaDateTimeField },\n      data() {\n        return {\n          form,\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField>\n          <SchemaDateTimeField x-component=\"Input\" />\n        </SchemaField>\n      </FormProvider>`,\n    })\n    expect(queryByTestId('input')).toBeVisible()\n  })\n\n  test('void', () => {\n    const form = createForm()\n    const VoidComponent = {\n      render(h: CreateElement) {\n        return h(\n          'div',\n          { attrs: { 'data-testid': 'void-component' } },\n          this.$slots.default\n        )\n      },\n    }\n    const { SchemaField, SchemaVoidField } = createSchemaField({\n      components: {\n        VoidComponent,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField, SchemaVoidField },\n      data() {\n        return {\n          form,\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField>\n          <SchemaVoidField x-component=\"VoidComponent\" />\n        </SchemaField>\n      </FormProvider>`,\n    })\n    expect(queryByTestId('void-component')).toBeVisible()\n  })\n\n  test('array', () => {\n    const form = createForm()\n    const components = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    render({\n      components: { ...components },\n      data() {\n        return {\n          form,\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField>\n          <SchemaArrayField>\n            <SchemaObjectField>\n              <SchemaStringField x-component=\"Input\" />\n            </SchemaObjectField>\n            <SchemaVoidField />\n          </SchemaArrayField>\n        </SchemaField>\n      </FormProvider>`,\n    })\n  })\n\n  test('other', () => {\n    const form = createForm()\n    const components = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    render({\n      components: { ...components },\n      data() {\n        return {\n          form,\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField>\n          <SchemaMarkupField type=\"other\">\n            <SchemaMarkupField />\n          </SchemaMarkupField>\n        </SchemaField>\n      </FormProvider>`,\n    })\n  })\n\n  test('no parent', () => {\n    const form = createForm()\n    const components = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    render({\n      components: { ...components },\n      data() {\n        return {\n          form,\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaMarkupField type=\"other\">\n          <SchemaMarkupField />\n        </SchemaMarkupField>\n      </FormProvider>`,\n    })\n  })\n})\n\ndescribe('recursion field', () => {\n  test('onlyRenderProperties', () => {\n    const form = createForm()\n\n    const CustomObject = defineComponent({\n      setup() {\n        const schemaRef = useFieldSchema()\n        return () => {\n          return h('div', { attrs: { 'data-testid': 'object' } }, [\n            h('RecursionField', { props: { schema: schemaRef.value } }),\n          ])\n        }\n      },\n    })\n\n    const CustomObject2 = defineComponent({\n      setup() {\n        const fieldRef = useField()\n        const schemaRef = useFieldSchema()\n        return () => {\n          const schema = schemaRef.value\n          const field = fieldRef.value\n          return h('div', { attrs: { 'data-testid': 'only-properties' } }, [\n            h('RecursionField', {\n              props: {\n                name: schema.name,\n                basePath: field.address,\n                schema,\n                onlyRenderProperties: true,\n              },\n            }),\n          ])\n        }\n      },\n    })\n\n    const components = createSchemaField({\n      components: {\n        Input,\n        CustomObject,\n        CustomObject2,\n      },\n    })\n\n    const { queryAllByTestId } = render({\n      components: components,\n      data() {\n        return {\n          form,\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField>\n          <SchemaObjectField x-component=\"CustomObject\">\n            <SchemaStringField x-component=\"Input\" />\n          </SchemaObjectField>\n          <SchemaObjectField x-component=\"CustomObject2\">\n            <SchemaStringField x-component=\"Input\" />\n          </SchemaObjectField>\n          <SchemaVoidField x-component=\"CustomObject2\">\n            <SchemaStringField x-component=\"Input\" />\n          </SchemaVoidField>\n        </SchemaField>\n      </FormProvider>`,\n    })\n    expect(queryAllByTestId('input').length).toEqual(3)\n    expect(queryAllByTestId('object').length).toEqual(1)\n    expect(queryAllByTestId('only-properties').length).toEqual(2)\n  })\n\n  test('mapProperties', () => {\n    const form = createForm()\n\n    const CustomObject = defineComponent({\n      setup() {\n        const schemaRef = useFieldSchema()\n        return () => {\n          return h('div', { attrs: { 'data-testid': 'object' } }, [\n            h('RecursionField', {\n              props: {\n                schema: schemaRef.value,\n                mapProperties: (schema) => {\n                  schema.default = '123'\n                  return schema\n                },\n              },\n            }),\n          ])\n        }\n      },\n    })\n\n    const CustomObject2 = defineComponent({\n      setup() {\n        const schemaRef = useFieldSchema()\n        return () => {\n          const schema = schemaRef.value\n          return h('div', { attrs: { 'data-testid': 'object' } }, [\n            h('RecursionField', {\n              props: {\n                schema,\n                mapProperties: () => {\n                  return null\n                },\n              },\n            }),\n          ])\n        }\n      },\n    })\n\n    const components = createSchemaField({\n      components: {\n        Input,\n        CustomObject,\n        CustomObject2,\n      },\n    })\n\n    const { queryAllByTestId } = render({\n      components: components,\n      data() {\n        return {\n          form,\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField>\n          <SchemaObjectField x-component=\"CustomObject\">\n            <SchemaStringField x-component=\"Input\" />\n          </SchemaObjectField>\n          <SchemaObjectField x-component=\"CustomObject2\">\n            <SchemaStringField x-component=\"Input\" />\n          </SchemaObjectField>\n        </SchemaField>\n      </FormProvider>`,\n    })\n    expect(queryAllByTestId('input').length).toEqual(2)\n    expect(queryAllByTestId('input')[0].getAttribute('value')).toEqual('123')\n    expect(queryAllByTestId('input')[1].getAttribute('value')).toBeFalsy()\n  })\n\n  test('filterProperties', () => {\n    const form = createForm()\n\n    const CustomObject = defineComponent({\n      setup() {\n        const schemaRef = useFieldSchema()\n        return () => {\n          return h('div', { attrs: { 'data-testid': 'object' } }, [\n            h('RecursionField', {\n              props: {\n                schema: schemaRef.value,\n                filterProperties: (schema: Schema) => {\n                  if (schema['x-component'] === 'Input') return false\n                  return true\n                },\n              },\n            }),\n          ])\n        }\n      },\n    })\n\n    const CustomObject2 = defineComponent({\n      setup() {\n        const schemaRef = useFieldSchema()\n        return () => {\n          return h('div', { attrs: { 'data-testid': 'object' } }, [\n            h('RecursionField', {\n              props: {\n                schema: schemaRef.value,\n                filterProperties: (schema: Schema) => {\n                  if (schema['x-component'] === 'Input') return\n                  return true\n                },\n              },\n            }),\n          ])\n        }\n      },\n    })\n\n    const components = createSchemaField({\n      components: {\n        Input,\n        CustomObject,\n        CustomObject2,\n      },\n    })\n\n    const { queryAllByTestId } = render({\n      components: components,\n      data() {\n        return {\n          form,\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField>\n          <SchemaObjectField x-component=\"CustomObject\">\n            <SchemaStringField x-component=\"Input\" />\n          </SchemaObjectField>\n          <SchemaObjectField x-component=\"CustomObject2\">\n            <SchemaStringField x-component=\"Input\" />\n          </SchemaObjectField>\n        </SchemaField>\n      </FormProvider>`,\n    })\n    expect(queryAllByTestId('input').length).toEqual(1)\n    expect(queryAllByTestId('object').length).toEqual(2)\n  })\n\n  test('onlyRenderSelf', () => {\n    const form = createForm()\n\n    const CustomObject = defineComponent({\n      setup() {\n        const schemaRef = useFieldSchema()\n        return () => {\n          return h('div', { attrs: { 'data-testid': 'object' } }, [\n            h('RecursionField', {\n              props: {\n                schema: schemaRef.value,\n                onlyRenderSelf: true,\n              },\n            }),\n          ])\n        }\n      },\n    })\n\n    const components = createSchemaField({\n      components: {\n        Input,\n        CustomObject,\n      },\n    })\n\n    const { queryAllByTestId } = render({\n      components: components,\n      data() {\n        return {\n          form,\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField>\n          <SchemaObjectField x-component=\"CustomObject\">\n            <SchemaStringField x-component=\"Input\" />\n          </SchemaObjectField>\n        </SchemaField>\n      </FormProvider>`,\n    })\n    expect(queryAllByTestId('input').length).toEqual(0)\n    expect(queryAllByTestId('object').length).toEqual(1)\n  })\n\n  test('illegal schema', () => {\n    const form = createForm()\n\n    const CustomObject = defineComponent({\n      setup() {\n        return () => {\n          return h('div', { attrs: { 'data-testid': 'object' } }, [\n            h('RecursionField', {\n              props: {\n                schema: null,\n              },\n            }),\n          ])\n        }\n      },\n    })\n\n    const CustomObject2 = defineComponent({\n      setup() {\n        return () => {\n          return h('div', { attrs: { 'data-testid': 'object' } }, [\n            h('RecursionField', {\n              props: {\n                schema: {},\n              },\n            }),\n          ])\n        }\n      },\n    })\n\n    const components = createSchemaField({\n      components: {\n        Input,\n        CustomObject,\n        CustomObject2,\n      },\n    })\n\n    const { queryByTestId } = render({\n      components: components,\n      data() {\n        return {\n          form,\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField>\n          <SchemaObjectField x-component=\"CustomObject\">\n            <SchemaStringField x-component=\"Input\" />\n          </SchemaObjectField>\n          <SchemaObjectField x-component=\"CustomObject2\">\n            <SchemaStringField x-component=\"Input\" />\n          </SchemaObjectField>\n        </SchemaField>\n      </FormProvider>`,\n    })\n    expect(queryByTestId('input')).toBeNull()\n  })\n\n  test('schema reactions', async () => {\n    const div = document.createElement('div')\n    document.body.appendChild(div)\n    const form = createForm()\n    const components = createSchemaField({\n      components: {\n        Input,\n      },\n    })\n    const localVue = createLocalVue()\n    localVue.component('FormProvider', FormProvider)\n    const TestComponent = {\n      components: components,\n      data() {\n        return {\n          form,\n          reactions: [\n            {\n              when: '{{$form.values.aaa === \"123\"}}',\n              fulfill: {\n                state: {\n                  visible: true,\n                },\n              },\n              otherwise: {\n                state: {\n                  visible: false,\n                },\n              },\n            },\n            {\n              when: '{{$self.value === \"123\"}}',\n              target: 'ccc',\n              fulfill: {\n                schema: {\n                  'x-visible': true,\n                },\n              },\n              otherwise: {\n                schema: {\n                  'x-visible': false,\n                },\n              },\n            },\n          ],\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField>\n          <SchemaStringField\n            name=\"aaa\"\n            x-component=\"Input\"\n            :x-component-props=\"{\n              'class': 'aaa',\n            }\"\n          />\n          <SchemaStringField\n            name=\"bbb\"\n            x-component=\"Input\"\n            :x-component-props=\"{\n              'class': 'bbb',\n            }\"\n            :x-reactions=\"reactions\"\n          />\n          <SchemaStringField\n            name=\"ccc\"\n            x-component=\"Input\"\n            :x-component-props=\"{\n              'class': 'ccc',\n            }\"\n          />\n        </SchemaField>\n      </FormProvider>`,\n    } as any\n    const wrapper = mount(TestComponent, {\n      // attachTo: div,\n      attachToDocument: true,\n      localVue,\n    })\n    expect(wrapper.find('.bbb').exists()).toBeFalsy()\n    wrapper.find('.aaa').setValue('123')\n    expect(form.query('aaa').get('value')).toEqual('123')\n    await wrapper.vm.$forceUpdate()\n    expect(wrapper.find('.bbb').exists()).toBeTruthy()\n    expect(wrapper.find('.ccc').exists()).toBeFalsy()\n    wrapper.find('.bbb').setValue('123')\n    expect(form.query('bbb').get('value')).toEqual('123')\n    await wrapper.vm.$forceUpdate()\n    expect(wrapper.find('.ccc').exists()).toBeTruthy()\n    wrapper.destroy()\n  })\n\n  test('void field children', () => {\n    const form = createForm()\n    const VoidComponent = {\n      render(h: CreateElement) {\n        return h('div', this.$slots.default || 'placeholder')\n      },\n    }\n    const { SchemaField, SchemaVoidField } = createSchemaField({\n      components: {\n        VoidComponent,\n      },\n    })\n    const { queryByTestId } = render({\n      components: { SchemaField, SchemaVoidField },\n      data() {\n        return {\n          form,\n        }\n      },\n      template: `<FormProvider :form=\"form\">\n        <SchemaField>\n          <SchemaVoidField x-component=\"VoidComponent\" :x-component-props=\"{ 'data-testid': 'void-component-1' }\" />\n          <SchemaVoidField x-component=\"VoidComponent\" :x-component-props=\"{ 'data-testid': 'void-component-2' }\" x-content=\"content\" />\n        </SchemaField>\n      </FormProvider>`,\n    })\n    expect(queryByTestId('void-component-1').textContent).toBe('placeholder')\n    expect(queryByTestId('void-component-2').textContent).toBe('content')\n  })\n})\n"
  },
  {
    "path": "packages/vue/src/__tests__/shared.spec.ts",
    "content": "import { createForm } from '../'\nimport { isRaw } from '@vue/composition-api'\n\ntest('createForm returns an un reactive form instance.', () => {\n  const form = createForm()\n  expect(isRaw(form)).toBeTruthy()\n})\n"
  },
  {
    "path": "packages/vue/src/__tests__/utils.spec.ts",
    "content": "import { formatVue3VNodeData } from '../utils/formatVNodeData'\n\ntest('valid formatVNodeData', () => {\n  const onClick = () => {}\n  const ondblclick = () => {}\n\n  const vNodeData = {\n    class: [{ bar: false }, { 'test-component': true }],\n    style: {\n      border: '4px solid red',\n      padding: '20px',\n      borderRadius: '10px',\n    },\n    attrs: {\n      id: 'foo',\n    },\n    props: {\n      value: 'leader',\n      user: {\n        name: '张三',\n        age: 18,\n        sex: 1,\n      },\n    },\n    domProps: {\n      innerHTML: 'innerHTML - baz',\n    },\n    on: {\n      click: onClick,\n    },\n    nativeOn: {\n      dblclick: ondblclick,\n    },\n  }\n\n  const vue3VNodeData = {\n    class: [{ bar: false }, { 'test-component': true }],\n    style: {\n      border: '4px solid red',\n      padding: '20px',\n      borderRadius: '10px',\n    },\n    id: 'foo',\n    value: 'leader',\n    user: {\n      name: '张三',\n      age: 18,\n      sex: 1,\n    },\n    innerHTML: 'innerHTML - baz',\n    onClick,\n    ondblclick,\n  }\n\n  expect(formatVue3VNodeData(vNodeData)).toEqual(vue3VNodeData)\n})\n"
  },
  {
    "path": "packages/vue/src/components/ArrayField.ts",
    "content": "import { isVue2, h as _h } from 'vue-demi'\nimport ReactiveField from './ReactiveField'\nimport { getRawComponent } from '../utils/getRawComponent'\n\nimport type { IArrayFieldProps, DefineComponent } from '../types'\nimport { getFieldProps } from '../utils/getFieldProps'\n\nlet ArrayField: DefineComponent<IArrayFieldProps>\n\n/* istanbul ignore else */\nif (isVue2) {\n  ArrayField = {\n    functional: true,\n    name: 'ArrayField',\n    props: getFieldProps(),\n    render(h, context) {\n      const props = context.props as IArrayFieldProps\n      const attrs = context.data.attrs\n      const componentData = {\n        ...context.data,\n        props: {\n          fieldType: 'ArrayField',\n          fieldProps: {\n            ...attrs,\n            ...props,\n            ...getRawComponent(props),\n          },\n        },\n      }\n      return _h(ReactiveField, componentData, context.children)\n    },\n  } as unknown as DefineComponent<IArrayFieldProps>\n} else {\n  ArrayField = {\n    name: 'ArrayField',\n    props: getFieldProps(),\n    setup(props: IArrayFieldProps, context) {\n      return () => {\n        const componentData = {\n          fieldType: 'ArrayField',\n          fieldProps: {\n            ...props,\n            ...getRawComponent(props),\n          },\n        } as Record<string, unknown>\n        return _h(ReactiveField, componentData, context.slots)\n      }\n    },\n  } as unknown as DefineComponent<IArrayFieldProps>\n}\n\nexport default ArrayField\n"
  },
  {
    "path": "packages/vue/src/components/ExpressionScope.ts",
    "content": "import { lazyMerge } from '@formily/shared'\nimport { computed, defineComponent, inject, provide, Ref } from 'vue-demi'\nimport { SchemaExpressionScopeSymbol, Fragment, h } from '../shared'\nimport { IExpressionScopeProps } from '../types'\n\nexport const ExpressionScope = defineComponent({\n  name: 'ExpressionScope',\n  props: ['value'],\n  setup(props: IExpressionScopeProps, { slots }) {\n    const scopeRef = inject<Ref>(SchemaExpressionScopeSymbol)\n    const expressionScopeRef = computed(() =>\n      lazyMerge(scopeRef.value, props.value)\n    )\n\n    provide(SchemaExpressionScopeSymbol, expressionScopeRef)\n\n    return () => h(Fragment, {}, slots)\n  },\n})\n"
  },
  {
    "path": "packages/vue/src/components/Field.ts",
    "content": "import { isVue2, h as _h } from 'vue-demi'\nimport ReactiveField from './ReactiveField'\nimport { getRawComponent } from '../utils/getRawComponent'\n\nimport type { IFieldProps, DefineComponent } from '../types'\nimport { getFieldProps } from '../utils/getFieldProps'\n\nlet Field: DefineComponent<IFieldProps>\n\n/* istanbul ignore else */\nif (isVue2) {\n  Field = {\n    functional: true,\n    name: 'Field',\n    props: getFieldProps(),\n    render(h, context) {\n      const props = context.props as IFieldProps\n      const attrs = context.data.attrs\n      const componentData = {\n        ...context.data,\n        props: {\n          fieldType: 'Field',\n          fieldProps: {\n            ...attrs,\n            ...props,\n            ...getRawComponent(props),\n          },\n        },\n      }\n      return _h(ReactiveField, componentData, context.children)\n    },\n  } as unknown as DefineComponent<IFieldProps>\n} else {\n  Field = {\n    name: 'Field',\n    props: getFieldProps(),\n    setup(props: IFieldProps, context) {\n      return () => {\n        const componentData = {\n          fieldType: 'Field',\n          fieldProps: {\n            ...props,\n            ...getRawComponent(props),\n          },\n        } as Record<string, unknown>\n        return _h(ReactiveField, componentData, context.slots)\n      }\n    },\n  } as unknown as DefineComponent<IFieldProps>\n}\n\nexport default Field\n"
  },
  {
    "path": "packages/vue/src/components/FormConsumer.ts",
    "content": "import { defineComponent } from 'vue-demi'\nimport { observer } from '@formily/reactive-vue'\nimport { useForm } from '../hooks'\nimport h from '../shared/h'\n\nexport default observer(\n  defineComponent({\n    name: 'FormConsumer',\n    inheritAttrs: false,\n    setup(props, { slots }) {\n      const formRef = useForm()\n      return () => {\n        // just like <Fragment>\n        return h(\n          'div',\n          { style: { display: 'contents' } },\n          {\n            default: () =>\n              slots.default?.({\n                form: formRef.value,\n              }),\n          }\n        )\n      }\n    },\n  }),\n  {\n    // make sure observables updated <cannot be tracked by tests>\n    scheduler: /* istanbul ignore next */ (update) =>\n      Promise.resolve().then(update),\n  }\n)\n"
  },
  {
    "path": "packages/vue/src/components/FormProvider.ts",
    "content": "import { provide, defineComponent, toRef } from 'vue-demi'\nimport {\n  FormSymbol,\n  FieldSymbol,\n  SchemaMarkupSymbol,\n  SchemaSymbol,\n  SchemaExpressionScopeSymbol,\n  SchemaOptionsSymbol,\n} from '../shared/context'\nimport { IProviderProps, DefineComponent } from '../types'\nimport { useAttach } from '../hooks/useAttach'\nimport { useInjectionCleaner } from '../hooks/useInjectionCleaner'\nimport h from '../shared/h'\nimport { Fragment } from '../shared/fragment'\n\nexport default defineComponent({\n  name: 'FormProvider',\n  inheritAttrs: false,\n  props: ['form'],\n  setup(props: IProviderProps, { slots }) {\n    const formRef = useAttach(toRef(props, 'form'))\n    provide(FormSymbol, formRef)\n    useInjectionCleaner([\n      FieldSymbol,\n      SchemaMarkupSymbol,\n      SchemaSymbol,\n      SchemaExpressionScopeSymbol,\n      SchemaOptionsSymbol,\n    ])\n\n    return () => h(Fragment, {}, slots)\n  },\n}) as DefineComponent<IProviderProps>\n"
  },
  {
    "path": "packages/vue/src/components/ObjectField.ts",
    "content": "import { isVue2, h as _h } from 'vue-demi'\nimport ReactiveField from './ReactiveField'\nimport { getRawComponent } from '../utils/getRawComponent'\n\nimport type { IObjectFieldProps, DefineComponent } from '../types'\nimport { getFieldProps } from '../utils/getFieldProps'\n\nlet ObjectField: DefineComponent<IObjectFieldProps>\n\n/* istanbul ignore else */\nif (isVue2) {\n  ObjectField = {\n    functional: true,\n    name: 'ObjectField',\n    props: getFieldProps(),\n    render(h, context) {\n      const props = context.props as IObjectFieldProps\n      const attrs = context.data.attrs\n      const componentData = {\n        ...context.data,\n        props: {\n          fieldType: 'ObjectField',\n          fieldProps: {\n            ...attrs,\n            ...props,\n            ...getRawComponent(props),\n          },\n        },\n      }\n      return _h(ReactiveField, componentData, context.children)\n    },\n  } as unknown as DefineComponent<IObjectFieldProps>\n} else {\n  ObjectField = {\n    name: 'ObjectField',\n    props: getFieldProps(),\n    setup(props: IObjectFieldProps, context) {\n      return () => {\n        const componentData = {\n          fieldType: 'ObjectField',\n          fieldProps: {\n            ...props,\n            ...getRawComponent(props),\n          },\n        } as Record<string, unknown>\n        return _h(ReactiveField, componentData, context.slots)\n      }\n    },\n  } as unknown as DefineComponent<IObjectFieldProps>\n}\n\nexport default ObjectField\n"
  },
  {
    "path": "packages/vue/src/components/ReactiveField.ts",
    "content": "import { inject, provide, Ref, ref, shallowRef, watch, isVue2 } from 'vue-demi'\nimport { GeneralField, isVoidField } from '@formily/core'\nimport { each, FormPath } from '@formily/shared'\nimport { observer } from '@formily/reactive-vue'\nimport { toJS, reaction } from '@formily/reactive'\nimport { SchemaOptionsSymbol, FieldSymbol, h, Fragment } from '../shared'\nimport { useAttach } from '../hooks/useAttach'\nimport { useField, useForm } from '../hooks'\n\nimport type {\n  IReactiveFieldProps,\n  VueComponentProps,\n  DefineComponent,\n} from '../types'\nimport type { VNode } from 'vue'\n\nfunction isVueOptions(options: Record<string, unknown>) {\n  return (\n    typeof options.template === 'string' ||\n    typeof options.render === 'function' ||\n    typeof options.setup === 'function'\n  )\n}\n\nconst wrapFragment = (childNodes: VNode[] | VNode): VNode => {\n  if (!Array.isArray(childNodes)) {\n    return childNodes\n  }\n  if (childNodes.length > 1) {\n    return h(Fragment, {}, { default: () => childNodes })\n  }\n  return childNodes[0]\n}\n\nconst resolveComponent = (render: () => unknown[], extra?: any) => {\n  if (extra === undefined || extra === null) {\n    return render\n  }\n  if (typeof extra === 'string') {\n    return () => [...render(), extra]\n  }\n  // not component\n  if (!isVueOptions(extra) && typeof extra !== 'function') {\n    return render\n  }\n  // for scoped slot\n  if (extra.length > 1 || extra?.render?.length > 1) {\n    return (scopedProps: VueComponentProps<any>) => [\n      ...render(),\n      h(extra, { props: scopedProps }, {}),\n    ]\n  }\n  return () => [...render(), h(extra, {}, {})]\n}\n\nconst mergeSlots = (\n  field: GeneralField,\n  slots: Record<string, any>,\n  content: any\n): Record<string, (...args: any) => any[]> => {\n  const slotNames = Object.keys(slots)\n  if (!slotNames.length) {\n    if (!content) {\n      return {}\n    }\n    if (typeof content === 'string') {\n      return {\n        default: resolveComponent(() => [], content),\n      }\n    }\n  }\n  const patchSlot =\n    (slotName: string) =>\n    (...originArgs) =>\n      slots[slotName]?.({ field, form: field.form, ...originArgs[0] }) ?? []\n\n  const patchedSlots: Record<string, (...args: any) => unknown[]> = {}\n  slotNames.forEach((name) => {\n    patchedSlots[name] = patchSlot(name)\n  })\n\n  // for named slots\n  if (content && typeof content === 'object' && !isVueOptions(content)) {\n    Object.keys(content).forEach((key) => {\n      const child = content[key]\n      const slot = patchedSlots[key] ?? (() => [])\n      patchedSlots[key] = resolveComponent(slot, child)\n    })\n    return patchedSlots\n  }\n  // maybe default slot is empty\n  patchedSlots['default'] = resolveComponent(\n    patchedSlots['default'] ?? (() => []),\n    content\n  )\n  return patchedSlots\n}\n\nconst createFieldInVue2 = (innerCreateField) => {\n  return () => {\n    let res: GeneralField\n    const disposer = reaction(() => {\n      res = innerCreateField()\n    })\n    disposer()\n    return res\n  }\n}\n\nexport default observer({\n  name: 'ReactiveField',\n  props: {\n    fieldType: {\n      type: String,\n      default: 'Field',\n    },\n    fieldProps: {\n      type: Object,\n      default: () => ({}),\n    },\n  },\n  setup(props: IReactiveFieldProps, { slots }) {\n    const formRef = useForm()\n    const parentRef = useField()\n    const optionsRef = inject(SchemaOptionsSymbol, ref(null))\n    let createField = () =>\n      formRef?.value?.[`create${props.fieldType}`]?.({\n        ...props.fieldProps,\n        basePath: props.fieldProps?.basePath ?? parentRef.value?.address,\n      })\n\n    if (isVue2) {\n      createField = createFieldInVue2(createField)\n    }\n\n    const fieldRef = shallowRef(createField()) as Ref<GeneralField>\n    watch(\n      () => props.fieldProps,\n      () => (fieldRef.value = createField())\n    )\n    useAttach(fieldRef)\n    provide(FieldSymbol, fieldRef)\n    return () => {\n      const field = fieldRef.value\n      const options = optionsRef.value\n      if (!field) {\n        return slots.default?.()\n      }\n      if (field.display !== 'visible') {\n        return h('template', {}, {})\n      }\n\n      const mergedSlots = mergeSlots(field, slots, field.content)\n\n      const renderDecorator = (childNodes: any[]) => {\n        if (!field.decoratorType) {\n          return wrapFragment(childNodes)\n        }\n        const finalComponent =\n          FormPath.getIn(options?.components, field.decoratorType as string) ??\n          field.decoratorType\n        const componentAttrs = toJS(field.decorator[1]) || {}\n\n        const events: Record<string, any> = {}\n        each(componentAttrs, (value, eventKey) => {\n          const onEvent = eventKey.startsWith('on')\n          const atEvent = eventKey.startsWith('@')\n          if (!onEvent && !atEvent) return\n          if (onEvent) {\n            const eventName = `${eventKey[2].toLowerCase()}${eventKey.slice(3)}`\n            // '@xxx' has higher priority\n            events[eventName] = events[eventName] || value\n          } else if (atEvent) {\n            const eventName = eventKey.slice(1)\n            events[eventName] = value\n            delete componentAttrs[eventKey]\n          }\n        })\n\n        const componentData = {\n          attrs: componentAttrs,\n          style: componentAttrs?.style,\n          class: componentAttrs?.class,\n          on: events,\n        }\n        delete componentData.attrs.style\n        delete componentData.attrs.class\n\n        return h(finalComponent, componentData, {\n          default: () => childNodes,\n        })\n      }\n\n      const renderComponent = () => {\n        if (!field.componentType) return wrapFragment(mergedSlots?.default?.())\n\n        const component =\n          FormPath.getIn(options?.components, field.componentType as string) ??\n          field.componentType\n\n        const originData = toJS(field.component[1]) || {}\n        const events = {} as Record<string, any>\n        const originChange = originData['@change'] || originData['onChange']\n        const originFocus = originData['@focus'] || originData['onFocus']\n        const originBlur = originData['@blur'] || originData['onBlur']\n\n        each(originData, (value, eventKey) => {\n          const onEvent = eventKey.startsWith('on')\n          const atEvent = eventKey.startsWith('@')\n          if (!onEvent && !atEvent) return\n          if (onEvent) {\n            const eventName = `${eventKey[2].toLowerCase()}${eventKey.slice(3)}`\n            // '@xxx' has higher priority\n            events[eventName] = events[eventName] || value\n          } else if (atEvent) {\n            const eventName = eventKey.slice(1)\n            events[eventName] = value\n            delete originData[eventKey]\n          }\n        })\n\n        events.change = (...args: any[]) => {\n          if (!isVoidField(field)) field.onInput(...args)\n          originChange?.(...args)\n        }\n        events.focus = (...args: any[]) => {\n          if (!isVoidField(field)) field.onFocus(...args)\n          originFocus?.(...args)\n        }\n        events.blur = (...args: any[]) => {\n          if (!isVoidField(field)) field.onBlur(...args)\n          originBlur?.(...args)\n        }\n\n        const componentData = {\n          attrs: {\n            disabled: !isVoidField(field)\n              ? field.pattern === 'disabled' || field.pattern === 'readPretty'\n              : undefined,\n            readOnly: !isVoidField(field)\n              ? field.pattern === 'readOnly'\n              : undefined,\n            ...originData,\n            value: !isVoidField(field) ? field.value : undefined,\n          },\n          style: originData?.style,\n          class: originData?.class,\n          on: events,\n        }\n        delete componentData.attrs.style\n        delete componentData.attrs.class\n\n        return h(component, componentData, mergedSlots)\n      }\n\n      return renderDecorator([renderComponent()])\n    }\n  },\n} as unknown as DefineComponent<IReactiveFieldProps>)\n"
  },
  {
    "path": "packages/vue/src/components/RecursionField.ts",
    "content": "import { inject, provide, watch, shallowRef, computed, markRaw } from 'vue-demi'\nimport { GeneralField } from '@formily/core'\nimport { isFn, isValid, lazyMerge } from '@formily/shared'\nimport { Schema } from '@formily/json-schema'\nimport {\n  SchemaSymbol,\n  SchemaOptionsSymbol,\n  SchemaExpressionScopeSymbol,\n} from '../shared'\nimport { useField } from '../hooks'\nimport ObjectField from './ObjectField'\nimport ArrayField from './ArrayField'\nimport Field from './Field'\nimport VoidField from './VoidField'\nimport { h } from '../shared/h'\n\nimport type { IRecursionFieldProps, DefineComponent } from '../types'\n\nconst resolveEmptySlot = (slots: Record<any, (...args: any[]) => any[]>) => {\n  return Object.keys(slots).length\n    ? h('div', { style: 'display:contents;' }, slots)\n    : undefined\n}\n\nconst RecursionField = {\n  name: 'RecursionField',\n  inheritAttrs: false,\n  props: {\n    schema: {\n      required: true,\n    },\n    name: [String, Number],\n    basePath: {},\n    onlyRenderProperties: {\n      type: Boolean,\n      default: undefined,\n    },\n    onlyRenderSelf: {\n      type: Boolean,\n      default: undefined,\n    },\n    mapProperties: {},\n    filterProperties: {},\n  },\n  setup(props: IRecursionFieldProps) {\n    const parentRef = useField()\n    const optionsRef = inject(SchemaOptionsSymbol)\n    const scopeRef = inject(SchemaExpressionScopeSymbol)\n    const createSchema = (schemaProp: IRecursionFieldProps['schema']) =>\n      markRaw(new Schema(schemaProp))\n    const fieldSchemaRef = computed(() => createSchema(props.schema))\n\n    const getPropsFromSchema = (schema: Schema) =>\n      schema?.toFieldProps?.({\n        ...optionsRef.value,\n        get scope() {\n          return lazyMerge(optionsRef.value.scope, scopeRef.value)\n        },\n      })\n    const fieldPropsRef = shallowRef(getPropsFromSchema(fieldSchemaRef.value))\n\n    watch([fieldSchemaRef, optionsRef], () => {\n      fieldPropsRef.value = getPropsFromSchema(fieldSchemaRef.value)\n    })\n\n    const getBasePath = () => {\n      if (props.onlyRenderProperties) {\n        return props.basePath ?? parentRef?.value?.address.concat(props.name)\n      }\n      return props.basePath ?? parentRef?.value?.address\n    }\n\n    provide(SchemaSymbol, fieldSchemaRef)\n\n    return () => {\n      const basePath = getBasePath()\n      const fieldProps = fieldPropsRef.value\n\n      const generateSlotsByProperties = (scoped = false) => {\n        if (props.onlyRenderSelf) return {}\n        const properties = Schema.getOrderProperties(fieldSchemaRef.value)\n        if (!properties.length) return {}\n        const renderMap: Record<string, ((field?: GeneralField) => unknown)[]> =\n          {}\n        const setRender = (\n          key: string,\n          value: (field?: GeneralField) => unknown\n        ) => {\n          if (!renderMap[key]) {\n            renderMap[key] = []\n          }\n          renderMap[key].push(value)\n        }\n        properties.forEach(({ schema: item, key: name }, index) => {\n          let schema: Schema = item\n          if (isFn(props.mapProperties)) {\n            const mapped = props.mapProperties(item, name)\n            if (mapped) {\n              schema = mapped\n            }\n          }\n          if (isFn(props.filterProperties)) {\n            if (props.filterProperties(schema, name) === false) {\n              return null\n            }\n          }\n          setRender(schema['x-slot'] ?? 'default', (field?: GeneralField) =>\n            h(\n              RecursionField,\n              {\n                key: `${index}-${name}`,\n                attrs: {\n                  schema,\n                  name,\n                  basePath: field?.address ?? basePath,\n                },\n                slot: schema['x-slot'],\n              },\n              {}\n            )\n          )\n        })\n        const slots = {}\n        Object.keys(renderMap).forEach((key) => {\n          const renderFns = renderMap[key]\n          slots[key] = scoped\n            ? ({ field }) => renderFns.map((fn) => fn(field))\n            : () => renderFns.map((fn) => fn())\n        })\n        return slots\n      }\n\n      const render = () => {\n        if (!isValid(props.name))\n          return resolveEmptySlot(generateSlotsByProperties())\n        if (fieldSchemaRef.value.type === 'object') {\n          if (props.onlyRenderProperties)\n            return resolveEmptySlot(generateSlotsByProperties())\n          return h(\n            ObjectField,\n            {\n              attrs: {\n                ...fieldProps,\n                name: props.name,\n                basePath: basePath,\n              },\n            },\n            generateSlotsByProperties(true)\n          )\n        } else if (fieldSchemaRef.value.type === 'array') {\n          return h(\n            ArrayField,\n            {\n              attrs: {\n                ...fieldProps,\n                name: props.name,\n                basePath: basePath,\n              },\n            },\n            {}\n          )\n        } else if (fieldSchemaRef.value.type === 'void') {\n          if (props.onlyRenderProperties)\n            return resolveEmptySlot(generateSlotsByProperties())\n          const slots = generateSlotsByProperties(true)\n          return h(\n            VoidField,\n            {\n              attrs: {\n                ...fieldProps,\n                name: props.name,\n                basePath: basePath,\n              },\n            },\n            slots\n          )\n        }\n\n        return h(\n          Field,\n          {\n            attrs: {\n              ...fieldProps,\n              name: props.name,\n              basePath: basePath,\n            },\n          },\n          {}\n        )\n      }\n\n      if (!fieldSchemaRef.value) return\n\n      return render()\n    }\n  },\n} as unknown as DefineComponent<IRecursionFieldProps>\n\nexport default RecursionField\n"
  },
  {
    "path": "packages/vue/src/components/SchemaField.ts",
    "content": "import { inject, provide, computed, shallowRef, watch } from 'vue-demi'\nimport { ISchema, Schema, SchemaTypes } from '@formily/json-schema'\nimport { RecursionField } from '../components'\nimport {\n  SchemaMarkupSymbol,\n  SchemaExpressionScopeSymbol,\n  SchemaOptionsSymbol,\n} from '../shared'\nimport {\n  ISchemaFieldVueFactoryOptions,\n  SchemaVueComponents,\n  ISchemaFieldProps,\n  ISchemaMarkupFieldProps,\n  ISchemaTypeFieldProps,\n} from '../types'\nimport { resolveSchemaProps } from '../utils/resolveSchemaProps'\nimport { h } from '../shared/h'\nimport { Fragment } from '../shared/fragment'\nimport type { DefineComponent } from '../types'\nimport { lazyMerge } from '@formily/shared'\n\ntype SchemaFieldComponents = {\n  SchemaField: DefineComponent<ISchemaFieldProps>\n  SchemaMarkupField: DefineComponent<ISchemaMarkupFieldProps>\n  SchemaStringField: DefineComponent<ISchemaTypeFieldProps>\n  SchemaObjectField: DefineComponent<ISchemaTypeFieldProps>\n  SchemaArrayField: DefineComponent<ISchemaTypeFieldProps>\n  SchemaBooleanField: DefineComponent<ISchemaTypeFieldProps>\n  SchemaDateField: DefineComponent<ISchemaTypeFieldProps>\n  SchemaDateTimeField: DefineComponent<ISchemaTypeFieldProps>\n  SchemaVoidField: DefineComponent<ISchemaTypeFieldProps>\n  SchemaNumberField: DefineComponent<ISchemaTypeFieldProps>\n}\n\nconst env = {\n  nonameId: 0,\n}\n\nconst getRandomName = () => {\n  return `NO_NAME_FIELD_$${env.nonameId++}`\n}\n\nconst markupProps = {\n  version: String,\n  name: [String, Number],\n  title: {},\n  description: {},\n  default: {},\n  readOnly: {\n    type: Boolean,\n    default: undefined,\n  },\n  writeOnly: {\n    type: Boolean,\n    default: undefined,\n  },\n  enum: {},\n  const: {},\n  multipleOf: Number,\n  maximum: Number,\n  exclusiveMaximum: Number,\n  minimum: Number,\n  exclusiveMinimum: Number,\n  maxLength: Number,\n  minLength: Number,\n  pattern: {},\n  maxItems: Number,\n  minItems: Number,\n  uniqueItems: {\n    type: Boolean,\n    default: undefined,\n  },\n  maxProperties: Number,\n  minProperties: Number,\n  required: {\n    type: [Boolean, Array, String],\n    default: undefined,\n  },\n  format: String,\n  properties: {},\n  items: {},\n  additionalItems: {},\n  patternProperties: {},\n  additionalProperties: {},\n  xIndex: Number,\n  xPattern: {},\n  xDisplay: {},\n  xValidator: {},\n  xDecorator: {},\n  xDecoratorProps: {},\n  xComponent: {},\n  xComponentProps: {},\n  xReactions: {},\n  xContent: {},\n  xVisible: {\n    type: Boolean,\n    default: undefined,\n  },\n  xHidden: {\n    type: Boolean,\n    default: undefined,\n  },\n  xDisabled: {\n    type: Boolean,\n    default: undefined,\n  },\n  xEditable: {\n    type: Boolean,\n    default: undefined,\n  },\n  xReadOnly: {\n    type: Boolean,\n    default: undefined,\n  },\n  xReadPretty: {\n    type: Boolean,\n    default: undefined,\n  },\n}\n\nexport function createSchemaField<\n  Components extends SchemaVueComponents = SchemaVueComponents\n>(options: ISchemaFieldVueFactoryOptions<Components> = {}): SchemaFieldComponents {\n  const SchemaField = {\n    name: 'SchemaField',\n    inheritAttrs: false,\n    props: {\n      schema: {},\n      scope: {},\n      components: {},\n      name: [String, Number],\n      basePath: {},\n      onlyRenderProperties: { type: Boolean, default: undefined },\n      onlyRenderSelf: { type: Boolean, default: undefined },\n      mapProperties: {},\n      filterProperties: {},\n    },\n    setup(props: ISchemaFieldProps, { slots }) {\n      const schemaRef = computed(() =>\n        Schema.isSchemaInstance(props.schema)\n          ? props.schema\n          : new Schema({\n              type: 'object',\n              ...props.schema,\n            })\n      )\n\n      const scopeRef = computed(() => lazyMerge(options.scope, props.scope))\n\n      const optionsRef = computed(() => ({\n        ...options,\n        components: {\n          ...options.components,\n          ...props.components,\n        },\n      }))\n\n      provide(SchemaMarkupSymbol, schemaRef)\n      provide(SchemaOptionsSymbol, optionsRef)\n      provide(SchemaExpressionScopeSymbol, scopeRef)\n\n      return () => {\n        env.nonameId = 0\n\n        return h(\n          Fragment,\n          {},\n          {\n            default: () => {\n              const children = []\n              if (slots.default) {\n                children.push(\n                  h(\n                    'template',\n                    {},\n                    {\n                      default: () => slots.default(),\n                    }\n                  )\n                )\n              }\n              children.push(\n                h(\n                  RecursionField,\n                  {\n                    attrs: {\n                      ...props,\n                      schema: schemaRef.value,\n                    },\n                  },\n                  {}\n                )\n              )\n              return children\n            },\n          }\n        )\n      }\n    },\n  }\n\n  const MarkupField = {\n    name: 'MarkupField',\n    props: {\n      type: String,\n      ...markupProps,\n    },\n    setup(props: ISchemaMarkupFieldProps, { slots }) {\n      const parentRef = inject(SchemaMarkupSymbol, null)\n      if (!parentRef || !parentRef.value) return () => h('template', {}, {})\n\n      const name = props.name || getRandomName()\n      const appendArraySchema = (schema: ISchema) => {\n        if (parentRef.value.items) {\n          return parentRef.value.addProperty(name, schema)\n        } else {\n          return parentRef.value.setItems(resolveSchemaProps(props))\n        }\n      }\n\n      const schemaRef = shallowRef(null)\n\n      watch(\n        parentRef,\n        () => {\n          if (\n            parentRef.value.type === 'object' ||\n            parentRef.value.type === 'void'\n          ) {\n            schemaRef.value = parentRef.value.addProperty(\n              name,\n              resolveSchemaProps(props)\n            )\n          } else if (parentRef.value.type === 'array') {\n            const schema = appendArraySchema(resolveSchemaProps(props))\n            schemaRef.value = Array.isArray(schema) ? schema[0] : schema\n          }\n        },\n        { immediate: true }\n      )\n      provide(SchemaMarkupSymbol, schemaRef)\n\n      return () => {\n        return h('div', { style: 'display: none;' }, slots)\n      }\n    },\n  }\n\n  const SchemaFieldFactory = (type: SchemaTypes, name: string) => {\n    return {\n      name: name,\n      props: { ...markupProps },\n      setup(props: ISchemaTypeFieldProps, { slots }) {\n        return () =>\n          h(\n            MarkupField,\n            {\n              attrs: {\n                ...props,\n                type: type,\n              },\n            },\n            slots\n          )\n      },\n    }\n  }\n\n  return {\n    SchemaField,\n    SchemaMarkupField: MarkupField,\n    SchemaStringField: SchemaFieldFactory('string', 'SchemaStringField'),\n    SchemaObjectField: SchemaFieldFactory('object', 'SchemaObjectField'),\n    SchemaArrayField: SchemaFieldFactory('array', 'SchemaArrayField'),\n    SchemaBooleanField: SchemaFieldFactory('boolean', 'SchemaBooleanField'),\n    SchemaDateField: SchemaFieldFactory('date', 'SchemaDateField'),\n    SchemaDateTimeField: SchemaFieldFactory('datetime', 'SchemaDatetimeField'),\n    SchemaVoidField: SchemaFieldFactory('void', 'SchemaVoidField'),\n    SchemaNumberField: SchemaFieldFactory('number', 'SchemaNumberField'),\n  } as unknown as SchemaFieldComponents\n}\n"
  },
  {
    "path": "packages/vue/src/components/VoidField.ts",
    "content": "import { isVue2, h as _h } from 'vue-demi'\nimport ReactiveField from './ReactiveField'\nimport { getRawComponent } from '../utils/getRawComponent'\n\nimport type { IVoidFieldProps, DefineComponent } from '../types'\nimport { getVoidFieldProps } from '../utils/getFieldProps'\n\nlet VoidField: DefineComponent<IVoidFieldProps>\n\n/* istanbul ignore else */\nif (isVue2) {\n  VoidField = {\n    functional: true,\n    name: 'VoidField',\n    props: getVoidFieldProps(),\n    render(h, context) {\n      const props = context.props as IVoidFieldProps\n      const attrs = context.data.attrs\n      const componentData = {\n        ...context.data,\n        props: {\n          fieldType: 'VoidField',\n          fieldProps: {\n            ...attrs,\n            ...props,\n            ...getRawComponent(props),\n          },\n        },\n      }\n      return _h(ReactiveField, componentData, context.children)\n    },\n  } as unknown as DefineComponent<IVoidFieldProps>\n} else {\n  VoidField = {\n    name: 'VoidField',\n    props: getVoidFieldProps(),\n    setup(props: IVoidFieldProps, context) {\n      return () => {\n        const componentData = {\n          fieldType: 'VoidField',\n          fieldProps: {\n            ...props,\n            ...getRawComponent(props),\n          },\n        } as Record<string, unknown>\n        return _h(ReactiveField, componentData, context.slots)\n      }\n    },\n  } as unknown as DefineComponent<IVoidFieldProps>\n}\n\nexport default VoidField\n"
  },
  {
    "path": "packages/vue/src/components/index.ts",
    "content": "export { default as FormProvider } from './FormProvider'\nexport { default as FormConsumer } from './FormConsumer'\nexport { default as ArrayField } from './ArrayField'\nexport { default as ObjectField } from './ObjectField'\nexport { default as VoidField } from './VoidField'\nexport { default as RecursionField } from './RecursionField'\nexport { default as Field } from './Field'\nexport { createSchemaField } from './SchemaField'\nexport { ExpressionScope } from './ExpressionScope'\n"
  },
  {
    "path": "packages/vue/src/global.d.ts",
    "content": "/// <reference types=\"@formily/core\" />\n/// <reference types=\"@formily/json-schema\" />\nimport * as Types from './types'\ndeclare global {\n  namespace Formily.Vue {\n    export { Types }\n  }\n}\n"
  },
  {
    "path": "packages/vue/src/hooks/index.ts",
    "content": "export * from './useForm'\nexport * from './useField'\nexport * from './useFormEffects'\nexport * from './useFieldSchema'\nexport * from './useParentForm'\n"
  },
  {
    "path": "packages/vue/src/hooks/useAttach.ts",
    "content": "import { onMounted, watch, Ref, onUnmounted, nextTick } from 'vue-demi'\n\ninterface IRecycleTarget {\n  onMount: () => void\n  onUnmount: () => void\n}\n\nexport const useAttach = <T extends IRecycleTarget>(target: Ref<T>): Ref<T> => {\n  watch(target, (v, old, onInvalidate) => {\n    if (v && v !== old) {\n      old?.onUnmount()\n      nextTick(() => v.onMount())\n      onInvalidate(() => v.onUnmount())\n    }\n  })\n  onMounted(() => {\n    target.value?.onMount()\n  })\n  onUnmounted(() => {\n    target.value?.onUnmount()\n  })\n  return target\n}\n"
  },
  {
    "path": "packages/vue/src/hooks/useField.ts",
    "content": "import { inject, Ref, ref } from 'vue-demi'\nimport { GeneralField } from '@formily/core'\nimport { FieldSymbol } from '../shared/context'\n\nexport const useField = <T = GeneralField>(): Ref<T> => {\n  return inject(FieldSymbol, ref()) as any\n}\n"
  },
  {
    "path": "packages/vue/src/hooks/useFieldSchema.ts",
    "content": "import { inject, ref } from 'vue-demi'\nimport { SchemaSymbol } from '../shared/context'\n\nexport const useFieldSchema = () => {\n  return inject(SchemaSymbol, ref())\n}\n"
  },
  {
    "path": "packages/vue/src/hooks/useForm.ts",
    "content": "import { inject, Ref, ref } from 'vue-demi'\nimport { Form } from '@formily/core'\nimport { FormSymbol } from '../shared/context'\n\nexport const useForm = (): Ref<Form> => {\n  const form = inject(FormSymbol, ref())\n  return form\n}\n"
  },
  {
    "path": "packages/vue/src/hooks/useFormEffects.ts",
    "content": "import { onBeforeUnmount, watchEffect } from 'vue-demi'\nimport { Form } from '@formily/core'\nimport { uid } from '@formily/shared'\nimport { useForm } from './useForm'\n\nexport const useFormEffects = (effects?: (form: Form) => void): void => {\n  const formRef = useForm()\n\n  const stop = watchEffect((onCleanup) => {\n    const id = uid()\n    formRef.value.addEffects(id, effects)\n\n    onCleanup(() => {\n      formRef.value.removeEffects(id)\n    })\n  })\n\n  onBeforeUnmount(() => stop())\n}\n"
  },
  {
    "path": "packages/vue/src/hooks/useInjectionCleaner.ts",
    "content": "import { InjectionKey, provide, Ref, ref } from 'vue-demi'\n\nexport const useInjectionCleaner = (\n  injectionKeys: InjectionKey<Ref<unknown>>[]\n) => {\n  injectionKeys.forEach((key) => provide(key, ref()))\n}\n"
  },
  {
    "path": "packages/vue/src/hooks/useParentForm.ts",
    "content": "import { isObjectField, GeneralField, Form, ObjectField } from '@formily/core'\nimport { computed, Ref } from 'vue-demi'\nimport { useField } from './useField'\nimport { useForm } from './useForm'\n\nexport const useParentForm = (): Ref<Form | ObjectField> => {\n  const field = useField()\n  const form = useForm()\n  const findObjectParent = (field: GeneralField) => {\n    if (!field) return form.value\n    if (isObjectField(field)) return field\n    return findObjectParent(field?.parent)\n  }\n  return computed(() => findObjectParent(field.value))\n}\n"
  },
  {
    "path": "packages/vue/src/index.ts",
    "content": "export * from '@formily/json-schema'\nexport * from './components'\nexport * from './shared'\nexport * from './hooks'\nexport * from './types'\nexport * as Vue2Components from './vue2-components'\n"
  },
  {
    "path": "packages/vue/src/shared/connect.ts",
    "content": "import { isVue2, markRaw, defineComponent, getCurrentInstance } from 'vue-demi'\nimport { isFn, isStr, FormPath, each, isValid } from '@formily/shared'\nimport { isVoidField, GeneralField } from '@formily/core'\nimport { observer } from '@formily/reactive-vue'\n\nimport { useField } from '../hooks/useField'\nimport h from './h'\n\nimport type {\n  VueComponent,\n  IComponentMapper,\n  IStateMapper,\n  VueComponentProps,\n} from '../types'\n\nexport function mapProps<T extends VueComponent = VueComponent>(\n  ...args: IStateMapper<VueComponentProps<T>>[]\n) {\n  const transform = (input: VueComponentProps<T>, field: GeneralField) =>\n    args.reduce((props, mapper) => {\n      if (isFn(mapper)) {\n        props = Object.assign(props, mapper(props, field))\n      } else {\n        each(mapper, (to, extract) => {\n          const extractValue = FormPath.getIn(field, extract)\n          const targetValue = isStr(to) ? to : extract\n          const originalValue = FormPath.getIn(props, targetValue)\n          if (extract === 'value') {\n            if (to !== extract) {\n              delete props['value']\n            }\n          }\n          if (isValid(originalValue) && !isValid(extractValue)) return\n          FormPath.setIn(props, targetValue, extractValue)\n        })\n      }\n      return props\n    }, input)\n\n  return (target: T) => {\n    return observer(\n      defineComponent({\n        name: target.name ? `Connected${target.name}` : `ConnectedComponent`,\n        setup(props, { attrs, slots, listeners }: any) {\n          const fieldRef = useField()\n          return () => {\n            const newAttrs = fieldRef.value\n              ? transform({ ...attrs } as VueComponentProps<T>, fieldRef.value)\n              : { ...attrs }\n            return h(\n              target,\n              {\n                attrs: newAttrs,\n                on: listeners,\n              },\n              slots\n            )\n          }\n        },\n      })\n    )\n  }\n}\n\nexport function mapReadPretty<T extends VueComponent, C extends VueComponent>(\n  component: C,\n  readPrettyProps?: Record<string, any>\n) {\n  return (target: T) => {\n    return observer(\n      defineComponent({\n        name: target.name ? `Read${target.name}` : `ReadComponent`,\n        setup(props, { attrs, slots, listeners }: Record<string, any>) {\n          const fieldRef = useField()\n          return () => {\n            const field = fieldRef.value\n            return h(\n              field && !isVoidField(field) && field.pattern === 'readPretty'\n                ? component\n                : target,\n              {\n                attrs: {\n                  ...readPrettyProps,\n                  ...attrs,\n                },\n                on: listeners,\n              },\n              slots\n            )\n          }\n        },\n      })\n    )\n  }\n}\n\nexport function connect<T extends VueComponent>(\n  target: T,\n  ...args: IComponentMapper[]\n): T {\n  const Component = args.reduce((target: VueComponent, mapper) => {\n    return mapper(target)\n  }, target)\n  /* istanbul ignore else */\n  if (isVue2) {\n    const functionalComponent = defineComponent({\n      functional: true,\n      name: target.name,\n      render(h, context) {\n        return h(Component, context.data, context.children)\n      },\n    })\n    return markRaw(functionalComponent) as T\n  } else {\n    const functionalComponent = defineComponent({\n      name: target.name,\n      setup(props, { attrs, slots }) {\n        return () => {\n          return h(Component, { props, attrs }, slots)\n        }\n      },\n    })\n    return markRaw(functionalComponent) as T\n  }\n}\n"
  },
  {
    "path": "packages/vue/src/shared/context.ts",
    "content": "import { InjectionKey, Ref } from 'vue-demi'\nimport { Form, GeneralField } from '@formily/core'\nimport { Schema } from '@formily/json-schema'\nimport { ISchemaFieldVueFactoryOptions } from '../types'\nexport const FormSymbol: InjectionKey<Ref<Form>> = Symbol('form')\nexport const FieldSymbol: InjectionKey<Ref<GeneralField>> = Symbol('field')\nexport const SchemaMarkupSymbol: InjectionKey<Ref<Schema>> =\n  Symbol('schemaMarkup')\nexport const SchemaSymbol: InjectionKey<Ref<Schema>> = Symbol('schema')\nexport const SchemaExpressionScopeSymbol: InjectionKey<\n  Ref<Record<string, any>>\n> = Symbol('schemaExpression')\nexport const SchemaOptionsSymbol: InjectionKey<\n  Ref<ISchemaFieldVueFactoryOptions>\n> = Symbol('schemaOptions')\n"
  },
  {
    "path": "packages/vue/src/shared/createForm.ts",
    "content": "import { createForm } from '@formily/core'\nimport { markRaw } from 'vue-demi'\n\nconst createRawForm = (...args: Parameters<typeof createForm>) => {\n  const form = createForm(...args)\n  return markRaw(form)\n}\n\nexport { createRawForm as createForm }\n"
  },
  {
    "path": "packages/vue/src/shared/fragment.ts",
    "content": "import { Fragment as FragmentV2 } from 'vue-frag'\nimport { DefineComponent } from '../types'\nimport { isVue2, defineComponent } from 'vue-demi'\n\nexport const Fragment = '#fragment'\n\nlet FragmentComponent: DefineComponent<{}>\n\nif (isVue2) {\n  FragmentComponent = {\n    name: 'Fragment',\n    ...FragmentV2,\n  } as unknown as DefineComponent<{}>\n} else {\n  /* istanbul ignore next */\n  FragmentComponent = defineComponent({\n    name: 'Fragment',\n    render() {\n      return this.$slots.default?.()\n    },\n  })\n}\n\nexport { FragmentComponent }\n"
  },
  {
    "path": "packages/vue/src/shared/h.ts",
    "content": "import { h, isVue2 } from 'vue-demi'\nimport { Fragment, FragmentComponent } from './fragment'\nimport { formatVue3VNodeData } from '../utils/formatVNodeData'\n\ntype RenderChildren = {\n  [key in string]?: (...args: any[]) => (VNode | string)[]\n}\n\ntype Tag = any\ntype VNodeData = Record<string, any>\ntype VNode = any\ntype VNodeChildren = any\n\nconst compatibleCreateElement = (\n  tag: Tag,\n  data: VNodeData,\n  components: RenderChildren\n): any => {\n  /* istanbul ignore else */\n  if (isVue2) {\n    const hInVue2 = h as (\n      tag: Tag,\n      data?: VNodeData,\n      components?: VNodeChildren\n    ) => VNode\n    const scopedSlots = components // 默认全部作为 scopedSlots 处理\n    const children = []\n\n    /**\n     * scopedSlots 不会映射为slots，所以这里手动映射一遍\n     * 主要为了解决 slots.x 问题\n     */\n    Object.keys(components).forEach((key) => {\n      const func = components[key]\n\n      // 转换为 slots 传递\n      if (typeof func === 'function' && func.length === 0) {\n        /**\n         * func 参数为0的判断不准确，因为composition-api包了一层，导致全部为0\n         * try catch 解决scoped slots 转换参数异常问题\n         * */\n        try {\n          const child = func()\n          children.push(\n            key === 'default'\n              ? child\n              : hInVue2(FragmentComponent, { slot: key }, [child])\n          )\n        } catch (error) {}\n      }\n    })\n    const newData = Object.assign({}, data)\n    if (Object.keys(scopedSlots).length > 0) {\n      if (!newData.scopedSlots) {\n        newData.scopedSlots = scopedSlots\n      } else {\n        newData.scopedSlots = {\n          ...newData.scopedSlots,\n          ...scopedSlots,\n        }\n      }\n    }\n    if (tag === Fragment) {\n      // sometimes we needn't to use Fragment component.\n      if (children.length === 1) {\n        if (!Array.isArray(children[0])) {\n          return children[0]\n        } else if (children[0].length === 1) {\n          if (!Array.isArray(children[0][0])) {\n            return children[0][0]\n          } else if (children[0][0].length === 1) {\n            return children[0][0][0]\n          }\n        }\n      }\n      tag = FragmentComponent\n    }\n    return hInVue2(tag, newData, children)\n  } else {\n    if (tag === Fragment) {\n      tag = FragmentComponent\n    }\n    const hInVue3 = h as (\n      tag: Tag,\n      data?: VNodeData,\n      components?: RenderChildren\n    ) => VNode\n    return hInVue3(tag, formatVue3VNodeData(data), components)\n  }\n}\n\nexport default compatibleCreateElement\n\nexport { compatibleCreateElement as h }\n"
  },
  {
    "path": "packages/vue/src/shared/index.ts",
    "content": "export * from './context'\nexport * from './connect'\nexport * from './h'\nexport * from './fragment'\nexport * from './createForm'\n"
  },
  {
    "path": "packages/vue/src/types/index.ts",
    "content": "import { Component } from 'vue'\nimport * as VueDemi from 'vue-demi'\nimport {\n  Form,\n  IFieldFactoryProps,\n  IVoidFieldFactoryProps,\n  GeneralField,\n  Field,\n  ObjectField,\n  FormPatternTypes,\n  FieldDisplayTypes,\n  FieldValidator,\n} from '@formily/core'\nimport type { FormPathPattern } from '@formily/shared'\nimport type { ISchema, Schema, SchemaKey } from '@formily/json-schema'\n\nclass Helper<Props> {\n  Return = VueDemi.defineComponent({} as { props: Record<keyof Props, any> })\n}\n\nexport type DefineComponent<Props> = Helper<Props>['Return']\n\nexport type VueComponent = Component\n\nexport type VueComponentOptionsWithProps = {\n  props: unknown\n}\n\nexport type VueComponentProps<T extends VueComponent> =\n  T extends VueComponentOptionsWithProps ? T['props'] : T\n\nexport interface IProviderProps {\n  form: Form\n}\n\nexport type IFieldProps<\n  D extends VueComponent = VueComponent,\n  C extends VueComponent = VueComponent\n> = IFieldFactoryProps<D, C>\n\nexport type IVoidFieldProps<\n  D extends VueComponent = VueComponent,\n  C extends VueComponent = VueComponent\n> = IVoidFieldFactoryProps<D, C>\n\nexport type IArrayFieldProps = IFieldProps\nexport type IObjectFieldProps = IFieldProps\n\nexport interface IReactiveFieldProps {\n  fieldType: 'Field' | 'ArrayField' | 'ObjectField' | 'VoidField'\n  fieldProps: IFieldProps | IVoidFieldProps\n}\n\nexport interface IComponentMapper<T extends VueComponent = any> {\n  (target: T): VueComponent\n}\n\nexport type IStateMapper<Props> =\n  | {\n      [key in keyof Field]?: keyof Props | boolean\n    }\n  | ((props: Props, field: GeneralField) => Props)\n\nexport type SchemaVueComponents = Record<string, VueComponent>\n\nexport interface ISchemaFieldVueFactoryOptions<\n  Components extends SchemaVueComponents = any\n> {\n  components?: Components\n  scope?: any\n}\n\nexport interface ISchemaFieldProps\n  extends Omit<IRecursionFieldProps, 'name' | 'schema'> {\n  schema?: ISchema\n  components?: {\n    [key: string]: VueComponent\n  }\n  scope?: any\n  name?: SchemaKey\n}\n\nexport interface ISchemaMapper {\n  (schema: Schema, name: SchemaKey): Schema\n}\n\nexport interface ISchemaFilter {\n  (schema: Schema, name: SchemaKey): boolean\n}\n\nexport interface IRecursionFieldProps {\n  schema: Schema\n  name?: SchemaKey\n  basePath?: FormPathPattern\n  onlyRenderProperties?: boolean\n  onlyRenderSelf?: boolean\n  mapProperties?: ISchemaMapper\n  filterProperties?: ISchemaFilter\n}\n\nexport type ObjectKey = string | number | boolean | symbol\n\nexport type KeyOfComponents<T> = keyof T\n\nexport type ComponentPath<\n  T,\n  Key extends KeyOfComponents<T> = KeyOfComponents<T>\n> = Key extends string ? Key : never\n\nexport type ComponentPropsByPathValue<\n  T extends SchemaVueComponents,\n  P extends ComponentPath<T>\n> = P extends keyof T ? VueComponentProps<T[P]> : never\n\nexport type ISchemaMarkupFieldProps<\n  Components extends SchemaVueComponents = SchemaVueComponents,\n  Decorator extends ComponentPath<Components> = ComponentPath<Components>,\n  Component extends ComponentPath<Components> = ComponentPath<Components>\n> = ISchema<\n  Decorator,\n  Component,\n  ComponentPropsByPathValue<Components, Decorator>,\n  ComponentPropsByPathValue<Components, Component>,\n  FormPatternTypes,\n  FieldDisplayTypes,\n  FieldValidator,\n  string,\n  GeneralField\n>\n\nexport type ISchemaTypeFieldProps<\n  Components extends SchemaVueComponents = SchemaVueComponents,\n  Decorator extends ComponentPath<Components> = ComponentPath<Components>,\n  Component extends ComponentPath<Components> = ComponentPath<Components>\n> = Omit<ISchemaMarkupFieldProps<Components, Decorator, Component>, 'type'>\n\nexport type IExpressionScopeProps = {\n  value: any\n}\n"
  },
  {
    "path": "packages/vue/src/utils/formatVNodeData.ts",
    "content": "import { each } from '@formily/shared'\n\ntype VNodeData = Record<string, any>\n\nexport const formatVue3VNodeData = (data: VNodeData) => {\n  const newData = {}\n  each(data, (value, key) => {\n    if (key === 'on' || key === 'nativeOn') {\n      if (value) {\n        each(value, (func, name) => {\n          const eventName = `on${\n            key === 'on' ? name[0].toUpperCase() : name[0]\n          }${name.slice(1)}`\n          newData[eventName] = func\n        })\n      }\n    } else if (key === 'attrs' || key === 'props' || key === 'domProps') {\n      Object.assign(newData, value)\n    } else {\n      newData[key] = value\n    }\n  })\n  return newData\n}\n"
  },
  {
    "path": "packages/vue/src/utils/getFieldProps.ts",
    "content": "export const getFieldProps = () => ({\n  name: {},\n  title: {},\n  description: {},\n  value: {},\n  initialValue: {},\n  basePath: {},\n  decorator: Array,\n  component: Array,\n  display: String,\n  pattern: String,\n  required: { type: Boolean, default: undefined },\n  validateFirst: { type: Boolean, default: undefined },\n  hidden: { type: Boolean, default: undefined },\n  visible: { type: Boolean, default: undefined },\n  editable: { type: Boolean, default: undefined },\n  disabled: { type: Boolean, default: undefined },\n  readOnly: { type: Boolean, default: undefined },\n  readPretty: { type: Boolean, default: undefined },\n  dataSource: {},\n  validator: {},\n  reactions: [Array, Function],\n})\n\nexport const getVoidFieldProps = () => ({\n  name: {},\n  title: {},\n  description: {},\n  basePath: {},\n  decorator: Array,\n  component: Array,\n  display: String,\n  pattern: String,\n  hidden: { type: Boolean, default: undefined },\n  visible: { type: Boolean, default: undefined },\n  editable: { type: Boolean, default: undefined },\n  disabled: { type: Boolean, default: undefined },\n  readOnly: { type: Boolean, default: undefined },\n  readPretty: { type: Boolean, default: undefined },\n  reactions: [Array, Function],\n})\n"
  },
  {
    "path": "packages/vue/src/utils/getRawComponent.ts",
    "content": "import { IFieldProps, VueComponent } from '../types'\nimport { toRaw } from 'vue-demi'\n\nexport const getRawComponent = (\n  props: IFieldProps<VueComponent, VueComponent>\n) => {\n  const { component, decorator } = props\n  let newComponent: typeof props.component\n  let newDecorator: typeof props.component\n  if (Array.isArray(component)) {\n    newComponent = [toRaw(component[0]), component[1]]\n  }\n  if (Array.isArray(decorator)) {\n    newDecorator = [toRaw(decorator[0]), decorator[1]]\n  }\n  return { component: newComponent, decorator: newDecorator }\n}\n"
  },
  {
    "path": "packages/vue/src/utils/resolveSchemaProps.ts",
    "content": "import { paramCase } from '@formily/shared'\n\nexport const resolveSchemaProps = (props: Record<string, any>) => {\n  const newProps = {}\n  Object.keys(props).forEach((key) => {\n    if (key.indexOf('x') === 0 && key.indexOf('x-') === -1) {\n      newProps[paramCase(key)] = props[key]\n    } else {\n      newProps[key] = props[key]\n    }\n  })\n  return newProps\n}\n"
  },
  {
    "path": "packages/vue/src/vue2-components.ts",
    "content": "// This file just converts types\nimport * as components from './components'\n\nimport type Vue from 'vue'\nimport type { VueConstructor } from 'vue'\nimport type {\n  IVoidFieldProps,\n  IArrayFieldProps,\n  IObjectFieldProps,\n  IFieldProps,\n  IRecursionFieldProps,\n  IProviderProps,\n  ISchemaMarkupFieldProps,\n  ISchemaFieldProps,\n  ISchemaFieldVueFactoryOptions,\n  ISchemaTypeFieldProps,\n  SchemaVueComponents,\n} from './types'\n\nconst {\n  Field: _Field,\n  ArrayField: _ArrayField,\n  FormConsumer: _FormConsumer,\n  FormProvider: _FormProvider,\n  ObjectField: _ObjectField,\n  RecursionField: _RecursionField,\n  VoidField: _VoidField,\n  createSchemaField: _createSchemaField,\n} = components\n\ntype DefineComponent<Props> = Vue & VueConstructor & Props\n\ntype SchemaFieldComponents = {\n  SchemaField: DefineComponent<Omit<ISchemaFieldProps, 'name' | 'components'>>\n  SchemaMarkupField: DefineComponent<ISchemaMarkupFieldProps>\n  SchemaStringField: DefineComponent<ISchemaTypeFieldProps>\n  SchemaObjectField: DefineComponent<ISchemaTypeFieldProps>\n  SchemaArrayField: DefineComponent<ISchemaTypeFieldProps>\n  SchemaBooleanField: DefineComponent<ISchemaTypeFieldProps>\n  SchemaDateField: DefineComponent<ISchemaTypeFieldProps>\n  SchemaDateTimeField: DefineComponent<ISchemaTypeFieldProps>\n  SchemaVoidField: DefineComponent<ISchemaTypeFieldProps>\n  SchemaNumberField: DefineComponent<ISchemaTypeFieldProps>\n}\n\ntype CreateSchemaField<\n  Components extends SchemaVueComponents = SchemaVueComponents\n> = (\n  options: ISchemaFieldVueFactoryOptions<Components>\n) => SchemaFieldComponents\n\nconst Field = _Field as unknown as DefineComponent<Omit<IFieldProps, 'name'>>\nconst ArrayField = _ArrayField as unknown as DefineComponent<\n  Omit<IArrayFieldProps, 'name'>\n>\nconst ObjectField = _ObjectField as unknown as DefineComponent<\n  Omit<IObjectFieldProps, 'name'>\n>\nconst VoidField = _VoidField as unknown as DefineComponent<\n  Omit<IVoidFieldProps, 'name'>\n>\nconst RecursionField = _RecursionField as unknown as DefineComponent<\n  Omit<IRecursionFieldProps, 'name'>\n>\nconst FormConsumer = _FormConsumer as unknown as DefineComponent<{}>\nconst FormProvider = _FormProvider as unknown as DefineComponent<IProviderProps>\nconst createSchemaField = _createSchemaField as unknown as CreateSchemaField\n\nexport {\n  Field,\n  ArrayField,\n  ObjectField,\n  VoidField,\n  RecursionField,\n  FormConsumer,\n  FormProvider,\n  createSchemaField,\n}\n"
  },
  {
    "path": "packages/vue/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*\", \"devtools/*\"]\n    },\n    \"declaration\": false\n  }\n}\n"
  },
  {
    "path": "packages/vue/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"compilerOptions\": {\n    \"skipLibCheck\": true\n  },\n  \"include\": [\"./src/**/*.ts\", \"./src/**/*.tsx\"],\n  \"exclude\": [\"./src/__tests__/*\", \"./esm/*\", \"./lib/*\"]\n}\n"
  },
  {
    "path": "packages/vue/tsconfig.types.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./type-artefacts\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*\", \"devtools/*\"]\n    },\n    \"declaration\": true,\n    \"sourceMap\": false,\n    \"inlineSources\": false\n  }\n}\n"
  },
  {
    "path": "scripts/build-style/buildAllStyles.ts",
    "content": "import typescript from 'rollup-plugin-typescript2'\nimport { build, getRollupBasePlugin } from './helper'\n\n// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\nexport const buildAllStyles = async (outputFile: string) => {\n  await build({\n    input: 'src/style.ts',\n    output: {\n      file: outputFile,\n    },\n    plugins: [\n      typescript({\n        tsconfig: './tsconfig.json',\n        tsconfigOverride: {\n          compilerOptions: {\n            module: 'ESNext',\n            declaration: false,\n          },\n        },\n      }),\n      ...getRollupBasePlugin(),\n    ],\n  })\n}\n"
  },
  {
    "path": "scripts/build-style/copy.ts",
    "content": "/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\nimport { copy, readFile, writeFile, existsSync } from 'fs-extra'\nimport glob from 'glob'\n\nexport type CopyBaseOptions = Record<'esStr' | 'libStr', string>\n\nconst importLibToEs = async ({\n  libStr,\n  esStr,\n  filename,\n}: CopyBaseOptions & { filename: string }) => {\n  if (!existsSync(filename)) {\n    return Promise.resolve()\n  }\n\n  const fileContent: string = (await readFile(filename)).toString()\n\n  return writeFile(\n    filename,\n    fileContent.replace(new RegExp(libStr, 'g'), esStr)\n  )\n}\n\nexport const runCopy = ({\n  resolveForItem,\n  ...lastOpts\n}: CopyBaseOptions & { resolveForItem?: (filename: string) => unknown }) => {\n  return new Promise((resolve, reject) => {\n    glob(`./src/**/*`, (err, files) => {\n      if (err) {\n        return reject(err)\n      }\n\n      const all = [] as Promise<unknown>[]\n\n      for (let i = 0; i < files.length; i += 1) {\n        const filename = files[i]\n\n        resolveForItem?.(filename)\n\n        if (/\\.(less|scss)$/.test(filename)) {\n          all.push(copy(filename, filename.replace(/src\\//, 'esm/')))\n          all.push(copy(filename, filename.replace(/src\\//, 'lib/')))\n\n          continue\n        }\n\n        if (/\\/style.ts$/.test(filename)) {\n          importLibToEs({\n            ...lastOpts,\n            filename: filename.replace(/src\\//, 'esm/').replace(/\\.ts$/, '.js'),\n          })\n\n          continue\n        }\n      }\n    })\n  })\n}\n"
  },
  {
    "path": "scripts/build-style/helper.ts",
    "content": "/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\nimport { OutputOptions, rollup, RollupOptions } from 'rollup'\nimport postcss from 'rollup-plugin-postcss'\nimport NpmImport from 'less-plugin-npm-import'\nimport resolve from 'rollup-plugin-node-resolve'\n\nexport const getRollupBasePlugin = () => [\n  resolve(),\n  postcss({\n    extract: true,\n    minimize: true,\n    sourceMap: true,\n    // extensions: ['.css', '.less', '.sass'],\n    use: {\n      less: {\n        plugins: [new NpmImport({ prefix: '~' })],\n        javascriptEnabled: true,\n      },\n      sass: {},\n      stylus: {},\n    },\n  }),\n]\n\nexport const build = async (\n  rollupConfig: Omit<RollupOptions, 'output'> & { output: OutputOptions }\n) => {\n  const { output, ...input } = rollupConfig\n  const bundle = await rollup(input)\n\n  return bundle.write(output as OutputOptions)\n}\n"
  },
  {
    "path": "scripts/build-style/index.ts",
    "content": "import { runCopy, CopyBaseOptions } from './copy'\nimport { buildAllStyles } from './buildAllStyles'\n\n// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\nexport function build({\n  allStylesOutputFile,\n  ...opts\n}: CopyBaseOptions & { allStylesOutputFile: string }) {\n  return Promise.all([buildAllStyles(allStylesOutputFile), runCopy(opts)])\n}\n\nexport { runCopy }\n"
  },
  {
    "path": "scripts/rollup.base.js",
    "content": "import path from 'path'\nimport typescript from 'rollup-plugin-typescript2'\nimport resolve from 'rollup-plugin-node-resolve'\nimport commonjs from '@rollup/plugin-commonjs'\nimport externalGlobals from 'rollup-plugin-external-globals'\nimport injectProcessEnv from 'rollup-plugin-inject-process-env'\nimport dts from 'rollup-plugin-dts'\nimport { terser } from 'rollup-plugin-terser'\n\nconst presets = () => {\n  const externals = {\n    antd: 'antd',\n    vue: 'Vue',\n    react: 'React',\n    moment: 'moment',\n    'react-is': 'ReactIs',\n    '@alifd/next': 'Next',\n    'mobx-react-lite': 'mobxReactLite',\n    'react-dom': 'ReactDOM',\n    'element-ui': 'Element',\n    '@ant-design/icons': 'icons',\n    '@vue/composition-api': 'VueCompositionAPI',\n    '@formily/reactive-react': 'Formily.ReactiveReact',\n    '@formily/reactive-vue': 'Formily.ReactiveVue',\n    '@formily/reactive': 'Formily.Reactive',\n    '@formily/path': 'Formily.Path',\n    '@formily/shared': 'Formily.Shared',\n    '@formily/validator': 'Formily.Validator',\n    '@formily/core': 'Formily.Core',\n    '@formily/json-schema': 'Formily.JSONSchema',\n    '@formily/react': 'Formily.React',\n    '@formily/vue': 'Formily.Vue',\n    'vue-demi': 'VueDemi'\n  }\n  return [\n    typescript({\n      tsconfig: './tsconfig.build.json',\n      tsconfigOverride: {\n        compilerOptions: {\n          module: 'ESNext',\n          declaration: false,\n        },\n      },\n    }),\n    resolve(),\n    commonjs(),\n    externalGlobals(externals, {\n      exclude: ['**/*.{less,sass,scss}'],\n    }),\n  ]\n}\n\nconst createEnvPlugin = (env) => {\n  return injectProcessEnv(\n    {\n      NODE_ENV: env,\n    },\n    {\n      exclude: '**/*.{css,less,sass,scss}',\n      verbose: false,\n    }\n  )\n}\n\nconst inputFilePath = path.join(process.cwd(), 'src/index.ts')\n\nconst noUIDtsPackages = [\n  'formily.core',\n  'formily.validator',\n  'formily.shared',\n  'formily.path',\n  'formily.json-schema',\n  'formily.reactive',\n]\n\nexport const removeImportStyleFromInputFilePlugin = () => ({\n  name: 'remove-import-style-from-input-file',\n  transform(code, id) {\n    // 样式由 build:style 进行打包，所以要删除入口文件上的 `import './style'`\n    if (inputFilePath === id) {\n      return code.replace(`import './style';`, '')\n    }\n\n    return code\n  },\n})\n\nexport default (filename, targetName, ...plugins) => {\n  const base = [\n    {\n      input: 'src/index.ts',\n      output: {\n        format: 'umd',\n        file: `dist/${filename}.umd.development.js`,\n        name: targetName,\n        sourcemap: true,\n        amd: {\n          id: filename,\n        },\n        globals: {\n          '@formily/json-schema': 'Formily.JSONSchema',\n        },\n      },\n      external: ['react', 'react-dom', 'react-is', '@formily/json-schema'],\n      plugins: [...presets(), ...plugins, createEnvPlugin('development')],\n    },\n    {\n      input: 'src/index.ts',\n      output: {\n        format: 'umd',\n        file: `dist/${filename}.umd.production.js`,\n        name: targetName,\n        sourcemap: true,\n        amd: {\n          id: filename,\n        },\n        globals: {\n          '@formily/json-schema': 'Formily.JSONSchema',\n        },\n      },\n      external: ['react', 'react-dom', 'react-is', '@formily/json-schema'],\n      plugins: [\n        ...presets(),\n        terser(),\n        ...plugins,\n        createEnvPlugin('production'),\n      ],\n    },\n  ]\n\n  if (noUIDtsPackages.includes(filename)) {\n    base.push({\n      input: 'esm/index.d.ts',\n      output: {\n        format: 'es',\n        file: `dist/${filename}.d.ts`,\n      },\n      plugins: [dts(), ...plugins],\n    })\n    base.push({\n      input: 'esm/index.d.ts',\n      output: {\n        format: 'es',\n        file: `dist/${filename}.all.d.ts`,\n      },\n      plugins: [\n        dts({\n          respectExternal: true,\n        }),\n        ...plugins,\n      ],\n    })\n  }\n\n  return base\n}\n"
  },
  {
    "path": "tsconfig.build.json",
    "content": "{\n  \"compilerOptions\": {\n    \"esModuleInterop\": true,\n    \"moduleResolution\": \"node\",\n    \"allowJs\": true,\n    \"module\": \"commonjs\",\n    \"target\": \"es5\",\n  }\n}"
  },
  {
    "path": "tsconfig.jest.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"jsx\": \"react\",\n    \"esModuleInterop\": true,\n    \"moduleResolution\": \"node\",\n    \"allowJs\": true,\n    \"module\": \"commonjs\",\n    \"target\": \"es5\",\n    \"paths\": {\n      \"@formily/*\": [\"./packages/*/src\"]\n    }\n  },\n  \"exclude\": [\"./packages/*/esm\", \"./packages/*/lib\"]\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"esModuleInterop\": true,\n    \"moduleResolution\": \"node\",\n    \"jsx\": \"react\",\n    \"module\": \"commonjs\",\n    \"target\": \"es5\",\n    \"allowJs\": false,\n    \"noUnusedLocals\": false,\n    \"preserveConstEnums\": true,\n    \"skipLibCheck\": true,\n    \"sourceMap\": true,\n    \"inlineSources\": true,\n    \"declaration\": true,\n    \"experimentalDecorators\": true,\n    \"downlevelIteration\": true,\n    \"baseUrl\": \".\",\n    \"paths\": {\n      \"@formily/*\": [\"packages/*/src\", \"devtools/*/src\"]\n    },\n    \"lib\": [\"ESNext\"]\n  }\n}\n"
  }
]