@kne-components/components-core 0.4.59 → 0.4.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/build/asset-manifest.json +84 -84
  2. package/build/index.html +1 -1
  3. package/build/remoteEntry.js +1 -1
  4. package/build/remoteEntry.js.map +1 -1
  5. package/build/static/css/1461.56c7ba82.chunk.css +2 -0
  6. package/build/static/css/{1461.e03665dd.chunk.css.map → 1461.56c7ba82.chunk.css.map} +1 -1
  7. package/build/static/css/{1624.f27a3400.chunk.css → 1624.f07f4ae9.chunk.css} +2 -2
  8. package/build/static/css/{1624.f27a3400.chunk.css.map → 1624.f07f4ae9.chunk.css.map} +1 -1
  9. package/build/static/css/{1769.57d65587.chunk.css → 1769.a0e6f277.chunk.css} +2 -2
  10. package/build/static/css/{1769.57d65587.chunk.css.map → 1769.a0e6f277.chunk.css.map} +1 -1
  11. package/build/static/css/2004.7a5c6d58.chunk.css +2 -0
  12. package/build/static/css/{2004.7bd302b2.chunk.css.map → 2004.7a5c6d58.chunk.css.map} +1 -1
  13. package/build/static/css/{2837.8e933f1e.chunk.css → 2837.b48048df.chunk.css} +2 -2
  14. package/build/static/css/{2837.8e933f1e.chunk.css.map → 2837.b48048df.chunk.css.map} +1 -1
  15. package/build/static/css/2943.5bde51f5.chunk.css +2 -0
  16. package/build/static/css/{2943.f8f1cde5.chunk.css.map → 2943.5bde51f5.chunk.css.map} +1 -1
  17. package/build/static/css/{3043.ca2262a4.chunk.css → 3043.de0e34c0.chunk.css} +2 -2
  18. package/build/static/css/{3043.ca2262a4.chunk.css.map → 3043.de0e34c0.chunk.css.map} +1 -1
  19. package/build/static/css/3404.f1c244d7.chunk.css +2 -0
  20. package/build/static/css/{3404.1600d8e0.chunk.css.map → 3404.f1c244d7.chunk.css.map} +1 -1
  21. package/build/static/css/{3467.63b13981.chunk.css → 3467.0f767a84.chunk.css} +2 -2
  22. package/build/static/css/{3467.63b13981.chunk.css.map → 3467.0f767a84.chunk.css.map} +1 -1
  23. package/build/static/css/{3771.6758a427.chunk.css → 3771.4fe764d3.chunk.css} +2 -2
  24. package/build/static/css/{3771.6758a427.chunk.css.map → 3771.4fe764d3.chunk.css.map} +1 -1
  25. package/build/static/css/4551.48804867.chunk.css +2 -0
  26. package/build/static/css/{4551.3296842c.chunk.css.map → 4551.48804867.chunk.css.map} +1 -1
  27. package/build/static/css/5462.5c532604.chunk.css +2 -0
  28. package/build/static/css/{5462.d209fbe9.chunk.css.map → 5462.5c532604.chunk.css.map} +1 -1
  29. package/build/static/css/{5506.e8ccaa89.chunk.css → 5506.6e440bad.chunk.css} +2 -2
  30. package/build/static/css/{5506.e8ccaa89.chunk.css.map → 5506.6e440bad.chunk.css.map} +1 -1
  31. package/build/static/css/6499.f1f833f9.chunk.css +2 -0
  32. package/build/static/css/{6499.aae5e258.chunk.css.map → 6499.f1f833f9.chunk.css.map} +1 -1
  33. package/build/static/css/7227.47933f05.chunk.css +2 -0
  34. package/build/static/css/{7227.fc8d0c28.chunk.css.map → 7227.47933f05.chunk.css.map} +1 -1
  35. package/build/static/css/7857.93635aee.chunk.css +2 -0
  36. package/build/static/css/{7857.5c99f79b.chunk.css.map → 7857.93635aee.chunk.css.map} +1 -1
  37. package/build/static/css/9556.b3d01a10.chunk.css +2 -0
  38. package/build/static/css/{9556.19ec43f7.chunk.css.map → 9556.b3d01a10.chunk.css.map} +1 -1
  39. package/build/static/css/9666.0c21fbba.chunk.css +2 -0
  40. package/build/static/css/{9666.2ad14c5f.chunk.css.map → 9666.0c21fbba.chunk.css.map} +1 -1
  41. package/build/static/css/9755.ded79788.chunk.css +2 -0
  42. package/build/static/css/{9755.eb57e17c.chunk.css.map → 9755.ded79788.chunk.css.map} +1 -1
  43. package/build/static/js/1461.866b1f45.chunk.js +2 -0
  44. package/build/static/js/{1461.c4071f0c.chunk.js.map → 1461.866b1f45.chunk.js.map} +1 -1
  45. package/build/static/js/1624.58cb67d0.chunk.js +2 -0
  46. package/build/static/js/{1624.1882567b.chunk.js.map → 1624.58cb67d0.chunk.js.map} +1 -1
  47. package/build/static/js/{1769.f85e2046.chunk.js → 1769.553d8f84.chunk.js} +2 -2
  48. package/build/static/js/{1769.f85e2046.chunk.js.map → 1769.553d8f84.chunk.js.map} +1 -1
  49. package/build/static/js/{2004.b3863616.chunk.js → 2004.224d5924.chunk.js} +3 -3
  50. package/build/static/js/{2004.b3863616.chunk.js.map → 2004.224d5924.chunk.js.map} +1 -1
  51. package/build/static/js/{2837.04bc9c19.chunk.js → 2837.4e2ea690.chunk.js} +2 -2
  52. package/build/static/js/{2837.04bc9c19.chunk.js.map → 2837.4e2ea690.chunk.js.map} +1 -1
  53. package/build/static/js/2943.641b0e6e.chunk.js +2 -0
  54. package/build/static/js/2943.641b0e6e.chunk.js.map +1 -0
  55. package/build/static/js/3043.ef9a25fc.chunk.js +2 -0
  56. package/build/static/js/{3043.dc272bd8.chunk.js.map → 3043.ef9a25fc.chunk.js.map} +1 -1
  57. package/build/static/js/{3404.08af0011.chunk.js → 3404.0829b4e4.chunk.js} +3 -3
  58. package/build/static/js/{3404.08af0011.chunk.js.map → 3404.0829b4e4.chunk.js.map} +1 -1
  59. package/build/static/js/{3467.0250db76.chunk.js → 3467.7b34461a.chunk.js} +2 -2
  60. package/build/static/js/{3467.0250db76.chunk.js.map → 3467.7b34461a.chunk.js.map} +1 -1
  61. package/build/static/js/3771.44c78e92.chunk.js +2 -0
  62. package/build/static/js/{3771.9aae1e84.chunk.js.map → 3771.44c78e92.chunk.js.map} +1 -1
  63. package/build/static/js/3856.7797c2d3.chunk.js +2 -0
  64. package/build/static/js/{3856.96518e39.chunk.js.map → 3856.7797c2d3.chunk.js.map} +1 -1
  65. package/build/static/js/4474.543ad85e.chunk.js +2 -0
  66. package/build/static/js/{4474.8cb64e21.chunk.js.map → 4474.543ad85e.chunk.js.map} +1 -1
  67. package/build/static/js/4551.401ea5cc.chunk.js +2 -0
  68. package/build/static/js/{4551.d7b70f2a.chunk.js.map → 4551.401ea5cc.chunk.js.map} +1 -1
  69. package/build/static/js/{5462.82092ca8.chunk.js → 5462.62aec0cc.chunk.js} +2 -2
  70. package/build/static/js/{5462.82092ca8.chunk.js.map → 5462.62aec0cc.chunk.js.map} +1 -1
  71. package/build/static/js/5506.c294f8f5.chunk.js +2 -0
  72. package/build/static/js/{5506.e21819f8.chunk.js.map → 5506.c294f8f5.chunk.js.map} +1 -1
  73. package/build/static/js/{7227.65a94d74.chunk.js → 7227.6ad50956.chunk.js} +3 -3
  74. package/build/static/js/{7227.65a94d74.chunk.js.map → 7227.6ad50956.chunk.js.map} +1 -1
  75. package/build/static/js/7394.ad3cac60.chunk.js +2 -0
  76. package/build/static/js/7394.ad3cac60.chunk.js.map +1 -0
  77. package/build/static/js/{7857.ceaa17ca.chunk.js → 7857.84c2a11b.chunk.js} +2 -2
  78. package/build/static/js/{7857.ceaa17ca.chunk.js.map → 7857.84c2a11b.chunk.js.map} +1 -1
  79. package/build/static/js/9556.eeb7c165.chunk.js +3 -0
  80. package/build/static/js/{9556.067ea852.chunk.js.map → 9556.eeb7c165.chunk.js.map} +1 -1
  81. package/build/static/js/{9666.b926633e.chunk.js → 9666.a00a8493.chunk.js} +2 -2
  82. package/build/static/js/{9666.b926633e.chunk.js.map → 9666.a00a8493.chunk.js.map} +1 -1
  83. package/build/static/js/{9755.e7a024e2.chunk.js → 9755.dbfce192.chunk.js} +2 -2
  84. package/build/static/js/{9755.e7a024e2.chunk.js.map → 9755.dbfce192.chunk.js.map} +1 -1
  85. package/build/static/js/{main.da7df6a0.js → main.3836f95d.js} +2 -2
  86. package/build/static/js/{main.da7df6a0.js.map → main.3836f95d.js.map} +1 -1
  87. package/package.json +1 -1
  88. package/build/static/css/1461.e03665dd.chunk.css +0 -2
  89. package/build/static/css/2004.7bd302b2.chunk.css +0 -2
  90. package/build/static/css/2943.f8f1cde5.chunk.css +0 -2
  91. package/build/static/css/3404.1600d8e0.chunk.css +0 -2
  92. package/build/static/css/4551.3296842c.chunk.css +0 -2
  93. package/build/static/css/5462.d209fbe9.chunk.css +0 -2
  94. package/build/static/css/6499.aae5e258.chunk.css +0 -2
  95. package/build/static/css/7227.fc8d0c28.chunk.css +0 -2
  96. package/build/static/css/7857.5c99f79b.chunk.css +0 -2
  97. package/build/static/css/9556.19ec43f7.chunk.css +0 -2
  98. package/build/static/css/9666.2ad14c5f.chunk.css +0 -2
  99. package/build/static/css/9755.eb57e17c.chunk.css +0 -2
  100. package/build/static/js/1461.c4071f0c.chunk.js +0 -2
  101. package/build/static/js/1624.1882567b.chunk.js +0 -2
  102. package/build/static/js/2943.3898d509.chunk.js +0 -2
  103. package/build/static/js/2943.3898d509.chunk.js.map +0 -1
  104. package/build/static/js/3043.dc272bd8.chunk.js +0 -2
  105. package/build/static/js/3771.9aae1e84.chunk.js +0 -2
  106. package/build/static/js/3856.96518e39.chunk.js +0 -2
  107. package/build/static/js/4474.8cb64e21.chunk.js +0 -2
  108. package/build/static/js/4551.d7b70f2a.chunk.js +0 -2
  109. package/build/static/js/5506.e21819f8.chunk.js +0 -2
  110. package/build/static/js/7394.d52d668e.chunk.js +0 -2
  111. package/build/static/js/7394.d52d668e.chunk.js.map +0 -1
  112. package/build/static/js/9556.067ea852.chunk.js +0 -3
  113. /package/build/static/js/{2004.b3863616.chunk.js.LICENSE.txt → 2004.224d5924.chunk.js.LICENSE.txt} +0 -0
  114. /package/build/static/js/{3404.08af0011.chunk.js.LICENSE.txt → 3404.0829b4e4.chunk.js.LICENSE.txt} +0 -0
  115. /package/build/static/js/{7227.65a94d74.chunk.js.LICENSE.txt → 7227.6ad50956.chunk.js.LICENSE.txt} +0 -0
  116. /package/build/static/js/{9556.067ea852.chunk.js.LICENSE.txt → 9556.eeb7c165.chunk.js.LICENSE.txt} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"static/js/7394.d52d668e.chunk.js","mappings":"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","sources":["components/ButtonGroup/README.md","components/Common/README.md","components/Drawer/README.md","components/Enum/README.md","components/Features/README.md","components/File/README.md","components/FileList/README.md","components/FilePreview/README.md","components/Filter/README.md","components/FlexBox/README.md","components/FormInfo/README.md","components/Global/README.md","components/HelperGuide/README.md","components/HistoryStore/README.md","components/Icon/README.md","components/Image/README.md","components/InfoPage/README.md","components/Intl/doc/locale/en-US.js","components/Intl/doc/locale/zh-CN.js","components/Intl/README.md","components/Layout/README.md","components/Menu/README.md","components/Modal/README.md","components/Navigation/README.md","components/Permissions/README.md","components/StateBar/README.md","components/StateTag/README.md","components/Table/README.md","components/Tooltip/README.md","webpack://@kne-components/components-core/./src/components/HistoryStore/style.module.scss?1856","components/HistoryStore/index.js"],"sourcesContent":["import * as component_1 from '@kne/button-group';\nimport * as component_2 from 'antd';\nimport '@kne/button-group/dist/index.css';\nimport '@kne/button-group/dist/index.css';\nconst readmeConfig = {\n name: `button-group`,\n summary: `<p>@kne/button-group 是一个 React 按钮组件库,提供了一系列功能丰富的按钮组件,用于简化常见的按钮交互场景。该库专注于提供自适应布局、加载状态管理、确认操作和数据请求等功能,使开发者能够快速实现各种复杂的按钮交互需求。</p>\n<h3>ButtonGroup</h3>\n<p>自适应按钮组组件,能够根据容器宽度自动调整显示的按钮数量。当容器宽度不足以显示所有按钮时,会自动将多余的按钮放入下拉菜单中,确保界面布局美观且功能完整。</p>\n<p><strong>主要特性:</strong></p>\n<ul>\n<li>自动适应容器宽度</li>\n<li>支持紧凑模式(Space.Compact)</li>\n<li>支持链接样式(适用于表格操作列)</li>\n<li>可指定显示的按钮数量</li>\n<li>支持禁用、隐藏状态</li>\n<li>支持自定义按钮渲染</li>\n<li>支持禁用按钮的工具提示</li>\n</ul>\n<p><strong>适用场景:</strong></p>\n<ul>\n<li>操作栏、工具栏</li>\n<li>表格操作列</li>\n<li>面板标题栏</li>\n<li>任何需要自适应按钮布局的场景</li>\n</ul>\n<h3>LoadingButton</h3>\n<p>封装了加载状态的按钮组件,简化了异步操作的处理。通过内置的状态管理,在异步操作执行期间自动显示加载状态,提升用户体验。同时提供了 useLoading hook,方便在其他组件中复用加载状态管理逻辑。</p>\n<p><strong>主要特性:</strong></p>\n<ul>\n<li>自动管理加载状态</li>\n<li>支持自定义加载文案</li>\n<li>自动处理错误情况</li>\n<li>支持 loading 属性手动控制</li>\n<li>提供的 useLoading Hook 可在其他组件使用</li>\n</ul>\n<p><strong>适用场景:</strong></p>\n<ul>\n<li>表单提交按钮</li>\n<li>数据导出按钮</li>\n<li>任何需要异步操作的按钮</li>\n<li>非按钮组件的异步状态管理</li>\n</ul>\n<h3>ConfirmButton</h3>\n<p>带有确认功能的按钮组件,支持弹窗确认(Popconfirm)和模态框确认(Modal)两种模式。适用于需要用户二次确认的操作,如删除、提交等重要操作。同时提供了 ConfirmLink 和 ConfirmText 变体,以及 withConfirm 高阶组件,满足不同场景的确认需求。</p>\n<p><strong>主要特性:</strong></p>\n<ul>\n<li>支持 Popconfirm 和 Modal 两种确认模式</li>\n<li>支持危险操作样式(红色按钮)</li>\n<li>可自定义确认和取消按钮文案</li>\n<li>提供 ConfirmLink 和 ConfirmText 变体</li>\n<li>确认时自动显示加载状态</li>\n</ul>\n<p><strong>适用场景:</strong></p>\n<ul>\n<li>删除操作</li>\n<li>数据提交</li>\n<li>审核操作</li>\n<li>表格行操作(使用 ConfirmLink/ConfirmText)</li>\n<li>任何需要用户二次确认的操作</li>\n</ul>\n<h3>FetchButton</h3>\n<p>集成了数据请求功能的按钮组件,基于 @kne/react-fetch 库实现。可以直接处理 API 请求,并在请求过程中自动管理加载状态,简化了数据交互的实现。</p>\n<p><strong>主要特性:</strong></p>\n<ul>\n<li>自动管理请求加载状态</li>\n<li>支持请求成功/失败回调</li>\n<li>支持参数传递</li>\n<li>支持请求拦截(beforeFetch)</li>\n<li>基于 @kne/react-fetch 实现</li>\n</ul>\n<p><strong>适用场景:</strong></p>\n<ul>\n<li>数据刷新按钮</li>\n<li>文件导出按钮</li>\n<li>API 请求按钮</li>\n<li>任何按钮触发的数据请求场景</li>\n</ul>\n<h3>ButtonFooter</h3>\n<p>页面底部按钮区域组件,可以自动计算高度并设置 CSS 变量,方便页面布局和样式调整。在小屏幕下,会自动将内容渲染到 body,确保按钮始终可见。</p>\n<p><strong>主要特性:</strong></p>\n<ul>\n<li>自动计算高度并设置 CSS 变量</li>\n<li>响应式设计,小屏幕下固定到底部</li>\n<li>支持多种布局方式(居中、左右分布等)</li>\n<li>适用于表单页面的底部操作区</li>\n</ul>\n<p><strong>适用场景:</strong></p>\n<ul>\n<li>表单页面底部操作按钮</li>\n<li>详情页面底部操作按钮</li>\n<li>对话框底部按钮</li>\n<li>任何需要固定在底部的操作按钮区域</li>\n</ul>\n<h2>组件关系</h2>\n<pre><code>ButtonGroup (自适应布局)\n ├── LoadingButton (加载状态)\n ├── ConfirmButton (确认功能)\n │ ├── ConfirmLink (链接变体)\n │ └── ConfirmText (文本变体)\n └── FetchButton (数据请求)\n └── 基于 LoadingButton\n\nButtonFooter (底部固定区域)\n</code></pre>\n<h2>设计理念</h2>\n<p>该组件库的设计理念是通过封装常见的按钮交互模式,提供开箱即用的解决方案,同时保持足够的灵活性和可扩展性:</p>\n<ol>\n<li>\n<p><strong>关注点分离</strong>:每个组件专注于解决特定的问题,如 ButtonGroup 专注于布局,LoadingButton 专注于状态管理。</p>\n</li>\n<li>\n<p><strong>组合优于继承</strong>:通过组合不同的功能组件,可以实现复杂的交互需求,如 FetchButton 就是 LoadingButton 与数据请求功能的组合。</p>\n</li>\n<li>\n<p><strong>声明式 API</strong>:提供简洁明了的 API,使开发者能够以声明式的方式描述 UI 和交互行为。</p>\n</li>\n<li>\n<p><strong>渐进式增强</strong>:基础组件可以独立使用,也可以与其他组件组合使用,实现更复杂的功能。</p>\n</li>\n<li>\n<p><strong>用户体验优先</strong>:注重细节,如自适应布局、加载状态反馈等,提升最终用户的使用体验。</p>\n</li>\n</ol>\n<h2>特性总结</h2>\n<ul>\n<li><strong>自适应布局</strong>:根据容器宽度自动调整按钮显示方式</li>\n<li><strong>加载状态管理</strong>:简化异步操作的加载状态处理</li>\n<li><strong>操作确认</strong>:提供多种确认模式,增强用户操作安全性</li>\n<li><strong>数据请求集成</strong>:简化按钮与后端 API 的交互</li>\n<li><strong>国际化支持</strong>:内置中英文语言包</li>\n<li><strong>高度可定制</strong>:组件提供丰富的配置选项</li>\n<li><strong>响应式设计</strong>:适配不同屏幕尺寸</li>\n<li><strong>TypeScript 友好</strong>:完整的类型定义</li>\n</ul>`,\n \n \n api: `<p>自适应按钮组组件,能够根据容器宽度自动调整显示的按钮数量,并将多余的按钮放入下拉菜单中。</p>\n<h3>属性</h3>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>list</td>\n<td>Array&lt;object | function&gt;</td>\n<td>[]</td>\n<td>按钮列表,可以是配置对象或渲染函数</td>\n</tr>\n<tr>\n<td>compact</td>\n<td>boolean</td>\n<td>false</td>\n<td>是否使用紧凑模式(Space.Compact)</td>\n</tr>\n<tr>\n<td>showLength</td>\n<td>number</td>\n<td>-</td>\n<td>指定显示的按钮数量,不指定则自动计算</td>\n</tr>\n<tr>\n<td>more</td>\n<td>ReactNode</td>\n<td>-</td>\n<td>自定义\"更多\"按钮</td>\n</tr>\n<tr>\n<td>moreType</td>\n<td>'default' | 'link'</td>\n<td>'default'</td>\n<td>更多按钮类型</td>\n</tr>\n<tr>\n<td>getPopupContainer</td>\n<td>function</td>\n<td>-</td>\n<td>下拉菜单渲染父节点</td>\n</tr>\n<tr>\n<td>trigger</td>\n<td>string</td>\n<td>-</td>\n<td>下拉菜单触发方式</td>\n</tr>\n<tr>\n<td>itemClassName</td>\n<td>string</td>\n<td>-</td>\n<td>按钮项的自定义类名</td>\n</tr>\n<tr>\n<td>...SpaceProps</td>\n<td>-</td>\n<td>-</td>\n<td>Space 组件的其他属性(size、split、align、style等)</td>\n</tr>\n</tbody>\n</table>\n<h3>list 配置项</h3>\n<p>当 list 项为对象时,支持以下属性:</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>children</td>\n<td>ReactNode</td>\n<td>-</td>\n<td>按钮内容</td>\n</tr>\n<tr>\n<td>type</td>\n<td>string</td>\n<td>-</td>\n<td>按钮类型(primary、default、dashed、link、text)</td>\n</tr>\n<tr>\n<td>disabled</td>\n<td>boolean</td>\n<td>false</td>\n<td>是否禁用</td>\n</tr>\n<tr>\n<td>hidden</td>\n<td>boolean</td>\n<td>false</td>\n<td>是否隐藏</td>\n</tr>\n<tr>\n<td>confirm</td>\n<td>boolean</td>\n<td>false</td>\n<td>是否需要确认</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string | ReactNode</td>\n<td>-</td>\n<td>确认提示内容(设置后会自动使用 ConfirmButton)</td>\n</tr>\n<tr>\n<td>isDelete</td>\n<td>boolean</td>\n<td>false</td>\n<td>是否为删除操作(红色按钮)</td>\n</tr>\n<tr>\n<td>isModal</td>\n<td>boolean</td>\n<td>false</td>\n<td>是否使用模态框确认(在下拉菜单中自动启用)</td>\n</tr>\n<tr>\n<td>buttonComponent</td>\n<td>ReactComponent</td>\n<td>-</td>\n<td>自定义按钮组件</td>\n</tr>\n<tr>\n<td>tooltipProps</td>\n<td>object</td>\n<td>-</td>\n<td>Tooltip 组件属性(禁用时显示提示)</td>\n</tr>\n<tr>\n<td>...ButtonProps</td>\n<td>-</td>\n<td>-</td>\n<td>Button 组件的其他属性</td>\n</tr>\n</tbody>\n</table>\n<p>当 list 项为函数时,函数签名为:</p>\n<pre><code class=\"language-typescript\">(props: { key: number; className: string }, context: { isDropdown: boolean }) =&gt; ReactNode\n</code></pre>\n<hr>\n<h2>LoadingButton</h2>\n<p>封装了加载状态的按钮组件,简化异步操作的处理。</p>\n<h3>属性</h3>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>onClick</td>\n<td>function | Promise</td>\n<td>-</td>\n<td>点击按钮时的回调函数,可以返回 Promise</td>\n</tr>\n<tr>\n<td>loading</td>\n<td>boolean</td>\n<td>false</td>\n<td>是否显示加载状态</td>\n</tr>\n<tr>\n<td>disabled</td>\n<td>boolean</td>\n<td>false</td>\n<td>是否禁用按钮</td>\n</tr>\n<tr>\n<td>children</td>\n<td>ReactNode | function</td>\n<td>-</td>\n<td>按钮内容,可以是函数接收 loading 状态</td>\n</tr>\n<tr>\n<td>...ButtonProps</td>\n<td>-</td>\n<td>-</td>\n<td>Button 组件的其他属性</td>\n</tr>\n</tbody>\n</table>\n<h3>useLoading Hook</h3>\n<p>用于管理异步操作加载状态的 Hook。</p>\n<h4>参数</h4>\n<table>\n<thead>\n<tr>\n<th>参数名</th>\n<th>类型</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>callback</td>\n<td>function</td>\n<td>-</td>\n<td>异步回调函数</td>\n</tr>\n</tbody>\n</table>\n<h4>返回值</h4>\n<table>\n<thead>\n<tr>\n<th>名称</th>\n<th>类型</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>isLoading</td>\n<td>boolean</td>\n<td>当前加载状态</td>\n</tr>\n<tr>\n<td>setIsLoading</td>\n<td>function</td>\n<td>设置加载状态的函数</td>\n</tr>\n<tr>\n<td>callback</td>\n<td>function</td>\n<td>包装后的回调函数</td>\n</tr>\n</tbody>\n</table>\n<hr>\n<h2>ConfirmButton</h2>\n<p>带有确认功能的按钮组件,支持弹窗确认和模态框确认两种模式。</p>\n<h3>属性</h3>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>children</td>\n<td>ReactNode</td>\n<td>-</td>\n<td>按钮内容</td>\n</tr>\n<tr>\n<td>onClick</td>\n<td>function | Promise</td>\n<td>-</td>\n<td>确认后的回调函数,可以返回 Promise</td>\n</tr>\n<tr>\n<td>title</td>\n<td>string | ReactNode</td>\n<td>-</td>\n<td>确认框标题</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string | ReactNode</td>\n<td>-</td>\n<td>确认框内容</td>\n</tr>\n<tr>\n<td>okText</td>\n<td>string</td>\n<td>-</td>\n<td>确认按钮文字(默认根据 isDelete 动态显示)</td>\n</tr>\n<tr>\n<td>cancelText</td>\n<td>string</td>\n<td>-</td>\n<td>取消按钮文字</td>\n</tr>\n<tr>\n<td>isModal</td>\n<td>boolean</td>\n<td>false</td>\n<td>是否使用模态框确认(默认为 Popconfirm)</td>\n</tr>\n<tr>\n<td>isDelete</td>\n<td>boolean</td>\n<td>true</td>\n<td>是否为删除操作(红色按钮、确认按钮)</td>\n</tr>\n<tr>\n<td>showCancel</td>\n<td>boolean</td>\n<td>true</td>\n<td>是否显示取消按钮</td>\n</tr>\n<tr>\n<td>placement</td>\n<td>string</td>\n<td>-</td>\n<td>Popconfirm 的位置</td>\n</tr>\n<tr>\n<td>getContainer</td>\n<td>function</td>\n<td>-</td>\n<td>确认框渲染容器</td>\n</tr>\n<tr>\n<td>renderModal</td>\n<td>function</td>\n<td>-</td>\n<td>自定义 Modal 渲染函数</td>\n</tr>\n<tr>\n<td>onCancel</td>\n<td>function</td>\n<td>-</td>\n<td>取消按钮的回调</td>\n</tr>\n<tr>\n<td>...ButtonProps</td>\n<td>-</td>\n<td>-</td>\n<td>Button 组件的其他属性</td>\n</tr>\n</tbody>\n</table>\n<h3>ConfirmLink</h3>\n<p>ConfirmButton 的链接样式变体。</p>\n<h3>ConfirmText</h3>\n<p>ConfirmButton 的纯文本样式变体。</p>\n<h3>withConfirm</h3>\n<p>高阶组件,用于为任意组件添加确认功能。</p>\n<blockquote>\n<p>⚠️ 该 API 已标记为废弃,后续版本可能删除,建议不要使用。</p>\n</blockquote>\n<hr>\n<h2>FetchButton</h2>\n<p>集成了数据请求功能的按钮组件,基于 @kne/react-fetch 库实现。</p>\n<h3>属性</h3>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>api</td>\n<td>object | function</td>\n<td>-</td>\n<td>请求 API 配置</td>\n</tr>\n<tr>\n<td>params</td>\n<td>object</td>\n<td>-</td>\n<td>请求参数</td>\n</tr>\n<tr>\n<td>onSuccess</td>\n<td>function</td>\n<td>-</td>\n<td>请求成功回调,参数为 <code>{ data }</code></td>\n</tr>\n<tr>\n<td>onError</td>\n<td>function</td>\n<td>-</td>\n<td>请求失败回调</td>\n</tr>\n<tr>\n<td>beforeFetch</td>\n<td>function</td>\n<td>-</td>\n<td>请求前处理函数,返回 false 可阻止请求</td>\n</tr>\n<tr>\n<td>afterFetch</td>\n<td>function</td>\n<td>-</td>\n<td>请求后处理函数</td>\n</tr>\n<tr>\n<td>fetchOptions</td>\n<td>object</td>\n<td>-</td>\n<td>传递给 fetch 函数的选项</td>\n</tr>\n<tr>\n<td>onClick</td>\n<td>function</td>\n<td>-</td>\n<td>请求成功后的回调(与 onSuccess 相同)</td>\n</tr>\n<tr>\n<td>...LoadingButtonProps</td>\n<td>-</td>\n<td>-</td>\n<td>LoadingButton 组件的其他属性</td>\n</tr>\n</tbody>\n</table>\n<h3>api 配置</h3>\n<p>api 可以是对象或函数:</p>\n<pre><code class=\"language-typescript\">// 对象形式\napi: {\n loader: async ({ params }) =&gt; {\n return { data: 'response data' };\n }\n}\n\n// 函数形式\napi: async ({ params }) =&gt; {\n return { data: 'response data' };\n}\n</code></pre>\n<hr>\n<h2>ButtonFooter</h2>\n<p>页面底部按钮区域组件,可以自动计算高度并设置 CSS 变量。</p>\n<h3>属性</h3>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>children</td>\n<td>ReactNode</td>\n<td>-</td>\n<td>按钮区域内容</td>\n</tr>\n<tr>\n<td>className</td>\n<td>string</td>\n<td>-</td>\n<td>容器的自定义类名</td>\n</tr>\n<tr>\n<td>innerClassName</td>\n<td>string</td>\n<td>-</td>\n<td>内部容器的自定义类名</td>\n</tr>\n<tr>\n<td>target</td>\n<td>HTMLElement</td>\n<td>document.body</td>\n<td>移动端渲染的目标容器</td>\n</tr>\n</tbody>\n</table>\n<h3>特性</h3>\n<ul>\n<li>在小屏幕(≤768px)下,会将内容使用 Portal 渲染到 body</li>\n<li>自动计算高度并设置 CSS 变量</li>\n<li>适用于固定在页面底部的操作按钮区域</li>\n</ul>`,\n example: {\n isFull: false,\n className: ``,\n style: ``,\n list: [{\n title: `ButtonGroup 基础用法`,\n description: `ButtonGroup 能够根据容器宽度自动调整显示的按钮数量,并将多余的按钮放入下拉菜单中。适用于操作栏、工具栏等场景。`,\n code: `const { default: ButtonGroup } = _ButtonGroup;\nconst { Flex, Button, Space, Typography } = antd;\nconst { useState } = React;\nconst { Text } = Typography;\n\n// 基础用法 - 自动适应容器宽度\nconst BasicExample = () => {\n const [width, setWidth] = useState(300);\n return (\n <Flex gap={16} vertical>\n <Text type=\"secondary\">调整容器宽度查看自适应效果</Text>\n <Flex gap={8}>\n <div style={{ width: \\`\\${width}px\\`, padding: '12px', background: '#f5f5f5', borderRadius: '8px' }}>\n <ButtonGroup\n list={[\n { type: 'primary', children: '新建' },\n { type: 'default', children: '编辑' },\n { type: 'default', children: '导出' },\n { type: 'default', children: '打印' },\n { children: '更多操作1', message: '确定执行吗?' },\n { children: '更多操作2', message: '确定执行吗?' }\n ]}\n />\n </div>\n </Flex>\n <Space>\n <Button onClick={() => setWidth(w => Math.max(200, w - 50))}>减少宽度</Button>\n <Button onClick={() => setWidth(w => Math.min(600, w + 50))}>增加宽度</Button>\n </Space>\n </Flex>\n );\n};\n\n// 紧凑模式\nconst CompactExample = () => {\n return (\n <Flex gap={16} vertical>\n <Text type=\"secondary\">紧凑模式(适用于工具栏)</Text>\n <ButtonGroup\n compact\n list={[\n { type: 'primary', children: '保存' },\n { children: '撤销' },\n { children: '重做' },\n { children: '删除', isDelete: true }\n ]}\n />\n </Flex>\n );\n};\n\n// 链接样式 - 更多按钮\nconst LinkStyleExample = () => {\n const [width, setWidth] = useState(200);\n return (\n <Flex gap={16} vertical>\n <Text type=\"secondary\">链接样式(适用于表格操作栏)</Text>\n <div style={{ width: \\`\\${width}px\\` }}>\n <ButtonGroup\n moreType=\"link\"\n list={[\n { children: '查看', type: 'link' },\n { children: '编辑', type: 'link' },\n { children: '删除', type: 'link', isDelete: true, message: '确定删除吗?' },\n { children: '审核', type: 'link' },\n { children: '驳回', type: 'link' }\n ]}\n />\n </div>\n <Space>\n <Button onClick={() => setWidth(w => Math.max(150, w - 30))}>-</Button>\n <Button onClick={() => setWidth(w => Math.min(400, w + 30))}>+</Button>\n </Space>\n </Flex>\n );\n};\n\n// 指定显示数量\nconst FixedLengthExample = () => {\n const [showLength, setShowLength] = useState(2);\n return (\n <Flex gap={16} vertical>\n <Text type=\"secondary\">指定显示按钮数量(showLength)</Text>\n <Space>\n <Button\n type={showLength === 1 ? 'primary' : 'default'}\n onClick={() => setShowLength(1)}\n >\n 显示1个\n </Button>\n <Button\n type={showLength === 2 ? 'primary' : 'default'}\n onClick={() => setShowLength(2)}\n >\n 显示2个\n </Button>\n <Button\n type={showLength === 3 ? 'primary' : 'default'}\n onClick={() => setShowLength(3)}\n >\n 显示3个\n </Button>\n </Space>\n <ButtonGroup\n showLength={showLength}\n list={[\n { type: 'primary', children: '主要操作' },\n { children: '次要操作1' },\n { children: '次要操作2' },\n { children: '次要操作3' },\n { children: '次要操作4' }\n ]}\n />\n </Flex>\n );\n};\n\n// 自定义渲染函数\nconst CustomRenderExample = () => {\n const CustomButton = (props) => (\n <Button {...props} style={{ borderRadius: '4px' }}>\n {props.children}\n </Button>\n );\n\n return (\n <Flex gap={16} vertical>\n <Text type=\"secondary\">自定义渲染(支持函数式配置)</Text>\n <div style={{ padding: '12px', background: '#f5f5f5', borderRadius: '8px', width: '280px' }}>\n <ButtonGroup\n moreType=\"link\"\n list={[\n (props) => <CustomButton {...props} type=\"primary\">自定义按钮</CustomButton>,\n (props) => <CustomButton {...props}>按钮2</CustomButton>,\n (props) => <CustomButton {...props}>按钮3</CustomButton>,\n (props) => <CustomButton {...props}>按钮4</CustomButton>\n ]}\n />\n </div>\n </Flex>\n );\n};\n\n// 禁用状态与隐藏\nconst StateExample = () => {\n const [disabled, setDisabled] = useState(true);\n const [hidden, setHidden] = useState(true);\n\n return (\n <Flex gap={16} vertical>\n <Text type=\"secondary\">禁用与隐藏状态</Text>\n <Space>\n <Button onClick={() => setDisabled(!disabled)}>\n {disabled ? '启用' : '禁用'}操作3\n </Button>\n <Button onClick={() => setHidden(!hidden)}>\n {hidden ? '显示' : '隐藏'}操作4\n </Button>\n </Space>\n <ButtonGroup\n list={[\n { type: 'primary', children: '操作1' },\n { children: '操作2' },\n { children: '操作3', disabled },\n { children: '操作4', hidden },\n { children: '操作5', message: '确定吗?' }\n ]}\n />\n </Flex>\n );\n};\n\n// 工具提示\nconst TooltipExample = () => {\n return (\n <Flex gap={16} vertical>\n <Text type=\"secondary\">禁用按钮提示(tooltipProps)</Text>\n <ButtonGroup\n list={[\n { type: 'primary', children: '可用操作' },\n {\n children: '已禁用操作',\n disabled: true,\n tooltipProps: {\n title: '此操作暂时不可用,请先完成前置步骤',\n placement: 'bottom'\n }\n },\n {\n children: '需要权限',\n disabled: true,\n tooltipProps: {\n title: '您没有执行此操作的权限',\n placement: 'bottom'\n }\n }\n ]}\n />\n </Flex>\n );\n};\n\nconst BaseExample = () => {\n return (\n <Space direction=\"vertical\" size=\"large\">\n <Typography.Title level={3}>ButtonGroup 自适应按钮组</Typography.Title>\n <Typography.Paragraph>\n ButtonGroup 是一个自适应按钮组组件,能够根据容器宽度自动调整显示的按钮数量,\n 多余的按钮会放入下拉菜单中。适用于操作栏、工具栏、表格操作列等场景。\n </Typography.Paragraph>\n\n <Flex vertical gap={32}>\n <div>\n <Typography.Title level={4}>基础用法</Typography.Title>\n <BasicExample />\n </div>\n\n <div>\n <Typography.Title level={4}>紧凑模式</Typography.Title>\n <CompactExample />\n </div>\n\n <div>\n <Typography.Title level={4}>链接样式</Typography.Title>\n <LinkStyleExample />\n </div>\n\n <div>\n <Typography.Title level={4}>指定显示数量</Typography.Title>\n <FixedLengthExample />\n </div>\n\n <div>\n <Typography.Title level={4}>自定义渲染</Typography.Title>\n <CustomRenderExample />\n </div>\n\n <div>\n <Typography.Title level={4}>禁用与隐藏</Typography.Title>\n <StateExample />\n </div>\n\n <div>\n <Typography.Title level={4}>禁用提示</Typography.Title>\n <TooltipExample />\n </div>\n </Flex>\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_ButtonGroup\",\n packageName: \"@kne/button-group\",\n importStatement: \"import * as _ButtonGroup from \\\"@kne/button-group\\\"\",\n component: component_1\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_2\n}]\n},{\n title: `LoadingButton 加载按钮`,\n description: `LoadingButton 封装了加载状态,简化异步操作的处理。点击按钮时自动显示加载状态,避免重复提交。`,\n code: `const { LoadingButton, useLoading } = _ButtonGroup;\nconst { Space, Button, Typography, message, Card, Alert, Flex } = antd;\nconst { useState } = React;\n\n// 基础用法 - 自动加载状态\nconst BasicExample = () => {\n const handleClick = () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n message.success('操作成功!');\n resolve();\n }, 1500);\n });\n };\n\n return (\n <Space direction=\"vertical\">\n <Typography.Text type=\"secondary\">点击按钮,自动管理加载状态</Typography.Text>\n <Space wrap>\n <LoadingButton type=\"primary\" onClick={handleClick}>\n 保存数据\n </LoadingButton>\n <LoadingButton onClick={handleClick}>提交审核</LoadingButton>\n <LoadingButton danger onClick={handleClick}>删除</LoadingButton>\n </Space>\n </Space>\n );\n};\n\n// 自定义加载文案\nconst CustomTextExample = () => {\n const handleClick = () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n message.success('上传完成');\n resolve();\n }, 2000);\n });\n };\n\n return (\n <Space direction=\"vertical\">\n <Typography.Text type=\"secondary\">使用函数自定义加载时的文案</Typography.Text>\n <Space>\n <LoadingButton onClick={handleClick}>\n {(isLoading) => (isLoading ? '正在上传...' : '上传文件')}\n </LoadingButton>\n <LoadingButton onClick={handleClick} type=\"primary\">\n {(isLoading) => (isLoading ? '提交中...' : '提交订单')}\n </LoadingButton>\n </Space>\n </Space>\n );\n};\n\n// 错误处理\nconst ErrorExample = () => {\n const [shouldFail, setShouldFail] = useState(false);\n\n const handleClick = () => {\n return new Promise((resolve, reject) => {\n setTimeout(() => {\n if (shouldFail) {\n message.error('操作失败,请重试');\n reject(new Error('操作失败'));\n } else {\n message.success('操作成功');\n resolve();\n }\n }, 1000);\n });\n };\n\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text type=\"secondary\">\n 演示错误处理:加载状态会自动解除\n </Typography.Text>\n <Space>\n <Button onClick={() => setShouldFail(!shouldFail)}>\n {shouldFail ? '切换为成功' : '切换为失败'}\n </Button>\n </Space>\n <Space>\n <LoadingButton onClick={handleClick}>\n {shouldFail ? '会失败的操作' : '会成功的操作'}\n </LoadingButton>\n </Space>\n {shouldFail && <Alert message=\"当前设置为失败模式\" type=\"warning\" />}\n </Space>\n );\n};\n\n// 手动控制加载状态\nconst ManualExample = () => {\n const [loading, setLoading] = useState(false);\n\n const handleClick = () => {\n setLoading(true);\n setTimeout(() => {\n setLoading(false);\n message.success('手动控制加载完成');\n }, 2000);\n };\n\n return (\n <Space direction=\"vertical\">\n <Typography.Text type=\"secondary\">通过 loading 属性手动控制加载状态</Typography.Text>\n <LoadingButton loading={loading} onClick={handleClick}>\n 手动控制加载\n </LoadingButton>\n </Space>\n );\n};\n\n// useLoading Hook 示例\nconst UseLoadingExample = () => {\n const { isLoading, callback } = useLoading(() => {\n return new Promise((resolve) => {\n setTimeout(() => {\n message.success('Hook 模式操作完成');\n resolve();\n }, 1500);\n });\n });\n\n return (\n <Card title=\"useLoading Hook\" style={{ width: 400 }}>\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text type=\"secondary\">\n 在非按钮组件中使用 useLoading 管理异步状态\n </Typography.Text>\n <Space>\n <Button onClick={callback} loading={isLoading}>\n 使用 Hook\n </Button>\n <Button onClick={() => {}}>\n 独立按钮(不受影响)\n </Button>\n </Space>\n {isLoading && (\n <Alert message=\"当前状态:加载中\" type=\"info\" showIcon />\n )}\n </Space>\n </Card>\n );\n};\n\n// 不同按钮类型\nconst ButtonTypesExample = () => {\n const handleClick = () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n message.success('完成');\n resolve();\n }, 1000);\n });\n };\n\n return (\n <Space direction=\"vertical\">\n <Typography.Text type=\"secondary\">支持所有 Ant Design Button 类型</Typography.Text>\n <Space wrap>\n <LoadingButton type=\"primary\" onClick={handleClick}>Primary</LoadingButton>\n <LoadingButton type=\"default\" onClick={handleClick}>Default</LoadingButton>\n <LoadingButton type=\"dashed\" onClick={handleClick}>Dashed</LoadingButton>\n <LoadingButton type=\"link\" onClick={handleClick}>Link</LoadingButton>\n <LoadingButton type=\"text\" onClick={handleClick}>Text</LoadingButton>\n </Space>\n <Space wrap>\n <LoadingButton type=\"primary\" ghost onClick={handleClick}>Primary Ghost</LoadingButton>\n <LoadingButton type=\"default\" ghost onClick={handleClick}>Default Ghost</LoadingButton>\n </Space>\n </Space>\n );\n};\n\n// 图标按钮\nconst IconExample = () => {\n const handleClick = () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n message.success('操作完成');\n resolve();\n }, 1200);\n });\n };\n\n return (\n <Space direction=\"vertical\">\n <Typography.Text type=\"secondary\">支持图标</Typography.Text>\n <Space>\n <LoadingButton type=\"primary\" icon={<span>⬆️</span>} onClick={handleClick}>\n 上传\n </LoadingButton>\n <LoadingButton icon={<span>⬇️</span>} onClick={handleClick}>\n 下载\n </LoadingButton>\n <LoadingButton danger icon={<span>🗑️</span>} onClick={handleClick}>\n 删除\n </LoadingButton>\n </Space>\n </Space>\n );\n};\n\n// 实际应用场景 - 表单提交\nconst FormSubmitExample = () => {\n const handleSubmit = async () => {\n // 模拟表单验证\n await new Promise(resolve => setTimeout(resolve, 500));\n // 模拟 API 请求\n await new Promise((resolve) => {\n setTimeout(() => {\n message.success('表单提交成功!');\n resolve();\n }, 1500);\n });\n };\n\n return (\n <Card title=\"表单提交场景\" style={{ width: 400 }}>\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text type=\"secondary\">\n 点击提交按钮,自动防止重复提交\n </Typography.Text>\n <Space>\n <LoadingButton type=\"primary\" onClick={handleSubmit}>\n 提交表单\n </LoadingButton>\n <Button onClick={() => message.info('已取消')}>取消</Button>\n </Space>\n </Space>\n </Card>\n );\n};\n\nconst BaseExample = () => {\n return (\n <Space direction=\"vertical\" size=\"large\">\n <Typography.Title level={3}>LoadingButton 加载按钮</Typography.Title>\n <Typography.Paragraph>\n LoadingButton 封装了加载状态,简化异步操作的处理。点击按钮时自动显示加载状态,\n 避免重复提交,同时提供 useLoading Hook 供其他组件使用。\n </Typography.Paragraph>\n\n <Flex vertical gap={32}>\n <div>\n <Typography.Title level={4}>基础用法</Typography.Title>\n <BasicExample />\n </div>\n\n <div>\n <Typography.Title level={4}>自定义加载文案</Typography.Title>\n <CustomTextExample />\n </div>\n\n <div>\n <Typography.Title level={4}>错误处理</Typography.Title>\n <ErrorExample />\n </div>\n\n <div>\n <Typography.Title level={4}>手动控制加载状态</Typography.Title>\n <ManualExample />\n </div>\n\n <div>\n <Typography.Title level={4}>useLoading Hook</Typography.Title>\n <UseLoadingExample />\n </div>\n\n <div>\n <Typography.Title level={4}>不同按钮类型</Typography.Title>\n <ButtonTypesExample />\n </div>\n\n <div>\n <Typography.Title level={4}>图标按钮</Typography.Title>\n <IconExample />\n </div>\n\n <div>\n <Typography.Title level={4}>实际应用场景</Typography.Title>\n <FormSubmitExample />\n </div>\n </Flex>\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_ButtonGroup\",\n packageName: \"@kne/button-group\",\n importStatement: \"import * as _ButtonGroup from \\\"@kne/button-group\\\"\",\n component: component_1\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_2\n}]\n},{\n title: `ConfirmButton 确认按钮`,\n description: `ConfirmButton 带有确认功能,支持弹窗确认和模态框确认两种模式。适用于删除、提交等重要操作。`,\n code: `const { ConfirmButton, ConfirmLink, ConfirmText } = _ButtonGroup;\nconst { Flex, Space, Typography, message, Card, List, Tag, Button } = antd;\nconst { useState } = React;\n\n// 基础用法 - Popconfirm 模式\nconst BasicExample = () => {\n const handleDelete = () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n message.success('删除成功');\n resolve();\n }, 500);\n });\n };\n\n return (\n <Space direction=\"vertical\">\n <Typography.Text type=\"secondary\">\n Popconfirm 模式(气泡确认框),适用于快速确认\n </Typography.Text>\n <Space>\n <ConfirmButton message=\"确定要删除吗?\" onClick={handleDelete}>\n 删除\n </ConfirmButton>\n <ConfirmButton message=\"确定要提交吗?\" onClick={handleDelete}>\n 提交\n </ConfirmButton>\n </Space>\n </Space>\n );\n};\n\n// Modal 模式\nconst ModalExample = () => {\n const handleSubmit = () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n message.success('提交成功');\n resolve();\n }, 500);\n });\n };\n\n return (\n <Space direction=\"vertical\">\n <Typography.Text type=\"secondary\">\n Modal 模式(模态框),适用于重要操作或长内容提示\n </Typography.Text>\n <Space>\n <ConfirmButton\n isModal\n message=\"此操作将永久删除该数据,删除后无法恢复。确定要继续吗?\"\n onClick={handleSubmit}\n >\n 删除数据\n </ConfirmButton>\n <ConfirmButton\n isModal\n title=\"提交确认\"\n message=\"提交后数据将进入审核流程,确认要提交吗?\"\n onClick={handleSubmit}\n >\n 提交审核\n </ConfirmButton>\n </Space>\n </Space>\n );\n};\n\n// 危险操作样式\nconst DangerExample = () => {\n const handleDelete = () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n message.success('已删除');\n resolve();\n }, 500);\n });\n };\n\n return (\n <Space direction=\"vertical\">\n <Typography.Text type=\"secondary\">\n 使用 isDelete 标识危险操作(红色按钮)\n </Typography.Text>\n <Space>\n <ConfirmButton\n danger\n message=\"确定删除吗?\"\n onClick={handleDelete}\n >\n 普通按钮\n </ConfirmButton>\n <ConfirmButton\n isDelete\n message=\"确定删除吗?\"\n onClick={handleDelete}\n >\n 删除按钮\n </ConfirmButton>\n <ConfirmButton\n isDelete\n isModal\n message=\"此操作无法撤销,确定要继续吗?\"\n onClick={handleDelete}\n >\n 删除(Modal)\n </ConfirmButton>\n </Space>\n </Space>\n );\n};\n\n// 自定义确认文案\nconst CustomTextExample = () => {\n const handleAction = () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n message.success('操作完成');\n resolve();\n }, 500);\n });\n };\n\n return (\n <Space direction=\"vertical\">\n <Typography.Text type=\"secondary\">自定义确认和取消按钮文案</Typography.Text>\n <Space>\n <ConfirmButton\n message=\"确定要执行此操作吗?\"\n okText=\"确认执行\"\n cancelText=\"暂不执行\"\n onClick={handleAction}\n >\n 自定义文案\n </ConfirmButton>\n <ConfirmButton\n isModal\n title=\"操作确认\"\n message=\"请确认是否继续执行此操作\"\n okText=\"是,继续\"\n cancelText=\"否,取消\"\n onClick={handleAction}\n >\n Modal 自定义文案\n </ConfirmButton>\n </Space>\n </Space>\n );\n};\n\n// ConfirmLink 和 ConfirmText\nconst LinkAndTextExample = () => {\n const handleAction = () => {\n message.success('操作成功');\n return Promise.resolve();\n };\n\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text type=\"secondary\">\n ConfirmLink 和 ConfirmText 变体,适用于表格行操作等场景\n </Typography.Text>\n <List\n bordered\n style={{ width: 400 }}\n dataSource={[\n { id: 1, name: '数据项 A', status: '已提交' },\n { id: 2, name: '数据项 B', status: '草稿' },\n { id: 3, name: '数据项 C', status: '已审核' }\n ]}\n renderItem={(item) => (\n <List.Item\n actions={[\n <ConfirmLink key=\"edit\" message=\"确定编辑吗?\" onClick={handleAction}>\n 编辑\n </ConfirmLink>,\n <ConfirmLink key=\"delete\" isDelete message=\"确定删除吗?\" onClick={handleAction}>\n 删除\n </ConfirmLink>\n ]}\n >\n <List.Item.Meta\n title={item.name}\n description={<Tag color={item.status === '已提交' ? 'blue' : 'default'}>{item.status}</Tag>}\n />\n </List.Item>\n )}\n />\n <Space>\n <ConfirmText onClick={handleAction}>纯文本确认</ConfirmText>\n <Typography.Text type=\"secondary\">|</Typography.Text>\n <ConfirmText isDelete onClick={handleAction}>删除</ConfirmText>\n </Space>\n </Space>\n );\n};\n\n// 禁用状态\nconst DisabledExample = () => {\n const [disabled, setDisabled] = useState(true);\n const handleDelete = () => {\n message.success('已删除');\n return Promise.resolve();\n };\n\n return (\n <Space direction=\"vertical\">\n <Typography.Text type=\"secondary\">禁用状态下不会触发确认</Typography.Text>\n <Space>\n <Button onClick={() => setDisabled(!disabled)}>\n {disabled ? '启用' : '禁用'}\n </Button>\n </Space>\n <Space>\n <ConfirmButton disabled={disabled} message=\"确定删除吗?\" onClick={handleDelete}>\n 删除\n </ConfirmButton>\n <ConfirmLink disabled={disabled} message=\"确定删除吗?\" onClick={handleDelete}>\n 删除\n </ConfirmLink>\n </Space>\n </Space>\n );\n};\n\n// 实际应用场景 - 表格操作\nconst TableActionExample = () => {\n const handleEdit = () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n message.success('进入编辑模式');\n resolve();\n }, 300);\n });\n };\n\n const handleDelete = () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n message.success('已删除');\n resolve();\n }, 300);\n });\n };\n\n const handleAudit = () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n message.success('审核通过');\n resolve();\n }, 300);\n });\n };\n\n return (\n <Card title=\"实际应用:表格操作栏\" style={{ width: 500 }}>\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text type=\"secondary\">\n 模拟表格中的操作按钮,包含不同的确认方式\n </Typography.Text>\n <List\n bordered\n dataSource={[\n { id: 1, name: '产品 A', price: '¥99.00' },\n { id: 2, name: '产品 B', price: '¥199.00' }\n ]}\n renderItem={(item) => (\n <List.Item\n actions={[\n <ConfirmButton key=\"edit\" type=\"link\" message={\\`确定编辑 \\${item.name} 吗?\\`} onClick={handleEdit}>\n 编辑\n </ConfirmButton>,\n <ConfirmButton key=\"audit\" type=\"link\" message={\\`确定通过 \\${item.name} 的审核吗?\\`} onClick={handleAudit}>\n 审核\n </ConfirmButton>,\n <ConfirmButton\n key=\"delete\"\n type=\"link\"\n danger\n message={\\`确定删除 \\${item.name} 吗?此操作无法撤销。\\`}\n onClick={handleDelete}\n >\n 删除\n </ConfirmButton>\n ]}\n >\n <List.Item.Meta\n title={item.name}\n description={item.price}\n />\n </List.Item>\n )}\n />\n </Space>\n </Card>\n );\n};\n\n// 批量操作\nconst BatchExample = () => {\n const [selectedCount, setSelectedCount] = useState(0);\n const handleBatchDelete = () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n message.success(\\`已删除 \\${selectedCount} 条数据\\`);\n setSelectedCount(0);\n resolve();\n }, 500);\n });\n };\n\n return (\n <Card title=\"批量操作场景\" style={{ width: 450 }}>\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Space>\n <Typography.Text type=\"secondary\">已选择:</Typography.Text>\n <Typography.Text strong>{selectedCount} 项</Typography.Text>\n <Button size=\"small\" onClick={() => setSelectedCount(Math.floor(Math.random() * 10))}>\n 随机选择\n </Button>\n </Space>\n <Space>\n <ConfirmButton\n type=\"primary\"\n disabled={selectedCount === 0}\n isModal\n title=\"批量删除确认\"\n message={\\`确定要删除选中的 \\${selectedCount} 条数据吗?此操作无法撤销。\\`}\n onClick={handleBatchDelete}\n >\n 批量删除\n </ConfirmButton>\n <ConfirmButton\n disabled={selectedCount === 0}\n message={\\`确定导出选中的 \\${selectedCount} 条数据吗?\\`}\n onClick={() => {\n message.success(\\`正在导出 \\${selectedCount} 条数据\\`);\n return Promise.resolve();\n }}\n >\n 导出\n </ConfirmButton>\n </Space>\n </Space>\n </Card>\n );\n};\n\nconst BaseExample = () => {\n return (\n <Space direction=\"vertical\" size=\"large\">\n <Typography.Title level={3}>ConfirmButton 确认按钮</Typography.Title>\n <Typography.Paragraph>\n ConfirmButton 提供确认功能,支持 Popconfirm(气泡确认框)和 Modal(模态框)两种模式。\n 还提供 ConfirmLink 和 ConfirmText 变体,以及 withConfirm 高阶组件。\n </Typography.Paragraph>\n\n <Flex vertical gap={32}>\n <div>\n <Typography.Title level={4}>Popconfirm 模式</Typography.Title>\n <BasicExample />\n </div>\n\n <div>\n <Typography.Title level={4}>Modal 模式</Typography.Title>\n <ModalExample />\n </div>\n\n <div>\n <Typography.Title level={4}>危险操作样式</Typography.Title>\n <DangerExample />\n </div>\n\n <div>\n <Typography.Title level={4}>自定义文案</Typography.Title>\n <CustomTextExample />\n </div>\n\n <div>\n <Typography.Title level={4}>Link 和 Text 变体</Typography.Title>\n <LinkAndTextExample />\n </div>\n\n <div>\n <Typography.Title level={4}>禁用状态</Typography.Title>\n <DisabledExample />\n </div>\n\n <div>\n <Typography.Title level={4}>实际应用场景</Typography.Title>\n <TableActionExample />\n </div>\n\n <div>\n <Typography.Title level={4}>批量操作</Typography.Title>\n <BatchExample />\n </div>\n </Flex>\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_ButtonGroup\",\n packageName: \"@kne/button-group\",\n importStatement: \"import * as _ButtonGroup from \\\"@kne/button-group\\\"\",\n component: component_1\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_2\n}]\n},{\n title: `FetchButton 请求按钮`,\n description: `FetchButton 集成了数据请求功能,自动管理加载状态和请求流程。适用于按钮触发 API 请求的场景。`,\n code: `const { FetchButton } = _ButtonGroup;\nconst { Space, Typography, message, Card, Alert, Form, Input, Select, Button, Flex } = antd;\nconst { useState } = React;\n\n// 基础用法\nconst BasicExample = () => {\n const handleSuccess = ({ data }) => {\n message.success(\\`获取数据成功: \\${data}\\`);\n };\n\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text type=\"secondary\">\n 点击按钮触发 API 请求,自动管理加载状态\n </Typography.Text>\n <FetchButton\n type=\"primary\"\n api={{\n loader: async () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve({ data: '用户信息数据' });\n }, 1500);\n });\n }\n }}\n onClick={handleSuccess}\n >\n 获取用户信息\n </FetchButton>\n </Space>\n );\n};\n\n// 带参数请求\nconst WithParamsExample = () => {\n const [userId, setUserId] = useState('1');\n\n const handleSuccess = ({ data }) => {\n message.success(\\`获取成功: \\${JSON.stringify(data)}\\`);\n };\n\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text type=\"secondary\">传递参数到 API 请求</Typography.Text>\n <Space>\n <Select\n value={userId}\n onChange={setUserId}\n style={{ width: 120 }}\n options={[\n { value: '1', label: '用户1' },\n { value: '2', label: '用户2' },\n { value: '3', label: '用户3' }\n ]}\n />\n <FetchButton\n params={{ userId }}\n api={{\n loader: async ({ params }) => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve({ data: { userId: params.userId, name: \\`用户\\${params.userId}\\`, role: '管理员' } });\n }, 1000);\n });\n }\n }}\n onClick={handleSuccess}\n >\n 获取用户详情\n </FetchButton>\n </Space>\n </Space>\n );\n};\n\n// 成功和失败回调\nconst CallbackExample = () => {\n const [status, setStatus] = useState('');\n const [shouldFail, setShouldFail] = useState(false);\n\n const handleSuccess = ({ data }) => {\n setStatus('success');\n message.success('数据加载成功');\n console.log('成功数据:', data);\n };\n\n const handleError = (error) => {\n setStatus('error');\n message.error('数据加载失败');\n console.error('错误信息:', error);\n };\n\n return (\n <Card title=\"成功与失败回调\" style={{ width: 450 }}>\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Space>\n <Button onClick={() => setShouldFail(!shouldFail)} size=\"small\">\n {shouldFail ? '切换为成功' : '切换为失败'}\n </Button>\n </Space>\n <FetchButton\n type=\"primary\"\n api={{\n loader: async () => {\n return new Promise((resolve, reject) => {\n setTimeout(() => {\n if (shouldFail) {\n reject(new Error('模拟的请求失败'));\n } else {\n resolve({ data: { message: '请求成功', timestamp: Date.now() } });\n }\n }, 1000);\n });\n }\n }}\n onSuccess={handleSuccess}\n onError={handleError}\n >\n {shouldFail ? '失败请求' : '成功请求'}\n </FetchButton>\n {status === 'success' && <Alert message=\"上次请求:成功\" type=\"success\" />}\n {status === 'error' && <Alert message=\"上次请求:失败\" type=\"error\" />}\n </Space>\n </Card>\n );\n};\n\n// 导出文件场景\nconst ExportExample = () => {\n const handleExport = ({ data }) => {\n message.success(\\`导出成功: \\${data.url}\\`);\n };\n\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text type=\"secondary\">模拟文件导出场景</Typography.Text>\n <Space>\n <FetchButton\n api={{\n loader: async () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve({ data: { url: '/download/report.xlsx', size: '2.5MB' } });\n }, 2000);\n });\n }\n }}\n onClick={handleExport}\n >\n 导出报表\n </FetchButton>\n <FetchButton\n type=\"primary\"\n api={{\n loader: async () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve({ data: { url: '/download/data.csv', size: '1.2MB' } });\n }, 1500);\n });\n }\n }}\n onClick={handleExport}\n >\n 导出 CSV\n </FetchButton>\n </Space>\n </Space>\n );\n};\n\n// 表单提交场景\nconst FormSubmitExample = () => {\n const [form] = Form.useForm();\n const [loading, setLoading] = useState(false);\n const [submittedData, setSubmittedData] = useState(null);\n\n const handleSubmit = ({ data }) => {\n setSubmittedData(data);\n message.success('表单提交成功');\n };\n\n const onFinish = async () => {\n try {\n const values = await form.validateFields();\n setLoading(true);\n // 使用 FetchButton 内部处理,这里只是演示\n await new Promise(resolve => setTimeout(resolve, 1000));\n setLoading(false);\n message.success('验证通过');\n } catch (error) {\n message.error('请检查表单内容');\n }\n };\n\n return (\n <Card title=\"表单提交场景\" style={{ width: 450 }}>\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Form\n form={form}\n layout=\"vertical\"\n >\n <Form.Item\n name=\"username\"\n label=\"用户名\"\n rules={[{ required: true, message: '请输入用户名' }]}\n >\n <Input placeholder=\"请输入用户名\" />\n </Form.Item>\n <Form.Item\n name=\"email\"\n label=\"邮箱\"\n rules={[{ required: true, message: '请输入邮箱' }]}\n >\n <Input placeholder=\"请输入邮箱\" />\n </Form.Item>\n </Form>\n <Space>\n <FetchButton\n type=\"primary\"\n api={{\n loader: async ({ params }) => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve({ data: { id: 123, ...params, createTime: new Date().toISOString() } });\n }, 1500);\n });\n }\n }}\n beforeFetch={() => {\n const values = form.getFieldsValue();\n if (!values.username || !values.email) {\n message.error('请填写完整信息');\n return false;\n }\n return true;\n }}\n onClick={handleSubmit}\n >\n 提交表单\n </FetchButton>\n <Button onClick={() => form.resetFields()}>重置</Button>\n </Space>\n {submittedData && (\n <Alert\n message=\"提交成功\"\n description={JSON.stringify(submittedData, null, 2)}\n type=\"success\"\n />\n )}\n </Space>\n </Card>\n );\n};\n\n// 刷新数据场景\nconst RefreshExample = () => {\n const [data, setData] = useState(null);\n const [lastRefresh, setLastRefresh] = useState(null);\n\n const handleRefresh = ({ data: newData }) => {\n console.log(newData);\n setData(newData);\n setLastRefresh(new Date().toLocaleTimeString());\n message.success('数据已更新');\n };\n\n return (\n <Card title=\"刷新数据场景\" style={{ width: 450 }}>\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Space>\n <Typography.Text type=\"secondary\">上次刷新:</Typography.Text>\n <Typography.Text>{lastRefresh || '从未刷新'}</Typography.Text>\n </Space>\n <FetchButton\n api={{\n loader: async () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve({\n users: [\n { id: 1, name: '用户A', status: '在线' },\n { id: 2, name: '用户B', status: '离线' },\n { id: 3, name: '用户C', status: '在线' }\n ],\n total: 3\n });\n }, 1000);\n });\n }\n }}\n onClick={handleRefresh}\n >\n 刷新数据\n </FetchButton>\n {data && (\n <Alert\n message={\\`当前数据:\\${data.users?.length} 个用户在线\\`}\n type=\"info\"\n />\n )}\n </Space>\n </Card>\n );\n};\n\n// beforeFetch 拦截\nconst BeforeFetchExample = () => {\n const [allowed, setAllowed] = useState(true);\n\n const handleFetch = ({ data }) => {\n message.success('请求通过');\n };\n\n const beforeFetch = () => {\n if (!allowed) {\n message.warning('请求被 beforeFetch 拦截');\n return false;\n }\n return true;\n };\n\n return (\n <Space direction=\"vertical\">\n <Typography.Text type=\"secondary\">beforeFetch 可以拦截请求</Typography.Text>\n <Space>\n <Button onClick={() => setAllowed(!allowed)} size=\"small\">\n {allowed ? '拦截请求' : '允许请求'}\n </Button>\n </Space>\n <FetchButton\n api={{\n loader: async () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve({ data: '请求成功' });\n }, 800);\n });\n }\n }}\n beforeFetch={beforeFetch}\n onClick={handleFetch}\n >\n {allowed ? '发送请求' : '请求已拦截'}\n </FetchButton>\n </Space>\n );\n};\n\nconst BaseExample = () => {\n return (\n <Space direction=\"vertical\" size=\"large\">\n <Typography.Title level={3}>FetchButton 请求按钮</Typography.Title>\n <Typography.Paragraph>\n FetchButton 集成了数据请求功能,基于 @kne/react-fetch 库实现。\n 自动管理加载状态,支持成功/失败回调、参数传递、请求拦截等功能。\n </Typography.Paragraph>\n\n <Flex vertical gap={32}>\n <div>\n <Typography.Title level={4}>基础用法</Typography.Title>\n <BasicExample />\n </div>\n\n <div>\n <Typography.Title level={4}>带参数请求</Typography.Title>\n <WithParamsExample />\n </div>\n\n <div>\n <Typography.Title level={4}>成功与失败回调</Typography.Title>\n <CallbackExample />\n </div>\n\n <div>\n <Typography.Title level={4}>文件导出场景</Typography.Title>\n <ExportExample />\n </div>\n\n <div>\n <Typography.Title level={4}>表单提交场景</Typography.Title>\n <FormSubmitExample />\n </div>\n\n <div>\n <Typography.Title level={4}>刷新数据场景</Typography.Title>\n <RefreshExample />\n </div>\n\n <div>\n <Typography.Title level={4}>请求拦截</Typography.Title>\n <BeforeFetchExample />\n </div>\n </Flex>\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_ButtonGroup\",\n packageName: \"@kne/button-group\",\n importStatement: \"import * as _ButtonGroup from \\\"@kne/button-group\\\"\",\n component: component_1\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_2\n}]\n},{\n title: `ButtonFooter 底部按钮区`,\n description: `ButtonFooter 是页面底部按钮区域组件,在小屏幕下自动将内容渲染到 body,方便表单页面的操作按钮布局。`,\n code: `const { ButtonFooter } = _ButtonGroup;\nconst { Flex, Button, Space, Typography, Card, Form, Input } = antd;\nconst { useState } = React;\n\n// 基础用法\nconst BasicExample = () => {\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text type=\"secondary\">\n ButtonFooter 固定在页面底部,在小屏幕(≤768px)下自动渲染到 body\n </Typography.Text>\n <Card\n title=\"页面内容区域\"\n style={{ width: 400, minHeight: 200 }}\n >\n <Typography.Paragraph>\n 这是页面的主要内容区域。ButtonFooter 会自动计算高度并设置 CSS 变量,\n 方便页面布局调整。\n </Typography.Paragraph>\n <Typography.Paragraph>\n 在移动端,按钮会自动固定在屏幕底部,确保操作按钮始终可见。\n </Typography.Paragraph>\n </Card>\n <ButtonFooter>\n <Flex justify=\"flex-end\" gap={8} style={{ padding: '16px 24px', background: '#fff', borderTop: '1px solid #f0f0f0' }}>\n <Button>取消</Button>\n <Button type=\"primary\">保存</Button>\n </Flex>\n </ButtonFooter>\n </Space>\n );\n};\n\n// 表单提交场景\nconst FormExample = () => {\n const [form] = Form.useForm();\n const [loading, setLoading] = useState(false);\n\n const handleSave = () => {\n setLoading(true);\n setTimeout(() => {\n setLoading(false);\n message.success('保存成功');\n }, 1000);\n };\n\n const handleSubmit = () => {\n setLoading(true);\n setTimeout(() => {\n setLoading(false);\n message.success('提交成功');\n }, 1000);\n };\n\n return (\n <Card title=\"表单底部操作\" style={{ width: 500 }}>\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text type=\"secondary\">\n 适用于表单页面的底部操作按钮\n </Typography.Text>\n <Form form={form} layout=\"vertical\">\n <Form.Item name=\"name\" label=\"名称\">\n <Input placeholder=\"请输入名称\" />\n </Form.Item>\n <Form.Item name=\"desc\" label=\"描述\">\n <Input.TextArea placeholder=\"请输入描述\" rows={4} />\n </Form.Item>\n </Form>\n <ButtonFooter>\n <Flex justify=\"flex-end\" gap={8} style={{ padding: '16px 0', borderTop: '1px solid #f0f0f0' }}>\n <Button onClick={() => form.resetFields()}>重置</Button>\n <Button onClick={handleSave}>保存草稿</Button>\n <Button type=\"primary\" loading={loading} onClick={handleSubmit}>\n 提交\n </Button>\n </Flex>\n </ButtonFooter>\n </Space>\n </Card>\n );\n};\n\n// 居中对齐\nconst CenterExample = () => {\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text type=\"secondary\">按钮居中对齐</Typography.Text>\n <Card title=\"对话框\" style={{ width: 400 }}>\n <Typography.Paragraph>\n 这是对话框的内容区域,底部按钮居中对齐。\n </Typography.Paragraph>\n </Card>\n <ButtonFooter>\n <Flex justify=\"center\" gap={8} style={{ padding: '16px 24px', background: '#fff', borderTop: '1px solid #f0f0f0' }}>\n <Button>关闭</Button>\n <Button type=\"primary\">确认</Button>\n </Flex>\n </ButtonFooter>\n </Space>\n );\n};\n\n// 多按钮布局\nconst MultipleButtonsExample = () => {\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text type=\"secondary\">多个操作按钮</Typography.Text>\n <Card title=\"详情页面\" style={{ width: 450 }}>\n <Typography.Paragraph>\n 页面详情内容区域...\n </Typography.Paragraph>\n <Typography.Paragraph>\n 支持多个按钮布局,包括主要操作、次要操作等。\n </Typography.Paragraph>\n </Card>\n <ButtonFooter>\n <Flex justify=\"space-between\" align=\"middle\" style={{ padding: '12px 24px', background: '#fff', borderTop: '1px solid #f0f0f0' }}>\n <Space>\n <Button type=\"text\" danger>删除</Button>\n <Button type=\"text\">导出</Button>\n </Space>\n <Space>\n <Button>编辑</Button>\n <Button type=\"primary\">提交审核</Button>\n </Space>\n </Flex>\n </ButtonFooter>\n </Space>\n );\n};\n\n// 紧凑样式\nconst CompactExample = () => {\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text type=\"secondary\">紧凑样式</Typography.Text>\n <Card title=\"设置页面\" style={{ width: 400 }}>\n <Typography.Paragraph>\n 系统设置内容区域...\n </Typography.Paragraph>\n </Card>\n <ButtonFooter>\n <Flex justify=\"flex-end\" gap={8} style={{ padding: '8px 0', borderTop: '1px solid #f0f0f0' }}>\n <Button size=\"small\">取消</Button>\n <Button size=\"small\" type=\"primary\">保存设置</Button>\n </Flex>\n </ButtonFooter>\n </Space>\n );\n};\n\n// 禁用状态\nconst DisabledExample = () => {\n const [disabled, setDisabled] = useState(true);\n\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text type=\"secondary\">按钮禁用状态</Typography.Text>\n <Space>\n <Button onClick={() => setDisabled(!disabled)} size=\"small\">\n {disabled ? '启用按钮' : '禁用按钮'}\n </Button>\n </Space>\n <Card title=\"详情页\" style={{ width: 400 }}>\n <Typography.Paragraph>\n 内容区域...\n </Typography.Paragraph>\n </Card>\n <ButtonFooter>\n <Flex justify=\"flex-end\" gap={8} style={{ padding: '16px 0', borderTop: '1px solid #f0f0f0' }}>\n <Button disabled={disabled}>编辑</Button>\n <Button type=\"primary\" disabled={disabled}>\n 提交\n </Button>\n </Flex>\n </ButtonFooter>\n </Space>\n );\n};\n\n// 步骤条场景\nconst StepsExample = () => {\n const [currentStep, setCurrentStep] = useState(0);\n const totalSteps = 3;\n\n const nextStep = () => {\n if (currentStep < totalSteps - 1) {\n setCurrentStep(currentStep + 1);\n }\n };\n\n const prevStep = () => {\n if (currentStep > 0) {\n setCurrentStep(currentStep - 1);\n }\n };\n\n const stepContent = [\n '第一步:填写基本信息',\n '第二步:上传相关文件',\n '第三步:确认提交信息'\n ];\n\n return (\n <Card title=\"步骤操作\" style={{ width: 450 }}>\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text type=\"secondary\">\n 当前步骤:{currentStep + 1} / {totalSteps}\n </Typography.Text>\n <div style={{ padding: '24px', background: '#f5f5f5', borderRadius: '8px', minHeight: '100px' }}>\n <Typography.Text>{stepContent[currentStep]}</Typography.Text>\n </div>\n <ButtonFooter>\n <Flex justify=\"space-between\" style={{ padding: '16px 0', borderTop: '1px solid #f0f0f0' }}>\n <Button disabled={currentStep === 0} onClick={prevStep}>\n 上一步\n </Button>\n <Button\n type=\"primary\"\n onClick={currentStep === totalSteps - 1 ? () => message.success('提交成功') : nextStep}\n >\n {currentStep === totalSteps - 1 ? '提交' : '下一步'}\n </Button>\n </Flex>\n </ButtonFooter>\n </Space>\n </Card>\n );\n};\n\n// 实际应用场景 - 完整页面\nconst FullPageExample = () => {\n const [form] = Form.useForm();\n\n const handleSubmit = () => {\n message.success('提交成功');\n };\n\n const handleSave = () => {\n message.success('已保存草稿');\n };\n\n return (\n <Card title=\"完整页面示例\" style={{ width: 500 }}>\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text type=\"secondary\">\n 模拟一个完整的表单页面,包含标题、内容区和底部操作按钮\n </Typography.Text>\n <div style={{ minHeight: '200px', padding: '20px', background: '#fafafa', borderRadius: '8px' }}>\n <Typography.Title level={5}>用户信息编辑</Typography.Title>\n <Form form={form} layout=\"vertical\">\n <Form.Item name=\"username\" label=\"用户名\">\n <Input placeholder=\"请输入用户名\" />\n </Form.Item>\n <Form.Item name=\"email\" label=\"邮箱\">\n <Input placeholder=\"请输入邮箱\" />\n </Form.Item>\n </Form>\n </div>\n <ButtonFooter>\n <Flex justify=\"flex-end\" gap={12} style={{ padding: '16px 24px', background: '#fff', borderTop: '1px solid #f0f0f0' }}>\n <Button onClick={() => form.resetFields()}>重置</Button>\n <Button onClick={handleSave}>保存草稿</Button>\n <Button type=\"primary\" onClick={handleSubmit}>提交</Button>\n </Flex>\n </ButtonFooter>\n </Space>\n </Card>\n );\n};\n\nconst BaseExample = () => {\n return (\n <Space direction=\"vertical\" size=\"large\">\n <Typography.Title level={3}>ButtonFooter 底部按钮区</Typography.Title>\n <Typography.Paragraph>\n ButtonFooter 是页面底部按钮区域组件,可以自动计算高度并设置 CSS 变量。\n 在小屏幕(≤768px)下,会将内容渲染到 body,确保按钮始终可见。\n 适用于表单页面、详情页面、对话框等场景。\n </Typography.Paragraph>\n\n <Flex vertical gap={32}>\n <div>\n <Typography.Title level={4}>基础用法</Typography.Title>\n <BasicExample />\n </div>\n\n <div>\n <Typography.Title level={4}>表单提交场景</Typography.Title>\n <FormExample />\n </div>\n\n <div>\n <Typography.Title level={4}>居中对齐</Typography.Title>\n <CenterExample />\n </div>\n\n <div>\n <Typography.Title level={4}>多按钮布局</Typography.Title>\n <MultipleButtonsExample />\n </div>\n\n <div>\n <Typography.Title level={4}>紧凑样式</Typography.Title>\n <CompactExample />\n </div>\n\n <div>\n <Typography.Title level={4}>禁用状态</Typography.Title>\n <DisabledExample />\n </div>\n\n <div>\n <Typography.Title level={4}>步骤操作</Typography.Title>\n <StepsExample />\n </div>\n\n <div>\n <Typography.Title level={4}>完整页面示例</Typography.Title>\n <FullPageExample />\n </div>\n </Flex>\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_ButtonGroup\",\n packageName: \"@kne/button-group\",\n importStatement: \"import * as _ButtonGroup from \\\"@kne/button-group\\\"\",\n component: component_1\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_2\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_13 from '@components/Common';\nimport * as component_14 from '@components/Modal';\nimport * as component_15 from 'antd';\nimport * as component_16 from '@kne/react-fetch';\nimport * as component_17 from 'lodash';\nconst readmeConfig = {\n name: `Common`,\n summary: `<p>为组件库提供通用的组件、方法、hooks</p>\n<h3>组件</h3>\n<ol>\n<li><strong>FetchButton</strong> - Button触发加载数据,支持弹窗展示加载结果</li>\n<li><strong>ScrollLoader</strong> - 下拉滚动加载组件,配合 Fetch 实现分页加载</li>\n<li><strong>SearchInput</strong> - 提供防抖的查询输入框</li>\n<li><strong>SimpleBarBox</strong> - 自定义滚动条容器(已废弃,请勿使用)</li>\n<li><strong>TreeField</strong> - 树形选择组件,支持单选和多选</li>\n<li><strong>CascaderField</strong> - 级联选择组件,支持多级联动选择</li>\n<li><strong>TypeDateRangePickerField</strong> - 类型日期范围选择器,支持按日、周、月选择</li>\n<li><strong>SuperSelectField</strong> - 新版高级选择组件,提供更强的自定义能力</li>\n<li><strong>SuperSelectUserField</strong> - 用户选择组件,展示用户头像和描述</li>\n<li><strong>SuperSelectTableListField</strong> - 表格列表选择组件</li>\n<li><strong>SuperSelectTreeField</strong> - 树形选择组件</li>\n<li><strong>AdvancedSelectField</strong> - 高级选择组件,支持用户选择、列表选择</li>\n<li><strong>UserField</strong> - 用户选择组件(旧版)</li>\n<li><strong>TableField</strong> - 表格选择组件</li>\n<li><strong>AddressSelectField</strong> - 地址选择组件</li>\n<li><strong>AddressInputField</strong> - 地址输入组件</li>\n<li><strong>AddressEnum</strong> - 地址枚举展示</li>\n<li><strong>FunctionSelectField</strong> - 职能选择组件</li>\n<li><strong>FunctionEnum</strong> - 职能枚举展示</li>\n<li><strong>IndustrySelectField</strong> - 行业选择组件</li>\n<li><strong>IndustryEnum</strong> - 行业枚举展示</li>\n</ol>\n<h3>方法</h3>\n<ol>\n<li><strong>changeMoneyToChinese</strong> - 将金额转化为大写的人民币金额</li>\n<li><strong>getPopupContainer</strong> - 获取弹窗容器</li>\n<li><strong>getContainerBody</strong> - 获取 body 容器</li>\n<li><strong>accept</strong> - 文件类型验证</li>\n<li><strong>createDeferred</strong> - 创建延迟对象</li>\n<li><strong>isNotEmpty</strong> - 非空判断</li>\n<li><strong>pxToNumber</strong> - px 转数字</li>\n<li><strong>numberToPx</strong> - 数字转 px</li>\n<li><strong>validateIDCard</strong> - 身份证号验证</li>\n</ol>\n<h3>HOC (高阶组件)</h3>\n<ol>\n<li><strong>withInputFile</strong> - 文件上传高阶组件</li>\n<li><strong>useFileUpload</strong> - 文件上传 Hook</li>\n<li><strong>InputFileButton</strong> - 文件上传按钮组件</li>\n<li><strong>InputFileLink</strong> - 文件上传链接组件</li>\n<li><strong>InputFileText</strong> - 文件上传文本组件</li>\n<li><strong>withOSSFile</strong> - OSS 文件上传高阶组件</li>\n</ol>\n<h3>Hooks</h3>\n<ol>\n<li><strong>useResize</strong> - 监听元素尺寸变化</li>\n<li><strong>usePreset</strong> - 获取预设配置</li>\n</ol>\n<h3>其他工具</h3>\n<ol>\n<li><strong>createTreeUtils</strong> - 创建树形数据工具函数</li>\n<li><strong>getScrollEl</strong> - 获取滚动元素</li>\n<li><strong>Scroller</strong> - 横向滚动组件</li>\n<li><strong>SelectInnerInput</strong> - 内部选择输入框基础组件</li>\n</ol>`,\n \n \n api: `<h2>FetchButton</h2>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>api</td>\n<td>API配置对象,包含loader等接口方法</td>\n<td><code>{ loader: Function }</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>modalProps</td>\n<td>弹窗属性配置函数,接收 contextProps 参数</td>\n<td><code>(contextProps) =&gt; ModalProps</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>modalFunc</td>\n<td>弹窗功能函数,接收 modalApi 参数</td>\n<td><code>(modalApi) =&gt; void</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>onError</td>\n<td>错误处理函数</td>\n<td><code>(error) =&gt; void</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>...ButtonProps</td>\n<td>继承 Button 组件所有属性</td>\n<td>-</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h2>ScrollLoader</h2>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>isLoading</td>\n<td>是否正在加载</td>\n<td><code>boolean</code></td>\n<td>false</td>\n</tr>\n<tr>\n<td>noMore</td>\n<td>是否已加载完毕</td>\n<td><code>boolean</code></td>\n<td>false</td>\n</tr>\n<tr>\n<td>onLoader</td>\n<td>加载更多回调函数</td>\n<td><code>() =&gt; Promise&lt;void&gt;</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>completeTips</td>\n<td>完成提示文本</td>\n<td><code>string</code></td>\n<td>\"没有更多了\"</td>\n</tr>\n<tr>\n<td>className</td>\n<td>样式类名</td>\n<td><code>string</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>子元素</td>\n<td><code>ReactNode</code></td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h2>SearchInput</h2>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>value</td>\n<td>输入框值</td>\n<td><code>string</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>onSearch</td>\n<td>搜索回调函数,已防抖</td>\n<td><code>(value: string) =&gt; void</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>debounce</td>\n<td>防抖延迟时间(毫秒)</td>\n<td><code>number</code></td>\n<td>500</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>占位符</td>\n<td><code>string</code></td>\n<td>\"请输入\"</td>\n</tr>\n<tr>\n<td>isPopup</td>\n<td>是否在弹窗中使用</td>\n<td><code>boolean</code></td>\n<td>false</td>\n</tr>\n<tr>\n<td>...InputProps</td>\n<td>继承 Input.Search 组件所有属性</td>\n<td>-</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h2>TreeField</h2>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>api</td>\n<td>API配置对象</td>\n<td><code>{ loader: Function }</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>value</td>\n<td>当前选中的值</td>\n<td><code>Array&lt;any&gt;</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>变化回调</td>\n<td><code>(value: Array&lt;any&gt;) =&gt; void</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>fieldNames</td>\n<td>字段名称映射</td>\n<td><code>{ key, title, children }</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>占位符</td>\n<td><code>string</code></td>\n<td>\"请选择\"</td>\n</tr>\n<tr>\n<td>single</td>\n<td>是否单选</td>\n<td><code>boolean</code></td>\n<td>false</td>\n</tr>\n<tr>\n<td>maxLength</td>\n<td>最大选择数量</td>\n<td><code>number</code></td>\n<td>MAX_VALUE</td>\n</tr>\n<tr>\n<td>isPopup</td>\n<td>是否弹窗展示</td>\n<td><code>boolean</code></td>\n<td>true</td>\n</tr>\n<tr>\n<td>checkStrictly</td>\n<td>父子节点是否不关联</td>\n<td><code>boolean</code></td>\n<td>false</td>\n</tr>\n<tr>\n<td>searchPlaceholder</td>\n<td>搜索框占位符</td>\n<td><code>string</code></td>\n<td>\"搜索\"</td>\n</tr>\n</tbody>\n</table>\n<h2>CascaderField</h2>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>api</td>\n<td>API配置对象</td>\n<td><code>{ loader: Function }</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>value</td>\n<td>当前选中的值</td>\n<td><code>Array&lt;any&gt;</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>变化回调</td>\n<td><code>(value: Array&lt;any&gt;) =&gt; void</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>占位符</td>\n<td><code>string</code></td>\n<td>\"请选择\"</td>\n</tr>\n<tr>\n<td>maxLength</td>\n<td>最大选择数量</td>\n<td><code>number</code></td>\n<td>MAX_VALUE</td>\n</tr>\n<tr>\n<td>isPopup</td>\n<td>是否弹窗展示</td>\n<td><code>boolean</code></td>\n<td>true</td>\n</tr>\n<tr>\n<td>overlayWidth</td>\n<td>弹窗宽度</td>\n<td><code>string</code></td>\n<td>\"460px\"</td>\n</tr>\n<tr>\n<td>menuItemWidth</td>\n<td>菜单项宽度</td>\n<td><code>string</code></td>\n<td>\"180px\"</td>\n</tr>\n<tr>\n<td>openLoadData</td>\n<td>是否开启懒加载</td>\n<td><code>boolean</code></td>\n<td>false</td>\n</tr>\n<tr>\n<td>onlyAllowLastLevel</td>\n<td>是否只允许选择最后一级</td>\n<td><code>boolean</code></td>\n<td>false</td>\n</tr>\n<tr>\n<td>parentIdKey</td>\n<td>父级ID字段名</td>\n<td><code>string</code></td>\n<td>\"id\"</td>\n</tr>\n<tr>\n<td>selectLevel</td>\n<td>选择层级</td>\n<td><code>number</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>searchPlaceholder</td>\n<td>搜索框占位符</td>\n<td><code>string</code></td>\n<td>\"搜索\"</td>\n</tr>\n<tr>\n<td>onSearch</td>\n<td>搜索回调函数</td>\n<td><code>(text: string, options) =&gt; Array</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>dataFormat</td>\n<td>数据格式化函数</td>\n<td><code>(data) =&gt; object</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>nodeFormat</td>\n<td>节点格式化函数</td>\n<td><code>(node) =&gt; object</code></td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h2>TypeDateRangePickerField</h2>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>value</td>\n<td>当前值,格式为 <code>{ type: string, value: [Date, Date] }</code></td>\n<td><code>object</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>变化回调</td>\n<td><code>(value: object) =&gt; void</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>占位符数组</td>\n<td><code>[string, string]</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>...RangePickerProps</td>\n<td>继承 DatePicker.RangePicker 组件所有属性</td>\n<td>-</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h2>SuperSelectField</h2>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>api</td>\n<td>API配置对象</td>\n<td><code>{ loader: Function }</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>value</td>\n<td>当前选中的值</td>\n<td><code>Array&lt;any&gt;</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>变化回调</td>\n<td><code>(value: any) =&gt; void</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>占位符</td>\n<td><code>string</code></td>\n<td>\"请选择\"</td>\n</tr>\n<tr>\n<td>getSearchProps</td>\n<td>获取搜索属性</td>\n<td><code>(text: string) =&gt; object</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>allowSelectedAll</td>\n<td>是否允许全选</td>\n<td><code>boolean</code></td>\n<td>false</td>\n</tr>\n<tr>\n<td>isPopup</td>\n<td>是否弹窗展示</td>\n<td><code>boolean</code></td>\n<td>true</td>\n</tr>\n<tr>\n<td>showSelectedTag</td>\n<td>是否显示已选中标签</td>\n<td><code>boolean</code></td>\n<td>true</td>\n</tr>\n<tr>\n<td>onConfirm</td>\n<td>确认回调</td>\n<td><code>(value) =&gt; void</code></td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h2>SuperSelectUserField</h2>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>api</td>\n<td>API配置对象</td>\n<td><code>{ loader: Function }</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>value</td>\n<td>当前选中的值</td>\n<td><code>Array&lt;any&gt;</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>变化回调</td>\n<td><code>(value: any) =&gt; void</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>占位符</td>\n<td><code>string</code></td>\n<td>\"请选择用户\"</td>\n</tr>\n<tr>\n<td>getSearchProps</td>\n<td>获取搜索属性</td>\n<td><code>(text: string) =&gt; object</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>allowSelectedAll</td>\n<td>是否允许全选</td>\n<td><code>boolean</code></td>\n<td>false</td>\n</tr>\n<tr>\n<td>labelKey</td>\n<td>标签字段名</td>\n<td><code>string</code></td>\n<td>\"label\"</td>\n</tr>\n<tr>\n<td>avatarKey</td>\n<td>头像字段名</td>\n<td><code>string</code></td>\n<td>\"avatar\"</td>\n</tr>\n<tr>\n<td>descriptionKey</td>\n<td>描述字段名</td>\n<td><code>string</code></td>\n<td>\"description\"</td>\n</tr>\n</tbody>\n</table>\n<h2>SuperSelectTableListField</h2>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>options</td>\n<td>选项数据数组</td>\n<td><code>Array&lt;object&gt;</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>columns</td>\n<td>表格列配置</td>\n<td><code>Array&lt;object&gt;</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>value</td>\n<td>当前选中的值</td>\n<td><code>Array&lt;any&gt;</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>变化回调</td>\n<td><code>(value: any) =&gt; void</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>占位符</td>\n<td><code>string</code></td>\n<td>\"请选择\"</td>\n</tr>\n<tr>\n<td>labelKey</td>\n<td>标签字段名</td>\n<td><code>string</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>valueKey</td>\n<td>值字段名</td>\n<td><code>string</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>isPopup</td>\n<td>是否弹窗展示</td>\n<td><code>boolean</code></td>\n<td>true</td>\n</tr>\n<tr>\n<td>getSearchCallback</td>\n<td>搜索回调函数</td>\n<td><code>(searchProps, item, contextProps) =&gt; boolean</code></td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h2>SuperSelectTreeField</h2>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>api</td>\n<td>API配置对象</td>\n<td><code>{ loader: Function }</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>value</td>\n<td>当前选中的值</td>\n<td><code>Array&lt;any&gt;</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>变化回调</td>\n<td><code>(value: any) =&gt; void</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>占位符</td>\n<td><code>string</code></td>\n<td>\"请选择\"</td>\n</tr>\n<tr>\n<td>...TreeProps</td>\n<td>继承 Tree 组件所有属性</td>\n<td>-</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h2>AdvancedSelectField</h2>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>api</td>\n<td>API配置对象</td>\n<td><code>{ loader: Function }</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>value</td>\n<td>当前选中的值</td>\n<td><code>Array&lt;any&gt;</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>变化回调</td>\n<td><code>(value: any) =&gt; void</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>占位符</td>\n<td><code>string</code></td>\n<td>\"请选择\"</td>\n</tr>\n<tr>\n<td>allowSelectAll</td>\n<td>是否允许全选</td>\n<td><code>boolean</code></td>\n<td>false</td>\n</tr>\n<tr>\n<td>showSelectedCount</td>\n<td>是否显示选中数量</td>\n<td><code>boolean</code></td>\n<td>false</td>\n</tr>\n<tr>\n<td>countUnit</td>\n<td>数量单位</td>\n<td><code>string</code></td>\n<td>\"个\"</td>\n</tr>\n<tr>\n<td>allLabel</td>\n<td>全选项标签</td>\n<td><code>string</code></td>\n<td>\"全部\"</td>\n</tr>\n<tr>\n<td>showSelectedTag</td>\n<td>是否显示选中标签</td>\n<td><code>boolean</code></td>\n<td>true</td>\n</tr>\n<tr>\n<td>single</td>\n<td>是否单选</td>\n<td><code>boolean</code></td>\n<td>false</td>\n</tr>\n<tr>\n<td>getSearchProps</td>\n<td>获取搜索属性</td>\n<td><code>(text: string) =&gt; object</code></td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h2>UserField (AdvancedSelect)</h2>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>api</td>\n<td>API配置对象</td>\n<td><code>{ loader: Function }</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>defaultValue</td>\n<td>默认值</td>\n<td><code>Array&lt;any&gt;</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>变化回调</td>\n<td><code>(value: any) =&gt; void</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>getSearchProps</td>\n<td>获取搜索属性</td>\n<td><code>(text: string) =&gt; object</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>allowSelectAll</td>\n<td>是否允许全选</td>\n<td><code>boolean</code></td>\n<td>false</td>\n</tr>\n<tr>\n<td>showSelectedCount</td>\n<td>是否显示选中数量</td>\n<td><code>boolean</code></td>\n<td>false</td>\n</tr>\n<tr>\n<td>countUnit</td>\n<td>数量单位</td>\n<td><code>string</code></td>\n<td>\"人\"</td>\n</tr>\n<tr>\n<td>allLabel</td>\n<td>全选项标签</td>\n<td><code>string</code></td>\n<td>\"所有人\"</td>\n</tr>\n<tr>\n<td>showSelectedTag</td>\n<td>是否显示选中标签</td>\n<td><code>boolean</code></td>\n<td>true</td>\n</tr>\n</tbody>\n</table>\n<h2>AddressEnum</h2>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>地址编码</td>\n<td><code>string</code></td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h2>FunctionEnum</h2>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>职能编码</td>\n<td><code>string</code></td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h2>IndustryEnum</h2>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>行业编码</td>\n<td><code>string</code></td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h2>InputFileButton / InputFileLink / InputFileText</h2>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>accept</td>\n<td>接受的文件类型</td>\n<td><code>string</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>multiple</td>\n<td>是否多选</td>\n<td><code>boolean</code></td>\n<td>false</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>文件选择回调</td>\n<td><code>(file: File) =&gt; void</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>...TypographyProps</td>\n<td>继承 Typography 组件所有属性</td>\n<td>-</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h2>changeMoneyToChinese</h2>\n<table>\n<thead>\n<tr>\n<th>参数名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>money</td>\n<td>金额数值</td>\n<td><code>number | string</code></td>\n</tr>\n</tbody>\n</table>\n<table>\n<thead>\n<tr>\n<th>返回值</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>chineseStr</td>\n<td>大写金额字符串</td>\n<td><code>string</code></td>\n</tr>\n</tbody>\n</table>\n<p>最大处理数字:999999999999999.999999</p>`,\n example: {\n isFull: false,\n className: `Common_d13bc`,\n style: `.Common_d13bc .scroll-list {\n max-height: 300px;\n}`,\n list: [{\n title: `FetchButton`,\n description: `Button触发加载数据,加载数据后在弹窗中展示`,\n code: `const {FetchButton} = _Common;\nconst {Typography, App} = _antd;\n\nconst {useModal} = _Modal;\n\nconst BaseExample = () => {\n const modal = useModal();\n\n return (<FetchButton\n api={{\n loader: () => {\n return [{id: 1, name: \"前端开发组\", count: 8, description: \"负责所有前端页面开发\"}, {\n id: 2,\n name: \"后端开发组\",\n count: 12,\n description: \"负责 API 和服务器开发\"\n }, {id: 3, name: \"测试组\", count: 5, description: \"负责功能测试和质量保证\"}, {\n id: 4,\n name: \"运维组\",\n count: 3,\n description: \"负责系统部署和维护\"\n },];\n },\n }}\n modalProps={(contextProps) => {\n const {data, fetchApi} = contextProps;\n return {\n title: \"团队信息\", children: (<div>\n <Typography.Paragraph>当前项目团队构成:</Typography.Paragraph>\n {data.map((item) => (<div key={item.id} style={{marginBottom: 16}}>\n <Typography.Text strong style={{fontSize: 15}}>\n {item.name}\n </Typography.Text>\n <div style={{marginTop: 4, color: '#666'}}>\n <Typography.Text>人数:{item.count} 人</Typography.Text>\n <Typography.Text style={{marginLeft: 16}}>\n 说明:{item.description}\n </Typography.Text>\n </div>\n </div>))}\n </div>),\n };\n }}\n modalFunc={modal}\n >\n 查看团队信息\n </FetchButton>);\n};\n\nrender(<BaseExample/>);\n\n`,\n scope: [{\n name: \"_Common\",\n packageName: \"@components/Common\",\n component: component_13\n},{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_14\n},{\n name: \"_antd\",\n packageName: \"antd\",\n component: component_15\n}]\n},{\n title: `Enum`,\n description: `枚举展示组件,展示地址、职能、行业等枚举信息`,\n code: `const Common = _Common;\nconst { Space } = _antd;\n\nconst { AddressEnum, FunctionEnum, IndustryEnum } = Common;\n\nconst BaseExample = () => {\n return (\n <Space direction={\"vertical\"}>\n <AddressEnum name={\"010\"} />\n <FunctionEnum name={\"010\"} />\n <IndustryEnum name={\"010\"} />\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Common\",\n packageName: \"@components/Common\",\n component: component_13\n},{\n name: \"_antd\",\n packageName: \"antd\",\n component: component_15\n}]\n},{\n title: `ScrollLoader`,\n description: `下拉滚动加载组件,配合 Fetch 实现分页加载`,\n code: `const { get, merge, range } = lodash;\nconst { ScrollLoader } = _Common;\nconst { default: Fetch } = _reactFetch;\nconst { Card, List, Avatar, Typography, Space, Tag } = _antd;\n\nconst BaseExample = () => {\n const mockUsers = [\n { name: \"张三\", avatar: \"https://api.dicebear.com/7.x/avataaars/svg?seed=zhang\", role: \"产品经理\" },\n { name: \"李四\", avatar: \"https://api.dicebear.com/7.x/avataaars/svg?seed=li\", role: \"UI设计师\" },\n { name: \"王五\", avatar: \"https://api.dicebear.com/7.x/avataaars/svg?seed=wang\", role: \"前端开发\" },\n { name: \"赵六\", avatar: \"https://api.dicebear.com/7.x/avataaars/svg?seed=zhao\", role: \"后端开发\" },\n { name: \"孙七\", avatar: \"https://api.dicebear.com/7.x/avataaars/svg?seed=sun\", role: \"测试工程师\" },\n { name: \"周八\", avatar: \"https://api.dicebear.com/7.x/avataaars/svg?seed=zhou\", role: \"运维工程师\" },\n ];\n\n const mockComments = [\n \"这个功能很实用,期待上线!\",\n \"界面设计简洁美观,用户体验不错。\",\n \"建议增加批量操作功能。\",\n \"加载速度很快,性能很好。\",\n \"文档清晰,上手容易。\",\n ];\n\n return (\n <Card title=\"团队评论列表\" style={{ maxWidth: 600 }}>\n <Fetch\n loader={({ data }) => {\n const params = Object.assign(\n {\n perPage: 10,\n currentPage: 1,\n },\n data\n );\n return new Promise((resolve) => {\n const start = (params.currentPage - 1) * params.perPage;\n setTimeout(() => {\n resolve({\n totalCount: 50,\n pageData: range(start, start + params.perPage).map((key) => {\n const user = mockUsers[key % mockUsers.length];\n const comment = mockComments[key % mockComments.length];\n const hours = Math.floor(key / 3);\n return {\n id: key + 1,\n user: user.name,\n avatar: user.avatar,\n role: user.role,\n content: comment,\n time: \\`\\${hours}小时前\\`,\n likes: Math.floor(Math.random() * 50) + 1,\n };\n }),\n });\n }, 500);\n });\n }}\n render={(fetchApi) => {\n const pagination = {\n paramsType: \"data\",\n current: \"currentPage\",\n pageSize: \"perPage\",\n defaultPageSize: 10,\n };\n const current = get(\n fetchApi.requestParams,\n [pagination.paramsType, pagination.current],\n 1\n ),\n pageSize =\n get(fetchApi.requestParams, [\n pagination.paramsType,\n pagination.pageSize,\n ]) || pagination.defaultPageSize;\n\n const formatData = {\n list: fetchApi.data.pageData || [],\n total: fetchApi.data.totalCount || 0,\n };\n return (\n <ScrollLoader\n completeTips=\"\"\n className=\"scroll-list\"\n isLoading={!fetchApi.isComplete}\n noMore={!formatData.total || current * pageSize >= formatData.total}\n onLoader={async () => {\n await fetchApi.loadMore(\n merge({\n data: {\n [pagination.pageSize]: pageSize,\n [pagination.current]: current + 1,\n },\n }),\n (data, newData) => {\n return Object.assign({}, newData, {\n pageData: data.pageData.concat(newData.pageData),\n });\n }\n );\n }}\n >\n <List\n dataSource={formatData.list}\n renderItem={(item) => (\n <List.Item style={{ padding: \"12px 0\", borderBottom: \"1px solid #f0f0f0\" }}>\n <List.Item.Meta\n avatar={<Avatar src={item.avatar} />}\n title={\n <Space>\n <Typography.Text strong>{item.user}</Typography.Text>\n <Tag color=\"blue\" style={{ fontSize: 12 }}>{item.role}</Tag>\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>{item.time}</Typography.Text>\n </Space>\n }\n description={\n <Space direction=\"vertical\" size={4}>\n <Typography.Text>{item.content}</Typography.Text>\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n 👍 {item.likes} 人赞同\n </Typography.Text>\n </Space>\n }\n />\n </List.Item>\n )}\n />\n </ScrollLoader>\n );\n }}\n />\n </Card>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Common\",\n packageName: \"@components/Common\",\n component: component_13\n},{\n name: \"_reactFetch\",\n packageName: \"@kne/react-fetch\",\n component: component_16\n},{\n name: \"lodash\",\n packageName: \"lodash\",\n component: component_17\n},{\n name: \"_antd\",\n packageName: \"antd\",\n component: component_15\n}]\n},{\n title: `SearchInput`,\n description: `提供防抖的查询输入框组件`,\n code: `const Common = _Common;\n\nconst { SearchInput } = Common;\nconst { useState } = React;\n\nconst BaseExample = () => {\n const [value, setValue] = useState(\"\");\n return (\n <SearchInput\n value={value}\n onSearch={(value) => {\n setValue(value);\n console.log(value);\n }}\n />\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Common\",\n packageName: \"@components/Common\",\n component: component_13\n}]\n},{\n title: `AdvancedSelect`,\n description: `高级选择组件,支持用户选择、列表选择等功能`,\n code: `const { UserField } = _Common;\nconst { Space, Typography } = _antd;\n\nconst BaseExample = () => {\n const [value, setValue] = React.useState([]);\n\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text>\n 已选择 {value.length} 人\n </Typography.Text>\n <UserField\n value={value}\n onChange={setValue}\n getSearchProps={(text) => {\n return {\n data: { keyword: text },\n };\n }}\n allowSelectAll\n showSelectedCount\n countUnit=\"人\"\n allLabel=\"所有人\"\n placeholder=\"选择团队成员\"\n api={{\n loader: () => {\n return {\n pageData: [\n {\n label: \"张三\",\n value: 1,\n avatar: \"avatar-001\",\n description: \"前端工程师\",\n },\n {\n label: \"李四\",\n value: 2,\n avatar: \"avatar-002\",\n description: \"后端工程师\",\n },\n {\n label: \"王五\",\n value: 3,\n avatar: \"avatar-003\",\n description: \"产品经理\",\n },\n {\n label: \"赵六\",\n value: 4,\n avatar: \"avatar-004\",\n description: \"UI设计师\",\n },\n {\n label: \"钱七\",\n value: 5,\n avatar: \"avatar-005\",\n description: \"测试工程师\",\n },\n ],\n };\n },\n }}\n />\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Common\",\n packageName: \"@components/Common\",\n component: component_13\n},{\n name: \"_antd\",\n packageName: \"antd\",\n component: component_15\n}]\n},{\n title: `SuperSelect`,\n description: `新版高级选择组件,提供更强的自定义能力`,\n code: `const { SuperSelectField, SuperSelectTableListField, SuperSelectUserField } = _Common;\nconst { Space, Typography } = _antd;\nconst { useState } = React;\n\nconst BaseExample = () => {\n const [userValue, setUserValue] = useState([]);\n const [deptValue, setDeptValue] = useState([]);\n\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text strong>用户选择</Typography.Text>\n <SuperSelectUserField\n value={userValue}\n onChange={setUserValue}\n allowSelectedAll\n placeholder=\"选择用户\"\n api={{\n loader: () => {\n return {\n pageData: [\n {\n label: \"张三\",\n value: 1,\n avatar: { src: \"https://api.dicebear.com/7.x/avataaars/svg?seed=zhang\" },\n description: \"高级前端工程师\",\n },\n {\n label: \"李四\",\n value: 2,\n avatar: { src: \"https://api.dicebear.com/7.x/avataaars/svg?seed=li\" },\n description: \"资深后端工程师\",\n },\n {\n label: \"王五\",\n value: 3,\n avatar: { src: \"https://api.dicebear.com/7.x/avataaars/svg?seed=wang\" },\n description: \"产品经理\",\n },\n {\n label: \"赵六\",\n value: 4,\n avatar: { src: \"https://api.dicebear.com/7.x/avataaars/svg?seed=zhao\" },\n description: \"UI设计师\",\n },\n {\n label: \"钱七\",\n value: 5,\n avatar: { src: \"https://api.dicebear.com/7.x/avataaars/svg?seed=qian\" },\n description: \"测试工程师\",\n },\n ],\n };\n },\n }}\n />\n\n <Typography.Text strong>部门选择</Typography.Text>\n <SuperSelectField\n isPopup={false}\n value={deptValue}\n onChange={setDeptValue}\n allowSelectedAll\n placeholder=\"选择部门\"\n api={{\n loader: () => {\n return {\n pageData: [\n {\n label: \"技术部\",\n value: \"tech\",\n description: \"负责产品技术实现\",\n },\n {\n label: \"产品部\",\n value: \"product\",\n description: \"负责产品规划和设计\",\n },\n {\n label: \"设计部\",\n value: \"design\",\n description: \"负责 UI/UX 设计\",\n },\n {\n label: \"市场部\",\n value: \"marketing\",\n description: \"负责市场推广和运营\",\n },\n ],\n };\n },\n }}\n />\n\n <Typography.Text strong>项目列表选择</Typography.Text>\n <SuperSelectTableListField\n isPopup={false}\n labelKey=\"name\"\n valueKey=\"id\"\n placeholder=\"选择项目\"\n getSearchCallback={(searchProps, item, contextProps) => {\n const { props } = contextProps;\n const { labelKey } = props;\n if (!searchProps.searchText) {\n return true;\n }\n return item[labelKey].indexOf(searchProps.searchText) > -1;\n }}\n options={[\n { id: 1, name: \"电商平台\", count: 15, description: \"在线购物平台\", disabled: false },\n { id: 2, name: \"OA系统\", count: 8, description: \"办公自动化系统\", disabled: true },\n { id: 3, name: \"CRM系统\", count: 10, description: \"客户关系管理\", disabled: false },\n { id: 4, name: \"数据大屏\", count: 5, description: \"数据可视化展示\", disabled: false },\n { id: 5, name: \"移动APP\", count: 12, description: \"移动端应用\", disabled: false },\n { id: 6, name: \"小程序\", count: 6, description: \"微信小程序\", disabled: false },\n ]}\n columns={[\n {\n name: \"name\",\n title: \"项目名称\",\n span: 8,\n },\n {\n name: \"count\",\n title: \"团队人数\",\n span: 8,\n },\n {\n name: \"description\",\n title: \"项目描述\",\n span: 8,\n },\n ]}\n />\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Common\",\n packageName: \"@components/Common\",\n component: component_13\n},{\n name: \"_antd\",\n packageName: \"antd\",\n component: component_15\n}]\n},{\n title: `TreeField`,\n description: `树形选择组件,支持单选和多选`,\n code: `const { TreeField } = _Common;\nconst { Space, Typography, Button } = _antd;\nconst { useState } = React;\n\nconst BaseExample = () => {\n const [value, setValue] = useState([]);\n\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text strong>组织架构选择(多选)</Typography.Text>\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n 已选择: {value.length} 个部门\n </Typography.Text>\n <TreeField\n api={{\n loader: () => {\n return [\n {\n key: 'tech',\n title: '技术部',\n children: [\n {\n key: 'frontend',\n title: '前端组',\n children: [\n { key: 'fe-web', title: 'Web前端' },\n { key: 'fe-mobile', title: '移动端' },\n ],\n },\n {\n key: 'backend',\n title: '后端组',\n children: [\n { key: 'be-java', title: 'Java后端' },\n { key: 'be-node', title: 'Node.js后端' },\n ],\n },\n ],\n },\n {\n key: 'product',\n title: '产品部',\n children: [\n { key: 'pm-web', title: 'Web产品' },\n { key: 'pm-mobile', title: '移动产品' },\n ],\n },\n {\n key: 'design',\n title: '设计部',\n children: [\n { key: 'ui', title: 'UI设计' },\n { key: 'ux', title: 'UX设计' },\n ],\n },\n {\n key: 'marketing',\n title: '市场部',\n children: [\n { key: 'market', title: '市场推广' },\n { key: 'operation', title: '运营' },\n ],\n },\n ];\n },\n }}\n value={value}\n onChange={setValue}\n placeholder=\"请选择部门\"\n single={false}\n />\n <Button onClick={() => setValue([])}>清空选择</Button>\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Common\",\n packageName: \"@components/Common\",\n component: component_13\n},{\n name: \"_antd\",\n packageName: \"antd\",\n component: component_15\n}]\n},{\n title: `CascaderField`,\n description: `级联选择组件,支持多级联动选择`,\n code: `const { CascaderField } = _Common;\nconst { Space, Typography, Button } = _antd;\nconst { useState } = React;\n\nconst BaseExample = () => {\n const [value, setValue] = useState([]);\n\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text strong>省市区级联选择(最多3个)</Typography.Text>\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n 已选择: {value.length} 个区域\n </Typography.Text>\n <CascaderField\n api={{\n loader: () => {\n return [\n {\n id: 'zhejiang',\n label: '浙江省',\n children: [\n {\n id: 'hangzhou',\n label: '杭州市',\n children: [\n { id: 'xihu', label: '西湖区' },\n { id: 'gongshu', label: '拱墅区' },\n { id: 'jianggan', label: '江干区' },\n { id: 'binjiang', label: '滨江区' },\n ],\n },\n {\n id: 'ningbo',\n label: '宁波市',\n children: [\n { id: 'haishu', label: '海曙区' },\n { id: 'jiangbei', label: '江北区' },\n { id: 'yinzhou', label: '鄞州区' },\n ],\n },\n ],\n },\n {\n id: 'jiangsu',\n label: '江苏省',\n children: [\n {\n id: 'nanjing',\n label: '南京市',\n children: [\n { id: 'xuanwu', label: '玄武区' },\n { id: 'jianye', label: '建邺区' },\n { id: 'gulou', label: '鼓楼区' },\n ],\n },\n {\n id: 'suzhou',\n label: '苏州市',\n children: [\n { id: 'gusu', label: '姑苏区' },\n { id: 'wuzhong', label: '吴中区' },\n ],\n },\n ],\n },\n {\n id: 'guangdong',\n label: '广东省',\n children: [\n {\n id: 'guangzhou',\n label: '广州市',\n children: [\n { id: 'yuexiu', label: '越秀区' },\n { id: 'tianhe', label: '天河区' },\n { id: 'baiyun', label: '白云区' },\n ],\n },\n {\n id: 'shenzhen',\n label: '深圳市',\n children: [\n { id: 'futian', label: '福田区' },\n { id: 'nanshan', label: '南山区' },\n { id: 'baoan', label: '宝安区' },\n ],\n },\n ],\n },\n ];\n },\n }}\n value={value}\n onChange={setValue}\n placeholder=\"请选择省市区\"\n maxLength={3}\n isPopup={true}\n />\n <Button onClick={() => setValue([])}>清空选择</Button>\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Common\",\n packageName: \"@components/Common\",\n component: component_13\n},{\n name: \"_antd\",\n packageName: \"antd\",\n component: component_15\n}]\n},{\n title: `TypeDateRangePicker`,\n description: `类型日期范围选择器,支持按日、周、月选择`,\n code: `const { TypeDateRangePickerField } = _Common;\nconst { Space, Typography } = _antd;\nconst { useState } = React;\n\nconst BaseExample = () => {\n const [value, setValue] = useState({\n type: 'date',\n value: [],\n });\n\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text>当前值: {JSON.stringify(value)}</Typography.Text>\n <TypeDateRangePickerField\n value={value}\n onChange={setValue}\n placeholder={['开始日期', '结束日期']}\n />\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Common\",\n packageName: \"@components/Common\",\n component: component_13\n},{\n name: \"_antd\",\n packageName: \"antd\",\n component: component_15\n}]\n},{\n title: `InputFile`,\n description: `文件上传组件,支持按钮、链接、文本等多种形式`,\n code: `const { InputFileButton, InputFileLink, InputFileText } = _Common;\nconst { Space, Typography, message, Alert } = _antd;\n\nconst BaseExample = () => {\n const handleFileChange = (file) => {\n console.log('选择的文件:', file);\n const sizeInMB = (file.size / 1024 / 1024).toFixed(2);\n message.success(\\`已选择文件: \\${file.name} (\\${sizeInMB}MB)\\`);\n };\n\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text strong>文件上传组件示例</Typography.Text>\n <Alert\n message=\"支持上传图片(JPG、PNG)和 PDF 文档,单个文件不超过 10MB\"\n type=\"info\"\n showIcon\n style={{ marginBottom: 16 }}\n />\n <Typography.Text>按钮形式上传:</Typography.Text>\n <InputFileButton\n accept=\".jpg,.png,.pdf\"\n onChange={handleFileChange}\n >\n 点击上传文件\n </InputFileButton>\n\n <Typography.Text style={{ marginTop: 8 }}>链接形式上传:</Typography.Text>\n <InputFileLink\n accept=\".jpg,.png,.pdf\"\n onChange={handleFileChange}\n >\n 选择要上传的文件\n </InputFileLink>\n\n <Typography.Text style={{ marginTop: 8 }}>文本形式上传:</Typography.Text>\n <InputFileText\n accept=\".jpg,.png,.pdf\"\n onChange={handleFileChange}\n >\n 浏览文件\n </InputFileText>\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Common\",\n packageName: \"@components/Common\",\n component: component_13\n},{\n name: \"_antd\",\n packageName: \"antd\",\n component: component_15\n}]\n},{\n title: `changeMoneyToChinese`,\n description: `金额转大写中文工具函数`,\n code: `const { changeMoneyToChinese } = _Common;\nconst { Space, Typography, Input, Button, Card } = _antd;\nconst { useState } = React;\n\nconst BaseExample = () => {\n const [amount, setAmount] = useState('');\n const chineseAmount = changeMoneyToChinese(amount);\n\n return (\n <Space direction=\"vertical\" style={{ width: '400px' }}>\n <Typography.Text strong style={{ fontSize: 16 }}>\n 金额转大写中文\n </Typography.Text>\n <Input\n placeholder=\"请输入金额\"\n value={amount}\n onChange={(e) => setAmount(e.target.value)}\n type=\"number\"\n prefix=\"¥\"\n size=\"large\"\n addonAfter=\"元\"\n />\n <Card size=\"small\" style={{ marginTop: 8 }}>\n <Typography.Text strong style={{ fontSize: 14 }}>\n 大写金额:\n </Typography.Text>\n <Typography.Text\n style={{\n fontSize: 18,\n fontWeight: 500,\n marginLeft: 8,\n color: '#1890ff'\n }}\n >\n {chineseAmount || '等待输入...'}\n </Typography.Text>\n </Card>\n <Space wrap>\n <Button onClick={() => setAmount('123456.78')}>\n 常用金额:123,456.78\n </Button>\n <Button onClick={() => setAmount('10000')}>\n 整数:10,000\n </Button>\n <Button onClick={() => setAmount('0')}>\n 零值:0\n </Button>\n <Button onClick={() => setAmount('')}>\n 清空\n </Button>\n </Space>\n <Typography.Text type=\"secondary\" style={{ fontSize: 12 }}>\n * 最大支持金额:999,999,999,999,999.999999\n </Typography.Text>\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Common\",\n packageName: \"@components/Common\",\n component: component_13\n},{\n name: \"_antd\",\n packageName: \"antd\",\n component: component_15\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_5 from '@components/Drawer';\nimport * as component_6 from '@components/Global';\nimport * as component_7 from 'antd';\nimport * as component_8 from 'lodash';\nimport * as component_9 from '@components/FormInfo';\nconst readmeConfig = {\n name: `Drawer`,\n summary: `<p>屏幕边缘滑出的浮层面板,适用于展示详细信息、表单编辑、数据查看等场景。支持三种使用方式:受控组件、Hook 调用、按钮触发。</p>\n<p>核心特性包括:</p>\n<ul>\n<li><strong>灵活的打开方式</strong>:支持受控模式、函数调用和按钮触发三种方式</li>\n<li><strong>多种尺寸规格</strong>:提供 small(600px)、default(1000px)、large(全屏-64px)三种预设尺寸</li>\n<li><strong>丰富的自定义能力</strong>:支持自定义底部按钮、装饰器修饰、异步操作等</li>\n<li><strong>数据加载集成</strong>:DrawerButton 组件结合数据加载,自动在加载完成后打开抽屉</li>\n<li><strong>优雅的交互体验</strong>:内置滚动条美化、加载状态支持、异步操作反馈</li>\n</ul>\n<p>适用于用户详情查看、表单编辑、信息展示、操作确认等多种业务场景。</p>`,\n \n \n api: `<h3>Drawer</h3>\n<p>屏幕边缘滑出的浮层面板,用于展示详细信息、表单编辑等场景。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>title</td>\n<td>抽屉标题</td>\n<td>ReactNode</td>\n<td>-</td>\n</tr>\n<tr>\n<td>size</td>\n<td>抽屉尺寸,可选值:<code>small</code>(600px)、<code>default</code>(1000px)、<code>large</code>(calc(100vw-64px))</td>\n<td>string</td>\n<td><code>small</code></td>\n</tr>\n<tr>\n<td>children</td>\n<td>抽屉内容,可以是 JSX 或函数,函数时可接收 close 方法和 props</td>\n<td>ReactNode | function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>footer</td>\n<td>抽屉底部内容,设为 null 且 footerButtons 未设置时不显示底部,函数时可接收 close 方法和 props</td>\n<td>ReactNode | function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>footerButtons</td>\n<td>底部按钮配置数组,默认显示\"取消\"和\"确定\"按钮</td>\n<td>array</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onConfirm</td>\n<td>点击确认按钮触发的回调,返回 Promise 时按钮显示 loading 状态,返回 false 时不关闭抽屉</td>\n<td>function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onCancel</td>\n<td>点击取消按钮触发的回调</td>\n<td>function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onClose</td>\n<td>抽屉关闭时的回调</td>\n<td>function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>closable</td>\n<td>是否显示关闭按钮</td>\n<td>boolean</td>\n<td>true</td>\n</tr>\n<tr>\n<td>maskClosable</td>\n<td>点击蒙层是否允许关闭</td>\n<td>boolean</td>\n<td>false</td>\n</tr>\n<tr>\n<td>disabledScroller</td>\n<td>是否禁用滚动条美化</td>\n<td>boolean</td>\n<td>false</td>\n</tr>\n<tr>\n<td>withDecorator</td>\n<td>抽屉内容修饰器,可在内容外层添加装饰</td>\n<td>function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>open</td>\n<td>受控模式下抽屉的显示状态</td>\n<td>boolean</td>\n<td>-</td>\n</tr>\n<tr>\n<td>width</td>\n<td>自定义抽屉宽度</td>\n<td>string | number</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<p><strong>注意</strong>:其他未列出的属性可参考 Ant Design Drawer 组件</p>\n<h4>footerButtons 数组项说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>children</td>\n<td>按钮文字</td>\n<td>ReactNode</td>\n<td>-</td>\n</tr>\n<tr>\n<td>type</td>\n<td>按钮类型,参考 Ant Design Button</td>\n<td>string</td>\n<td>-</td>\n</tr>\n<tr>\n<td>danger</td>\n<td>是否为危险按钮</td>\n<td>boolean</td>\n<td>false</td>\n</tr>\n<tr>\n<td>ButtonComponent</td>\n<td>自定义按钮组件</td>\n<td>Component</td>\n<td>LoadingButton</td>\n</tr>\n<tr>\n<td>onClick</td>\n<td>点击事件回调</td>\n<td>function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>autoClose</td>\n<td>点击后是否自动关闭抽屉</td>\n<td>boolean</td>\n<td>true</td>\n</tr>\n<tr>\n<td>display</td>\n<td>是否显示该按钮</td>\n<td>boolean | function</td>\n<td>true</td>\n</tr>\n</tbody>\n</table>\n<h3>useDrawer</h3>\n<p>用于获取一个可以调用 Drawer 的 Hook 函数,配合 AppDrawer 使用。</p>\n<h4>返回值</h4>\n<p>返回一个数组:<code>[drawer, DrawerContextHolder]</code></p>\n<ul>\n<li>\n<p><strong>drawer</strong>: 函数,执行后可打开一个 Drawer,参数同 Drawer 组件属性</p>\n<ul>\n<li>返回对象包含 <code>destroy</code> 方法用于关闭 Drawer</li>\n<li>返回对象包含 <code>update</code> 方法用于更新 Drawer 配置</li>\n</ul>\n</li>\n<li>\n<p><strong>DrawerContextHolder</strong>: 必须渲染在组件树中,用于承载 Drawer 实例</p>\n</li>\n</ul>\n<h3>DrawerButton</h3>\n<p>结合 FetchButton 功能的按钮组件,点击后加载数据,加载完成后自动打开 Drawer。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>api</td>\n<td>FetchButton 的 API 配置对象</td>\n<td><code>{ loader: Function }</code></td>\n<td>-</td>\n</tr>\n<tr>\n<td>modalProps</td>\n<td>Drawer 属性配置,可以是对象或函数</td>\n<td>object | function({ data, fetchApi, close })</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onError</td>\n<td>数据加载错误回调</td>\n<td>function</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<p><strong>注意</strong>:其他属性同 Ant Design Button 组件</p>\n<h4>modalProps 为函数时的参数说明</h4>\n<table>\n<thead>\n<tr>\n<th>参数名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>data</td>\n<td>加载的数据</td>\n<td>any</td>\n</tr>\n<tr>\n<td>fetchApi</td>\n<td>Fetch API 对象</td>\n<td>object</td>\n</tr>\n<tr>\n<td>close</td>\n<td>关闭 Drawer 的方法</td>\n<td>function</td>\n</tr>\n</tbody>\n</table>\n<h3>AppDrawer</h3>\n<p>全局 Drawer 提供者组件,为内部使用 useDrawer 的组件提供上下文环境。</p>\n<h4>使用方式</h4>\n<p>在应用最外层包裹 AppDrawer,即可在任意组件中使用 useDrawer:</p>\n<pre><code class=\"language-javascript\">import { AppDrawer } from '@components/Drawer';\n\nfunction App() {\n return (\n &lt;AppDrawer&gt;\n &lt;YourAppContent /&gt;\n &lt;/AppDrawer&gt;\n );\n}\n</code></pre>`,\n example: {\n isFull: false,\n className: ``,\n style: ``,\n list: [{\n title: `基础用法`,\n description: `展示 Drawer 组件的三种使用方式:受控组件、Hook调用、按钮触发`,\n code: `const { default: Drawer, useDrawer, DrawerButton } = _Drawer;\nconst { Button, Space, Typography, Descriptions, Avatar, Tag } = _antd;\nconst { useState } = React;\nconst {default: Global} = _Global;\n\nconst BasicExample = () => {\n const [open, setOpen] = useState(false);\n const drawer = useDrawer();\n\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text strong>方式一:受控组件</Typography.Text>\n <Button type=\"primary\" onClick={() => setOpen(true)}>\n 打开详情抽屉\n </Button>\n <Drawer\n title=\"用户信息\"\n open={open}\n onClose={() => setOpen(false)}\n width={600}\n >\n <Descriptions column={1} bordered>\n <Descriptions.Item label=\"姓名\">张三</Descriptions.Item>\n <Descriptions.Item label=\"部门\">技术部</Descriptions.Item>\n <Descriptions.Item label=\"职位\">高级前端工程师</Descriptions.Item>\n <Descriptions.Item label=\"邮箱\">zhangsan@example.com</Descriptions.Item>\n </Descriptions>\n </Drawer>\n\n <Typography.Text strong>方式二:Hook调用</Typography.Text>\n <Button\n onClick={() => {\n drawer({\n title: \"项目信息\",\n children: (\n <div>\n <Typography.Paragraph>项目名称:电商平台</Typography.Paragraph>\n <Typography.Paragraph>项目负责人:李四</Typography.Paragraph>\n <Typography.Paragraph>开发周期:6个月</Typography.Paragraph>\n <Typography.Paragraph>团队成员:12人</Typography.Paragraph>\n </div>\n ),\n });\n }}\n >\n 使用Hook打开\n </Button>\n </Space>\n );\n};\n\nrender(<Global><BasicExample /></Global>);\n\n`,\n scope: [{\n name: \"_Drawer\",\n packageName: \"@components/Drawer\",\n component: component_5\n},{\n name: \"_Global\",\n packageName: \"@components/Global\",\n component: component_6\n},{\n name: \"_antd\",\n packageName: \"antd\",\n component: component_7\n}]\n},{\n title: `用户详情`,\n description: `使用 DrawerButton 加载数据后展示用户详细信息,模拟真实业务场景`,\n code: `const { DrawerButton } = _Drawer;\nconst { Card, Avatar, Typography, Tag, Space, Divider, Descriptions, Timeline } = _antd;\nconst { range } = lodash;\nconst {default: Global} = _Global;\n\nconst UserDetailExample = () => {\n const mockUserData = {\n id: 1,\n name: \"张三\",\n avatar: { src: \"https://api.dicebear.com/7.x/avataaars/svg?seed=zhang\" },\n role: \"高级前端工程师\",\n department: \"技术部-前端组\",\n email: \"zhangsan@company.com\",\n phone: \"138****8888\",\n joinDate: \"2020-03-15\",\n skills: [\"React\", \"Vue\", \"TypeScript\", \"Node.js\"],\n projects: [\n { name: \"电商平台重构\", role: \"负责人\", status: \"进行中\", date: \"2024-01\" },\n { name: \"OA系统开发\", role: \"核心开发\", status: \"已完成\", date: \"2023-08\" },\n { name: \"数据大屏\", role: \"参与\", status: \"已完成\", date: \"2023-03\" },\n ],\n performance: [\n { quarter: \"2024 Q1\", score: 95, comment: \"工作表现优异,项目交付及时\" },\n { quarter: \"2023 Q4\", score: 92, comment: \"技术能力强,团队协作好\" },\n { quarter: \"2023 Q3\", score: 88, comment: \"稳步提升,建议加强文档能力\" },\n ],\n };\n\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <DrawerButton\n type=\"primary\"\n api={{\n loader: () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve(mockUserData);\n }, 800);\n });\n },\n }}\n modalProps={(contextProps) => {\n const { data } = contextProps;\n return {\n title: \"员工档案详情\",\n size: \"large\",\n children: (\n <div>\n <Card style={{ marginBottom: 16 }}>\n <Space align=\"start\" size=\"large\">\n <Avatar size={80} src={data.avatar.src} />\n <Space direction=\"vertical\" size={4}>\n <Typography.Title level={4} style={{ margin: 0 }}>\n {data.name}\n </Typography.Title>\n <Space>\n <Tag color=\"blue\">{data.role}</Tag>\n <Tag color=\"green\">{data.department}</Tag>\n </Space>\n <Typography.Text type=\"secondary\">\n 入职时间:{data.joinDate}\n </Typography.Text>\n </Space>\n </Space>\n </Card>\n\n <Descriptions title=\"基本信息\" column={2} bordered style={{ marginBottom: 16 }}>\n <Descriptions.Item label=\"工号\">EMP{String(data.id).padStart(4, '0')}</Descriptions.Item>\n <Descriptions.Item label=\"姓名\">{data.name}</Descriptions.Item>\n <Descriptions.Item label=\"部门\">{data.department}</Descriptions.Item>\n <Descriptions.Item label=\"职位\">{data.role}</Descriptions.Item>\n <Descriptions.Item label=\"邮箱\">{data.email}</Descriptions.Item>\n <Descriptions.Item label=\"电话\">{data.phone}</Descriptions.Item>\n </Descriptions>\n\n <Typography.Title level={5}>技术栈</Typography.Title>\n <Space wrap style={{ marginBottom: 16 }}>\n {data.skills.map((skill) => (\n <Tag key={skill} color=\"processing\">{skill}</Tag>\n ))}\n </Space>\n\n <Typography.Title level={5}>项目经历</Typography.Title>\n <Card size=\"small\" style={{ marginBottom: 16 }}>\n {data.projects.map((project, index) => (\n <div key={index}>\n <Space>\n <Typography.Text strong>{project.name}</Typography.Text>\n <Tag color={project.status === \"进行中\" ? \"processing\" : \"success\"}>\n {project.status}\n </Tag>\n </Space>\n <Typography.Text type=\"secondary\" style={{ marginLeft: 16 }}>\n {project.role} · {project.date}\n </Typography.Text>\n {index < data.projects.length - 1 && <Divider style={{ margin: \"8px 0\" }} />}\n </div>\n ))}\n </Card>\n\n <Typography.Title level={5}>绩效考核</Typography.Title>\n <Timeline\n items={data.performance.map((item) => ({\n children: (\n <Space direction=\"vertical\" size={2}>\n <Space>\n <Typography.Text strong>{item.quarter}</Typography.Text>\n <Tag color={item.score >= 90 ? \"success\" : \"warning\"}>\n {item.score}分\n </Tag>\n </Space>\n <Typography.Text type=\"secondary\">{item.comment}</Typography.Text>\n </Space>\n ),\n }))}\n />\n </div>\n ),\n };\n }}\n >\n 查看员工档案\n </DrawerButton>\n </Space>\n );\n};\n\nrender(<Global><UserDetailExample /></Global>);\n\n`,\n scope: [{\n name: \"_Drawer\",\n packageName: \"@components/Drawer\",\n component: component_5\n},{\n name: \"_Global\",\n packageName: \"@components/Global\",\n component: component_6\n},{\n name: \"_antd\",\n packageName: \"antd\",\n component: component_7\n},{\n name: \"lodash\",\n packageName: \"lodash\",\n component: component_8\n}]\n},{\n title: `表单编辑`,\n description: `在 Drawer 中展示表单进行编辑,支持确认和取消操作`,\n code: `const {useFormDrawer, FormDrawerButton, default: FormInfo} = _FormInfo;\nconst {Button, Space, Typography, message, Divider} = _antd;\nconst {default: Global} = _Global;\n\nconst FormDrawerExample = () => {\n const formDrawer = useFormDrawer();\n const {Form} = FormInfo;\n const {Input} = FormInfo.fields;\n\n const handleEdit = (userData) => {\n formDrawer({\n title: \"编辑员工信息\", size: \"small\", formProps: {\n data: userData, onSubmit: async (data) => {\n await new Promise((resolve) => setTimeout(resolve, 1000));\n message.success(\\`已更新员工信息:\\${data.name}\\`);\n }\n }, children: (<FormInfo\n column={1}\n list={[<Input\n name=\"name\"\n label=\"姓名\"\n rule=\"REQ\"\n tips=\"请输入员工姓名\"\n />, <Input\n name=\"department\"\n label=\"部门\"\n rule=\"REQ\"\n options={[{label: \"技术部\", value: \"tech\"}, {\n label: \"产品部\",\n value: \"product\"\n }, {label: \"设计部\", value: \"design\"}, {label: \"市场部\", value: \"marketing\"}]}\n single\n tips=\"请选择所属部门\"\n />, <Input\n name=\"position\"\n label=\"职位\"\n rule=\"REQ\"\n tips=\"请输入职位名称\"\n />, <Input\n name=\"email\"\n label=\"邮箱\"\n rule=\"REQ EMAIL\"\n tips=\"请输入有效的邮箱地址\"\n />, <Input\n name=\"phone\"\n label=\"电话\"\n rule=\"REQ TEL\"\n tips=\"请输入有效的手机号码\"\n />]}\n />)\n });\n };\n\n return (<Space direction=\"vertical\" style={{width: '100%'}}>\n <Typography.Text strong>使用 useFormDrawer 编辑员工信息</Typography.Text>\n <Typography.Text type=\"secondary\" style={{fontSize: 12}}>\n FormDrawer 结合了 Drawer 和 FormInfo 的功能,提供了更便捷的表单抽屉体验,支持校验规则和自动数据加载\n </Typography.Text>\n\n <Divider/>\n\n <Button\n type=\"primary\"\n onClick={() => {\n handleEdit({\n name: \"张三\",\n department: \"tech\",\n position: \"高级前端工程师\",\n email: \"zhangsan@example.com\",\n phone: \"13888888888\",\n });\n }}\n >\n 编辑员工信息\n </Button>\n <Button\n onClick={() => {\n handleEdit({\n name: \"李四\",\n department: \"product\",\n position: \"产品经理\",\n email: \"lisi@example.com\",\n phone: \"13999999999\",\n });\n }}\n >\n 编辑另一位员工\n </Button>\n </Space>);\n};\n\nrender(<Global><FormDrawerExample/></Global>);\n\n`,\n scope: [{\n name: \"_Drawer\",\n packageName: \"@components/Drawer\",\n component: component_5\n},{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_9\n},{\n name: \"_Global\",\n packageName: \"@components/Global\",\n component: component_6\n},{\n name: \"_antd\",\n packageName: \"antd\",\n component: component_7\n}]\n},{\n title: `不同尺寸`,\n description: `展示 small、default、large 三种不同尺寸的 Drawer`,\n code: `const { useDrawer } = _Drawer;\nconst { Button, Space, Typography, Descriptions, Timeline, Card } = _antd;\nconst {default: Global} = _Global;\n\nconst SizesExample = () => {\n const drawer = useDrawer();\n\n const content1 = (\n <Descriptions column={1} bordered>\n <Descriptions.Item label=\"项目名称\">OA系统</Descriptions.Item>\n <Descriptions.Item label=\"负责人\">张三</Descriptions.Item>\n <Descriptions.Item label=\"开始时间\">2024-01-01</Descriptions.Item>\n <Descriptions.Item label=\"状态\">进行中</Descriptions.Item>\n <Descriptions.Item label=\"进度\">60%</Descriptions.Item>\n </Descriptions>\n );\n\n const content2 = (\n <div>\n <Typography.Paragraph>\n <strong>项目概述:</strong>\n 这是一个企业办公自动化系统,提供包括审批流程、日程管理、文档协作等功能。\n </Typography.Paragraph>\n <Descriptions column={2} bordered style={{ marginTop: 16 }}>\n <Descriptions.Item label=\"项目经理\">李四</Descriptions.Item>\n <Descriptions.Item label=\"技术负责人\">王五</Descriptions.Item>\n <Descriptions.Item label=\"开发周期\">6个月</Descriptions.Item>\n <Descriptions.Item label=\"团队规模\">12人</Descriptions.Item>\n <Descriptions.Item label=\"预算\">50万</Descriptions.Item>\n <Descriptions.Item label=\"截止时间\">2024-06-30</Descriptions.Item>\n </Descriptions>\n <Typography.Title level={5} style={{ marginTop: 24 }}>\n 项目里程碑\n </Typography.Title>\n <Timeline\n items={[\n {\n children: \"需求分析与设计完成\",\n color: \"green\",\n },\n {\n children: \"前端框架搭建完成\",\n color: \"green\",\n },\n {\n children: \"后端接口开发进行中\",\n color: \"blue\",\n },\n {\n children: \"系统联调测试\",\n color: \"gray\",\n },\n {\n children: \"上线部署\",\n color: \"gray\",\n },\n ]}\n />\n </div>\n );\n\n const content3 = (\n <div>\n <Card title=\"项目基本信息\" style={{ marginBottom: 16 }}>\n <Descriptions column={3} bordered>\n <Descriptions.Item label=\"项目名称\">电商平台重构</Descriptions.Item>\n <Descriptions.Item label=\"项目编号\">PRJ-2024-001</Descriptions.Item>\n <Descriptions.Item label=\"项目类型\">重构升级</Descriptions.Item>\n <Descriptions.Item label=\"负责人\">赵六</Descriptions.Item>\n <Descriptions.Item label=\"开发团队\">技术部</Descriptions.Item>\n <Descriptions.Item label=\"优先级\">P0</Descriptions.Item>\n </Descriptions>\n </Card>\n\n <Card title=\"团队成员\" style={{ marginBottom: 16 }}>\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n {[\n { name: \"张三\", role: \"技术负责人\", count: 8 },\n { name: \"李四\", role: \"前端组长\", count: 12 },\n { name: \"王五\", role: \"后端组长\", count: 15 },\n { name: \"赵六\", role: \"测试负责人\", count: 6 },\n { name: \"钱七\", role: \"UI设计师\", count: 3 },\n ].map((member) => (\n <div key={member.name} style={{ display: 'flex', justifyContent: 'space-between', padding: '8px 0', borderBottom: '1px solid #f0f0f0' }}>\n <span><strong>{member.name}</strong> - {member.role}</span>\n <span>{member.count} 人</span>\n </div>\n ))}\n </Space>\n </Card>\n\n <Card title=\"技术架构\">\n <Space wrap>\n {[\"React\", \"TypeScript\", \"Next.js\", \"Node.js\", \"PostgreSQL\", \"Redis\", \"Docker\", \"Kubernetes\"].map((tech) => (\n <span key={tech} style={{ padding: '4px 12px', background: '#e6f7ff', borderRadius: '4px', color: '#1890ff' }}>\n {tech}\n </span>\n ))}\n </Space>\n </Card>\n\n <Card title=\"开发计划\" style={{ marginTop: 16 }}>\n <Timeline\n items={[\n {\n children: <><strong>第一阶段(1-2月):</strong>技术调研与架构设计</>,\n color: \"green\",\n },\n {\n children: <><strong>第二阶段(3-4月):</strong>核心功能开发</>,\n color: \"green\",\n },\n {\n children: <><strong>第三阶段(5月):</strong>联调测试与优化</>,\n color: \"blue\",\n },\n {\n children: <><strong>第四阶段(6月):</strong>灰度发布与上线</>,\n color: \"gray\",\n },\n ]}\n />\n </Card>\n </div>\n );\n\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text strong>选择不同尺寸的抽屉</Typography.Text>\n <Button\n onClick={() => {\n drawer({\n title: \"Small 尺寸\",\n size: \"small\",\n children: content1,\n });\n }}\n >\n Small (600px)\n </Button>\n <Button\n onClick={() => {\n drawer({\n title: \"Default 尺寸\",\n size: \"default\",\n children: content2,\n });\n }}\n >\n Default (1000px)\n </Button>\n <Button\n onClick={() => {\n drawer({\n title: \"Large 尺寸\",\n size: \"large\",\n children: content3,\n });\n }}\n >\n Large (全屏-64px)\n </Button>\n </Space>\n );\n};\n\nrender(<Global><SizesExample /></Global>);\n\n`,\n scope: [{\n name: \"_Drawer\",\n packageName: \"@components/Drawer\",\n component: component_5\n},{\n name: \"_Global\",\n packageName: \"@components/Global\",\n component: component_6\n},{\n name: \"_antd\",\n packageName: \"antd\",\n component: component_7\n}]\n},{\n title: `自定义操作`,\n description: `自定义底部按钮、添加额外功能按钮,支持异步操作`,\n code: `const { useDrawer, DrawerButton } = _Drawer;\nconst { Button, Space, Typography, message, Popconfirm, Tag, Descriptions } = _antd;\nconst {default: Global} = _Global;\n\nconst CustomActionsExample = () => {\n const drawer = useDrawer();\n\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Typography.Text strong>自定义底部按钮和额外操作</Typography.Text>\n\n <Button\n onClick={() => {\n drawer({\n title: \"自定义按钮\",\n size: \"small\",\n children: (\n <div>\n <Typography.Paragraph>这个示例展示了如何自定义底部按钮。</Typography.Paragraph>\n <Typography.Paragraph>自定义了三个按钮:预览、取消、保存。</Typography.Paragraph>\n </div>\n ),\n footerButtons: [\n {\n children: \"预览\",\n onClick: () => {\n message.info(\"预览功能\");\n },\n },\n {\n children: \"取消\",\n onClick: () => {\n message.info(\"已取消\");\n },\n },\n {\n type: \"primary\",\n children: \"保存\",\n onClick: async () => {\n await new Promise((resolve) => setTimeout(resolve, 1000));\n message.success(\"保存成功!\");\n return true;\n },\n },\n ],\n });\n }}\n >\n 自定义按钮示例\n </Button>\n\n <DrawerButton\n api={{\n loader: () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve({\n id: 1,\n name: \"张三\",\n role: \"高级前端工程师\",\n department: \"技术部\",\n status: \"在职\",\n joinDate: \"2020-03-15\",\n });\n }, 500);\n });\n },\n }}\n modalProps={(contextProps) => {\n const { data } = contextProps;\n return {\n title: \"员工档案操作\",\n size: \"small\",\n children: (\n <Descriptions column={1} bordered>\n <Descriptions.Item label=\"姓名\">{data.name}</Descriptions.Item>\n <Descriptions.Item label=\"职位\">{data.role}</Descriptions.Item>\n <Descriptions.Item label=\"部门\">{data.department}</Descriptions.Item>\n <Descriptions.Item label=\"状态\">\n <Tag color=\"green\">{data.status}</Tag>\n </Descriptions.Item>\n <Descriptions.Item label=\"入职时间\">{data.joinDate}</Descriptions.Item>\n </Descriptions>\n ),\n footerButtons: [\n {\n children: \"查看详情\",\n onClick: () => {\n message.info(\"查看更多详情\");\n },\n },\n {\n children: \"导出档案\",\n onClick: () => {\n message.info(\"正在导出档案...\");\n },\n },\n {\n children: \"编辑\",\n type: \"default\",\n onClick: () => {\n message.info(\"打开编辑模式\");\n },\n },\n {\n type: \"primary\",\n children: \"确认\",\n onClick: async () => {\n await new Promise((resolve) => setTimeout(resolve, 1000));\n message.success(\"操作成功!\");\n return true;\n },\n },\n ],\n };\n }}\n >\n 加载数据并自定义操作\n </DrawerButton>\n\n <Button\n danger\n onClick={() => {\n drawer({\n title: \"删除确认\",\n size: \"small\",\n children: (\n <div>\n <Typography.Paragraph>\n <Typography.Text type=\"warning\">⚠️ 警告:</Typography.Text>\n 此操作将永久删除该员工档案,删除后无法恢复。\n </Typography.Paragraph>\n <Typography.Paragraph>是否继续删除?</Typography.Paragraph>\n </div>\n ),\n footerButtons: [\n {\n children: \"取消\",\n onClick: () => {\n message.info(\"已取消删除\");\n },\n },\n {\n danger: true,\n type: \"primary\",\n children: \"确认删除\",\n onClick: async () => {\n await new Promise((resolve) => setTimeout(resolve, 1000));\n message.success(\"已删除员工档案\");\n return true;\n },\n },\n ],\n });\n }}\n >\n 危险操作示例\n </Button>\n </Space>\n );\n};\n\nrender(<Global><CustomActionsExample /></Global>);\n\n`,\n scope: [{\n name: \"_Drawer\",\n packageName: \"@components/Drawer\",\n component: component_5\n},{\n name: \"_Global\",\n packageName: \"@components/Global\",\n component: component_6\n},{\n name: \"_antd\",\n packageName: \"antd\",\n component: component_7\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_10 from '@kne/react-enum';\nimport * as component_11 from 'antd';\nimport * as component_12 from '@kne/remote-loader';\nconst readmeConfig = {\n name: `react-enum`,\n summary: `<p>枚举值管理和展示组件,用于统一管理应用中的枚举数据,如性别、状态、类型等选项列表。</p>\n<h2>何时使用</h2>\n<ul>\n<li>需要展示枚举值的描述文本时</li>\n<li>需要将枚举列表渲染为下拉框、单选框等表单组件时</li>\n<li>需要统一管理应用中的枚举数据时</li>\n<li>需要支持多语言的枚举描述时</li>\n</ul>\n<h2>特性</h2>\n<ul>\n<li>📦 统一的枚举数据管理</li>\n<li>🔄 支持同步/异步加载</li>\n<li>📡 内置LRU缓存机制</li>\n<li>🌍 支持多语言</li>\n<li>🎨 多种格式化方式</li>\n<li>🔧 灵活的渲染函数</li>\n</ul>`,\n \n \n api: `<h2>Enum 组件 API</h2>\n<h3>Enum(默认导出)</h3>\n<p>用于获取单个或多个枚举值的展示内容。</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>moduleName</td>\n<td>枚举模块名称,对应预设中配置的枚举名称</td>\n<td>string | string[]</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>枚举值,当提供时获取单个枚举项;不提供时获取整个枚举列表</td>\n<td>string | number</td>\n<td>-</td>\n</tr>\n<tr>\n<td>format</td>\n<td>格式化方式:'default'返回描述文本,'origin'返回原始对象,'option'返回{label, value}格式</td>\n<td>'default' | 'origin' | 'option'</td>\n<td>'default'</td>\n</tr>\n<tr>\n<td>force</td>\n<td>是否强制刷新缓存,跳过缓存直接请求</td>\n<td>boolean</td>\n<td>false</td>\n</tr>\n<tr>\n<td>children</td>\n<td>子元素或渲染函数。函数接收(data, fetchApi)参数</td>\n<td>ReactNode | Function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>数据加载中时的占位内容</td>\n<td>ReactNode</td>\n<td>'--'</td>\n</tr>\n<tr>\n<td>error</td>\n<td>加载失败时的展示内容</td>\n<td>ReactNode | Function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>loading</td>\n<td>自定义加载中状态的展示</td>\n<td>ReactNode</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>EnumResource</h3>\n<p>用于获取完整的枚举列表资源。</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>moduleName</td>\n<td>枚举模块名称,支持数组以同时获取多个枚举</td>\n<td>string | string[]</td>\n<td>-</td>\n</tr>\n<tr>\n<td>format</td>\n<td>格式化方式</td>\n<td>'origin' | 'option' | 'default'</td>\n<td>'origin'</td>\n</tr>\n<tr>\n<td>children</td>\n<td>渲染函数,接收枚举列表作为参数</td>\n<td>Function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>数据加载中时的占位内容</td>\n<td>ReactNode</td>\n<td>'--'</td>\n</tr>\n<tr>\n<td>error</td>\n<td>加载失败时的展示内容</td>\n<td>ReactNode | Function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>loading</td>\n<td>自定义加载中状态的展示</td>\n<td>ReactNode</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>枚举配置</h3>\n<p>枚举数据通过 <code>preset</code> 函数或 <code>PureGlobal/Global</code> 组件的 <code>preset.enums</code> 配置:</p>\n<pre><code class=\"language-javascript\">// 全局配置\npreset({\n base: {\n gender: () =&gt; [\n { value: 'M', description: '男' },\n { value: 'F', description: '女' }\n ]\n }\n});\n\n// 或通过 Global 组件配置\n&lt;PureGlobal preset={{\n enums: {\n status: async ({ language }) =&gt; {\n // 支持异步加载\n return [\n { value: '1', description: '启用' },\n { value: '0', description: '禁用' }\n ];\n }\n }\n}}&gt;\n</code></pre>\n<h3>枚举项数据结构</h3>\n<table>\n<thead>\n<tr>\n<th>字段名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>value</td>\n<td>枚举值</td>\n<td>string | number</td>\n<td>是</td>\n</tr>\n<tr>\n<td>description</td>\n<td>枚举描述文本</td>\n<td>string</td>\n<td>是</td>\n</tr>\n<tr>\n<td>translation</td>\n<td>多语言翻译对象</td>\n<td>object</td>\n<td>否</td>\n</tr>\n</tbody>\n</table>`,\n example: {\n isFull: false,\n className: ``,\n style: ``,\n list: [{\n title: `EnumLegacy`,\n description: `兼容老版本Enum的API`,\n code: `const { default: Enum, preset } = _ReactEnum;\nconst { createWithRemoteLoader } = remoteLoader;\nconst { Divider } = antd;\n\npreset({\n base: {\n confirm: () => [{ description: '是', value: 'Y' }, {\n description: '否', value: 'N'\n }]\n }\n});\n\nconst BaseExample = createWithRemoteLoader({\n modules: ['components-core:Global@PureGlobal']\n})(({ remoteModules }) => {\n const [PureGlobal] = remoteModules;\n return <PureGlobal preset={{\n enums: {\n gender: [{ value: 'M', description: '男' }, {\n value: 'F', description: '女'\n }], marital: async () => [{ description: '已婚', value: 'Y' }, {\n description: '未婚', value: 'N'\n }]\n }\n }}>\n <Enum moduleName=\"gender\" name=\"M\" />\n <Divider />\n <Enum moduleName=\"gender\">{(data) => {\n return data.map((data) => \\`\\${data.value}:\\${data.description}\\`).join(',');\n }}</Enum>\n <Divider />\n <Enum moduleName={['gender', 'marital']}>{([gender, marital]) => {\n return <div>\n <div>{gender.map((data) => \\`\\${data.value}:\\${data.description}\\`).join(',')}</div>\n <div>{marital.map((data) => \\`\\${data.value}:\\${data.description}\\`).join(',')}</div>\n </div>;\n }}</Enum>\n <Divider />\n <Enum moduleName=\"confirm\" name=\"Y\" />\n <Enum moduleName=\"confirm\" name=\"N\">{(data) => data.description}</Enum>\n </PureGlobal>;\n});\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_ReactEnum\",\n packageName: \"@kne/react-enum\",\n importStatement: \"import * as _ReactEnum from \\\"@kne/react-enum\\\"\",\n component: component_10\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_11\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_12\n}]\n},{\n title: `基础用法`,\n description: `展示枚举的基本使用,包括获取单个枚举值和枚举列表`,\n code: `const { default: Enum } = _Enum;\nconst { createWithRemoteLoader } = remoteLoader;\nconst { Space, Select, Divider } = antd;\nconst BaseExample = createWithRemoteLoader({\n modules: ['components-core:Global@PureGlobal']\n})(({ remoteModules }) => {\n const [PureGlobal] = remoteModules;\n return (\n <PureGlobal\n preset={{\n locale: \"zh-CN\",\n enums: {\n // 同步加载的枚举\n gender: [\n { value: \"M\", description: \"男\" },\n { value: \"F\", description: \"女\" },\n ],\n // 异步加载的枚举\n status: async ({ locale }) => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve([\n { value: \"1\", description: \"启用\" },\n { value: \"0\", description: \"禁用\" },\n ]);\n }, 500);\n });\n },\n },\n }}\n >\n <Space direction=\"vertical\" size=\"large\" style={{ width: \"100%\" }}>\n <div>\n <h4>获取单个枚举值</h4>\n <Space>\n <span>性别:</span>\n <Enum moduleName=\"gender\" name=\"M\" />\n <Divider type=\"vertical\" />\n <span>自定义渲染:</span>\n <Enum moduleName=\"gender\" name=\"F\">\n {(data) => <strong style={{ color: \"#f5222d\" }}>{data.description}</strong>}\n </Enum>\n </Space>\n </div>\n \n <div>\n <h4>获取枚举列表</h4>\n <Enum moduleName=\"gender\">\n {(list) => {\n return (\n <Space>\n <span>可选项:</span>\n {list.map((item, index) => (\n <span key={item.value}>\n {item.description}\n {index < list.length - 1 && \"、\"}\n </span>\n ))}\n </Space>\n );\n }}\n </Enum>\n </div>\n \n <div>\n <h4>渲染为下拉框</h4>\n <Enum moduleName=\"status\">\n {(list) => {\n return (\n <Select\n style={{ width: 150 }}\n placeholder=\"请选择状态\"\n options={list.map((item) => ({\n value: item.value,\n label: item.description,\n }))}\n />\n );\n }}\n </Enum>\n </div>\n \n <div>\n <h4>占位符和加载状态</h4>\n <Space>\n <span>状态:</span>\n <Enum \n moduleName=\"status\" \n name=\"1\"\n placeholder=\"加载中...\"\n />\n </Space>\n </div>\n \n <div>\n <h4>使用format=\"option\"直接获取选项格式</h4>\n <Enum moduleName=\"gender\" format=\"option\">\n {(list) => (\n <Select\n style={{ width: 150 }}\n placeholder=\"请选择性别\"\n options={list}\n />\n )}\n </Enum>\n </div>\n </Space>\n </PureGlobal>\n );\n});\n\nrender(<BaseExample />);\n`,\n scope: [{\n name: \"_Enum\",\n packageName: \"@kne/react-enum\",\n importStatement: \"import * as _ReactEnum from \\\"@kne/react-enum\\\"\",\n component: component_10\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_11\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_12\n}]\n},{\n title: `异步加载与缓存`,\n description: `展示异步加载枚举数据、Loading状态和强制刷新缓存`,\n code: `const { default: Enum } = _Enum;\nconst { Space, Button, message } = antd;\nconst { useState } = React;\nconst { createWithRemoteLoader } = remoteLoader;\n\nconst AsyncEnumExample = createWithRemoteLoader({\n modules: ['components-core:Global@PureGlobal']\n})(({ remoteModules }) => {\n const [PureGlobal] = remoteModules;\n const [refreshKey, setRefreshKey] = useState(0);\n \n return (\n <PureGlobal\n preset={{\n locale: \"zh-CN\",\n enums: {\n // 异步加载枚举数据\n userStatus: async ({ language }) => {\n // 模拟从服务器获取数据\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve([\n { value: \"active\", description: \"活跃\" },\n { value: \"inactive\", description: \"非活跃\" },\n { value: \"pending\", description: \"待审核\" },\n { value: \"banned\", description: \"已禁用\" },\n ]);\n }, 1500);\n });\n },\n // 同步枚举数据\n priority: [\n { value: \"low\", description: \"低优先级\" },\n { value: \"medium\", description: \"中优先级\" },\n { value: \"high\", description: \"高优先级\" },\n { value: \"urgent\", description: \"紧急\" },\n ],\n },\n }}\n >\n <Space direction=\"vertical\" size=\"large\" style={{ width: \"100%\" }}>\n <div>\n <h4>异步加载枚举(带Loading状态)</h4>\n <Enum \n key={refreshKey}\n moduleName=\"userStatus\" \n name=\"active\"\n loading={<span>正在加载用户状态...</span>}\n placeholder=\"--\"\n >\n {(data) => <div>当前状态:{data.description}</div>}\n </Enum>\n </div>\n \n <div>\n <h4>强制刷新缓存</h4>\n <Space>\n <Enum \n moduleName=\"userStatus\" \n name=\"banned\"\n force={refreshKey > 0}\n >\n {(data) => data.description}\n </Enum>\n <Button \n onClick={() => {\n setRefreshKey(prev => prev + 1);\n message.info(\"已刷新缓存\");\n }}\n >\n 刷新缓存\n </Button>\n </Space>\n </div>\n \n <div>\n <h4>同步枚举数据(立即显示)</h4>\n <Space>\n <Enum moduleName=\"priority\" name=\"high\" />\n <Enum moduleName=\"priority\" name=\"urgent\">\n {(data) => <span style={{ color: \"red\" }}>{data.description}</span>}\n </Enum>\n </Space>\n </div>\n </Space>\n </PureGlobal>\n );\n});\n\nrender(<AsyncEnumExample />);\n\n`,\n scope: [{\n name: \"_Enum\",\n packageName: \"@kne/react-enum\",\n importStatement: \"import * as _ReactEnum from \\\"@kne/react-enum\\\"\",\n component: component_10\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_11\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_12\n}]\n},{\n title: `格式化方式`,\n description: `展示不同的格式化方式和自定义渲染`,\n code: `const { default: Enum } = _Enum;\nconst { createWithRemoteLoader } = remoteLoader;\nconst { Space, Divider, Card } = antd;\n\nconst FormatEnumExample = createWithRemoteLoader({\n modules: ['components-core:Global@PureGlobal']\n})(({ remoteModules }) => {\n const [PureGlobal] = remoteModules;\n return (\n <PureGlobal\n preset={{\n locale: \"zh-CN\",\n enums: {\n orderStatus: [\n { value: \"created\", description: \"已创建\", color: \"#666\" },\n { value: \"paid\", description: \"已支付\", color: \"#1890ff\" },\n { value: \"shipped\", description: \"已发货\", color: \"#52c41a\" },\n { value: \"completed\", description: \"已完成\", color: \"#52c41a\" },\n { value: \"cancelled\", description: \"已取消\", color: \"#f5222d\" },\n ],\n },\n }}\n >\n <Space direction=\"vertical\" size=\"large\" style={{ width: \"100%\" }}>\n <Card title=\"不同格式化方式\" size=\"small\">\n <Space direction=\"vertical\">\n <div>\n <strong>默认格式(format=\"default\"):</strong>\n <Enum moduleName=\"orderStatus\" name=\"paid\" format=\"default\" />\n </div>\n \n <Divider />\n \n <div>\n <strong>原始对象(format=\"origin\"):</strong>\n <Enum moduleName=\"orderStatus\" name=\"paid\" format=\"origin\">\n {(data) => (\n <pre>{JSON.stringify(data, null, 2)}</pre>\n )}\n </Enum>\n </div>\n \n <Divider />\n \n <div>\n <strong>选项格式(format=\"option\"):</strong>\n <Enum moduleName=\"orderStatus\" name=\"paid\" format=\"option\">\n {(data) => {\n return (\n <span>label: {data.description}, value: {data.value}</span>\n )\n }}\n </Enum>\n </div>\n </Space>\n </Card>\n \n <Card title=\"自定义渲染\" size=\"small\">\n <Space>\n <Enum moduleName=\"orderStatus\" name=\"shipped\" format=\"origin\">\n {(data) => (\n <span style={{ color: data.color }}>\n ● {data.description}\n </span>\n )}\n </Enum>\n \n <Enum moduleName=\"orderStatus\" name=\"cancelled\" format=\"origin\">\n {(data) => (\n <span style={{ \n padding: \"2px 8px\",\n backgroundColor: data.color,\n color: \"#fff\",\n borderRadius: \"4px\"\n }}>\n {data.description}\n </span>\n )}\n </Enum>\n </Space>\n </Card>\n </Space>\n </PureGlobal>\n );\n});\n\nrender(<FormatEnumExample />);\n\n`,\n scope: [{\n name: \"_Enum\",\n packageName: \"@kne/react-enum\",\n importStatement: \"import * as _ReactEnum from \\\"@kne/react-enum\\\"\",\n component: component_10\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_11\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_12\n}]\n},{\n title: `渲染枚举列表`,\n description: `将枚举列表渲染为各种表单组件`,\n code: `const { default: Enum } = _Enum;\nconst { createWithRemoteLoader } = remoteLoader;\nconst { Space, Select, Radio, Checkbox, Table } = antd;\n\nconst ListEnumExample = createWithRemoteLoader({\n modules: ['components-core:Global@PureGlobal']\n})(({ remoteModules }) => {\n const [PureGlobal] = remoteModules;\n return (\n <PureGlobal\n preset={{\n locale: \"zh-CN\",\n enums: {\n department: [\n { value: \"tech\", description: \"技术部\" },\n { value: \"product\", description: \"产品部\" },\n { value: \"design\", description: \"设计部\" },\n { value: \"marketing\", description: \"市场部\" },\n { value: \"hr\", description: \"人力资源部\" },\n { value: \"finance\", description: \"财务部\" },\n ],\n role: [\n { value: \"admin\", description: \"管理员\", level: 1 },\n { value: \"manager\", description: \"经理\", level: 2 },\n { value: \"employee\", description: \"员工\", level: 3 },\n { value: \"intern\", description: \"实习生\", level: 4 },\n ],\n },\n }}\n >\n <Space direction=\"vertical\" size=\"large\" style={{ width: \"100%\" }}>\n <div>\n <h4>渲染为 Select 下拉框</h4>\n <Enum moduleName=\"department\">\n {(list) => (\n <Select\n style={{ width: 200 }}\n placeholder=\"请选择部门\"\n options={list.map((item) => ({\n value: item.value,\n label: item.description,\n }))}\n />\n )}\n </Enum>\n </div>\n \n <div>\n <h4>渲染为 Radio 单选组</h4>\n <Enum moduleName=\"role\">\n {(list) => (\n <Radio.Group>\n {list.map((item) => (\n <Radio key={item.value} value={item.value}>\n {item.description}\n </Radio>\n ))}\n </Radio.Group>\n )}\n </Enum>\n </div>\n \n <div>\n <h4>渲染为 Checkbox 多选组</h4>\n <Enum moduleName=\"department\">\n {(list) => (\n <Checkbox.Group>\n {list.slice(0, 4).map((item) => (\n <Checkbox key={item.value} value={item.value}>\n {item.description}\n </Checkbox>\n ))}\n </Checkbox.Group>\n )}\n </Enum>\n </div>\n \n <div>\n <h4>渲染为 Table 表格</h4>\n <Enum moduleName=\"role\" format=\"origin\">\n {(list) => (\n <Table\n size=\"small\"\n pagination={false}\n columns={[\n { title: \"编码\", dataIndex: \"value\", key: \"value\" },\n { title: \"名称\", dataIndex: \"description\", key: \"description\" },\n { title: \"级别\", dataIndex: \"level\", key: \"level\" },\n ]}\n dataSource={list.map(item => ({ ...item, key: item.value }))}\n />\n )}\n </Enum>\n </div>\n </Space>\n </PureGlobal>\n );\n});\n\nrender(<ListEnumExample />);\n\n`,\n scope: [{\n name: \"_Enum\",\n packageName: \"@kne/react-enum\",\n importStatement: \"import * as _ReactEnum from \\\"@kne/react-enum\\\"\",\n component: component_10\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_11\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_12\n}]\n},{\n title: `多枚举模块`,\n description: `同时获取多个枚举模块和错误处理`,\n code: `const { default: Enum } = _Enum;\nconst { createWithRemoteLoader } = remoteLoader;\nconst { Space, Card, Tag } = antd;\n\nconst MultiEnumExample = createWithRemoteLoader({\n modules: ['components-core:Global@PureGlobal']\n})(({ remoteModules }) => {\n const [PureGlobal] = remoteModules;\n return (\n <PureGlobal\n preset={{\n locale: \"zh-CN\",\n enums: {\n country: [\n { value: \"CN\", description: \"中国\" },\n { value: \"US\", description: \"美国\" },\n { value: \"UK\", description: \"英国\" },\n { value: \"JP\", description: \"日本\" },\n ],\n language: [\n { value: \"zh-CN\", description: \"简体中文\" },\n { value: \"en-US\", description: \"英语\" },\n { value: \"ja-JP\", description: \"日语\" },\n { value: \"ko-KR\", description: \"韩语\" },\n ],\n timezone: [\n { value: \"UTC+8\", description: \"北京时间\" },\n { value: \"UTC+0\", description: \"格林威治时间\" },\n { value: \"UTC-5\", description: \"纽约时间\" },\n { value: \"UTC+9\", description: \"东京时间\" },\n ],\n },\n }}\n >\n <Space direction=\"vertical\" size=\"large\" style={{ width: \"100%\" }}>\n <Card title=\"同时获取多个枚举模块\" size=\"small\">\n <Enum moduleName={[\"country\", \"language\", \"timezone\"]}>\n {([countries, languages, timezones]) => (\n <Space direction=\"vertical\">\n <div>\n <strong>国家列表:</strong>\n <Space>\n {countries.map(item => (\n <Tag key={item.value}>{item.description}</Tag>\n ))}\n </Space>\n </div>\n <div>\n <strong>语言列表:</strong>\n <Space>\n {languages.map(item => (\n <Tag key={item.value} color=\"blue\">{item.description}</Tag>\n ))}\n </Space>\n </div>\n <div>\n <strong>时区列表:</strong>\n <Space>\n {timezones.map(item => (\n <Tag key={item.value} color=\"green\">{item.description}</Tag>\n ))}\n </Space>\n </div>\n </Space>\n )}\n </Enum>\n </Card>\n \n <Card title=\"组合使用多个枚举\" size=\"small\">\n <Space>\n <span>用户来自</span>\n <Enum moduleName=\"country\" name=\"CN\">\n {(data) => <strong>{data.description}</strong>}\n </Enum>\n <span>,使用</span>\n <Enum moduleName=\"language\" name=\"zh-CN\">\n {(data) => <strong>{data.description}</strong>}\n </Enum>\n <span>,时区为</span>\n <Enum moduleName=\"timezone\" name=\"UTC+8\">\n {(data) => <strong>{data.description}</strong>}\n </Enum>\n </Space>\n </Card>\n \n <Card title=\"错误处理\" size=\"small\">\n <Space direction=\"vertical\">\n <div>\n <strong>不存在的枚举模块:</strong>\n <Enum \n moduleName=\"notExist\" \n name=\"test\"\n error={<span style={{ color: \"red\" }}>枚举加载失败</span>}\n />\n </div>\n <div>\n <strong>不存在的枚举值(显示占位符):</strong>\n <Enum \n moduleName=\"country\" \n name=\"XX\"\n placeholder=\"未知国家\"\n />\n </div>\n </Space>\n </Card>\n </Space>\n </PureGlobal>\n );\n});\n\nrender(<MultiEnumExample />);\n\n`,\n scope: [{\n name: \"_Enum\",\n packageName: \"@kne/react-enum\",\n importStatement: \"import * as _ReactEnum from \\\"@kne/react-enum\\\"\",\n component: component_10\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_11\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_12\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_22 from '@components/Features';\nimport * as component_23 from '@components/Global';\nimport * as component_24 from '@components/Layout';\nimport * as component_25 from 'react-router-dom';\nimport * as component_26 from 'antd';\nconst readmeConfig = {\n name: `Features`,\n summary: `<p>Features 是一个功能开关管理组件,用于在系统中通过条件控制功能的开启或关闭,实现系统功能的灵活配置。</p>\n<p>通过全局配置的方式,Features 组件可以统一管理系统功能的可见性和可访问性,避免在代码中散落大量判断逻辑。它支持基于依赖关系的智能判断,只有当功能及其依赖项都满足条件时才会被标记为可用状态。同时,该组件还支持为功能的开启和关闭状态传递不同的配置参数,实现更精细的交互控制。</p>\n<p>核心特性:</p>\n<ul>\n<li><strong>集中配置管理</strong>:通过 Global preset 统一声明,避免判断语句散落在代码各处</li>\n<li><strong>依赖关系支持</strong>:智能判断功能是否可用,只有满足所有依赖条件才开启</li>\n<li><strong>双状态参数</strong>:可为开启和关闭状态分别配置不同的参数(options/rejectedOptions)</li>\n<li><strong>调试模式</strong>:提供 debug 模式方便开发时查看功能状态和真实 ID</li>\n<li><strong>嵌套功能管理</strong>:支持 system/module/feature 三级结构,通过冒号连接完整 ID</li>\n</ul>\n<p>适用于企业级管理系统、SaaS 平台、多租户应用等需要精细化功能控制的场景。</p>`,\n \n \n api: `<h3>Features 组件</h3>\n<p>Features 是一个功能开关组件,用于根据配置控制子组件的显示或隐藏。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>id</td>\n<td>功能标识符,对应 preset.features.profile 中定义的 id</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>子内容,可以是 JSX 或函数。为函数时接收 {isPass, options, currentId} 参数</td>\n<td>ReactNode | Function</td>\n<td>是</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h4>children 函数参数</h4>\n<p>当 children 为函数时,接收的参数对象包含以下属性:</p>\n<table>\n<thead>\n<tr>\n<th>参数名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>isPass</td>\n<td>功能是否通过(开启)</td>\n<td>boolean</td>\n</tr>\n<tr>\n<td>options</td>\n<td>开启或关闭状态对应的配置参数</td>\n<td>any</td>\n</tr>\n<tr>\n<td>currentId</td>\n<td>当前功能的完整 ID(包含父级路径)</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n<h3>features 配置</h3>\n<p>features 配置在 Global preset 中定义。</p>\n<h4>features 配置属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>debug</td>\n<td>是否开启调试模式,开启后会在控制台打印所有功能的 ID 和判断状态</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>profile</td>\n<td>功能配置树结构</td>\n<td>object</td>\n<td>是</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>profile 配置结构</h3>\n<p>profile 采用树形结构配置系统的功能模块。</p>\n<h4>profile 节点属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>id</td>\n<td>当前节点的标识符,同级节点中需唯一,完整 ID 由父级 ID 和当前 ID 通过冒号连接</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>type</td>\n<td>节点类型,可选值为:system(系统根节点)、module(功能模块)、feature(具体功能)</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>节点中文名称,仅用于标识和说明</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>close</td>\n<td>是否强制关闭该功能。true 表示关闭,false 或不配置表示开启(存在该节点配置时)</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>dependencies</td>\n<td>依赖的功能列表,数组中的 ID 必须是完整的功能 ID。只有所有依赖功能都开启时,当前功能才会被标记为开启</td>\n<td>array&lt;string&gt;</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>options</td>\n<td>功能开启时传递给 children 的参数</td>\n<td>any</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>rejectedOptions</td>\n<td>功能关闭时传递给 children 的参数</td>\n<td>any</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>子功能节点数组</td>\n<td>array&lt;object&gt;</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h4>功能判断规则</h4>\n<ol>\n<li>功能开启条件:profile 中存在该节点配置,且 close 不为 true,且所有 dependencies 依赖的功能都已开启</li>\n<li>功能关闭条件:profile 中不存在该节点配置,或 close 为 true,或存在依赖项功能关闭</li>\n<li>根节点 type 必须为 system</li>\n</ol>`,\n example: {\n isFull: true,\n className: ``,\n style: ``,\n list: [{\n title: `基础用法 - 依赖关系控制功能开关`,\n description: `展示如何通过依赖关系控制功能模块的开启与关闭,批量导入功能依赖编辑模块`,\n code: `const { default: Features } = _Features;\nconst { default: Layout, PermissionsPage } = layout;\nconst { PureGlobal } = global;\n\nconst BaseExample = () => {\n return (\n <PureGlobal\n preset={{\n features: {\n debug: true,\n profile: {\n id: \"hr-system\",\n type: \"system\",\n name: \"人力资源管理系统\",\n children: [\n {\n id: \"employee\",\n type: \"module\",\n name: \"员工管理\",\n children: [\n {\n id: \"import\",\n type: \"feature\",\n name: \"批量导入\",\n dependencies: [\"hr-system:employee:edit\"],\n },\n {\n id: \"export\",\n type: \"feature\",\n name: \"数据导出\",\n },\n ],\n },\n {\n id: \"attendance\",\n type: \"module\",\n name: \"考勤管理\",\n children: [\n {\n id: \"check-in\",\n type: \"feature\",\n name: \"签到打卡\",\n },\n ],\n },\n {\n id: \"edit\",\n type: \"module\",\n name: \"编辑模块\",\n },\n ],\n },\n },\n }}\n >\n <Layout navigation={{ isFixed: false }}>\n <PermissionsPage name=\"employee\" openFeatures>\n <Features id=\"import\">\n <div>\n <h3>批量导入员工数据</h3>\n <p>支持 Excel 文件批量导入,一次性添加多名员工</p>\n </div>\n </Features>\n <Features id=\"export\">\n <div>\n <h3>导出员工数据</h3>\n <p>导出员工列表到 Excel,支持自定义筛选条件</p>\n </div>\n </Features>\n <Features id=\"analytics\">\n <div>\n <h3>数据分析</h3>\n <p>统计分析员工数据,生成可视化报表</p>\n </div>\n </Features>\n </PermissionsPage>\n </Layout>\n </PureGlobal>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Features\",\n packageName: \"@components/Features\",\n component: component_22\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_23\n},{\n name: \"layout\",\n packageName: \"@components/Layout\",\n component: component_24\n}]\n},{\n title: `页面级功能控制`,\n description: `展示如何在多页面应用中使用 Features 控制不同页面的功能模块,销售趋势图、客户增长图等功能展示`,\n code: `const {default: Features} = _Features;\nconst {default: Layout, PermissionsPage} = layout;\nconst {PureGlobal} = global;\nconst {Route, Routes} = Router;\n\nconst ModuleExample = () => {\n return (<PureGlobal\n preset={{\n features: {\n debug: true, profile: {\n id: \"crm-system\", type: \"system\", name: \"客户关系管理系统\", children: [{\n id: \"dashboard\", type: \"module\", name: \"数据看板\", children: [{\n id: \"sales-chart\", type: \"feature\", name: \"销售趋势图\",\n }, {\n id: \"customer-chart\", type: \"feature\", name: \"客户增长图\",\n },],\n }, {\n id: \"customer\", type: \"module\", name: \"客户管理\", children: [{\n id: \"advanced-filter\",\n type: \"feature\",\n name: \"高级筛选\",\n dependencies: [\"crm-system:dashboard\"],\n },],\n },],\n },\n },\n }}\n >\n <Layout\n navigation={{\n isFixed: false, showIndex: false, base: '/Features', list: [{\n key: \"dashboard\", title: \"数据看板\", path: \"/Features\",\n }, {\n key: \"customer\", title: \"客户管理\", path: \"/Features/customer\",\n },],\n }}\n >\n <Routes>\n <Route\n path=\"/Features\"\n element={<PermissionsPage name=\"dashboard\" openFeatures>\n <div>\n <h2>数据看板</h2>\n <div style={{\n padding: '16px',\n marginBottom: '16px',\n border: '1px solid #d9d9d9',\n borderRadius: '4px'\n }}>\n <Features id=\"sales-chart\">\n <h3>销售趋势分析</h3>\n <p>展示最近30天销售数据变化趋势</p>\n </Features>\n </div>\n <div style={{padding: '16px', border: '1px solid #d9d9d9', borderRadius: '4px'}}>\n <Features id=\"customer-chart\">\n <h3>客户增长分析</h3>\n <p>展示客户数量变化趋势</p>\n </Features>\n </div>\n </div>\n </PermissionsPage>}\n />\n <Route\n path=\"/Features/customer\"\n element={<PermissionsPage name=\"customer\" openFeatures>\n <div>\n <h2>客户管理</h2>\n <div style={{padding: '16px', border: '1px solid #d9d9d9', borderRadius: '4px'}}>\n <Features id=\"advanced-filter\">\n <h3>高级筛选功能</h3>\n <p>支持多维度组合筛选客户数据</p>\n </Features>\n </div>\n </div>\n </PermissionsPage>}\n />\n </Routes>\n </Layout>\n </PureGlobal>);\n};\n\nrender(<ModuleExample/>);\n\n`,\n scope: [{\n name: \"_Features\",\n packageName: \"@components/Features\",\n component: component_22\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_23\n},{\n name: \"layout\",\n packageName: \"@components/Layout\",\n component: component_24\n},{\n name: \"Router\",\n packageName: \"react-router-dom\",\n component: component_25\n}]\n},{\n title: `动态参数传递`,\n description: `展示如何根据功能开启/关闭状态传递不同的配置参数(options/rejectedOptions),薪资可见性和绩效考核功能`,\n code: `const { default: Features } = _Features;\nconst { default: Layout, PermissionsPage } = layout;\nconst { PureGlobal } = global;\nconst { useState } = React;\nconst { Button, Space, Card, Tag, Alert } = antd;\n\nconst OptionsExample = () => {\n const [featureEnabled, setFeatureEnabled] = useState(true);\n\n return (\n <PureGlobal\n preset={{\n features: {\n debug: true,\n profile: {\n id: \"hr-system\",\n type: \"system\",\n name: \"人力资源系统\",\n children: [\n {\n id: \"employee\",\n type: \"module\",\n name: \"员工管理\",\n children: [\n {\n id: \"salary-visibility\",\n type: \"feature\",\n name: \"薪资可见性\",\n options: {\n permission: \"full\",\n canEdit: true,\n maxViewLevel: \"all\"\n },\n rejectedOptions: {\n permission: \"limited\",\n canEdit: false,\n maxViewLevel: \"self\"\n },\n close: !featureEnabled,\n },\n {\n id: \"performance\",\n type: \"feature\",\n name: \"绩效考核\",\n options: {\n scoreRange: \"0-100\",\n hasReview: true,\n allowAppeal: true\n },\n rejectedOptions: {\n scoreRange: \"0-10\",\n hasReview: false,\n allowAppeal: false\n }\n }\n ],\n },\n ],\n },\n },\n }}\n >\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Card>\n <Button\n type=\"primary\"\n onClick={() => {\n setFeatureEnabled((value) => !value);\n }}\n >\n {featureEnabled ? \"关闭薪资功能\" : \"开启薪资功能\"}\n </Button>\n <p style={{ marginTop: 12 }}>\n 点击按钮切换薪资可见性功能,观察不同状态下传递的参数变化\n </p>\n </Card>\n\n <Layout navigation={{ isFixed: false }}>\n <PermissionsPage name=\"employee\" openFeatures>\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Card title=\"薪资可见性功能\" size=\"small\">\n <Features id=\"salary-visibility\">\n {({ isPass, options }) => (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Alert\n message={isPass ? \"功能已开启\" : \"功能已关闭\"}\n type={isPass ? \"success\" : \"warning\"}\n showIcon\n />\n <div>\n <strong>权限级别:</strong>\n <Tag color={isPass ? \"green\" : \"orange\"}>\n {options.permission}\n </Tag>\n </div>\n <div>\n <strong>编辑权限:</strong>\n <Tag color={options.canEdit ? \"blue\" : \"default\"}>\n {options.canEdit ? \"允许编辑\" : \"只读\"}\n </Tag>\n </div>\n <div>\n <strong>查看范围:</strong>\n <Tag>{options.maxViewLevel}</Tag>\n </div>\n </Space>\n )}\n </Features>\n </Card>\n\n <Card title=\"绩效考核功能\" size=\"small\">\n <Features id=\"performance\">\n {({ isPass, options }) => (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Alert\n message={isPass ? \"功能已开启\" : \"功能已关闭\"}\n type=\"success\"\n showIcon\n />\n <div>\n <strong>评分范围:</strong>\n <Tag>{options.scoreRange}</Tag>\n </div>\n <div>\n <strong>绩效复核:</strong>\n <Tag color={options.hasReview ? \"blue\" : \"default\"}>\n {options.hasReview ? \"启用\" : \"禁用\"}\n </Tag>\n </div>\n <div>\n <strong>申诉功能:</strong>\n <Tag color={options.allowAppeal ? \"blue\" : \"default\"}>\n {options.allowAppeal ? \"允许\" : \"禁止\"}\n </Tag>\n </div>\n </Space>\n )}\n </Features>\n </Card>\n </Space>\n </PermissionsPage>\n </Layout>\n </Space>\n </PureGlobal>\n );\n};\n\nrender(<OptionsExample />);\n\n`,\n scope: [{\n name: \"_Features\",\n packageName: \"@components/Features\",\n component: component_22\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_23\n},{\n name: \"layout\",\n packageName: \"@components/Layout\",\n component: component_24\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_26\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_18 from '@components/File';\nimport * as component_19 from '@components/Global';\nimport * as component_20 from '@kne/remote-loader';\nimport * as component_21 from 'antd';\nconst readmeConfig = {\n name: `File`,\n summary: `<p>File 组件提供了一套完整的文件管理解决方案,包括文件展示、OSS 文件 ID 转换、文件列表展示、文件下载等功能。</p>\n<p>该组件集成了文件上传、预览、编辑、删除等常见操作,支持通过 OSS ID 自动获取文件访问地址,并提供文件列表组件来展示和管理多个文件。同时提供了文件下载、文件预览链接等便捷组件,方便在各种场景下使用。</p>\n<p>核心特性:</p>\n<ul>\n<li><strong>自动 OSS 地址转换</strong>:支持通过文件 ID 自动获取 OSS 访问地址,无需手动处理 URL 转换</li>\n<li><strong>完整的文件操作</strong>:提供文件预览、编辑名称、下载、删除等完整操作功能</li>\n<li><strong>灵活的列表展示</strong>:支持自定义列渲染、权限控制、上传状态展示</li>\n<li><strong>多种使用方式</strong>:提供按钮、链接、列表等多种形式的组件,适应不同场景需求</li>\n<li><strong>下载状态管理</strong>:内置下载状态管理,支持下载进度控制和回调处理</li>\n</ul>\n<p>适用于文档管理系统、文件共享平台、数据导入导出等需要文件处理的应用场景。</p>`,\n \n \n api: `<h3>File 组件</h3>\n<p>File 组件用于通过 OSS ID 获取文件访问地址并展示文件内容。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>id</td>\n<td>OSS 文件的唯一标识符</td>\n<td>string</td>\n<td>否*</td>\n<td>-</td>\n</tr>\n<tr>\n<td>url</td>\n<td>直接指定文件的访问地址</td>\n<td>string</td>\n<td>否*</td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>渲染函数,接收 <code>{ url }</code> 参数</td>\n<td>Function</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis</td>\n<td>OSS 接口配置,包含 <code>oss</code> 属性</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>error</td>\n<td>加载失败时显示的内容</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>null</td>\n</tr>\n<tr>\n<td>loading</td>\n<td>加载中显示的内容</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>null</td>\n</tr>\n</tbody>\n</table>\n<p><strong>注意</strong>:<code>id</code> 和 <code>url</code> 至少需要传入其中一个。</p>\n<h3>Download 组件</h3>\n<p>文件下载按钮组件,支持通过 OSS ID 或 URL 下载文件。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>id</td>\n<td>OSS 文件的唯一标识符</td>\n<td>string</td>\n<td>否*</td>\n<td>-</td>\n</tr>\n<tr>\n<td>url</td>\n<td>直接指定文件的下载地址</td>\n<td>string</td>\n<td>否*</td>\n<td>-</td>\n</tr>\n<tr>\n<td>filename</td>\n<td>下载后的文件名</td>\n<td>string</td>\n<td>否</td>\n<td>未命名下载文件</td>\n</tr>\n<tr>\n<td>apis</td>\n<td>OSS 接口配置,包含 <code>oss</code> 属性</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onSuccess</td>\n<td>下载成功回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onError</td>\n<td>下载失败回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>按钮内容</td>\n<td>ReactNode</td>\n<td>是</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<p><strong>注意</strong>:<code>id</code> 和 <code>url</code> 至少需要传入其中一个。</p>\n<h3>List 组件</h3>\n<p>文件列表展示组件,支持文件预览、编辑名称、下载、删除等操作。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>dataSource</td>\n<td>文件数据列表</td>\n<td>array</td>\n<td>否</td>\n<td>[]</td>\n</tr>\n<tr>\n<td>getPermission</td>\n<td>权限控制函数,接收 <code>{ type, itemData }</code> 参数,返回 <code>false</code> 表示无权限</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>hasPreview</td>\n<td>是否启用预览功能</td>\n<td>boolean</td>\n<td>否</td>\n<td>true</td>\n</tr>\n<tr>\n<td>infoItemRenders</td>\n<td>自定义列配置,数组中每项包含 <code>span</code>(栅格数)和 <code>render</code>(渲染函数)</td>\n<td>array</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>renderModal</td>\n<td>自定义 Modal 渲染函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis</td>\n<td>操作 API 配置</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis.onEdit</td>\n<td>编辑文件名称回调,接收参数 <code>(formData, itemData)</code></td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis.onPreview</td>\n<td>预览文件回调,接收参数 <code>(itemData)</code></td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis.onDelete</td>\n<td>删除文件回调,接收参数 <code>(itemData)</code></td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h4>dataSource 数据结构</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>id</td>\n<td>文件唯一标识符(一般为 OSS ID)</td>\n<td>string</td>\n</tr>\n<tr>\n<td>uuid</td>\n<td>临时文件唯一标识符</td>\n<td>string</td>\n</tr>\n<tr>\n<td>type</td>\n<td>文件状态,值为 <code>\"uploading\"</code> 时显示上传中状态</td>\n<td>string</td>\n</tr>\n<tr>\n<td>filename</td>\n<td>文件名称</td>\n<td>string</td>\n</tr>\n<tr>\n<td>date</td>\n<td>上传日期(时间戳或 Date 对象)</td>\n<td>Date | string</td>\n</tr>\n<tr>\n<td>userName</td>\n<td>上传人姓名</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n<h3>OptionButtons 组件</h3>\n<p>文件操作按钮组,提供预览、编辑、删除等操作按钮。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>itemData</td>\n<td>文件数据对象</td>\n<td>object</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis</td>\n<td>操作 API 配置</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis.onEdit</td>\n<td>编辑文件名称回调</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis.onPreview</td>\n<td>预览文件回调</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis.onDelete</td>\n<td>删除文件回调</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>hasPreview</td>\n<td>是否显示预览按钮</td>\n<td>boolean</td>\n<td>否</td>\n<td>true</td>\n</tr>\n<tr>\n<td>renderModal</td>\n<td>自定义 Modal 渲染函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>FileLink 组件</h3>\n<p>文件链接组件,点击后弹出文件预览弹窗。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>id</td>\n<td>OSS 文件的唯一标识符</td>\n<td>string</td>\n<td>否*</td>\n<td>-</td>\n</tr>\n<tr>\n<td>url</td>\n<td>直接指定文件的访问地址</td>\n<td>string</td>\n<td>否*</td>\n<td>-</td>\n</tr>\n<tr>\n<td>originName</td>\n<td>文件原始名称</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>title</td>\n<td>预览弹窗标题</td>\n<td>string | ReactNode</td>\n<td>否</td>\n<td>originName</td>\n</tr>\n<tr>\n<td>apis</td>\n<td>OSS 接口配置,包含 <code>oss</code> 属性</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>openDownload</td>\n<td>是否启用下载功能</td>\n<td>boolean</td>\n<td>否</td>\n<td>true</td>\n</tr>\n<tr>\n<td>modalProps</td>\n<td>Modal 组件的额外属性</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>链接文字内容,不传则显示 <code>originName</code></td>\n<td>ReactNode</td>\n<td>否</td>\n<td>originName</td>\n</tr>\n</tbody>\n</table>\n<p><strong>注意</strong>:<code>id</code> 和 <code>url</code> 至少需要传入其中一个。</p>\n<h3>downloadBlobFile 函数</h3>\n<p>下载文件的工具函数。</p>\n<h4>函数签名</h4>\n<pre><code class=\"language-typescript\">downloadBlobFile(target: string | Blob, filename: string): void\n</code></pre>\n<h4>参数说明</h4>\n<table>\n<thead>\n<tr>\n<th>参数名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>target</td>\n<td>文件下载地址或二进制数据(Blob)</td>\n<td>string | Blob</td>\n<td>是</td>\n</tr>\n<tr>\n<td>filename</td>\n<td>下载后的文件名</td>\n<td>string</td>\n<td>是</td>\n</tr>\n</tbody>\n</table>\n<h3>useDownload Hook</h3>\n<p>生成下载函数并管理下载状态的 Hook。</p>\n<h4>Hook 返回值</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>download</td>\n<td>执行下载的函数</td>\n<td>function</td>\n</tr>\n<tr>\n<td>isLoading</td>\n<td>是否正在下载</td>\n<td>boolean</td>\n</tr>\n<tr>\n<td>others</td>\n<td>其他 useFetch 返回的属性</td>\n<td>object</td>\n</tr>\n</tbody>\n</table>\n<h4>Hook 参数</h4>\n<table>\n<thead>\n<tr>\n<th>参数名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>id</td>\n<td>OSS 文件的唯一标识符</td>\n<td>string</td>\n<td>否*</td>\n<td>-</td>\n</tr>\n<tr>\n<td>url</td>\n<td>直接指定文件的下载地址</td>\n<td>string</td>\n<td>否*</td>\n<td>-</td>\n</tr>\n<tr>\n<td>filename</td>\n<td>下载后的文件名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis</td>\n<td>OSS 接口配置,包含 <code>oss</code> 属性</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onSuccess</td>\n<td>下载成功回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onError</td>\n<td>下载失败回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<p><strong>注意</strong>:<code>id</code> 和 <code>url</code> 至少需要传入其中一个。</p>\n<h3>useFileModal Hook</h3>\n<p>生成文件预览弹窗函数的 Hook。</p>\n<h4>Hook 返回值</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>modal</td>\n<td>打开文件预览弹窗的函数</td>\n<td>function</td>\n</tr>\n</tbody>\n</table>\n<h4>modal 函数参数</h4>\n<table>\n<thead>\n<tr>\n<th>参数名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>id</td>\n<td>OSS 文件的唯一标识符</td>\n<td>string</td>\n<td>否*</td>\n<td>-</td>\n</tr>\n<tr>\n<td>url</td>\n<td>直接指定文件的访问地址</td>\n<td>string</td>\n<td>否*</td>\n<td>-</td>\n</tr>\n<tr>\n<td>originName</td>\n<td>文件原始名称</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>title</td>\n<td>预览弹窗标题</td>\n<td>string | ReactNode</td>\n<td>否</td>\n<td>originName</td>\n</tr>\n<tr>\n<td>apis</td>\n<td>OSS 接口配置,包含 <code>oss</code> 属性</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>openDownload</td>\n<td>是否启用下载功能</td>\n<td>boolean</td>\n<td>否</td>\n<td>true</td>\n</tr>\n<tr>\n<td>modalProps</td>\n<td>Modal 组件的额外属性</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<p><strong>注意</strong>:<code>id</code> 和 <code>url</code> 至少需要传入其中一个。</p>\n<h3>FileButton 组件</h3>\n<p>文件按钮组件,点击后弹出文件预览弹窗。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>id</td>\n<td>OSS 文件的唯一标识符</td>\n<td>string</td>\n<td>否*</td>\n<td>-</td>\n</tr>\n<tr>\n<td>url</td>\n<td>直接指定文件的访问地址</td>\n<td>string</td>\n<td>否*</td>\n<td>-</td>\n</tr>\n<tr>\n<td>originName</td>\n<td>文件原始名称</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>title</td>\n<td>预览弹窗标题</td>\n<td>string | ReactNode</td>\n<td>否</td>\n<td>originName</td>\n</tr>\n<tr>\n<td>apis</td>\n<td>OSS 接口配置,包含 <code>oss</code> 属性</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>openDownload</td>\n<td>是否启用下载功能</td>\n<td>boolean</td>\n<td>否</td>\n<td>true</td>\n</tr>\n<tr>\n<td>modalProps</td>\n<td>Modal 组件的额外属性</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>type</td>\n<td>按钮类型</td>\n<td>string</td>\n<td>否</td>\n<td>default</td>\n</tr>\n<tr>\n<td>children</td>\n<td>按钮内容</td>\n<td>ReactNode</td>\n<td>是</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<p><strong>注意</strong>:<code>id</code> 和 <code>url</code> 至少需要传入其中一个。</p>`,\n example: {\n isFull: false,\n className: ``,\n style: ``,\n list: [{\n title: `获取文件地址`,\n description: `通过 OSS ID 获取文件访问地址,展示员工头像和公司 Logo 地址获取`,\n code: `const { default: File } = _File;\nconst { PureGlobal } = global;\nconst { getPublicPath } = remoteLoader;\nconst { Typography, Card, Space, Alert } = antd;\n\nconst { Paragraph, Text } = Typography;\n\nconst BaseExample = () => {\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Alert\n message=\"文件地址获取示例\"\n description=\"演示如何通过 OSS ID 获取文件访问地址\"\n type=\"info\"\n showIcon\n />\n\n <Card title=\"员工头像地址\">\n <File id=\"employee-avatar-001\">\n {({ url, isLoading }) => (\n <Space direction=\"vertical\">\n <Text strong>访问地址:</Text>\n <Paragraph copyable>\n {isLoading ? '加载中...' : url}\n </Paragraph>\n </Space>\n )}\n </File>\n </Card>\n\n <Card title=\"公司 Logo 地址\">\n <File id=\"company-logo-main\">\n {({ url, isLoading }) => (\n <Space direction=\"vertical\">\n <Text strong>访问地址:</Text>\n <Paragraph copyable>\n {isLoading ? '加载中...' : url}\n </Paragraph>\n </Space>\n )}\n </File>\n </Card>\n </Space>\n );\n};\n\nrender(\n <PureGlobal\n preset={{\n apis: {\n file: {\n getUrl: {\n loader: async ({ params }) => {\n const mapping = {\n \"employee-avatar-001\": \"/avatar.png\",\n \"company-logo-main\": \"/mock/resume.pdf\"\n };\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve(getPublicPath(\"components-core\") + mapping[params.id] || \"\");\n }, 500);\n });\n },\n },\n },\n },\n }}\n >\n <BaseExample />\n </PureGlobal>\n);\n\n`,\n scope: [{\n name: \"_File\",\n packageName: \"@components/File\",\n component: component_18\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_19\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_20\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_21\n}]\n},{\n title: `文件下载`,\n description: `展示不同类型文件的下载功能,包括成功和失败回调,人力资源相关文档下载`,\n code: `const { Download } = _File;\nconst { PureGlobal } = global;\nconst { getPublicPath } = remoteLoader;\nconst { Space, Card, Alert, Typography, message } = antd;\n\nconst { Title, Text } = Typography;\n\nconst BaseExample = () => {\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Alert\n message=\"文件下载示例\"\n description=\"演示不同类型文件的下载功能,包括成功和失败回调\"\n type=\"info\"\n showIcon\n />\n\n <Card title=\"人力资源相关文档下载\">\n <Space direction=\"vertical\">\n <div>\n <Text type=\"secondary\">员工入职手册:</Text>\n <br />\n <Download\n id=\"doc-employee-handbook\"\n filename=\"员工入职手册.pdf\"\n onSuccess={() => message.success('员工入职手册下载成功')}\n onError={() => message.error('文件下载失败')}\n >\n 点击下载\n </Download>\n </div>\n\n <div>\n <Text type=\"secondary\">公司规章制度:</Text>\n <br />\n <Download\n id=\"doc-company-rules\"\n filename=\"公司规章制度.docx\"\n onSuccess={() => message.success('公司规章制度下载成功')}\n >\n 点击下载\n </Download>\n </div>\n\n <div>\n <Text type=\"secondary\">薪酬福利政策:</Text>\n <br />\n <Download\n id=\"doc-salary-policy\"\n filename=\"薪酬福利政策.pdf\"\n onSuccess={() => message.success('薪酬福利政策下载成功')}\n >\n 点击下载\n </Download>\n </div>\n </Space>\n </Card>\n </Space>\n );\n};\n\nrender(\n <PureGlobal\n preset={{\n apis: {\n file: {\n getUrl: {\n loader: async ({ params }) => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve(getPublicPath(\"components-core\") + \"/avatar.png\");\n }, 800);\n });\n },\n },\n },\n },\n }}\n >\n <BaseExample />\n </PureGlobal>\n);\n\n`,\n scope: [{\n name: \"_File\",\n packageName: \"@components/File\",\n component: component_18\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_19\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_20\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_21\n}]\n},{\n title: `文件列表`,\n description: `展示文件列表组件,支持上传状态、文件信息展示、编辑、预览、删除等操作,项目文档库和员工简历场景`,\n code: `const { List } = _FileList;\nconst { Space, Card, Alert, Typography } = antd;\nconst { PureGlobal } = global;\nconst { getPublicPath } = remoteLoader;\n\nconst { Title } = Typography;\n\nconst BaseExample = () => {\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Alert\n message=\"文件列表示例\"\n description=\"展示文件上传状态、文件信息及操作功能\"\n type=\"info\"\n showIcon\n />\n\n <Card title=\"项目文档库\">\n <List\n dataSource={[\n {\n uuid: \"upload-001\",\n type: \"uploading\",\n filename: \"项目需求规格说明书.docx\",\n },\n {\n id: \"doc-project-plan\",\n filename: \"项目执行计划.pdf\",\n date: \"2024-01-15T10:30:00.000+08:00\",\n userName: \"张三\",\n },\n {\n id: \"doc-technical-design\",\n filename: \"技术架构设计文档.pdf\",\n date: \"2024-01-16T14:20:00.000+08:00\",\n userName: \"李四\",\n },\n {\n id: \"doc-api-interface\",\n filename: \"API 接口文档.md\",\n date: \"2024-01-17T09:15:00.000+08:00\",\n userName: \"王五\",\n },\n ]}\n apis={{\n onEdit: async (formData, itemData) => {\n console.log('编辑文件:', formData, itemData);\n },\n onDelete: async (itemData) => {\n console.log('删除文件:', itemData);\n },\n onPreview: async (itemData) => {\n console.log('预览文件:', itemData);\n },\n }}\n />\n </Card>\n\n <Card title=\"员工简历上传\">\n <List\n dataSource={[\n {\n id: \"resume-zhangsan\",\n filename: \"张三-高级前端工程师-简历.pdf\",\n date: \"2024-01-18T16:45:00.000+08:00\",\n userName: \"张三\",\n },\n {\n id: \"resume-lisi\",\n filename: \"李四-产品经理-简历.doc\",\n date: \"2024-01-19T11:20:00.000+08:00\",\n userName: \"李四\",\n },\n ]}\n apis={{\n onEdit: async (formData, itemData) => {\n console.log('编辑简历:', formData, itemData);\n },\n onDelete: async (itemData) => {\n console.log('删除简历:', itemData);\n },\n onPreview: async (itemData) => {\n console.log('预览简历:', itemData);\n },\n }}\n />\n </Card>\n </Space>\n );\n};\n\nrender(\n <PureGlobal\n preset={{\n apis: {\n file: {\n getUrl: {\n loader: async ({ params }) => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve(getPublicPath(\"components-core\") + \"/mock/resume.pdf\");\n }, 600);\n });\n },\n },\n },\n },\n }}\n >\n <BaseExample />\n </PureGlobal>\n);\n\n`,\n scope: [{\n name: \"_File\",\n packageName: \"@components/File\",\n component: component_18\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_19\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_20\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_21\n}]\n},{\n title: `文件链接`,\n description: `展示 FileLink 和 useFileModal 的使用,合同文档、财务发票、政策文档预览`,\n code: `const { FileLink, useFileModal } = _File;\nconst { getPublicPath } = remoteLoader;\nconst { PureGlobal } = global;\nconst { Space, Card, Alert, Typography, Button, Descriptions } = antd;\n\nconst { Title, Text } = Typography;\n\nconst CustomPreviewButton = ({ children, ...props }) => {\n const modal = useFileModal(props);\n return (\n <Button type=\"primary\" onClick={() => modal()}>\n {props.originName || children}\n </Button>\n );\n};\n\nconst BaseExample = () => {\n return (\n <PureGlobal\n preset={{\n apis: {\n file: {\n getUrl: {\n loader: async ({ params }) => {\n const mapping = {\n \"contract-001\": \"/avatar.png\",\n \"contract-002\": \"/mock/resume.pdf\",\n \"invoice-001\": \"/avatar.png\",\n \"policy-001\": \"/mock/resume.pdf\",\n };\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve(getPublicPath(\"components-core\") + (mapping[params.id] || \"\"));\n }, 500);\n });\n },\n },\n },\n },\n }}\n >\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Alert\n message=\"文件链接示例\"\n description=\"展示 FileLink 和 useFileModal 的使用方式\"\n type=\"info\"\n showIcon\n />\n\n <Card title=\"合同文档(FileLink)\">\n <Space direction=\"vertical\">\n <FileLink\n id=\"contract-001\"\n originName=\"员工劳动合同.pdf\"\n />\n <FileLink\n id=\"contract-002\"\n originName=\"保密协议.docx\"\n />\n </Space>\n </Card>\n\n <Card title=\"财务发票(使用 useFileModal 自定义按钮)\">\n <Descriptions column={1} size=\"small\">\n <Descriptions.Item label=\"发票编号\">INV-2024-0001</Descriptions.Item>\n <Descriptions.Item label=\"开票日期\">2024-01-20</Descriptions.Item>\n <Descriptions.Item label=\"发票类型\">增值税专用发票</Descriptions.Item>\n </Descriptions>\n <div style={{ marginTop: 16 }}>\n <CustomPreviewButton\n id=\"invoice-001\"\n originName=\"查看发票详情\"\n />\n </div>\n </Card>\n\n <Card title=\"政策文档\">\n <Space direction=\"vertical\">\n <Text type=\"secondary\">点击下方链接预览公司政策文档:</Text>\n <FileLink\n id=\"policy-001\"\n originName=\"2024年度绩效考核管理办法.pdf\"\n />\n </Space>\n </Card>\n </Space>\n </PureGlobal>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_File\",\n packageName: \"@components/File\",\n component: component_18\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_20\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_19\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_21\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_27 from '@components/FileList';\nimport * as component_28 from '@kne/remote-loader';\nimport * as component_29 from 'lodash';\nimport * as component_30 from 'antd';\nconst readmeConfig = {\n name: `FileList`,\n summary: `<p>FileList 组件提供了一套完整的文件管理解决方案,集成了文件列表展示、文件预览、文件上传等功能。</p>\n<p>该组件支持拖拽上传、点击上传两种方式,提供了列表和预览两种视图模式。列表视图展示文件详细信息并支持编辑、删除、预览等操作,预览视图直接展示文件内容。组件内置了文件类型识别、上传进度管理、权限控制等功能,可以轻松集成到各种业务场景中。</p>\n<p>核心特性:</p>\n<ul>\n<li><strong>多视图模式</strong>:支持列表视图和预览视图切换,满足不同使用需求</li>\n<li><strong>拖拽上传</strong>:支持拖拽文件到指定区域进行上传,提升用户体验</li>\n<li><strong>文件预览</strong>:内置预览功能,支持多种文件格式的在线预览</li>\n<li><strong>权限控制</strong>:支持细粒度的权限控制,可控制添加、编辑、删除、预览等操作</li>\n<li><strong>灵活配置</strong>:支持自定义文件类型、文件大小限制、最大上传数量等参数</li>\n<li><strong>受控/非受控</strong>:同时支持受控和非受控模式,适应不同的使用场景</li>\n</ul>\n<p>适用于文档管理系统、人力资源系统、项目管理工具等需要文件处理的应用场景。</p>`,\n \n \n api: `<h3>FileList 组件</h3>\n<p>文件列表组件,提供文件展示、预览、上传等完整功能。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>list</td>\n<td>文件列表数据</td>\n<td>array</td>\n<td>否</td>\n<td>[]</td>\n</tr>\n<tr>\n<td>setList</td>\n<td>更新文件列表的函数</td>\n<td>function</td>\n<td>否*</td>\n<td>-</td>\n</tr>\n<tr>\n<td>defaultPreviewFileId</td>\n<td>默认预览的文件 ID</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>defaultTab</td>\n<td>默认显示的标签页,可选值为 <code>\"list\"</code> 或 <code>\"preview\"</code></td>\n<td>string</td>\n<td>否</td>\n<td><code>\"list\"</code></td>\n</tr>\n<tr>\n<td>maxLength</td>\n<td>最大文件数量</td>\n<td>number</td>\n<td>否</td>\n<td>Number.MAX_VALUE</td>\n</tr>\n<tr>\n<td>fileSize</td>\n<td>单个文件最大大小(MB)</td>\n<td>number</td>\n<td>否</td>\n<td>20</td>\n</tr>\n<tr>\n<td>accept</td>\n<td>允许上传的文件类型数组</td>\n<td>array&lt;string&gt;</td>\n<td>否</td>\n<td><code>[\".png\", \".jpg\", \".pdf\", \".docx\", \".doc\"]</code></td>\n</tr>\n<tr>\n<td>getPermission</td>\n<td>权限控制函数,接收参数 <code>(type, itemData)</code>,返回 <code>false</code> 表示无权限</td>\n<td>function</td>\n<td>否</td>\n<td><code>() =&gt; true</code></td>\n</tr>\n<tr>\n<td>infoItemRenders</td>\n<td>自定义列渲染配置</td>\n<td>array</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis</td>\n<td>操作 API 配置</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis.onSave</td>\n<td>保存文件回调,接收参数 <code>(response, ...args)</code></td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis.onEdit</td>\n<td>编辑文件名称回调,接收参数 <code>({formData, item})</code></td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis.onPreview</td>\n<td>预览文件回调,接收参数 <code>(item)</code></td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis.onDelete</td>\n<td>删除文件回调,接收参数 <code>(item)</code></td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis.onUpload</td>\n<td>文件上传回调</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>titleExtra</td>\n<td>标题额外内容,可以是 ReactNode 或函数</td>\n<td>ReactNode | function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>getPopupContainer</td>\n<td>指定下拉菜单挂载的父节点</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<p><strong>注意</strong>:使用受控模式时需要同时提供 <code>list</code> 和 <code>setList</code> 属性。</p>\n<h4>list 数据结构</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>id</td>\n<td>文件唯一标识符</td>\n<td>string</td>\n</tr>\n<tr>\n<td>ossId</td>\n<td>OSS 文件标识符</td>\n<td>string</td>\n</tr>\n<tr>\n<td>filename</td>\n<td>文件名称</td>\n<td>string</td>\n</tr>\n<tr>\n<td>date</td>\n<td>上传日期(时间戳或 Date 对象)</td>\n<td>Date | string</td>\n</tr>\n<tr>\n<td>userName</td>\n<td>上传人姓名</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n<h3>FileUpload 组件</h3>\n<p>简化的文件上传组件,专注于文件上传和列表展示功能。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>list</td>\n<td>文件列表数据</td>\n<td>array</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>defaultList</td>\n<td>默认文件列表数据</td>\n<td>array</td>\n<td>否</td>\n<td>[]</td>\n</tr>\n<tr>\n<td>setList</td>\n<td>更新文件列表的函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>maxLength</td>\n<td>最大文件数量</td>\n<td>number</td>\n<td>否</td>\n<td>Number.MAX_VALUE</td>\n</tr>\n<tr>\n<td>fileSize</td>\n<td>单个文件最大大小(MB)</td>\n<td>number</td>\n<td>否</td>\n<td>20</td>\n</tr>\n<tr>\n<td>accept</td>\n<td>允许上传的文件类型数组</td>\n<td>array&lt;string&gt;</td>\n<td>否</td>\n<td><code>[\".png\", \".jpg\", \".pdf\", \".docx\", \".doc\"]</code></td>\n</tr>\n<tr>\n<td>getPermission</td>\n<td>权限控制函数,接收参数 <code>(type, itemData)</code>,返回 <code>false</code> 表示无权限</td>\n<td>function</td>\n<td>否</td>\n<td><code>() =&gt; true</code></td>\n</tr>\n<tr>\n<td>apis</td>\n<td>操作 API 配置</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis.onSave</td>\n<td>保存文件回调</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis.onEdit</td>\n<td>编辑文件名称回调</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis.onPreview</td>\n<td>预览文件回调</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis.onDelete</td>\n<td>删除文件回调</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>DragArea 组件</h3>\n<p>拖拽上传区域组件。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>children</td>\n<td>拖拽区域内显示的内容</td>\n<td>ReactNode</td>\n<td>否</td>\n<td><code>&lt;UploadTips /&gt;</code></td>\n</tr>\n<tr>\n<td>className</td>\n<td>自定义类名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>DragAreaOuter 组件</h3>\n<p>拖拽上传区域外层容器组件。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>title</td>\n<td>标题内容</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>子内容</td>\n<td>ReactNode</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>accept</td>\n<td>允许上传的文件类型数组</td>\n<td>array&lt;string&gt;</td>\n<td>否</td>\n<td><code>[\".png\", \".jpg\", \".pdf\", \".docx\", \".doc\"]</code></td>\n</tr>\n<tr>\n<td>fileSize</td>\n<td>单个文件最大大小(MB)</td>\n<td>number</td>\n<td>否</td>\n<td>20</td>\n</tr>\n<tr>\n<td>maxLength</td>\n<td>最大文件数量</td>\n<td>number</td>\n<td>否</td>\n<td>Number.MAX_VALUE</td>\n</tr>\n<tr>\n<td>onFileSelected</td>\n<td>文件选择回调,接收参数 <code>(fileList)</code></td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>defaultOpen</td>\n<td>默认是否打开拖拽区域</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>className</td>\n<td>自定义类名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>DragButton 组件</h3>\n<p>拖拽上传按钮组件。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>children</td>\n<td>按钮文字内容</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>UploadButton 组件</h3>\n<p>点击上传按钮组件。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>children</td>\n<td>按钮文字内容</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>UploadTips 组件</h3>\n<p>上传提示组件,显示上传说明信息。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>icon</td>\n<td>自定义图标</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>title</td>\n<td>提示标题</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>renderTips</td>\n<td>自定义提示内容渲染函数,接收参数 <code>(defaultTips, {fileSize, maxLength, accept})</code></td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>`,\n example: {\n isFull: true,\n className: ``,\n style: ``,\n list: [{\n title: `完整示例`,\n description: `展示完整的文件列表功能,包含文件展示、预览、上传、编辑、删除等操作,员工简历、合同、政策文档场景`,\n code: `const { default: FileList } = _FileList;\nconst { createWithRemoteLoader, getPublicPath } = remoteLoader;\nconst { useState } = React;\nconst { uniqueId } = lodash;\n\nconst ajax = {\n postForm: (config) => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve({\n data: {\n code: 0,\n data: {\n id: \"uBFNeYQBnHRXlZaTGZpA\",\n originalName: config.file.name,\n },\n },\n });\n }, 800);\n });\n },\n};\n\nconst apis = {\n onSave: async ({ data }) => {\n return {\n ossId: uniqueId(\"oss_\"),\n filename: data.originalName,\n date: new Date(),\n userName: \"张三\",\n };\n },\n onDelete: (item) => {\n console.log('删除文件:', item);\n },\n};\n\nconst preset = {\n apis: {\n file: {\n getUrl: {\n loader: async ({ params }) => {\n const mapping = {\n \"resume-zhangsan\": \"/mock/resume.pdf\",\n \"contract-employee\": \"/avatar.png\",\n \"policy-2024\": \"/mock/resume.pdf\",\n };\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve(getPublicPath(\"components-core\") + mapping[params.id] || \"\");\n }, 100);\n });\n },\n },\n },\n previewOffice: {\n loader: async () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve({\n name: \"员工入职登记表.docx\",\n data: [\n {\n id: \"doc-preview-001\",\n originalName: \"preview.pdf\",\n url: getPublicPath(\"components-core\") + \"/mock/resume.pdf\",\n },\n ],\n });\n }, 0);\n });\n },\n },\n ossUpload: ({ file }) => {\n return ajax.postForm({ file });\n },\n },\n};\n\nconst BaseExample = createWithRemoteLoader({\n modules: [\"components-core:Global@PureGlobal\"],\n})(({ remoteModules }) => {\n const [PureGlobal] = remoteModules;\n const [list, setList] = useState([\n {\n id: \"resume-zhangsan\",\n filename: \"张三-高级前端工程师-简历.pdf\",\n date: \"2024-01-15T10:30:00.000+08:00\",\n userName: \"张三\",\n },\n {\n id: \"contract-employee\",\n filename: \"劳动合同模板.docx\",\n date: \"2024-01-16T14:20:00.000+08:00\",\n userName: \"李四\",\n },\n {\n id: \"policy-2024\",\n filename: \"2024年度绩效考核管理办法.pdf\",\n date: \"2024-01-17T09:15:00.000+08:00\",\n userName: \"王五\",\n },\n ]);\n return (\n <PureGlobal preset={preset}>\n <FileList\n defaultPreviewFileId=\"resume-zhangsan\"\n list={list}\n setList={setList}\n apis={apis}\n titleExtra={({ currentTab, currentPreviewFileId }) => (\n <span style={{ fontSize: '12px', color: '#999' }}>\n {currentTab === 'preview' ? '预览模式' : '列表模式'}\n {currentPreviewFileId && \\` | 当前: \\${list.find(f => f.id === currentPreviewFileId)?.filename}\\`}\n </span>\n )}\n />\n </PureGlobal>\n );\n});\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FileList\",\n packageName: \"@components/FileList\",\n component: component_27\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_28\n},{\n name: \"lodash\",\n packageName: \"lodash\",\n component: component_29\n}]\n},{\n title: `文件上传`,\n description: `展示受控和非受控模式的文件上传功能,支持设置文件大小和数量限制`,\n code: `const { FileUpload } = _FileList;\nconst { createWithRemoteLoader, getPublicPath } = remoteLoader;\nconst { useState } = React;\nconst { uniqueId } = lodash;\nconst { Space, Typography, Alert } = antd;\n\nconst { Text } = Typography;\n\nconst ajax = {\n postForm: (config) => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve({\n data: {\n code: 0,\n data: {\n id: \"uBFNeYQBnHRXlZaTGZpA\",\n originalName: config.file.name,\n },\n },\n });\n }, 800);\n });\n },\n};\n\nconst apis = {\n onSave: async ({ data }) => {\n return {\n ossId: uniqueId(\"oss_\"),\n filename: data.originalName,\n date: new Date(),\n userName: \"张三\",\n };\n },\n onDelete: (item) => {\n console.log('删除文件:', item);\n },\n};\n\nconst preset = {\n apis: {\n file: {\n getUrl: {\n loader: async ({ params }) => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve(getPublicPath(\"components-core\") + \"/avatar.png\");\n }, 500);\n });\n },\n },\n },\n ossUpload: ({ file }) => {\n return ajax.postForm({ file });\n },\n },\n};\n\nconst BaseExample = createWithRemoteLoader({\n modules: [\"components-core:Global@PureGlobal\"],\n})(({ remoteModules }) => {\n const [PureGlobal] = remoteModules;\n const [list, setList] = useState([]);\n const [uncontrolledList, setUncontrolledList] = useState([]);\n\n return (\n <PureGlobal preset={preset}>\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Alert\n message=\"文件上传示例\"\n description=\"展示受控和非受控模式的文件上传功能\"\n type=\"info\"\n showIcon\n />\n\n <div>\n <Text strong>受控模式:</Text>\n <Text type=\"secondary\" style={{ marginLeft: 8 }}>\n 通过 list 和 setList 完全控制文件列表\n </Text>\n <FileUpload\n list={list}\n setList={setList}\n apis={apis}\n fileSize={10}\n maxLength={5}\n />\n <div style={{ marginTop: 8, padding: '12px', background: '#f5f5f5', borderRadius: '4px' }}>\n <Text type=\"secondary\">当前文件数量:{list.length}</Text>\n </div>\n </div>\n\n <div>\n <Text strong>非受控模式:</Text>\n <Text type=\"secondary\" style={{ marginLeft: 8 }}>\n 只通过 setList 接收变化,不传入 list\n </Text>\n <FileUpload\n setList={(fileList) => {\n setUncontrolledList(fileList);\n }}\n apis={apis}\n fileSize={10}\n />\n <div style={{ marginTop: 8, padding: '12px', background: '#f5f5f5', borderRadius: '4px' }}>\n <Text type=\"secondary\">当前文件数量:{uncontrolledList.length}</Text>\n </div>\n </div>\n </Space>\n </PureGlobal>\n );\n});\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FileList\",\n packageName: \"@components/FileList\",\n component: component_27\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_28\n},{\n name: \"lodash\",\n packageName: \"lodash\",\n component: component_29\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_30\n}]\n},{\n title: `拖拽上传`,\n description: `展示拖拽上传功能,支持自定义上传提示,项目文档和员工资料上传场景`,\n code: `const { DragArea, DragAreaOuter, UploadButton, DragButton, UploadTips } = _FileList;\nconst { Row, Col, Divider, Space, Typography, Alert, Card, message } = antd;\n\nconst { Text } = Typography;\n\nconst BaseExample = () => {\n return (\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Alert\n message=\"拖拽上传示例\"\n description=\"支持拖拽文件到指定区域进行上传,或使用按钮点击上传\"\n type=\"info\"\n showIcon\n />\n\n <Card title=\"项目文档上传\">\n <DragAreaOuter\n title={\n <Row>\n <Col flex={1}>\n <Text strong>上传项目文档</Text>\n </Col>\n <Col>\n <Space split={<Divider type=\"vertical\" />}>\n <DragButton />\n <UploadButton>选择文件</UploadButton>\n </Space>\n </Col>\n </Row>\n }\n onFileSelected={(fileList) => {\n message.success(\\`已选择 \\${fileList.length} 个文件\\`);\n console.log('选中的文件:', fileList);\n }}\n fileSize={10}\n maxLength={10}\n >\n <DragArea>\n <UploadTips\n icon={<span style={{ fontSize: '48px' }}>📁</span>}\n title=\"拖拽文件到这里\"\n renderTips={(defaultTips, { fileSize, maxLength }) => (\n <div>\n <div>{defaultTips}</div>\n <Text type=\"secondary\" style={{ fontSize: '12px' }}>\n 支持批量上传,最多 {maxLength} 个文件\n </Text>\n </div>\n )}\n />\n </DragArea>\n </DragAreaOuter>\n </Card>\n\n <Card title=\"员工资料上传\">\n <DragAreaOuter\n title={\n <Row>\n <Col flex={1}>\n <Text strong>上传员工资料</Text>\n </Col>\n <Col>\n <Space split={<Divider type=\"vertical\" />}>\n <DragButton />\n <UploadButton>选择文件</UploadButton>\n </Space>\n </Col>\n </Row>\n }\n onFileSelected={(fileList) => {\n message.success(\\`已选择 \\${fileList.length} 个文件\\`);\n console.log('选中的文件:', fileList);\n }}\n fileSize={5}\n accept={['.pdf', '.jpg', '.png', '.docx']}\n >\n <DragArea />\n </DragAreaOuter>\n </Card>\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FileList\",\n packageName: \"@components/FileList\",\n component: component_27\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_30\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_31 from '@components/FilePreview';\nimport * as component_32 from '@kne/remote-loader';\nimport * as component_33 from '@components/Global';\nconst readmeConfig = {\n name: `FilePreview`,\n summary: `<p>FilePreview 是一个功能全面的文件预览组件库,支持多种常见文件格式的在线预览。该组件基于 @kne/react-file 封装,提供了统一的 API 接口,可根据文件类型自动选择合适的预览方式,极大简化了文件预览功能的集成。</p>\n<p>核心特性包括:支持图片、音频、视频、PDF、HTML、文本和 Office 文档等多种格式;提供 OSS 文件预览能力,通过文件 ID 自动获取预览地址;响应式设计,自动适配容器宽度;完善的加载状态和错误提示;支持自定义 PDF 渲染参数和 Office 预览配置。</p>\n<p>适用于文档管理系统、在线办公平台、内容管理系统等需要文件预览功能的场景,特别适合需要处理多种文件类型的企业级应用。组件采用模块化设计,可以独立使用各个预览组件,也可使用统一的 FilePreview 组件自动判断文件类型。</p>`,\n \n \n api: `<h3>FilePreview 组件</h3>\n<p>智能文件预览组件,根据文件类型自动选择对应的预览方式。支持直接传入文件 URL 或 OSS 文件 ID 两种方式。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>src</td>\n<td>文件预览地址,优先使用该参数</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>id</td>\n<td>OSS 文件标识符,当 src 未提供时使用</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>originName</td>\n<td>原始文件名,用于判断文件类型</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>filename</td>\n<td>文件名,用于判断文件类型</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis</td>\n<td>API 配置对象</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>OSSFilePreview 组件</h3>\n<p>OSS 文件预览组件,通过文件 ID 从服务器获取文件地址后进行预览。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>id</td>\n<td>OSS 文件标识符</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>filename</td>\n<td>文件名,用于判断文件类型</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>staticUrl</td>\n<td>静态文件地址前缀</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>render</td>\n<td>自定义渲染函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis</td>\n<td>API 配置对象</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>HtmlPreview 组件</h3>\n<p>HTML 文件预览组件,支持在 iframe 中展示 HTML 内容。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>url</td>\n<td>HTML 文件地址</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>maxWidth</td>\n<td>最大显示宽度</td>\n<td>number</td>\n<td>否</td>\n<td>1200</td>\n</tr>\n<tr>\n<td>ignoreContent</td>\n<td>是否忽略内容检查,直接使用 iframe</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>className</td>\n<td>自定义类名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>PdfPreview 组件</h3>\n<p>PDF 文件预览组件,基于 react-pdf 实现,支持缩放和旋转。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>url</td>\n<td>PDF 文件地址</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>maxWidth</td>\n<td>最大显示宽度</td>\n<td>number</td>\n<td>否</td>\n<td>1200</td>\n</tr>\n<tr>\n<td>scale</td>\n<td>缩放比例(100 为原始大小)</td>\n<td>number</td>\n<td>否</td>\n<td>100</td>\n</tr>\n<tr>\n<td>rotate</td>\n<td>旋转角度</td>\n<td>number</td>\n<td>否</td>\n<td>0</td>\n</tr>\n<tr>\n<td>pdfjsUrl</td>\n<td>pdf.js CDN 地址</td>\n<td>string</td>\n<td>否</td>\n<td>https://cdn.jsdelivr.net/npm/pdfjs-dist@5.4.296</td>\n</tr>\n<tr>\n<td>className</td>\n<td>自定义类名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>TextPreview 组件</h3>\n<p>文本文件预览组件,支持纯文本文件的在线展示。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>url</td>\n<td>文本文件地址</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>maxWidth</td>\n<td>最大显示宽度</td>\n<td>number</td>\n<td>否</td>\n<td>1200</td>\n</tr>\n<tr>\n<td>className</td>\n<td>自定义类名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>ImagePreview 组件</h3>\n<p>图片预览组件,支持常见图片格式的展示。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>url</td>\n<td>图片地址</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>maxWidth</td>\n<td>最大显示宽度</td>\n<td>number</td>\n<td>否</td>\n<td>1200</td>\n</tr>\n<tr>\n<td>scale</td>\n<td>缩放比例</td>\n<td>number</td>\n<td>否</td>\n<td>1</td>\n</tr>\n<tr>\n<td>rotate</td>\n<td>旋转角度</td>\n<td>number</td>\n<td>否</td>\n<td>0</td>\n</tr>\n<tr>\n<td>origin</td>\n<td>是否使用原生 img 标签,不带容器和加载状态</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>className</td>\n<td>自定义类名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>AudioPreview 组件</h3>\n<p>音频预览组件,使用原生 audio 标签进行音频播放。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>url</td>\n<td>音频文件地址</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>maxWidth</td>\n<td>最大显示宽度</td>\n<td>number</td>\n<td>否</td>\n<td>1200</td>\n</tr>\n<tr>\n<td>className</td>\n<td>自定义类名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>VideoPreview 组件</h3>\n<p>视频预览组件,使用原生 video 标签进行视频播放。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>url</td>\n<td>视频文件地址</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>maxWidth</td>\n<td>最大显示宽度</td>\n<td>number</td>\n<td>否</td>\n<td>1200</td>\n</tr>\n<tr>\n<td>controls</td>\n<td>是否显示播放控件</td>\n<td>boolean</td>\n<td>否</td>\n<td>true</td>\n</tr>\n<tr>\n<td>origin</td>\n<td>是否使用原生 video 标签,不带容器</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>getElement</td>\n<td>获取 video 元素的回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>className</td>\n<td>自定义类名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>OfficePreview 组件</h3>\n<p>Office 文件预览组件,使用 Office Online Viewer 进行预览。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>url</td>\n<td>Office 文件地址</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>className</td>\n<td>自定义类名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>apis</td>\n<td>API 配置对象,可配置自定义预览服务</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>UnknownPreview 组件</h3>\n<p>未知类型文件预览组件,用于不支持预览的文件类型。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>maxWidth</td>\n<td>最大显示宽度</td>\n<td>number</td>\n<td>否</td>\n<td>1200</td>\n</tr>\n</tbody>\n</table>`,\n example: {\n isFull: true,\n className: ``,\n style: ``,\n list: [{\n title: `HtmlPreview`,\n description: `这里填写示例说明`,\n code: `const { default: FilePreview, HtmlPreview } = _FilePreview;\nconst { getPublicPath } = remoteLoader;\nconst BaseExample = () => {\n return (\n <HtmlPreview\n maxWidth={900}\n url={getPublicPath(\"components-core\") + \"/mock/demo2.html\"}\n />\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FilePreview\",\n packageName: \"@components/FilePreview\",\n component: component_31\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_32\n}]\n},{\n title: `PdfPreview`,\n description: `这里填写示例说明`,\n code: `const { PdfPreview } = _FilePreview;\nconst { getPublicPath } = remoteLoader;\nconst BaseExample = () => {\n return (\n <PdfPreview\n maxWidth={900}\n url={getPublicPath(\"components-core\") + \"/mock/resume.pdf\"}\n renderTextLayer={true}\n />\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FilePreview\",\n packageName: \"@components/FilePreview\",\n component: component_31\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_32\n}]\n},{\n title: `TextPreview`,\n description: `这里填写示例说明`,\n code: `const { TextPreview } = _FilePreview;\nconst { getPublicPath } = remoteLoader;\nconst BaseExample = () => {\n return (\n <TextPreview\n maxWidth={900}\n url={getPublicPath(\"components-core\") + \"/mock/demo.txt\"}\n />\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FilePreview\",\n packageName: \"@components/FilePreview\",\n component: component_31\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_32\n}]\n},{\n title: `ImagePreview`,\n description: `这里填写示例说明`,\n code: `const { ImagePreview } = _FilePreview;\nconst { getPublicPath } = remoteLoader;\nconst BaseExample = () => {\n return (\n <ImagePreview url={getPublicPath(\"components-core\") + \"/mock/resume.png\"} />\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FilePreview\",\n packageName: \"@components/FilePreview\",\n component: component_31\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_32\n}]\n},{\n title: `unknown`,\n description: `这里填写示例说明`,\n code: `const { UnknownPreview } = _FilePreview;\nconst { getPublicPath } = remoteLoader;\nconst BaseExample = () => {\n return (\n <UnknownPreview url={getPublicPath(\"components-core\") + \"/mock/demo.des\"} />\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FilePreview\",\n packageName: \"@components/FilePreview\",\n component: component_31\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_32\n}]\n},{\n title: `office`,\n description: `这里填写示例说明`,\n code: `const {default: FilePreview} = _FilePreview;\nconst {getPublicPath} = remoteLoader;\nconst {PureGlobal} = _Global;\nconst BaseExample = () => {\n return (\n <PureGlobal\n preset={{\n apis: {\n file: {\n getUrl: {\n loader:()=>{\n return \"http://ieee802.org:80/secmail/docIZSEwEqHFr.doc\";\n },\n },\n },\n },\n }}\n >\n <FilePreview\n id=\"63bb2013-c743-4d2d-9d91-935c865f1c4d\"\n originName=\"docIZSEwEqHFr.doc\"\n />\n </PureGlobal>\n );\n};\n\nrender(<BaseExample/>);\n\n`,\n scope: [{\n name: \"_FilePreview\",\n packageName: \"@components/FilePreview\",\n component: component_31\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_32\n},{\n name: \"_Global\",\n packageName: \"@components/Global\",\n component: component_33\n}]\n},{\n title: `audio`,\n description: `这里填写示例说明`,\n code: `const { AudioPreview } = _FilePreview;\nconst { getPublicPath } = remoteLoader;\nconst BaseExample = () => {\n return (\n <AudioPreview\n maxWidth={900}\n url={getPublicPath(\"components-core\") + \"/mock/audio.wav\"}\n />\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FilePreview\",\n packageName: \"@components/FilePreview\",\n component: component_31\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_32\n},{\n name: \"_Global\",\n packageName: \"@components/Global\",\n component: component_33\n}]\n},{\n title: `video`,\n description: `这里填写示例说明`,\n code: `const { VideoPreview } = _FilePreview;\nconst { getPublicPath } = remoteLoader;\nconst BaseExample = () => {\n return (\n <VideoPreview\n maxWidth={900}\n url={getPublicPath(\"components-core\") + \"/mock/video.mp4\"}\n />\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FilePreview\",\n packageName: \"@components/FilePreview\",\n component: component_31\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_32\n},{\n name: \"_Global\",\n packageName: \"@components/Global\",\n component: component_33\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_34 from '@components/Filter';\nimport * as component_35 from 'antd';\nimport * as component_36 from '@components/Filter/doc/mock/tree-data.json';\nconst readmeConfig = {\n name: `Filter`,\n summary: `<p>Filter 是一个功能强大的筛选组件库,用于构建灵活的筛选条件界面。该组件提供了多种预置的筛选字段类型,支持自定义筛选项,并提供了完整的筛选值管理和展示功能。</p>\n<p>核心特性包括:丰富的预置筛选字段,涵盖文本输入、日期选择、城市选择、用户选择、行业选择、职能选择等多种类型;灵活的筛选值管理,支持受控和非受控模式;支持展开/收起筛选项,避免筛选条件过多导致界面混乱;提供高级筛选组件,适用于复杂筛选场景;支持自定义字段和组合使用,满足各种业务需求;内置搜索输入框和筛选值展示组件,提升用户体验。</p>\n<p>适用于数据列表、表格筛选、报表查询等需要多条件筛选的场景。组件采用 Context API 进行状态管理,支持嵌套使用和组合,能够满足企业级应用中各种复杂的筛选需求。</p>`,\n \n \n api: `<h3>Filter 组件</h3>\n<p>筛选组件的主入口,用于构建灵活的筛选条件界面。支持受控和非受控模式,自动管理筛选值状态。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>value</td>\n<td>筛选值数组,受控模式使用</td>\n<td>array</td>\n<td>否</td>\n<td>[]</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>筛选值变化回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>defaultValue</td>\n<td>默认筛选值</td>\n<td>array</td>\n<td>否</td>\n<td>[]</td>\n</tr>\n<tr>\n<td>list</td>\n<td>筛选项配置数组,支持多行布局</td>\n<td>array</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>displayLine</td>\n<td>默认显示的行数,超过则支持展开/收起</td>\n<td>number</td>\n<td>否</td>\n<td>1</td>\n</tr>\n<tr>\n<td>label</td>\n<td>筛选标题,默认显示\"筛选\"</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>extra</td>\n<td>额外内容,通常用于放置搜索输入框等</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>extraExpand</td>\n<td>额外展开内容,显示在已选筛选值右侧</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>className</td>\n<td>自定义类名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h4>value 数据结构</h4>\n<p>筛选值数组中每个元素的结构:</p>\n<pre><code class=\"language-javascript\">{\n name: 'city', // 筛选字段名\n label: '城市', // 筛选项标签\n value: [ // 筛选值,可以是单个值或数组\n { label: '上海', value: '010' },\n { label: '北京', value: '020' }\n ]\n}\n</code></pre>\n<h3>AdvancedFilter 组件</h3>\n<p>高级筛选组件,适用于需要展示多个筛选条件且支持展开/收起的场景。相比普通 Filter 组件,提供更紧凑的布局。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>value</td>\n<td>筛选值数组</td>\n<td>array</td>\n<td>否</td>\n<td>[]</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>筛选值变化回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>defaultValue</td>\n<td>默认筛选值</td>\n<td>array</td>\n<td>否</td>\n<td>[]</td>\n</tr>\n<tr>\n<td>list</td>\n<td>筛选项配置数组</td>\n<td>array</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>more</td>\n<td>更多筛选项,支持展开/收起</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>FilterLines 组件</h3>\n<p>筛选项布局组件,用于按照行展示筛选项,支持展开/收起功能。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>list</td>\n<td>筛选项配置数组,支持多行布局</td>\n<td>array</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>displayLine</td>\n<td>默认显示的行数</td>\n<td>number</td>\n<td>否</td>\n<td>1</td>\n</tr>\n<tr>\n<td>label</td>\n<td>筛选标题</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>extra</td>\n<td>额外内容</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>className</td>\n<td>自定义类名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>FilterValueDisplay 组件</h3>\n<p>筛选值展示组件,用于展示已选择的筛选条件,支持单个删除和清空全部。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>value</td>\n<td>筛选值数组</td>\n<td>array</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>筛选值变化回调函数</td>\n<td>function</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>extraExpand</td>\n<td>额外展开内容,显示在清空按钮左侧</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>FilterItem 组件</h3>\n<p>筛选项容器组件,提供统一的样式和交互效果。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>筛选项标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>open</td>\n<td>是否打开下拉</td>\n<td>boolean</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>active</td>\n<td>是否激活状态(有选中值时自动激活)</td>\n<td>boolean</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>筛选项内容</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>PopoverItem 组件</h3>\n<p>弹出式筛选项组件,基于 Popover 实现。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>筛选项标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>渲染函数,接收 { value, onChange } 参数</td>\n<td>function</td>\n<td>是</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>SearchInput 组件</h3>\n<p>搜索输入框组件,通常用于放置在筛选器右侧的搜索功能。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>输入框占位符</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>value</td>\n<td>输入框值</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>值变化回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>FilterItemContainer 组件</h3>\n<p>筛选项容器组件,用于包装需要传递额外属性的筛选项。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>渲染函数,接收筛选项 props</td>\n<td>function</td>\n<td>是</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>InputFilterItem 组件</h3>\n<p>文本输入筛选项组件,用于文本类型的筛选。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>输入框占位符</td>\n<td>string</td>\n<td>否</td>\n<td>请输入{label}</td>\n</tr>\n<tr>\n<td>value</td>\n<td>输入框值</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>值变化回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>DatePickerFilterItem 组件</h3>\n<p>日期选择筛选项组件,支持多种日期选择模式。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>picker</td>\n<td>日期选择器类型,可选值:<code>date</code>、<code>week</code>、<code>month</code>、<code>quarter</code>、<code>year</code></td>\n<td>string</td>\n<td>否</td>\n<td><code>date</code></td>\n</tr>\n<tr>\n<td>value</td>\n<td>日期值</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>值变化回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>DateRangePickerFilterItem 组件</h3>\n<p>日期范围选择筛选项组件,用于选择日期范围。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>value</td>\n<td>日期范围值</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>值变化回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>TypeDateRangePickerFilterItem 组件</h3>\n<p>类型化日期范围选择筛选项组件,支持日期类型选择(如创建时间、更新时间等)。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>allowEmpty</td>\n<td>是否允许清空 [开始时间清空, 结束时间清空]</td>\n<td>array</td>\n<td>否</td>\n<td>[false, false]</td>\n</tr>\n<tr>\n<td>value</td>\n<td>日期范围值</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>值变化回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>CityFilterItem 组件</h3>\n<p>城市选择筛选项组件,支持省市区三级联动选择。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>value</td>\n<td>城市值</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>值变化回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>single</td>\n<td>是否单选</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n</tbody>\n</table>\n<h3>NumberRangeFilterItem 组件</h3>\n<p>数值范围筛选项组件,用于选择数值范围。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>unit</td>\n<td>数值单位</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>value</td>\n<td>数值范围值</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>值变化回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>AdvancedSelectFilterItem 组件</h3>\n<p>高级选择筛选项组件,支持远程数据加载、分页、搜索等功能。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>api</td>\n<td>API 配置对象</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>api.loader</td>\n<td>数据加载函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>value</td>\n<td>选择值</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>值变化回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>SuperSelectFilterItem 组件</h3>\n<p>超级选择筛选项组件,支持展示描述信息、图标等丰富的选项内容。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>options</td>\n<td>选项数据数组</td>\n<td>array</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>value</td>\n<td>选择值</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>值变化回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>UserFilterItem 组件</h3>\n<p>用户选择筛选项组件,专门用于用户选择场景。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>api</td>\n<td>API 配置对象</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>api.loader</td>\n<td>数据加载函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>value</td>\n<td>用户值</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>值变化回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>SuperSelectUserFilterItem 组件</h3>\n<p>超级用户选择筛选项组件,支持展示用户描述信息。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>api</td>\n<td>API 配置对象</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>api.loader</td>\n<td>数据加载函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>value</td>\n<td>用户值</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>值变化回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>FunctionSelectFilterItem 组件</h3>\n<p>职能选择筛选项组件,用于选择职能信息。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>selectLevel</td>\n<td>选择层级</td>\n<td>number</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>maxLength</td>\n<td>最大选择数量</td>\n<td>number</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>single</td>\n<td>是否单选</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>onlyAllowLastLevel</td>\n<td>是否只允许选择最后一级</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>value</td>\n<td>职能值</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>值变化回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>IndustrySelectFilterItem 组件</h3>\n<p>行业选择筛选项组件,用于选择行业信息。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>selectLevel</td>\n<td>选择层级</td>\n<td>number</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>maxLength</td>\n<td>最大选择数量</td>\n<td>number</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>single</td>\n<td>是否单选</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>onlyAllowLastLevel</td>\n<td>是否只允许选择最后一级</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>value</td>\n<td>行业值</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>值变化回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>CascaderFilterItem 组件</h3>\n<p>级联选择筛选项组件,用于级联数据的选择。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>options</td>\n<td>选项数据数组</td>\n<td>array</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>value</td>\n<td>选择值</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>值变化回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>TreeFilterItem 组件</h3>\n<p>树形选择筛选项组件,用于树形结构数据的选择。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>api</td>\n<td>API 配置对象</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>api.loader</td>\n<td>数据加载函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>fieldNames</td>\n<td>字段名映射</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>fieldNames.title</td>\n<td>标题字段名</td>\n<td>string</td>\n<td>否</td>\n<td><code>title</code></td>\n</tr>\n<tr>\n<td>fieldNames.key</td>\n<td>键字段名</td>\n<td>string</td>\n<td>否</td>\n<td><code>key</code></td>\n</tr>\n<tr>\n<td>fieldNames.children</td>\n<td>子节点字段名</td>\n<td>string</td>\n<td>否</td>\n<td><code>children</code></td>\n</tr>\n<tr>\n<td>single</td>\n<td>是否单选</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>value</td>\n<td>选择值</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>值变化回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>高级字段组件</h3>\n<h4>ListFilterItem 组件(AdvancedFilter.fields)</h4>\n<p>列表选择筛选项组件,以标签形式展示选项,支持单选和多选。</p>\n<h4>组件属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>items</td>\n<td>选项数据数组</td>\n<td>array</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>single</td>\n<td>是否单选</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>maxLength</td>\n<td>最大选择数量</td>\n<td>number</td>\n<td>否</td>\n<td>5</td>\n</tr>\n<tr>\n<td>custom</td>\n<td>自定义筛选项</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>value</td>\n<td>选择值</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>值变化回调函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>工具函数</h3>\n<h4>getFilterValue</h4>\n<p>将筛选值数组转换为对象格式。</p>\n<p><strong>函数签名:</strong></p>\n<pre><code class=\"language-javascript\">getFilterValue(filterValue: array): object\n</code></pre>\n<p><strong>参数说明:</strong></p>\n<table>\n<thead>\n<tr>\n<th>参数名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>filterValue</td>\n<td>筛选值数组</td>\n<td>array</td>\n</tr>\n</tbody>\n</table>\n<p><strong>返回值:</strong></p>\n<p>转换后的对象,格式为 <code>{ name: value, ... }</code>,其中 value 是提取的值数组或单个值。</p>\n<p><strong>示例:</strong></p>\n<pre><code class=\"language-javascript\">const filterValue = [\n { name: 'city', value: [{ label: '上海', value: '010' }] },\n { name: 'text', value: { label: '测试', value: 'test' } }\n];\nconst result = getFilterValue(filterValue);\n// result: { city: ['010'], text: 'test' }\n</code></pre>\n<h4>useFilter</h4>\n<p>获取筛选上下文的 Hook。</p>\n<p><strong>函数签名:</strong></p>\n<pre><code class=\"language-javascript\">useFilter(): object\n</code></pre>\n<p><strong>返回值:</strong></p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>value</td>\n<td>筛选值 Map</td>\n<td>Map</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>筛选值变化函数</td>\n<td>function</td>\n</tr>\n</tbody>\n</table>\n<h4>withFilterValue</h4>\n<p>高阶组件,用于自动连接筛选上下文。</p>\n<p><strong>函数签名:</strong></p>\n<pre><code class=\"language-javascript\">withFilterValue(WrappedComponent): ReactComponent\n</code></pre>\n<p><strong>参数说明:</strong></p>\n<table>\n<thead>\n<tr>\n<th>参数名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>WrappedComponent</td>\n<td>被包装的组件</td>\n<td>ReactComponent</td>\n</tr>\n</tbody>\n</table>\n<p><strong>新增 Props:</strong></p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n<h4>withFieldItem</h4>\n<p>高阶组件,用于将表单字段组件包装为筛选项组件。</p>\n<p><strong>函数签名:</strong></p>\n<pre><code class=\"language-javascript\">withFieldItem(WrappedComponent): ReactComponent\n</code></pre>\n<p><strong>参数说明:</strong></p>\n<table>\n<thead>\n<tr>\n<th>参数名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>WrappedComponent</td>\n<td>被包装的组件</td>\n<td>ReactComponent</td>\n</tr>\n</tbody>\n</table>\n<p><strong>新增 Props:</strong></p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>string</td>\n</tr>\n<tr>\n<td>interceptor</td>\n<td>拦截器,用于值转换</td>\n<td>object</td>\n</tr>\n<tr>\n<td>interceptor.input</td>\n<td>输入拦截器</td>\n<td>function</td>\n</tr>\n<tr>\n<td>interceptor.output</td>\n<td>输出拦截器</td>\n<td>function</td>\n</tr>\n</tbody>\n</table>`,\n example: {\n isFull: true,\n className: ``,\n style: ``,\n list: [{\n title: `基础用法`,\n description: `展示 Filter 组件的基本使用方式,包括各种常见的筛选字段类型`,\n code: `const {\n default: Filter,\n InputFilterItem,\n DatePickerFilterItem,\n DateRangePickerFilterItem,\n TypeDateRangePickerFilterItem,\n CityFilterItem,\n AdvancedSelectFilterItem,\n SuperSelectFilterItem,\n SuperSelectUserFilterItem,\n UserFilterItem,\n FunctionSelectFilterItem,\n IndustrySelectFilterItem,\n getFilterValue,\n FilterItemContainer,\n} = _Filter;\nconst { useState } = React;\nconst BaseExample = () => {\n const [value, onChange] = useState([]);\n return (\n <Filter\n value={value}\n onChange={(value) => {\n console.log(getFilterValue(value));\n onChange(value);\n }}\n extra={<Filter.SearchInput name=\"name\" label=\"姓名\" />}\n list={[\n [\n <InputFilterItem label=\"文字\" name=\"text\" />,\n <CityFilterItem label=\"城市\" name=\"city\" />,\n <FilterItemContainer name=\"select\" label=\"高级选择\">\n {(props) => (\n <div>\n <AdvancedSelectFilterItem\n {...props}\n api={{\n loader: () => {\n return {\n pageData: [\n { label: \"第一项\", value: 1 },\n {\n label: \"第二项\",\n value: 2,\n disabled: true,\n },\n {\n label: \"第三项\",\n value: 3,\n },\n ],\n };\n },\n }}\n />\n </div>\n )}\n </FilterItemContainer>,\n <DatePickerFilterItem label=\"日期\" name=\"date\" picker=\"week\" />,\n <TypeDateRangePickerFilterItem\n label=\"复杂日期范围\"\n name=\"type-data-range\"\n allowEmpty={[true, true]}\n />,\n <DateRangePickerFilterItem label=\"日期范围\" name=\"date-range\" />,\n <SuperSelectFilterItem\n label=\"选择信息\"\n name=\"select-value\"\n options={[\n {\n label: \"用户一\",\n value: 1,\n description: \"我是用户描述\",\n },\n {\n label: \"用户二\",\n value: 2,\n description: \"我是用户描述\",\n },\n ]}\n />,\n <SuperSelectUserFilterItem\n label=\"用户选择\"\n name=\"user\"\n api={{\n loader: () => {\n return {\n pageData: [\n {\n label: \"用户一\",\n value: 1,\n description: \"我是用户描述\",\n },\n {\n label: \"用户二\",\n value: 2,\n description: \"我是用户描述\",\n },\n {\n label: \"用户三\",\n value: 3,\n description: \"我是用户描述\",\n },\n ],\n };\n },\n }}\n />,\n <FunctionSelectFilterItem\n label=\"职能选择\"\n name=\"functionLast\"\n onlyAllowLastLevel\n />,\n <FunctionSelectFilterItem\n label=\"职能选择\"\n name=\"function\"\n selectLevel={3}\n maxLength={3}\n />,\n <FunctionSelectFilterItem\n label=\"职能选择\"\n name=\"functionSingle\"\n single\n />,\n <IndustrySelectFilterItem\n label=\"行业选择\"\n name=\"industryLast\"\n onlyAllowLastLevel\n />,\n <IndustrySelectFilterItem\n label=\"行业选择\"\n name=\"industry\"\n selectLevel={2}\n maxLength={3}\n />,\n <IndustrySelectFilterItem\n label=\"行业选择\"\n name=\"industrySingle\"\n single\n />,\n ],\n ]}\n />\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Filter\",\n packageName: \"@components/Filter\",\n component: component_34\n}]\n},{\n title: `高级筛选`,\n description: `展示 AdvancedFilter 组件的高级筛选功能,适用于复杂筛选场景`,\n code: `const {\n default: Filter,\n AdvancedFilter,\n InputFilterItem,\n DatePickerFilterItem,\n DateRangePickerFilterItem,\n TypeDateRangePickerFilterItem,\n CityFilterItem,\n AdvancedSelectFilterItem,\n UserFilterItem,\n FunctionSelectFilterItem,\n IndustrySelectFilterItem,\n NumberRangeFilterItem,\n getFilterValue,\n FilterItemContainer,\n} = _Filter;\nconst { useState } = React;\n\nconst {\n CityFilterItem: CityAdvancedFilterItem,\n ListFilterItem,\n InputFilterItem: InputAdvancedFilterItem,\n} = AdvancedFilter.fields;\nconst BaseExample = () => {\n const [value, onChange] = useState([]);\n return (\n <AdvancedFilter\n value={value}\n onChange={(value) => {\n console.log(getFilterValue(value));\n onChange(value);\n }}\n list={[\n [<CityAdvancedFilterItem name=\"currentCity\" label=\"当前城市\" single />],\n [<CityAdvancedFilterItem name=\"expectCity\" label=\"期望城市\" />],\n [\n <ListFilterItem\n name=\"experience\"\n label=\"工作经验\"\n single\n items={[\n {\n value: [null, 1],\n label: \"1年以下\",\n },\n {\n value: [1, 5],\n label: \"1-5年\",\n },\n { value: [5, null], label: \"5年以上\" },\n ]}\n custom={<NumberRangeFilterItem label=\"自定义\" unit=\"年\" />}\n />,\n ],\n [<InputAdvancedFilterItem name=\"company\" label=\"公司\" />],\n ]}\n more={[\n <InputFilterItem label=\"文字\" name=\"text\" />,\n <CityFilterItem label=\"城市\" name=\"city\" />,\n <FilterItemContainer name=\"select\" label=\"高级选择\">\n {(props) => (\n <div>\n <AdvancedSelectFilterItem\n {...props}\n api={{\n loader: () => {\n return {\n pageData: [\n { label: \"第一项\", value: 1 },\n {\n label: \"第二项\",\n value: 2,\n disabled: true,\n },\n {\n label: \"第三项\",\n value: 3,\n },\n ],\n };\n },\n }}\n />\n </div>\n )}\n </FilterItemContainer>,\n <DatePickerFilterItem label=\"日期\" name=\"date\" picker=\"week\" />,\n <TypeDateRangePickerFilterItem\n label=\"复杂日期范围\"\n name=\"type-data-range\"\n allowEmpty={[true, true]}\n />,\n <DateRangePickerFilterItem label=\"日期范围\" name=\"date-range\" />,\n <UserFilterItem\n label=\"用户选择\"\n name=\"user\"\n api={{\n loader: () => {\n return {\n pageData: [\n {\n label: \"用户一\",\n value: 1,\n description: \"我是用户描述\",\n },\n {\n label: \"用户二\",\n value: 2,\n description: \"我是用户描述\",\n },\n {\n label: \"用户三\",\n value: 3,\n description: \"我是用户描述\",\n },\n ],\n };\n },\n }}\n />,\n <FunctionSelectFilterItem\n label=\"职能选择\"\n name=\"function\"\n onlyAllowLastLevel\n single\n />,\n <IndustrySelectFilterItem\n label=\"行业选择\"\n name=\"industry\"\n onlyAllowLastLevel\n />,\n ]}\n />\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Filter\",\n packageName: \"@components/Filter\",\n component: component_34\n}]\n},{\n title: `树形筛选`,\n description: `展示 TreeFilterItem 树形选择组件的使用`,\n code: `const { default: Filter, TreeFilterItem } = _Filter;\nconst { default: treeData } = _data;\nconst { useState } = React;\nconst { Space } = antd;\n\nconst BaseExample = () => {\n const [filter, setFilter] = useState([]);\n const [filter2, setFilter2] = useState([]);\n\n return (\n <Space direction=\"vertical\">\n <Filter\n value={filter}\n onChange={setFilter}\n list={[\n [\n <TreeFilterItem\n name=\"tree\"\n single\n label=\"树组件\"\n fieldNames={{\n title: \"name\",\n key: \"id\",\n children: \"children\",\n }}\n api={{\n loader: () => {\n return treeData.children;\n },\n }}\n />,\n ],\n ]}\n />\n <Filter\n value={filter2}\n onChange={setFilter2}\n list={[\n [\n <TreeFilterItem\n name=\"tree\"\n label=\"树组件\"\n fieldNames={{\n title: \"name\",\n key: \"id\",\n children: \"children\",\n }}\n api={{\n loader: () => {\n return treeData.children;\n },\n }}\n />,\n ],\n ]}\n />\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Filter\",\n packageName: \"@components/Filter\",\n component: component_34\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_35\n},{\n name: \"_data\",\n packageName: \"@components/Filter/doc/mock/tree-data.json\",\n component: component_36\n}]\n},{\n title: `筛选值展示`,\n description: `展示 FilterValueDisplay、FilterItem、FilterLines、PopoverItem 等组件的独立使用`,\n code: `const {\n FilterValueDisplay,\n FilterItem,\n FilterLines,\n PopoverItem,\n InputFilterItem,\n CityFilterItem,\n AdvancedSelectFilterItem,\n UserFilterItem,\n FunctionSelectFilterItem,\n IndustrySelectFilterItem,\n} = _Filter;\nconst { Space, Input } = antd;\nconst { useState } = React;\nconst BaseExample = () => {\n const [value, setValue] = useState([\n {\n label: \"城市\",\n name: \"city\",\n value: [\n { label: \"上海\", value: \"010\" },\n { label: \"北京\", value: \"020\" },\n ],\n },\n {\n label: \"职能\",\n name: \"function\",\n value: [\n { label: \"产品经理\", value: \"010\" },\n { label: \"销售\", value: \"020\" },\n {\n label: \"客户经理\",\n value: \"030\",\n },\n ],\n },\n ]);\n return (\n <Space direction=\"vertical\">\n <FilterValueDisplay value={value} onChange={setValue} />\n <Space>\n <FilterItem label=\"客户\" />\n <FilterItem label=\"客户\" active />\n <FilterItem label=\"客户\" open />\n <FilterItem label=\"超长超长超长超长超长超长超长超长\" active open />\n </Space>\n <FilterLines\n list={[\n [\n <FilterItem label=\"客户\" />,\n <FilterItem label=\"职位\" />,\n <FilterItem label=\"职位负责人\" />,\n ],\n [\n <FilterItem label=\"开始时间\" />,\n <FilterItem label=\"结束时间\" />,\n <FilterItem label=\"职位BD人\" />,\n ],\n [\n <FilterItem label=\"开始时间\" />,\n <FilterItem label=\"结束时间\" />,\n <FilterItem label=\"职位BD人\" />,\n ],\n [\n <FilterItem label=\"开始时间\" />,\n <FilterItem label=\"结束时间\" />,\n <FilterItem label=\"职位BD人\" />,\n ],\n ]}\n />\n <PopoverItem label=\"客户\">\n {({ value, onChange }) => (\n <Input value={value} onChange={(e) => onChange(e.target.value)} />\n )}\n </PopoverItem>\n <FilterLines\n list={[\n [\n <InputFilterItem label=\"文字\" />,\n <CityFilterItem label=\"城市\" />,\n <AdvancedSelectFilterItem\n label=\"高级选择\"\n api={{\n loader: () => {\n return {\n pageData: [\n { label: \"第一项\", value: 1 },\n { label: \"第二项\", value: 2, disabled: true },\n {\n label: \"第三项\",\n value: 3,\n },\n ],\n };\n },\n }}\n />,\n <UserFilterItem\n label=\"用户选择\"\n api={{\n loader: () => {\n return {\n pageData: [\n {\n label: \"用户一\",\n value: 1,\n description: \"我是用户描述\",\n },\n {\n label: \"用户二\",\n value: 2,\n description: \"我是用户描述\",\n },\n {\n label: \"用户三\",\n value: 3,\n description: \"我是用户描述\",\n },\n ],\n };\n },\n }}\n />,\n <FunctionSelectFilterItem label=\"职能选择\" />,\n <IndustrySelectFilterItem label=\"行业选择\" />,\n ],\n ]}\n />\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Filter\",\n packageName: \"@components/Filter\",\n component: component_34\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_35\n}]\n},{\n title: `数值范围筛选`,\n description: `展示 NumberRangeFilterItem 数值范围筛选组件的使用`,\n code: `const {\n default: Filter,\n NumberRangeFilterItem,\n getFilterValue,\n} = _Filter;\nconst { useState } = React;\n\nconst BaseExample = () => {\n const [value, onChange] = useState([]);\n\n return (\n <Filter\n value={value}\n onChange={(value) => {\n console.log('筛选值:', getFilterValue(value));\n onChange(value);\n }}\n list={[\n [\n <NumberRangeFilterItem label=\"年龄\" name=\"age\" unit=\"岁\" />,\n <NumberRangeFilterItem label=\"薪资\" name=\"salary\" unit=\"万\" />,\n <NumberRangeFilterItem label=\"工作经验\" name=\"experience\" unit=\"年\" />,\n ],\n ]}\n />\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Filter\",\n packageName: \"@components/Filter\",\n component: component_34\n}]\n},{\n title: `级联筛选`,\n description: `展示 CascaderFilterItem 级联选择组件的使用`,\n code: `const {\n default: Filter,\n CascaderFilterItem,\n getFilterValue,\n} = _Filter;\nconst { useState } = React;\n\nconst options = [\n {\n label: '浙江',\n value: 'zhejiang',\n children: [\n {\n label: '杭州',\n value: 'hangzhou',\n children: [\n { label: '西湖区', value: 'xihu' },\n { label: '滨江区', value: 'binjiang' },\n { label: '余杭区', value: 'yuhang' },\n ],\n },\n {\n label: '宁波',\n value: 'ningbo',\n children: [\n { label: '海曙区', value: 'haishu' },\n { label: '江北区', value: 'jiangbei' },\n ],\n },\n ],\n },\n {\n label: '江苏',\n value: 'jiangsu',\n children: [\n {\n label: '南京',\n value: 'nanjing',\n children: [\n { label: '玄武区', value: 'xuanwu' },\n { label: '秦淮区', value: 'qinhuai' },\n ],\n },\n {\n label: '苏州',\n value: 'suzhou',\n children: [\n { label: '姑苏区', value: 'gusu' },\n { label: '吴中区', value: 'wuzhong' },\n ],\n },\n ],\n },\n];\n\nconst BaseExample = () => {\n const [value, onChange] = useState([]);\n\n return (\n <Filter\n value={value}\n onChange={(value) => {\n console.log('筛选值:', getFilterValue(value));\n onChange(value);\n }}\n list={[\n [\n <CascaderFilterItem\n label=\"地区选择\"\n name=\"region\"\n options={options}\n placeholder=\"请选择地区\"\n />,\n ],\n ]}\n />\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Filter\",\n packageName: \"@components/Filter\",\n component: component_34\n}]\n},{\n title: `自定义筛选字段`,\n description: `展示如何使用 withFilterValue 将原生 Select 组件包装成筛选字段`,\n code: `const {\n default: Filter,\n InputFilterItem,\n CityFilterItem,\n withFilterValue,\n} = _Filter;\nconst { Select } = antd;\nconst { useState } = React;\n\n// 自定义下拉筛选组件 - 展示如何使用 withFilterValue 包装原生组件\nconst CustomSelectFilter = withFilterValue(({ label, value, onChange, options }) => {\n return (\n <Select\n placeholder={\\`请选择\\${label}\\`}\n value={value?.value}\n onChange={(val) => onChange({ label, value: val })}\n allowClear\n style={{ width: 200 }}\n options={options}\n />\n );\n});\n\nconst BaseExample = () => {\n const [value, onChange] = useState([]);\n\n return (\n <Filter\n value={value}\n onChange={(value) => {\n console.log('筛选值:', value);\n onChange(value);\n }}\n list={[\n [\n <InputFilterItem label=\"部门\" name=\"department\" placeholder=\"请输入部门名称\" />,\n <CityFilterItem label=\"城市\" name=\"city\" />,\n <CustomSelectFilter\n label=\"项目状态\"\n name=\"status\"\n options={[\n { label: '进行中', value: 'ongoing' },\n { label: '已完成', value: 'completed' },\n { label: '已暂停', value: 'paused' },\n { label: '已取消', value: 'cancelled' },\n ]}\n />,\n <CustomSelectFilter\n label=\"优先级\"\n name=\"priority\"\n options={[\n { label: '高', value: 'high' },\n { label: '中', value: 'medium' },\n { label: '低', value: 'low' },\n ]}\n />,\n ],\n ]}\n />\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Filter\",\n packageName: \"@components/Filter\",\n component: component_34\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_35\n}]\n},{\n title: `FilterProvider 和 useFilter`,\n description: `展示如何使用 FilterProvider 和 useFilter Hook 自定义筛选界面`,\n code: `const {\n FilterProvider,\n FilterLines,\n FilterValueDisplay,\n useFilter,\n InputFilterItem,\n CityFilterItem,\n UserFilterItem,\n FunctionSelectFilterItem,\n IndustrySelectFilterItem,\n DatePickerFilterItem,\n NumberRangeFilterItem,\n} = _Filter;\nconst { Space, Card, Button, Modal, Tag, Alert } = antd;\nconst { useState } = React;\n\n// 演示 FilterProvider 和 useFilter 的使用\nconst CustomFilterContent = () => {\n const { value, onChange } = useFilter();\n const [modalVisible, setModalVisible] = useState(false);\n\n const handleViewFilterValue = () => {\n setModalVisible(true);\n };\n\n const renderFilterValue = () => {\n if (!value) {\n return <p>暂无筛选条件</p>;\n }\n\n // 处理 value 可能是 Map 的情况\n const valueArray = value instanceof Map ? Array.from(value.values()) : (Array.isArray(value) ? value : []);\n\n if (valueArray.length === 0) {\n return <p>暂无筛选条件</p>;\n }\n\n return (\n <Space direction=\"vertical\" size={12}>\n {valueArray.map((item, index) => (\n <Tag key={index} color=\"blue\" style={{ fontSize: 14 }}>\n <strong>{item.label}</strong>: {Array.isArray(item.value)\n ? item.value.map(v => v.label).join(', ')\n : item.value?.label || item.value}\n </Tag>\n ))}\n </Space>\n );\n };\n\n return (\n <Space direction=\"vertical\" size={16} style={{ width: '100%' }}>\n <Alert\n message=\"使用提示\"\n description=\"点击筛选项,输入值后点击「确定」按钮,然后点击下方按钮查看筛选条件\"\n type=\"info\"\n showIcon\n />\n\n <Card title=\"筛选器\" size=\"small\">\n <FilterLines\n list={[\n [\n <InputFilterItem label=\"姓名\" name=\"name\" />,\n <CityFilterItem label=\"城市\" name=\"city\" />,\n <UserFilterItem label=\"用户\" name=\"user\" />,\n <FunctionSelectFilterItem label=\"职能\" name=\"function\" />,\n ],\n [\n <IndustrySelectFilterItem label=\"行业\" name=\"industry\" />,\n <DatePickerFilterItem label=\"创建时间\" name=\"createTime\" />,\n <NumberRangeFilterItem label=\"年龄\" name=\"age\" />,\n ],\n ]}\n />\n </Card>\n\n <Button type=\"primary\" onClick={handleViewFilterValue}>\n 查看筛选值\n </Button>\n\n <Modal\n title=\"当前筛选值\"\n open={modalVisible}\n onCancel={() => setModalVisible(false)}\n footer={[\n <Button key=\"close\" onClick={() => setModalVisible(false)}>\n 关闭\n </Button>,\n ]}\n width={600}\n >\n {renderFilterValue()}\n <div style={{ marginTop: 16 }}>\n <Button\n type=\"link\"\n size=\"small\"\n onClick={() => {\n navigator.clipboard.writeText(JSON.stringify(value, null, 2));\n }}\n >\n 复制 JSON 数据\n </Button>\n </div>\n </Modal>\n </Space>\n );\n};\n\nconst BaseExample = () => {\n const [value, setValue] = useState([]);\n\n return (\n <FilterProvider value={value} onChange={setValue}>\n <CustomFilterContent />\n {value.length > 0 && (\n <FilterValueDisplay value={value} onChange={setValue} />\n )}\n </FilterProvider>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Filter\",\n packageName: \"@components/Filter\",\n component: component_34\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_35\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_37 from '@kne/flex-box';\nimport * as component_38 from 'antd';\nconst readmeConfig = {\n name: `flex-box`,\n summary: ``,\n \n \n api: `<h3>useFlexBox</h3>\n<p>const {ref, column} = useFlexBox(props);</p>\n<p>注意:返回的 ref 必须传给一个 dom 的 ref</p>\n<p>继承了<a href=\"https://ant.design/components/list-cn#list\">Ant Design List props</a>的参数,同时也新增了两个参数:</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>columns</td>\n<td>实际用于 <code>List</code> 的 <code>grid</code></td>\n<td><code>columnProps[]</code></td>\n<td><code>defaultColumns</code></td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>设置 <code>column</code></td>\n<td>(column) =&gt; onChange()</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h4>columnProps</h4>\n<p>默认值:</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>width</td>\n<td>视口宽度</td>\n<td>number</td>\n<td>-</td>\n</tr>\n<tr>\n<td>col</td>\n<td>列数</td>\n<td>number</td>\n<td>-</td>\n</tr>\n<tr>\n<td>size</td>\n<td>根据 <code>col</code> 列数填每页数据加载多少条</td>\n<td>number</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<pre><code class=\"language-text\"> defaultColumns = [\n {width: 576, col: 1, size: 15},\n {width: 768, col: 2, size: 12},\n {width: 1200, col: 4, size: 12},\n {width: 1600, col: 5, size: 15}\n ]\n</code></pre>\n<h3>FlexBox</h3>\n<p>同 <code>useFlexBox</code> 参数</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>outerClassName</td>\n<td><code>FlexBox</code> 父元素的 <code>className</code></td>\n<td>string</td>\n<td>-</td>\n</tr>\n<tr>\n<td>gutter</td>\n<td>栅格间隔</td>\n<td>number</td>\n<td>16</td>\n</tr>\n</tbody>\n</table>\n<h4>FlexBox.Item</h4>\n<p>同 <a href=\"https://ant.design/components/list-cn#listitem\">Ant Design List.Item</a></p>`,\n example: {\n isFull: false,\n className: ``,\n style: ``,\n list: [{\n title: `这里填写示例标题`,\n description: `这里填写示例说明`,\n code: `const {default:FlexBox} = _FlexBox;\nconst { Card } = antd;\n\nconst BaseExample = () => {\n return (\n <FlexBox\n dataSource={[\n {\n title: \"Title 1\",\n },\n {\n title: \"Title 2\",\n },\n {\n title: \"Title 3\",\n },\n {\n title: \"Title 4\",\n },\n {\n title: \"Title 5\",\n },\n {\n title: \"Title 6\",\n },\n ]}\n renderItem={(item) => (\n <FlexBox.Item>\n <Card title={item.title}>Card content</Card>\n </FlexBox.Item>\n )}\n />\n );\n};\n\nrender(<BaseExample />);\n\n\n`,\n scope: [{\n name: \"_FlexBox\",\n packageName: \"@kne/flex-box\",\n component: component_37\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_38\n}]\n},{\n title: `这里填写示例标题`,\n description: `这里填写示例说明`,\n code: `const {FlexBoxFetch} = _FlexBox;\nconst {Card, Button} = antd;\nconst {useRef} = React;\nconst BaseExample = () => {\n const ref = useRef();\n return (<div>\n <FlexBoxFetch\n ref={ref}\n pagination={{ position: 'bottom', align: 'center' }}\n getFetchApi={({size}) => {\n return {\n data: {\n pageSize: size,\n }, loader: ({data}) => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve({\n pageData: Array.from({length: data.pageSize}).map((item, index) => {\n return {\n key: index, title: \\`第\\${index}项\\`,\n };\n }),\n });\n }, 1000);\n });\n },\n };\n }}\n renderItem={(item) => (<FlexBoxFetch.Item>\n <Card title={item.title}>Card content</Card>\n </FlexBoxFetch.Item>)}\n />\n <Button\n onClick={() => {\n console.log(ref.current);\n }}\n >\n 获取FetchApi\n </Button>\n </div>);\n};\n\nrender(<BaseExample/>);\n\n`,\n scope: [{\n name: \"_FlexBox\",\n packageName: \"@kne/flex-box\",\n component: component_37\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_38\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_39 from '@components/FormInfo';\nimport * as component_40 from '@components/Modal';\nimport * as component_41 from 'antd';\nimport * as component_42 from '@components/Global';\nimport * as component_43 from '@components/Content';\nimport * as component_44 from 'lodash';\nconst readmeConfig = {\n name: `FormInfo`,\n summary: `<p>功能强大的表单组件,提供完整的数据管理、校验和样式解决方案</p>\n<p>FormInfo 是一个全功能的表单解决方案,集成了数据录入、校验规则管理、样式布局等功能,适用于各种复杂场景的表单需求。</p>\n<h3>核心特性</h3>\n<p><strong>分层校验规则管理</strong></p>\n<ul>\n<li>支持默认级、preset 级、Form 级三层校验规则覆盖</li>\n<li>字符串形式规则调用,简洁直观(如 <code>REQ LEN-3-10 EMAIL</code>)</li>\n<li>支持异步校验规则,满足复杂业务场景需求</li>\n<li>规则参数化支持,灵活可配置</li>\n</ul>\n<p><strong>丰富的表单组件</strong></p>\n<ul>\n<li>提供基础组件:Input、TextArea、Select、DatePicker、RadioGroup、Checkbox、Switch 等</li>\n<li>提供业务组件:地址选择、行业选择、职能选择、用户选择、级联选择等</li>\n<li>提供高级组件:头像上传、文件上传、签名、薪资输入、电话号码输入、金额输入等</li>\n<li>所有组件统一封装,使用体验一致</li>\n</ul>\n<p><strong>灵活的布局方式</strong></p>\n<ul>\n<li>FormInfo 支持分组展示和分栏布局</li>\n<li>List 组件实现多段式列表表单,支持动态添加删除</li>\n<li>TableList 组件提供表格形式的列表展示</li>\n<li>支持无限嵌套,轻松实现复杂表单结构</li>\n</ul>\n<p><strong>多种表单形态</strong></p>\n<ul>\n<li>Form:基础表单组件</li>\n<li>FormModal:弹窗表单,配合 Modal 使用</li>\n<li>FormDrawer:抽屉表单,配合 Drawer 使用</li>\n<li>FormStepModal:分步表单,支持多步骤数据收集</li>\n<li>提供 useFormModal、useFormDrawer、useFormStepModal Hooks</li>\n</ul>\n<p><strong>事件驱动架构</strong></p>\n<ul>\n<li>完善的事件机制,支持表单生命周期监听</li>\n<li>可监听字段添加、删除、校验、值变化等事件</li>\n<li>便于扩展和集成自定义逻辑</li>\n</ul>\n<p><strong>拦截器支持</strong></p>\n<ul>\n<li>支持字段值拦截器</li>\n<li>可实现 Field 值和 Form Data 之间的转换</li>\n<li>解决日期格式化、数据映射等常见问题</li>\n</ul>\n<h3>适用场景</h3>\n<p><strong>数据采集场景</strong></p>\n<ul>\n<li>用户注册、信息录入、问卷调查等基础表单</li>\n<li>个人资料编辑、设置修改等表单场景</li>\n</ul>\n<p><strong>业务流程场景</strong></p>\n<ul>\n<li>审批流程中的信息填写</li>\n<li>订单创建、项目立项等复杂表单</li>\n<li>多步骤向导式数据收集</li>\n</ul>\n<p><strong>数据管理场景</strong></p>\n<ul>\n<li>列表数据的批量编辑</li>\n<li>动态列表的增删改查</li>\n<li>复杂嵌套数据结构的录入</li>\n</ul>\n<p><strong>集成场景</strong></p>\n<ul>\n<li>配合弹窗、抽屉组件的表单展示</li>\n<li>与数据加载组件结合的表单编辑</li>\n<li>自定义业务组件的表单集成</li>\n</ul>\n<h3>技术亮点</h3>\n<p><strong>上下文与 Ref 双重 API</strong></p>\n<ul>\n<li>提供 useFormContext Hook 在组件内获取表单实例</li>\n<li>支持 ref 方式在外部访问表单方法</li>\n<li>灵活的表单操作方式</li>\n</ul>\n<p><strong>多语言支持</strong></p>\n<ul>\n<li>内置国际化支持</li>\n<li>可自定义多语言配置</li>\n<li>支持字段级别的语言切换</li>\n</ul>\n<p><strong>类型安全</strong></p>\n<ul>\n<li>完善的 TypeScript 类型定义</li>\n<li>编译时类型检查</li>\n<li>良好的开发体验</li>\n</ul>\n<p><strong>高度可扩展</strong></p>\n<ul>\n<li>Field 组件实现规范清晰</li>\n<li>支持自定义 Field 组件</li>\n<li>选择器组件统一封装模式</li>\n</ul>\n<p><strong>性能优化</strong></p>\n<ul>\n<li>按需加载组件</li>\n<li>优化的重渲染机制</li>\n<li>支持大规模表单场景</li>\n</ul>`,\n \n \n api: `<h3>Form</h3>\n<p>表单核心组件,提供数据域管理、校验规则、事件驱动等功能。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>data</td>\n<td>表单初始数据</td>\n<td>object</td>\n<td>否</td>\n<td>{}</td>\n</tr>\n<tr>\n<td>rules</td>\n<td>自定义校验规则,key为规则名,value为校验函数</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>interceptors</td>\n<td>自定义拦截器配置</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onSubmit</td>\n<td>表单提交成功的回调,接收表单数据</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onError</td>\n<td>表单校验失败的回调</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onPrevSubmit</td>\n<td>提交前回调,校验前触发</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>debug</td>\n<td>是否开启调试模式,打印表单状态</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>noFilter</td>\n<td>是否禁用数据过滤</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>helperGuideName</td>\n<td>帮助指引配置名称</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>lang</td>\n<td>语言配置,支持多语言</td>\n<td>array</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>FormInfo</h3>\n<p>表单信息分组组件,用于组织和管理表单字段的布局。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>title</td>\n<td>分组标题</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>list</td>\n<td>字段数组</td>\n<td>array</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>column</td>\n<td>分栏数量,响应式布局</td>\n<td>number</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>gap</td>\n<td>字段间距</td>\n<td>number</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>extra</td>\n<td>额外内容,显示在标题右侧</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>List</h3>\n<p>多段式列表表单组件,支持动态添加和删除表单项。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名,对应表单数据中的 key</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>title</td>\n<td>列表标题</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>list</td>\n<td>字段数组</td>\n<td>array</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>maxLength</td>\n<td>最大数量,达到后隐藏添加按钮</td>\n<td>number</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>minLength</td>\n<td>最小数量,达到后隐藏删除按钮</td>\n<td>number</td>\n<td>否</td>\n<td>0</td>\n</tr>\n<tr>\n<td>addText</td>\n<td>添加按钮文本</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>itemTitle</td>\n<td>单项标题,可以是字符串或函数</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>important</td>\n<td>是否标记为重要项,样式区分</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>block</td>\n<td>是否占满一行</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>outer</td>\n<td>外层容器组件</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>Outer</td>\n</tr>\n<tr>\n<td>renderChildren</td>\n<td>子项渲染函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>deleteButtonProps</td>\n<td>删除按钮属性</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>TableList</h3>\n<p>表格形式的列表表单组件,继承自 List,提供表格展示方式。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>title</td>\n<td>列表标题</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>list</td>\n<td>字段数组</td>\n<td>array</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>maxLength</td>\n<td>最大数量</td>\n<td>number</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>minLength</td>\n<td>最小数量</td>\n<td>number</td>\n<td>否</td>\n<td>0</td>\n</tr>\n<tr>\n<td>isUnshift</td>\n<td>新增项是否添加到开头</td>\n<td>boolean</td>\n<td>否</td>\n<td>true</td>\n</tr>\n</tbody>\n</table>\n<h3>FormModal</h3>\n<p>弹窗表单组件,将 Form 和 Modal 组合使用。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>open</td>\n<td>是否显示弹窗</td>\n<td>boolean</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>title</td>\n<td>弹窗标题</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onClose</td>\n<td>关闭回调</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>formProps</td>\n<td>Form 组件属性</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>表单内容</td>\n<td>ReactNode</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>footerButtons</td>\n<td>底部按钮配置</td>\n<td>array</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>width</td>\n<td>弹窗宽度</td>\n<td>string</td>\n<td>否</td>\n<td>520</td>\n</tr>\n<tr>\n<td>withDecorator</td>\n<td>装饰器函数,用于包装表单内容</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>FormDrawer</h3>\n<p>抽屉表单组件,将 Form 和 Drawer 组合使用。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>open</td>\n<td>是否显示抽屉</td>\n<td>boolean</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>title</td>\n<td>抽屉标题</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onClose</td>\n<td>关闭回调</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>formProps</td>\n<td>Form 组件属性</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>表单内容</td>\n<td>ReactNode</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>footerButtons</td>\n<td>底部按钮配置</td>\n<td>array</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>width</td>\n<td>抽屉宽度</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>withDecorator</td>\n<td>装饰器函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>FormStepModal</h3>\n<p>分步表单弹窗组件,支持多步骤数据收集。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>open</td>\n<td>是否显示弹窗</td>\n<td>boolean</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>items</td>\n<td>步骤配置数组</td>\n<td>array</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onClose</td>\n<td>关闭回调</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>footerButtons</td>\n<td>底部按钮配置</td>\n<td>array</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>withDecorator</td>\n<td>装饰器函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>autoClose</td>\n<td>最后一步完成后是否自动关闭</td>\n<td>boolean</td>\n<td>否</td>\n<td>true</td>\n</tr>\n<tr>\n<td>cancelText</td>\n<td>取消按钮文本</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>completeText</td>\n<td>完成按钮文本</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>nextText</td>\n<td>下一步按钮文本</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h4>items 配置说明</h4>\n<p>items 数组中每个元素为步骤配置对象:</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>title</td>\n<td>步骤标题</td>\n<td>ReactNode</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>formProps</td>\n<td>Form 组件属性,可以是对象或函数</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>footerButtons</td>\n<td>步骤底部按钮配置</td>\n<td>array</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>useFormModal</h3>\n<p>获取表单弹窗 Hook,返回一个可调用函数来弹出表单弹窗。</p>\n<h4>返回值</h4>\n<p>返回一个函数,调用该函数弹出 FormModal 弹窗,参数同 FormModal 组件属性。</p>\n<h3>useFormDrawer</h3>\n<p>获取表单抽屉 Hook,返回一个可调用函数来弹出表单抽屉。</p>\n<h4>返回值</h4>\n<p>返回一个函数,调用该函数弹出 FormDrawer 抽屉,参数同 FormDrawer 组件属性。</p>\n<h3>useFormStepModal</h3>\n<p>获取分步表单弹窗 Hook,返回一个可调用函数来弹出分步表单弹窗。</p>\n<h4>返回值</h4>\n<p>返回一个函数,调用该函数弹出 FormStepModal 弹窗,参数同 FormStepModal 组件属性。</p>\n<h3>FormModalButton</h3>\n<p>按钮触发表单弹窗组件,支持加载数据后弹出。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>api</td>\n<td>数据加载配置,参考 @kne/react-fetch</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>modalProps</td>\n<td>FormModal 弹窗属性,可以是对象或函数</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>按钮内容</td>\n<td>ReactNode</td>\n<td>是</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h4>modalProps 函数形式参数</h4>\n<p>当 modalProps 为函数时,接收以下参数:</p>\n<table>\n<thead>\n<tr>\n<th>参数名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>data</td>\n<td>加载的数据</td>\n<td>any</td>\n</tr>\n<tr>\n<td>fetchApi</td>\n<td>fetch 实例</td>\n<td>object</td>\n</tr>\n<tr>\n<td>close</td>\n<td>关闭弹窗方法</td>\n<td>function</td>\n</tr>\n</tbody>\n</table>\n<h3>FormStepModalButton</h3>\n<p>按钮触发的分步表单弹窗组件。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>api</td>\n<td>数据加载配置</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>modalProps</td>\n<td>FormStepModal 弹窗属性</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>按钮内容</td>\n<td>ReactNode</td>\n<td>是</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>FormDrawerButton</h3>\n<p>按钮触发的表单抽屉组件。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>api</td>\n<td>数据加载配置</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>drawerProps</td>\n<td>FormDrawer 抽屉属性</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>按钮内容</td>\n<td>ReactNode</td>\n<td>是</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>SubmitButton</h3>\n<p>提交按钮组件,点击后触发表单校验和提交。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>autoClose</td>\n<td>提交成功后是否自动关闭弹窗</td>\n<td>boolean</td>\n<td>否</td>\n<td>true</td>\n</tr>\n<tr>\n<td>children</td>\n<td>按钮内容</td>\n<td>ReactNode</td>\n<td>是</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>CancelButton</h3>\n<p>取消按钮组件,点击后重置表单或关闭弹窗。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>children</td>\n<td>按钮内容</td>\n<td>ReactNode</td>\n<td>是</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>FormApiButton</h3>\n<p>表单 API 按钮组件,可执行表单操作。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>onClick</td>\n<td>点击回调,接收表单 API 对象</td>\n<td>function</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>autoClose</td>\n<td>点击后是否自动关闭弹窗</td>\n<td>boolean</td>\n<td>否</td>\n<td>true</td>\n</tr>\n<tr>\n<td>children</td>\n<td>按钮内容</td>\n<td>ReactNode</td>\n<td>是</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h4>onClick 回调参数</h4>\n<p>onClick 回调接收包含表单操作 API 的对象:</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>openApi</td>\n<td>表单 API 对象</td>\n<td>object</td>\n</tr>\n<tr>\n<td>submit</td>\n<td>触发表单提交方法</td>\n<td>function</td>\n</tr>\n<tr>\n<td>reset</td>\n<td>重置表单方法</td>\n<td>function</td>\n</tr>\n<tr>\n<td>validate</td>\n<td>校验表单方法</td>\n<td>function</td>\n</tr>\n<tr>\n<td>setFields</td>\n<td>设置字段值方法</td>\n<td>function</td>\n</tr>\n<tr>\n<td>getFields</td>\n<td>获取字段值方法</td>\n<td>function</td>\n</tr>\n</tbody>\n</table>\n<h3>useFormContext</h3>\n<p>表单上下文 Hook,在 Form 内部获取表单实例和方法。</p>\n<h4>返回值</h4>\n<p>返回表单 API 对象,包含以下属性和方法:</p>\n<table>\n<thead>\n<tr>\n<th>属性名/方法名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>openApi</td>\n<td>表单 API 对象</td>\n<td>object</td>\n</tr>\n<tr>\n<td>formData</td>\n<td>表单数据</td>\n<td>object</td>\n</tr>\n</tbody>\n</table>\n<p>openApi 包含以下方法:</p>\n<table>\n<thead>\n<tr>\n<th>方法名</th>\n<th>说明</th>\n<th>参数</th>\n<th>返回值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>submit</td>\n<td>提交表单</td>\n<td>-</td>\n<td>Promise</td>\n</tr>\n<tr>\n<td>reset</td>\n<td>重置表单</td>\n<td>-</td>\n<td>void</td>\n</tr>\n<tr>\n<td>validate</td>\n<td>校验表单</td>\n<td>-</td>\n<td>Promise</td>\n</tr>\n<tr>\n<td>setFields</td>\n<td>设置字段值</td>\n<td>fields: array, options: object</td>\n<td>void</td>\n</tr>\n<tr>\n<td>getFields</td>\n<td>获取字段值</td>\n<td>names: array</td>\n<td>object</td>\n</tr>\n</tbody>\n</table>\n<h3>MultiField</h3>\n<p>多字段组件,支持在单个 Field 中包含多个子字段。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>rule</td>\n<td>校验规则</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>子字段组件</td>\n<td>ReactNode</td>\n<td>是</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>ErrorTip</h3>\n<p>错误提示组件,可自定义字段错误信息的展示方式。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>errorRender</td>\n<td>自定义错误渲染函数</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>字段组件</td>\n<td>ReactNode</td>\n<td>是</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h4>errorRender 回调参数</h4>\n<p>errorRender 回调接收以下参数:</p>\n<table>\n<thead>\n<tr>\n<th>参数名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>validateData</td>\n<td>字段校验数据</td>\n<td>object</td>\n</tr>\n<tr>\n<td>hasError</td>\n<td>是否有错误</td>\n<td>boolean</td>\n</tr>\n<tr>\n<td>errorMsg</td>\n<td>错误信息</td>\n<td>string</td>\n</tr>\n</tbody>\n</table>\n<h3>FormItem</h3>\n<p>表单项容器组件,用于包装表单字段。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>rule</td>\n<td>校验规则</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>tips</td>\n<td>提示信息</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>labelHidden</td>\n<td>是否隐藏标签</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>children</td>\n<td>字段组件</td>\n<td>ReactNode</td>\n<td>是</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>Field 类型:基础组件</h3>\n<p>以下为基础表单字段组件,请参考 antd 文档:</p>\n<p><strong>Input</strong> - 文本输入框</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>rule</td>\n<td>校验规则</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>占位符</td>\n<td>string</td>\n<td>否</td>\n<td>请输入{label}</td>\n</tr>\n<tr>\n<td>tips</td>\n<td>提示信息,显示问号图标</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<p><strong>TextArea</strong> - 多行文本输入框</p>\n<p><strong>InputNumber</strong> - 数字输入框</p>\n<p><strong>Select</strong> - 下拉选择框</p>\n<p><strong>DatePicker</strong> - 日期选择器</p>\n<ul>\n<li>DatePicker.MonthPicker</li>\n<li>DatePicker.RangePicker</li>\n<li>DatePicker.WeekPicker</li>\n</ul>\n<p><strong>TimePicker</strong> - 时间选择器</p>\n<ul>\n<li>TimePicker.RangePicker</li>\n</ul>\n<p><strong>RadioGroup</strong> - 单选按钮组</p>\n<p><strong>Checkbox</strong> - 复选框</p>\n<p><strong>CheckboxGroup</strong> - 复选框组</p>\n<p><strong>Switch</strong> - 开关</p>\n<p><strong>Rate</strong> - 评分</p>\n<p><strong>Slider</strong> - 滑块</p>\n<p><strong>TreeSelect</strong> - 树选择</p>\n<h3>Field 类型:业务组件</h3>\n<p><strong>AddressSelect</strong> - 地址选择组件</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>rule</td>\n<td>校验规则</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>single</td>\n<td>是否单选</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>isPopup</td>\n<td>是否使用弹窗形式</td>\n<td>boolean</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<p><strong>FunctionSelect</strong> - 职能选择组件</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>rule</td>\n<td>校验规则</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>single</td>\n<td>是否单选</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n</tbody>\n</table>\n<p><strong>IndustrySelect</strong> - 行业选择组件</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>rule</td>\n<td>校验规则</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>single</td>\n<td>是否单选</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n</tbody>\n</table>\n<p><strong>Cascader</strong> - 级联选择组件</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>options</td>\n<td>选项数据</td>\n<td>array</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>rule</td>\n<td>校验规则</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>single</td>\n<td>是否单选</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n</tbody>\n</table>\n<p><strong>Avatar</strong> - 头像上传组件</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>rule</td>\n<td>校验规则</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>border</td>\n<td>裁剪边框</td>\n<td>number</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>width</td>\n<td>宽度</td>\n<td>number</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>height</td>\n<td>高度</td>\n<td>number</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>dropModalSize</td>\n<td>弹窗尺寸</td>\n<td>string</td>\n<td>否</td>\n<td>small</td>\n</tr>\n<tr>\n<td>block</td>\n<td>是否占满一行</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n</tbody>\n</table>\n<p><strong>PhoneNumber</strong> - 电话号码输入组件</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>rule</td>\n<td>校验规则</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<p><strong>MoneyInput</strong> - 金额输入组件</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>rule</td>\n<td>校验规则</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<p><strong>SalaryInput</strong> - 薪资范围输入组件</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>rule</td>\n<td>校验规则</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<p><strong>Upload</strong> - 文件上传组件</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>rule</td>\n<td>校验规则</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>maxCount</td>\n<td>最大上传数量</td>\n<td>number</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>block</td>\n<td>是否占满一行</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n</tbody>\n</table>\n<p><strong>ColorPicker</strong> - 颜色选择器</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<p><strong>Signature</strong> - 签名组件</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>Field 类型:高级选择组件</h3>\n<p><strong>AdvancedSelect</strong> - 高级选择组件,支持列表和表格两种形态</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>api</td>\n<td>数据加载 API 配置</td>\n<td>object</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>rule</td>\n<td>校验规则</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>single</td>\n<td>是否单选</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n<tr>\n<td>isPopup</td>\n<td>是否使用弹窗形式</td>\n<td>boolean</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>getSearchProps</td>\n<td>搜索框配置</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h4>api 配置说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>loader</td>\n<td>数据加载函数</td>\n<td>function</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>params</td>\n<td>加载参数</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<p><strong>SuperSelect</strong> - 超级选择组件</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>api</td>\n<td>数据加载 API 配置</td>\n<td>object</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>rule</td>\n<td>校验规则</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>single</td>\n<td>是否单选</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n</tr>\n</tbody>\n</table>\n<p><strong>SuperSelectTableList</strong> - 表格列表选择组件</p>\n<p><strong>SuperSelectUser</strong> - 用户选择组件</p>\n<p><strong>SuperSelectTree</strong> - 树选择组件</p>\n<h3>Field 类型:特殊组件</h3>\n<p><strong>TypeDateRangePicker</strong> - 类型日期范围选择器</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>rule</td>\n<td>校验规则</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<p><strong>DatePickerToday</strong> - 至今日期选择器</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>字段名</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n</tr>\n<tr>\n<td>label</td>\n<td>字段标签</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>rule</td>\n<td>校验规则</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n</tr>\n<tr>\n<td>soFarText</td>\n<td>至今文本</td>\n<td>string</td>\n<td>否</td>\n<td>至今</td>\n</tr>\n</tbody>\n</table>\n<h3>fieldDecorator</h3>\n<p>字段装饰器工具,用于创建自定义 Field 组件。</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>createWithFieldDecorator</td>\n<td>创建带装饰器的字段组件</td>\n<td>function</td>\n</tr>\n<tr>\n<td>withInputDefaultPlaceholder</td>\n<td>添加输入框默认占位符</td>\n<td>function</td>\n</tr>\n<tr>\n<td>withSelectDefaultPlaceholder</td>\n<td>添加选择器默认占位符</td>\n<td>function</td>\n</tr>\n<tr>\n<td>withLang</td>\n<td>添加多语言支持</td>\n<td>function</td>\n</tr>\n</tbody>\n</table>\n<h3>hooks</h3>\n<p>表单相关 Hooks 集合。</p>\n<h4>常用 Hooks</h4>\n<table>\n<thead>\n<tr>\n<th>Hook 名</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>useField</td>\n<td>获取字段 API</td>\n</tr>\n<tr>\n<td>useReset</td>\n<td>获取重置方法</td>\n</tr>\n<tr>\n<td>useSubmit</td>\n<td>获取提交方法</td>\n</tr>\n</tbody>\n</table>\n<h3>widget</h3>\n<p>表单组件工具集。</p>\n<h3>utils</h3>\n<p>表单工具函数集。</p>\n<h3>formUtils</h3>\n<p>表单实用工具集。</p>\n<h3>RULES</h3>\n<p>内置校验规则。</p>\n<h4>常用规则</h4>\n<table>\n<thead>\n<tr>\n<th>规则名</th>\n<th>说明</th>\n<th>参数</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>REQ</td>\n<td>必填</td>\n<td>-</td>\n</tr>\n<tr>\n<td>LEN</td>\n<td>长度限制</td>\n<td>MIN-MAX</td>\n</tr>\n<tr>\n<td>EMAIL</td>\n<td>邮箱格式</td>\n<td>-</td>\n</tr>\n<tr>\n<td>TEL</td>\n<td>电话号码</td>\n<td>-</td>\n</tr>\n<tr>\n<td>NUM</td>\n<td>数字</td>\n<td>-</td>\n</tr>\n<tr>\n<td>INT</td>\n<td>整数</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>interceptors</h3>\n<p>内置拦截器。</p>\n<h4>使用方式</h4>\n<pre><code class=\"language-javascript\">// 注册拦截器\ninterceptors.input.use(\"date-string\", (value) =&gt; {\n return value ? new Date(value) : null;\n});\n\ninterceptors.output.use(\"date-string\", (value) =&gt; {\n return value ? dayjs(value).format(\"YYYY-MM-DD\") : \"\";\n});\n\n// 在字段中使用\n&lt;Input name=\"date\" label=\"日期\" interceptor=\"date-string\"/&gt;\n</code></pre>\n<h3>SelectInnerInput</h3>\n<p>选择器内部输入框组件,用于自定义选择器开发。</p>\n<h3>FormSteps</h3>\n<p>表单步骤组件,用于 FormStepModal 中显示步骤条。</p>\n<h3>formModule</h3>\n<p>表单模块,导出所有表单相关的组件和工具。</p>`,\n example: {\n isFull: true,\n className: `FormInfo_f344c`,\n style: `.FormInfo_f344c .input > .ant-row > .ant-col {\n padding: 10px 0;\n}\n.FormInfo_f344c .input .ant-space-item:last-child {\n width: 100%;\n}`,\n list: [{\n title: `基础表单`,\n description: `最简单的表单示例,包含常用的输入框、日期选择、下拉选择等基础字段,适合快速上手`,\n code: `const { default: FormInfo, Form, SubmitButton, fields } = _FormInfo;\nconst { useModal } = _Modal;\nconst { Space } = antd;\n\nconst { Input, TextArea, DatePicker, Select } = fields;\n\nconst BaseExample = () => {\n const modal = useModal();\n return (\n <Form\n onSubmit={(data) => {\n modal({\n title: \"客户信息提交成功\",\n children: <pre>{JSON.stringify(data, null, 2)}</pre>,\n });\n }}\n >\n <Space direction=\"vertical\" size={16}>\n <FormInfo\n title=\"客户基本信息\"\n list={[\n <Input name=\"name\" label=\"客户姓名\" rule=\"REQ\" />,\n <Input name=\"phone\" label=\"联系电话\" rule=\"REQ PHONE\" />,\n <Input name=\"email\" label=\"电子邮箱\" rule=\"EMAIL\" />,\n <DatePicker name=\"birthday\" label=\"出生日期\" />,\n <Select\n name=\"gender\"\n label=\"性别\"\n rule=\"REQ\"\n options={[\n { label: \"男\", value: \"male\" },\n { label: \"女\", value: \"female\" },\n ]}\n />,\n <TextArea name=\"remark\" label=\"备注说明\" />,\n ]}\n />\n <SubmitButton type=\"primary\">保存客户信息</SubmitButton>\n </Space>\n </Form>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_40\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_41\n}]\n},{\n title: `字段类型`,\n description: `展示FormInfo支持的各种字段类型,包括输入类、选择类、以及其他特殊字段类型`,\n code: `const { default: FormInfo, Form, SubmitButton, fields } = _FormInfo;\nconst { useModal } = _Modal;\nconst { Space, Divider } = antd;\n\nconst {\n Input,\n TextArea,\n InputNumber,\n DatePicker,\n DateRangePicker,\n Select,\n Switch,\n Rate,\n Slider,\n MoneyInput,\n ColorPicker,\n} = fields;\n\nconst BaseExample = () => {\n const modal = useModal();\n return (\n <Form\n onSubmit={(data) => {\n modal({\n title: \"供应商信息提交成功\",\n children: <pre>{JSON.stringify(data, null, 2)}</pre>,\n });\n }}\n >\n <Space direction=\"vertical\" size={24}>\n <FormInfo\n title=\"基本资料\"\n list={[\n <Input name=\"companyName\" label=\"供应商名称\" rule=\"REQ LEN-3-50\" />,\n <TextArea name=\"description\" label=\"公司简介\" maxLength={500} />,\n <InputNumber name=\"creditScore\" label=\"信用评分\" min={0} max={100} />,\n <MoneyInput name=\"annualRevenue\" label=\"年营业额\" />,\n ]}\n />\n\n <Divider />\n\n <FormInfo\n title=\"合作信息\"\n list={[\n <DatePicker name=\"cooperateDate\" label=\"合作起始日期\" />,\n <DateRangePicker name=\"contractPeriod\" label=\"合同有效期\" />,\n <Select\n name=\"cooperateType\"\n label=\"合作类型\"\n rule=\"REQ\"\n options={[\n { label: \"独家代理\", value: \"exclusive\" },\n { label: \"一般代理\", value: \"normal\" },\n { label: \"战略合作伙伴\", value: \"strategic\" },\n ]}\n />,\n <Select\n name=\"productCategory\"\n label=\"供应产品类别\"\n mode=\"multiple\"\n options={[\n { label: \"电子元器件\", value: \"electronics\" },\n { label: \"机械配件\", value: \"machinery\" },\n { label: \"原材料\", value: \"materials\" },\n { label: \"包装材料\", value: \"packaging\" },\n ]}\n />,\n ]}\n />\n\n <Divider />\n\n <FormInfo\n title=\"其他配置\"\n list={[\n <Switch name=\"isPreferred\" label=\"是否优先供应商\" />,\n <Rate name=\"qualityRating\" label=\"质量评级\" />,\n <Slider name=\"deliveryScore\" label=\"交付及时性评分\" />,\n <ColorPicker name=\"brandColor\" label=\"品牌标识色\" />,\n ]}\n />\n\n <SubmitButton type=\"primary\">提交供应商信息</SubmitButton>\n </Space>\n </Form>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_40\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_41\n}]\n},{\n title: `表单校验`,\n description: `展示表单的校验规则使用,包括内置规则和自定义规则,以及异步校验和错误提示`,\n code: `const { default: FormInfo, Form, SubmitButton, ErrorTip, fields } = _FormInfo;\nconst { useModal } = _Modal;\nconst { Space, Alert } = antd;\n\nconst { Input, Password } = fields;\n\nconst BaseExample = () => {\n const modal = useModal();\n return (\n <Form\n rules={{\n USERNAME: (value) => {\n // 自定义规则:用户名必须是字母开头,4-16位\n const pattern = /^[a-zA-Z][a-zA-Z0-9]{3,15}\\$/;\n return {\n result: pattern.test(value),\n errMsg: \"用户名必须以字母开头,4-16位字母或数字\",\n };\n },\n PASSWORD_STRENGTH: (value) => {\n // 自定义规则:密码强度校验\n const hasLetter = /[a-zA-Z]/.test(value);\n const hasNumber = /[0-9]/.test(value);\n const hasSpecial = /[!@#\\$%^&*]/.test(value);\n if (!hasLetter || !hasNumber || !hasSpecial) {\n return {\n result: false,\n errMsg: \"密码必须包含字母、数字和特殊字符\",\n };\n }\n return { result: true, errMsg: \"\" };\n },\n USERNAME_EXISTS: (value) => {\n // 异步校验:检查用户名是否已存在\n return new Promise((resolve) => {\n setTimeout(() => {\n const exists = [\"admin\", \"wangming\", \"zhangwei\"].includes(value);\n resolve({\n result: !exists,\n errMsg: exists ? \"该用户名已被占用\" : \"\",\n });\n }, 500);\n });\n },\n }}\n onSubmit={(data) => {\n modal({\n title: \"管理员账号创建成功\",\n children: <pre>{JSON.stringify(data, null, 2)}</pre>,\n });\n }}\n >\n <Space direction=\"vertical\" size={16}>\n <Alert\n message=\"账号注册规范\"\n description=\"REQ-必填 | LEN-最小-最大 | EMAIL-邮箱 | PHONE-手机号 | URL-网址 | USERNAME-自定义规则\"\n type=\"info\"\n />\n\n <FormInfo\n title=\"管理员账号信息\"\n list={[\n <ErrorTip name=\"username\">\n <Input\n name=\"username\"\n label=\"用户名\"\n rule=\"REQ LEN-4-16 USERNAME USERNAME_EXISTS\"\n tips=\"4-16位字母或数字,以字母开头(admin、wangming、zhangwei已被占用)\"\n />\n </ErrorTip>,\n <Password\n name=\"password\"\n label=\"登录密码\"\n rule=\"REQ LEN-8-20 PASSWORD_STRENGTH\"\n tips=\"至少8位,包含字母、数字和特殊字符\"\n />,\n <Password\n name=\"confirmPassword\"\n label=\"确认密码\"\n rule=\"REQ\"\n tips=\"请再次输入密码\"\n />,\n <Input name=\"email\" label=\"工作邮箱\" rule=\"REQ EMAIL\" />,\n <Input name=\"phone\" label=\"联系电话\" rule=\"REQ PHONE\" />,\n ]}\n />\n <SubmitButton type=\"primary\">创建管理员账号</SubmitButton>\n </Space>\n </Form>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_40\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_41\n}]\n},{\n title: `多行字段`,\n description: `展示MultiField的使用,可以将多个字段在一行中横向排列`,\n code: `const { default: FormInfo, Form, MultiField, SubmitButton, fields } = _FormInfo;\nconst { useModal } = _Modal;\n\nconst { Input, TextArea, DatePicker } = fields;\n\nconst BaseExample = () => {\n const modal = useModal();\n return (\n <Form\n onSubmit={(data) => {\n modal({\n title: \"采购订单信息提交成功\",\n children: <pre>{JSON.stringify(data, null, 2)}</pre>,\n });\n }}\n >\n <FormInfo\n list={[\n <MultiField\n name=\"purchaseOrderNo\"\n label=\"采购单号\"\n rule=\"REQ\"\n field={Input}\n maxLength={20}\n />,\n <MultiField name=\"productName\" label=\"采购产品\" field={Input} />,\n <MultiField name=\"quantity\" label=\"采购数量\" field={Input} type=\"number\" />,\n <MultiField name=\"unitPrice\" label=\"单价\" field={Input} type=\"number\" />,\n <MultiField name=\"deliveryDate\" label=\"交付日期\" field={DatePicker} />,\n <MultiField name=\"note\" label=\"备注说明\" field={TextArea} />,\n ]}\n />\n <SubmitButton type=\"primary\">提交采购订单</SubmitButton>\n </Form>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_40\n}]\n},{\n title: `业务字段`,\n description: `展示FormInfo提供的业务字段组件,如手机号、职能选择、行业选择、地址选择等`,\n code: `const { default: FormInfo, Form, SubmitButton, fields } = _FormInfo;\nconst { useModal } = _Modal;\nconst { PureGlobal } = global;\nconst { Space } = antd;\n\nconst {\n PhoneNumber,\n FunctionSelect,\n IndustrySelect,\n AddressSelect,\n SuperSelectUser,\n Avatar,\n Upload,\n SalaryInput,\n Input,\n} = fields;\n\nconst BaseExample = () => {\n const modal = useModal();\n return (\n <Form\n onSubmit={(data) => {\n modal({\n title: \"候选人信息提交成功\",\n children: <pre>{JSON.stringify(data, null, 2)}</pre>,\n });\n }}\n >\n <Space direction=\"vertical\" size={16}>\n <FormInfo\n title=\"候选人基本信息\"\n list={[\n <Avatar name=\"avatar\" label=\"头像照片\" />,\n <SuperSelectUser name=\"userId\" label=\"内部推荐人\" rule=\"REQ\" />,\n <PhoneNumber name=\"phone\" label=\"联系电话\" rule=\"REQ\" />,\n <Input name=\"email\" label=\"电子邮箱\" rule=\"EMAIL\" />,\n ]}\n />\n\n <FormInfo\n title=\"职业发展信息\"\n list={[\n <FunctionSelect name=\"function\" label=\"职能领域\" rule=\"REQ\" />,\n <IndustrySelect name=\"industry\" label=\"所属行业\" rule=\"REQ\" />,\n <SalaryInput\n name=\"salaryRange\"\n label=\"期望薪资范围\"\n rule=\"REQ\"\n showMonth\n remindUnit\n />,\n ]}\n />\n\n <FormInfo\n title=\"其他补充信息\"\n list={[\n <AddressSelect name=\"address\" label=\"工作地址\" level={3} />,\n <Upload name=\"resume\" label=\"简历附件\" block />,\n ]}\n />\n\n <SubmitButton type=\"primary\">提交候选人信息</SubmitButton>\n </Space>\n </Form>\n );\n};\n\nrender(\n <PureGlobal>\n <BaseExample />\n </PureGlobal>\n);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_40\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_42\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_41\n}]\n},{\n title: `高级选择组件`,\n description: `展示AdvancedSelect高级选择组件的使用,支持从API加载数据、自定义列配置、多选等功能`,\n code: `const { default: FormInfo, Form, SubmitButton, AdvancedSelect, fields } = _FormInfo;\nconst { useModal } = _Modal;\nconst { Space } = antd;\n\nconst { Input, TextArea } = fields;\n\nconst BaseExample = () => {\n const modal = useModal();\n return (\n <Form\n onSubmit={(data) => {\n modal({\n title: \"培训计划配置成功\",\n children: <pre>{JSON.stringify(data, null, 2)}</pre>,\n });\n }}\n >\n <Space direction=\"vertical\" size={16}>\n <FormInfo\n title=\"课程选择\"\n list={[\n <AdvancedSelect\n name=\"trainingCourses\"\n label=\"选择培训课程\"\n rule=\"REQ\"\n mode=\"multiple\"\n api={{\n loader: () => {\n return {\n pageData: [\n {\n id: 1,\n name: \"前端架构设计最佳实践\",\n category: \"前端技术\",\n duration: 12,\n description: \"深入学习企业级前端架构设计方法\",\n },\n {\n id: 2,\n name: \"微服务架构设计与实现\",\n category: \"后端技术\",\n duration: 16,\n description: \"掌握微服务架构的核心设计模式\",\n },\n {\n id: 3,\n name: \"云原生应用开发\",\n category: \"云原生\",\n duration: 20,\n description: \"基于Kubernetes的云原生应用开发\",\n },\n {\n id: 4,\n name: \"大数据处理与分析\",\n category: \"数据技术\",\n duration: 18,\n description: \"Hadoop/Spark大数据处理技术\",\n },\n {\n id: 5,\n name: \"AI与机器学习实战\",\n category: \"人工智能\",\n duration: 24,\n description: \"深度学习模型训练与部署\",\n },\n ],\n };\n },\n }}\n columns={[\n { title: \"课程名称\", key: \"name\" },\n { title: \"技术方向\", key: \"category\" },\n { title: \"课时\", key: \"duration\" },\n ]}\n nameKey=\"id\"\n labelKey=\"name\"\n />,\n ]}\n />\n\n <FormInfo\n title=\"培训计划详情\"\n list={[\n <Input name=\"trainingObjective\" label=\"培训目标\" />,\n <TextArea name=\"trainingRequirements\" label=\"培训要求与说明\" block />,\n ]}\n />\n\n <SubmitButton type=\"primary\">提交培训计划</SubmitButton>\n </Space>\n </Form>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_40\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_41\n}]\n},{\n title: `列表字段`,\n description: `展示List和TableList多段式列表字段的使用,支持动态添加、删除、最大长度限制等功能`,\n code: `const { default: FormInfo, Form, List, TableList, SubmitButton, fields } = _FormInfo;\nconst { useModal } = _Modal;\nconst { Space } = antd;\n\nconst { Input, DatePicker, TextArea } = fields;\n\nconst BaseExample = () => {\n const modal = useModal();\n return (\n <Form\n onSubmit={(data) => {\n modal({\n title: \"企业信息提交成功\",\n children: <pre>{JSON.stringify(data, null, 2)}</pre>,\n });\n }}\n >\n <Space direction=\"vertical\" size={16}>\n <FormInfo\n title=\"企业基本信息\"\n list={[\n <Input name=\"companyName\" label=\"企业名称\" rule=\"REQ\" />,\n <TextArea name=\"companyDescription\" label=\"企业简介\" block />,\n ]}\n />\n\n <List\n name=\"productLines\"\n title=\"产品线列表\"\n itemTitle={({ index }) => \\`产品线 \\${index + 1}\\`}\n maxLength={10}\n list={[\n <Input name=\"lineName\" label=\"产品线名称\" rule=\"REQ\" />,\n <Input name=\"annualSales\" label=\"年销售额(万元)\" rule=\"REQ\" />,\n <TextArea name=\"lineFeatures\" label=\"产品线特点\" block />,\n ]}\n />\n\n <TableList\n name=\"partnerContacts\"\n title=\"合作伙伴联系人\"\n maxLength={5}\n list={[\n <Input name=\"contactName\" label=\"联系人姓名\" rule=\"REQ\" />,\n <DatePicker name=\"cooperateDate\" label=\"合作起始日期\" />,\n <Input name=\"contactPhone\" label=\"联系电话\" rule=\"REQ\" />,\n ]}\n />\n\n <SubmitButton type=\"primary\">提交企业信息</SubmitButton>\n </Space>\n </Form>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_40\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_41\n}]\n},{\n title: `嵌套列表`,\n description: `展示在List中嵌套TableList的使用场景,实现更复杂的多层级数据结构`,\n code: `const { default: FormInfo, Form, List, TableList, SubmitButton, fields } = _FormInfo;\nconst { useModal } = _Modal;\nconst { Space } = antd;\n\nconst { Input, DatePicker, TextArea, Select } = fields;\n\nconst BaseExample = () => {\n const modal = useModal();\n return (\n <Form\n onSubmit={(data) => {\n modal({\n title: \"研发项目信息提交成功\",\n children: <pre>{JSON.stringify(data, null, 2)}</pre>,\n });\n }}\n >\n <Space direction=\"vertical\" size={16}>\n <FormInfo\n title=\"项目基本信息\"\n list={[\n <Input name=\"projectName\" label=\"项目名称\" rule=\"REQ\" />,\n <TextArea name=\"projectDescription\" label=\"项目描述\" block />,\n ]}\n />\n\n <List\n name=\"releaseMilestones\"\n title=\"发布里程碑\"\n itemTitle={({ index }) => \\`里程碑 \\${index + 1}\\`}\n maxLength={5}\n important\n list={[\n <Input name=\"milestoneName\" label=\"里程碑名称\" rule=\"REQ\" />,\n <DatePicker name=\"releaseDate\" label=\"发布日期\" rule=\"REQ\" />,\n <TableList\n name=\"deliverables\"\n title=\"交付物清单\"\n maxLength={10}\n block\n list={[\n <Input name=\"deliverableName\" label=\"交付物名称\" rule=\"REQ\" />,\n <Select\n name=\"deliverableType\"\n label=\"交付物类型\"\n rule=\"REQ\"\n options={[\n { label: \"源代码\", value: \"code\" },\n { label: \"文档\", value: \"doc\" },\n { label: \"测试用例\", value: \"test\" },\n ]}\n />,\n ]}\n />,\n ]}\n />\n\n <SubmitButton type=\"primary\">提交项目信息</SubmitButton>\n </Space>\n </Form>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_40\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_41\n}]\n},{\n title: `动态字段`,\n description: `展示根据选择值动态显示/隐藏字段的使用场景,实现字段联动效果`,\n code: `const { default: FormInfo, Form, SubmitButton, fields } = _FormInfo;\nconst { useModal } = _Modal;\nconst { Space, Alert } = antd;\nconst { useState } = React;\n\nconst { Input, Select, TextArea } = fields;\n\nconst BaseExample = () => {\n const modal = useModal();\n const [employmentType, setEmploymentType] = useState(\"fulltime\");\n\n return (\n <Form\n onSubmit={(data) => {\n modal({\n title: \"人才录用信息提交成功\",\n children: <pre>{JSON.stringify(data, null, 2)}</pre>,\n });\n }}\n >\n <Space direction=\"vertical\" size={16}>\n <Alert\n message=\"动态字段展示\"\n description=\"根据录用类型显示不同的字段信息,实现字段联动效果\"\n type=\"info\"\n />\n\n <FormInfo\n title=\"候选人基本信息\"\n list={[\n <Input name=\"candidateName\" label=\"候选人姓名\" rule=\"REQ\" />,\n <Select\n name=\"employmentType\"\n label=\"录用类型\"\n rule=\"REQ\"\n onChange={(value) => {\n setEmploymentType(value);\n }}\n options={[\n { label: \"全职员工\", value: \"fulltime\" },\n { label: \"兼职顾问\", value: \"parttime\" },\n { label: \"外包合同\", value: \"contract\" },\n ]}\n />,\n ]}\n />\n\n {employmentType === \"fulltime\" && (\n <FormInfo\n title=\"全职员工信息\"\n list={[\n <Input name=\"employeeId\" label=\"员工工号\" rule=\"REQ\" />,\n <Input name=\"monthlySalary\" label=\"月薪(元)\" rule=\"REQ\" />,\n <Input name=\"socialSecurityNo\" label=\"社保账号\" />,\n <Select\n name=\"benefitLevel\"\n label=\"福利等级\"\n options={[\n { label: \"基础福利\", value: \"basic\" },\n { label: \"标准福利\", value: \"standard\" },\n { label: \"优厚福利\", value: \"premium\" },\n ]}\n />,\n ]}\n />\n )}\n\n {employmentType === \"parttime\" && (\n <FormInfo\n title=\"兼职顾问信息\"\n list={[\n <Input name=\"hourlyRate\" label=\"时薪(元/小时)\" rule=\"REQ\" />,\n <Input name=\"maxMonthlyHours\" label=\"最大月工时\" rule=\"REQ\" />,\n <TextArea name=\"serviceScope\" label=\"服务范围\" block />,\n ]}\n />\n )}\n\n {employmentType === \"contract\" && (\n <FormInfo\n title=\"外包合同信息\"\n list={[\n <Input name=\"contractPeriod\" label=\"合同期限\" rule=\"REQ\" />,\n <Input name=\"projectFee\" label=\"项目费用(元)\" rule=\"REQ\" />,\n <Select\n name=\"paymentTerm\"\n label=\"付款方式\"\n options={[\n { label: \"一次性付款\", value: \"onetime\" },\n { label: \"分期付款\", value: \"installment\" },\n { label: \"按里程碑付款\", value: \"milestone\" },\n ]}\n />,\n ]}\n />\n )}\n\n <FormInfo\n title=\"其他备注\"\n list={[<TextArea name=\"remark\" label=\"录用备注说明\" block />]}\n />\n\n <SubmitButton type=\"primary\">提交录用信息</SubmitButton>\n </Space>\n </Form>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_40\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_41\n}]\n},{\n title: `表单弹窗`,\n description: `展示FormModal的使用,在弹窗中展示表单,适合数据录入、编辑等场景`,\n code: `const {default: FormInfo, useFormModal, fields} = _FormInfo;\nconst {PureGlobal} = global;\nconst {Button, Space} = antd;\nconst {useState} = React;\n\nconst {Input, DatePicker, Select} = fields;\n\nconst EmployeeModal = () => {\n const modal = useFormModal();\n\n const handleAddEmployee = () => {\n const modalApi = modal({\n title: \"新建员工档案\", formProps: {\n onSubmit: (data) => {\n console.log(\"提交数据:\", data);\n modalApi.close();\n },\n }, children: (<FormInfo\n list={[<Input name=\"name\" label=\"员工姓名\" rule=\"REQ\"/>,\n <Input name=\"phone\" label=\"联系电话\" rule=\"REQ PHONE\"/>,\n <DatePicker name=\"joinDate\" label=\"入职日期\" rule=\"REQ\"/>, <Select\n name=\"department\"\n label=\"所属部门\"\n rule=\"REQ\"\n options={[{label: \"技术研发中心\", value: \"tech\"}, {\n label: \"产品管理中心\",\n value: \"product\"\n }, {label: \"市场营销中心\", value: \"marketing\"},]}\n />, <Select\n name=\"position\"\n label=\"职位名称\"\n rule=\"REQ\"\n options={[{label: \"高级工程师\", value: \"senior\"}, {\n label: \"产品经理\",\n value: \"pm\"\n }, {label: \"UI设计师\", value: \"designer\"},]}\n />,]}\n />),\n });\n };\n\n return (<Space>\n <Button type=\"primary\" onClick={handleAddEmployee}>\n 新建员工档案\n </Button>\n <Button onClick={() => modalApi.close()}>关闭</Button>\n </Space>);\n};\n\nconst BaseExample = () => {\n return (<PureGlobal>\n <EmployeeModal/>\n </PureGlobal>);\n};\n\nrender(<BaseExample/>);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_42\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_41\n}]\n},{\n title: `表单抽屉`,\n description: `展示FormDrawer的使用,在抽屉中展示表单,适合展示更多表单内容的场景`,\n code: `const { default: FormInfo, useFormDrawer, fields } = _FormInfo;\nconst { PureGlobal } = global;\nconst { Button, Space } = antd;\n\nconst { Input, DatePicker, Select, TextArea } = fields;\n\nconst ProjectDrawer = () => {\n const drawer = useFormDrawer();\n\n const handleCreateProject = () => {\n const drawerApi = drawer({\n title: \"发起研发项目\",\n width: 600,\n formProps: {\n onSubmit: (data) => {\n console.log(\"提交数据:\", data);\n drawerApi.close();\n },\n },\n children: (\n <FormInfo\n list={[\n <Input name=\"name\" label=\"项目名称\" rule=\"REQ\" />,\n <TextArea name=\"description\" label=\"项目背景与目标\" block />,\n <DatePicker name=\"startDate\" label=\"计划启动日期\" rule=\"REQ\" />,\n <DatePicker name=\"endDate\" label=\"计划完成日期\" rule=\"REQ\" />,\n <Select\n name=\"projectManager\"\n label=\"项目负责人\"\n rule=\"REQ\"\n options={[\n { label: \"王建国\", value: 1 },\n { label: \"李晓华\", value: 2 },\n { label: \"张思远\", value: 3 },\n ]}\n />,\n <Select\n name=\"projectStatus\"\n label=\"项目阶段\"\n rule=\"REQ\"\n options={[\n { label: \"需求分析\", value: \"requirement\" },\n { label: \"开发实施\", value: \"development\" },\n { label: \"测试验收\", value: \"testing\" },\n { label: \"上线部署\", value: \"deployment\" },\n ]}\n />,\n ]}\n />\n ),\n });\n };\n\n return (\n <Space>\n <Button type=\"primary\" onClick={handleCreateProject}>\n 发起研发项目\n </Button>\n <Button onClick={() => drawerApi.close()}>关闭</Button>\n </Space>\n );\n};\n\nconst BaseExample = () => {\n return (\n <PureGlobal>\n <ProjectDrawer />\n </PureGlobal>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_42\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_41\n}]\n},{\n title: `分步表单弹窗`,\n description: `展示FormStepModal的使用,将表单分为多个步骤,逐步引导用户填写,适合复杂表单场景`,\n code: `const {default: FormInfo, useFormStepModal, fields} = _FormInfo;\nconst {PureGlobal} = global;\nconst {Button, Space, Card, Tag, Divider} = antd;\nconst {useModal} = _Modal;\n\nconst {Input, DatePicker, Select, TextArea, PhoneNumber} = fields;\n\nconst RecruitmentStepModal = () => {\n const modal = useFormStepModal();\n const handleOpenRecruitment = () => {\n const modalApi = modal({\n title: \"人才招聘流程\", items: [{\n title: \"基本信息\", formProps: {\n onSubmit: (data, {stepCacheRef, currentIndex}) => {\n console.log(\"基本信息提交:\", data);\n console.log(\"步骤缓存:\", stepCacheRef.current);\n }\n }, children: (<FormInfo\n list={[<Input name=\"candidateName\" label=\"候选人姓名\" rule=\"REQ\"/>,\n <PhoneNumber name=\"contactPhone\" label=\"联系电话\" rule=\"REQ\"/>,\n <Input name=\"email\" label=\"电子邮箱\" rule=\"REQ EMAIL\"/>,\n <DatePicker name=\"dateOfBirth\" label=\"出生日期\"/>,]}\n />),\n }, {\n title: \"教育经历\", formProps: {\n onSubmit: (data, {stepCacheRef, currentIndex}) => {\n console.log(\"教育经历提交:\", data);\n console.log(\"步骤缓存:\", stepCacheRef.current);\n }\n }, children: (<FormInfo\n list={[<Input name=\"university\" label=\"毕业院校\" rule=\"REQ\"/>, <Select\n name=\"educationDegree\"\n label=\"最高学历\"\n rule=\"REQ\"\n options={[{label: \"本科\", value: \"bachelor\"}, {\n label: \"硕士研究生\", value: \"master\"\n }, {label: \"博士研究生\", value: \"doctor\"},]}\n />, <Select\n name=\"major\"\n label=\"专业领域\"\n rule=\"REQ\"\n options={[{label: \"计算机科学与技术\", value: \"cs\"}, {\n label: \"软件工程\", value: \"se\"\n }, {label: \"信息管理与信息系统\", value: \"im\"},]}\n />,]}\n />),\n }, {\n title: \"工作经历\", formProps: {\n onSubmit: (data, {stepCacheRef, currentIndex, isLastStep}) => {\n console.log(\"工作经历提交:\", data);\n console.log(\"所有步骤缓存数据:\", stepCacheRef.current);\n // 在最后一步合并所有步骤的数据\n const allData = {};\n Object.keys(stepCacheRef.current).forEach(key => {\n Object.assign(allData, stepCacheRef.current[key].data);\n });\n console.log(\"合并后的完整数据:\", allData);\n alert(\"人才信息提交成功!\" + JSON.stringify(allData, null, 2));\n }\n }, children: (<FormInfo\n list={[<Input name=\"lastCompany\" label=\"上家公司名称\"/>, <Select\n name=\"position\"\n label=\"职位级别\"\n options={[{label: \"初级工程师\", value: \"junior\"}, {\n label: \"中级工程师\", value: \"mid\"\n }, {label: \"高级工程师\", value: \"senior\"},]}\n />, <TextArea name=\"workExperience\" label=\"工作经历描述\" block/>,]}\n />),\n },],\n });\n };\n\n return (<Space>\n <Button type=\"primary\" onClick={handleOpenRecruitment}>\n 发起人才招聘\n </Button>\n <Button onClick={() => modalApi.close()}>关闭</Button>\n </Space>);\n};\n\n// 演示 stepCacheRef 的使用\nconst StepCacheExample = () => {\n const modal = useFormStepModal();\n const normalModal = useModal();\n const handleOpen = () => {\n const modalApi = modal({\n title: \"stepCacheRef 演示\", items: [{\n title: \"第一步\", formProps: {\n onSubmit: (data, {stepCacheRef, currentIndex}) => {\n console.log(\"第一步数据:\", data);\n console.log(\"当前缓存:\", stepCacheRef.current);\n }\n }, children: (<FormInfo\n list={[<Input name=\"field1\" label=\"字段1\" rule=\"REQ\"/>, <Input name=\"field2\" label=\"字段2\"/>,]}\n />),\n }, {\n title: \"第二步\", formProps: {\n onSubmit: (data, {stepCacheRef, currentIndex}) => {\n console.log(\"第二步数据:\", data);\n console.log(\"当前缓存:\", stepCacheRef.current);\n console.log(\"第一步缓存数据:\", stepCacheRef.current[0]);\n }\n }, children: (<FormInfo\n list={[<Input name=\"field3\" label=\"字段3\" rule=\"REQ\"/>, <Input name=\"field4\" label=\"字段4\"/>,]}\n />),\n }, {\n title: \"第三步\", formProps: {\n onSubmit: (data, {stepCacheRef, currentIndex, isLastStep}) => {\n console.log(\"第三步数据:\", data);\n console.log(\"所有缓存数据:\", stepCacheRef.current);\n\n // 合并所有步骤的数据\n const allData = {};\n Object.keys(stepCacheRef.current).forEach(key => {\n Object.assign(allData, stepCacheRef.current[key].data);\n });\n console.log(\"完整数据:\", allData);\n\n // 显示缓存内容\n const cacheContent = Object.entries(stepCacheRef.current).map(([index, cache]) => ({\n step: index, data: cache.data, output: cache.output\n }));\n\n normalModal({\n children: (<Space direction=\"vertical\" size={16} style={{padding: 24}}>\n <Card title=\"提交成功\" size=\"small\">\n <Space direction=\"vertical\" size={8}>\n {cacheContent.map((item, idx) => (<Card key={idx} size=\"small\" type=\"inner\"\n title={\\`步骤 \\${parseInt(item.step) + 1}\\`}>\n <Space direction=\"vertical\" size={4}>\n {Object.entries(item.data).map(([key, value]) => (\n <Tag key={key}>{key}: {String(value)}</Tag>))}\n </Space>\n </Card>))}\n </Space>\n </Card>\n <Button onClick={() => modalApi.close()}>关闭</Button>\n </Space>), footerButtons: []\n });\n }\n }, children: (<FormInfo\n list={[<Input name=\"field5\" label=\"字段5\" rule=\"REQ\"/>, <Input name=\"field6\" label=\"字段6\"/>,]}\n />),\n },],\n });\n };\n\n return (<Button onClick={handleOpen}>stepCacheRef 演示</Button>);\n};\n\nconst BaseExample = () => {\n return (<PureGlobal>\n <Space direction=\"vertical\">\n <RecruitmentStepModal/>\n <Divider/>\n <Space>\n <StepCacheExample/>\n </Space>\n </Space>\n </PureGlobal>);\n};\n\nrender(<BaseExample/>);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_42\n},{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_40\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_41\n}]\n},{\n title: `useFormContext`,\n description: `展示如何使用useFormContext Hook访问表单API,实现查看值、设置值、校验、重置等操作`,\n code: `const { default: FormInfo, Form, useFormContext, fields } = _FormInfo;\nconst { Space, Card, Button, Tag, Divider } = antd;\nconst { useState } = React;\n\nconst { Input, DatePicker, Select } = fields;\n\nconst FormActions = () => {\n const { openApi, formData } = useFormContext();\n const [showData, setShowData] = useState(false);\n\n return (\n <Space direction=\"vertical\" size={16} style={{ width: \"100%\" }}>\n <Space wrap>\n <Button\n type=\"primary\"\n onClick={() => {\n openApi.setFields(\n [\n { name: \"employeeName\", value: \"王建国\" },\n { name: \"workEmail\", value: \"wangjianguo@company.com\" },\n { name: \"department\", value: \"tech\" },\n ],\n { runValidate: false }\n );\n }}\n >\n 填充员工信息\n </Button>\n <Button\n onClick={() => {\n setShowData(!showData);\n }}\n >\n {showData ? \"隐藏数据\" : \"查看数据\"}\n </Button>\n <Button\n onClick={() => {\n openApi.validateAll();\n }}\n >\n 校验表单\n </Button>\n <Button onClick={openApi.reset}>重置表单</Button>\n </Space>\n\n {showData && (\n <Card title=\"当前表单数据\" size=\"small\">\n <Space direction=\"vertical\" size={8}>\n {Object.entries(formData).map(([key, value]) => (\n <Tag key={key} color=\"blue\">\n <strong>{key}</strong>:{\" \"}\n {typeof value === \"object\" && value !== null\n ? JSON.stringify(value)\n : String(value)}\n </Tag>\n ))}\n </Space>\n </Card>\n )}\n <Divider />\n </Space>\n );\n};\n\nconst BaseExample = () => {\n return (\n <Form\n onSubmit={(data) => {\n console.log(\"提交数据:\", data);\n alert(\"员工信息保存成功!\");\n }}\n >\n <Space direction=\"vertical\" size={16}>\n <FormInfo\n title=\"员工基本信息\"\n list={[\n <Input name=\"employeeName\" label=\"员工姓名\" rule=\"REQ\" />,\n <Input name=\"workEmail\" label=\"工作邮箱\" rule=\"REQ EMAIL\" />,\n <DatePicker name=\"onboardingDate\" label=\"入职日期\" />,\n <Select\n name=\"department\"\n label=\"所属部门\"\n options={[\n { label: \"技术研发中心\", value: \"tech\" },\n { label: \"产品管理中心\", value: \"product\" },\n { label: \"市场营销中心\", value: \"marketing\" },\n ]}\n />,\n ]}\n />\n\n <FormActions />\n </Space>\n </Form>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_41\n}]\n},{\n title: `FormApiButton`,\n description: `展示FormApiButton的使用,通过按钮访问表单API,实现各种表单操作`,\n code: `const { default: FormInfo, Form, FormApiButton, fields } = _FormInfo;\nconst { Space, Flex } = antd;\n\nconst { Input, DatePicker, Select } = fields;\n\nconst BaseExample = () => {\n return (\n <Form\n onSubmit={(data) => {\n console.log(\"提交数据:\", data);\n alert(\"员工信息保存成功!\");\n }}\n >\n <Space direction=\"vertical\" size={16} style={{ width: \"100%\" }}>\n <FormInfo\n title=\"员工基本信息\"\n list={[\n <Input name=\"employeeName\" label=\"员工姓名\" rule=\"REQ\" />,\n <Input name=\"workEmail\" label=\"工作邮箱\" rule=\"REQ EMAIL\" />,\n <DatePicker name=\"onboardingDate\" label=\"入职日期\" />,\n <Select\n name=\"department\"\n label=\"所属部门\"\n options={[\n { label: \"技术研发中心\", value: \"tech\" },\n { label: \"产品管理中心\", value: \"product\" },\n { label: \"市场营销中心\", value: \"marketing\" },\n ]}\n />,\n ]}\n />\n\n <FormInfo\n list={[\n <Flex gap={8} wrap>\n <FormApiButton\n type=\"default\"\n onClick={({ openApi, formData }) => {\n alert(\"当前表单数据:\" + JSON.stringify(formData, null, 2));\n }}\n >\n 查看表单数据\n </FormApiButton>\n <FormApiButton\n type=\"default\"\n onClick={({ openApi }) => {\n openApi.setFields(\n [\n { name: \"employeeName\", value: \"王建国\" },\n { name: \"workEmail\", value: \"wangjianguo@company.com\" },\n { name: \"department\", value: \"tech\" },\n ],\n { runValidate: false }\n );\n }}\n >\n 填充员工信息\n </FormApiButton>\n <FormApiButton\n type=\"default\"\n onClick={({ openApi }) => {\n openApi.validateAll();\n }}\n >\n 校验表单\n </FormApiButton>\n <FormApiButton\n type=\"default\"\n danger\n onClick={({ openApi }) => {\n openApi.reset();\n }}\n >\n 重置表单\n </FormApiButton>\n <FormApiButton\n type=\"primary\"\n htmlType=\"submit\"\n onClick={({ openApi }) => {\n openApi.submit();\n }}\n >\n 保存员工信息\n </FormApiButton>\n </Flex>,\n ]}\n />\n </Space>\n </Form>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_41\n}]\n},{\n title: `自定义校验规则`,\n description: `展示如何定义自定义校验规则,包括同步校验、异步校验和字段间联动校验`,\n code: `const { default: FormInfo, Form, SubmitButton, ErrorTip, fields } = _FormInfo;\nconst { useModal } = _Modal;\nconst { Space, Alert } = antd;\n\nconst { Input, Password, Select } = fields;\n\nconst BaseExample = () => {\n const modal = useModal();\n return (\n <Form\n rules={{\n // 自定义规则:密码强度校验\n PASSWORD_STRENGTH: (value) => {\n const hasLetter = /[a-zA-Z]/.test(value);\n const hasNumber = /[0-9]/.test(value);\n const hasSpecial = /[!@#\\$%^&*]/.test(value);\n if (!hasLetter || !hasNumber || !hasSpecial) {\n return {\n result: false,\n errMsg: \"密码必须包含字母、数字和特殊字符\",\n };\n }\n return { result: true, errMsg: \"\" };\n },\n // 自定义规则:异步校验用户名\n USERNAME_EXISTS: (value) => {\n return new Promise((resolve) => {\n setTimeout(() => {\n const exists = [\"wangming\", \"lihua\", \"zhangwei\"].includes(value);\n resolve({\n result: !exists,\n errMsg: exists ? \"该用户名已被占用\" : \"\",\n });\n }, 800);\n });\n },\n }}\n onSubmit={(data) => {\n modal({\n title: \"管理员账号创建成功\",\n children: <pre>{JSON.stringify(data, null, 2)}</pre>,\n });\n }}\n >\n <Space direction=\"vertical\" size={16}>\n <Alert\n message=\"自定义校验规则说明\"\n description=\"PASSWORD_STRENGTH-密码强度校验(必须包含字母、数字和特殊字符)| USERNAME_EXISTS-异步校验用户名是否已存在\"\n type=\"info\"\n />\n\n <FormInfo\n title=\"管理员账号配置\"\n list={[\n <ErrorTip name=\"username\">\n <Input\n name=\"username\"\n label=\"管理员用户名\"\n rule=\"REQ LEN-4-16 USERNAME_EXISTS\"\n tips=\"4-16位,wangming、lihua、zhangwei已被占用\"\n />\n </ErrorTip>,\n <Password\n name=\"password\"\n label=\"设置密码\"\n rule=\"REQ LEN-8-20 PASSWORD_STRENGTH\"\n tips=\"至少8位,包含字母、数字和特殊字符\"\n />,\n <Password\n name=\"confirmPassword\"\n label=\"确认密码\"\n rule=\"REQ\"\n tips=\"请再次输入密码\"\n />,\n <Select\n name=\"adminRole\"\n label=\"管理权限级别\"\n rule=\"REQ\"\n options={[\n { label: \"系统管理员\", value: \"superadmin\" },\n { label: \"部门管理员\", value: \"department\" },\n { label: \"内容管理员\", value: \"content\" },\n ]}\n />,\n ]}\n />\n\n <SubmitButton type=\"primary\">创建管理员账号</SubmitButton>\n </Space>\n </Form>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_40\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_41\n}]\n},{\n title: `地址选择`,\n description: `展示AddressSelect地址选择组件,支持省市区三级联动选择`,\n code: `const { AddressSelect: _AddressSelect, AddressInput: _AddressInput } =\n _FormInfo;\nconst { PureGlobal } = global;\nconst { Space, Button } = antd;\nconst { default: Content } = _Content;\nconst { range, uniqueId } = lodash;\n\nconst AddressSelect = _AddressSelect.Field;\nconst AddressEnum = _AddressSelect.AddressEnum;\nconst AddressInput = _AddressInput.Field;\n\nconst BaseExample = () => {\n return (\n <Content\n col={2}\n list={[\n {\n label: \"业务区域多选\",\n content: (\n <AddressSelect\n maxLength={3}\n defaultValue={[\"110\"]}\n onChange={(value) => {\n console.log(value);\n }}\n />\n ),\n },\n {\n label: \"业务区域单选\",\n content: (\n <AddressSelect\n single\n defaultValue={\"110\"}\n onChange={(value) => {\n console.log(value);\n }}\n />\n ),\n },\n {\n label: \"modal业务区域多选\",\n content: (\n <AddressSelect\n maxLength={3}\n isPopup={false}\n defaultValue={[\"110\"]}\n onChange={(value) => {\n console.log(value);\n }}\n />\n ),\n },\n {\n label: \"modal业务区域单选\",\n content: (\n <AddressSelect\n isPopup={false}\n single\n defaultValue={\"110\"}\n onChange={(value) => {\n console.log(value);\n }}\n />\n ),\n },\n {\n label: \"valueType为all\",\n content: (\n <AddressSelect\n valueType=\"all\"\n onChange={(value) => {\n console.log(value);\n }}\n />\n ),\n },\n {\n label: \"地址显示\",\n content: <AddressEnum name=\"270070\" />,\n },\n {\n label: \"显示父级\",\n content: <AddressEnum name=\"270070\" displayParent />,\n },\n {\n label: \"详细地址输入\",\n content: (\n <AddressInput\n onChange={(value) => {\n console.log(value);\n }}\n />\n ),\n },\n ]}\n />\n );\n};\n\nrender(\n <div className=\"input\">\n <BaseExample />\n </div>\n);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_42\n},{\n name: \"_Content\",\n packageName: \"@components/Content\",\n component: component_43\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_41\n},{\n name: \"lodash\",\n packageName: \"lodash\",\n component: component_44\n}]\n},{\n title: `级联选择`,\n description: `展示级联选择组件,支持多级联动选择`,\n code: `const { Cascader: _Cascader } = _FormInfo;\nconst { PureGlobal } = global;\nconst { default: Content } = _Content;\n\nconst { range, get } = lodash;\n\nconst Cascader = _Cascader.Field;\n\nconst BaseExample = () => {\n return (\n <Content\n col={2}\n list={[\n {\n label: \"一次性获取数据\",\n content: (\n <Cascader\n onlyAllowLastLevel\n single\n api={{\n loader: async () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve([\n {\n id: \"client\",\n value: \"client\",\n type: \"module\",\n name: \"客户管理\",\n label: \"客户管理\",\n children: [\n {\n id: \"client-list\",\n value: \"client-list\",\n type: \"feature\",\n name: \"客户列表\",\n label: \"客户列表\",\n },\n {\n id: \"client-detail\",\n value: \"client-detail\",\n type: \"module\",\n name: \"客户详情\",\n label: \"客户详情\",\n children: [\n {\n id: \"contract\",\n value: \"contract\",\n type: \"module\",\n name: \"合同管理\",\n label: \"合同管理\",\n },\n ],\n },\n {\n id: \"client-form\",\n value: \"client-form\",\n type: \"feature\",\n name: \"客户表单\",\n label: \"客户表单\",\n children: [\n {\n id: \"taxpayerIdNumber\",\n value: \"taxpayerIdNumber\",\n type: \"feature\",\n name: \"税号\",\n label: \"税号\",\n },\n ],\n },\n ],\n },\n {\n id: \"position\",\n value: \"position\",\n type: \"module\",\n name: \"招聘管理\",\n label: \"招聘管理\",\n children: [\n {\n id: \"position-list\",\n value: \"position-list\",\n type: \"feature\",\n name: \"职位列表\",\n label: \"职位列表\",\n },\n {\n id: \"position-detail\",\n value: \"position-detail\",\n type: \"module\",\n name: \"职位详情\",\n label: \"职位详情\",\n },\n {\n id: \"position-form\",\n value: \"position-form\",\n type: \"feature\",\n name: \"职位表单\",\n label: \"职位表单\",\n children: [\n {\n id: \"industry\",\n value: \"industry\",\n type: \"feature\",\n name: \"行业选择\",\n label: \"行业选择\",\n },\n ],\n },\n ],\n },\n ]);\n }, 1000);\n });\n },\n }}\n onChange={(value) => {\n console.log(value);\n }}\n />\n ),\n },\n {\n label: \"分层加载数据\",\n content: (\n <Cascader\n openLoadData\n onSearch={async (searchText) => {\n return range(0, 20).map((key) => {\n const parentId = \"2\";\n return {\n id: \\`\\${parentId ? \\`\\${parentId}-\\` : \"\"}\\${key + 1}\\`,\n label: \\`部门-\\${searchText}-\\${\n parentId ? \\`\\${parentId}-\\` : \"\"\n }\\${key + 1}\\`,\n parentId,\n };\n });\n }}\n api={{\n loader: async ({ data }) => {\n const parentId = get(data, \"id\", \"\");\n const level = parentId.split(\"-\").length;\n console.log(\"loadData\", parentId, level);\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve(\n range(0, 20).map((key) => {\n return Object.assign(\n {\n id: \\`\\${parentId ? \\`\\${parentId}-\\` : \"\"}\\${key + 1}\\`,\n label: \\`部门-\\${parentId ? \\`\\${parentId}-\\` : \"\"}\\${\n key + 1\n }\\`,\n parentId,\n },\n level >= 3 ? { children: null } : {}\n );\n })\n );\n }, 1000);\n });\n },\n }}\n />\n ),\n },\n {\n label: \"modal分层加载数据\",\n content: (\n <Cascader\n openLoadData\n isPopup={false}\n api={{\n loader: async ({ data }) => {\n const parentId = get(data, \"id\", \"\");\n const level = parentId.split(\"-\").length;\n console.log(\"loadData\", parentId, level);\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve(\n range(0, 20).map((key) => {\n return Object.assign(\n {\n id: \\`\\${parentId ? \\`\\${parentId}-\\` : \"\"}\\${key + 1}\\`,\n label: \\`部门-\\${parentId ? \\`\\${parentId}-\\` : \"\"}\\${\n key + 1\n }\\`,\n parentId,\n },\n level >= 3 ? { children: null } : {}\n );\n })\n );\n }, 1000);\n });\n },\n }}\n />\n ),\n },\n ]}\n />\n );\n};\n\nrender(\n <PureGlobal>\n <div className=\"input\">\n <BaseExample />\n </div>\n </PureGlobal>\n);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_42\n},{\n name: \"_Content\",\n packageName: \"@components/Content\",\n component: component_43\n},{\n name: \"lodash\",\n packageName: \"lodash\",\n component: component_44\n}]\n},{\n title: `职能选择`,\n description: `展示FunctionSelect职能选择组件,支持多级职能树选择`,\n code: `const { FunctionSelect: _FunctionSelect } = _FormInfo;\nconst { PureGlobal } = global;\nconst { default: Content } = _Content;\n\nconst { range, get } = lodash;\n\nconst FunctionSelect = _FunctionSelect.Field;\n\nconst BaseExample = () => {\n return (\n <Content\n col={2}\n list={[\n {\n label: \"职能选择\",\n content: (\n <FunctionSelect\n onChange={(value) => {\n console.log(value);\n }}\n />\n ),\n },\n {\n label: \"modal职能选择\",\n content: (\n <FunctionSelect\n isPopup={false}\n onChange={(value) => {\n console.log(value);\n }}\n />\n ),\n },\n {\n label: \"职能选择无搜索\",\n content: (\n <FunctionSelect\n search={null}\n onChange={(value) => {\n console.log(value);\n }}\n />\n ),\n },\n {\n label: \"职能枚举显示\",\n content: <FunctionSelect.Enum name=\"001\" />,\n },\n ]}\n />\n );\n};\n\nrender(\n <div className=\"input\">\n <BaseExample />\n </div>\n);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_42\n},{\n name: \"_Content\",\n packageName: \"@components/Content\",\n component: component_43\n},{\n name: \"lodash\",\n packageName: \"lodash\",\n component: component_44\n}]\n},{\n title: `行业选择`,\n description: `展示IndustrySelect行业选择组件,支持多级行业树选择`,\n code: `const { IndustrySelect: _IndustrySelect } = _FormInfo;\nconst { PureGlobal } = global;\nconst { default: Content } = _Content;\n\nconst { range, get } = lodash;\n\nconst IndustrySelect = _IndustrySelect.Field;\n\nconst BaseExample = () => {\n return (\n <Content\n col={2}\n list={[\n {\n label: \"所属行业\",\n content: (\n <IndustrySelect\n defaultValue={[\"001\"]}\n onChange={(value) => {\n console.log(value);\n }}\n />\n ),\n },\n {\n label: \"modal所属行业\",\n content: (\n <IndustrySelect\n isPopup={false}\n onChange={(value) => {\n console.log(value);\n }}\n />\n ),\n },\n {\n label: \"行业枚举显示\",\n content: <IndustrySelect.Enum name=\"004\" />,\n },\n ]}\n />\n );\n};\n\nrender(\n <div className=\"input\">\n <BaseExample />\n </div>\n);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_42\n},{\n name: \"_Content\",\n packageName: \"@components/Content\",\n component: component_43\n},{\n name: \"lodash\",\n packageName: \"lodash\",\n component: component_44\n}]\n},{\n title: `金额输入`,\n description: `展示MoneyInput金额输入组件,支持金额格式化和单位选择`,\n code: `const { MoneyInput: _MoneyInput } = _FormInfo;\nconst { PureGlobal } = global;\nconst { default: Content } = _Content;\n\nconst MoneyInput = _MoneyInput.Field;\n\nconst BaseExample = () => {\n return (\n <Content\n col={2}\n list={[\n {\n label: \"合同金额输入\",\n content: <MoneyInput />,\n },\n ]}\n />\n );\n};\n\nrender(\n <PureGlobal>\n <div className=\"input\">\n <BaseExample />\n </div>\n </PureGlobal>\n);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_42\n},{\n name: \"_Content\",\n packageName: \"@components/Content\",\n component: component_43\n}]\n},{\n title: `电话号码`,\n description: `展示PhoneNumber手机号输入组件,支持手机号格式化和校验`,\n code: `const { PhoneNumber: _PhoneNumber } = _FormInfo;\nconst { PureGlobal } = global;\nconst { default: Content } = _Content;\n\nconst PhoneNumber = _PhoneNumber.Field;\n\nconst BaseExample = () => {\n return (\n <Content\n col={2}\n list={[\n {\n label: \"联系电话\",\n content: (\n <PhoneNumber\n onChange={(value) => {\n console.log(value);\n }}\n />\n ),\n },\n ]}\n />\n );\n};\n\nrender(\n <PureGlobal>\n <div className=\"input\">\n <BaseExample />\n </div>\n </PureGlobal>\n);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_42\n},{\n name: \"_Content\",\n packageName: \"@components/Content\",\n component: component_43\n}]\n},{\n title: `薪资范围`,\n description: `展示SalaryInput薪资范围输入组件,支持薪资类型、月薪/年薪选择和范围校验`,\n code: `const { SalaryInput, Form } = _FormInfo;\nconst { PureGlobal } = global;\nconst { default: Content } = _Content;\n\nconst SalaryInputField = SalaryInput.Field;\n\nconst BaseExample = () => {\n return (\n <div>\n <Content\n col={1}\n list={[\n {\n label: \"薪资范围\",\n content: (\n <SalaryInputField\n onChange={(value) => {\n console.log(value);\n }}\n />\n ),\n },\n ]}\n />\n <Form\n rules={{\n SALARYRANGE: ({ min, max, type }) => {\n if (type !== 1) {\n if (!min || !max) {\n return {\n result: false,\n errMsg: \\`\\${!min ? \"最低薪资\" : \"最高薪资\"}不能为空\\`,\n };\n }\n if (min > max) {\n return {\n result: false,\n errMsg: \"最高薪资应大于最低薪资\",\n };\n }\n }\n return {\n result: true,\n errMsg: \"\",\n };\n },\n }}\n data={{ salaryRange: { type: 5, month: 12 } }}\n >\n <SalaryInput\n name=\"salaryRange\"\n label=\"薪资范围\"\n rule=\"REQ SALARYRANGE\"\n showMonth\n remindUnit\n />\n </Form>\n </div>\n );\n};\n\nrender(\n <PureGlobal>\n <div className=\"input\">\n <BaseExample />\n </div>\n </PureGlobal>\n);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_42\n},{\n name: \"_Content\",\n packageName: \"@components/Content\",\n component: component_43\n}]\n},{\n title: `helperGuideName 和 lang`,\n description: `展示 helperGuideName 为字段添加帮助指引功能,以及 lang 配置实现多语言支持`,\n code: `const {default: FormInfo, Form, SubmitButton, fields, List} = _FormInfo;\nconst {useModal} = _Modal;\nconst {PureGlobal} = global;\nconst {Space, Alert, Radio} = antd;\nconst {useState} = React;\n\nconst {Input, TextArea, Select} = fields;\n\nconst BaseExample = () => {\n const modal = useModal();\n const [helperGuideName, setHelperGuideName] = useState(\"employee-form\");\n const [langOpen, setLangOpen] = useState(true);\n\n return (<Space direction=\"vertical\" size={24} style={{width: \"100%\"}}>\n <Alert\n message=\"helperGuideName 和 lang 使用说明\"\n description=\"helperGuideName-为字段添加帮助指引功能 | lang-启用多语言支持,为每个字段生成多语言版本\"\n type=\"info\"\n />\n\n <Space direction=\"vertical\" size={16} style={{width: \"100%\"}}>\n <div>\n <span style={{marginRight: 12, fontWeight: 500}}>帮助指引名称:</span>\n <Radio.Group\n value={helperGuideName}\n onChange={(e) => setHelperGuideName(e.target.value)}\n >\n <Radio.Button value=\"employee-form\">启用 (employee-form)</Radio.Button>\n <Radio.Button value=\"\">禁用</Radio.Button>\n </Radio.Group>\n </div>\n\n <div>\n <span style={{marginRight: 12, fontWeight: 500}}>多语言配置:</span>\n <Radio.Group\n value={langOpen}\n onChange={(e) => setLangOpen(e.target.value)}\n >\n <Radio.Button value={true}>中文+英文</Radio.Button>\n <Radio.Button value={false}>仅中文</Radio.Button>\n </Radio.Group>\n </div>\n </Space>\n\n <Form\n helperGuideName={helperGuideName}\n lang={langOpen ? [\"cn\", {\n name: \"EnUS\", label: \"英文\", options: {\n labelTransform: (label) => label + \"(en)\",\n ignore: [{name: \"avatar\"}, {name: \"photo\"}],\n disabled: [{name: \"file\"}], //fields:[{name:'name'}]\n },\n },] : undefined}\n onSubmit={(data) => {\n modal({\n title: \"员工档案提交成功\", children: <pre>{JSON.stringify(data, null, 2)}</pre>,\n });\n }}\n >\n <Space direction=\"vertical\" size={16}>\n <FormInfo\n title=\"基本信息\"\n list={[<Input name=\"name\" label=\"员工姓名\" rule=\"REQ\"/>,\n <Input name=\"email\" label=\"工作邮箱\" rule=\"REQ EMAIL\"/>,\n <TextArea name=\"description\" label=\"个人简介\" block/>,]}\n />\n\n <FormInfo\n title=\"工作信息\"\n list={[<Select\n name=\"department\"\n label=\"所属部门\"\n rule=\"REQ\"\n options={[{label: \"技术研发中心\", value: \"tech\"}, {\n label: \"产品管理中心\", value: \"product\"\n }, {label: \"市场营销中心\", value: \"marketing\"},]}\n />, <Select\n name=\"position\"\n label=\"职位名称\"\n rule=\"REQ\"\n options={[{label: \"高级工程师\", value: \"senior\"}, {\n label: \"产品经理\", value: \"pm\"\n }, {label: \"UI设计师\", value: \"designer\"},]}\n />,]}\n />\n\n <List\n name=\"skills\"\n title=\"专业技能列表\"\n itemTitle={({index}) => \\`技能 \\${index + 1}\\`}\n list={[<Input name=\"name\" label=\"技能名称\" rule=\"REQ\"/>, <Select\n name=\"level\"\n label=\"熟练程度\"\n rule=\"REQ\"\n options={[{label: \"初级\", value: \"beginner\"}, {\n label: \"中级\", value: \"intermediate\"\n }, {label: \"高级\", value: \"advanced\"},]}\n />,]}\n />\n\n <SubmitButton type=\"primary\">提交员工档案</SubmitButton>\n </Space>\n </Form>\n </Space>);\n};\n\nrender(<PureGlobal\n preset={{\n enums: {\n helperGuide: () => [{\n value: \"employee-form-name\", content: \"请输入员工的真实姓名,用于身份识别和档案管理\", url: \"#\",\n }, {\n value: \"employee-form-email\", content: \"请输入有效的电子邮箱地址,用于接收工作通知和系统消息\", url: \"#\",\n }, {\n value: \"employee-form-department\",\n content: \"请选择员工所属的部门,部门决定了员工的汇报关系和权限范围\",\n url: \"#\",\n }, {\n value: \"employee-form-position\", content: \"请选择员工的职位,职位决定了员工的级别和职责范围\", url: \"#\",\n }, {\n value: \"employee-form-skills-name\", content: \"请填写员工掌握的技能名称,如编程语言、专业技能等\", url: \"#\",\n }, {\n value: \"employee-form-skills-level\",\n content: \"请选择员工对该技能的熟练程度,便于合理分配工作任务\",\n url: \"#\",\n },],\n },\n }}\n>\n <BaseExample/>\n</PureGlobal>);\n\n`,\n scope: [{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_39\n},{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_40\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_41\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_42\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_45 from '@components/Global';\nimport * as component_46 from 'antd';\nimport * as component_47 from '@components/Icon';\nconst readmeConfig = {\n name: `Global`,\n summary: `<h3>何时使用</h3>\n<p>在使用components-core的任何组件的业务系统,需要将该组件放置于最外层,并且按照要求正确设置preset。</p>\n<p>以下是components-core组件系统中需要设置的preset值,及使用这些值的组件</p>\n<table>\n<thead>\n<tr>\n<th>名称</th>\n<th>说明</th>\n<th>类型</th>\n<th>使用组件</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>permissions</td>\n<td>配置功能权限列表,Permissions根据该列表里面是否存在某权限名称判断用户是否具有该功能权限,来控制对应操作行为</td>\n<td>array</td>\n<td>Permissions</td>\n</tr>\n<tr>\n<td>ajax</td>\n<td>用于发送ajax请求的方法,一般情况下其应该是一个axios对象</td>\n<td>object</td>\n<td>Image</td>\n</tr>\n<tr>\n<td>apis</td>\n<td>用于和后端进行一些交互行为的接口集合</td>\n<td>object</td>\n<td>Image</td>\n</tr>\n<tr>\n<td>apis.oss</td>\n<td>用于通过一个ossId向后端oss服务获取一个可以访问到指定文件的url</td>\n<td>object</td>\n<td>Image</td>\n</tr>\n<tr>\n<td>apis.ossUpload</td>\n<td>用于向oss服务上传一个文件</td>\n<td>object</td>\n<td>FormInfo.Upload,FormInfo.Avatar</td>\n</tr>\n<tr>\n<td>features</td>\n<td>用于配置系统的特性参数</td>\n<td>object</td>\n<td>Features</td>\n</tr>\n<tr>\n<td>features.profile</td>\n<td>系统的特性列表参考组件Features</td>\n<td>object</td>\n<td>Features</td>\n</tr>\n<tr>\n<td>features.debug</td>\n<td>特性的调试模式,可以在控制台打印Features的id和状态</td>\n<td>boolean</td>\n<td>Features</td>\n</tr>\n<tr>\n<td>enums</td>\n<td>公共枚举值,详情参看Enum组件</td>\n<td>object</td>\n<td>Enum</td>\n</tr>\n<tr>\n<td>enums.helperGuide</td>\n<td>帮助文档枚举配置</td>\n<td>function</td>\n<td>HelperGuide</td>\n</tr>\n<tr>\n<td>formInfo</td>\n<td>表单配置</td>\n<td>object</td>\n<td>FormInfo.formModule</td>\n</tr>\n<tr>\n<td>formInfo.rules</td>\n<td>表单规则配置</td>\n<td>object</td>\n<td>FormInfo.formModule</td>\n</tr>\n</tbody>\n</table>\n<p>全局context管理设置及默认样式</p>\n<ul>\n<li>请将全局覆盖性的样式放在此组件中</li>\n<li>请将字体文件的引用放在此组件中</li>\n<li>请将antd的覆盖性样式放在此组件中</li>\n<li>该组件需要放置在应用根位置</li>\n</ul>\n<p>更新字体文件:</p>\n<ul>\n<li>将iconfont上下载的字体包解压后放在public文件夹下面</li>\n<li>更新src/common/params.js 中的变量 iconfontBase</li>\n<li>修改后构建该项目发布到对应环境</li>\n</ul>`,\n \n \n api: `<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>preset</td>\n<td>全局预设参数,可以通过usePreset获取,由业务系统设置</td>\n<td>object</td>\n<td>{}</td>\n</tr>\n<tr>\n<td>themeToken</td>\n<td>设置主题,参看antd的themeToken,一般只需要设置{colorPrimary}</td>\n<td>object</td>\n<td>{}</td>\n</tr>\n<tr>\n<td>init</td>\n<td>初始化方法,在系统首次加载时执行,可以返回Promise。用来放置系统显示之前的异步操作</td>\n<td>function</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>PureGlobal</h3>\n<p>api同Global,但是少了页面错误捕获和className:container-body带来的默认最小宽度等样式设置,主要用在组件库的演示环境和弹窗中</p>\n<h3>usePreset</h3>\n<p>获取预设的preset,已经确定为系统需要使用的key值:permissions,apis,formOptions,modalOptions</p>\n<h3>useGlobalContext</h3>\n<p>获取和设置全局状态,该状态保存在Global组件一级,不会随着内部组件本身的销毁而销毁。\n主要给组件内部使用,业务应该避免使用该api设置新的global变量。业务如果有需要应当自行在顶级组件中设置context。</p>\n<h4>params:useGlobalContext(globalKey)</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>globalKey</td>\n<td>全局参数的key,当存在globalKey时,默认获取和设置都是global[key],当不存在globalKey获取和设置的都是global,除非存在多个获取和设置global的key-value,否则不推荐直接使用不存在globalKey的情况</td>\n<td>string</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h4>return:{global,setGlobal}</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>global</td>\n<td>当前的global值</td>\n<td>any</td>\n</tr>\n<tr>\n<td>setGlobal</td>\n<td>设置当前的global值</td>\n<td>function</td>\n</tr>\n</tbody>\n</table>`,\n example: {\n isFull: false,\n className: `Global_4cc66`,\n style: `.Global_4cc66 .label {\n font-weight: bold;\n}`,\n list: [{\n title: `基本示例`,\n description: `展示了文字大小颜色行高的设置`,\n code: `const { PureGlobal } = _Global;\nconst { Space, Divider } = antd;\nconst BaseExample = () => {\n return (\n <PureGlobal>\n <Space direction=\"vertical\">\n <div className=\"label\">文字大小:</div>\n <div style={{ fontSize: 'var(--font-size-large)' }}>大号文字</div>\n <div>默认大小文字</div>\n <div style={{ fontSize: 'var(--font-size-small)' }}>小号文字</div>\n <Divider />\n <div className=\"label\">文字颜色:</div>\n <div style={{ color: 'var(--font-color)' }}>默认颜色</div>\n <div style={{ color: 'var(--font-color-grey)' }}>灰色</div>\n <div style={{ color: 'var(--font-color-grey-1)' }}>灰色1</div>\n <div style={{ color: 'var(--font-color-grey-2)' }}>灰色2</div>\n <Divider />\n <div className=\"label\">行高:</div>\n <div style={{ lineHeight: 'var(--line-height-large)' }}>\n 宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高宽松行高\n </div>\n <div>\n 默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高默认行高\n </div>\n <div style={{ lineHeight: 'var(--line-height-small)' }}>\n 紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高紧凑行高\n </div>\n </Space>\n </PureGlobal>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Global\",\n packageName: \"@components/Global\",\n component: component_45\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_46\n}]\n},{\n title: `警告提示`,\n description: `展示了警告提示的覆盖样式`,\n code: `const { PureGlobal } = _Global;\nconst { Alert, Space } = antd;\nconst { default: Icon } = icon;\n\nconst BasicExample = () => {\n return (\n <PureGlobal>\n <Space direction=\"vertical\">\n <Alert message=\"这是一条操作成功的状态反馈\" type=\"success\" showIcon />\n <Alert message=\"这是一条普通的信息说明\" type=\"info\" showIcon />\n <Alert message=\"这是一条提示信息\" type=\"warning\" showIcon />\n <Alert message=\"这是一条请求失败的状态反馈\" type=\"error\" showIcon />\n <Alert\n message=\"这是一条警示信息\"\n type=\"error\"\n showIcon\n icon={<Icon colorful type=\"icon-color-caisejingshi\" />}\n />\n\n <Alert\n message=\"这是一条操作成功的状态反馈\"\n description=\"提示提示提示提示提示提示提示提示提示\"\n type=\"success\"\n showIcon\n />\n <Alert\n message=\"这是一条普通的信息说明\"\n description=\"提示提示提示提示提示提示提示提示提示\"\n type=\"info\"\n showIcon\n />\n <Alert\n message=\"这是一条提示信息\"\n description=\"提示提示提示提示提示提示提示提示提示\"\n type=\"warning\"\n showIcon\n />\n <Alert\n message=\"这是一条请求失败的状态反馈\"\n description=\"提示提示提示提示提示提示提示提示提示\"\n type=\"error\"\n showIcon\n />\n <Alert\n message=\"这是一条警示信息\"\n description=\"提示提示提示提示提示提示提示提示提示\"\n type=\"error\"\n showIcon\n icon={<Icon colorful type=\"icon-color-caisejingshi\" />}\n />\n\n <Alert\n message=\"这是一条操作成功的状态反馈\"\n description=\"提示提示提示提示提示提示提示提示提示\"\n type=\"success\"\n showIcon\n closable\n />\n <Alert\n message=\"这是一条普通的信息说明\"\n description=\"提示提示提示提示提示提示提示提示提示\"\n type=\"info\"\n showIcon\n closable\n />\n <Alert\n message=\"这是一条提示信息\"\n description=\"提示提示提示提示提示提示提示提示提示\"\n type=\"warning\"\n showIcon\n closable\n />\n <Alert\n message=\"这是一条请求失败的状态反馈\"\n description=\"提示提示提示提示提示提示提示提示提示\"\n type=\"error\"\n showIcon\n closable\n />\n <Alert\n message=\"这是一条警示信息\"\n description=\"提示提示提示提示提示提示提示提示提示\"\n type=\"error\"\n showIcon\n closable\n icon={<Icon colorful type=\"icon-color-caisejingshi\" />}\n />\n </Space>\n </PureGlobal>\n );\n};\n\nrender(<BasicExample />);\n\n`,\n scope: [{\n name: \"_Global\",\n packageName: \"@components/Global\",\n component: component_45\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_46\n},{\n name: \"icon\",\n packageName: \"@components/Icon\",\n component: component_47\n}]\n},{\n title: `按钮`,\n description: `展示了按钮的覆盖样式`,\n code: `const { PureGlobal } = _Global;\nconst { Button, Typography, Space } = antd;\nconst { default: Icon } = icon;\n\nconst BaseExample = () => {\n return (\n <PureGlobal>\n <Space direction=\"vertical\">\n <Space>\n <Button size=\"large\">大按钮</Button>\n <Button>默认按钮</Button>\n <Button size=\"small\">小按钮</Button>\n </Space>\n <Space>\n <Button type=\"primary\">按钮</Button>\n <Button type=\"link\">按钮</Button>\n <Button type=\"text\">按钮</Button>\n </Space>\n <Space>\n <Button danger>危险按钮</Button>\n <Button type=\"primary\" danger>\n 危险按钮\n </Button>\n <Button type=\"link\" danger>\n 危险按钮\n </Button>\n <Button type=\"text\" danger>\n 危险按钮\n </Button>\n </Space>\n <Space>\n <Button disabled>禁用按钮</Button>\n <Button type=\"primary\" danger disabled>\n 禁用危险按钮\n </Button>\n <Button type=\"link\" disabled>\n 禁用Link按钮\n </Button>\n <Button type=\"text\" disabled>\n 禁用Text按钮\n </Button>\n </Space>\n <Space>\n <Button type=\"text\" icon={<Icon type=\"icon-tianjia\" />}>\n 图标按钮\n </Button>\n <Button type=\"text\">\n 图标按钮右\n <Icon type=\"icon-arrow-thin-down\" />\n </Button>\n </Space>\n <Space>\n <Button type=\"primary\" icon={<Icon type=\"icon-tianjia\" />} />\n <Button icon={<Icon type=\"icon-tianjia\" />} />\n <Button danger icon={<Icon type=\"icon-tianjia\" />} />\n <Button type=\"link\" icon={<Icon type=\"icon-tianjia\" />} />\n <Button type=\"text\" icon={<Icon type=\"icon-tianjia\" />} />\n </Space>\n <Space>\n <Button type=\"primary\" disabled icon={<Icon type=\"icon-tianjia\" />} />\n <Button disabled icon={<Icon type=\"icon-tianjia\" />} />\n <Button disabled danger icon={<Icon type=\"icon-tianjia\" />} />\n <Button disabled type=\"link\" icon={<Icon type=\"icon-tianjia\" />} />\n <Button disabled type=\"text\" icon={<Icon type=\"icon-tianjia\" />} />\n </Space>\n <Space>\n <Typography.Link>Link文字</Typography.Link>\n <Typography.Text className=\"ant-btn\">文字</Typography.Text>\n <Typography.Link>\n <Icon type=\"icon-tianjia\" />\n Link文字\n </Typography.Link>\n <Typography.Text className=\"ant-btn\">\n <Icon type=\"icon-tianjia\" />\n 文字\n </Typography.Text>\n <Typography.Link className=\"ant-btn-dangerous\">\n Link文字\n </Typography.Link>\n </Space>\n <Space>\n <Button className=\"btn-no-padding\" type=\"link\" size=\"large\">\n 大按钮\n </Button>\n <Button className=\"btn-no-padding\" type=\"link\">\n 默认按钮\n </Button>\n <Button className=\"btn-no-padding\" type=\"link\" size=\"small\">\n 小按钮\n </Button>\n <Button className=\"btn-no-padding\" type=\"text\" size=\"large\">\n 大按钮\n </Button>\n <Button className=\"btn-no-padding\" type=\"text\">\n 默认按钮\n </Button>\n <Button className=\"btn-no-padding\" type=\"text\" size=\"small\">\n 小按钮\n </Button>\n <Button className=\"btn-no-padding\" type=\"link\" size=\"large\" danger>\n 大按钮\n </Button>\n <Button className=\"btn-no-padding\" type=\"link\" danger>\n 默认按钮\n </Button>\n <Button className=\"btn-no-padding\" type=\"link\" size=\"small\" danger>\n 小按钮\n </Button>\n </Space>\n </Space>\n </PureGlobal>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Global\",\n packageName: \"@components/Global\",\n component: component_45\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_46\n},{\n name: \"icon\",\n packageName: \"@components/Icon\",\n component: component_47\n}]\n},{\n title: `无边框标签`,\n description: `展示了无边框标签`,\n code: `const { PureGlobal } = _Global;\nconst { Tag, Space } = antd;\n\nconst BasicExample = () => {\n return (\n <PureGlobal>\n <Space>\n <Tag className=\"no-border\" closable>\n 标签1\n </Tag>\n <Tag className=\"no-border\" closable>\n 标签2\n </Tag>\n <Tag className=\"no-border\" closable>\n 标签3\n </Tag>\n </Space>\n </PureGlobal>\n );\n};\n\nrender(<BasicExample />);\n\n`,\n scope: [{\n name: \"_Global\",\n packageName: \"@components/Global\",\n component: component_45\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_46\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_50 from '@components/HelperGuide';\nimport * as component_51 from '@components/Global';\nconst readmeConfig = {\n name: `HelperGuide`,\n summary: `<p>给用户提供帮助文档</p>`,\n \n \n api: `<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n</table>`,\n example: {\n isFull: false,\n className: ``,\n style: ``,\n list: [{\n title: `这里填写示例标题`,\n description: `这里填写示例说明`,\n code: `const { default: HelperGuide } = _HelperGuide;\nconst { PureGlobal } = Global;\nconst BaseExample = () => {\n return (\n <PureGlobal\n preset={{\n enums: {\n helperGuide: () => [\n {\n value: \"test\",\n content:\n \"哈哈哈哈哈哈哈哈啊哈哈哈哈哈哈哈哈哈哈哈啊哈哈哈哈哈哈哈哈哈哈哈啊哈哈哈哈哈哈哈哈哈哈哈啊哈哈哈哈哈哈哈哈哈哈哈啊哈哈哈哈哈哈哈哈哈哈哈啊哈哈哈\",\n url: \"/xxxx\",\n },\n ],\n },\n }}\n >\n <HelperGuide name=\"test\" />\n </PureGlobal>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_HelperGuide\",\n packageName: \"@components/HelperGuide\",\n component: component_50\n},{\n name: \"Global\",\n packageName: \"@components/Global\",\n component: component_51\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_48 from '@components/HistoryStore';\nimport * as component_49 from 'antd';\nconst readmeConfig = {\n name: `HistoryStore`,\n summary: `<p>历史记录提示</p>`,\n \n \n api: `<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n</table>`,\n example: {\n isFull: false,\n className: ``,\n style: ``,\n list: [{\n title: `这里填写示例标题`,\n description: `这里填写示例说明`,\n code: `const { default: HistoryStore } = _HistoryStore;\nconst { Input } = antd;\nconst { useState } = React;\nconst BaseExample = () => {\n const [value, setValue] = useState(\"\");\n return (\n <HistoryStore\n onSelect={(value) => {\n setValue(value);\n }}\n >\n {({ appendHistory, openHistory }) => (\n <Input.Search\n value={value}\n onChange={(e) => {\n setValue(e.target.value);\n }}\n onFocus={openHistory}\n onSearch={(value) => {\n appendHistory({\n value,\n label: value,\n });\n }}\n />\n )}\n </HistoryStore>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_HistoryStore\",\n packageName: \"@components/HistoryStore\",\n component: component_48\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_49\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_55 from '@components/Icon';\nimport * as component_56 from 'antd';\nimport * as component_57 from '@kne/react-fetch';\nimport * as component_58 from '@components/Global';\nimport * as component_59 from 'axios';\nimport * as component_60 from '@kne/remote-loader';\nconst readmeConfig = {\n name: `Icon`,\n summary: `<p>可以显示一个图标,图标必须在字体文件中被定义过</p>`,\n \n \n api: `<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>type</td>\n<td>图标类型,参考示例下的字符串</td>\n<td>string</td>\n<td>-</td>\n</tr>\n<tr>\n<td>colorful</td>\n<td>是否是彩色图标</td>\n<td>boolean</td>\n<td>false</td>\n</tr>\n<tr>\n<td>prefix</td>\n<td>图标前缀</td>\n<td>string</td>\n<td>\"\"</td>\n</tr>\n<tr>\n<td>size</td>\n<td>图标大小</td>\n<td>number</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>`,\n example: {\n isFull: true,\n className: `Icon_81743`,\n style: `.Icon_81743 .item {\n width: 150px;\n word-break: break-all;\n}\n.Icon_81743 .item .ant-typography {\n position: relative;\n}\n.Icon_81743 .item .ant-typography-copy {\n visibility: hidden;\n position: absolute;\n right: -20px;\n}\n.Icon_81743 .item:hover .ant-typography-copy {\n visibility: visible;\n}`,\n list: [{\n title: `这里填写示例标题`,\n description: `这里填写示例说明`,\n code: `const { default: Icon } = _Icon;\nconst { Slider, Space, Typography } = antd;\nconst { useState } = React;\nconst { createWithFetch } = ReactFetch;\nconst { loadFont } = Global;\nconst { default: axios } = _axios;\nconst { createWithRemoteLoader } = remoteLoader;\n\nconst BaseExample = createWithRemoteLoader({\n modules: [\"components-iconfont:Font\"],\n})(({ remoteModules }) => {\n const [Font] = remoteModules;\n const [value, setValue] = useState(30);\n return (\n <Space direction=\"vertical\">\n <Space>\n <div>调整大小:</div>\n <Slider\n style={{ width: 100 }}\n max={60}\n min={12}\n value={value}\n onChange={setValue}\n />\n <div>{value}px</div>\n </Space>\n {\n <Font>\n {({ list }) => {\n return (\n <Space wrap align=\"top\" size=\"large\">\n {list.map(({ name, font_class }) => {\n return (\n <Space\n className=\"item\"\n direction=\"vertical\"\n align=\"center\"\n key={name}\n >\n <Icon type={font_class} size={value} />\n <Typography.Text\n copyable={{\n text:\n '<Icon type=\"' +\n font_class +\n '\" size={' +\n value +\n \"} />\",\n }}\n >\n {font_class}\n </Typography.Text>\n <div>{name}</div>\n </Space>\n );\n })}\n </Space>\n );\n }}\n </Font>\n }\n </Space>\n );\n});\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Icon\",\n packageName: \"@components/Icon\",\n component: component_55\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_56\n},{\n name: \"ReactFetch\",\n packageName: \"@kne/react-fetch\",\n component: component_57\n},{\n name: \"Global\",\n packageName: \"@components/Global\",\n component: component_58\n},{\n name: \"_axios\",\n packageName: \"axios\",\n component: component_59\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_60\n}]\n},{\n title: `这里填写示例标题`,\n description: `这里填写示例说明`,\n code: `const { default: Icon } = _Icon;\nconst { Space, Slider, Typography } = antd;\nconst { useState } = React;\nconst { createWithFetch } = ReactFetch;\nconst { createWithRemoteLoader } = remoteLoader;\nconst { default: axios } = _axios;\n\nconst BaseExample = createWithRemoteLoader({\n modules: [\"components-iconfont:ColorfulFont\"],\n})(({ remoteModules }) => {\n const [ColorfulFont] = remoteModules;\n const [value, setValue] = useState(30);\n return (\n <Space direction=\"vertical\">\n <Space>\n <div>调整大小:</div>\n <Slider\n style={{ width: 100 }}\n max={60}\n min={12}\n value={value}\n onChange={setValue}\n />\n <div>{value}px</div>\n </Space>\n <ColorfulFont>\n {({ list }) => (\n <Space wrap align=\"top\" size=\"large\">\n {list.map(({ name }) => {\n return (\n <Space\n className=\"item\"\n direction=\"vertical\"\n align=\"center\"\n key={name}\n >\n <Icon colorful type={name} size={value} />\n <Typography.Text\n copyable={{\n text:\n '<Icon colorful type=\"' +\n name +\n '\" size={' +\n value +\n \"} />\",\n }}\n >\n {name}\n </Typography.Text>\n </Space>\n );\n })}\n </Space>\n )}\n </ColorfulFont>\n </Space>\n );\n});\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Icon\",\n packageName: \"@components/Icon\",\n component: component_55\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_56\n},{\n name: \"ReactFetch\",\n packageName: \"@kne/react-fetch\",\n component: component_57\n},{\n name: \"Global\",\n packageName: \"@components/Global\",\n component: component_58\n},{\n name: \"_axios\",\n packageName: \"axios\",\n component: component_59\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_60\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_52 from '@components/Image';\nimport * as component_53 from '@components/Global';\nimport * as component_54 from 'antd';\nconst readmeConfig = {\n name: `Image`,\n summary: `<p>用于展示一张图片,和img标签不同的是,可以展示一张普通图片,也可以通过id加载一张oss图片,在加载oss地址和图片数据的时候会显示loading状态</p>`,\n \n \n api: `<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>src</td>\n<td>图片的src地址</td>\n<td>string</td>\n<td>-</td>\n</tr>\n<tr>\n<td>id</td>\n<td>oss的id</td>\n<td>string</td>\n<td>-</td>\n</tr>\n<tr>\n<td>loading</td>\n<td>加载时显示的组件</td>\n<td>jsx</td>\n<td>-</td>\n</tr>\n<tr>\n<td>error</td>\n<td>加载错误时显示的组件</td>\n<td>jsx</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>Image.Avatar</h3>\n<p>用antd的Avatar来显示图片,可以显示默认的男女头像,其他参数参考antd的Avatar组件</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>gender</td>\n<td>性别 F,female,f为女其他为男</td>\n<td>string</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>`,\n example: {\n isFull: false,\n className: ``,\n style: ``,\n list: [{\n title: `通过src加载一个普通图片`,\n description: `通过src加载一个普通图片`,\n code: `const {default: Image} = _Image;\nconst BaseExample = () => {\n return <Image src={window.PUBLIC_URL + \"/logo512.png\"} style={{width: '100px', height: '100px'}}/>;\n};\n\nrender(<BaseExample/>);\n\n`,\n scope: [{\n name: \"_Image\",\n packageName: \"@components/Image\",\n component: component_52\n}]\n},{\n title: `通过id加载一个oss图片`,\n description: `图片一加载成功,图片二加载中,图片三加载失败`,\n code: `const {default: Image} = _Image;\nconst {PureGlobal} = global;\nconst {Space} = antd;\nconst BaseExample = () => {\n return <PureGlobal preset={{\n apis: {\n file: {\n getUrl: {\n loader: ({params}) => {\n if (params.id === 'logo513.png') {\n return new Promise(() => {\n\n });\n }\n return new Promise((resolve) => {\n resolve(window.PUBLIC_URL + '/' + params.id);\n });\n\n }\n }\n }\n }\n }}>\n <Space>\n <Image id=\"logo512.png\" style={{width: '100px', height: '100px'}}/>\n <Image id=\"logo513.png\" style={{width: '100px', height: '100px'}}/>\n <Image id=\"logo511.png\" style={{width: '100px', height: '100px'}}/>\n </Space>\n </PureGlobal>;\n};\n\nrender(<BaseExample/>);\n\n`,\n scope: [{\n name: \"_Image\",\n packageName: \"@components/Image\",\n component: component_52\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_53\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_54\n}]\n},{\n title: `显示一个头像`,\n description: `显示图片头像和默认头像`,\n code: `const { default: Image } = _Image;\nconst { Space } = antd;\nconst BaseExample = () => {\n return (\n <Space>\n <Image.Avatar src={window.PUBLIC_URL + \"/avatar.png\"} shape=\"circle\" />\n <Image.Avatar\n src={window.PUBLIC_URL + \"/avatar.png\"}\n shape=\"circle\"\n size={80}\n />\n <Image.Avatar\n src={window.PUBLIC_URL + \"/avatar.png\"}\n shape=\"circle\"\n size={50}\n />\n\n <Image.Avatar shape=\"circle\" />\n <Image.Avatar gender=\"M\" shape=\"circle\" size={80} />\n <Image.Avatar gender=\"female\" shape=\"circle\" size={50} />\n <Image.Avatar gender=\"m\" shape=\"circle\" size={50} />\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Image\",\n packageName: \"@components/Image\",\n component: component_52\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_54\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_66 from '@kne/info-page';\nimport '@kne/info-page/dist/index.css';\nimport * as component_68 from 'antd';\nimport '@kne/info-page/dist/index.css';\nimport '@kne/info-page/dist/index.css';\nimport '@kne/info-page/dist/index.css';\nimport '@kne/info-page/dist/index.css';\nimport '@kne/info-page/dist/index.css';\nimport '@kne/info-page/dist/index.css';\nimport '@kne/info-page/dist/index.css';\nimport '@kne/info-page/dist/index.css';\nimport * as component_77 from '@kne/remote-loader';\nimport * as component_78 from '@ant-design/icons';\nimport '@kne/info-page/dist/index.css';\nimport '@kne/info-page/dist/index.css';\nimport '@kne/info-page/dist/index.css';\nimport '@kne/info-page/dist/index.css';\nimport '@kne/info-page/dist/index.css';\nconst readmeConfig = {\n name: `info-page`,\n summary: `<p>info-page 是一个专为复杂详情展示页面设计的 React 组件库,提供标准化的信息展示格式和丰富的布局选项。</p>\n<h2>核心特性</h2>\n<ul>\n<li><strong>统一的信息展示标准</strong>:提供一致的详情页面展示格式,确保用户体验的连贯性</li>\n<li><strong>灵活的布局组件</strong>:包含多种布局方式,支持网格、表格、分栏等多种展示形式</li>\n<li><strong>强大的数据处理能力</strong>:内置数据格式化、空值处理、条件显示等实用功能</li>\n<li><strong>高度可定制化</strong>:支持自定义渲染、样式定制和扩展配置</li>\n<li><strong>现代化设计</strong>:基于 Ant Design 构建,支持响应式布局</li>\n</ul>\n<h2>适用场景</h2>\n<ul>\n<li><strong>管理系统详情页</strong>:用户信息、订单详情、产品信息等复杂展示场景</li>\n<li><strong>数据报告页面</strong>:需要结构化展示多维度数据的报表和统计页面</li>\n<li><strong>工作流展示</strong>:流程审批记录、操作历史等时序信息展示</li>\n<li><strong>数据对比页面</strong>:多列对比展示、评分系统等</li>\n<li><strong>打印友好设计</strong>:支持分页打印的报告生成</li>\n</ul>\n<h2>技术亮点</h2>\n<ul>\n<li><strong>组件化设计</strong>:提供 InfoPage、Content、TableView、Flow 等独立组件,可单独使用也可组合使用</li>\n<li><strong>智能列计算</strong>:自动计算列宽、响应式布局适配,支持固定列和自适应列混合使用</li>\n<li><strong>丰富的格式化选项</strong>:内置日期、数字、货币、布尔值等多种数据格式化器</li>\n<li><strong>条件渲染机制</strong>:支持基于数据动态控制字段显示状态</li>\n<li><strong>TypeScript 友好</strong>:完整的类型定义支持,提供良好的开发体验</li>\n</ul>`,\n \n \n api: `<h3>InfoPage</h3>\n<p>信息展示页面容器组件,提供统一的页面布局和间距控制</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>className</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n<td>自定义样式类名</td>\n</tr>\n<tr>\n<td>children</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n<td>子组件内容</td>\n</tr>\n</tbody>\n</table>\n<h3>InfoPage.Part</h3>\n<p>信息展示区块组件,用于包装具体的信息内容</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>className</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n<td>自定义样式类名</td>\n</tr>\n<tr>\n<td>title</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n<td>区块标题</td>\n</tr>\n<tr>\n<td>subtitle</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n<td>区块副标题</td>\n</tr>\n<tr>\n<td>extra</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n<td>区块额外操作区域</td>\n</tr>\n<tr>\n<td>children</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n<td>区块内容</td>\n</tr>\n<tr>\n<td>bordered</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n<td>是否显示额外边框样式</td>\n</tr>\n</tbody>\n</table>\n<h3>Content / InfoList</h3>\n<p>通用内容展示组件,支持标签-内容的灵活布局</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>list</td>\n<td>array</td>\n<td>否</td>\n<td>[]</td>\n<td>展示数据列表</td>\n</tr>\n<tr>\n<td>labelAlign</td>\n<td>string</td>\n<td>否</td>\n<td>'left'</td>\n<td>标签对齐方式,可选 'left'、'center'、'right'、'auto'</td>\n</tr>\n<tr>\n<td>col</td>\n<td>number</td>\n<td>否</td>\n<td>1</td>\n<td>每行显示的列数</td>\n</tr>\n<tr>\n<td>gutter</td>\n<td>number</td>\n<td>否</td>\n<td>0</td>\n<td>栅格间隔</td>\n</tr>\n<tr>\n<td>className</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n<td>自定义样式类名</td>\n</tr>\n<tr>\n<td>size</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n<td>尺寸大小,可选 'small'</td>\n</tr>\n<tr>\n<td>itemRender</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n<td>自定义列表项渲染函数</td>\n</tr>\n</tbody>\n</table>\n<h4>列表项数据结构</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>label</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n<td>标签内容</td>\n</tr>\n<tr>\n<td>content</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n<td>内容区域</td>\n</tr>\n<tr>\n<td>block</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n<td>是否占据整行</td>\n</tr>\n<tr>\n<td>display</td>\n<td>boolean/function</td>\n<td>否</td>\n<td>true</td>\n<td>是否显示该项</td>\n</tr>\n</tbody>\n</table>\n<h3>Descriptions / DetailList</h3>\n<p>描述列表组件,类似于 Ant Design 的 Descriptions,专为详情页设计</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>dataSource</td>\n<td>array</td>\n<td>是</td>\n<td>-</td>\n<td>二维数组数据源,每个子数组代表一行</td>\n</tr>\n<tr>\n<td>isFull</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n<td>标签是否占据更大空间</td>\n</tr>\n<tr>\n<td>className</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n<td>自定义样式类名</td>\n</tr>\n<tr>\n<td>itemRender</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n<td>自定义项渲染函数</td>\n</tr>\n</tbody>\n</table>\n<h3>CentralContent / FieldView</h3>\n<p>居中内容展示组件,支持列定义和自动布局</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>dataSource</td>\n<td>object</td>\n<td>否</td>\n<td>{}</td>\n<td>数据源对象</td>\n</tr>\n<tr>\n<td>columns</td>\n<td>array</td>\n<td>否</td>\n<td>[]</td>\n<td>列定义数组</td>\n</tr>\n<tr>\n<td>col</td>\n<td>number</td>\n<td>否</td>\n<td>2</td>\n<td>展示列数</td>\n</tr>\n<tr>\n<td>type</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n<td>组件类型,可选 'compact'(紧凑模式)</td>\n</tr>\n<tr>\n<td>valueIsEmpty</td>\n<td>function</td>\n<td>否</td>\n<td>isEmpty</td>\n<td>值为空的判断函数</td>\n</tr>\n<tr>\n<td>emptyIsPlaceholder</td>\n<td>boolean</td>\n<td>否</td>\n<td>true</td>\n<td>空值是否显示占位符</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>'-'</td>\n<td>空值占位符</td>\n</tr>\n<tr>\n<td>className</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n<td>自定义样式类名</td>\n</tr>\n<tr>\n<td>context</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n<td>上下文数据</td>\n</tr>\n</tbody>\n</table>\n<h4>列定义数据结构</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>name</td>\n<td>string</td>\n<td>是</td>\n<td>-</td>\n<td>字段名称</td>\n</tr>\n<tr>\n<td>title</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n<td>显示标题</td>\n</tr>\n<tr>\n<td>format</td>\n<td>string/function</td>\n<td>否</td>\n<td>-</td>\n<td>格式化规则</td>\n</tr>\n<tr>\n<td>render</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n<td>自定义渲染函数</td>\n</tr>\n<tr>\n<td>span</td>\n<td>number</td>\n<td>否</td>\n<td>-</td>\n<td>栅格占位格数</td>\n</tr>\n<tr>\n<td>block</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n<td>是否占据整行</td>\n</tr>\n</tbody>\n</table>\n<h3>TableView</h3>\n<p>表格视图组件,支持行选择和自定义列配置</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>dataSource</td>\n<td>array</td>\n<td>否</td>\n<td>[]</td>\n<td>表格数据源</td>\n</tr>\n<tr>\n<td>columns</td>\n<td>array</td>\n<td>是</td>\n<td>-</td>\n<td>列定义数组</td>\n</tr>\n<tr>\n<td>rowKey</td>\n<td>string/function</td>\n<td>否</td>\n<td>'id'</td>\n<td>行数据的唯一标识</td>\n</tr>\n<tr>\n<td>rowSelection</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n<td>行选择配置</td>\n</tr>\n<tr>\n<td>valueIsEmpty</td>\n<td>function</td>\n<td>否</td>\n<td>isEmpty</td>\n<td>值为空的判断函数</td>\n</tr>\n<tr>\n<td>emptyIsPlaceholder</td>\n<td>boolean</td>\n<td>否</td>\n<td>true</td>\n<td>空值是否显示占位符</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>'-'</td>\n<td>空值占位符</td>\n</tr>\n<tr>\n<td>empty</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>&lt;Empty /&gt;</td>\n<td>空数据展示内容</td>\n</tr>\n<tr>\n<td>onRowSelect</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n<td>行选择回调函数</td>\n</tr>\n<tr>\n<td>render</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n<td>自定义渲染函数</td>\n</tr>\n<tr>\n<td>context</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n<td>上下文数据</td>\n</tr>\n<tr>\n<td>sticky</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n<td>表头是否固定</td>\n</tr>\n<tr>\n<td>className</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n<td>自定义样式类名</td>\n</tr>\n</tbody>\n</table>\n<h4>行选择配置</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>type</td>\n<td>string</td>\n<td>否</td>\n<td>'checkbox'</td>\n<td>选择类型,可选 'checkbox'、'radio'</td>\n</tr>\n<tr>\n<td>selectedRowKeys</td>\n<td>array</td>\n<td>否</td>\n<td>[]</td>\n<td>已选中行的key数组</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>function</td>\n<td>否</td>\n<td>-</td>\n<td>选择变化回调函数</td>\n</tr>\n<tr>\n<td>isSelectedAll</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n<td>是否全选状态</td>\n</tr>\n<tr>\n<td>allowSelectedAll</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n<td>是否允许全选(配合 isSelectedAll 使用)</td>\n</tr>\n</tbody>\n</table>\n<h3>Flow</h3>\n<p>流程展示组件,基于 Ant Design Steps 组件扩展</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>dataSource</td>\n<td>array</td>\n<td>否</td>\n<td>[]</td>\n<td>流程数据源</td>\n</tr>\n<tr>\n<td>columns</td>\n<td>array</td>\n<td>否</td>\n<td>[]</td>\n<td>列定义数组</td>\n</tr>\n<tr>\n<td>size</td>\n<td>string</td>\n<td>否</td>\n<td>'small'</td>\n<td>步骤条大小</td>\n</tr>\n<tr>\n<td>current</td>\n<td>number</td>\n<td>否</td>\n<td>-</td>\n<td>当前步骤(从0开始)</td>\n</tr>\n<tr>\n<td>direction</td>\n<td>string</td>\n<td>否</td>\n<td>'vertical'</td>\n<td>步骤条方向,可选 'vertical'、'horizontal'</td>\n</tr>\n<tr>\n<td>progressDot</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n<td>是否使用点状步骤条</td>\n</tr>\n<tr>\n<td>labelPlacement</td>\n<td>string</td>\n<td>否</td>\n<td>'vertical'</td>\n<td>标签位置,可选 'vertical'、'horizontal'</td>\n</tr>\n<tr>\n<td>empty</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>&lt;Empty /&gt;</td>\n<td>空数据展示内容</td>\n</tr>\n<tr>\n<td>valueIsEmpty</td>\n<td>function</td>\n<td>否</td>\n<td>isEmpty</td>\n<td>值为空的判断函数</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>'-'</td>\n<td>空值占位符</td>\n</tr>\n<tr>\n<td>emptyIsPlaceholder</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n<td>空值是否显示占位符</td>\n</tr>\n<tr>\n<td>className</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n<td>自定义样式类名</td>\n</tr>\n</tbody>\n</table>\n<h4>columns 列定义支持的 type 类型</h4>\n<table>\n<thead>\n<tr>\n<th>type</th>\n<th>说明</th>\n<th>特殊处理</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>title</td>\n<td>标题</td>\n<td>-</td>\n</tr>\n<tr>\n<td>subTitle</td>\n<td>副标题</td>\n<td>-</td>\n</tr>\n<tr>\n<td>description</td>\n<td>描述</td>\n<td>-</td>\n</tr>\n<tr>\n<td>status</td>\n<td>状态</td>\n<td>-</td>\n</tr>\n<tr>\n<td>content</td>\n<td>额外内容</td>\n<td>渲染为独立区块</td>\n</tr>\n<tr>\n<td>actionList</td>\n<td>操作列表</td>\n<td>唯一支持 children 的类型</td>\n</tr>\n</tbody>\n</table>\n<h3>SplitLine</h3>\n<p>分割线展示组件,用于横向展示多个字段</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>dataSource</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n<td>数据源对象</td>\n</tr>\n<tr>\n<td>columns</td>\n<td>array</td>\n<td>是</td>\n<td>-</td>\n<td>列定义数组</td>\n</tr>\n<tr>\n<td>valueIsEmpty</td>\n<td>function</td>\n<td>否</td>\n<td>isEmpty</td>\n<td>值为空的判断函数</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>'-'</td>\n<td>空值占位符</td>\n</tr>\n<tr>\n<td>emptyIsPlaceholder</td>\n<td>boolean</td>\n<td>否</td>\n<td>false</td>\n<td>空值是否显示占位符</td>\n</tr>\n<tr>\n<td>size</td>\n<td>number</td>\n<td>否</td>\n<td>0</td>\n<td>分割线间距</td>\n</tr>\n<tr>\n<td>labelGap</td>\n<td>number</td>\n<td>否</td>\n<td>4</td>\n<td>标签与内容的间距</td>\n</tr>\n<tr>\n<td>labelMode</td>\n<td>string</td>\n<td>否</td>\n<td>'horizontal'</td>\n<td>标签模式,可选 'horizontal'、'vertical'</td>\n</tr>\n<tr>\n<td>split</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>&lt;Divider type=\"vertical\" /&gt;</td>\n<td>分割线组件</td>\n</tr>\n<tr>\n<td>context</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n<td>上下文数据</td>\n</tr>\n<tr>\n<td>className</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n<td>自定义样式类名</td>\n</tr>\n</tbody>\n</table>\n<h4>columns 列定义特殊属性</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>icon</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n<td>图标元素</td>\n</tr>\n</tbody>\n</table>\n<h3>Report</h3>\n<p>报告容器组件,用于生成打印友好的报告页面</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>title</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n<td>报告标题</td>\n</tr>\n<tr>\n<td>subtitle</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n<td>报告副标题</td>\n</tr>\n<tr>\n<td>extra</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n<td>标题额外内容</td>\n</tr>\n<tr>\n<td>border</td>\n<td>boolean</td>\n<td>否</td>\n<td>true</td>\n<td>是否显示边框</td>\n</tr>\n<tr>\n<td>children</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>-</td>\n<td>子组件内容</td>\n</tr>\n<tr>\n<td>className</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n<td>自定义样式类名</td>\n</tr>\n</tbody>\n</table>\n<h3>Report.List</h3>\n<p>报告列表子组件,展示键值对形式的报告内容</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>report</td>\n<td>object</td>\n<td>是</td>\n<td>-</td>\n<td>报告数据对象,包含 list 数组</td>\n</tr>\n<tr>\n<td>report.list</td>\n<td>array</td>\n<td>是</td>\n<td>-</td>\n<td>列表项数组,每项包含 label、content 等</td>\n</tr>\n</tbody>\n</table>\n<h3>Report.Result</h3>\n<p>报告结果子组件,展示评分结果和详细描述</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>report</td>\n<td>object</td>\n<td>是</td>\n<td>-</td>\n<td>报告数据对象,包含 total 和 list</td>\n</tr>\n<tr>\n<td>report.total</td>\n<td>object</td>\n<td>是</td>\n<td>-</td>\n<td>总分信息,包含 score、label</td>\n</tr>\n<tr>\n<td>report.list</td>\n<td>array</td>\n<td>是</td>\n<td>-</td>\n<td>评分明细列表,每项包含 label、score、content</td>\n</tr>\n</tbody>\n</table>\n<h3>Report.Table</h3>\n<p>报告表格子组件,展示分组评分表格</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>report</td>\n<td>object</td>\n<td>是</td>\n<td>-</td>\n<td>报告数据对象</td>\n</tr>\n<tr>\n<td>report.columns</td>\n<td>array</td>\n<td>是</td>\n<td>-</td>\n<td>表格列定义</td>\n</tr>\n<tr>\n<td>report.group</td>\n<td>array</td>\n<td>是</td>\n<td>-</td>\n<td>分组定义数组,每项包含 name、label</td>\n</tr>\n<tr>\n<td>report.list</td>\n<td>array</td>\n<td>是</td>\n<td>-</td>\n<td>表格数据列表</td>\n</tr>\n</tbody>\n</table>\n<h3>Report.Part</h3>\n<p>报告内容区块子组件,展示段落形式的内容</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>report</td>\n<td>object</td>\n<td>是</td>\n<td>-</td>\n<td>报告数据对象,包含 list 数组</td>\n</tr>\n<tr>\n<td>report.list</td>\n<td>array</td>\n<td>是</td>\n<td>-</td>\n<td>内容项数组,每项包含 label、content 等</td>\n</tr>\n</tbody>\n</table>\n<h3>Report.Score</h3>\n<p>报告评分展示子组件</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>value</td>\n<td>number</td>\n<td>是</td>\n<td>-</td>\n<td>当前评分值</td>\n</tr>\n</tbody>\n</table>\n<h3>Score</h3>\n<p>评分展示组件,以星形图标展示评分</p>\n<h4>属性说明</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>value</td>\n<td>number</td>\n<td>是</td>\n<td>-</td>\n<td>当前评分值</td>\n</tr>\n<tr>\n<td>gap</td>\n<td>number</td>\n<td>否</td>\n<td>4</td>\n<td>评分项之间的间距</td>\n</tr>\n<tr>\n<td>total</td>\n<td>number</td>\n<td>否</td>\n<td>5</td>\n<td>总评分项数</td>\n</tr>\n<tr>\n<td>className</td>\n<td>string</td>\n<td>否</td>\n<td>-</td>\n<td>自定义样式类名</td>\n</tr>\n</tbody>\n</table>\n<h3>formatView</h3>\n<p>数据格式化工具函数,提供多种常用格式化规则</p>\n<h4>方法说明</h4>\n<table>\n<thead>\n<tr>\n<th>方法名</th>\n<th>参数</th>\n<th>返回值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>default</td>\n<td>(value, format, context)</td>\n<td>string/object</td>\n<td>根据格式规则格式化数据</td>\n</tr>\n</tbody>\n</table>\n<h4>支持的格式化规则</h4>\n<table>\n<thead>\n<tr>\n<th>格式名</th>\n<th>说明</th>\n<th>参数</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>date</td>\n<td>日期格式化</td>\n<td>模板字符串,默认 'YYYY-MM-DD'</td>\n</tr>\n<tr>\n<td>datetime</td>\n<td>日期时间格式化</td>\n<td>模板字符串,默认 'YYYY-MM-DD HH:mm:ss'</td>\n</tr>\n<tr>\n<td>dateRange</td>\n<td>日期范围格式化</td>\n<td>模板字符串、是否允许空值</td>\n</tr>\n<tr>\n<td>boolean</td>\n<td>布尔值格式化</td>\n<td>true值对应的文本,默认 'true'</td>\n</tr>\n<tr>\n<td>number</td>\n<td>数字格式化</td>\n<td>样式、单位、小数位数等</td>\n</tr>\n<tr>\n<td>money</td>\n<td>金额格式化</td>\n<td>单位,默认 '元'</td>\n</tr>\n</tbody>\n</table>\n<h3>computeColumnsValue</h3>\n<p>列值计算工具函数,用于统一处理列数据的显示逻辑</p>\n<h4>方法说明</h4>\n<table>\n<thead>\n<tr>\n<th>方法名</th>\n<th>参数</th>\n<th>返回值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>default</td>\n<td>(config)</td>\n<td>array</td>\n<td>计算列的显示值</td>\n</tr>\n<tr>\n<td>computeDisplay</td>\n<td>(config)</td>\n<td>ReactNode</td>\n<td>计算单个列的显示内容</td>\n</tr>\n<tr>\n<td>computeColumnsDisplay</td>\n<td>(config)</td>\n<td>array</td>\n<td>计算所有列的显示内容</td>\n</tr>\n</tbody>\n</table>\n<h4>配置参数</h4>\n<table>\n<thead>\n<tr>\n<th>参数名</th>\n<th>类型</th>\n<th>必填</th>\n<th>默认值</th>\n<th>说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>columns</td>\n<td>array</td>\n<td>是</td>\n<td>-</td>\n<td>列定义数组</td>\n</tr>\n<tr>\n<td>dataSource</td>\n<td>object/array</td>\n<td>是</td>\n<td>-</td>\n<td>数据源</td>\n</tr>\n<tr>\n<td>context</td>\n<td>object</td>\n<td>否</td>\n<td>-</td>\n<td>上下文数据</td>\n</tr>\n<tr>\n<td>valueIsEmpty</td>\n<td>function</td>\n<td>否</td>\n<td>isEmpty</td>\n<td>值为空的判断函数</td>\n</tr>\n<tr>\n<td>emptyIsPlaceholder</td>\n<td>boolean</td>\n<td>否</td>\n<td>true</td>\n<td>空值是否显示占位符</td>\n</tr>\n<tr>\n<td>removeEmpty</td>\n<td>boolean</td>\n<td>否</td>\n<td>true</td>\n<td>是否移除空值列</td>\n</tr>\n<tr>\n<td>placeholder</td>\n<td>ReactNode</td>\n<td>否</td>\n<td>'-'</td>\n<td>空值占位符</td>\n</tr>\n</tbody>\n</table>`,\n example: {\n isFull: false,\n className: ``,\n style: ``,\n list: [{\n title: `基础布局`,\n description: `展示InfoPage容器组件和Part区块组件的基本使用方法`,\n code: `const { default: InfoPage } = _InfoPage;\nconst { Button, Space, Flex, Tag } = antd;\n\nconst BaseExample = () => {\n return (\n <Flex vertical gap={24}>\n <Space direction=\"vertical\" size={16}>\n {/* 基础 Part 使用 */}\n <InfoPage.Part title=\"个人信息\" subtitle=\"展示基础 Part 用法\">\n <Space direction=\"vertical\" size={8}>\n <div><strong>姓名:</strong>张三</div>\n <div><strong>性别:</strong>男</div>\n <div><strong>年龄:</strong>28岁</div>\n </Space>\n </InfoPage.Part>\n\n {/* 带 extra 的 Part */}\n <InfoPage.Part \n title=\"联系方式\" \n subtitle=\"展示标题和额外操作区\"\n extra={<Button type=\"primary\" size=\"small\">编辑</Button>}\n >\n <Space direction=\"vertical\" size={8}>\n <div><strong>手机:</strong>138-0013-8000</div>\n <div><strong>邮箱:</strong>zhangsan@example.com</div>\n <div><strong>地址:</strong>深圳市南山区科技园</div>\n </Space>\n </InfoPage.Part>\n\n {/* 嵌套 Part */}\n <InfoPage.Part title=\"工作经历\">\n <p>以下展示了 Part 的嵌套使用:</p>\n <InfoPage.Part subtitle=\"现任职位\" style={{ background: '#f5f5f5', padding: '12px' }}>\n <Space direction=\"vertical\" size={8}>\n <div><strong>公司:</strong>腾讯科技</div>\n <div><strong>职位:</strong>高级前端工程师</div>\n <div><strong>入职时间:</strong>2020年3月</div>\n </Space>\n </InfoPage.Part>\n </InfoPage.Part>\n\n {/* 带 bordered 的 Part */}\n <InfoPage.Part title=\"项目经验\" bordered>\n <Space direction=\"vertical\" size={8}>\n <div><strong>项目名称:</strong>企业级管理系统</div>\n <div><strong>技术栈:</strong>React、TypeScript、Ant Design</div>\n <div><strong>职责:</strong>负责前端架构设计与核心功能开发</div>\n </Space>\n </InfoPage.Part>\n\n {/* Collapse 折叠面板 */}\n <InfoPage.Collapse\n items={[\n { \n key: '1', \n label: '教育背景', \n children: (\n <Space direction=\"vertical\" size={8}>\n <div><strong>学校:</strong>深圳大学</div>\n <div><strong>专业:</strong>计算机科学与技术</div>\n <div><strong>学历:</strong>本科</div>\n <div><strong>毕业时间:</strong>2018年6月</div>\n </Space>\n )\n },\n { \n key: '2', \n label: '技能证书', \n children: (\n <Space wrap>\n <Tag color=\"blue\">PMP项目管理</Tag>\n <Tag color=\"green\">阿里云ACP认证</Tag>\n <Tag color=\"purple\">AWS解决方案架构师</Tag>\n </Space>\n )\n }\n ]}\n />\n\n {/* 无标题 Part */}\n <InfoPage.Part>\n <div style={{ color: '#666', padding: '12px', background: '#fafafa' }}>\n <strong>备注:</strong>以上信息仅供示例展示,不代表真实数据\n </div>\n </InfoPage.Part>\n </Space>\n </Flex>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_InfoPage\",\n packageName: \"@kne/info-page\",\n component: component_66\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_68\n}]\n},{\n title: `内容列表`,\n description: `支持多列布局和标签对齐的灵活内容展示组件`,\n code: `const { Content } = _InfoPage;\nconst { Space, Radio, Tag } = antd;\nconst { useState } = React;\n\nconst BaseExample = () => {\n const [listProps, setListProps] = useState({\n col: 2,\n size: 'default',\n labelAlign: 'left'\n });\n\n const onChange = (e, name) => {\n const val = e?.target.value;\n setListProps(prevState => Object.assign({}, prevState, { [name]: val }));\n };\n\n return (\n <Space direction='vertical' size={16}>\n {/* 控制面板 */}\n <div style={{ background: '#f5f5f5', padding: '16px', borderRadius: '8px' }}>\n <Space direction=\"vertical\" size={12} style={{ width: '100%' }}>\n <div>\n <span style={{ marginRight: 8 }}>列数:</span>\n <Radio.Group onChange={(e) => onChange(e, 'col')} value={listProps.col}>\n <Radio.Button value={1}>单列</Radio.Button>\n <Radio.Button value={2}>两列</Radio.Button>\n <Radio.Button value={3}>三列</Radio.Button>\n </Radio.Group>\n </div>\n <div>\n <span style={{ marginRight: 8 }}>标签对齐:</span>\n <Radio.Group onChange={(e) => onChange(e, 'labelAlign')} value={listProps.labelAlign}>\n <Radio.Button value='left'>左对齐</Radio.Button>\n <Radio.Button value='center'>居中</Radio.Button>\n <Radio.Button value='right'>右对齐</Radio.Button>\n <Radio.Button value='auto'>自适应</Radio.Button>\n </Radio.Group>\n </div>\n <div>\n <span style={{ marginRight: 8 }}>尺寸:</span>\n <Radio.Group onChange={(e) => onChange(e, 'size')} value={listProps.size}>\n <Radio.Button value='default'>默认</Radio.Button>\n <Radio.Button value='small'>小尺寸</Radio.Button>\n </Radio.Group>\n </div>\n </Space>\n </div>\n\n {/* Content 组件展示 */}\n <Content\n {...listProps}\n list={[\n { label: '客户名称', content: '深圳市腾讯计算机系统有限公司' },\n { label: '统一社会信用代码', content: '914403007109410773' },\n { label: '法定代表人', content: '马化腾' },\n { label: '企业类型', content: <Tag color=\"blue\">有限责任公司</Tag> },\n { label: '成立日期', content: '1998-11-11' },\n { label: '注册资本', content: '500万美元' },\n { label: '经营状态', content: <Tag color=\"success\">存续</Tag> },\n { label: '注册地址', content: '深圳市南山区高新科技园科技中一路腾讯大厦' },\n {\n label: '经营范围',\n content: '计算机软硬件的技术开发、销售;计算机网络工程;系统集成;软件开发及技术服务;信息咨询;网络设备、通讯设备、电子产品的技术开发与销售;国内贸易。',\n block: true\n }\n ]}\n itemRender={(inner, other) => {\n return other?.index === 8 ? <div style={{ color: '#999', fontSize: '12px', marginTop: '8px' }}>\n * 以上信息仅供展示,不代表真实数据\n </div> : inner;\n }}\n />\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_InfoPage\",\n packageName: \"@kne/info-page\",\n component: component_66\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_68\n}]\n},{\n title: `内容展示`,\n description: `展示Content组件的各种配置和用法`,\n code: `const { Content } = _InfoPage;\nconst { Flex, Radio, Space, Tag, Avatar } = antd;\nconst { useState } = React;\n\nconst BaseExample = () => {\n const [listProps, setListProps] = useState({\n col: 2,\n size: 'default',\n labelAlign: 'auto',\n gutter: 16\n });\n\n const [showDisabled, setShowDisabled] = useState(false);\n\n const onChange = (e, name) => {\n const val = e?.target.value;\n setListProps(prevState => ({ ...prevState, [name]: val }));\n };\n\n const dataList = [\n { label: '客户姓名', content: <Flex align=\"center\" gap={8}><Avatar size=\"small\">张</Avatar>张三</Flex>, block: true },\n { label: '客户编号', content: 'C20240115001' },\n { label: '联系电话', content: '138-0013-8000' },\n { label: '电子邮箱', content: 'zhangsan@example.com' },\n { label: '客户类型', content: <Tag color=\"blue\">VIP客户</Tag> },\n { label: '信用等级', content: <Tag color=\"green\">A级</Tag> },\n { label: '所属公司', content: '深圳市腾讯计算机系统有限公司', block: true },\n { label: '所在部门', content: '技术部', display: !showDisabled },\n { label: '职位', content: '高级前端工程师', display: !showDisabled },\n { label: '注册时间', content: '2020-03-15' },\n { label: '最后登录', content: '2024-01-15 10:30:00' },\n { label: '账户状态', content: <Tag color=\"success\">正常</Tag> },\n { label: '备注信息', content: '该客户为公司长期合作伙伴,合作期间表现优秀,建议继续保持良好合作关系。', block: true }\n ];\n\n return (\n <Flex vertical gap={16}>\n {/* 控制面板 */}\n <Space direction=\"vertical\" size={12} style={{ background: '#f5f5f5', padding: '16px', borderRadius: '8px' }}>\n <div>\n <span style={{ marginRight: 8 }}>列数:</span>\n <Radio.Group onChange={(e) => onChange(e, 'col')} value={listProps.col}>\n <Radio.Button value={1}>单列</Radio.Button>\n <Radio.Button value={2}>两列</Radio.Button>\n <Radio.Button value={3}>三列</Radio.Button>\n <Radio.Button value={4}>四列</Radio.Button>\n </Radio.Group>\n </div>\n\n <div>\n <span style={{ marginRight: 8 }}>标签对齐:</span>\n <Radio.Group onChange={(e) => onChange(e, 'labelAlign')} value={listProps.labelAlign}>\n <Radio.Button value='left'>左对齐</Radio.Button>\n <Radio.Button value='center'>居中</Radio.Button>\n <Radio.Button value='right'>右对齐</Radio.Button>\n <Radio.Button value='auto'>自适应</Radio.Button>\n </Radio.Group>\n </div>\n\n <div>\n <span style={{ marginRight: 8 }}>尺寸:</span>\n <Radio.Group onChange={(e) => onChange(e, 'size')} value={listProps.size}>\n <Radio.Button value='default'>默认</Radio.Button>\n <Radio.Button value='small'>小尺寸</Radio.Button>\n </Radio.Group>\n </div>\n\n <div>\n <span style={{ marginRight: 8 }}>显示隐藏:</span>\n <Radio.Group onChange={(e) => setShowDisabled(e.target.value)} value={showDisabled}>\n <Radio.Button value={false}>显示全部</Radio.Button>\n <Radio.Button value={true}>隐藏部分</Radio.Button>\n </Radio.Group>\n </div>\n </Space>\n\n {/* Content 组件展示 */}\n <Content\n {...listProps}\n list={dataList.map(item => ({\n ...item,\n display: typeof item.display === 'boolean' ? item.display : undefined\n }))}\n />\n </Flex>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_InfoPage\",\n packageName: \"@kne/info-page\",\n component: component_66\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_68\n}]\n},{\n title: `描述列表`,\n description: `二维数组结构的详情信息展示,适合表单数据展示`,\n code: `const { Descriptions } = _InfoPage;\nconst { Tag, Space } = antd;\n\nconst BaseExample = () => {\n return (\n <Descriptions\n dataSource={[\n // 基本信息分组\n [\n { label: \"订单编号\", content: <strong style={{ color: '#1890ff' }}>ORD20240115001</strong> },\n { label: \"订单类型\", content: <Tag color=\"blue\">普通订单</Tag> },\n ],\n [\n { label: \"下单时间\", content: \"2024-01-15 10:30:25\" },\n { label: \"支付时间\", content: \"2024-01-15 10:32:18\" },\n ],\n [\n { label: \"客户名称\", content: \"深圳市腾讯计算机系统有限公司\" },\n { label: \"客户类型\", content: <Tag color=\"gold\">VIP客户</Tag> },\n ],\n // 收货信息分组\n [\n { label: \"收货人\", content: \"张三\" },\n { label: \"联系电话\", content: \"138-0013-8000\" },\n ],\n [\n { label: \"收货地址\", content: \"广东省深圳市南山区科技园科技中一路腾讯大厦A座18层\" },\n ],\n // 商品信息分组\n [\n {\n label: \"商品清单\",\n content: (\n <Space direction=\"vertical\" size={4}>\n <div>1. 腾讯云服务器(2核4G)× 1台 - ¥3000.00</div>\n <div>2. 云数据库 MySQL(50GB)× 1个 - ¥1200.00</div>\n <div>3. 对象存储(500GB)× 1个 - ¥800.00</div>\n </Space>\n ),\n },\n ],\n // 金额信息分组\n [\n { label: \"商品总额\", content: <strong>¥5,000.00</strong> },\n { label: \"运费\", content: \"¥0.00\" },\n ],\n [\n { label: \"优惠金额\", content: <span style={{ color: '#52c41a' }}>-¥750.00</span> },\n { label: \"实付金额\", content: <strong style={{ color: '#f5222d', fontSize: '16px' }}>¥4,250.00</strong> },\n ],\n // 发票信息分组\n [\n { label: \"发票类型\", content: \"增值税专用发票\" },\n { label: \"发票抬头\", content: \"深圳市腾讯计算机系统有限公司\" },\n ],\n [\n { label: \"纳税人识别号\", content: \"914403007109410773\" },\n { label: \"发票状态\", content: <Tag color=\"success\">已开具</Tag> },\n ],\n // 售后信息分组\n [\n { label: \"退款状态\", content: \"无退款\" },\n { label: \"发票抬头\", content: \"未申请\" },\n ],\n [\n { label: \"订单状态\", content: <Tag color=\"processing\">处理中</Tag> },\n {\n label: \"预计送达\",\n content: \"2024-01-17\",\n },\n ],\n // 备注信息\n [\n {\n label: \"订单备注\",\n content: \"请务必在工作日配送,配送前请提前电话联系收货人。收到商品后请当面验货,确认无误后再签收。\",\n block: true\n },\n ],\n // 操作记录\n [\n { label: \"创建时间\", content: \"2024-01-15 10:30:25\" },\n { label: \"创建人\", content: \"张三(客户)\" },\n ],\n ]}\n />\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_InfoPage\",\n packageName: \"@kne/info-page\",\n component: component_66\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_68\n}]\n},{\n title: `智能布局`,\n description: `支持数据格式化和自动栅格优化的高级内容展示组件`,\n code: `const { CentralContent } = _InfoPage;\nconst { Tag, Space } = antd;\n\nconst BaseExample = () => {\n return (\n <CentralContent\n dataSource={{\n id: 'RC20240115001',\n name: '张三',\n department: '技术研发部',\n position: '高级前端工程师',\n email: 'zhangsan@tencent.com',\n phone: '138-0013-8000',\n entryDate: '2020-03-15',\n workYears: 4,\n performanceScore: 92.5,\n salary: 35000,\n bonus: 50000,\n leaveDays: 5,\n projectCount: 8,\n description: \\`负责公司核心产品的前端架构设计与开发工作,主导了多个重要项目的技术方案设计。精通React、Vue等主流前端框架,对TypeScript有深入理解。在性能优化方面有丰富经验,成功将项目加载时间减少40%。\\`,\n skills: \\`React, Vue, TypeScript, Node.js, Webpack, Vite, Jenkins, Docker, Kubernetes\\`\n }}\n col={3}\n columns={[\n { name: 'id', title: '员工编号', block: true },\n { name: 'name', title: '姓名', span: 8 },\n { name: 'department', title: '部门' },\n { name: 'position', title: '职位', span: 10 },\n { name: 'email', title: '电子邮箱' },\n { name: 'phone', title: '联系电话' },\n { name: 'entryDate', title: '入职日期', format: 'date' },\n { name: 'workYears', title: '工作年限', format: 'number-suffix:年' },\n { name: 'performanceScore', title: '绩效评分', format: 'number-maximumFractionDigits:1-suffix:分' },\n { name: 'salary', title: '月薪', format: 'number-useGrouping:true-suffix:元' },\n { name: 'bonus', title: '年终奖金', format: 'number-useGrouping:true-suffix:元' },\n { name: 'leaveDays', title: '年度剩余年假', format: 'number-suffix:天' },\n { name: 'projectCount', title: '参与项目数', format: 'number-suffix:个' },\n { name: 'empty', title: '公积金账号' },\n { name: 'empty2', title: '社保卡号', placeholder: '未办理' },\n { name: 'description', title: '工作描述', block: true },\n { name: 'skills', title: '技能标签', render: (value) => (\n <Space wrap>\n {value.split(',').map(skill => (\n <Tag key={skill} color=\"blue\" style={{ marginBottom: 4 }}>{skill.trim()}</Tag>\n ))}\n </Space>\n )}\n ]}\n />\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_InfoPage\",\n packageName: \"@kne/info-page\",\n component: component_66\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_68\n}]\n},{\n title: `边框区块`,\n description: `展示InfoPage.Part的bordered属性配合CentralContent使用`,\n code: `const { default: InfoPage, CentralContent } = _InfoPage;\nconst { Tag, Avatar, Space } = antd;\n\nconst BaseExample = () => {\n return (\n <InfoPage>\n <InfoPage.Part bordered title=\"员工档案\" subtitle=\"基本信息\">\n <CentralContent\n type=\"compact\"\n dataSource={{\n id: 'RC20240115001',\n name: '张三',\n gender: '男',\n birthday: '1992-03-15',\n idCard: '440301199203154512',\n maritalStatus: '已婚',\n education: '本科',\n graduationSchool: '深圳大学',\n major: '计算机科学与技术',\n entryDate: '2020-03-15',\n workYears: 4,\n phone: '138-0013-8000',\n email: 'zhangsan@tencent.com',\n address: '广东省深圳市南山区科技园科技中一路腾讯大厦',\n emergencyContact: '李四',\n emergencyPhone: '139-0014-9000',\n emergencyRelation: '配偶'\n }}\n col={3}\n columns={[\n {\n name: 'id',\n title: '员工编号',\n block: true\n },\n {\n name: 'name',\n title: '姓名',\n render: (value) => (\n <Space align=\"center\">\n <Avatar style={{ backgroundColor: '#1890ff' }}>{value[0]}</Avatar>\n <strong>{value}</strong>\n </Space>\n ),\n span: 10\n },\n {\n name: 'gender',\n title: '性别'\n },\n {\n name: 'birthday',\n title: '出生日期',\n format: 'date'\n },\n {\n name: 'idCard',\n title: '身份证号',\n render: (value) => value.replace(/(\\d{6})(\\d{8})(\\d{4})/, '\\$1********\\$3')\n },\n {\n name: 'maritalStatus',\n title: '婚姻状况'\n },\n {\n name: 'education',\n title: '学历'\n },\n {\n name: 'graduationSchool',\n title: '毕业院校'\n },\n {\n name: 'major',\n title: '专业'\n },\n {\n name: 'entryDate',\n title: '入职日期',\n format: 'date'\n },\n {\n name: 'workYears',\n title: '工作年限',\n format: 'number-suffix:年'\n },\n {\n name: 'phone',\n title: '联系电话',\n render: (value) => value.replace(/(\\d{3})(\\d{4})(\\d{4})/, '\\$1-\\$2-\\$3')\n },\n {\n name: 'email',\n title: '电子邮箱'\n },\n {\n name: 'address',\n title: '家庭住址',\n block: true\n },\n {\n name: 'emergencyContact',\n title: '紧急联系人'\n },\n {\n name: 'emergencyPhone',\n title: '紧急联系电话',\n render: (value) => value.replace(/(\\d{3})(\\d{4})(\\d{4})/, '\\$1-\\$2-\\$3')\n },\n {\n name: 'emergencyRelation',\n title: '与本人关系'\n }\n ]}\n />\n </InfoPage.Part>\n\n <InfoPage.Part bordered title=\"工作信息\" subtitle=\"部门与职位\">\n <CentralContent\n type=\"compact\"\n dataSource={{\n department: '技术研发部',\n position: '高级前端工程师',\n level: 'T4-2',\n supervisor: '王总监',\n team: '前端开发组',\n workLocation: '深圳总部',\n office: '腾讯大厦A座18层',\n workStatus: '在职',\n contractType: '正式员工',\n contractStartDate: '2023-03-15',\n contractEndDate: '2026-03-14',\n probationPeriod: '已转正'\n }}\n col={2}\n columns={[\n { name: 'department', title: '所属部门', span: 12 },\n { name: 'position', title: '职位', span: 12 },\n { name: 'level', title: '职级' },\n { name: 'supervisor', title: '直属主管' },\n { name: 'team', title: '所属团队' },\n { name: 'workLocation', title: '工作地点' },\n { name: 'office', title: '办公室位置' },\n { name: 'workStatus', title: '工作状态', render: (value) => <Tag color=\"success\">{value}</Tag> },\n { name: 'contractType', title: '合同类型' },\n { name: 'contractStartDate', title: '合同开始日期', format: 'date' },\n { name: 'contractEndDate', title: '合同结束日期', format: 'date' },\n { name: 'probationPeriod', title: '试用期状态', render: (value) => <Tag color=\"success\">{value}</Tag> }\n ]}\n />\n </InfoPage.Part>\n\n <InfoPage.Part bordered title=\"福利待遇\" subtitle=\"薪资与福利\">\n <CentralContent\n type=\"compact\"\n dataSource={{\n baseSalary: 30000,\n performanceBonus: 5000,\n annualBonus: 50000,\n socialInsurance: '已缴纳(五险一金)',\n housingFund: 3600,\n medicalInsurance: '已包含',\n mealAllowance: 1500,\n transportAllowance: 800,\n stockOptions: 5000,\n otherBenefits: '年度体检、节日礼品、团建活动'\n }}\n col={2}\n columns={[\n { name: 'baseSalary', title: '基本月薪', format: 'number-useGrouping:true-suffix:元', span: 12 },\n { name: 'performanceBonus', title: '绩效奖金', format: 'number-useGrouping:true-suffix:元/月', span: 12 },\n { name: 'annualBonus', title: '年终奖金', format: 'number-useGrouping:true-suffix:元', block: true },\n { name: 'socialInsurance', title: '社会保险', render: (value) => <Tag color=\"success\">{value}</Tag> },\n { name: 'housingFund', title: '公积金', format: 'number-useGrouping:true-suffix:元/月' },\n { name: 'medicalInsurance', title: '医疗保险', render: (value) => <Tag color=\"success\">{value}</Tag> },\n { name: 'mealAllowance', title: '餐补', format: 'number-useGrouping:true-suffix:元/月' },\n { name: 'transportAllowance', title: '交通补贴', format: 'number-useGrouping:true-suffix:元/月' },\n { name: 'stockOptions', title: '股票期权', format: 'number-useGrouping:true-suffix:股', block: true },\n { name: 'otherBenefits', title: '其他福利', block: true }\n ]}\n />\n </InfoPage.Part>\n </InfoPage>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_InfoPage\",\n packageName: \"@kne/info-page\",\n component: component_66\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_68\n}]\n},{\n title: `表格视图`,\n description: `支持行选择、固定表头和多数据展示的表格组件`,\n code: `const { TableView } = _InfoPage;\nconst { Flex, Tag, Badge } = antd;\nconst { useState } = React;\n\nconst dataSource = [\n {\n id: 'ORD20240115001',\n customerName: '深圳市腾讯计算机系统有限公司',\n contact: '张三',\n phone: '138-0013-8000',\n amount: 42500,\n status: '已完成',\n orderDate: '2024-01-15',\n deliveryDate: '2024-01-17'\n },\n {\n id: 'ORD20240115002',\n customerName: '华为技术有限公司',\n contact: '李四',\n phone: '139-0014-9000',\n amount: 85000,\n status: '处理中',\n orderDate: '2024-01-15',\n deliveryDate: '2024-01-20'\n },\n {\n id: 'ORD20240115003',\n customerName: '阿里巴巴集团控股有限公司',\n contact: '王五',\n phone: '137-0015-7000',\n amount: 120000,\n status: '待发货',\n orderDate: '2024-01-14',\n deliveryDate: '2024-01-22'\n },\n {\n id: 'ORD20240115004',\n customerName: '北京字节跳动科技有限公司',\n contact: '赵六',\n phone: '136-0016-6000',\n amount: 65000,\n status: '已完成',\n orderDate: '2024-01-13',\n deliveryDate: '2024-01-16'\n },\n {\n id: 'ORD20240115005',\n customerName: '百度在线网络技术(北京)有限公司',\n contact: '钱七',\n phone: '135-0017-5000',\n amount: 95000,\n status: '已取消',\n orderDate: '2024-01-12',\n deliveryDate: ''\n }\n];\n\nconst columns = [\n { name: 'id', title: '订单编号' },\n { name: 'customerName', title: '客户名称', span: 10 },\n { name: 'contact', title: '联系人' },\n { name: 'phone', title: '联系电话', render: (value) => value.replace(/(\\d{3})(\\d{4})(\\d{4})/, '\\$1-\\$2-\\$3') },\n { name: 'amount', title: '订单金额(元)', render: (value) => <strong style={{ color: '#f5222d' }}>¥{value.toLocaleString()}</strong> },\n { name: 'orderDate', title: '下单日期', format: 'date' },\n { name: 'deliveryDate', title: '预计送达', format: 'date' },\n { name: 'status', title: '订单状态', render: (value) => {\n const config = {\n '已完成': { color: 'success', text: '已完成' },\n '处理中': { color: 'processing', text: '处理中' },\n '待发货': { color: 'warning', text: '待发货' },\n '已取消': { color: 'default', text: '已取消' }\n };\n const { color, text } = config[value] || { color: 'default', text: value };\n return <Badge status={color} text={text} />;\n }}\n];\n\nconst WithCheckbox = () => {\n const [selectKeys, setSelectKeys] = useState([]);\n const totalAmount = selectKeys.reduce((sum, id) => sum + (dataSource.find(d => d.id === id)?.amount || 0), 0);\n return (\n <div>\n <Flex justify=\"space-between\" align=\"center\" style={{ marginBottom: 12 }}>\n <span>已选 <strong>{selectKeys.length}</strong> 个订单,总金额 <strong style={{ color: '#52c41a' }}>¥{totalAmount.toLocaleString()}</strong></span>\n </Flex>\n <TableView dataSource={dataSource} columns={columns} rowSelection={{\n type: 'checkbox', allowSelectedAll: true, selectedRowKeys: selectKeys, onChange: setSelectKeys\n }} />\n </div>\n );\n};\n\nconst WithSelected = () => {\n const [selectKeys, setSelectKeys] = useState([]);\n const selectedOrder = dataSource.find(d => d.id === selectKeys[0]);\n return (\n <div>\n <Flex justify=\"space-between\" align=\"center\" style={{ marginBottom: 12 }}>\n <span>已选订单:{selectedOrder ? \\`\\${selectedOrder.id} (\\${selectedOrder.customerName})\\` : '无'}</span>\n {selectedOrder && <Tag color=\"blue\">¥{selectedOrder.amount.toLocaleString()}</Tag>}\n </Flex>\n <TableView dataSource={dataSource} columns={columns} rowSelection={{\n type: 'radio', selectedRowKeys: selectKeys, onChange: setSelectKeys\n }} />\n </div>\n );\n};\n\nconst BaseExample = () => {\n return (\n <Flex vertical gap={16}>\n <div style={{ background: '#f5f5f5', padding: '12px', borderRadius: '8px' }}>\n 订单列表 - 共 <strong>{dataSource.length}</strong> 个订单\n </div>\n <TableView dataSource={dataSource} columns={columns} />\n <WithCheckbox />\n <WithSelected />\n <div style={{ padding: '16px', background: '#fafafa', border: '1px dashed #d9d9d9', borderRadius: '8px' }}>\n 暂无订单数据\n </div>\n <TableView\n style={{ height: '250px', overflowY: 'scroll' }}\n dataSource={dataSource}\n columns={columns}\n sticky\n headerStyle={{ position: 'sticky', top: 0, zIndex: 1, background: '#fafafa' }}\n />\n </Flex>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_InfoPage\",\n packageName: \"@kne/info-page\",\n component: component_66\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_68\n}]\n},{\n title: `表格选择`,\n description: `展示TableView组件的各种选择模式`,\n code: `const { TableView } = _InfoPage;\nconst { Flex, Radio, Space, Button, Tag, Avatar } = antd;\nconst { useState } = React;\n\nconst dataSource = [\n { id: 'C20240115001', name: '张三', company: '腾讯科技', contact: '138-0013-8000', amount: 50000, status: '已签约' },\n { id: 'C20240115002', name: '李四', company: '华为技术', contact: '139-0014-9000', amount: 85000, status: '跟进中' },\n { id: 'C20240115003', name: '王五', company: '阿里巴巴', contact: '137-0015-7000', amount: 120000, status: '已签约' },\n { id: 'C20240115004', name: '赵六', company: '字节跳动', contact: '136-0016-6000', amount: 65000, status: '待跟进' },\n { id: 'C20240115005', name: '钱七', company: '百度在线', contact: '135-0017-5000', amount: 95000, status: '已签约' }\n];\n\nconst columns = [\n { name: 'id', title: '客户编号' },\n { name: 'name', title: '联系人' },\n { name: 'company', title: '所属公司' },\n { name: 'contact', title: '联系电话' },\n { name: 'amount', title: '签约金额(元)' },\n { name: 'status', title: '状态' }\n];\n\nconst BaseExample = () => {\n const [selectionType, setSelectionType] = useState('none');\n const [selectedRowKeys, setSelectedRowKeys] = useState([]);\n\n // 复选框选择示例\n const CheckboxExample = () => {\n const [keys, setKeys] = useState([]);\n const totalAmount = keys.reduce((sum, id) => sum + (dataSource.find(d => d.id === id)?.amount || 0), 0);\n return (\n <div>\n <Flex justify=\"space-between\" align=\"center\" style={{ marginBottom: 12 }}>\n <span>已选 <strong style={{ color: '#1890ff' }}>{keys.length}</strong> 位客户,总金额 <strong style={{ color: '#52c41a' }}>¥{totalAmount.toLocaleString()}</strong></span>\n <Space>\n <Button size=\"small\" onClick={() => setKeys(dataSource.filter(d => d.status === '已签约').map(d => d.id))}>\n 选已签约\n </Button>\n <Button size=\"small\" onClick={() => setKeys([])}>清空</Button>\n </Space>\n </Flex>\n <TableView\n dataSource={dataSource}\n columns={columns}\n rowSelection={{\n type: 'checkbox',\n selectedRowKeys: keys,\n onChange: setKeys\n }}\n />\n </div>\n );\n };\n\n // 全选状态示例\n const SelectAllExample = () => {\n const [keys, setKeys] = useState([]);\n const [isSelectedAll, setIsSelectedAll] = useState(false);\n\n const handleSelectAll = () => {\n if (isSelectedAll) {\n setKeys([]);\n } else {\n setKeys(dataSource.map(d => d.id));\n }\n setIsSelectedAll(!isSelectedAll);\n };\n\n return (\n <div>\n <Flex justify=\"space-between\" align=\"center\" style={{ marginBottom: 12 }}>\n <span>{isSelectedAll ? <Tag color=\"green\">已全选所有客户</Tag> : <Tag>未全选</Tag>}</span>\n <Button size=\"small\" onClick={handleSelectAll}>\n {isSelectedAll ? '取消全选' : '全选客户'}\n </Button>\n </Flex>\n <TableView\n dataSource={dataSource}\n columns={columns}\n rowSelection={{\n type: 'checkbox',\n isSelectedAll,\n allowSelectedAll: true,\n selectedRowKeys: keys,\n onChange: (keys) => {\n setKeys(keys);\n setIsSelectedAll(keys.length === dataSource.length);\n }\n }}\n />\n </div>\n );\n };\n\n // 单选框示例\n const RadioExample = () => {\n const [key, setKey] = useState(null);\n const selectedCustomer = dataSource.find(d => d.id === key);\n return (\n <div>\n <Flex justify=\"space-between\" align=\"center\" style={{ marginBottom: 12 }}>\n <span>已选客户:{selectedCustomer ? \\`\\${selectedCustomer.name} (\\${selectedCustomer.company})\\` : '无'}</span>\n <Tag color={selectedCustomer ? 'blue' : 'default'}>{selectedCustomer ? \\`¥\\${selectedCustomer.amount.toLocaleString()}\\` : '-'}</Tag>\n </Flex>\n <TableView\n dataSource={dataSource}\n columns={columns}\n rowSelection={{\n type: 'radio',\n selectedRowKeys: key ? [key] : [],\n onChange: (keys) => setKey(keys.length > 0 ? keys[0] : null)\n }}\n />\n </div>\n );\n };\n\n // 无选择模式\n const NoSelectionExample = () => (\n <div>\n <div style={{ marginBottom: 12 }}>客户列表 - 共 {dataSource.length} 位</div>\n <TableView dataSource={dataSource} columns={columns} />\n </div>\n );\n\n // 自定义渲染示例\n const CustomRenderExample = () => {\n const [keys, setKeys] = useState([]);\n return (\n <div>\n <div style={{ marginBottom: 12 }}>自定义渲染客户列表</div>\n <TableView\n dataSource={dataSource}\n columns={[\n { name: 'id', title: '客户编号' },\n { name: 'name', title: '联系人', render: (value) => <Flex align=\"center\" gap={8}><Avatar size=\"small\">{value[0]}</Avatar>{value}</Flex> },\n { name: 'company', title: '所属公司' },\n { name: 'contact', title: '联系电话' },\n { name: 'amount', title: '签约金额', render: (value) => <strong style={{ color: '#52c41a' }}>¥{value.toLocaleString()}</strong> },\n { name: 'status', title: '状态', render: (value) => {\n const config = {\n '已签约': { color: 'success', text: '已签约' },\n '跟进中': { color: 'processing', text: '跟进中' },\n '待跟进': { color: 'warning', text: '待跟进' }\n };\n const { color, text } = config[value] || { color: 'default', text: value };\n return <Tag color={color}>{text}</Tag>;\n }}\n ]}\n rowSelection={{\n type: 'checkbox',\n selectedRowKeys: keys,\n onChange: setKeys\n }}\n />\n </div>\n );\n };\n\n const renderExample = () => {\n switch (selectionType) {\n case 'checkbox':\n return <CheckboxExample />;\n case 'selectAll':\n return <SelectAllExample />;\n case 'radio':\n return <RadioExample />;\n case 'custom':\n return <CustomRenderExample />;\n default:\n return <NoSelectionExample />;\n }\n };\n\n return (\n <Flex vertical gap={16}>\n {/* 控制面板 */}\n <div style={{ background: '#f5f5f5', padding: '16px', borderRadius: '8px' }}>\n <span style={{ marginRight: 12 }}>选择模式:</span>\n <Radio.Group value={selectionType} onChange={(e) => setSelectionType(e.target.value)}>\n <Radio.Button value=\"none\">无选择</Radio.Button>\n <Radio.Button value=\"checkbox\">复选框</Radio.Button>\n <Radio.Button value=\"selectAll\">全选状态</Radio.Button>\n <Radio.Button value=\"radio\">单选框</Radio.Button>\n <Radio.Button value=\"custom\">自定义渲染</Radio.Button>\n </Radio.Group>\n </div>\n\n {/* 示例展示区 */}\n {renderExample()}\n </Flex>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_InfoPage\",\n packageName: \"@kne/info-page\",\n component: component_66\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_68\n}]\n},{\n title: `分割线展示`,\n description: `支持图标和垂直/横向布局的紧凑信息展示`,\n code: `const { SplitLine } = _InfoPage;\nconst { Flex, Tag, Avatar } = antd;\nconst { MobileOutlined, CompassOutlined, MailOutlined, TeamOutlined, CalendarOutlined, EnvironmentOutlined } = antdIcons;\n\nconst BaseExample = () => {\n return (\n <Flex vertical gap={20}>\n {/* 个人信息展示 - 水平布局 */}\n <div>\n <h4 style={{ marginBottom: 12, color: '#333' }}>员工卡片</h4>\n <SplitLine wrap\n dataSource={{\n name: '张三',\n position: '高级前端工程师',\n department: '技术研发部',\n phone: '138-0013-8000',\n email: 'zhangsan@tencent.com',\n workYears: 4,\n entryDate: '2020-03-15',\n status: '在职'\n }}\n columns={[\n {\n name: 'name',\n title: '姓名',\n render: (value) => (\n <Flex align=\"center\" gap={8}>\n <Avatar style={{ backgroundColor: '#1890ff' }}>{value[0]}</Avatar>\n <strong>{value}</strong>\n </Flex>\n )\n },\n {\n name: 'position',\n title: '职位',\n render: (value) => <Tag color=\"blue\">{value}</Tag>\n },\n {\n name: 'department',\n title: '部门',\n render: (value) => <Tag color=\"cyan\">{value}</Tag>\n },\n {\n name: 'phone',\n title: '联系电话',\n icon: <MobileOutlined />,\n render: (value) => value.replace(/(\\d{3})(\\d{4})(\\d{4})/, '\\$1-\\$2-\\$3')\n },\n {\n name: 'email',\n title: '电子邮箱',\n icon: <MailOutlined />\n },\n {\n name: 'workYears',\n title: '工作年限',\n icon: <CalendarOutlined />,\n render: (value) => \\`\\${value}年\\`\n },\n {\n name: 'entryDate',\n title: '入职日期',\n icon: <CalendarOutlined />,\n render: (value) => value\n },\n {\n name: 'status',\n title: '状态',\n render: (value) => <Tag color=\"success\">{value}</Tag>\n }\n ]}\n />\n </div>\n\n {/* 公司信息展示 - 垂直布局 */}\n <div>\n <h4 style={{ marginBottom: 12, color: '#333' }}>公司信息</h4>\n <SplitLine wrap\n labelMode=\"vertical\"\n dataSource={{\n companyName: '深圳市腾讯计算机系统有限公司',\n creditCode: '914403007109410773',\n legalPerson: '马化腾',\n registerDate: '1998-11-11',\n capital: '500万美元',\n address: '深圳市南山区高新科技园科技中一路腾讯大厦',\n businessScope: '计算机软硬件的技术开发、销售;计算机网络工程;系统集成;软件开发及技术服务;信息咨询;网络设备、通讯设备、电子产品的技术开发与销售;国内贸易。'\n }}\n columns={[\n {\n name: 'companyName',\n title: '企业名称'\n },\n {\n name: 'creditCode',\n title: '统一社会信用代码',\n icon: <TeamOutlined />\n },\n {\n name: 'legalPerson',\n title: '法定代表人'\n },\n {\n name: 'registerDate',\n title: '成立日期',\n icon: <CalendarOutlined />\n },\n {\n name: 'capital',\n title: '注册资本'\n },\n {\n name: 'address',\n title: '注册地址',\n icon: <EnvironmentOutlined />\n },\n {\n name: 'businessScope',\n title: '经营范围'\n }\n ]}\n />\n </div>\n\n {/* 项目信息展示 */}\n <div>\n <h4 style={{ marginBottom: 12, color: '#333' }}>项目详情</h4>\n <SplitLine wrap\n dataSource={{\n projectName: '企业级管理系统重构',\n projectCode: 'PRJ-2024-001',\n manager: '张三',\n teamSize: 12,\n startDate: '2024-01-01',\n endDate: '2024-06-30',\n progress: 35,\n budget: 1500000,\n spent: 525000\n }}\n columns={[\n {\n name: 'projectName',\n title: '项目名称'\n },\n {\n name: 'projectCode',\n title: '项目编号'\n },\n {\n name: 'manager',\n title: '项目经理',\n icon: <TeamOutlined />\n },\n {\n name: 'teamSize',\n title: '团队规模',\n render: (value) => \\`\\${value}人\\`\n },\n {\n name: 'startDate',\n title: '开始日期',\n icon: <CalendarOutlined />\n },\n {\n name: 'endDate',\n title: '结束日期',\n icon: <CalendarOutlined />\n },\n {\n name: 'progress',\n title: '项目进度',\n render: (value) => <Tag color={value >= 100 ? 'success' : 'processing'}>{value}%</Tag>\n },\n {\n name: 'budget',\n title: '项目预算',\n render: (value) => \\`¥\\${value.toLocaleString()}\\`\n },\n {\n name: 'spent',\n title: '已投入',\n render: (value) => \\`¥\\${value.toLocaleString()}\\`\n }\n ]}\n />\n </div>\n </Flex>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_InfoPage\",\n packageName: \"@kne/info-page\",\n component: component_66\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_68\n},{\n name: \"remoteLoader\",\n packageName: \"@kne/remote-loader\",\n component: component_77\n},{\n name: \"antdIcons\",\n packageName: \"@ant-design/icons\",\n component: component_78\n}]\n},{\n title: `流程步骤`,\n description: `支持自定义渲染和多种状态的流程时序展示组件`,\n code: `const { Flex, Space, Divider, Tag } = antd;\nconst { Flow } = _InfoPage;\n\nconst BaseExample = () => {\n return (\n <Space direction=\"vertical\" size={24} style={{ width: '100%' }}>\n {/* 基础流程示例 */}\n <div>\n <Divider orientation=\"left\">请假审批流程</Divider>\n <Flow\n current={1}\n dataSource={[\n { title: '提交申请', description: '2024-01-15 09:00 张三提交请假申请', status: 'finish' },\n { title: '部门审批', description: '等待李经理审批', status: 'process' },\n { title: '人事审核', description: '待人事部审核', status: 'wait' },\n { title: '流程结束', description: '审批流程完成', status: 'wait' }\n ]}\n />\n </div>\n\n {/* 带副标题的流程 */}\n <div>\n <Divider orientation=\"left\">订单处理流程</Divider>\n <Flow\n current={2}\n dataSource={[\n { title: '创建订单', subTitle: '2024-01-15 09:30', status: 'finish' },\n { title: '支付成功', subTitle: '2024-01-15 10:15', status: 'finish' },\n { title: '仓库发货', subTitle: '2024-01-15 14:00', status: 'finish' },\n { title: '配送中', subTitle: '2024-01-16 08:30', status: 'process' },\n { title: '已签收', subTitle: '待确认', status: 'wait' }\n ]}\n />\n </div>\n\n {/* 使用 columns 自定义渲染 */}\n <div>\n <Divider orientation=\"left\">项目审批流程</Divider>\n <Flow\n dataSource={[\n {\n title: '需求评审',\n description: '通过',\n operator: '张产品',\n time: '2024-01-15 09:00',\n logs: [\n { name: '张产品', action: '提交需求文档', time: '2024-01-15 09:00', content: '包含功能列表、技术方案、时间计划' },\n { name: '李技术', action: '技术评审通过', time: '2024-01-15 11:00', content: '技术方案可行,资源充足' }\n ]\n },\n {\n title: '开发实施',\n description: '进行中',\n operator: '王开发',\n time: '2024-01-16 09:00',\n logs: [\n { name: '王开发', action: '开始开发', time: '2024-01-16 09:00', content: '前端和后端并行开发' }\n ]\n },\n {\n title: '测试验收',\n description: '待处理',\n operator: '赵测试',\n time: '2024-01-20 00:00',\n logs: []\n }\n ]}\n columns={[\n { name: 'title' },\n { name: 'description', render: (value) => <Tag color={value === '通过' ? 'success' : value === '进行中' ? 'processing' : 'default'}>{value}</Tag> },\n { type: 'subTitle', name: 'time', format: 'datetime' },\n {\n type: 'actionList',\n name: 'logs',\n children: [\n { name: 'name' },\n { name: 'action' },\n { type: 'options', name: 'time', format: 'datetime' },\n { name: 'content' }\n ]\n }\n ]}\n />\n </div>\n\n {/* 点状步骤条 */}\n <div>\n <Divider orientation=\"left\">项目里程碑</Divider>\n <Flex gap={16}>\n <div style={{ flex: 1 }}>\n <p style={{ marginBottom: 8, color: '#666' }}>垂直时间轴</p>\n <Flow\n direction=\"vertical\"\n progressDot\n dataSource={[\n { title: '项目启动', description: '2024-01-01', status: 'finish' },\n { title: '需求分析', description: '2024-01-15', status: 'finish' },\n { title: '系统设计', description: '2024-02-01', status: 'process' },\n { title: '开发实施', description: '2024-03-01', status: 'wait' },\n { title: '测试上线', description: '2024-04-01', status: 'wait' }\n ]}\n />\n </div>\n <div style={{ flex: 1 }}>\n <p style={{ marginBottom: 8, color: '#666' }}>水平进度条</p>\n <Flow\n direction=\"horizontal\"\n progressDot\n dataSource={[\n { title: '注册', description: '完成', status: 'finish' },\n { title: '验证', description: '完成', status: 'finish' },\n { title: '审核', description: '进行中', status: 'process' },\n { title: '通过', description: '待办', status: 'wait' }\n ]}\n />\n </div>\n </Flex>\n </div>\n\n {/* 使用 content 类型自定义内容 */}\n <div>\n <Divider orientation=\"left\">合同审批流程</Divider>\n <Flow\n dataSource={[\n {\n title: '草拟阶段',\n description: '法务部',\n content: '合同条款已草拟完成,包含保密协议、付款条款、违约责任等内容。',\n status: 'finish'\n },\n {\n title: '业务审核',\n description: '业务部门',\n content: '业务部门已确认合同内容,符合业务需求。',\n status: 'finish'\n },\n {\n title: '财务审核',\n description: '财务部',\n content: '财务部正在审核付款条款和预算安排,预计2个工作日完成。',\n status: 'process'\n },\n {\n title: '最终签署',\n description: '等待',\n content: '',\n status: 'wait'\n }\n ]}\n columns={[\n {\n type: 'content',\n name: 'content',\n render: (item) => (\n <div style={{ background: '#f9f9f9', padding: '12px', borderRadius: '4px', fontSize: '13px', lineHeight: '1.6' }}>\n {item}\n </div>\n )\n }\n ]}\n />\n </div>\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_InfoPage\",\n packageName: \"@kne/info-page\",\n component: component_66\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_68\n}]\n},{\n title: `报告页面`,\n description: `完整的测评报告生成组件,支持评分、表格和详细描述`,\n code: `const { Report } = _InfoPage;\nconst { Space } = antd;\nconst BaseExample = () => {\n return (\n <div className=\"outer\">\n <Space direction=\"vertical\" size={24}>\n <Report title=\"报告概述\">\n <Report.List\n report={{\n list: [\n {\n label: '目的',\n content: '本报告旨在评估招聘顾问使用AI工具进行候选人初次沟通的能力,特别是在理解候选人需求、传达职位信息以及建立初步信任关系的效果。'\n },\n {\n label: '测评对象',\n content: '姓名:张伟'\n },\n {\n label: '测评工具',\n content: \\`AI模拟系统:提供基于语音和文本的交互模拟环境。\\n评分标准:沟通技巧、信息传达清晰度、候选人反馈、建立关系的能力。\\`\n },\n {\n label: '任务目标',\n content: (\n <ul>\n <li>完整呈现初次沟通话术,展现每个关键动作和沟通顺序。</li>\n <li>收集候选人信息:了解候选人工作背景,技术能力及其薪资要求。</li>\n <li>挖掘需求:全面了解候选人求职动态和需求,从而掌握候选人存在的顾虑及。</li>\n <li>有效推荐:根据候选人求职需求链接职位优势,强化技术吸引点,妥善处理候选人疑虑。</li>\n <li>建立信任关系:使用沟通技巧,态度诚恳,和候选人站在一起,而非“博弈”关系。</li>\n </ul>\n )\n }\n ]\n }}\n />\n </Report>\n <Report title=\"测评结果\">\n <Report.Result\n report={{\n total: {\n score: '81.8',\n label: '综合得分'\n },\n list: [\n {\n label: '沟通程序指引及话术',\n score: '86',\n content:\n '张伟在这一部分的表现总体上是专业且有条理的,能够按照一定的流程顺利开展对话。他表现出的礼貌和专业性在询问是否方便通话时得到了完美的体现,得到了满分。然而,他在介绍职位时未能充分利用机会强调职位的吸引点,可能影响候选人的兴趣。'\n },\n {\n label: '收集信息(现状\\$&\\$期望)',\n score: '90',\n content: '张伟在收集候选人的现状和期望方面做得相对完善,能够获得关于候选人当前工作和技术栈的重要信息。但对于候选人的项目经验和薪资结构的探讨不够深入,这可能会影响到后续的职位匹配和期望管理。'\n },\n {\n label: '挖掘需求',\n score: '70',\n content: '张伟在挖掘候选人需求方面还有提升空间。虽然基本了解了候选人的职业期望,但在探索候选人的非薪酬动机和深层次需求方面表现不够充分,这是建立有效推荐和深度关系的关键。'\n },\n {\n label: '有效推荐',\n score: '73',\n content: '在有效推荐职位方面,张伟需要加强与候选人需求的匹配度和说服力。虽然提到了职位的技术优势,但未根据候选人的具体技术背景进行个性化强调,可能减少候选人的兴趣。'\n },\n {\n label: '建立信任关系',\n score: '84',\n content: '张伟能够通过有效的沟通建立信任关系,使用开放性问题和积极肯定候选人的表现。然而,需要提高在换位思考和理解候选人深层需求方面的能力,确保信任关系的深度和真实性。'\n }\n ]\n }}\n />\n </Report>\n <Report title=\"评分细节\">\n <Report.Table\n report={{\n columns: [\n {\n title: '评估维度',\n name: 'group',\n isSubTitle: true\n },\n {\n title: '评分项',\n name: 'item',\n span: 10\n },\n {\n title: '得分',\n name: 'score',\n span: 4,\n valueOf: value => <div className=\"score\">{value}</div>\n },\n {\n title: '描述',\n name: 'description',\n span: 10\n }\n ],\n group: [\n {\n name: 'group1',\n label: '沟通程序指引及话术'\n },\n {\n name: 'group2',\n label: '收集信息(现状&期望)'\n },\n {\n name: 'group3',\n label: '挖掘需求'\n },\n {\n name: 'group4',\n label: '有效推荐'\n },\n {\n name: 'group5',\n label: '建立信任关系'\n }\n ],\n list: [\n {\n group: 'group1',\n item: '专业开场',\n score: <Report.Score value={4}/>,\n description: '开场专业,语气友好,略显急促。'\n },\n {\n group: 'group1',\n item: '询问是否方便通话',\n score: <Report.Score value={5}/>,\n description: '表现出极好的礼貌和考虑。'\n },\n {\n group: 'group1',\n item: '先了解候选人整体情况',\n score: <Report.Score value={3}/>,\n description: '详细询问了技术和动机,未深入个人发展。'\n },\n {\n group: 'group1',\n item: '后介绍推荐OD职位',\n score: <Report.Score value={4}/>,\n description: '介绍清晰,未充分突出职位吸引力。'\n },\n {\n group: 'group1',\n item: '介绍整体面试流程',\n score: <Report.Score value={1}/>,\n description: '详尽介绍流程,缺少机考准备细节说明。'\n },\n {\n group: 'group1',\n item: '交换联系方式',\n score: <Report.Score value={5}/>,\n description: '有效且自然,确保双方畅通无阻。'\n },\n {\n group: 'group2',\n item: '了解候选人目前就业状态',\n score: <Report.Score value={5}/>,\n description: '详尽了解候选人的当前就业状况。'\n },\n {\n group: 'group2',\n item: '了解候选人技术栈及项目经验',\n score: <Report.Score value={4}/>,\n description: '详细询问技术栈,对项目经验探讨不足。'\n },\n {\n group: 'group2',\n item: '了解候选人薪资情况与结构',\n score: <Report.Score value={4}/>,\n description: '了解薪资期望清晰,未详细探讨薪资构成。'\n },\n {\n group: 'group3',\n item: '了解候选人对下一份工作的期望',\n score: <Report.Score value={3}/>,\n description: '探讨了职业规划,但未深挖发展意愿。'\n },\n {\n group: 'group3',\n item: '探索非薪资求职动机',\n score: <Report.Score value={2}/>,\n description: '基本了解求职动机,缺乏深度和细节。'\n },\n {\n group: 'group3',\n item: '识别并处理顾虑',\n score: <Report.Score value={4}/>,\n description: '识别了顾虑,回应稍显模糊。'\n },\n {\n group: 'group4',\n item: '链接职位优势与求职动机',\n score: <Report.Score value={3}/>,\n description: '提及职位相关性,缺乏说服力。'\n },\n {\n group: 'group4',\n item: '强化项目技术吸引点',\n score: <Report.Score value={3}/>,\n description: '提及技术优势,未针对候选人背景定制。'\n },\n {\n group: 'group4',\n item: '关注并处理候选人顾虑',\n score: <Report.Score value={4}/>,\n description: '正面回应顾虑,但解决方案不具体。'\n },\n {\n group: 'group5',\n item: '应用开放性提问',\n score: <Report.Score value={0}/>,\n description: '使用开放性问题促进了对话深入。'\n },\n {\n group: 'group5',\n item: '换位思考与表达同理心',\n score: <Report.Score value={1}/>,\n description: '表达了同理心,但部分回答未完全站在候选人角度。'\n },\n {\n group: 'group5',\n item: '表达肯定和欣赏',\n score: <Report.Score value={5}/>,\n description: '非常好地肯定了候选人的能力和经验。'\n },\n {\n group: 'group5',\n item: '清晰表达观点',\n score: <Report.Score value={2}/>,\n description: '观点主要清晰,偶有不够准确的情况。'\n },\n {\n group: 'group5',\n item: '有效倾听与理解',\n score: <Report.Score value={3}/>,\n description: '倾听良好,但有时未能完全抓住候选人的意图。'\n }\n ]\n }}\n />\n </Report>\n <Report title=\"结论与建议\">\n <Report.Part\n report={{\n list: [\n {\n label: '结论',\n hasBgColor: true,\n content:\n '在此次AI情景模拟测评中,李四表现出了较强的沟通能力和专业性,尤其是在程序指引及话术方面。他成功地收集了候选人的基本信息并建立了初步的信任关系。然而,他在深入挖掘候选人需求和个性化推荐职位方面的表现还有待提高。总体而言,李四的表现良好,显示出了他作为招聘顾问的潜力。'\n },\n {\n label: '建议',\n style: { '--marker-color': '#027A48', '--label-bg-color': '#027A481a' },\n content: (\n <ol>\n <li>增强职位介绍的吸引力,特别是将职位优势与候选人的需求直接关联,突出表现职位的独特之处。</li>\n <li>对候选人的项目经验进行更详细的询问,尤其是关于如何在项目中解决问题和技术应用的具体情况。</li>\n <li>在讨论薪资时,应详细了解候选人的薪资构成和期望,确保提供的职位与候选人的薪资期望相匹配。</li>\n <li>在交流中穿插探讨候选人的个人兴趣和长期职业目标,以便更好地理解其动机。</li>\n <li>根据候选人的技术能力和职业兴趣定制职位推荐,突出职位的技术挑战和成长机会。</li>\n <li>加强同理心的表达,尤其在讨论候选人关切的问题时,从其角度出发提供解决方案。</li>\n </ol>\n )\n }\n ]\n }}\n />\n </Report>\n <Report title=\"结论与建议\">自定义 area</Report>\n </Space>\n </div>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_InfoPage\",\n packageName: \"@kne/info-page\",\n component: component_66\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_68\n}]\n},{\n title: `报告组件`,\n description: `展示Report的各子组件:List、Result、Table、Part`,\n code: `const { Report, Score } = _InfoPage;\nconst { Flex, Radio, Space } = antd;\nconst { useState } = React;\n\nconst reportData = {\n total: {\n score: '88.5',\n label: '综合评分'\n },\n list: [\n {\n label: '代码质量',\n score: '95',\n content: '代码风格规范,注释清晰完整,遵循ESLint和Prettier规范。组件拆分合理,复用性强,单元测试覆盖率达到85%。代码审查中提出的修改意见响应及时,整改完成率高。'\n },\n {\n label: '技术深度',\n score: '90',\n content: '深入理解React源码原理,熟悉Hooks工作机制和性能优化技巧。对前端工程化、微前端架构有实践经验。在项目中成功实现SSR方案,提升首屏渲染速度60%。'\n },\n {\n label: '团队协作',\n score: '85',\n content: '积极参与代码评审和技术讨论,乐于分享技术心得。与产品、设计、测试团队沟通顺畅,能够准确理解需求并给出合理的技术建议。协助新同事快速融入团队。'\n },\n {\n label: '创新意识',\n score: '82',\n content: '主动探索新技术,将AI辅助开发工具引入团队,提升开发效率约20%。提出多个优化方案并被采纳,为业务增长做出了贡献。持续关注行业动态,技术敏感度高。'\n }\n ]\n};\n\nconst tableReportData = {\n columns: [\n { title: '评估维度', name: 'group', isSubTitle: true, span: 24 },\n { title: '评估项', name: 'item', span: 12 },\n { title: '得分', name: 'score', span: 4 },\n { title: '说明', name: 'description', span: 8 }\n ],\n group: [\n { name: 'group1', label: '📌 核心技术能力' },\n { name: 'group2', label: '💼 工作业绩' },\n { name: 'group3', label: '🎯 职业素养' }\n ],\n list: [\n { group: 'group1', item: '前端框架', score: <Score value={5} total={5} />, description: 'React/Vue熟练掌握' },\n { group: 'group1', item: 'TypeScript', score: <Score value={5} total={5} />, description: '类型定义规范完整' },\n { group: 'group1', item: '性能优化', score: <Score value={4} total={5} />, description: 'SSR首屏优化显著' },\n { group: 'group1', item: '工程化', score: <Score value={4} total={5} />, description: 'CI/CD流程完善' },\n { group: 'group2', item: '需求交付', score: <Score value={5} total={5} />, description: '按时交付率98%' },\n { group: 'group2', item: '质量保障', score: <Score value={4} total={5} />, description: '线上故障率低' },\n { group: 'group2', item: '文档输出', score: <Score value={3} total={5} />, description: 'API文档需完善' },\n { group: 'group3', item: '团队协作', score: <Score value={5} total={5} />, description: '沟通顺畅主动' },\n { group: 'group3', item: '学习成长', score: <Score value={4} total={5} />, description: '技术分享积极' },\n { group: 'group3', item: '责任意识', score: <Score value={5} total={5} />, description: '工作认真负责' }\n ],\n footer: (item, index) => (\n <div style={{ padding: '4px 0', color: '#999', fontSize: '12px' }}>\n 第 {index + 1} 项\n </div>\n )\n};\n\nconst listReportData = {\n list: [\n { label: '👤 评估对象', content: '王明远' },\n { label: '🏢 所属部门', content: '技术研发中心 - 前端架构组' },\n { label: '💼 职级职位', content: '资深前端工程师(P6+)' },\n { label: '📅 入职时间', content: '2021年3月15日' },\n { label: '📊 评估周期', content: '2024年度' },\n { label: '🔍 评估日期', content: '2025年1月10日' },\n { label: '👨‍💼 评估人', content: '技术总监 - 陈思远' },\n { label: '📋 评估维度', content: '核心技能、项目绩效、职业素养' },\n { label: '🔧 评估方法', content: '代码审查 + 绩效数据 + 360度评估 + 技术面试' }\n ]\n};\n\nconst partReportData = {\n list: [\n {\n label: '✨ 核心优势',\n hasBgColor: true,\n content: '1. 技术视野开阔,对前端技术栈有系统性理解,能够从架构层面思考问题。2. 学习能力强,快速掌握新技术并转化为生产力,AI工具应用效果显著。3. 代码质量意识强,注重可维护性和扩展性,推动团队代码规范落地。4. 工作积极主动,主动承担复杂任务,多次解决关键技术难题。'\n },\n {\n label: '📈 成长空间',\n content: '1. 在技术管理和团队带领方面需要更多历练。2. 跨部门协作时的商业思维有待提升,需要更好地理解业务价值。3. 技术成果的可视化展示和影响力打造可以进一步加强。'\n },\n {\n label: '🎯 发展建议',\n content: '1. 争取担任小型项目的Tech Lead,积累团队管理经验。2. 加强对后端、运维相关技术的学习,建立全栈技术视角。3. 每季度组织至少一次技术分享,提升团队技术氛围。4. 参与技术面试和人才评估,锻炼识人用人能力。5. 关注行业前沿趋势,定期输出技术文章或开源贡献。'\n },\n {\n label: '📚 培养计划',\n content: '1. Q2参加技术管理进阶培训。2. Q3参与微服务架构专项学习。3. Q4承担新人导师角色。4. 全年参与至少3个技术峰会或工作坊。5. 建立个人技术博客,每月至少输出1篇技术文章。'\n }\n ]\n};\n\nconst BaseExample = () => {\n const [componentType, setComponentType] = useState('list');\n\n const renderComponent = () => {\n switch (componentType) {\n case 'list':\n return <Report.List report={listReportData} />;\n case 'result':\n return <Report.Result report={reportData} />;\n case 'table':\n return <Report.Table report={tableReportData} />;\n case 'part':\n return <Report.Part report={partReportData} />;\n default:\n return <Report.List report={listReportData} />;\n }\n };\n\n return (\n <Flex vertical gap={16}>\n {/* 控制面板 */}\n <div style={{ background: '#f5f5f5', padding: '16px', borderRadius: '8px' }}>\n <span style={{ marginRight: 12 }}>子组件类型:</span>\n <Radio.Group value={componentType} onChange={(e) => setComponentType(e.target.value)}>\n <Radio.Button value=\"list\">Report.List</Radio.Button>\n <Radio.Button value=\"result\">Report.Result</Radio.Button>\n <Radio.Button value=\"table\">Report.Table</Radio.Button>\n <Radio.Button value=\"part\">Report.Part</Radio.Button>\n </Radio.Group>\n </div>\n\n {/* 组件展示区 */}\n <Space direction=\"vertical\" size={24}>\n <Report title=\"📄 员工年度绩效评估报告\" subtitle=\"2024年度 | 技术研发中心 | 前端架构组\">\n {renderComponent()}\n </Report>\n </Space>\n </Flex>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_InfoPage\",\n packageName: \"@kne/info-page\",\n component: component_66\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_68\n}]\n},{\n title: `评分展示`,\n description: `支持自定义总分和间距的星级评分组件`,\n code: `const { Score } = _InfoPage;\nconst { Flex, Badge, Card, Divider, Tag, Space } = antd;\n\nconst BaseExample = () => {\n return (\n <Flex vertical gap={16}>\n {/* 基础用法 */}\n <Card title=\"基础评分\" size=\"small\">\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Flex gap={24} align=\"center\">\n <span>产品评分:</span>\n <Score value={5} />\n </Flex>\n <Flex gap={24} align=\"center\">\n <span>服务质量:</span>\n <Score value={4} />\n </Flex>\n <Flex gap={24} align=\"center\">\n <span>物流速度:</span>\n <Score value={3} />\n </Flex>\n <Flex gap={24} align=\"center\">\n <span>性价比:</span>\n <Score value={2} />\n </Flex>\n <Flex gap={24} align=\"center\">\n <span>用户满意:</span>\n <Score value={1} />\n </Flex>\n </Space>\n </Card>\n\n <Divider />\n\n {/* 自定义总分 */}\n <Card title=\"自定义总分\" size=\"small\">\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <Flex gap={24} align=\"center\">\n <span>3分制:</span>\n <Score value={0} total={3} />\n <Score value={1} total={3} />\n <Score value={2} total={3} />\n <Score value={3} total={3} />\n </Flex>\n <Flex gap={24} align=\"center\">\n <span>4分制:</span>\n <Score value={1} total={4} />\n <Score value={2} total={4} />\n <Score value={3} total={4} />\n <Score value={4} total={4} />\n </Flex>\n <Flex gap={24} align=\"center\">\n <span>5分制:</span>\n <Score value={2} total={5} />\n <Score value={3} total={5} />\n <Score value={4} total={5} />\n <Score value={5} total={5} />\n </Flex>\n </Space>\n </Card>\n\n <Divider />\n\n {/* 无间距 */}\n <Card title=\"紧凑模式(gap=0)\" size=\"small\">\n <Flex gap={24} align=\"center\">\n <Score value={1} total={5} gap={0} />\n <Score value={2} total={5} gap={0} />\n <Score value={3} total={5} gap={0} />\n <Score value={4} total={5} gap={0} />\n <Score value={5} total={5} gap={0} />\n </Flex>\n </Card>\n\n <Divider />\n\n {/* 业务场景 */}\n <Card title=\"业务场景示例\" size=\"small\">\n <Space direction=\"vertical\" style={{ width: '100%' }}>\n <div style={{ padding: '8px 0' }}>\n <Flex justify=\"space-between\" align=\"center\" style={{ marginBottom: 8 }}>\n <span>商品名称</span>\n <Tag color=\"blue\">新品上市</Tag>\n </Flex>\n <Flex justify=\"space-between\" align=\"center\" style={{ marginBottom: 4 }}>\n <span style={{ color: '#999', fontSize: 12 }}>用户评价</span>\n <Badge count={128} showZero />\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span style={{ fontSize: 14, fontWeight: 500 }}>Apple iPhone 15 Pro</span>\n <Score value={5} />\n </Flex>\n </div>\n\n <div style={{ padding: '8px 0', borderTop: '1px solid #f0f0f0' }}>\n <Flex justify=\"space-between\" align=\"center\" style={{ marginBottom: 4 }}>\n <span style={{ color: '#999', fontSize: 12 }}>商品评分</span>\n <span style={{ fontSize: 12, color: '#ff4d4f' }}>4.8/5.0</span>\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span style={{ fontSize: 14 }}>综合得分</span>\n <Score value={4} total={5} />\n </Flex>\n </div>\n </Space>\n </Card>\n\n <Divider />\n\n {/* 所有评分展示 */}\n <Card title=\"完整评分展示\" size=\"small\">\n <Flex wrap=\"wrap\" gap={16}>\n {Array.from({ length: 6 }).map((_, index) => (\n <Flex key={index} vertical align=\"center\" gap={4}>\n <Score value={index} />\n <span style={{ fontSize: 12, color: '#999' }}>{index}分</span>\n </Flex>\n ))}\n </Flex>\n </Card>\n </Flex>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_InfoPage\",\n packageName: \"@kne/info-page\",\n component: component_66\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_68\n}]\n},{\n title: `格式化视图`,\n description: `展示formatView工具函数的各种格式化用法`,\n code: `const { formatView } = _InfoPage;\nconst { Flex, Space, Tag, Badge } = antd;\n\n// 演示 formatView 工具函数的使用\nconst FormatDemo = () => {\n const demoData = {\n orderDate: '2024-01-15T10:30:00',\n deliveryDate: '2024-01-20',\n serviceDateRange: ['2024-01-01', '2024-12-31'],\n isVip: true,\n isActivated: false,\n userCount: 15678,\n totalAmount: 99999.99,\n discountRate: 0.085,\n completionRate: 85.67,\n phoneNumber: '13800138000'\n };\n\n // 自定义格式化函数\n const formatPhone = (val) => {\n if (!val) return '-';\n return val.replace(/(\\d{3})(\\d{4})(\\d{4})/, '\\$1-\\$2-\\$3');\n };\n\n return (\n <Flex vertical gap={16}>\n <div style={{ background: '#f5f5f5', padding: '16px', borderRadius: '8px' }}>\n <h4 style={{ margin: '0 0 12px 0' }}>formatView 工具函数演示</h4>\n <Space direction=\"vertical\" size={8} style={{ width: '100%' }}>\n <Flex justify=\"space-between\" align=\"center\">\n <span><strong>datetime:</strong></span>\n <span>{formatView(demoData.orderDate, 'datetime')} → {formatView(demoData.orderDate, 'datetime-YYYY年MM月DD日 HH:mm')}</span>\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span><strong>date:</strong></span>\n <span>{formatView(demoData.deliveryDate, 'date')} → {formatView(demoData.deliveryDate, 'date-YYYY/MM/DD')}</span>\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span><strong>dateRange:</strong></span>\n <span>{formatView(demoData.serviceDateRange, 'dateRange')}</span>\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span><strong>boolean:</strong></span>\n <Flex gap={8}>\n <span>VIP客户: {formatView(demoData.isVip, 'boolean-是/否')}</span>\n <span>已激活: {formatView(demoData.isActivated, 'boolean-是/否')}</span>\n </Flex>\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span><strong>number:</strong></span>\n <span>{formatView(demoData.userCount, 'number-useGrouping:true')} 用户</span>\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span><strong>money:</strong></span>\n <span style={{ color: '#f5222d', fontWeight: 'bold' }}>{formatView(demoData.totalAmount, 'money-元')}</span>\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span><strong>discount:</strong></span>\n <span>折扣: {formatView(demoData.discountRate * 100, 'number-maximumFractionDigits:1-suffix:折')}</span>\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span><strong>percent:</strong></span>\n <span>完成率: {formatView(demoData.completionRate, 'number-maximumFractionDigits:2-suffix:%')}</span>\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span><strong>custom:</strong></span>\n <span>{formatPhone(demoData.phoneNumber)}</span>\n </Flex>\n </Space>\n </div>\n\n {/* 实际应用场景演示 */}\n <div style={{ background: '#fff', padding: '16px', borderRadius: '8px', border: '1px solid #e8e8e8' }}>\n <h4 style={{ margin: '0 0 12px 0' }}>实际应用场景:订单详情</h4>\n <Flex vertical gap={8}>\n <Flex justify=\"space-between\" align=\"center\">\n <span style={{ color: '#666' }}>订单编号</span>\n <span>ORD20240115001</span>\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span style={{ color: '#666' }}>下单时间</span>\n <span>{formatView(demoData.orderDate, 'datetime')}</span>\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span style={{ color: '#666' }}>预计送达</span>\n <span>{formatView(demoData.deliveryDate, 'date-YYYY年MM月DD日')}</span>\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span style={{ color: '#666' }}>服务期限</span>\n <span>{formatView(demoData.serviceDateRange, 'dateRange')}</span>\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span style={{ color: '#666' }}>客户类型</span>\n <Tag color={demoData.isVip ? 'gold' : 'default'}>{formatView(demoData.isVip, 'boolean-VIP/普通')}</Tag>\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span style={{ color: '#666' }}>订单金额</span>\n <span style={{ color: '#f5222d', fontSize: '18px', fontWeight: 'bold' }}>\n {formatView(demoData.totalAmount, 'money-元')}\n </span>\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span style={{ color: '#666' }}>优惠折扣</span>\n <span style={{ color: '#52c41a' }}>{formatView(demoData.discountRate * 100, 'number-maximumFractionDigits:1-suffix:折')}</span>\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span style={{ color: '#666' }}>订单状态</span>\n <Badge status={demoData.completionRate >= 100 ? 'success' : 'processing'} text={demoData.completionRate >= 100 ? '已完成' : '处理中'} />\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span style={{ color: '#666' }}>完成进度</span>\n <span>{formatView(demoData.completionRate, 'number-maximumFractionDigits:2-suffix:%')}</span>\n </Flex>\n <Flex justify=\"space-between\" align=\"center\">\n <span style={{ color: '#666' }}>联系电话</span>\n <span>{formatPhone(demoData.phoneNumber)}</span>\n </Flex>\n </Flex>\n </div>\n </Flex>\n );\n};\n\nconst BaseExample = () => {\n return (\n <Flex vertical gap={24}>\n <FormatDemo />\n </Flex>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_InfoPage\",\n packageName: \"@kne/info-page\",\n component: component_66\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_68\n}]\n}]\n }\n};\nexport default readmeConfig;\n","const message = {\n ButtonText: \"confirm\"\n};\n\nexport default message;","const message = {\n ButtonText: \"确定\"\n};\n\nexport default message;","import * as component_61 from '@components/Intl';\nimport * as component_62 from '@components/Global';\nimport * as component_63 from 'antd';\nimport * as component_64 from '@components/Intl/doc/locale/en-US';\nimport * as component_65 from '@components/Intl/doc/locale/zh-CN';\nconst readmeConfig = {\n name: `Intl`,\n summary: `<p>支持系统国际化</p>`,\n \n \n api: `<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n</table>`,\n example: {\n isFull: false,\n className: ``,\n style: ``,\n list: [{\n title: `这里填写示例标题`,\n description: `这里填写示例说明`,\n code: `const {FormattedMessage, IntlProvider} = _Intl;\nconst {PureGlobal} = global;\nconst {Select, Space} = antd;\nconst {default: en} = localeEN;\nconst {default: cn} = localeCN;\nconst {useState} = React;\nconst BaseExample = () => {\n const [locale, setLocale] = useState('zh-CN');\n return (<Space>\n <Select value={locale} onChange={setLocale}\n options={['zh-CN', 'en-US'].map(key => ({value: key, label: key}))}/>\n <PureGlobal\n preset={{\n locale\n }}\n >\n <IntlProvider locale={locale} importMessages={locale => {\n return {\n default: {\n 'zh-CN': cn, 'en-US': en\n }[locale]\n };\n }}>\n <FormattedMessage defaultMessage=\"按钮\" id=\"ButtonText\">\n {text => <div>{text}</div>}\n </FormattedMessage>\n </IntlProvider>\n\n </PureGlobal>\n </Space>);\n};\n\nrender(<BaseExample/>);\n\n`,\n scope: [{\n name: \"_Intl\",\n packageName: \"@components/Intl\",\n component: component_61\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_62\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_63\n},{\n name: \"localeEN\",\n packageName: \"@components/Intl/doc/locale/en-US\",\n component: component_64\n},{\n name: \"localeCN\",\n packageName: \"@components/Intl/doc/locale/zh-CN\",\n component: component_65\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_84 from '@components/Layout';\nimport * as component_85 from '@components/Global';\nimport * as component_86 from 'antd';\nimport * as component_87 from '@components/Filter';\nconst readmeConfig = {\n name: `Layout`,\n summary: `<h3>何时使用</h3>\n<p>每个登录后的系统页面都应该在Layout的框架之下,它定义了页面的基本框架。根据设计对于页面的不同要求,适当选择不同的组合</p>\n<h3>特点</h3>\n<p>Layout将整个页面划分成以下几个区域</p>\n<ol>\n<li>导航区</li>\n<li>内容区</li>\n<li>左菜单区</li>\n<li>右操作区</li>\n<li>页头区</li>\n<li>页头信息区</li>\n<li>页面标题区</li>\n</ol>\n<p>通过给Page配置不同的参数实现不同区域的显示</p>\n<h3>注意</h3>\n<ul>\n<li>Page的name参数必须要传,用来在页面跳转时确定Page是不是同一个,决定着Page是否走install周期</li>\n<li>Page组件的参数是通过Context保存在Layout中的,这样做的目的是为了让页面跳转时,除页面区以外的区域在前后俩页面差别不大的情况下走更新周期而不是install周期,以此带来更快的渲染速度避免不必要的重复安装和卸载</li>\n<li>请尽量通过Page提供的参数来配置出设计要求的页面,不要自行用css实现,以便于Layout组件能从整体控制页面的基本形式和不同区域的padding和margin,让系统更加统一化标准化</li>\n</ul>`,\n \n \n api: `<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>navigation</td>\n<td>导航参数参考 Navigation 组件参数</td>\n<td>object</td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>一般放置Page组件</td>\n<td>jsx</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>Page</h3>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>menu</td>\n<td>左菜单区内容</td>\n<td>jsx</td>\n<td>-</td>\n</tr>\n<tr>\n<td>filter</td>\n<td>页面标题位置筛选器参数,参考 Filter 组件参数</td>\n<td>object</td>\n<td>-</td>\n</tr>\n<tr>\n<td>menuOpen</td>\n<td>左菜单是否默认打开</td>\n<td>boolean</td>\n<td>true</td>\n</tr>\n<tr>\n<td>menuWidth</td>\n<td>左菜单宽度</td>\n<td>string</td>\n<td>240px</td>\n</tr>\n<tr>\n<td>menuFixed</td>\n<td>左菜单是否fixed布局</td>\n<td>boolean</td>\n<td>true</td>\n</tr>\n<tr>\n<td>menuCloseButton</td>\n<td>控制左菜单显示隐藏的按钮是否显示</td>\n<td>boolean</td>\n<td>true</td>\n</tr>\n<tr>\n<td>header</td>\n<td>页头区内容</td>\n<td>jsx</td>\n<td>-</td>\n</tr>\n<tr>\n<td>headerFixed</td>\n<td>页头区是否fixed布局</td>\n<td>boolean</td>\n<td>true</td>\n</tr>\n<tr>\n<td>headerInfo</td>\n<td>页头信息区内容</td>\n<td>jsx</td>\n<td>-</td>\n</tr>\n<tr>\n<td>backUrl</td>\n<td>右侧内容区的标题前展示返回按钮,并返回到该url</td>\n<td>参考 useNavigate</td>\n<td>-</td>\n</tr>\n<tr>\n<td>title</td>\n<td>页面标题</td>\n<td>string,jsx</td>\n<td>-</td>\n</tr>\n<tr>\n<td>titleExtra</td>\n<td>页面标题区右侧位置内容</td>\n<td>jsx</td>\n<td>-</td>\n</tr>\n<tr>\n<td>titleLeftExtra</td>\n<td>页面标题区左侧位置内容</td>\n<td>jsx</td>\n<td>-</td>\n</tr>\n<tr>\n<td>noMargin</td>\n<td>页面内容区是否去掉Margin</td>\n<td>boolean</td>\n<td>false</td>\n</tr>\n<tr>\n<td>noPadding</td>\n<td>页面内容区是否去掉Padding</td>\n<td>boolean</td>\n<td>false</td>\n</tr>\n<tr>\n<td>option</td>\n<td>右操作区内容</td>\n<td>jsx</td>\n<td>-</td>\n</tr>\n<tr>\n<td>optionWidth</td>\n<td>右操作区宽度</td>\n<td>string</td>\n<td>400px</td>\n</tr>\n<tr>\n<td>optionNoPadding</td>\n<td>右操作区是否去掉Padding</td>\n<td>boolean</td>\n<td>false</td>\n</tr>\n<tr>\n<td>optionFixed</td>\n<td>右操作区是否fixed布局</td>\n<td>boolean</td>\n<td>false</td>\n</tr>\n<tr>\n<td>optionFooter</td>\n<td>右操作区底部内容</td>\n<td>jsx</td>\n<td>-</td>\n</tr>\n<tr>\n<td>openFeatures</td>\n<td>Page是否启用Features,启用时如果配置文件中没有该模块id则判断为模块关闭,会将name作为Features的id进行设置</td>\n<td>boolean</td>\n<td>false</td>\n</tr>\n</tbody>\n</table>\n<h3>Affix</h3>\n<p>可以控制其中的内容是否是fixed布局</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>isFixed</td>\n<td>内容是否fixed布局</td>\n<td>boolean</td>\n<td>true</td>\n</tr>\n<tr>\n<td>offsetTop</td>\n<td>距离窗口顶部达到指定偏移量后触发</td>\n<td>number</td>\n<td>0</td>\n</tr>\n<tr>\n<td>offsetBottom</td>\n<td>距离窗口底部达到指定偏移量后触发</td>\n<td>number</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>固定状态改变时触发的回调函数</td>\n<td>function</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>Menu</h3>\n<p>显示一个菜单,最多支持两级,支持第一级展开收起,支持路径匹配自动高亮</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>items</td>\n<td>菜单项</td>\n<td>array[object]</td>\n<td>[]</td>\n</tr>\n<tr>\n<td>items[].label</td>\n<td>菜单项显示内容</td>\n<td>jsx</td>\n<td>-</td>\n</tr>\n<tr>\n<td>items[].key</td>\n<td>菜单项的key要求必须唯一</td>\n<td>string</td>\n<td>-</td>\n</tr>\n<tr>\n<td>items[].iconType</td>\n<td>菜单项前面的icon类型参考 Icon组件的type参数</td>\n<td>string</td>\n<td>-</td>\n</tr>\n<tr>\n<td>items[].path</td>\n<td>菜单项的路径</td>\n<td>string</td>\n<td>-</td>\n</tr>\n<tr>\n<td>items[].onClick</td>\n<td>菜单项点击触发事件,注意:如果菜单项已经传入path参数则该参数不生效</td>\n<td>function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>items[].children</td>\n<td>菜单项的第二级项列表,参考items参数。注意该组件只支持两级菜单,所以该参数内部的菜单项不再支持children参数</td>\n<td>array[object]</td>\n<td>-</td>\n</tr>\n<tr>\n<td>currentKey</td>\n<td>当前被选中的菜单项的key,如果菜单项又path参数,不需要传递该参数,组件会根据路由自动判断选中项</td>\n<td>string</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>currentKey产生修改时触发函数,注意:如果菜单项已经传入path参数则该参数不生效</td>\n<td>function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>allowCollapsed</td>\n<td>是否允许一级菜单收起</td>\n<td>boolean</td>\n<td>true</td>\n</tr>\n<tr>\n<td>defaultOpenKeys</td>\n<td>初始展开的 SubMenu 菜单项 key 数组</td>\n<td>string[]</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>PermissionsPage</h3>\n<p>加入权限判断的Page,错误类型默认为error,即在该页面没有权限时显示错误</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>permissions</td>\n<td>权限列表参考 Permissions 组件参数</td>\n<td>object</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>`,\n example: {\n isFull: true,\n className: `Layout_ebd9b`,\n style: `.Layout_ebd9b .layout-content {\n color: #fff;\n background: var(--primary-color-4);\n height: 100%;\n text-align: center;\n line-height: 300px;\n}\n.Layout_ebd9b .with-title-layout-content {\n height: 100%;\n}\n.Layout_ebd9b .layout-menu {\n background: #ff9c6e;\n color: #fff;\n height: 110vh;\n text-align: center;\n line-height: 300px;\n}\n.Layout_ebd9b .header {\n background: #ff9c6e;\n height: 100px;\n padding: 10px;\n color: #fff;\n}\n.Layout_ebd9b .right-options {\n background: var(--primary-color-4);\n height: 110vh;\n color: #fff;\n}\n.Layout_ebd9b .header-info {\n padding: 10px;\n height: 100px;\n background: var(--primary-color-4);\n color: #fff;\n}`,\n list: [{\n title: `基础上下布局`,\n description: `展示最基础的上导航栏,下内容的布局`,\n code: `const { default: Layout, Page } = _Layout;\nconst { PureGlobal } = global;\nconst BaseExample = () => {\n return (\n <PureGlobal\n preset={{\n enums: {\n helperGuide: () => [\n {\n value: \"base-detail\",\n content: \"测试帮助文档\",\n url: \"/\",\n },\n ],\n },\n }}\n >\n <Layout navigation={{ isFixed: false }}>\n <Page name=\"base\" helperGuideName=\"base-detail\">\n <div className=\"layout-content\">内容区</div>\n </Page>\n </Layout>\n </PureGlobal>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Layout\",\n packageName: \"@components/Layout\",\n component: component_84\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_85\n}]\n},{\n title: `带有左侧菜单布局`,\n description: `展示带有左侧菜单布局`,\n code: `const { default: Layout, Page, Menu } = layout;\nconst { Button, Space } = antd;\nconst { PureGlobal } = global;\n\nconst Example = () => {\n return (\n <Layout navigation={{ isFixed: false }}>\n <Page\n name=\"left-menu\"\n menuFixed={false}\n menu={\n <Menu\n items={[\n {\n label: \"父级标题1\",\n key: \"p-0\",\n iconType: \"icon-zhanghaodenglu\",\n children: [\n {\n label: \"子标题1\",\n key: \"s-0\",\n path: \"/link1\",\n },\n {\n label: \"子标题2\",\n key: \"s-1\",\n path: \"/link2\",\n },\n ],\n },\n {\n label: \"父级标题2\",\n key: \"p-1\",\n iconType: \"icon-zhanghaodenglu\",\n children: [\n {\n label: \"子标题1\",\n key: \"s-2\",\n path: \"/link3\",\n },\n {\n label: \"子标题2\",\n key: \"s-3\",\n path: \"/link4\",\n },\n ],\n },\n {\n label: \"父级标题3\",\n key: \"p-2\",\n iconType: \"icon-zhanghaodenglu\",\n path: \"/link5\",\n },\n ]}\n />\n }\n titleExtra={\n <Space>\n <Button type=\"primary\">新建</Button>\n </Space>\n }\n backUrl={\"/\"}\n title=\"标题\"\n >\n <div className=\"layout-content with-title-layout-content\">内容区</div>\n </Page>\n </Layout>\n );\n};\n\nrender(\n <PureGlobal>\n <Example />\n </PureGlobal>\n);\n\n`,\n scope: [{\n name: \"layout\",\n packageName: \"@components/Layout\",\n component: component_84\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_86\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_85\n}]\n},{\n title: `左侧固定带Header`,\n description: `展示带有header的左侧固定菜单布局`,\n code: `const { default: Layout, Page } = layout;\nconst { Button, Space } = antd;\nconst { PureGlobal } = global;\n\nconst Example = () => {\n return (\n <Space className=\"container\" direction=\"vertical\">\n <Layout navigation={{ isFixed: false }}>\n <Page\n name=\"with-header\"\n helperGuideName=\"base-detail\"\n menu={<div className=\"layout-menu\">左侧菜单区</div>}\n titleExtra={\n <Space>\n <Button type=\"primary\">新建</Button>\n </Space>\n }\n title=\"标题\"\n hideCloseSvg={true}\n headerHeight=\"40px\"\n menuFixed={false}\n header={<div className=\"header\">header</div>}\n headerFixed={false}\n headerInfo={<div className=\"header-info\">header info区域</div>}\n >\n <div>内容区</div>\n </Page>\n </Layout>\n </Space>\n );\n};\n\nrender(\n <PureGlobal\n preset={{\n enums: {\n helperGuide: () => [\n {\n value: \"base-detail\",\n content: \"测试帮助文档\",\n url: \"/\",\n },\n ],\n },\n }}\n >\n <Example />\n </PureGlobal>\n);\n\n`,\n scope: [{\n name: \"layout\",\n packageName: \"@components/Layout\",\n component: component_84\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_86\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_85\n}]\n},{\n title: `右侧固定`,\n description: `展示带有header的右侧固定菜单布局`,\n code: `const { default: Layout, Page } = layout;\nconst { Button, Space } = antd;\nconst { PureGlobal } = global;\n\nconst Example = () => {\n return (\n <Layout navigation={{ isFixed: false }}>\n <Page\n name=\"fix-right-menu\"\n optionFixed={false}\n option={<div className=\"right-options\">右侧操作区域</div>}\n optionFooter={\n <Space>\n <Button type=\"primary\">新建</Button>\n </Space>\n }\n titleExtra={\n <Space>\n <Button type=\"primary\">新建</Button>\n </Space>\n }\n title=\"标题\"\n header={<div className=\"header\">header</div>}\n headerFixed={false}\n menuFixed={false}\n >\n <div>内容区</div>\n </Page>\n </Layout>\n );\n};\n\nrender(\n <PureGlobal>\n <Example />\n </PureGlobal>\n);\n\n`,\n scope: [{\n name: \"layout\",\n packageName: \"@components/Layout\",\n component: component_84\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_86\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_85\n}]\n},{\n title: `带有filter的列表页`,\n description: `展示带有filter的列表页`,\n code: `const { default: Layout, Page } = layout;\nconst {\n InputFilterItem,\n CityFilterItem,\n AdvancedSelectFilterItem,\n UserFilterItem,\n FunctionSelectFilterItem,\n IndustrySelectFilterItem,\n getFilterValue,\n} = filter;\nconst { useState } = React;\nconst { Space, Button } = antd;\nconst { PureGlobal } = global;\nconst BaseExample = () => {\n const [filter, setFilter] = useState([]);\n return (\n <PureGlobal preset={{}}>\n <Layout navigation={{ isFixed: false }}>\n <Page\n name=\"base\"\n helperGuideName=\"base-detail\"\n titleExtra={\n <Space>\n <Button type=\"primary\">添加</Button>\n </Space>\n }\n filter={{\n extraExpand: (\n <Button type=\"primary\" size=\"small\">\n 订阅筛选项\n </Button>\n ),\n value: filter,\n onChange: (value) => {\n setFilter(value);\n console.log(getFilterValue(value));\n },\n list: [\n [\n <InputFilterItem label=\"文字\" name=\"text\" />,\n <CityFilterItem label=\"城市\" name=\"city\" />,\n <AdvancedSelectFilterItem\n label=\"高级选择\"\n name=\"select\"\n api={{\n loader: () => {\n return {\n pageData: [\n { label: \"第一项\", value: 1 },\n { label: \"第二项\", value: 2, disabled: true },\n {\n label: \"第三项\",\n value: 3,\n },\n ],\n };\n },\n }}\n />,\n <UserFilterItem\n label=\"用户选择\"\n name=\"user\"\n api={{\n loader: () => {\n return {\n pageData: [\n {\n label: \"用户一\",\n value: 1,\n description: \"我是用户描述\",\n },\n {\n label: \"用户二\",\n value: 2,\n description: \"我是用户描述\",\n },\n {\n label: \"用户三\",\n value: 3,\n description: \"我是用户描述\",\n },\n ],\n };\n },\n }}\n />,\n <FunctionSelectFilterItem\n label=\"职能选择\"\n name=\"function\"\n onlyAllowLastLevel\n single\n />,\n <IndustrySelectFilterItem\n label=\"行业选择\"\n name=\"industry\"\n onlyAllowLastLevel\n />,\n ],\n [\n <UserFilterItem\n label=\"职位协助人\"\n name=\"position_user\"\n api={{\n loader: () => {\n return {\n pageData: [\n {\n label: \"用户一\",\n value: 1,\n description: \"我是用户描述\",\n },\n {\n label: \"用户二\",\n value: 2,\n description: \"我是用户描述\",\n },\n {\n label: \"用户三\",\n value: 3,\n description: \"我是用户描述\",\n },\n ],\n };\n },\n }}\n />,\n ],\n ],\n }}\n >\n <div className=\"layout-content\">内容区</div>\n </Page>\n </Layout>\n </PureGlobal>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"layout\",\n packageName: \"@components/Layout\",\n component: component_84\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_86\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_85\n},{\n name: \"filter\",\n packageName: \"@components/Filter\",\n component: component_87\n}]\n},{\n title: `左侧导航菜单`,\n description: `展示一个左侧导航菜单`,\n code: `const { Menu } = layout;\nconst { Space } = antd;\nconst { useState } = React;\n\nconst ControlMenu = () => {\n const [current, setCurrent] = useState();\n return (\n <Menu\n currentKey={current}\n onChange={setCurrent}\n items={[\n {\n label: \"父级标题1\",\n key: \"p-0\",\n iconType: \"icon-zhanghaodenglu\",\n children: [\n {\n label: \"子标题1\",\n key: \"s-0\",\n },\n {\n label: \"子标题2\",\n key: \"s-1\",\n },\n ],\n },\n {\n label: \"父级标题2\",\n key: \"p-1\",\n iconType: \"icon-zhanghaodenglu\",\n children: [\n {\n label: \"子标题1\",\n key: \"s-2\",\n },\n {\n label: \"子标题2\",\n key: \"s-3\",\n },\n ],\n },\n {\n label: \"父级标题3\",\n key: \"p-2\",\n iconType: \"icon-zhanghaodenglu\",\n },\n ]}\n />\n );\n};\n\nconst Example = () => {\n return (\n <Space size={10}>\n <Menu\n items={[\n {\n label: \"父级标题1\",\n key: \"p-0\",\n iconType: \"icon-zhanghaodenglu\",\n children: [\n {\n label: \"子标题1\",\n key: \"s-0\",\n path: \"/link1\",\n },\n {\n label: \"子标题2\",\n key: \"s-1\",\n path: \"/link2\",\n },\n ],\n },\n {\n label: \"父级标题2\",\n key: \"p-1\",\n iconType: \"icon-zhanghaodenglu\",\n children: [\n {\n label: \"子标题1\",\n key: \"s-2\",\n path: \"/link3\",\n },\n {\n label: \"子标题2\",\n key: \"s-3\",\n path: \"/link4\",\n },\n ],\n },\n {\n label: \"父级标题3\",\n key: \"p-2\",\n iconType: \"icon-zhanghaodenglu\",\n path: \"/link5\",\n },\n ]}\n />\n <Menu\n items={[\n {\n iconType: \"icon-zhanghaodenglu\",\n label: \"子标题1\",\n key: \"s-0\",\n path: \"/link1\",\n },\n {\n iconType: \"icon-zhanghaodenglu\",\n label: \"子标题2\",\n key: \"s-1\",\n path: \"/link2\",\n },\n {\n iconType: \"icon-zhanghaodenglu\",\n label: \"子标题1\",\n key: \"s-2\",\n path: \"/link3\",\n },\n {\n iconType: \"icon-zhanghaodenglu\",\n label: \"子标题2\",\n key: \"s-3\",\n path: \"/link4\",\n },\n ]}\n />\n <Menu\n allowCollapsed={false}\n items={[\n {\n label: \"父级标题1\",\n key: \"p-0\",\n iconType: \"icon-zhanghaodenglu\",\n children: [\n {\n label: \"子标题1\",\n key: \"s-0\",\n path: \"/link1\",\n },\n {\n label: \"子标题2\",\n key: \"s-1\",\n path: \"/link2\",\n },\n ],\n },\n {\n label: \"父级标题2\",\n key: \"p-1\",\n iconType: \"icon-zhanghaodenglu\",\n children: [\n {\n label: \"子标题1\",\n key: \"s-2\",\n path: \"/link3\",\n },\n {\n label: \"子标题2\",\n key: \"s-3\",\n path: \"/link4\",\n },\n ],\n },\n {\n label: \"父级标题3\",\n key: \"p-2\",\n iconType: \"icon-zhanghaodenglu\",\n path: \"/link5\",\n },\n ]}\n />\n <ControlMenu />\n </Space>\n );\n};\n\nrender(<Example />);\n\n`,\n scope: [{\n name: \"layout\",\n packageName: \"@components/Layout\",\n component: component_84\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_86\n}]\n},{\n title: `PageHeader`,\n description: `页面头`,\n code: `const { default: Layout, Page, Menu, PageHeader } = layout;\n\nconst Example = () => {\n return (\n <Layout navigation={{ isFixed: false }}>\n <Page\n menu={<div className=\"layout-menu\">左侧菜单区</div>}\n title=\"标题\"\n hideCloseSvg={true}\n menuFixed={false}\n name=\"pageHeaderLayout\"\n header={\n <PageHeader\n iconType=\"icon-color-shenpi-biaoti\"\n title=\"详情页名称\"\n info=\"编号:85767\"\n options={[\n {\n children: \"新建\",\n },\n {\n children: \"操作1\",\n },\n {\n children: \"操作2\",\n },\n {\n children: \"操作3\",\n },\n {\n children: \"操作4\",\n },\n ]}\n tags={[\"辅助信息\", \"辅助信息\", \"辅助信息\", \"辅助信息\"]}\n />\n }\n headerFixed={false}\n >\n <div>内容区</div>\n </Page>\n </Layout>\n );\n};\n\nrender(<Example />);\n\n`,\n scope: [{\n name: \"layout\",\n packageName: \"@components/Layout\",\n component: component_84\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_86\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_88 from '@components/Menu';\nimport * as component_89 from 'antd';\nconst readmeConfig = {\n name: `Menu`,\n summary: `<p>支持远程加载数据的菜单</p>`,\n \n \n api: `<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n</table>`,\n example: {\n isFull: false,\n className: ``,\n style: ``,\n list: [{\n title: `这里填写示例标题`,\n description: `这里填写示例说明`,\n code: `const { default: Menu } = _Menu;\nconst { Space } = antd;\nconst { useState } = React;\n\nconst ControlMenu = () => {\n const [current, setCurrent] = useState(\"s-0\");\n return (\n <Menu\n currentKey={current}\n onChange={setCurrent}\n items={[\n {\n label: \"父级标题1\",\n key: \"p-0\",\n iconType: \"icon-zhanghaodenglu\",\n children: [\n {\n label: \"子标题1\",\n key: \"s-0\",\n },\n {\n label: \"子标题2\",\n key: \"s-1\",\n },\n ],\n },\n {\n label: \"父级标题2\",\n key: \"p-1\",\n iconType: \"icon-zhanghaodenglu\",\n children: [\n {\n label: \"子标题1\",\n key: \"s-2\",\n },\n {\n label: \"子标题2\",\n key: \"s-3\",\n },\n ],\n },\n {\n label: \"父级标题3\",\n key: \"p-2\",\n iconType: \"icon-zhanghaodenglu\",\n },\n ]}\n />\n );\n};\nconst BaseExample = () => {\n return (\n <Space>\n <div style={{ maxWidth: \"200px\" }}>\n <Menu\n defaultItems={[\n {\n label: \"父级标题1\",\n iconType: \"icon-zhanghaodenglu\",\n children: [\n {\n label:\n \"子标题1超级长超级长超级长超级长超级长超级长超级长超级长超级长超级长超级长超级长超级长子标题1超级长超级长超级长超级长超级长超级长超级长超级长超级长超级长超级长超级长超级长子标题1超级长超级长超级长超级长超级长超级长超级长超级长超级长超级长超级长超级长超级长子标题1超级长超级长超级长超级长超级长超级长超级长超级长超级长超级长超级长超级\",\n path: \"/link1\",\n },\n {\n label: \"子标题2\",\n path: \"/link2\",\n },\n ],\n },\n {\n label: \"父级标题2\",\n iconType: \"icon-zhanghaodenglu\",\n children: [\n {\n label: \"子标题1\",\n path: \"/link3\",\n },\n {\n label: \"子标题2\",\n path: \"/link4\",\n },\n ],\n },\n {\n label: \"父级标题3\",\n iconType: \"icon-zhanghaodenglu\",\n fetchOptions: {\n loader: () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve([\n {\n label: \"子标题1\",\n path: \"/link5\",\n },\n {\n label: \"子标题2\",\n path: \"/link6\",\n },\n ]);\n }, 1000);\n });\n },\n },\n },\n ]}\n />\n </div>\n\n <Menu\n items={[\n {\n iconType: \"icon-zhanghaodenglu\",\n label: \"子标题1\",\n key: \"s-0\",\n path: \"/link1\",\n },\n {\n iconType: \"icon-zhanghaodenglu\",\n label: \"子标题2\",\n key: \"s-1\",\n path: \"/link2\",\n },\n {\n iconType: \"icon-zhanghaodenglu\",\n label: \"子标题1\",\n key: \"s-2\",\n path: \"/link3\",\n },\n {\n iconType: \"icon-zhanghaodenglu\",\n label: \"子标题2\",\n key: \"s-3\",\n path: \"/link4\",\n },\n ]}\n />\n <Menu\n allowCollapsed={false}\n items={[\n {\n label: \"父级标题1\",\n key: \"p-0\",\n iconType: \"icon-zhanghaodenglu\",\n children: [\n {\n label: \"子标题1\",\n key: \"s-0\",\n path: \"/link1\",\n },\n {\n label: \"子标题2\",\n key: \"s-1\",\n path: \"/link2\",\n },\n ],\n },\n {\n label: \"父级标题2\",\n key: \"p-1\",\n iconType: \"icon-zhanghaodenglu\",\n children: [\n {\n label: \"子标题1\",\n key: \"s-2\",\n path: \"/link3\",\n },\n {\n label: \"子标题2\",\n key: \"s-3\",\n path: \"/link4\",\n },\n ],\n },\n {\n label: \"父级标题3\",\n key: \"p-2\",\n iconType: \"icon-zhanghaodenglu\",\n path: \"/link5\",\n },\n ]}\n />\n <Menu\n allowCollapsed={false}\n defaultItems={[\n {\n label: \"父级标题1\",\n iconType: \"icon-zhanghaodenglu\",\n children: [\n {\n label: \"子标题1\",\n path: \"/link1\",\n },\n {\n label: \"子标题2\",\n path: \"/link2\",\n },\n ],\n },\n {\n label: \"父级标题2\",\n iconType: \"icon-zhanghaodenglu\",\n children: [\n {\n label: \"子标题1\",\n path: \"/link3\",\n },\n {\n label: \"子标题2\",\n path: \"/link4\",\n },\n ],\n },\n {\n label: \"父级标题3\",\n iconType: \"icon-zhanghaodenglu\",\n fetchOptions: {\n loader: () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve([\n {\n label: \"子标题1\",\n path: \"/link5\",\n },\n {\n label: \"子标题2\",\n path: \"/link6\",\n },\n ]);\n }, 1000);\n });\n },\n },\n },\n ]}\n />\n <Menu\n defaultItems={[\n {\n label: \"父级标题1\",\n children: [\n {\n label: \"子标题1\",\n path: \"/link1\",\n },\n {\n label: \"子标题2\",\n path: \"/link2\",\n },\n ],\n },\n {\n label: \"父级标题2\",\n children: [\n {\n label: \"子标题1\",\n path: \"/link3\",\n },\n {\n label: \"子标题2\",\n path: \"/link4\",\n },\n ],\n },\n ]}\n />\n <ControlMenu />\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Menu\",\n packageName: \"@components/Menu\",\n component: component_88\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_89\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_90 from '@components/Modal';\nimport * as component_91 from '@components/Global';\nimport * as component_92 from 'antd';\nimport * as component_93 from '@kne/react-fetch';\nimport * as component_94 from '@components/Content';\nimport * as component_95 from '@components/FormInfo';\nconst readmeConfig = {\n name: `Modal`,\n summary: `<h3>何时使用</h3>\n<p>需要用户处理事务,又不希望跳转页面以致打断工作流程时,可以在当前页面正中打开一个浮层,承载相应的操作。</p>\n<h3>特点</h3>\n<p>该组件是antd Modal组件的再封装:</p>\n<ul>\n<li>修改了footer部分的设置逻辑,能更加简单的定义footer区域的功能</li>\n<li>添加了withDecorator可以更加方便的处理Modal外层的显示逻辑</li>\n<li>扩展了用于方法调用的useModal的hooks,可以通过hooks获得一个Modal的调用方法,并且保证其和Modal组件式调用有相同的UI表现和行为</li>\n<li>扩展了ModalButton组件,可以在点击该按钮时执行加载数据,并且Button的状态变为loading,在数据加载完成之后再弹出弹窗</li>\n<li>扩展了TabsModal组件,它是一个Tabs和Modal组合起来的组件,对弹窗title做了特殊处理,更加符合UI交互逻辑</li>\n</ul>`,\n \n \n api: `<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>footer</td>\n<td>弹窗的footer,当其被显式设置成null且footerButtons没有设置过时弹窗不显示footer。当它类型为function时可以得到close方法和withDecorator设置的props</td>\n<td>jsx,function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>footerButtons</td>\n<td>弹窗footer的按钮区,默认为确认和取消按钮,默认按钮分别响应onConfirm和onCancel方法,如果自定义设置footerButtons则需要自行传入onClick参数,onConfirm和onCancel方法将不生效</td>\n<td>array</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onClose</td>\n<td>弹窗关闭时调用,弹窗受控时由该方法将外部open状态修改</td>\n<td>function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onConfirm</td>\n<td>当footerButtons未自定义设置时点击确认按钮触发执行该方法,当其返回Promise点击后Promise,resolve之前确认按钮显示为loading状态,返回值为false或者Promise的resolve值为false时弹窗不会被关闭,其他情况弹窗默认关闭</td>\n<td>function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>onCancel</td>\n<td>和onConfirm类似,其为点击取消按钮触发</td>\n<td>function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>children</td>\n<td>弹窗内容,可以为jsx或者function,为function时可以接收到close和withDecorator设置的props</td>\n<td>jsx,function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>withDecorator</td>\n<td>弹窗修饰器,会接收到弹窗children的render方法,可以在其外部添加修饰内容后执行render方法,给render方法传入的值可以在children,footer,rightOptions类型为function时接收到对应的参数</td>\n<td>function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>rightOptions</td>\n<td>弹窗右侧区域,和children类似可以为jsx或者function类型</td>\n<td>jsx,function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>maskClosable</td>\n<td>点击蒙层是否允许关闭</td>\n<td>boolean</td>\n<td>false</td>\n</tr>\n</tbody>\n</table>\n<p>其他参数参考antd Modal组件</p>\n<h3>useModal</h3>\n<p>获取一个执行后可以弹出一个Modal组件的方法</p>\n<h4>return:modal</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>modal</td>\n<td>执行后可以弹出一个Modal弹窗,参数同Modal组件参数</td>\n<td>function</td>\n</tr>\n</tbody>\n</table>\n<h3>TabsModal</h3>\n<p>一个Tabs和Modal组合起来的组件,对弹窗title做了特殊处理,更加符合UI交互逻辑</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>items</td>\n<td>同antd Tabs的items参数</td>\n<td>array</td>\n<td>-</td>\n</tr>\n<tr>\n<td>items[].label</td>\n<td>选项卡头显示文字</td>\n<td>string</td>\n<td>-</td>\n</tr>\n<tr>\n<td>items[].children</td>\n<td>选项卡头显示内容,和antd Tabs不同的是它可以是一个function和Modal的children类似可以接收items[].withDecorator传入的参数</td>\n<td>jsx,function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>items[].key</td>\n<td>对应activeKey值</td>\n<td>string</td>\n<td>-</td>\n</tr>\n<tr>\n<td>activeKey</td>\n<td>当前激活 tab 面板的 key</td>\n<td>string</td>\n<td></td>\n</tr>\n<tr>\n<td>withDecorator</td>\n<td>弹窗修饰器和Modal的withDecorator作用一致</td>\n<td>function</td>\n<td>-</td>\n</tr>\n<tr>\n<td>defaultActiveKey</td>\n<td>初始化选中面板的 key,如果没有设置 activeKey</td>\n<td>string</td>\n<td></td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>切换面板的回调</td>\n<td>function</td>\n<td></td>\n</tr>\n</tbody>\n</table>\n<h3>useTabsModal</h3>\n<p>获取一个执行后可以弹出一个TabsModal组件的方法</p>\n<h4>return:tabsModal</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>tabsModal</td>\n<td>执行后可以弹出一个TabsModal弹窗,参数同TabsModal组件参数</td>\n<td>function</td>\n</tr>\n</tbody>\n</table>\n<h3>ModalButton</h3>\n<p>点击以后可以执行获取数据,在数据未返回时按钮展示为loading状态,数据返回后弹出Modal弹窗</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>api</td>\n<td>@kne/react-fetch 所需参数</td>\n<td>object</td>\n<td>-</td>\n</tr>\n<tr>\n<td>modalProps</td>\n<td>同Modal参数,当它为function时,执行function后返回的值作为modalProps</td>\n<td>object,function({data,fetchApi,close})</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<p>其他参数同antd Button 组件</p>\n<h3>TabsModalButton</h3>\n<p>点击以后可以执行获取数据,在数据未返回时按钮展示为loading状态,数据返回后弹出TabsModal弹窗</p>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>api</td>\n<td>@kne/react-fetch 所需参数</td>\n<td>object</td>\n<td>-</td>\n</tr>\n<tr>\n<td>modalProps</td>\n<td>同TabsModal参数,当它为function时,执行function后返回的值作为modalProps</td>\n<td>object,function({data,fetchApi,close})</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<p>其他参数同antd Button 组件</p>`,\n example: {\n isFull: false,\n className: ``,\n style: ``,\n list: [{\n title: `普通弹窗`,\n description: `展示弹窗的基本用法,自定义footer等功能。\n注意:\n1.onConfirm和onCancel只对于默认的footerButtons生效,如果是自定义的footerButtons则不需要传这两个参数,直接定义按钮的onClick即可。\n2.自定义的footerButtons的onClick可以返回一个Promise来延迟关闭弹窗,resolve的值为false不关闭弹窗,其他情况会自动关闭弹窗。在resolve未返回之前按钮会变成loading状态`,\n code: `const { default: Modal, useModal } = _Modal;\nconst { useState } = React;\nconst { Button, Space, message, Radio } = antd;\nconst { PureGlobal } = global;\n\nconst BaseExample = () => {\n const modal = useModal();\n const [size, setSize] = useState(\"default\");\n const [open, setOpen] = useState(false);\n return (\n <Space direction=\"vertical\">\n <Radio.Group\n value={size}\n options={[\n { label: \"small\", value: \"small\" },\n { label: \"default\", value: \"default\" },\n {\n label: \"large\",\n value: \"large\",\n },\n ]}\n onChange={(e) => {\n setSize(e.target.value);\n }}\n optionType=\"button\"\n buttonStyle=\"solid\"\n />\n <Space wrap>\n <Modal\n title=\"确定延迟关闭弹窗\"\n size={size}\n open={open}\n onClose={() => {\n setOpen(false);\n }}\n onConfirm={() => {\n return new Promise((resolve) => {\n message.success(\"弹窗1s后关闭\");\n setTimeout(() => {\n message.success(\"弹窗关闭\");\n resolve();\n }, 1000);\n });\n }}\n >\n <div>弹窗弹窗弹窗弹窗弹窗弹窗弹窗</div>\n </Modal>\n <Button\n onClick={() => {\n setOpen(true);\n }}\n >\n 确定延迟关闭弹窗\n </Button>\n <Button\n onClick={() => {\n modal({\n title: \"hooks调用弹框\",\n size,\n children: <div>弹窗弹窗弹窗弹窗弹窗弹窗弹窗</div>,\n });\n }}\n >\n hooks调用弹框\n </Button>\n <Button\n onClick={() => {\n modal({\n title: \"超高弹窗\",\n size,\n children: (\n <div style={{ height: \"2000px\" }}>\n 超高弹窗超高弹窗超高弹窗超高弹窗超高弹窗超高弹窗超高弹窗超高弹窗超高弹窗超高弹窗\n </div>\n ),\n });\n }}\n >\n 展示超高弹窗\n </Button>\n <Button\n onClick={() => {\n modal({\n title: \"自定义footer弹框\",\n size,\n children: <div>弹窗弹窗弹窗弹窗弹窗弹窗弹窗</div>,\n footer: ({ close }) => (\n <Space>\n <span>自定义footer</span>\n <Button\n type=\"link\"\n onClick={() => {\n close();\n }}\n >\n 关闭\n </Button>\n </Space>\n ),\n });\n }}\n >\n 展示自定义footer弹框\n </Button>\n <Button\n onClick={() => {\n modal({\n title: \"无footer弹框\",\n size,\n children: <div>弹窗弹窗弹窗弹窗弹窗弹窗弹窗</div>,\n footer: null,\n });\n }}\n >\n 无footer弹框\n </Button>\n <Button\n onClick={() => {\n modal({\n title: \"自定义按钮组\",\n size,\n children: <div>弹窗弹窗弹窗弹窗弹窗弹窗弹窗</div>,\n footerButtons: [\n {\n children: \"按钮一\",\n },\n {\n type: \"primary\",\n children: \"按钮二\",\n },\n {\n children: \"按钮三\",\n },\n ],\n });\n }}\n >\n 自定义按钮组\n </Button>\n <Button\n onClick={() => {\n modal({\n title: \"有rightOptions的弹窗\",\n size,\n children: <div>弹窗弹窗弹窗弹窗弹窗弹窗弹窗</div>,\n rightOptions: <div>右侧内容右侧内容右侧内容右侧内容</div>,\n rightSpan: 12,\n });\n }}\n >\n 有rightOptions的弹窗\n </Button>\n <Button\n onClick={() => {\n const StateContainer = ({ children }) => {\n const [disabled, setDisabled] = useState(false);\n return children({ disabled, setDisabled });\n };\n\n modal({\n title: \"有rightOptions的弹窗\",\n size,\n withDecorator: (render) => {\n return <StateContainer>{render}</StateContainer>;\n },\n footerButtons: ({ disabled }) => [\n {\n type: \"primary\",\n disabled,\n children: \"确定\",\n },\n ],\n children: ({ disabled, setDisabled }) => (\n <div>\n 弹窗弹窗弹窗弹窗弹窗弹窗弹窗[{String(disabled)}]\n <Button\n onClick={() => {\n setDisabled((disabled) => !disabled);\n }}\n >\n 切换确定按钮disabled\n </Button>\n </div>\n ),\n });\n }}\n >\n children控制footerButtons状态\n </Button>\n </Space>\n </Space>\n );\n};\n\nrender(\n <PureGlobal>\n <BaseExample />\n </PureGlobal>\n);\n\n`,\n scope: [{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_90\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_91\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_92\n}]\n},{\n title: `childrenRef的使用`,\n description: ``,\n code: `const { default: Modal, useModal } = _Modal;\nconst { Button } = antd;\nconst BaseExample = () => {\n const modal = useModal();\n\n return (\n <Button\n onClick={() => {\n modal({\n title: \"示例弹框\",\n children: ({ childrenRef }) => {\n return (\n <div ref={childrenRef}>\n 示例弹框示例弹框示例弹框示例弹框示例弹框示例弹框\n </div>\n );\n },\n onConfirm: (e, { childrenRef }) => {\n console.log(childrenRef.current);\n },\n });\n }}\n >\n 点击弹出弹框\n </Button>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_90\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_92\n}]\n},{\n title: `需要加载数据的弹窗`,\n description: `可以通过withDecorator属性实现弹窗的加载数据或者加载远程组件的逻辑,在数据或者远程组件加载完成之前弹窗展示loading状态,加载完成之后children可以获取到加载的数据`,\n code: `const { default: Modal, useModal } = _Modal;\nconst { useState } = React;\nconst { Button, Space } = antd;\nconst { default: Fetch } = fetch;\nconst { PureGlobal } = global;\nconst { default: Content } = _Content;\n\nconst BaseExample = () => {\n const modal = useModal();\n const [open, setOpen] = useState(false);\n return (\n <Space wrap>\n <Modal\n title=\"组件调用方式\"\n withDecorator={(render) => (\n <Fetch\n loader={() => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve([\n {\n label: \"内容1\",\n content: \"内容1内容1内容1内容1内容1内容1内容1\",\n },\n {\n label: \"内容2\",\n content: \"内容2内容2内容2内容2内容2内容2内容2内容2\",\n },\n ]);\n }, 1000);\n });\n }}\n render={({ data }) => render({ data })}\n />\n )}\n open={open}\n onClose={() => {\n setOpen(false);\n }}\n >\n {({ data }) => <Content list={data} col={2} />}\n </Modal>\n <Button\n onClick={() => {\n setOpen(true);\n }}\n >\n 组件调用方式\n </Button>\n <Button\n onClick={() => {\n modal({\n title: \"hooks调用方式\",\n withDecorator: (render) => (\n <Fetch\n loader={() => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve([\n {\n label: \"内容1\",\n content: \"内容1内容1内容1内容1内容1内容1内容1\",\n },\n {\n label: \"内容2\",\n content: \"内容2内容2内容2内容2内容2内容2内容2内容2\",\n },\n ]);\n }, 1000);\n });\n }}\n render={({ data }) => render({ data })}\n />\n ),\n children: ({ data }) => <Content list={data} col={2} />,\n });\n }}\n >\n hooks调用方式\n </Button>\n <Button\n onClick={() => {\n modal({\n title: (props) => {\n return \"hooks调用方式\";\n },\n withDecorator: (render) => (\n <Fetch\n loader={() => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve([\n {\n label: \"内容1\",\n content: \"内容1内容1内容1内容1内容1内容1内容1\",\n },\n {\n label: \"内容2\",\n content: \"内容2内容2内容2内容2内容2内容2内容2内容2\",\n },\n ]);\n }, 1000);\n });\n }}\n render={({ data }) => render({ data })}\n />\n ),\n children: ({ data }) => <Content list={data} col={2} />,\n });\n }}\n >\n hooks title调用方式\n </Button>\n </Space>\n );\n};\n\nrender(\n <PureGlobal>\n <BaseExample />\n </PureGlobal>\n);\n\n`,\n scope: [{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_90\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_91\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_92\n},{\n name: \"fetch\",\n packageName: \"@kne/react-fetch\",\n component: component_93\n},{\n name: \"_Content\",\n packageName: \"@components/Content\",\n component: component_94\n}]\n},{\n title: `可以弹出弹窗的按钮`,\n description: `可以点击按钮弹出弹窗,并且在弹窗弹出之前可以加载数据,加载数据时,按钮为loading状态,数据加载完成之后再弹出弹窗`,\n code: `const { ModalButton, TabsModalButton } = _Modal;\nconst { Space } = antd;\nconst { PureGlobal } = global;\nconst { default: Content } = _Content;\nconst { default: FormInfo, Input, TextArea } = _FormInfo;\n\nconst api = {\n loader: () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve([\n { label: \"内容1\", content: \"内容1内容1内容1内容1内容1内容1内容1\" },\n {\n label: \"内容2\",\n content: \"内容2内容2内容2内容2内容2内容2内容2内容2\",\n },\n ]);\n }, 1000);\n });\n },\n};\n\nconst BaseExample = () => {\n return (\n <Space wrap>\n <ModalButton\n api={api}\n modalProps={({ data }) => {\n return {\n title: \"加载数据的弹窗\",\n children: <Content list={data} col={2} />,\n };\n }}\n >\n 点击加载数据\n </ModalButton>\n <TabsModalButton\n api={api}\n modalProps={({ data }) => {\n return {\n items: data.map(({ label, content }, index) => {\n return {\n key: index,\n children: content,\n label,\n };\n }),\n };\n }}\n >\n 点击加载数据的Tabs弹窗\n </TabsModalButton>\n </Space>\n );\n};\n\nrender(\n <PureGlobal>\n <BaseExample />\n </PureGlobal>\n);\n\n`,\n scope: [{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_90\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_91\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_92\n},{\n name: \"_Content\",\n packageName: \"@components/Content\",\n component: component_94\n},{\n name: \"_FormInfo\",\n packageName: \"@components/FormInfo\",\n component: component_95\n}]\n},{\n title: `tabs弹窗`,\n description: `展示一个tabs弹窗,tabs的选项的label会占据弹窗title位置,弹框的title将不显示\ntabs的items多加了withDecorator参数和Modal的withDecorator参数类似可以控制其外部显示及渲染内容\ntabs的items的children也可以是function,同样可以接收到TabsModal的withDecorator传回的参数`,\n code: `const { TabsModal, useTabsModal } = _Modal;\nconst { useState } = React;\nconst { default: Fetch } = fetch;\nconst { Button, Space } = antd;\nconst { PureGlobal } = global;\nconst { default: Content } = _Content;\n\nconst BaseExample = () => {\n const [open, setOpen] = useState(false);\n const tabsModal = useTabsModal();\n return <Space wrap>\n <TabsModal open={open} onClose={() => {\n setOpen(false);\n }} items={[{\n label: \"项目 1\", key: \"item-1\", children: <div>项目 1项目 1项目 1项目 1项目 1项目 1项目 1项目 1</div>\n }, {\n label: \"项目 2\", key: \"item-2\", children: <div>项目 2项目 2项目 2项目 2项目 2项目 2项目 2项目 2</div>\n }]} rightOptions={<div>右边栏内容右边栏内容右边栏内容右边栏内容</div>}>\n <div>弹窗弹窗弹窗弹窗弹窗弹窗弹窗</div>\n </TabsModal>\n <Button onClick={() => {\n setOpen(true);\n }}>组件调用方式</Button>\n <Button onClick={() => {\n tabsModal({\n rightOptions: <div>右边栏内容右边栏内容右边栏内容右边栏内容</div>, items: [{\n label: \"项目 1\", key: \"item-1\", children: <div>项目 1项目 1项目 1项目 1项目 1项目 1项目 1项目 1</div>\n }, {\n label: \"项目 2\", key: \"item-2\", children: <div>项目 2项目 2项目 2项目 2项目 2项目 2项目 2项目 2</div>\n }]\n });\n }}>hooks调用方式</Button>\n <Button onClick={() => {\n tabsModal({\n title: \"此title不展示\",\n rightOptions: ({ data }) => <Content list={data} />,\n withDecorator: (render) => <Fetch loader={() => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve([{ label: \"内容1\", content: \"内容1内容1内容1内容1内容1内容1内容1\" }, {\n label: \"内容2\", content: \"内容2内容2内容2内容2内容2内容2内容2内容2\"\n }]);\n }, 1000);\n });\n }} render={({ data }) => render({ data })} />,\n items: [{\n label: \"项目 1\", key: \"item-1\", children: ({ data }) => <Content list={data} col={2} />\n }, {\n withDecorator: (render) => <Fetch loader={() => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve([{ label: \"内容3\", content: \"内容3内容3内容3内容3内容3内容3内容3\" }, {\n label: \"内容4\", content: \"内容4内容4内容4内容4内容4内容4内容4内容4\"\n }]);\n }, 1000);\n });\n }} render={({ data }) => render({ tabData: data })} />,\n label: \"项目 2\",\n key: \"item-2\",\n children: ({ data, tabData }) => <Content list={[...data, ...tabData]} col={2} />\n }]\n });\n }}>复杂数据加载</Button>\n </Space>;\n};\n\nrender(<PureGlobal><BaseExample /></PureGlobal>);\n`,\n scope: [{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_90\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_91\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_92\n},{\n name: \"fetch\",\n packageName: \"@kne/react-fetch\",\n component: component_93\n},{\n name: \"_Content\",\n packageName: \"@components/Content\",\n component: component_94\n}]\n},{\n title: `消息确认和提示`,\n description: `展示确认消息提醒`,\n code: `const { default: Modal, useConfirmModal } = _Modal;\nconst { useState } = React;\nconst { Button, Space, message } = antd;\nconst { PureGlobal } = global;\nconst BaseExample = () => {\n const confirmModal = useConfirmModal();\n return (\n <Space wrap>\n <Button\n onClick={() => {\n confirmModal({\n danger: true,\n type: \"confirm\",\n title: \"确定要删除吗?\",\n message:\n \"确定要删除确定要删除确定要删除确定要删除确定要删除确定要删除\",\n });\n }}\n >\n confirm\n </Button>\n <Button\n onClick={() => {\n confirmModal({\n type: \"confirm\",\n confirmType: \"warning\",\n title: \"确定要编辑吗?\",\n message:\n \"确定要编辑确定要编辑确定要编辑确定要编辑确定要编辑确定要编辑确定要编辑\",\n });\n }}\n >\n confirm 警告\n </Button>\n <Button\n onClick={() => {\n confirmModal({\n type: \"info\",\n title: \"确定要删除吗?\",\n message:\n \"确定要删除确定要删除确定要删除确定要删除确定要删除确定要删除\",\n });\n }}\n >\n info\n </Button>\n <Button\n onClick={() => {\n confirmModal({\n type: \"info\",\n message:\n \"确定要删除确定要删除确定要删除确定要删除确定要删除确定要删除\",\n });\n }}\n >\n info无标题\n </Button>\n <Button\n onClick={() => {\n confirmModal({\n type: \"success\",\n title: \"确定要删除吗?\",\n message:\n \"确定要删除确定要删除确定要删除确定要删除确定要删除确定要删除\",\n });\n }}\n >\n success\n </Button>\n <Button\n onClick={() => {\n confirmModal({\n type: \"warning\",\n title: \"确定要删除吗?\",\n message:\n \"确定要删除确定要删除确定要删除确定要删除确定要删除确定要删除\",\n });\n }}\n >\n warning\n </Button>\n <Button\n onClick={() => {\n confirmModal({\n type: \"error\",\n title: \"确定要删除吗?\",\n message:\n \"确定要删除确定要删除确定要删除确定要删除确定要删除确定要删除\",\n });\n }}\n >\n error\n </Button>\n </Space>\n );\n};\n\nrender(\n <PureGlobal>\n <BaseExample />\n </PureGlobal>\n);\n\n`,\n scope: [{\n name: \"_Modal\",\n packageName: \"@components/Modal\",\n component: component_90\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_91\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_92\n},{\n name: \"fetch\",\n packageName: \"@kne/react-fetch\",\n component: component_93\n},{\n name: \"_Content\",\n packageName: \"@components/Content\",\n component: component_94\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_96 from '@components/Navigation';\nimport * as component_97 from '@components/Global';\nimport * as component_98 from 'antd';\nconst readmeConfig = {\n name: `Navigation`,\n summary: `<h3>何时使用</h3>\n<p>系统的顶部导航,一级导航项偏左靠近 logo 放置,辅助菜单偏右放置。</p>\n<h3>特点</h3>\n<ul>\n<li>集成了Permissions权限判断,可以通过权限列表来判断导项是否显示</li>\n<li>在屏幕显示不了全部的一级导航时可以自动将后面的导航项收起到更多下拉菜单里面</li>\n</ul>`,\n \n \n api: `<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n</table>`,\n example: {\n isFull: true,\n className: `Navigation_84649`,\n style: `.Navigation_84649 .fold-items {\n width: 600px;\n}`,\n list: [{\n title: `这里填写示例标题`,\n description: `这里填写示例说明`,\n code: `const { default: Navigation } = _Navigation;\nconst { PureGlobal } = global;\n\nconst menuList = [\n {\n key: \"client\",\n title: \"客户\",\n path: \"/client\",\n permission: \"client:client:look\",\n },\n {\n key: \"position\",\n title: \"职位\",\n path: \"/position\",\n permission: \"jd:job:look\",\n },\n {\n key: \"ats\",\n title: \"招聘流程\",\n path: \"/ats\",\n },\n {\n key: \"talent\",\n title: \"人才库\",\n permission: \"cv:cv:look\",\n path: \"/talent\",\n },\n {\n key: \"contract\",\n title: \"合同\",\n permission: \"contract:mgr:look\",\n path: \"/contract\",\n },\n {\n key: \"payment\",\n title: \"付款信息\",\n permission: \"payment:mgr:look\",\n path: \"/payment\",\n },\n {\n key: \"invoice-center\",\n title: \"开票\",\n permission: \"client:invoice:center\",\n path: \"/invoice-center\",\n },\n {\n key: \"invoice-manage\",\n title: \"发票管理\",\n permission: \"client:invoice:manager\",\n path: \"/invoice-manage\",\n },\n {\n key: \"setting\",\n title: \"设置\",\n permission: (permissions) =>\n permissions.some(\n (x) =>\n [\n \"system:permissions:mgr\",\n \"system:org:mgr\",\n \"system:user:mgr\",\n ].indexOf(x) !== -1\n ),\n path: \"/setting\",\n },\n];\n\nrender(\n <PureGlobal>\n <Navigation\n list={menuList}\n isFixed={false}\n permissions={[\n \"client:client:look\",\n \"jd:job:look\",\n \"cv:cv:look\",\n \"contract:mgr:look\",\n \"payment:mgr:look\",\n \"client:invoice:center\",\n \"client:invoice:manager\",\n \"system:permissions:mgr\",\n ]}\n />\n </PureGlobal>\n);\n\n`,\n scope: [{\n name: \"_Navigation\",\n packageName: \"@components/Navigation\",\n component: component_96\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_97\n}]\n},{\n title: `这里填写示例标题`,\n description: `这里填写示例说明`,\n code: `const { default: Navigation } = _Navigation;\nconst { PureGlobal } = global;\n\nconst menuList = [\n {\n key: \"client\",\n title: \"客户\",\n path: \"/client\",\n permission: \"client:client:look\",\n },\n {\n key: \"position\",\n title: \"职位\",\n path: \"/position\",\n permission: \"jd:job:look\",\n },\n {\n key: \"ats\",\n title: \"招聘流程\",\n path: \"/ats\",\n },\n {\n key: \"talent\",\n title: \"人才库\",\n permission: \"cv:cv:look\",\n path: \"/talent\",\n },\n {\n key: \"contract\",\n title: \"合同\",\n permission: \"contract:mgr:look\",\n path: \"/contract\",\n },\n {\n key: \"payment\",\n title: \"付款信息\",\n permission: \"payment:mgr:look\",\n path: \"/payment\",\n },\n {\n key: \"invoice-center\",\n title: \"开票\",\n permission: \"client:invoice:center\",\n path: \"/invoice-center\",\n },\n {\n key: \"invoice-manage\",\n title: \"发票管理\",\n permission: \"client:invoice:manager\",\n path: \"/invoice-manage\",\n },\n {\n key: \"setting\",\n title: \"设置\",\n permission: (permissions) =>\n permissions.some(\n (x) =>\n [\n \"system:permissions:mgr\",\n \"system:org:mgr\",\n \"system:user:mgr\",\n ].indexOf(x) !== -1\n ),\n path: \"/setting\",\n },\n];\n\nrender(\n <PureGlobal>\n <div className=\"fold-items\">\n <Navigation\n isFixed={false}\n list={menuList}\n permissions={[\n \"client:client:look\",\n \"jd:job:look\",\n \"cv:cv:look\",\n \"contract:mgr:look\",\n \"payment:mgr:look\",\n \"client:invoice:center\",\n \"client:invoice:manager\",\n \"system:permissions:mgr\",\n ]}\n />\n </div>\n </PureGlobal>\n);\n\n`,\n scope: [{\n name: \"_Navigation\",\n packageName: \"@components/Navigation\",\n component: component_96\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_97\n}]\n},{\n title: `这里填写示例标题`,\n description: `这里填写示例说明`,\n code: `const { useState } = React;\nconst { PureGlobal } = global;\nconst { default: Navigation } = _Navigation;\nconst { Checkbox, Space } = antd;\n\nconst menuList = [\n {\n key: \"client\",\n title: \"客户\",\n path: \"/client\",\n permission: \"client:client:look\",\n },\n {\n key: \"position\",\n title: \"职位\",\n path: \"/position\",\n permission: \"jd:job:look\",\n },\n {\n key: \"ats\",\n title: \"招聘流程\",\n path: \"/ats\",\n },\n {\n key: \"talent\",\n title: \"人才库\",\n permission: \"cv:cv:look\",\n path: \"/talent\",\n },\n {\n key: \"contract\",\n title: \"合同\",\n permission: \"contract:mgr:look\",\n path: \"/contract\",\n },\n {\n key: \"payment\",\n title: \"付款信息\",\n permission: \"payment:mgr:look\",\n path: \"/payment\",\n },\n {\n key: \"invoice-center\",\n title: \"开票\",\n permission: \"client:invoice:center\",\n path: \"/invoice-center\",\n },\n {\n key: \"invoice-manage\",\n title: \"发票管理\",\n permission: \"client:invoice:manager\",\n path: \"/invoice-manage\",\n },\n {\n key: \"setting\",\n title: \"设置\",\n permission: (permissions) =>\n permissions.some(\n (x) =>\n [\n \"system:permissions:mgr\",\n \"system:org:mgr\",\n \"system:user:mgr\",\n ].indexOf(x) !== -1\n ),\n path: \"/setting\",\n },\n];\n\nconst Example = () => {\n const [permissions, setPermissions] = useState([]);\n return (\n <PureGlobal>\n <Space className=\"container\" direction=\"vertical\" size={32}>\n <Navigation isFixed={false} list={menuList} permissions={permissions} />\n <Checkbox.Group\n value={permissions}\n options={[\n \"client:client:look\",\n \"jd:job:look\",\n \"cv:cv:look\",\n \"contract:mgr:look\",\n \"payment:mgr:look\",\n \"client:invoice:center\",\n \"client:invoice:manager\",\n \"system:permissions:mgr\",\n ]}\n onChange={(values) => {\n setPermissions(values);\n }}\n />\n </Space>\n </PureGlobal>\n );\n};\n\nrender(<Example />);\n\n`,\n scope: [{\n name: \"_Navigation\",\n packageName: \"@components/Navigation\",\n component: component_96\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_98\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_97\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_101 from '@components/Permissions';\nimport * as component_102 from '@components/Global';\nimport * as component_103 from 'antd';\nconst readmeConfig = {\n name: `Permissions`,\n summary: `<h3>何时使用</h3>\n<p>在系统中存在一些功能和操作只允许某些角色用户使用,使用该组件可以让其包裹的组件或者区域根据系统的权限列表配置展示不同的状态</p>\n<h3>特点</h3>\n<p>通过在Global中的preset中设置permissions作为当前用户的权限列表,在Permissions组件配置permissions作为该功能要求具备的权限项,当要求具备的权限项全部在用户的权限列表中找到时为权限通过状态否则为权限不通过状态</p>\n<p>当权限不通过时,Permissions组件可以有三种方式呈现:</p>\n<ol>\n<li>用户可以看到操作功能的组件显示,但是不能进行操作,在鼠标移入时会以ToolTip提示错误原因,一般用在按钮等需要用户交互的功能位置</li>\n<li>用户不能看到操作功能或者数据呈现,对应区域显示错误原因,一般用在要数据展示等场景</li>\n<li>隐藏内部组件,一般用在不需要干扰到用户或用户不需要了解其没有权限的功能或数据等场景</li>\n</ol>`,\n \n \n api: `<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>type</td>\n<td>类型,可选值为hidden,tooltip,error,分别为隐藏,气泡提示,错误提示三种形式</td>\n<td>string</td>\n<td>hidden</td>\n</tr>\n<tr>\n<td>tagName</td>\n<td>当前组件的tagName,同React.createElement的type参数,默认为span</td>\n<td>string</td>\n<td>span</td>\n</tr>\n<tr>\n<td>message</td>\n<td>提示文案</td>\n<td>string</td>\n<td>您暂无权限,请联系管理员</td>\n</tr>\n<tr>\n<td>request</td>\n<td>权限列表为一个字符串数组,每个item为一项权限的key,所有权限在全局的permissions中存在则判断为权限通过</td>\n<td>array[string]</td>\n<td>[]</td>\n</tr>\n<tr>\n<td>children</td>\n<td>该参数可以传function类型,children({isPass, type, request}),isPass为权限校验是否通过,type为提示类型,request为所需权限列表,可以自行实现权限的展示</td>\n<td>jsx,function</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>`,\n example: {\n isFull: false,\n className: `Permissions_d08cc`,\n style: `.Permissions_d08cc .box {\n padding: 20px;\n background: #f8f8f8;\n}`,\n list: [{\n title: `展示权限不通过的几种形式`,\n description: `通过切换不同的type,可以预览三种不同type的表现形式`,\n code: `const { default: Permissions } = _Permissions;\nconst { PureGlobal } = global;\nconst { Button, Radio, Space } = antd;\nconst { useState } = React;\n\nconst BaseExample = () => {\n const [type, setType] = useState(\"tooltip\");\n return (\n <PureGlobal\n preset={{\n permissions: [\"permission_1\", \"permission_2\"],\n }}\n >\n <Space direction=\"vertical\">\n <Radio.Group\n value={type}\n options={[\n { label: \"tooltip\", value: \"tooltip\" },\n {\n label: \"error\",\n value: \"error\",\n },\n { label: \"hidden\", value: \"hidden\" },\n ]}\n onChange={(e) => {\n setType(e.target.value);\n }}\n optionType=\"button\"\n buttonStyle=\"solid\"\n />\n <Permissions type={type} request={[\"permission_2\"]}>\n <div className=\"box\">\n <Button onClick={() => console.log(\"执行操作\")}>有权限操作</Button>\n </div>\n </Permissions>\n <Permissions type={type} request={[\"permission_3\"]}>\n <div className=\"box\">\n <Button onClick={() => console.log(\"执行操作\")}>无权限操作</Button>\n </div>\n </Permissions>\n </Space>\n </PureGlobal>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Permissions\",\n packageName: \"@components/Permissions\",\n component: component_101\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_102\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_103\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_99 from '@components/StateBar';\nimport * as component_100 from 'antd';\nconst readmeConfig = {\n name: `StateBar`,\n summary: `<p>用于 State Bar</p>`,\n \n \n api: `<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>stateOption</td>\n<td>state操作列表</td>\n<td>string</td>\n<td>{key: string, tab: ReactNode}[]</td>\n</tr>\n<tr>\n<td>activeKey</td>\n<td>当前激活 tab 面板的 key</td>\n<td>string</td>\n<td>-</td>\n</tr>\n<tr>\n<td>type</td>\n<td>当前tab展示样式</td>\n<td>'tab'、'radio'、'step'</td>\n<td>'tab'</td>\n</tr>\n<tr>\n<td>onChange</td>\n<td>事件返回选中的key</td>\n<td>(value: string) =&gt; void</td>\n<td></td>\n</tr>\n<tr>\n<td>tabBarExtraContent</td>\n<td>展示在state bar右侧</td>\n<td>ReactNode</td>\n<td>null</td>\n</tr>\n<tr>\n<td>isInner</td>\n<td>底部线延展至总长</td>\n<td>boolean</td>\n<td>false</td>\n</tr>\n</tbody>\n</table>\n<h3>Mapping</h3>\n<h4>stateOption</h4>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>key</td>\n<td>对应 activeKey</td>\n<td>string</td>\n<td>-</td>\n</tr>\n<tr>\n<td>tab</td>\n<td>选项卡头显示文字</td>\n<td>ReactNode</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>`,\n example: {\n isFull: false,\n className: ``,\n style: ``,\n list: [{\n title: `State Bar`,\n description: `State Bar`,\n code: `const { default: StateBar } = _StateBar;\nconst { Button, Radio, Space } = antd;\nconst { useState } = React;\n\nconst BaseExample = () => {\n const [size, setSize] = useState(\"default\");\n const [isInner, setIsInner] = useState(false);\n return (\n <Space direction=\"vertical\">\n <Radio.Group\n value={isInner}\n options={[\n { label: \"inner\", value: true },\n { label: \"normal\", value: false },\n ]}\n onChange={(e) => {\n setIsInner(e.target.value);\n }}\n optionType=\"button\"\n buttonStyle=\"solid\"\n />\n <Radio.Group\n value={size}\n options={[\n { label: \"small\", value: \"small\" },\n { label: \"default\", value: \"default\" },\n { label: \"large\", value: \"large\" },\n ]}\n onChange={(e) => {\n setSize(e.target.value);\n }}\n optionType=\"button\"\n buttonStyle=\"solid\"\n />\n <StateBar\n size={size}\n isInner={isInner}\n stateOption={[\n { tab: \"全部\", key: \"1\" },\n { tab: \"科目一\", key: \"2\" },\n {\n tab: \"科目二\",\n key: \"3\",\n },\n { tab: \"科目三\", key: \"4\" },\n { tab: \"科目四\", key: \"5\" },\n ]}\n />\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_StateBar\",\n packageName: \"@components/StateBar\",\n component: component_99\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_100\n}]\n},{\n title: `Radio State Bar`,\n description: `Radio State Bar`,\n code: `const { default: StateBar } = _StateBar;\nconst { Radio, Space } = antd;\nconst { useState } = React;\n\nconst BaseStateExample = () => {\n const [size, setSize] = useState(\"default\");\n return (\n <Space direction=\"vertical\">\n <Radio.Group\n value={size}\n options={[\n { label: \"small\", value: \"small\" },\n { label: \"default\", value: \"default\" },\n { label: \"large\", value: \"large\" },\n ]}\n onChange={(e) => {\n setSize(e.target.value);\n }}\n optionType=\"button\"\n buttonStyle=\"solid\"\n />\n <StateBar\n size={size}\n type=\"radio\"\n stateOption={[\n { tab: \"全部\", key: \"1\" },\n { tab: \"科目一\", key: \"2\" },\n { tab: \"科目二\", key: \"3\" },\n { tab: \"科目三\", key: \"4\" },\n { tab: \"科目四\", key: \"5\" },\n { tab: \"科目一1\", key: \"22\" },\n { tab: \"科目二2\", key: \"33\" },\n { tab: \"科目三3\", key: \"44\" },\n { tab: \"科目四4\", key: \"55\", style: { cursor: \"copy\" } },\n ]}\n />\n </Space>\n );\n};\n\nrender(<BaseStateExample />);\n\n`,\n scope: [{\n name: \"_StateBar\",\n packageName: \"@components/StateBar\",\n component: component_99\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_100\n}]\n},{\n title: `Step State Bar`,\n description: `Step State Bar`,\n code: `const { default: StateBar } = _StateBar;\n\nconst BaseStateExample = () => {\n return (\n <StateBar\n type=\"step\"\n stateOption={[\n { tab: \"全部\", key: \"1\" },\n { tab: \"科目一\", key: \"2\" },\n { tab: \"科目二\", key: \"3\" },\n { tab: \"科目三\", key: \"4\" },\n { tab: \"科目四\", key: \"5\" },\n { tab: \"科目一1\", key: \"22\" },\n { tab: \"科目二2\", key: \"33\" },\n { tab: \"科目三3\", key: \"44\" },\n { tab: \"科目四4\", key: \"55\", className: \"last\" },\n ]}\n tabBarExtraContent={<div>测试</div>}\n />\n );\n};\n\nrender(<BaseStateExample />);\n\n`,\n scope: [{\n name: \"_StateBar\",\n packageName: \"@components/StateBar\",\n component: component_99\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_109 from '@components/StateTag';\nimport * as component_110 from '@components/Descriptions';\nimport * as component_111 from 'lodash';\nimport * as component_112 from 'antd';\nimport * as component_113 from '@components/Global';\nconst readmeConfig = {\n name: `StateTag`,\n summary: `<p>用于展示标签</p>`,\n \n \n api: `<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>type</td>\n<td>tag的类型,类型决定显示的颜色</td>\n<td>'default'(#666666)、'skill'(#666666)(此时边框颜色为 #EEEEEE)、'success'(#027A48)、'progress'(#F09700)、'danger'(#D14343)、'info'(#155ACF)、'other'(#6740C3)(待定颜色)、'result'(#666666)、'filterResult'(#5CB8B2)</td>\n<td>'default'</td>\n</tr>\n<tr>\n<td>showBorder</td>\n<td>是否展示边框</td>\n<td>boolean</td>\n<td>false</td>\n</tr>\n<tr>\n<td>showBackground</td>\n<td>是否展示背景色</td>\n<td>boolean</td>\n<td>true</td>\n</tr>\n<tr>\n<td>text</td>\n<td>tag文案</td>\n<td>string</td>\n<td>''</td>\n</tr>\n<tr>\n<td>filterName</td>\n<td>tag类型为“filterResult”时显示在前边的文案</td>\n<td>string</td>\n<td>''</td>\n</tr>\n</tbody>\n</table>\n<p>其他参数参考 <a href=\"https://ant.design/components/tag-cn\">antd Tag.Tag</a></p>`,\n example: {\n isFull: true,\n className: ``,\n style: ``,\n list: [{\n title: `基本示例`,\n description: `状态标签`,\n code: `const { default: StateTag } = _StateTag;\nconst { default: Descriptions } = _Descriptions;\nconst { range } = lodash;\nconst { Space, Typography } = antd;\n\nconst BaseExample = () => {\n return (\n <div>\n <div>使用场景: 列表页Table,简历详情页</div>\n <br />\n <Descriptions\n dataSource={[\n [\n { label: \"使用规则\", content: \"待XX,暂停\" },\n {\n label: \"示例\",\n content: (\n <Space>\n <StateTag {...{ type: \"info\", text: \"待提交开票\" }} />\n <Typography.Text\n copyable={{\n text: '<StateTag type=\"info\" text=\"标签内容\" />',\n }}\n />\n </Space>\n ),\n },\n ],\n [\n { label: \"使用规则\", content: \"XX中,正在XX中\" },\n {\n label: \"示例\",\n content: (\n <Space>\n <StateTag {...{ type: \"progress\", text: \"退票审核中\" }} />\n <Typography.Text\n copyable={{\n text: '<StateTag type=\"progress\" text=\"标签内容\" />',\n }}\n />\n </Space>\n ),\n },\n ],\n [\n { label: \"使用规则\", content: \"通过,成功,完成\" },\n {\n label: \"示例\",\n content: (\n <Space>\n <StateTag {...{ type: \"success\", text: \"标签内容\" }} />\n <Typography.Text\n copyable={{\n text: '<StateTag type=\"success\" text=\"标签内容\" />',\n }}\n />\n </Space>\n ),\n },\n ],\n [\n { label: \"使用规则\", content: \"不通过,失败,淘汰,缺席,拒绝\" },\n {\n label: \"示例\",\n content: (\n <Space>\n <StateTag {...{ type: \"danger\", text: \"退票拒绝\" }} />\n <Typography.Text\n copyable={{\n text: '<StateTag type=\"danger\" text=\"标签内容\" />',\n }}\n />\n </Space>\n ),\n },\n ],\n [\n { label: \"使用规则\", content: \"取消,撤销,停止\" },\n {\n label: \"示例\",\n content: (\n <Space>\n <StateTag {...{ type: \"default\", text: \"撤销开票审核\" }} />\n <Typography.Text\n copyable={{\n text: '<StateTag type=\"default\" text=\"标签内容\" />',\n }}\n />\n </Space>\n ),\n },\n ],\n [\n { label: \"使用规则\", content: \"(暂时还未用到)\" },\n {\n label: \"示例\",\n content: (\n <Space>\n <StateTag {...{ type: \"other\", text: \"标签内容\" }} />\n <Typography.Text\n copyable={{\n text: '<StateTag type=\"other\" text=\"标签内容\" />',\n }}\n />\n </Space>\n ),\n },\n ],\n ]}\n />\n <br />\n <br />\n <div>个别特殊场景(需要单独询问UI):</div>\n <br />\n <Descriptions\n dataSource={[\n [\n { label: \"使用规则\", content: \"待XX,暂停\" },\n {\n label: \"示例\",\n content: (\n <div>\n <StateTag {...{ type: \"success\", text: \"已推荐简历\" }} />\n <StateTag {...{ type: \"success\", text: \"已退票\" }} />\n </div>\n ),\n },\n ],\n [\n { label: \"使用规则\", content: \"已XX待XX\" },\n {\n label: \"示例\",\n content: (\n <div>\n <StateTag {...{ type: \"success\", text: \"已开票待寄出\" }} />\n <StateTag {...{ type: \"success\", text: \"已待寄待收款\" }} />\n </div>\n ),\n },\n ],\n [\n {\n label: \"使用规则\",\n content: \"已XX+词语:根据后面的词语语义进行判断\",\n },\n {\n label: \"示例\",\n content: (\n <div>\n <StateTag {...{ type: \"success\", text: \"已成功\" }} />\n <StateTag {...{ type: \"default\", text: \"已取消\" }} />\n <StateTag {...{ type: \"danger\", text: \"已失败\" }} />\n <StateTag {...{ type: \"progress\", text: \"已暂停\" }} />\n </div>\n ),\n },\n ],\n [\n { label: \"使用规则\", content: \"完全根据语义语境判断\" },\n {\n label: \"示例\",\n content: (\n <div>\n <StateTag {...{ type: \"success\", text: \"全部到款\" }} />\n <StateTag {...{ type: \"success\", text: \"部分到款\" }} />\n <StateTag {...{ type: \"success\", text: \"简历亮点\" }} />\n <StateTag {...{ type: \"danger\", text: \"简历风险点\" }} />\n </div>\n ),\n },\n ],\n ]}\n />\n </div>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_StateTag\",\n packageName: \"@components/StateTag\",\n component: component_109\n},{\n name: \"_Descriptions\",\n packageName: \"@components/Descriptions\",\n component: component_110\n},{\n name: \"lodash\",\n packageName: \"lodash\",\n component: component_111\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_112\n}]\n},{\n title: `基本示例`,\n description: `技能标签`,\n code: `const { default: StateTag } = _StateTag;\n\nconst BaseExample = () => {\n return (\n <div>\n <StateTag\n text={\"技能标签\"}\n type={\"skill\"}\n showBorder\n showBackground={false}\n />\n </div>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_StateTag\",\n packageName: \"@components/StateTag\",\n component: component_109\n}]\n},{\n title: `基本示例`,\n description: `下拉菜单、弹窗中已选结果标签`,\n code: `const { default: StateTag } = _StateTag;\n\nconst BaseExample = () => {\n return (\n <div>\n <StateTag\n text={\"技能标签\"}\n type={\"result\"}\n showBackground={false}\n closable\n onClose={() => console.log(\"close\")}\n />\n <StateTag\n text={\"技能标签\"}\n type={\"result\"}\n closable\n onClose={() => console.log(\"close\")}\n />\n </div>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_StateTag\",\n packageName: \"@components/StateTag\",\n component: component_109\n}]\n},{\n title: `基本示例`,\n description: `筛选组件中筛选结果标签`,\n code: `const { default: StateTag } = _StateTag;\n\nconst BaseExample = () => {\n return (\n <div>\n <StateTag\n filterName={\"BD\"}\n text={\"陈枫林,王晓晨\"}\n type={\"filterResult\"}\n closable\n onClose={() => console.log(\"close\")}\n />\n <br />\n <StateTag\n filterName={\"添加人\"}\n text={\"陈枫林,王晓晨,陈路,张力\"}\n type={\"filterResult\"}\n closable\n onClose={() => console.log(\"close\")}\n />\n </div>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_StateTag\",\n packageName: \"@components/StateTag\",\n component: component_109\n}]\n},{\n title: `基本示例`,\n description: `枚举状态标签`,\n code: `const { StateTagEnum } = _StateTag;\nconst { PureGlobal } = global;\nconst { Space } = antd;\n\nconst BaseExample = ()=>{\n return (\n <PureGlobal\n preset={{\n locale: \"zh-CN\",\n enums: {\n testEnums: async ({ locale }) => {\n console.log(locale);\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve([\n { value: \"1\", description: \"第一项\", type: 'success' },\n { value: \"2\", description: \"第二项\", type: 'danger' },\n { value: \"3\", description: \"第三项\", type: 'info'},\n ]);\n }, 1000);\n });\n },\n },\n }}\n >\n <Space>\n <StateTagEnum moduleName=\"testEnums\" name=\"1\" />\n <StateTagEnum moduleName=\"testEnums\" name=\"2\" />\n <StateTagEnum moduleName=\"testEnums\" name=\"3\" />\n </Space>\n </PureGlobal>\n )\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_StateTag\",\n packageName: \"@components/StateTag\",\n component: component_109\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_112\n},{\n name: \"global\",\n packageName: \"@components/Global\",\n component: component_113\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_104 from '@components/Table';\nimport * as component_105 from '@components/Global';\nimport * as component_106 from '@kne/react-fetch';\nimport * as component_107 from 'lodash';\nimport * as component_108 from 'antd';\nconst readmeConfig = {\n name: `Table`,\n summary: `<p>可以从后端获取数据,然后展示为一个表格</p>`,\n \n \n api: `<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n</table>`,\n example: {\n isFull: true,\n className: ``,\n style: ``,\n list: [{\n title: `这里填写示例标题`,\n description: `这里填写示例说明`,\n code: `const { default: Table } = _Table;\nconst { PureGlobal } = _Global;\nconst { preset } = reactFetch;\n\nconst ajax = (config) => {\n return new Promise((resolve) => {\n setTimeout(() => {\n if (config.url === \"/api/v1/user/user/user_key_get\") {\n resolve({\n data: {\n code: 0,\n data: \\`{\"date\":{\"visible\":false},\"serialNumber\":{\"width\":400}}\\`,\n },\n });\n } else if (config.url === \"/api/v1/user/user/user_key_set\") {\n console.log(config.data);\n resolve({\n data: {\n code: 0,\n data: \"\",\n },\n });\n }\n }, 100);\n });\n};\n\npreset({\n ajax,\n});\n\nconst BaseExample = () => {\n return (\n <PureGlobal\n preset={{\n ajax /*tableServerApis: {\n getDataApi: (name) => {\n return {\n url: \"/api/v1/user/user/user_key_get\",\n method: \"GET\",\n params: {\n key: \\`table_config_v2_\\${name}\\`,\n },\n transformResponse: (response) => {\n const { data } = response;\n response.data = Object.assign({}, data, {\n data: (() => {\n try {\n return JSON.parse(data.data);\n } catch (e) {\n return [];\n }\n })(),\n });\n\n response.data = {\n code: response.data.code === 0 ? 200 : data.code,\n msg: response.data.msg,\n results: response.data.data,\n };\n\n return response;\n },\n cache: \"TABLE_PAGE_CONFIG\",\n };\n },\n setDataFunc: (name, data) => {\n return ajax({\n url: \"/api/v1/user/user/user_key_set\",\n data: {\n map: {\n [\\`table_config_v2_\\${name}\\`]: JSON.stringify(data),\n },\n },\n });\n },\n },*/,\n }}\n >\n <Table\n name=\"test-table\"\n onTablePropsReady={({ columns, dataSource }) => {\n console.log({ columns, dataSource });\n }}\n dataSource={[\n {\n id: 0,\n date: \"2021-07-21\",\n datetime: \"2023-07-22 09:00:00\",\n serialNumber: \"SX00192932323434\",\n serialNumberShort: \"SH0023\",\n userName: \"林珊珊\",\n title: \"我是主要字段\",\n tagEnum: null,\n enUserName: \"Lin Shanshan\",\n phoneNumber: \"+86 18792877372\",\n email: \"a@a.com\",\n count: 4,\n description:\n \"我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述\",\n description2:\n \"我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述\",\n other: \"其他信息\",\n },\n {\n id: 1,\n date: \"\",\n datetime: \"2023-07-22 09:00:00\",\n serialNumber: \"SX00192932323434\",\n serialNumberShort: \"SH0023\",\n userName: \"林珊珊1\",\n title: \"我是主要字段\",\n tagEnum: \"Y\",\n enUserName: \"Lin Shanshan\",\n phoneNumber: null,\n email: \"a@a.com\",\n count: 5,\n description: \"我是一段描述\",\n description2: \"我是一段描述\",\n other: \"其他信息\",\n },\n ]}\n columns={[\n {\n name: \"date\",\n title: \"日期\",\n type: \"date\",\n hover: true,\n },\n {\n name: \"datetime\",\n title: \"日期时间\",\n type: \"datetime\",\n hideSecond: true,\n },\n {\n name: \"serialNumber\",\n title: \"编号\",\n type: \"serialNumber\",\n primary: true,\n onClick: async (item) => {\n console.log(item);\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve(true);\n }, 10000);\n });\n },\n },\n {\n name: \"serialNumberShort\",\n title: \"短编号\",\n type: \"serialNumberShort\",\n },\n {\n name: \"title\",\n title: \"主要信息\",\n type: \"mainInfo\",\n },\n {\n name: \"tag\",\n title: \"状态标签\",\n type: \"tag\",\n valueOf: () => ({ type: \"success\", text: \"审核通过\" }),\n },\n {\n name: \"tagEnum\",\n title: \"标签枚举\",\n type: \"tag\",\n valueOf: (item) =>\n item.tagEnum && {\n type: \"success\",\n isEnum: true,\n moduleName: \"marital\",\n name: item.tagEnum,\n },\n },\n {\n name: \"avatar\",\n title: \"头像\",\n type: \"avatar\",\n valueOf: () => ({ gender: \"F\" }),\n },\n {\n name: \"user\",\n title: \"用户\",\n type: \"user\",\n valueOf: (item) => \\`\\${item.enUserName} \\${item.userName}\\`,\n },\n {\n name: \"hideInfo\",\n title: \"隐藏字段\",\n type: \"hideInfo\",\n valueOf: (item) =>\n item[\"phoneNumber\"] && {\n loader: () => {\n return item[\"phoneNumber\"] + \"-\" + item[\"id\"];\n },\n },\n },\n {\n name: \"userName\",\n title: \"用户名\",\n type: \"userName\",\n },\n {\n name: \"contacts\",\n title: \"联系人\",\n type: \"contacts\",\n valueOf: (item) => \\`\\${item.userName} \\${item.phoneNumber}\\`,\n },\n {\n name: \"count\",\n title: \"数量\",\n type: \"singleRow\",\n render: ({ target }) => {\n return target.count === 5 ? { hover: true } : { hover: false };\n },\n },\n {\n name: \"description\",\n title: \"描述\",\n type: \"description\",\n },\n {\n name: \"description2\",\n title: \"描述(省略)\",\n type: \"description\",\n ellipsis: true,\n },\n {\n name: \"other\",\n title: \"其他\",\n type: \"other\",\n hover: true,\n },\n {\n name: \"options\",\n title: \"操作\",\n type: \"options\",\n valueOf: (item) => [\n {\n onClick: () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve();\n }, 1000);\n });\n },\n children: \"分配\",\n message: \"确定要分配吗\",\n isDelete: false,\n },\n {\n children: \"审核\",\n },\n {\n onClick: () => {\n console.log(item);\n },\n children: \"淘汰\",\n },\n {\n onClick: () => {\n console.log(item);\n },\n children: \"一键约面\",\n },\n {\n children: \"删除\",\n confirm: true,\n onClick: () => {\n console.log(\"删除\");\n },\n },\n ],\n },\n ]}\n />\n </PureGlobal>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Table\",\n packageName: \"@components/Table\",\n component: component_104\n},{\n name: \"_Global\",\n packageName: \"@components/Global\",\n component: component_105\n},{\n name: \"reactFetch\",\n packageName: \"@kne/react-fetch\",\n component: component_106\n}]\n},{\n title: `这里填写示例标题`,\n description: `这里填写示例说明`,\n code: `const { PureGlobal } = _Global;\nconst { TablePage } = _Table;\nconst { range } = lodash;\nconst BaseExample = () => {\n return (\n <PureGlobal\n preset={{\n features: {\n debug: true,\n profile: {\n id: \"erc\",\n type: \"system\",\n name: \"业务系统\",\n children: [\n {\n id: \"test\",\n type: \"feature\",\n name: \"测试功能\",\n options: {\n hiddenColumns: [\"date\", \"datetime\"],\n },\n },\n ],\n },\n },\n }}\n >\n <TablePage\n featureId=\"test\"\n name=\"test-2\"\n sticky={false}\n rowSelection={{\n type: \"checkbox\",\n }}\n loader={() => {\n return {\n addUserName: \"我是大魔王\",\n pageData: range(0, 50).map((index) => ({\n id: index,\n date: \"2021-07-21\",\n datetime: \"2023-07-22 09:00:00\",\n serialNumber: \"SX00192932323434\",\n serialNumberShort: \"SH0023\",\n userName: \"林珊珊\" + index,\n title: \"我是主要字段\",\n enUserName: \"Lin Shanshan\",\n phoneNumber: \"+86 18792877372\",\n email: \"a@a.com\",\n count: 5,\n description:\n \"我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述\",\n other: \"其他信息\",\n })),\n totalCount: 50,\n };\n }}\n columns={[\n {\n name: \"date\",\n title: \"日期\",\n type: \"date\",\n hover: true,\n },\n {\n name: \"datetime\",\n title: \"日期时间\",\n type: \"datetime\",\n },\n {\n name: \"dateRange\",\n title: \"日期范围\",\n type: \"dateRange\",\n valueOf: ({ date, datetime }) => [date, datetime],\n },\n {\n name: \"serialNumber\",\n title: \"编号\",\n type: \"serialNumber\",\n primary: true,\n },\n {\n name: \"serialNumberShort\",\n title: \"短编号\",\n type: \"serialNumberShort\",\n },\n {\n name: \"title\",\n title: \"主要信息\",\n type: \"mainInfo\",\n },\n {\n name: \"phone\",\n title: \"手机号\",\n type: \"hideInfo\",\n primary: true,\n valueOf: (item) => ({\n loader: () => {\n return item[\"phoneNumber\"] + \"-\" + item[\"id\"];\n },\n }),\n },\n {\n name: \"email\",\n title: \"邮箱\",\n type: \"hideInfo\",\n valueOf: (item) => ({\n loader: () => {\n return item[\"email\"] + \"-\" + item[\"id\"];\n },\n children: (data) => {\n return \\`\\${data},\\${item[\"userName\"]}\\`;\n },\n }),\n },\n {\n name: \"tag\",\n title: \"状态标签\",\n type: \"tag\",\n valueOf: () => ({ type: \"success\", text: \"审核通过\" }),\n },\n {\n name: \"avatar\",\n title: \"头像\",\n type: \"avatar\",\n valueOf: () => ({ gender: \"F\" }),\n },\n {\n name: \"user\",\n title: \"用户\",\n type: \"user\",\n valueOf: (item) => \\`\\${item.enUserName} \\${item.userName}\\`,\n },\n {\n name: \"userName\",\n title: \"用户名\",\n type: \"userName\",\n },\n {\n name: \"contacts\",\n title: \"联系人\",\n type: \"contacts\",\n valueOf: (item) => \\`\\${item.userName} \\${item.phoneNumber}\\`,\n },\n {\n name: \"count\",\n title: \"数量\",\n type: \"singleRow\",\n },\n {\n name: \"description\",\n title: \"描述(省略)\",\n type: \"description\",\n ellipsis: true,\n },\n {\n name: \"other\",\n title: \"其他\",\n type: \"other\",\n hover: true,\n },\n {\n name: \"addUser\",\n title: \"添加人\",\n type: \"user\",\n render: ({ data }) => ({ valueOf: () => data.addUserName }),\n },\n {\n name: \"options\",\n title: \"操作\",\n type: \"options\",\n fixed: \"right\",\n valueOf: (item) => [\n {\n onClick: () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve();\n }, 1000);\n });\n },\n children: \"编辑\",\n disabled: true,\n tooltipProps: {\n title: \"不能编辑这条信息\",\n },\n },\n {\n children: \"审核\",\n tooltipProps: {\n title: (\n <div\n style={{ padding: \"10px\", backgroundColor: \"skyblue\" }}\n >\n 审核操作的tooltip\n </div>\n ),\n },\n },\n {\n onClick: () => {\n console.log(item);\n },\n children: \"淘汰\",\n },\n {\n onClick: () => {\n console.log(item);\n },\n children: \"一键约面\",\n },\n {\n children: \"删除\",\n },\n ],\n },\n ]}\n />\n </PureGlobal>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Table\",\n packageName: \"@components/Table\",\n component: component_104\n},{\n name: \"lodash\",\n packageName: \"lodash\",\n component: component_107\n},{\n name: \"_Global\",\n packageName: \"@components/Global\",\n component: component_105\n}]\n},{\n title: `这里填写示例标题`,\n description: `这里填写示例说明`,\n code: `const { default: Table } = _Table;\nconst { PureGlobal } = _Global;\nconst { preset } = reactFetch;\nconst { useState } = React;\nconst { Input } = antd;\nconst ajax = (config) => {\n return new Promise((resolve) => {\n setTimeout(() => {\n if (config.url === \"/api/v1/user/user/user_key_get\") {\n resolve({\n data: {\n code: 0,\n data: \\`{\"date\":{},\"serialNumber\":{\"width\":400}}\\`,\n },\n });\n } else if (config.url === \"/api/v1/user/user/user_key_set\") {\n console.log(config.data);\n resolve({\n data: {\n code: 0,\n data: \"\",\n },\n });\n }\n }, 100);\n });\n};\n\npreset({\n ajax,\n});\n\nconst ValueEdit = ({ value, targetRender }) => {\n const [isEdit, setIsEdit] = useState(false);\n return (\n <span\n onClick={() => {\n setIsEdit(true);\n }}\n >\n {isEdit ? (\n <Input\n type=\"text\"\n size=\"small\"\n defaultValue={value}\n onBlur={() => {\n setIsEdit(false);\n }}\n />\n ) : (\n targetRender(value)\n )}\n </span>\n );\n};\n\nconst BaseExample = () => {\n return (\n <PureGlobal\n preset={{\n ajax,\n tableServerApis: {\n getDataApi: (name) => {\n return {\n url: \"/api/v1/user/user/user_key_get\",\n method: \"GET\",\n params: {\n key: \\`table_config_v2_\\${name}\\`,\n },\n transformResponse: (response) => {\n const { data } = response;\n response.data = Object.assign({}, data, {\n data: (() => {\n try {\n return JSON.parse(data.data);\n } catch (e) {\n return [];\n }\n })(),\n });\n\n response.data = {\n code: response.data.code === 0 ? 200 : data.code,\n msg: response.data.msg,\n results: response.data.data,\n };\n\n return response;\n },\n cache: \"TABLE_PAGE_CONFIG\",\n };\n },\n setDataFunc: (name, data) => {\n return ajax({\n url: \"/api/v1/user/user/user_key_set\",\n data: {\n map: {\n [\\`table_config_v2_\\${name}\\`]: JSON.stringify(data),\n },\n },\n });\n },\n },\n }}\n >\n <Table\n name=\"test-table\"\n dataSource={[\n {\n id: 0,\n date: \"2021-07-21\",\n datetime: \"2023-07-22 09:00:00\",\n serialNumber: \"SX00192932323434\",\n serialNumberShort: \"SH0023\",\n userName: \"林珊珊\",\n title: \"我是主要字段\",\n tagEnum: \"Y\",\n enUserName: \"Lin Shanshan\",\n phoneNumber: \"+86 18792877372\",\n email: \"a@a.com\",\n count: 4,\n description:\n \"我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述\",\n description2:\n \"我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述我是一段描述\",\n other: \"其他信息\",\n },\n {\n id: 1,\n date: \"\",\n datetime: \"2023-07-22 09:00:00\",\n serialNumber: \"SX00192932323434\",\n serialNumberShort: \"SH0023\",\n userName: \"林珊珊1\",\n title: \"我是主要字段\",\n tagEnum: \"Y\",\n enUserName: \"Lin Shanshan\",\n phoneNumber: \"+86 18792877372\",\n email: \"a@a.com\",\n count: 5,\n description: \"我是一段描述\",\n description2: \"我是一段描述\",\n other: \"其他信息\",\n },\n ]}\n columns={[\n {\n name: \"date\",\n title: \"日期\",\n sort: true,\n groupHeader: [\n {\n name: \"group1\",\n title: \"分组1\",\n },\n {\n name: \"group1-1\",\n title: \"分组1-1\",\n },\n ],\n type: \"date\",\n hover: true,\n },\n {\n name: \"datetime\",\n title: \"日期时间\",\n sort: true,\n groupHeader: [\n {\n name: \"group1\",\n title: \"分组1\",\n },\n {\n name: \"group1-2\",\n title: \"分组1-2\",\n },\n ],\n type: \"datetime\",\n },\n {\n name: \"serialNumber\",\n title: \"编号\",\n sort: true,\n groupHeader: [\n {\n name: \"group1\",\n title: \"分组1\",\n },\n {\n name: \"group1-1\",\n title: \"分组1-1\",\n },\n ],\n type: \"serialNumber\",\n primary: true,\n },\n {\n name: \"serialNumberShort\",\n title: \"短编号\",\n type: \"serialNumberShort\",\n },\n {\n name: \"title\",\n title: \"主要信息\",\n type: \"mainInfo\",\n disableColItem: true,\n valueOf: (item, { targetRender }) => (\n <ValueEdit value={item[\"title\"]} targetRender={targetRender} />\n ),\n },\n {\n name: \"tag\",\n title: \"状态标签\",\n type: \"tag\",\n valueOf: () => ({ type: \"success\", text: \"审核通过\" }),\n },\n {\n name: \"tagEnum\",\n title: \"标签枚举\",\n type: \"tag\",\n valueOf: (item) => ({\n type: \"success\",\n isEnum: true,\n moduleName: \"marital\",\n name: item.tagEnum,\n }),\n },\n {\n name: \"avatar\",\n title: \"头像\",\n type: \"avatar\",\n valueOf: () => ({ gender: \"F\" }),\n },\n {\n name: \"user\",\n title: \"用户\",\n type: \"user\",\n valueOf: (item) => \\`\\${item.enUserName} \\${item.userName}\\`,\n },\n {\n name: \"hideInfo\",\n title: \"隐藏字段\",\n type: \"hideInfo\",\n valueOf: (item) => ({\n loader: () => {\n return item[\"phoneNumber\"] + \"-\" + item[\"id\"];\n },\n }),\n },\n {\n name: \"userName\",\n title: \"用户名\",\n type: \"userName\",\n },\n {\n name: \"contacts\",\n title: \"联系人\",\n type: \"contacts\",\n valueOf: (item) => \\`\\${item.userName} \\${item.phoneNumber}\\`,\n },\n {\n name: \"count\",\n title: \"数量\",\n type: \"singleRow\",\n render: ({ target }) => {\n return target.count === 5 ? { hover: true } : { hover: false };\n },\n },\n {\n name: \"description\",\n title: \"描述\",\n type: \"description\",\n },\n {\n name: \"description2\",\n title: \"描述(省略)\",\n type: \"description\",\n ellipsis: true,\n },\n {\n name: \"other\",\n title: \"其他\",\n type: \"other\",\n hover: true,\n sort: true,\n },\n {\n name: \"options\",\n title: \"操作\",\n type: \"options\",\n fixed: \"right\",\n sort: true,\n valueOf: (item) => [\n {\n onClick: () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve();\n }, 1000);\n });\n },\n children: \"分配Program及教练\",\n },\n {\n children: \"审核\",\n },\n {\n onClick: () => {\n console.log(item);\n },\n children: \"淘汰\",\n },\n {\n onClick: () => {\n console.log(item);\n },\n children: \"一键约面\",\n },\n {\n children: \"删除\",\n },\n ],\n },\n ]}\n onSortChange={(sort) => {\n console.log(\">>>>>>\", sort);\n }}\n />\n </PureGlobal>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Table\",\n packageName: \"@components/Table\",\n component: component_104\n},{\n name: \"_Global\",\n packageName: \"@components/Global\",\n component: component_105\n},{\n name: \"reactFetch\",\n packageName: \"@kne/react-fetch\",\n component: component_106\n},{\n name: \"antd\",\n packageName: \"antd\",\n component: component_108\n}]\n}]\n }\n};\nexport default readmeConfig;\n","import * as component_114 from '@components/Tooltip';\nimport * as component_115 from 'antd/lib/space';\nimport * as component_116 from '@components/FormInfo';\nimport * as component_117 from '@kne/react-fetch';\nimport * as component_118 from '@components/Descriptions';\nimport * as component_119 from '@components/StateTag';\nconst readmeConfig = {\n name: `Tooltip`,\n summary: `<p>简单的文字提示气泡框</p>`,\n \n \n api: `<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>size</td>\n<td>默认宽度 360,small 宽度 240</td>\n<td>string</td>\n<td>-</td>\n</tr>\n<tr>\n<td>title</td>\n<td>标题内容</td>\n<td>string,jsx</td>\n<td>-</td>\n</tr>\n<tr>\n<td>showInfo</td>\n<td>展示标题旁的提示按钮</td>\n<td>boolean</td>\n<td>-</td>\n</tr>\n<tr>\n<td>importantInfo</td>\n<td>重要内容</td>\n<td>string,jsx</td>\n<td>-</td>\n</tr>\n<tr>\n<td>subtitle</td>\n<td>副标题</td>\n<td>string,jsx</td>\n<td>-</td>\n</tr>\n<tr>\n<td>content</td>\n<td>内容</td>\n<td>string,jsx</td>\n<td>-</td>\n</tr>\n<tr>\n<td>importantInfoType</td>\n<td>重要内容类型,success,error,warning</td>\n<td>string,jsx</td>\n<td>-</td>\n</tr>\n<tr>\n<td>moreInfo</td>\n<td>其他内容</td>\n<td>jsx</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>\n<h3>TooltipFetch</h3>\n<table>\n<thead>\n<tr>\n<th>属性名</th>\n<th>说明</th>\n<th>类型</th>\n<th>默认值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>api</td>\n<td>获取数据的接口,参考@kne/react-fetch</td>\n<td>object</td>\n<td>-</td>\n</tr>\n<tr>\n<td>fetchContent</td>\n<td>当api接口返回值的时候调用,可以获取到接口参数,返回值会更新到Tootip的参数中</td>\n<td>function</td>\n<td>-</td>\n</tr>\n</tbody>\n</table>`,\n example: {\n isFull: false,\n className: ``,\n style: ``,\n list: [{\n title: `这里填写示例标题`,\n description: `这里填写示例说明`,\n code: `const { default: Tooltip, TooltipInfoLabel } = _Tooltip;\nconst { default: Space } = space;\nconst {\n default: FormInfo,\n Form,\n Input,\n TypeDateRangePicker,\n SubmitButton,\n CancelButton,\n} = formInfo;\n\nconst MoreInfo = () => {\n return (\n <Form>\n <FormInfo\n column={1}\n list={[\n <Input label=\"姓名\" name=\"name\" rule=\"REQ\" />,\n <TypeDateRangePicker\n name=\"type_date\"\n label=\"日期时间段\"\n rule=\"REQ\"\n />,\n <Space\n style={{\n width: \"100%\",\n justifyContent: \"end\",\n }}\n >\n <CancelButton>取消</CancelButton>\n <SubmitButton>确定</SubmitButton>\n </Space>,\n ]}\n />\n </Form>\n );\n};\n\nconst BaseExample = () => {\n return (\n <Space>\n <Tooltip content=\"这里显示完整的信息\">小段信息</Tooltip>\n <Tooltip\n size=\"small\"\n content=\"这里显示完整的信息完整的信息,这里显示完整的信息完整的信息这里显示完整的信息完整的信息这里显示完整的信息完整的信息,这里显示完整的信息。\"\n >\n 大段信息\n </Tooltip>\n <Tooltip title=\"标题\" content=\"内容描述内容描述内容。\">\n 带有标题的小段信息\n </Tooltip>\n <Tooltip\n title=\"标题\"\n content=\"内容描述内容描述内容描述内容描述内容描述内容描述内容描述内容描述内容描述内容描述内容描述\"\n >\n 带有标题的大段信息\n </Tooltip>\n <Tooltip\n importantInfo=\"筛选日期范围内,职位上安排顾问面试的候选人总数。根据所填写的顾问【面试面试】时间来进行统计,而非在系统的操作时间。\"\n subtitle=\"示例:\"\n content=\"2022.10.21在系统操作顾问面试,但填写的顾问面试时间为2022.10.20,则数据会统计在2022.10.20,而非2022.10.21 。\"\n >\n 带有重要信息\n </Tooltip>\n <TooltipInfoLabel\n title=\"带有Info信息\"\n tooltipTitle={{\n importantInfo:\n \"筛选日期范围内,职位上安排顾问面试的候选人总数。根据所填写的顾问【面试面试】时间来进行统计,而非在系统的操作时间。\",\n subtitle: \"示例:\",\n content:\n \"2022.10.21在系统操作顾问面试,但填写的顾问面试时间为2022.10.20,则数据会统计在2022.10.20,而非2022.10.21 。\",\n }}\n />\n <Tooltip\n trigger=\"click\"\n title=\"标题\"\n content=\"辅助信息描述内容辅助信息描述内容辅助信息描述内容辅助信息描述内容辅助信息描述内容\"\n moreInfo={<MoreInfo />}\n >\n 带有表单信息\n </Tooltip>\n </Space>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Tooltip\",\n packageName: \"@components/Tooltip\",\n component: component_114\n},{\n name: \"space\",\n packageName: \"antd/lib/space\",\n component: component_115\n},{\n name: \"formInfo\",\n packageName: \"@components/FormInfo\",\n component: component_116\n}]\n},{\n title: `带有远程数据加载的提示`,\n description: `展示带有远程数据加载的提示`,\n code: `const { TooltipFetch } = _Tooltip;\nconst { preset } = reactFetch;\nconst { default: Descriptions } = _Descriptions;\nconst { default: StateTag } = _StateTag;\n\npreset({\n ajax: () => {\n return new Promise((resolve) => {\n setTimeout(() => {\n resolve({\n data: {\n code: 0,\n data: {\n clientName: \"腾讯\",\n title: \"腾讯科技公司\",\n type: \"增值税专用发票\",\n date: \"2022-08-15\",\n },\n },\n });\n }, 1000);\n });\n },\n});\n\nconst BaseExample = () => {\n return (\n <TooltipFetch\n api={{\n url: \"/api/data\",\n }}\n size=\"large\"\n fetchContent={(data) => {\n return {\n content: (\n <Descriptions\n dataSource={[\n [\n { label: \"客户名称\", content: data.clientName },\n { label: \"发票抬头\", content: data.title },\n ],\n [\n { label: \"发票类型\", content: data.type },\n { label: \"发票日期\", content: data.date },\n ],\n ]}\n />\n ),\n };\n }}\n >\n <StateTag text=\"哈哈哈\" />\n </TooltipFetch>\n );\n};\n\nrender(<BaseExample />);\n\n`,\n scope: [{\n name: \"_Tooltip\",\n packageName: \"@components/Tooltip\",\n component: component_114\n},{\n name: \"reactFetch\",\n packageName: \"@kne/react-fetch\",\n component: component_117\n},{\n name: \"_Descriptions\",\n packageName: \"@components/Descriptions\",\n component: component_118\n},{\n name: \"_StateTag\",\n packageName: \"@components/StateTag\",\n component: component_119\n}]\n}]\n }\n};\nexport default readmeConfig;\n","// extracted by mini-css-extract-plugin\nexport default {\"overlay\":\"style_overlay__ZS5Wz__CoAiq\",\"overlay-content\":\"style_overlay-content__IVFmc__CoAiq\",\"state-tag\":\"style_state-tag__+59RJ__CoAiq\"};","import style from \"./style.module.scss\";\nimport {\n useState, useCallback, useEffect, useRef, useLayoutEffect,\n} from \"react\";\nimport localStorage from \"@common/utils/localStorage\";\nimport StateTag from \"@components/StateTag\";\nimport {Popover, Space} from \"antd\";\nimport dropWhile from \"lodash/dropWhile\";\nimport uniqBy from \"lodash/uniqBy\";\nimport useClickOutside from \"@kne/use-click-outside\";\nimport classnames from \"classnames\";\n\nconst HistoryStore = ({\n className,\n overlayClassName,\n storeName = 'HISTORY_STORE_KEY',\n maxLength = 5,\n label = '最近搜索',\n children,\n onSelect,\n zIndex,\n getPopupContainer,\n }) => {\n const [list, setList] = useState(() => {\n return localStorage.getItem(storeName) || [];\n });\n const [open, setOpen] = useState(false);\n const openHistory = useCallback(() => {\n if (list.length === 0) {\n return;\n }\n setOpen(true);\n }, [list]);\n const storeNameRef = useRef(storeName);\n storeNameRef.current = storeName;\n useEffect(() => {\n localStorage.setItem(storeNameRef.current, list);\n }, [list]);\n\n const appendHistory = useCallback((item) => {\n if (item.value && item.label) {\n setList((list) => {\n const newList = dropWhile(list, {value: item.value});\n newList.splice(0, 0, item);\n return maxLength ? uniqBy(newList, \"value\").slice(0, maxLength) : newList;\n });\n }\n setOpen(false);\n }, [maxLength]);\n\n const close = useCallback(() => {\n setOpen(false);\n }, []);\n\n const outerRef = useClickOutside(close);\n\n const popoverChildrenRef = useRef(null), popoverContentRef = useRef(null);\n outerRef.current = {\n contains: (target) => {\n return (popoverChildrenRef.current.contains(target) || (open && popoverContentRef.current.contains(target)));\n },\n };\n\n const onSelectRef = useRef(null);\n const setOnSelect = (callback) => {\n onSelectRef.current = callback;\n };\n\n const [width, setWidth] = useState(0);\n\n useLayoutEffect(() => {\n const callback = () => {\n setWidth(popoverChildrenRef.current.clientWidth);\n };\n callback();\n const resizeObserver = new ResizeObserver(callback);\n resizeObserver.observe(popoverChildrenRef.current);\n const mutationObserver = new MutationObserver(callback);\n mutationObserver.observe(popoverChildrenRef.current, {\n subtree: true, childList: true,\n });\n return () => {\n mutationObserver.disconnect();\n resizeObserver.disconnect();\n };\n }, []);\n\n return (<Popover\n zIndex={zIndex}\n placement=\"bottom\"\n transitionName={\"ant-slide-up\"}\n arrow={false}\n open={open}\n getPopupContainer={getPopupContainer}\n overlayClassName={classnames(overlayClassName, style[\"overlay\"])}\n content={<div\n className={style[\"overlay-content\"]}\n style={{width}}\n ref={popoverContentRef}\n >\n <Space direction=\"vertical\">\n <div>{label}</div>\n <Space wrap>\n {list.map((item) => (<StateTag\n className={style[\"state-tag\"]}\n text={item.label}\n type={\"result\"}\n onClick={() => {\n onSelect && onSelect(item.value, item);\n onSelectRef.current && onSelectRef.current(item.value, item);\n close();\n appendHistory(item);\n }}\n />))}\n </Space>\n </Space>\n </div>}\n >\n <div ref={popoverChildrenRef} className={classnames(className)}>\n {children({\n open, openHistory, appendHistory, setOnSelect, close,\n })}\n </div>\n </Popover>);\n};\n\nexport default HistoryStore;\n"],"names":["name","summary","api","example","isFull","className","style","list","title","description","code","scope","packageName","importStatement","component","ButtonText","_ref","overlayClassName","storeName","maxLength","label","children","onSelect","zIndex","getPopupContainer","setList","useState","localStorage","getItem","open","setOpen","openHistory","useCallback","length","storeNameRef","useRef","current","useEffect","setItem","appendHistory","item","value","newList","dropWhile","splice","uniqBy","slice","close","outerRef","useClickOutside","popoverChildrenRef","popoverContentRef","contains","target","onSelectRef","width","setWidth","useLayoutEffect","callback","clientWidth","resizeObserver","ResizeObserver","observe","mutationObserver","MutationObserver","subtree","childList","disconnect","_jsx","Popover","placement","transitionName","arrow","classnames","content","ref","_jsxs","Space","direction","wrap","map","StateTag","text","type","onClick","setOnSelect"],"sourceRoot":""}