{"id":23468223,"url":"https://github.com/docoder/kitten","last_synced_at":"2025-06-14T16:34:32.874Z","repository":{"id":35001114,"uuid":"196336655","full_name":"docoder/kitten","owner":"docoder","description":"🐈 Server JSON driving UI","archived":false,"fork":false,"pushed_at":"2023-01-04T21:54:25.000Z","size":2100,"stargazers_count":5,"open_issues_count":32,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-15T01:19:47.347Z","etag":null,"topics":["components","json","kitten","kittenjs","kittenjs-default-ui","react","typescript","ui"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/docoder.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-07-11T06:51:51.000Z","updated_at":"2020-04-28T09:09:10.000Z","dependencies_parsed_at":"2023-01-15T12:01:04.508Z","dependency_job_id":null,"html_url":"https://github.com/docoder/kitten","commit_stats":null,"previous_names":[],"tags_count":51,"template":false,"template_full_name":null,"purl":"pkg:github/docoder/kitten","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docoder%2Fkitten","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docoder%2Fkitten/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docoder%2Fkitten/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docoder%2Fkitten/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/docoder","download_url":"https://codeload.github.com/docoder/kitten/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docoder%2Fkitten/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259845897,"owners_count":22920822,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["components","json","kitten","kittenjs","kittenjs-default-ui","react","typescript","ui"],"created_at":"2024-12-24T13:39:38.717Z","updated_at":"2025-06-14T16:34:32.834Z","avatar_url":"https://github.com/docoder.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"#\"\u003e\n    \u003cimg alt=\"kitten\" src=\"https://raw.githubusercontent.com/docoder/kitten/master/assets/kitten.png\" width=\"128\"\u003e\n  \u003c/a\u003e\n  \u003ch3 align=\"center\"\u003e\n    Kitten\n    \u003c/h3\u003e\n\u003c/div\u003e\n\u003cdiv align=\"center\"\u003e\n  Server JSON Driving UI\n\n [![NPM](https://img.shields.io/npm/v/kittenjs.svg)](https://www.npmjs.com/package/kittenjs)  [![NPM](https://img.shields.io/npm/v/kittenjs-default-ui.svg)](https://www.npmjs.com/package/kittenjs-default-ui)\n\n\u003c/div\u003e\n\n# 📦 Installation\n\n#### 1.kittenjs\n\n```bash\nyarn add react kittenjs\n```\n\n#### 2.kittenjs-default-ui\n\n```bash\nyarn add react-dom react-router-dom antd ant-colony-ui styled-components kittenjs-default-ui\n```\n\n# 🔨 Usage\n\n**You can see [example ](https://github.com/docoder/kitten/tree/master/example) for detail**\n\n#### 1. Use as a whole application (`example/index.tsx`)\n\n```typescript\nimport { Kitten } from 'kittenjs'\nimport { Renderer, ui } from 'kittenjs-default-ui'\nimport Sub1ListPlugin from './plugins/Sub1ListPlugin'\nimport OtherListPlugin from './plugins/OtherListPlugin'\nconst app = new Kitten(ui, {\n    appKey: \"ke\",\n    appTitle: 'Kitten Example',\n    pageAPI: 'http://api.example.com/pages',\n    loginUrl: 'http://api.example.com/login',\n    menus: [\n        {\n            key: 'dashbord',\n            label: '仪表盘',\n            index: true,\n            pageJSON: []\n        }, {\n            label: '菜单 1',\n            subs: [\n                {\n                    label: '子菜单 1',\n                    key: 'sub1',\n                },\n                {\n                    label: '子菜单 2',\n                    key: 'sub2'\n                }\n            ]\n        }\n    ],\n}, [\n    new Sub1ListPlugin(), // plugins\n    new OtherListPlugin()\n], [\n    'beforeTableColumnFinalization'  // debug kitten hooks\n])\napp.render(Renderer,  document.getElementById('root')!)\n```\n#### 2. Use as a partial component (`example/index-partial.tsx`)\n\n```tsx\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport { BrowserRouter as Router, Route, Redirect } from \"react-router-dom\"\nimport { AppProvider, Entry, PageSection } from 'kittenjs'\nimport { ui } from 'kittenjs-default-ui'\nimport Page1ListPlugin from './plugins/Page1ListPlugin'\n\nfunction Header(props: any): JSX.Element {\n    return (\n        \u003cdiv\u003e\n            \u003cEntry // Kitten entry component with pageAPI or pageJSON\n                pageKey=\"test-entry-header\"\n                pageJSON={[\n                    {\n                        key: 'header',\n                        type: 'Button',\n                        meta: {\n                            label: 'Header'\n                        }\n                    }\n                ]}\n            /\u003e\n        \u003c/div\u003e\n    )\n}\n\nconst page1JSON: PageSection[] = [\n  //...\n]\nfunction Page1(props: any): JSX.Element {\n    return (\n        \u003cdiv\u003e\n            \u003cEntry\n                pageAPI=\"http://api.example.com/pages\"\n                pageKey=\"test-entry-page1\"\n                pageJSON={page1JSON} // pageJSON can make pageAPI disabled\n                history={props.history}\n                match={props.match}\n            /\u003e\n        \u003c/div\u003e\n    )\n}\n\nfunction App (props: any): JSX.Element {\n    return (\n        \u003cdiv\u003e\n            \u003cHeader /\u003e\n            \u003cRouter\u003e\n                \u003cRoute exact path=\"/\" component={() =\u003e \u003cRedirect to=\"/main\" /\u003e} /\u003e\n                \u003cRoute exact path=\"/main\" component={Page1} /\u003e\n            \u003c/Router\u003e\n        \u003c/div\u003e\n        \n    )\n}\n\nReactDOM.render(\n    \u003cAppProvider // You should generally set up a \u003cAppProvider\u003e at the root of your app\n        ui={ui} \n        config={{\n            appKey: 'Test-Entry'\n        }} \n        plugins={[\n            new Page1ListPlugin() // plugins\n        ]}\n        debugHooks={[\n            'beforeTableColumnFinalization' // debug kitten hooks\n        ]}\n    \u003e\n        \u003cApp /\u003e\n    \u003c/AppProvider\u003e, \n    document.getElementById('root')\n);\n```\n\n\n\n# ⌨️ Development\n\n#### 1.install\n\n```bash\ncd kittenjs\nyarn install --ignore-scripts\n\ncd kittenjs-default-ui\nyarn install --ignore-scripts\n\ncd example\nyarn install --ignore-scripts\n```\n\n#### 2.link\n\n```bash\ncd kittenjs\nyarn link\n# Fix Duplicate React: https://github.com/facebook/react/issues/15315#issuecomment-479802153\nnpm link ../example/node_modules/react\n\ncd kittenjs-default-ui\nyarn link\nyarn link \"kittenjs\"\nnpm link ../example/node_modules/react\n\ncd example\nyarn link \"kittenjs\"\nyarn link \"kittenjs-default-ui\"\n```\n\n#### 3.run in development mode\n\n```bash\ncd kittenjs\nyarn start\n\ncd kittenjs-default-ui\nyarn start\n\ncd example\nyarn run dev\n```\n\n# 📖 Document\n\n## Overview\n\n```tsx\nimport { Kitten } from 'kittenjs' // 逻辑抽象层\nimport { Renderer, ui } from 'kittenjs-default-ui' // UI 渲染层\n\nimport YourPlugin from './plugins/YourPlugin'\n\nconst app = new Kitten(ui, { // 将 ui 传入，kitten 会使用此进行 UI 渲染\n    appKey: '\u003c--appKey--\u003e',\n    appTitle: '\u003c--appTitle--\u003e',\n    pageAPI: '\u003c--pageAPI--\u003e',\n    loginUrl: '\u003c--loginUrl--\u003e',\n    menus: [], // 菜单配置\n}, [\n    new YourPlugin()\n], [\n   'beforeTableColumnFinalization' // 输出指定插件的调试信息\n])\napp.render(Renderer,  document.getElementById('root')!)\n```\n\n```tsx\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport { BrowserRouter as Router, Route, Redirect } from \"react-router-dom\"\nimport { AppProvider, Entry, PageSection } from 'kittenjs'\nimport { ui } from 'kittenjs-default-ui'\nimport Page1ListPlugin from './plugins/Page1ListPlugin'\n\nfunction Header(props: any): JSX.Element {\n    return (\n        \u003cdiv\u003e\n            \u003cEntry // Kitten entry 组件，可以配置 pageAPI 或 pageJSON\n                pageKey=\"test-entry-header\"\n                pageJSON={[\n                    {\n                        key: 'header',\n                        type: 'Button',\n                        meta: {\n                            label: 'Header'\n                        }\n                    }\n                ]}\n            /\u003e\n        \u003c/div\u003e\n    )\n}\n\nconst page1JSON: PageSection[] = [\n  //...\n]\nfunction Page1(props: any): JSX.Element {\n    return (\n        \u003cdiv\u003e\n            \u003cEntry\n                pageAPI=\"http://api.example.com/pages\"\n                pageKey=\"test-entry-page1\"\n                pageJSON={page1JSON} // 配置了 pageJSON 会使 pageAPI 无效\n              \t// Page1 在 Router 中可配置 history 和 match\n              \t// 此时 page JSON 里可配置 link 等路由相关功能\n                history={props.history}\n                match={props.match}\n            /\u003e\n        \u003c/div\u003e\n    )\n}\n\nfunction App (props: any): JSX.Element {\n    return (\n        \u003cdiv\u003e\n            \u003cHeader /\u003e\n            \u003cRouter\u003e\n                \u003cRoute exact path=\"/\" component={() =\u003e \u003cRedirect to=\"/main\" /\u003e} /\u003e\n                \u003cRoute exact path=\"/main\" component={Page1} /\u003e\n            \u003c/Router\u003e\n        \u003c/div\u003e\n        \n    )\n}\n\nReactDOM.render(\n    \u003cAppProvider // 需要在使用了 Kitten Entry 组件的最顶层处使用 \u003cAppProvider\u003e 包裹\n        ui={ui} \n        config={{\n            appKey: 'Test-Entry'\n        }} \n        plugins={[\n            new Page1ListPlugin() // 插件\n        ]}\n        debugHooks={[\n            'beforeTableColumnFinalization' // 输出指定插件的调试信息\n        ]}\n    \u003e\n        \u003cApp /\u003e\n    \u003c/AppProvider\u003e, \n    document.getElementById('root')\n);\n```\n\n## App\n\n### appKey\n\n- 唯一的应用标识，以字母开头的字母或数字及下划线组合\n\n### appTitle\n\n- 应用标题，会显示在页面标题位置\n\n### pageAPI\n\n- 接收 pageKey 作为参数，返回 pageJSON 的 API 接口\n\n### loginUrl\n\n- 统一的登录 URL\n- 当应用其他接口返回 401 等，会跳转到此 URL\n\n### menus\n\n- 菜单配置\n\n  ```js\n  [\n          {\n              key: 'dashbord',\n              label: '仪表盘',\n              pageJSON: [...] // 如果配置了 pageJSON，将不会去请求 pageAPI 获得 pageJSON\n          }, {\n              label: '菜单 1',\n              subs: [\n                  {\n                      label: '子菜单 1', \n                      key: 'sub1',\n                      pageJSON: [...],\n                      subPages: [ \t// KCP 暂不支持\n                          {\n                              key: 'subpage',\n                              label: '子页面1',\n                              pageJSON: [{\n                                  key: 'backToSub1',\n                                  type: 'Button',\n                                  meta: {\n                                      label: '返回',\n                                      link: '\u003c'\n                                  }\n                              }]\n                          }\n                      ]\n                  },\n                  {\n                      label: '子菜单 2', \n                      key: 'sub2',\n                      pageJSON: JSON.parse(JSON.stringify(sub2PageJSON))\n                  }\n              ]\n          },\n          {\n              key: 'menu2',\n              label: '菜单 2'\n            \t// 没有配置 pageJSON，将会用 key 作为参数，请求 pageAPI 来获取 pageJSON\n          }\n      ]\n  ```\n\n- 只要配置好 `Page` , 无需关心 menu 的配置\n\n### Plugin\n\n- kitten 支持插件，来满足特殊的交互或业务需求\n\n  ```tsx\n  import React from 'react'\n  import { Plugin, AppHooks } from 'kittenjs'\n  export default class YourPlugin implements Plugin {\n      apply(hooks: AppHooks) {\n          ...\n      }\n  }\n  ```\n\n- 需继承` Plugin` , 实现 `apply` 方法\n\n- kitten 插件 理论上可以通过预先定义好的 hooks 在 kittenjs 的任何位置插入代码\n\n- hooks 通过 `apply` 方法参数传入\n\n  ```tsx\n  ...\n  apply(hooks: AppHooks) {\n     hooks.beforeTableColumnFinalization.tap(\n       'YourPlugin--beforeTableColumnFinalization', \n       (appkey: string, pageKey: string, tableKey:string, column: TableColumn) =\u003e {\n         \t\t\t// 通常需要通过 pageKey 以及相应组件的 key 等来确定你所关心的页面或组件等\n              if (pageKey !== 'other' || tableKey !== 'yourTable') return;\n              ...\n        })\n  }\n  ...\n  ```\n\n- 目前 AppHooks 有 (还不完善，之后会根据业务需求来增加和迭代) :\n\n  - renderCustomRoutes\n    - appKey, RouteComponents, mainRender\n    - 可自定义路由，用于添加自定义页面\n    - RouteComponents, 包含三个 react-router-dom  路由组件\n      - Route\n      - Switch\n      - Redirect\n    - mainRender, 整个 kitten 应用变为一个组件, 需要至少有一个路由指向进行渲染\n\t\t\n  \t```jsx\n  \thooks.renderCustomRoutes.tap('OtherRoutePage--renderCustomRoutes', (appkey: string, RouteComponents: any, mainRender: Function) =\u003e {\n  \t  const {Route, Switch, Redirect} = RouteComponents\n  \t  return (\n  \t    \u003c\u003e\n  \t    \u003cRoute exact path=\"/\" component={() =\u003e \u003cRedirect to=\"/main\" /\u003e} /\u003e\n  \t    \u003cRoute path=\"/login\" component={() =\u003e \u003cdiv\u003eLogin\u003c/div\u003e} /\u003e\n  \t    \u003cRoute path=\"/main\" component={mainRender} /\u003e\n  \t    \u003c/\u003e\n  \t  )\n  \t})\n  \t```\n  \t\n  - renderHeaderActions\n    \n    - appKey\n    \n  - renderSiderTopSection\n  \n    - appKey\n  \n  - renderCustomRoutes\n  \n    - appKey, RouteComponents, mainRender\n    - 可添加自定义路由，如，增加一个登陆页面\n  \n  - afterPageLoaded\n    \n    - appKey, pageKey, props\n    - 页面加载时调用\n    \n  - afterPageUnloaded\n    - appKey, pageKey, props\n    - 页面卸载时调用\n    \n  - afterComponentLoaded\n    - appKey, pageKey, componentType, componentKey, props\n    - 组件加载时调用\n    \n  - afterComponentUnloaded\n    - appKey, pageKey, componentType, componentKey, props\n    - 组件卸载时调用\n    \n  - beforeSelectDataFetched\n    - appKey, pageKey, componentKey, items, selectKey\n    - Form 或 Table 有 Select 时，在请求接口获取 Select 数据**前**调用\n    \n  - afterSelectDataFetched\n    - appKey, pageKey, componentKey, items, selectKey, selectData\n    - Form 或 Table 有 Select 时，在请求接口获取 Select 数据**后**调用\n    \n  - beforeTableDataSourceFetched\n    - appKey, pageKey, tableKey, columns, pagination\n    - Table 在请求接口获取数据**前**调用\n    \n  - afterTableDataSourceFetched\n    - appKey, pageKey, tableKey, columns, dataSource, pagination\n    - Table 在请求接口获取数据**后**调用\n    \n  - beforeTablePaginationFinalization\n  \n    - appKey，pageKey，tableKey，props，dataSource，pagination\n    - Table 分页最终确定前调用\n  \n  - beforeFormItemFinalization\n    - appKey, pageKey, formKey, props, item\n    - 在 Form 的 每个item (表单条目) 最终确定前调用\n    \n  - beforeFormAllItemsFinalization\n    - appKey, pageKey, formKey, props, items\n    - 在 Form 的所有 items 最终确定前调用\n    \n  - beforeTableColumnFinalization\n    - appKey, pageKey, tableKey, props, column\n    - 在 Table 的每个 Column (列) 最终确定前调用\n    \n  - beforeTableAllColumnsFinalization\n    - appKey, pageKey, tableKey, props, columns\n    - 在 Table 的所有 Columns 最终确定前调用\n    \n  - beforeButtonClick\n    - appKey, pageKey, buttonKey\n    - 在 Button 点击前调用\n    \n  - beforeFormSubmit\n    - appKey, pageKey, formKey, values\n    - 在 Form 提交前调用\n    \n  - beforeCheckboxChange\n    - appKey, pageKey, checkboxKey, value\n    - 在 Checkbox 改变前调用\n    \n  - afterTableCellChanged\n    - appKey, pageKey, tableKey, dataSource, row\n    - 在 Table Cell 为可编辑时，值改变后调用\n\n## Page\n\n- pageKey\n  - 唯一的页面标识，以字母开头的字母或数字及下划线组合\n\n## Section\n\n### key\n\n- 唯一的组件块标识，以字母开头的字母或数字及下划线组合\n\n### type\n\n- 组件块类型\n  - Table, Form, Button, Stack, Checkbox, Modal, Tabs, Panel, Iframe\n  - Panel\n    - items 要么全是 Sections (配置了 type)，要么全是 Items (不配置 type, 配置 key, label, value)\n    - item 的 meta 支持 `url` (当 item 的 value 不是 `$#` 时, 点击发送请求), ` link` (页面跳转), `href ` (链接跳转)\n    - Panel item 的 value 支持 `$.` 和 `$#`\n         - `$.` 获取 Panel 的 meta 的 url 请求返回数据的字段\n      - `$#` 获取 Panel Item 的 meta 的 url 请求返回数据的字段\n\n### meta\n\n#### url\n\n- Form, Table\n- Table 为数据请求接口\n- Form 为表单提交接口\n\n#### method\n\n- Form, Table\n- POST 或 GET\n\n#### pageSize\n\n- Table\n- Table 分页时，可选配置\n\n#### disablePagination\n\n- Table\n- 取消 Table 的分页\n\n#### label\n\n- Button, Modal\n- Button 或 Modal 的标题\n\n#### modal\n\n- Button, Table, Form\n- Button 点击要显示的 Modal 的 key\n- 如果 Table 和 Form 为 Modal 的子 Section，需要配置 modal 为其 Modal 的 key，则可获取 Modal 弹起时获取的参数\n\n#### accessories\n\n- Form\n- Form 的附加 sections\n\n#### form\n\n- Table\n- 当 Table 作为 Form 的 accessories 时, 需要配置 form 为此 Form 的 key，这样 Form 才能获取 Table 的数据\n\n#### params\n\n- Table, Form\n- 当 Table 作为 Form 的 accessories 时\n  - params: {form: {key: ..., fields: [...]}}\n  - key (字符串) 为 Form 提交时的字段，与提交接口字段名称一致\n  - fields (字符串数组) 为 Table 中需要提交的字段，可选。如果不配置，则默认为全部字段。\n- 当 Form 需要提交额外字段时\n  - params: { get/post: {key1: '$.key1', key2: 'key2'}}\n  - get 或 post 对应提交接口 method 为 GET 或 POST\n  - key1 和 key2 为提交的额外字段，会成为请求接口的参数\n  - 如果 Form 为 Modal 的子 section，则提交字段的 value (以 $. 开头) 可以获取 Modal 弹起时获取的参数\n\n#### width\n\n- Modal, Panel\n- Modal 的宽度， 如：800px\n- Panel 的宽度，通常为 Panel 的 子 Panel 时进行配置，来布局，通常为百分比，如： 25%\n\n#### filter\n\n- Form\n- 当 Form 为 Table 的搜索筛选表单时\n  - filter 填写为此 Table 的 key，即可完成其 Form 提交携带新参数重新请求 Table 数据接口的功能\n\n#### direction\n\n- Stack, Panel\n- Stack 是一个布局 section, 分为由上到下垂直布局和由左到右水平布局\n- Panel 对子 Panel 的布局\n- horizontal，水平布局\n- vertical，垂直布局\n\n#### columnsCount\n\n- Form, Panel\n- Form 的表单条目的列数，用于布局\n- Panel 控制 items 的列数，用于布局\n\n#### rowColCounts\n\n- Form\n- Form 表单条目每行布局几个条目，不能超过 columnsCount, 用于布局\n- 例如： [2, 1, 3]\n  - 第一行 2 个，第二行  1 个，第三行 3 个，第四行及其下面都为 3 个\n\n#### disableGroupCol\n\n- Form\n- 用于布局，当 Form 里有 checkbox 群时，将其置为 true, 可能会使布局更紧凑\n\n#### style\n\n- Table, Form, Stack, Button, Modal, Checkbox\n- 可以写自定义样式，用于修正布局或样式\n\n#### link\n\n- Button\n- 页面跳转\n- '/pageKey'，/ 表示为根页面，非子页面\n- 'subPageKey', 子页面\n- '\u003c', 页面返回上一页面\n\n#### componentKey\n\n- Form\n- Form 提交时需要把提交的数据传递给某个组件，设置为此组件的 key\n  - 通常为某一页面在某一操作弹起 Modal 时，其中的 Form 提交后需把提交的数据传递到此页面的 Table 中，如新建此页面 Table 的条目时\n\n#### alias\n\n- Table\n- 当接口字段与配置字段格式不一致时，需要配置\n- Table 分页数据不一致时\n  - alias: { currentPage: 'page', pageSize: 'pagesize', total: 'paginate.total'}\n  - 字段支持属性嵌套，如，paginate.total\n\n#### actionsShow\n\n- Form\n- 是否显示 Form 的提交重置按钮，当 Form 用于纯展示时，可设为 false\n\n#### labelPostion\n\n- Form\n- Form 布局，支持 left, top, horizontal, vertical, inline\n  - left: label 在左边，每行左对齐\n  - top: label 在上边，输入框和 label 对齐，并一起左对齐\n  - horizontal: label 在左边, 每行输入框对齐，label 右对齐\n  - vertical: 与 top 类似，但使用的是 row col 布局\n  - inline: 行内布局\n\n#### submitTitle\n\n- Form\n- 表单提交按钮文字配置\n\n#### clearTitle\n\n- Form\n- 表单清空按钮文字配置\n\n#### actionDirection\n\n- Form\n- 表单提交清空按钮的布局\n  - left\n  - right\n  - center\n\n#### clearButtonShow\n\n- Form\n- 是否显示表单清空按钮\n\n#### href\n\n- Iframe, Button\n- Iframe 加载页面\n- Button 跳转链接\n\n#### headerBgColor\n\n- Panel\n- Panel header 的背景颜色\n\n#### headerColor\n\n- Panel\n- Panel header 字体颜色\n\n#### block\n\n- Iframe\n- 为 ture 时，Iframe 为块级普通 iframe, 可配置 style 控制宽高等, 也可放入 Stack 来被布局\n- 不配置或为 false 时，Iframe 为 页面级 iframe, 宽度高度撑满并随窗口改变而改变，可配置 offset 进行高度的调整\n\n#### offset\n\n- Iframe\n- Iframe 为 页面级 iframe 时, 可配置 offset 进行高度的调整\n\n### items \n\nForm 或 Table 中的条目\n\n#### key\n\n- Form, Table\n- 字段名称，需跟接口字段一致\n\n#### label\n\n- Form, Table\n- 字段标签名称\n\n#### type\n\n- Form, Table\n- Form 的条目输入类型，默认为 input\n  - input, select, radio, checkbox, textArea, date, rangeDate, month, info, codeEditor\n- 当 Table 配置 editable 为 true 时，可以配置 type 类型，默认为 input\n  - input, select, tags, multiple\n\n#### showTime\n\n- Form\n- Form 的条目 type 为 date, 或 rangeDate时有效\n- 是否增加日期的时间选择\n\n#### id\n\n- Table\n- 为 true 时，用此字段作为 Table 的唯一标识 rowKey\n\n#### actionDisabled\n\n- Form\n- 为 true 时，Form 不会提交此字段\n\n#### required\n\n- Form, Table\n- 为true时，此字段为必填\n- Table 时，需配置 editable 为 true 时才生效\n\n#### editable\n\n- Table\n- 为 true 时，Table 此字段可编辑，默认为 input\n\n#### reg\n\n- Form, Table\n- 正则匹配\n- 如：reg: {pattern: '^([1-9][0-9]*)?[05]$', message: '请输入5的倍数'}\n  - pattern 为正则表达式字符串\n  - message 为不满足正则时的提示信息\n\n#### value\n\n- Form, Table\n- 默认值\n\n#### placeholder\n\n- Form\n- 输入占位符字符串\n\n#### disabled\n\n- Form, Table\n- 禁止输入\n\n#### actions\n\n- Table\n\n- 配置为 Table 的操作列\n\n  ```js\n  actions: [\n    {\n      key: 'yourTableEdit',\n      meta: {\n        label: '修改',\n        modal: 'yourTableEditModal',\n        // $. 取 table record\n        // $# 取 url 请求数据\n        params: {\n          get: {\n            id: '$.id'\n          },\n          id: '$.id',\n          field1: '$#field1'\n        },\n        url: '...',\n        method: 'GET'\n      }\n    },\n    {\n      key: 'yourTableDelete',\n      meta: {\n        label: '删除',\n        confirm: true,\n        confirmLabel: '确定删除?',\n        url: '...,\n        method: 'POST',\n        params: {\n          post: {\n            id: '$.id'\n          }\n        }\n      }\n    }\n  ]\n  ```\n\n  - key\n\n    - 唯一标识\n\n  - meta\n\n    - label\n\n      - 操作按钮标题\n\n    - url\n\n      - 操作按钮点击请求的 URL\n\n    - method\n\n      - 操作按钮点击请求的 method\n\n    - modal\n\n      - 操作按钮点击弹起 Modal 的 key\n\n    - params\n\n      - get 或 post 可以在请求 url 时增加请求参数，需与 method 的 GET 或 POST 一致\n      - 其他字段，当配置了 modal 时有效，会将其传递给 key 为 modal 配置值 的 Modal\n      - 字段值，可以为 `$.` 或 `$#` 开头\n        - `$.` 会取 Table 中的字段值\n        - `$#` 会取请求 url 返回数据中的字段值\n        \n  \n- show\n  \n  - 按钮是否显示，true 或 false\n      - 支持`$.` , 会取 Table 中的字段值的真假值\n  \n- confirm\n  \n  - 操作按钮点击是否需要确认操作\n      - 如**删除**操作经常需要确认，则将其置为true\n  \n- confirmLabel\n  \n  - 操作确认弹出框的提示信息\n      - 如： '确定删除?'\n      \n    - rowAction\n    \n      ```js\n      actions: [\n        {\n          key: \"add\",\n          meta: {\n            label: \"添加\",\n            rowAction: \"insert\"\n          }\n        },\n        {\n          key: \"delete\",\n          meta: {\n            label: \"删除\",\n            rowAction: \"delete\"\n      }\n        }\n      ]\n      ```\n  ```\n    \n  - insert，当点击操作按钮时，会增加一行；当 Table 为空时，此按钮会显示为占位符位置，点击可增加一行\n      - delete，当点击操作按钮时，会删除一行\n    \n    - link\n    \n      - 跳转页面，同 Section meta 中的 link\n  ```\n\n#### alias\n\n- Form, Table\n- 当请求接口字段与 key 不一致时，需要配置此字段为接口请求字段\n- 为字符串，只能配置一个字段的别称，与 section meta 中 alias 不同\n\n#### meta\n\n- width\n  - Table\n  - Table 列的宽度，单位： 'px'\n    - 如： '100px'\n- format\n  - Table,  Form\n  - Table 列的格式化，支持 三种，timestamp，date，code，需要以 `$:`分隔\n    - timestamp`$:`YYYY-MM-DD HH:mm:ss\n    - date`$:`YYYY-MM-DD HH:mm:ss\n    - code`$:`java，支持四种\n      - java\n      - jsx\n      - tsx\n      - sql\n  - Form item value (默认值) 的格式化 (仅在 disabled 时才生效)\n    - 常用于用 Form 来显示数据时进行格式化\n    - 支持两种，timestamp，date 需要以 `$:`分隔\n      - timestamp`$:`YYYY-MM-DD HH:mm:ss\n      - date`$:`YYYY-MM-DD HH:mm:ss\n- size\n  - Panel\n  - 可配置为 big, extrabig 来控制 Panel item 的 value 字体的大小\n\n**当 Form 或 Table 的条目 type 为 select 类型 (包括 tags, multiple) 时有效 **\n\n- url\n  - Form, Table, Panel\n  - 请求 select 数据 URL\n  - Panel item 的 value 可点击发送请求，必须配置 method\n- method\n  - Form, Table， Panel\n  - 请求 select 数据 method\n  - Panel item 的 value 可点击发送请求，必须配置 url\n\n- link\n  - Panel\n  - Panel item 的 value 可点击跳转页面\n  - '/pageKey'，/ 表示为根页面，非子页面\n  - 'subPageKey', 子页面\n  - '\u003c', 页面返回上一页面\n\n- ref\n  - Form, Table\n  - 联动依赖的条目的 key\n- refData\n  - Form, Table\n  - 以联动依赖的条目 (以 ref 为 key的条目) 的值为键的全量字典\n  - 当联动依赖的条目选择改变时，根据其值查找字典返回其本身的 select 数据\n- data\n  - Form, Table\n  -  select 数据\n  - [{value: '1', label:'值1' }, {value: '2', label: '值2'}]\n- alias\n  - Form, Table\n  - 当 select 数据接口的条目字段不是 value 和 label时，需要配置 value 和 label\n    - {value: \"yourValueKey\", label: \"yourLabelKey\"}\n\n# License\n\nMIT © [docoder](https://github.com/docoder)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdocoder%2Fkitten","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdocoder%2Fkitten","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdocoder%2Fkitten/lists"}