diff --git a/.codecheck/check.yml b/.codecheck/check.yml index 4a049241a0..d485815226 100644 --- a/.codecheck/check.yml +++ b/.codecheck/check.yml @@ -8,4 +8,4 @@ tool_params: secsolar: source_dir: ./ cmetrics: - exclude: vite.config.js|package.json|index.js|axios.js|.eslintrc.js|mockServer|packages/vue-generator/test|packages/vue-generator/src/templates|packages/build/vite-plugin-meta-comments/src/test + exclude: vite.config.js|package.json|index.js|axios.js|.eslintrc.js|mockServer|packages/engine-cli/template|packages/vue-generator/test|packages/vue-generator/src/templates|packages/build/vite-plugin-meta-comments/src/test diff --git a/.env.local b/.env.local index a361a78c8f..93b036e1e4 100644 --- a/.env.local +++ b/.env.local @@ -2,4 +2,6 @@ SQL_HOST=localhost SQL_PORT=3306 SQL_USER=root SQL_PASSWORD=admin -SQL_DATABASE=tiny_engine \ No newline at end of file +SQL_DATABASE=tiny_engine + +backend_url=http://localhost:9090/material-center/api/component/bundle/create \ No newline at end of file diff --git a/.github/auto-labeler.yml b/.github/auto-labeler.yml index 47770e6244..e0ef8c69a2 100644 --- a/.github/auto-labeler.yml +++ b/.github/auto-labeler.yml @@ -10,7 +10,7 @@ labels: sync: true matcher: title: '^.+!:|#breaking' - body: '#breaking' + body: '## Does this PR introduce a breaking change\?\s+- \[[xX]\] *Yes' - label: 'enhancement' sync: true matcher: diff --git a/.github/workflows/deploy-gh-pages.yml b/.github/workflows/deploy-gh-pages.yml new file mode 100644 index 0000000000..340c6fdbbd --- /dev/null +++ b/.github/workflows/deploy-gh-pages.yml @@ -0,0 +1,56 @@ +name: Deploy to GitHub Pages + +on: + push: + branches: [develop] + +jobs: + deploy-gh-pages: + runs-on: ubuntu-latest + concurrency: + group: deploy-gh-pages + cancel-in-progress: true + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + run_install: false + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + registry-url: 'https://registry.npmjs.org' + + - name: Install dependencies + run: pnpm install + + - name: add environment variable + run: | + cat <<'EOF' >> designer-demo/env/.env.alpha + // ---- appended by CI (gh-pages) ---- + VITE_ORIGIN=https://agent.opentiny.design/ + EOF + - name: change material url + run: | + sed -i "s#material: \['/mock/bundle.json'\]#material: \['https://opentiny.github.io/tiny-engine/mock/bundle.json'\]#g" designer-demo/engine.config.js + echo "Updated material url in designer-demo/engine.config.js" + - name: Run Build + run: | + set -eo pipefail + pnpm run build:plugin 2>&1 | tee /tmp/build-plugin.log + pnpm run build:alpha 2>&1 | tee /tmp/build-alpha.log + + - name: Deploy + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./designer-demo/dist/ + keep_files: true + force_orphan: false + user_name: 'github-actions[bot]' + user_email: 'github-actions[bot]@users.noreply.github.com' diff --git a/README.md b/README.md index 395c6909f0..34b9befafa 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@
TinyEngine enables developers to customize low-code platforms, build low-code platforms online in real time, and support secondary development or integration of low-code platform capabilities.
+[](https://deepwiki.com/opentiny/tiny-engine) + English | [简体中文](README.zh-CN.md) 🌈 Features: diff --git a/designer-demo/engine.config.js b/designer-demo/engine.config.js index fa308f9bc2..0ed7c1858a 100644 --- a/designer-demo/engine.config.js +++ b/designer-demo/engine.config.js @@ -3,5 +3,7 @@ export default { theme: 'light', material: ['/mock/bundle.json'], scripts: [], - styles: [] + styles: [], + // 是否开启 TailWindCSS 特性 + enableTailwindCSS: true } diff --git a/designer-demo/package.json b/designer-demo/package.json index 746ea8144b..248aab5d45 100644 --- a/designer-demo/package.json +++ b/designer-demo/package.json @@ -1,7 +1,7 @@ { "name": "designer-demo", "private": true, - "version": "2.7.0", + "version": "2.9.0", "type": "module", "scripts": { "dev": "cross-env vite", diff --git a/designer-demo/public/default-template-cover.png b/designer-demo/public/default-template-cover.png new file mode 100644 index 0000000000..e9d55e0d30 Binary files /dev/null and b/designer-demo/public/default-template-cover.png differ diff --git a/designer-demo/public/mock/bundle.json b/designer-demo/public/mock/bundle.json index 53c0ca0d82..5bf5429a01 100644 --- a/designer-demo/public/mock/bundle.json +++ b/designer-demo/public/mock/bundle.json @@ -4,53 +4,26 @@ "materials": { "components": [ { - "id": 1, - "version": "2.4.2", + "version": "3.22.0", "name": { - "zh_CN": "输入框" + "zh_CN": "评分" }, - "component": "ElInput", - "icon": "input", - "description": "通过鼠标或键盘输入字符", - "doc_url": "", + "component": "TinyRate", + "icon": "line", + "description": "评分", + "docUrl": "", "screenshot": "", "tags": "", "keywords": "", - "dev_mode": "proCode", + "devMode": "proCode", "npm": { - "package": "element-plus", - "exportName": "ElInput", + "package": "@opentiny/vue", + "exportName": "TinyRate", "destructuring": true }, - "group": "表单组件", - "category": "element-plus", - "configure": { - "loop": true, - "condition": true, - "styles": true, - "isContainer": false, - "isModal": false, - "isPopper": false, - "nestingRule": { - "childWhitelist": "", - "parentWhitelist": "", - "descendantBlacklist": "", - "ancestorWhitelist": "" - }, - "isNullNode": false, - "isLayout": false, - "rootSelector": "", - "shortcuts": { - "properties": ["type", "size"] - }, - "contextMenu": { - "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"], - "disable": [] - }, - "invalidity": [""], - "clickCapture": true, - "framework": "Vue" - }, + "group": "component", + "category": "评分组件", + "priority": 2, "schema": { "properties": [ { @@ -60,721 +33,561 @@ }, "content": [ { - "property": "modelValue", + "cols": 12, + "type": "number", "label": { "text": { "zh_CN": "绑定值" } }, + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" + }, + "disabled": false, + "property": "modelValue", + "readOnly": false, + "required": false, "description": { "zh_CN": "绑定值" }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "widget": { - "component": "InputConfigurator", - "props": {} - } + "defaultValue": 0, + "labelPosition": "left" }, { - "property": "size", + "cols": 12, + "type": "number", "label": { "text": { - "zh_CN": "尺寸" + "zh_CN": "最大分值" } }, - "description": { - "zh_CN": "尺寸" + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, + "property": "max", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "最大分值" + }, + "defaultValue": 5, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性" + } + }, + { + "name": "1", + "label": { + "zh_CN": "样式属性" + }, + "content": [ + { "cols": 12, - "labelPosition": "left", - "type": "string", - "defaultValue": "default", + "type": "array", + "label": { + "text": { + "zh_CN": "颜色数组" + } + }, "widget": { - "component": "SelectConfigurator", "props": { - "options": [ - { - "label": "large", - "value": "large" - }, - { - "label": "default", - "value": "default" - }, - { - "label": "small", - "value": "small" - } - ] - } - } + "height": 150, + "language": "json" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "colors", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "icon 的颜色数组,为 Threshold 三个分段所对应的颜色" + }, + "defaultValue": "['#FADB14', '#FADB14', '#FADB14']", + "labelPosition": "left" }, { - "property": "type", + "cols": 12, + "type": "string", "label": { "text": { - "zh_CN": "类型" + "zh_CN": "禁用未选中颜色" } }, - "description": { - "zh_CN": "类型" + "widget": { + "props": {}, + "component": "ColorConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, + "property": "disabled-void-color", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "禁用状态下未选中 icon 的颜色" + }, + "defaultValue": "#D9D9D9", + "labelPosition": "left" + }, + { "cols": 12, - "labelPosition": "left", "type": "string", + "label": { + "text": { + "zh_CN": "禁用未选中图标类" + } + }, "widget": { - "component": "InputConfigurator", - "props": {} - } + "props": { + "placeholder": "请输入图标名称" + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "disabled-void-icon-class", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "只读状态下未选中的图标样式名" + }, + "defaultValue": "icon-starActive", + "labelPosition": "left" }, { - "property": "placeholder", + "cols": 12, + "type": "array", "label": { "text": { - "zh_CN": "占位文本" + "zh_CN": "图标类数组" } }, - "description": { - "zh_CN": "输入框占位文本" + "widget": { + "props": { + "height": 150, + "language": "json" + }, + "component": "CodeConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, + "property": "icon-classes", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "三个分段对应的图标样式名" + }, + "defaultValue": "['icon-starActive', 'icon-starActive', 'icon-starActive']", + "labelPosition": "left" + }, + { "cols": 12, - "labelPosition": "left", "type": "string", + "label": { + "text": { + "zh_CN": "图标大小" + } + }, "widget": { - "component": "I18nConfigurator", - "props": {} + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" }, - "device": [] + "disabled": false, + "property": "size", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "图标字体大小" + }, + "defaultValue": "18px", + "labelPosition": "left" }, { - "property": "maxlength", + "cols": 12, + "type": "string", "label": { "text": { - "zh_CN": "最大长度" + "zh_CN": "图标间距" } }, - "description": { - "zh_CN": "最大输入长度" + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, + "property": "space", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "每个图标所占宽度" + }, + "defaultValue": "24px", + "labelPosition": "left" + }, + { "cols": 12, - "labelPosition": "left", - "type": "number", + "type": "string", + "label": { + "text": { + "zh_CN": "文字颜色" + } + }, "widget": { - "component": "NumberConfigurator", - "props": {} + "props": {}, + "component": "ColorConfigurator" }, - "device": [] + "disabled": false, + "property": "text-color", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "辅助文字的颜色" + }, + "defaultValue": "#666666", + "labelPosition": "left" }, { - "property": "disabled", + "cols": 12, + "type": "string", "label": { "text": { - "zh_CN": "是否禁用" + "zh_CN": "未选中颜色" } }, - "description": { - "zh_CN": "是否禁用" + "widget": { + "props": {}, + "component": "ColorConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, + "property": "void-color", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "未选中 icon 的颜色" + }, + "defaultValue": "#BFBFBF", + "labelPosition": "left" + }, + { "cols": 12, - "labelPosition": "left", - "defaultValue": false, - "type": "boolean", + "type": "string", + "label": { + "text": { + "zh_CN": "未选中图标类" + } + }, "widget": { - "component": "CheckBoxConfigurator", - "props": {} + "props": { + "placeholder": "请输入图标名称" + }, + "component": "InputConfigurator" }, - "device": [] + "disabled": false, + "property": "void-icon-class", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "未选中 icon 的图标样式名" + }, + "defaultValue": "icon-starDisable", + "labelPosition": "left" } ], "description": { - "zh_CN": "" - } - } - ], - "events": { - "onUpdate:modelValue": { - "label": { - "zh_CN": "双向绑定值改变时触发" - }, - "description": { - "zh_CN": "双向绑定值改变时触发" - } - }, - "onBlur": { - "label": { - "zh_CN": "输入框失去焦点时触发" - }, - "description": { - "zh_CN": "输入框失去焦点时触发" - }, - "type": "event", - "functionInfo": { - "params": [ - { - "name": "event", - "type": "Object", - "defaultValue": "", - "description": { - "zh_CN": "原生 event" - } - } - ], - "returns": {} - }, - "defaultValue": "" - } - }, - "slots": { - "prefix": { - "label": { - "zh_CN": "头部内容" - }, - "description": { - "zh_CN": "输入框头部内容,只对非 type='textarea' 有效" - } - }, - "suffix": { - "label": { - "zh_CN": "尾部内容" - }, - "description": { - "zh_CN": "输入框尾部内容,只对非 type='textarea' 有效" - } - }, - "prepend": { - "label": { - "zh_CN": "前置内容" - }, - "description": { - "zh_CN": "输入框前置内容,只对非 type='textarea' 有效" + "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性" } }, - "append": { - "label": { - "zh_CN": "后置内容" - }, - "description": { - "zh_CN": "输入框后置内容,只对非 type='textarea' 有效" - } - } - } - } - }, - { - "id": 1, - "version": "2.4.2", - "name": { - "zh_CN": "日期选择器" - }, - "component": "ElDatePicker", - "icon": "datepick", - "description": "日期选择器", - "doc_url": "", - "screenshot": "", - "tags": "", - "keywords": "", - "dev_mode": "proCode", - "npm": { - "package": "element-plus", - "exportName": "ElDatePicker", - "destructuring": true - }, - "group": "表单组件", - "category": "element-plus", - "configure": { - "loop": true, - "condition": true, - "styles": true, - "isContainer": false, - "isModal": false, - "isPopper": false, - "nestingRule": { - "childWhitelist": "", - "parentWhitelist": "", - "descendantBlacklist": "", - "ancestorWhitelist": "" - }, - "isNullNode": false, - "isLayout": false, - "rootSelector": "", - "shortcuts": { - "properties": ["type", "size"] - }, - "contextMenu": { - "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"], - "disable": [] - }, - "invalidity": [""], - "clickCapture": true, - "framework": "Vue" - }, - "schema": { - "properties": [ { - "name": "0", + "name": "2", "label": { - "zh_CN": "基础属性" + "zh_CN": "行为属性" }, "content": [ { - "property": "modelValue", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "绑定值" + "zh_CN": "允许半选" } }, - "description": { - "zh_CN": "绑定值" - }, - "required": false, - "readOnly": false, - "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", "widget": { - "component": "InputConfigurator", - "props": {} - } - }, - { - "property": "readonly", - "label": { - "text": { - "zh_CN": "只读" - } + "props": {}, + "component": "CheckBoxConfigurator" }, + "disabled": false, + "property": "allow-half", + "readOnly": false, + "required": false, "description": { - "zh_CN": "是否只读" + "zh_CN": "是否允许半选" }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "boolean", "defaultValue": false, - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "labelPosition": "left" }, { - "property": "disabled", + "cols": 12, + "type": "boolean", "label": { "text": { "zh_CN": "禁用" } }, - "description": { - "zh_CN": "是否禁用" + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "boolean", + "property": "disabled", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否为只读" + }, "defaultValue": false, - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "labelPosition": "left" }, { - "property": "size", + "cols": 12, + "type": "number", "label": { "text": { - "zh_CN": "尺寸" + "zh_CN": "高分阈值" } }, - "description": { - "zh_CN": "输入框尺寸" - }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "defaultValue": "", "widget": { - "component": "SelectConfigurator", "props": { - "allowClear": true, - "options": [ - { - "label": "large", - "value": "large" - }, - { - "label": "default", - "value": "default" - }, - { - "label": "small", - "value": "small" - } - ] - } - } + "step": 1 + }, + "component": "NumberConfigurator" + }, + "disabled": false, + "property": "high-threshold", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "高分和中等分数的界限值,值本身被划分在高分中" + }, + "defaultValue": 4, + "labelPosition": "left" }, { - "property": "editable", + "cols": 12, + "type": "number", "label": { "text": { - "zh_CN": "是否可编辑" + "zh_CN": "低分阈值" } }, - "description": { - "zh_CN": "文本框是否可编辑" + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "boolean", - "defaultValue": true, - "widget": { - "component": "CheckBoxConfigurator", - "props": {} + "property": "low-threshold", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "低分和中等分数的界限值,值本身被划分在低分中" }, - "device": [] + "defaultValue": 2, + "labelPosition": "left" }, { - "property": "clearable", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "是否可清除" + "zh_CN": "单选形态" } }, - "description": { - "zh_CN": "是否显示清楚按钮" + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "boolean", - "defaultValue": true, - "widget": { - "component": "CheckBoxConfigurator", - "props": {} + "property": "radio", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "评分其他形态单选" }, - "device": [] + "defaultValue": false, + "labelPosition": "left" }, { - "property": "placeholder", + "cols": 12, + "type": "string", "label": { "text": { - "zh_CN": "占位文本" + "zh_CN": "分数模板" } }, - "description": { - "zh_CN": "非范围选择时的占位内容" + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "defaultValue": "", - "type": "string", - "widget": { - "component": "InputConfigurator", - "props": {} + "property": "score-template", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "分数显示模板,用“{value}”代表分数" }, - "device": [] + "defaultValue": "{value}", + "labelPosition": "left" }, { - "property": "start-placeholder", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "起始占位文本" + "zh_CN": "显示分数" } }, - "description": { - "zh_CN": "范围选择时开始日期的占位内容" + "widget": { + "props": {}, + "component": "SwitchConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "defaultValue": "", - "type": "string", - "widget": { - "component": "InputConfigurator", - "props": {} + "property": "show-score", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否显示当前分数,show-score 和 show-text 不能同时为真" }, - "device": [] + "defaultValue": false, + "labelPosition": "left" }, { - "property": "end-placeholder", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "结束占位文本" + "zh_CN": "显示文字" } }, - "description": { - "zh_CN": "范围选择时结束日期的占位内容" + "widget": { + "props": {}, + "component": "SwitchConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "defaultValue": "", - "type": "string", - "widget": { - "component": "InputConfigurator", - "props": {} + "property": "show-text", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否显示辅助文字,若为真,则会从 texts 数组中选取当前分数对应的文字内容" }, - "device": [] + "defaultValue": false, + "labelPosition": "left" }, { - "property": "type", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "类型" + "zh_CN": "文字在底部" } }, - "description": { - "zh_CN": "显示类型" + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "defaultValue": "date", - "type": "string", - "widget": { - "component": "SelectConfigurator", - "props": { - "options": [ - { - "label": "year", - "value": "year" - }, - { - "label": "years", - "value": "years" - }, - { - "label": "month", - "value": "month" - }, - { - "label": "months", - "value": "months" - }, - { - "label": "date", - "value": "date" - }, - { - "label": "dates", - "value": "dates" - }, - { - "label": "datetime", - "value": "datetime" - }, - { - "label": "week", - "value": "week" - }, - { - "label": "datetimerange", - "value": "datetimerange" - }, - { - "label": "daterange", - "value": "daterange" - }, - { - "label": "monthrange", - "value": "monthrange" - }, - { - "label": "yearrange", - "value": "yearrange" - } - ] - } + "property": "text-on-bottom", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否在图标下显示对应的文字" }, - "device": [] + "defaultValue": false, + "labelPosition": "left" }, { - "property": "popper-class", + "cols": 12, + "type": "array", "label": { "text": { - "zh_CN": "下拉框类名" + "zh_CN": "文字数组" } }, - "description": { - "zh_CN": "DatePicker 下拉框的类名" + "widget": { + "props": { + "height": 150, + "language": "json" + }, + "component": "CodeConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "defaultValue": "", - "type": "string", - "widget": { - "component": "InputConfigurator", - "props": {} + "property": "texts", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "辅助文字数组,文字的数量应该与max属性一致" }, - "device": [] + "defaultValue": "['很差', '差', '一般', '好', '很好']", + "labelPosition": "left" } ], "description": { - "zh_CN": "" + "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性" } } ], "events": { - "onUpdate:modelValue": { - "label": { - "zh_CN": "双向绑定值改变时触发" - }, - "description": { - "zh_CN": "双向绑定值改变时触发" - } - }, "onChange": { - "label": { - "zh_CN": "用户确认选定的值时触发" - }, - "description": { - "zh_CN": "用户确认选定的值时触发" - }, - "type": "event", - "defaultValue": "" - }, - "onBlur": { - "label": { - "zh_CN": "在组件 Input 失去焦点时触发" - }, - "description": { - "zh_CN": "在组件 Input 失去焦点时触发" - }, - "type": "event", - "defaultValue": "" - }, - "onFocus": { - "label": { - "zh_CN": "在组件 Input 获得焦点时触发" - }, - "description": { - "zh_CN": "在组件 Input 获得焦点时触发" - }, - "type": "event", - "defaultValue": "" - }, - "onCalendarChange": { - "label": { - "zh_CN": "在日历所选日期更改时触发" - }, - "description": { - "zh_CN": "在日历所选日期更改时触发" - }, - "type": "event", - "defaultValue": "" - }, - "onPanelChange": { - "label": { - "zh_CN": "当日期面板改变时触发。" - }, - "description": { - "zh_CN": "当日期面板改变时触发。" - }, "type": "event", - "defaultValue": "" - }, - "onVisibleChange": { "label": { - "zh_CN": "当 DatePicker 的下拉列表出现/消失时触发" + "zh_CN": "分值改变时触发" }, "description": { - "zh_CN": "当 DatePicker 的下拉列表出现/消失时触发" + "zh_CN": "分值改变时触发" }, - "type": "event", - "defaultValue": "" + "defaultValue": "", + "functionInfo": { + "params": [ + { + "name": "value", + "type": "number", + "description": { + "zh_CN": "改变后的分值" + }, + "defaultValue": "" + } + ], + "returns": { + "type": "", + "description": { + "zh_CN": "" + }, + "defaultValue": "" + } + } } }, - "slots": { - "default": { - "label": { - "zh_CN": "自定义单元格内容" - }, - "description": { - "zh_CN": "自定义单元格内容" - } - }, - "range-separator": { - "label": { - "zh_CN": "自定义范围分割符内容" - }, - "description": { - "zh_CN": "自定义范围分割符内容" - } - } - } - } - }, - { - "id": 1, - "version": "2.4.2", - "name": { - "zh_CN": "按钮" - }, - "component": "ElButton", - "icon": "button", - "description": "常用的操作按钮", - "doc_url": "", - "screenshot": "", - "tags": "", - "keywords": "", - "dev_mode": "proCode", - "npm": { - "package": "element-plus", - "exportName": "ElButton", - "destructuring": true + "slots": {} }, - "group": "基础组件", - "category": "element-plus", "configure": { "loop": true, "condition": true, "styles": true, - "isContainer": true, + "isContainer": false, "isModal": false, - "isPopper": false, "nestingRule": { "childWhitelist": "", "parentWhitelist": "", @@ -785,16 +598,35 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["type", "size"] + "properties": [] }, "contextMenu": { - "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"], - "disable": [] - }, - "invalidity": [""], - "clickCapture": true, - "framework": "Vue" + "actions": ["create symbol"], + "disable": ["copy", "remove"] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "滑块" + }, + "component": "TinySlider", + "icon": "slider", + "description": "滑块", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "package": "@opentiny/vue", + "exportName": "TinySlider", + "destructuring": true }, + "group": "component", + "category": "滑块组件", + "priority": 2, "schema": { "properties": [ { @@ -804,297 +636,465 @@ }, "content": [ { - "property": "size", + "cols": 12, + "type": "object", "label": { "text": { - "zh_CN": "尺寸" + "zh_CN": "绑定值" } }, - "description": { - "zh_CN": "尺寸" - }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "defaultValue": "default", "widget": { - "component": "SelectConfigurator", "props": { - "options": [ - { - "label": "large", - "value": "large" - }, - { - "label": "default", - "value": "default" - }, - { - "label": "small", - "value": "small" - } - ] - } - } + "height": 150, + "language": "json" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "modelValue", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "设置单滑块的当前值,必需是整数或数组" + }, + "defaultValue": null, + "labelPosition": "left" }, { - "property": "type", + "cols": 12, + "type": "number", "label": { "text": { - "zh_CN": "类型" + "zh_CN": "最小值" } }, - "description": { - "zh_CN": "类型" + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "widget": { - "component": "InputConfigurator", - "props": {} - } + "property": "min", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "设置最小值" + }, + "defaultValue": 0, + "labelPosition": "left" }, { - "property": "plain", + "cols": 12, + "type": "number", "label": { "text": { - "zh_CN": "朴素按钮" + "zh_CN": "最大值" } }, - "description": { - "zh_CN": "是否为朴素按钮" + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "widget": { - "component": "CheckBoxConfigurator", - "props": {} + "property": "max", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "设置最大值,必需是整数,可以负数,必需大于所设置的最小值" }, - "device": [] + "defaultValue": 100, + "labelPosition": "left" }, { - "property": "text", + "cols": 12, + "type": "number", "label": { "text": { - "zh_CN": "文字按钮" + "zh_CN": "步长" } }, - "description": { - "zh_CN": "是否为文字按钮" + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "widget": { - "component": "CheckBoxConfigurator", - "props": {} + "property": "step", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "设置滑块移动时,每步位移距离,必需是大于0的正整数" }, - "device": [] - }, + "defaultValue": 1, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性" + } + }, + { + "name": "1", + "label": { + "zh_CN": "样式属性" + }, + "content": [ { - "property": "bg", + "cols": 12, + "type": "string", "label": { "text": { - "zh_CN": "背景颜色" + "zh_CN": "高度" } }, - "description": { - "zh_CN": "是否显示文字按钮背景颜色" + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "widget": { - "component": "CheckBoxConfigurator", - "props": {} + "property": "height", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "Slider 组件的高度,当 vertical 为 true 时有效" }, - "device": [] - }, + "defaultValue": "300px", + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性" + } + }, + { + "name": "2", + "label": { + "zh_CN": "行为属性" + }, + "content": [ { - "property": "link", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "链接按钮" + "zh_CN": "禁用" } }, - "description": { - "zh_CN": "是否为链接按钮" + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "widget": { - "component": "CheckBoxConfigurator", - "props": {} + "property": "disabled", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否禁用" }, - "device": [] + "defaultValue": false, + "labelPosition": "left" }, { - "property": "round", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "圆角按钮" + "zh_CN": "显示输入框" } }, - "description": { - "zh_CN": "是否为圆角按钮" + "widget": { + "props": {}, + "component": "SwitchConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "widget": { - "component": "CheckBoxConfigurator", - "props": {} + "property": "show-input", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否显示输入框" }, - "device": [] + "defaultValue": false, + "labelPosition": "left" }, { - "property": "circle", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "圆形按钮" + "zh_CN": "显示提示" } }, - "description": { - "zh_CN": "是否为圆形按钮" + "widget": { + "props": {}, + "component": "SwitchConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, + "property": "show-tip", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否显示 tooltip" + }, + "defaultValue": true, + "labelPosition": "left" + }, + { "cols": 12, - "labelPosition": "left", - "type": "string", + "type": "boolean", + "label": { + "text": { + "zh_CN": "单位" + } + }, "widget": { - "component": "CheckBoxConfigurator", - "props": {} + "props": {}, + "component": "CheckBoxConfigurator" }, - "device": [] + "disabled": false, + "property": "unit", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "输入框后面显示的单位,仅在输入框模式下有效" + }, + "defaultValue": false, + "labelPosition": "left" }, { - "property": "loading", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "加载中状态" + "zh_CN": "竖向模式" } }, - "description": { - "zh_CN": "是否为加载中状态" + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, + "property": "vertical", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否竖向模式" + }, + "defaultValue": false, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性" + } + }, + { + "name": "3", + "label": { + "zh_CN": "高级属性" + }, + "content": [ + { "cols": 12, - "labelPosition": "left", - "type": "string", + "type": "function", + "label": { + "text": { + "zh_CN": "格式化提示" + } + }, "widget": { - "component": "CheckBoxConfigurator", - "props": {} + "props": { + "height": 150, + "language": "javascript" + }, + "component": "CodeConfigurator" }, - "device": [] + "disabled": false, + "property": "format-tooltip", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "格式化 tooltip 提示" + }, + "defaultValue": null, + "labelPosition": "left" }, { - "property": "disabled", + "cols": 12, + "type": "object", "label": { "text": { - "zh_CN": "禁用" + "zh_CN": "刻度" } }, - "description": { - "zh_CN": "是否禁用" + "widget": { + "props": { + "height": 150, + "language": "json" + }, + "component": "CodeConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, + "property": "marks", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "设置滑杆的刻度值" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { "cols": 12, - "labelPosition": "left", - "defaultValue": false, - "type": "boolean", + "type": "number", + "label": { + "text": { + "zh_CN": "总步数" + } + }, "widget": { - "component": "CheckBoxConfigurator", - "props": {} + "props": { + "step": 1 + }, + "component": "NumberConfigurator" }, - "device": [] + "disabled": false, + "property": "num-pages", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "设置总步数,即按快捷键 PageDown/PageUp 时,每次移动的距离是 \"⌈(max-min)/num-pages⌉\"" + }, + "defaultValue": 1, + "labelPosition": "left" } ], "description": { - "zh_CN": "" + "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置" } } ], - "events": {}, - "slots": { - "default": { + "events": { + "onStop": { + "type": "event", "label": { - "zh_CN": "default" + "zh_CN": "滑动结束时触发" }, "description": { - "zh_CN": "自定义默认内容" + "zh_CN": "设置滑块滑动结束时,触发该事件" + }, + "defaultValue": "", + "functionInfo": { + "params": [ + { + "name": "value", + "type": "number | [number, number]", + "description": { + "zh_CN": "当前值" + }, + "defaultValue": "" + } + ], + "returns": { + "type": "", + "description": { + "zh_CN": "" + }, + "defaultValue": "" + } } }, - "loading": { + "onStart": { + "type": "event", "label": { - "zh_CN": "loading" + "zh_CN": "滑动开始时触发" }, "description": { - "zh_CN": "自定义加载中组件" + "zh_CN": "设置滑块滑动开始时,触发该事件" + }, + "defaultValue": "", + "functionInfo": { + "params": [ + { + "name": "event", + "type": "Event", + "description": { + "zh_CN": "事件对象" + }, + "defaultValue": "" + }, + { + "name": "value", + "type": "number | [number, number]", + "description": { + "zh_CN": "当前值" + }, + "defaultValue": "" + } + ], + "returns": { + "type": "", + "description": { + "zh_CN": "" + }, + "defaultValue": "" + } + } + }, + "onChange": { + "type": "event", + "label": { + "zh_CN": "值改变时触发" + }, + "description": { + "zh_CN": "值改变时触发(使用鼠标拖曳时,只在松开鼠标后触发)" + }, + "defaultValue": "", + "functionInfo": { + "params": [ + { + "name": "value", + "type": "number | [number, number]", + "description": { + "zh_CN": "当前值" + }, + "defaultValue": "" + } + ], + "returns": { + "type": "", + "description": { + "zh_CN": "" + }, + "defaultValue": "" + } + } + } + }, + "slots": { + "default": { + "label": { + "zh_CN": "默认内容" + }, + "description": { + "zh_CN": "显示滑块值的插槽,仅仅 v-model 是单数值时才有效" } } } - } - }, - { - "id": 1, - "version": "2.4.2", - "name": { - "zh_CN": "表单" - }, - "component": "ElForm", - "icon": "form", - "description": "表单包含 输入框, 单选框, 下拉选择, 多选框 等用户输入的组件。 使用表单,您可以收集、验证和提交数据。", - "doc_url": "", - "screenshot": "", - "tags": "", - "keywords": "", - "dev_mode": "proCode", - "npm": { - "package": "element-plus", - "exportName": "ElForm", - "destructuring": true }, - "group": "表单组件", - "category": "element-plus", "configure": { "loop": true, "condition": true, "styles": true, - "isContainer": true, + "isContainer": false, "isModal": false, - "isPopper": false, "nestingRule": { - "childWhitelist": ["ElFormItem"], + "childWhitelist": "", "parentWhitelist": "", "descendantBlacklist": "", "ancestorWhitelist": "" @@ -1103,16 +1103,35 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["inline", "label-width"] + "properties": [] }, "contextMenu": { - "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"], - "disable": [] - }, - "invalidity": [""], - "clickCapture": true, - "framework": "Vue" + "actions": ["create symbol"], + "disable": ["copy", "remove"] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "级联选择器" }, + "component": "TinyCascader", + "icon": "cascader", + "description": "级联选择器", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "package": "@opentiny/vue", + "exportName": "TinyCascader", + "destructuring": true + }, + "group": "component", + "category": "组件", + "priority": 2, "schema": { "properties": [ { @@ -1122,429 +1141,612 @@ }, "content": [ { - "property": "model", + "cols": 12, + "type": "object", "label": { "text": { - "zh_CN": "数据对象" + "zh_CN": "绑定值" } }, - "description": { - "zh_CN": "表单数据对象" - }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "labelPosition": "top", "widget": { - "component": "CodeConfigurator", "props": { + "height": 150, "language": "json" - } - } + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "modelValue", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "选中项绑定值, 其类型由 props.multiple、props.emitPath 共同决定" + }, + "defaultValue": null, + "labelPosition": "left" }, { - "property": "rules", + "cols": 12, + "type": "array", "label": { "text": { - "zh_CN": "验证规则" + "zh_CN": "选项数据" } }, - "description": { - "zh_CN": "表单验证规则" - }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "labelPosition": "top", "widget": { - "component": "CodeConfigurator", "props": { + "height": 150, "language": "json" - } - } + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "options", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "可选项数据源,键名可通过 Props 属性配置" + }, + "defaultValue": null, + "labelPosition": "left" }, { - "property": "inline", + "cols": 12, + "type": "string", "label": { "text": { - "zh_CN": "行内模式" + "zh_CN": "占位文本" } }, - "description": { - "zh_CN": "行内表单模式" + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "boolean", - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "property": "placeholder", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "输入框占位文本" + }, + "defaultValue": "请选择", + "labelPosition": "left" }, { - "property": "label-position", + "cols": 12, + "type": "enum", "label": { "text": { - "zh_CN": "标签位置" + "zh_CN": "尺寸" } }, - "description": { - "zh_CN": "表单域标签的位置, 当设置为 left 或 right 时,则也需要设置标签宽度属性" - }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "defaultValue": "right", "widget": { - "component": "SelectConfigurator", "props": { "options": [ { - "label": "left", - "value": "left" + "label": "medium", + "value": "medium" }, { - "label": "right", - "value": "right" + "label": "small", + "value": "small" }, { - "label": "top", - "value": "top" + "label": "mini", + "value": "mini" } ] - } - } + }, + "component": "SelectConfigurator" + }, + "disabled": false, + "property": "size", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "尺寸" + }, + "defaultValue": null, + "labelPosition": "left" }, { - "property": "label-width", + "cols": 12, + "type": "string", "label": { "text": { - "zh_CN": "标签宽度" + "zh_CN": "分隔符" } }, - "description": { - "zh_CN": "标签的长度,例如 '50px'。 作为 Form 直接子元素的 form-item 会继承该值。 可以使用 auto。" + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "widget": { - "component": "InputConfigurator", - "props": {} + "property": "separator", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "选项分隔符" }, - "device": [] + "defaultValue": "/", + "labelPosition": "left" }, { - "property": "label-suffix", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "标签后缀" + "zh_CN": "显示所有层级" } }, - "description": { - "zh_CN": "表单域标签的后缀" + "widget": { + "props": {}, + "component": "SwitchConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "widget": { - "component": "InputConfigurator", - "props": {} + "property": "show-all-levels", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "输入框中是否显示选中值的完整路径" }, - "device": [] - }, + "defaultValue": true, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性" + } + }, + { + "name": "1", + "label": { + "zh_CN": "行为属性" + }, + "content": [ { - "property": "hide-required-asterisk", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "隐藏必填星号" + "zh_CN": "禁用" } }, - "description": { - "zh_CN": "是否隐藏必填字段标签旁边的红色星号" + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "boolean", - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "property": "disabled", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否禁用" + }, + "defaultValue": false, + "labelPosition": "left" }, { - "property": "require-asterisk-position", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "星号位置" + "zh_CN": "可清空" } }, - "description": { - "zh_CN": "星号的位置" + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "defaultValue": "left", - "widget": { - "component": "ButtonGroupConfigurator", - "props": { - "options": [ - { - "label": "left", - "value": "left" - }, - { - "label": "right", - "value": "right" - } - ] - } - } + "property": "clearable", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否支持清空选项" + }, + "defaultValue": false, + "labelPosition": "left" }, { - "property": "show-message", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "显示校验信息" + "zh_CN": "折叠标签" } }, - "description": { - "zh_CN": "是否显示校验错误信息" + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "defaultValue": true, - "type": "boolean", - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "property": "collapse-tags", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "多选模式下是否折叠 Tag" + }, + "defaultValue": false, + "labelPosition": "left" }, { - "property": "inline-message", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "行内显示校验信息" + "zh_CN": "可筛选" } }, - "description": { - "zh_CN": "是否以行内形式展示校验信息" + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "defaultValue": false, - "type": "boolean", - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "property": "filterable", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否可搜索选项" + }, + "defaultValue": null, + "labelPosition": "left" }, { - "property": "status-icon", + "cols": 12, + "type": "number", "label": { "text": { - "zh_CN": "显示校验结果图标" + "zh_CN": "去抖延迟" } }, - "description": { - "zh_CN": "是否在输入框中显示校验结果反馈图标" + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, + "property": "debounce", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "搜索关键词输入的去抖延迟,单位毫秒" + }, + "defaultValue": 300, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性" + } + }, + { + "name": "2", + "label": { + "zh_CN": "高级属性" + }, + "content": [ + { "cols": 12, - "labelPosition": "left", - "defaultValue": false, - "type": "boolean", + "type": "object", + "label": { + "text": { + "zh_CN": "筛选前钩子" + } + }, "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "props": { + "height": 150, + "language": "json" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "before-filter", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "筛选之前的钩子,参数为输入的值,若返回 false 或者返回 Promise 且被 reject,则停止筛选" + }, + "defaultValue": null, + "labelPosition": "left" }, { - "property": "validate-on-rule-change", + "cols": 12, + "type": "object", "label": { "text": { - "zh_CN": "触发验证" + "zh_CN": "筛选方法" } }, - "description": { - "zh_CN": "是否在 rules 属性改变后立即触发一次验证" + "widget": { + "props": { + "height": 150, + "language": "json" + }, + "component": "CodeConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, + "property": "filter-method", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "自定义搜索逻辑,第一个参数是节点 node,第二个参数是搜索关键词 keyword,通过返回布尔值表示是否命中" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { "cols": 12, - "labelPosition": "left", - "defaultValue": true, - "type": "boolean", + "type": "object", + "label": { + "text": { + "zh_CN": "配置选项" + } + }, "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "props": { + "height": 150, + "language": "json" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "props", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "配置选项,具体见 ICascaderPanelConfig 表" + }, + "defaultValue": null, + "labelPosition": "left" }, { - "property": "size", + "cols": 12, + "type": "string", "label": { "text": { - "zh_CN": "尺寸" + "zh_CN": "形状模式" } }, - "description": { - "zh_CN": "用于控制该表单内组件的尺寸" + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, + "property": "shape", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "通过 shape='filter' 属性切换至过滤器模式" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { "cols": 12, - "labelPosition": "left", "type": "string", - "defaultValue": "default", + "label": { + "text": { + "zh_CN": "标签" + } + }, "widget": { - "component": "SelectConfigurator", "props": { - "options": [ - { - "label": "large", - "value": "large" - }, - { - "label": "default", - "value": "default" - }, - { - "label": "small", - "value": "small" - } - ] - } - } + "placeholder": "请输入..." + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "label", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "shape='filter' 时生效,可传入 label 显示标题" + }, + "defaultValue": null, + "labelPosition": "left" }, { - "property": "disabled", + "cols": 12, + "type": "string", "label": { "text": { - "zh_CN": "禁用" + "zh_CN": "提示信息" } }, - "description": { - "zh_CN": "是否禁用该表单内的所有组件。 如果设置为 true, 它将覆盖内部组件的 disabled 属性" + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, + "property": "tip", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "shape='filter' 时生效,可传入 tip 显示提示信息" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { "cols": 12, - "labelPosition": "left", - "defaultValue": false, "type": "boolean", + "label": { + "text": { + "zh_CN": "透明背景" + } + }, "widget": { - "component": "CheckBoxConfigurator", - "props": {} + "props": {}, + "component": "CheckBoxConfigurator" }, - "device": [] + "disabled": false, + "property": "blank", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "shape='filter' 时生效,设置过滤器模式背景为透明" + }, + "defaultValue": false, + "labelPosition": "left" }, { - "property": "scroll-to-error", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "滚动到错误项" + "zh_CN": "弹出框插入 body" } }, - "description": { - "zh_CN": "当校验失败时,滚动到第一个错误表单项" + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, + "property": "popper-append-to-body", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否将弹出框插入至 body 元素。在弹出框的定位出现问题时,可将该属性设置为 false (可参考 select 组件)" + }, + "defaultValue": true, + "labelPosition": "left" + }, + { "cols": 12, - "labelPosition": "left", - "defaultValue": false, - "type": "boolean", + "type": "string", + "label": { + "text": { + "zh_CN": "弹出框类名" + } + }, "widget": { - "component": "CheckBoxConfigurator", - "props": {} + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" }, - "device": [] + "disabled": false, + "property": "popper-class", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "为 popper 添加类名(可参考 popover 组件)" + }, + "defaultValue": null, + "labelPosition": "left" } ], "description": { - "zh_CN": "" + "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置" } } ], "events": { - "onValidate": { + "onBlur": { + "type": "event", "label": { - "zh_CN": "任一表单项被校验后触发" + "zh_CN": "当失去焦点时触发" }, "description": { - "zh_CN": "任一表单项被校验后触发" + "zh_CN": "当失去焦点时触发" }, + "defaultValue": "" + }, + "onFocus": { "type": "event", - "functionInfo": { - "params": [], - "returns": {} + "label": { + "zh_CN": "当获得焦点时触发" + }, + "description": { + "zh_CN": "当获得焦点时触发" }, "defaultValue": "" - } - }, - "slots": {} - } - }, - { - "id": 1, - "version": "2.4.2", - "name": { - "zh_CN": "表单子项" - }, - "component": "ElFormItem", - "icon": "formItem", - "description": "表单包含 输入框, 单选框, 下拉选择, 多选框 等用户输入的组件。 使用表单,您可以收集、验证和提交数据。", - "doc_url": "", - "screenshot": "", - "tags": "", - "keywords": "", - "dev_mode": "proCode", - "npm": { - "package": "element-plus", - "exportName": "ElFormItem", - "destructuring": true + }, + "onChange": { + "type": "event", + "label": { + "zh_CN": "当选中节点变化时触发" + }, + "description": { + "zh_CN": "当选中节点变化时触发" + }, + "defaultValue": "" + }, + "onRemoveTag": { + "type": "event", + "label": { + "zh_CN": "在多选模式下,移除Tag时触发" + }, + "description": { + "zh_CN": "在多选模式下,移除Tag时触发" + }, + "defaultValue": "" + }, + "onExpandChange": { + "type": "event", + "label": { + "zh_CN": "当展开节点发生变化时触发" + }, + "description": { + "zh_CN": "当展开节点发生变化时触发" + }, + "defaultValue": "" + }, + "onVisibleChange": { + "type": "event", + "label": { + "zh_CN": "下拉框出现/隐藏时触发" + }, + "description": { + "zh_CN": "下拉框出现/隐藏时触发" + }, + "defaultValue": "" + } + }, + "slots": { + "empty": { + "label": { + "zh_CN": "空状态" + }, + "description": { + "zh_CN": "无匹配选项时的内容" + } + }, + "default": { + "label": { + "zh_CN": "默认内容" + }, + "description": { + "zh_CN": "自定义备选项的节点内容,参数为 { node: ICascaderPanelNode, data: ICascaderPanelData },分别为当前节点的 Node 对象和数据" + } + }, + "no-data": { + "label": { + "zh_CN": "无数据" + }, + "description": { + "zh_CN": "通过 no-data 插槽设置没有数据时显示的内容" + } + } + } }, - "group": "表单组件", - "category": "element-plus", "configure": { "loop": true, "condition": true, "styles": true, - "isContainer": true, + "isContainer": false, "isModal": false, - "isPopper": false, "nestingRule": { "childWhitelist": "", "parentWhitelist": "", @@ -1555,16 +1757,35 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["inline", "label-width"] + "properties": [] }, "contextMenu": { - "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"], - "disable": [] - }, - "invalidity": [""], - "clickCapture": true, - "framework": "Vue" + "actions": ["create symbol"], + "disable": ["copy", "remove"] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "单选组" + }, + "component": "TinyRadioGroup", + "icon": "radiogroup", + "description": "单选组", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "package": "@opentiny/vue", + "exportName": "TinyRadioGroup", + "destructuring": true }, + "group": "component", + "category": "组件", + "priority": 2, "schema": { "properties": [ { @@ -1574,325 +1795,324 @@ }, "content": [ { - "property": "prop", + "cols": 12, + "type": "array", "label": { "text": { - "zh_CN": "键名" + "zh_CN": "绑定值" } }, - "description": { - "zh_CN": "model 的键名。 它可以是一个属性的值(如 a.b.0 或 [a', 'b', '0'])。 在定义了 validate、resetFields 的方法时,该属性是必填的" + "widget": { + "props": { + "height": 150, + "language": "json" + }, + "component": "CodeConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "widget": { - "component": "InputConfigurator", - "props": {} - } + "property": "modelValue", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "单选组绑定值" + }, + "defaultValue": null, + "labelPosition": "left" }, { - "property": "label", + "cols": 12, + "type": "string", "label": { "text": { - "zh_CN": "标签文本" + "zh_CN": "尺寸" } }, - "description": { - "zh_CN": "标签文本" + "widget": { + "props": { + "options": [ + { + "label": "medium", + "value": "medium" + }, + { + "label": "small", + "value": "small" + }, + { + "label": "mini", + "value": "mini" + } + ] + }, + "component": "SelectConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "widget": { - "component": "InputConfigurator", - "props": {} - } + "property": "size", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "单选组尺寸" + }, + "defaultValue": null, + "labelPosition": "left" }, { - "property": "label-width", + "cols": 12, + "type": "string", "label": { "text": { - "zh_CN": "标签宽度" + "zh_CN": "类型" } }, - "description": { - "zh_CN": "标签宽度,例如 '50px'。 可以使用 auto" + "widget": { + "props": { + "options": [ + { + "label": "radio", + "value": "radio" + }, + { + "label": "button", + "value": "button" + } + ] + }, + "component": "SelectConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, + "property": "type", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "配置式单选组的展示形式" + }, + "defaultValue": "radio", + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性" + } + }, + { + "name": "1", + "label": { + "zh_CN": "样式属性" + }, + "content": [ + { "cols": 12, - "labelPosition": "left", "type": "string", - "widget": { - "component": "InputConfigurator", - "props": {} - } - }, - { - "property": "required", "label": { "text": { - "zh_CN": "必填项" + "zh_CN": "填充颜色" } }, - "description": { - "zh_CN": "是否为必填项,如不设置,则会根据校验规则确认" + "widget": { + "props": {}, + "component": "ColorConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "boolean", - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "property": "fill", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "按钮形式单选选中时的背景颜色" + }, + "defaultValue": null, + "labelPosition": "left" }, { - "property": "rules", + "cols": 12, + "type": "string", "label": { "text": { - "zh_CN": "验证规则" + "zh_CN": "文本颜色" } }, - "description": { - "zh_CN": "表单验证规则, 更多内容可以参考async-validator" + "widget": { + "props": {}, + "component": "ColorConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "top", - "widget": { - "component": "CodeConfigurator", - "props": { - "language": "json" - } - } - }, + "property": "text-color", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "按钮形式单选激活时的文本颜色" + }, + "defaultValue": null, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性" + } + }, + { + "name": "2", + "label": { + "zh_CN": "行为属性" + }, + "content": [ { - "property": "error", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "错误信息" + "zh_CN": "禁用" } }, - "description": { - "zh_CN": "表单域验证错误时的提示信息。设置该值会导致表单验证状态变为 error,并显示该错误信息" + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "widget": { - "component": "InputConfigurator", - "props": {} - } - }, - { - "property": "show-message", - "label": { - "text": { - "zh_CN": "显示错误信息" - } - }, + "property": "disabled", + "readOnly": false, + "required": false, "description": { - "zh_CN": "是否显示校验错误信息" + "zh_CN": "是否禁用单选组" }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "boolean", - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "defaultValue": false, + "labelPosition": "left" }, { - "property": "inline-message", - "label": { - "text": { - "zh_CN": "行内显示错误信息" - } - }, - "description": { - "zh_CN": "是否在行内显示校验信息" - }, - "required": true, - "readOnly": false, - "disabled": false, "cols": 12, - "labelPosition": "left", "type": "boolean", - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } - }, - { - "property": "size", "label": { "text": { - "zh_CN": "尺寸" + "zh_CN": "只读" } }, - "description": { - "zh_CN": "用于控制该表单内组件的尺寸" + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "defaultValue": "default", - "widget": { - "component": "SelectConfigurator", - "props": { - "options": [ - { - "label": "large", - "value": "large" - }, - { - "label": "default", - "value": "default" - }, - { - "label": "small", - "value": "small" - } - ] - } - } + "property": "display-only", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否只读状态" + }, + "defaultValue": false, + "labelPosition": "left" }, { - "property": "for", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "for" + "zh_CN": "垂直显示" } }, - "description": { - "zh_CN": "和原生标签相同能力" + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "widget": { - "component": "InputConfigurator", - "props": {} - } - }, + "property": "vertical", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "垂直显示单选组" + }, + "defaultValue": false, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性" + } + }, + { + "name": "3", + "label": { + "zh_CN": "高级属性" + }, + "content": [ { - "property": "validate-status", + "cols": 12, + "type": "array", "label": { "text": { - "zh_CN": "校验状态" + "zh_CN": "选项配置" } }, - "description": { - "zh_CN": "formItem 校验的状态" - }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", "widget": { - "component": "SelectConfigurator", "props": { - "options": [ - { - "label": "error", - "value": "error" - }, - { - "label": "validating", - "value": "validating" - }, - { - "label": "success", - "value": "success" - } - ] - } - } + "height": 150, + "language": "json" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "options", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "配置式单选组设置列表" + }, + "defaultValue": null, + "labelPosition": "left" } ], "description": { - "zh_CN": "" + "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置" } } ], - "events": {}, - "slots": { - "label": { + "events": { + "onChange": { + "type": "event", "label": { - "zh_CN": "label" + "zh_CN": "绑定值变化时触发" }, "description": { - "zh_CN": "标签位置显示的内容" + "zh_CN": "绑定值变化时触发的事件" + }, + "defaultValue": "", + "functionInfo": { + "params": [ + { + "name": "value", + "type": "number[] | string[]", + "description": { + "zh_CN": "变化后的值" + }, + "defaultValue": "" + } + ], + "returns": { + "type": "void", + "description": { + "zh_CN": "无返回值" + }, + "defaultValue": "" + } } - }, - "error": { + } + }, + "slots": { + "default": { "label": { - "zh_CN": "error" + "zh_CN": "默认内容" }, "description": { - "zh_CN": "验证错误信息的显示内容" + "zh_CN": "radio-group 的默认插槽" } } } - } - }, - { - "id": 1, - "version": "2.4.2", - "name": { - "zh_CN": "表单" - }, - "component": "ElTable", - "icon": "table", - "description": "用于展示多条结构类似的数据, 可对数据进行排序、筛选、对比或其他自定义操作", - "doc_url": "", - "screenshot": "", - "tags": "", - "keywords": "", - "dev_mode": "proCode", - "npm": { - "package": "element-plus", - "exportName": "ElTable", - "destructuring": true }, - "group": "数据展示", - "category": "element-plus", "configure": { "loop": true, "condition": true, "styles": true, "isContainer": false, "isModal": false, - "isPopper": false, "nestingRule": { - "childWhitelist": ["ElTableColumn"], + "childWhitelist": "", "parentWhitelist": "", "descendantBlacklist": "", "ancestorWhitelist": "" @@ -1901,16 +2121,35 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["inline", "label-width"] + "properties": [] }, "contextMenu": { - "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"], - "disable": [] - }, - "invalidity": [""], - "clickCapture": true, - "framework": "Vue" + "actions": ["create symbol"], + "disable": ["copy", "remove"] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "步骤条" + }, + "component": "TinySteps", + "icon": "steps", + "description": "步骤条", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "package": "@opentiny/vue", + "exportName": "TinySteps", + "destructuring": true }, + "group": "component", + "category": "步骤条", + "priority": 2, "schema": { "properties": [ { @@ -1920,147 +2159,5147 @@ }, "content": [ { - "property": "data", + "cols": 12, + "type": "number", "label": { "text": { - "zh_CN": "数据" + "zh_CN": "当前步骤" } }, - "description": { - "zh_CN": "显示的数据" + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, + "property": "active", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "当前步骤索引,从0开始计数" + }, + "defaultValue": -1, + "labelPosition": "left" + }, + { "cols": 12, - "labelPosition": "top", - "widget": { - "component": "CodeConfigurator", + "type": "array", + "label": { + "text": { + "zh_CN": "数据" + } + }, + "widget": { "props": { + "height": 150, "language": "json" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "data", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "步骤条的数据" + }, + "defaultValue": [], + "labelPosition": "left" + }, + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "名称字段" } - } + }, + "widget": { + "props": { + "placeholder": "请输入字段名" + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "name-field", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "节点名称对应的字段名" + }, + "defaultValue": "", + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件核心功能相关的配置,包括当前步骤、数据等核心属性" + } + }, + { + "name": "1", + "label": { + "zh_CN": "样式属性" + }, + "content": [ + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "内容居中" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "content-center", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "使步骤条内容默认居中显示" + }, + "defaultValue": false, + "labelPosition": "left" }, { - "property": "columns", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "表格列配置" + "zh_CN": "点状样式" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "dot", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "点状形步骤条,当值只支持垂直样式" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "自适应宽度" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "flex", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "节点是否自适应宽度" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "横向单链" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "line", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "通过 line 设置横向单链型步骤条" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "间距" } }, + "widget": { + "props": { + "placeholder": "请输入宽度值" + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "space", + "readOnly": false, "required": true, + "description": { + "zh_CN": "节点宽度, 可取值数字、带长度单位数值与百分比,传数字则默认以 px 为长度单位" + }, + "defaultValue": null, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性" + } + }, + { + "name": "2", + "label": { + "zh_CN": "行为属性" + }, + "content": [ + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "高级模式" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "advanced", "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否开启高级向导模式" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "number", + "label": { + "text": { + "zh_CN": "持续时间" + } + }, + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" + }, "disabled": false, + "property": "duration", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "节点滚动的持续时间(单位 ms),仅高级向导模式有效" + }, + "defaultValue": 300, + "labelPosition": "left" + }, + { "cols": 12, - "properties": [ - { - "label": { - "zh_CN": "默认分组" - }, - "content": [ - { - "property": "type", - "type": "string", - "labelPosition": "top", - "label": { - "text": { - "zh_CN": "type" - } - }, - "description": { - "text": { - "zh_CN": "对应列的类型。 如果设置了selection则显示多选框; 如果设置了 index 则显示该行的索引(从 1 开始计算); 如果设置了 expand 则显示为一个可展开的按钮" - } - }, - "widget": { - "component": "SelectConfigurator", - "props": { - "options": [ - { - "label": "selection", - "value": "selection" - }, - { - "label": "index", - "value": "index" - }, - { - "label": "expand", - "value": "expand" - } - ] - } - } - }, - { - "property": "index", - "type": "string", - "labelPosition": "top", - "label": { - "text": { - "zh_CN": "index" - } - }, - "description": { - "text": { - "zh_CN": "如果设置了 type=index,可以通过传递 index 属性来自定义索引" - } - }, - "widget": { - "component": "CodeConfigurator", - "props": {} - } - }, - { - "property": "label", - "type": "string", - "labelPosition": "top", - "label": { - "text": { - "zh_CN": "label" - } - }, - "description": { - "text": { - "zh_CN": "显示的标题" - } - }, - "widget": { - "component": "InputConfigurator", - "props": {} - } - }, - { - "property": "column-key", - "type": "string", - "labelPosition": "top", - "label": { - "text": { - "zh_CN": "column-key" - } + "type": "number", + "label": { + "text": { + "zh_CN": "可见节点数" + } + }, + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" + }, + "disabled": false, + "property": "visible-num", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "控制信息可见的节点数,默认可见5个" + }, + "defaultValue": 5, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性" + } + }, + { + "name": "3", + "label": { + "zh_CN": "高级属性" + }, + "content": [ + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "计数字段" + } + }, + "widget": { + "props": { + "placeholder": "请输入字段名" + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "count-field", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "条形步骤条里徽标计数对应的字段名" + }, + "defaultValue": "", + "labelPosition": "left" + }, + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "状态字段" + } + }, + "widget": { + "props": { + "placeholder": "请输入字段名" + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "status-field", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "数据状态对应的字段名,用于条形步骤条" + }, + "defaultValue": "", + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置" + } + } + ], + "events": { + "onClick": { + "type": "event", + "label": { + "zh_CN": "节点点击事件" + }, + "description": { + "zh_CN": "节点点击事件,参数:index: 点击节点的索引node:点击节点的数据" + }, + "defaultValue": "", + "functionInfo": { + "params": [ + { + "name": "index", + "type": "number", + "description": { + "zh_CN": "点击节点的索引" + }, + "defaultValue": "" + }, + { + "name": "node", + "type": "IStepsItem", + "description": { + "zh_CN": "点击节点的数据" + }, + "defaultValue": "" + } + ], + "returns": { + "type": "", + "description": { + "zh_CN": "" + }, + "defaultValue": "" + } + } + } + }, + "slots": { + "item": { + "label": { + "zh_CN": "数据项" + }, + "description": { + "zh_CN": "步骤条数据项插槽,用于条形步骤条" + } + }, + "itemFooter": { + "label": { + "zh_CN": "itemFooter" + }, + "description": { + "zh_CN": "步骤条数据项底部插槽,用于条形步骤条" + } + } + } + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [] + }, + "contextMenu": { + "actions": ["create symbol"], + "disable": ["copy", "remove"] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "树形菜单" + }, + "component": "TinyTreeMenu", + "icon": "tree", + "description": "树形菜单", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "package": "@opentiny/vue", + "exportName": "TinyTreeMenu", + "destructuring": true + }, + "group": "component", + "category": "组件", + "priority": 2, + "schema": { + "properties": [ + { + "name": "0", + "label": { + "zh_CN": "基础属性" + }, + "content": [ + { + "cols": 12, + "type": "array", + "label": { + "text": { + "zh_CN": "数据源" + } + }, + "widget": { + "props": { + "height": 150, + "language": "json" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "data", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "静态数据源" + }, + "defaultValue": [], + "labelPosition": "left" + }, + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "节点键" + } + }, + "widget": { + "props": { + "placeholder": "请输入节点键字段名" + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "node-key", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "设置每个树节点唯一标识(key)的属性,在整棵树中都是唯一的" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "object", + "label": { + "text": { + "zh_CN": "映射字段" + } + }, + "widget": { + "props": { + "height": 150, + "language": "json" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "props", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "映射字段" + }, + "defaultValue": { + "label": "label", + "isLeaf": "isLeaf", + "children": "children", + "disabled": "disabled" + }, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "array", + "label": { + "text": { + "zh_CN": "默认勾选键" + } + }, + "widget": { + "props": { + "height": 150, + "language": "json" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "default-checked-keys", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "默认勾选节点的 key 的数组" + }, + "defaultValue": [], + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "默认展开所有" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "default-expand-all", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否默认展开所有子节点" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "array", + "label": { + "text": { + "zh_CN": "默认展开键" + } + }, + "widget": { + "props": { + "height": 150, + "language": "json" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "default-expanded-keys", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "默认展开节点的 key 的数组" + }, + "defaultValue": [], + "labelPosition": "left" + }, + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "默认展开高亮键" + } + }, + "widget": { + "props": { + "placeholder": "请输入高亮节点键" + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "default-expanded-keys-highlight", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "设置默认展开节点中的某个节点高亮,配合 default-expanded-keys 属性使用" + }, + "defaultValue": null, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件核心功能相关的配置,包括 data、node-key、props 等核心属性" + } + }, + { + "name": "1", + "label": { + "zh_CN": "样式属性" + }, + "content": [ + { + "cols": 12, + "type": "number", + "label": { + "text": { + "zh_CN": "缩进距离" + } + }, + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" + }, + "disabled": false, + "property": "indent", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "子级相对于父级节点的水平缩进距离,单位 px" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "number", + "label": { + "text": { + "zh_CN": "节点高度" + } + }, + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" + }, + "disabled": false, + "property": "node-height", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "节点高度" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "文字省略" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "ellipsis", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否文字超长省略显示。优先级高于 wrap" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "换行显示" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "wrap", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否换行显示" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "component", + "label": { + "text": { + "zh_CN": "自定义图标" + } + }, + "widget": { + "props": { + "height": 150, + "language": "javascript" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "customIcon", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "设置带图标树形菜单" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "component", + "label": { + "text": { + "zh_CN": "搜索图标" + } + }, + "widget": { + "props": { + "height": 150, + "language": "javascript" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "search-icon", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "自定义搜索图标" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "component", + "label": { + "text": { + "zh_CN": "后缀图标" + } + }, + "widget": { + "props": { + "height": 150, + "language": "javascript" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "suffix-icon", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "全局设置带图标树形菜单" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "显示数字" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "show-number", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "右侧下拉图标区域是否显示为 number 属性定义的数字内容,建议不超过 4 个字符" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "width-adapt" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "width-adapt", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "通过 widthAdapt 属性,是否让组件宽度自适应父容器。" + }, + "defaultValue": false, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 indent、node-height、ellipsis 等与视觉呈现相关的属性" + } + }, + { + "name": "2", + "label": { + "zh_CN": "行为属性" + }, + "content": [ + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "手风琴效果" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "accordion", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否设置为手风琴效果(只能展开一个同级别的节点)" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "严格勾选" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "check-strictly", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否遵循父级和子级严格不相关联的做法,配合 show-checkbox 属性使用" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "可清空" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "clearable", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "搜索框是否可清空" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "可收起" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "collapsible", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否允许展开后的菜单收起,未和 show-number 配套使用时,仍可以点击图标收起" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "可拖动" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "draggable", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否可拖动菜单节点" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "点击节点展开" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "expand-on-click-node", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否能点击节点即展开/收起。配置为 fasle 则只能点击下拉图标展开/收起" + }, + "defaultValue": true, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "highlight-query" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "highlight-query", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "通过 highlightQuery 属性,是否在匹配的节点中,高亮搜索文字。" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "懒加载" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "lazy", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否懒加载子节点,配合 load 属性使用" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "侧边折叠按钮" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "menu-collapsible", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否显示侧边折叠与展开按钮" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "仅子级可选" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "only-check-children", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "父级是否不可选,只能展开不能跳转" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "显示复选框" + } + }, + "widget": { + "props": {}, + "component": "SwitchConfigurator" + }, + "disabled": false, + "property": "show-checkbox", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "节点是否可被选择" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "显示展开收起" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "show-expand", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否启用一键展开/收起功能。点击左下角图标可展开/收起菜单注意:配合 customIcon 属性使用,纯文本菜单不支持此功能" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "显示搜索框" + } + }, + "widget": { + "props": {}, + "component": "SwitchConfigurator" + }, + "disabled": false, + "property": "show-filter", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否显示搜索框,可搜索过滤节点" + }, + "defaultValue": true, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "显示标题提示" + } + }, + "widget": { + "props": {}, + "component": "SwitchConfigurator" + }, + "disabled": false, + "property": "show-title", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否显示节点的 title 提示,鼠标悬浮节点之上触发" + }, + "defaultValue": true, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件交互、事件、状态相关的配置,包括 accordion、draggable、show-checkbox 等与用户操作和状态相关的属性" + } + }, + { + "name": "3", + "label": { + "zh_CN": "高级属性" + }, + "content": [ + { + "cols": 12, + "type": "function", + "label": { + "text": { + "zh_CN": "允许拖拽回调" + } + }, + "widget": { + "props": { + "height": 150, + "language": "javascript" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "allow-drag", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "拖拽开始前的回调事件,定义节点是否允许拖拽的规则,返回 true 则允许拖拽,配合 draggable 属性使用" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "function", + "label": { + "text": { + "zh_CN": "允许放置回调" + } + }, + "widget": { + "props": { + "height": 150, + "language": "javascript" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "allow-drop", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "拖拽结束前的回调事件,定义节点是否允许放置到模板节点的规则,返回 true 则允许放置,配合 draggable 属性使用" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "function", + "label": { + "text": { + "zh_CN": "节点过滤方法" + } + }, + "widget": { + "props": { + "height": 150, + "language": "javascript" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "filter-node-method", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "自定义树节点过滤的方法,返回 true 表示这个节点可以显示,返回 false 则表示这个节点会被隐藏" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "function", + "label": { + "text": { + "zh_CN": "获取数据方法" + } + }, + "widget": { + "props": { + "height": 150, + "language": "javascript" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "get-menu-data-sync", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "自定义获取服务端数据源的方法,返回一个 Promise 对象" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "function", + "label": { + "text": { + "zh_CN": "加载子树方法" + } + }, + "widget": { + "props": { + "height": 150, + "language": "javascript" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "load", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "加载子树数据的方法,仅当 lazy 属性为 true 时生效" + }, + "defaultValue": null, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置" + } + }, + { + "name": "4", + "label": { + "zh_CN": "其他属性" + }, + "content": [ + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "空文本" + } + }, + "widget": { + "props": { + "placeholder": "请输入空文本" + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "empty-text", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "内容为空时展示的文本" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "占位符" + } + }, + "widget": { + "props": { + "placeholder": "请输入占位符" + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "placeholder", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "当数据为空时的占位符" + }, + "defaultValue": null, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "无法归属到 “基础/样式/行为/高级属性” 的特殊配置项,这类属性通常不具备前四类分组的明确功能共性" + } + } + ], + "events": { + "onNodeClick": { + "type": "event", + "label": { + "zh_CN": "节点点击" + }, + "description": { + "zh_CN": "监听节点被点击时的事件" + }, + "defaultValue": "", + "functionInfo": { + "params": [ + { + "name": "nodeData", + "type": "ITreeNodeData", + "description": { + "zh_CN": "节点数据" + }, + "defaultValue": "" + }, + { + "name": "node", + "type": "ITreeNodeVm", + "description": { + "zh_CN": "节点对象" + }, + "defaultValue": "" + } + ], + "returns": { + "type": "void", + "description": { + "zh_CN": "无返回值" + }, + "defaultValue": "" + } + } + }, + "onNodeExpand": { + "type": "event", + "label": { + "zh_CN": "节点展开" + }, + "description": { + "zh_CN": "监听节点被点击展开时的事件;" + }, + "defaultValue": "", + "functionInfo": { + "params": [ + { + "name": "nodeData", + "type": "ITreeNodeData", + "description": { + "zh_CN": "节点数据" + }, + "defaultValue": "" + }, + { + "name": "node", + "type": "ITreeNodeVm", + "description": { + "zh_CN": "节点对象" + }, + "defaultValue": "" + } + ], + "returns": { + "type": "void", + "description": { + "zh_CN": "无返回值" + }, + "defaultValue": "" + } + } + }, + "onCheckChange": { + "type": "event", + "label": { + "zh_CN": "勾选状态变化" + }, + "description": { + "zh_CN": "监听可勾选节点的勾选状态发生变化时的事件" + }, + "defaultValue": "", + "functionInfo": { + "params": [ + { + "name": "node", + "type": "ITreeNodeVm", + "description": { + "zh_CN": "节点对象" + }, + "defaultValue": "" + }, + { + "name": "checked", + "type": "boolean", + "description": { + "zh_CN": "是否勾选" + }, + "defaultValue": "" + }, + { + "name": "indeterminate", + "type": "boolean", + "description": { + "zh_CN": "是否半选" + }, + "defaultValue": "" + } + ], + "returns": { + "type": "void", + "description": { + "zh_CN": "无返回值" + }, + "defaultValue": "" + } + } + }, + "onNodeDragEnd": { + "type": "event", + "label": { + "zh_CN": "节点拖拽结束" + }, + "description": { + "zh_CN": "监听节点拖拽结束(可能未成功)的事件" + }, + "defaultValue": "", + "functionInfo": { + "params": [ + { + "name": "draggingNode", + "type": "ITreeNodeVm", + "description": { + "zh_CN": "拖拽节点" + }, + "defaultValue": "" + }, + { + "name": "targetNode", + "type": "ITreeNodeVm", + "description": { + "zh_CN": "目标节点" + }, + "defaultValue": "" + }, + { + "name": "dropType", + "type": "IDropType", + "description": { + "zh_CN": "放置类型" + }, + "defaultValue": "" + }, + { + "name": "event", + "type": "DragEvent", + "description": { + "zh_CN": "拖拽事件" + }, + "defaultValue": "" + } + ], + "returns": { + "type": "void", + "description": { + "zh_CN": "无返回值" + }, + "defaultValue": "" + } + } + }, + "onNodeCollapse": { + "type": "event", + "label": { + "zh_CN": "节点收起" + }, + "description": { + "zh_CN": "监听节点被点击收起时的事件;" + }, + "defaultValue": "", + "functionInfo": { + "params": [ + { + "name": "nodeData", + "type": "ITreeNodeData", + "description": { + "zh_CN": "节点数据" + }, + "defaultValue": "" + }, + { + "name": "node", + "type": "ITreeNodeVm", + "description": { + "zh_CN": "节点对象" + }, + "defaultValue": "" + } + ], + "returns": { + "type": "void", + "description": { + "zh_CN": "无返回值" + }, + "defaultValue": "" + } + } + }, + "onCurrentChange": { + "type": "event", + "label": { + "zh_CN": "当前节点变化" + }, + "description": { + "zh_CN": "监听当前选中节点发生变化时的事件" + }, + "defaultValue": "", + "functionInfo": { + "params": [ + { + "name": "nodeData", + "type": "ITreeNodeData", + "description": { + "zh_CN": "节点数据" + }, + "defaultValue": "" + }, + { + "name": "node", + "type": "ITreeNodeVm", + "description": { + "zh_CN": "节点对象" + }, + "defaultValue": "" + } + ], + "returns": { + "type": "void", + "description": { + "zh_CN": "无返回值" + }, + "defaultValue": "" + } + } + }, + "onNodeDragStart": { + "type": "event", + "label": { + "zh_CN": "节点拖拽开始" + }, + "description": { + "zh_CN": "监听节点开始拖拽的事件" + }, + "defaultValue": "", + "functionInfo": { + "params": [ + { + "name": "node", + "type": "ITreeNodeVm", + "description": { + "zh_CN": "节点对象" + }, + "defaultValue": "" + }, + { + "name": "event", + "type": "DragEvent", + "description": { + "zh_CN": "拖拽事件" + }, + "defaultValue": "" + } + ], + "returns": { + "type": "void", + "description": { + "zh_CN": "无返回值" + }, + "defaultValue": "" + } + } + } + }, + "slots": { + "default": { + "label": { + "zh_CN": "默认内容" + }, + "description": { + "zh_CN": "自定义树节点的内容,参数为 { node, data }" + } + } + } + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [] + }, + "contextMenu": { + "actions": ["create symbol"], + "disable": ["copy", "remove"] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "折线图" + }, + "component": "TinyHuichartsLine", + "icon": "line", + "description": "折线图", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "destructuring": true, + "exportName": "TinyHuichartsLine", + "name": "TinyVueHuicharts组件库", + "package": "@opentiny/vue-huicharts", + "version": "3.22.0", + "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs" + }, + "group": "chart", + "category": "图表组件", + "priority": 2, + "schema": { + "properties": [ + { + "label": { + "zh_CN": "基础信息" + }, + "description": { + "zh_CN": "基础信息" + }, + "content": [ + { + "property": "options", + "label": { + "text": { + "zh_CN": "图表配置" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + }, + "description": { + "zh_CN": "折线图配置" + }, + "labelPosition": "left" + } + ] + } + ], + "events": {} + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [] + }, + "contextMenu": { + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "柱状图" + }, + "component": "TinyHuichartsHistogram", + "icon": "histogram", + "description": "柱状图", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "destructuring": true, + "exportName": "TinyHuichartsHistogram", + "name": "TinyVueHuicharts组件库", + "package": "@opentiny/vue-huicharts", + "version": "3.22.0", + "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs" + }, + "group": "chart", + "category": "图表组件", + "priority": 2, + "schema": { + "properties": [ + { + "label": { + "zh_CN": "基础信息" + }, + "description": { + "zh_CN": "基础信息" + }, + "content": [ + { + "property": "options", + "label": { + "text": { + "zh_CN": "图表配置" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + }, + "description": { + "zh_CN": "柱状图配置" + }, + "labelPosition": "left" + } + ] + } + ], + "events": {} + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [] + }, + "contextMenu": { + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "条形图" + }, + "component": "TinyHuichartsBar", + "icon": "bar", + "description": "条形图", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "destructuring": true, + "exportName": "TinyHuichartsBar", + "name": "TinyVueHuicharts组件库", + "package": "@opentiny/vue-huicharts", + "version": "3.22.0", + "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs" + }, + "group": "chart", + "category": "图表组件", + "priority": 2, + "schema": { + "properties": [ + { + "label": { + "zh_CN": "基础信息" + }, + "description": { + "zh_CN": "基础信息" + }, + "content": [ + { + "property": "options", + "label": { + "text": { + "zh_CN": "图表配置" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + }, + "description": { + "zh_CN": "条形图配置" + }, + "labelPosition": "left" + } + ] + } + ], + "events": { + "onReady": { + "type": "event", + "label": { + "zh_CN": "图表渲染完成后触发" + }, + "description": { + "zh_CN": "图表渲染完成后触发,每次渲染都会触发一次" + }, + "defaultValue": "", + "functionInfo": { + "params": [], + "returns": {} + } + }, + "onReadyOnce": { + "type": "event", + "label": { + "zh_CN": "图表渲染完成后触发" + }, + "description": { + "zh_CN": "图表渲染完成后触发,只会在首次渲染完成后触发" + }, + "defaultValue": "", + "functionInfo": { + "params": [], + "returns": {} + } + } + } + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [] + }, + "contextMenu": { + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "圆盘图" + }, + "component": "TinyHuichartsPie", + "icon": "pie", + "description": "圆盘图", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "destructuring": true, + "exportName": "TinyHuichartsPie", + "name": "TinyVueHuicharts组件库", + "package": "@opentiny/vue-huicharts", + "version": "3.22.0", + "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs" + }, + "group": "chart", + "category": "图表组件", + "priority": 2, + "schema": { + "properties": [ + { + "label": { + "zh_CN": "基础信息" + }, + "description": { + "zh_CN": "基础信息" + }, + "content": [ + { + "property": "options", + "label": { + "text": { + "zh_CN": "图表配置" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + }, + "description": { + "zh_CN": "圆盘图配置" + }, + "labelPosition": "left" + } + ] + } + ], + "events": {} + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [] + }, + "contextMenu": { + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "环形图" + }, + "component": "TinyHuichartsRing", + "icon": "ring", + "description": "环形图", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "destructuring": true, + "exportName": "TinyHuichartsRing", + "name": "TinyVueHuicharts组件库", + "package": "@opentiny/vue-huicharts", + "version": "3.22.0", + "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs" + }, + "group": "chart", + "category": "图表组件", + "priority": 2, + "schema": { + "properties": [ + { + "label": { + "zh_CN": "基础信息" + }, + "description": { + "zh_CN": "基础信息" + }, + "content": [ + { + "property": "options", + "label": { + "text": { + "zh_CN": "图表配置" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + }, + "description": { + "zh_CN": "环形图配置" + }, + "labelPosition": "left" + } + ] + } + ], + "events": { + "onReady": { + "type": "event", + "label": { + "zh_CN": "图表渲染完成后触发" + }, + "description": { + "zh_CN": "图表渲染完成后触发,每次渲染都会触发一次" + }, + "defaultValue": "", + "functionInfo": { + "params": [], + "returns": {} + } + }, + "onReadyOnce": { + "type": "event", + "label": { + "zh_CN": "图表渲染完成后触发" + }, + "description": { + "zh_CN": "图表渲染完成后触发,只会在首次渲染完成后触发" + }, + "defaultValue": "", + "functionInfo": { + "params": [], + "returns": {} + } + } + }, + "slots": { + "default": { + "label": { + "zh_CN": "默认内容" + }, + "description": { + "zh_CN": "组件默认插槽" + } + } + } + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [] + }, + "contextMenu": { + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "雷达图" + }, + "component": "TinyHuichartsRadar", + "icon": "radar", + "description": "雷达图", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "destructuring": true, + "exportName": "TinyHuichartsRadar", + "name": "TinyVueHuicharts组件库", + "package": "@opentiny/vue-huicharts", + "version": "3.22.0", + "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs" + }, + "group": "chart", + "category": "图表组件", + "priority": 2, + "schema": { + "properties": [ + { + "label": { + "zh_CN": "基础信息" + }, + "description": { + "zh_CN": "基础信息" + }, + "content": [ + { + "property": "options", + "label": { + "text": { + "zh_CN": "图表配置" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + }, + "description": { + "zh_CN": "雷达图配置" + }, + "labelPosition": "left" + } + ] + } + ], + "events": { + "onReady": { + "type": "event", + "label": { + "zh_CN": "图表渲染完成后触发" + }, + "description": { + "zh_CN": "图表渲染完成后触发,每次渲染都会触发一次" + }, + "defaultValue": "", + "functionInfo": { + "params": [], + "returns": {} + } + }, + "onReadyOnce": { + "type": "event", + "label": { + "zh_CN": "图表渲染完成后触发" + }, + "description": { + "zh_CN": "图表渲染完成后触发,只会在首次渲染完成后触发" + }, + "defaultValue": "", + "functionInfo": { + "params": [], + "returns": {} + } + } + }, + "slots": { + "default": { + "label": { + "zh_CN": "默认内容" + }, + "description": { + "zh_CN": "组件默认插槽" + } + } + } + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [] + }, + "contextMenu": { + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "漏斗图" + }, + "component": "TinyHuichartsFunnel", + "icon": "funnel", + "description": "漏斗图", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "destructuring": true, + "exportName": "TinyHuichartsFunnel", + "name": "TinyVueHuicharts组件库", + "package": "@opentiny/vue-huicharts", + "version": "3.22.0", + "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs" + }, + "group": "chart", + "category": "图表组件", + "priority": 2, + "schema": { + "properties": [ + { + "label": { + "zh_CN": "基础信息" + }, + "description": { + "zh_CN": "基础信息" + }, + "content": [ + { + "property": "options", + "label": { + "text": { + "zh_CN": "图表配置" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + }, + "description": { + "zh_CN": "漏斗图配置" + }, + "labelPosition": "left" + } + ] + } + ], + "events": {} + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [] + }, + "contextMenu": { + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "散点图" + }, + "component": "TinyHuichartsScatter", + "icon": "scatter", + "description": "散点图", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "destructuring": true, + "exportName": "TinyHuichartsScatter", + "name": "TinyVueHuicharts组件库", + "package": "@opentiny/vue-huicharts", + "version": "3.22.0", + "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs" + }, + "group": "chart", + "category": "图表组件", + "priority": 2, + "schema": { + "properties": [ + { + "label": { + "zh_CN": "基础信息" + }, + "description": { + "zh_CN": "基础信息" + }, + "content": [ + { + "property": "options", + "label": { + "text": { + "zh_CN": "图表配置" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + }, + "description": { + "zh_CN": "散点图配置" + }, + "labelPosition": "left" + } + ] + } + ], + "events": {} + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [] + }, + "contextMenu": { + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "瀑布图" + }, + "component": "TinyHuichartsWaterfall", + "icon": "waterfall", + "description": "瀑布图", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "destructuring": true, + "exportName": "TinyHuichartsWaterfall", + "name": "TinyVueHuicharts组件库", + "package": "@opentiny/vue-huicharts", + "version": "3.22.0", + "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs" + }, + "group": "chart", + "category": "图表组件", + "priority": 2, + "schema": { + "properties": [ + { + "label": { + "zh_CN": "基础信息" + }, + "description": { + "zh_CN": "基础信息" + }, + "content": [ + { + "property": "options", + "label": { + "text": { + "zh_CN": "图表配置" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + }, + "description": { + "zh_CN": "瀑布图配置" + }, + "labelPosition": "left" + } + ] + } + ], + "events": {} + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [] + }, + "contextMenu": { + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] + } + } + }, + { + "id": 1, + "version": "2.4.2", + "name": { + "zh_CN": "输入框" + }, + "component": "ElInput", + "icon": "input", + "description": "通过鼠标或键盘输入字符", + "doc_url": "", + "screenshot": "", + "tags": "", + "keywords": "", + "dev_mode": "proCode", + "npm": { + "package": "element-plus", + "exportName": "ElInput", + "destructuring": true + }, + "group": "表单组件", + "category": "element-plus", + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "isPopper": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [ + "type", + "size" + ] + }, + "contextMenu": { + "actions": [ + "copy", + "remove", + "insert", + "updateAttr", + "bindEvent", + "createBlock" + ], + "disable": [] + }, + "invalidity": [ + "" + ], + "clickCapture": true, + "framework": "Vue" + }, + "schema": { + "properties": [ + { + "name": "0", + "label": { + "zh_CN": "基础属性" + }, + "content": [ + { + "property": "modelValue", + "label": { + "text": { + "zh_CN": "绑定值" + } + }, + "description": { + "zh_CN": "绑定值" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "InputConfigurator", + "props": {} + } + }, + { + "property": "size", + "label": { + "text": { + "zh_CN": "尺寸" + } + }, + "description": { + "zh_CN": "尺寸" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "defaultValue": "default", + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "large", + "value": "large" + }, + { + "label": "default", + "value": "default" + }, + { + "label": "small", + "value": "small" + } + ] + } + } + }, + { + "property": "type", + "label": { + "text": { + "zh_CN": "类型" + } + }, + "description": { + "zh_CN": "类型" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "InputConfigurator", + "props": {} + } + }, + { + "property": "placeholder", + "label": { + "text": { + "zh_CN": "占位文本" + } + }, + "description": { + "zh_CN": "输入框占位文本" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "I18nConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "maxlength", + "label": { + "text": { + "zh_CN": "最大长度" + } + }, + "description": { + "zh_CN": "最大输入长度" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "number", + "widget": { + "component": "NumberConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "disabled", + "label": { + "text": { + "zh_CN": "是否禁用" + } + }, + "description": { + "zh_CN": "是否禁用" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": false, + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "device": [] + } + ], + "description": { + "zh_CN": "" + } + } + ], + "events": { + "onUpdate:modelValue": { + "label": { + "zh_CN": "双向绑定值改变时触发" + }, + "description": { + "zh_CN": "双向绑定值改变时触发" + } + }, + "onBlur": { + "label": { + "zh_CN": "输入框失去焦点时触发" + }, + "description": { + "zh_CN": "输入框失去焦点时触发" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "event", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "原生 event" + } + } + ], + "returns": {} + }, + "defaultValue": "" + } + }, + "slots": { + "prefix": { + "label": { + "zh_CN": "头部内容" + }, + "description": { + "zh_CN": "输入框头部内容,只对非 type='textarea' 有效" + } + }, + "suffix": { + "label": { + "zh_CN": "尾部内容" + }, + "description": { + "zh_CN": "输入框尾部内容,只对非 type='textarea' 有效" + } + }, + "prepend": { + "label": { + "zh_CN": "前置内容" + }, + "description": { + "zh_CN": "输入框前置内容,只对非 type='textarea' 有效" + } + }, + "append": { + "label": { + "zh_CN": "后置内容" + }, + "description": { + "zh_CN": "输入框后置内容,只对非 type='textarea' 有效" + } + } + } + } + }, + { + "id": 1, + "version": "2.4.2", + "name": { + "zh_CN": "日期选择器" + }, + "component": "ElDatePicker", + "icon": "datepick", + "description": "日期选择器", + "doc_url": "", + "screenshot": "", + "tags": "", + "keywords": "", + "dev_mode": "proCode", + "npm": { + "package": "element-plus", + "exportName": "ElDatePicker", + "destructuring": true + }, + "group": "表单组件", + "category": "element-plus", + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "isPopper": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [ + "type", + "size" + ] + }, + "contextMenu": { + "actions": [ + "copy", + "remove", + "insert", + "updateAttr", + "bindEvent", + "createBlock" + ], + "disable": [] + }, + "invalidity": [ + "" + ], + "clickCapture": true, + "framework": "Vue" + }, + "schema": { + "properties": [ + { + "name": "0", + "label": { + "zh_CN": "基础属性" + }, + "content": [ + { + "property": "modelValue", + "label": { + "text": { + "zh_CN": "绑定值" + } + }, + "description": { + "zh_CN": "绑定值" + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "InputConfigurator", + "props": {} + } + }, + { + "property": "readonly", + "label": { + "text": { + "zh_CN": "只读" + } + }, + "description": { + "zh_CN": "是否只读" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "boolean", + "defaultValue": false, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "disabled", + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "description": { + "zh_CN": "是否禁用" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "boolean", + "defaultValue": false, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "size", + "label": { + "text": { + "zh_CN": "尺寸" + } + }, + "description": { + "zh_CN": "输入框尺寸" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "defaultValue": "", + "widget": { + "component": "SelectConfigurator", + "props": { + "allowClear": true, + "options": [ + { + "label": "large", + "value": "large" + }, + { + "label": "default", + "value": "default" + }, + { + "label": "small", + "value": "small" + } + ] + } + } + }, + { + "property": "editable", + "label": { + "text": { + "zh_CN": "是否可编辑" + } + }, + "description": { + "zh_CN": "文本框是否可编辑" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "boolean", + "defaultValue": true, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "clearable", + "label": { + "text": { + "zh_CN": "是否可清除" + } + }, + "description": { + "zh_CN": "是否显示清楚按钮" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "boolean", + "defaultValue": true, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "placeholder", + "label": { + "text": { + "zh_CN": "占位文本" + } + }, + "description": { + "zh_CN": "非范围选择时的占位内容" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": "", + "type": "string", + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "start-placeholder", + "label": { + "text": { + "zh_CN": "起始占位文本" + } + }, + "description": { + "zh_CN": "范围选择时开始日期的占位内容" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": "", + "type": "string", + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "end-placeholder", + "label": { + "text": { + "zh_CN": "结束占位文本" + } + }, + "description": { + "zh_CN": "范围选择时结束日期的占位内容" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": "", + "type": "string", + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "type", + "label": { + "text": { + "zh_CN": "类型" + } + }, + "description": { + "zh_CN": "显示类型" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": "date", + "type": "string", + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "year", + "value": "year" + }, + { + "label": "years", + "value": "years" + }, + { + "label": "month", + "value": "month" + }, + { + "label": "months", + "value": "months" + }, + { + "label": "date", + "value": "date" + }, + { + "label": "dates", + "value": "dates" + }, + { + "label": "datetime", + "value": "datetime" + }, + { + "label": "week", + "value": "week" + }, + { + "label": "datetimerange", + "value": "datetimerange" + }, + { + "label": "daterange", + "value": "daterange" + }, + { + "label": "monthrange", + "value": "monthrange" + }, + { + "label": "yearrange", + "value": "yearrange" + } + ] + } + }, + "device": [] + }, + { + "property": "popper-class", + "label": { + "text": { + "zh_CN": "下拉框类名" + } + }, + "description": { + "zh_CN": "DatePicker 下拉框的类名" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": "", + "type": "string", + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "device": [] + } + ], + "description": { + "zh_CN": "" + } + } + ], + "events": { + "onUpdate:modelValue": { + "label": { + "zh_CN": "双向绑定值改变时触发" + }, + "description": { + "zh_CN": "双向绑定值改变时触发" + } + }, + "onChange": { + "label": { + "zh_CN": "用户确认选定的值时触发" + }, + "description": { + "zh_CN": "用户确认选定的值时触发" + }, + "type": "event", + "defaultValue": "" + }, + "onBlur": { + "label": { + "zh_CN": "在组件 Input 失去焦点时触发" + }, + "description": { + "zh_CN": "在组件 Input 失去焦点时触发" + }, + "type": "event", + "defaultValue": "" + }, + "onFocus": { + "label": { + "zh_CN": "在组件 Input 获得焦点时触发" + }, + "description": { + "zh_CN": "在组件 Input 获得焦点时触发" + }, + "type": "event", + "defaultValue": "" + }, + "onCalendarChange": { + "label": { + "zh_CN": "在日历所选日期更改时触发" + }, + "description": { + "zh_CN": "在日历所选日期更改时触发" + }, + "type": "event", + "defaultValue": "" + }, + "onPanelChange": { + "label": { + "zh_CN": "当日期面板改变时触发。" + }, + "description": { + "zh_CN": "当日期面板改变时触发。" + }, + "type": "event", + "defaultValue": "" + }, + "onVisibleChange": { + "label": { + "zh_CN": "当 DatePicker 的下拉列表出现/消失时触发" + }, + "description": { + "zh_CN": "当 DatePicker 的下拉列表出现/消失时触发" + }, + "type": "event", + "defaultValue": "" + } + }, + "slots": { + "default": { + "label": { + "zh_CN": "自定义单元格内容" + }, + "description": { + "zh_CN": "自定义单元格内容" + } + }, + "range-separator": { + "label": { + "zh_CN": "自定义范围分割符内容" + }, + "description": { + "zh_CN": "自定义范围分割符内容" + } + } + } + } + }, + { + "id": 1, + "version": "2.4.2", + "name": { + "zh_CN": "按钮" + }, + "component": "ElButton", + "icon": "button", + "description": "常用的操作按钮", + "doc_url": "", + "screenshot": "", + "tags": "", + "keywords": "", + "dev_mode": "proCode", + "npm": { + "package": "element-plus", + "exportName": "ElButton", + "destructuring": true + }, + "group": "基础组件", + "category": "element-plus", + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": true, + "isModal": false, + "isPopper": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [ + "type", + "size" + ] + }, + "contextMenu": { + "actions": [ + "copy", + "remove", + "insert", + "updateAttr", + "bindEvent", + "createBlock" + ], + "disable": [] + }, + "invalidity": [ + "" + ], + "clickCapture": true, + "framework": "Vue" + }, + "schema": { + "properties": [ + { + "name": "0", + "label": { + "zh_CN": "基础属性" + }, + "content": [ + { + "property": "size", + "label": { + "text": { + "zh_CN": "尺寸" + } + }, + "description": { + "zh_CN": "尺寸" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "defaultValue": "default", + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "large", + "value": "large" + }, + { + "label": "default", + "value": "default" + }, + { + "label": "small", + "value": "small" + } + ] + } + } + }, + { + "property": "type", + "label": { + "text": { + "zh_CN": "类型" + } + }, + "description": { + "zh_CN": "类型" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "InputConfigurator", + "props": {} + } + }, + { + "property": "plain", + "label": { + "text": { + "zh_CN": "朴素按钮" + } + }, + "description": { + "zh_CN": "是否为朴素按钮" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "text", + "label": { + "text": { + "zh_CN": "文字按钮" + } + }, + "description": { + "zh_CN": "是否为文字按钮" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "bg", + "label": { + "text": { + "zh_CN": "背景颜色" + } + }, + "description": { + "zh_CN": "是否显示文字按钮背景颜色" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "link", + "label": { + "text": { + "zh_CN": "链接按钮" + } + }, + "description": { + "zh_CN": "是否为链接按钮" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "round", + "label": { + "text": { + "zh_CN": "圆角按钮" + } + }, + "description": { + "zh_CN": "是否为圆角按钮" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "circle", + "label": { + "text": { + "zh_CN": "圆形按钮" + } + }, + "description": { + "zh_CN": "是否为圆形按钮" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "loading", + "label": { + "text": { + "zh_CN": "加载中状态" + } + }, + "description": { + "zh_CN": "是否为加载中状态" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "disabled", + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "description": { + "zh_CN": "是否禁用" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": false, + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "device": [] + } + ], + "description": { + "zh_CN": "" + } + } + ], + "events": {}, + "slots": { + "default": { + "label": { + "zh_CN": "default" + }, + "description": { + "zh_CN": "自定义默认内容" + } + }, + "loading": { + "label": { + "zh_CN": "loading" + }, + "description": { + "zh_CN": "自定义加载中组件" + } + } + } + } + }, + { + "id": 1, + "version": "2.4.2", + "name": { + "zh_CN": "表单" + }, + "component": "ElForm", + "icon": "form", + "description": "表单包含 输入框, 单选框, 下拉选择, 多选框 等用户输入的组件。 使用表单,您可以收集、验证和提交数据。", + "doc_url": "", + "screenshot": "", + "tags": "", + "keywords": "", + "dev_mode": "proCode", + "npm": { + "package": "element-plus", + "exportName": "ElForm", + "destructuring": true + }, + "group": "表单组件", + "category": "element-plus", + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": true, + "isModal": false, + "isPopper": false, + "nestingRule": { + "childWhitelist": [ + "ElFormItem" + ], + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [ + "inline", + "label-width" + ] + }, + "contextMenu": { + "actions": [ + "copy", + "remove", + "insert", + "updateAttr", + "bindEvent", + "createBlock" + ], + "disable": [] + }, + "invalidity": [ + "" + ], + "clickCapture": true, + "framework": "Vue" + }, + "schema": { + "properties": [ + { + "name": "0", + "label": { + "zh_CN": "基础属性" + }, + "content": [ + { + "property": "model", + "label": { + "text": { + "zh_CN": "数据对象" + } + }, + "description": { + "zh_CN": "表单数据对象" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "top", + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + } + }, + { + "property": "rules", + "label": { + "text": { + "zh_CN": "验证规则" + } + }, + "description": { + "zh_CN": "表单验证规则" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "top", + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + } + }, + { + "property": "inline", + "label": { + "text": { + "zh_CN": "行内模式" + } + }, + "description": { + "zh_CN": "行内表单模式" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "label-position", + "label": { + "text": { + "zh_CN": "标签位置" + } + }, + "description": { + "zh_CN": "表单域标签的位置, 当设置为 left 或 right 时,则也需要设置标签宽度属性" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "defaultValue": "right", + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "left", + "value": "left" + }, + { + "label": "right", + "value": "right" + }, + { + "label": "top", + "value": "top" + } + ] + } + } + }, + { + "property": "label-width", + "label": { + "text": { + "zh_CN": "标签宽度" + } + }, + "description": { + "zh_CN": "标签的长度,例如 '50px'。 作为 Form 直接子元素的 form-item 会继承该值。 可以使用 auto。" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "label-suffix", + "label": { + "text": { + "zh_CN": "标签后缀" + } + }, + "description": { + "zh_CN": "表单域标签的后缀" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "hide-required-asterisk", + "label": { + "text": { + "zh_CN": "隐藏必填星号" + } + }, + "description": { + "zh_CN": "是否隐藏必填字段标签旁边的红色星号" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "require-asterisk-position", + "label": { + "text": { + "zh_CN": "星号位置" + } + }, + "description": { + "zh_CN": "星号的位置" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "defaultValue": "left", + "widget": { + "component": "ButtonGroupConfigurator", + "props": { + "options": [ + { + "label": "left", + "value": "left" + }, + { + "label": "right", + "value": "right" + } + ] + } + } + }, + { + "property": "show-message", + "label": { + "text": { + "zh_CN": "显示校验信息" + } + }, + "description": { + "zh_CN": "是否显示校验错误信息" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": true, + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "inline-message", + "label": { + "text": { + "zh_CN": "行内显示校验信息" + } + }, + "description": { + "zh_CN": "是否以行内形式展示校验信息" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": false, + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "status-icon", + "label": { + "text": { + "zh_CN": "显示校验结果图标" + } + }, + "description": { + "zh_CN": "是否在输入框中显示校验结果反馈图标" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": false, + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "validate-on-rule-change", + "label": { + "text": { + "zh_CN": "触发验证" + } + }, + "description": { + "zh_CN": "是否在 rules 属性改变后立即触发一次验证" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": true, + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "size", + "label": { + "text": { + "zh_CN": "尺寸" + } + }, + "description": { + "zh_CN": "用于控制该表单内组件的尺寸" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "defaultValue": "default", + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "large", + "value": "large" + }, + { + "label": "default", + "value": "default" + }, + { + "label": "small", + "value": "small" + } + ] + } + } + }, + { + "property": "disabled", + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "description": { + "zh_CN": "是否禁用该表单内的所有组件。 如果设置为 true, 它将覆盖内部组件的 disabled 属性" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": false, + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "scroll-to-error", + "label": { + "text": { + "zh_CN": "滚动到错误项" + } + }, + "description": { + "zh_CN": "当校验失败时,滚动到第一个错误表单项" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": false, + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "device": [] + } + ], + "description": { + "zh_CN": "" + } + } + ], + "events": { + "onValidate": { + "label": { + "zh_CN": "任一表单项被校验后触发" + }, + "description": { + "zh_CN": "任一表单项被校验后触发" + }, + "type": "event", + "functionInfo": { + "params": [], + "returns": {} + }, + "defaultValue": "" + } + }, + "slots": {} + } + }, + { + "id": 1, + "version": "2.4.2", + "name": { + "zh_CN": "表单子项" + }, + "component": "ElFormItem", + "icon": "formItem", + "description": "表单包含 输入框, 单选框, 下拉选择, 多选框 等用户输入的组件。 使用表单,您可以收集、验证和提交数据。", + "doc_url": "", + "screenshot": "", + "tags": "", + "keywords": "", + "dev_mode": "proCode", + "npm": { + "package": "element-plus", + "exportName": "ElFormItem", + "destructuring": true + }, + "group": "表单组件", + "category": "element-plus", + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": true, + "isModal": false, + "isPopper": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [ + "inline", + "label-width" + ] + }, + "contextMenu": { + "actions": [ + "copy", + "remove", + "insert", + "updateAttr", + "bindEvent", + "createBlock" + ], + "disable": [] + }, + "invalidity": [ + "" + ], + "clickCapture": true, + "framework": "Vue" + }, + "schema": { + "properties": [ + { + "name": "0", + "label": { + "zh_CN": "基础属性" + }, + "content": [ + { + "property": "prop", + "label": { + "text": { + "zh_CN": "键名" + } + }, + "description": { + "zh_CN": "model 的键名。 它可以是一个属性的值(如 a.b.0 或 [a', 'b', '0'])。 在定义了 validate、resetFields 的方法时,该属性是必填的" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "InputConfigurator", + "props": {} + } + }, + { + "property": "label", + "label": { + "text": { + "zh_CN": "标签文本" + } + }, + "description": { + "zh_CN": "标签文本" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "InputConfigurator", + "props": {} + } + }, + { + "property": "label-width", + "label": { + "text": { + "zh_CN": "标签宽度" + } + }, + "description": { + "zh_CN": "标签宽度,例如 '50px'。 可以使用 auto" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "InputConfigurator", + "props": {} + } + }, + { + "property": "required", + "label": { + "text": { + "zh_CN": "必填项" + } + }, + "description": { + "zh_CN": "是否为必填项,如不设置,则会根据校验规则确认" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "rules", + "label": { + "text": { + "zh_CN": "验证规则" + } + }, + "description": { + "zh_CN": "表单验证规则, 更多内容可以参考async-validator" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "top", + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + } + }, + { + "property": "error", + "label": { + "text": { + "zh_CN": "错误信息" + } + }, + "description": { + "zh_CN": "表单域验证错误时的提示信息。设置该值会导致表单验证状态变为 error,并显示该错误信息" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "InputConfigurator", + "props": {} + } + }, + { + "property": "show-message", + "label": { + "text": { + "zh_CN": "显示错误信息" + } + }, + "description": { + "zh_CN": "是否显示校验错误信息" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "inline-message", + "label": { + "text": { + "zh_CN": "行内显示错误信息" + } + }, + "description": { + "zh_CN": "是否在行内显示校验信息" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "size", + "label": { + "text": { + "zh_CN": "尺寸" + } + }, + "description": { + "zh_CN": "用于控制该表单内组件的尺寸" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "defaultValue": "default", + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "large", + "value": "large" + }, + { + "label": "default", + "value": "default" + }, + { + "label": "small", + "value": "small" + } + ] + } + } + }, + { + "property": "for", + "label": { + "text": { + "zh_CN": "for" + } + }, + "description": { + "zh_CN": "和原生标签相同能力" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "InputConfigurator", + "props": {} + } + }, + { + "property": "validate-status", + "label": { + "text": { + "zh_CN": "校验状态" + } + }, + "description": { + "zh_CN": "formItem 校验的状态" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "error", + "value": "error" + }, + { + "label": "validating", + "value": "validating" + }, + { + "label": "success", + "value": "success" + } + ] + } + } + } + ], + "description": { + "zh_CN": "" + } + } + ], + "events": {}, + "slots": { + "label": { + "label": { + "zh_CN": "label" + }, + "description": { + "zh_CN": "标签位置显示的内容" + } + }, + "error": { + "label": { + "zh_CN": "error" + }, + "description": { + "zh_CN": "验证错误信息的显示内容" + } + } + } + } + }, + { + "id": 1, + "version": "2.4.2", + "name": { + "zh_CN": "表单" + }, + "component": "ElTable", + "icon": "table", + "description": "用于展示多条结构类似的数据, 可对数据进行排序、筛选、对比或其他自定义操作", + "doc_url": "", + "screenshot": "", + "tags": "", + "keywords": "", + "dev_mode": "proCode", + "npm": { + "package": "element-plus", + "exportName": "ElTable", + "destructuring": true + }, + "group": "数据展示", + "category": "element-plus", + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "isPopper": false, + "nestingRule": { + "childWhitelist": [ + "ElTableColumn" + ], + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [ + "inline", + "label-width" + ] + }, + "contextMenu": { + "actions": [ + "copy", + "remove", + "insert", + "updateAttr", + "bindEvent", + "createBlock" + ], + "disable": [] + }, + "invalidity": [ + "" + ], + "clickCapture": true, + "framework": "Vue" + }, + "schema": { + "properties": [ + { + "name": "0", + "label": { + "zh_CN": "基础属性" + }, + "content": [ + { + "property": "data", + "label": { + "text": { + "zh_CN": "数据" + } + }, + "description": { + "zh_CN": "显示的数据" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "top", + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + } + }, + { + "property": "columns", + "label": { + "text": { + "zh_CN": "表格列配置" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "properties": [ + { + "label": { + "zh_CN": "默认分组" + }, + "content": [ + { + "property": "type", + "type": "string", + "labelPosition": "top", + "label": { + "text": { + "zh_CN": "type" + } + }, + "description": { + "text": { + "zh_CN": "对应列的类型。 如果设置了selection则显示多选框; 如果设置了 index 则显示该行的索引(从 1 开始计算); 如果设置了 expand 则显示为一个可展开的按钮" + } + }, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "selection", + "value": "selection" + }, + { + "label": "index", + "value": "index" + }, + { + "label": "expand", + "value": "expand" + } + ] + } + } + }, + { + "property": "index", + "type": "string", + "labelPosition": "top", + "label": { + "text": { + "zh_CN": "index" + } + }, + "description": { + "text": { + "zh_CN": "如果设置了 type=index,可以通过传递 index 属性来自定义索引" + } + }, + "widget": { + "component": "CodeConfigurator", + "props": {} + } + }, + { + "property": "label", + "type": "string", + "labelPosition": "top", + "label": { + "text": { + "zh_CN": "label" + } + }, + "description": { + "text": { + "zh_CN": "显示的标题" + } + }, + "widget": { + "component": "InputConfigurator", + "props": {} + } + }, + { + "property": "column-key", + "type": "string", + "labelPosition": "top", + "label": { + "text": { + "zh_CN": "column-key" + } + }, + "description": { + "text": { + "zh_CN": "column 的 key, column 的 key, 如果需要使用 filter-change 事件,则需要此属性标识是哪个 column 的筛选条件" + } + }, + "widget": { + "component": "InputConfigurator", + "props": {} + } + }, + { + "property": "prop", + "type": "string", + "labelPosition": "top", + "label": { + "text": { + "zh_CN": "prop" + } + }, + "description": { + "text": { + "zh_CN": "字段名称 对应列内容的字段名, 也可以使用 property属性" + } + }, + "widget": { + "component": "InputConfigurator", + "props": {} + } + }, + { + "property": "width", + "type": "number", + "labelPosition": "top", + "label": { + "text": { + "zh_CN": "width" + } + }, + "description": { + "text": { + "zh_CN": "对应列的宽度" + } + }, + "widget": { + "component": "NumberConfigurator", + "props": {} + } + }, + { + "property": "min-width", + "type": "number", + "labelPosition": "top", + "label": { + "text": { + "zh_CN": "min-width" + } + }, + "description": { + "text": { + "zh_CN": "对应列的最小宽度, 对应列的最小宽度, 与 width 的区别是 width 是固定的,min-width 会把剩余宽度按比例分配给设置了 min-width 的列" + } + }, + "widget": { + "component": "NumberConfigurator", + "props": {} + } + }, + { + "property": "fixed", + "type": "string", + "labelPosition": "top", + "label": { + "text": { + "zh_CN": "fixed" + } + }, + "description": { + "text": { + "zh_CN": "列是否固定在左侧或者右侧。 true 表示固定在左侧" + } + }, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "left", + "value": "left" + }, + { + "label": "right", + "value": "right" + } + ] + } + } + }, + { + "property": "sortable", + "type": "boolean", + "labelPosition": "left", + "label": { + "text": { + "zh_CN": "sortable" + } + }, + "description": { + "text": { + "zh_CN": "对应列是否可以排序" + } + }, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "sort-method", + "type": "function", + "labelPosition": "top", + "label": { + "text": { + "zh_CN": "sort-method" + } + }, + "description": { + "text": { + "zh_CN": "指定数据按照哪个属性进行排序,仅当sortable设置为true的时候有效。 应该如同 Array.sort 那样返回一个 Number" + } + }, + "widget": { + "component": "CodeConfigurator", + "props": {} + } + }, + { + "property": "sort-by", + "type": "array", + "labelPosition": "top", + "label": { + "text": { + "zh_CN": "sort-by" + } + }, + "description": { + "text": { + "zh_CN": "指定数据按照哪个属性进行排序,仅当 sortable 设置为 true 且没有设置 sort-method 的时候有效。 如果 sort-by 为数组,则先按照第 1 个属性排序,如果第 1 个相等,再按照第 2 个排序,以此类推" + } + }, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + } + }, + { + "property": "sort-orders", + "type": "array", + "labelPosition": "top", + "label": { + "text": { + "zh_CN": "sort-orders" + } + }, + "description": { + "text": { + "zh_CN": "数据在排序时所使用排序策略的轮转顺序,仅当 sortable 为 true 时有效。 需传入一个数组,随着用户点击表头,该列依次按照数组中元素的顺序进行排序" + } + }, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + } + }, + { + "property": "resizable", + "type": "boolean", + "labelPosition": "left", + "defaultValue": true, + "label": { + "text": { + "zh_CN": "resizable" + } + }, + "description": { + "text": { + "zh_CN": "对应列是否可以通过拖动改变宽度(需要在 el-table 上设置 border 属性为真)" + } + }, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "formatter", + "type": "function", + "labelPosition": "top", + "defaultValue": true, + "label": { + "text": { + "zh_CN": "formatter" + } + }, + "description": { + "text": { + "zh_CN": "用来格式化内容" + } + }, + "widget": { + "component": "CodeConfigurator", + "props": { + "dataType": "JSFunction" + } + } + }, + { + "property": "show-overflow-tooltip", + "type": "boolean", + "labelPosition": "left", + "defaultValue": true, + "label": { + "text": { + "zh_CN": "show-overflow-tooltip" + } + }, + "description": { + "text": { + "zh_CN": "当内容过长被隐藏时显示 tooltip" + } + }, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "align", + "type": "string", + "labelPosition": "top", + "defaultValue": "left", + "label": { + "text": { + "zh_CN": "align" + } + }, + "description": { + "text": { + "zh_CN": "对齐方式" + } + }, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "left", + "value": "left" + }, + { + "label": "center", + "value": "center" + }, + { + "label": "right", + "value": "right" + } + ] + } + } + }, + { + "property": "header-align", + "type": "string", + "labelPosition": "top", + "defaultValue": "left", + "label": { + "text": { + "zh_CN": "header-align" + } + }, + "description": { + "text": { + "zh_CN": "表头对齐方式, 若不设置该项,则使用表格的对齐方式" + } + }, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "left", + "value": "left" + }, + { + "label": "center", + "value": "center" + }, + { + "label": "right", + "value": "right" + } + ] + } + } + }, + { + "property": "class-name", + "type": "string", + "labelPosition": "top", + "defaultValue": "left", + "label": { + "text": { + "zh_CN": "class-name" + } + }, + "description": { + "text": { + "zh_CN": "列的 className" + } + }, + "widget": { + "component": "InputConfigurator", + "props": {} + } + }, + { + "property": "label-class-name", + "type": "string", + "labelPosition": "top", + "defaultValue": "left", + "label": { + "text": { + "zh_CN": "label-class-name" + } + }, + "description": { + "text": { + "zh_CN": "当前列标题的自定义类名" + } + }, + "widget": { + "component": "InputConfigurator", + "props": {} + } + }, + { + "property": "selectable", + "type": "function", + "labelPosition": "top", + "defaultValue": true, + "label": { + "text": { + "zh_CN": "selectable" + } + }, + "description": { + "text": { + "zh_CN": "仅对 type=selection 的列有效,类型为 Function,Function 的返回值用来决定这一行的 CheckBox 是否可以勾选" + } + }, + "widget": { + "component": "CodeConfigurator", + "props": {} + } + }, + { + "property": "reserve-selection", + "type": "boolean", + "labelPosition": "left", + "defaultValue": true, + "label": { + "text": { + "zh_CN": "reserve-selection" + } + }, + "description": { + "text": { + "zh_CN": "数据刷新后是否保留选项,仅对 type=selection 的列有效, 请注意, 需指定 row-key 来让这个功能生效。" + } + }, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "filters", + "type": "array", + "labelPosition": "top", + "defaultValue": true, + "label": { + "text": { + "zh_CN": "filters" + } }, "description": { "text": { - "zh_CN": "column 的 key, column 的 key, 如果需要使用 filter-change 事件,则需要此属性标识是哪个 column 的筛选条件" + "zh_CN": "数据刷新后是否保留选项,仅对 type=selection 的列有效, 请注意, 需指定 row-key 来让这个功能生效。" } }, "widget": { - "component": "InputConfigurator", - "props": {} + "component": "CodeConfigurator", + "props": { + "language": "json" + } } }, { - "property": "prop", + "property": "filter-placement", "type": "string", "labelPosition": "top", "label": { "text": { - "zh_CN": "prop" + "zh_CN": "filter-placement" } }, "description": { "text": { - "zh_CN": "字段名称 对应列内容的字段名, 也可以使用 property属性" + "zh_CN": "过滤弹出框的定位" } }, "widget": { @@ -2069,1062 +7308,2851 @@ } }, { - "property": "width", - "type": "number", + "property": "filter-multiple", + "type": "string", + "labelPosition": "left", + "defaultValue": true, + "label": { + "text": { + "zh_CN": "filter-multiple" + } + }, + "description": { + "text": { + "zh_CN": "数据过滤的选项是否多选" + } + }, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "filter-method", + "type": "function", "labelPosition": "top", + "defaultValue": true, "label": { "text": { - "zh_CN": "width" + "zh_CN": "filter-method" } }, "description": { "text": { - "zh_CN": "对应列的宽度" + "zh_CN": "数据过滤使用的方法, 如果是多选的筛选项,对每一条数据会执行多次,任意一次返回 true 就会显示" } }, "widget": { - "component": "NumberConfigurator", + "component": "CodeConfigurator", "props": {} } }, { - "property": "min-width", - "type": "number", - "labelPosition": "top", - "label": { - "text": { - "zh_CN": "min-width" - } - }, - "description": { - "text": { - "zh_CN": "对应列的最小宽度, 对应列的最小宽度, 与 width 的区别是 width 是固定的,min-width 会把剩余宽度按比例分配给设置了 min-width 的列" - } - }, - "widget": { - "component": "NumberConfigurator", - "props": {} - } + "property": "filtered-value", + "type": "array", + "labelPosition": "top", + "defaultValue": true, + "label": { + "text": { + "zh_CN": "filtered-value" + } + }, + "description": { + "text": { + "zh_CN": "选中的数据过滤项,如果需要自定义表头过滤的渲染方式,可能会需要此属性" + } + }, + "widget": { + "component": "CodeConfigurator", + "props": { + "language": "json" + } + } + } + ] + } + ], + "widget": { + "component": "TableColumnsConfigurator", + "props": { + "type": "object", + "textField": "label", + "language": "json", + "buttonText": "编辑列配置", + "title": "编辑列配置", + "expand": true + } + }, + "description": { + "zh_CN": "表格列的配置信息" + }, + "labelPosition": "top" + }, + { + "property": "max-height", + "label": { + "text": { + "zh_CN": "最大高度" + } + }, + "description": { + "zh_CN": "Table 的最大高度。" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "number", + "widget": { + "component": "NumberConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "height", + "label": { + "text": { + "zh_CN": "表格高度" + } + }, + "description": { + "zh_CN": "Table 的高度, 默认为自动高度。 这个高度会设置为 Table 的 style.height 的值,Table 的高度会受控于外部样式。" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "stripe", + "label": { + "text": { + "zh_CN": "斑马纹" + } + }, + "description": { + "zh_CN": "是否为斑马纹 table" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": false, + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "border", + "label": { + "text": { + "zh_CN": "纵向边框" + } + }, + "description": { + "zh_CN": "是否带有纵向边框" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": false, + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "size", + "label": { + "text": { + "zh_CN": "表格尺寸" + } + }, + "description": { + "zh_CN": "Table 的尺寸" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "type": "string", + "defaultValue": "default", + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "large", + "value": "large" + }, + { + "label": "default", + "value": "default" + }, + { + "label": "small", + "value": "small" + } + ] + } + } + }, + { + "property": "fit", + "label": { + "text": { + "zh_CN": "列宽自撑开" + } + }, + "description": { + "zh_CN": "列的宽度是否自撑开" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": true, + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "show-header", + "label": { + "text": { + "zh_CN": "显示表头" + } + }, + "description": { + "zh_CN": "是否显示表头" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": true, + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "highlight-current-row", + "label": { + "text": { + "zh_CN": "高亮当前行" + } + }, + "description": { + "zh_CN": "是否要高亮当前行" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": false, + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "current-row-key", + "label": { + "text": { + "zh_CN": "当前行的 key" + } + }, + "description": { + "zh_CN": "当前行的 key,只写属性" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "top", + "type": "string", + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "row-class-name", + "label": { + "text": { + "zh_CN": "行的类名" + } + }, + "description": { + "zh_CN": "行的 className" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "row-key", + "label": { + "text": { + "zh_CN": "行数据的 Key" + } + }, + "description": { + "zh_CN": "行数据的 Key,用来优化 Table 的渲染; 在使用reserve-selection功能与显示树形数据时,该属性是必填的。 类型为 String 时,支持多层访问:user.info.id,但不支持 user.info[0].id,此种情况请使用 Function" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "top", + "widget": { + "component": "CodeConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "empty-text", + "label": { + "text": { + "zh_CN": "空数据文本" + } + }, + "description": { + "zh_CN": "空数据时显示的文本内容" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "device": [] + }, + { + "property": "table-layout", + "label": { + "text": { + "zh_CN": "表格布局方式" + } + }, + "description": { + "zh_CN": "设置表格单元、行和列的布局方式" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "top", + "defaultValue": "fixed", + "widget": { + "component": "InputConfigurator", + "props": { + "options": [ + { + "label": "fixed", + "value": "fixed" }, { - "property": "fixed", - "type": "string", - "labelPosition": "top", - "label": { - "text": { - "zh_CN": "fixed" - } - }, - "description": { - "text": { - "zh_CN": "列是否固定在左侧或者右侧。 true 表示固定在左侧" - } - }, - "widget": { - "component": "SelectConfigurator", - "props": { - "options": [ - { - "label": "left", - "value": "left" - }, - { - "label": "right", - "value": "right" - } - ] - } - } - }, + "label": "auto", + "value": "auto" + } + ] + } + }, + "device": [] + }, + { + "property": "scrollbar-always-on", + "label": { + "text": { + "zh_CN": "显示滚动条" + } + }, + "description": { + "zh_CN": "总是显示滚动条" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": false, + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + }, + { + "property": "flexible", + "label": { + "text": { + "zh_CN": "主轴最小尺寸" + } + }, + "description": { + "zh_CN": "确保主轴的最小尺寸,以便不超过内容" + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "labelPosition": "left", + "defaultValue": false, + "type": "boolean", + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + } + } + ], + "description": { + "zh_CN": "" + } + } + ], + "events": { + "onSelect": { + "label": { + "zh_CN": "勾选数据行的 Checkbox 时触发" + }, + "description": { + "zh_CN": "当用户手动勾选数据行的 Checkbox 时触发的事件" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "selection", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "当前选中项" + } + }, + { + "name": "row", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "当前行" + } + } + ], + "returns": {} + } + }, + "onSelectAll": { + "label": { + "zh_CN": "勾选全选时触发" + }, + "description": { + "zh_CN": "当用户手动勾选全选 Checkbox 时触发的事件" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "selection", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "当前选中项" + } + } + ], + "returns": {} + } + }, + "onSelectionChange": { + "label": { + "zh_CN": "选择项发生变化时会触发" + }, + "description": { + "zh_CN": "当选择项发生变化时会触发该事件" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "selection", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "当前选中项" + } + } + ], + "returns": {} + } + }, + "onCellMouseEnter": { + "label": { + "zh_CN": "单元格 hover 时会触发" + }, + "description": { + "zh_CN": "当单元格 hover 进入时会触发该事件" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "row", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "当前行" + } + }, + { + "name": "column", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "当前列" + } + }, + { + "name": "cell", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "当前单元格" + } + }, + { + "name": "event", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "原生事件 event" + } + } + ], + "returns": {} + } + }, + "onCellMouseLeave": { + "label": { + "zh_CN": "单元格 hover 退出时会触发" + }, + "description": { + "zh_CN": "当单元格 hover 退出时会触发该事件" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "row", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "当前行" + } + }, + { + "name": "column", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "当前列" + } + }, + { + "name": "cell", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "当前单元格" + } + }, + { + "name": "event", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "原生事件 event" + } + } + ], + "returns": {} + } + } + }, + "slots": { + "empty": { + "label": { + "zh_CN": "empty" + }, + "description": { + "zh_CN": "当数据为空时自定义的内容" + } + }, + "append": { + "label": { + "zh_CN": "append" + }, + "description": { + "zh_CN": "插入至表格最后一行之后的内容, 如果需要对表格的内容进行无限滚动操作,可能需要用到这个 slot。 若表格有合计行,该 slot 会位于合计行之上。" + } + } + } + } + }, + { + "id": 1, + "version": "2.4.2", + "name": { + "zh_CN": "表单" + }, + "component": "ElTableColumn", + "icon": "table", + "description": "用于展示多条结构类似的数据, 可对数据进行排序、筛选、对比或其他自定义操作", + "doc_url": "", + "screenshot": "", + "tags": "", + "keywords": "", + "dev_mode": "proCode", + "npm": { + "package": "element-plus", + "exportName": "ElTableColumn", + "destructuring": true + }, + "group": "表单组件", + "category": "element-plus", + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "isPopper": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [ + "inline", + "label-width" + ] + }, + "contextMenu": { + "actions": [ + "copy", + "remove", + "insert", + "updateAttr", + "bindEvent", + "createBlock" + ], + "disable": [] + }, + "invalidity": [ + "" + ], + "clickCapture": true, + "framework": "Vue" + }, + "schema": { + "properties": [ + { + "name": "0", + "label": { + "zh_CN": "基础属性" + }, + "content": [], + "description": { + "zh_CN": "" + } + } + ], + "events": {}, + "slots": {} + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "进度条" + }, + "component": "TinyProgress", + "icon": "progress", + "description": "进度条", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "package": "@opentiny/vue", + "exportName": "TinyProgress", + "destructuring": true + }, + "group": "component", + "category": "进度条", + "priority": 2, + "schema": { + "properties": [ + { + "name": "0", + "label": { + "zh_CN": "基础属性" + }, + "content": [ + { + "cols": 12, + "type": "number", + "label": { + "text": { + "zh_CN": "百分比" + } + }, + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" + }, + "disabled": false, + "property": "percentage", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "百分比(必填);该属性的可选值为 0-100" + }, + "defaultValue": 0, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "enum", + "label": { + "text": { + "zh_CN": "类型" + } + }, + "widget": { + "props": { + "options": [ { - "property": "sortable", - "type": "boolean", - "labelPosition": "left", - "label": { - "text": { - "zh_CN": "sortable" - } - }, - "description": { - "text": { - "zh_CN": "对应列是否可以排序" - } - }, - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "label": "line", + "value": "line" }, { - "property": "sort-method", - "type": "function", - "labelPosition": "top", - "label": { - "text": { - "zh_CN": "sort-method" - } - }, - "description": { - "text": { - "zh_CN": "指定数据按照哪个属性进行排序,仅当sortable设置为true的时候有效。 应该如同 Array.sort 那样返回一个 Number" - } - }, - "widget": { - "component": "CodeConfigurator", - "props": {} - } + "label": "circle", + "value": "circle" }, { - "property": "sort-by", - "type": "array", - "labelPosition": "top", - "label": { - "text": { - "zh_CN": "sort-by" - } - }, - "description": { - "text": { - "zh_CN": "指定数据按照哪个属性进行排序,仅当 sortable 设置为 true 且没有设置 sort-method 的时候有效。 如果 sort-by 为数组,则先按照第 1 个属性排序,如果第 1 个相等,再按照第 2 个排序,以此类推" - } - }, - "widget": { - "component": "CodeConfigurator", - "props": { - "language": "json" - } - } - }, + "label": "dashboard", + "value": "dashboard" + } + ] + }, + "component": "SelectConfigurator" + }, + "disabled": false, + "property": "type", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "进度条类型" + }, + "defaultValue": "line", + "labelPosition": "left" + }, + { + "cols": 12, + "type": "enum", + "label": { + "text": { + "zh_CN": "状态" + } + }, + "widget": { + "props": { + "options": [ { - "property": "sort-orders", - "type": "array", - "labelPosition": "top", - "label": { - "text": { - "zh_CN": "sort-orders" - } - }, - "description": { - "text": { - "zh_CN": "数据在排序时所使用排序策略的轮转顺序,仅当 sortable 为 true 时有效。 需传入一个数组,随着用户点击表头,该列依次按照数组中元素的顺序进行排序" - } - }, - "widget": { - "component": "CodeConfigurator", - "props": { - "language": "json" - } - } + "label": "success", + "value": "success" }, { - "property": "resizable", - "type": "boolean", - "labelPosition": "left", - "defaultValue": true, - "label": { - "text": { - "zh_CN": "resizable" - } - }, - "description": { - "text": { - "zh_CN": "对应列是否可以通过拖动改变宽度(需要在 el-table 上设置 border 属性为真)" - } - }, - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "label": "exception", + "value": "exception" }, { - "property": "formatter", - "type": "function", - "labelPosition": "top", - "defaultValue": true, - "label": { - "text": { - "zh_CN": "formatter" - } - }, - "description": { - "text": { - "zh_CN": "用来格式化内容" - } - }, - "widget": { - "component": "CodeConfigurator", - "props": { - "dataType": "JSFunction" - } - } - }, + "label": "warning", + "value": "warning" + } + ] + }, + "component": "SelectConfigurator" + }, + "disabled": false, + "property": "status", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "进度条当前状态" + }, + "defaultValue": null, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性" + } + }, + { + "name": "1", + "label": { + "zh_CN": "样式属性" + }, + "content": [ + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "颜色" + } + }, + "widget": { + "props": {}, + "component": "ColorConfigurator" + }, + "disabled": false, + "property": "color", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "进度条背景色(会覆盖 status 状态颜色)" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "number", + "label": { + "text": { + "zh_CN": "线条宽度" + } + }, + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" + }, + "disabled": false, + "property": "stroke-width", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "line 类型进度条的宽度,单位 px" + }, + "defaultValue": 6, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "number", + "label": { + "text": { + "zh_CN": "宽度" + } + }, + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" + }, + "disabled": false, + "property": "width", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "环形进度条画布宽度(只在 type 为 circle 或 dashboard 时可用)" + }, + "defaultValue": 126, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性" + } + }, + { + "name": "2", + "label": { + "zh_CN": "行为属性" + }, + "content": [ + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "显示文字" + } + }, + "widget": { + "props": {}, + "component": "SwitchConfigurator" + }, + "disabled": false, + "property": "show-text", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否显示进度条文字内容" + }, + "defaultValue": true, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "文字内置" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "text-inside", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "进度条显示文字内置在进度条内(只在 type=line 时可用)" + }, + "defaultValue": false, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性" + } + }, + { + "name": "3", + "label": { + "zh_CN": "高级属性" + }, + "content": [ + { + "cols": 12, + "type": "function", + "label": { + "text": { + "zh_CN": "格式" + } + }, + "widget": { + "props": { + "height": 150, + "language": "javascript" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "format", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "自定义进度条的文字" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "状态图标" + } + }, + "widget": { + "props": { + "options": [ { - "property": "show-overflow-tooltip", - "type": "boolean", - "labelPosition": "left", - "defaultValue": true, - "label": { - "text": { - "zh_CN": "show-overflow-tooltip" - } - }, - "description": { - "text": { - "zh_CN": "当内容过长被隐藏时显示 tooltip" - } - }, - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "label": "successIcon", + "value": "successIcon" }, { - "property": "align", - "type": "string", - "labelPosition": "top", - "defaultValue": "left", - "label": { - "text": { - "zh_CN": "align" - } - }, - "description": { - "text": { - "zh_CN": "对齐方式" - } - }, - "widget": { - "component": "SelectConfigurator", - "props": { - "options": [ - { - "label": "left", - "value": "left" - }, - { - "label": "center", - "value": "center" - }, - { - "label": "right", - "value": "right" - } - ] - } - } + "label": "exceptionIcon", + "value": "exceptionIcon" }, { - "property": "header-align", - "type": "string", - "labelPosition": "top", - "defaultValue": "left", - "label": { - "text": { - "zh_CN": "header-align" - } - }, - "description": { - "text": { - "zh_CN": "表头对齐方式, 若不设置该项,则使用表格的对齐方式" - } - }, - "widget": { - "component": "SelectConfigurator", - "props": { - "options": [ - { - "label": "left", - "value": "left" - }, - { - "label": "center", - "value": "center" - }, - { - "label": "right", - "value": "right" - } - ] - } - } + "label": "warningIcon", + "value": "warningIcon" + } + ] + }, + "component": "SelectConfigurator" + }, + "disabled": false, + "property": "statusIcon", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "状态插槽,successIcon / exceptionIcon / warningIcon" + }, + "defaultValue": null, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置" + } + } + ], + "events": {}, + "slots": {} + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [] + }, + "contextMenu": { + "actions": ["create symbol"], + "disable": ["copy", "remove"] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "骨架屏" + }, + "component": "TinySkeleton", + "icon": "skeleton", + "description": "骨架屏", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "package": "@opentiny/vue", + "exportName": "TinySkeleton", + "destructuring": true + }, + "group": "component", + "category": "骨架屏", + "priority": 2, + "schema": { + "properties": [ + { + "name": "0", + "label": { + "zh_CN": "基础属性" + }, + "content": [ + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "显示头像" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "avatar", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否显示头像" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "number", + "label": { + "text": { + "zh_CN": "行数" + } + }, + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" + }, + "disabled": false, + "property": "rows", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "默认样式,可配置段落显示行数" + }, + "defaultValue": 3, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "形态" + } + }, + "widget": { + "props": { + "options": [ + { + "label": "image", + "value": "image" }, { - "property": "class-name", - "type": "string", - "labelPosition": "top", - "defaultValue": "left", - "label": { - "text": { - "zh_CN": "class-name" - } - }, - "description": { - "text": { - "zh_CN": "列的 className" - } - }, - "widget": { - "component": "InputConfigurator", - "props": {} - } + "label": "circle", + "value": "circle" }, { - "property": "label-class-name", - "type": "string", - "labelPosition": "top", - "defaultValue": "left", - "label": { - "text": { - "zh_CN": "label-class-name" - } - }, - "description": { - "text": { - "zh_CN": "当前列标题的自定义类名" - } - }, - "widget": { - "component": "InputConfigurator", - "props": {} - } + "label": "square", + "value": "square" + } + ] + }, + "component": "SelectConfigurator" + }, + "disabled": false, + "property": "variant", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "骨架屏形态" + }, + "defaultValue": "square", + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性" + } + }, + { + "name": "1", + "label": { + "zh_CN": "样式属性" + }, + "content": [ + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "尺寸" + } + }, + "widget": { + "props": { + "options": [ + { + "label": "large", + "value": "large" }, { - "property": "selectable", - "type": "function", - "labelPosition": "top", - "defaultValue": true, - "label": { - "text": { - "zh_CN": "selectable" - } - }, - "description": { - "text": { - "zh_CN": "仅对 type=selection 的列有效,类型为 Function,Function 的返回值用来决定这一行的 CheckBox 是否可以勾选" - } - }, - "widget": { - "component": "CodeConfigurator", - "props": {} - } + "label": "medium", + "value": "medium" }, { - "property": "reserve-selection", - "type": "boolean", - "labelPosition": "left", - "defaultValue": true, - "label": { - "text": { - "zh_CN": "reserve-selection" - } - }, - "description": { - "text": { - "zh_CN": "数据刷新后是否保留选项,仅对 type=selection 的列有效, 请注意, 需指定 row-key 来让这个功能生效。" - } - }, - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "label": "small", + "value": "small" + } + ] + }, + "component": "SelectConfigurator" + }, + "disabled": false, + "property": "size", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "针对 image 和 circle 形态,内置三种大小" + }, + "defaultValue": "medium", + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性" + } + }, + { + "name": "2", + "label": { + "zh_CN": "行为属性" + }, + "content": [ + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "开启动画" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "animated", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否开启动画" + }, + "defaultValue": true, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "显示骨架屏" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "loading", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否显示骨架屏,传 false 时会展示加载完成后的内容" + }, + "defaultValue": true, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性" + } + }, + { + "name": "3", + "label": { + "zh_CN": "高级属性" + }, + "content": [ + { + "cols": 12, + "type": "array", + "label": { + "text": { + "zh_CN": "行宽度" + } + }, + "widget": { + "props": { + "height": 150, + "language": "json" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "rows-width", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "自定义段落每一行的宽度,数组中的每一项可以为 number 或 string ,当为 number 时,组件会自动增加 px 单位" + }, + "defaultValue": [], + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置" + } + } + ], + "events": {}, + "slots": { + "default": { + "label": { + "zh_CN": "默认内容" + }, + "description": { + "zh_CN": "加载完成后显示的内容" + } + }, + "placeholder": { + "label": { + "zh_CN": "占位符" + }, + "description": { + "zh_CN": "自定义骨架屏结构" + } + } + } + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [] + }, + "contextMenu": { + "actions": ["create symbol"], + "disable": ["copy", "remove"] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "卡片" + }, + "component": "TinyCard", + "icon": "card", + "description": "卡片", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "package": "@opentiny/vue", + "exportName": "TinyCard", + "destructuring": true + }, + "group": "component", + "category": "组件", + "priority": 2, + "schema": { + "properties": [ + { + "name": "0", + "label": { + "zh_CN": "基础属性" + }, + "content": [ + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "源地址" + } + }, + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "src", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "图片或者视频的地址" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "标题" + } + }, + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "title", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "卡片的标题" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "enum", + "label": { + "text": { + "zh_CN": "类型" + } + }, + "widget": { + "props": { + "options": [ + { + "label": "text", + "value": "text" }, { - "property": "filters", - "type": "array", - "labelPosition": "top", - "defaultValue": true, - "label": { - "text": { - "zh_CN": "filters" - } - }, - "description": { - "text": { - "zh_CN": "数据刷新后是否保留选项,仅对 type=selection 的列有效, 请注意, 需指定 row-key 来让这个功能生效。" - } - }, - "widget": { - "component": "CodeConfigurator", - "props": { - "language": "json" - } - } + "label": "image", + "value": "image" }, { - "property": "filter-placement", - "type": "string", - "labelPosition": "top", - "label": { - "text": { - "zh_CN": "filter-placement" - } - }, - "description": { - "text": { - "zh_CN": "过滤弹出框的定位" - } - }, - "widget": { - "component": "InputConfigurator", - "props": {} - } + "label": "video", + "value": "video" }, { - "property": "filter-multiple", - "type": "string", - "labelPosition": "left", - "defaultValue": true, - "label": { - "text": { - "zh_CN": "filter-multiple" - } - }, - "description": { - "text": { - "zh_CN": "数据过滤的选项是否多选" - } - }, - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } - }, + "label": "logo", + "value": "logo" + } + ] + }, + "component": "SelectConfigurator" + }, + "disabled": false, + "property": "type", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "设置卡片类型" + }, + "defaultValue": "text", + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性" + } + }, + { + "name": "1", + "label": { + "zh_CN": "样式属性" + }, + "content": [ + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "自动宽度" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "auto-width", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "卡片的宽度是否自动撑开,设置后将不再给卡片设置固定宽度" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "自定义类名" + } + }, + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "custom-class", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "卡片的class" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "高度" + } + }, + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "height", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "卡片内容区域的高度" + }, + "defaultValue": null, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性" + } + } + ], + "events": {}, + "slots": { + "title": { + "label": { + "zh_CN": "标题" + }, + "description": { + "zh_CN": "标题插槽" + } + }, + "footer": { + "label": { + "zh_CN": "底部" + }, + "description": { + "zh_CN": "组件底部插槽" + } + }, + "default": { + "label": { + "zh_CN": "默认内容" + }, + "description": { + "zh_CN": "组件默认插槽" + } + }, + "title-left": { + "label": { + "zh_CN": "标题左侧" + }, + "description": { + "zh_CN": "标题左侧插槽" + } + }, + "title-right": { + "label": { + "zh_CN": "标题右侧" + }, + "description": { + "zh_CN": "标题右侧插槽" + } + } + } + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [] + }, + "contextMenu": { + "actions": ["create symbol"], + "disable": ["copy", "remove"] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "日历" + }, + "component": "TinyCalendar", + "icon": "calendar", + "description": "日历", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "package": "@opentiny/vue", + "exportName": "TinyCalendar", + "destructuring": true + }, + "group": "component", + "category": "组件", + "priority": 2, + "schema": { + "properties": [ + { + "name": "0", + "label": { + "zh_CN": "基础属性" + }, + "content": [ + { + "cols": 12, + "type": "enum", + "label": { + "text": { + "zh_CN": "显示模式" + } + }, + "widget": { + "props": { + "options": [ { - "property": "filter-method", - "type": "function", - "labelPosition": "top", - "defaultValue": true, - "label": { - "text": { - "zh_CN": "filter-method" - } - }, - "description": { - "text": { - "zh_CN": "数据过滤使用的方法, 如果是多选的筛选项,对每一条数据会执行多次,任意一次返回 true 就会显示" - } - }, - "widget": { - "component": "CodeConfigurator", - "props": {} - } + "label": "month", + "value": "month" }, { - "property": "filtered-value", - "type": "array", - "labelPosition": "top", - "defaultValue": true, - "label": { - "text": { - "zh_CN": "filtered-value" - } - }, - "description": { - "text": { - "zh_CN": "选中的数据过滤项,如果需要自定义表头过滤的渲染方式,可能会需要此属性" - } - }, - "widget": { - "component": "CodeConfigurator", - "props": { - "language": "json" - } - } + "label": "year", + "value": "year" } ] + }, + "component": "SelectConfigurator" + }, + "disabled": false, + "property": "mode", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "日历显示模式" + }, + "defaultValue": "month", + "labelPosition": "left" + }, + { + "cols": 12, + "type": "number", + "label": { + "text": { + "zh_CN": "月份" + } + }, + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" + }, + "disabled": false, + "property": "month", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "指定月份,默认当前月份" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "number", + "label": { + "text": { + "zh_CN": "年份" + } + }, + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" + }, + "disabled": false, + "property": "year", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "指定年份,默认当前年份" + }, + "defaultValue": null, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性" + } + }, + { + "name": "2", + "label": { + "zh_CN": "行为属性" + }, + "content": [ + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "显示选中日期" + } + }, + "widget": { + "props": {}, + "component": "SwitchConfigurator" + }, + "disabled": false, + "property": "show-selected", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否显示选中的日期" + }, + "defaultValue": false, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性" + } + }, + { + "name": "3", + "label": { + "zh_CN": "高级属性" + }, + "content": [ + { + "cols": 12, + "type": "array", + "label": { + "text": { + "zh_CN": "事件列表" + } + }, + "widget": { + "props": { + "height": 150, + "language": "json" + }, + "component": "CodeConfigurator" + }, + "disabled": false, + "property": "events", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "事件列表" + }, + "defaultValue": null, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置" + } + } + ], + "events": {}, + "slots": { + "day": { + "label": { + "zh_CN": "日期单元格" + }, + "description": { + "zh_CN": "日期单元格插槽" + } + }, + "tool": { + "label": { + "zh_CN": "日历工具栏" + }, + "description": { + "zh_CN": "日历工具栏插槽" + } + } + } + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [] + }, + "contextMenu": { + "actions": ["create symbol"], + "disable": ["copy", "remove"] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "标记" + }, + "component": "TinyBadge", + "icon": "badge", + "description": "标记", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "package": "@opentiny/vue", + "exportName": "TinyBadge", + "destructuring": true + }, + "group": "component", + "category": "组件", + "priority": 2, + "schema": { + "properties": [ + { + "name": "0", + "label": { + "zh_CN": "基础属性" + }, + "content": [ + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "数据条目数" + } + }, + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "value", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "相关数据条目数" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "标记类型" } - ], + }, "widget": { - "component": "TableColumnsConfigurator", "props": { - "type": "object", - "textField": "label", - "language": "json", - "buttonText": "编辑列配置", - "title": "编辑列配置", - "expand": true + "placeholder": "请输入..." + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "type", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "标记的类型" + }, + "defaultValue": "danger", + "labelPosition": "left" + }, + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "文本内容" } }, + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "data", + "readOnly": false, + "required": true, "description": { - "zh_CN": "表格列的配置信息" + "zh_CN": "文本内容" }, - "labelPosition": "top" + "defaultValue": null, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性" + } + }, + { + "name": "1", + "label": { + "zh_CN": "行为属性" + }, + "content": [ + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "是否隐藏" + } + }, + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" + }, + "disabled": false, + "property": "hidden", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否隐藏标记" + }, + "defaultValue": false, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "boolean", + "label": { + "text": { + "zh_CN": "是否小圆点" + } + }, + "widget": { + "props": {}, + "component": "SwitchConfigurator" + }, + "disabled": false, + "property": "is-dot", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否以小圆点的形式来显示标记" + }, + "defaultValue": false, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性" + } + }, + { + "name": "2", + "label": { + "zh_CN": "样式属性" + }, + "content": [ + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "自定义标记类名" + } + }, + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "badge-class", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "自定义标记的类名" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "偏移量" + } + }, + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "offset", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "设置标记位置的偏移量" + }, + "defaultValue": null, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性" + } + }, + { + "name": "3", + "label": { + "zh_CN": "高级属性" + }, + "content": [ + { + "cols": 12, + "type": "number", + "label": { + "text": { + "zh_CN": "最大值" + } + }, + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" + }, + "disabled": false, + "property": "max", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "指定徽章显示的最大值,如果实际获取的徽章值超过该最大值,则以最大值后接一个 '+' 的形式显示徽章数,要求 value 是 number 类型" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "跳转地址" + } + }, + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "href", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "指定跳转的目标页面地址" + }, + "defaultValue": null, + "labelPosition": "left" }, { - "property": "max-height", + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "跳转方式" + } + }, + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "target", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "点击标记时链接到目标页面的跳转方式,仅在 href 属性存在时使用" + }, + "defaultValue": null, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置" + } + } + ], + "events": {}, + "slots": { + "content": { + "label": { + "zh_CN": "内容" + }, + "description": { + "zh_CN": "消息提示内容" + } + }, + "default": { + "label": { + "zh_CN": "默认内容" + }, + "description": { + "zh_CN": "默认插槽,有data属性时,默认插槽不生效" + } + } + } + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [] + }, + "contextMenu": { + "actions": ["create symbol"], + "disable": ["copy", "remove"] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "标签" + }, + "component": "TinyTag", + "icon": "tag", + "description": "标签", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "package": "@opentiny/vue", + "exportName": "TinyTag", + "destructuring": true + }, + "group": "component", + "category": "组件", + "priority": 2, + "schema": { + "properties": [ + { + "name": "0", + "label": { + "zh_CN": "基础属性" + }, + "content": [ + { + "cols": 12, + "type": "string", "label": { "text": { - "zh_CN": "最大高度" + "zh_CN": "显示类型" } }, - "description": { - "zh_CN": "Table 的最大高度。" + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "number", - "widget": { - "component": "NumberConfigurator", - "props": {} + "property": "type", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "显示类型" }, - "device": [] + "defaultValue": null, + "labelPosition": "left" }, { - "property": "height", + "cols": 12, + "type": "string", "label": { "text": { - "zh_CN": "表格高度" + "zh_CN": "标签内容" } }, - "description": { - "zh_CN": "Table 的高度, 默认为自动高度。 这个高度会设置为 Table 的 style.height 的值,Table 的高度会受控于外部样式。" + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "widget": { - "component": "InputConfigurator", - "props": {} + "property": "value", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "配置式标签,自定义标签内容" }, - "device": [] - }, + "defaultValue": null, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性" + } + }, + { + "name": "1", + "label": { + "zh_CN": "样式属性" + }, + "content": [ { - "property": "stripe", + "cols": 12, + "type": "string", "label": { "text": { - "zh_CN": "斑马纹" + "zh_CN": "颜色" } }, - "description": { - "zh_CN": "是否为斑马纹 table" - }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "labelPosition": "left", - "defaultValue": false, - "type": "boolean", "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } - }, - { - "property": "border", - "label": { - "text": { - "zh_CN": "纵向边框" - } + "props": {}, + "component": "ColorConfigurator" }, + "disabled": false, + "property": "color", + "readOnly": false, + "required": true, "description": { - "zh_CN": "是否带有纵向边框" + "zh_CN": "控制标签文本色和背景色,可使用 IColor 类型中的预设值,也可自定义值" }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "labelPosition": "left", - "defaultValue": false, - "type": "boolean", - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "defaultValue": null, + "labelPosition": "left" }, { - "property": "size", + "cols": 12, + "type": "string", "label": { "text": { - "zh_CN": "表格尺寸" + "zh_CN": "主题" } }, - "description": { - "zh_CN": "Table 的尺寸" - }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "labelPosition": "left", - "type": "string", - "defaultValue": "default", "widget": { - "component": "SelectConfigurator", "props": { - "options": [ - { - "label": "large", - "value": "large" - }, - { - "label": "default", - "value": "default" - }, - { - "label": "small", - "value": "small" - } - ] - } - } - }, - { - "property": "fit", - "label": { - "text": { - "zh_CN": "列宽自撑开" - } + "placeholder": "请输入..." + }, + "component": "InputConfigurator" }, + "disabled": false, + "property": "effect", + "readOnly": false, + "required": false, "description": { - "zh_CN": "列的宽度是否自撑开" + "zh_CN": "主题" }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "labelPosition": "left", - "defaultValue": true, - "type": "boolean", - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "defaultValue": "light", + "labelPosition": "left" }, { - "property": "show-header", + "cols": 12, + "type": "string", "label": { "text": { - "zh_CN": "显示表头" + "zh_CN": "最大宽度" } }, - "description": { - "zh_CN": "是否显示表头" - }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "labelPosition": "left", - "defaultValue": true, - "type": "boolean", "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } - }, - { - "property": "highlight-current-row", - "label": { - "text": { - "zh_CN": "高亮当前行" - } + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" }, + "disabled": false, + "property": "max-width", + "readOnly": false, + "required": true, "description": { - "zh_CN": "是否要高亮当前行" + "zh_CN": "设置最大宽度" }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "labelPosition": "left", - "defaultValue": false, - "type": "boolean", - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "defaultValue": null, + "labelPosition": "left" }, { - "property": "current-row-key", - "label": { - "text": { - "zh_CN": "当前行的 key" - } - }, - "description": { - "zh_CN": "当前行的 key,只写属性" - }, - "required": true, - "readOnly": false, - "disabled": false, "cols": 12, - "labelPosition": "top", "type": "string", - "widget": { - "component": "InputConfigurator", - "props": {} - }, - "device": [] - }, - { - "property": "row-class-name", "label": { "text": { - "zh_CN": "行的类名" + "zh_CN": "尺寸" } }, - "description": { - "zh_CN": "行的 className" + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "widget": { - "component": "InputConfigurator", - "props": {} + "property": "size", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "尺寸" }, - "device": [] - }, + "defaultValue": null, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性" + } + }, + { + "name": "2", + "label": { + "zh_CN": "行为属性" + }, + "content": [ { - "property": "row-key", + "cols": 12, + "type": "function", "label": { "text": { - "zh_CN": "行数据的 Key" + "zh_CN": "删除前回调" } }, - "description": { - "zh_CN": "行数据的 Key,用来优化 Table 的渲染; 在使用reserve-selection功能与显示树形数据时,该属性是必填的。 类型为 String 时,支持多层访问:user.info.id,但不支持 user.info[0].id,此种情况请使用 Function" + "widget": { + "props": { + "height": 150, + "language": "javascript" + }, + "component": "CodeConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "top", - "widget": { - "component": "CodeConfigurator", - "props": {} + "property": "before-delete", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "删除前回调函数" }, - "device": [] + "defaultValue": null, + "labelPosition": "left" }, { - "property": "empty-text", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "空数据文本" + "zh_CN": "可关闭" } }, - "description": { - "zh_CN": "空数据时显示的文本内容" + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", - "widget": { - "component": "InputConfigurator", - "props": {} + "property": "closable", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否可关闭" }, - "device": [] + "defaultValue": false, + "labelPosition": "left" }, { - "property": "table-layout", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "表格布局方式" + "zh_CN": "禁用" } }, - "description": { - "zh_CN": "设置表格单元、行和列的布局方式" - }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "labelPosition": "top", - "defaultValue": "fixed", "widget": { - "component": "InputConfigurator", - "props": { - "options": [ - { - "label": "fixed", - "value": "fixed" - }, - { - "label": "auto", - "value": "auto" - } - ] - } - }, - "device": [] - }, - { - "property": "scrollbar-always-on", - "label": { - "text": { - "zh_CN": "显示滚动条" - } + "props": {}, + "component": "CheckBoxConfigurator" }, + "disabled": false, + "property": "disabled", + "readOnly": false, + "required": false, "description": { - "zh_CN": "总是显示滚动条" + "zh_CN": "是否禁用" }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "labelPosition": "left", "defaultValue": false, - "type": "boolean", - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "labelPosition": "left" }, { - "property": "flexible", + "cols": 12, + "type": "boolean", "label": { "text": { - "zh_CN": "主轴最小尺寸" + "zh_CN": "纯图标模式" } }, - "description": { - "zh_CN": "确保主轴的最小尺寸,以便不超过内容" + "widget": { + "props": {}, + "component": "CheckBoxConfigurator" }, - "required": true, - "readOnly": false, "disabled": false, - "cols": 12, - "labelPosition": "left", + "property": "only-icon", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "是否为纯图标的模式" + }, "defaultValue": false, - "type": "boolean", - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - } + "labelPosition": "left" } ], "description": { - "zh_CN": "" + "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性" } } ], "events": { - "onSelect": { + "onClick": { + "type": "event", "label": { - "zh_CN": "勾选数据行的 Checkbox 时触发" + "zh_CN": "点击标签时触发" }, "description": { - "zh_CN": "当用户手动勾选数据行的 Checkbox 时触发的事件" + "zh_CN": "点击标签时触发的事件" }, - "type": "event", + "defaultValue": "", "functionInfo": { "params": [ { - "name": "selection", - "type": "Object", - "defaultValue": "", - "description": { - "zh_CN": "当前选中项" - } - }, - { - "name": "row", - "type": "Object", - "defaultValue": "", + "name": "event", + "type": "Event", "description": { - "zh_CN": "当前行" - } + "zh_CN": "事件对象" + }, + "defaultValue": "" } ], - "returns": {} + "returns": { + "type": "", + "description": { + "zh_CN": "" + }, + "defaultValue": "" + } } }, - "onSelectAll": { + "onClose": { + "type": "event", "label": { - "zh_CN": "勾选全选时触发" + "zh_CN": "点击关闭按钮时触发" }, "description": { - "zh_CN": "当用户手动勾选全选 Checkbox 时触发的事件" + "zh_CN": "点击关闭按钮时触发的事件" }, - "type": "event", + "defaultValue": "", "functionInfo": { "params": [ { - "name": "selection", - "type": "Object", - "defaultValue": "", + "name": "event", + "type": "Event", "description": { - "zh_CN": "当前选中项" - } + "zh_CN": "事件对象" + }, + "defaultValue": "" } ], - "returns": {} + "returns": { + "type": "", + "description": { + "zh_CN": "" + }, + "defaultValue": "" + } } - }, - "onSelectionChange": { + } + }, + "slots": { + "default": { "label": { - "zh_CN": "选择项发生变化时会触发" + "zh_CN": "默认内容" }, "description": { - "zh_CN": "当选择项发生变化时会触发该事件" + "zh_CN": "标签内容" + } + } + } + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [] + }, + "contextMenu": { + "actions": ["create symbol"], + "disable": ["copy", "remove"] + } + } + }, + { + "version": "3.22.0", + "name": { + "zh_CN": "统计数值" + }, + "component": "TinyStatistic", + "icon": "statistic", + "description": "统计数值", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "package": "@opentiny/vue", + "exportName": "TinyStatistic", + "destructuring": true + }, + "group": "component", + "category": "组件", + "priority": 2, + "schema": { + "properties": [ + { + "name": "0", + "label": { + "zh_CN": "基础属性" }, - "type": "event", - "functionInfo": { - "params": [ - { - "name": "selection", - "type": "Object", - "defaultValue": "", - "description": { - "zh_CN": "当前选中项" + "content": [ + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "值" } - } - ], - "returns": {} + }, + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "value", + "readOnly": false, + "required": false, + "description": { + "zh_CN": "数字显示内容" + }, + "defaultValue": "0", + "labelPosition": "left" + }, + { + "cols": 12, + "type": "number", + "label": { + "text": { + "zh_CN": "精度" + } + }, + "widget": { + "props": { + "step": 1 + }, + "component": "NumberConfigurator" + }, + "disabled": false, + "property": "precision", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "精度值" + }, + "defaultValue": null, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性" } }, - "onCellMouseEnter": { + { + "name": "1", "label": { - "zh_CN": "单元格 hover 时会触发" - }, - "description": { - "zh_CN": "当单元格 hover 进入时会触发该事件" + "zh_CN": "样式属性" }, - "type": "event", - "functionInfo": { - "params": [ - { - "name": "row", - "type": "Object", - "defaultValue": "", - "description": { - "zh_CN": "当前行" + "content": [ + { + "cols": 12, + "type": "object", + "label": { + "text": { + "zh_CN": "值样式" } }, - { - "name": "column", - "type": "Object", - "defaultValue": "", - "description": { - "zh_CN": "当前列" - } + "widget": { + "props": { + "height": 150, + "language": "json" + }, + "component": "CodeConfigurator" }, - { - "name": "cell", - "type": "Object", - "defaultValue": "", - "description": { - "zh_CN": "当前单元格" - } + "disabled": false, + "property": "value-style", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "设置数字样式" }, - { - "name": "event", - "type": "Object", - "defaultValue": "", - "description": { - "zh_CN": "原生事件 event" - } - } - ], - "returns": {} + "defaultValue": null, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性" } }, - "onCellMouseLeave": { + { + "name": "2", "label": { - "zh_CN": "单元格 hover 退出时会触发" - }, - "description": { - "zh_CN": "当单元格 hover 退出时会触发该事件" + "zh_CN": "高级属性" }, - "type": "event", - "functionInfo": { - "params": [ - { - "name": "row", - "type": "Object", - "defaultValue": "", - "description": { - "zh_CN": "当前行" + "content": [ + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "前缀" } }, - { - "name": "column", - "type": "Object", - "defaultValue": "", - "description": { - "zh_CN": "当前列" - } + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" }, - { - "name": "cell", - "type": "Object", - "defaultValue": "", - "description": { - "zh_CN": "当前单元格" + "disabled": false, + "property": "prefix", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "设置数字内容前缀" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "后缀" } }, - { - "name": "event", - "type": "Object", - "defaultValue": "", - "description": { - "zh_CN": "原生事件 event" + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "suffix", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "设置数字内容后缀" + }, + "defaultValue": null, + "labelPosition": "left" + }, + { + "cols": 12, + "type": "string", + "label": { + "text": { + "zh_CN": "标题" } - } - ], - "returns": {} + }, + "widget": { + "props": { + "placeholder": "请输入..." + }, + "component": "InputConfigurator" + }, + "disabled": false, + "property": "title", + "readOnly": false, + "required": true, + "description": { + "zh_CN": "设置数字内容标题" + }, + "defaultValue": null, + "labelPosition": "left" + } + ], + "description": { + "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置" } } - }, + ], + "events": {}, "slots": { - "empty": { + "title": { "label": { - "zh_CN": "empty" + "zh_CN": "标题" }, "description": { - "zh_CN": "当数据为空时自定义的内容" + "zh_CN": "数字内容标题插槽" } }, - "append": { + "prefix": { "label": { - "zh_CN": "append" + "zh_CN": "前缀" }, "description": { - "zh_CN": "插入至表格最后一行之后的内容, 如果需要对表格的内容进行无限滚动操作,可能需要用到这个 slot。 若表格有合计行,该 slot 会位于合计行之上。" + "zh_CN": "数字内容前置插槽" + } + }, + "suffix": { + "label": { + "zh_CN": "后缀" + }, + "description": { + "zh_CN": "数字内容后置插槽" } } } - } - }, - { - "id": 1, - "version": "2.4.2", - "name": { - "zh_CN": "表单" - }, - "component": "ElTableColumn", - "icon": "table", - "description": "用于展示多条结构类似的数据, 可对数据进行排序、筛选、对比或其他自定义操作", - "doc_url": "", - "screenshot": "", - "tags": "", - "keywords": "", - "dev_mode": "proCode", - "npm": { - "package": "element-plus", - "exportName": "ElTableColumn", - "destructuring": true }, - "group": "表单组件", - "category": "element-plus", "configure": { "loop": true, "condition": true, "styles": true, "isContainer": false, "isModal": false, - "isPopper": false, "nestingRule": { "childWhitelist": "", "parentWhitelist": "", @@ -3135,31 +10163,12 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["inline", "label-width"] + "properties": [] }, "contextMenu": { - "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"], - "disable": [] - }, - "invalidity": [""], - "clickCapture": true, - "framework": "Vue" - }, - "schema": { - "properties": [ - { - "name": "0", - "label": { - "zh_CN": "基础属性" - }, - "content": [], - "description": { - "zh_CN": "" - } - } - ], - "events": {}, - "slots": {} + "actions": ["create symbol"], + "disable": ["copy", "remove"] + } } }, { @@ -3285,11 +10294,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["disabled", "size"] + "properties": [ + "disabled", + "size" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -3604,7 +10621,9 @@ "clickCapture": false, "isModal": false, "nestingRule": { - "childWhitelist": ["TinyCarouselItem"], + "childWhitelist": [ + "TinyCarouselItem" + ], "parentWhitelist": "", "descendantBlacklist": "", "ancestorWhitelist": "" @@ -3613,11 +10632,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["disabled", "size"] + "properties": [ + "disabled", + "size" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -3771,7 +10798,14 @@ "name": { "zh_CN": "标题" }, - "component": ["h1", "h2", "h3", "h4", "h5", "h6"], + "component": [ + "h1", + "h2", + "h3", + "h4", + "h5", + "h6" + ], "icon": "h16", "description": "标题", "docUrl": "", @@ -3856,11 +10890,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["disabled", "size"] + "properties": [ + "disabled", + "size" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -4219,11 +11261,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["disabled", "size"] + "properties": [ + "disabled", + "size" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -4433,18 +11483,19 @@ "bindState": true, "label": { "text": { - "zh_CN": "资源" + "zh_CN": "资源选择" } }, "cols": 12, "rules": [], "widget": { - "component": "InputConfigurator", + "component": "SourceSelectConfigurator", "props": {} }, "description": { "zh_CN": "src路径" - } + }, + "labelPosition": "top" }, { "property": "attributes3", @@ -4471,7 +11522,9 @@ ], "events": {}, "shortcuts": { - "properties": ["src"] + "properties": [ + "src" + ] }, "contentMenu": { "actions": [] @@ -5124,11 +12177,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["disabled", "size"] + "properties": [ + "disabled", + "size" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -5272,11 +12333,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["label-width", "disabled"] + "properties": [ + "label-width", + "disabled" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -5369,7 +12438,10 @@ "isContainer": true, "isModal": false, "nestingRule": { - "childWhitelist": ["TinyRow", "TinyCol"], + "childWhitelist": [ + "TinyRow", + "TinyCol" + ], "parentWhitelist": "", "descendantBlacklist": "", "ancestorWhitelist": "" @@ -5378,11 +12450,18 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["disabled"] + "properties": [ + "disabled" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -5730,11 +12809,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["label-width", "disabled"] + "properties": [ + "label-width", + "disabled" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -5852,7 +12939,9 @@ "isModal": false, "nestingRule": { "childWhitelist": "", - "parentWhitelist": ["TinyForm"], + "parentWhitelist": [ + "TinyForm" + ], "descendantBlacklist": "", "ancestorWhitelist": "" }, @@ -5860,11 +12949,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["label", "rules"] + "properties": [ + "label", + "rules" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -6136,11 +13233,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["label", "rules"] + "properties": [ + "label", + "rules" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -6473,11 +13578,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["text", "size"] + "properties": [ + "text", + "size" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -6885,11 +13998,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["value", "disabled"] + "properties": [ + "value", + "disabled" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -7120,11 +14241,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["visible", "width"] + "properties": [ + "visible", + "width" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -7523,11 +14652,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["multiple", "options"] + "properties": [ + "multiple", + "options" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -7720,11 +14857,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["disabled", "mini"] + "properties": [ + "disabled", + "mini" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -7993,11 +15138,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["clearable", "mini"] + "properties": [ + "clearable", + "mini" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -8250,11 +15403,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["border", "disabled"] + "properties": [ + "border", + "disabled" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -8436,11 +15597,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["text", "size"] + "properties": [ + "text", + "size" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -8645,11 +15814,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["disabled", "type"] + "properties": [ + "disabled", + "type" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -8921,11 +16098,19 @@ "isLayout": false, "rootSelector": ".tiny-dialog-box", "shortcuts": { - "properties": ["visible", "width"] + "properties": [ + "visible", + "width" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -9171,7 +16356,9 @@ "clickCapture": false, "isModal": false, "nestingRule": { - "childWhitelist": ["TinyTabItem"], + "childWhitelist": [ + "TinyTabItem" + ], "parentWhitelist": [], "descendantBlacklist": [], "ancestorWhitelist": [] @@ -9180,11 +16367,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["size", "tab-style"] + "properties": [ + "size", + "tab-style" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -9279,7 +16474,9 @@ "isModal": false, "nestingRule": { "childWhitelist": "", - "parentWhitelist": ["TinyTab"], + "parentWhitelist": [ + "TinyTab" + ], "descendantBlacklist": "", "ancestorWhitelist": "" }, @@ -9287,11 +16484,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["name", "title"] + "properties": [ + "name", + "title" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -9415,7 +16620,9 @@ "clickCapture": false, "isModal": false, "nestingRule": { - "childWhitelist": ["TinyBreadcrumbItem"], + "childWhitelist": [ + "TinyBreadcrumbItem" + ], "parentWhitelist": [], "descendantBlacklist": [], "ancestorWhitelist": [] @@ -9424,11 +16631,18 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["separator"] + "properties": [ + "separator" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -9503,7 +16717,9 @@ "isModal": false, "nestingRule": { "childWhitelist": "", - "parentWhitelist": ["TinyBreadcrumb"], + "parentWhitelist": [ + "TinyBreadcrumb" + ], "descendantBlacklist": "", "ancestorWhitelist": "" }, @@ -9511,11 +16727,18 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["to"] + "properties": [ + "to" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -9636,11 +16859,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["label-width", "disabled"] + "properties": [ + "label-width", + "disabled" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -9745,15 +16976,24 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["label-width", "disabled"] + "properties": [ + "label-width", + "disabled" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, { + "version": "3.20.0", "icon": "grid", "name": { "zh_CN": "表格" @@ -9961,7 +17201,10 @@ "widget": { "component": "JsSlotConfigurator", "props": { - "slots": ["header", "default"] + "slots": [ + "header", + "default" + ] } } }, @@ -10633,10 +17876,15 @@ } }, "shortcuts": { - "properties": ["sortable", "columns"] + "properties": [ + "sortable", + "columns" + ] }, "contentMenu": { - "actions": ["create symbol"] + "actions": [ + "create symbol" + ] }, "onBeforeMount": "console.log('table on load'); this.pager = source.pager; this.fetchData = source.fetchData; this.data = source.data ;this.columns = source.columns" }, @@ -10656,11 +17904,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["sortable", "columns"] + "properties": [ + "sortable", + "columns" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -10689,7 +17945,9 @@ "events": {}, "shortcuts": {}, "contentMenu": { - "actions": ["create symbol"] + "actions": [ + "create symbol" + ] } }, "configure": { @@ -10709,8 +17967,13 @@ "rootSelector": "", "shortcuts": {}, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -10937,11 +18200,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["currentPage", "total"] + "properties": [ + "currentPage", + "total" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -11319,11 +18590,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["modelValue", "disabled"] + "properties": [ + "modelValue", + "disabled" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -11652,11 +18931,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["data", "show-checkbox"] + "properties": [ + "data", + "show-checkbox" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -11828,11 +19115,19 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["active", "data"] + "properties": [ + "active", + "data" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, @@ -11855,7 +19150,234 @@ "destructuring": true }, "group": "component", - "priority": 11, + "priority": 11, + "schema": { + "properties": [ + { + "label": { + "zh_CN": "基础信息" + }, + "description": { + "zh_CN": "基础信息" + }, + "content": [ + { + "property": "placement", + "label": { + "text": { + "zh_CN": "提示位置" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "top", + "value": "top" + }, + { + "label": "top-start", + "value": "top-start" + }, + { + "label": "top-end", + "value": "top-end" + }, + { + "label": "bottom", + "value": "bottom" + }, + { + "label": "bottom-start", + "value": "bottom-start" + }, + { + "label": "bottom-end", + "value": "bottom-end" + }, + { + "label": "left", + "value": "left" + }, + { + "label": "left-start", + "value": "left-start" + }, + { + "label": "left-end", + "value": "left-end" + }, + { + "label": "right", + "value": "right" + }, + { + "label": "right-start", + "value": "right-start" + }, + { + "label": "right-end", + "value": "right-end" + } + ] + } + }, + "description": { + "zh_CN": "Tooltip 的出现位置" + }, + "labelPosition": "left" + }, + { + "property": "content", + "label": { + "text": { + "zh_CN": "内容" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "defaultValue": "提示信息", + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "显示的内容,也可以通过 slot#content 传入 DOM" + }, + "labelPosition": "left" + }, + { + "property": "render-content", + "label": { + "text": { + "zh_CN": "渲染函数" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": { + "disabled": true, + "placeholder": "请使用变量绑定来绑定函数" + } + }, + "description": { + "zh_CN": "自定义渲染函数,返回需要渲染的节点内容" + } + }, + { + "property": "modelValue", + "label": { + "text": { + "zh_CN": "是否可见" + } + }, + "defaultValue": true, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "状态是否可见" + }, + "labelPosition": "left" + }, + { + "property": "manual", + "label": { + "text": { + "zh_CN": "手动控制" + } + }, + "defaultValue": true, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "手动控制模式,设置为 true 后,mouseenter 和 mouseleave 事件将不会生效" + }, + "labelPosition": "left" + } + ] + } + ], + "events": {}, + "slots": { + "content": { + "label": { + "zh_CN": "提示内容" + }, + "description": { + "zh_CN": "自定义提示内容" + } + } + } + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": true, + "isModal": false, + "isPopper": true, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [ + "disabled", + "content" + ] + }, + "contextMenu": { + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] + } + } + }, + { + "version": "3.20.0", + "icon": "popover", + "name": { + "zh_CN": "提示框" + }, + "component": "TinyPopover", + "description": "Popover可通过对一个触发源操作触发弹出框,支持自定义弹出内容,延迟触发和渐变动画", + "docUrl": "", + "screenshot": "", + "tags": "", + "keywords": "", + "devMode": "proCode", + "npm": { + "package": "@opentiny/vue", + "exportName": "Popover", + "destructuring": true + }, + "group": "component", + "priority": 7, "schema": { "properties": [ { @@ -11866,11 +19388,31 @@ "zh_CN": "基础信息" }, "content": [ + { + "property": "modelValue", + "label": { + "text": { + "zh_CN": "绑定值" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "双向绑定,手动控制是否可见的状态值" + }, + "labelPosition": "left" + }, { "property": "placement", "label": { "text": { - "zh_CN": "提示位置" + "zh_CN": "位置" } }, "required": true, @@ -11933,100 +19475,354 @@ } }, "description": { - "zh_CN": "Tooltip 的出现位置" + "zh_CN": "提示框位置" + }, + "labelPosition": "left" + }, + { + "property": "trigger", + "label": { + "text": { + "zh_CN": "触发方式" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "click", + "value": "click" + }, + { + "label": "focus", + "value": "focus" + }, + { + "label": "hover", + "value": "hover" + }, + { + "label": "manual", + "value": "manual" + } + ] + } + }, + "description": { + "zh_CN": "触发方式,该属性的可选值为 click / focus / hover / manual,该属性的默认值为 click" + }, + "labelPosition": "left" + }, + { + "property": "popper-class", + "label": { + "text": { + "zh_CN": "自定义类" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "为 popper 添加类名" + }, + "labelPosition": "left" + }, + { + "property": "visible-arrow", + "label": { + "text": { + "zh_CN": "显示箭头" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "是否显示 Tooltip 箭头" + }, + "labelPosition": "left" + }, + { + "property": "append-to-body", + "label": { + "text": { + "zh_CN": "添加到body上" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "Popover弹窗是否添加到body上" + }, + "labelPosition": "left" + }, + { + "property": "arrow-offset", + "label": { + "text": { + "zh_CN": "箭头的位置偏移" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "NumberConfigurator", + "props": {} + }, + "description": { + "zh_CN": "箭头的位置偏移,该属性的默认值为 0" + } + }, + { + "property": "close-delay", + "label": { + "text": { + "zh_CN": "延迟隐藏" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "NumberConfigurator", + "props": {} + }, + "description": { + "zh_CN": "触发方式为 hover 时的隐藏延迟,单位为毫秒" + }, + "labelPosition": "left" + }, + { + "property": "content", + "label": { + "text": { + "zh_CN": "显示的内容" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "InputConfigurator", + "props": {} + }, + "description": { + "zh_CN": "显示的内容,也可以通过 slot 传入 DOM" + }, + "labelPosition": "left" + }, + { + "property": "disabled", + "label": { + "text": { + "zh_CN": "禁用" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "Popover 是否可用" + }, + "labelPosition": "left" + }, + { + "property": "offset", + "label": { + "text": { + "zh_CN": "位置偏移量" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "NumberConfigurator", + "props": {} + }, + "description": { + "zh_CN": "出现位置的偏移量" + }, + "labelPosition": "left" + }, + { + "property": "open-delay", + "label": { + "text": { + "zh_CN": "显示延迟" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "NumberConfigurator", + "props": {} + }, + "description": { + "zh_CN": "触发方式为 hover 时的显示延迟,单位为毫秒" + }, + "labelPosition": "left" + }, + { + "property": "popper-options", + "label": { + "text": { + "zh_CN": "弹出层参数" + } + }, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "CodeConfigurator", + "props": {} + }, + "description": { + "zh_CN": "popper.js 的参数" }, - "labelPosition": "left" + "labelPosition": "top" }, { - "property": "content", + "property": "title", "label": { "text": { - "zh_CN": "内容" + "zh_CN": "标题" } }, "required": true, "readOnly": false, "disabled": false, - "defaultValue": "提示信息", "cols": 12, "widget": { "component": "InputConfigurator", "props": {} }, "description": { - "zh_CN": "显示的内容,也可以通过 slot#content 传入 DOM" + "zh_CN": "提示内容标题" }, "labelPosition": "left" }, { - "property": "render-content", + "property": "transform-origin", "label": { "text": { - "zh_CN": "渲染函数" + "zh_CN": "旋转中心点" } }, - "required": false, + "required": true, "readOnly": false, "disabled": false, "cols": 12, "widget": { - "component": "InputConfigurator", - "props": { - "disabled": true, - "placeholder": "请使用变量绑定来绑定函数" - } + "component": "CheckBoxConfigurator", + "props": {} }, "description": { - "zh_CN": "自定义渲染函数,返回需要渲染的节点内容" - } + "zh_CN": "组件的旋转中心点,组件的旋转中心点" + }, + "labelPosition": "left" }, { - "property": "modelValue", + "property": "transition", "label": { "text": { - "zh_CN": "是否可见" + "zh_CN": "渐变动画" } }, - "defaultValue": true, + "required": true, + "readOnly": false, + "disabled": false, "cols": 12, "widget": { - "component": "CheckBoxConfigurator", + "component": "InputConfigurator", "props": {} }, "description": { - "zh_CN": "状态是否可见" + "zh_CN": "该属性的默认值为 fade-in-linear" }, "labelPosition": "left" }, { - "property": "manual", + "property": "width", "label": { "text": { - "zh_CN": "手动控制" + "zh_CN": "宽度" } }, - "defaultValue": true, + "required": true, + "readOnly": false, + "disabled": false, + "cols": 12, "widget": { - "component": "CheckBoxConfigurator", + "component": "NumberConfigurator", "props": {} }, "description": { - "zh_CN": "手动控制模式,设置为 true 后,mouseenter 和 mouseleave 事件将不会生效" + "zh_CN": "宽度" }, "labelPosition": "left" } ] } ], - "events": {}, - "slots": { - "content": { + "events": { + "onUpdate:modelValue": { "label": { - "zh_CN": "提示内容" + "zh_CN": "双向绑定的值改变时触发" }, "description": { - "zh_CN": "自定义提示内容" - } + "zh_CN": "手动控制是否可见的状态值改变时触发" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "value", + "type": "boolean", + "defaultValue": "", + "description": { + "zh_CN": "双向绑定的可见状态值" + } + } + ], + "returns": {} + }, + "defaultValue": "" } } }, @@ -12047,22 +19843,30 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["disabled", "content"] + "properties": [ + "visible", + "width" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, { "version": "3.20.0", - "icon": "popover", "name": { - "zh_CN": "提示框" + "zh_CN": "日期选择" }, - "component": "TinyPopover", - "description": "Popover可通过对一个触发源操作触发弹出框,支持自定义弹出内容,延迟触发和渐变动画", + "component": "TinyDatePicker", + "icon": "datepick", + "description": "用于输入或选择日期", "docUrl": "", "screenshot": "", "tags": "", @@ -12070,176 +19874,26 @@ "devMode": "proCode", "npm": { "package": "@opentiny/vue", - "exportName": "Popover", + "exportName": "DatePicker", "destructuring": true }, "group": "component", - "priority": 7, + "priority": 1, "schema": { "properties": [ { "label": { - "zh_CN": "基础信息" - }, - "description": { - "zh_CN": "基础信息" - }, - "content": [ - { - "property": "modelValue", - "label": { - "text": { - "zh_CN": "绑定值" - } - }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - }, - "description": { - "zh_CN": "双向绑定,手动控制是否可见的状态值" - }, - "labelPosition": "left" - }, - { - "property": "placement", - "label": { - "text": { - "zh_CN": "位置" - } - }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "widget": { - "component": "SelectConfigurator", - "props": { - "options": [ - { - "label": "top", - "value": "top" - }, - { - "label": "top-start", - "value": "top-start" - }, - { - "label": "top-end", - "value": "top-end" - }, - { - "label": "bottom", - "value": "bottom" - }, - { - "label": "bottom-start", - "value": "bottom-start" - }, - { - "label": "bottom-end", - "value": "bottom-end" - }, - { - "label": "left", - "value": "left" - }, - { - "label": "left-start", - "value": "left-start" - }, - { - "label": "left-end", - "value": "left-end" - }, - { - "label": "right", - "value": "right" - }, - { - "label": "right-start", - "value": "right-start" - }, - { - "label": "right-end", - "value": "right-end" - } - ] - } - }, - "description": { - "zh_CN": "提示框位置" - }, - "labelPosition": "left" - }, - { - "property": "trigger", - "label": { - "text": { - "zh_CN": "触发方式" - } - }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "widget": { - "component": "SelectConfigurator", - "props": { - "options": [ - { - "label": "click", - "value": "click" - }, - { - "label": "focus", - "value": "focus" - }, - { - "label": "hover", - "value": "hover" - }, - { - "label": "manual", - "value": "manual" - } - ] - } - }, - "description": { - "zh_CN": "触发方式,该属性的可选值为 click / focus / hover / manual,该属性的默认值为 click" - }, - "labelPosition": "left" - }, - { - "property": "popper-class", - "label": { - "text": { - "zh_CN": "自定义类" - } - }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "widget": { - "component": "InputConfigurator", - "props": {} - }, - "description": { - "zh_CN": "为 popper 添加类名" - }, - "labelPosition": "left" - }, + "zh_CN": "基础信息" + }, + "description": { + "zh_CN": "基础信息" + }, + "content": [ { - "property": "visible-arrow", + "property": "modelValue", "label": { "text": { - "zh_CN": "显示箭头" + "zh_CN": "绑定值" } }, "required": true, @@ -12247,58 +19901,58 @@ "disabled": false, "cols": 12, "widget": { - "component": "CheckBoxConfigurator", + "component": "I18nConfigurator", "props": {} }, "description": { - "zh_CN": "是否显示 Tooltip 箭头" + "zh_CN": "双向绑定值" }, "labelPosition": "left" }, { - "property": "append-to-body", + "property": "type", "label": { "text": { - "zh_CN": "添加到body上" + "zh_CN": "类型" } }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, "widget": { - "component": "CheckBoxConfigurator", - "props": {} + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "日期", + "value": "date" + }, + { + "label": "日期时间", + "value": "datetime" + }, + { + "label": "周", + "value": "week" + }, + { + "label": "月份", + "value": "month" + }, + { + "label": "年份", + "value": "year" + } + ] + } }, "description": { - "zh_CN": "Popover弹窗是否添加到body上" + "zh_CN": "设置日期框的type属性" }, "labelPosition": "left" }, { - "property": "arrow-offset", - "label": { - "text": { - "zh_CN": "箭头的位置偏移" - } - }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "widget": { - "component": "NumberConfigurator", - "props": {} - }, - "description": { - "zh_CN": "箭头的位置偏移,该属性的默认值为 0" - } - }, - { - "property": "close-delay", + "property": "placeholder", "label": { "text": { - "zh_CN": "延迟隐藏" + "zh_CN": "占位文本" } }, "required": true, @@ -12306,19 +19960,19 @@ "disabled": false, "cols": 12, "widget": { - "component": "NumberConfigurator", + "component": "I18nConfigurator", "props": {} }, "description": { - "zh_CN": "触发方式为 hover 时的隐藏延迟,单位为毫秒" + "zh_CN": "输入框占位文本" }, "labelPosition": "left" }, { - "property": "content", + "property": "clearable", "label": { "text": { - "zh_CN": "显示的内容" + "zh_CN": "清除按钮" } }, "required": true, @@ -12326,11 +19980,11 @@ "disabled": false, "cols": 12, "widget": { - "component": "InputConfigurator", + "component": "CheckBoxConfigurator", "props": {} }, "description": { - "zh_CN": "显示的内容,也可以通过 slot 传入 DOM" + "zh_CN": "是否显示清除按钮" }, "labelPosition": "left" }, @@ -12341,7 +19995,7 @@ "zh_CN": "禁用" } }, - "required": true, + "required": false, "readOnly": false, "disabled": false, "cols": 12, @@ -12350,35 +20004,15 @@ "props": {} }, "description": { - "zh_CN": "Popover 是否可用" - }, - "labelPosition": "left" - }, - { - "property": "offset", - "label": { - "text": { - "zh_CN": "位置偏移量" - } - }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "widget": { - "component": "NumberConfigurator", - "props": {} - }, - "description": { - "zh_CN": "出现位置的偏移量" + "zh_CN": "是否禁用" }, "labelPosition": "left" }, { - "property": "open-delay", + "property": "readonly", "label": { "text": { - "zh_CN": "显示延迟" + "zh_CN": "只读" } }, "required": true, @@ -12386,39 +20020,19 @@ "disabled": false, "cols": 12, "widget": { - "component": "NumberConfigurator", + "component": "CheckBoxConfigurator", "props": {} }, "description": { - "zh_CN": "触发方式为 hover 时的显示延迟,单位为毫秒" + "zh_CN": "是否只读" }, "labelPosition": "left" }, { - "property": "popper-options", - "label": { - "text": { - "zh_CN": "弹出层参数" - } - }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "widget": { - "component": "CodeConfigurator", - "props": {} - }, - "description": { - "zh_CN": "popper.js 的参数" - }, - "labelPosition": "top" - }, - { - "property": "title", + "property": "size", "label": { "text": { - "zh_CN": "标题" + "zh_CN": "尺寸" } }, "required": true, @@ -12426,39 +20040,42 @@ "disabled": false, "cols": 12, "widget": { - "component": "InputConfigurator", - "props": {} - }, - "description": { - "zh_CN": "提示内容标题" - }, - "labelPosition": "left" - }, - { - "property": "transform-origin", - "label": { - "text": { - "zh_CN": "旋转中心点" + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "medium", + "value": "medium" + }, + { + "label": "small", + "value": "small" + }, + { + "label": "mini", + "value": "mini" + } + ] } }, - "required": true, - "readOnly": false, - "disabled": false, - "cols": 12, - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - }, "description": { - "zh_CN": "组件的旋转中心点,组件的旋转中心点" + "zh_CN": "日期框尺寸。该属性的可选值为 medium / small / mini" }, "labelPosition": "left" - }, + } + ] + }, + { + "name": "1", + "label": { + "zh_CN": "其他" + }, + "content": [ { - "property": "transition", + "property": "maxlength", "label": { "text": { - "zh_CN": "渐变动画" + "zh_CN": "输入最大长度" } }, "required": true, @@ -12466,19 +20083,18 @@ "disabled": false, "cols": 12, "widget": { - "component": "InputConfigurator", + "component": "NumberConfigurator", "props": {} }, "description": { - "zh_CN": "该属性的默认值为 fade-in-linear" - }, - "labelPosition": "left" + "zh_CN": "设置 input 框的maxLength" + } }, { - "property": "width", + "property": "autofocus", "label": { "text": { - "zh_CN": "宽度" + "zh_CN": "聚焦" } }, "required": true, @@ -12486,40 +20102,149 @@ "disabled": false, "cols": 12, "widget": { - "component": "NumberConfigurator", + "component": "CheckBoxConfigurator", "props": {} }, "description": { - "zh_CN": "宽度" + "zh_CN": "自动获取焦点" }, "labelPosition": "left" } - ] + ], + "description": { + "zh_CN": "" + } } ], "events": { + "onChange": { + "label": { + "zh_CN": "值改变时触发" + }, + "description": { + "zh_CN": "在 Input 值改变时触发" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "value", + "type": "string", + "defaultValue": "", + "description": { + "zh_CN": "输入框改变后的值" + } + } + ], + "returns": {} + }, + "defaultValue": "" + }, + "onInput": { + "label": { + "zh_CN": "输入值改变时触发" + }, + "description": { + "zh_CN": "在 Input 输入值改变时触发" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "value", + "type": "string", + "defaultValue": "", + "description": { + "zh_CN": "输入框输入的值" + } + } + ], + "returns": {} + }, + "defaultValue": "" + }, "onUpdate:modelValue": { "label": { "zh_CN": "双向绑定的值改变时触发" }, "description": { - "zh_CN": "手动控制是否可见的状态值改变时触发" + "zh_CN": "在 Input 输入值改变时触发" }, "type": "event", "functionInfo": { "params": [ { "name": "value", - "type": "boolean", + "type": "string", "defaultValue": "", "description": { - "zh_CN": "双向绑定的可见状态值" + "zh_CN": "双向绑定的值" + } + } + ], + "returns": {} + }, + "defaultValue": "" + }, + "onBlur": { + "label": { + "zh_CN": "失去焦点时触发" + }, + "description": { + "zh_CN": "在 Input 失去焦点时触发" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "event", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "原生 event" + } + } + ], + "returns": {} + }, + "defaultValue": "" + }, + "onFocus": { + "label": { + "zh_CN": "获取焦点时触发" + }, + "description": { + "zh_CN": "在 Input 获取焦点时触发" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "event", + "type": "Object", + "defaultValue": "", + "description": { + "zh_CN": "原生 event" } } ], "returns": {} }, "defaultValue": "" + }, + "onClear": { + "label": { + "zh_CN": "点击清空按钮时触发" + }, + "description": { + "zh_CN": "点击清空按钮时触发" + }, + "type": "event", + "functionInfo": { + "params": [], + "returns": {} + }, + "defaultValue": "" } } }, @@ -12529,7 +20254,6 @@ "styles": true, "isContainer": true, "isModal": false, - "isPopper": true, "nestingRule": { "childWhitelist": "", "parentWhitelist": "", @@ -12540,22 +20264,30 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["visible", "width"] + "properties": [ + "value", + "disabled" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, { "version": "3.20.0", "name": { - "zh_CN": "日期选择" + "zh_CN": "数字输入框" }, - "component": "TinyDatePicker", - "icon": "datepick", - "description": "用于输入或选择日期", + "component": "TinyNumeric", + "icon": "numeric", + "description": "通过鼠标或键盘输入字符", "docUrl": "", "screenshot": "", "tags": "", @@ -12563,7 +20295,7 @@ "devMode": "proCode", "npm": { "package": "@opentiny/vue", - "exportName": "DatePicker", + "exportName": "Numeric", "destructuring": true }, "group": "component", @@ -12588,7 +20320,6 @@ "required": true, "readOnly": false, "disabled": false, - "cols": 12, "widget": { "component": "I18nConfigurator", "props": {} @@ -12598,45 +20329,6 @@ }, "labelPosition": "left" }, - { - "property": "type", - "label": { - "text": { - "zh_CN": "类型" - } - }, - "widget": { - "component": "SelectConfigurator", - "props": { - "options": [ - { - "label": "日期", - "value": "date" - }, - { - "label": "日期时间", - "value": "datetime" - }, - { - "label": "周", - "value": "week" - }, - { - "label": "月份", - "value": "month" - }, - { - "label": "年份", - "value": "year" - } - ] - } - }, - "description": { - "zh_CN": "设置日期框的type属性" - }, - "labelPosition": "left" - }, { "property": "placeholder", "label": { @@ -12658,10 +20350,10 @@ "labelPosition": "left" }, { - "property": "clearable", + "property": "allow-empty", "label": { "text": { - "zh_CN": "清除按钮" + "zh_CN": "内容可清空" } }, "required": true, @@ -12673,7 +20365,7 @@ "props": {} }, "description": { - "zh_CN": "是否显示清除按钮" + "zh_CN": "是否内容可清空" }, "labelPosition": "left" }, @@ -12698,33 +20390,68 @@ "labelPosition": "left" }, { - "property": "readonly", + "property": "size", "label": { "text": { - "zh_CN": "只读" + "zh_CN": "尺寸" } }, "required": true, "readOnly": false, "disabled": false, "cols": 12, + "widget": { + "component": "SelectConfigurator", + "props": { + "options": [ + { + "label": "medium", + "value": "medium" + }, + { + "label": "small", + "value": "small" + }, + { + "label": "mini", + "value": "mini" + } + ] + } + }, + "description": { + "zh_CN": "输入框尺寸。该属性的可选值为 medium / small / mini" + }, + "labelPosition": "left" + }, + { + "property": "controls", + "label": { + "text": { + "zh_CN": "加减按钮" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, "widget": { "component": "CheckBoxConfigurator", "props": {} }, "description": { - "zh_CN": "是否只读" + "zh_CN": "是否使用加减按钮" }, "labelPosition": "left" }, { - "property": "size", + "property": "controls-position", "label": { "text": { - "zh_CN": "尺寸" + "zh_CN": "加减按钮位置" } }, - "required": true, + "required": false, "readOnly": false, "disabled": false, "cols": 12, @@ -12733,76 +20460,109 @@ "props": { "options": [ { - "label": "medium", - "value": "medium" - }, - { - "label": "small", - "value": "small" + "label": "左右两侧", + "value": "" }, { - "label": "mini", - "value": "mini" + "label": "只在右侧", + "value": "right" } ] } }, "description": { - "zh_CN": "日期框尺寸。该属性的可选值为 medium / small / mini" + "zh_CN": "加减按钮位置" + } + }, + { + "property": "precision", + "label": { + "text": { + "zh_CN": "精度" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "NumberConfigurator", + "props": { + "allowEmpty": true + } + }, + "description": { + "zh_CN": "数值精度" }, "labelPosition": "left" - } - ] - }, - { - "name": "1", - "label": { - "zh_CN": "其他" - }, - "content": [ + }, { - "property": "maxlength", + "property": "step", "label": { "text": { - "zh_CN": "输入最大长度" + "zh_CN": "步长" } }, - "required": true, + "required": false, "readOnly": false, "disabled": false, "cols": 12, "widget": { "component": "NumberConfigurator", - "props": {} + "props": { + "allowEmpty": true + } }, "description": { - "zh_CN": "设置 input 框的maxLength" - } + "zh_CN": "步长" + }, + "labelPosition": "left" + }, + { + "property": "max", + "label": { + "text": { + "zh_CN": "最大数值" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "cols": 12, + "widget": { + "component": "NumberConfigurator", + "props": { + "allowEmpty": true + } + }, + "description": { + "zh_CN": "可输入的最大数值" + }, + "labelPosition": "left" }, { - "property": "autofocus", + "property": "min", "label": { "text": { - "zh_CN": "聚焦" + "zh_CN": "最小数值" } }, - "required": true, + "required": false, "readOnly": false, "disabled": false, "cols": 12, "widget": { - "component": "CheckBoxConfigurator", - "props": {} + "component": "NumberConfigurator", + "props": { + "allowEmpty": true + } }, "description": { - "zh_CN": "自动获取焦点" + "zh_CN": "可输入的最大数值" }, "labelPosition": "left" } - ], - "description": { - "zh_CN": "" - } + ] } ], "events": { @@ -12953,22 +20713,30 @@ "isLayout": false, "rootSelector": "", "shortcuts": { - "properties": ["value", "disabled"] + "properties": [ + "value", + "disabled" + ] }, "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] } } }, { "version": "3.20.0", "name": { - "zh_CN": "数字输入框" + "zh_CN": "穿梭框" }, - "component": "TinyNumeric", - "icon": "numeric", - "description": "通过鼠标或键盘输入字符", + "component": "TinyTransfer", + "icon": "transfer", + "description": "穿梭框,实现左右表格数据的双向交换的组件", "docUrl": "", "screenshot": "", "tags": "", @@ -12976,7 +20744,7 @@ "devMode": "proCode", "npm": { "package": "@opentiny/vue", - "exportName": "Numeric", + "exportName": "TinyTransfer", "destructuring": true }, "group": "component", @@ -13011,988 +20779,1343 @@ "labelPosition": "left" }, { - "property": "placeholder", + "property": "data", "label": { "text": { - "zh_CN": "占位文本" + "zh_CN": "左右列表的全量数据源" } }, "required": true, "readOnly": false, "disabled": false, - "cols": 12, "widget": { - "component": "I18nConfigurator", + "component": "CodeConfigurator", + "props": { + "language": "json" + } + }, + "description": { + "zh_CN": "左右列表的全量数据源" + }, + "labelPosition": "left" + }, + { + "property": "filterable", + "label": { + "text": { + "zh_CN": "是否启用搜索的功能" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "widget": { + "component": "CheckBoxConfigurator", "props": {} }, "description": { - "zh_CN": "输入框占位文本" + "zh_CN": "是否启用搜索的功能" }, "labelPosition": "left" }, { - "property": "allow-empty", + "property": "showAllBtn", "label": { "text": { - "zh_CN": "内容可清空" + "zh_CN": "是否显示全部移动按钮" } }, - "required": true, + "required": false, "readOnly": false, "disabled": false, - "cols": 12, "widget": { "component": "CheckBoxConfigurator", "props": {} }, "description": { - "zh_CN": "是否内容可清空" + "zh_CN": "是否显示全部移动按钮" }, "labelPosition": "left" }, { - "property": "disabled", + "property": "toLeftDisable", "label": { "text": { - "zh_CN": "禁用" + "zh_CN": "组件初始化状态下未选中时,默认按钮显示禁用状态" } }, "required": false, "readOnly": false, "disabled": false, - "cols": 12, "widget": { "component": "CheckBoxConfigurator", "props": {} }, "description": { - "zh_CN": "是否禁用" + "zh_CN": "组件初始化状态下未选中时,默认按钮显示禁用状态" }, "labelPosition": "left" }, { - "property": "size", + "property": "toRightDisable", "label": { "text": { - "zh_CN": "尺寸" + "zh_CN": "组件初始化状态下未选中时,默认按钮显示禁用状态" } }, - "required": true, + "required": false, "readOnly": false, "disabled": false, - "cols": 12, "widget": { - "component": "SelectConfigurator", + "component": "CheckBoxConfigurator", + "props": {} + }, + "description": { + "zh_CN": "组件初始化状态下未选中时,默认按钮显示禁用状态" + }, + "labelPosition": "left" + }, + { + "property": "titles", + "label": { + "text": { + "zh_CN": "自定义列表的标题" + } + }, + "required": false, + "readOnly": false, + "disabled": false, + "widget": { + "component": "CodeConfigurator", "props": { - "options": [ - { - "label": "medium", - "value": "medium" - }, - { - "label": "small", - "value": "small" - }, - { - "label": "mini", - "value": "mini" - } - ] + "language": "json" + } + }, + "description": { + "zh_CN": "自定义列表的标题;不设置titles时,左右列表的标题默认显示为: 列表 1, 列表 2" + }, + "labelPosition": "left" + } + ] + } + ], + "events": { + "onChange": { + "label": { + "zh_CN": "右侧列表元素变化时触发" + }, + "description": { + "zh_CN": "右侧列表元素变化时触发" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "value", + "type": "string", + "defaultValue": "", + "description": { + "zh_CN": "右侧列表元素变化时触发" + } + } + ], + "returns": {} + }, + "defaultValue": "" + }, + "onLeftCheckChange": { + "label": { + "zh_CN": "左侧列表元素被用户选中 / 取消选中时触发;" + }, + "description": { + "zh_CN": "左侧列表元素被用户选中 / 取消选中时触发;" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "value", + "type": "string", + "defaultValue": "", + "description": { + "zh_CN": "左侧列表元素被用户选中 / 取消选中时触发;" + } + } + ], + "returns": {} + }, + "defaultValue": "" + }, + "onRightCheckChange": { + "label": { + "zh_CN": "右侧列表元素被用户选中 / 取消选中时触发" + }, + "description": { + "zh_CN": "右侧列表元素被用户选中 / 取消选中时触发" + }, + "type": "event", + "functionInfo": { + "params": [ + { + "name": "value", + "type": "string", + "defaultValue": "", + "description": { + "zh_CN": "右侧列表元素被用户选中 / 取消选中时触发" + } + } + ], + "returns": {} + }, + "defaultValue": "" + } + } + }, + "configure": { + "loop": true, + "condition": true, + "styles": true, + "isContainer": false, + "isModal": false, + "nestingRule": { + "childWhitelist": "", + "parentWhitelist": "", + "descendantBlacklist": "", + "ancestorWhitelist": "" + }, + "isNullNode": false, + "isLayout": false, + "rootSelector": "", + "shortcuts": { + "properties": [ + "value", + "disabled" + ] + }, + "contextMenu": { + "actions": [ + "create symbol" + ], + "disable": [ + "copy", + "remove" + ] + } + } + } + ], + "blocks": [], + "snippets": [ + { + "group": "layout", + "label": { + "zh_CN": "布局与容器" + }, + "children": [ + { + "name": { + "zh_CN": "栅格布局" + }, + "icon": "row", + "screenshot": "", + "snippetName": "TinyLayout", + "schema": { + "componentName": "TinyLayout", + "props": {}, + "children": [ + { + "componentName": "TinyRow", + "props": { + "style": "padding: 10px;" + }, + "children": [ + { + "componentName": "TinyCol", + "props": { + "span": 3 + } + }, + { + "componentName": "TinyCol", + "props": { + "span": 3 + } + }, + { + "componentName": "TinyCol", + "props": { + "span": 3 + } + }, + { + "componentName": "TinyCol", + "props": { + "span": 3 + } } - }, - "description": { - "zh_CN": "输入框尺寸。该属性的可选值为 medium / small / mini" - }, - "labelPosition": "left" + ] }, { - "property": "controls", - "label": { - "text": { - "zh_CN": "加减按钮" - } - }, - "required": false, - "readOnly": false, - "disabled": false, - "cols": 12, - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - }, - "description": { - "zh_CN": "是否使用加减按钮" + "componentName": "TinyRow", + "props": { + "style": "padding: 10px;" }, - "labelPosition": "left" + "children": [ + { + "componentName": "TinyCol", + "props": { + "span": 3 + } + }, + { + "componentName": "TinyCol", + "props": { + "span": 3 + } + }, + { + "componentName": "TinyCol", + "props": { + "span": 3 + } + }, + { + "componentName": "TinyCol", + "props": { + "span": 3 + } + } + ] + } + ] + } + } + ] + }, + { + "group": "basic", + "label": { + "zh_CN": "基础元素" + }, + "children": [ + { + "name": { + "zh_CN": "段落" + }, + "icon": "paragraph", + "screenshot": "", + "snippetName": "p", + "schema": { + "componentName": "p", + "children": "TinyEngine 前端可视化设计器致力于通过友好的用户交互提升业务应用的开发效率。" + } + }, + { + "name": { + "zh_CN": "链接" + }, + "icon": "link", + "screenshot": "", + "snippetName": "a", + "schema": { + "componentName": "a", + "children": "链接" + } + }, + { + "name": { + "zh_CN": "分隔线" + }, + "icon": "hr", + "screenshot": "", + "snippetName": "hr", + "schema": {} + }, + { + "name": { + "zh_CN": "标题" + }, + "icon": "h16", + "screenshot": "", + "snippetName": "h1", + "schema": { + "componentName": "h1", + "props": {}, + "children": "Heading" + } + }, + { + "name": { + "zh_CN": "视频" + }, + "icon": "video", + "screenshot": "", + "snippetName": "video", + "schema": { + "componentName": "video", + "props": { + "src": "https://tinyengine-assets.obs.myhuaweicloud.com/files/in-action.mp4#t=1.5", + "width": "200", + "height": "100", + "style": "border:1px solid #ccc" + } + } + }, + { + "name": { + "zh_CN": "按钮" + }, + "icon": "button", + "screenshot": "", + "snippetName": "TinyButton", + "schema": { + "componentName": "TinyButton", + "props": { + "text": "按钮文案" + } + } + }, + { + "name": { + "zh_CN": "按钮组" + }, + "icon": "buttons", + "snippetName": "TinyButtons", + "screenshot": "", + "schema": { + "componentName": "div", + "props": {}, + "children": [ + { + "componentName": "TinyButton", + "props": { + "text": "提交", + "type": "primary", + "style": "margin: 0 5px 0 5px;" + } }, { - "property": "controls-position", - "label": { - "text": { - "zh_CN": "加减按钮位置" - } + "componentName": "TinyButton", + "props": { + "text": "重置", + "style": "margin: 0 5px 0 5px;" + } + }, + { + "componentName": "TinyButton", + "props": { + "text": "取消" + } + } + ] + }, + "configure": { + "isContainer": true + } + }, + { + "name": { + "zh_CN": "互斥按钮组" + }, + "icon": "MutexButtons", + "snippetName": "TinyButtonGroup", + "screenshot": "", + "schema": { + "componentName": "TinyButtonGroup", + "props": { + "data": [ + { + "text": "Button1", + "value": "1" }, - "required": false, - "readOnly": false, - "disabled": false, - "cols": 12, - "widget": { - "component": "SelectConfigurator", - "props": { - "options": [ - { - "label": "左右两侧", - "value": "" - }, - { - "label": "只在右侧", - "value": "right" - } - ] - } + { + "text": "Button2", + "value": "2" }, - "description": { - "zh_CN": "加减按钮位置" + { + "text": "Button3", + "value": "3" } - }, + ], + "modelValue": "1" + } + } + }, + { + "name": { + "zh_CN": "搜索框" + }, + "icon": "search", + "screenshot": "", + "snippetName": "TinySearch", + "schema": { + "componentName": "TinySearch", + "props": { + "modelValue": "", + "placeholder": "输入关键词" + } + } + } + ] + }, + { + "group": "form", + "label": { + "zh_CN": "表单类型" + }, + "children": [ + { + "name": { + "zh_CN": "表单" + }, + "screenshot": "", + "snippetName": "TinyForm", + "icon": "form", + "schema": { + "componentName": "TinyForm", + "props": { + "labelWidth": "80px", + "labelPosition": "top" + }, + "children": [ { - "property": "precision", - "label": { - "text": { - "zh_CN": "精度" - } + "componentName": "TinyFormItem", + "props": { + "label": "人员" }, - "required": false, - "readOnly": false, - "disabled": false, - "cols": 12, - "widget": { - "component": "NumberConfigurator", - "props": { - "allowEmpty": true + "children": [ + { + "componentName": "TinyInput", + "props": { + "placeholder": "请输入", + "modelValue": "" + } } - }, - "description": { - "zh_CN": "数值精度" - }, - "labelPosition": "left" + ] }, { - "property": "step", - "label": { - "text": { - "zh_CN": "步长" - } + "componentName": "TinyFormItem", + "props": { + "label": "密码" }, - "required": false, - "readOnly": false, - "disabled": false, - "cols": 12, - "widget": { - "component": "NumberConfigurator", - "props": { - "allowEmpty": true + "children": [ + { + "componentName": "TinyInput", + "props": { + "placeholder": "请输入", + "modelValue": "", + "type": "password" + } } - }, - "description": { - "zh_CN": "步长" - }, - "labelPosition": "left" + ] }, { - "property": "max", - "label": { - "text": { - "zh_CN": "最大数值" - } + "componentName": "TinyFormItem", + "props": { + "label": "" }, - "required": false, - "readOnly": false, - "disabled": false, - "cols": 12, - "widget": { - "component": "NumberConfigurator", - "props": { - "allowEmpty": true + "children": [ + { + "componentName": "TinyButton", + "props": { + "text": "提交", + "type": "primary", + "style": "margin-right: 10px" + } + }, + { + "componentName": "TinyButton", + "props": { + "text": "重置", + "type": "primary" + } } + ] + } + ] + } + }, + { + "name": { + "zh_CN": "下拉框" + }, + "icon": "select", + "screenshot": "", + "snippetName": "TinySelect", + "schema": { + "componentName": "TinySelect", + "props": { + "modelValue": "", + "placeholder": "请选择", + "options": [ + { + "value": "1", + "label": "黄金糕" }, - "description": { - "zh_CN": "可输入的最大数值" + { + "value": "2", + "label": "双皮奶" + } + ] + } + } + }, + { + "name": { + "zh_CN": "开关" + }, + "icon": "switch", + "screenshot": "", + "snippetName": "TinySwitch", + "schema": { + "componentName": "TinySwitch", + "props": { + "modelValue": "" + } + } + }, + { + "name": { + "zh_CN": "复选框组" + }, + "icon": "checkboxs", + "screenshot": "", + "snippetName": "TinyCheckboxGroup", + "schema": { + "componentName": "TinyCheckboxGroup", + "props": { + "modelValue": [ + "name1", + "name2" + ], + "type": "checkbox", + "options": [ + { + "text": "复选框1", + "label": "name1" }, - "labelPosition": "left" - }, + { + "text": "复选框2", + "label": "name2" + }, + { + "text": "复选框3", + "label": "name3" + } + ] + } + } + }, + { + "name": { + "zh_CN": "复选框拖拽按钮组" + }, + "icon": "checkboxgroup", + "screenshot": "", + "snippetName": "TinyCheckboxbuttonGroup", + "schema": { + "componentName": "TinyCheckboxGroup", + "props": { + "modelValue": [] + }, + "children": [ { - "property": "min", - "label": { - "text": { - "zh_CN": "最小数值" + "componentName": "TinyCheckboxButton", + "children": [ + { + "componentName": "div" } + ] + } + ] + } + }, + { + "name": { + "zh_CN": "输入框" + }, + "icon": "input", + "screenshot": "", + "snippetName": "TinyInput", + "schema": { + "componentName": "TinyInput", + "props": { + "placeholder": "请输入", + "modelValue": "" + } + } + }, + { + "name": { + "zh_CN": "单选" + }, + "icon": "radio", + "screenshot": "", + "snippetName": "TinyRadio", + "schema": { + "componentName": "TinyRadio", + "props": { + "label": "1", + "text": "单选文本" + } + } + }, + { + "name": { + "zh_CN": "单选组" + }, + "icon": "radiogroup", + "screenshot": "", + "snippetName": "TinyRadioGroup", + "schema": { + "props": { + "type": "radio", + "modelValue": "1", + "options": [ + { "label": "1", "text": "选项一" }, + { "label": "2", "text": "选项二" } + ] + } + } + }, + { + "name": { + "zh_CN": "复选框" + }, + "icon": "checkbox", + "screenshot": "", + "snippetName": "TinyCheckbox", + "schema": { + "componentName": "TinyCheckbox", + "props": { + "text": "复选框文案" + } + } + }, + { + "name": { + "zh_CN": "日期选择" + }, + "icon": "datepick", + "screenshot": "", + "snippetName": "TinyDatePicker", + "schema": { + "componentName": "TinyDatePicker", + "props": { + "placeholder": "请输入", + "modelValue": "" + } + } + }, + { + "name": { + "zh_CN": "数字输入框" + }, + "icon": "numeric", + "screenshot": "", + "snippetName": "TinyNumeric", + "schema": { + "componentName": "TinyNumeric", + "props": { + "allow-empty": true, + "placeholder": "请输入", + "controls-position": "right", + "step": 1 + } + } + }, + { + "name": { + "zh_CN": "穿梭框" + }, + "icon": "transfer", + "screenshot": "", + "snippetName": "TinyTransfer", + "schema": { + "componentName": "TinyTransfer", + "props": { + "modelValue": [ + 3 + ], + "data": [ + { + "key": 1, + "label": "备选项1", + "disabled": false }, - "required": false, - "readOnly": false, - "disabled": false, - "cols": 12, - "widget": { - "component": "NumberConfigurator", - "props": { - "allowEmpty": true - } + { + "key": 2, + "label": "备选项2", + "disabled": false }, - "description": { - "zh_CN": "可输入的最大数值" + { + "key": 3, + "label": "备选项3", + "disabled": false }, - "labelPosition": "left" - } - ] - } - ], - "events": { - "onChange": { - "label": { - "zh_CN": "值改变时触发" - }, - "description": { - "zh_CN": "在 Input 值改变时触发" - }, - "type": "event", - "functionInfo": { - "params": [ { - "name": "value", - "type": "string", - "defaultValue": "", - "description": { - "zh_CN": "输入框改变后的值" - } + "key": 4, + "label": "备选项4", + "disabled": false } - ], - "returns": {} - }, - "defaultValue": "" + ] + } + } + }, + { + "icon": "rate", + "name": { + "zh_CN": "评分" }, - "onInput": { - "label": { - "zh_CN": "输入值改变时触发" - }, - "description": { - "zh_CN": "在 Input 输入值改变时触发" - }, - "type": "event", - "functionInfo": { - "params": [ - { - "name": "value", - "type": "string", - "defaultValue": "", - "description": { - "zh_CN": "输入框输入的值" - } - } - ], - "returns": {} - }, - "defaultValue": "" + "schema": { + "props": { + "allow-half": true, + "modelValue": 3, + "show-score": true + } }, - "onUpdate:modelValue": { - "label": { - "zh_CN": "双向绑定的值改变时触发" - }, - "description": { - "zh_CN": "在 Input 输入值改变时触发" - }, - "type": "event", - "functionInfo": { - "params": [ - { - "name": "value", - "type": "string", - "defaultValue": "", - "description": { - "zh_CN": "双向绑定的值" - } - } - ], - "returns": {} - }, - "defaultValue": "" + "screenshot": "", + "snippetName": "TinyRate" + }, + { + "name": { + "zh_CN": "滑块" }, - "onBlur": { - "label": { - "zh_CN": "失去焦点时触发" - }, - "description": { - "zh_CN": "在 Input 失去焦点时触发" - }, - "type": "event", - "functionInfo": { - "params": [ - { - "name": "event", - "type": "Object", - "defaultValue": "", - "description": { - "zh_CN": "原生 event" - } - } - ], - "returns": {} - }, - "defaultValue": "" + "icon": "slider", + "screenshot": "", + "snippetName": "TinySlider", + "schema": { + "componentName": "TinySlider", + "props": { + "max": 100, + "min": 0, + "step": 1, + "modelValue": 50 + } + } + }, + { + "name": { + "zh_CN": "级联选择器" }, - "onFocus": { - "label": { - "zh_CN": "获取焦点时触发" - }, - "description": { - "zh_CN": "在 Input 获取焦点时触发" - }, - "type": "event", - "functionInfo": { - "params": [ + "icon": "cascader", + "screenshot": "", + "snippetName": "TinyCascader", + "schema": { + "componentName": "TinyCascader", + "props": { + "modelValue": "anzhuangcli", + "options": [ { - "name": "event", - "type": "Object", - "defaultValue": "", - "description": { - "zh_CN": "原生 event" - } + "value": "zhinan", + "label": "指南", + "children": [ + { + "value": "anzhuang", + "label": "安装", + "children": [ + { + "value": "xiangmudengji", + "label": "项目登记" + }, + { + "value": "huanjingzhunbei", + "label": "环境准备" + }, + { + "value": "anzhuangcli", + "label": "安装 CLI" + }, + { + "value": "chuangjianxiangmu", + "label": "创建项目" + } + ] + }, + { + "value": "kaifa", + "label": "开发", + "children": [ + { + "value": "yinruzujian", + "label": "引入组件" + }, + { + "value": "monishuju", + "label": "模拟数据" + } + ] + } + ] + }, + { + "value": "zujian", + "label": "组件", + "children": [ + { + "value": "basic", + "label": "框架风格", + "children": [ + { + "value": "layout", + "label": "Layout 布局" + }, + { + "value": "color", + "label": "Color 色彩" + }, + { + "value": "font", + "label": "Font 字体" + }, + { + "value": "icon", + "label": "Icon 图标" + } + ] + }, + { + "value": "data", + "label": "数据组件", + "children": [ + { + "value": "tree", + "label": "Tree 树形控件" + }, + { + "value": "pager", + "label": "Pager 分页" + } + ] + } + ] } ], - "returns": {} - }, - "defaultValue": "" - }, - "onClear": { - "label": { - "zh_CN": "点击清空按钮时触发" - }, - "description": { - "zh_CN": "点击清空按钮时触发" - }, - "type": "event", - "functionInfo": { - "params": [], - "returns": {} - }, - "defaultValue": "" + "placeholder": "请选择" + } } } - }, - "configure": { - "loop": true, - "condition": true, - "styles": true, - "isContainer": true, - "isModal": false, - "nestingRule": { - "childWhitelist": "", - "parentWhitelist": "", - "descendantBlacklist": "", - "ancestorWhitelist": "" - }, - "isNullNode": false, - "isLayout": false, - "rootSelector": "", - "shortcuts": { - "properties": ["value", "disabled"] - }, - "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] - } - } + ] }, { - "version": "3.20.0", - "name": { - "zh_CN": "穿梭框" - }, - "component": "TinyTransfer", - "icon": "transfer", - "description": "穿梭框,实现左右表格数据的双向交换的组件", - "docUrl": "", - "screenshot": "", - "tags": "", - "keywords": "", - "devMode": "proCode", - "npm": { - "package": "@opentiny/vue", - "exportName": "TinyTransfer", - "destructuring": true + "group": "table", + "label": { + "zh_CN": "表格类型" }, - "group": "component", - "priority": 1, - "schema": { - "properties": [ - { - "label": { - "zh_CN": "基础信息" - }, - "description": { - "zh_CN": "基础信息" - }, - "content": [ - { - "property": "modelValue", - "label": { - "text": { - "zh_CN": "绑定值" - } - }, - "required": true, - "readOnly": false, - "disabled": false, - "widget": { - "component": "I18nConfigurator", - "props": {} - }, - "description": { - "zh_CN": "双向绑定值" - }, - "labelPosition": "left" - }, - { - "property": "data", - "label": { - "text": { - "zh_CN": "左右列表的全量数据源" - } - }, - "required": true, - "readOnly": false, - "disabled": false, - "widget": { - "component": "CodeConfigurator", - "props": { - "language": "json" - } - }, - "description": { - "zh_CN": "左右列表的全量数据源" - }, - "labelPosition": "left" - }, - { - "property": "filterable", - "label": { - "text": { - "zh_CN": "是否启用搜索的功能" - } - }, - "required": false, - "readOnly": false, - "disabled": false, - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - }, - "description": { - "zh_CN": "是否启用搜索的功能" - }, - "labelPosition": "left" - }, - { - "property": "showAllBtn", - "label": { - "text": { - "zh_CN": "是否显示全部移动按钮" - } - }, - "required": false, - "readOnly": false, - "disabled": false, - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - }, - "description": { - "zh_CN": "是否显示全部移动按钮" - }, - "labelPosition": "left" - }, - { - "property": "toLeftDisable", - "label": { - "text": { - "zh_CN": "组件初始化状态下未选中时,默认按钮显示禁用状态" - } - }, - "required": false, - "readOnly": false, - "disabled": false, - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - }, - "description": { - "zh_CN": "组件初始化状态下未选中时,默认按钮显示禁用状态" - }, - "labelPosition": "left" + "children": [ + { + "name": { + "zh_CN": "表格" + }, + "icon": "grid", + "screenshot": "", + "snippetName": "TinyGrid", + "schema": { + "componentName": "TinyGrid", + "props": { + "editConfig": { + "trigger": "click", + "mode": "cell", + "showStatus": true }, - { - "property": "toRightDisable", - "label": { - "text": { - "zh_CN": "组件初始化状态下未选中时,默认按钮显示禁用状态" - } - }, - "required": false, - "readOnly": false, - "disabled": false, - "widget": { - "component": "CheckBoxConfigurator", - "props": {} - }, - "description": { - "zh_CN": "组件初始化状态下未选中时,默认按钮显示禁用状态" + "columns": [ + { + "type": "index", + "width": 60 }, - "labelPosition": "left" - }, - { - "property": "titles", - "label": { - "text": { - "zh_CN": "自定义列表的标题" - } + { + "type": "selection", + "width": 60 }, - "required": false, - "readOnly": false, - "disabled": false, - "widget": { - "component": "CodeConfigurator", - "props": { - "language": "json" - } + { + "field": "employees", + "title": "员工数" }, - "description": { - "zh_CN": "自定义列表的标题;不设置titles时,左右列表的标题默认显示为: 列表 1, 列表 2" + { + "field": "created_date", + "title": "创建日期" }, - "labelPosition": "left" - } - ] - } - ], - "events": { - "onChange": { - "label": { - "zh_CN": "右侧列表元素变化时触发" - }, - "description": { - "zh_CN": "右侧列表元素变化时触发" - }, - "type": "event", - "functionInfo": { - "params": [ { - "name": "value", - "type": "string", - "defaultValue": "", - "description": { - "zh_CN": "右侧列表元素变化时触发" - } + "field": "city", + "title": "城市" } ], - "returns": {} - }, - "defaultValue": "" - }, - "onLeftCheckChange": { - "label": { - "zh_CN": "左侧列表元素被用户选中 / 取消选中时触发;" - }, - "description": { - "zh_CN": "左侧列表元素被用户选中 / 取消选中时触发;" - }, - "type": "event", - "functionInfo": { - "params": [ + "data": [ { - "name": "value", - "type": "string", - "defaultValue": "", - "description": { - "zh_CN": "左侧列表元素被用户选中 / 取消选中时触发;" - } - } - ], - "returns": {} - }, - "defaultValue": "" - }, - "onRightCheckChange": { - "label": { - "zh_CN": "右侧列表元素被用户选中 / 取消选中时触发" - }, - "description": { - "zh_CN": "右侧列表元素被用户选中 / 取消选中时触发" - }, - "type": "event", - "functionInfo": { - "params": [ + "id": "1", + "name": "GFD科技有限公司", + "city": "福州", + "employees": 800, + "created_date": "2014-04-30 00:56:00", + "boole": false + }, { - "name": "value", - "type": "string", - "defaultValue": "", - "description": { - "zh_CN": "右侧列表元素被用户选中 / 取消选中时触发" - } + "id": "2", + "name": "WWW科技有限公司", + "city": "深圳", + "employees": 300, + "created_date": "2016-07-08 12:36:22", + "boole": true } - ], - "returns": {} - }, - "defaultValue": "" + ] + } } - } - }, - "configure": { - "loop": true, - "condition": true, - "styles": true, - "isContainer": false, - "isModal": false, - "nestingRule": { - "childWhitelist": "", - "parentWhitelist": "", - "descendantBlacklist": "", - "ancestorWhitelist": "" - }, - "isNullNode": false, - "isLayout": false, - "rootSelector": "", - "shortcuts": { - "properties": ["value", "disabled"] }, - "contextMenu": { - "actions": ["create symbol"], - "disable": ["copy", "remove"] + { + "name": { + "zh_CN": "分页" + }, + "icon": "pager", + "screenshot": "", + "snippetName": "TinyPager", + "schema": { + "componentName": "TinyPager", + "props": { + "layout": "total, sizes, prev, pager, next", + "total": 100, + "pageSize": 10, + "currentPage": 1 + } + } } - } - } - ], - "blocks": [], - "snippets": [ + ] + }, { - "group": "layout", + "group": "data-display", "label": { - "zh_CN": "布局与容器" + "zh_CN": "数据展示类" }, "children": [ { "name": { - "zh_CN": "栅格布局" + "zh_CN": "走马灯" }, - "icon": "row", "screenshot": "", - "snippetName": "TinyLayout", + "snippetName": "TinyCarousel", + "icon": "carousel", "schema": { - "componentName": "TinyLayout", - "props": {}, + "componentName": "TinyCarousel", + "props": { + "height": "180px" + }, "children": [ { - "componentName": "TinyRow", + "componentName": "TinyCarouselItem", "props": { - "style": "padding: 10px;" + "title": "carousel-item-a" }, "children": [ { - "componentName": "TinyCol", - "props": { - "span": 3 - } - }, - { - "componentName": "TinyCol", - "props": { - "span": 3 - } - }, - { - "componentName": "TinyCol", - "props": { - "span": 3 - } - }, - { - "componentName": "TinyCol", + "componentName": "div", "props": { - "span": 3 + "style": "margin:10px 0 0 30px" } } ] }, { - "componentName": "TinyRow", + "componentName": "TinyCarouselItem", "props": { - "style": "padding: 10px;" + "title": "carousel-item-b" }, "children": [ { - "componentName": "TinyCol", - "props": { - "span": 3 - } - }, - { - "componentName": "TinyCol", - "props": { - "span": 3 - } - }, - { - "componentName": "TinyCol", - "props": { - "span": 3 - } - }, - { - "componentName": "TinyCol", + "componentName": "div", "props": { - "span": 3 - } - } - ] - } - ] - } - } - ] - }, - { - "group": "basic", - "label": { - "zh_CN": "基础元素" - }, - "children": [ - { - "name": { - "zh_CN": "段落" - }, - "icon": "paragraph", - "screenshot": "", - "snippetName": "p", - "schema": { - "componentName": "p", - "children": "TinyEngine 前端可视化设计器致力于通过友好的用户交互提升业务应用的开发效率。" - } - }, - { - "name": { - "zh_CN": "链接" - }, - "icon": "link", - "screenshot": "", - "snippetName": "a", - "schema": { - "componentName": "a", - "children": "链接" - } - }, - { - "name": { - "zh_CN": "分隔线" - }, - "icon": "hr", - "screenshot": "", - "snippetName": "hr", - "schema": {} - }, - { - "name": { - "zh_CN": "标题" - }, - "icon": "h16", - "screenshot": "", - "snippetName": "h1", - "schema": { - "componentName": "h1", - "props": {}, - "children": "Heading" - } - }, - { - "name": { - "zh_CN": "视频" - }, - "icon": "video", - "screenshot": "", - "snippetName": "video", - "schema": { - "componentName": "video", - "props": { - "src": "https://tinyengine-assets.obs.myhuaweicloud.com/files/in-action.mp4#t=1.5", - "width": "200", - "height": "100", - "style": "border:1px solid #ccc" - } + "style": "margin:10px 0 0 30px" + } + } + ] + } + ] } }, { "name": { - "zh_CN": "按钮" + "zh_CN": "对话框" }, - "icon": "button", "screenshot": "", - "snippetName": "TinyButton", + "snippetName": "TinyDialogBox", + "icon": "dialogbox", "schema": { - "componentName": "TinyButton", + "componentName": "TinyDialogBox", "props": { - "text": "按钮文案" - } + "visible": true, + "show-close": true, + "title": "dialogBox title" + }, + "children": [ + { + "componentName": "div" + } + ] } }, { "name": { - "zh_CN": "按钮组" + "zh_CN": "折叠面板" }, - "icon": "buttons", - "snippetName": "TinyButtons", "screenshot": "", + "snippetName": "TinyCollapse", + "icon": "collapse", "schema": { - "componentName": "div", - "props": {}, + "componentName": "TinyCollapse", + "props": { + "modelValue": "collapse1" + }, "children": [ { - "componentName": "TinyButton", + "componentName": "TinyCollapseItem", "props": { - "text": "提交", - "type": "primary", - "style": "margin: 0 5px 0 5px;" - } + "name": "collapse1", + "title": "折叠项1" + }, + "children": [ + { + "componentName": "div" + } + ] }, { - "componentName": "TinyButton", + "componentName": "TinyCollapseItem", "props": { - "text": "重置", - "style": "margin: 0 5px 0 5px;" - } + "name": "collapse2", + "title": "折叠项2" + }, + "children": [ + { + "componentName": "div" + } + ] }, { - "componentName": "TinyButton", + "componentName": "TinyCollapseItem", "props": { - "text": "取消" - } + "name": "collapse3", + "title": "折叠项3" + }, + "children": [ + { + "componentName": "div" + } + ] } ] + } + }, + { + "name": { + "zh_CN": "弹出编辑" }, - "configure": { - "isContainer": true + "icon": "popeditor", + "screenshot": "", + "snippetName": "TinyPopeditor", + "schema": { + "componentName": "TinyPopeditor", + "props": { + "modelValue": "", + "placeholder": "请选择", + "grid-op": { + "columns": [ + { + "field": "id", + "title": "ID", + "width": 40 + }, + { + "field": "name", + "title": "名称", + "showOverflow": "tooltip" + }, + { + "field": "province", + "title": "省份", + "width": 80 + }, + { + "field": "city", + "title": "城市", + "width": 80 + } + ], + "data": [ + { + "id": "1", + "name": "GFD科技有限公司GFD科技有限公司GFD科技有限公司GFD科技有限公司GFD科技有限公司GFD科技有限公司GFD科技有限公司", + "city": "福州", + "province": "福建" + }, + { + "id": "2", + "name": "WWW科技有限公司", + "city": "深圳", + "province": "广东" + }, + { + "id": "3", + "name": "RFV有限责任公司", + "city": "中山", + "province": "广东" + }, + { + "id": "4", + "name": "TGB科技有限公司", + "city": "龙岩", + "province": "福建" + }, + { + "id": "5", + "name": "YHN科技有限公司", + "city": "韶关", + "province": "广东" + }, + { + "id": "6", + "name": "WSX科技有限公司", + "city": "黄冈", + "province": "武汉" + } + ] + } + } } }, { "name": { - "zh_CN": "互斥按钮组" + "zh_CN": "树" }, - "icon": "MutexButtons", - "snippetName": "TinyButtonGroup", + "icon": "tree", "screenshot": "", + "snippetName": "TinyTree", "schema": { - "componentName": "TinyButtonGroup", + "componentName": "TinyTree", "props": { "data": [ { - "text": "Button1", - "value": "1" - }, - { - "text": "Button2", - "value": "2" + "label": "一级 1", + "children": [ + { + "label": "二级 1-1", + "children": [ + { + "label": "三级 1-1-1" + } + ] + } + ] }, { - "text": "Button3", - "value": "3" + "label": "一级 2", + "children": [ + { + "label": "二级 2-1", + "children": [ + { + "label": "三级 2-1-1" + } + ] + }, + { + "label": "二级 2-2", + "children": [ + { + "label": "三级 2-2-1" + } + ] + } + ] } - ], - "modelValue": "1" + ] } } }, { "name": { - "zh_CN": "搜索框" + "zh_CN": "文字提示框" }, - "icon": "search", + "icon": "tooltip", "screenshot": "", - "snippetName": "TinySearch", + "snippetName": "TinyTooltip", "schema": { - "componentName": "TinySearch", + "componentName": "TinyTooltip", "props": { - "modelValue": "", - "placeholder": "输入关键词" - } - } - } - ] - }, - { - "group": "form", - "label": { - "zh_CN": "表单类型" - }, - "children": [ + "content": "Top Left 提示文字", + "placement": "top-start", + "manual": true, + "modelValue": true + }, + "children": [ + { + "componentName": "span", + "children": [ + { + "componentName": "div", + "props": {} + } + ] + }, + { + "componentName": "Template", + "props": { + "slot": "content" + }, + "children": [ + { + "componentName": "span", + "children": [ + { + "componentName": "div", + "props": { + "placeholder": "提示内容" + } + } + ] + } + ] + } + ] + } + }, { "name": { - "zh_CN": "表单" + "zh_CN": "提示框" }, + "icon": "popover", "screenshot": "", - "snippetName": "tiny-form", - "icon": "form", + "snippetName": "TinyPopover", "schema": { - "componentName": "TinyForm", + "componentName": "TinyPopover", "props": { - "labelWidth": "80px", - "labelPosition": "top" + "width": 200, + "title": "弹框标题", + "trigger": "manual", + "modelValue": true }, "children": [ { - "componentName": "TinyFormItem", - "props": { - "label": "人员" - }, - "children": [ - { - "componentName": "TinyInput", - "props": { - "placeholder": "请输入", - "modelValue": "" - } - } - ] - }, - { - "componentName": "TinyFormItem", + "componentName": "Template", "props": { - "label": "密码" + "slot": "reference" }, "children": [ { - "componentName": "TinyInput", + "componentName": "div", "props": { - "placeholder": "请输入", - "modelValue": "", - "type": "password" + "placeholder": "触发源" } } ] }, { - "componentName": "TinyFormItem", + "componentName": "Template", "props": { - "label": "" + "slot": "default" }, "children": [ { - "componentName": "TinyButton", - "props": { - "text": "提交", - "type": "primary", - "style": "margin-right: 10px" - } - }, - { - "componentName": "TinyButton", + "componentName": "div", "props": { - "text": "重置", - "type": "primary" + "placeholder": "提示内容" } } ] @@ -14002,269 +22125,155 @@ }, { "name": { - "zh_CN": "下拉框" - }, - "icon": "select", - "screenshot": "", - "snippetName": "TinySelect", - "schema": { - "componentName": "TinySelect", - "props": { - "modelValue": "", - "placeholder": "请选择", - "options": [ - { - "value": "1", - "label": "黄金糕" - }, - { - "value": "2", - "label": "双皮奶" - } - ] - } - } - }, - { - "name": { - "zh_CN": "开关" - }, - "icon": "switch", - "screenshot": "", - "snippetName": "TinySwitch", - "schema": { - "componentName": "TinySwitch", - "props": { - "modelValue": "" - } - } - }, - { - "name": { - "zh_CN": "复选框组" + "zh_CN": "骨架屏" }, - "icon": "checkboxs", + "icon": "skeleton", "screenshot": "", - "snippetName": "TinyCheckboxGroup", + "snippetName": "TinySkeleton", "schema": { - "componentName": "TinyCheckboxGroup", + "componentName": "TinySkeleton", "props": { - "modelValue": ["name1", "name2"], - "type": "checkbox", - "options": [ - { - "text": "复选框1", - "label": "name1" - }, - { - "text": "复选框2", - "label": "name2" + "rows": 3, + "loading": true, + "animated": true + }, + "children": [ + { + "props": { + "text": "实际内容" }, - { - "text": "复选框3", - "label": "name3" - } - ] - } + "componentName": "Text" + } + ] } }, { "name": { - "zh_CN": "复选框拖拽按钮组" + "zh_CN": "卡片" }, - "icon": "checkboxgroup", + "icon": "card", "screenshot": "", - "snippetName": "TinyCheckboxbuttonGroup", + "snippetName": "TinyCard", "schema": { - "componentName": "TinyCheckboxGroup", + "componentName": "TinyCard", "props": { - "modelValue": [] + "type": "text", + "title": "卡片标题" }, "children": [ { - "componentName": "TinyCheckboxButton", - "children": [ - { - "componentName": "div" - } - ] + "props": { + "text": "这是一个文本卡片的示例内容。" + }, + "componentName": "Text" } ] } }, { "name": { - "zh_CN": "输入框" - }, - "icon": "input", - "screenshot": "", - "snippetName": "TinyInput", - "schema": { - "componentName": "TinyInput", - "props": { - "placeholder": "请输入", - "modelValue": "" - } - } - }, - { - "name": { - "zh_CN": "单选" + "zh_CN": "日历" }, - "icon": "radio", + "icon": "calendar", "screenshot": "", - "snippetName": "TinyRadio", + "snippetName": "TinyCalendar", "schema": { - "componentName": "TinyRadio", + "componentName": "TinyCalendar", "props": { - "label": "1", - "text": "单选文本" + "mode": "month", + "show-selected": false } } }, { "name": { - "zh_CN": "复选框" + "zh_CN": "进度条" }, - "icon": "checkbox", + "icon": "progress", "screenshot": "", - "snippetName": "TinyCheckbox", + "snippetName": "TinyProgress", "schema": { - "componentName": "TinyCheckbox", + "componentName": "TinyProgress", "props": { - "text": "复选框文案" + "type": "line", + "status": "success", + "percentage": 50 } } }, { "name": { - "zh_CN": "日期选择" + "zh_CN": "标记" }, - "icon": "datepick", + "icon": "badge", "screenshot": "", - "snippetName": "TinyDatePicker", + "snippetName": "TinyBadge", "schema": { - "componentName": "TinyDatePicker", + "componentName": "TinyBadge", "props": { - "placeholder": "请输入", - "modelValue": "" + "value": 10, + "data": "我的待办" } } }, { "name": { - "zh_CN": "数字输入框" + "zh_CN": "标签" }, - "icon": "numeric", + "icon": "tag", "screenshot": "", - "snippetName": "TinyNumeric", + "snippetName": "TinyTag", "schema": { - "componentName": "TinyNumeric", + "componentName": "TinyTag", "props": { - "allow-empty": true, - "placeholder": "请输入", - "controls-position": "right", - "step": 1 + "type": "success", + "value": "成功" } } }, { "name": { - "zh_CN": "穿梭框" + "zh_CN": "统计数值" }, - "icon": "transfer", + "icon": "statistic", "screenshot": "", - "snippetName": "TinyTransfer", + "snippetName": "TinyStatistic", "schema": { - "componentName": "TinyTransfer", + "componentName": "TinyStatistic", "props": { - "modelValue": [3], - "data": [ - { - "key": 1, - "label": "备选项1", - "disabled": false - }, - { - "key": 2, - "label": "备选项2", - "disabled": false - }, - { - "key": 3, - "label": "备选项3", - "disabled": false - }, - { - "key": 4, - "label": "备选项4", - "disabled": false - } - ] + "value": 36256.22, + "precision": 2 } } } ] }, { - "group": "table", + "group": "navigation", "label": { - "zh_CN": "表格类型" + "zh_CN": "导航类型" }, "children": [ { "name": { - "zh_CN": "表格" + "zh_CN": "时间线" }, - "icon": "grid", + "icon": "timeline", "screenshot": "", - "snippetName": "tinyGrid", + "snippetName": "TinyTimeLine", "schema": { - "componentName": "TinyGrid", + "componentName": "TinyTimeLine", "props": { - "editConfig": { - "trigger": "click", - "mode": "cell", - "showStatus": true - }, - "columns": [ - { - "type": "index", - "width": 60 - }, - { - "type": "selection", - "width": 60 - }, - { - "field": "employees", - "title": "员工数" - }, - { - "field": "created_date", - "title": "创建日期" - }, - { - "field": "city", - "title": "城市" - } - ], + "active": "2", "data": [ { - "id": "1", - "name": "GFD科技有限公司", - "city": "福州", - "employees": 800, - "created_date": "2014-04-30 00:56:00", - "boole": false + "name": "已下单" }, { - "id": "2", - "name": "WWW科技有限公司", - "city": "深圳", - "employees": 300, - "created_date": "2016-07-08 12:36:22", - "boole": true + "name": "运输中" + }, + { + "name": "已签收" } ] } @@ -14272,46 +22281,50 @@ }, { "name": { - "zh_CN": "分页" + "zh_CN": "面包屑" }, - "icon": "pager", + "icon": "breadcrumb", "screenshot": "", - "snippetName": "TinyPager", + "snippetName": "TinyBreadcrumb", "schema": { - "componentName": "TinyPager", + "componentName": "TinyBreadcrumb", "props": { - "layout": "total, sizes, prev, pager, next", - "total": 100, - "pageSize": 10, - "currentPage": 1 + "options": [ + { + "to": "{ path: '/' }", + "label": "首页" + }, + { + "to": "{ path: '/breadcrumb' }", + "label": "产品" + }, + { + "replace": "true", + "label": "软件" + } + ] } } - } - ] - }, - { - "group": "data-display", - "label": { - "zh_CN": "数据展示类" - }, - "children": [ + }, { "name": { - "zh_CN": "走马灯" + "zh_CN": "标签页" }, + "icon": "tabs", "screenshot": "", - "snippetName": "tiny-carousel", - "icon": "carousel", + "group": true, + "snippetName": "TinyTabs", "schema": { - "componentName": "TinyCarousel", + "componentName": "TinyTabs", "props": { - "height": "180px" + "modelValue": "first" }, "children": [ { - "componentName": "TinyCarouselItem", + "componentName": "TinyTabItem", "props": { - "title": "carousel-item-a" + "title": "标签页1", + "name": "first" }, "children": [ { @@ -14323,9 +22336,10 @@ ] }, { - "componentName": "TinyCarouselItem", + "componentName": "TinyTabItem", "props": { - "title": "carousel-item-b" + "title": "标签页2", + "name": "second" }, "children": [ { @@ -14341,402 +22355,730 @@ }, { "name": { - "zh_CN": "对话框" + "zh_CN": "步骤条" }, + "icon": "steps", "screenshot": "", - "snippetName": "TinyDialogBox", - "icon": "dialogbox", + "snippetName": "TinySteps", "schema": { - "componentName": "TinyDialogBox", + "componentName": "TinySteps", "props": { - "visible": true, - "show-close": true, - "title": "dialogBox title" - }, - "children": [ - { - "componentName": "div" - } - ] + "data": [ + { + "name": "步骤一", + "status": "wait" + }, + { + "name": "步骤二", + "status": "process" + }, + { + "name": "步骤三", + "status": "finish" + } + ], + "active": 1 + } } }, { "name": { - "zh_CN": "折叠面板" + "zh_CN": "树形菜单" }, + "icon": "treemenu", "screenshot": "", - "snippetName": "TinyCollapse", - "icon": "collapse", + "snippetName": "TinyTreeMenu", "schema": { - "componentName": "TinyCollapse", + "componentName": "TinyTreeMenu", "props": { - "modelValue": "collapse1" - }, - "children": [ - { - "componentName": "TinyCollapseItem", - "props": { - "name": "collapse1", - "title": "折叠项1" + "data": [ + { + "id": 1, + "label": "一级节点1", + "children": [ + { + "id": 2, + "label": "二级节点1-1" + }, + { + "id": 3, + "label": "二级节点1-2" + } + ] }, - "children": [ - { - "componentName": "div" - } - ] - }, - { - "componentName": "TinyCollapseItem", - "props": { - "name": "collapse2", - "title": "折叠项2" + { + "id": 4, + "label": "一级节点2" + } + ], + "placeholder": "输入关键字搜索", + "node-key": "id" + } + } + } + ] + }, + { + "group": "chart", + "label": { + "zh_CN": "图表类型" + }, + "children": [ + { + "name": { + "zh_CN": "折线图" + }, + "icon": "line", + "screenshot": "", + "snippetName": "TinyHuichartsLine", + "schema": { + "componentName": "TinyHuichartsLine", + "props": { + "options": { + "theme": "hdesign-light", + "padding": [ + 50, + 30, + 50, + 20 + ], + "legend": { + "show": true, + "icon": "line" }, - "children": [ + "data": [ { - "componentName": "div" - } - ] - }, - { - "componentName": "TinyCollapseItem", - "props": { - "name": "collapse3", - "title": "折叠项3" - }, - "children": [ + "Month": "Jan", + "Domestics": 33, + "Abroad": 37 + }, { - "componentName": "div" + "Month": "Feb", + "Domestics": 27, + "Abroad": 39 + }, + { + "Month": "Mar", + "Domestics": 31, + "Abroad": 20 + }, + { + "Month": "Apr", + "Domestics": 30, + "Abroad": 15 + }, + { + "Month": "May", + "Domestics": 37, + "Abroad": 13 + }, + { + "Month": "Jun", + "Domestics": 36, + "Abroad": 17 + }, + { + "Month": "Jul", + "Domestics": 42, + "Abroad": 22 + }, + { + "Month": "Aug", + "Domestics": 22, + "Abroad": 12 + }, + { + "Month": "Sep", + "Domestics": 17, + "Abroad": 30 + }, + { + "Month": "Oct", + "Domestics": 40, + "Abroad": 33 + }, + { + "Month": "Nov", + "Domestics": 42, + "Abroad": 22 + }, + { + "Month": "Dec", + "Domestics": 32, + "Abroad": 11 } - ] + ], + "xAxis": { + "data": "Month" + }, + "yAxis": { + "name": "Percentage(%)" + } } - ] + } } }, { "name": { - "zh_CN": "弹出编辑" + "zh_CN": "柱状图" }, - "icon": "popeditor", + "icon": "histogram", "screenshot": "", - "snippetName": "TinyPopeditor", + "snippetName": "TinyHuichartsHistogram", "schema": { - "componentName": "TinyPopeditor", + "componentName": "TinyHuichartsHistogram", "props": { - "modelValue": "", - "placeholder": "请选择", - "grid-op": { - "columns": [ + "options": { + "theme": "hdesign-light", + "padding": [ + 50, + 30, + 50, + 20 + ], + "data": [ { - "field": "id", - "title": "ID", - "width": 40 + "Month": "Jan", + "Domestic": 33, + "Abroad": 1 }, { - "field": "name", - "title": "名称", - "showOverflow": "tooltip" + "Month": "Feb", + "Domestic": 27, + "Abroad": 39 }, { - "field": "province", - "title": "省份", - "width": 80 + "Month": "Mar", + "Domestic": 31, + "Abroad": 20 }, { - "field": "city", - "title": "城市", - "width": 80 + "Month": "Apr", + "Domestic": 30, + "Abroad": 15 + }, + { + "Month": "May", + "Domestic": 37, + "Abroad": 1 + }, + { + "Month": "Jun", + "Domestic": 36, + "Abroad": 17 + }, + { + "Month": "Jul", + "Domestic": 42, + "Abroad": 22 + }, + { + "Month": "Aug", + "Domestic": 22, + "Abroad": 12 + }, + { + "Month": "Sep", + "Domestic": 17, + "Abroad": 30 + }, + { + "Month": "Oct", + "Domestic": 40, + "Abroad": 33 + }, + { + "Month": "Nov", + "Domestic": 42, + "Abroad": 22 + }, + { + "Month": "Dec", + "Domestic": 32, + "Abroad": 1 } ], + "xAxis": { + "data": "Month" + }, + "yAxis": { + "name": "Percentage(%)" + } + } + } + } + }, + { + "name": { + "zh_CN": "条形图" + }, + "icon": "bar", + "screenshot": "", + "snippetName": "TinyHuichartsBar", + "schema": { + "componentName": "TinyHuichartsBar", + "props": { + "options": { + "theme": "hdesign-light", + "padding": [ + 50, + 30, + 50, + 20 + ], "data": [ { - "id": "1", - "name": "GFD科技有限公司GFD科技有限公司GFD科技有限公司GFD科技有限公司GFD科技有限公司GFD科技有限公司GFD科技有限公司", - "city": "福州", - "province": "福建" + "Month": "Jan", + "Domestic": 33, + "Abroad": 1 }, { - "id": "2", - "name": "WWW科技有限公司", - "city": "深圳", - "province": "广东" + "Month": "Feb", + "Domestic": 27, + "Abroad": 39 }, { - "id": "3", - "name": "RFV有限责任公司", - "city": "中山", - "province": "广东" + "Month": "Mar", + "Domestic": 31, + "Abroad": 20 }, { - "id": "4", - "name": "TGB科技有限公司", - "city": "龙岩", - "province": "福建" + "Month": "Apr", + "Domestic": 30, + "Abroad": 15 }, { - "id": "5", - "name": "YHN科技有限公司", - "city": "韶关", - "province": "广东" + "Month": "May", + "Domestic": 37, + "Abroad": 1 }, { - "id": "6", - "name": "WSX科技有限公司", - "city": "黄冈", - "province": "武汉" + "Month": "Jun", + "Domestic": 36, + "Abroad": 17 + }, + { + "Month": "Jul", + "Domestic": 42, + "Abroad": 22 + }, + { + "Month": "Aug", + "Domestic": 22, + "Abroad": 12 + }, + { + "Month": "Sep", + "Domestic": 17, + "Abroad": 30 + }, + { + "Month": "Oct", + "Domestic": 40, + "Abroad": 33 + }, + { + "Month": "Nov", + "Domestic": 42, + "Abroad": 22 + }, + { + "Month": "Dec", + "Domestic": 32, + "Abroad": 1 } - ] + ], + "xAxis": { + "data": "Month" + }, + "yAxis": { + "name": "Percentage(%)" + }, + "direction": "horizontal" } } } }, { "name": { - "zh_CN": "树" + "zh_CN": "圆盘图" }, - "icon": "tree", + "icon": "pie", "screenshot": "", - "snippetName": "TinyTree", + "snippetName": "TinyHuichartsPie", "schema": { - "componentName": "TinyTree", + "componentName": "TinyHuichartsPie", "props": { - "data": [ - { - "label": "一级 1", - "children": [ - { - "label": "二级 1-1", - "children": [ - { - "label": "三级 1-1-1" - } - ] - } - ] - }, - { - "label": "一级 2", - "children": [ - { - "label": "二级 2-1", - "children": [ - { - "label": "三级 2-1-1" - } + "options": { + "type": "pie", + "theme": "hdesign-light", + "label": { + "show": true, + "line": true, + "labelHtml": "{a|}{b|{b}:}{c|{d}%}", + "rich": { + "a": { + "width": 12, + "height": 12, + "backgroundColor": { + "image": "./image/charts/pie/ic_jiantou_hong.svg" + } + }, + "b": { + "padding": [ + 2, + 4, + 0, + 0 ] }, - { - "label": "二级 2-2", - "children": [ - { - "label": "三级 2-2-1" - } + "c": { + "fontWeight": "bold", + "padding": [ + 2, + 0, + 0, + 0 ] } - ] - } - ] + } + }, + "data": [ + { + "value": 100, + "name": "VPC" + }, + { + "value": 90, + "name": "IM" + }, + { + "value": 49, + "name": "EIP" + }, + { + "value": 14, + "name": "SG" + } + ] + } } } }, { "name": { - "zh_CN": "文字提示框" + "zh_CN": "环形图" }, - "icon": "tooltip", + "icon": "ring", "screenshot": "", - "snippetName": "TinyTooltip", + "snippetName": "TinyHuichartsRing", "schema": { - "componentName": "TinyTooltip", + "componentName": "TinyHuichartsRing", "props": { - "content": "Top Left 提示文字", - "placement": "top-start", - "manual": true, - "modelValue": true - }, - "children": [ - { - "componentName": "span", - "children": [ + "options": { + "theme": "hdesign-light", + "type": "circle", + "data": [ { - "componentName": "div", - "props": {} - } - ] - }, - { - "componentName": "Template", - "props": { - "slot": "content" - }, - "children": [ + "value": 100, + "name": "VPC" + }, { - "componentName": "span", - "children": [ - { - "componentName": "div", - "props": { - "placeholder": "提示内容" - } - } - ] + "value": 90, + "name": "IM" + }, + { + "value": 49, + "name": "EIP" + }, + { + "value": 14, + "name": "SG" } ] } - ] + } } }, { "name": { - "zh_CN": "提示框" + "zh_CN": "雷达图" }, - "icon": "popover", + "icon": "radar", "screenshot": "", - "snippetName": "TinyPopover", + "snippetName": "TinyHuichartsRadar", "schema": { - "componentName": "TinyPopover", + "componentName": "TinyHuichartsRadar", "props": { - "width": 200, - "title": "弹框标题", - "trigger": "manual", - "modelValue": true - }, - "children": [ - { - "componentName": "Template", - "props": { - "slot": "reference" - }, - "children": [ - { - "componentName": "div", - "props": { - "placeholder": "触发源" - } - } - ] - }, - { - "componentName": "Template", - "props": { - "slot": "default" - }, - "children": [ - { - "componentName": "div", - "props": { - "placeholder": "提示内容" - } + "options": { + "theme": "hdesign-light", + "legend": { + "show": true, + "position": { + "left": "center", + "bottom": 20.1 + } + }, + "radarMax": 100, + "data": { + "Domestic": { + "Equipment": 41, + "VM": 91, + "CSP": 81, + "RD": 51, + "Markets": 71 + }, + "Abroad": { + "Equipment": 72, + "VM": 55, + "CSP": 93, + "RD": 90, + "Markets": 82 } - ] + } } - ] + } } - } - ] - }, - { - "group": "navigation", - "label": { - "zh_CN": "导航类型" - }, - "children": [ + }, { "name": { - "zh_CN": "时间线" + "zh_CN": "瀑布图" }, - "icon": "timeline", + "icon": "waterfall", "screenshot": "", - "snippetName": "TinyTimeLine", + "snippetName": "TinyHuichartsWaterfall", "schema": { - "componentName": "TinyTimeLine", + "componentName": "TinyHuichartsWaterfall", "props": { - "active": "2", - "data": [ - { - "name": "已下单" + "options": { + "padding": [ + 50, + 30, + 20, + 20 + ], + "legend": { + "show": false }, - { - "name": "运输中" + "type": "water-fall", + "data": [ + { + "Name": "NLE", + "User": 10 + }, + { + "Name": "HIN", + "User": 20 + }, + { + "Name": "FBP", + "User": 9 + }, + { + "Name": "VEDIO", + "User": 35 + }, + { + "Name": "SASS", + "User": 20 + }, + { + "Name": "RDS", + "User": 35 + }, + { + "Name": "E-SYS", + "User": 9 + } + ], + "xAxis": { + "data": "Name" }, - { - "name": "已签收" + "yAxis": { + "name": "Number" } - ] + } } } }, { "name": { - "zh_CN": "面包屑" + "zh_CN": "漏斗图" }, - "icon": "breadcrumb", + "icon": "funnel", "screenshot": "", - "snippetName": "TinyBreadcrumb", + "snippetName": "TinyHuichartsFunnel", "schema": { - "componentName": "TinyBreadcrumb", + "componentName": "TinyHuichartsFunnel", "props": { - "options": [ - { - "to": "{ path: '/' }", - "label": "首页" - }, - { - "to": "{ path: '/breadcrumb' }", - "label": "产品" - }, - { - "replace": "true", - "label": "软件" - } - ] + "options": { + "data": [ + { + "value": 100, + "name": "Show" + }, + { + "value": 75, + "name": "Click" + }, + { + "value": 50, + "name": "Visit" + }, + { + "value": 25, + "name": "Order" + } + ] + } } } }, { "name": { - "zh_CN": "标签页" + "zh_CN": "散点图" }, - "icon": "tabs", + "icon": "scatter", "screenshot": "", - "group": true, - "snippetName": "TinyTabs", + "snippetName": "TinyHuichartsScatter", "schema": { - "componentName": "TinyTabs", + "componentName": "TinyHuichartsScatter", "props": { - "modelValue": "first" - }, - "children": [ - { - "componentName": "TinyTabItem", - "props": { - "title": "标签页1", - "name": "first" - }, - "children": [ - { - "componentName": "div", - "props": { - "style": "margin:10px 0 0 30px" - } + "options": { + "padding": [ + 50, + 30, + 50, + 20 + ], + "legend": { + "orient": "horizontal", + "show": true, + "position": { + "left": "center", + "bottom": 15 } - ] - }, - { - "componentName": "TinyTabItem", - "props": { - "title": "标签页2", - "name": "second" }, - "children": [ - { - "componentName": "div", - "props": { - "style": "margin:10px 0 0 30px" - } - } - ] + "bubbleSize": [ + 20, + 100 + ], + "xAxisType": "value", + "data": { + "1990": [ + [ + 28604, + 77, + 1709866, + "Australia", + 1990 + ], + [ + 31163, + 77.4, + 27662440, + "Canada", + 1990 + ], + [ + 60001, + 68, + 1154605773, + "China", + 1990 + ], + [ + 13670, + 74.7, + 10582082, + "Cuba", + 1990 + ], + [ + 28599, + 75, + 4986705, + "Finland", + 1990 + ] + ], + "2000": [ + [ + 19349, + 69.6, + 147568552, + "Russia", + 2000 + ], + [ + 10670, + 67.3, + 53994606, + "Turkey", + 2000 + ], + [ + 26424, + 75.7, + 57110117, + "United Kingdom", + 2000 + ], + [ + 37062, + 75.4, + 252847810, + "United States", + 2000 + ], + [ + 23038, + 73.13, + 143456918, + "Russia", + 2000 + ] + ], + "2015": [ + [ + 44056, + 81.8, + 23968976, + "Australia", + 2015 + ], + [ + 43294, + 81.7, + 35939927, + "Canada", + 2015 + ], + [ + 13334, + 76.9, + 1376048943, + "Cuba", + 2015 + ], + [ + 21291, + 78.5, + 11389566, + "Finland", + 2015 + ], + [ + 38923, + 80.8, + 5503457, + "France", + 2015 + ] + ] + } } - ] + } } } ] @@ -14918,6 +23260,13 @@ } ], "packages": [ + { + "name": "TinyVueHuicharts组件库", + "package": "@opentiny/vue-huicharts", + "version": "3.22.0", + "destructuring": true, + "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs" + }, { "name": "TinyVue组件库", "package": "@opentiny/vue", @@ -14937,4 +23286,4 @@ ] } } -} +} \ No newline at end of file diff --git a/designer-demo/registry.js b/designer-demo/registry.js index 23d7d0c824..bf89228632 100644 --- a/designer-demo/registry.js +++ b/designer-demo/registry.js @@ -13,6 +13,9 @@ import { META_SERVICE, META_APP } from '@opentiny/tiny-engine-meta-register' import engineConfig from './engine.config' import { HttpService } from './src/composable' +const baseURL = import.meta.env.BASE_URL || '.' +const baseURLWithoutSlash = baseURL.replace(/\/$/, '') + export default { [META_SERVICE.Http]: HttpService, 'engine.config': { @@ -43,5 +46,12 @@ export default { } } } + }, + [META_APP.Preview]: { + options: { + // 配置预览跳转的 url:根据实际业务需求进行配置 + // 文档:https://opentiny.design/tiny-engine#/help-center/course/dev/preview-api + previewUrl: ['prod', 'alpha'].includes(import.meta.env.MODE) ? `${baseURLWithoutSlash}/preview.html` : '' + } } } diff --git a/designer-demo/src/composable/http/index.js b/designer-demo/src/composable/http/index.js index f11538395a..141c885c7b 100644 --- a/designer-demo/src/composable/http/index.js +++ b/designer-demo/src/composable/http/index.js @@ -16,6 +16,7 @@ const procession = { let loginVM = null const showError = (url, message) => { + if (message === 'canceled') return // 取消请求场景不报错 globalNotify({ type: 'error', title: '接口报错', @@ -46,7 +47,7 @@ const preResponse = (res) => { return Promise.reject(res.data.error) } - return res.data?.data + return res.data?.data || res.data } const openLogin = () => { diff --git a/designer-demo/src/preview.js b/designer-demo/src/preview.js index 47c726cc88..c35f036f65 100644 --- a/designer-demo/src/preview.js +++ b/designer-demo/src/preview.js @@ -10,6 +10,7 @@ * */ import { defineEntry } from '@opentiny/tiny-engine-meta-register' +import engineConfig from '../engine.config' import 'virtual:svg-icons-register' async function startApp() { @@ -23,9 +24,7 @@ async function startApp() { const registry = { [META_SERVICE.Http]: HttpService, 'engine.config': { - id: 'engine.config', - theme: 'light', - material: ['/mock/bundle.json'] + ...engineConfig } } diff --git a/docs/README.md b/docs/README.md index 0a6c9a6fbd..ca958736c8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -50,6 +50,7 @@ - [更新日志](./changelog/changelog.md) - [v2.7升级指南](./changelog/v2.7-upgrade-guide.md) - 解决方案 + - [前端及Java服务端docker部署](./solutions/front-backend-docker-deployment.md) - [Java服务端部署](./solutions/server-deployment-solution-java.md) - [Node.js服务端部署](./solutions/server-deployment-solution.md) - [区块发布方案(Node.js服务端)](./solutions/block-release-solution.md) diff --git a/docs/advanced-features/imgs/ai-assistant-chat.png b/docs/advanced-features/imgs/ai-assistant-chat.png new file mode 100644 index 0000000000..254d79e035 Binary files /dev/null and b/docs/advanced-features/imgs/ai-assistant-chat.png differ diff --git a/docs/advanced-features/imgs/ai-assistant-enable-mcp-tools.png b/docs/advanced-features/imgs/ai-assistant-enable-mcp-tools.png new file mode 100644 index 0000000000..5b99aa1285 Binary files /dev/null and b/docs/advanced-features/imgs/ai-assistant-enable-mcp-tools.png differ diff --git a/docs/advanced-features/imgs/ai-assistant-fullscreen.png b/docs/advanced-features/imgs/ai-assistant-fullscreen.png new file mode 100644 index 0000000000..b1109fe874 Binary files /dev/null and b/docs/advanced-features/imgs/ai-assistant-fullscreen.png differ diff --git a/docs/advanced-features/imgs/ai-assistant-image-to-page.png b/docs/advanced-features/imgs/ai-assistant-image-to-page.png new file mode 100644 index 0000000000..599f571fbe Binary files /dev/null and b/docs/advanced-features/imgs/ai-assistant-image-to-page.png differ diff --git a/docs/advanced-features/imgs/ai-assistant-interface.png b/docs/advanced-features/imgs/ai-assistant-interface.png new file mode 100644 index 0000000000..bed41328b0 Binary files /dev/null and b/docs/advanced-features/imgs/ai-assistant-interface.png differ diff --git a/docs/advanced-features/imgs/ai-assistant-mcp-tools-management.png b/docs/advanced-features/imgs/ai-assistant-mcp-tools-management.png new file mode 100644 index 0000000000..767db48f48 Binary files /dev/null and b/docs/advanced-features/imgs/ai-assistant-mcp-tools-management.png differ diff --git a/docs/advanced-features/imgs/ai-assistant-open.png b/docs/advanced-features/imgs/ai-assistant-open.png new file mode 100644 index 0000000000..c84d4ece3a Binary files /dev/null and b/docs/advanced-features/imgs/ai-assistant-open.png differ diff --git a/docs/advanced-features/imgs/ai-assistant-prompts.png b/docs/advanced-features/imgs/ai-assistant-prompts.png new file mode 100644 index 0000000000..5ad998edbd Binary files /dev/null and b/docs/advanced-features/imgs/ai-assistant-prompts.png differ diff --git a/docs/advanced-features/imgs/ai-assistant-session-management.png b/docs/advanced-features/imgs/ai-assistant-session-management.png new file mode 100644 index 0000000000..f0f51200c5 Binary files /dev/null and b/docs/advanced-features/imgs/ai-assistant-session-management.png differ diff --git a/docs/advanced-features/imgs/ai-assistant-setting-select-model.png b/docs/advanced-features/imgs/ai-assistant-setting-select-model.png new file mode 100644 index 0000000000..4dd2d5d722 Binary files /dev/null and b/docs/advanced-features/imgs/ai-assistant-setting-select-model.png differ diff --git a/docs/advanced-features/imgs/ai-assistant-settings.png b/docs/advanced-features/imgs/ai-assistant-settings.png new file mode 100644 index 0000000000..be25158010 Binary files /dev/null and b/docs/advanced-features/imgs/ai-assistant-settings.png differ diff --git a/docs/advanced-features/imgs/ai-assistant-text-to-page.png b/docs/advanced-features/imgs/ai-assistant-text-to-page.png new file mode 100644 index 0000000000..4979762e0b Binary files /dev/null and b/docs/advanced-features/imgs/ai-assistant-text-to-page.png differ diff --git a/docs/advanced-features/imgs/ai-assistant-tool-execution-process.png b/docs/advanced-features/imgs/ai-assistant-tool-execution-process.png new file mode 100644 index 0000000000..26256e2bb8 Binary files /dev/null and b/docs/advanced-features/imgs/ai-assistant-tool-execution-process.png differ diff --git a/docs/advanced-features/imgs/ai-assistant-tool-execution1.png b/docs/advanced-features/imgs/ai-assistant-tool-execution1.png new file mode 100644 index 0000000000..68a9ed28ad Binary files /dev/null and b/docs/advanced-features/imgs/ai-assistant-tool-execution1.png differ diff --git a/docs/advanced-features/imgs/ai-assistant-tool-execution2.png b/docs/advanced-features/imgs/ai-assistant-tool-execution2.png new file mode 100644 index 0000000000..d41191b125 Binary files /dev/null and b/docs/advanced-features/imgs/ai-assistant-tool-execution2.png differ diff --git a/docs/advanced-features/imgs/use-function.png b/docs/advanced-features/imgs/use-function.png new file mode 100644 index 0000000000..77e98411cb Binary files /dev/null and b/docs/advanced-features/imgs/use-function.png differ diff --git a/docs/advanced-features/loop-rendering.md b/docs/advanced-features/loop-rendering.md index d78e66d8c0..86a9a8db00 100644 --- a/docs/advanced-features/loop-rendering.md +++ b/docs/advanced-features/loop-rendering.md @@ -10,7 +10,7 @@  3. 选中组件,在组件属性设置面板选择“高级”。 -4. 单击“循环数据“后的,进行变量绑定。 +4. 单击“循环数据“后的,进行变量绑定。 5. 选择绑定的变量,单击“确定”。 **图 2** 绑定变量 diff --git a/docs/advanced-features/new-ai-plugin-usage.md b/docs/advanced-features/new-ai-plugin-usage.md new file mode 100644 index 0000000000..bb346270c4 --- /dev/null +++ b/docs/advanced-features/new-ai-plugin-usage.md @@ -0,0 +1,568 @@ +# TinyEngine AI 插件使用指南 + +随着 TinyEngine 低代码平台的不断升级,AI 插件迎来了全面升级。新版 AI 插件集成了现代化的聊天界面,提供 Agent 模式和 Chat 模式,支持上传图片生成页面,支持 MCP(Model Context Protocol)工具调用能力,让 AI 辅助开发更加智能、强大。 + +## 一、功能概览 + +新版 AI 插件具备以下核心功能: + +### 1.1 全新 Agent 智能搭建模式,支持模式切换 + +**Agent 模式(智能搭建)** + +- 支持上传图片或自然语言搭建页面 +- 流式页面渲染,实时看到页面效果 +- 通过对话创建组件、调整样式、修改属性 +- 适合页面搭建、界面调整等场景 + +**Chat 模式(智能对话)** + +- 传统问答式交互体验 +- 支持代码生成、文档编写、技术咨询 +- 支持调用平台 MCP 工具完成特定任务 + +### 1.2 核心特性 + +- **现代化界面**:全新的聊天界面,支持 Markdown 渲染、代码高亮 +- **智能工具调用**:可以调用平台各种工具,如创建页面、修改组件等 +- **思考模式**:支持推理模型的深度思考,提供更准确的解决方案 +- **多模型支持**:兼容各种主流 AI 模型 +- **会话管理**:支持多个对话会话,自动保存历史记录 + +## 二、界面介绍 + +### 2.1 主界面 + +在编辑器界面右上角插件栏,您可以看到 AI 助手的图标。点击图标即可打开主界面对话窗口。 + + + +主界面包含以下元素: + +- **顶部工具栏**:包含设置模型、会话管理、全屏切换等功能 +- **欢迎区域**:显示 AI 助手的欢迎信息 +- **提示项**:快速开始的常用问题示例 +- **对话区域**:显示用户与 AI 的对话历史 +- **输入区域**:用户输入问题区域、上传文件区域,同时包含模式切换、MCP 工具、深度思考等按钮 + + + +### 2.2 模式切换 + +新版 AI 插件支持两种工作模式: + +#### Agent 模式(默认) + +- **文件上传**:支持上传图片生成页面 +- **智能页面搭建**:AI 可以直接修改页面 Schema,实时更新画布 +- **实时预览**:修改即时生效,无需手动刷新 +- **适用场景**:页面搭建、组件配置、样式调整等 + +#### Chat 模式 + +- **对话交互**:传统的问答式对话体验 +- **工具调用**:支持调用 MCP 工具完成特定任务 +- **适用场景**:咨询问答、代码生成、文档编写等 + +可以通过底部的模式切换按钮在两种模式间切换。 + +### 2.3 MCP 工具管理 + + + +MCP 工具管理面板允许用户: + +- 查看启用的 MCP 服务器 +- 启用/禁用特定的 MCP 工具 + +### 2.4 深度思考 + +启用推理模型的深度思考功能,AI 会自动进行深度思考,提供更准确的解决方案。 + +### 2.5 模型设置面板 + +点击顶部的设置图标,可以进入设置面板,包含以下两个配置页签: + +#### 模型选择 + +- **默认助手模型**:选择 AI 对话使用的主模型,支持按服务商筛选。模型列表会标注能力标签(工具调用、视觉理解) +- **快速模型**:用于代码补全、话题命名等场景,建议选择轻量模型(如 flash 类型或 8b/14b 模型)以获得更快响应 +- 选择模型后会显示当前模型所属的服务名称及 API Key 配置状态 +  + +#### 模型服务 + +- **查看服务列表**:展示所有已配置的模型服务,包含 Base URL、模型数量、API Key 状态 +- **配置内置服务**:为内置服务(如 OpenAI、DeepSeek 等)配置 API Key +- **添加自定义服务**:支持添加兼容 OpenAI 格式的自定义模型服务,需配置: + - **服务名称**:自定义的服务标识 + - **Base URL**:API 地址(支持末尾缺省`/chat/completions`,`#`结尾强制使用输入地址) + - **API Key**:访问认证信息 + - **模型配置**:添加一个或多个模型,设置模型名称、显示名称及能力(工具调用、视觉理解、快速模型) +- **编辑/删除服务**:可编辑自定义服务的全部配置,或删除自定义服务 + + + +**注意**:切换 AI 模型会开启新的会话;若选择的模型未配置 API Key,会提示前往模型服务页签进行配置。 + +### 2.6 会话管理 + + +用户会话会保存到浏览器缓存中,点击顶部的会话管理图标可以查看当前会话历史 + +会话管理面板允许用户: + +- 查看当前会话历史 +- 点击会话可以切换当前会话(图标区分 Agent 与 Chat 模式) +- 删除特定的会话 + +## 三、快速开始 + +### 3.1 打开 AI 插件 + +在 TinyEngine 编辑器界面左下角插件栏,点击 AI 助手图标即可打开对话窗口。 + +### 3.2 首次配置 + +首次使用时,需要进行简单配置: + +1. **选择 AI 模型**:点击右上角设置按钮,选择合适的 AI 模型 +2. **配置 API Token**:输入对应 AI 服务的 API 密钥 +3. **选择工作模式**:根据需要选择 Agent 模式或 Chat 模式 + +### 3.3 开始使用 + +配置完成后,您可以: + +- **直接对话**:在输入框中输入问题,按回车发送 +- **使用提示**:点击界面上的快速提示开始对话 +- **上传文件**:在 Agent 模式下可以上传图片生成页面 +- **切换模式**:随时在 Agent 和 Chat 模式间切换 + +### 3.4 进阶配置(可选) + +对于开发者,可以进行更多自定义配置: +通过在注册表中添加 options 配置项,可以配置 AI 模型、上下文功能开关等。 + +```javascript +// registry.js +export default { + // ...... + [META_APP.Robot]: { + options: { + // enableResourceContext: false, // 提示词上下文携带资源插件图片,默认true + // enableRagContext: true, // 提示词上下文携带查询到的知识库内容,默认false + // customCompatibleAIModels: [] // 自定义AI模型(OpenAI兼容格式) + } + } + // ...... +} +``` + +#### 自定义 AI 模型 + +```javascript +// 在项目配置中添加OpenAI兼容格式自定义模型,也支持删除内置模型服务和模型 +customCompatibleAIModels: [ + // ==================== 示例 1:删除整个服务 ==================== + // 删除 DeepSeek 服务 + { + provider: 'deepseek', + _remove: true + }, + + // ==================== 示例 2:修改现有服务 ==================== + // 修改阿里云百炼服务:删除部分模型 + 添加新模型 + 覆盖配置 + { + provider: 'qwen', + // 可选:修改服务的显示名称 + label: '阿里云百炼 (自定义)', + // 可选:修改服务的 baseUrl + // baseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1', + models: [ + // 删除不需要的模型 + { name: 'qwen-turbo', _remove: true }, + { name: 'qwen-plus', _remove: true }, + + // 添加新模型 + { + label: 'Qwen Max', + name: 'qwen-max', + capabilities: { + toolCalling: true, + vision: true, + reasoning: true + } + }, + + // 覆盖已有模型的配置 + { + label: 'Qwen2.5-72B (推荐)', + name: 'qwen2.5-72b-instruct', + capabilities: { + toolCalling: true, + vision: false, + reasoning: false, + compact: false + } + } + ] + }, + + // ==================== 示例 3:添加全新的 OpenAI 服务 ==================== + { + provider: 'openai', // AI模型提供商 + label: 'OpenAI', // AI模型名称 + baseUrl: 'https://api.openai.com/v1', // AI模型API地址 + allowEmptyApiKey: false, // 是否允许API Token为空 + models: [ + { + label: 'GPT-4o', // AI模型名称 + name: 'gpt-4o', // AI模型名称 + capabilities: { + toolCalling: true, // 是否支持工具调用 + vision: true, // 是否支持视觉理解 + reasoning: true // 是否支持推理 + } + }, + { + label: 'GPT-4o Mini', + name: 'gpt-4o-mini', + capabilities: { + toolCalling: true, + vision: true, + compact: true + } + }, + { + label: 'o1-preview', + name: 'o1-preview', + capabilities: { + toolCalling: false, + vision: false, + reasoning: true + } + } + ] + } +] +``` + +#### 自定义 Agent 模式上下文功能 + +- enableResourceContext: 该参数配置是否在提示词上下文携带资源插件图片,AI 会在生成的页面中自动匹配合适的图片资源,默认开启 +- enableRagContext: 该参数配置是否在提示词上下文携带查询到的知识库内容,可以根据场景在后端知识库中添加文档知识,以优化 AI 的生成效果,默认关闭 + +#### 其他配置 + +- encryptServiceApiKey: 该参数配置是否加密服务 API 密钥 +- modeImplementation: 该参数配置 Agent 模式/Chat 模式的实现,支持自定义 Agent 模式/Chat 模式的实现 + +#### 本地开发代理(可选) + +```javascript +// vite.config.js - 用于本地开发调试 +proxy: { + '/app-center/api/chat/completions': { + target: 'https://api.deepseek.com', + changeOrigin: true, + rewrite: path => path.replace('/app-center/api/chat/completions', '/v1/chat/completions') + }, + '/app-center/api/ai/chat': { + target: 'https://api.deepseek.com', + changeOrigin: true, + rewrite: path => path.replace('/app-center/api/ai/chat', '/v1/chat/completions') + } +} +``` + +## 四、开始对话 + +### 4.1 Agent 模式 + +图片生成页面: +首先切换到 Agent 模式,然后点击上传图片按钮,上传您想要生成页面的图片。 + + + +自然语言生成页面: +切换到 Agent 模式,然后直接在输入框中输入您想要生成页面的描述,AI 会根据您的描述生成页面。 + + + +### 4.2 Chat 模式 + +Chat 模式支持传统的问答式交互体验,AI 会根据您的问题提供答案。同时支持调用 MCP 工具完成特定任务。 + + + +## 五、MCP 工具使用 + +### 5.1 什么是 MCP 工具 + +MCP(Model Context Protocol)工具让 AI 能够调用平台的各种功能,实现真正的智能操作: + +- **页面管理**:创建、删除、修改页面 +- **组件操作**:添加、配置、调整组件 +- **样式设置**:修改 CSS 样式和布局 +- **数据查询**:获取项目信息、页面列表等 +- **资源管理**:处理图片、文件等资源 + +### 5.2 如何启用工具 + +1. **打开工具面板**:点击输入框旁的"MCP"按钮 +2. **查看可用工具**:浏览平台提供的各种工具 +3. **启用所需工具**:勾选您需要使用的工具 +4. **开始使用**:AI 会在需要时自动调用这些工具 + + + +### 5.3 工具调用示例 + +AI 会根据您的需求自动选择和调用合适的工具: + +**示例对话:** + +``` +用户:帮我查看当前项目有哪些页面 +AI:我来为您查询项目中的页面信息... +[自动调用页面查询工具] +AI:当前项目包含以下页面:首页、用户管理、设置页面... +``` + +**工具执行过程:** + +- 🔄 AI 识别需求并选择工具 +- ⚙️ 自动调用相应的平台功能 +- 📊 展示执行结果和详细信息 +- ✅ 可展开查看调用参数和返回值 + + + +## 六、典型使用场景 + +### 6.1 Agent 模式 - 智能页面搭建 + +Agent 模式让您可以通过对话直接操作页面,实时看到效果。 + +#### 创建新组件 + +``` +用户:在页面中添加一个用户信息表单,包含姓名、邮箱、手机号字段 +AI:页面正在生成中,请稍等片刻... +[实时更新页面布局] +[完成后插件界面会更新提示和状态] +``` + +#### 修改组件属性 + +``` +用户:将页面中的按钮文字改为"提交表单",颜色设为主色 +AI:页面正在生成中,请稍等片刻... +[实时更新页面布局] +[完成后插件界面会更新提示和状态] +``` + +#### 调整布局和样式 + +``` +用户:调整表单布局,让字段按两列显示,添加一些间距 +AI:页面正在生成中,请稍等片刻... +[实时更新页面布局] +[完成后插件界面会更新提示和状态] +``` + +### 6.2 Chat 模式 - 智能对话交互 + +Chat 模式适合传统的问答式交互和工具调用。 + +#### 代码生成和解释 + +``` +用户:帮我写一个 Vue3 的表单验证组件 +AI:我来为您创建一个Vue3表单验证组件... +[返回完整的Vue3组件代码和使用说明] +``` + +#### MCP 工具调用 + +``` +用户:查询当前项目的所有页面 +AI:我来查询项目中的页面信息... +[调用MCP工具获取页面列表] +AI:当前项目包含以下页面:... +``` + +### 6.3 思考模式 - 深度推理 + +对于支持推理能力的模型(如 DeepSeek Reasoner),可以启用思考模式: + +``` +用户:设计一个复杂的电商购物车页面,需要考虑用户体验和性能优化 +AI:[开始深度思考] +让我仔细分析这个需求... +首先,电商购物车页面需要考虑以下几个方面: +1. 用户体验方面... +2. 性能优化方面... +3. 功能设计方面... +[经过深度思考后提供详细的设计方案] +[最后AI会提供一个完整的页面设计,包括组件、布局、样式等] +``` + +## 七、实用功能 + +### 7.1 会话管理 + +- **多会话支持**:可以同时进行多个不同主题的对话 +- **历史记录**:自动保存所有对话内容,随时查看 +- **智能标题**:根据对话内容自动生成有意义的标题 +- **快速搜索**:在历史对话中快速找到需要的内容 + +### 7.2 工具调用 + +- **自动识别**:AI 会根据您的需求自动选择合适的工具 +- **可视化结果**:工具执行结果以易读的方式展示 +- **操作记录**:清晰记录每个工具的调用过程和参数 +- **错误重试**:当工具执行失败时,可以重新尝试 + +### 7.3 智能提示 + +- **快速开始**:提供常用场景的示例问题,点击即可使用 +- **上下文提示**:根据当前页面情况提供相关建议 +- **功能引导**:帮助新用户快速上手各项功能 + +### 7.4 界面体验 + +- **富文本支持**:支持 Markdown 格式,可以显示表格、列表、代码等 +- **代码高亮**:自动识别并高亮显示各种编程语言 +- **全屏模式**:可以将对话窗口放大到全屏,获得更好的使用体验 + + + +## 八、注意事项 + +### 8.1 使用前准备 + +1. **保存提醒**:在使用 Agent 模式修改页面前,请确保当前页面已保存 +2. **网络要求**:需要稳定的网络连接支持流式数据传输 +3. **API 配置**:确保正确配置了 AI 模型的 API Token 和基础 URL +4. **浏览器兼容性**:建议使用现代浏览器,支持最新的 Web 标准 + +### 8.2 模式选择建议 + +- **Agent 模式**:适用于页面搭建、组件修改、样式调整等直接操作场景 +- **Chat 模式**:适用于咨询问答、代码生成、文档编写等对话场景 +- **思考模式**:仅在使用支持推理的模型时启用,会增加响应时间 + +### 8.3 性能优化 + +- **消息历史**:定期清理过多的对话历史以保持性能 +- **流式处理**:在网络较慢时可能出现延迟,属于正常现象 +- **工具调用**:复杂的工具调用可能需要较长时间,请耐心等待 + +## 九、故障排除 + +### 9.1 连接问题 + +**现象**:无法连接 AI 服务或请求超时 + +**解决方案**: + +- 检查网络连接是否稳定 +- 确认 API Token 和基础 URL 配置正确 +- 检查代理配置是否正确(本地开发环境) +- 查看控制台网络请求错误信息 + +### 9.2 Agent 模式问题 + +**现象**:页面更新失败或显示异常 + +**解决方案**: + +- 检查当前页面是否已保存 +- 确认页面格式正确 +- 查看控制台错误信息 +- 尝试新建会话并创建新空白页面再重试 + +### 9.3 MCP 工具问题 + +**现象**:MCP 工具无法调用或调用失败 + +**解决方案**: + +- 检查 MCP 工具管理面板中的工具状态 +- 查看控制台 MCP 服务错误信息 +- 尝试重新启用对应的工具 + +### 9.4 性能问题 + +**现象**:界面卡顿或响应缓慢 + +**解决方案**: + +- 清理过多的对话历史 +- 关闭不必要的浏览器标签页 +- 检查浏览器内存使用情况 +- 尝试刷新页面或重启浏览器 + +### 9.5 紧急恢复 + +如果遇到严重问题,可以尝试以下步骤: + +1. **清除缓存**:清除浏览器缓存和 LocalStorage +2. **重置配置**:在设置面板中重新配置 AI 模型 +3. **重启服务**:重启开发服务器(本地开发环境) +4. **联系支持**:如问题依然存在,请在[GitHub](https://github.com/opentiny/tiny-engine/issues)提交问题 + +## 十、总结 + +### 10.1 为什么选择新版 AI 插件 + +新版 AI 插件相比以往版本带来了显著改进: + +**更强大的功能** + +- 多模态支持,支持上传图片或者自然语言搭建页面 +- 双模式设计满足不同使用需求:既可以直接搭建页面,也可以进行技术咨询 +- 智能工具调用让 AI 能够实际操作平台功能,而不仅仅是对话 +- 思考模式提供更深入的分析和解决方案 + +**更好的体验** + +- 现代化的界面设计,支持富文本显示和代码高亮 +- 实时响应,无需等待,边说边看到结果 +- 完善的会话管理,不用担心丢失重要对话 + +**更简单的使用** + +- 无需复杂配置,开箱即用 +- 智能提示帮助快速上手 +- 支持多种 AI 模型,灵活选择 + +### 10.2 实际价值 + +使用新版 AI 插件,您可以: + +- **大幅提升开发效率**:原本需要手动点击多次的操作,现在只需一句话 +- **降低学习成本**:新手也能快速上手,无需深入学习复杂功能 +- **减少出错概率**:AI 辅助生成的代码更加规范和可靠 + +### 10.3 未来更新计划 + +我们正在不断改进和完善 AI 插件,即将推出: + +**后续更新** + +- 优化 AI 生成能力,生成更准确、更稳定的页面 UI 效果 +- 更好的组件支持 +- 结合模板实现更好的效果 +- 优化性能,让响应更快、体验更流畅 + +**长期愿景** + +- 应用级的代码生成 +- 更智能的代码生成和优化建议 + +--- + +新版 AI 插件不仅仅是一个工具,更是您的智能开发助手。它将帮助您在 TinyEngine 平台上实现更高效、更智能的低代码开发体验。现在就开始使用吧! diff --git a/docs/advanced-features/imgs/final-effect.gif b/docs/advanced-features/route-capabilities/imgs/final-effect.gif similarity index 100% rename from docs/advanced-features/imgs/final-effect.gif rename to docs/advanced-features/route-capabilities/imgs/final-effect.gif diff --git a/docs/advanced-features/using-utils-methods.md b/docs/advanced-features/using-utils-methods.md index 6894322a8e..fdb9a036e1 100644 --- a/docs/advanced-features/using-utils-methods.md +++ b/docs/advanced-features/using-utils-methods.md @@ -13,7 +13,7 @@ 提供输入框,直接编写函数代码 - + 如上图: - 第一步,点击添加工具类,选择 function diff --git a/docs/api/backend-api/dsl-code-generation.md b/docs/api/backend-api/dsl-code-generation.md index dd61638c0d..1dff789d74 100644 --- a/docs/api/backend-api/dsl-code-generation.md +++ b/docs/api/backend-api/dsl-code-generation.md @@ -13,6 +13,7 @@ **接口描述:**作为npm包使用generateCode方法生成代码示例:
+const path = require('path')
const fs = require('fs')
const { generateCode } = require('@opentiny/tiny-engine-dsl-ng-tiny/lib/generate-code.js')
@@ -24,6 +25,7 @@ result.forEach((item) => fs.writeFileSync(`dist/${item.filePath}/${item.panel
输入示例: { pageInfo, blocksData };
+// pageInfo为页面的schema信息,
// pageInfo: { schema, name });
{
diff --git a/docs/api/backend-api/material-center.md b/docs/api/backend-api/material-center.md
index 52c0049a22..222bd09b46 100644
--- a/docs/api/backend-api/material-center.md
+++ b/docs/api/backend-api/material-center.md
@@ -327,3 +327,54 @@ tenant 通过前端配置统一 x-lowcode-org 请求头传递,接口中不用
+## 物料同步接口
+
+
+
+### 基本信息
+
+**Path:** /material-center/api/component/bundle/create
+
+**Method:** POST
+
+**接口描述:**
+
+处理物料同步上传bundle.json文件创建或更新组件
+
+
+### 请求参数
+
+**Headers**
+
+| 参数名称 | 参数值 | 是否必须 | 示例 | 备注 |
+| ------------ | ---------------- | -------- | ---- | ---- |
+| Content-Type | multipart/form-data | 是 | | |
+
+**路径参数**
+
+| 参数名称 | 示例 | 备注 |
+| -------- | ---- | ------ |
+| file | bundle.json | bundle.json文件 |
+
+**Body**
+
+
+
+
+ 名称 类型 是否必须 默认值 备注 其他信息
+
+
+
+
+
+
+### 返回数据
+
+
+
+
+ 名称 类型 是否必须 默认值 备注 其他信息
+
+ data object 非必须 ├─ insertNum number 非必须 新增组件数 ├─ updateNum number 非必须 更新组件数
+
+
\ No newline at end of file
diff --git a/docs/api/frontend-api/main-package-api.md b/docs/api/frontend-api/main-package-api.md
index 4f3b42127f..20c62c4aac 100644
--- a/docs/api/frontend-api/main-package-api.md
+++ b/docs/api/frontend-api/main-package-api.md
@@ -34,6 +34,7 @@ export { default as Bridge } from '@opentiny/tiny-engine-plugin-bridge'
export { default as Block, BlockService } from '@opentiny/tiny-engine-plugin-block'
export { default as Datasource, DataSourceService } from '@opentiny/tiny-engine-plugin-datasource'
export { default as Robot } from '@opentiny/tiny-engine-plugin-robot'
+export { default as ModelManager } from '@opentiny/tiny-engine-plugin-model-manager'
export { default as Props, PropertiesService, PropertyService } from '@opentiny/tiny-engine-setting-props'
export { default as Events } from '@opentiny/tiny-engine-setting-events'
export { default as Styles } from '@opentiny/tiny-engine-setting-styles'
diff --git a/docs/api/frontend-api/material-api.md b/docs/api/frontend-api/material-api.md
index 162894e7f1..2ba0892854 100644
--- a/docs/api/frontend-api/material-api.md
+++ b/docs/api/frontend-api/material-api.md
@@ -1,19 +1,21 @@
-# 物料模块API
+# 物料模块 API
+
## 物料插件元应用
```js
export default {
id: 'engine.plugins.materials', // 元应用id
title: '物料', // 元应用名称
- type: 'plugins', // 元应用类型
+ type: 'plugins', // 元应用类型
icon: 'plugin-icon-materials', // 元应用图标
align: 'top', // 元应用在当前类型下的位置
entry, // 入口文件
layout: MaterialLayout, // 布局文件,可替换布局
options: {
defaultTabId: 'engine.plugins.materials.component', // 默认激活的Tab的元应用ID
- displayComponentIds: ['engine.plugins.materials.component', 'engine.plugins.materials.block'], // 需要展示的Tab组件ID列表,可以为单个,单个的时候,不展示tab,直接显示该元应用
- basePropertyOptions //基础属性配置
+ displayComponentIds: ['engine.plugins.materials.component', 'engine.plugins.materials.block'], // 需要展示的Tab组件ID列表,可以为单个,单个的时候,不展示tab,直接显示该元应用
+ basePropertyOptions, //基础属性配置
+ hiddenBuiltinMaterials: [] // 隐藏的内置物料组件列表,配置的组件不会在物料面板中显示
},
components: {
header: MaterialHeader // 公共组件,可自行提供
@@ -23,17 +25,55 @@ export default {
}
export { entry, ResourceService, MaterialService }
-
```
-### 物料插件元应用暴露出来的API
+### 物料插件配置选项详解
+
+#### hiddenBuiltinMaterials 配置
+
+用于隐藏不需要在物料面板中显示的内置组件,提高物料面板的整洁性和用户体验。
+
+**配置示例:**
+
```js
- apis: {
- fetchGroups: fetchGroups // 获取区块分组列表
+// registry.js
+export default {
+ [META_APP.Materials]: {
+ options: {
+ hiddenBuiltinMaterials: [
+ 'Box', // 盒子容器(普通div 容器)
+ 'CanvasRowColContainer', // 行列容器
+ 'CanvasFlexBox', // 弹性容器
+ 'CanvasSection', // 全宽居中容器
+ 'Text', // 文本
+ 'Icon', // 图标
+ 'Img', // 图片
+ 'Slot', // 插槽(区块插槽需要)
+ 'RouterView', // 路由视图(子页面需要,不建议隐藏)
+ 'RouterLink', // 路由链接
+ 'CanvasNavigation', // 导航条
+ 'Collection' // 数据源容器(数据源功能依赖,不建议隐藏)
+ ]
+ }
}
+}
+```
+
+**使用场景:**
+
+- 隐藏不常用的内置组件,简化物料面板
+- 根据项目需求定制显示的组件列表
+
+### 物料插件元应用暴露出来的 API
+
+```js
+apis: {
+ fetchGroups: fetchGroups // 获取区块分组列表
+}
```
## 物料模块元服务
+
### useResource 元服务
负责全局统一的资源管理,如:国际化、大纲树、工具类、全局状态,全局数据源
@@ -47,7 +87,6 @@ const resState = reactive({
globalState: []
})
-
return {
resState, // 保存着整个tiny-engine的国际化、大纲树、工具类、全局状态,全局数据源数据
fetchResource, // 进行初始化,获取后端返回的资源信息
@@ -67,7 +106,7 @@ return {
```js
const materialState = reactive({
components: [], // 这里存放的是物料插件面板里所有显示的组件
- blocks: [], // 这里存放的是物料插件面板里所有显示的区块
+ blocks: [], // 这里存放的是物料插件面板里所有显示的区块
componentsDepsMap: { scripts: [], styles: new Set() }, // 这里存放组件依赖的映射
packages: [] // 物料依赖的包
})
@@ -75,7 +114,7 @@ const materialState = reactive({
**使用示例**
-```useMaterial().materialState```
+`useMaterial().materialState`
2. 暴露出来的方法函数详情
@@ -83,37 +122,30 @@ const materialState = reactive({
{
// 状态对象
materialState, // 存放着组件、物料侧区块、第三方依赖信息
-
- // 初始化和请求方法
- initMaterial, // 物料模块初始化,参数: { isInit = true, appData = {} }
- fetchMaterial, // 请求物料并进行处理
- refreshMaterial, // 刷新物料,清空后重新初始化和获取
-
- // 物料资源获取方法
- getMaterialsRes, // 获取物料,并返回符合物料协议的bundle.json内容,返回: Promise
- getMaterial, // 获取单个物料,参数: (name: string) => Material
- getComponentsByGroup, // 根据组名获取指定分组组件,参数: (components: Component[], groupName: string) => Component[]
-
- // 物料操作方法
- generateNode, // 根据包含{ type, component }的组件信息生成组件schema节点
- setMaterial, // 设置单个物料,参数: (name: string, data: Material) => void
- addMaterials, // 添加多个物料,参数: (materials: Material) => void
-
- // 物料清理方法
- clearMaterials, // 清空所有物料
- clearBlockResources, // 清空区块缓存,以便更新最新版区块
-
- getBlockByName, // 通过区块名称获取区块
- getBlockCompileRes, // 获取区块编译结果
- addBlockResources, // 增加区块缓存,参数: (id: string, resource: BlockResource) => void
- updateBlockCompileCache, // 更新区块编译缓存
-
- // 依赖相关方法
- getCanvasDeps, // 组装画布依赖,包含物料和工具类的依赖
- updateCanvasDeps, // 通知画布更新依赖
-
- // 配置相关方法
- getConfigureMap // 获取物料组件的配置信息,返回组件名到配置的映射
+ // 初始化和请求方法
+ initMaterial, // 物料模块初始化,参数: { isInit = true, appData = {} }
+ fetchMaterial, // 请求物料并进行处理
+ refreshMaterial, // 刷新物料,清空后重新初始化和获取
+ // 物料资源获取方法
+ getMaterialsRes, // 获取物料,并返回符合物料协议的bundle.json内容,返回: Promise
+ getMaterial, // 获取单个物料,参数: (name: string) => Material
+ getComponentsByGroup, // 根据组名获取指定分组组件,参数: (components: Component[], groupName: string) => Component[]
+ // 物料操作方法
+ generateNode, // 根据包含{ type, component }的组件信息生成组件schema节点
+ setMaterial, // 设置单个物料,参数: (name: string, data: Material) => void
+ addMaterials, // 添加多个物料,参数: (materials: Material) => void
+ // 物料清理方法
+ clearMaterials, // 清空所有物料
+ clearBlockResources, // 清空区块缓存,以便更新最新版区块
+ getBlockByName, // 通过区块名称获取区块
+ getBlockCompileRes, // 获取区块编译结果
+ addBlockResources, // 增加区块缓存,参数: (id: string, resource: BlockResource) => void
+ updateBlockCompileCache, // 更新区块编译缓存
+ // 依赖相关方法
+ getCanvasDeps, // 组装画布依赖,包含物料和工具类的依赖
+ updateCanvasDeps, // 通知画布更新依赖
+ // 配置相关方法
+ getConfigureMap // 获取物料组件的配置信息,返回组件名到配置的映射
}
```
@@ -122,10 +154,10 @@ const materialState = reactive({
```js
// 初始化物料
useMaterial().initMaterial({ isInit: true, appData }) // appData为远程拉取的应用数据
-
+
// 获取单个物料
const material = useMaterial().getMaterial('ComponentName')
-
+
// 生成组件节点
const node = useMaterial().generateNode({ type: 'component', component: 'Button' })
@@ -133,7 +165,7 @@ const node = useMaterial().generateNode({ type: 'component', component: 'Button'
await useMaterial().refreshMaterial()
```
-#### 主要API详解
+#### 主要 API 详解
##### 初始化和请求相关方法
@@ -171,7 +203,6 @@ refreshMaterial()
使用场景:二开工程中,允许用户上传物料,或者是动态更新物料后,需要刷新物料,此时可以调用该方法。
-
##### 物料资源获取方法
1. `getMaterialsRes`:获取物料资源
@@ -280,42 +311,47 @@ updateCanvasDeps()
使用场景:如果需要画布刷新 script 或者 import-map 的时候,可以调用此方法让画布重新加载。(该方法会调用 getCanvasDeps 方法,获取画布依赖,并通知画布更新依赖)
#### 物料类型结构
+
主要的物料类型定义包括:
-1. `Material`: 物料包定义,符合物料协议的bundle.json内容
+1. `Material`: 物料包定义,符合物料协议的 bundle.json 内容
+
```ts
interface Material {
- components: Component[]; // 组件列表
- blocks?: Block[]; // 区块列表
- snippets?: Snippet[]; // 物料分组列表
- packages?: Dependency[]; // 物料依赖的包
+ components: Component[] // 组件列表
+ blocks?: Block[] // 区块列表
+ snippets?: Snippet[] // 物料分组列表
+ packages?: Dependency[] // 物料依赖的包
}
```
2. `Component`: 组件物料定义
+
```ts
interface Component {
- component: string; // 组件名称
- group: string; // 组件分组
- npm?: { // 组件NPM包信息
- package: string; // 包名
- script?: string; // 脚本路径
- exportName: string; // 导出名称
- css?: string; // 样式路径
- };
- schema?: Schema; // 组件配置信息
+ component: string // 组件名称
+ group: string // 组件分组
+ npm?: {
+ // 组件NPM包信息
+ package: string // 包名
+ script?: string // 脚本路径
+ exportName: string // 导出名称
+ css?: string // 样式路径
+ }
+ schema?: Schema // 组件配置信息
}
```
3. `Block`: 区块物料定义
+
```ts
interface Block {
- label: string; // 区块标识
- blockName: string; // 区块名称
- version?: string; // 区块版本
- description?: string; // 区块描述
- screenshot?: string; // 区块截图
- content?: BlockResource; // 区块内容
+ label: string // 区块标识
+ blockName: string // 区块名称
+ version?: string // 区块版本
+ description?: string // 区块描述
+ screenshot?: string // 区块截图
+ content?: BlockResource // 区块内容
}
```
@@ -346,13 +382,13 @@ import { useMaterial, useCanvas } from '@opentiny/tiny-engine'
export const addComponent = (componentName) => {
const material = useMaterial()
const canvas = useCanvas()
-
+
// 生成组件节点
- const schema = material.generateNode({
- type: 'component',
- component: componentName
+ const schema = material.generateNode({
+ type: 'component',
+ component: componentName
})
-
+
// 添加到画布
canvas.canvasApi.value.addComponent(schema)
}
@@ -365,14 +401,14 @@ import { useMaterial } from '@opentiny/tiny-engine'
export const getComponentConfigure = (componentName) => {
const material = useMaterial()
-
+
// 获取单个物料信息
const componentInfo = material.getMaterial(componentName)
-
+
// 获取组件配置
const configureMap = material.getConfigureMap()
const configure = configureMap[componentName]
-
+
return { componentInfo, configure }
}
```
diff --git a/docs/api/frontend-api/preview-api.md b/docs/api/frontend-api/preview-api.md
index 2d1605c609..250d326087 100644
--- a/docs/api/frontend-api/preview-api.md
+++ b/docs/api/frontend-api/preview-api.md
@@ -74,11 +74,14 @@ const registry = {
-import { Preview } from '@opentiny/tiny-engine'
+// registry.js
+import { META_APP } from '@opentiny/tiny-engine-meta-register'
export default {
- toolbars: [
- [Preview, { options: { ...Preview.options, previewUrl: import.meta.env.MODE.includes('prod') ? 'http://tiny-engine-preview.com/customPreview' : '' } }]
- ]
+ [META_APP.Preview]: {
+ options: {
+ previewUrl: import.meta.env.MODE.includes('prod') ? 'http://tiny-engine-preview.com/customPreview' : ''
+ }
+ }
}
@@ -91,22 +94,17 @@ export default {
例如:
```javascript
-import { Preview } from '@opentiny/tiny-engine'
+// registry.js
+import { META_APP } from '@opentiny/tiny-engine-meta-register'
export default {
- toolbars: [
- [
- Preview,
- {
- options: {
- ...Preview.options,
- previewUrl: (originUrl, query) => {
- // 这里我们增加了自定义的 query: `test=1`
- return `http://tiny-engine-preview.com/customPreview?test=1&${query}`
- }
- }
- }
- ]
- ]
+ [META_APP.Preview]: {
+ options: {
+ previewUrl: (originUrl, query) => {
+ // 这里我们增加了自定义的 query: `test=1`
+ return `http://tiny-engine-preview.com/customPreview?test=1&${query}`
+ }
+ }
+ }
}
```
@@ -119,7 +117,12 @@ export default {
initPreview({
registry: {
- config: { id: 'engine.config', theme: 'light', previewHotReload: false },
+ 'engine.config': {
+ id: 'engine.config',
+ theme: 'light',
+ // 配置 false 关闭热更新
+ previewHotReload: false
+ }
// ... other config
}
})
diff --git a/docs/basic-features/internationalization.md b/docs/basic-features/internationalization.md
index 323cc1debd..1c9b252159 100644
--- a/docs/basic-features/internationalization.md
+++ b/docs/basic-features/internationalization.md
@@ -4,7 +4,7 @@
同一个项目,可能需要同时支持多个语言,设计器提供了中英文切换,在能够一键切换语言,提升开发效率与开发体验。 国际化是应用级别的,在任何一个页面都可以访问。
->  **说明:**
+> **说明:**
> 注意的是国际化只针对画布中的项目,不针对设计器本身。
## 添加国际化词条
@@ -13,7 +13,7 @@
2. 单击“新增词条”。
3. 编辑key,中文和英文内容
- >  **说明:**
+ > **说明:**
>- 创建时key会自动生成,也可以自定义输入。
>- key需为唯一值,不可与现有key重复。
>- 创建后key值不可修改。
diff --git a/docs/catalog.json b/docs/catalog.json
index 3066d29117..9682235a13 100644
--- a/docs/catalog.json
+++ b/docs/catalog.json
@@ -41,6 +41,7 @@
{ "title": "循环渲染", "name": "loop-rendering.md" },
{ "title": "条件渲染", "name": "conditional-rendering.md" },
{ "title": "集成ChatGPT搭建简单页面能力", "name": "integrating-chatgpt-for-simple-pages.md" },
+ { "title": "新版AI插件使用", "name": "new-ai-plugin-usage.md" },
{ "title": "数据源和Collection—远程字段", "name": "data-source-and-collection-remote-fields.md" },
{ "title": "数据源和Collection—mock数据", "name": "data-source-and-collection-mock-data.md" },
{ "title": "数据源和Collection—使用数据源", "name": "data-source-and-collection-usage.md" },
@@ -94,6 +95,7 @@
"title": "解决方案",
"name": "solutions",
"articles": [
+ {"title": "前端及Java服务端docker部署", "name": "front-backend-docker-deployment.md"},
{ "title": "Java服务端部署", "name": "server-deployment-solution-java.md" },
{ "title": "Node.js服务端部署", "name": "server-deployment-solution.md" },
{ "title": "区块发布方案(Node.js服务端)", "name": "block-release-solution.md" },
diff --git a/docs/changelog/changelog.md b/docs/changelog/changelog.md
index 4adeda5e8f..a7a62aff27 100644
--- a/docs/changelog/changelog.md
+++ b/docs/changelog/changelog.md
@@ -23,8 +23,8 @@
#### 📚 Documentation
- 新增 [v2.7 升级指南](./v2.7-upgrade-guide.md)
-- 新增 [新注册表](../extension-capabilities-overview/new-registry.md) 文档
-- 新增 [注册表高级配置](../extension-capabilities-overview/new-registry-advanced.md) 文档
+- 新增 [新注册表](../extension-capabilities-overview/new-registry.md "dev") 文档
+- 新增 [注册表高级配置](../extension-capabilities-overview/new-registry-advanced.md "dev") 文档
#### ⚙️ Other changes
diff --git a/docs/changelog/v2.7-upgrade-guide.md b/docs/changelog/v2.7-upgrade-guide.md
index 5e6865e9c7..a7d795cce6 100644
--- a/docs/changelog/v2.7-upgrade-guide.md
+++ b/docs/changelog/v2.7-upgrade-guide.md
@@ -76,7 +76,7 @@ const register = {
> **重要提示⚠️**:v2.7 开始,如果对原插件没有改动(配置、替换、删除),则不需要在注册表中进行声明,因为官方内置了全量的注册表。
-详细内容请参考 [新注册表](../extension-capabilities-overview/new-registry.md)。
+详细内容请参考 [新注册表](../extension-capabilities-overview/new-registry.md "dev")。
## API 变更
@@ -184,7 +184,7 @@ await initHotfixRegistry({
- 使用 `getAllMergeMeta()` 获取完整注册表信息,便于调试和开发
- 使用 `initHotfixRegistry()` 实现热修复功能
-详细API请参考 [注册表 API](../api/frontend-api/registry-api.md)。
+详细API请参考 [注册表 API](../api/frontend-api/registry-api.md "dev")。
## Vite 配置要求
@@ -266,7 +266,7 @@ export default {
> **注意⚠️**:当同时配置 `layoutConfig` 和 `relativeLayoutConfig` 时,`layoutConfig` 优先级更高,`relativeLayoutConfig` 将被忽略。
-详细内容请参考 [布局配置](../api/frontend-api/global-layout-api.md)。
+详细内容请参考 [布局配置](../api/frontend-api/global-layout-api.md "dev")。
### 3. 插件配置变更
@@ -361,6 +361,95 @@ const register = {
}
```
+#### 3.3 仅支持在第一层声明(子层声明不会生效)
+
+自 v2.7 起,我们只读取注册表对象的“第一层”。只有第一层的键会被注册进 `metaHashMap`。
+
+也就是说:把插件/配置项写在子层(无论是把唯一 ID 放到某个插件的子属性里,还是通过 `metas` 往里塞)都不会被注册,`getMergeMeta`/`getMergeMetaByType`/`getAllMergeMeta` 也就找不到它们。
+
+简而言之:请把所有需要生效的插件/配置项,都放到注册表的第一层来声明。
+
+错误示例(不会生效):
+```javascript
+import { META_APP } from '@opentiny/tiny-engine'
+import testMeta from './testMeta'
+
+export default {
+ // 1) 在子层直接再次声明插件/配置项(无效,不会注册到 metaHashMap)
+ [META_APP.Materials]: {
+ 'engine.plugins.test': testMeta
+ },
+
+ // 2) 通过 metas 在子层注入(无效,不会注册到 metaHashMap)
+ [META_APP.Materials]: {
+ options: {
+ displayComponentIds: ['engine.plugins.test'],
+ metas: [testMeta]
+ }
+ }
+}
+```
+
+正确示例(第一层声明 + 通过 ID 引用):
+```javascript
+import { META_APP } from '@opentiny/tiny-engine'
+import testMeta from './testMeta' // testMeta.id = 'engine.plugins.test'
+
+export default {
+ // 作为第一层键单独注册
+ [testMeta.id]: testMeta,
+
+ // 在需要的插件或布局中通过 ID 引用
+ [META_APP.Materials]: {
+ options: {
+ displayComponentIds: ['engine.plugins.test']
+ }
+ }
+}
+```
+
+适用范围:所有插件与配置项都遵循该规则。用户注册表只支持:
+- 把已有的插件/配置项设为 `false`(删除默认);
+- 在第一层新增插件/配置项;
+- 在第一层用相同 ID 覆盖默认配置。
+
+##### 物料插件(Materials 插件)迁移建议
+
+如果你旧版本是在 `Materials` 插件内部(例如 `Materials.metas` 或把自定义 ID 放到 `Materials` 的子属性里)扩展物料插件,请按下面方式迁移:
+
+错误示例(不会生效):
+```javascript
+import { META_APP } from '@opentiny/tiny-engine'
+import MyMaterial from './MyMaterial' // MyMaterial.id = 'engine.plugins.myMaterial'
+
+export default {
+ [META_APP.Materials]: {
+ // 通过 metas 向物料插件塞入物料项(无效)
+ options: {
+ metas: [MyMaterial]
+ }
+ }
+}
+```
+
+正确示例(第一层声明 + 在物料插件中引用):
+```javascript
+import { META_APP } from '@opentiny/tiny-engine'
+import MyMaterial from './MyMaterial' // MyMaterial.id = 'engine.plugins.myMaterial'
+
+export default {
+ // 1) 物料项作为第一层键单独注册
+ [MyMaterial.id]: MyMaterial,
+
+ // 2) 在 Materials 插件中通过 ID Tab 组件显示
+ [META_APP.Materials]: {
+ options: {
+ displayComponentIds: ['engine.plugins.myMaterial']
+ }
+ }
+}
+```
+
### 4. 注册表热修复功能
v2.7 版本新增了注册表热修复(hotfix)功能,可以通过覆盖官方插件的特定函数或模板,实现紧急 bug 修复,而不需要等待官方版本发布。
@@ -386,7 +475,7 @@ export default {
}
```
-详细内容请参考 [注册表高级配置](../extension-capabilities-overview/new-registry-advanced.md)。
+详细内容请参考 [注册表高级配置](../extension-capabilities-overview/new-registry-advanced.md "dev")。
## 其他改进
diff --git a/docs/development-getting-started/dev-quick-start.md b/docs/development-getting-started/dev-quick-start.md
index ca05663012..05a559d459 100644
--- a/docs/development-getting-started/dev-quick-start.md
+++ b/docs/development-getting-started/dev-quick-start.md
@@ -88,11 +88,7 @@ import engineConfig from './engine.config'
export default {
// ...
--- plugins: [Materials, Tree, Page, Block, Datasource, Bridge, I18n, Script, State, Schema, Help, Robot],
-++ plugins: [DemoPlugin, Materials, Tree, Page, Block, Datasource, Bridge, I18n, Script, State, Schema, Help, Robot],
- dsls: [{ id: 'engine.dsls.dslvue' }],
- settings: [Props, Styles, Events],
- canvas: Canvas
+++ [DemoPlugin.id]: DemoPlugin
}
```
diff --git a/docs/extension-capabilities-overview/new-registry.md b/docs/extension-capabilities-overview/new-registry.md
index e75ca723cd..6232f2b560 100644
--- a/docs/extension-capabilities-overview/new-registry.md
+++ b/docs/extension-capabilities-overview/new-registry.md
@@ -271,6 +271,47 @@ export default {
更多高级特性,请参考 [注册表高级配置](./new-registry-advanced.md)。
+## Tailwind CSS 支持
+
+TinyEngine 自 v2.9 起支持在注册表中通过 `engine.config.enableTailwindCSS` 开关启用 Tailwind CSS(默认开启)。
+
+### 开关配置
+
+```javascript
+// registry.js
+export default {
+ 'engine.config': {
+ // ...其他配置
+ enableTailwindCSS: true // 开启(默认即为 true);设为 false 可关闭
+ }
+}
+```
+
+### 启用后的行为
+
+- 预览态:自动按需加载 `@tailwindcss/browser`,使画布/预览中可直接使用 Tailwind 原子类。
+- 出码生成:生成的应用将自动完成以下配置(基于 Tailwind CSS v4 零配置方案):
+ - 在依赖中添加 `tailwindcss`,并在开发依赖中添加 `@tailwindcss/vite`;
+ - 在 Vite 配置中注册 `tailwindcss()` 插件;
+ - 生成 `src/style.css`,内容包含 `@import "tailwindcss";`;
+ - 在 `src/main.js` 自动引入 `./style.css`。
+
+以上步骤由引擎/出码器自动完成,无需手动干预。
+
+### 关闭 Tailwind
+
+当配置为 `enableTailwindCSS: false` 时:
+
+- 预览态不会加载 `@tailwindcss/browser`;
+- 出码时不会注入与 Tailwind 相关的依赖、Vite 插件及样式文件导入。
+
+### 注意事项
+
+- 预览依赖解析:内置 import-map 已包含 `@tailwindcss/browser` 映射;如使用自定义 CDN/离线环境,请确保该映射可用。
+- 自定义样式:可在生成的 `src/style.css` 中追加自定义样式,或在项目中新增样式文件后自行引入。
+- 运行时渲染:如果您自定义了运行时渲染引擎,请确保在运行时渲染中增加对 Tailwind CSS 的支持。
+
+
## Vite 配置要求
**重要说明⚠️**:为了使注册表的 tree-shaking 功能正常工作,您需要在 `vite.config.js` 中配置 `registryPath` 参数,指向您的注册表文件路径。
diff --git a/docs/extension-capabilities-tutorial/ai-plugin-configuration.md b/docs/extension-capabilities-tutorial/ai-plugin-configuration.md
index 9c4c508ba8..18913de1e0 100644
--- a/docs/extension-capabilities-tutorial/ai-plugin-configuration.md
+++ b/docs/extension-capabilities-tutorial/ai-plugin-configuration.md
@@ -16,7 +16,7 @@
### 前端代码改动
-在`tiny-engine/packages/plugins/robot/src/js/robotSetting.js`文件改动如下
+在`tiny-engine/packages/plugins/robot/src/composables/useRobot.ts`文件改动如下

diff --git a/docs/extension-capabilities-tutorial/customize-page-configured.md b/docs/extension-capabilities-tutorial/customize-page-configured.md
index 8ba33685ae..f1f106e8dc 100644
--- a/docs/extension-capabilities-tutorial/customize-page-configured.md
+++ b/docs/extension-capabilities-tutorial/customize-page-configured.md
@@ -18,11 +18,11 @@
import { handleClickDelete } from './tests/utils'
export default {
// ...
- plugins: [
- // ...
- [Page, { options: { ...Page.options, customPageOperations: [{type: 'delete', label: '删除', action: handleClickDelete}] } }]
- // ...
- ]
+ [META_APP.AppManage]: {
+ options: {
+ customPageOperations: [{type: 'delete', label: '删除', action: handleClickDelete}]
+ }
+ }
// ...
}
```
diff --git a/docs/extension-capabilities-tutorial/customize-plugin-ui.md b/docs/extension-capabilities-tutorial/customize-plugin-ui.md
index 5c7a951f26..31e4d6c3f0 100644
--- a/docs/extension-capabilities-tutorial/customize-plugin-ui.md
+++ b/docs/extension-capabilities-tutorial/customize-plugin-ui.md
@@ -8,24 +8,18 @@
- `title`。标题
- `icon`。图标,可以为字符串或者组件。如果是字符串,则会使用 tiny-engine 自带的 svg 图标
-- `align`。对齐位置,根据插件位置的不同可以为不同的值。如果是顶部工具栏,可以为 `left`, `center`, `right`;如果是左侧插件栏,可以为 `top`, `bottom`
比如替换 Page 插件的图标和对齐位置
```js
// registry.js
+import { META_APP } from '@opentiny/tiny-engine-meta-register'
export default {
// ...
- plugins: [
- // ...
- {
- ...Page,
- title: '定制页面插件位置',
- icon: 'box',
- align: 'bottom'
- }
- // ...
- ]
+ [META_APP.AppManage]: {
+ title: '定制页面插件位置',
+ icon: 'box'
+ }
// ...
}
```
@@ -40,14 +34,13 @@ export default {
```js
// registry.js
+import { META_APP } from '@opentiny/tiny-engine-meta-register'
import CustomPage from './custom-page'
export default {
// ...
- plugins: [
- // ...
- { ...Page, entry: CustomPage }
- // ...
- ]
+ [META_APP.AppManage]: {
+ entry: CustomPage
+ }
// ...
}
```
diff --git a/docs/extension-capabilities-tutorial/mcpService.md b/docs/extension-capabilities-tutorial/mcpService.md
new file mode 100644
index 0000000000..bb54fb0b5e
--- /dev/null
+++ b/docs/extension-capabilities-tutorial/mcpService.md
@@ -0,0 +1,697 @@
+# MCP 服务扩展能力
+
+## 概述
+
+MCP (Model Context Protocol) 服务是 tiny-engine 智能化的核心扩展能力之一,它基于 [Model Context Protocol](https://modelcontextprotocol.io/introduction) 标准协议,提供了工具(Tools)的管理和执行能力。
+
+关于 MCP 协议的详细介绍,请参考官方文档:[https://modelcontextprotocol.io/introduction](https://modelcontextprotocol.io/introduction)
+
+## 快速开始
+
+### 基本使用
+
+```typescript
+import { getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register'
+import type { ToolItem } from '@opentiny/tiny-engine-common'
+import { z } from 'zod'
+
+// 获取 MCP 服务实例
+const mcpService = getMetaApi(META_SERVICE.McpService)
+
+// 注册一个简单的工具
+const helloTool: ToolItem = {
+ name: 'hello_world',
+ title: 'Hello World 工具',
+ description: '一个简单的问候工具',
+ inputSchema: {
+ name: z.string().optional()
+ },
+ outputSchema: {
+ content: z.string()
+ },
+ annotations: {
+ readOnlyHint: true,
+ destructiveHint: false,
+ idempotentHint: true,
+ openWorldHint: false
+ },
+ callback: async (params) => {
+ return { content: `Hello, ${params.name || 'World'}!` }
+ }
+}
+
+// 注册工具
+mcpService.registerTool(helloTool)
+
+// 获取工具列表
+const toolList = mcpService.getToolList()
+console.log('已注册的工具:', toolList)
+```
+
+### 高级配置
+
+```typescript
+// 配置 MCP 服务选项
+const mcpOptions = {
+ proxyUrl: 'https://your-agent-server.com/mcp',
+ connectToAgentServer: true,
+ reconnectAttempts: 5,
+ reconnectInterval: 2000
+}
+
+// 通过 setOptions 设置自定义配置
+const mcpService = getMetaApi('engine.service.mcp')
+mcpService.setOptions(mcpOptions)
+```
+
+## API 参考
+
+### 服务配置接口
+
+```typescript
+interface IOptions {
+ // 代理服务器 URL,用于连接远程 Agent 服务器
+ proxyUrl: string | null
+
+ // 是否连接到 Agent 服务器
+ connectToAgentServer: boolean
+
+ // 重连尝试次数(默认:3)
+ reconnectAttempts?: number
+
+ // 重连间隔时间,毫秒(默认:1000)
+ reconnectInterval?: number
+}
+```
+
+### 工具定义接口
+
+```typescript
+interface ToolItem {
+ // 工具唯一标识符
+ name: string
+
+ // 工具显示名称
+ title?: string
+
+ // 工具描述
+ description?: string
+
+ // 输入参数 schema(Zod)
+ inputSchema?: ZodRawShape
+
+ // 输出结果 schema(Zod)
+ outputSchema?: ZodRawShape
+
+ // 工具注解信息
+ annotations?: ToolAnnotations
+
+ // 工具执行回调函数
+ callback: ToolCallback
+}
+```
+
+### 连接状态类型
+
+```typescript
+type ServerConnectionStatus =
+ | 'connected' // 已连接
+ | 'disconnected' // 已断开
+ | 'connecting' // 连接中
+ | 'disconnecting' // 断开中
+ | 'error' // 连接错误
+```
+
+### 主要 API 方法
+
+#### 服务器管理
+
+```typescript
+// 获取 MCP 服务器实例
+getMcpServer(): McpServer | null
+
+// 获取 MCP 客户端实例
+getMcpClient(): Client | null
+
+// 获取远程传输实例
+getRemoteTransport(): any
+
+// 获取服务器连接状态
+getServerConnectionStatus(): ServerConnectionStatus
+```
+
+#### 连接管理
+
+```typescript
+// 连接到远程服务器(遥控端)
+connectToRemoteServer(): Promise
+
+// 重新连接到远程服务器(遥控端)
+reconnectToRemoteServer(): Promise
+
+// 关闭远程服务器连接(遥控端)
+closeRemoteServer(): Promise
+
+// 关闭传输连接(遥控端)
+closeTransport(): Promise
+```
+
+#### 工具管理
+
+```typescript
+// 注册工具
+registerTool(tool: ToolItem): void
+
+// 获取所有工具列表
+getToolList(): ToolItem[]
+
+// 根据名称获取工具
+getToolByName(name: string): ToolItem | undefined
+
+// 获取工具实例
+getToolInstance(name: string): RegisteredTool | undefined
+
+// 启用工具
+enableTool(name: string): void
+
+// 禁用工具
+disableTool(name: string): void
+
+// 移除工具
+removeTool(name: string): void
+
+// 更新工具配置
+updateTool(name: string, config?: UpdateToolConfig): void
+```
+
+## 工具管理详解
+
+### 工具注册
+
+工具注册是 MCP 服务的核心功能。每个工具都需要定义清晰的接口和回调函数:
+
+```typescript
+import { z } from 'zod'
+import { getMetaApi } from '@opentiny/tiny-engine-meta-register'
+
+// 定义工具的输入 schema
+const calculateInputSchema = {
+ operation: z.enum(['add', 'subtract', 'multiply', 'divide']),
+ a: z.number(),
+ b: z.number()
+}
+
+// 定义工具的输出 schema
+const calculateOutputSchema = {
+ result: z.number(),
+ operation: z.string()
+}
+
+// 创建计算器工具
+const calculatorTool: ToolItem = {
+ name: 'calculator',
+ title: '数学计算器',
+ description: '执行基本的数学运算',
+ inputSchema: calculateInputSchema,
+ outputSchema: calculateOutputSchema,
+ callback: async (params) => {
+ const { operation, a, b } = params
+
+ let result: number
+ switch (operation) {
+ case 'add':
+ result = a + b
+ break
+ case 'subtract':
+ result = a - b
+ break
+ case 'multiply':
+ result = a * b
+ break
+ case 'divide':
+ if (b === 0) {
+ throw new Error('除数不能为零')
+ }
+ result = a / b
+ break
+ default:
+ throw new Error('不支持的操作')
+ }
+
+ return {
+ result,
+ operation: `${a} ${operation} ${b} = ${result}`
+ }
+ }
+}
+
+// 获取 MCP 服务并注册工具
+const mcpService = getMetaApi('engine.service.mcp')
+mcpService.registerTool(calculatorTool)
+```
+
+### 工具生命周期管理
+
+```typescript
+import { getMetaApi } from '@opentiny/tiny-engine-meta-register'
+
+const mcpService = getMetaApi('engine.service.mcp')
+
+// 检查工具是否存在
+const tool = mcpService.getToolByName('calculator')
+if (tool) {
+ console.log('工具已存在:', tool.title)
+}
+
+// 临时禁用工具
+mcpService.disableTool('calculator')
+
+// 重新启用工具
+mcpService.enableTool('calculator')
+
+// 更新工具配置
+mcpService.updateTool('calculator', {
+ description: '更新后的计算器描述',
+ title: '高级计算器'
+})
+
+// 移除工具
+mcpService.removeTool('calculator')
+```
+
+### 批量工具注册
+
+```typescript
+// 从注册表中自动收集工具
+// MCP 服务会自动扫描所有注册的 meta 数据中的 mcp.tools 字段
+
+// 在插件的 meta 数据中定义工具
+const pluginMeta = {
+ mcp: {
+ tools: [
+ {
+ name: 'file_reader',
+ title: '文件读取器',
+ description: '读取文件内容',
+ callback: async (params) => {
+ // 实现文件读取逻辑
+ return { content: '文件内容' }
+ }
+ },
+ {
+ name: 'data_processor',
+ title: '数据处理器',
+ description: '处理数据',
+ callback: async (params) => {
+ // 实现数据处理逻辑
+ return { processed: true }
+ }
+ }
+ ]
+ }
+}
+
+// 工具会在服务初始化时自动注册
+```
+
+## 连接管理详解
+
+### 连接状态监控
+
+```typescript
+import { useMessage } from '@opentiny/tiny-engine-meta-register'
+import { getMetaApi } from '@opentiny/tiny-engine-meta-register'
+
+// 监听连接状态变化
+const { subscribe } = useMessage()
+
+subscribe({
+ topic: 'serverConnectionStatusChanged',
+ callback: ({ status, error }) => {
+ console.log('连接状态变化:', status)
+
+ switch (status) {
+ case 'connecting':
+ console.log('正在连接到服务器...')
+ break
+ case 'connected':
+ console.log('已成功连接到服务器')
+ break
+ case 'disconnected':
+ console.log('与服务器断开连接')
+ break
+ case 'error':
+ console.error('连接错误:', error)
+ break
+ }
+ }
+})
+
+// 获取当前连接状态
+const mcpService = getMetaApi('engine.service.mcp')
+const currentStatus = mcpService.getServerConnectionStatus()
+console.log('当前连接状态:', currentStatus)
+```
+
+### 手动连接管理
+
+```typescript
+import { getMetaApi } from '@opentiny/tiny-engine-meta-register'
+
+const mcpService = getMetaApi('engine.service.mcp')
+
+// 手动连接到远程服务器
+try {
+ await mcpService.connectToRemoteServer()
+ console.log('连接成功')
+} catch (error) {
+ console.error('连接失败:', error)
+}
+
+// 重新连接(会先断开现有连接)
+try {
+ await mcpService.reconnectToRemoteServer()
+ console.log('重连成功')
+} catch (error) {
+ console.error('重连失败:', error)
+}
+
+// 关闭连接
+await mcpService.closeRemoteServer()
+```
+
+### 会话持久化
+
+MCP 服务支持会话持久化,确保页面刷新后能够恢复连接:
+
+```typescript
+// 会话 ID 会自动保存到 sessionStorage
+// 页面刷新后会尝试使用相同的会话 ID 重新连接
+
+// 手动获取当前会话 ID
+const sessionId = sessionStorage.getItem('mcp-session-id')
+console.log('当前会话 ID:', sessionId)
+
+// 清除会话(强制创建新会话)
+sessionStorage.removeItem('mcp-session-id')
+```
+
+## 配置选项详解
+
+### 基本配置
+
+```typescript
+import { getMetaApi } from '@opentiny/tiny-engine-meta-register'
+
+const mcpService = getMetaApi('engine.service.mcp')
+
+// 不连接远程服务器,仅使用本地模式
+mcpService.setOptions({
+ connectToAgentServer: false
+})
+```
+
+### 远程服务器配置
+
+```typescript
+import { getMetaApi } from '@opentiny/tiny-engine-meta-register'
+
+const mcpService = getMetaApi('engine.service.mcp')
+
+const remoteConfig = {
+ proxyUrl: 'https://api.example.com/mcp',
+ connectToAgentServer: true,
+ reconnectAttempts: 3, // 重连尝试次数
+ reconnectInterval: 1000 // 重连间隔(毫秒)
+}
+
+mcpService.setOptions(remoteConfig)
+```
+
+### 高级配置
+
+
+
+import { getMetaApi } from '@opentiny/tiny-engine-meta-register'
+
+const mcpService = getMetaApi('engine.service.mcp')
+
+const advancedConfig = {
+ proxyUrl: process.env.MCP_PROXY_URL || 'http://localhost:3000/mcp',
+ connectToAgentServer: process.env.NODE_ENV === 'production',
+ reconnectAttempts: 5,
+ reconnectInterval: 2000
+}
+
+mcpService.setOptions(advancedConfig)
+
+
+
+## 最佳实践
+
+### 1. 工具设计原则
+
+```typescript
+// ✅ 好的工具设计
+const goodTool: ToolItem = {
+ name: 'format_text', // 使用描述性的名称
+ title: '文本格式化工具', // 提供清晰的标题
+ description: '将文本格式化为指定的样式', // 详细的描述
+ inputSchema: { // 明确的输入验证
+ text: z.string().min(1),
+ format: z.enum(['uppercase', 'lowercase', 'capitalize'])
+ },
+ outputSchema: { // 明确的输出结构
+ formatted: z.string(),
+ original: z.string()
+ },
+ callback: async (params) => {
+ // 实现具体的逻辑
+ const { text, format } = params
+
+ let formatted: string
+ switch (format) {
+ case 'uppercase':
+ formatted = text.toUpperCase()
+ break
+ case 'lowercase':
+ formatted = text.toLowerCase()
+ break
+ case 'capitalize':
+ formatted = text.charAt(0).toUpperCase() + text.slice(1)
+ break
+ default:
+ formatted = text
+ }
+
+ return { formatted, original: text }
+ }
+}
+
+// ❌ 避免的设计
+const badTool: ToolItem = {
+ name: 'tool1', // 名称不够描述性
+ description: '处理文本', // 描述太模糊
+ callback: async (params) => {
+ // 没有输入验证
+ return params.text.toUpperCase() // 返回格式不一致
+ }
+}
+```
+
+### 2. 错误处理
+
+```typescript
+const robustTool: ToolItem = {
+ name: 'file_processor',
+ title: '文件处理器',
+ description: '处理各种格式的文件',
+ callback: async (params) => {
+ try {
+ // 验证输入
+ if (!params.filePath) {
+ throw new Error('文件路径不能为空')
+ }
+
+ // 执行处理逻辑
+ const result = await processFile(params.filePath)
+
+ return {
+ success: true,
+ result,
+ message: '文件处理成功'
+ }
+ } catch (error) {
+ // 统一的错误处理
+ return {
+ success: false,
+ error: error.message,
+ message: '文件处理失败'
+ }
+ }
+ }
+}
+```
+
+### 3. 异步操作处理
+
+```typescript
+const asyncTool: ToolItem = {
+ name: 'data_fetcher',
+ title: '数据获取器',
+ description: '从远程 API 获取数据',
+ callback: async (params) => {
+ const { url, timeout = 5000 } = params
+
+ // 使用 Promise.race 实现超时控制
+ const timeoutPromise = new Promise((_, reject) => {
+ setTimeout(() => reject(new Error('请求超时')), timeout)
+ })
+
+ const fetchPromise = fetch(url).then(res => res.json())
+
+ try {
+ const data = await Promise.race([fetchPromise, timeoutPromise])
+ return {
+ success: true,
+ data,
+ timestamp: Date.now()
+ }
+ } catch (error) {
+ return {
+ success: false,
+ error: error.message,
+ timestamp: Date.now()
+ }
+ }
+ }
+}
+```
+
+### 4. 资源管理
+
+```typescript
+import { getMetaApi } from '@opentiny/tiny-engine-meta-register'
+
+const mcpService = getMetaApi('engine.service.mcp')
+
+// 在页面卸载时清理资源
+window.addEventListener('beforeunload', async () => {
+ await mcpService.closeTransport()
+})
+
+// 组件卸载时清理工具
+const cleanup = () => {
+ // 移除临时工具
+ mcpService.removeTool('temporary_tool')
+
+ // 关闭连接
+ mcpService.closeRemoteServer()
+}
+```
+
+## 故障排除
+
+### 常见问题
+
+#### 1. 工具注册失败
+
+**问题**:工具注册时报错或没有生效
+
+**解决方案**:
+```typescript
+import { getMetaApi } from '@opentiny/tiny-engine-meta-register'
+
+const mcpService = getMetaApi('engine.service.mcp')
+
+// 检查工具名称是否重复
+const existingTool = mcpService.getToolByName('my_tool')
+if (existingTool) {
+ console.log('工具已存在,先移除再注册')
+ mcpService.removeTool('my_tool')
+}
+
+// 确保 callback 函数正确
+const tool: ToolItem = {
+ name: 'my_tool',
+ title: '我的工具',
+ callback: async (params) => { // 必须是 async 函数
+ return { result: 'success' } // 必须返回对象
+ }
+}
+
+mcpService.registerTool(tool)
+```
+
+#### 2. 连接失败
+
+**问题**:无法连接到远程服务器
+
+**解决方案**:
+```typescript
+import { getMetaApi, useMessage } from '@opentiny/tiny-engine-meta-register'
+
+const mcpService = getMetaApi('engine.service.mcp')
+const { subscribe } = useMessage()
+
+// 检查配置
+mcpService.setOptions({
+ proxyUrl: 'https://your-server.com/mcp', // 确保 URL 正确
+ connectToAgentServer: true
+})
+
+// 监听连接状态
+subscribe({
+ topic: 'serverConnectionStatusChanged',
+ callback: ({ status, error }) => {
+ if (status === 'error') {
+ console.error('连接错误详情:', error)
+
+ // 检查网络连接
+ if (error.message.includes('网络')) {
+ console.log('请检查网络连接')
+ }
+
+ // 检查认证
+ if (error.message.includes('401')) {
+ console.log('请检查认证配置')
+ }
+ }
+ }
+})
+```
+
+#### 3. 工具执行错误
+
+**问题**:工具执行时出现异常
+
+**解决方案**:
+```typescript
+// 添加详细的错误日志
+const debugTool: ToolItem = {
+ name: 'debug_tool',
+ callback: async (params) => {
+ console.log('工具执行开始,参数:', params)
+
+ try {
+ const result = await yourToolLogic(params)
+ console.log('工具执行成功,结果:', result)
+ return result
+ } catch (error) {
+ console.error('工具执行失败:', error)
+ console.error('错误堆栈:', error.stack)
+ throw error // 重新抛出错误以便上层处理
+ }
+ }
+}
+```
+
+## 完整示例
+
+### 综合示例
+
+TODO
+
+## 总结
+
+MCP 服务为 tiny-engine 智能化提供了强大的驱动。通过合理的增加工具、prompts 等 mcp 能力,它能够让 AI 理解TinyEngine,以及我们自定义的插件扩展,让 AI 为我们提供更加智能化的服务。
diff --git a/docs/solutions/front-backend-docker-deployment.md b/docs/solutions/front-backend-docker-deployment.md
new file mode 100644
index 0000000000..63001571c3
--- /dev/null
+++ b/docs/solutions/front-backend-docker-deployment.md
@@ -0,0 +1,57 @@
+# 前端及Java服务端docker部署
+
+## 1、环境准备
+- **工具安装**
+
+ 根据自己的linux操作系统安装docker,配置国内镜像加速,编辑/etc/docker/daemon.json文件镜像地址,如图
+
+ ```sh
+ {
+ "registry-mirrors": [
+ "https://docker.m.daocloud.io",
+ "https://mirror.iscas.ac.cn",
+ "https://docker.rainbond.cc",
+ "https://dockerproxy.cn",
+ "https://docker.udayun.com"
+ ]
+ }
+ ```
+
+ 
+
+ 编辑完成后重载配置重启docker
+ ```sh
+ sudo systemctl daemon-reload
+ sudo systemctl restart docker
+ ```
+ docker-compose安装
+ ```sh
+ sudo curl -L "https://ghproxy.com/https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
+ sudo chmod +x /usr/local/bin/docker-compose
+ ```
+- **拉取代码**
+ ```sh
+ git clone -b develop https://github.com/opentiny/tiny-engine.git
+ git clone -b develop https://github.com/opentiny/tiny-engine-backend-java.git
+ ```
+## 2、配置修改
+- **nginx配置修改**
+
+ 修改 Java 项目 /tiny-engine-backend-java/docker-deploy-data/nginx.conf 文件,如图所示将ip改为自己服务器ip或域名
+ 
+
+## 3、服务启动与停止
+
+- **服务启动**
+
+ 在 Java 项目根目录 docker-compose.yml 文件同级执行命令
+ ```sh
+ docker-compose up -d
+ ```
+- **服务停止**
+
+ ```sh
+ docker-compose stop
+ ```
+## 4、视频讲解
+- [TinyEngine实操教程(4)——前后端部署](https://www.bilibili.com/video/BV1gGgcz8Eek/?spm_id_from=333.1387.homepage.video_card.click&vd_source=ea0e34d0a465d263673f7f36dcae0edf)
\ No newline at end of file
diff --git a/docs/solutions/imgs/bundle_upload.png b/docs/solutions/imgs/bundle_upload.png
new file mode 100644
index 0000000000..886b3472d2
Binary files /dev/null and b/docs/solutions/imgs/bundle_upload.png differ
diff --git a/docs/solutions/imgs/component_create_code.png b/docs/solutions/imgs/component_create_code.png
new file mode 100644
index 0000000000..d78665185e
Binary files /dev/null and b/docs/solutions/imgs/component_create_code.png differ
diff --git a/docs/solutions/imgs/daemon.png b/docs/solutions/imgs/daemon.png
new file mode 100644
index 0000000000..d4a8523621
Binary files /dev/null and b/docs/solutions/imgs/daemon.png differ
diff --git a/docs/solutions/imgs/nginxcof.png b/docs/solutions/imgs/nginxcof.png
new file mode 100644
index 0000000000..0db211b8c8
Binary files /dev/null and b/docs/solutions/imgs/nginxcof.png differ
diff --git a/docs/solutions/material-sync-solution.md b/docs/solutions/material-sync-solution.md
index 3a7cda1cc4..2e1343eb15 100644
--- a/docs/solutions/material-sync-solution.md
+++ b/docs/solutions/material-sync-solution.md
@@ -1,10 +1,24 @@
## 物料同步方案
+### 方案一 (推荐使用)
+通过前端脚本上传编辑好的bundle.json文件。
+```shell
+pnpm uploadMaterials
+```
+
+#### 注意事项
+1. bundle.json文件内组件版本version字段为必须字段,缺少的需要补充不然上传接口报错
+2. bundle.json文件内组件版本version与数据库t_component内version不一致时为新增,一致为更新,也可根据自身需求更改相关代码逻辑
+3. .env.local中配置访问后端接口的路径,默认java后端路径
+
+
+
+### 方案二
由于当前情况下物料无法通过页面交互维护,提供一个临时方案,由前端托管物料。
在本地运行时提供nodejs脚本维护物料,执行脚本保证mockServer工程和前端工程物料的同步。如果启动了后端服务,还可以连接数据库,保证本地json文件和数据库的一致性。

-### 拆分脚本
+#### 拆分脚本
```shell
pnpm splitMaterials
@@ -13,7 +27,7 @@ pnpm splitMaterials
之前对物料的修改要先从大文件bundle.json中找到对应组件,然后进行修改调试,很容易出现找错组件或难以对比历史的情况。
执行该脚本可以将物料资产包拆分为单个组件或区块,再结合构建的脚本,可以将修改限制在相对较小的文件中,便于维护物料和对比变更。
-### 构建脚本
+#### 构建脚本
```shell
pnpm buildMaterials
@@ -26,14 +40,15 @@ pnpm buildMaterials
- 连接数据库,初始化组件表,将组件数据写入数据库
- 监听组件文件变化,重新构建物料资产包和应用 mock 数据,新增或更新数据库中组件数据
-### 注意事项
+#### 注意事项
1. 本地还没有执行过拆分脚本的,先执行一次,后续可以不用再执行,只需要对单个组件进行维护
2. 单个组件文件需要遵循物料协议,更新文件后保存即可触发重新构建物料资产包,刷新页面后生效
3. 连接数据库失败,不影响构建本地物料资产包即bundle.json
4. 连接数据库需要的配置项在`.env.local`中
+5. 数据关联关系可能没有入库,如果查询不到新添加的组件,需要手动在数据库表r_material_component、r_material_history_component添加关联关系数据
-### 部署建议
+#### 部署建议
需要将设计器进行部署时,关于物料的部署方案,以下供参考:
diff --git a/docs/tutorials/issue-1-2023.10.27.md b/docs/tutorials/issue-1-2023.10.27.md
index 9e1e585c68..f2cb7562fe 100644
--- a/docs/tutorials/issue-1-2023.10.27.md
+++ b/docs/tutorials/issue-1-2023.10.27.md
@@ -34,20 +34,20 @@
答:先简要介绍一下我们工程中主要的 package:
```js
- |_ canvas 负责中间画布渲染
- |_ common 公共的组件以及 metaComponent
- |_ controller 公共逻辑控制层
- |_ design-core 总入口
- |_ http 负责 http 相关请求
- |_ i18n lowcode-i18n 包裹层
- |_ plugins 左侧面板相关插件
- |_ settings 右侧设置面板相关组件
- |_ svgs svg 封装组件
- |_ theme 主题相关样式
- |_ toolbars 顶部工具栏相关 package
- |_ utils 公共utils
- |_ vue-generator 出码package
- |_ webcomponent webcomponent 封装
+ |_ canvas 负责中间画布渲染
+ |_ common 公共的组件以及 metaComponent
+ |_ controller 公共逻辑控制层
+ |_ design-core 总入口
+ |_ http 负责 http 相关请求
+ |_ i18n lowcode-i18n 包裹层
+ |_ plugins 左侧面板相关插件
+ |_ settings 右侧设置面板相关组件
+ |_ svgs svg 封装组件
+ |_ theme 主题相关样式
+ |_ toolbars 顶部工具栏相关 package
+ |_ utils 公共utils
+ |_ vue-generator 出码package
+ |_ webcomponent webcomponent 封装
```
区域大致职责划分:
@@ -61,8 +61,8 @@
1、资源请求
```js
-// packages/design-core/src/App.vue
-// 这里发起请求物料、请求数据源、请求页面等相关资源请求,很关键
+// packages/design-core/src/App.vue
+// 这里发起请求物料、请求数据源、请求页面等相关资源请求,很关键
useResource().fetchResource()
```
@@ -70,49 +70,49 @@ useResource().fetchResource()
```js
packages
- |_ canvas
- |_ src
- |_ components
- |_ render
- |_ runner.js # 用于画布相关的资源请求,预设
- |_ RenderMain.js # 画布渲染的入口,同时也暴露了许多 api 供修改 schema
- |_ render.js # RenderMain.js 会调用该文件的 renderer 方法,递归渲染 schema
+ |_ canvas
+ |_ src
+ |_ components
+ |_ render
+ |_ runner.js # 用于画布相关的资源请求,预设
+ |_ RenderMain.js # 画布渲染的入口,同时也暴露了许多 api 供修改 schema
+ |_ render.js # RenderMain.js 会调用该文件的 renderer 方法,递归渲染 schema
```
3、画布选中后,如何关联渲染右侧属性面板?
```js
-// DesignCanvas.vue
-
-// 画布中节点选中后,会触发该方法
-const nodeSelected = (node, parent, type) => {
- const { toolbars } = useLayout().layoutState
- if (type !== 'clickTree') {
- useLayout().closePlugin()
- }
- // 动态计算该方法需要渲染的 属性面板
- useProperties().getProps(node, parent)
- // 设置当前 schema
- useCanvas().setCurrentSchema(node)
- footData.value = getNodePath(node?.id)
- toolbars.visiblePopover = false
+// DesignCanvas.vue
+
+// 画布中节点选中后,会触发该方法
+const nodeSelected = (node, parent, type) => {
+ const { toolbars } = useLayout().layoutState
+ if (type !== 'clickTree') {
+ useLayout().closePlugin()
+ }
+ // 动态计算该方法需要渲染的 属性面板
+ useProperties().getProps(node, parent)
+ // 设置当前 schema
+ useCanvas().setCurrentSchema(node)
+ footData.value = getNodePath(node?.id)
+ toolbars.visiblePopover = false
}
```
- ```js
-// settings/props/src/Main.vue
+ ```vue
+// settings/props/src/Main.vue
-
-
-
-
-
+
+
+
+
+
```
@@ -130,7 +130,7 @@ const { properties } = useProperty({ pageState })
可以拉下来源代码,按照原来静态资源图片等分类,放置进去要用的图片,在开发设计器的时候可以直接使用。
- 页面运行态:
-可以通过 标签选中你要的静态资源,这部分的逻辑完全取决于用户
+可以通过 标签选中你要的静态资源,这部分的逻辑完全取决于用户
- 页面设计态:
低代码引擎在开源之前是有这样的功能的,但是为了开源的合规,屏蔽了该功能。因为在设计态想用到静态资源的话,要选中静态资源,并上传到公司的文件管理系统,然后文件系统返回静态资源地址,然后再展示在画布中。如果用户想要这样的功能,只需要开发一个文件上传按钮,并把上传的内容放置用户的文件管理系统。
@@ -141,26 +141,26 @@ const { properties } = useProperty({ pageState })
以下为 bundle.json 这个文件的节选:
```json
-{ "property": "text",
- "label": {
- "text": {
- "zh_CN": "按钮名称",
- "en_US": "Button Name"
- }
- },
- "required": true,
- "readOnly": false,
- "disabled": false,
- "cols": 12,
- "widget": {
- "component": "MetaBindI18n",
- "props": {}
- },
- "description": {
- "zh_CN": "按钮名称",
- "en_US": "Name of the button."
- }
- }
+{ "property": "text",
+ "label": {
+ "text": {
+ "zh_CN": "按钮名称",
+ "en_US": "Button Name"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "MetaBindI18n",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "按钮名称",
+ "en_US": "Name of the button."
+ }
+ }
```
### 问题9:在使用 TinyEngine 低代码引擎后,组件之间应该如何联动?
@@ -192,10 +192,10 @@ const { properties } = useProperty({ pageState })
答:AI 能力目前已经在 TinyEngine 官网部署,当前采用的大模型是文心一言,通过 AI生成代码->生成 AST->页面 schema->展示在页面->下载源代码 ,后续会切回华为的盘古大模型。现在 AI 能力的取决于文心一言生成的代码。同时我们也通过数据和资源的不断投入在持续训练我们的 AI 能力,大家敬请期待 AI 能力的持续迭代。
-### 问题6:TinyEngine 低代码引擎是否支持 nuxt.js 作为后端的开发?
+### 问题6:TinyEngine 低代码引擎是否支持 nuxt.js 作为后端的开发?
答:后端的开发与技术栈无关,是可以采用任意的技术栈的。我们提供了所有后端接口的文档,只需要按照设计器的文档来,给出对应接口的出入参即可。
### 问题7:目前 TinyEngine 低代码引擎的物料平台是否会开源?
-答:TinyEngine 目前是用到的物料是已开源的 TinyVue 组件库,欢迎大家使用~
\ No newline at end of file
+答:TinyEngine 目前是用到的物料是已开源的 TinyVue 组件库,欢迎大家使用~
diff --git a/logo.svg b/logo.svg
index 429ef19d5d..550ca5ac10 100644
--- a/logo.svg
+++ b/logo.svg
@@ -1,10 +1,15 @@
\ No newline at end of file
diff --git a/mockServer/package.json b/mockServer/package.json
index b9e3af7a4d..fc51eb47a3 100644
--- a/mockServer/package.json
+++ b/mockServer/package.json
@@ -1,6 +1,6 @@
{
"name": "@opentiny/tiny-engine-mock",
- "version": "2.7.0",
+ "version": "2.9.0",
"publishConfig": {
"access": "public"
},
diff --git a/mockServer/src/assets/json/appinfo.json b/mockServer/src/assets/json/appinfo.json
index 8642dbbf1a..9aca3c9a4a 100644
--- a/mockServer/src/assets/json/appinfo.json
+++ b/mockServer/src/assets/json/appinfo.json
@@ -1684,21 +1684,6 @@
"created_at": "2022-07-01T03:21:19.000Z",
"updated_at": "2022-07-01T03:21:19.000Z"
},
- {
- "id": 146,
- "name": "npm",
- "type": "function",
- "content": {
- "type": "JSFunction",
- "value": "''"
- },
- "app": 1,
- "category": "utils",
- "created_by": null,
- "updated_by": null,
- "created_at": "2022-08-29T06:54:02.000Z",
- "updated_at": "2023-01-05T01:00:52.000Z"
- },
{
"id": 102,
"name": "Pager",
diff --git a/mockServer/src/mock/get/app-center/apps/extension/list.json b/mockServer/src/mock/get/app-center/apps/extension/list.json
index 5b50e93108..87f2cbde9c 100644
--- a/mockServer/src/mock/get/app-center/apps/extension/list.json
+++ b/mockServer/src/mock/get/app-center/apps/extension/list.json
@@ -66,19 +66,6 @@
"created_at": "2022-07-01T03:21:19.000Z",
"updated_at": "2022-07-01T03:21:19.000Z"
},
- {
- "id": 146,
- "name": "npm",
- "type": "function",
- "content": {
- "type": "JSFunction",
- "value": "''"
- },
- "app": 1,
- "category": "utils",
- "created_at": "2022-08-29T06:54:02.000Z",
- "updated_at": "2023-01-05T01:00:52.000Z"
- },
{
"id": 102,
"name": "Pager",
diff --git a/mockServer/src/mock/get/app-center/v1/apps/schema/1.json b/mockServer/src/mock/get/app-center/v1/apps/schema/1.json
index 96b7617b9b..9240b466b8 100644
--- a/mockServer/src/mock/get/app-center/v1/apps/schema/1.json
+++ b/mockServer/src/mock/get/app-center/v1/apps/schema/1.json
@@ -2015,6 +2015,48 @@
"destructuring": true,
"version": "3.20.0"
},
+ {
+ "componentName": "TinyRate",
+ "package": "@opentiny/vue",
+ "exportName": "TinyRate",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinySlider",
+ "package": "@opentiny/vue",
+ "exportName": "TinySlider",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinyCascader",
+ "package": "@opentiny/vue",
+ "exportName": "TinyCascader",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinySteps",
+ "package": "@opentiny/vue",
+ "exportName": "TinySteps",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinyTreeMenu",
+ "package": "@opentiny/vue",
+ "exportName": "TinyTreeMenu",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinyRadioGroup",
+ "package": "@opentiny/vue",
+ "exportName": "TinyRadioGroup",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
{
"componentName": "ElInput",
"package": "element-plus",
@@ -2057,6 +2099,118 @@
"destructuring": true,
"version": "2.4.2"
},
+ {
+ "componentName": "TinyProgress",
+ "package": "@opentiny/vue",
+ "exportName": "TinyProgress",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinySkeleton",
+ "package": "@opentiny/vue",
+ "exportName": "TinySkeleton",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinyCard",
+ "package": "@opentiny/vue",
+ "exportName": "TinyCard",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinyCalendar",
+ "package": "@opentiny/vue",
+ "exportName": "TinyCalendar",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinyBadge",
+ "package": "@opentiny/vue",
+ "exportName": "TinyBadge",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinyTag",
+ "package": "@opentiny/vue",
+ "exportName": "TinyTag",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinyStatistic",
+ "package": "@opentiny/vue",
+ "exportName": "TinyStatistic",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinyHuichartsFunnel",
+ "package": "@opentiny/vue-huicharts",
+ "exportName": "TinyHuichartsFunnel",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinyHuichartsScatter",
+ "package": "@opentiny/vue-huicharts",
+ "exportName": "TinyHuichartsScatter",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinyHuichartsWaterfall",
+ "package": "@opentiny/vue-huicharts",
+ "exportName": "TinyHuichartsWaterfall",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinyHuichartsLine",
+ "package": "@opentiny/vue-huicharts",
+ "exportName": "TinyHuichartsLine",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinyHuichartsHistogram",
+ "package": "@opentiny/vue-huicharts",
+ "exportName": "TinyHuichartsHistogram",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinyHuichartsPie",
+ "package": "@opentiny/vue-huicharts",
+ "exportName": "TinyHuichartsPie",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinyHuichartsBar",
+ "package": "@opentiny/vue-huicharts",
+ "exportName": "TinyHuichartsBar",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinyHuichartsRing",
+ "package": "@opentiny/vue-huicharts",
+ "exportName": "TinyHuichartsRing",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
+ {
+ "componentName": "TinyHuichartsRadar",
+ "package": "@opentiny/vue-huicharts",
+ "exportName": "TinyHuichartsRadar",
+ "destructuring": true,
+ "version": "3.22.0"
+ },
{
"componentName": "PortalHome",
"main": "common/components/home",
@@ -2137,14 +2291,6 @@
"main": ""
}
},
- {
- "name": "npm",
- "type": "function",
- "content": {
- "type": "JSFunction",
- "value": "''"
- }
- },
{
"name": "Pager",
"type": "npm",
diff --git a/package.json b/package.json
index 290df88e42..5e101abe25 100644
--- a/package.json
+++ b/package.json
@@ -20,7 +20,8 @@
"setup": "node ./scripts/setup.js",
"splitMaterials": "node ./scripts/splitMaterials.mjs",
"buildMaterials": "node ./scripts/buildMaterials.mjs",
- "updateTemplate": "node ./scripts/updateTemplate.mjs"
+ "updateTemplate": "node ./scripts/updateTemplate.mjs",
+ "uploadMaterials": "node scripts/uploadMaterials.mjs"
},
"devDependencies": {
"@eslint/js": "^8.57.1",
@@ -55,7 +56,7 @@
},
"pnpm": {
"patchedDependencies": {
- "@vue/repl@2.9.0": "patches/@vue__repl@2.9.0.patch"
+ "@vue/repl@4.6.1": "patches/@vue__repl@4.6.1.patch"
},
"overrides": {
"rollup": "~4.44.0"
diff --git a/packages/block-compiler/package.json b/packages/block-compiler/package.json
index 6069be67e6..1dc770dd0d 100644
--- a/packages/block-compiler/package.json
+++ b/packages/block-compiler/package.json
@@ -1,6 +1,6 @@
{
"name": "@opentiny/tiny-engine-block-compiler",
- "version": "2.7.0",
+ "version": "2.9.0",
"publishConfig": {
"access": "public"
},
diff --git a/packages/build/vite-config/package.json b/packages/build/vite-config/package.json
index 830e776236..0443a2e95c 100644
--- a/packages/build/vite-config/package.json
+++ b/packages/build/vite-config/package.json
@@ -1,6 +1,6 @@
{
"name": "@opentiny/tiny-engine-vite-config",
- "version": "2.7.0",
+ "version": "2.9.0",
"description": "",
"type": "module",
"main": "./index.js",
diff --git a/packages/build/vite-config/src/canvas-dev-external.js b/packages/build/vite-config/src/canvas-dev-external.js
index 464f11d7f6..86db5844fc 100644
--- a/packages/build/vite-config/src/canvas-dev-external.js
+++ b/packages/build/vite-config/src/canvas-dev-external.js
@@ -1,37 +1,38 @@
import vitePluginExternalize from 'vite-plugin-externalize-dependencies'
import { genImportMapPlugin } from './vite-plugins/genImportMapOnly.js'
-export function canvasDevExternal(override = {}) {
- const prefix = '/node_modules/@opentiny/tiny-engine'
- // 以下内容由于区块WebComponent加载需要补充
- const blockRequire = {
- externals: [/^@opentiny\/vue$/, /^@opentiny\/vue-icon$/],
+export const prefix = '/node_modules/@opentiny/tiny-engine'
+export const dependencies = {
+ base: {
imports: {
- '@opentiny/vue': `${prefix}/node_modules/@opentiny/vue-runtime/dist3/tiny-vue-pc.mjs`,
- '@opentiny/vue-icon': `${prefix}/node_modules/@opentiny/vue-runtime/dist3/tiny-vue-icon.mjs`
+ vue: `${prefix}/node_modules/vue/dist/vue.runtime.esm-browser.js`,
+ 'vue-i18n': `${prefix}/node_modules/vue-i18n/dist/vue-i18n.esm-browser.js`
},
- importStyles: [`${prefix}/node_modules/@opentiny/vue-theme/index.css`]
- }
- // 以下内容由于物料协议不支持声明子依赖而@opentiny/vue需要依赖所以需要补充
- const tinyVueRequire = {
+ externals: [/^vue$/, /^vue-i18n$/]
+ },
+ ui: {
imports: {
+ '@opentiny/vue': `${prefix}/node_modules/@opentiny/vue-runtime/dist3/tiny-vue-pc.mjs`,
+ '@opentiny/vue-icon': `${prefix}/node_modules/@opentiny/vue-runtime/dist3/tiny-vue-icon.mjs`,
'@opentiny/vue-common': `${prefix}/node_modules/@opentiny/vue-runtime/dist3/tiny-vue-common.mjs`,
'@opentiny/vue-locale': `${prefix}/node_modules/@opentiny/vue-runtime/dist3/tiny-vue-locale.mjs`
- }
+ },
+ externals: [/^@opentiny\/vue$/, /^@opentiny\/vue-icon$/, /^@opentiny\/vue-common$/, /^@opentiny\/vue-locale$/],
+ importStyles: [`${prefix}/node_modules/@opentiny/vue-theme/index.css`]
}
+}
+export function canvasDevExternal(override = {}) {
return [
- vitePluginExternalize({ externals: [/^vue$/, /^vue-i18n$/, ...blockRequire.externals] }),
+ vitePluginExternalize({ externals: [...dependencies.base.externals, ...dependencies.ui.externals] }),
genImportMapPlugin(
{
imports: {
- vue: `${prefix}/node_modules/vue/dist/vue.runtime.esm-browser.js`,
- 'vue-i18n': `${prefix}/node_modules/vue-i18n/dist/vue-i18n.esm-browser.js`,
- ...blockRequire.imports,
- ...tinyVueRequire.imports,
+ ...dependencies.base.imports,
+ ...dependencies.ui.imports,
...override
}
},
- [...blockRequire.importStyles]
+ [...dependencies.ui.importStyles]
)
]
}
diff --git a/packages/build/vite-config/src/default-config.js b/packages/build/vite-config/src/default-config.js
index d58b02cf8a..010bf4e148 100644
--- a/packages/build/vite-config/src/default-config.js
+++ b/packages/build/vite-config/src/default-config.js
@@ -6,15 +6,15 @@ import vueJsx from '@vitejs/plugin-vue-jsx'
import nodeGlobalsPolyfillPluginCjs from '@esbuild-plugins/node-globals-polyfill'
import nodeModulesPolyfillPluginCjs from '@esbuild-plugins/node-modules-polyfill'
import nodePolyfill from 'rollup-plugin-polyfill-node'
-import esbuildCopy from 'esbuild-plugin-copy'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import visualizerCjs from 'rollup-plugin-visualizer'
import generateComment from '@opentiny/tiny-engine-vite-plugin-meta-comments'
import { getBaseUrlFromCli, copyBundleDeps, importMapLocalPlugin } from './localCdnFile/index.js'
import { devAliasPlugin } from './vite-plugins/devAliasPlugin.js'
import { htmlUpgradeHttpsPlugin } from './vite-plugins/upgradeHttpsPlugin.js'
-import { canvasDevExternal } from './canvas-dev-external.js'
import { treeShakingPlugin } from './vite-plugins/treeShakingPlugin.js'
+import { canvasDevExternal } from './canvas-dev-external.js'
+import { runtimeExternal } from './runtime-external.js'
const monacoEditorPlugin = monacoEditorPluginCjs.default
const nodeGlobalsPolyfillPlugin = nodeGlobalsPolyfillPluginCjs.default
@@ -78,25 +78,21 @@ const getDefaultConfig = (engineConfig) => {
vueJsx()
],
optimizeDeps: {
+ // 避免 @vue/repl 的 monaco-editor 等依赖被优化掉
+ exclude: ['@vue/repl'],
esbuildOptions: {
plugins: [
nodeGlobalsPolyfillPlugin({
process: true,
buffer: true
}),
- nodeModulesPolyfillPlugin(),
- esbuildCopy({
- //@vue/repl monaco编辑器需要
- resolveFrom: 'cwd',
- assets: {
- from: ['./node_modules/@vue/repl/dist/assets/*'], // worker.js文件以url形式引用不会被esbuild拉起,需要手动复制
- to: ['./node_modules/.vite/assets'] // 开发态,js文件被缓存在.vite/deps,请求相对路径为.vite/assets
- },
- watch: true
- })
+ nodeModulesPolyfillPlugin()
]
}
},
+ define: {
+ 'process.env': {}
+ },
build: {
commonjsOptions: {
transformMixedEsModules: true,
@@ -193,5 +189,9 @@ export function useTinyEngineBaseConfig(engineConfig) {
config.plugins.push(canvasDevExternal())
}
+ if (engineConfig.useSourceAlias && command !== 'serve') {
+ config.plugins.push(runtimeExternal())
+ }
+
return config
}
diff --git a/packages/build/vite-config/src/runtime-external.js b/packages/build/vite-config/src/runtime-external.js
new file mode 100644
index 0000000000..d051137f3a
--- /dev/null
+++ b/packages/build/vite-config/src/runtime-external.js
@@ -0,0 +1,84 @@
+import { dependencies } from './canvas-dev-external.js'
+
+/**
+ * 嵌入
+
diff --git a/packages/builtinComponent/src/components/BasePage.vue b/packages/builtinComponent/src/components/BasePage.vue
new file mode 100644
index 0000000000..5c1d0ef475
--- /dev/null
+++ b/packages/builtinComponent/src/components/BasePage.vue
@@ -0,0 +1,533 @@
+
+
+ 请选择模型
+
+
+
+
+
+
+
+ {{ item.label }}
+
+
+
+
+
+
+
+
+
+ {{ insideItem.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 新增
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ operate.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.label }}
+
+
+
+
+
+
+
+
+
+ {{ insideItem.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 取 消
+ 确 定
+
+
+
+
+
+
+
diff --git a/packages/builtinComponent/src/components/BaseTable.vue b/packages/builtinComponent/src/components/BaseTable.vue
new file mode 100644
index 0000000000..a9bb0e5c84
--- /dev/null
+++ b/packages/builtinComponent/src/components/BaseTable.vue
@@ -0,0 +1,269 @@
+
+
+ 请选择表格模型
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ operate.label }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/builtinComponent/src/components/CanvasNavigation.vue b/packages/builtinComponent/src/components/CanvasNavigation.vue
new file mode 100644
index 0000000000..181c0b14d3
--- /dev/null
+++ b/packages/builtinComponent/src/components/CanvasNavigation.vue
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
diff --git a/packages/builtinComponent/src/meta/BaseForm.json b/packages/builtinComponent/src/meta/BaseForm.json
new file mode 100644
index 0000000000..b32343d0d5
--- /dev/null
+++ b/packages/builtinComponent/src/meta/BaseForm.json
@@ -0,0 +1,1158 @@
+{
+ "component": {
+ "icon": "form",
+ "name": {
+ "zh_CN": "FormModel"
+ },
+ "component": "FormModel",
+ "schema": {
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "选择模型"
+ },
+ "description": {
+ "zh_CN": "选择模型"
+ },
+ "content": [
+ {
+ "property": "serviceModel",
+ "label": {
+ "text": {
+ "zh_CN": "选择模型"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "bindState": false,
+ "cols": 12,
+ "widget": {
+ "component": "ModelConfigurator",
+ "props": {
+ "expand": true
+ }
+ },
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "默认分组",
+ "en_US": "Default Group"
+ },
+ "content": [
+ {
+ "property": "label",
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "表单项标签",
+ "en_US": "Form Item Label"
+ }
+ },
+ "required": true,
+ "bindState": false,
+ "cols": 12,
+ "widget": {
+ "component": "I18nConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "表单项标签",
+ "en_US": "Form item's label."
+ }
+ },
+ {
+ "property": "prop",
+ "bindState": false,
+ "disabled": true,
+ "label": {
+ "text": {
+ "zh_CN": "字段名",
+ "en_US": "Field Name"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "字段名",
+ "en_US": "Name of the form field."
+ }
+ },
+ {
+ "property": "required",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "必填",
+ "en_US": "Required"
+ }
+ },
+ "required": false,
+ "bindState": true,
+ "cols": 12,
+ "widget": {
+ "component": "SwitchConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否必填",
+ "en_US": "Enable required or not."
+ }
+ },
+ {
+ "property": "rules",
+ "label": {
+ "text": {
+ "zh_CN": "校验规则",
+ "en_US": "Verification Rules"
+ }
+ },
+ "required": false,
+ "bindState": true,
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ },
+ "description": {
+ "zh_CN": "表单项校验",
+ "en_US": "Verification for form item."
+ }
+ },
+ {
+ "property": "component",
+ "type": "string",
+ "required": false,
+ "bindState": true,
+ "cols": 12,
+ "label": {
+ "text": {
+ "zh_CN": "输入类型",
+ "en_US": "Input Type"
+ }
+ },
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": {
+ "zh_CN": "输入框",
+ "en_US": "Input"
+ },
+ "value": "TinyInput"
+ },
+ {
+ "label": {
+ "zh_CN": "选择器",
+ "en_US": "Select"
+ },
+ "value": "TinySelect"
+ },
+ {
+ "label": {
+ "zh_CN": "多选框",
+ "en_US": "Checkbox"
+ },
+ "value": "TinyCheckbox"
+ },
+ {
+ "label": {
+ "zh_CN": "单选框",
+ "en_US": "Radio"
+ },
+ "value": "TinyRadio"
+ },
+ {
+ "label": {
+ "zh_CN": "日期选择器",
+ "en_US": "Date Picker"
+ },
+ "value": "TinyDatePicker"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "输入类型",
+ "en_US": "Type of the input."
+ }
+ }
+ ]
+ },
+ {
+ "componentName": "TinyInput",
+ "label": {
+ "zh_CN": "输入框",
+ "en_US": "Input"
+ },
+ "content": [
+ {
+ "property": "type",
+ "label": {
+ "text": {
+ "zh_CN": "类型"
+ }
+ },
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "textarea",
+ "value": "textarea"
+ },
+ {
+ "label": "text",
+ "value": "text"
+ },
+ {
+ "label": "password",
+ "value": "password"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "设置input框的type属性"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "rows",
+ "label": {
+ "text": {
+ "zh_CN": "行数"
+ }
+ },
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "输入框行数,只对 type='textarea' 有效"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "placeholder",
+ "label": {
+ "text": {
+ "zh_CN": "占位文本"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "I18nConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "输入框占位文本"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "clearable",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "清除按钮"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否显示清除按钮"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "disabled",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ },
+ {
+ "componentName": "TinySelect",
+ "label": {
+ "zh_CN": "选择器",
+ "en_US": "Select"
+ },
+ "content": [
+ {
+ "property": "placeholder",
+ "label": {
+ "text": {
+ "zh_CN": "占位文本"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "输入框占位文本"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "clearable",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "清除按钮"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否显示清除按钮"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "searchable",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "下拉可搜索"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "下拉面板是否可搜索"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "disabled",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "options",
+ "label": {
+ "text": {
+ "zh_CN": "选项数据"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "bindState": true,
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ },
+ "description": {
+ "zh_CN": "配置 Select 下拉数据项"
+ },
+ "labelPosition": "top"
+ },
+ {
+ "property": "multiple",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "多选"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否允许输入框输入或选择多个项"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ },
+ {
+ "componentName": "TinyDatePicker",
+ "label": {
+ "zh_CN": "日期选择器",
+ "en_US": "DatePicker"
+ },
+ "content": [
+ {
+ "property": "type",
+ "label": {
+ "text": {
+ "zh_CN": "类型"
+ }
+ },
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "日期",
+ "value": "date"
+ },
+ {
+ "label": "日期时间",
+ "value": "datetime"
+ },
+ {
+ "label": "周",
+ "value": "week"
+ },
+ {
+ "label": "月份",
+ "value": "month"
+ },
+ {
+ "label": "年份",
+ "value": "year"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "设置日期框的type属性"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "placeholder",
+ "label": {
+ "text": {
+ "zh_CN": "占位文本"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "I18nConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "输入框占位文本"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "clearable",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "清除按钮"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否显示清除按钮"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "disabled",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "readonly",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "只读"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否只读"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "format",
+ "type": "string",
+ "defaultValue": "",
+ "label": {
+ "text": {
+ "zh_CN": "格式化"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否只读"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "valueFormat",
+ "type": "string",
+ "defaultValue": "",
+ "label": {
+ "text": {
+ "zh_CN": "绑定值格式化"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "value-format"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ },
+ {
+ "componentName": "TinyRadio",
+ "label": {
+ "zh_CN": "单选框",
+ "en_US": "Radio"
+ },
+ "content": [
+ {
+ "property": "text",
+ "label": {
+ "text": {
+ "zh_CN": "文本内容"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "单选框文本内容"
+ }
+ },
+ {
+ "property": "label",
+ "label": {
+ "text": {
+ "zh_CN": "选中值"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "radio 选中时的值"
+ }
+ },
+ {
+ "property": "disabled",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ },
+ {
+ "componentName": "TinyCheckbox",
+ "label": {
+ "zh_CN": "多选框",
+ "en_US": "Checkbox"
+ },
+ "content": [
+ {
+ "property": "disabled",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "checked",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "勾选"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "当前是否勾选"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "text",
+ "label": {
+ "text": {
+ "zh_CN": "文本"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "复选框的文本"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ },
+ {
+ "componentName": "TinyNumeric",
+ "label": {
+ "zh_CN": "数组输入框",
+ "en_US": "Numeric"
+ },
+ "content": [
+ {
+ "property": "placeholder",
+ "label": {
+ "text": {
+ "zh_CN": "占位文本"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "I18nConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "输入框占位文本"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "allow-empty",
+ "label": {
+ "text": {
+ "zh_CN": "内容可清空"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否内容可清空"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "disabled",
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "size",
+ "label": {
+ "text": {
+ "zh_CN": "尺寸"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "medium",
+ "value": "medium"
+ },
+ {
+ "label": "small",
+ "value": "small"
+ },
+ {
+ "label": "mini",
+ "value": "mini"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "输入框尺寸。该属性的可选值为 medium / small / mini"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "controls",
+ "label": {
+ "text": {
+ "zh_CN": "加减按钮"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否使用加减按钮"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "controls-position",
+ "label": {
+ "text": {
+ "zh_CN": "加减按钮位置"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "左右两侧",
+ "value": ""
+ },
+ {
+ "label": "只在右侧",
+ "value": "right"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "加减按钮位置"
+ }
+ },
+ {
+ "property": "precision",
+ "label": {
+ "text": {
+ "zh_CN": "精度"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {
+ "allowEmpty": true
+ }
+ },
+ "description": {
+ "zh_CN": "数值精度"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "step",
+ "label": {
+ "text": {
+ "zh_CN": "步长"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {
+ "allowEmpty": true
+ }
+ },
+ "description": {
+ "zh_CN": "步长"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ }
+ ],
+ "labelPosition": "top"
+ },
+ {
+ "property": "modelApis",
+ "label": {
+ "text": {
+ "zh_CN": "绑定模型方法"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "bindState": false,
+ "cols": 12,
+ "widget": {
+ "component": "ModelApiConfigurator",
+ "props": {}
+ },
+ "labelPosition": "top"
+ }
+ ]
+ },
+ {
+ "label": {
+ "zh_CN": "基础信息"
+ },
+ "description": {
+ "zh_CN": "基础信息"
+ },
+ "content": [
+ {
+ "property": "layout",
+ "label": {
+ "text": {
+ "zh_CN": "表单布局",
+ "en_US": "From Layout"
+ }
+ },
+ "required": true,
+ "bindState": false,
+ "cols": 12,
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": {
+ "zh_CN": "一列布局",
+ "en_US": "One-column Layout"
+ },
+ "value": 1
+ },
+ {
+ "label": {
+ "zh_CN": "两列布局",
+ "en_US": "Two-column Layout"
+ },
+ "value": 2
+ },
+ {
+ "label": {
+ "zh_CN": "三列布局",
+ "en_US": "Three-column Layout"
+ },
+ "value": 3
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "设置表单布局",
+ "en_US": "Set the form layout."
+ }
+ },
+ {
+ "property": "size",
+ "label": {
+ "text": {
+ "zh_CN": "尺寸"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "medium",
+ "value": "medium"
+ },
+ {
+ "label": "small",
+ "value": "small"
+ },
+ {
+ "label": "mini",
+ "value": "mini"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "输入框尺寸。该属性的可选值为 medium / small / mini"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "disabled",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "禁用",
+ "en_US": "Disabled"
+ }
+ },
+ "required": false,
+ "bindState": true,
+ "cols": 12,
+ "widget": {
+ "component": "SwitchConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用",
+ "en_US": "Enable Disabled or not."
+ }
+ },
+ {
+ "property": "viewOnly",
+ "label": {
+ "text": {
+ "zh_CN": "只读",
+ "en_US": "Readonly"
+ }
+ },
+ "required": false,
+ "bindState": true,
+ "cols": 12,
+ "widget": {
+ "component": "SwitchConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "控制编辑态、查看态",
+ "en_US": "Control the editing and viewing states."
+ }
+ },
+ {
+ "property": "modelValue",
+ "label": {
+ "text": {
+ "zh_CN": "表单数据绑定变量",
+ "en_US": "Binding Variables For Form Data"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "BindVariableConfigurator",
+ "props": {
+ "defaultValue": []
+ }
+ },
+ "description": {
+ "zh_CN": "为表单数据绑定变量",
+ "en_US": "Binding Variables For Form Data."
+ }
+ }
+ ]
+ }
+ ],
+ "events": {
+ "onUpdate:modelValue": {
+ "label": {
+ "zh_CN": "绑定值改变时触发",
+ "en_US": "Binding changed Triggered"
+ },
+ "description": {
+ "zh_CN": "绑定值改变时触发",
+ "en_US": "Triggered when the value of the binding changes."
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "value",
+ "type": "array",
+ "defaultValue": [],
+ "description": {
+ "zh_CN": "双向绑定值",
+ "en_US": "Binding value."
+ }
+ }
+ ],
+ "returns": {}
+ }
+ }
+ }
+ },
+ "configure": {
+ "loop": false,
+ "condition": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": [],
+ "parentWhitelist": ""
+ }
+ }
+ },
+ "snippet": {
+ "name": {
+ "zh_CN": "表单模型",
+ "en_US": "FormModel"
+ },
+ "icon": "form",
+ "screenshot": "",
+ "snippetName": "FormModel",
+ "schema": {
+ "componentName": "FormModel",
+ "props": {}
+ }
+ }
+}
diff --git a/packages/builtinComponent/src/meta/BasePage.json b/packages/builtinComponent/src/meta/BasePage.json
new file mode 100644
index 0000000000..7e095e6f15
--- /dev/null
+++ b/packages/builtinComponent/src/meta/BasePage.json
@@ -0,0 +1,1666 @@
+{
+ "component": {
+ "icon": "form",
+ "name": {
+ "zh_CN": "PageModel"
+ },
+ "component": "PageModel",
+ "schema": {
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "选择模型"
+ },
+ "description": {
+ "zh_CN": "选择模型"
+ },
+ "content": [
+ {
+ "property": "serviceModel",
+ "label": {
+ "text": {
+ "zh_CN": "选择模型"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "bindState": false,
+ "cols": 12,
+ "widget": {
+ "component": "ModelConfigurator",
+ "props": {
+ "expand": true
+ }
+ },
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "默认分组",
+ "en_US": "Default Group"
+ },
+ "content": [
+ {
+ "property": "label",
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "表单项标签",
+ "en_US": "Form Item Label"
+ }
+ },
+ "required": true,
+ "bindState": false,
+ "cols": 12,
+ "widget": {
+ "component": "I18nConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "表单项标签",
+ "en_US": "Form item's label."
+ }
+ },
+ {
+ "property": "prop",
+ "bindState": false,
+ "disabled": true,
+ "label": {
+ "text": {
+ "zh_CN": "字段名",
+ "en_US": "Field Name"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "字段名",
+ "en_US": "Name of the form field."
+ }
+ },
+ {
+ "property": "required",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "必填",
+ "en_US": "Required"
+ }
+ },
+ "required": false,
+ "bindState": true,
+ "cols": 12,
+ "widget": {
+ "component": "SwitchConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否必填",
+ "en_US": "Enable required or not."
+ }
+ },
+ {
+ "property": "rules",
+ "label": {
+ "text": {
+ "zh_CN": "校验规则",
+ "en_US": "Verification Rules"
+ }
+ },
+ "required": false,
+ "bindState": true,
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ },
+ "description": {
+ "zh_CN": "表单项校验",
+ "en_US": "Verification for form item."
+ }
+ },
+ {
+ "property": "component",
+ "type": "string",
+ "required": false,
+ "bindState": true,
+ "cols": 12,
+ "label": {
+ "text": {
+ "zh_CN": "输入类型",
+ "en_US": "Input Type"
+ }
+ },
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": {
+ "zh_CN": "输入框",
+ "en_US": "Input"
+ },
+ "value": "TinyInput"
+ },
+ {
+ "label": {
+ "zh_CN": "选择器",
+ "en_US": "Select"
+ },
+ "value": "TinySelect"
+ },
+ {
+ "label": {
+ "zh_CN": "多选框",
+ "en_US": "Checkbox"
+ },
+ "value": "TinyCheckbox"
+ },
+ {
+ "label": {
+ "zh_CN": "单选框",
+ "en_US": "Radio"
+ },
+ "value": "TinyRadio"
+ },
+ {
+ "label": {
+ "zh_CN": "日期选择器",
+ "en_US": "Date Picker"
+ },
+ "value": "TinyDatePicker"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "输入类型",
+ "en_US": "Type of the input."
+ }
+ }
+ ]
+ },
+ {
+ "componentName": "TinyInput",
+ "label": {
+ "zh_CN": "输入框",
+ "en_US": "Input"
+ },
+ "content": [
+ {
+ "property": "type",
+ "label": {
+ "text": {
+ "zh_CN": "类型"
+ }
+ },
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "textarea",
+ "value": "textarea"
+ },
+ {
+ "label": "text",
+ "value": "text"
+ },
+ {
+ "label": "password",
+ "value": "password"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "设置input框的type属性"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "rows",
+ "label": {
+ "text": {
+ "zh_CN": "行数"
+ }
+ },
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "输入框行数,只对 type='textarea' 有效"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "placeholder",
+ "label": {
+ "text": {
+ "zh_CN": "占位文本"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "I18nConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "输入框占位文本"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "clearable",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "清除按钮"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否显示清除按钮"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "disabled",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ },
+ {
+ "componentName": "TinySelect",
+ "label": {
+ "zh_CN": "选择器",
+ "en_US": "Select"
+ },
+ "content": [
+ {
+ "property": "placeholder",
+ "label": {
+ "text": {
+ "zh_CN": "占位文本"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "输入框占位文本"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "clearable",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "清除按钮"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否显示清除按钮"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "searchable",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "下拉可搜索"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "下拉面板是否可搜索"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "disabled",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "options",
+ "label": {
+ "text": {
+ "zh_CN": "选项数据"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "bindState": true,
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ },
+ "description": {
+ "zh_CN": "配置 Select 下拉数据项"
+ },
+ "labelPosition": "top"
+ },
+ {
+ "property": "multiple",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "多选"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否允许输入框输入或选择多个项"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ },
+ {
+ "componentName": "TinyDatePicker",
+ "label": {
+ "zh_CN": "日期选择器",
+ "en_US": "DatePicker"
+ },
+ "content": [
+ {
+ "property": "type",
+ "label": {
+ "text": {
+ "zh_CN": "类型"
+ }
+ },
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "日期",
+ "value": "date"
+ },
+ {
+ "label": "日期时间",
+ "value": "datetime"
+ },
+ {
+ "label": "周",
+ "value": "week"
+ },
+ {
+ "label": "月份",
+ "value": "month"
+ },
+ {
+ "label": "年份",
+ "value": "year"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "设置日期框的type属性"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "placeholder",
+ "label": {
+ "text": {
+ "zh_CN": "占位文本"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "I18nConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "输入框占位文本"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "clearable",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "清除按钮"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否显示清除按钮"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "disabled",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "readonly",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "只读"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否只读"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "format",
+ "type": "string",
+ "defaultValue": "",
+ "label": {
+ "text": {
+ "zh_CN": "格式化"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否只读"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "valueFormat",
+ "type": "string",
+ "defaultValue": "",
+ "label": {
+ "text": {
+ "zh_CN": "绑定值格式化"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "value-format"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ },
+ {
+ "componentName": "TinyRadio",
+ "label": {
+ "zh_CN": "单选框",
+ "en_US": "Radio"
+ },
+ "content": [
+ {
+ "property": "text",
+ "label": {
+ "text": {
+ "zh_CN": "文本内容"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "单选框文本内容"
+ }
+ },
+ {
+ "property": "label",
+ "label": {
+ "text": {
+ "zh_CN": "选中值"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "radio 选中时的值"
+ }
+ },
+ {
+ "property": "disabled",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ },
+ {
+ "componentName": "TinyCheckbox",
+ "label": {
+ "zh_CN": "多选框",
+ "en_US": "Checkbox"
+ },
+ "content": [
+ {
+ "property": "disabled",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "checked",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "勾选"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "当前是否勾选"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "text",
+ "label": {
+ "text": {
+ "zh_CN": "文本"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "复选框的文本"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ },
+ {
+ "componentName": "TinyNumeric",
+ "label": {
+ "zh_CN": "数组输入框",
+ "en_US": "Numeric"
+ },
+ "content": [
+ {
+ "property": "placeholder",
+ "label": {
+ "text": {
+ "zh_CN": "占位文本"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "I18nConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "输入框占位文本"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "allow-empty",
+ "label": {
+ "text": {
+ "zh_CN": "内容可清空"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否内容可清空"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "disabled",
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "size",
+ "label": {
+ "text": {
+ "zh_CN": "尺寸"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "medium",
+ "value": "medium"
+ },
+ {
+ "label": "small",
+ "value": "small"
+ },
+ {
+ "label": "mini",
+ "value": "mini"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "输入框尺寸。该属性的可选值为 medium / small / mini"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "controls",
+ "label": {
+ "text": {
+ "zh_CN": "加减按钮"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否使用加减按钮"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "controls-position",
+ "label": {
+ "text": {
+ "zh_CN": "加减按钮位置"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "左右两侧",
+ "value": ""
+ },
+ {
+ "label": "只在右侧",
+ "value": "right"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "加减按钮位置"
+ }
+ },
+ {
+ "property": "precision",
+ "label": {
+ "text": {
+ "zh_CN": "精度"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {
+ "allowEmpty": true
+ }
+ },
+ "description": {
+ "zh_CN": "数值精度"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "step",
+ "label": {
+ "text": {
+ "zh_CN": "步长"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {
+ "allowEmpty": true
+ }
+ },
+ "description": {
+ "zh_CN": "步长"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ }
+ ],
+ "labelPosition": "top"
+ },
+ {
+ "property": "modelApis",
+ "label": {
+ "text": {
+ "zh_CN": "绑定模型方法"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "bindState": false,
+ "cols": 12,
+ "widget": {
+ "component": "ModelApiConfigurator",
+ "props": {}
+ },
+ "labelPosition": "top"
+ },
+ {
+ "property": "searchFormData",
+ "label": {
+ "text": {
+ "zh_CN": "搜索表单绑定变量",
+ "en_US": "Binding Variables For Search Form"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "BindVariableConfigurator"
+ },
+ "description": {
+ "zh_CN": "为搜索表单绑定变量",
+ "en_US": "Binding Variables For Search Form."
+ }
+ },
+ {
+ "property": "tableData",
+ "label": {
+ "text": {
+ "zh_CN": "表格数据绑定变量",
+ "en_US": "Binding Variables For Table Data"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "BindVariableConfigurator",
+ "props": {
+ "defaultValue": [],
+ "isValueArray": true
+ }
+ },
+ "description": {
+ "zh_CN": "为表格数据绑定变量",
+ "en_US": "Binding Variables For Search Form."
+ }
+ },
+ {
+ "property": "editFormData",
+ "label": {
+ "text": {
+ "zh_CN": "数据表单绑定变量",
+ "en_US": "Binding Variables For Data Form"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "BindVariableConfigurator"
+ },
+ "description": {
+ "zh_CN": "为新增数据或编辑数据表单绑定变量",
+ "en_US": "Binding Variables For Add or Edit Form."
+ }
+ }
+ ]
+ },
+ {
+ "label": {
+ "zh_CN": "基础信息"
+ },
+ "description": {
+ "zh_CN": "基础信息"
+ },
+ "content": [
+ {
+ "property": "layout",
+ "label": {
+ "text": {
+ "zh_CN": "表单布局",
+ "en_US": "From Layout"
+ }
+ },
+ "required": true,
+ "bindState": false,
+ "cols": 12,
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": {
+ "zh_CN": "一列布局",
+ "en_US": "One-column Layout"
+ },
+ "value": 1
+ },
+ {
+ "label": {
+ "zh_CN": "两列布局",
+ "en_US": "Two-column Layout"
+ },
+ "value": 2
+ },
+ {
+ "label": {
+ "zh_CN": "三列布局",
+ "en_US": "Three-column Layout"
+ },
+ "value": 3
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "设置表单布局",
+ "en_US": "Set the form layout."
+ }
+ },
+ {
+ "property": "size",
+ "label": {
+ "text": {
+ "zh_CN": "尺寸"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "medium",
+ "value": "medium"
+ },
+ {
+ "label": "small",
+ "value": "small"
+ },
+ {
+ "label": "mini",
+ "value": "mini"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "输入框尺寸。该属性的可选值为 medium / small / mini"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ },
+ {
+ "label": {
+ "zh_CN": "表格信息"
+ },
+ "description": {
+ "zh_CN": "表格信息"
+ },
+ "content": [
+ {
+ "property": "selectedEnabled",
+ "resetProps": true,
+ "label": {
+ "text": {
+ "zh_CN": "启用复选",
+ "en_US": "enable select data"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SwitchConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否允许复选框选中数据",
+ "en_US": "Whether to allow the check box to select data"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "handleSelectedRows",
+ "label": {
+ "text": {
+ "zh_CN": "处理选中数据方法",
+ "en_US": "Method of Processing Selected Data"
+ }
+ },
+ "defaultValue": {
+ "type": "JSFunction",
+ "value": "/**\r\n * 获取表格勾选数据方法\r\n * tableSelection - 表格已勾选的数据\r\n */\r\nfunction handleSelectedRows(tableSelection) {\r\n // 处理方法函数体\r\n}"
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "javascript",
+ "dataType": "JSFunction"
+ }
+ },
+ "description": {
+ "zh_CN": "处理选中数据方法",
+ "en_US": "Method of Processing Selected Data"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "rowOperationEnabled",
+ "resetProps": true,
+ "label": {
+ "text": {
+ "zh_CN": "启用行操作",
+ "en_US": "enable row operation"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SwitchConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否使用行操作",
+ "en_US": "Whether to allow the row operation"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "useIconOperation",
+ "resetProps": true,
+ "label": {
+ "text": {
+ "zh_CN": "使用图标",
+ "en_US": "use icon operation"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SwitchConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "行操作是否使用图标",
+ "en_US": "use Icon Whether to handle the row operation"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "type": "configList",
+ "property": "rowOperations",
+ "label": {
+ "text": {
+ "zh_CN": "行操作",
+ "en_US": "Row Operation"
+ }
+ },
+ "required": false,
+ "cols": 12,
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "默认分组",
+ "en_US": "Default Group"
+ },
+ "content": [
+ {
+ "property": "label",
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "文本",
+ "en_US": "Text"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "I18nConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "操作名称",
+ "en_US": "Operation's name."
+ }
+ },
+ {
+ "property": "icon",
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "图标",
+ "en_US": "Icon"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {
+ "placeholder": "请输入图标类名"
+ }
+ },
+ "description": {
+ "zh_CN": "图标库地址: https://tinyuidesign.cloudbu.huawei.com/tiny-vue/zh-CN/os-theme/components/icon#list",
+ "en_US": "Icon Library Address: https://tinyuidesign.cloudbu.huawei.com/tiny-vue/zh-CN/os-theme/components/icon#list"
+ }
+ },
+ {
+ "property": "handler",
+ "label": {
+ "text": {
+ "zh_CN": "点击回调事件",
+ "en_US": "Click Callback Event"
+ }
+ },
+ "defaultValue": {
+ "type": "JSFunction",
+ "value": "function handleRow(row, index, extendApis) {}"
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "dataType": "JSFunction"
+ }
+ },
+ "description": {
+ "zh_CN": "操作的回调函数",
+ "en_US": "Callback functions for operations."
+ }
+ }
+ ]
+ }
+ ],
+ "widget": {
+ "component": "OperatorGroupConfigurator",
+ "props": {
+ "type": "object",
+ "textField": "label",
+ "language": "json",
+ "buttonText": "编辑行操作",
+ "title": "编辑行操作",
+ "enableVisibleControl": true,
+ "disableDelete": true,
+ "expand": true,
+ "isAbleBatchOperation": true
+ }
+ },
+ "description": {
+ "zh_CN": "表格自定义行操作",
+ "en_US": "Custom operations For table's row."
+ },
+ "labelPosition": "top"
+ },
+ {
+ "property": "columnMinWidth",
+ "label": {
+ "text": {
+ "zh_CN": "表格列最小宽度",
+ "en_US": "Minimum Column Width"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "表格列最小宽度",
+ "en_US": "Minimum width of table's column."
+ }
+ },
+ {
+ "property": "columnWidth",
+ "label": {
+ "text": {
+ "zh_CN": "表格列宽度",
+ "en_US": "Column Width"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "表格列宽度",
+ "en_US": "Width of table's column."
+ }
+ }
+ ]
+ }
+ ],
+ "events": {
+ "onUpdate:modelValue": {
+ "label": {
+ "zh_CN": "绑定值改变时触发",
+ "en_US": "Binding changed Triggered"
+ },
+ "description": {
+ "zh_CN": "绑定值改变时触发",
+ "en_US": "Triggered when the value of the binding changes."
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "value",
+ "type": "array",
+ "defaultValue": [],
+ "description": {
+ "zh_CN": "双向绑定值",
+ "en_US": "Binding value."
+ }
+ }
+ ],
+ "returns": {}
+ }
+ },
+ "onUpdate:searchFormData": {
+ "label": {
+ "zh_CN": "绑定值改变时触发",
+ "en_US": "Binding changed Triggered"
+ },
+ "description": {
+ "zh_CN": "绑定值改变时触发",
+ "en_US": "Triggered when the value of the binding changes."
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "value",
+ "type": "object",
+ "defaultValue": {},
+ "description": {
+ "zh_CN": "双向绑定值",
+ "en_US": "Binding value."
+ }
+ }
+ ],
+ "returns": {}
+ }
+ },
+ "onUpdate:tableData": {
+ "label": {
+ "zh_CN": "绑定值改变时触发",
+ "en_US": "Binding changed Triggered"
+ },
+ "description": {
+ "zh_CN": "绑定值改变时触发",
+ "en_US": "Triggered when the value of the binding changes."
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "value",
+ "type": "array",
+ "defaultValue": [],
+ "description": {
+ "zh_CN": "双向绑定值",
+ "en_US": "Binding value."
+ }
+ }
+ ],
+ "returns": {}
+ }
+ },
+ "onUpdate:editFormData": {
+ "label": {
+ "zh_CN": "绑定值改变时触发",
+ "en_US": "Binding changed Triggered"
+ },
+ "description": {
+ "zh_CN": "绑定值改变时触发",
+ "en_US": "Triggered when the value of the binding changes."
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "value",
+ "type": "object",
+ "defaultValue": {},
+ "description": {
+ "zh_CN": "双向绑定值",
+ "en_US": "Binding value."
+ }
+ }
+ ],
+ "returns": {}
+ }
+ },
+ "onFilterChange": {
+ "label": {
+ "zh_CN": "筛选条件改变时触发改事件"
+ },
+ "description": {
+ "zh_CN": "配置 remote-filter 开启服务端过滤,服务端过滤会调用表格 fetch-data 进行查询,filter-change 服务端过滤后触发的事件"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "table",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "{$table,filters} 包含 table 实例对象和过滤条件的对象"
+ }
+ }
+ ],
+ "returns": {}
+ },
+ "defaultValue": "function onClick(e) {}"
+ },
+ "onSortChange": {
+ "label": {
+ "zh_CN": "点击列头,执行数据排序前触发的事件"
+ },
+ "description": {
+ "zh_CN": "配置 remote-filter 开启服务端过滤,服务端过滤会调用表格 fetch-data 进行查询,filter-change 服务端过滤后触发的事件"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "table",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "{$table,filters} 包含 table 实例对象和过滤条件的对象"
+ }
+ }
+ ],
+ "returns": {}
+ },
+ "defaultValue": "function onClick(e) {}"
+ },
+ "onSelectAll": {
+ "label": {
+ "zh_CN": "当手动勾选全选时触发的事件"
+ },
+ "description": {
+ "zh_CN": "只对 type=selection 有效,当手动勾选全选时触发的事件"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "table",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": " 包含 table 实例对象"
+ }
+ },
+ {
+ "name": "checked",
+ "type": "boolean",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "勾选状态"
+ }
+ },
+ {
+ "name": "selction",
+ "type": "Array",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "选中的表格数据数组"
+ }
+ }
+ ],
+ "returns": {}
+ },
+ "defaultValue": "function onClick(e) {}"
+ },
+ "onSelectChange": {
+ "label": {
+ "zh_CN": "手动勾选并且值发生改变时触发的事件"
+ },
+ "description": {
+ "zh_CN": "只对 type=selection 有效,当手动勾选并且值发生改变时触发的事件"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "table",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": " table 实例对象"
+ }
+ },
+ {
+ "name": "event",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": " 原生 Event"
+ }
+ }
+ ],
+ "returns": {}
+ },
+ "defaultValue": "function onClick(e) {}"
+ },
+ "onToggleExpandChange": {
+ "label": {
+ "zh_CN": "当行展开或收起时会触发该事件"
+ },
+ "description": {
+ "zh_CN": "当行展开或收起时会触发该事件"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "table",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "{$table,row,rowIndex} 包含 table 实例对象和当前行数据的对象"
+ }
+ },
+ {
+ "name": "event",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": " 原生 Event"
+ }
+ }
+ ],
+ "returns": {}
+ },
+ "defaultValue": "function onClick(e) {}"
+ },
+ "onCurrentChange": {
+ "label": {
+ "zh_CN": "行点击时触发"
+ },
+ "description": {
+ "zh_CN": "行点击时触发"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [],
+ "returns": {}
+ },
+ "defaultValue": ""
+ }
+ }
+ },
+ "configure": {
+ "loop": false,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": [],
+ "parentWhitelist": ""
+ }
+ }
+ },
+ "snippet": {
+ "name": {
+ "zh_CN": "页面模型",
+ "en_US": "PageModel"
+ },
+ "icon": "page",
+ "screenshot": "",
+ "snippetName": "PageModel",
+ "schema": {
+ "componentName": "PageModel",
+ "props": {
+ "rowOperations": {
+ "value": [
+ {
+ "label": "编辑",
+ "icon": "IconEdit",
+ "builtIn": true,
+ "itemVisible": true
+ },
+ {
+ "label": "删除",
+ "icon": "IconDel",
+ "builtIn": true,
+ "itemVisible": true
+ }
+ ]
+ }
+ }
+ }
+ }
+}
diff --git a/packages/builtinComponent/src/meta/BaseTable.json b/packages/builtinComponent/src/meta/BaseTable.json
new file mode 100644
index 0000000000..009d9edb37
--- /dev/null
+++ b/packages/builtinComponent/src/meta/BaseTable.json
@@ -0,0 +1,1792 @@
+{
+ "component": {
+ "icon": "grid",
+ "name": {
+ "zh_CN": "TableModel"
+ },
+ "component": "TableModel",
+ "schema": {
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "选择模型"
+ },
+ "description": {
+ "zh_CN": "选择模型"
+ },
+ "content": [
+ {
+ "property": "serviceModel",
+ "label": {
+ "text": {
+ "zh_CN": "选择模型"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "bindState": false,
+ "cols": 12,
+ "widget": {
+ "component": "ModelConfigurator",
+ "props": {
+ "expand": true
+ }
+ },
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "默认分组",
+ "en_US": "Default Group"
+ },
+ "content": [
+ {
+ "property": "label",
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "列标题",
+ "en_US": "Column Title"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "I18nConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "列标题",
+ "en_US": "Column's title."
+ }
+ },
+ {
+ "property": "prop",
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "列字段",
+ "en_US": "Column Field"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": true,
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "列字段",
+ "en_US": "Column's field."
+ }
+ },
+ {
+ "property": "width",
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "列宽",
+ "en_US": "Column Width"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "列宽",
+ "en_US": "Column's width."
+ }
+ },
+ {
+ "property": "minWidth",
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "最小列宽",
+ "en_US": "Minimum Width"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "最小列宽",
+ "en_US": "Minimum width of column."
+ }
+ },
+ {
+ "property": "formatter",
+ "type": "object",
+ "label": {
+ "text": {
+ "zh_CN": "格式化方法",
+ "en_US": "Formatting Method"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "dataType": "JSFunction"
+ }
+ },
+ "description": {
+ "zh_CN": "格式化方法",
+ "en_US": "Method to format."
+ }
+ },
+ {
+ "property": "showOverflowTooltip",
+ "type": "boolean",
+ "defaultValue": false,
+ "label": {
+ "text": {
+ "zh_CN": "文本溢出显示tooltip",
+ "en_US": "Tooltips when Text Overflow"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SwitchConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "文本溢出是否显示tooltip",
+ "en_US": "Whether to display tooltips when text overflow?"
+ }
+ },
+ {
+ "property": "fixed",
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "列固定",
+ "en_US": "Column Fixed"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": {
+ "zh_CN": "固定左侧",
+ "en_US": "Fixed Left"
+ },
+ "value": "left"
+ },
+ {
+ "label": {
+ "zh_CN": "固定右侧",
+ "en_US": "Fixed Right"
+ },
+ "value": "right"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "列固定",
+ "en_US": "Fixed table column on which side."
+ }
+ },
+ {
+ "property": "sortable",
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "是否排序",
+ "en_US": "Sortable"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SwitchConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否排序",
+ "en_US": "Enable sortable or not."
+ }
+ },
+ {
+ "property": "tip",
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "表头tip",
+ "en_US": "Table Header Tip"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SwitchConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "表头tip",
+ "en_US": "Tip of table's header."
+ }
+ },
+ {
+ "property": "tipContent",
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "表头tip内容",
+ "en_US": "Header Tip Content"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "表头tip内容",
+ "en_US": "Content of table header's tip."
+ }
+ },
+ {
+ "property": "edit",
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "是否可编辑",
+ "en_US": "Editable"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SwitchConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否可编辑",
+ "en_US": "Enable editable or not."
+ }
+ },
+ {
+ "property": "required",
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "必填",
+ "en_US": "Required"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SwitchConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "不可编辑时,默认必填不生效",
+ "en_US": "When it is not editable, the default requirement for mandatory filling does not take effect."
+ }
+ },
+ {
+ "property": "component",
+ "defaultValue": "TinyInput",
+ "type": "string",
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "label": {
+ "text": {
+ "zh_CN": "控件类型",
+ "en_US": "Control Type"
+ }
+ },
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": {
+ "zh_CN": "输入框",
+ "en_US": "Input"
+ },
+ "value": "TinyInput"
+ },
+ {
+ "label": {
+ "zh_CN": "选择框",
+ "en_US": "Select"
+ },
+ "value": "TinySelect"
+ },
+ {
+ "label": {
+ "zh_CN": "布尔值",
+ "en_US": "Boolean"
+ },
+ "value": "TinyRadio"
+ },
+ {
+ "label": {
+ "zh_CN": "状态标识",
+ "en_US": "StatusMarker"
+ },
+ "value": "TinyModelStatus"
+ },
+ {
+ "label": {
+ "zh_CN": "日期选择器",
+ "en_US": "Date Picker"
+ },
+ "value": "TinyDatePicker"
+ },
+ {
+ "label": {
+ "zh_CN": "计数器",
+ "en_US": "Input Number"
+ },
+ "value": "TinyNumeric"
+ }
+ ],
+ "labelZhCN": "表格列配置"
+ }
+ },
+ "description": {
+ "zh_CN": "控件类型",
+ "en_US": "Type of control."
+ }
+ }
+ ]
+ },
+ {
+ "componentName": "TinyInput",
+ "label": {
+ "zh_CN": "输入框",
+ "en_US": "Input"
+ },
+ "content": [
+ {
+ "property": "type",
+ "label": {
+ "text": {
+ "zh_CN": "类型"
+ }
+ },
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "textarea",
+ "value": "textarea"
+ },
+ {
+ "label": "text",
+ "value": "text"
+ },
+ {
+ "label": "password",
+ "value": "password"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "设置input框的type属性"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "rows",
+ "label": {
+ "text": {
+ "zh_CN": "行数"
+ }
+ },
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "输入框行数,只对 type='textarea' 有效"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "placeholder",
+ "label": {
+ "text": {
+ "zh_CN": "占位文本"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "I18nConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "输入框占位文本"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "clearable",
+ "label": {
+ "text": {
+ "zh_CN": "清除按钮"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否显示清除按钮"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "disabled",
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "size",
+ "label": {
+ "text": {
+ "zh_CN": "尺寸"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "medium",
+ "value": "medium"
+ },
+ {
+ "label": "small",
+ "value": "small"
+ },
+ {
+ "label": "mini",
+ "value": "mini"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "输入框尺寸。该属性的可选值为 medium / small / mini"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ },
+ {
+ "componentName": "TinySelect",
+ "label": {
+ "zh_CN": "选择器",
+ "en_US": "Select"
+ },
+ "content": [
+ {
+ "property": "placeholder",
+ "label": {
+ "text": {
+ "zh_CN": "占位文本"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "输入框占位文本"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "clearable",
+ "label": {
+ "text": {
+ "zh_CN": "清除按钮"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否显示清除按钮"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "searchable",
+ "label": {
+ "text": {
+ "zh_CN": "下拉可搜索"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "下拉面板是否可搜索"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "disabled",
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "options",
+ "label": {
+ "text": {
+ "zh_CN": "选项数据"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ },
+ "description": {
+ "zh_CN": "配置 Select 下拉数据项"
+ },
+ "labelPosition": "top"
+ },
+ {
+ "property": "multiple",
+ "label": {
+ "text": {
+ "zh_CN": "多选"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否允许输入框输入或选择多个项"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ },
+ {
+ "componentName": "TinyDatePicker",
+ "label": {
+ "zh_CN": "日期选择器",
+ "en_US": "DatePicker"
+ },
+ "content": [
+ {
+ "property": "type",
+ "label": {
+ "text": {
+ "zh_CN": "类型"
+ }
+ },
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "日期",
+ "value": "date"
+ },
+ {
+ "label": "日期时间",
+ "value": "datetime"
+ },
+ {
+ "label": "周",
+ "value": "week"
+ },
+ {
+ "label": "月份",
+ "value": "month"
+ },
+ {
+ "label": "年份",
+ "value": "year"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "设置日期框的type属性"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "placeholder",
+ "label": {
+ "text": {
+ "zh_CN": "占位文本"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "I18nConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "输入框占位文本"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "clearable",
+ "label": {
+ "text": {
+ "zh_CN": "清除按钮"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否显示清除按钮"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "disabled",
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "readonly",
+ "label": {
+ "text": {
+ "zh_CN": "只读"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否只读"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "size",
+ "label": {
+ "text": {
+ "zh_CN": "尺寸"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "medium",
+ "value": "medium"
+ },
+ {
+ "label": "small",
+ "value": "small"
+ },
+ {
+ "label": "mini",
+ "value": "mini"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "日期框尺寸。该属性的可选值为 medium / small / mini"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "format",
+ "type": "string",
+ "defaultValue": "",
+ "label": {
+ "text": {
+ "zh_CN": "格式化"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否只读"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "valueFormat",
+ "type": "string",
+ "defaultValue": "",
+ "label": {
+ "text": {
+ "zh_CN": "绑定值格式化"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "value-format"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ },
+ {
+ "componentName": "TinyRadio",
+ "label": {
+ "zh_CN": "单选框",
+ "en_US": "Radio"
+ },
+ "content": [
+ {
+ "property": "text",
+ "label": {
+ "text": {
+ "zh_CN": "文本内容"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "单选框文本内容"
+ }
+ },
+ {
+ "property": "label",
+ "label": {
+ "text": {
+ "zh_CN": "选中值"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "radio 选中时的值"
+ }
+ },
+ {
+ "property": "disabled",
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ },
+ {
+ "componentName": "TinyCheckbox",
+ "label": {
+ "zh_CN": "多选框",
+ "en_US": "Checkbox"
+ },
+ "content": [
+ {
+ "property": "disabled",
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "checked",
+ "label": {
+ "text": {
+ "zh_CN": "勾选"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "当前是否勾选"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "text",
+ "label": {
+ "text": {
+ "zh_CN": "文本"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "复选框的文本"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ },
+ {
+ "componentName": "TinyNumeric",
+ "label": {
+ "zh_CN": "数组输入框",
+ "en_US": "Numeric"
+ },
+ "content": [
+ {
+ "property": "placeholder",
+ "label": {
+ "text": {
+ "zh_CN": "占位文本"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "I18nConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "输入框占位文本"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "allow-empty",
+ "label": {
+ "text": {
+ "zh_CN": "内容可清空"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否内容可清空"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "disabled",
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "size",
+ "label": {
+ "text": {
+ "zh_CN": "尺寸"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "medium",
+ "value": "medium"
+ },
+ {
+ "label": "small",
+ "value": "small"
+ },
+ {
+ "label": "mini",
+ "value": "mini"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "输入框尺寸。该属性的可选值为 medium / small / mini"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "controls",
+ "label": {
+ "text": {
+ "zh_CN": "加减按钮"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否使用加减按钮"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "controls-position",
+ "label": {
+ "text": {
+ "zh_CN": "加减按钮位置"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "左右两侧",
+ "value": ""
+ },
+ {
+ "label": "只在右侧",
+ "value": "right"
+ }
+ ]
+ }
+ },
+ "description": {
+ "zh_CN": "加减按钮位置"
+ }
+ },
+ {
+ "property": "precision",
+ "label": {
+ "text": {
+ "zh_CN": "精度"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {
+ "allowEmpty": true
+ }
+ },
+ "description": {
+ "zh_CN": "数值精度"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "step",
+ "label": {
+ "text": {
+ "zh_CN": "步长"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {
+ "allowEmpty": true
+ }
+ },
+ "description": {
+ "zh_CN": "步长"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ }
+ ],
+ "labelPosition": "top"
+ },
+ {
+ "property": "modelApis",
+ "label": {
+ "text": {
+ "zh_CN": "绑定模型方法"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "bindState": false,
+ "cols": 12,
+ "widget": {
+ "component": "ModelApiConfigurator",
+ "props": {}
+ },
+ "labelPosition": "top"
+ }
+ ]
+ },
+ {
+ "label": {
+ "zh_CN": "基础属性",
+ "en_US": "Basic Attributes"
+ },
+ "description": {
+ "zh_CN": "基础属性",
+ "en_US": "Basic attributes."
+ },
+ "collapse": {
+ "number": 6,
+ "text": {
+ "zh_CN": "显示更多",
+ "en_US": "Show More"
+ }
+ },
+ "content": [
+ {
+ "property": "viewOnly",
+ "label": {
+ "text": {
+ "zh_CN": "只读",
+ "en_US": "Readonly"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SwitchConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "控制编辑态、查看态",
+ "en_US": "Control the editing and viewing states."
+ }
+ },
+ {
+ "property": "selectedEnabled",
+ "resetProps": true,
+ "label": {
+ "text": {
+ "zh_CN": "启用复选",
+ "en_US": "enable select data"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SwitchConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否允许复选框选中数据",
+ "en_US": "Whether to allow the check box to select data"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "handleSelectedRows",
+ "label": {
+ "text": {
+ "zh_CN": "处理选中数据方法",
+ "en_US": "Method of Processing Selected Data"
+ }
+ },
+ "defaultValue": {
+ "type": "JSFunction",
+ "value": "/**\r\n * 获取表格勾选数据方法\r\n * tableSelection - 表格已勾选的数据\r\n */\r\nfunction handleSelectedRows(tableSelection) {\r\n // 处理方法函数体\r\n}"
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "javascript",
+ "dataType": "JSFunction"
+ }
+ },
+ "description": {
+ "zh_CN": "处理选中数据方法",
+ "en_US": "Method of Processing Selected Data"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ },
+ {
+ "label": {
+ "zh_CN": "表格数据配置",
+ "en_US": "Form Data Configuration"
+ },
+ "description": {
+ "zh_CN": "表格数据配置",
+ "en_US": "Configuration of form data."
+ },
+ "collapse": {
+ "number": 6,
+ "text": {
+ "zh_CN": "显示更多",
+ "en_US": "Show More"
+ }
+ },
+ "content": [
+ {
+ "property": "modelValue",
+ "label": {
+ "text": {
+ "zh_CN": "表格数据绑定变量",
+ "en_US": "Binding Variables For Table Data"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "BindVariableConfigurator",
+ "props": {
+ "defaultValue": [],
+ "isValueArray": true
+ }
+ },
+ "description": {
+ "zh_CN": "为表格数据绑定变量",
+ "en_US": "Binding Variables For Search Form."
+ }
+ }
+ ]
+ },
+ {
+ "label": {
+ "zh_CN": "表格列配置",
+ "en_US": "Columns Configuration"
+ },
+ "description": {
+ "zh_CN": "表格列配置",
+ "en_US": "Configuration for table column."
+ },
+ "collapse": {
+ "number": 6,
+ "text": {
+ "zh_CN": "显示更多",
+ "en_US": "Show More"
+ }
+ },
+ "content": [
+ {
+ "property": "rowOperationEnabled",
+ "resetProps": true,
+ "label": {
+ "text": {
+ "zh_CN": "启用行操作",
+ "en_US": "enable row operation"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SwitchConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否使用行操作",
+ "en_US": "Whether to allow the row operation"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "useIconOperation",
+ "resetProps": true,
+ "label": {
+ "text": {
+ "zh_CN": "使用图标",
+ "en_US": "use icon operation"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "SwitchConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "行操作是否使用图标",
+ "en_US": "use Icon Whether to handle the row operation"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "type": "configList",
+ "property": "rowOperations",
+ "label": {
+ "text": {
+ "zh_CN": "行操作",
+ "en_US": "Row Operation"
+ }
+ },
+ "required": false,
+ "cols": 12,
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "默认分组",
+ "en_US": "Default Group"
+ },
+ "content": [
+ {
+ "property": "label",
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "文本",
+ "en_US": "Text"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "I18nConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "操作名称",
+ "en_US": "Operation's name."
+ }
+ },
+ {
+ "property": "icon",
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "图标",
+ "en_US": "Icon"
+ }
+ },
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {
+ "placeholder": "请输入图标类名"
+ }
+ },
+ "description": {
+ "zh_CN": "图标库地址: https://tinyuidesign.cloudbu.huawei.com/tiny-vue/zh-CN/os-theme/components/icon#list",
+ "en_US": "Icon Library Address: https://tinyuidesign.cloudbu.huawei.com/tiny-vue/zh-CN/os-theme/components/icon#list"
+ }
+ },
+ {
+ "property": "handler",
+ "label": {
+ "text": {
+ "zh_CN": "点击回调事件",
+ "en_US": "Click Callback Event"
+ }
+ },
+ "defaultValue": {
+ "type": "JSFunction",
+ "value": "function handleRow(row, index, extendApis) {}"
+ },
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "dataType": "JSFunction"
+ }
+ },
+ "description": {
+ "zh_CN": "操作的回调函数",
+ "en_US": "Callback functions for operations."
+ }
+ }
+ ]
+ }
+ ],
+ "widget": {
+ "component": "OperatorGroupConfigurator",
+ "props": {
+ "type": "object",
+ "textField": "label",
+ "language": "json",
+ "buttonText": "编辑行操作",
+ "title": "编辑行操作",
+ "enableVisibleControl": true,
+ "disableDelete": true,
+ "expand": true,
+ "isAbleBatchOperation": true
+ }
+ },
+ "description": {
+ "zh_CN": "表格自定义行操作",
+ "en_US": "Custom operations For table's row."
+ },
+ "labelPosition": "top"
+ },
+ {
+ "property": "columnMinWidth",
+ "label": {
+ "text": {
+ "zh_CN": "表格列最小宽度",
+ "en_US": "Minimum Column Width"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "表格列最小宽度",
+ "en_US": "Minimum width of table's column."
+ }
+ },
+ {
+ "property": "columnWidth",
+ "label": {
+ "text": {
+ "zh_CN": "表格列宽度",
+ "en_US": "Column Width"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "表格列宽度",
+ "en_US": "Width of table's column."
+ }
+ }
+ ]
+ }
+ ],
+ "events": {
+ "onFilterChange": {
+ "label": {
+ "zh_CN": "筛选条件改变时触发改事件"
+ },
+ "description": {
+ "zh_CN": "配置 remote-filter 开启服务端过滤,服务端过滤会调用表格 fetch-data 进行查询,filter-change 服务端过滤后触发的事件"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "table",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "{$table,filters} 包含 table 实例对象和过滤条件的对象"
+ }
+ }
+ ],
+ "returns": {}
+ },
+ "defaultValue": "function onClick(e) {}"
+ },
+ "onSortChange": {
+ "label": {
+ "zh_CN": "点击列头,执行数据排序前触发的事件"
+ },
+ "description": {
+ "zh_CN": "配置 remote-filter 开启服务端过滤,服务端过滤会调用表格 fetch-data 进行查询,filter-change 服务端过滤后触发的事件"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "table",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "{$table,filters} 包含 table 实例对象和过滤条件的对象"
+ }
+ }
+ ],
+ "returns": {}
+ },
+ "defaultValue": "function onClick(e) {}"
+ },
+ "onSelectAll": {
+ "label": {
+ "zh_CN": "当手动勾选全选时触发的事件"
+ },
+ "description": {
+ "zh_CN": "只对 type=selection 有效,当手动勾选全选时触发的事件"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "table",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": " 包含 table 实例对象"
+ }
+ },
+ {
+ "name": "checked",
+ "type": "boolean",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "勾选状态"
+ }
+ },
+ {
+ "name": "selction",
+ "type": "Array",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "选中的表格数据数组"
+ }
+ }
+ ],
+ "returns": {}
+ },
+ "defaultValue": "function onClick(e) {}"
+ },
+ "onSelectChange": {
+ "label": {
+ "zh_CN": "手动勾选并且值发生改变时触发的事件"
+ },
+ "description": {
+ "zh_CN": "只对 type=selection 有效,当手动勾选并且值发生改变时触发的事件"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "table",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": " table 实例对象"
+ }
+ },
+ {
+ "name": "event",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": " 原生 Event"
+ }
+ }
+ ],
+ "returns": {}
+ },
+ "defaultValue": "function onClick(e) {}"
+ },
+ "onToggleExpandChange": {
+ "label": {
+ "zh_CN": "当行展开或收起时会触发该事件"
+ },
+ "description": {
+ "zh_CN": "当行展开或收起时会触发该事件"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "table",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "{$table,row,rowIndex} 包含 table 实例对象和当前行数据的对象"
+ }
+ },
+ {
+ "name": "event",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": " 原生 Event"
+ }
+ }
+ ],
+ "returns": {}
+ },
+ "defaultValue": "function onClick(e) {}"
+ },
+ "onCurrentChange": {
+ "label": {
+ "zh_CN": "行点击时触发"
+ },
+ "description": {
+ "zh_CN": "行点击时触发"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [],
+ "returns": {}
+ },
+ "defaultValue": ""
+ }
+ },
+ "shortcuts": {
+ "properties": ["sortable", "columns"]
+ },
+ "contentMenu": {
+ "actions": ["create symbol"]
+ },
+ "onBeforeMount": "console.log('table on load'); this.pager = source.pager; this.fetchData = source.fetchData; this.data = source.data ;this.columns = source.columns"
+ },
+ "configure": {
+ "loop": false,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": ""
+ }
+ }
+ },
+ "snippet": {
+ "name": {
+ "zh_CN": "表格模型",
+ "en_US": "TableModel"
+ },
+ "icon": "grid",
+ "screenshot": "",
+ "snippetName": "TableModel",
+ "schema": {
+ "componentName": "TableModel",
+ "props": {
+ "editConfig": {
+ "trigger": "click",
+ "mode": "cell",
+ "showStatus": true
+ },
+ "rowOperations": {
+ "type": "object",
+ "value": []
+ }
+ }
+ }
+ }
+}
diff --git a/packages/builtinComponent/src/meta/CanvasNavigation.json b/packages/builtinComponent/src/meta/CanvasNavigation.json
new file mode 100644
index 0000000000..b054cd9dc0
--- /dev/null
+++ b/packages/builtinComponent/src/meta/CanvasNavigation.json
@@ -0,0 +1,193 @@
+{
+ "component": {
+ "icon": "navigation",
+ "name": {
+ "zh_CN": "导航条"
+ },
+ "component": "CanvasNavigation",
+ "schema": {
+ "slots": {},
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "基础信息"
+ },
+ "description": {
+ "zh_CN": "基础信息"
+ },
+ "collapse": {
+ "number": 6,
+ "text": {
+ "zh_CN": "显示更多"
+ }
+ },
+ "content": [
+ {
+ "property": "type",
+ "label": {
+ "text": {
+ "zh_CN": "类型"
+ }
+ },
+ "description": {
+ "zh_CN": "类型"
+ },
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "defaultValue": "horizontal",
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "horizontal",
+ "value": "horizontal"
+ },
+ {
+ "label": "vertical",
+ "value": "vertical"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "property": "tabs",
+ "label": {
+ "text": {
+ "zh_CN": "选项卡"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "defaultValue": "",
+ "cols": 12,
+ "bindState": false,
+ "widget": {
+ "component": "TabBarConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "tabs 选项卡"
+ },
+ "labelPosition": "none"
+ }
+ ]
+ }
+ ],
+ "events": {
+ "onClick": {
+ "label": {
+ "zh_CN": "点击事件"
+ },
+ "description": {
+ "zh_CN": "点击时触发的回调函数"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [],
+ "returns": {}
+ },
+ "defaultValue": ""
+ }
+ },
+ "shortcuts": {
+ "properties": []
+ },
+ "contentMenu": {
+ "actions": []
+ }
+ },
+ "configure": {
+ "loop": true,
+ "isContainer": true,
+ "nestingRule": {
+ "childWhitelist": [],
+ "descendantBlacklist": []
+ }
+ }
+ },
+ "snippet": {
+ "name": {
+ "zh_CN": "导航条"
+ },
+ "snippetName": "CanvasNavigation",
+ "icon": "navigation",
+ "schema": {
+ "componentName": "CanvasNavigation",
+ "props": {
+ "style": "text-align: center; padding: 8px 12px; box-shadow: 0 0 4px #0003;"
+ },
+ "children": [
+ {
+ "componentName": "RouterLink",
+ "props": {
+ "to": "",
+ "style": "display: inline-flex; gap: 8px; padding: 10px 20px; color: inherit; text-decoration: none;"
+ },
+ "children": [
+ {
+ "componentName": "Icon",
+ "props": {
+ "name": "IconPublicHome",
+ "style": "margin-top: 3px;"
+ }
+ },
+ {
+ "componentName": "Text",
+ "props": {
+ "text": "首页"
+ }
+ }
+ ]
+ },
+ {
+ "componentName": "RouterLink",
+ "props": {
+ "to": "",
+ "style": "display: inline-flex; gap: 8px; padding: 10px 20px; color: inherit; text-decoration: none;"
+ },
+ "children": [
+ {
+ "componentName": "Icon",
+ "props": {
+ "name": "IconTaskCooperation",
+ "style": "margin-top: 3px;"
+ }
+ },
+ {
+ "componentName": "Text",
+ "props": {
+ "text": "介绍"
+ }
+ }
+ ]
+ },
+ {
+ "componentName": "RouterLink",
+ "props": {
+ "to": "",
+ "style": "display: flex; gap: 8px; padding: 10px 20px; color: inherit; text-decoration: none;"
+ },
+ "children": [
+ {
+ "componentName": "Icon",
+ "props": {
+ "name": "IconText",
+ "style": "margin-top: 3px;"
+ }
+ },
+ {
+ "componentName": "Text",
+ "props": {
+ "text": "文档"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/packages/builtinComponent/src/meta/index.js b/packages/builtinComponent/src/meta/index.js
index 7521af69aa..3054420082 100644
--- a/packages/builtinComponent/src/meta/index.js
+++ b/packages/builtinComponent/src/meta/index.js
@@ -3,6 +3,10 @@ import CanvasRow from './CanvasRow.json'
import CanvasRowColContainer from './CanvasRowColContainer.json'
import CanvasFlexBox from './CanvasFlexBox.json'
import CanvasSection from './CanvasSection.json'
+import CanvasNavigation from './CanvasNavigation.json'
+import BaseForm from './BaseForm.json'
+import BaseTable from './BaseTable.json'
+import BasePage from './BasePage.json'
export default {
components: [
@@ -10,7 +14,11 @@ export default {
CanvasRow.component,
CanvasRowColContainer.component,
CanvasFlexBox.component,
- CanvasSection.component
+ CanvasSection.component,
+ CanvasNavigation.component,
+ BaseForm.component,
+ BaseTable.component,
+ BasePage.component
],
snippets: [
{
@@ -19,6 +27,20 @@ export default {
zh_CN: '布局与容器'
},
children: [CanvasRowColContainer.snippet, CanvasFlexBox.snippet, CanvasSection.snippet]
+ },
+ {
+ group: 'advanced',
+ label: {
+ zh_CN: '高级元素'
+ },
+ children: [CanvasNavigation.snippet]
+ },
+ {
+ group: 'model',
+ label: {
+ zh_CN: '模型组件'
+ },
+ children: [BaseForm.snippet, BaseTable.snippet, BasePage.snippet]
}
]
}
diff --git a/packages/builtinComponent/tsconfig.json b/packages/builtinComponent/tsconfig.json
new file mode 100644
index 0000000000..17484c7e9c
--- /dev/null
+++ b/packages/builtinComponent/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "include": ["./index.ts", "./src/**/*.ts", "./src/**/*.tsx", "./src/**/*.vue"]
+}
diff --git a/packages/builtinComponent/vite.config.ts b/packages/builtinComponent/vite.config.ts
index 1af413f568..081583f8af 100644
--- a/packages/builtinComponent/vite.config.ts
+++ b/packages/builtinComponent/vite.config.ts
@@ -14,9 +14,18 @@ import path from 'path'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import vitePluginCssInjectedByJs from 'vite-plugin-css-injected-by-js'
+import dts from 'vite-plugin-dts'
export default defineConfig({
- plugins: [vue(), vueJsx(), vitePluginCssInjectedByJs()],
+ plugins: [
+ vue(),
+ vueJsx(),
+ vitePluginCssInjectedByJs(),
+ dts({
+ tsconfigPath: path.resolve(__dirname, './tsconfig.json'),
+ rollupTypes: true
+ })
+ ],
publicDir: false,
build: {
sourcemap: true,
@@ -28,7 +37,7 @@ export default defineConfig({
formats: ['es']
},
rollupOptions: {
- external: ['vue']
+ external: ['vue', '@opentiny/vue', '@opentiny/vue-icon', '@opentiny/vue-renderless']
}
}
})
diff --git a/packages/canvas/DesignCanvas/index.ts b/packages/canvas/DesignCanvas/index.ts
index 6f439f9a58..057ff92d28 100644
--- a/packages/canvas/DesignCanvas/index.ts
+++ b/packages/canvas/DesignCanvas/index.ts
@@ -2,11 +2,14 @@ import { HOOK_NAME } from '@opentiny/tiny-engine-meta-register'
import DesignCanvas from './src/DesignCanvas.vue'
import metaData from './meta'
import api from './src/api'
+import mcp from './src/mcp'
+
export default {
...metaData,
entry: DesignCanvas,
apis: api(),
composable: {
name: HOOK_NAME.useCanvas
- }
+ },
+ mcp
}
diff --git a/packages/canvas/DesignCanvas/src/DesignCanvas.vue b/packages/canvas/DesignCanvas/src/DesignCanvas.vue
index 99a0099fe0..8b11b4bfd8 100644
--- a/packages/canvas/DesignCanvas/src/DesignCanvas.vue
+++ b/packages/canvas/DesignCanvas/src/DesignCanvas.vue
@@ -76,9 +76,9 @@ export default {
return
}
- const { importMap, importStyles } = getImportMapData(deps)
+ const { importMap, importStyles, importScripts } = getImportMapData(deps)
- canvasSrcDoc.value = initCanvas(importMap, importStyles).html
+ canvasSrcDoc.value = initCanvas(importMap, importStyles, importScripts).html
}
})
@@ -87,6 +87,9 @@ export default {
footData.value = useCanvas().getNodePath(node?.id)
pageState.currentSchema = {}
pageState.properties = null
+ // 删除节点后,重置pageState中组件的属性
+ // 后续需要改造
+ useProperties().getProps(null, null)
}
const isBlock = useCanvas().isBlock
@@ -106,9 +109,9 @@ export default {
empty: () => '应用下暂无页面,需新建页面后体验画布功能',
release: (type) => `当前${componentType[type]}未锁定,点击右上角 “锁定” 图标后编辑${componentType[type]}`,
lock: (type) =>
- `当前${componentType[type]}被 ${pageInfo?.username || ''} 锁定,如需编辑请先联系他解锁文件,然后再锁定该${
+ `当前${componentType[type]}被 ${pageInfo?.username || ''} 锁定,您可以创建新页面,如需编辑请先联系他解锁${
componentType[type]
- }后编辑!`
+ },然后再锁定该${componentType[type]}后编辑!`
}
const renderMsg = message[pageStatus.state](pageSchema.componentName)
@@ -287,7 +290,8 @@ export default {
getBlockByName: useMaterial().getBlockByName,
useModal,
useMessage,
- useNotify
+ useNotify,
+ enableTailwindCSS: getMergeMeta('engine.config')?.enableTailwindCSS
},
isBlock,
getMoveDragBarState,
diff --git a/packages/canvas/DesignCanvas/src/importMap.ts b/packages/canvas/DesignCanvas/src/importMap.ts
index 499154c47d..632c2f8370 100644
--- a/packages/canvas/DesignCanvas/src/importMap.ts
+++ b/packages/canvas/DesignCanvas/src/importMap.ts
@@ -94,9 +94,13 @@ export function getImportMapData(canvasDeps = { scripts: [], styles: [] }) {
}
const importStyles = [...blockRequire.importStyles, ...canvasDeps.styles]
+ const customEnableTailWindCSS = getMergeMeta('engine.config')?.enableTailwindCSS
+ const tailwindURL = getImportUrl('@tailwindcss/browser')
+ const importScripts = customEnableTailWindCSS && tailwindURL ? [tailwindURL] : []
return {
importMap,
- importStyles
+ importStyles,
+ importScripts
}
}
diff --git a/packages/canvas/DesignCanvas/src/mcp/index.ts b/packages/canvas/DesignCanvas/src/mcp/index.ts
new file mode 100644
index 0000000000..01324bdca1
--- /dev/null
+++ b/packages/canvas/DesignCanvas/src/mcp/index.ts
@@ -0,0 +1,13 @@
+import {
+ getCurrentSelectedNode,
+ getPageSchema,
+ queryNodeById,
+ delNode,
+ addNode,
+ changeNodeProps,
+ selectSpecificNode
+} from './tools'
+
+export default {
+ tools: [getCurrentSelectedNode, getPageSchema, queryNodeById, delNode, addNode, changeNodeProps, selectSpecificNode]
+}
diff --git a/packages/canvas/DesignCanvas/src/mcp/tools/addNode.ts b/packages/canvas/DesignCanvas/src/mcp/tools/addNode.ts
new file mode 100644
index 0000000000..04e7c860e2
--- /dev/null
+++ b/packages/canvas/DesignCanvas/src/mcp/tools/addNode.ts
@@ -0,0 +1,136 @@
+import { z } from 'zod'
+import { useCanvas, useMaterial } from '@opentiny/tiny-engine-meta-register'
+import { utils } from '@opentiny/tiny-engine-utils'
+
+const { validateParams } = utils
+
+const inputSchema = z.object({
+ parentId: z
+ .string()
+ .optional()
+ .describe(
+ 'The id of the parent node. If not provided, the new node will be added to the root. if you don\'t know the parentId, you can use the tool "get_page_schema" to get the page schema. if you want to add to page root, just don\'t provide the parentId.'
+ ),
+ newNodeData: z.object({
+ componentName: z.string().describe('The name of the component.'),
+ props: z.record(z.string(), z.any()).describe('The props of the component.'),
+ children: z
+ .array(z.record(z.string(), z.any()))
+ .describe('Array of child nodes; each child has the same shape as newNodeData (recursive tree).')
+ }),
+ position: z
+ .enum(['before', 'after'])
+ .optional()
+ .describe(
+ 'The position of the new node. If not provided, the new node will be added to the end of the parent node.'
+ ),
+ referTargetNodeId: z
+ .string()
+ .optional()
+ .describe(
+ 'The id of the reference target node. If not provided, the new node will be added to the end of the parent node. if you don\'t know the referTargetNodeId, you can use the tool "get_page_schema" to get the page schema. if you dont want to refer to any node, just don\'t provide the referTargetNodeId.'
+ )
+})
+
+export const addNode = {
+ name: 'add_node',
+ title: '添加节点',
+ description:
+ 'Add a new node to the current TinyEngine low-code application. Use this when you need to add new node to your application.',
+ inputSchema: inputSchema.shape,
+ annotations: {
+ title: '添加节点',
+ readOnlyHint: false,
+ destructiveHint: false,
+ idempotentHint: false,
+ openWorldHint: false
+ },
+ callback: async (args: z.infer) => {
+ const { parentId, newNodeData, position, referTargetNodeId } = args
+ const componentName = newNodeData.componentName
+ const { props = {}, children = [] } = newNodeData
+
+ const validateResult = validateParams(args, {
+ parentId: {
+ validator: (value: string) => {
+ const parentNode = useCanvas().getNodeById(value)
+ return !!parentNode
+ },
+ message:
+ 'Parent node not found, please check the parentId is correct. if you don\'t know the parentId, you can use the tool "get_page_schema" to get the page schema. if you want to add to page root, just don\'t provide the parentId.'
+ },
+ referTargetNodeId: {
+ validator: (value: string) => {
+ const referTargetNode = useCanvas().getNodeById(value)
+ return !!referTargetNode
+ },
+ message:
+ "Refer target node not found, please check the referTargetNodeId is correct. if you don't want to refer to any node, just don't provide the referTargetNodeId."
+ }
+ })
+
+ if (!validateResult.isValid) {
+ return validateResult.error
+ }
+
+ const { getMaterial } = useMaterial()
+ const material = getMaterial(componentName)
+ const isEmptyPlainObject =
+ material &&
+ typeof material === 'object' &&
+ !Array.isArray(material) &&
+ Object.keys(material as Record).length === 0
+
+ if (!newNodeData.componentName || isEmptyPlainObject) {
+ return {
+ isError: true,
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify({
+ status: 'error',
+ errorCode: 'COMPONENT_NAME_REQUIRED',
+ reason: 'Component name is required',
+ userMessage: 'Component name is required. Fetch the available component list.',
+ next_action: {
+ type: 'tool_call',
+ name: 'get_component_list',
+ args: {}
+ }
+ })
+ }
+ ]
+ }
+ }
+
+ const insertData = {
+ componentName,
+ props,
+ children
+ }
+
+ useCanvas().operateNode({
+ type: 'insert',
+ parentId: parentId!,
+ // @ts-ignore
+ newNodeData: insertData,
+ position: position!,
+ referTargetNodeId
+ })
+
+ const res = {
+ status: 'success',
+ message: `Node added successfully`,
+ data: insertData
+ }
+
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify(res)
+ }
+ ]
+ }
+ }
+}
diff --git a/packages/canvas/DesignCanvas/src/mcp/tools/changeNodeProps.ts b/packages/canvas/DesignCanvas/src/mcp/tools/changeNodeProps.ts
new file mode 100644
index 0000000000..29cbb8a2c3
--- /dev/null
+++ b/packages/canvas/DesignCanvas/src/mcp/tools/changeNodeProps.ts
@@ -0,0 +1,98 @@
+import { z } from 'zod'
+import { useCanvas } from '@opentiny/tiny-engine-meta-register'
+
+const inputSchema = z.object({
+ id: z
+ .string()
+ .describe(
+ 'The id of the node to change the props of. if you don\'t know the id, you can use the tool "get_current_selected_node" to get the current selected node. or you can use the tool "get_page_schema" to get the page schema. when get the page schema, you can find the id in the "id" field.'
+ ),
+ props: z
+ .record(z.string(), z.any())
+ .describe(
+ 'The props of the component. if you don\'t know available props, you can use the "get_component_detail" tool to get component detail and available props.'
+ ),
+ overwrite: z.boolean().optional().describe('Whether to overwrite the existing props.')
+})
+
+export const changeNodeProps = {
+ name: 'change_node_props',
+ title: '修改节点属性',
+ description:
+ 'Change the props of a node in the current TinyEngine low-code application. Use this when you need to change the props of a node in your application.',
+ inputSchema: inputSchema.shape,
+ // 添加 annotations 配置
+ annotations: {
+ title: '修改节点属性', // 人性化标题
+ readOnlyHint: false, // 非只读操作,会修改节点属性
+ destructiveHint: false, // 非破坏性操作,只是修改属性值
+ idempotentHint: false, // 非幂等操作,不同的属性修改会产生不同效果
+ openWorldHint: false // 不与外部世界交互,只在 TinyEngine 内部操作
+ },
+ callback: async (args: z.infer) => {
+ const { id, overwrite = false } = args
+ let props = args.props
+
+ if (!props || typeof props !== 'object') {
+ props = {}
+ }
+
+ const node = useCanvas().getNodeById(id)
+ if (!node) {
+ return {
+ content: [
+ {
+ isError: true,
+ type: 'text',
+ text: JSON.stringify({
+ errorCode: 'NODE_NOT_FOUND',
+ reason: `Node not found: ${id}`,
+ userMessage: `Node not found: ${id}. Fetch the available node list.`,
+ next_action: [
+ {
+ type: 'tool_call',
+ name: 'get_current_selected_node',
+ args: {},
+ when: 'you want to change the props of the current selected node'
+ },
+ {
+ type: 'tool_call',
+ name: 'get_page_schema',
+ args: {},
+ when: 'you want to change the props of the node with the specified id'
+ }
+ ]
+ })
+ }
+ ]
+ }
+ }
+
+ useCanvas().operateNode({
+ type: 'changeProps',
+ id,
+ value: { props },
+ option: {
+ overwrite
+ }
+ })
+
+ const res = {
+ status: 'success',
+ message: `Node props changed successfully`,
+ data: {
+ id,
+ props
+ }
+ }
+
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify(res)
+ }
+ ]
+ }
+ }
+}
diff --git a/packages/canvas/DesignCanvas/src/mcp/tools/delNode.ts b/packages/canvas/DesignCanvas/src/mcp/tools/delNode.ts
new file mode 100644
index 0000000000..810d43da36
--- /dev/null
+++ b/packages/canvas/DesignCanvas/src/mcp/tools/delNode.ts
@@ -0,0 +1,66 @@
+import { z } from 'zod'
+import { useCanvas } from '@opentiny/tiny-engine-meta-register'
+
+const inputSchema = z.object({
+ id: z
+ .string()
+ .describe(
+ 'The id of the node to delete. if you don\'t know the id, you can use the tool "get_current_selected_node" to get the current selected node. or you can use the tool "get_page_schema" to get the page schema. when get the page schema, you can find the id in the "id" field.'
+ )
+})
+
+export const delNode = {
+ name: 'del_node',
+ title: '删除节点',
+ description:
+ 'Delete a node from the current TinyEngine low-code application. Use this when you need to delete a node from your application.',
+ inputSchema: inputSchema.shape,
+ // 添加 annotations 配置
+ annotations: {
+ title: '删除节点', // 人性化标题
+ readOnlyHint: false, // 非只读操作,会删除节点
+ destructiveHint: true, // 破坏性操作,会永久删除节点
+ idempotentHint: true, // 幂等操作,删除同一个节点多次没有额外效果
+ openWorldHint: false // 不与外部世界交互,只在 TinyEngine 内部操作
+ },
+ callback: async (args: z.infer) => {
+ const { id } = args
+ const node = useCanvas().getNodeById(id)
+
+ if (!node) {
+ return {
+ content: [
+ {
+ type: 'json',
+ value: {
+ status: 'error',
+ message: 'Node not found, please check the id is correct.'
+ }
+ }
+ ]
+ }
+ }
+
+ useCanvas().operateNode({
+ type: 'delete',
+ id
+ })
+
+ const res = {
+ status: 'success',
+ message: `Node deleted successfully`,
+ data: {
+ id
+ }
+ }
+
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify(res)
+ }
+ ]
+ }
+ }
+}
diff --git a/packages/canvas/DesignCanvas/src/mcp/tools/getCurrentSelectedNode.ts b/packages/canvas/DesignCanvas/src/mcp/tools/getCurrentSelectedNode.ts
new file mode 100644
index 0000000000..15ea5dd1a0
--- /dev/null
+++ b/packages/canvas/DesignCanvas/src/mcp/tools/getCurrentSelectedNode.ts
@@ -0,0 +1,57 @@
+import { z } from 'zod'
+import { useCanvas } from '@opentiny/tiny-engine-meta-register'
+
+const inputSchema = z.object({})
+
+export const getCurrentSelectedNode = {
+ name: 'get_current_selected_node',
+ title: '获取当前选中节点',
+ description:
+ 'Get the current selected node from the current TinyEngine low-code application. Use this when you need to get the current selected node from your application.',
+ inputSchema: inputSchema.shape,
+ // 添加 annotations 配置
+ annotations: {
+ title: '获取当前选中节点', // 人性化标题
+ readOnlyHint: true, // 只读操作,不会修改任何状态
+ openWorldHint: false // 不与外部世界交互,只在 TinyEngine 内部操作
+ },
+ callback: async (_args: z.infer) => {
+ const currentSelectedNode = useCanvas().canvasApi.value?.getCurrent?.()
+
+ // 安全检查,确保 currentSelectedNode 存在
+ if (!currentSelectedNode) {
+ return {
+ content: [
+ {
+ isError: true,
+ type: 'text',
+ text: JSON.stringify({
+ status: 'error',
+ message: 'No node is currently selected'
+ })
+ }
+ ]
+ }
+ }
+
+ const { schema, parent } = currentSelectedNode
+
+ const res = {
+ status: 'success',
+ message: `Current selected node retrieved successfully`,
+ data: {
+ currentSelectedNode: schema,
+ parent
+ }
+ }
+
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify(res)
+ }
+ ]
+ }
+ }
+}
diff --git a/packages/canvas/DesignCanvas/src/mcp/tools/getPageSchema.ts b/packages/canvas/DesignCanvas/src/mcp/tools/getPageSchema.ts
new file mode 100644
index 0000000000..5b51e747c1
--- /dev/null
+++ b/packages/canvas/DesignCanvas/src/mcp/tools/getPageSchema.ts
@@ -0,0 +1,38 @@
+import { z } from 'zod'
+import { useCanvas } from '@opentiny/tiny-engine-meta-register'
+
+const inputSchema = z.object({})
+
+export const getPageSchema = {
+ name: 'get_page_schema',
+ title: '获取页面结构',
+ description:
+ 'Get current editing page schema from the current TinyEngine low-code application. Use this when you need to get current editing page schema from your application.',
+ inputSchema: inputSchema.shape,
+ // 添加 annotations 配置
+ annotations: {
+ title: '获取页面结构', // 人性化标题
+ readOnlyHint: true, // 只读操作,不会修改任何状态
+ openWorldHint: false // 不与外部世界交互,只在 TinyEngine 内部操作
+ },
+ callback: async (_args: z.infer) => {
+ const pageSchema = useCanvas().getSchema()
+
+ const res = {
+ status: 'success',
+ message: `Page schema retrieved successfully`,
+ data: {
+ pageSchema
+ }
+ }
+
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify(res)
+ }
+ ]
+ }
+ }
+}
diff --git a/packages/canvas/DesignCanvas/src/mcp/tools/index.ts b/packages/canvas/DesignCanvas/src/mcp/tools/index.ts
new file mode 100644
index 0000000000..aa6beac593
--- /dev/null
+++ b/packages/canvas/DesignCanvas/src/mcp/tools/index.ts
@@ -0,0 +1,7 @@
+export { getCurrentSelectedNode } from './getCurrentSelectedNode'
+export { getPageSchema } from './getPageSchema'
+export { queryNodeById } from './queryNodeById'
+export { delNode } from './delNode'
+export { addNode } from './addNode'
+export { changeNodeProps } from './changeNodeProps'
+export { selectSpecificNode } from './selectSpecificNode'
diff --git a/packages/canvas/DesignCanvas/src/mcp/tools/queryNodeById.ts b/packages/canvas/DesignCanvas/src/mcp/tools/queryNodeById.ts
new file mode 100644
index 0000000000..a6608ea127
--- /dev/null
+++ b/packages/canvas/DesignCanvas/src/mcp/tools/queryNodeById.ts
@@ -0,0 +1,79 @@
+import { z } from 'zod'
+import { useCanvas } from '@opentiny/tiny-engine-meta-register'
+
+const inputSchema = z.object({
+ id: z
+ .string()
+ .describe(
+ 'The id of the node to query. if you don\'t know the id, you can use the tool "get_current_selected_node" to get the current selected node. or you can use the tool "get_page_schema" to get the page schema. when get the page schema, you can find the id in the "id" field.'
+ )
+})
+
+export const queryNodeById = {
+ name: 'query_node_by_id',
+ title: '根据ID查询节点',
+ description:
+ 'Query a node by id from the current TinyEngine low-code application. Use this when you need to query a node by id from your application.',
+ inputSchema: inputSchema.shape,
+ // 添加 annotations 配置
+ annotations: {
+ title: '根据ID查询节点', // 人性化标题
+ readOnlyHint: true, // 只读操作,不会修改任何状态
+ openWorldHint: false // 不与外部世界交互,只在 TinyEngine 内部操作
+ },
+ callback: async (args: z.infer) => {
+ const { id } = args
+ const result = useCanvas().getNodeWithParentById(id)
+
+ // 安全检查,确保找到了节点
+ if (!result) {
+ return {
+ content: [
+ {
+ isError: true,
+ type: 'text',
+ text: JSON.stringify({
+ errorCode: 'NODE_NOT_FOUND',
+ reason: `Node not found: ${id}`,
+ userMessage: `Node not found: ${id}. Fetch the available node list.`,
+ next_action: [
+ {
+ type: 'tool_call',
+ name: 'get_current_selected_node',
+ args: {},
+ when: 'you want to query the current selected node'
+ },
+ {
+ type: 'tool_call',
+ name: 'get_page_schema',
+ args: {},
+ when: 'you want to query the node with the specified id'
+ }
+ ]
+ })
+ }
+ ]
+ }
+ }
+
+ const { node, parent } = result
+
+ const res = {
+ status: 'success',
+ message: `Node retrieved successfully`,
+ data: {
+ node,
+ parent
+ }
+ }
+
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify(res)
+ }
+ ]
+ }
+ }
+}
diff --git a/packages/canvas/DesignCanvas/src/mcp/tools/selectSpecificNode.ts b/packages/canvas/DesignCanvas/src/mcp/tools/selectSpecificNode.ts
new file mode 100644
index 0000000000..7e6e0d7e2c
--- /dev/null
+++ b/packages/canvas/DesignCanvas/src/mcp/tools/selectSpecificNode.ts
@@ -0,0 +1,78 @@
+import { z } from 'zod'
+import { useCanvas } from '@opentiny/tiny-engine-meta-register'
+
+const inputSchema = z.object({
+ id: z
+ .string()
+ .describe(
+ 'The id of the node to select. if you don\'t know the id, you can use the tool "get_page_schema" to get the page schema. when get the page schema, you can find the id in the "id" field.'
+ )
+})
+
+export const selectSpecificNode = {
+ name: 'select_specific_node',
+ title: '选择特定节点',
+ description:
+ 'Select a specific node from the current TinyEngine low-code application. Use this when you need to select a specific node from your application.',
+ inputSchema: inputSchema.shape,
+ // 添加 annotations 配置
+ annotations: {
+ title: '选择特定节点', // 人性化标题
+ readOnlyHint: false, // 非只读操作,会改变选择状态
+ destructiveHint: false, // 非破坏性操作,只是改变选择状态
+ idempotentHint: false, // 非幂等操作,重复选择可能触发不同的 UI 效果
+ openWorldHint: false // 不与外部世界交互,只在 TinyEngine 内部操作
+ },
+ callback: async (args: z.infer) => {
+ const { id } = args
+ const node = useCanvas().getNodeById(id)
+
+ if (!node) {
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify({
+ errorCode: 'NODE_NOT_FOUND',
+ reason: `Node not found: ${id}`,
+ userMessage: `Node not found: ${id}. Fetch the available node list.`,
+ next_action: [
+ {
+ type: 'tool_call',
+ name: 'get_current_selected_node',
+ args: {},
+ when: 'you want to select the current selected node'
+ },
+ {
+ type: 'tool_call',
+ name: 'get_page_schema',
+ args: {},
+ when: 'you want to select the node with the specified id'
+ }
+ ]
+ })
+ }
+ ]
+ }
+ }
+
+ useCanvas().canvasApi.value?.selectNode?.(id, 'clickTree')
+
+ const res = {
+ status: 'success',
+ message: `Node selected successfully`,
+ data: {
+ id
+ }
+ }
+
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify(res)
+ }
+ ]
+ }
+ }
+}
diff --git a/packages/canvas/canvas.html b/packages/canvas/canvas.html
index 42304ac0e3..e1e7a68832 100644
--- a/packages/canvas/canvas.html
+++ b/packages/canvas/canvas.html
@@ -78,75 +78,6 @@
animation-delay: 2s;
}
html,
- body,
- object,
- iframe,
- p,
- blockquote,
- pre,
- abbr,
- address,
- cite,
- code,
- del,
- dfn,
- em,
- img,
- ins,
- kbd,
- q,
- samp,
- small,
- strong,
- sub,
- sup,
- var,
- b,
- i,
- dl,
- dt,
- dd,
- ol,
- ul,
- li,
- fieldset,
- form,
- label,
- legend,
- table,
- caption,
- tbody,
- tfoot,
- thead,
- tr,
- th,
- td,
- article,
- aside,
- canvas,
- details,
- figcaption,
- figure,
- footer,
- header,
- hgroup,
- menu,
- nav,
- section,
- summary,
- time,
- mark,
- audio,
- video {
- margin: 0;
- padding: 0;
- border: 0;
- outline: 0;
- font-size: 100%;
- background: transparent;
- user-select: none;
- }
- html,
body {
width: 100%;
height: 100%;
diff --git a/packages/canvas/container/src/components/CanvasAction.vue b/packages/canvas/container/src/components/CanvasAction.vue
index b06830588f..9df3bc0cac 100644
--- a/packages/canvas/container/src/components/CanvasAction.vue
+++ b/packages/canvas/container/src/components/CanvasAction.vue
@@ -251,7 +251,12 @@ export default {
}
const hide = () => {
- getRenderer().setCondition(getCurrent().schema?.id, false)
+ if (getCurrent().schema?.id) {
+ const { clearSelect } = useCanvas().canvasApi.value
+ getRenderer().setCondition(getCurrent().schema.id, false)
+ useCanvas().pageState.nodesStatus[getCurrent().schema.id] = false
+ clearSelect()
+ }
updateRect()
}
@@ -417,32 +422,128 @@ export default {
}
}
+ /**
+ * 检查元素在画布中的可用空间
+ * @param {number} top - 选中元素顶部位置
+ * @param {number} selectedHeight - 选中元素高度
+ * @param {number} canvasHeight - 画布高度
+ * @param {number} elementHeight - 要放置元素的高度
+ * @returns {{hasTopSpace: boolean, hasBottomSpace: boolean}}
+ */
+ const checkElementSpace = (top, selectedHeight, canvasHeight, elementHeight) => {
+ return {
+ hasTopSpace: top >= elementHeight,
+ hasBottomSpace: canvasHeight - top - selectedHeight >= elementHeight
+ }
+ }
+
+ /**
+ * 根据策略决定元素应该放置在顶部还是底部
+ * @param {number} top - 选中元素顶部位置
+ * @param {number} elementHeight - 要放置元素的高度
+ * @param {boolean} hasTopSpace - 顶部是否有足够空间
+ * @param {boolean} hasBottomSpace - 底部是否有足够空间
+ * @param {string} strategy - 放置策略 ('topFirst' | 'bottomFirst')
+ * @returns {boolean} 是否放置在底部
+ */
+ const determineElementPosition = (hasTopSpace, hasBottomSpace, strategy = 'topFirst') => {
+ if (strategy === 'bottomFirst') {
+ // Option策略:优先底部,或顶部没空间时放底部
+ return hasBottomSpace || !hasTopSpace
+ } else {
+ // Label策略:顶部没空间且底部有空间才放底部
+ return !hasTopSpace && hasBottomSpace
+ }
+ }
+
+ /**
+ * 通用的垂直对齐计算函数
+ * @param {boolean} isAtBottom - 是否放置在底部
+ * @param {number} elementHeight - 元素高度
+ * @param {boolean} hasTopSpace - 顶部是否有足够空间
+ * @param {boolean} hasBottomSpace - 底部是否有足够空间
+ * @param {boolean} bottomFirst - 是否底部优先策略(true: Option策略, false: Label策略)
+ * @returns {{alignTop: boolean, verticalValue: number}}
+ */
+ const calculateVerticalAlignment = (
+ isAtBottom,
+ elementHeight,
+ hasTopSpace,
+ hasBottomSpace,
+ bottomFirst = false
+ ) => {
+ const alignTop = !isAtBottom
+
+ let verticalValue
+ if (bottomFirst) {
+ // Option策略:不在底部 OR 底部有空间时偏移
+ verticalValue = !isAtBottom || hasBottomSpace ? -elementHeight : 0
+ } else {
+ // Label策略:在底部 OR 顶部有空间时偏移
+ verticalValue = isAtBottom || hasTopSpace ? -elementHeight : 0
+ }
+
+ return { alignTop, verticalValue }
+ }
+
+ /**
+ * 一站式元素对齐计算函数(组合了空间检查、位置决策、对齐计算)
+ * @param {number} top - 选中元素顶部位置
+ * @param {number} selectedHeight - 选中元素高度
+ * @param {number} canvasHeight - 画布高度
+ * @param {number} elementHeight - 要放置元素的高度
+ * @param {string} strategy - 放置策略 ('topFirst' | 'bottomFirst')
+ * @returns {{alignTop: boolean, verticalValue: number}}
+ */
+ const calculateElementAlignment = (top, selectedHeight, canvasHeight, elementHeight, strategy = 'topFirst') => {
+ const spaceInfo = checkElementSpace(top, selectedHeight, canvasHeight, elementHeight)
+ const isAtBottom = determineElementPosition(spaceInfo.hasTopSpace, spaceInfo.hasBottomSpace, strategy)
+ return calculateVerticalAlignment(
+ isAtBottom,
+ elementHeight,
+ spaceInfo.hasTopSpace,
+ spaceInfo.hasBottomSpace,
+ strategy === 'bottomFirst'
+ )
+ }
+
const getStyleValues = (selectState, canvasSize, labelWidth, optionWidth) => {
const { left, top, width, height, doc } = selectState
const { width: canvasWidth, height: canvasHeight } = canvasSize
// 标签宽度和工具操作条宽度之和加上间距
const fullRectWidth = labelWidth + optionWidth + OPTION_SPACE
+ const labelAlignment = calculateElementAlignment(
+ top,
+ height,
+ canvasHeight,
+ LABEL_HEIGHT,
+ 'topFirst' // Label策略:顶部优先
+ )
- // 是否 将label 标签放置到底部,判断 top 距离
- const isLabelAtBottom = top < LABEL_HEIGHT
const labelAlign = new Align({
alignLeft: true,
horizontalValue: 0,
- alignTop: !isLabelAtBottom,
- verticalValue: -LABEL_HEIGHT
+ alignTop: labelAlignment.alignTop,
+ verticalValue: labelAlignment.verticalValue
})
if (!doc) {
return {}
}
- // 是否将操作栏放置到底部,判断当前选中组件底部与页面底部的距离。
- const isOptionAtBottom = canvasHeight - top - height >= OPTION_BAR_HEIGHT
+ const optionAlignment = calculateElementAlignment(
+ top,
+ height,
+ canvasHeight,
+ OPTION_BAR_HEIGHT,
+ 'bottomFirst' // Option策略:底部优先
+ )
+
const optionAlign = new Align({
alignLeft: false,
horizontalValue: 0,
- alignTop: !isOptionAtBottom,
- verticalValue: -OPTION_BAR_HEIGHT
+ alignTop: optionAlignment.alignTop,
+ verticalValue: optionAlignment.verticalValue
})
const scrollBarWidth = doc.documentElement.scrollHeight > doc.documentElement.clientHeight ? SCROLL_BAR_WIDTH : 0
@@ -462,7 +563,7 @@ export default {
optionAlign.align(positions.LEFT)
}
- if (isLabelAtBottom === isOptionAtBottom) {
+ if (labelAlignment.alignTop === optionAlignment.alignTop) {
// 标签框和工具操作框都在顶部或者都在底部
if (left + fullRectWidth < canvasWidth) {
@@ -562,6 +663,12 @@ export default {
pointer-events: none;
border: 1px solid var(--te-canvas-container-border-color-checked);
z-index: 2;
+ // 禁止文本选择
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+
&.absolute {
pointer-events: all;
}
diff --git a/packages/canvas/container/src/components/CanvasResize.vue b/packages/canvas/container/src/components/CanvasResize.vue
index 820a0ecf47..32b11e90a0 100644
--- a/packages/canvas/container/src/components/CanvasResize.vue
+++ b/packages/canvas/container/src/components/CanvasResize.vue
@@ -116,6 +116,8 @@ export default {
watch(() => useLayout().rightFixedPanelsStorage.value, setScale, { flush: 'post' })
+ watch(() => useLayout().layoutState.toolbars.render, setScale, { flush: 'post' })
+
watch(
() => useLayout().getSettingState().render,
(value) => {
diff --git a/packages/canvas/container/src/container.ts b/packages/canvas/container/src/container.ts
index f81e18444a..fecf997f32 100644
--- a/packages/canvas/container/src/container.ts
+++ b/packages/canvas/container/src/container.ts
@@ -466,6 +466,34 @@ const setSelectRect = (
)
}
+const getElementDurationTime = (elementId?: string) => {
+ const element = elementId ? querySelectById(elementId) : getDocument().body
+ const transitionDuration = window.getComputedStyle(element).getPropertyValue('transition-duration')
+ const transitionDelay = window.getComputedStyle(element).getPropertyValue('transition-delay')
+ let delayTime = 0
+ const getMaxMillisecondNumber = (arr: string[]) => {
+ const millisecondNumber = arr.map((item) => {
+ if (item.endsWith('ms')) {
+ return parseFloat(item)
+ } else {
+ return parseFloat(item) * 1000
+ }
+ })
+ return millisecondNumber.length ? Math.max(...millisecondNumber) : 0
+ }
+ if (transitionDuration) {
+ const transitionDurations = transitionDuration.split(',')
+ delayTime += getMaxMillisecondNumber(transitionDurations)
+ }
+
+ if (transitionDelay) {
+ const transitionDelays = transitionDelay.split(',')
+ delayTime += getMaxMillisecondNumber(transitionDelays)
+ }
+
+ return delayTime
+}
+
export const updateRect = (id?: string) => {
id = (typeof id === 'string' && id) || getCurrent().schema?.id
clearHover()
@@ -481,7 +509,9 @@ export const updateRect = (id?: string) => {
const isBodySelected = !selectState.componentName && selectState.width > 0
if (id || isBodySelected) {
- setTimeout(() => setSelectRect(id))
+ // 获取元素动画持续时间
+ const waitTime = getElementDurationTime(id)
+ setTimeout(() => setSelectRect(id), waitTime)
} else {
clearSelect()
}
@@ -816,7 +846,6 @@ export const dragMove = (event: DragEvent, isHover: boolean) => {
// type == clickTree, 为点击大纲; type == loop-id=xxx ,为点击循环数据
export const selectNode = async (id: string, type?: string, isMultiple = false) => {
const { node } = useCanvas().getNodeWithParentById(id) || {}
-
let element = querySelectById(id)
if (element && node) {
@@ -825,7 +854,6 @@ export const selectNode = async (id: string, type?: string, isMultiple = false)
}
const nodeIsSelected = setSelectRect(id, element, { isMultiple, type, schema: node })
-
// 执行setSelectRect之后再去判断multiSelectedStates的长度
if (multiSelectedStates.value.length === 1) {
const { schema: node, parent, type } = multiSelectedStates.value[0]
@@ -851,6 +879,7 @@ export const selectNode = async (id: string, type?: string, isMultiple = false)
if (multiSelectedStates.value.length === 1) {
const { schema: node, parent, type, id } = multiSelectedStates.value[0]
canvasState.emit('selected', node, parent, type, id)
+
return node
} else {
canvasState.emit('selected')
diff --git a/packages/canvas/init-canvas/canvas.html b/packages/canvas/init-canvas/canvas.html
index e9d2b2efaa..1dcefc4015 100644
--- a/packages/canvas/init-canvas/canvas.html
+++ b/packages/canvas/init-canvas/canvas.html
@@ -6,6 +6,7 @@
+
diff --git a/packages/common/component/toolbar-built-in/ToolbarBaseIcon.vue b/packages/common/component/toolbar-built-in/ToolbarBaseIcon.vue
index f669467932..489892c7a2 100644
--- a/packages/common/component/toolbar-built-in/ToolbarBaseIcon.vue
+++ b/packages/common/component/toolbar-built-in/ToolbarBaseIcon.vue
@@ -1,11 +1,12 @@
+
@@ -18,10 +19,11 @@
+
+
diff --git a/packages/configurator/src/bind-variable-configurator/BindVariableConfigurator.vue b/packages/configurator/src/bind-variable-configurator/BindVariableConfigurator.vue
new file mode 100644
index 0000000000..ccfc805015
--- /dev/null
+++ b/packages/configurator/src/bind-variable-configurator/BindVariableConfigurator.vue
@@ -0,0 +1,108 @@
+
+
+
+
+
+ 绑定
+
+
+
+
+
+
+
+
diff --git a/packages/configurator/src/button-group-configurator/ButtonGroupConfigurator.vue b/packages/configurator/src/button-group-configurator/ButtonGroupConfigurator.vue
index 47bc705d1b..62185fa088 100644
--- a/packages/configurator/src/button-group-configurator/ButtonGroupConfigurator.vue
+++ b/packages/configurator/src/button-group-configurator/ButtonGroupConfigurator.vue
@@ -9,15 +9,16 @@
-
diff --git a/packages/configurator/src/code-list-configurator/CodeListConfigurator.vue b/packages/configurator/src/code-list-configurator/CodeListConfigurator.vue
index 66bfffa0fe..651d39252c 100644
--- a/packages/configurator/src/code-list-configurator/CodeListConfigurator.vue
+++ b/packages/configurator/src/code-list-configurator/CodeListConfigurator.vue
@@ -39,8 +39,9 @@
-
+
+
diff --git a/packages/configurator/src/model-api-configurator/ParamsBindGrid.vue b/packages/configurator/src/model-api-configurator/ParamsBindGrid.vue
new file mode 100644
index 0000000000..90bd238611
--- /dev/null
+++ b/packages/configurator/src/model-api-configurator/ParamsBindGrid.vue
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+ {{ data.row?.required ? '是' : '否' }}
+
+
+
+
+
+
+
+
diff --git a/packages/configurator/src/model-common/ModelSelect.vue b/packages/configurator/src/model-common/ModelSelect.vue
new file mode 100644
index 0000000000..8c708b6adb
--- /dev/null
+++ b/packages/configurator/src/model-common/ModelSelect.vue
@@ -0,0 +1,147 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/configurator/src/model-common/constants.js b/packages/configurator/src/model-common/constants.js
new file mode 100644
index 0000000000..8a095ceec8
--- /dev/null
+++ b/packages/configurator/src/model-common/constants.js
@@ -0,0 +1,23 @@
+export const typeComponentsMap = {
+ String: { component: 'TinyInput' },
+ Boolean: {
+ component: 'TinySelect',
+ props: {
+ options: [
+ {
+ label: '是',
+ value: true
+ },
+ {
+ label: '否',
+ value: false
+ }
+ ]
+ }
+ },
+ Date: { component: 'TinyDatePicker', props: { format: 'yyyy-MM-dd', valueFormat: 'yyyy-MM-dd' } },
+ Number: { component: 'TinyNumeric' },
+ Enum: {
+ component: 'TinySelect'
+ }
+}
diff --git a/packages/configurator/src/model-common/http.js b/packages/configurator/src/model-common/http.js
new file mode 100644
index 0000000000..f1c104b3dd
--- /dev/null
+++ b/packages/configurator/src/model-common/http.js
@@ -0,0 +1,6 @@
+import { getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register'
+
+export const getModelList = (currentPage, params) =>
+ getMetaApi(META_SERVICE.Http).get(`/material-center/api/model/list?currentPage=${currentPage}&pageSize=10`, {
+ params: params || {}
+ })
diff --git a/packages/configurator/src/model-common/utils.js b/packages/configurator/src/model-common/utils.js
new file mode 100644
index 0000000000..7c760f315d
--- /dev/null
+++ b/packages/configurator/src/model-common/utils.js
@@ -0,0 +1,52 @@
+import { getModelList } from './http'
+import { typeComponentsMap } from './constants'
+
+const handleModelParameters = (paramItem) => {
+ const extension = {}
+ if (paramItem.type === 'Enum') {
+ extension.options = JSON.parse(paramItem.options) || []
+ }
+ const item = {
+ ...paramItem,
+ ...(typeComponentsMap[paramItem.type]?.props || {}),
+ ...extension,
+ originType: paramItem.type,
+ label: paramItem?.label ?? paramItem.prop,
+ isModel: paramItem.isModel,
+ component: typeComponentsMap[paramItem.type]?.component ?? 'TinyInput',
+ itemVisible: true
+ }
+ delete item.type
+ return item
+}
+
+export const handleSelectedModelParameters = async (model) => {
+ const parameters = await Promise.all(
+ (model?.parameters || model).map(async (item) => {
+ const defaultItem = handleModelParameters(item)
+ // 如果是关联字段,则查询关联模型数据
+ if (item?.isModel) {
+ const data = await getModelList(1, { id: item.defaultValue })
+ return {
+ ...defaultItem,
+ defaultValue: (data.records.length > 0 ? data.records[0].parameters : []).map((insideItem) =>
+ handleModelParameters(insideItem)
+ )
+ }
+ } else {
+ return defaultItem
+ }
+ })
+ )
+ return model?.parameters
+ ? {
+ id: model.id,
+ name: model.nameCn,
+ nameEn: model.nameEn,
+ description: model.description,
+ version: model.version,
+ baseUrl: model.modelUrl ?? '',
+ parameters
+ }
+ : parameters
+}
diff --git a/packages/configurator/src/model-configurator/MetaListItem.vue b/packages/configurator/src/model-configurator/MetaListItem.vue
new file mode 100644
index 0000000000..f75803564b
--- /dev/null
+++ b/packages/configurator/src/model-configurator/MetaListItem.vue
@@ -0,0 +1,258 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/configurator/src/model-configurator/ModelConfigurator.vue b/packages/configurator/src/model-configurator/ModelConfigurator.vue
new file mode 100644
index 0000000000..49c90fb682
--- /dev/null
+++ b/packages/configurator/src/model-configurator/ModelConfigurator.vue
@@ -0,0 +1,513 @@
+
+
+
+
+
+ 绑定模型数据
+
+ 确认
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ modelDetail?.name }}
+
+ 选择模型
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/configurator/src/operator-group-configurator/MetaChildItem.vue b/packages/configurator/src/operator-group-configurator/MetaChildItem.vue
new file mode 100644
index 0000000000..c9a18f1499
--- /dev/null
+++ b/packages/configurator/src/operator-group-configurator/MetaChildItem.vue
@@ -0,0 +1,121 @@
+
+
+ {{ title }}
+
+
+
+
+
+
+
diff --git a/packages/configurator/src/operator-group-configurator/MetaList.vue b/packages/configurator/src/operator-group-configurator/MetaList.vue
new file mode 100644
index 0000000000..fefeead3fb
--- /dev/null
+++ b/packages/configurator/src/operator-group-configurator/MetaList.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/packages/configurator/src/operator-group-configurator/MetaListItem.vue b/packages/configurator/src/operator-group-configurator/MetaListItem.vue
new file mode 100644
index 0000000000..c0396ab153
--- /dev/null
+++ b/packages/configurator/src/operator-group-configurator/MetaListItem.vue
@@ -0,0 +1,354 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 确定删除吗?
+
+
+ 取消
+ 删除
+
+
+
+
+
+
+
+
+
diff --git a/packages/configurator/src/operator-group-configurator/OperatorGroupConfigurator.vue b/packages/configurator/src/operator-group-configurator/OperatorGroupConfigurator.vue
new file mode 100644
index 0000000000..d155d1fb29
--- /dev/null
+++ b/packages/configurator/src/operator-group-configurator/OperatorGroupConfigurator.vue
@@ -0,0 +1,210 @@
+
+
+
+
+
+
+
diff --git a/packages/configurator/src/radio-configurator/RadioConfigurator.vue b/packages/configurator/src/radio-configurator/RadioConfigurator.vue
index aef009fd0b..d5a6970f8a 100644
--- a/packages/configurator/src/radio-configurator/RadioConfigurator.vue
+++ b/packages/configurator/src/radio-configurator/RadioConfigurator.vue
@@ -20,13 +20,14 @@
-
diff --git a/packages/configurator/src/select-configurator/SelectConfigurator.vue b/packages/configurator/src/select-configurator/SelectConfigurator.vue
index c095ccb43d..573e0d78cb 100644
--- a/packages/configurator/src/select-configurator/SelectConfigurator.vue
+++ b/packages/configurator/src/select-configurator/SelectConfigurator.vue
@@ -43,8 +43,9 @@
-
+
diff --git a/packages/configurator/src/source-select-configurator/http.ts b/packages/configurator/src/source-select-configurator/http.ts
new file mode 100644
index 0000000000..5de4688fcc
--- /dev/null
+++ b/packages/configurator/src/source-select-configurator/http.ts
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+import { getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register'
+
+const baseUrl = '/material-center/api'
+
+// 资源管理 -- 根据分组ID获取资源列表
+export const fetchResourceListByGroupId = (resourceGroupId: number) =>
+ getMetaApi(META_SERVICE.Http).get(`${baseUrl}/resource/find/${resourceGroupId}`)
+
+// 资源管理 -- 根据appId查询资源分组列表
+export const fetchResourceGroupByAppId = (appId?: number) =>
+ getMetaApi(META_SERVICE.Http).get(
+ `${baseUrl}/resource-group/${appId || getMetaApi(META_SERVICE.GlobalService).getBaseInfo().id}`
+ )
diff --git a/packages/configurator/src/styles/vars.less b/packages/configurator/src/styles/vars.less
index bae819898c..d628d7fe0e 100644
--- a/packages/configurator/src/styles/vars.less
+++ b/packages/configurator/src/styles/vars.less
@@ -43,4 +43,7 @@
--te-configurator-container-bg-color: var(--te-common-bg-container);
--te-configurator-container-border-color-divider: var(--te-common-border-bg-divider);
+
+ --te-configurator-tab-bar-bg-color: var(--te-common-bg-container);
+ --te-configurator-tab-bar-border-color-divider: var(--te-common-border-bg-divider);
}
diff --git a/packages/configurator/src/tab-bar-configurator/TabBarConfigurator.vue b/packages/configurator/src/tab-bar-configurator/TabBarConfigurator.vue
new file mode 100644
index 0000000000..f8bccac239
--- /dev/null
+++ b/packages/configurator/src/tab-bar-configurator/TabBarConfigurator.vue
@@ -0,0 +1,236 @@
+
+
+
+
+ 标签栏项
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 新增一项
+
+
+
+
+
+
diff --git a/packages/configurator/src/variable-configurator/VariableConfigurator.vue b/packages/configurator/src/variable-configurator/VariableConfigurator.vue
index efb5bc1b3a..dab946b29e 100644
--- a/packages/configurator/src/variable-configurator/VariableConfigurator.vue
+++ b/packages/configurator/src/variable-configurator/VariableConfigurator.vue
@@ -70,6 +70,7 @@
:value="state.variable"
:options="editorOptions"
@editorDidMount="editorDidMount"
+ @change="editorChange"
>
-'
- }
-
- const transformedScript = transformSync(p1, {
- babelrc: false,
- plugins: [[vueJsx, { pragma: 'h' }]],
- sourceMaps: false,
- configFile: false
- })
-
- const res = `'
-
- return `${res}${endTag}`
- })
-
- newFiles[panelName] = newPanelValue
+ newFiles[panelName] = panelValue
}
// 根据新的参数更新预览
@@ -371,58 +358,266 @@ export const usePreviewData = ({ setFiles, store }: IUsePreviewData) => {
scripts: Record
styles: string[]
}) => {
+ const searchParams = new URLSearchParams(location.search)
+ const previewType = searchParams.get('previewType')
const { appData, metaData, importMapData } = await getBasicData(basicFiles, params.scripts)
- previewState.currentPage = params.currentPage
- previewState.ancestors = params.ancestors
+ if (previewType === 'page') {
+ previewState.currentPage = params.currentPage
+ previewState.ancestors = params.ancestors
- // importMap 发生变化才更新 importMap
- if (JSON.stringify(previewState.importMap) !== JSON.stringify(importMapData)) {
- store.setImportMap(importMapData)
- previewState.importMap = importMapData
- }
+ // importMap 发生变化才更新 importMap
+ if (JSON.stringify(previewState.importMap) !== JSON.stringify(importMapData)) {
+ setImportMap(importMapData)
+ previewState.importMap = importMapData
+ }
- const blockSet = new Set()
+ const blockSet = new Set()
- let blocks = []
- const { getAllNestedBlocksSchema, generatePageCode } = getMetaApi('engine.service.generateCode')
+ let blocks = []
+ const { getAllNestedBlocksSchema, generatePageCode } = getMetaApi('engine.service.generateCode')
+
+ if (params.ancestors?.length) {
+ const promises = params.ancestors.map((item) =>
+ getAllNestedBlocksSchema(item.page_content, fetchBlockSchema, blockSet)
+ )
+ blocks = (await Promise.all(promises)).flat()
+ }
- if (params.ancestors?.length) {
- const promises = params.ancestors.map((item) =>
- getAllNestedBlocksSchema(item.page_content, fetchBlockSchema, blockSet)
+ const currentPageBlocks = await getAllNestedBlocksSchema(
+ params.currentPage?.page_content || {},
+ fetchBlockSchema,
+ blockSet
)
- blocks = (await Promise.all(promises)).flat()
- }
+ blocks = blocks.concat(currentPageBlocks)
+ const pageCode = [
+ ...getPageAncestryFiles(appData, params),
+ ...(blocks || []).map((blockSchema) => {
+ return {
+ panelName: `${blockSchema.fileName}.vue`,
+ panelValue: generatePageCode(blockSchema, appData?.componentsMap || [], { blockRelativePath: './' }) || '',
+ panelType: 'vue'
+ }
+ })
+ ]
+
+ const newFiles = store.getFiles()
+ const enableTailwindCSS = getMergeMeta('engine.config')?.enableTailwindCSS
+ const appJsCode = processAppJsCode(newFiles['app.js'] || '', params.styles, enableTailwindCSS)
+
+ newFiles['app.js'] = appJsCode
+ pageCode.forEach((item) => assignFiles(item, newFiles))
+
+ const metaFiles = generateMetaFiles(metaData)
+ Object.assign(newFiles, metaFiles)
+ setFiles(newFiles, 'App.vue')
+ } else if (previewType === 'app') {
+ const appId = searchParams.get('id')
+ const { getAllNestedBlocksSchema, generateAppCode } = getMetaApi('engine.service.generateCode')
+
+ let appSchema
+
+ const getPreGenerateInfo = async () => {
+ const promises = [
+ getMetaApi(META_SERVICE.Http).get(`/app-center/v1/api/apps/schema/${appId}`),
+ fetchPageList(appId)
+ ]
+
+ const [appData, pageList] = await Promise.all(promises)
+ const pageDetailList = pageList
+
+ // 这里需要手动传入 blockSet 的原因是多页面可能会存在重复的区块
+ const blockSet = new Set()
+ const list = pageDetailList.map((page) =>
+ getAllNestedBlocksSchema(page.page_content, fetchBlockSchema, blockSet)
+ )
+ const blocks = await Promise.allSettled(list)
+
+ const blockSchema = []
+ blocks.forEach((item) => {
+ if (item.status === 'fulfilled' && Array.isArray(item.value)) {
+ blockSchema.push(...item.value)
+ }
+ })
- const currentPageBlocks = await getAllNestedBlocksSchema(
- params.currentPage?.page_content || {},
- fetchBlockSchema,
- blockSet
- )
- blocks = blocks.concat(currentPageBlocks)
-
- const pageCode = [
- ...getPageAncestryFiles(appData, params),
- ...(blocks || []).map((blockSchema) => {
- return {
- panelName: `${blockSchema.fileName}.vue`,
- panelValue: generatePageCode(blockSchema, appData?.componentsMap || [], { blockRelativePath: './' }) || '',
- panelType: 'vue'
+ appSchema = {
+ dataSource: appData.dataSource,
+ utils: appData.utils,
+ i18n: appData.i18n,
+ globalState: appData.globalState,
+ // 页面 schema
+ pageSchema: pageDetailList.map((item) => {
+ const { page_content, ...meta } = item
+
+ return {
+ ...page_content,
+ meta: {
+ ...meta,
+ router: meta.route
+ }
+ }
+ }),
+ blockSchema,
+ // 物料数据
+ componentsMap: [...(appData.componentsMap || [])],
+ // 物料依赖
+ packages: [...(appData.packages || [])],
+ meta: {
+ ...(appData.meta || {})
+ }
}
- })
- ]
- const newFiles = store.getFiles()
- const appJsCode = processAppJsCode(newFiles['app.js'], params.styles)
+ const res = await generateAppCode(appSchema)
+
+ const { genResult = [] } = res || {}
+ const fileRes = genResult.map(({ fileContent, fileName, path, fileType }) => {
+ const slash = path.endsWith('/') || path === '.' ? '' : '/'
+ let filePath = `${path}${slash}`
+ if (filePath.startsWith('./')) {
+ filePath = filePath.slice(2)
+ }
+ if (filePath.startsWith('.')) {
+ filePath = filePath.slice(1)
+ }
+
+ if (filePath.startsWith('/')) {
+ filePath = filePath.slice(1)
+ }
- newFiles['app.js'] = appJsCode
+ return {
+ fileContent,
+ filePath: `${filePath}${fileName}`,
+ fileType
+ }
+ })
- pageCode.map(fixScriptLang).forEach((item) => assignFiles(item, newFiles))
+ return fileRes
+ }
- const metaFiles = generateMetaFiles(metaData)
- Object.assign(newFiles, metaFiles)
+ const buildTreeRoutes = (routes) => {
+ const tree = []
+ const routeMap = new Map()
- setFiles(newFiles)
+ // 首先将所有路由存入一个 Map 中,以便快速查找
+ routes.forEach((route) => {
+ routeMap.set(route.path, route)
+ })
+
+ // 递归构建树状结构
+ const buildTree = (route) => {
+ const children = routes.filter((childRoute) => {
+ return childRoute.path.startsWith(route.path) && childRoute.path !== route.path
+ })
+
+ if (children.length > 0) {
+ route.children = children.map((childRoute) => {
+ const child = { ...childRoute }
+ buildTree(child)
+ return child
+ })
+ }
+ }
+
+ // 找到所有根路由
+ routes.forEach((route) => {
+ if (!routes.some((otherRoute) => otherRoute.path !== route.path && route.path.startsWith(otherRoute.path))) {
+ const root = { ...route }
+ buildTree(root)
+ tree.push(root)
+ }
+ })
+
+ return tree
+ }
+
+ const getRoutesAndImportSet = (schema) => {
+ const importSet = new Set()
+ const pageSchema = (schema.pageSchema || []).sort((a, b) => a.meta?.router?.length - b.meta?.router?.length)
+ const result = []
+ const home = {
+ path: '/'
+ }
+ let isGetHome = false
+ pageSchema.forEach((item) => {
+ if ((item.meta?.isHome || item.meta?.isDefault) && !isGetHome) {
+ home.redirect = { name: `${item.meta.id}` }
+ isGetHome = true
+ }
+ importSet.add(
+ `import ${item.fileName} from './views${item.path ? `/${item.path}` : ''}/${item.fileName}.vue'`
+ )
+ const newNode = {
+ path: `/${item.meta.router}`,
+ component: item.fileName,
+ name: `${item.meta.id}`
+ }
+ result.push(newNode)
+ })
+ if (!isGetHome) {
+ isGetHome = true
+ home.redirect = { name: result[0]?.name }
+ }
+
+ return { routes: [home, ...buildTreeRoutes(result)], importSet }
+ }
+
+ const getRouterFile = (schema) => {
+ const { routes, importSet } = getRoutesAndImportSet(schema)
+ const resultStr = JSON.stringify(routes, null, 2).replace(
+ /("component":\s*)"(.*?)"/g,
+ (match, p1, p2) => p1 + p2
+ )
+
+ // TODO: 支持 hash 模式、history 模式
+ const importSnippet = `import { createRouter, createMemoryHistory } from 'vue-router'\n${[...importSet].join(
+ '\n'
+ )}`
+ const exportSnippet = `export default createRouter({history: createMemoryHistory(),routes })`
+
+ const routeSnippets = `const routes = ${resultStr}`
+
+ return `${importSnippet}\n ${routeSnippets} \n ${exportSnippet}`
+ }
+
+ const formatCode = (fileContent, fileName) => {
+ if (fileName === 'src/router/index.js') {
+ fileContent = getRouterFile(appSchema)
+ } else {
+ fileContent = fileContent.replace(/(from\s*')(@)(\/.*')/g, '$1.$3')
+ }
+ if (fileName === 'src/App.vue') {
+ fileContent = fileContent.replace(
+ ' ',
+ ` \n `
+ )
+ fileContent = fileContent.replace(
+ `import { provide } from 'vue'`,
+ `import { Select as TinySelect } from '@opentiny/vue'\nimport { ref, provide, watchEffect } from 'vue'\nimport { useRoute, useRouter } from 'vue-router'`
+ )
+ fileContent = fileContent.replace(
+ `provide(I18nInjectionKey, i18n)`,
+ `const route = useRoute()\nconst router = useRouter()\nconst currentRoute = ref()\n\nwatchEffect(() => {\n\tcurrentRoute.value = route.path\n})\n\nconst routeChange = () => {\n\trouter.push(currentRoute.value)\n}\nprovide(I18nInjectionKey, i18n)`
+ )
+ }
+ return fileContent
+ }
+
+ const fileRes = await getPreGenerateInfo()
+ const newFileRes = fileRes.filter((item) => item.filePath.includes('src/'))
+ const srcFiles = newFileRes.reduce((prev, item) => {
+ const fileName = item.filePath
+ prev[fileName] = formatCode(item.fileContent, fileName)
+ return prev
+ }, {})
+ srcFiles['import-map.json'] = JSON.stringify(importMapData)
+ const newFiles = store.getFiles()
+ const enableTailwindCSS = getMergeMeta('engine.config')?.enableTailwindCSS
+ const appJsCode = processAppJsCode(newFiles['app.js'] || '', params.styles, enableTailwindCSS)
+ srcFiles['app.js'] = appJsCode
+ srcFiles['main.js'] = `import app from './app.js' \n ${srcFiles['src/main.js']}`
+ srcFiles['main.js'] = srcFiles['main.js'].replace("import 'element-plus/dist/index.css'", '')
+ setFiles(srcFiles, 'src/main.js')
+ }
}
const loadInitialData = async () => {
diff --git a/packages/design-core/src/preview/src/previewDefaultRegistry.js b/packages/design-core/src/preview/src/previewDefaultRegistry.js
index bcb5a04038..d2b67b89e2 100644
--- a/packages/design-core/src/preview/src/previewDefaultRegistry.js
+++ b/packages/design-core/src/preview/src/previewDefaultRegistry.js
@@ -86,7 +86,8 @@ export default {
icon: 'dark',
oppositeTheme: 'light'
}
- ]
+ ],
+ enableTailwindCSS: true
},
toolbars: [Breadcrumb, Media, Lang]
}
diff --git a/packages/engine-cli/package.json b/packages/engine-cli/package.json
index 4969f83f50..3e9e77c7af 100644
--- a/packages/engine-cli/package.json
+++ b/packages/engine-cli/package.json
@@ -1,6 +1,6 @@
{
"name": "@opentiny/tiny-engine-cli",
- "version": "2.7.0",
+ "version": "2.9.0",
"description": "",
"main": "dist/index.js",
"scripts": {
diff --git a/packages/engine-cli/template/designer/engine.config.js b/packages/engine-cli/template/designer/engine.config.js
index fa308f9bc2..0ed7c1858a 100644
--- a/packages/engine-cli/template/designer/engine.config.js
+++ b/packages/engine-cli/template/designer/engine.config.js
@@ -3,5 +3,7 @@ export default {
theme: 'light',
material: ['/mock/bundle.json'],
scripts: [],
- styles: []
+ styles: [],
+ // 是否开启 TailWindCSS 特性
+ enableTailwindCSS: true
}
diff --git a/packages/engine-cli/template/designer/package.json b/packages/engine-cli/template/designer/package.json
index 01d9c9d09f..9d07a03e07 100644
--- a/packages/engine-cli/template/designer/package.json
+++ b/packages/engine-cli/template/designer/package.json
@@ -11,9 +11,9 @@
"serve:mock": "node node_modules/@opentiny/tiny-engine-mock/dist/app.js"
},
"dependencies": {
- "@opentiny/tiny-engine": "^2.7.0",
- "@opentiny/tiny-engine-meta-register": "^2.7.0",
- "@opentiny/tiny-engine-utils": "^2.7.0",
+ "@opentiny/tiny-engine": "^2.9.0",
+ "@opentiny/tiny-engine-meta-register": "^2.9.0",
+ "@opentiny/tiny-engine-utils": "^2.9.0",
"@opentiny/vue": "~3.20.0",
"@opentiny/vue-design-smb": "~3.20.0",
"@opentiny/vue-icon": "~3.20.0",
@@ -24,8 +24,8 @@
"vue": "^3.4.21"
},
"devDependencies": {
- "@opentiny/tiny-engine-mock": "^2.7.0",
- "@opentiny/tiny-engine-vite-config": "^2.7.0",
+ "@opentiny/tiny-engine-mock": "^2.9.0",
+ "@opentiny/tiny-engine-vite-config": "^2.9.0",
"@vitejs/plugin-vue": "^5.1.2",
"cross-env": "^7.0.3",
"vite": "^5.4.2",
diff --git a/packages/engine-cli/template/designer/public/mock/bundle.json b/packages/engine-cli/template/designer/public/mock/bundle.json
index 53c0ca0d82..13b15cfc4f 100644
--- a/packages/engine-cli/template/designer/public/mock/bundle.json
+++ b/packages/engine-cli/template/designer/public/mock/bundle.json
@@ -4,53 +4,26 @@
"materials": {
"components": [
{
- "id": 1,
- "version": "2.4.2",
+ "version": "3.22.0",
"name": {
- "zh_CN": "输入框"
+ "zh_CN": "评分"
},
- "component": "ElInput",
- "icon": "input",
- "description": "通过鼠标或键盘输入字符",
- "doc_url": "",
+ "component": "TinyRate",
+ "icon": "line",
+ "description": "评分",
+ "docUrl": "",
"screenshot": "",
"tags": "",
"keywords": "",
- "dev_mode": "proCode",
+ "devMode": "proCode",
"npm": {
- "package": "element-plus",
- "exportName": "ElInput",
+ "package": "@opentiny/vue",
+ "exportName": "TinyRate",
"destructuring": true
},
- "group": "表单组件",
- "category": "element-plus",
- "configure": {
- "loop": true,
- "condition": true,
- "styles": true,
- "isContainer": false,
- "isModal": false,
- "isPopper": false,
- "nestingRule": {
- "childWhitelist": "",
- "parentWhitelist": "",
- "descendantBlacklist": "",
- "ancestorWhitelist": ""
- },
- "isNullNode": false,
- "isLayout": false,
- "rootSelector": "",
- "shortcuts": {
- "properties": ["type", "size"]
- },
- "contextMenu": {
- "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"],
- "disable": []
- },
- "invalidity": [""],
- "clickCapture": true,
- "framework": "Vue"
- },
+ "group": "component",
+ "category": "评分组件",
+ "priority": 2,
"schema": {
"properties": [
{
@@ -60,721 +33,561 @@
},
"content": [
{
- "property": "modelValue",
+ "cols": 12,
+ "type": "number",
"label": {
"text": {
"zh_CN": "绑定值"
}
},
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
+ },
+ "disabled": false,
+ "property": "modelValue",
+ "readOnly": false,
+ "required": false,
"description": {
"zh_CN": "绑定值"
},
- "required": true,
- "readOnly": false,
- "disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "widget": {
- "component": "InputConfigurator",
- "props": {}
- }
+ "defaultValue": 0,
+ "labelPosition": "left"
},
{
- "property": "size",
+ "cols": 12,
+ "type": "number",
"label": {
"text": {
- "zh_CN": "尺寸"
+ "zh_CN": "最大分值"
}
},
- "description": {
- "zh_CN": "尺寸"
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
+ "property": "max",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "最大分值"
+ },
+ "defaultValue": 5,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性"
+ }
+ },
+ {
+ "name": "1",
+ "label": {
+ "zh_CN": "样式属性"
+ },
+ "content": [
+ {
"cols": 12,
- "labelPosition": "left",
- "type": "string",
- "defaultValue": "default",
+ "type": "array",
+ "label": {
+ "text": {
+ "zh_CN": "颜色数组"
+ }
+ },
"widget": {
- "component": "SelectConfigurator",
"props": {
- "options": [
- {
- "label": "large",
- "value": "large"
- },
- {
- "label": "default",
- "value": "default"
- },
- {
- "label": "small",
- "value": "small"
- }
- ]
- }
- }
+ "height": 150,
+ "language": "json"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "colors",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "icon 的颜色数组,为 Threshold 三个分段所对应的颜色"
+ },
+ "defaultValue": "['#FADB14', '#FADB14', '#FADB14']",
+ "labelPosition": "left"
},
{
- "property": "type",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "类型"
+ "zh_CN": "禁用未选中颜色"
}
},
- "description": {
- "zh_CN": "类型"
+ "widget": {
+ "props": {},
+ "component": "ColorConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
+ "property": "disabled-void-color",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "禁用状态下未选中 icon 的颜色"
+ },
+ "defaultValue": "#D9D9D9",
+ "labelPosition": "left"
+ },
+ {
"cols": 12,
- "labelPosition": "left",
"type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "禁用未选中图标类"
+ }
+ },
"widget": {
- "component": "InputConfigurator",
- "props": {}
- }
+ "props": {
+ "placeholder": "请输入图标名称"
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "disabled-void-icon-class",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "只读状态下未选中的图标样式名"
+ },
+ "defaultValue": "icon-starActive",
+ "labelPosition": "left"
},
{
- "property": "placeholder",
+ "cols": 12,
+ "type": "array",
"label": {
"text": {
- "zh_CN": "占位文本"
+ "zh_CN": "图标类数组"
}
},
- "description": {
- "zh_CN": "输入框占位文本"
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "json"
+ },
+ "component": "CodeConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
+ "property": "icon-classes",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "三个分段对应的图标样式名"
+ },
+ "defaultValue": "['icon-starActive', 'icon-starActive', 'icon-starActive']",
+ "labelPosition": "left"
+ },
+ {
"cols": 12,
- "labelPosition": "left",
"type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "图标大小"
+ }
+ },
"widget": {
- "component": "I18nConfigurator",
- "props": {}
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
},
- "device": []
+ "disabled": false,
+ "property": "size",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "图标字体大小"
+ },
+ "defaultValue": "18px",
+ "labelPosition": "left"
},
{
- "property": "maxlength",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "最大长度"
+ "zh_CN": "图标间距"
}
},
- "description": {
- "zh_CN": "最大输入长度"
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
+ "property": "space",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "每个图标所占宽度"
+ },
+ "defaultValue": "24px",
+ "labelPosition": "left"
+ },
+ {
"cols": 12,
- "labelPosition": "left",
- "type": "number",
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "文字颜色"
+ }
+ },
"widget": {
- "component": "NumberConfigurator",
- "props": {}
+ "props": {},
+ "component": "ColorConfigurator"
},
- "device": []
+ "disabled": false,
+ "property": "text-color",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "辅助文字的颜色"
+ },
+ "defaultValue": "#666666",
+ "labelPosition": "left"
},
{
- "property": "disabled",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "是否禁用"
+ "zh_CN": "未选中颜色"
}
},
- "description": {
- "zh_CN": "是否禁用"
+ "widget": {
+ "props": {},
+ "component": "ColorConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
+ "property": "void-color",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "未选中 icon 的颜色"
+ },
+ "defaultValue": "#BFBFBF",
+ "labelPosition": "left"
+ },
+ {
"cols": 12,
- "labelPosition": "left",
- "defaultValue": false,
- "type": "boolean",
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "未选中图标类"
+ }
+ },
"widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ "props": {
+ "placeholder": "请输入图标名称"
+ },
+ "component": "InputConfigurator"
},
- "device": []
+ "disabled": false,
+ "property": "void-icon-class",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "未选中 icon 的图标样式名"
+ },
+ "defaultValue": "icon-starDisable",
+ "labelPosition": "left"
}
],
"description": {
- "zh_CN": ""
- }
- }
- ],
- "events": {
- "onUpdate:modelValue": {
- "label": {
- "zh_CN": "双向绑定值改变时触发"
- },
- "description": {
- "zh_CN": "双向绑定值改变时触发"
- }
- },
- "onBlur": {
- "label": {
- "zh_CN": "输入框失去焦点时触发"
- },
- "description": {
- "zh_CN": "输入框失去焦点时触发"
- },
- "type": "event",
- "functionInfo": {
- "params": [
- {
- "name": "event",
- "type": "Object",
- "defaultValue": "",
- "description": {
- "zh_CN": "原生 event"
- }
- }
- ],
- "returns": {}
- },
- "defaultValue": ""
- }
- },
- "slots": {
- "prefix": {
- "label": {
- "zh_CN": "头部内容"
- },
- "description": {
- "zh_CN": "输入框头部内容,只对非 type='textarea' 有效"
- }
- },
- "suffix": {
- "label": {
- "zh_CN": "尾部内容"
- },
- "description": {
- "zh_CN": "输入框尾部内容,只对非 type='textarea' 有效"
- }
- },
- "prepend": {
- "label": {
- "zh_CN": "前置内容"
- },
- "description": {
- "zh_CN": "输入框前置内容,只对非 type='textarea' 有效"
+ "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性"
}
},
- "append": {
- "label": {
- "zh_CN": "后置内容"
- },
- "description": {
- "zh_CN": "输入框后置内容,只对非 type='textarea' 有效"
- }
- }
- }
- }
- },
- {
- "id": 1,
- "version": "2.4.2",
- "name": {
- "zh_CN": "日期选择器"
- },
- "component": "ElDatePicker",
- "icon": "datepick",
- "description": "日期选择器",
- "doc_url": "",
- "screenshot": "",
- "tags": "",
- "keywords": "",
- "dev_mode": "proCode",
- "npm": {
- "package": "element-plus",
- "exportName": "ElDatePicker",
- "destructuring": true
- },
- "group": "表单组件",
- "category": "element-plus",
- "configure": {
- "loop": true,
- "condition": true,
- "styles": true,
- "isContainer": false,
- "isModal": false,
- "isPopper": false,
- "nestingRule": {
- "childWhitelist": "",
- "parentWhitelist": "",
- "descendantBlacklist": "",
- "ancestorWhitelist": ""
- },
- "isNullNode": false,
- "isLayout": false,
- "rootSelector": "",
- "shortcuts": {
- "properties": ["type", "size"]
- },
- "contextMenu": {
- "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"],
- "disable": []
- },
- "invalidity": [""],
- "clickCapture": true,
- "framework": "Vue"
- },
- "schema": {
- "properties": [
{
- "name": "0",
+ "name": "2",
"label": {
- "zh_CN": "基础属性"
+ "zh_CN": "行为属性"
},
"content": [
{
- "property": "modelValue",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "绑定值"
+ "zh_CN": "允许半选"
}
},
- "description": {
- "zh_CN": "绑定值"
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
},
- "required": false,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "widget": {
- "component": "InputConfigurator",
- "props": {}
- }
+ "property": "allow-half",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否允许半选"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
},
{
- "property": "readonly",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "只读"
+ "zh_CN": "禁用"
}
},
- "description": {
- "zh_CN": "是否只读"
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "boolean",
+ "property": "disabled",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否为只读"
+ },
"defaultValue": false,
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
+ "labelPosition": "left"
},
{
- "property": "disabled",
+ "cols": 12,
+ "type": "number",
"label": {
"text": {
- "zh_CN": "禁用"
+ "zh_CN": "高分阈值"
}
},
- "description": {
- "zh_CN": "是否禁用"
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "boolean",
- "defaultValue": false,
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
+ "property": "high-threshold",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "高分和中等分数的界限值,值本身被划分在高分中"
+ },
+ "defaultValue": 4,
+ "labelPosition": "left"
},
{
- "property": "size",
+ "cols": 12,
+ "type": "number",
"label": {
"text": {
- "zh_CN": "尺寸"
+ "zh_CN": "低分阈值"
}
},
- "description": {
- "zh_CN": "输入框尺寸"
- },
- "required": true,
- "readOnly": false,
- "disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "defaultValue": "",
"widget": {
- "component": "SelectConfigurator",
"props": {
- "allowClear": true,
- "options": [
- {
- "label": "large",
- "value": "large"
- },
- {
- "label": "default",
- "value": "default"
- },
- {
- "label": "small",
- "value": "small"
- }
- ]
- }
- }
+ "step": 1
+ },
+ "component": "NumberConfigurator"
+ },
+ "disabled": false,
+ "property": "low-threshold",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "低分和中等分数的界限值,值本身被划分在低分中"
+ },
+ "defaultValue": 2,
+ "labelPosition": "left"
},
{
- "property": "editable",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "是否可编辑"
+ "zh_CN": "单选形态"
}
},
- "description": {
- "zh_CN": "文本框是否可编辑"
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "boolean",
- "defaultValue": true,
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ "property": "radio",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "评分其他形态单选"
},
- "device": []
+ "defaultValue": false,
+ "labelPosition": "left"
},
{
- "property": "clearable",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "是否可清除"
+ "zh_CN": "分数模板"
}
},
- "description": {
- "zh_CN": "是否显示清楚按钮"
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "boolean",
- "defaultValue": true,
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ "property": "score-template",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "分数显示模板,用“{value}”代表分数"
},
- "device": []
+ "defaultValue": "{value}",
+ "labelPosition": "left"
},
{
- "property": "placeholder",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "占位文本"
+ "zh_CN": "显示分数"
}
},
- "description": {
- "zh_CN": "非范围选择时的占位内容"
+ "widget": {
+ "props": {},
+ "component": "SwitchConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "defaultValue": "",
- "type": "string",
- "widget": {
- "component": "InputConfigurator",
- "props": {}
+ "property": "show-score",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否显示当前分数,show-score 和 show-text 不能同时为真"
},
- "device": []
+ "defaultValue": false,
+ "labelPosition": "left"
},
{
- "property": "start-placeholder",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "起始占位文本"
+ "zh_CN": "显示文字"
}
},
- "description": {
- "zh_CN": "范围选择时开始日期的占位内容"
+ "widget": {
+ "props": {},
+ "component": "SwitchConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "defaultValue": "",
- "type": "string",
- "widget": {
- "component": "InputConfigurator",
- "props": {}
+ "property": "show-text",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否显示辅助文字,若为真,则会从 texts 数组中选取当前分数对应的文字内容"
},
- "device": []
+ "defaultValue": false,
+ "labelPosition": "left"
},
{
- "property": "end-placeholder",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "结束占位文本"
+ "zh_CN": "文字在底部"
}
},
- "description": {
- "zh_CN": "范围选择时结束日期的占位内容"
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "defaultValue": "",
- "type": "string",
- "widget": {
- "component": "InputConfigurator",
- "props": {}
+ "property": "text-on-bottom",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否在图标下显示对应的文字"
},
- "device": []
+ "defaultValue": false,
+ "labelPosition": "left"
},
{
- "property": "type",
+ "cols": 12,
+ "type": "array",
"label": {
"text": {
- "zh_CN": "类型"
+ "zh_CN": "文字数组"
}
},
- "description": {
- "zh_CN": "显示类型"
- },
- "required": true,
- "readOnly": false,
- "disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "defaultValue": "date",
- "type": "string",
"widget": {
- "component": "SelectConfigurator",
"props": {
- "options": [
- {
- "label": "year",
- "value": "year"
- },
- {
- "label": "years",
- "value": "years"
- },
- {
- "label": "month",
- "value": "month"
- },
- {
- "label": "months",
- "value": "months"
- },
- {
- "label": "date",
- "value": "date"
- },
- {
- "label": "dates",
- "value": "dates"
- },
- {
- "label": "datetime",
- "value": "datetime"
- },
- {
- "label": "week",
- "value": "week"
- },
- {
- "label": "datetimerange",
- "value": "datetimerange"
- },
- {
- "label": "daterange",
- "value": "daterange"
- },
- {
- "label": "monthrange",
- "value": "monthrange"
- },
- {
- "label": "yearrange",
- "value": "yearrange"
- }
- ]
- }
- },
- "device": []
- },
- {
- "property": "popper-class",
- "label": {
- "text": {
- "zh_CN": "下拉框类名"
- }
- },
- "description": {
- "zh_CN": "DatePicker 下拉框的类名"
+ "height": 150,
+ "language": "json"
+ },
+ "component": "CodeConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "defaultValue": "",
- "type": "string",
- "widget": {
- "component": "InputConfigurator",
- "props": {}
+ "property": "texts",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "辅助文字数组,文字的数量应该与max属性一致"
},
- "device": []
+ "defaultValue": "['很差', '差', '一般', '好', '很好']",
+ "labelPosition": "left"
}
],
"description": {
- "zh_CN": ""
+ "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性"
}
}
],
"events": {
- "onUpdate:modelValue": {
- "label": {
- "zh_CN": "双向绑定值改变时触发"
- },
- "description": {
- "zh_CN": "双向绑定值改变时触发"
- }
- },
"onChange": {
- "label": {
- "zh_CN": "用户确认选定的值时触发"
- },
- "description": {
- "zh_CN": "用户确认选定的值时触发"
- },
- "type": "event",
- "defaultValue": ""
- },
- "onBlur": {
- "label": {
- "zh_CN": "在组件 Input 失去焦点时触发"
- },
- "description": {
- "zh_CN": "在组件 Input 失去焦点时触发"
- },
- "type": "event",
- "defaultValue": ""
- },
- "onFocus": {
- "label": {
- "zh_CN": "在组件 Input 获得焦点时触发"
- },
- "description": {
- "zh_CN": "在组件 Input 获得焦点时触发"
- },
- "type": "event",
- "defaultValue": ""
- },
- "onCalendarChange": {
- "label": {
- "zh_CN": "在日历所选日期更改时触发"
- },
- "description": {
- "zh_CN": "在日历所选日期更改时触发"
- },
- "type": "event",
- "defaultValue": ""
- },
- "onPanelChange": {
- "label": {
- "zh_CN": "当日期面板改变时触发。"
- },
- "description": {
- "zh_CN": "当日期面板改变时触发。"
- },
"type": "event",
- "defaultValue": ""
- },
- "onVisibleChange": {
"label": {
- "zh_CN": "当 DatePicker 的下拉列表出现/消失时触发"
+ "zh_CN": "分值改变时触发"
},
"description": {
- "zh_CN": "当 DatePicker 的下拉列表出现/消失时触发"
+ "zh_CN": "分值改变时触发"
},
- "type": "event",
- "defaultValue": ""
- }
- },
- "slots": {
- "default": {
- "label": {
- "zh_CN": "自定义单元格内容"
- },
- "description": {
- "zh_CN": "自定义单元格内容"
- }
- },
- "range-separator": {
- "label": {
- "zh_CN": "自定义范围分割符内容"
- },
- "description": {
- "zh_CN": "自定义范围分割符内容"
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "value",
+ "type": "number",
+ "description": {
+ "zh_CN": "改变后的分值"
+ },
+ "defaultValue": ""
+ }
+ ],
+ "returns": {
+ "type": "",
+ "description": {
+ "zh_CN": ""
+ },
+ "defaultValue": ""
+ }
}
}
- }
- }
- },
- {
- "id": 1,
- "version": "2.4.2",
- "name": {
- "zh_CN": "按钮"
- },
- "component": "ElButton",
- "icon": "button",
- "description": "常用的操作按钮",
- "doc_url": "",
- "screenshot": "",
- "tags": "",
- "keywords": "",
- "dev_mode": "proCode",
- "npm": {
- "package": "element-plus",
- "exportName": "ElButton",
- "destructuring": true
+ },
+ "slots": {}
},
- "group": "基础组件",
- "category": "element-plus",
"configure": {
"loop": true,
"condition": true,
"styles": true,
- "isContainer": true,
+ "isContainer": false,
"isModal": false,
- "isPopper": false,
"nestingRule": {
"childWhitelist": "",
"parentWhitelist": "",
@@ -785,16 +598,35 @@
"isLayout": false,
"rootSelector": "",
"shortcuts": {
- "properties": ["type", "size"]
+ "properties": []
},
"contextMenu": {
- "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"],
- "disable": []
- },
- "invalidity": [""],
- "clickCapture": true,
- "framework": "Vue"
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "滑块"
+ },
+ "component": "TinySlider",
+ "icon": "slider",
+ "description": "滑块",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "package": "@opentiny/vue",
+ "exportName": "TinySlider",
+ "destructuring": true
},
+ "group": "component",
+ "category": "滑块组件",
+ "priority": 2,
"schema": {
"properties": [
{
@@ -804,297 +636,465 @@
},
"content": [
{
- "property": "size",
+ "cols": 12,
+ "type": "object",
"label": {
"text": {
- "zh_CN": "尺寸"
+ "zh_CN": "绑定值"
}
},
- "description": {
- "zh_CN": "尺寸"
- },
- "required": true,
- "readOnly": false,
- "disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "defaultValue": "default",
"widget": {
- "component": "SelectConfigurator",
"props": {
- "options": [
- {
- "label": "large",
- "value": "large"
- },
- {
- "label": "default",
- "value": "default"
- },
- {
- "label": "small",
- "value": "small"
- }
- ]
- }
- }
+ "height": 150,
+ "language": "json"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "modelValue",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "设置单滑块的当前值,必需是整数或数组"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "type",
+ "cols": 12,
+ "type": "number",
"label": {
"text": {
- "zh_CN": "类型"
+ "zh_CN": "最小值"
}
},
- "description": {
- "zh_CN": "类型"
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "widget": {
- "component": "InputConfigurator",
- "props": {}
- }
+ "property": "min",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "设置最小值"
+ },
+ "defaultValue": 0,
+ "labelPosition": "left"
},
{
- "property": "plain",
+ "cols": 12,
+ "type": "number",
"label": {
"text": {
- "zh_CN": "朴素按钮"
+ "zh_CN": "最大值"
}
},
- "description": {
- "zh_CN": "是否为朴素按钮"
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ "property": "max",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "设置最大值,必需是整数,可以负数,必需大于所设置的最小值"
},
- "device": []
+ "defaultValue": 100,
+ "labelPosition": "left"
},
{
- "property": "text",
+ "cols": 12,
+ "type": "number",
"label": {
"text": {
- "zh_CN": "文字按钮"
+ "zh_CN": "步长"
}
},
- "description": {
- "zh_CN": "是否为文字按钮"
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ "property": "step",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "设置滑块移动时,每步位移距离,必需是大于0的正整数"
},
- "device": []
- },
+ "defaultValue": 1,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性"
+ }
+ },
+ {
+ "name": "1",
+ "label": {
+ "zh_CN": "样式属性"
+ },
+ "content": [
{
- "property": "bg",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "背景颜色"
+ "zh_CN": "高度"
}
},
- "description": {
- "zh_CN": "是否显示文字按钮背景颜色"
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ "property": "height",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "Slider 组件的高度,当 vertical 为 true 时有效"
},
- "device": []
- },
+ "defaultValue": "300px",
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性"
+ }
+ },
+ {
+ "name": "2",
+ "label": {
+ "zh_CN": "行为属性"
+ },
+ "content": [
{
- "property": "link",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "链接按钮"
+ "zh_CN": "禁用"
}
},
- "description": {
- "zh_CN": "是否为链接按钮"
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ "property": "disabled",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否禁用"
},
- "device": []
+ "defaultValue": false,
+ "labelPosition": "left"
},
{
- "property": "round",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "圆角按钮"
+ "zh_CN": "显示输入框"
}
},
- "description": {
- "zh_CN": "是否为圆角按钮"
+ "widget": {
+ "props": {},
+ "component": "SwitchConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ "property": "show-input",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否显示输入框"
},
- "device": []
+ "defaultValue": false,
+ "labelPosition": "left"
},
{
- "property": "circle",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "圆形按钮"
+ "zh_CN": "显示提示"
}
},
- "description": {
- "zh_CN": "是否为圆形按钮"
+ "widget": {
+ "props": {},
+ "component": "SwitchConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
+ "property": "show-tip",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否显示 tooltip"
+ },
+ "defaultValue": true,
+ "labelPosition": "left"
+ },
+ {
"cols": 12,
- "labelPosition": "left",
- "type": "string",
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "单位"
+ }
+ },
"widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ "props": {},
+ "component": "CheckBoxConfigurator"
},
- "device": []
+ "disabled": false,
+ "property": "unit",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "输入框后面显示的单位,仅在输入框模式下有效"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
},
{
- "property": "loading",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "加载中状态"
+ "zh_CN": "竖向模式"
}
},
- "description": {
- "zh_CN": "是否为加载中状态"
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
+ "property": "vertical",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否竖向模式"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性"
+ }
+ },
+ {
+ "name": "3",
+ "label": {
+ "zh_CN": "高级属性"
+ },
+ "content": [
+ {
"cols": 12,
- "labelPosition": "left",
- "type": "string",
+ "type": "function",
+ "label": {
+ "text": {
+ "zh_CN": "格式化提示"
+ }
+ },
"widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ "props": {
+ "height": 150,
+ "language": "javascript"
+ },
+ "component": "CodeConfigurator"
},
- "device": []
+ "disabled": false,
+ "property": "format-tooltip",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "格式化 tooltip 提示"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "disabled",
+ "cols": 12,
+ "type": "object",
"label": {
"text": {
- "zh_CN": "禁用"
+ "zh_CN": "刻度"
}
},
- "description": {
- "zh_CN": "是否禁用"
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "json"
+ },
+ "component": "CodeConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
+ "property": "marks",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "设置滑杆的刻度值"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
"cols": 12,
- "labelPosition": "left",
- "defaultValue": false,
- "type": "boolean",
+ "type": "number",
+ "label": {
+ "text": {
+ "zh_CN": "总步数"
+ }
+ },
"widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
},
- "device": []
+ "disabled": false,
+ "property": "num-pages",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "设置总步数,即按快捷键 PageDown/PageUp 时,每次移动的距离是 \"⌈(max-min)/num-pages⌉\""
+ },
+ "defaultValue": 1,
+ "labelPosition": "left"
}
],
"description": {
- "zh_CN": ""
+ "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置"
}
}
],
- "events": {},
- "slots": {
- "default": {
+ "events": {
+ "onStop": {
+ "type": "event",
"label": {
- "zh_CN": "default"
+ "zh_CN": "滑动结束时触发"
},
"description": {
- "zh_CN": "自定义默认内容"
+ "zh_CN": "设置滑块滑动结束时,触发该事件"
+ },
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "value",
+ "type": "number | [number, number]",
+ "description": {
+ "zh_CN": "当前值"
+ },
+ "defaultValue": ""
+ }
+ ],
+ "returns": {
+ "type": "",
+ "description": {
+ "zh_CN": ""
+ },
+ "defaultValue": ""
+ }
}
},
- "loading": {
+ "onStart": {
+ "type": "event",
"label": {
- "zh_CN": "loading"
+ "zh_CN": "滑动开始时触发"
},
"description": {
- "zh_CN": "自定义加载中组件"
+ "zh_CN": "设置滑块滑动开始时,触发该事件"
+ },
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "event",
+ "type": "Event",
+ "description": {
+ "zh_CN": "事件对象"
+ },
+ "defaultValue": ""
+ },
+ {
+ "name": "value",
+ "type": "number | [number, number]",
+ "description": {
+ "zh_CN": "当前值"
+ },
+ "defaultValue": ""
+ }
+ ],
+ "returns": {
+ "type": "",
+ "description": {
+ "zh_CN": ""
+ },
+ "defaultValue": ""
+ }
+ }
+ },
+ "onChange": {
+ "type": "event",
+ "label": {
+ "zh_CN": "值改变时触发"
+ },
+ "description": {
+ "zh_CN": "值改变时触发(使用鼠标拖曳时,只在松开鼠标后触发)"
+ },
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "value",
+ "type": "number | [number, number]",
+ "description": {
+ "zh_CN": "当前值"
+ },
+ "defaultValue": ""
+ }
+ ],
+ "returns": {
+ "type": "",
+ "description": {
+ "zh_CN": ""
+ },
+ "defaultValue": ""
+ }
+ }
+ }
+ },
+ "slots": {
+ "default": {
+ "label": {
+ "zh_CN": "默认内容"
+ },
+ "description": {
+ "zh_CN": "显示滑块值的插槽,仅仅 v-model 是单数值时才有效"
}
}
}
- }
- },
- {
- "id": 1,
- "version": "2.4.2",
- "name": {
- "zh_CN": "表单"
},
- "component": "ElForm",
- "icon": "form",
- "description": "表单包含 输入框, 单选框, 下拉选择, 多选框 等用户输入的组件。 使用表单,您可以收集、验证和提交数据。",
- "doc_url": "",
- "screenshot": "",
- "tags": "",
- "keywords": "",
- "dev_mode": "proCode",
- "npm": {
- "package": "element-plus",
- "exportName": "ElForm",
- "destructuring": true
- },
- "group": "表单组件",
- "category": "element-plus",
"configure": {
"loop": true,
"condition": true,
"styles": true,
- "isContainer": true,
+ "isContainer": false,
"isModal": false,
- "isPopper": false,
"nestingRule": {
- "childWhitelist": ["ElFormItem"],
+ "childWhitelist": "",
"parentWhitelist": "",
"descendantBlacklist": "",
"ancestorWhitelist": ""
@@ -1103,448 +1103,650 @@
"isLayout": false,
"rootSelector": "",
"shortcuts": {
- "properties": ["inline", "label-width"]
+ "properties": []
},
"contextMenu": {
- "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"],
- "disable": []
- },
- "invalidity": [""],
- "clickCapture": true,
- "framework": "Vue"
- },
- "schema": {
- "properties": [
- {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "级联选择器"
+ },
+ "component": "TinyCascader",
+ "icon": "cascader",
+ "description": "级联选择器",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "package": "@opentiny/vue",
+ "exportName": "TinyCascader",
+ "destructuring": true
+ },
+ "group": "component",
+ "category": "组件",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
"name": "0",
"label": {
"zh_CN": "基础属性"
},
"content": [
{
- "property": "model",
+ "cols": 12,
+ "type": "object",
"label": {
"text": {
- "zh_CN": "数据对象"
+ "zh_CN": "绑定值"
}
},
- "description": {
- "zh_CN": "表单数据对象"
- },
- "required": true,
- "readOnly": false,
- "disabled": false,
- "cols": 12,
- "labelPosition": "top",
"widget": {
- "component": "CodeConfigurator",
"props": {
+ "height": 150,
"language": "json"
- }
- }
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "modelValue",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "选中项绑定值, 其类型由 props.multiple、props.emitPath 共同决定"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "rules",
+ "cols": 12,
+ "type": "array",
"label": {
"text": {
- "zh_CN": "验证规则"
+ "zh_CN": "选项数据"
}
},
- "description": {
- "zh_CN": "表单验证规则"
- },
- "required": true,
- "readOnly": false,
- "disabled": false,
- "cols": 12,
- "labelPosition": "top",
"widget": {
- "component": "CodeConfigurator",
"props": {
+ "height": 150,
"language": "json"
- }
- }
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "options",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "可选项数据源,键名可通过 Props 属性配置"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "inline",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "行内模式"
+ "zh_CN": "占位文本"
}
},
- "description": {
- "zh_CN": "行内表单模式"
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "boolean",
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
+ "property": "placeholder",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "输入框占位文本"
+ },
+ "defaultValue": "请选择",
+ "labelPosition": "left"
},
{
- "property": "label-position",
+ "cols": 12,
+ "type": "enum",
"label": {
"text": {
- "zh_CN": "标签位置"
+ "zh_CN": "尺寸"
}
},
- "description": {
- "zh_CN": "表单域标签的位置, 当设置为 left 或 right 时,则也需要设置标签宽度属性"
- },
- "required": true,
- "readOnly": false,
- "disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "defaultValue": "right",
"widget": {
- "component": "SelectConfigurator",
"props": {
"options": [
{
- "label": "left",
- "value": "left"
+ "label": "medium",
+ "value": "medium"
},
{
- "label": "right",
- "value": "right"
+ "label": "small",
+ "value": "small"
},
{
- "label": "top",
- "value": "top"
+ "label": "mini",
+ "value": "mini"
}
]
- }
- }
+ },
+ "component": "SelectConfigurator"
+ },
+ "disabled": false,
+ "property": "size",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "尺寸"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "label-width",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "标签宽度"
+ "zh_CN": "分隔符"
}
},
- "description": {
- "zh_CN": "标签的长度,例如 '50px'。 作为 Form 直接子元素的 form-item 会继承该值。 可以使用 auto。"
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "widget": {
- "component": "InputConfigurator",
- "props": {}
+ "property": "separator",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "选项分隔符"
},
- "device": []
+ "defaultValue": "/",
+ "labelPosition": "left"
},
{
- "property": "label-suffix",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "标签后缀"
+ "zh_CN": "显示所有层级"
}
},
- "description": {
- "zh_CN": "表单域标签的后缀"
+ "widget": {
+ "props": {},
+ "component": "SwitchConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "widget": {
- "component": "InputConfigurator",
- "props": {}
+ "property": "show-all-levels",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "输入框中是否显示选中值的完整路径"
},
- "device": []
- },
+ "defaultValue": true,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性"
+ }
+ },
+ {
+ "name": "1",
+ "label": {
+ "zh_CN": "行为属性"
+ },
+ "content": [
{
- "property": "hide-required-asterisk",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "隐藏必填星号"
+ "zh_CN": "禁用"
}
},
- "description": {
- "zh_CN": "是否隐藏必填字段标签旁边的红色星号"
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "boolean",
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
+ "property": "disabled",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
},
{
- "property": "require-asterisk-position",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "星号位置"
+ "zh_CN": "可清空"
}
},
- "description": {
- "zh_CN": "星号的位置"
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "defaultValue": "left",
- "widget": {
- "component": "ButtonGroupConfigurator",
- "props": {
- "options": [
- {
- "label": "left",
- "value": "left"
- },
- {
- "label": "right",
- "value": "right"
- }
- ]
- }
- }
+ "property": "clearable",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否支持清空选项"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
},
{
- "property": "show-message",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "显示校验信息"
+ "zh_CN": "折叠标签"
}
},
- "description": {
- "zh_CN": "是否显示校验错误信息"
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
+ "property": "collapse-tags",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "多选模式下是否折叠 Tag"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
"cols": 12,
- "labelPosition": "left",
- "defaultValue": true,
"type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "可筛选"
+ }
+ },
"widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "filterable",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否可搜索选项"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "inline-message",
+ "cols": 12,
+ "type": "number",
"label": {
"text": {
- "zh_CN": "行内显示校验信息"
+ "zh_CN": "去抖延迟"
}
},
- "description": {
- "zh_CN": "是否以行内形式展示校验信息"
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
+ "property": "debounce",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "搜索关键词输入的去抖延迟,单位毫秒"
+ },
+ "defaultValue": 300,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性"
+ }
+ },
+ {
+ "name": "2",
+ "label": {
+ "zh_CN": "高级属性"
+ },
+ "content": [
+ {
"cols": 12,
- "labelPosition": "left",
- "defaultValue": false,
- "type": "boolean",
+ "type": "object",
+ "label": {
+ "text": {
+ "zh_CN": "筛选前钩子"
+ }
+ },
"widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
+ "props": {
+ "height": 150,
+ "language": "json"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "before-filter",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "筛选之前的钩子,参数为输入的值,若返回 false 或者返回 Promise 且被 reject,则停止筛选"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "status-icon",
+ "cols": 12,
+ "type": "object",
"label": {
"text": {
- "zh_CN": "显示校验结果图标"
+ "zh_CN": "筛选方法"
}
},
- "description": {
- "zh_CN": "是否在输入框中显示校验结果反馈图标"
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "json"
+ },
+ "component": "CodeConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "defaultValue": false,
- "type": "boolean",
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
+ "property": "filter-method",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "自定义搜索逻辑,第一个参数是节点 node,第二个参数是搜索关键词 keyword,通过返回布尔值表示是否命中"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "validate-on-rule-change",
+ "cols": 12,
+ "type": "object",
"label": {
"text": {
- "zh_CN": "触发验证"
+ "zh_CN": "配置选项"
}
},
- "description": {
- "zh_CN": "是否在 rules 属性改变后立即触发一次验证"
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "json"
+ },
+ "component": "CodeConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "defaultValue": true,
- "type": "boolean",
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
+ "property": "props",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "配置选项,具体见 ICascaderPanelConfig 表"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "size",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "尺寸"
+ "zh_CN": "形状模式"
}
},
- "description": {
- "zh_CN": "用于控制该表单内组件的尺寸"
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
+ "property": "shape",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "通过 shape='filter' 属性切换至过滤器模式"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
"cols": 12,
- "labelPosition": "left",
"type": "string",
- "defaultValue": "default",
+ "label": {
+ "text": {
+ "zh_CN": "标签"
+ }
+ },
"widget": {
- "component": "SelectConfigurator",
"props": {
- "options": [
- {
- "label": "large",
- "value": "large"
- },
- {
- "label": "default",
- "value": "default"
- },
- {
- "label": "small",
- "value": "small"
- }
- ]
- }
- }
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "label",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "shape='filter' 时生效,可传入 label 显示标题"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "disabled",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "禁用"
+ "zh_CN": "提示信息"
}
},
- "description": {
- "zh_CN": "是否禁用该表单内的所有组件。 如果设置为 true, 它将覆盖内部组件的 disabled 属性"
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
+ "property": "tip",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "shape='filter' 时生效,可传入 tip 显示提示信息"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
"cols": 12,
- "labelPosition": "left",
- "defaultValue": false,
"type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "透明背景"
+ }
+ },
"widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ "props": {},
+ "component": "CheckBoxConfigurator"
},
- "device": []
+ "disabled": false,
+ "property": "blank",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "shape='filter' 时生效,设置过滤器模式背景为透明"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
},
{
- "property": "scroll-to-error",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "滚动到错误项"
+ "zh_CN": "弹出框插入 body"
}
},
- "description": {
- "zh_CN": "当校验失败时,滚动到第一个错误表单项"
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
+ "property": "popper-append-to-body",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否将弹出框插入至 body 元素。在弹出框的定位出现问题时,可将该属性设置为 false (可参考 select 组件)"
+ },
+ "defaultValue": true,
+ "labelPosition": "left"
+ },
+ {
"cols": 12,
- "labelPosition": "left",
- "defaultValue": false,
- "type": "boolean",
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "弹出框类名"
+ }
+ },
"widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
},
- "device": []
+ "disabled": false,
+ "property": "popper-class",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "为 popper 添加类名(可参考 popover 组件)"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
}
],
"description": {
- "zh_CN": ""
+ "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置"
}
}
],
"events": {
- "onValidate": {
+ "onBlur": {
+ "type": "event",
"label": {
- "zh_CN": "任一表单项被校验后触发"
+ "zh_CN": "当失去焦点时触发"
},
"description": {
- "zh_CN": "任一表单项被校验后触发"
+ "zh_CN": "当失去焦点时触发"
},
+ "defaultValue": ""
+ },
+ "onFocus": {
"type": "event",
- "functionInfo": {
- "params": [],
- "returns": {}
+ "label": {
+ "zh_CN": "当获得焦点时触发"
+ },
+ "description": {
+ "zh_CN": "当获得焦点时触发"
+ },
+ "defaultValue": ""
+ },
+ "onChange": {
+ "type": "event",
+ "label": {
+ "zh_CN": "当选中节点变化时触发"
+ },
+ "description": {
+ "zh_CN": "当选中节点变化时触发"
+ },
+ "defaultValue": ""
+ },
+ "onRemoveTag": {
+ "type": "event",
+ "label": {
+ "zh_CN": "在多选模式下,移除Tag时触发"
+ },
+ "description": {
+ "zh_CN": "在多选模式下,移除Tag时触发"
+ },
+ "defaultValue": ""
+ },
+ "onExpandChange": {
+ "type": "event",
+ "label": {
+ "zh_CN": "当展开节点发生变化时触发"
+ },
+ "description": {
+ "zh_CN": "当展开节点发生变化时触发"
+ },
+ "defaultValue": ""
+ },
+ "onVisibleChange": {
+ "type": "event",
+ "label": {
+ "zh_CN": "下拉框出现/隐藏时触发"
+ },
+ "description": {
+ "zh_CN": "下拉框出现/隐藏时触发"
},
"defaultValue": ""
}
},
- "slots": {}
- }
- },
- {
- "id": 1,
- "version": "2.4.2",
- "name": {
- "zh_CN": "表单子项"
- },
- "component": "ElFormItem",
- "icon": "formItem",
- "description": "表单包含 输入框, 单选框, 下拉选择, 多选框 等用户输入的组件。 使用表单,您可以收集、验证和提交数据。",
- "doc_url": "",
- "screenshot": "",
- "tags": "",
- "keywords": "",
- "dev_mode": "proCode",
- "npm": {
- "package": "element-plus",
- "exportName": "ElFormItem",
- "destructuring": true
+ "slots": {
+ "empty": {
+ "label": {
+ "zh_CN": "空状态"
+ },
+ "description": {
+ "zh_CN": "无匹配选项时的内容"
+ }
+ },
+ "default": {
+ "label": {
+ "zh_CN": "默认内容"
+ },
+ "description": {
+ "zh_CN": "自定义备选项的节点内容,参数为 { node: ICascaderPanelNode, data: ICascaderPanelData },分别为当前节点的 Node 对象和数据"
+ }
+ },
+ "no-data": {
+ "label": {
+ "zh_CN": "无数据"
+ },
+ "description": {
+ "zh_CN": "通过 no-data 插槽设置没有数据时显示的内容"
+ }
+ }
+ }
},
- "group": "表单组件",
- "category": "element-plus",
"configure": {
"loop": true,
"condition": true,
"styles": true,
- "isContainer": true,
+ "isContainer": false,
"isModal": false,
- "isPopper": false,
"nestingRule": {
"childWhitelist": "",
"parentWhitelist": "",
@@ -1555,16 +1757,35 @@
"isLayout": false,
"rootSelector": "",
"shortcuts": {
- "properties": ["inline", "label-width"]
+ "properties": []
},
"contextMenu": {
- "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"],
- "disable": []
- },
- "invalidity": [""],
- "clickCapture": true,
- "framework": "Vue"
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "单选组"
},
+ "component": "TinyRadioGroup",
+ "icon": "radiogroup",
+ "description": "单选组",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "package": "@opentiny/vue",
+ "exportName": "TinyRadioGroup",
+ "destructuring": true
+ },
+ "group": "component",
+ "category": "组件",
+ "priority": 2,
"schema": {
"properties": [
{
@@ -1574,325 +1795,324 @@
},
"content": [
{
- "property": "prop",
+ "cols": 12,
+ "type": "array",
"label": {
"text": {
- "zh_CN": "键名"
+ "zh_CN": "绑定值"
}
},
- "description": {
- "zh_CN": "model 的键名。 它可以是一个属性的值(如 a.b.0 或 [a', 'b', '0'])。 在定义了 validate、resetFields 的方法时,该属性是必填的"
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "json"
+ },
+ "component": "CodeConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "widget": {
- "component": "InputConfigurator",
- "props": {}
- }
+ "property": "modelValue",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "单选组绑定值"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "label",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "标签文本"
+ "zh_CN": "尺寸"
}
},
- "description": {
- "zh_CN": "标签文本"
+ "widget": {
+ "props": {
+ "options": [
+ {
+ "label": "medium",
+ "value": "medium"
+ },
+ {
+ "label": "small",
+ "value": "small"
+ },
+ {
+ "label": "mini",
+ "value": "mini"
+ }
+ ]
+ },
+ "component": "SelectConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "widget": {
- "component": "InputConfigurator",
- "props": {}
- }
+ "property": "size",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "单选组尺寸"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "label-width",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "标签宽度"
+ "zh_CN": "类型"
}
},
- "description": {
- "zh_CN": "标签宽度,例如 '50px'。 可以使用 auto"
+ "widget": {
+ "props": {
+ "options": [
+ {
+ "label": "radio",
+ "value": "radio"
+ },
+ {
+ "label": "button",
+ "value": "button"
+ }
+ ]
+ },
+ "component": "SelectConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
+ "property": "type",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "配置式单选组的展示形式"
+ },
+ "defaultValue": "radio",
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性"
+ }
+ },
+ {
+ "name": "1",
+ "label": {
+ "zh_CN": "样式属性"
+ },
+ "content": [
+ {
"cols": 12,
- "labelPosition": "left",
"type": "string",
- "widget": {
- "component": "InputConfigurator",
- "props": {}
- }
- },
- {
- "property": "required",
"label": {
"text": {
- "zh_CN": "必填项"
+ "zh_CN": "填充颜色"
}
},
- "description": {
- "zh_CN": "是否为必填项,如不设置,则会根据校验规则确认"
+ "widget": {
+ "props": {},
+ "component": "ColorConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "boolean",
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
+ "property": "fill",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "按钮形式单选选中时的背景颜色"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "rules",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "验证规则"
+ "zh_CN": "文本颜色"
}
},
- "description": {
- "zh_CN": "表单验证规则, 更多内容可以参考async-validator"
+ "widget": {
+ "props": {},
+ "component": "ColorConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "top",
- "widget": {
- "component": "CodeConfigurator",
- "props": {
- "language": "json"
- }
- }
- },
- {
- "property": "error",
- "label": {
- "text": {
- "zh_CN": "错误信息"
- }
- },
- "description": {
- "zh_CN": "表单域验证错误时的提示信息。设置该值会导致表单验证状态变为 error,并显示该错误信息"
- },
- "required": true,
+ "property": "text-color",
"readOnly": false,
- "disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "widget": {
- "component": "InputConfigurator",
- "props": {}
- }
- },
- {
- "property": "show-message",
- "label": {
- "text": {
- "zh_CN": "显示错误信息"
- }
- },
+ "required": false,
"description": {
- "zh_CN": "是否显示校验错误信息"
+ "zh_CN": "按钮形式单选激活时的文本颜色"
},
- "required": true,
- "readOnly": false,
- "disabled": false,
+ "defaultValue": null,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性"
+ }
+ },
+ {
+ "name": "2",
+ "label": {
+ "zh_CN": "行为属性"
+ },
+ "content": [
+ {
"cols": 12,
- "labelPosition": "left",
"type": "boolean",
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
- },
- {
- "property": "inline-message",
"label": {
"text": {
- "zh_CN": "行内显示错误信息"
+ "zh_CN": "禁用"
}
},
- "description": {
- "zh_CN": "是否在行内显示校验信息"
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "boolean",
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
+ "property": "disabled",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否禁用单选组"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
},
{
- "property": "size",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "尺寸"
+ "zh_CN": "只读"
}
},
- "description": {
- "zh_CN": "用于控制该表单内组件的尺寸"
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "defaultValue": "default",
- "widget": {
- "component": "SelectConfigurator",
- "props": {
- "options": [
- {
- "label": "large",
- "value": "large"
- },
- {
- "label": "default",
- "value": "default"
- },
- {
- "label": "small",
- "value": "small"
- }
- ]
- }
- }
+ "property": "display-only",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否只读状态"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
},
{
- "property": "for",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "for"
+ "zh_CN": "垂直显示"
}
},
- "description": {
- "zh_CN": "和原生标签相同能力"
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "widget": {
- "component": "InputConfigurator",
- "props": {}
- }
- },
+ "property": "vertical",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "垂直显示单选组"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性"
+ }
+ },
+ {
+ "name": "3",
+ "label": {
+ "zh_CN": "高级属性"
+ },
+ "content": [
{
- "property": "validate-status",
+ "cols": 12,
+ "type": "array",
"label": {
"text": {
- "zh_CN": "校验状态"
+ "zh_CN": "选项配置"
}
},
- "description": {
- "zh_CN": "formItem 校验的状态"
- },
- "required": true,
- "readOnly": false,
- "disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
"widget": {
- "component": "SelectConfigurator",
"props": {
- "options": [
- {
- "label": "error",
- "value": "error"
- },
- {
- "label": "validating",
- "value": "validating"
- },
- {
- "label": "success",
- "value": "success"
- }
- ]
- }
- }
+ "height": 150,
+ "language": "json"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "options",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "配置式单选组设置列表"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
}
],
"description": {
- "zh_CN": ""
+ "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置"
}
}
],
- "events": {},
- "slots": {
- "label": {
+ "events": {
+ "onChange": {
+ "type": "event",
"label": {
- "zh_CN": "label"
+ "zh_CN": "绑定值变化时触发"
},
"description": {
- "zh_CN": "标签位置显示的内容"
+ "zh_CN": "绑定值变化时触发的事件"
+ },
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "value",
+ "type": "number[] | string[]",
+ "description": {
+ "zh_CN": "变化后的值"
+ },
+ "defaultValue": ""
+ }
+ ],
+ "returns": {
+ "type": "void",
+ "description": {
+ "zh_CN": "无返回值"
+ },
+ "defaultValue": ""
+ }
}
- },
- "error": {
+ }
+ },
+ "slots": {
+ "default": {
"label": {
- "zh_CN": "error"
+ "zh_CN": "默认内容"
},
"description": {
- "zh_CN": "验证错误信息的显示内容"
+ "zh_CN": "radio-group 的默认插槽"
}
}
}
- }
- },
- {
- "id": 1,
- "version": "2.4.2",
- "name": {
- "zh_CN": "表单"
- },
- "component": "ElTable",
- "icon": "table",
- "description": "用于展示多条结构类似的数据, 可对数据进行排序、筛选、对比或其他自定义操作",
- "doc_url": "",
- "screenshot": "",
- "tags": "",
- "keywords": "",
- "dev_mode": "proCode",
- "npm": {
- "package": "element-plus",
- "exportName": "ElTable",
- "destructuring": true
},
- "group": "数据展示",
- "category": "element-plus",
"configure": {
"loop": true,
"condition": true,
"styles": true,
"isContainer": false,
"isModal": false,
- "isPopper": false,
"nestingRule": {
- "childWhitelist": ["ElTableColumn"],
+ "childWhitelist": "",
"parentWhitelist": "",
"descendantBlacklist": "",
"ancestorWhitelist": ""
@@ -1901,109 +2121,4769 @@
"isLayout": false,
"rootSelector": "",
"shortcuts": {
- "properties": ["inline", "label-width"]
+ "properties": []
},
"contextMenu": {
- "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"],
- "disable": []
- },
- "invalidity": [""],
- "clickCapture": true,
- "framework": "Vue"
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "步骤条"
},
- "schema": {
- "properties": [
- {
- "name": "0",
- "label": {
+ "component": "TinySteps",
+ "icon": "steps",
+ "description": "步骤条",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "package": "@opentiny/vue",
+ "exportName": "TinySteps",
+ "destructuring": true
+ },
+ "group": "component",
+ "category": "步骤条",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
+ "name": "0",
+ "label": {
"zh_CN": "基础属性"
},
"content": [
{
- "property": "data",
+ "cols": 12,
+ "type": "number",
+ "label": {
+ "text": {
+ "zh_CN": "当前步骤"
+ }
+ },
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
+ },
+ "disabled": false,
+ "property": "active",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "当前步骤索引,从0开始计数"
+ },
+ "defaultValue": -1,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "array",
"label": {
"text": {
"zh_CN": "数据"
}
},
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "json"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "data",
+ "readOnly": false,
+ "required": false,
"description": {
- "zh_CN": "显示的数据"
+ "zh_CN": "步骤条的数据"
},
- "required": true,
+ "defaultValue": [],
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "名称字段"
+ }
+ },
+ "widget": {
+ "props": {
+ "placeholder": "请输入字段名"
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "name-field",
"readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "节点名称对应的字段名"
+ },
+ "defaultValue": "",
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件核心功能相关的配置,包括当前步骤、数据等核心属性"
+ }
+ },
+ {
+ "name": "1",
+ "label": {
+ "zh_CN": "样式属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "内容居中"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
"disabled": false,
+ "property": "content-center",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "使步骤条内容默认居中显示"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
"cols": 12,
- "labelPosition": "top",
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "点状样式"
+ }
+ },
"widget": {
- "component": "CodeConfigurator",
- "props": {
- "language": "json"
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "dot",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "点状形步骤条,当值只支持垂直样式"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "自适应宽度"
}
- }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "flex",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "节点是否自适应宽度"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
},
{
- "property": "columns",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "表格列配置"
+ "zh_CN": "横向单链"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "line",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "通过 line 设置横向单链型步骤条"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "间距"
}
},
+ "widget": {
+ "props": {
+ "placeholder": "请输入宽度值"
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "space",
+ "readOnly": false,
"required": true,
+ "description": {
+ "zh_CN": "节点宽度, 可取值数字、带长度单位数值与百分比,传数字则默认以 px 为长度单位"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性"
+ }
+ },
+ {
+ "name": "2",
+ "label": {
+ "zh_CN": "行为属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "高级模式"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "advanced",
"readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否开启高级向导模式"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "number",
+ "label": {
+ "text": {
+ "zh_CN": "持续时间"
+ }
+ },
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
+ },
"disabled": false,
+ "property": "duration",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "节点滚动的持续时间(单位 ms),仅高级向导模式有效"
+ },
+ "defaultValue": 300,
+ "labelPosition": "left"
+ },
+ {
"cols": 12,
- "properties": [
- {
- "label": {
- "zh_CN": "默认分组"
- },
- "content": [
- {
- "property": "type",
- "type": "string",
- "labelPosition": "top",
- "label": {
- "text": {
- "zh_CN": "type"
- }
- },
- "description": {
- "text": {
- "zh_CN": "对应列的类型。 如果设置了selection则显示多选框; 如果设置了 index 则显示该行的索引(从 1 开始计算); 如果设置了 expand 则显示为一个可展开的按钮"
- }
- },
- "widget": {
- "component": "SelectConfigurator",
- "props": {
- "options": [
- {
- "label": "selection",
- "value": "selection"
- },
- {
- "label": "index",
- "value": "index"
- },
- {
- "label": "expand",
- "value": "expand"
- }
- ]
- }
- }
- },
- {
- "property": "index",
- "type": "string",
- "labelPosition": "top",
- "label": {
- "text": {
- "zh_CN": "index"
- }
- },
- "description": {
- "text": {
- "zh_CN": "如果设置了 type=index,可以通过传递 index 属性来自定义索引"
+ "type": "number",
+ "label": {
+ "text": {
+ "zh_CN": "可见节点数"
+ }
+ },
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
+ },
+ "disabled": false,
+ "property": "visible-num",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "控制信息可见的节点数,默认可见5个"
+ },
+ "defaultValue": 5,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性"
+ }
+ },
+ {
+ "name": "3",
+ "label": {
+ "zh_CN": "高级属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "计数字段"
+ }
+ },
+ "widget": {
+ "props": {
+ "placeholder": "请输入字段名"
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "count-field",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "条形步骤条里徽标计数对应的字段名"
+ },
+ "defaultValue": "",
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "状态字段"
+ }
+ },
+ "widget": {
+ "props": {
+ "placeholder": "请输入字段名"
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "status-field",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "数据状态对应的字段名,用于条形步骤条"
+ },
+ "defaultValue": "",
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置"
+ }
+ }
+ ],
+ "events": {
+ "onClick": {
+ "type": "event",
+ "label": {
+ "zh_CN": "节点点击事件"
+ },
+ "description": {
+ "zh_CN": "节点点击事件,参数:index: 点击节点的索引node:点击节点的数据"
+ },
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "index",
+ "type": "number",
+ "description": {
+ "zh_CN": "点击节点的索引"
+ },
+ "defaultValue": ""
+ },
+ {
+ "name": "node",
+ "type": "IStepsItem",
+ "description": {
+ "zh_CN": "点击节点的数据"
+ },
+ "defaultValue": ""
+ }
+ ],
+ "returns": {
+ "type": "",
+ "description": {
+ "zh_CN": ""
+ },
+ "defaultValue": ""
+ }
+ }
+ }
+ },
+ "slots": {
+ "item": {
+ "label": {
+ "zh_CN": "数据项"
+ },
+ "description": {
+ "zh_CN": "步骤条数据项插槽,用于条形步骤条"
+ }
+ },
+ "itemFooter": {
+ "label": {
+ "zh_CN": "itemFooter"
+ },
+ "description": {
+ "zh_CN": "步骤条数据项底部插槽,用于条形步骤条"
+ }
+ }
+ }
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": []
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "树形菜单"
+ },
+ "component": "TinyTreeMenu",
+ "icon": "tree",
+ "description": "树形菜单",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "package": "@opentiny/vue",
+ "exportName": "TinyTreeMenu",
+ "destructuring": true
+ },
+ "group": "component",
+ "category": "组件",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
+ "name": "0",
+ "label": {
+ "zh_CN": "基础属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "array",
+ "label": {
+ "text": {
+ "zh_CN": "数据源"
+ }
+ },
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "json"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "data",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "静态数据源"
+ },
+ "defaultValue": [],
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "节点键"
+ }
+ },
+ "widget": {
+ "props": {
+ "placeholder": "请输入节点键字段名"
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "node-key",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "设置每个树节点唯一标识(key)的属性,在整棵树中都是唯一的"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "object",
+ "label": {
+ "text": {
+ "zh_CN": "映射字段"
+ }
+ },
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "json"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "props",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "映射字段"
+ },
+ "defaultValue": {
+ "label": "label",
+ "isLeaf": "isLeaf",
+ "children": "children",
+ "disabled": "disabled"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "array",
+ "label": {
+ "text": {
+ "zh_CN": "默认勾选键"
+ }
+ },
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "json"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "default-checked-keys",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "默认勾选节点的 key 的数组"
+ },
+ "defaultValue": [],
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "默认展开所有"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "default-expand-all",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否默认展开所有子节点"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "array",
+ "label": {
+ "text": {
+ "zh_CN": "默认展开键"
+ }
+ },
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "json"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "default-expanded-keys",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "默认展开节点的 key 的数组"
+ },
+ "defaultValue": [],
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "默认展开高亮键"
+ }
+ },
+ "widget": {
+ "props": {
+ "placeholder": "请输入高亮节点键"
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "default-expanded-keys-highlight",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "设置默认展开节点中的某个节点高亮,配合 default-expanded-keys 属性使用"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件核心功能相关的配置,包括 data、node-key、props 等核心属性"
+ }
+ },
+ {
+ "name": "1",
+ "label": {
+ "zh_CN": "样式属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "number",
+ "label": {
+ "text": {
+ "zh_CN": "缩进距离"
+ }
+ },
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
+ },
+ "disabled": false,
+ "property": "indent",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "子级相对于父级节点的水平缩进距离,单位 px"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "number",
+ "label": {
+ "text": {
+ "zh_CN": "节点高度"
+ }
+ },
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
+ },
+ "disabled": false,
+ "property": "node-height",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "节点高度"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "文字省略"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "ellipsis",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否文字超长省略显示。优先级高于 wrap"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "换行显示"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "wrap",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否换行显示"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "component",
+ "label": {
+ "text": {
+ "zh_CN": "自定义图标"
+ }
+ },
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "javascript"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "customIcon",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "设置带图标树形菜单"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "component",
+ "label": {
+ "text": {
+ "zh_CN": "搜索图标"
+ }
+ },
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "javascript"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "search-icon",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "自定义搜索图标"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "component",
+ "label": {
+ "text": {
+ "zh_CN": "后缀图标"
+ }
+ },
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "javascript"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "suffix-icon",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "全局设置带图标树形菜单"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "显示数字"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "show-number",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "右侧下拉图标区域是否显示为 number 属性定义的数字内容,建议不超过 4 个字符"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "width-adapt"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "width-adapt",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "通过 widthAdapt 属性,是否让组件宽度自适应父容器。"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 indent、node-height、ellipsis 等与视觉呈现相关的属性"
+ }
+ },
+ {
+ "name": "2",
+ "label": {
+ "zh_CN": "行为属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "手风琴效果"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "accordion",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否设置为手风琴效果(只能展开一个同级别的节点)"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "严格勾选"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "check-strictly",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否遵循父级和子级严格不相关联的做法,配合 show-checkbox 属性使用"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "可清空"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "clearable",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "搜索框是否可清空"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "可收起"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "collapsible",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否允许展开后的菜单收起,未和 show-number 配套使用时,仍可以点击图标收起"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "可拖动"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "draggable",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否可拖动菜单节点"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "点击节点展开"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "expand-on-click-node",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否能点击节点即展开/收起。配置为 fasle 则只能点击下拉图标展开/收起"
+ },
+ "defaultValue": true,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "highlight-query"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "highlight-query",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "通过 highlightQuery 属性,是否在匹配的节点中,高亮搜索文字。"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "懒加载"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "lazy",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否懒加载子节点,配合 load 属性使用"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "侧边折叠按钮"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "menu-collapsible",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否显示侧边折叠与展开按钮"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "仅子级可选"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "only-check-children",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "父级是否不可选,只能展开不能跳转"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "显示复选框"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "SwitchConfigurator"
+ },
+ "disabled": false,
+ "property": "show-checkbox",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "节点是否可被选择"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "显示展开收起"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "show-expand",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否启用一键展开/收起功能。点击左下角图标可展开/收起菜单注意:配合 customIcon 属性使用,纯文本菜单不支持此功能"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "显示搜索框"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "SwitchConfigurator"
+ },
+ "disabled": false,
+ "property": "show-filter",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否显示搜索框,可搜索过滤节点"
+ },
+ "defaultValue": true,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "显示标题提示"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "SwitchConfigurator"
+ },
+ "disabled": false,
+ "property": "show-title",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否显示节点的 title 提示,鼠标悬浮节点之上触发"
+ },
+ "defaultValue": true,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件交互、事件、状态相关的配置,包括 accordion、draggable、show-checkbox 等与用户操作和状态相关的属性"
+ }
+ },
+ {
+ "name": "3",
+ "label": {
+ "zh_CN": "高级属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "function",
+ "label": {
+ "text": {
+ "zh_CN": "允许拖拽回调"
+ }
+ },
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "javascript"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "allow-drag",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "拖拽开始前的回调事件,定义节点是否允许拖拽的规则,返回 true 则允许拖拽,配合 draggable 属性使用"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "function",
+ "label": {
+ "text": {
+ "zh_CN": "允许放置回调"
+ }
+ },
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "javascript"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "allow-drop",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "拖拽结束前的回调事件,定义节点是否允许放置到模板节点的规则,返回 true 则允许放置,配合 draggable 属性使用"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "function",
+ "label": {
+ "text": {
+ "zh_CN": "节点过滤方法"
+ }
+ },
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "javascript"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "filter-node-method",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "自定义树节点过滤的方法,返回 true 表示这个节点可以显示,返回 false 则表示这个节点会被隐藏"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "function",
+ "label": {
+ "text": {
+ "zh_CN": "获取数据方法"
+ }
+ },
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "javascript"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "get-menu-data-sync",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "自定义获取服务端数据源的方法,返回一个 Promise 对象"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "function",
+ "label": {
+ "text": {
+ "zh_CN": "加载子树方法"
+ }
+ },
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "javascript"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "load",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "加载子树数据的方法,仅当 lazy 属性为 true 时生效"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置"
+ }
+ },
+ {
+ "name": "4",
+ "label": {
+ "zh_CN": "其他属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "空文本"
+ }
+ },
+ "widget": {
+ "props": {
+ "placeholder": "请输入空文本"
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "empty-text",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "内容为空时展示的文本"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "占位符"
+ }
+ },
+ "widget": {
+ "props": {
+ "placeholder": "请输入占位符"
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "placeholder",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "当数据为空时的占位符"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "无法归属到 “基础/样式/行为/高级属性” 的特殊配置项,这类属性通常不具备前四类分组的明确功能共性"
+ }
+ }
+ ],
+ "events": {
+ "onNodeClick": {
+ "type": "event",
+ "label": {
+ "zh_CN": "节点点击"
+ },
+ "description": {
+ "zh_CN": "监听节点被点击时的事件"
+ },
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "nodeData",
+ "type": "ITreeNodeData",
+ "description": {
+ "zh_CN": "节点数据"
+ },
+ "defaultValue": ""
+ },
+ {
+ "name": "node",
+ "type": "ITreeNodeVm",
+ "description": {
+ "zh_CN": "节点对象"
+ },
+ "defaultValue": ""
+ }
+ ],
+ "returns": {
+ "type": "void",
+ "description": {
+ "zh_CN": "无返回值"
+ },
+ "defaultValue": ""
+ }
+ }
+ },
+ "onNodeExpand": {
+ "type": "event",
+ "label": {
+ "zh_CN": "节点展开"
+ },
+ "description": {
+ "zh_CN": "监听节点被点击展开时的事件;"
+ },
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "nodeData",
+ "type": "ITreeNodeData",
+ "description": {
+ "zh_CN": "节点数据"
+ },
+ "defaultValue": ""
+ },
+ {
+ "name": "node",
+ "type": "ITreeNodeVm",
+ "description": {
+ "zh_CN": "节点对象"
+ },
+ "defaultValue": ""
+ }
+ ],
+ "returns": {
+ "type": "void",
+ "description": {
+ "zh_CN": "无返回值"
+ },
+ "defaultValue": ""
+ }
+ }
+ },
+ "onCheckChange": {
+ "type": "event",
+ "label": {
+ "zh_CN": "勾选状态变化"
+ },
+ "description": {
+ "zh_CN": "监听可勾选节点的勾选状态发生变化时的事件"
+ },
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "node",
+ "type": "ITreeNodeVm",
+ "description": {
+ "zh_CN": "节点对象"
+ },
+ "defaultValue": ""
+ },
+ {
+ "name": "checked",
+ "type": "boolean",
+ "description": {
+ "zh_CN": "是否勾选"
+ },
+ "defaultValue": ""
+ },
+ {
+ "name": "indeterminate",
+ "type": "boolean",
+ "description": {
+ "zh_CN": "是否半选"
+ },
+ "defaultValue": ""
+ }
+ ],
+ "returns": {
+ "type": "void",
+ "description": {
+ "zh_CN": "无返回值"
+ },
+ "defaultValue": ""
+ }
+ }
+ },
+ "onNodeDragEnd": {
+ "type": "event",
+ "label": {
+ "zh_CN": "节点拖拽结束"
+ },
+ "description": {
+ "zh_CN": "监听节点拖拽结束(可能未成功)的事件"
+ },
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "draggingNode",
+ "type": "ITreeNodeVm",
+ "description": {
+ "zh_CN": "拖拽节点"
+ },
+ "defaultValue": ""
+ },
+ {
+ "name": "targetNode",
+ "type": "ITreeNodeVm",
+ "description": {
+ "zh_CN": "目标节点"
+ },
+ "defaultValue": ""
+ },
+ {
+ "name": "dropType",
+ "type": "IDropType",
+ "description": {
+ "zh_CN": "放置类型"
+ },
+ "defaultValue": ""
+ },
+ {
+ "name": "event",
+ "type": "DragEvent",
+ "description": {
+ "zh_CN": "拖拽事件"
+ },
+ "defaultValue": ""
+ }
+ ],
+ "returns": {
+ "type": "void",
+ "description": {
+ "zh_CN": "无返回值"
+ },
+ "defaultValue": ""
+ }
+ }
+ },
+ "onNodeCollapse": {
+ "type": "event",
+ "label": {
+ "zh_CN": "节点收起"
+ },
+ "description": {
+ "zh_CN": "监听节点被点击收起时的事件;"
+ },
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "nodeData",
+ "type": "ITreeNodeData",
+ "description": {
+ "zh_CN": "节点数据"
+ },
+ "defaultValue": ""
+ },
+ {
+ "name": "node",
+ "type": "ITreeNodeVm",
+ "description": {
+ "zh_CN": "节点对象"
+ },
+ "defaultValue": ""
+ }
+ ],
+ "returns": {
+ "type": "void",
+ "description": {
+ "zh_CN": "无返回值"
+ },
+ "defaultValue": ""
+ }
+ }
+ },
+ "onCurrentChange": {
+ "type": "event",
+ "label": {
+ "zh_CN": "当前节点变化"
+ },
+ "description": {
+ "zh_CN": "监听当前选中节点发生变化时的事件"
+ },
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "nodeData",
+ "type": "ITreeNodeData",
+ "description": {
+ "zh_CN": "节点数据"
+ },
+ "defaultValue": ""
+ },
+ {
+ "name": "node",
+ "type": "ITreeNodeVm",
+ "description": {
+ "zh_CN": "节点对象"
+ },
+ "defaultValue": ""
+ }
+ ],
+ "returns": {
+ "type": "void",
+ "description": {
+ "zh_CN": "无返回值"
+ },
+ "defaultValue": ""
+ }
+ }
+ },
+ "onNodeDragStart": {
+ "type": "event",
+ "label": {
+ "zh_CN": "节点拖拽开始"
+ },
+ "description": {
+ "zh_CN": "监听节点开始拖拽的事件"
+ },
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "node",
+ "type": "ITreeNodeVm",
+ "description": {
+ "zh_CN": "节点对象"
+ },
+ "defaultValue": ""
+ },
+ {
+ "name": "event",
+ "type": "DragEvent",
+ "description": {
+ "zh_CN": "拖拽事件"
+ },
+ "defaultValue": ""
+ }
+ ],
+ "returns": {
+ "type": "void",
+ "description": {
+ "zh_CN": "无返回值"
+ },
+ "defaultValue": ""
+ }
+ }
+ }
+ },
+ "slots": {
+ "default": {
+ "label": {
+ "zh_CN": "默认内容"
+ },
+ "description": {
+ "zh_CN": "自定义树节点的内容,参数为 { node, data }"
+ }
+ }
+ }
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": []
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "折线图"
+ },
+ "component": "TinyHuichartsLine",
+ "icon": "line",
+ "description": "折线图",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "destructuring": true,
+ "exportName": "TinyHuichartsLine",
+ "name": "TinyVueHuicharts组件库",
+ "package": "@opentiny/vue-huicharts",
+ "version": "3.22.0",
+ "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs"
+ },
+ "group": "chart",
+ "category": "图表组件",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "基础信息"
+ },
+ "description": {
+ "zh_CN": "基础信息"
+ },
+ "content": [
+ {
+ "property": "options",
+ "label": {
+ "text": {
+ "zh_CN": "图表配置"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ },
+ "description": {
+ "zh_CN": "折线图配置"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ }
+ ],
+ "events": {}
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": []
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "柱状图"
+ },
+ "component": "TinyHuichartsHistogram",
+ "icon": "histogram",
+ "description": "柱状图",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "destructuring": true,
+ "exportName": "TinyHuichartsHistogram",
+ "name": "TinyVueHuicharts组件库",
+ "package": "@opentiny/vue-huicharts",
+ "version": "3.22.0",
+ "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs"
+ },
+ "group": "chart",
+ "category": "图表组件",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "基础信息"
+ },
+ "description": {
+ "zh_CN": "基础信息"
+ },
+ "content": [
+ {
+ "property": "options",
+ "label": {
+ "text": {
+ "zh_CN": "图表配置"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ },
+ "description": {
+ "zh_CN": "柱状图配置"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ }
+ ],
+ "events": {}
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": []
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "条形图"
+ },
+ "component": "TinyHuichartsBar",
+ "icon": "bar",
+ "description": "条形图",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "destructuring": true,
+ "exportName": "TinyHuichartsBar",
+ "name": "TinyVueHuicharts组件库",
+ "package": "@opentiny/vue-huicharts",
+ "version": "3.22.0",
+ "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs"
+ },
+ "group": "chart",
+ "category": "图表组件",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "基础信息"
+ },
+ "description": {
+ "zh_CN": "基础信息"
+ },
+ "content": [
+ {
+ "property": "options",
+ "label": {
+ "text": {
+ "zh_CN": "图表配置"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ },
+ "description": {
+ "zh_CN": "条形图配置"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ }
+ ],
+ "events": {
+ "onReady": {
+ "type": "event",
+ "label": {
+ "zh_CN": "图表渲染完成后触发"
+ },
+ "description": {
+ "zh_CN": "图表渲染完成后触发,每次渲染都会触发一次"
+ },
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [],
+ "returns": {}
+ }
+ },
+ "onReadyOnce": {
+ "type": "event",
+ "label": {
+ "zh_CN": "图表渲染完成后触发"
+ },
+ "description": {
+ "zh_CN": "图表渲染完成后触发,只会在首次渲染完成后触发"
+ },
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [],
+ "returns": {}
+ }
+ }
+ }
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": []
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "圆盘图"
+ },
+ "component": "TinyHuichartsPie",
+ "icon": "pie",
+ "description": "圆盘图",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "destructuring": true,
+ "exportName": "TinyHuichartsPie",
+ "name": "TinyVueHuicharts组件库",
+ "package": "@opentiny/vue-huicharts",
+ "version": "3.22.0",
+ "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs"
+ },
+ "group": "chart",
+ "category": "图表组件",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "基础信息"
+ },
+ "description": {
+ "zh_CN": "基础信息"
+ },
+ "content": [
+ {
+ "property": "options",
+ "label": {
+ "text": {
+ "zh_CN": "图表配置"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ },
+ "description": {
+ "zh_CN": "圆盘图配置"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ }
+ ],
+ "events": {}
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": []
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "环形图"
+ },
+ "component": "TinyHuichartsRing",
+ "icon": "ring",
+ "description": "环形图",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "destructuring": true,
+ "exportName": "TinyHuichartsRing",
+ "name": "TinyVueHuicharts组件库",
+ "package": "@opentiny/vue-huicharts",
+ "version": "3.22.0",
+ "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs"
+ },
+ "group": "chart",
+ "category": "图表组件",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "基础信息"
+ },
+ "description": {
+ "zh_CN": "基础信息"
+ },
+ "content": [
+ {
+ "property": "options",
+ "label": {
+ "text": {
+ "zh_CN": "图表配置"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ },
+ "description": {
+ "zh_CN": "环形图配置"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ }
+ ],
+ "events": {
+ "onReady": {
+ "type": "event",
+ "label": {
+ "zh_CN": "图表渲染完成后触发"
+ },
+ "description": {
+ "zh_CN": "图表渲染完成后触发,每次渲染都会触发一次"
+ },
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [],
+ "returns": {}
+ }
+ },
+ "onReadyOnce": {
+ "type": "event",
+ "label": {
+ "zh_CN": "图表渲染完成后触发"
+ },
+ "description": {
+ "zh_CN": "图表渲染完成后触发,只会在首次渲染完成后触发"
+ },
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [],
+ "returns": {}
+ }
+ }
+ },
+ "slots": {
+ "default": {
+ "label": {
+ "zh_CN": "默认内容"
+ },
+ "description": {
+ "zh_CN": "组件默认插槽"
+ }
+ }
+ }
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": []
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "雷达图"
+ },
+ "component": "TinyHuichartsRadar",
+ "icon": "radar",
+ "description": "雷达图",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "destructuring": true,
+ "exportName": "TinyHuichartsRadar",
+ "name": "TinyVueHuicharts组件库",
+ "package": "@opentiny/vue-huicharts",
+ "version": "3.22.0",
+ "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs"
+ },
+ "group": "chart",
+ "category": "图表组件",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "基础信息"
+ },
+ "description": {
+ "zh_CN": "基础信息"
+ },
+ "content": [
+ {
+ "property": "options",
+ "label": {
+ "text": {
+ "zh_CN": "图表配置"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ },
+ "description": {
+ "zh_CN": "雷达图配置"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ }
+ ],
+ "events": {
+ "onReady": {
+ "type": "event",
+ "label": {
+ "zh_CN": "图表渲染完成后触发"
+ },
+ "description": {
+ "zh_CN": "图表渲染完成后触发,每次渲染都会触发一次"
+ },
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [],
+ "returns": {}
+ }
+ },
+ "onReadyOnce": {
+ "type": "event",
+ "label": {
+ "zh_CN": "图表渲染完成后触发"
+ },
+ "description": {
+ "zh_CN": "图表渲染完成后触发,只会在首次渲染完成后触发"
+ },
+ "defaultValue": "",
+ "functionInfo": {
+ "params": [],
+ "returns": {}
+ }
+ }
+ },
+ "slots": {
+ "default": {
+ "label": {
+ "zh_CN": "默认内容"
+ },
+ "description": {
+ "zh_CN": "组件默认插槽"
+ }
+ }
+ }
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": []
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "漏斗图"
+ },
+ "component": "TinyHuichartsFunnel",
+ "icon": "funnel",
+ "description": "漏斗图",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "destructuring": true,
+ "exportName": "TinyHuichartsFunnel",
+ "name": "TinyVueHuicharts组件库",
+ "package": "@opentiny/vue-huicharts",
+ "version": "3.22.0",
+ "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs"
+ },
+ "group": "chart",
+ "category": "图表组件",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "基础信息"
+ },
+ "description": {
+ "zh_CN": "基础信息"
+ },
+ "content": [
+ {
+ "property": "options",
+ "label": {
+ "text": {
+ "zh_CN": "图表配置"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ },
+ "description": {
+ "zh_CN": "漏斗图配置"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ }
+ ],
+ "events": {}
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": []
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "散点图"
+ },
+ "component": "TinyHuichartsScatter",
+ "icon": "scatter",
+ "description": "散点图",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "destructuring": true,
+ "exportName": "TinyHuichartsScatter",
+ "name": "TinyVueHuicharts组件库",
+ "package": "@opentiny/vue-huicharts",
+ "version": "3.22.0",
+ "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs"
+ },
+ "group": "chart",
+ "category": "图表组件",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "基础信息"
+ },
+ "description": {
+ "zh_CN": "基础信息"
+ },
+ "content": [
+ {
+ "property": "options",
+ "label": {
+ "text": {
+ "zh_CN": "图表配置"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ },
+ "description": {
+ "zh_CN": "散点图配置"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ }
+ ],
+ "events": {}
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": []
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "瀑布图"
+ },
+ "component": "TinyHuichartsWaterfall",
+ "icon": "waterfall",
+ "description": "瀑布图",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "destructuring": true,
+ "exportName": "TinyHuichartsWaterfall",
+ "name": "TinyVueHuicharts组件库",
+ "package": "@opentiny/vue-huicharts",
+ "version": "3.22.0",
+ "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs"
+ },
+ "group": "chart",
+ "category": "图表组件",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "基础信息"
+ },
+ "description": {
+ "zh_CN": "基础信息"
+ },
+ "content": [
+ {
+ "property": "options",
+ "label": {
+ "text": {
+ "zh_CN": "图表配置"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ },
+ "description": {
+ "zh_CN": "瀑布图配置"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ }
+ ],
+ "events": {}
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": []
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "id": 1,
+ "version": "2.4.2",
+ "name": {
+ "zh_CN": "输入框"
+ },
+ "component": "ElInput",
+ "icon": "input",
+ "description": "通过鼠标或键盘输入字符",
+ "doc_url": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "dev_mode": "proCode",
+ "npm": {
+ "package": "element-plus",
+ "exportName": "ElInput",
+ "destructuring": true
+ },
+ "group": "表单组件",
+ "category": "element-plus",
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "isPopper": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": ["type", "size"]
+ },
+ "contextMenu": {
+ "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"],
+ "disable": []
+ },
+ "invalidity": [""],
+ "clickCapture": true,
+ "framework": "Vue"
+ },
+ "schema": {
+ "properties": [
+ {
+ "name": "0",
+ "label": {
+ "zh_CN": "基础属性"
+ },
+ "content": [
+ {
+ "property": "modelValue",
+ "label": {
+ "text": {
+ "zh_CN": "绑定值"
+ }
+ },
+ "description": {
+ "zh_CN": "绑定值"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "size",
+ "label": {
+ "text": {
+ "zh_CN": "尺寸"
+ }
+ },
+ "description": {
+ "zh_CN": "尺寸"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "defaultValue": "default",
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "large",
+ "value": "large"
+ },
+ {
+ "label": "default",
+ "value": "default"
+ },
+ {
+ "label": "small",
+ "value": "small"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "property": "type",
+ "label": {
+ "text": {
+ "zh_CN": "类型"
+ }
+ },
+ "description": {
+ "zh_CN": "类型"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "placeholder",
+ "label": {
+ "text": {
+ "zh_CN": "占位文本"
+ }
+ },
+ "description": {
+ "zh_CN": "输入框占位文本"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "I18nConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "maxlength",
+ "label": {
+ "text": {
+ "zh_CN": "最大长度"
+ }
+ },
+ "description": {
+ "zh_CN": "最大输入长度"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "number",
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "disabled",
+ "label": {
+ "text": {
+ "zh_CN": "是否禁用"
+ }
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": false,
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "device": []
+ }
+ ],
+ "description": {
+ "zh_CN": ""
+ }
+ }
+ ],
+ "events": {
+ "onUpdate:modelValue": {
+ "label": {
+ "zh_CN": "双向绑定值改变时触发"
+ },
+ "description": {
+ "zh_CN": "双向绑定值改变时触发"
+ }
+ },
+ "onBlur": {
+ "label": {
+ "zh_CN": "输入框失去焦点时触发"
+ },
+ "description": {
+ "zh_CN": "输入框失去焦点时触发"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "event",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "原生 event"
+ }
+ }
+ ],
+ "returns": {}
+ },
+ "defaultValue": ""
+ }
+ },
+ "slots": {
+ "prefix": {
+ "label": {
+ "zh_CN": "头部内容"
+ },
+ "description": {
+ "zh_CN": "输入框头部内容,只对非 type='textarea' 有效"
+ }
+ },
+ "suffix": {
+ "label": {
+ "zh_CN": "尾部内容"
+ },
+ "description": {
+ "zh_CN": "输入框尾部内容,只对非 type='textarea' 有效"
+ }
+ },
+ "prepend": {
+ "label": {
+ "zh_CN": "前置内容"
+ },
+ "description": {
+ "zh_CN": "输入框前置内容,只对非 type='textarea' 有效"
+ }
+ },
+ "append": {
+ "label": {
+ "zh_CN": "后置内容"
+ },
+ "description": {
+ "zh_CN": "输入框后置内容,只对非 type='textarea' 有效"
+ }
+ }
+ }
+ }
+ },
+ {
+ "id": 1,
+ "version": "2.4.2",
+ "name": {
+ "zh_CN": "日期选择器"
+ },
+ "component": "ElDatePicker",
+ "icon": "datepick",
+ "description": "日期选择器",
+ "doc_url": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "dev_mode": "proCode",
+ "npm": {
+ "package": "element-plus",
+ "exportName": "ElDatePicker",
+ "destructuring": true
+ },
+ "group": "表单组件",
+ "category": "element-plus",
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "isPopper": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": ["type", "size"]
+ },
+ "contextMenu": {
+ "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"],
+ "disable": []
+ },
+ "invalidity": [""],
+ "clickCapture": true,
+ "framework": "Vue"
+ },
+ "schema": {
+ "properties": [
+ {
+ "name": "0",
+ "label": {
+ "zh_CN": "基础属性"
+ },
+ "content": [
+ {
+ "property": "modelValue",
+ "label": {
+ "text": {
+ "zh_CN": "绑定值"
+ }
+ },
+ "description": {
+ "zh_CN": "绑定值"
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "readonly",
+ "label": {
+ "text": {
+ "zh_CN": "只读"
+ }
+ },
+ "description": {
+ "zh_CN": "是否只读"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "boolean",
+ "defaultValue": false,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "disabled",
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "boolean",
+ "defaultValue": false,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "size",
+ "label": {
+ "text": {
+ "zh_CN": "尺寸"
+ }
+ },
+ "description": {
+ "zh_CN": "输入框尺寸"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "defaultValue": "",
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "allowClear": true,
+ "options": [
+ {
+ "label": "large",
+ "value": "large"
+ },
+ {
+ "label": "default",
+ "value": "default"
+ },
+ {
+ "label": "small",
+ "value": "small"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "property": "editable",
+ "label": {
+ "text": {
+ "zh_CN": "是否可编辑"
+ }
+ },
+ "description": {
+ "zh_CN": "文本框是否可编辑"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "boolean",
+ "defaultValue": true,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "clearable",
+ "label": {
+ "text": {
+ "zh_CN": "是否可清除"
+ }
+ },
+ "description": {
+ "zh_CN": "是否显示清楚按钮"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "boolean",
+ "defaultValue": true,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "placeholder",
+ "label": {
+ "text": {
+ "zh_CN": "占位文本"
+ }
+ },
+ "description": {
+ "zh_CN": "非范围选择时的占位内容"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": "",
+ "type": "string",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "start-placeholder",
+ "label": {
+ "text": {
+ "zh_CN": "起始占位文本"
+ }
+ },
+ "description": {
+ "zh_CN": "范围选择时开始日期的占位内容"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": "",
+ "type": "string",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "end-placeholder",
+ "label": {
+ "text": {
+ "zh_CN": "结束占位文本"
+ }
+ },
+ "description": {
+ "zh_CN": "范围选择时结束日期的占位内容"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": "",
+ "type": "string",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "type",
+ "label": {
+ "text": {
+ "zh_CN": "类型"
+ }
+ },
+ "description": {
+ "zh_CN": "显示类型"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": "date",
+ "type": "string",
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "year",
+ "value": "year"
+ },
+ {
+ "label": "years",
+ "value": "years"
+ },
+ {
+ "label": "month",
+ "value": "month"
+ },
+ {
+ "label": "months",
+ "value": "months"
+ },
+ {
+ "label": "date",
+ "value": "date"
+ },
+ {
+ "label": "dates",
+ "value": "dates"
+ },
+ {
+ "label": "datetime",
+ "value": "datetime"
+ },
+ {
+ "label": "week",
+ "value": "week"
+ },
+ {
+ "label": "datetimerange",
+ "value": "datetimerange"
+ },
+ {
+ "label": "daterange",
+ "value": "daterange"
+ },
+ {
+ "label": "monthrange",
+ "value": "monthrange"
+ },
+ {
+ "label": "yearrange",
+ "value": "yearrange"
+ }
+ ]
+ }
+ },
+ "device": []
+ },
+ {
+ "property": "popper-class",
+ "label": {
+ "text": {
+ "zh_CN": "下拉框类名"
+ }
+ },
+ "description": {
+ "zh_CN": "DatePicker 下拉框的类名"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": "",
+ "type": "string",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "device": []
+ }
+ ],
+ "description": {
+ "zh_CN": ""
+ }
+ }
+ ],
+ "events": {
+ "onUpdate:modelValue": {
+ "label": {
+ "zh_CN": "双向绑定值改变时触发"
+ },
+ "description": {
+ "zh_CN": "双向绑定值改变时触发"
+ }
+ },
+ "onChange": {
+ "label": {
+ "zh_CN": "用户确认选定的值时触发"
+ },
+ "description": {
+ "zh_CN": "用户确认选定的值时触发"
+ },
+ "type": "event",
+ "defaultValue": ""
+ },
+ "onBlur": {
+ "label": {
+ "zh_CN": "在组件 Input 失去焦点时触发"
+ },
+ "description": {
+ "zh_CN": "在组件 Input 失去焦点时触发"
+ },
+ "type": "event",
+ "defaultValue": ""
+ },
+ "onFocus": {
+ "label": {
+ "zh_CN": "在组件 Input 获得焦点时触发"
+ },
+ "description": {
+ "zh_CN": "在组件 Input 获得焦点时触发"
+ },
+ "type": "event",
+ "defaultValue": ""
+ },
+ "onCalendarChange": {
+ "label": {
+ "zh_CN": "在日历所选日期更改时触发"
+ },
+ "description": {
+ "zh_CN": "在日历所选日期更改时触发"
+ },
+ "type": "event",
+ "defaultValue": ""
+ },
+ "onPanelChange": {
+ "label": {
+ "zh_CN": "当日期面板改变时触发。"
+ },
+ "description": {
+ "zh_CN": "当日期面板改变时触发。"
+ },
+ "type": "event",
+ "defaultValue": ""
+ },
+ "onVisibleChange": {
+ "label": {
+ "zh_CN": "当 DatePicker 的下拉列表出现/消失时触发"
+ },
+ "description": {
+ "zh_CN": "当 DatePicker 的下拉列表出现/消失时触发"
+ },
+ "type": "event",
+ "defaultValue": ""
+ }
+ },
+ "slots": {
+ "default": {
+ "label": {
+ "zh_CN": "自定义单元格内容"
+ },
+ "description": {
+ "zh_CN": "自定义单元格内容"
+ }
+ },
+ "range-separator": {
+ "label": {
+ "zh_CN": "自定义范围分割符内容"
+ },
+ "description": {
+ "zh_CN": "自定义范围分割符内容"
+ }
+ }
+ }
+ }
+ },
+ {
+ "id": 1,
+ "version": "2.4.2",
+ "name": {
+ "zh_CN": "按钮"
+ },
+ "component": "ElButton",
+ "icon": "button",
+ "description": "常用的操作按钮",
+ "doc_url": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "dev_mode": "proCode",
+ "npm": {
+ "package": "element-plus",
+ "exportName": "ElButton",
+ "destructuring": true
+ },
+ "group": "基础组件",
+ "category": "element-plus",
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": true,
+ "isModal": false,
+ "isPopper": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": ["type", "size"]
+ },
+ "contextMenu": {
+ "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"],
+ "disable": []
+ },
+ "invalidity": [""],
+ "clickCapture": true,
+ "framework": "Vue"
+ },
+ "schema": {
+ "properties": [
+ {
+ "name": "0",
+ "label": {
+ "zh_CN": "基础属性"
+ },
+ "content": [
+ {
+ "property": "size",
+ "label": {
+ "text": {
+ "zh_CN": "尺寸"
+ }
+ },
+ "description": {
+ "zh_CN": "尺寸"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "defaultValue": "default",
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "large",
+ "value": "large"
+ },
+ {
+ "label": "default",
+ "value": "default"
+ },
+ {
+ "label": "small",
+ "value": "small"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "property": "type",
+ "label": {
+ "text": {
+ "zh_CN": "类型"
+ }
+ },
+ "description": {
+ "zh_CN": "类型"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "plain",
+ "label": {
+ "text": {
+ "zh_CN": "朴素按钮"
+ }
+ },
+ "description": {
+ "zh_CN": "是否为朴素按钮"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "text",
+ "label": {
+ "text": {
+ "zh_CN": "文字按钮"
+ }
+ },
+ "description": {
+ "zh_CN": "是否为文字按钮"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "bg",
+ "label": {
+ "text": {
+ "zh_CN": "背景颜色"
+ }
+ },
+ "description": {
+ "zh_CN": "是否显示文字按钮背景颜色"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "link",
+ "label": {
+ "text": {
+ "zh_CN": "链接按钮"
+ }
+ },
+ "description": {
+ "zh_CN": "是否为链接按钮"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "round",
+ "label": {
+ "text": {
+ "zh_CN": "圆角按钮"
+ }
+ },
+ "description": {
+ "zh_CN": "是否为圆角按钮"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "circle",
+ "label": {
+ "text": {
+ "zh_CN": "圆形按钮"
+ }
+ },
+ "description": {
+ "zh_CN": "是否为圆形按钮"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "loading",
+ "label": {
+ "text": {
+ "zh_CN": "加载中状态"
+ }
+ },
+ "description": {
+ "zh_CN": "是否为加载中状态"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "disabled",
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": false,
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "device": []
+ }
+ ],
+ "description": {
+ "zh_CN": ""
+ }
+ }
+ ],
+ "events": {},
+ "slots": {
+ "default": {
+ "label": {
+ "zh_CN": "default"
+ },
+ "description": {
+ "zh_CN": "自定义默认内容"
+ }
+ },
+ "loading": {
+ "label": {
+ "zh_CN": "loading"
+ },
+ "description": {
+ "zh_CN": "自定义加载中组件"
+ }
+ }
+ }
+ }
+ },
+ {
+ "id": 1,
+ "version": "2.4.2",
+ "name": {
+ "zh_CN": "表单"
+ },
+ "component": "ElForm",
+ "icon": "form",
+ "description": "表单包含 输入框, 单选框, 下拉选择, 多选框 等用户输入的组件。 使用表单,您可以收集、验证和提交数据。",
+ "doc_url": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "dev_mode": "proCode",
+ "npm": {
+ "package": "element-plus",
+ "exportName": "ElForm",
+ "destructuring": true
+ },
+ "group": "表单组件",
+ "category": "element-plus",
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": true,
+ "isModal": false,
+ "isPopper": false,
+ "nestingRule": {
+ "childWhitelist": ["ElFormItem"],
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": ["inline", "label-width"]
+ },
+ "contextMenu": {
+ "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"],
+ "disable": []
+ },
+ "invalidity": [""],
+ "clickCapture": true,
+ "framework": "Vue"
+ },
+ "schema": {
+ "properties": [
+ {
+ "name": "0",
+ "label": {
+ "zh_CN": "基础属性"
+ },
+ "content": [
+ {
+ "property": "model",
+ "label": {
+ "text": {
+ "zh_CN": "数据对象"
+ }
+ },
+ "description": {
+ "zh_CN": "表单数据对象"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "top",
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ }
+ },
+ {
+ "property": "rules",
+ "label": {
+ "text": {
+ "zh_CN": "验证规则"
+ }
+ },
+ "description": {
+ "zh_CN": "表单验证规则"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "top",
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ }
+ },
+ {
+ "property": "inline",
+ "label": {
+ "text": {
+ "zh_CN": "行内模式"
+ }
+ },
+ "description": {
+ "zh_CN": "行内表单模式"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "label-position",
+ "label": {
+ "text": {
+ "zh_CN": "标签位置"
+ }
+ },
+ "description": {
+ "zh_CN": "表单域标签的位置, 当设置为 left 或 right 时,则也需要设置标签宽度属性"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "defaultValue": "right",
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "left",
+ "value": "left"
+ },
+ {
+ "label": "right",
+ "value": "right"
+ },
+ {
+ "label": "top",
+ "value": "top"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "property": "label-width",
+ "label": {
+ "text": {
+ "zh_CN": "标签宽度"
+ }
+ },
+ "description": {
+ "zh_CN": "标签的长度,例如 '50px'。 作为 Form 直接子元素的 form-item 会继承该值。 可以使用 auto。"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "label-suffix",
+ "label": {
+ "text": {
+ "zh_CN": "标签后缀"
+ }
+ },
+ "description": {
+ "zh_CN": "表单域标签的后缀"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "hide-required-asterisk",
+ "label": {
+ "text": {
+ "zh_CN": "隐藏必填星号"
+ }
+ },
+ "description": {
+ "zh_CN": "是否隐藏必填字段标签旁边的红色星号"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "require-asterisk-position",
+ "label": {
+ "text": {
+ "zh_CN": "星号位置"
+ }
+ },
+ "description": {
+ "zh_CN": "星号的位置"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "defaultValue": "left",
+ "widget": {
+ "component": "ButtonGroupConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "left",
+ "value": "left"
+ },
+ {
+ "label": "right",
+ "value": "right"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "property": "show-message",
+ "label": {
+ "text": {
+ "zh_CN": "显示校验信息"
+ }
+ },
+ "description": {
+ "zh_CN": "是否显示校验错误信息"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": true,
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "inline-message",
+ "label": {
+ "text": {
+ "zh_CN": "行内显示校验信息"
+ }
+ },
+ "description": {
+ "zh_CN": "是否以行内形式展示校验信息"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": false,
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "status-icon",
+ "label": {
+ "text": {
+ "zh_CN": "显示校验结果图标"
+ }
+ },
+ "description": {
+ "zh_CN": "是否在输入框中显示校验结果反馈图标"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": false,
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "validate-on-rule-change",
+ "label": {
+ "text": {
+ "zh_CN": "触发验证"
+ }
+ },
+ "description": {
+ "zh_CN": "是否在 rules 属性改变后立即触发一次验证"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": true,
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "size",
+ "label": {
+ "text": {
+ "zh_CN": "尺寸"
+ }
+ },
+ "description": {
+ "zh_CN": "用于控制该表单内组件的尺寸"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "defaultValue": "default",
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "large",
+ "value": "large"
+ },
+ {
+ "label": "default",
+ "value": "default"
+ },
+ {
+ "label": "small",
+ "value": "small"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "property": "disabled",
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "description": {
+ "zh_CN": "是否禁用该表单内的所有组件。 如果设置为 true, 它将覆盖内部组件的 disabled 属性"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": false,
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "scroll-to-error",
+ "label": {
+ "text": {
+ "zh_CN": "滚动到错误项"
+ }
+ },
+ "description": {
+ "zh_CN": "当校验失败时,滚动到第一个错误表单项"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": false,
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "device": []
+ }
+ ],
+ "description": {
+ "zh_CN": ""
+ }
+ }
+ ],
+ "events": {
+ "onValidate": {
+ "label": {
+ "zh_CN": "任一表单项被校验后触发"
+ },
+ "description": {
+ "zh_CN": "任一表单项被校验后触发"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [],
+ "returns": {}
+ },
+ "defaultValue": ""
+ }
+ },
+ "slots": {}
+ }
+ },
+ {
+ "id": 1,
+ "version": "2.4.2",
+ "name": {
+ "zh_CN": "表单子项"
+ },
+ "component": "ElFormItem",
+ "icon": "formItem",
+ "description": "表单包含 输入框, 单选框, 下拉选择, 多选框 等用户输入的组件。 使用表单,您可以收集、验证和提交数据。",
+ "doc_url": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "dev_mode": "proCode",
+ "npm": {
+ "package": "element-plus",
+ "exportName": "ElFormItem",
+ "destructuring": true
+ },
+ "group": "表单组件",
+ "category": "element-plus",
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": true,
+ "isModal": false,
+ "isPopper": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": ["inline", "label-width"]
+ },
+ "contextMenu": {
+ "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"],
+ "disable": []
+ },
+ "invalidity": [""],
+ "clickCapture": true,
+ "framework": "Vue"
+ },
+ "schema": {
+ "properties": [
+ {
+ "name": "0",
+ "label": {
+ "zh_CN": "基础属性"
+ },
+ "content": [
+ {
+ "property": "prop",
+ "label": {
+ "text": {
+ "zh_CN": "键名"
+ }
+ },
+ "description": {
+ "zh_CN": "model 的键名。 它可以是一个属性的值(如 a.b.0 或 [a', 'b', '0'])。 在定义了 validate、resetFields 的方法时,该属性是必填的"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "label",
+ "label": {
+ "text": {
+ "zh_CN": "标签文本"
+ }
+ },
+ "description": {
+ "zh_CN": "标签文本"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "label-width",
+ "label": {
+ "text": {
+ "zh_CN": "标签宽度"
+ }
+ },
+ "description": {
+ "zh_CN": "标签宽度,例如 '50px'。 可以使用 auto"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "required",
+ "label": {
+ "text": {
+ "zh_CN": "必填项"
+ }
+ },
+ "description": {
+ "zh_CN": "是否为必填项,如不设置,则会根据校验规则确认"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "rules",
+ "label": {
+ "text": {
+ "zh_CN": "验证规则"
+ }
+ },
+ "description": {
+ "zh_CN": "表单验证规则, 更多内容可以参考async-validator"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "top",
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ }
+ },
+ {
+ "property": "error",
+ "label": {
+ "text": {
+ "zh_CN": "错误信息"
+ }
+ },
+ "description": {
+ "zh_CN": "表单域验证错误时的提示信息。设置该值会导致表单验证状态变为 error,并显示该错误信息"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "show-message",
+ "label": {
+ "text": {
+ "zh_CN": "显示错误信息"
+ }
+ },
+ "description": {
+ "zh_CN": "是否显示校验错误信息"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "inline-message",
+ "label": {
+ "text": {
+ "zh_CN": "行内显示错误信息"
+ }
+ },
+ "description": {
+ "zh_CN": "是否在行内显示校验信息"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "size",
+ "label": {
+ "text": {
+ "zh_CN": "尺寸"
+ }
+ },
+ "description": {
+ "zh_CN": "用于控制该表单内组件的尺寸"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "defaultValue": "default",
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "large",
+ "value": "large"
+ },
+ {
+ "label": "default",
+ "value": "default"
+ },
+ {
+ "label": "small",
+ "value": "small"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "property": "for",
+ "label": {
+ "text": {
+ "zh_CN": "for"
+ }
+ },
+ "description": {
+ "zh_CN": "和原生标签相同能力"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "validate-status",
+ "label": {
+ "text": {
+ "zh_CN": "校验状态"
+ }
+ },
+ "description": {
+ "zh_CN": "formItem 校验的状态"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "error",
+ "value": "error"
+ },
+ {
+ "label": "validating",
+ "value": "validating"
+ },
+ {
+ "label": "success",
+ "value": "success"
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "description": {
+ "zh_CN": ""
+ }
+ }
+ ],
+ "events": {},
+ "slots": {
+ "label": {
+ "label": {
+ "zh_CN": "label"
+ },
+ "description": {
+ "zh_CN": "标签位置显示的内容"
+ }
+ },
+ "error": {
+ "label": {
+ "zh_CN": "error"
+ },
+ "description": {
+ "zh_CN": "验证错误信息的显示内容"
+ }
+ }
+ }
+ }
+ },
+ {
+ "id": 1,
+ "version": "2.4.2",
+ "name": {
+ "zh_CN": "表单"
+ },
+ "component": "ElTable",
+ "icon": "table",
+ "description": "用于展示多条结构类似的数据, 可对数据进行排序、筛选、对比或其他自定义操作",
+ "doc_url": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "dev_mode": "proCode",
+ "npm": {
+ "package": "element-plus",
+ "exportName": "ElTable",
+ "destructuring": true
+ },
+ "group": "数据展示",
+ "category": "element-plus",
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "isPopper": false,
+ "nestingRule": {
+ "childWhitelist": ["ElTableColumn"],
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": ["inline", "label-width"]
+ },
+ "contextMenu": {
+ "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"],
+ "disable": []
+ },
+ "invalidity": [""],
+ "clickCapture": true,
+ "framework": "Vue"
+ },
+ "schema": {
+ "properties": [
+ {
+ "name": "0",
+ "label": {
+ "zh_CN": "基础属性"
+ },
+ "content": [
+ {
+ "property": "data",
+ "label": {
+ "text": {
+ "zh_CN": "数据"
+ }
+ },
+ "description": {
+ "zh_CN": "显示的数据"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "top",
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ }
+ },
+ {
+ "property": "columns",
+ "label": {
+ "text": {
+ "zh_CN": "表格列配置"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "默认分组"
+ },
+ "content": [
+ {
+ "property": "type",
+ "type": "string",
+ "labelPosition": "top",
+ "label": {
+ "text": {
+ "zh_CN": "type"
+ }
+ },
+ "description": {
+ "text": {
+ "zh_CN": "对应列的类型。 如果设置了selection则显示多选框; 如果设置了 index 则显示该行的索引(从 1 开始计算); 如果设置了 expand 则显示为一个可展开的按钮"
+ }
+ },
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "selection",
+ "value": "selection"
+ },
+ {
+ "label": "index",
+ "value": "index"
+ },
+ {
+ "label": "expand",
+ "value": "expand"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "property": "index",
+ "type": "string",
+ "labelPosition": "top",
+ "label": {
+ "text": {
+ "zh_CN": "index"
+ }
+ },
+ "description": {
+ "text": {
+ "zh_CN": "如果设置了 type=index,可以通过传递 index 属性来自定义索引"
+ }
+ },
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "label",
+ "type": "string",
+ "labelPosition": "top",
+ "label": {
+ "text": {
+ "zh_CN": "label"
+ }
+ },
+ "description": {
+ "text": {
+ "zh_CN": "显示的标题"
+ }
+ },
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "column-key",
+ "type": "string",
+ "labelPosition": "top",
+ "label": {
+ "text": {
+ "zh_CN": "column-key"
+ }
+ },
+ "description": {
+ "text": {
+ "zh_CN": "column 的 key, column 的 key, 如果需要使用 filter-change 事件,则需要此属性标识是哪个 column 的筛选条件"
+ }
+ },
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "prop",
+ "type": "string",
+ "labelPosition": "top",
+ "label": {
+ "text": {
+ "zh_CN": "prop"
+ }
+ },
+ "description": {
+ "text": {
+ "zh_CN": "字段名称 对应列内容的字段名, 也可以使用 property属性"
+ }
+ },
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "width",
+ "type": "number",
+ "labelPosition": "top",
+ "label": {
+ "text": {
+ "zh_CN": "width"
+ }
+ },
+ "description": {
+ "text": {
+ "zh_CN": "对应列的宽度"
+ }
+ },
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "min-width",
+ "type": "number",
+ "labelPosition": "top",
+ "label": {
+ "text": {
+ "zh_CN": "min-width"
+ }
+ },
+ "description": {
+ "text": {
+ "zh_CN": "对应列的最小宽度, 对应列的最小宽度, 与 width 的区别是 width 是固定的,min-width 会把剩余宽度按比例分配给设置了 min-width 的列"
+ }
+ },
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "fixed",
+ "type": "string",
+ "labelPosition": "top",
+ "label": {
+ "text": {
+ "zh_CN": "fixed"
+ }
+ },
+ "description": {
+ "text": {
+ "zh_CN": "列是否固定在左侧或者右侧。 true 表示固定在左侧"
+ }
+ },
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "left",
+ "value": "left"
+ },
+ {
+ "label": "right",
+ "value": "right"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "property": "sortable",
+ "type": "boolean",
+ "labelPosition": "left",
+ "label": {
+ "text": {
+ "zh_CN": "sortable"
+ }
+ },
+ "description": {
+ "text": {
+ "zh_CN": "对应列是否可以排序"
+ }
+ },
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "sort-method",
+ "type": "function",
+ "labelPosition": "top",
+ "label": {
+ "text": {
+ "zh_CN": "sort-method"
+ }
+ },
+ "description": {
+ "text": {
+ "zh_CN": "指定数据按照哪个属性进行排序,仅当sortable设置为true的时候有效。 应该如同 Array.sort 那样返回一个 Number"
}
},
"widget": {
@@ -2012,36 +6892,192 @@
}
},
{
- "property": "label",
- "type": "string",
+ "property": "sort-by",
+ "type": "array",
"labelPosition": "top",
"label": {
"text": {
- "zh_CN": "label"
+ "zh_CN": "sort-by"
}
},
"description": {
"text": {
- "zh_CN": "显示的标题"
+ "zh_CN": "指定数据按照哪个属性进行排序,仅当 sortable 设置为 true 且没有设置 sort-method 的时候有效。 如果 sort-by 为数组,则先按照第 1 个属性排序,如果第 1 个相等,再按照第 2 个排序,以此类推"
}
},
"widget": {
- "component": "InputConfigurator",
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ }
+ },
+ {
+ "property": "sort-orders",
+ "type": "array",
+ "labelPosition": "top",
+ "label": {
+ "text": {
+ "zh_CN": "sort-orders"
+ }
+ },
+ "description": {
+ "text": {
+ "zh_CN": "数据在排序时所使用排序策略的轮转顺序,仅当 sortable 为 true 时有效。 需传入一个数组,随着用户点击表头,该列依次按照数组中元素的顺序进行排序"
+ }
+ },
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
+ }
+ },
+ {
+ "property": "resizable",
+ "type": "boolean",
+ "labelPosition": "left",
+ "defaultValue": true,
+ "label": {
+ "text": {
+ "zh_CN": "resizable"
+ }
+ },
+ "description": {
+ "text": {
+ "zh_CN": "对应列是否可以通过拖动改变宽度(需要在 el-table 上设置 border 属性为真)"
+ }
+ },
+ "widget": {
+ "component": "CheckBoxConfigurator",
"props": {}
}
},
{
- "property": "column-key",
+ "property": "formatter",
+ "type": "function",
+ "labelPosition": "top",
+ "defaultValue": true,
+ "label": {
+ "text": {
+ "zh_CN": "formatter"
+ }
+ },
+ "description": {
+ "text": {
+ "zh_CN": "用来格式化内容"
+ }
+ },
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {
+ "dataType": "JSFunction"
+ }
+ }
+ },
+ {
+ "property": "show-overflow-tooltip",
+ "type": "boolean",
+ "labelPosition": "left",
+ "defaultValue": true,
+ "label": {
+ "text": {
+ "zh_CN": "show-overflow-tooltip"
+ }
+ },
+ "description": {
+ "text": {
+ "zh_CN": "当内容过长被隐藏时显示 tooltip"
+ }
+ },
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "align",
"type": "string",
"labelPosition": "top",
+ "defaultValue": "left",
"label": {
"text": {
- "zh_CN": "column-key"
+ "zh_CN": "align"
}
},
"description": {
"text": {
- "zh_CN": "column 的 key, column 的 key, 如果需要使用 filter-change 事件,则需要此属性标识是哪个 column 的筛选条件"
+ "zh_CN": "对齐方式"
+ }
+ },
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "left",
+ "value": "left"
+ },
+ {
+ "label": "center",
+ "value": "center"
+ },
+ {
+ "label": "right",
+ "value": "right"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "property": "header-align",
+ "type": "string",
+ "labelPosition": "top",
+ "defaultValue": "left",
+ "label": {
+ "text": {
+ "zh_CN": "header-align"
+ }
+ },
+ "description": {
+ "text": {
+ "zh_CN": "表头对齐方式, 若不设置该项,则使用表格的对齐方式"
+ }
+ },
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "left",
+ "value": "left"
+ },
+ {
+ "label": "center",
+ "value": "center"
+ },
+ {
+ "label": "right",
+ "value": "right"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "property": "class-name",
+ "type": "string",
+ "labelPosition": "top",
+ "defaultValue": "left",
+ "label": {
+ "text": {
+ "zh_CN": "class-name"
+ }
+ },
+ "description": {
+ "text": {
+ "zh_CN": "列的 className"
}
},
"widget": {
@@ -2050,17 +7086,18 @@
}
},
{
- "property": "prop",
+ "property": "label-class-name",
"type": "string",
"labelPosition": "top",
+ "defaultValue": "left",
"label": {
"text": {
- "zh_CN": "prop"
+ "zh_CN": "label-class-name"
}
},
"description": {
"text": {
- "zh_CN": "字段名称 对应列内容的字段名, 也可以使用 property属性"
+ "zh_CN": "当前列标题的自定义类名"
}
},
"widget": {
@@ -2069,85 +7106,99 @@
}
},
{
- "property": "width",
- "type": "number",
+ "property": "selectable",
+ "type": "function",
"labelPosition": "top",
+ "defaultValue": true,
"label": {
"text": {
- "zh_CN": "width"
+ "zh_CN": "selectable"
}
},
"description": {
"text": {
- "zh_CN": "对应列的宽度"
+ "zh_CN": "仅对 type=selection 的列有效,类型为 Function,Function 的返回值用来决定这一行的 CheckBox 是否可以勾选"
}
},
"widget": {
- "component": "NumberConfigurator",
+ "component": "CodeConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "reserve-selection",
+ "type": "boolean",
+ "labelPosition": "left",
+ "defaultValue": true,
+ "label": {
+ "text": {
+ "zh_CN": "reserve-selection"
+ }
+ },
+ "description": {
+ "text": {
+ "zh_CN": "数据刷新后是否保留选项,仅对 type=selection 的列有效, 请注意, 需指定 row-key 来让这个功能生效。"
+ }
+ },
+ "widget": {
+ "component": "CheckBoxConfigurator",
"props": {}
}
},
{
- "property": "min-width",
- "type": "number",
+ "property": "filters",
+ "type": "array",
"labelPosition": "top",
+ "defaultValue": true,
"label": {
"text": {
- "zh_CN": "min-width"
+ "zh_CN": "filters"
}
},
"description": {
"text": {
- "zh_CN": "对应列的最小宽度, 对应列的最小宽度, 与 width 的区别是 width 是固定的,min-width 会把剩余宽度按比例分配给设置了 min-width 的列"
+ "zh_CN": "数据刷新后是否保留选项,仅对 type=selection 的列有效, 请注意, 需指定 row-key 来让这个功能生效。"
}
},
"widget": {
- "component": "NumberConfigurator",
- "props": {}
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
}
},
{
- "property": "fixed",
+ "property": "filter-placement",
"type": "string",
"labelPosition": "top",
"label": {
"text": {
- "zh_CN": "fixed"
+ "zh_CN": "filter-placement"
}
},
"description": {
"text": {
- "zh_CN": "列是否固定在左侧或者右侧。 true 表示固定在左侧"
+ "zh_CN": "过滤弹出框的定位"
}
},
"widget": {
- "component": "SelectConfigurator",
- "props": {
- "options": [
- {
- "label": "left",
- "value": "left"
- },
- {
- "label": "right",
- "value": "right"
- }
- ]
- }
+ "component": "InputConfigurator",
+ "props": {}
}
},
{
- "property": "sortable",
- "type": "boolean",
+ "property": "filter-multiple",
+ "type": "string",
"labelPosition": "left",
+ "defaultValue": true,
"label": {
"text": {
- "zh_CN": "sortable"
+ "zh_CN": "filter-multiple"
}
},
"description": {
"text": {
- "zh_CN": "对应列是否可以排序"
+ "zh_CN": "数据过滤的选项是否多选"
}
},
"widget": {
@@ -2156,17 +7207,18 @@
}
},
{
- "property": "sort-method",
+ "property": "filter-method",
"type": "function",
"labelPosition": "top",
+ "defaultValue": true,
"label": {
"text": {
- "zh_CN": "sort-method"
+ "zh_CN": "filter-method"
}
},
"description": {
"text": {
- "zh_CN": "指定数据按照哪个属性进行排序,仅当sortable设置为true的时候有效。 应该如同 Array.sort 那样返回一个 Number"
+ "zh_CN": "数据过滤使用的方法, 如果是多选的筛选项,对每一条数据会执行多次,任意一次返回 true 就会显示"
}
},
"widget": {
@@ -2175,17 +7227,18 @@
}
},
{
- "property": "sort-by",
+ "property": "filtered-value",
"type": "array",
"labelPosition": "top",
+ "defaultValue": true,
"label": {
"text": {
- "zh_CN": "sort-by"
+ "zh_CN": "filtered-value"
}
},
"description": {
"text": {
- "zh_CN": "指定数据按照哪个属性进行排序,仅当 sortable 设置为 true 且没有设置 sort-method 的时候有效。 如果 sort-by 为数组,则先按照第 1 个属性排序,如果第 1 个相等,再按照第 2 个排序,以此类推"
+ "zh_CN": "选中的数据过滤项,如果需要自定义表头过滤的渲染方式,可能会需要此属性"
}
},
"widget": {
@@ -2194,937 +7247,2779 @@
"language": "json"
}
}
+ }
+ ]
+ }
+ ],
+ "widget": {
+ "component": "TableColumnsConfigurator",
+ "props": {
+ "type": "object",
+ "textField": "label",
+ "language": "json",
+ "buttonText": "编辑列配置",
+ "title": "编辑列配置",
+ "expand": true
+ }
+ },
+ "description": {
+ "zh_CN": "表格列的配置信息"
+ },
+ "labelPosition": "top"
+ },
+ {
+ "property": "max-height",
+ "label": {
+ "text": {
+ "zh_CN": "最大高度"
+ }
+ },
+ "description": {
+ "zh_CN": "Table 的最大高度。"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "number",
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "height",
+ "label": {
+ "text": {
+ "zh_CN": "表格高度"
+ }
+ },
+ "description": {
+ "zh_CN": "Table 的高度, 默认为自动高度。 这个高度会设置为 Table 的 style.height 的值,Table 的高度会受控于外部样式。"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "stripe",
+ "label": {
+ "text": {
+ "zh_CN": "斑马纹"
+ }
+ },
+ "description": {
+ "zh_CN": "是否为斑马纹 table"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": false,
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "border",
+ "label": {
+ "text": {
+ "zh_CN": "纵向边框"
+ }
+ },
+ "description": {
+ "zh_CN": "是否带有纵向边框"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": false,
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "size",
+ "label": {
+ "text": {
+ "zh_CN": "表格尺寸"
+ }
+ },
+ "description": {
+ "zh_CN": "Table 的尺寸"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "type": "string",
+ "defaultValue": "default",
+ "widget": {
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "large",
+ "value": "large"
+ },
+ {
+ "label": "default",
+ "value": "default"
},
{
- "property": "sort-orders",
- "type": "array",
- "labelPosition": "top",
- "label": {
- "text": {
- "zh_CN": "sort-orders"
- }
- },
- "description": {
- "text": {
- "zh_CN": "数据在排序时所使用排序策略的轮转顺序,仅当 sortable 为 true 时有效。 需传入一个数组,随着用户点击表头,该列依次按照数组中元素的顺序进行排序"
- }
- },
- "widget": {
- "component": "CodeConfigurator",
- "props": {
- "language": "json"
- }
- }
+ "label": "small",
+ "value": "small"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "property": "fit",
+ "label": {
+ "text": {
+ "zh_CN": "列宽自撑开"
+ }
+ },
+ "description": {
+ "zh_CN": "列的宽度是否自撑开"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": true,
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "show-header",
+ "label": {
+ "text": {
+ "zh_CN": "显示表头"
+ }
+ },
+ "description": {
+ "zh_CN": "是否显示表头"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": true,
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "highlight-current-row",
+ "label": {
+ "text": {
+ "zh_CN": "高亮当前行"
+ }
+ },
+ "description": {
+ "zh_CN": "是否要高亮当前行"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": false,
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "current-row-key",
+ "label": {
+ "text": {
+ "zh_CN": "当前行的 key"
+ }
+ },
+ "description": {
+ "zh_CN": "当前行的 key,只写属性"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "top",
+ "type": "string",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "row-class-name",
+ "label": {
+ "text": {
+ "zh_CN": "行的类名"
+ }
+ },
+ "description": {
+ "zh_CN": "行的 className"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "row-key",
+ "label": {
+ "text": {
+ "zh_CN": "行数据的 Key"
+ }
+ },
+ "description": {
+ "zh_CN": "行数据的 Key,用来优化 Table 的渲染; 在使用reserve-selection功能与显示树形数据时,该属性是必填的。 类型为 String 时,支持多层访问:user.info.id,但不支持 user.info[0].id,此种情况请使用 Function"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "top",
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "empty-text",
+ "label": {
+ "text": {
+ "zh_CN": "空数据文本"
+ }
+ },
+ "description": {
+ "zh_CN": "空数据时显示的文本内容"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "device": []
+ },
+ {
+ "property": "table-layout",
+ "label": {
+ "text": {
+ "zh_CN": "表格布局方式"
+ }
+ },
+ "description": {
+ "zh_CN": "设置表格单元、行和列的布局方式"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "top",
+ "defaultValue": "fixed",
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "fixed",
+ "value": "fixed"
},
{
- "property": "resizable",
- "type": "boolean",
- "labelPosition": "left",
- "defaultValue": true,
- "label": {
- "text": {
- "zh_CN": "resizable"
- }
- },
- "description": {
- "text": {
- "zh_CN": "对应列是否可以通过拖动改变宽度(需要在 el-table 上设置 border 属性为真)"
- }
- },
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
+ "label": "auto",
+ "value": "auto"
+ }
+ ]
+ }
+ },
+ "device": []
+ },
+ {
+ "property": "scrollbar-always-on",
+ "label": {
+ "text": {
+ "zh_CN": "显示滚动条"
+ }
+ },
+ "description": {
+ "zh_CN": "总是显示滚动条"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": false,
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ },
+ {
+ "property": "flexible",
+ "label": {
+ "text": {
+ "zh_CN": "主轴最小尺寸"
+ }
+ },
+ "description": {
+ "zh_CN": "确保主轴的最小尺寸,以便不超过内容"
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "labelPosition": "left",
+ "defaultValue": false,
+ "type": "boolean",
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ }
+ }
+ ],
+ "description": {
+ "zh_CN": ""
+ }
+ }
+ ],
+ "events": {
+ "onSelect": {
+ "label": {
+ "zh_CN": "勾选数据行的 Checkbox 时触发"
+ },
+ "description": {
+ "zh_CN": "当用户手动勾选数据行的 Checkbox 时触发的事件"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "selection",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "当前选中项"
+ }
+ },
+ {
+ "name": "row",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "当前行"
+ }
+ }
+ ],
+ "returns": {}
+ }
+ },
+ "onSelectAll": {
+ "label": {
+ "zh_CN": "勾选全选时触发"
+ },
+ "description": {
+ "zh_CN": "当用户手动勾选全选 Checkbox 时触发的事件"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "selection",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "当前选中项"
+ }
+ }
+ ],
+ "returns": {}
+ }
+ },
+ "onSelectionChange": {
+ "label": {
+ "zh_CN": "选择项发生变化时会触发"
+ },
+ "description": {
+ "zh_CN": "当选择项发生变化时会触发该事件"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "selection",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "当前选中项"
+ }
+ }
+ ],
+ "returns": {}
+ }
+ },
+ "onCellMouseEnter": {
+ "label": {
+ "zh_CN": "单元格 hover 时会触发"
+ },
+ "description": {
+ "zh_CN": "当单元格 hover 进入时会触发该事件"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "row",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "当前行"
+ }
+ },
+ {
+ "name": "column",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "当前列"
+ }
+ },
+ {
+ "name": "cell",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "当前单元格"
+ }
+ },
+ {
+ "name": "event",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "原生事件 event"
+ }
+ }
+ ],
+ "returns": {}
+ }
+ },
+ "onCellMouseLeave": {
+ "label": {
+ "zh_CN": "单元格 hover 退出时会触发"
+ },
+ "description": {
+ "zh_CN": "当单元格 hover 退出时会触发该事件"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "row",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "当前行"
+ }
+ },
+ {
+ "name": "column",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "当前列"
+ }
+ },
+ {
+ "name": "cell",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "当前单元格"
+ }
+ },
+ {
+ "name": "event",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "原生事件 event"
+ }
+ }
+ ],
+ "returns": {}
+ }
+ }
+ },
+ "slots": {
+ "empty": {
+ "label": {
+ "zh_CN": "empty"
+ },
+ "description": {
+ "zh_CN": "当数据为空时自定义的内容"
+ }
+ },
+ "append": {
+ "label": {
+ "zh_CN": "append"
+ },
+ "description": {
+ "zh_CN": "插入至表格最后一行之后的内容, 如果需要对表格的内容进行无限滚动操作,可能需要用到这个 slot。 若表格有合计行,该 slot 会位于合计行之上。"
+ }
+ }
+ }
+ }
+ },
+ {
+ "id": 1,
+ "version": "2.4.2",
+ "name": {
+ "zh_CN": "表单"
+ },
+ "component": "ElTableColumn",
+ "icon": "table",
+ "description": "用于展示多条结构类似的数据, 可对数据进行排序、筛选、对比或其他自定义操作",
+ "doc_url": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "dev_mode": "proCode",
+ "npm": {
+ "package": "element-plus",
+ "exportName": "ElTableColumn",
+ "destructuring": true
+ },
+ "group": "表单组件",
+ "category": "element-plus",
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "isPopper": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": ["inline", "label-width"]
+ },
+ "contextMenu": {
+ "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"],
+ "disable": []
+ },
+ "invalidity": [""],
+ "clickCapture": true,
+ "framework": "Vue"
+ },
+ "schema": {
+ "properties": [
+ {
+ "name": "0",
+ "label": {
+ "zh_CN": "基础属性"
+ },
+ "content": [],
+ "description": {
+ "zh_CN": ""
+ }
+ }
+ ],
+ "events": {},
+ "slots": {}
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "进度条"
+ },
+ "component": "TinyProgress",
+ "icon": "progress",
+ "description": "进度条",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "package": "@opentiny/vue",
+ "exportName": "TinyProgress",
+ "destructuring": true
+ },
+ "group": "component",
+ "category": "进度条",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
+ "name": "0",
+ "label": {
+ "zh_CN": "基础属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "number",
+ "label": {
+ "text": {
+ "zh_CN": "百分比"
+ }
+ },
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
+ },
+ "disabled": false,
+ "property": "percentage",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "百分比(必填);该属性的可选值为 0-100"
+ },
+ "defaultValue": 0,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "enum",
+ "label": {
+ "text": {
+ "zh_CN": "类型"
+ }
+ },
+ "widget": {
+ "props": {
+ "options": [
+ {
+ "label": "line",
+ "value": "line"
},
{
- "property": "formatter",
- "type": "function",
- "labelPosition": "top",
- "defaultValue": true,
- "label": {
- "text": {
- "zh_CN": "formatter"
- }
- },
- "description": {
- "text": {
- "zh_CN": "用来格式化内容"
- }
- },
- "widget": {
- "component": "CodeConfigurator",
- "props": {
- "dataType": "JSFunction"
- }
- }
+ "label": "circle",
+ "value": "circle"
},
{
- "property": "show-overflow-tooltip",
- "type": "boolean",
- "labelPosition": "left",
- "defaultValue": true,
- "label": {
- "text": {
- "zh_CN": "show-overflow-tooltip"
- }
- },
- "description": {
- "text": {
- "zh_CN": "当内容过长被隐藏时显示 tooltip"
- }
- },
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
+ "label": "dashboard",
+ "value": "dashboard"
+ }
+ ]
+ },
+ "component": "SelectConfigurator"
+ },
+ "disabled": false,
+ "property": "type",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "进度条类型"
+ },
+ "defaultValue": "line",
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "enum",
+ "label": {
+ "text": {
+ "zh_CN": "状态"
+ }
+ },
+ "widget": {
+ "props": {
+ "options": [
+ {
+ "label": "success",
+ "value": "success"
},
{
- "property": "align",
- "type": "string",
- "labelPosition": "top",
- "defaultValue": "left",
- "label": {
- "text": {
- "zh_CN": "align"
- }
- },
- "description": {
- "text": {
- "zh_CN": "对齐方式"
- }
- },
- "widget": {
- "component": "SelectConfigurator",
- "props": {
- "options": [
- {
- "label": "left",
- "value": "left"
- },
- {
- "label": "center",
- "value": "center"
- },
- {
- "label": "right",
- "value": "right"
- }
- ]
- }
- }
+ "label": "exception",
+ "value": "exception"
},
{
- "property": "header-align",
- "type": "string",
- "labelPosition": "top",
- "defaultValue": "left",
- "label": {
- "text": {
- "zh_CN": "header-align"
- }
- },
- "description": {
- "text": {
- "zh_CN": "表头对齐方式, 若不设置该项,则使用表格的对齐方式"
- }
- },
- "widget": {
- "component": "SelectConfigurator",
- "props": {
- "options": [
- {
- "label": "left",
- "value": "left"
- },
- {
- "label": "center",
- "value": "center"
- },
- {
- "label": "right",
- "value": "right"
- }
- ]
- }
- }
+ "label": "warning",
+ "value": "warning"
+ }
+ ]
+ },
+ "component": "SelectConfigurator"
+ },
+ "disabled": false,
+ "property": "status",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "进度条当前状态"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性"
+ }
+ },
+ {
+ "name": "1",
+ "label": {
+ "zh_CN": "样式属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "颜色"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "ColorConfigurator"
+ },
+ "disabled": false,
+ "property": "color",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "进度条背景色(会覆盖 status 状态颜色)"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "number",
+ "label": {
+ "text": {
+ "zh_CN": "线条宽度"
+ }
+ },
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
+ },
+ "disabled": false,
+ "property": "stroke-width",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "line 类型进度条的宽度,单位 px"
+ },
+ "defaultValue": 6,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "number",
+ "label": {
+ "text": {
+ "zh_CN": "宽度"
+ }
+ },
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
+ },
+ "disabled": false,
+ "property": "width",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "环形进度条画布宽度(只在 type 为 circle 或 dashboard 时可用)"
+ },
+ "defaultValue": 126,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性"
+ }
+ },
+ {
+ "name": "2",
+ "label": {
+ "zh_CN": "行为属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "显示文字"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "SwitchConfigurator"
+ },
+ "disabled": false,
+ "property": "show-text",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否显示进度条文字内容"
+ },
+ "defaultValue": true,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "文字内置"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "text-inside",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "进度条显示文字内置在进度条内(只在 type=line 时可用)"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性"
+ }
+ },
+ {
+ "name": "3",
+ "label": {
+ "zh_CN": "高级属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "function",
+ "label": {
+ "text": {
+ "zh_CN": "格式"
+ }
+ },
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "javascript"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "format",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "自定义进度条的文字"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "状态图标"
+ }
+ },
+ "widget": {
+ "props": {
+ "options": [
+ {
+ "label": "successIcon",
+ "value": "successIcon"
},
{
- "property": "class-name",
- "type": "string",
- "labelPosition": "top",
- "defaultValue": "left",
- "label": {
- "text": {
- "zh_CN": "class-name"
- }
- },
- "description": {
- "text": {
- "zh_CN": "列的 className"
- }
- },
- "widget": {
- "component": "InputConfigurator",
- "props": {}
- }
+ "label": "exceptionIcon",
+ "value": "exceptionIcon"
},
{
- "property": "label-class-name",
- "type": "string",
- "labelPosition": "top",
- "defaultValue": "left",
- "label": {
- "text": {
- "zh_CN": "label-class-name"
- }
- },
- "description": {
- "text": {
- "zh_CN": "当前列标题的自定义类名"
- }
- },
- "widget": {
- "component": "InputConfigurator",
- "props": {}
- }
- },
+ "label": "warningIcon",
+ "value": "warningIcon"
+ }
+ ]
+ },
+ "component": "SelectConfigurator"
+ },
+ "disabled": false,
+ "property": "statusIcon",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "状态插槽,successIcon / exceptionIcon / warningIcon"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置"
+ }
+ }
+ ],
+ "events": {},
+ "slots": {}
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": []
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "骨架屏"
+ },
+ "component": "TinySkeleton",
+ "icon": "skeleton",
+ "description": "骨架屏",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "package": "@opentiny/vue",
+ "exportName": "TinySkeleton",
+ "destructuring": true
+ },
+ "group": "component",
+ "category": "骨架屏",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
+ "name": "0",
+ "label": {
+ "zh_CN": "基础属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "显示头像"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "avatar",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否显示头像"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "number",
+ "label": {
+ "text": {
+ "zh_CN": "行数"
+ }
+ },
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
+ },
+ "disabled": false,
+ "property": "rows",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "默认样式,可配置段落显示行数"
+ },
+ "defaultValue": 3,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "形态"
+ }
+ },
+ "widget": {
+ "props": {
+ "options": [
{
- "property": "selectable",
- "type": "function",
- "labelPosition": "top",
- "defaultValue": true,
- "label": {
- "text": {
- "zh_CN": "selectable"
- }
- },
- "description": {
- "text": {
- "zh_CN": "仅对 type=selection 的列有效,类型为 Function,Function 的返回值用来决定这一行的 CheckBox 是否可以勾选"
- }
- },
- "widget": {
- "component": "CodeConfigurator",
- "props": {}
- }
+ "label": "image",
+ "value": "image"
},
{
- "property": "reserve-selection",
- "type": "boolean",
- "labelPosition": "left",
- "defaultValue": true,
- "label": {
- "text": {
- "zh_CN": "reserve-selection"
- }
- },
- "description": {
- "text": {
- "zh_CN": "数据刷新后是否保留选项,仅对 type=selection 的列有效, 请注意, 需指定 row-key 来让这个功能生效。"
- }
- },
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
+ "label": "circle",
+ "value": "circle"
},
{
- "property": "filters",
- "type": "array",
- "labelPosition": "top",
- "defaultValue": true,
- "label": {
- "text": {
- "zh_CN": "filters"
- }
- },
- "description": {
- "text": {
- "zh_CN": "数据刷新后是否保留选项,仅对 type=selection 的列有效, 请注意, 需指定 row-key 来让这个功能生效。"
- }
- },
- "widget": {
- "component": "CodeConfigurator",
- "props": {
- "language": "json"
- }
- }
+ "label": "square",
+ "value": "square"
+ }
+ ]
+ },
+ "component": "SelectConfigurator"
+ },
+ "disabled": false,
+ "property": "variant",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "骨架屏形态"
+ },
+ "defaultValue": "square",
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性"
+ }
+ },
+ {
+ "name": "1",
+ "label": {
+ "zh_CN": "样式属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "尺寸"
+ }
+ },
+ "widget": {
+ "props": {
+ "options": [
+ {
+ "label": "large",
+ "value": "large"
},
{
- "property": "filter-placement",
- "type": "string",
- "labelPosition": "top",
- "label": {
- "text": {
- "zh_CN": "filter-placement"
- }
- },
- "description": {
- "text": {
- "zh_CN": "过滤弹出框的定位"
- }
- },
- "widget": {
- "component": "InputConfigurator",
- "props": {}
- }
+ "label": "medium",
+ "value": "medium"
},
{
- "property": "filter-multiple",
- "type": "string",
- "labelPosition": "left",
- "defaultValue": true,
- "label": {
- "text": {
- "zh_CN": "filter-multiple"
- }
- },
- "description": {
- "text": {
- "zh_CN": "数据过滤的选项是否多选"
- }
- },
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
+ "label": "small",
+ "value": "small"
+ }
+ ]
+ },
+ "component": "SelectConfigurator"
+ },
+ "disabled": false,
+ "property": "size",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "针对 image 和 circle 形态,内置三种大小"
+ },
+ "defaultValue": "medium",
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性"
+ }
+ },
+ {
+ "name": "2",
+ "label": {
+ "zh_CN": "行为属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "开启动画"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "animated",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否开启动画"
+ },
+ "defaultValue": true,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "显示骨架屏"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "loading",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否显示骨架屏,传 false 时会展示加载完成后的内容"
+ },
+ "defaultValue": true,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性"
+ }
+ },
+ {
+ "name": "3",
+ "label": {
+ "zh_CN": "高级属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "array",
+ "label": {
+ "text": {
+ "zh_CN": "行宽度"
+ }
+ },
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "json"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "rows-width",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "自定义段落每一行的宽度,数组中的每一项可以为 number 或 string ,当为 number 时,组件会自动增加 px 单位"
+ },
+ "defaultValue": [],
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置"
+ }
+ }
+ ],
+ "events": {},
+ "slots": {
+ "default": {
+ "label": {
+ "zh_CN": "默认内容"
+ },
+ "description": {
+ "zh_CN": "加载完成后显示的内容"
+ }
+ },
+ "placeholder": {
+ "label": {
+ "zh_CN": "占位符"
+ },
+ "description": {
+ "zh_CN": "自定义骨架屏结构"
+ }
+ }
+ }
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": []
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "卡片"
+ },
+ "component": "TinyCard",
+ "icon": "card",
+ "description": "卡片",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "package": "@opentiny/vue",
+ "exportName": "TinyCard",
+ "destructuring": true
+ },
+ "group": "component",
+ "category": "组件",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
+ "name": "0",
+ "label": {
+ "zh_CN": "基础属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "源地址"
+ }
+ },
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "src",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "图片或者视频的地址"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "标题"
+ }
+ },
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "title",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "卡片的标题"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "enum",
+ "label": {
+ "text": {
+ "zh_CN": "类型"
+ }
+ },
+ "widget": {
+ "props": {
+ "options": [
+ {
+ "label": "text",
+ "value": "text"
},
{
- "property": "filter-method",
- "type": "function",
- "labelPosition": "top",
- "defaultValue": true,
- "label": {
- "text": {
- "zh_CN": "filter-method"
- }
- },
- "description": {
- "text": {
- "zh_CN": "数据过滤使用的方法, 如果是多选的筛选项,对每一条数据会执行多次,任意一次返回 true 就会显示"
- }
- },
- "widget": {
- "component": "CodeConfigurator",
- "props": {}
- }
+ "label": "image",
+ "value": "image"
},
{
- "property": "filtered-value",
- "type": "array",
- "labelPosition": "top",
- "defaultValue": true,
- "label": {
- "text": {
- "zh_CN": "filtered-value"
- }
- },
- "description": {
- "text": {
- "zh_CN": "选中的数据过滤项,如果需要自定义表头过滤的渲染方式,可能会需要此属性"
- }
- },
- "widget": {
- "component": "CodeConfigurator",
- "props": {
- "language": "json"
- }
- }
+ "label": "video",
+ "value": "video"
+ },
+ {
+ "label": "logo",
+ "value": "logo"
+ }
+ ]
+ },
+ "component": "SelectConfigurator"
+ },
+ "disabled": false,
+ "property": "type",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "设置卡片类型"
+ },
+ "defaultValue": "text",
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性"
+ }
+ },
+ {
+ "name": "1",
+ "label": {
+ "zh_CN": "样式属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "自动宽度"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "auto-width",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "卡片的宽度是否自动撑开,设置后将不再给卡片设置固定宽度"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "自定义类名"
+ }
+ },
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "custom-class",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "卡片的class"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "高度"
+ }
+ },
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "height",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "卡片内容区域的高度"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性"
+ }
+ }
+ ],
+ "events": {},
+ "slots": {
+ "title": {
+ "label": {
+ "zh_CN": "标题"
+ },
+ "description": {
+ "zh_CN": "标题插槽"
+ }
+ },
+ "footer": {
+ "label": {
+ "zh_CN": "底部"
+ },
+ "description": {
+ "zh_CN": "组件底部插槽"
+ }
+ },
+ "default": {
+ "label": {
+ "zh_CN": "默认内容"
+ },
+ "description": {
+ "zh_CN": "组件默认插槽"
+ }
+ },
+ "title-left": {
+ "label": {
+ "zh_CN": "标题左侧"
+ },
+ "description": {
+ "zh_CN": "标题左侧插槽"
+ }
+ },
+ "title-right": {
+ "label": {
+ "zh_CN": "标题右侧"
+ },
+ "description": {
+ "zh_CN": "标题右侧插槽"
+ }
+ }
+ }
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": []
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "日历"
+ },
+ "component": "TinyCalendar",
+ "icon": "calendar",
+ "description": "日历",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "package": "@opentiny/vue",
+ "exportName": "TinyCalendar",
+ "destructuring": true
+ },
+ "group": "component",
+ "category": "组件",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
+ "name": "0",
+ "label": {
+ "zh_CN": "基础属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "enum",
+ "label": {
+ "text": {
+ "zh_CN": "显示模式"
+ }
+ },
+ "widget": {
+ "props": {
+ "options": [
+ {
+ "label": "month",
+ "value": "month"
+ },
+ {
+ "label": "year",
+ "value": "year"
}
]
+ },
+ "component": "SelectConfigurator"
+ },
+ "disabled": false,
+ "property": "mode",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "日历显示模式"
+ },
+ "defaultValue": "month",
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "number",
+ "label": {
+ "text": {
+ "zh_CN": "月份"
+ }
+ },
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
+ },
+ "disabled": false,
+ "property": "month",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "指定月份,默认当前月份"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "number",
+ "label": {
+ "text": {
+ "zh_CN": "年份"
+ }
+ },
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
+ },
+ "disabled": false,
+ "property": "year",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "指定年份,默认当前年份"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性"
+ }
+ },
+ {
+ "name": "2",
+ "label": {
+ "zh_CN": "行为属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "显示选中日期"
}
- ],
+ },
+ "widget": {
+ "props": {},
+ "component": "SwitchConfigurator"
+ },
+ "disabled": false,
+ "property": "show-selected",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否显示选中的日期"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性"
+ }
+ },
+ {
+ "name": "3",
+ "label": {
+ "zh_CN": "高级属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "array",
+ "label": {
+ "text": {
+ "zh_CN": "事件列表"
+ }
+ },
"widget": {
- "component": "TableColumnsConfigurator",
"props": {
- "type": "object",
- "textField": "label",
- "language": "json",
- "buttonText": "编辑列配置",
- "title": "编辑列配置",
- "expand": true
+ "height": 150,
+ "language": "json"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "events",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "事件列表"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置"
+ }
+ }
+ ],
+ "events": {},
+ "slots": {
+ "day": {
+ "label": {
+ "zh_CN": "日期单元格"
+ },
+ "description": {
+ "zh_CN": "日期单元格插槽"
+ }
+ },
+ "tool": {
+ "label": {
+ "zh_CN": "日历工具栏"
+ },
+ "description": {
+ "zh_CN": "日历工具栏插槽"
+ }
+ }
+ }
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": []
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "标记"
+ },
+ "component": "TinyBadge",
+ "icon": "badge",
+ "description": "标记",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "package": "@opentiny/vue",
+ "exportName": "TinyBadge",
+ "destructuring": true
+ },
+ "group": "component",
+ "category": "组件",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
+ "name": "0",
+ "label": {
+ "zh_CN": "基础属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "数据条目数"
}
},
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "value",
+ "readOnly": false,
+ "required": true,
"description": {
- "zh_CN": "表格列的配置信息"
+ "zh_CN": "相关数据条目数"
},
- "labelPosition": "top"
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "标记类型"
+ }
+ },
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "type",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "标记的类型"
+ },
+ "defaultValue": "danger",
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "文本内容"
+ }
+ },
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "data",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "文本内容"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性"
+ }
+ },
+ {
+ "name": "1",
+ "label": {
+ "zh_CN": "行为属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "是否隐藏"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
+ },
+ "disabled": false,
+ "property": "hidden",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否隐藏标记"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "boolean",
+ "label": {
+ "text": {
+ "zh_CN": "是否小圆点"
+ }
+ },
+ "widget": {
+ "props": {},
+ "component": "SwitchConfigurator"
+ },
+ "disabled": false,
+ "property": "is-dot",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否以小圆点的形式来显示标记"
+ },
+ "defaultValue": false,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性"
+ }
+ },
+ {
+ "name": "2",
+ "label": {
+ "zh_CN": "样式属性"
+ },
+ "content": [
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "自定义标记类名"
+ }
+ },
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "badge-class",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "自定义标记的类名"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "max-height",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "最大高度"
+ "zh_CN": "偏移量"
}
},
- "description": {
- "zh_CN": "Table 的最大高度。"
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "number",
- "widget": {
- "component": "NumberConfigurator",
- "props": {}
+ "property": "offset",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "设置标记位置的偏移量"
},
- "device": []
- },
+ "defaultValue": null,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性"
+ }
+ },
+ {
+ "name": "3",
+ "label": {
+ "zh_CN": "高级属性"
+ },
+ "content": [
{
- "property": "height",
+ "cols": 12,
+ "type": "number",
"label": {
"text": {
- "zh_CN": "表格高度"
+ "zh_CN": "最大值"
}
},
- "description": {
- "zh_CN": "Table 的高度, 默认为自动高度。 这个高度会设置为 Table 的 style.height 的值,Table 的高度会受控于外部样式。"
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "widget": {
- "component": "InputConfigurator",
- "props": {}
+ "property": "max",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "指定徽章显示的最大值,如果实际获取的徽章值超过该最大值,则以最大值后接一个 '+' 的形式显示徽章数,要求 value 是 number 类型"
},
- "device": []
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "stripe",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "斑马纹"
+ "zh_CN": "跳转地址"
}
},
- "description": {
- "zh_CN": "是否为斑马纹 table"
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "defaultValue": false,
- "type": "boolean",
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
+ "property": "href",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "指定跳转的目标页面地址"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "border",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "纵向边框"
+ "zh_CN": "跳转方式"
}
},
- "description": {
- "zh_CN": "是否带有纵向边框"
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "defaultValue": false,
- "type": "boolean",
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
- },
+ "property": "target",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "点击标记时链接到目标页面的跳转方式,仅在 href 属性存在时使用"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置"
+ }
+ }
+ ],
+ "events": {},
+ "slots": {
+ "content": {
+ "label": {
+ "zh_CN": "内容"
+ },
+ "description": {
+ "zh_CN": "消息提示内容"
+ }
+ },
+ "default": {
+ "label": {
+ "zh_CN": "默认内容"
+ },
+ "description": {
+ "zh_CN": "默认插槽,有data属性时,默认插槽不生效"
+ }
+ }
+ }
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": []
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "标签"
+ },
+ "component": "TinyTag",
+ "icon": "tag",
+ "description": "标签",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "package": "@opentiny/vue",
+ "exportName": "TinyTag",
+ "destructuring": true
+ },
+ "group": "component",
+ "category": "组件",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
+ "name": "0",
+ "label": {
+ "zh_CN": "基础属性"
+ },
+ "content": [
{
- "property": "size",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "表格尺寸"
+ "zh_CN": "显示类型"
}
},
- "description": {
- "zh_CN": "Table 的尺寸"
- },
- "required": true,
- "readOnly": false,
- "disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "type": "string",
- "defaultValue": "default",
"widget": {
- "component": "SelectConfigurator",
"props": {
- "options": [
- {
- "label": "large",
- "value": "large"
- },
- {
- "label": "default",
- "value": "default"
- },
- {
- "label": "small",
- "value": "small"
- }
- ]
- }
- }
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "type",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "显示类型"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "fit",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "列宽自撑开"
+ "zh_CN": "标签内容"
}
},
- "description": {
- "zh_CN": "列的宽度是否自撑开"
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "defaultValue": true,
- "type": "boolean",
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
- },
+ "property": "value",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "配置式标签,自定义标签内容"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性"
+ }
+ },
+ {
+ "name": "1",
+ "label": {
+ "zh_CN": "样式属性"
+ },
+ "content": [
{
- "property": "show-header",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "显示表头"
+ "zh_CN": "颜色"
}
},
- "description": {
- "zh_CN": "是否显示表头"
- },
- "required": true,
- "readOnly": false,
- "disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "defaultValue": true,
- "type": "boolean",
"widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
- },
- {
- "property": "highlight-current-row",
- "label": {
- "text": {
- "zh_CN": "高亮当前行"
- }
+ "props": {},
+ "component": "ColorConfigurator"
},
+ "disabled": false,
+ "property": "color",
+ "readOnly": false,
+ "required": true,
"description": {
- "zh_CN": "是否要高亮当前行"
+ "zh_CN": "控制标签文本色和背景色,可使用 IColor 类型中的预设值,也可自定义值"
},
- "required": true,
- "readOnly": false,
- "disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "defaultValue": false,
- "type": "boolean",
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "current-row-key",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "当前行的 key"
+ "zh_CN": "主题"
}
},
- "description": {
- "zh_CN": "当前行的 key,只写属性"
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "top",
- "type": "string",
- "widget": {
- "component": "InputConfigurator",
- "props": {}
+ "property": "effect",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "主题"
},
- "device": []
+ "defaultValue": "light",
+ "labelPosition": "left"
},
{
- "property": "row-class-name",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "行的类名"
+ "zh_CN": "最大宽度"
}
},
- "description": {
- "zh_CN": "行的 className"
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "widget": {
- "component": "InputConfigurator",
- "props": {}
+ "property": "max-width",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "设置最大宽度"
},
- "device": []
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "row-key",
+ "cols": 12,
+ "type": "string",
"label": {
"text": {
- "zh_CN": "行数据的 Key"
+ "zh_CN": "尺寸"
}
},
- "description": {
- "zh_CN": "行数据的 Key,用来优化 Table 的渲染; 在使用reserve-selection功能与显示树形数据时,该属性是必填的。 类型为 String 时,支持多层访问:user.info.id,但不支持 user.info[0].id,此种情况请使用 Function"
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "top",
- "widget": {
- "component": "CodeConfigurator",
- "props": {}
+ "property": "size",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "尺寸"
},
- "device": []
- },
+ "defaultValue": null,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性"
+ }
+ },
+ {
+ "name": "2",
+ "label": {
+ "zh_CN": "行为属性"
+ },
+ "content": [
{
- "property": "empty-text",
+ "cols": 12,
+ "type": "function",
"label": {
"text": {
- "zh_CN": "空数据文本"
+ "zh_CN": "删除前回调"
}
},
- "description": {
- "zh_CN": "空数据时显示的文本内容"
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "javascript"
+ },
+ "component": "CodeConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
- "widget": {
- "component": "InputConfigurator",
- "props": {}
+ "property": "before-delete",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "删除前回调函数"
},
- "device": []
+ "defaultValue": null,
+ "labelPosition": "left"
},
{
- "property": "table-layout",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "表格布局方式"
+ "zh_CN": "可关闭"
}
},
- "description": {
- "zh_CN": "设置表格单元、行和列的布局方式"
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "top",
- "defaultValue": "fixed",
- "widget": {
- "component": "InputConfigurator",
- "props": {
- "options": [
- {
- "label": "fixed",
- "value": "fixed"
- },
- {
- "label": "auto",
- "value": "auto"
- }
- ]
- }
+ "property": "closable",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否可关闭"
},
- "device": []
+ "defaultValue": false,
+ "labelPosition": "left"
},
{
- "property": "scrollbar-always-on",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "显示滚动条"
+ "zh_CN": "禁用"
}
},
- "description": {
- "zh_CN": "总是显示滚动条"
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
+ "property": "disabled",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否禁用"
+ },
"defaultValue": false,
- "type": "boolean",
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
+ "labelPosition": "left"
},
{
- "property": "flexible",
+ "cols": 12,
+ "type": "boolean",
"label": {
"text": {
- "zh_CN": "主轴最小尺寸"
+ "zh_CN": "纯图标模式"
}
},
- "description": {
- "zh_CN": "确保主轴的最小尺寸,以便不超过内容"
+ "widget": {
+ "props": {},
+ "component": "CheckBoxConfigurator"
},
- "required": true,
- "readOnly": false,
"disabled": false,
- "cols": 12,
- "labelPosition": "left",
+ "property": "only-icon",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "是否为纯图标的模式"
+ },
"defaultValue": false,
- "type": "boolean",
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- }
+ "labelPosition": "left"
}
],
"description": {
- "zh_CN": ""
+ "zh_CN": "组件交互、事件、状态相关的配置,包括 disabled、loading、onClick 等与用户操作和状态相关的属性"
}
}
],
"events": {
- "onSelect": {
- "label": {
- "zh_CN": "勾选数据行的 Checkbox 时触发"
- },
- "description": {
- "zh_CN": "当用户手动勾选数据行的 Checkbox 时触发的事件"
- },
+ "onClick": {
"type": "event",
- "functionInfo": {
- "params": [
- {
- "name": "selection",
- "type": "Object",
- "defaultValue": "",
- "description": {
- "zh_CN": "当前选中项"
- }
- },
- {
- "name": "row",
- "type": "Object",
- "defaultValue": "",
- "description": {
- "zh_CN": "当前行"
- }
- }
- ],
- "returns": {}
- }
- },
- "onSelectAll": {
"label": {
- "zh_CN": "勾选全选时触发"
+ "zh_CN": "点击标签时触发"
},
"description": {
- "zh_CN": "当用户手动勾选全选 Checkbox 时触发的事件"
+ "zh_CN": "点击标签时触发的事件"
},
- "type": "event",
+ "defaultValue": "",
"functionInfo": {
"params": [
{
- "name": "selection",
- "type": "Object",
- "defaultValue": "",
+ "name": "event",
+ "type": "Event",
"description": {
- "zh_CN": "当前选中项"
- }
+ "zh_CN": "事件对象"
+ },
+ "defaultValue": ""
}
],
- "returns": {}
+ "returns": {
+ "type": "",
+ "description": {
+ "zh_CN": ""
+ },
+ "defaultValue": ""
+ }
}
},
- "onSelectionChange": {
+ "onClose": {
+ "type": "event",
"label": {
- "zh_CN": "选择项发生变化时会触发"
+ "zh_CN": "点击关闭按钮时触发"
},
"description": {
- "zh_CN": "当选择项发生变化时会触发该事件"
+ "zh_CN": "点击关闭按钮时触发的事件"
},
- "type": "event",
+ "defaultValue": "",
"functionInfo": {
"params": [
{
- "name": "selection",
- "type": "Object",
- "defaultValue": "",
+ "name": "event",
+ "type": "Event",
"description": {
- "zh_CN": "当前选中项"
- }
+ "zh_CN": "事件对象"
+ },
+ "defaultValue": ""
}
],
- "returns": {}
+ "returns": {
+ "type": "",
+ "description": {
+ "zh_CN": ""
+ },
+ "defaultValue": ""
+ }
}
- },
- "onCellMouseEnter": {
+ }
+ },
+ "slots": {
+ "default": {
"label": {
- "zh_CN": "单元格 hover 时会触发"
+ "zh_CN": "默认内容"
},
"description": {
- "zh_CN": "当单元格 hover 进入时会触发该事件"
+ "zh_CN": "标签内容"
+ }
+ }
+ }
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": []
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.22.0",
+ "name": {
+ "zh_CN": "统计数值"
+ },
+ "component": "TinyStatistic",
+ "icon": "statistic",
+ "description": "统计数值",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "package": "@opentiny/vue",
+ "exportName": "TinyStatistic",
+ "destructuring": true
+ },
+ "group": "component",
+ "category": "组件",
+ "priority": 2,
+ "schema": {
+ "properties": [
+ {
+ "name": "0",
+ "label": {
+ "zh_CN": "基础属性"
},
- "type": "event",
- "functionInfo": {
- "params": [
- {
- "name": "row",
- "type": "Object",
- "defaultValue": "",
- "description": {
- "zh_CN": "当前行"
+ "content": [
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "值"
}
},
- {
- "name": "column",
- "type": "Object",
- "defaultValue": "",
- "description": {
- "zh_CN": "当前列"
- }
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
},
- {
- "name": "cell",
- "type": "Object",
- "defaultValue": "",
- "description": {
- "zh_CN": "当前单元格"
- }
+ "disabled": false,
+ "property": "value",
+ "readOnly": false,
+ "required": false,
+ "description": {
+ "zh_CN": "数字显示内容"
},
- {
- "name": "event",
- "type": "Object",
- "defaultValue": "",
- "description": {
- "zh_CN": "原生事件 event"
+ "defaultValue": "0",
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "number",
+ "label": {
+ "text": {
+ "zh_CN": "精度"
}
- }
- ],
- "returns": {}
+ },
+ "widget": {
+ "props": {
+ "step": 1
+ },
+ "component": "NumberConfigurator"
+ },
+ "disabled": false,
+ "property": "precision",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "精度值"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件核心功能相关的配置,包括 name、size、type 等核心属性"
}
},
- "onCellMouseLeave": {
+ {
+ "name": "1",
"label": {
- "zh_CN": "单元格 hover 退出时会触发"
+ "zh_CN": "样式属性"
},
+ "content": [
+ {
+ "cols": 12,
+ "type": "object",
+ "label": {
+ "text": {
+ "zh_CN": "值样式"
+ }
+ },
+ "widget": {
+ "props": {
+ "height": 150,
+ "language": "json"
+ },
+ "component": "CodeConfigurator"
+ },
+ "disabled": false,
+ "property": "value-style",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "设置数字样式"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ }
+ ],
"description": {
- "zh_CN": "当单元格 hover 退出时会触发该事件"
+ "zh_CN": "组件外观、颜色、尺寸相关的配置,包括 width、height、backgroundColor、color 等与视觉呈现相关的属性"
+ }
+ },
+ {
+ "name": "2",
+ "label": {
+ "zh_CN": "高级属性"
},
- "type": "event",
- "functionInfo": {
- "params": [
- {
- "name": "row",
- "type": "Object",
- "defaultValue": "",
- "description": {
- "zh_CN": "当前行"
+ "content": [
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "前缀"
}
},
- {
- "name": "column",
- "type": "Object",
- "defaultValue": "",
- "description": {
- "zh_CN": "当前列"
- }
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
},
- {
- "name": "cell",
- "type": "Object",
- "defaultValue": "",
- "description": {
- "zh_CN": "当前单元格"
+ "disabled": false,
+ "property": "prefix",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "设置数字内容前缀"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "后缀"
}
},
- {
- "name": "event",
- "type": "Object",
- "defaultValue": "",
- "description": {
- "zh_CN": "原生事件 event"
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "suffix",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "设置数字内容后缀"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ },
+ {
+ "cols": 12,
+ "type": "string",
+ "label": {
+ "text": {
+ "zh_CN": "标题"
}
- }
- ],
- "returns": {}
+ },
+ "widget": {
+ "props": {
+ "placeholder": "请输入..."
+ },
+ "component": "InputConfigurator"
+ },
+ "disabled": false,
+ "property": "title",
+ "readOnly": false,
+ "required": true,
+ "description": {
+ "zh_CN": "设置数字内容标题"
+ },
+ "defaultValue": null,
+ "labelPosition": "left"
+ }
+ ],
+ "description": {
+ "zh_CN": "组件可选的专业配置项,包括复杂对象配置、高级功能选项等不常用的特殊配置"
}
}
- },
+ ],
+ "events": {},
"slots": {
- "empty": {
+ "title": {
"label": {
- "zh_CN": "empty"
+ "zh_CN": "标题"
},
"description": {
- "zh_CN": "当数据为空时自定义的内容"
+ "zh_CN": "数字内容标题插槽"
}
},
- "append": {
+ "prefix": {
"label": {
- "zh_CN": "append"
+ "zh_CN": "前缀"
},
"description": {
- "zh_CN": "插入至表格最后一行之后的内容, 如果需要对表格的内容进行无限滚动操作,可能需要用到这个 slot。 若表格有合计行,该 slot 会位于合计行之上。"
+ "zh_CN": "数字内容前置插槽"
+ }
+ },
+ "suffix": {
+ "label": {
+ "zh_CN": "后缀"
+ },
+ "description": {
+ "zh_CN": "数字内容后置插槽"
}
}
}
- }
- },
- {
- "id": 1,
- "version": "2.4.2",
- "name": {
- "zh_CN": "表单"
- },
- "component": "ElTableColumn",
- "icon": "table",
- "description": "用于展示多条结构类似的数据, 可对数据进行排序、筛选、对比或其他自定义操作",
- "doc_url": "",
- "screenshot": "",
- "tags": "",
- "keywords": "",
- "dev_mode": "proCode",
- "npm": {
- "package": "element-plus",
- "exportName": "ElTableColumn",
- "destructuring": true
},
- "group": "表单组件",
- "category": "element-plus",
"configure": {
"loop": true,
"condition": true,
"styles": true,
"isContainer": false,
"isModal": false,
- "isPopper": false,
"nestingRule": {
"childWhitelist": "",
"parentWhitelist": "",
@@ -3135,31 +10030,12 @@
"isLayout": false,
"rootSelector": "",
"shortcuts": {
- "properties": ["inline", "label-width"]
+ "properties": []
},
"contextMenu": {
- "actions": ["copy", "remove", "insert", "updateAttr", "bindEvent", "createBlock"],
- "disable": []
- },
- "invalidity": [""],
- "clickCapture": true,
- "framework": "Vue"
- },
- "schema": {
- "properties": [
- {
- "name": "0",
- "label": {
- "zh_CN": "基础属性"
- },
- "content": [],
- "description": {
- "zh_CN": ""
- }
- }
- ],
- "events": {},
- "slots": {}
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
}
},
{
@@ -4433,18 +11309,19 @@
"bindState": true,
"label": {
"text": {
- "zh_CN": "资源"
+ "zh_CN": "资源选择"
}
},
"cols": 12,
"rules": [],
"widget": {
- "component": "InputConfigurator",
+ "component": "SourceSelectConfigurator",
"props": {}
},
"description": {
"zh_CN": "src路径"
- }
+ },
+ "labelPosition": "top"
},
{
"property": "attributes3",
@@ -9754,6 +16631,7 @@
}
},
{
+ "version": "3.20.0",
"icon": "grid",
"name": {
"zh_CN": "表格"
@@ -12231,15 +19109,194 @@
"props": {}
},
"description": {
- "zh_CN": "为 popper 添加类名"
+ "zh_CN": "为 popper 添加类名"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "visible-arrow",
+ "label": {
+ "text": {
+ "zh_CN": "显示箭头"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否显示 Tooltip 箭头"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "append-to-body",
+ "label": {
+ "text": {
+ "zh_CN": "添加到body上"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "Popover弹窗是否添加到body上"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "arrow-offset",
+ "label": {
+ "text": {
+ "zh_CN": "箭头的位置偏移"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "箭头的位置偏移,该属性的默认值为 0"
+ }
+ },
+ {
+ "property": "close-delay",
+ "label": {
+ "text": {
+ "zh_CN": "延迟隐藏"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "触发方式为 hover 时的隐藏延迟,单位为毫秒"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "content",
+ "label": {
+ "text": {
+ "zh_CN": "显示的内容"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "InputConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "显示的内容,也可以通过 slot 传入 DOM"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "disabled",
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "Popover 是否可用"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "offset",
+ "label": {
+ "text": {
+ "zh_CN": "位置偏移量"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "出现位置的偏移量"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "open-delay",
+ "label": {
+ "text": {
+ "zh_CN": "显示延迟"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "NumberConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "触发方式为 hover 时的显示延迟,单位为毫秒"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "popper-options",
+ "label": {
+ "text": {
+ "zh_CN": "弹出层参数"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CodeConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "popper.js 的参数"
},
- "labelPosition": "left"
+ "labelPosition": "top"
},
{
- "property": "visible-arrow",
+ "property": "title",
"label": {
"text": {
- "zh_CN": "显示箭头"
+ "zh_CN": "标题"
}
},
"required": true,
@@ -12247,19 +19304,19 @@
"disabled": false,
"cols": 12,
"widget": {
- "component": "CheckBoxConfigurator",
+ "component": "InputConfigurator",
"props": {}
},
"description": {
- "zh_CN": "是否显示 Tooltip 箭头"
+ "zh_CN": "提示内容标题"
},
"labelPosition": "left"
},
{
- "property": "append-to-body",
+ "property": "transform-origin",
"label": {
"text": {
- "zh_CN": "添加到body上"
+ "zh_CN": "旋转中心点"
}
},
"required": true,
@@ -12271,15 +19328,15 @@
"props": {}
},
"description": {
- "zh_CN": "Popover弹窗是否添加到body上"
+ "zh_CN": "组件的旋转中心点,组件的旋转中心点"
},
"labelPosition": "left"
},
{
- "property": "arrow-offset",
+ "property": "transition",
"label": {
"text": {
- "zh_CN": "箭头的位置偏移"
+ "zh_CN": "渐变动画"
}
},
"required": true,
@@ -12287,18 +19344,19 @@
"disabled": false,
"cols": 12,
"widget": {
- "component": "NumberConfigurator",
+ "component": "InputConfigurator",
"props": {}
},
"description": {
- "zh_CN": "箭头的位置偏移,该属性的默认值为 0"
- }
+ "zh_CN": "该属性的默认值为 fade-in-linear"
+ },
+ "labelPosition": "left"
},
{
- "property": "close-delay",
+ "property": "width",
"label": {
"text": {
- "zh_CN": "延迟隐藏"
+ "zh_CN": "宽度"
}
},
"required": true,
@@ -12310,15 +19368,99 @@
"props": {}
},
"description": {
- "zh_CN": "触发方式为 hover 时的隐藏延迟,单位为毫秒"
+ "zh_CN": "宽度"
},
"labelPosition": "left"
- },
+ }
+ ]
+ }
+ ],
+ "events": {
+ "onUpdate:modelValue": {
+ "label": {
+ "zh_CN": "双向绑定的值改变时触发"
+ },
+ "description": {
+ "zh_CN": "手动控制是否可见的状态值改变时触发"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "value",
+ "type": "boolean",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "双向绑定的可见状态值"
+ }
+ }
+ ],
+ "returns": {}
+ },
+ "defaultValue": ""
+ }
+ }
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": true,
+ "isModal": false,
+ "isPopper": true,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": ["visible", "width"]
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ },
+ {
+ "version": "3.20.0",
+ "name": {
+ "zh_CN": "日期选择"
+ },
+ "component": "TinyDatePicker",
+ "icon": "datepick",
+ "description": "用于输入或选择日期",
+ "docUrl": "",
+ "screenshot": "",
+ "tags": "",
+ "keywords": "",
+ "devMode": "proCode",
+ "npm": {
+ "package": "@opentiny/vue",
+ "exportName": "DatePicker",
+ "destructuring": true
+ },
+ "group": "component",
+ "priority": 1,
+ "schema": {
+ "properties": [
+ {
+ "label": {
+ "zh_CN": "基础信息"
+ },
+ "description": {
+ "zh_CN": "基础信息"
+ },
+ "content": [
{
- "property": "content",
+ "property": "modelValue",
"label": {
"text": {
- "zh_CN": "显示的内容"
+ "zh_CN": "绑定值"
}
},
"required": true,
@@ -12326,39 +19468,58 @@
"disabled": false,
"cols": 12,
"widget": {
- "component": "InputConfigurator",
+ "component": "I18nConfigurator",
"props": {}
},
"description": {
- "zh_CN": "显示的内容,也可以通过 slot 传入 DOM"
+ "zh_CN": "双向绑定值"
},
"labelPosition": "left"
},
{
- "property": "disabled",
+ "property": "type",
"label": {
"text": {
- "zh_CN": "禁用"
+ "zh_CN": "类型"
}
},
- "required": true,
- "readOnly": false,
- "disabled": false,
- "cols": 12,
"widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "日期",
+ "value": "date"
+ },
+ {
+ "label": "日期时间",
+ "value": "datetime"
+ },
+ {
+ "label": "周",
+ "value": "week"
+ },
+ {
+ "label": "月份",
+ "value": "month"
+ },
+ {
+ "label": "年份",
+ "value": "year"
+ }
+ ]
+ }
},
"description": {
- "zh_CN": "Popover 是否可用"
+ "zh_CN": "设置日期框的type属性"
},
"labelPosition": "left"
},
{
- "property": "offset",
+ "property": "placeholder",
"label": {
"text": {
- "zh_CN": "位置偏移量"
+ "zh_CN": "占位文本"
}
},
"required": true,
@@ -12366,19 +19527,19 @@
"disabled": false,
"cols": 12,
"widget": {
- "component": "NumberConfigurator",
+ "component": "I18nConfigurator",
"props": {}
},
"description": {
- "zh_CN": "出现位置的偏移量"
+ "zh_CN": "输入框占位文本"
},
"labelPosition": "left"
},
{
- "property": "open-delay",
+ "property": "clearable",
"label": {
"text": {
- "zh_CN": "显示延迟"
+ "zh_CN": "清除按钮"
}
},
"required": true,
@@ -12386,39 +19547,39 @@
"disabled": false,
"cols": 12,
"widget": {
- "component": "NumberConfigurator",
+ "component": "CheckBoxConfigurator",
"props": {}
},
"description": {
- "zh_CN": "触发方式为 hover 时的显示延迟,单位为毫秒"
+ "zh_CN": "是否显示清除按钮"
},
"labelPosition": "left"
},
{
- "property": "popper-options",
+ "property": "disabled",
"label": {
"text": {
- "zh_CN": "弹出层参数"
+ "zh_CN": "禁用"
}
},
- "required": true,
+ "required": false,
"readOnly": false,
"disabled": false,
"cols": 12,
"widget": {
- "component": "CodeConfigurator",
+ "component": "CheckBoxConfigurator",
"props": {}
},
"description": {
- "zh_CN": "popper.js 的参数"
+ "zh_CN": "是否禁用"
},
- "labelPosition": "top"
+ "labelPosition": "left"
},
{
- "property": "title",
+ "property": "readonly",
"label": {
"text": {
- "zh_CN": "标题"
+ "zh_CN": "只读"
}
},
"required": true,
@@ -12426,19 +19587,19 @@
"disabled": false,
"cols": 12,
"widget": {
- "component": "InputConfigurator",
+ "component": "CheckBoxConfigurator",
"props": {}
},
"description": {
- "zh_CN": "提示内容标题"
+ "zh_CN": "是否只读"
},
"labelPosition": "left"
},
{
- "property": "transform-origin",
+ "property": "size",
"label": {
"text": {
- "zh_CN": "旋转中心点"
+ "zh_CN": "尺寸"
}
},
"required": true,
@@ -12446,19 +19607,42 @@
"disabled": false,
"cols": 12,
"widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "medium",
+ "value": "medium"
+ },
+ {
+ "label": "small",
+ "value": "small"
+ },
+ {
+ "label": "mini",
+ "value": "mini"
+ }
+ ]
+ }
},
"description": {
- "zh_CN": "组件的旋转中心点,组件的旋转中心点"
+ "zh_CN": "日期框尺寸。该属性的可选值为 medium / small / mini"
},
"labelPosition": "left"
- },
+ }
+ ]
+ },
+ {
+ "name": "1",
+ "label": {
+ "zh_CN": "其他"
+ },
+ "content": [
{
- "property": "transition",
+ "property": "maxlength",
"label": {
"text": {
- "zh_CN": "渐变动画"
+ "zh_CN": "输入最大长度"
}
},
"required": true,
@@ -12466,19 +19650,18 @@
"disabled": false,
"cols": 12,
"widget": {
- "component": "InputConfigurator",
+ "component": "NumberConfigurator",
"props": {}
},
"description": {
- "zh_CN": "该属性的默认值为 fade-in-linear"
- },
- "labelPosition": "left"
+ "zh_CN": "设置 input 框的maxLength"
+ }
},
{
- "property": "width",
+ "property": "autofocus",
"label": {
"text": {
- "zh_CN": "宽度"
+ "zh_CN": "聚焦"
}
},
"required": true,
@@ -12486,40 +19669,149 @@
"disabled": false,
"cols": 12,
"widget": {
- "component": "NumberConfigurator",
+ "component": "CheckBoxConfigurator",
"props": {}
},
"description": {
- "zh_CN": "宽度"
+ "zh_CN": "自动获取焦点"
},
"labelPosition": "left"
}
- ]
+ ],
+ "description": {
+ "zh_CN": ""
+ }
}
],
"events": {
+ "onChange": {
+ "label": {
+ "zh_CN": "值改变时触发"
+ },
+ "description": {
+ "zh_CN": "在 Input 值改变时触发"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "value",
+ "type": "string",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "输入框改变后的值"
+ }
+ }
+ ],
+ "returns": {}
+ },
+ "defaultValue": ""
+ },
+ "onInput": {
+ "label": {
+ "zh_CN": "输入值改变时触发"
+ },
+ "description": {
+ "zh_CN": "在 Input 输入值改变时触发"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "value",
+ "type": "string",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "输入框输入的值"
+ }
+ }
+ ],
+ "returns": {}
+ },
+ "defaultValue": ""
+ },
"onUpdate:modelValue": {
"label": {
"zh_CN": "双向绑定的值改变时触发"
},
"description": {
- "zh_CN": "手动控制是否可见的状态值改变时触发"
+ "zh_CN": "在 Input 输入值改变时触发"
},
"type": "event",
"functionInfo": {
"params": [
{
"name": "value",
- "type": "boolean",
+ "type": "string",
"defaultValue": "",
"description": {
- "zh_CN": "双向绑定的可见状态值"
+ "zh_CN": "双向绑定的值"
+ }
+ }
+ ],
+ "returns": {}
+ },
+ "defaultValue": ""
+ },
+ "onBlur": {
+ "label": {
+ "zh_CN": "失去焦点时触发"
+ },
+ "description": {
+ "zh_CN": "在 Input 失去焦点时触发"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "event",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "原生 event"
+ }
+ }
+ ],
+ "returns": {}
+ },
+ "defaultValue": ""
+ },
+ "onFocus": {
+ "label": {
+ "zh_CN": "获取焦点时触发"
+ },
+ "description": {
+ "zh_CN": "在 Input 获取焦点时触发"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "event",
+ "type": "Object",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "原生 event"
}
}
],
"returns": {}
},
"defaultValue": ""
+ },
+ "onClear": {
+ "label": {
+ "zh_CN": "点击清空按钮时触发"
+ },
+ "description": {
+ "zh_CN": "点击清空按钮时触发"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [],
+ "returns": {}
+ },
+ "defaultValue": ""
}
}
},
@@ -12529,7 +19821,6 @@
"styles": true,
"isContainer": true,
"isModal": false,
- "isPopper": true,
"nestingRule": {
"childWhitelist": "",
"parentWhitelist": "",
@@ -12540,7 +19831,7 @@
"isLayout": false,
"rootSelector": "",
"shortcuts": {
- "properties": ["visible", "width"]
+ "properties": ["value", "disabled"]
},
"contextMenu": {
"actions": ["create symbol"],
@@ -12551,11 +19842,11 @@
{
"version": "3.20.0",
"name": {
- "zh_CN": "日期选择"
+ "zh_CN": "数字输入框"
},
- "component": "TinyDatePicker",
- "icon": "datepick",
- "description": "用于输入或选择日期",
+ "component": "TinyNumeric",
+ "icon": "numeric",
+ "description": "通过鼠标或键盘输入字符",
"docUrl": "",
"screenshot": "",
"tags": "",
@@ -12563,7 +19854,7 @@
"devMode": "proCode",
"npm": {
"package": "@opentiny/vue",
- "exportName": "DatePicker",
+ "exportName": "Numeric",
"destructuring": true
},
"group": "component",
@@ -12588,7 +19879,6 @@
"required": true,
"readOnly": false,
"disabled": false,
- "cols": 12,
"widget": {
"component": "I18nConfigurator",
"props": {}
@@ -12599,89 +19889,155 @@
"labelPosition": "left"
},
{
- "property": "type",
+ "property": "placeholder",
"label": {
"text": {
- "zh_CN": "类型"
+ "zh_CN": "占位文本"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "I18nConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "输入框占位文本"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "allow-empty",
+ "label": {
+ "text": {
+ "zh_CN": "内容可清空"
+ }
+ },
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否内容可清空"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "disabled",
+ "label": {
+ "text": {
+ "zh_CN": "禁用"
+ }
+ },
+ "required": false,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
+ "widget": {
+ "component": "CheckBoxConfigurator",
+ "props": {}
+ },
+ "description": {
+ "zh_CN": "是否禁用"
+ },
+ "labelPosition": "left"
+ },
+ {
+ "property": "size",
+ "label": {
+ "text": {
+ "zh_CN": "尺寸"
}
},
+ "required": true,
+ "readOnly": false,
+ "disabled": false,
+ "cols": 12,
"widget": {
"component": "SelectConfigurator",
"props": {
"options": [
{
- "label": "日期",
- "value": "date"
- },
- {
- "label": "日期时间",
- "value": "datetime"
- },
- {
- "label": "周",
- "value": "week"
+ "label": "medium",
+ "value": "medium"
},
{
- "label": "月份",
- "value": "month"
+ "label": "small",
+ "value": "small"
},
{
- "label": "年份",
- "value": "year"
+ "label": "mini",
+ "value": "mini"
}
]
}
},
"description": {
- "zh_CN": "设置日期框的type属性"
+ "zh_CN": "输入框尺寸。该属性的可选值为 medium / small / mini"
},
"labelPosition": "left"
},
{
- "property": "placeholder",
+ "property": "controls",
"label": {
"text": {
- "zh_CN": "占位文本"
+ "zh_CN": "加减按钮"
}
},
- "required": true,
+ "required": false,
"readOnly": false,
"disabled": false,
"cols": 12,
"widget": {
- "component": "I18nConfigurator",
+ "component": "CheckBoxConfigurator",
"props": {}
},
"description": {
- "zh_CN": "输入框占位文本"
+ "zh_CN": "是否使用加减按钮"
},
"labelPosition": "left"
},
{
- "property": "clearable",
+ "property": "controls-position",
"label": {
"text": {
- "zh_CN": "清除按钮"
+ "zh_CN": "加减按钮位置"
}
},
- "required": true,
+ "required": false,
"readOnly": false,
"disabled": false,
"cols": 12,
"widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ "component": "SelectConfigurator",
+ "props": {
+ "options": [
+ {
+ "label": "左右两侧",
+ "value": ""
+ },
+ {
+ "label": "只在右侧",
+ "value": "right"
+ }
+ ]
+ }
},
"description": {
- "zh_CN": "是否显示清除按钮"
- },
- "labelPosition": "left"
+ "zh_CN": "加减按钮位置"
+ }
},
{
- "property": "disabled",
+ "property": "precision",
"label": {
"text": {
- "zh_CN": "禁用"
+ "zh_CN": "精度"
}
},
"required": false,
@@ -12689,120 +20045,83 @@
"disabled": false,
"cols": 12,
"widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ "component": "NumberConfigurator",
+ "props": {
+ "allowEmpty": true
+ }
},
"description": {
- "zh_CN": "是否禁用"
+ "zh_CN": "数值精度"
},
"labelPosition": "left"
},
{
- "property": "readonly",
+ "property": "step",
"label": {
"text": {
- "zh_CN": "只读"
+ "zh_CN": "步长"
}
},
- "required": true,
+ "required": false,
"readOnly": false,
"disabled": false,
"cols": 12,
"widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ "component": "NumberConfigurator",
+ "props": {
+ "allowEmpty": true
+ }
},
"description": {
- "zh_CN": "是否只读"
+ "zh_CN": "步长"
},
"labelPosition": "left"
},
{
- "property": "size",
+ "property": "max",
"label": {
"text": {
- "zh_CN": "尺寸"
+ "zh_CN": "最大数值"
}
},
- "required": true,
+ "required": false,
"readOnly": false,
"disabled": false,
"cols": 12,
"widget": {
- "component": "SelectConfigurator",
+ "component": "NumberConfigurator",
"props": {
- "options": [
- {
- "label": "medium",
- "value": "medium"
- },
- {
- "label": "small",
- "value": "small"
- },
- {
- "label": "mini",
- "value": "mini"
- }
- ]
+ "allowEmpty": true
}
},
"description": {
- "zh_CN": "日期框尺寸。该属性的可选值为 medium / small / mini"
+ "zh_CN": "可输入的最大数值"
},
"labelPosition": "left"
- }
- ]
- },
- {
- "name": "1",
- "label": {
- "zh_CN": "其他"
- },
- "content": [
+ },
{
- "property": "maxlength",
+ "property": "min",
"label": {
"text": {
- "zh_CN": "输入最大长度"
+ "zh_CN": "最小数值"
}
},
- "required": true,
+ "required": false,
"readOnly": false,
"disabled": false,
"cols": 12,
"widget": {
"component": "NumberConfigurator",
- "props": {}
- },
- "description": {
- "zh_CN": "设置 input 框的maxLength"
- }
- },
- {
- "property": "autofocus",
- "label": {
- "text": {
- "zh_CN": "聚焦"
+ "props": {
+ "allowEmpty": true
}
},
- "required": true,
- "readOnly": false,
- "disabled": false,
- "cols": 12,
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- },
"description": {
- "zh_CN": "自动获取焦点"
+ "zh_CN": "可输入的最大数值"
},
"labelPosition": "left"
}
- ],
- "description": {
- "zh_CN": ""
- }
+ ]
}
],
"events": {
@@ -12964,11 +20283,11 @@
{
"version": "3.20.0",
"name": {
- "zh_CN": "数字输入框"
+ "zh_CN": "穿梭框"
},
- "component": "TinyNumeric",
- "icon": "numeric",
- "description": "通过鼠标或键盘输入字符",
+ "component": "TinyTransfer",
+ "icon": "transfer",
+ "description": "穿梭框,实现左右表格数据的双向交换的组件",
"docUrl": "",
"screenshot": "",
"tags": "",
@@ -12976,7 +20295,7 @@
"devMode": "proCode",
"npm": {
"package": "@opentiny/vue",
- "exportName": "Numeric",
+ "exportName": "TinyTransfer",
"destructuring": true
},
"group": "component",
@@ -13011,988 +20330,1330 @@
"labelPosition": "left"
},
{
- "property": "placeholder",
+ "property": "data",
"label": {
"text": {
- "zh_CN": "占位文本"
+ "zh_CN": "左右列表的全量数据源"
}
},
"required": true,
"readOnly": false,
"disabled": false,
- "cols": 12,
"widget": {
- "component": "I18nConfigurator",
- "props": {}
+ "component": "CodeConfigurator",
+ "props": {
+ "language": "json"
+ }
},
"description": {
- "zh_CN": "输入框占位文本"
+ "zh_CN": "左右列表的全量数据源"
},
"labelPosition": "left"
},
{
- "property": "allow-empty",
+ "property": "filterable",
"label": {
"text": {
- "zh_CN": "内容可清空"
+ "zh_CN": "是否启用搜索的功能"
}
},
- "required": true,
+ "required": false,
"readOnly": false,
"disabled": false,
- "cols": 12,
"widget": {
"component": "CheckBoxConfigurator",
"props": {}
},
"description": {
- "zh_CN": "是否内容可清空"
+ "zh_CN": "是否启用搜索的功能"
},
"labelPosition": "left"
},
{
- "property": "disabled",
+ "property": "showAllBtn",
"label": {
"text": {
- "zh_CN": "禁用"
+ "zh_CN": "是否显示全部移动按钮"
}
},
"required": false,
"readOnly": false,
"disabled": false,
- "cols": 12,
"widget": {
"component": "CheckBoxConfigurator",
"props": {}
},
"description": {
- "zh_CN": "是否禁用"
+ "zh_CN": "是否显示全部移动按钮"
},
"labelPosition": "left"
},
{
- "property": "size",
+ "property": "toLeftDisable",
"label": {
"text": {
- "zh_CN": "尺寸"
+ "zh_CN": "组件初始化状态下未选中时,默认按钮显示禁用状态"
}
},
- "required": true,
+ "required": false,
"readOnly": false,
"disabled": false,
- "cols": 12,
"widget": {
- "component": "SelectConfigurator",
- "props": {
- "options": [
- {
- "label": "medium",
- "value": "medium"
- },
- {
- "label": "small",
- "value": "small"
- },
- {
- "label": "mini",
- "value": "mini"
- }
- ]
- }
+ "component": "CheckBoxConfigurator",
+ "props": {}
},
"description": {
- "zh_CN": "输入框尺寸。该属性的可选值为 medium / small / mini"
+ "zh_CN": "组件初始化状态下未选中时,默认按钮显示禁用状态"
},
"labelPosition": "left"
},
{
- "property": "controls",
+ "property": "toRightDisable",
"label": {
"text": {
- "zh_CN": "加减按钮"
+ "zh_CN": "组件初始化状态下未选中时,默认按钮显示禁用状态"
}
},
"required": false,
"readOnly": false,
"disabled": false,
- "cols": 12,
"widget": {
"component": "CheckBoxConfigurator",
"props": {}
},
"description": {
- "zh_CN": "是否使用加减按钮"
+ "zh_CN": "组件初始化状态下未选中时,默认按钮显示禁用状态"
},
"labelPosition": "left"
},
{
- "property": "controls-position",
+ "property": "titles",
"label": {
"text": {
- "zh_CN": "加减按钮位置"
+ "zh_CN": "自定义列表的标题"
}
},
"required": false,
"readOnly": false,
"disabled": false,
- "cols": 12,
"widget": {
- "component": "SelectConfigurator",
+ "component": "CodeConfigurator",
"props": {
- "options": [
- {
- "label": "左右两侧",
- "value": ""
- },
- {
- "label": "只在右侧",
- "value": "right"
- }
- ]
+ "language": "json"
+ }
+ },
+ "description": {
+ "zh_CN": "自定义列表的标题;不设置titles时,左右列表的标题默认显示为: 列表 1, 列表 2"
+ },
+ "labelPosition": "left"
+ }
+ ]
+ }
+ ],
+ "events": {
+ "onChange": {
+ "label": {
+ "zh_CN": "右侧列表元素变化时触发"
+ },
+ "description": {
+ "zh_CN": "右侧列表元素变化时触发"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "value",
+ "type": "string",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "右侧列表元素变化时触发"
+ }
+ }
+ ],
+ "returns": {}
+ },
+ "defaultValue": ""
+ },
+ "onLeftCheckChange": {
+ "label": {
+ "zh_CN": "左侧列表元素被用户选中 / 取消选中时触发;"
+ },
+ "description": {
+ "zh_CN": "左侧列表元素被用户选中 / 取消选中时触发;"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "value",
+ "type": "string",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "左侧列表元素被用户选中 / 取消选中时触发;"
+ }
+ }
+ ],
+ "returns": {}
+ },
+ "defaultValue": ""
+ },
+ "onRightCheckChange": {
+ "label": {
+ "zh_CN": "右侧列表元素被用户选中 / 取消选中时触发"
+ },
+ "description": {
+ "zh_CN": "右侧列表元素被用户选中 / 取消选中时触发"
+ },
+ "type": "event",
+ "functionInfo": {
+ "params": [
+ {
+ "name": "value",
+ "type": "string",
+ "defaultValue": "",
+ "description": {
+ "zh_CN": "右侧列表元素被用户选中 / 取消选中时触发"
}
- },
- "description": {
- "zh_CN": "加减按钮位置"
}
- },
+ ],
+ "returns": {}
+ },
+ "defaultValue": ""
+ }
+ }
+ },
+ "configure": {
+ "loop": true,
+ "condition": true,
+ "styles": true,
+ "isContainer": false,
+ "isModal": false,
+ "nestingRule": {
+ "childWhitelist": "",
+ "parentWhitelist": "",
+ "descendantBlacklist": "",
+ "ancestorWhitelist": ""
+ },
+ "isNullNode": false,
+ "isLayout": false,
+ "rootSelector": "",
+ "shortcuts": {
+ "properties": ["value", "disabled"]
+ },
+ "contextMenu": {
+ "actions": ["create symbol"],
+ "disable": ["copy", "remove"]
+ }
+ }
+ }
+ ],
+ "blocks": [],
+ "snippets": [
+ {
+ "group": "layout",
+ "label": {
+ "zh_CN": "布局与容器"
+ },
+ "children": [
+ {
+ "name": {
+ "zh_CN": "栅格布局"
+ },
+ "icon": "row",
+ "screenshot": "",
+ "snippetName": "TinyLayout",
+ "schema": {
+ "componentName": "TinyLayout",
+ "props": {},
+ "children": [
{
- "property": "precision",
- "label": {
- "text": {
- "zh_CN": "精度"
- }
+ "componentName": "TinyRow",
+ "props": {
+ "style": "padding: 10px;"
},
- "required": false,
- "readOnly": false,
- "disabled": false,
- "cols": 12,
- "widget": {
- "component": "NumberConfigurator",
- "props": {
- "allowEmpty": true
+ "children": [
+ {
+ "componentName": "TinyCol",
+ "props": {
+ "span": 3
+ }
+ },
+ {
+ "componentName": "TinyCol",
+ "props": {
+ "span": 3
+ }
+ },
+ {
+ "componentName": "TinyCol",
+ "props": {
+ "span": 3
+ }
+ },
+ {
+ "componentName": "TinyCol",
+ "props": {
+ "span": 3
+ }
}
- },
- "description": {
- "zh_CN": "数值精度"
- },
- "labelPosition": "left"
+ ]
},
{
- "property": "step",
- "label": {
- "text": {
- "zh_CN": "步长"
- }
+ "componentName": "TinyRow",
+ "props": {
+ "style": "padding: 10px;"
},
- "required": false,
- "readOnly": false,
- "disabled": false,
- "cols": 12,
- "widget": {
- "component": "NumberConfigurator",
- "props": {
- "allowEmpty": true
+ "children": [
+ {
+ "componentName": "TinyCol",
+ "props": {
+ "span": 3
+ }
+ },
+ {
+ "componentName": "TinyCol",
+ "props": {
+ "span": 3
+ }
+ },
+ {
+ "componentName": "TinyCol",
+ "props": {
+ "span": 3
+ }
+ },
+ {
+ "componentName": "TinyCol",
+ "props": {
+ "span": 3
+ }
}
- },
- "description": {
- "zh_CN": "步长"
- },
- "labelPosition": "left"
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "group": "basic",
+ "label": {
+ "zh_CN": "基础元素"
+ },
+ "children": [
+ {
+ "name": {
+ "zh_CN": "段落"
+ },
+ "icon": "paragraph",
+ "screenshot": "",
+ "snippetName": "p",
+ "schema": {
+ "componentName": "p",
+ "children": "TinyEngine 前端可视化设计器致力于通过友好的用户交互提升业务应用的开发效率。"
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "链接"
+ },
+ "icon": "link",
+ "screenshot": "",
+ "snippetName": "a",
+ "schema": {
+ "componentName": "a",
+ "children": "链接"
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "分隔线"
+ },
+ "icon": "hr",
+ "screenshot": "",
+ "snippetName": "hr",
+ "schema": {}
+ },
+ {
+ "name": {
+ "zh_CN": "标题"
+ },
+ "icon": "h16",
+ "screenshot": "",
+ "snippetName": "h1",
+ "schema": {
+ "componentName": "h1",
+ "props": {},
+ "children": "Heading"
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "视频"
+ },
+ "icon": "video",
+ "screenshot": "",
+ "snippetName": "video",
+ "schema": {
+ "componentName": "video",
+ "props": {
+ "src": "https://tinyengine-assets.obs.myhuaweicloud.com/files/in-action.mp4#t=1.5",
+ "width": "200",
+ "height": "100",
+ "style": "border:1px solid #ccc"
+ }
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "按钮"
+ },
+ "icon": "button",
+ "screenshot": "",
+ "snippetName": "TinyButton",
+ "schema": {
+ "componentName": "TinyButton",
+ "props": {
+ "text": "按钮文案"
+ }
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "按钮组"
+ },
+ "icon": "buttons",
+ "snippetName": "TinyButtons",
+ "screenshot": "",
+ "schema": {
+ "componentName": "div",
+ "props": {},
+ "children": [
+ {
+ "componentName": "TinyButton",
+ "props": {
+ "text": "提交",
+ "type": "primary",
+ "style": "margin: 0 5px 0 5px;"
+ }
},
{
- "property": "max",
- "label": {
- "text": {
- "zh_CN": "最大数值"
- }
- },
- "required": false,
- "readOnly": false,
- "disabled": false,
- "cols": 12,
- "widget": {
- "component": "NumberConfigurator",
- "props": {
- "allowEmpty": true
- }
- },
- "description": {
- "zh_CN": "可输入的最大数值"
- },
- "labelPosition": "left"
+ "componentName": "TinyButton",
+ "props": {
+ "text": "重置",
+ "style": "margin: 0 5px 0 5px;"
+ }
},
{
- "property": "min",
- "label": {
- "text": {
- "zh_CN": "最小数值"
- }
- },
- "required": false,
- "readOnly": false,
- "disabled": false,
- "cols": 12,
- "widget": {
- "component": "NumberConfigurator",
- "props": {
- "allowEmpty": true
- }
- },
- "description": {
- "zh_CN": "可输入的最大数值"
- },
- "labelPosition": "left"
+ "componentName": "TinyButton",
+ "props": {
+ "text": "取消"
+ }
}
]
- }
- ],
- "events": {
- "onChange": {
- "label": {
- "zh_CN": "值改变时触发"
- },
- "description": {
- "zh_CN": "在 Input 值改变时触发"
- },
- "type": "event",
- "functionInfo": {
- "params": [
- {
- "name": "value",
- "type": "string",
- "defaultValue": "",
- "description": {
- "zh_CN": "输入框改变后的值"
- }
- }
- ],
- "returns": {}
- },
- "defaultValue": ""
},
- "onInput": {
- "label": {
- "zh_CN": "输入值改变时触发"
- },
- "description": {
- "zh_CN": "在 Input 输入值改变时触发"
- },
- "type": "event",
- "functionInfo": {
- "params": [
- {
- "name": "value",
- "type": "string",
- "defaultValue": "",
- "description": {
- "zh_CN": "输入框输入的值"
- }
- }
- ],
- "returns": {}
- },
- "defaultValue": ""
+ "configure": {
+ "isContainer": true
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "互斥按钮组"
},
- "onUpdate:modelValue": {
- "label": {
- "zh_CN": "双向绑定的值改变时触发"
- },
- "description": {
- "zh_CN": "在 Input 输入值改变时触发"
- },
- "type": "event",
- "functionInfo": {
- "params": [
+ "icon": "MutexButtons",
+ "snippetName": "TinyButtonGroup",
+ "screenshot": "",
+ "schema": {
+ "componentName": "TinyButtonGroup",
+ "props": {
+ "data": [
{
- "name": "value",
- "type": "string",
- "defaultValue": "",
- "description": {
- "zh_CN": "双向绑定的值"
- }
- }
- ],
- "returns": {}
- },
- "defaultValue": ""
- },
- "onBlur": {
- "label": {
- "zh_CN": "失去焦点时触发"
- },
- "description": {
- "zh_CN": "在 Input 失去焦点时触发"
- },
- "type": "event",
- "functionInfo": {
- "params": [
+ "text": "Button1",
+ "value": "1"
+ },
{
- "name": "event",
- "type": "Object",
- "defaultValue": "",
- "description": {
- "zh_CN": "原生 event"
- }
- }
- ],
- "returns": {}
- },
- "defaultValue": ""
- },
- "onFocus": {
- "label": {
- "zh_CN": "获取焦点时触发"
- },
- "description": {
- "zh_CN": "在 Input 获取焦点时触发"
- },
- "type": "event",
- "functionInfo": {
- "params": [
+ "text": "Button2",
+ "value": "2"
+ },
{
- "name": "event",
- "type": "Object",
- "defaultValue": "",
- "description": {
- "zh_CN": "原生 event"
- }
+ "text": "Button3",
+ "value": "3"
}
],
- "returns": {}
- },
- "defaultValue": ""
- },
- "onClear": {
- "label": {
- "zh_CN": "点击清空按钮时触发"
- },
- "description": {
- "zh_CN": "点击清空按钮时触发"
- },
- "type": "event",
- "functionInfo": {
- "params": [],
- "returns": {}
- },
- "defaultValue": ""
+ "modelValue": "1"
+ }
}
- }
- },
- "configure": {
- "loop": true,
- "condition": true,
- "styles": true,
- "isContainer": true,
- "isModal": false,
- "nestingRule": {
- "childWhitelist": "",
- "parentWhitelist": "",
- "descendantBlacklist": "",
- "ancestorWhitelist": ""
- },
- "isNullNode": false,
- "isLayout": false,
- "rootSelector": "",
- "shortcuts": {
- "properties": ["value", "disabled"]
},
- "contextMenu": {
- "actions": ["create symbol"],
- "disable": ["copy", "remove"]
- }
- }
- },
- {
- "version": "3.20.0",
- "name": {
- "zh_CN": "穿梭框"
- },
- "component": "TinyTransfer",
- "icon": "transfer",
- "description": "穿梭框,实现左右表格数据的双向交换的组件",
- "docUrl": "",
- "screenshot": "",
- "tags": "",
- "keywords": "",
- "devMode": "proCode",
- "npm": {
- "package": "@opentiny/vue",
- "exportName": "TinyTransfer",
- "destructuring": true
+ {
+ "name": {
+ "zh_CN": "搜索框"
+ },
+ "icon": "search",
+ "screenshot": "",
+ "snippetName": "TinySearch",
+ "schema": {
+ "componentName": "TinySearch",
+ "props": {
+ "modelValue": "",
+ "placeholder": "输入关键词"
+ }
+ }
+ }
+ ]
+ },
+ {
+ "group": "form",
+ "label": {
+ "zh_CN": "表单类型"
},
- "group": "component",
- "priority": 1,
- "schema": {
- "properties": [
- {
- "label": {
- "zh_CN": "基础信息"
- },
- "description": {
- "zh_CN": "基础信息"
+ "children": [
+ {
+ "name": {
+ "zh_CN": "表单"
+ },
+ "screenshot": "",
+ "snippetName": "TinyForm",
+ "icon": "form",
+ "schema": {
+ "componentName": "TinyForm",
+ "props": {
+ "labelWidth": "80px",
+ "labelPosition": "top"
},
- "content": [
- {
- "property": "modelValue",
- "label": {
- "text": {
- "zh_CN": "绑定值"
- }
- },
- "required": true,
- "readOnly": false,
- "disabled": false,
- "widget": {
- "component": "I18nConfigurator",
- "props": {}
- },
- "description": {
- "zh_CN": "双向绑定值"
- },
- "labelPosition": "left"
- },
+ "children": [
{
- "property": "data",
- "label": {
- "text": {
- "zh_CN": "左右列表的全量数据源"
- }
+ "componentName": "TinyFormItem",
+ "props": {
+ "label": "人员"
},
- "required": true,
- "readOnly": false,
- "disabled": false,
- "widget": {
- "component": "CodeConfigurator",
- "props": {
- "language": "json"
+ "children": [
+ {
+ "componentName": "TinyInput",
+ "props": {
+ "placeholder": "请输入",
+ "modelValue": ""
+ }
}
- },
- "description": {
- "zh_CN": "左右列表的全量数据源"
- },
- "labelPosition": "left"
+ ]
},
{
- "property": "filterable",
- "label": {
- "text": {
- "zh_CN": "是否启用搜索的功能"
- }
- },
- "required": false,
- "readOnly": false,
- "disabled": false,
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- },
- "description": {
- "zh_CN": "是否启用搜索的功能"
+ "componentName": "TinyFormItem",
+ "props": {
+ "label": "密码"
},
- "labelPosition": "left"
- },
- {
- "property": "showAllBtn",
- "label": {
- "text": {
- "zh_CN": "是否显示全部移动按钮"
+ "children": [
+ {
+ "componentName": "TinyInput",
+ "props": {
+ "placeholder": "请输入",
+ "modelValue": "",
+ "type": "password"
+ }
}
- },
- "required": false,
- "readOnly": false,
- "disabled": false,
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- },
- "description": {
- "zh_CN": "是否显示全部移动按钮"
- },
- "labelPosition": "left"
+ ]
},
{
- "property": "toLeftDisable",
- "label": {
- "text": {
- "zh_CN": "组件初始化状态下未选中时,默认按钮显示禁用状态"
- }
- },
- "required": false,
- "readOnly": false,
- "disabled": false,
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
- },
- "description": {
- "zh_CN": "组件初始化状态下未选中时,默认按钮显示禁用状态"
+ "componentName": "TinyFormItem",
+ "props": {
+ "label": ""
},
- "labelPosition": "left"
- },
- {
- "property": "toRightDisable",
- "label": {
- "text": {
- "zh_CN": "组件初始化状态下未选中时,默认按钮显示禁用状态"
+ "children": [
+ {
+ "componentName": "TinyButton",
+ "props": {
+ "text": "提交",
+ "type": "primary",
+ "style": "margin-right: 10px"
+ }
+ },
+ {
+ "componentName": "TinyButton",
+ "props": {
+ "text": "重置",
+ "type": "primary"
+ }
}
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "下拉框"
+ },
+ "icon": "select",
+ "screenshot": "",
+ "snippetName": "TinySelect",
+ "schema": {
+ "componentName": "TinySelect",
+ "props": {
+ "modelValue": "",
+ "placeholder": "请选择",
+ "options": [
+ {
+ "value": "1",
+ "label": "黄金糕"
},
- "required": false,
- "readOnly": false,
- "disabled": false,
- "widget": {
- "component": "CheckBoxConfigurator",
- "props": {}
+ {
+ "value": "2",
+ "label": "双皮奶"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "开关"
+ },
+ "icon": "switch",
+ "screenshot": "",
+ "snippetName": "TinySwitch",
+ "schema": {
+ "componentName": "TinySwitch",
+ "props": {
+ "modelValue": ""
+ }
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "复选框组"
+ },
+ "icon": "checkboxs",
+ "screenshot": "",
+ "snippetName": "TinyCheckboxGroup",
+ "schema": {
+ "componentName": "TinyCheckboxGroup",
+ "props": {
+ "modelValue": ["name1", "name2"],
+ "type": "checkbox",
+ "options": [
+ {
+ "text": "复选框1",
+ "label": "name1"
},
- "description": {
- "zh_CN": "组件初始化状态下未选中时,默认按钮显示禁用状态"
+ {
+ "text": "复选框2",
+ "label": "name2"
},
- "labelPosition": "left"
- },
+ {
+ "text": "复选框3",
+ "label": "name3"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "复选框拖拽按钮组"
+ },
+ "icon": "checkboxgroup",
+ "screenshot": "",
+ "snippetName": "TinyCheckboxbuttonGroup",
+ "schema": {
+ "componentName": "TinyCheckboxGroup",
+ "props": {
+ "modelValue": []
+ },
+ "children": [
{
- "property": "titles",
- "label": {
- "text": {
- "zh_CN": "自定义列表的标题"
- }
- },
- "required": false,
- "readOnly": false,
- "disabled": false,
- "widget": {
- "component": "CodeConfigurator",
- "props": {
- "language": "json"
+ "componentName": "TinyCheckboxButton",
+ "children": [
+ {
+ "componentName": "div"
}
- },
- "description": {
- "zh_CN": "自定义列表的标题;不设置titles时,左右列表的标题默认显示为: 列表 1, 列表 2"
- },
- "labelPosition": "left"
+ ]
}
]
}
- ],
- "events": {
- "onChange": {
- "label": {
- "zh_CN": "右侧列表元素变化时触发"
- },
- "description": {
- "zh_CN": "右侧列表元素变化时触发"
- },
- "type": "event",
- "functionInfo": {
- "params": [
- {
- "name": "value",
- "type": "string",
- "defaultValue": "",
- "description": {
- "zh_CN": "右侧列表元素变化时触发"
- }
- }
- ],
- "returns": {}
- },
- "defaultValue": ""
+ },
+ {
+ "name": {
+ "zh_CN": "输入框"
},
- "onLeftCheckChange": {
- "label": {
- "zh_CN": "左侧列表元素被用户选中 / 取消选中时触发;"
- },
- "description": {
- "zh_CN": "左侧列表元素被用户选中 / 取消选中时触发;"
- },
- "type": "event",
- "functionInfo": {
- "params": [
- {
- "name": "value",
- "type": "string",
- "defaultValue": "",
- "description": {
- "zh_CN": "左侧列表元素被用户选中 / 取消选中时触发;"
- }
- }
- ],
- "returns": {}
- },
- "defaultValue": ""
+ "icon": "input",
+ "screenshot": "",
+ "snippetName": "TinyInput",
+ "schema": {
+ "componentName": "TinyInput",
+ "props": {
+ "placeholder": "请输入",
+ "modelValue": ""
+ }
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "单选"
},
- "onRightCheckChange": {
- "label": {
- "zh_CN": "右侧列表元素被用户选中 / 取消选中时触发"
- },
- "description": {
- "zh_CN": "右侧列表元素被用户选中 / 取消选中时触发"
- },
- "type": "event",
- "functionInfo": {
- "params": [
+ "icon": "radio",
+ "screenshot": "",
+ "snippetName": "TinyRadio",
+ "schema": {
+ "componentName": "TinyRadio",
+ "props": {
+ "label": "1",
+ "text": "单选文本"
+ }
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "单选组"
+ },
+ "icon": "radiogroup",
+ "screenshot": "",
+ "snippetName": "TinyRadioGroup",
+ "schema": {
+ "props": {
+ "type": "radio",
+ "modelValue": "1",
+ "options": [
+ { "label": "1", "text": "选项一" },
+ { "label": "2", "text": "选项二" }
+ ]
+ }
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "复选框"
+ },
+ "icon": "checkbox",
+ "screenshot": "",
+ "snippetName": "TinyCheckbox",
+ "schema": {
+ "componentName": "TinyCheckbox",
+ "props": {
+ "text": "复选框文案"
+ }
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "日期选择"
+ },
+ "icon": "datepick",
+ "screenshot": "",
+ "snippetName": "TinyDatePicker",
+ "schema": {
+ "componentName": "TinyDatePicker",
+ "props": {
+ "placeholder": "请输入",
+ "modelValue": ""
+ }
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "数字输入框"
+ },
+ "icon": "numeric",
+ "screenshot": "",
+ "snippetName": "TinyNumeric",
+ "schema": {
+ "componentName": "TinyNumeric",
+ "props": {
+ "allow-empty": true,
+ "placeholder": "请输入",
+ "controls-position": "right",
+ "step": 1
+ }
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "穿梭框"
+ },
+ "icon": "transfer",
+ "screenshot": "",
+ "snippetName": "TinyTransfer",
+ "schema": {
+ "componentName": "TinyTransfer",
+ "props": {
+ "modelValue": [3],
+ "data": [
{
- "name": "value",
- "type": "string",
- "defaultValue": "",
- "description": {
- "zh_CN": "右侧列表元素被用户选中 / 取消选中时触发"
- }
+ "key": 1,
+ "label": "备选项1",
+ "disabled": false
+ },
+ {
+ "key": 2,
+ "label": "备选项2",
+ "disabled": false
+ },
+ {
+ "key": 3,
+ "label": "备选项3",
+ "disabled": false
+ },
+ {
+ "key": 4,
+ "label": "备选项4",
+ "disabled": false
}
- ],
- "returns": {}
- },
- "defaultValue": ""
+ ]
+ }
}
- }
- },
- "configure": {
- "loop": true,
- "condition": true,
- "styles": true,
- "isContainer": false,
- "isModal": false,
- "nestingRule": {
- "childWhitelist": "",
- "parentWhitelist": "",
- "descendantBlacklist": "",
- "ancestorWhitelist": ""
},
- "isNullNode": false,
- "isLayout": false,
- "rootSelector": "",
- "shortcuts": {
- "properties": ["value", "disabled"]
+ {
+ "icon": "rate",
+ "name": {
+ "zh_CN": "评分"
+ },
+ "schema": {
+ "props": {
+ "allow-half": true,
+ "modelValue": 3,
+ "show-score": true
+ }
+ },
+ "screenshot": "",
+ "snippetName": "TinyRate"
+ },
+ {
+ "name": {
+ "zh_CN": "滑块"
+ },
+ "icon": "slider",
+ "screenshot": "",
+ "snippetName": "TinySlider",
+ "schema": {
+ "componentName": "TinySlider",
+ "props": {
+ "max": 100,
+ "min": 0,
+ "step": 1,
+ "modelValue": 50
+ }
+ }
},
- "contextMenu": {
- "actions": ["create symbol"],
- "disable": ["copy", "remove"]
- }
- }
- }
- ],
- "blocks": [],
- "snippets": [
- {
- "group": "layout",
- "label": {
- "zh_CN": "布局与容器"
- },
- "children": [
{
"name": {
- "zh_CN": "栅格布局"
+ "zh_CN": "级联选择器"
},
- "icon": "row",
+ "icon": "cascader",
"screenshot": "",
- "snippetName": "TinyLayout",
+ "snippetName": "TinyCascader",
"schema": {
- "componentName": "TinyLayout",
- "props": {},
- "children": [
- {
- "componentName": "TinyRow",
- "props": {
- "style": "padding: 10px;"
- },
- "children": [
- {
- "componentName": "TinyCol",
- "props": {
- "span": 3
- }
- },
- {
- "componentName": "TinyCol",
- "props": {
- "span": 3
- }
- },
- {
- "componentName": "TinyCol",
- "props": {
- "span": 3
- }
- },
- {
- "componentName": "TinyCol",
- "props": {
- "span": 3
+ "componentName": "TinyCascader",
+ "props": {
+ "modelValue": "anzhuangcli",
+ "options": [
+ {
+ "value": "zhinan",
+ "label": "指南",
+ "children": [
+ {
+ "value": "anzhuang",
+ "label": "安装",
+ "children": [
+ {
+ "value": "xiangmudengji",
+ "label": "项目登记"
+ },
+ {
+ "value": "huanjingzhunbei",
+ "label": "环境准备"
+ },
+ {
+ "value": "anzhuangcli",
+ "label": "安装 CLI"
+ },
+ {
+ "value": "chuangjianxiangmu",
+ "label": "创建项目"
+ }
+ ]
+ },
+ {
+ "value": "kaifa",
+ "label": "开发",
+ "children": [
+ {
+ "value": "yinruzujian",
+ "label": "引入组件"
+ },
+ {
+ "value": "monishuju",
+ "label": "模拟数据"
+ }
+ ]
}
- }
- ]
- },
- {
- "componentName": "TinyRow",
- "props": {
- "style": "padding: 10px;"
+ ]
},
- "children": [
- {
- "componentName": "TinyCol",
- "props": {
- "span": 3
- }
- },
- {
- "componentName": "TinyCol",
- "props": {
- "span": 3
- }
- },
- {
- "componentName": "TinyCol",
- "props": {
- "span": 3
- }
- },
- {
- "componentName": "TinyCol",
- "props": {
- "span": 3
+ {
+ "value": "zujian",
+ "label": "组件",
+ "children": [
+ {
+ "value": "basic",
+ "label": "框架风格",
+ "children": [
+ {
+ "value": "layout",
+ "label": "Layout 布局"
+ },
+ {
+ "value": "color",
+ "label": "Color 色彩"
+ },
+ {
+ "value": "font",
+ "label": "Font 字体"
+ },
+ {
+ "value": "icon",
+ "label": "Icon 图标"
+ }
+ ]
+ },
+ {
+ "value": "data",
+ "label": "数据组件",
+ "children": [
+ {
+ "value": "tree",
+ "label": "Tree 树形控件"
+ },
+ {
+ "value": "pager",
+ "label": "Pager 分页"
+ }
+ ]
}
- }
- ]
- }
- ]
+ ]
+ }
+ ],
+ "placeholder": "请选择"
+ }
}
}
]
},
{
- "group": "basic",
+ "group": "table",
"label": {
- "zh_CN": "基础元素"
+ "zh_CN": "表格类型"
},
"children": [
{
"name": {
- "zh_CN": "段落"
- },
- "icon": "paragraph",
- "screenshot": "",
- "snippetName": "p",
- "schema": {
- "componentName": "p",
- "children": "TinyEngine 前端可视化设计器致力于通过友好的用户交互提升业务应用的开发效率。"
- }
- },
- {
- "name": {
- "zh_CN": "链接"
+ "zh_CN": "表格"
},
- "icon": "link",
+ "icon": "grid",
"screenshot": "",
- "snippetName": "a",
+ "snippetName": "TinyGrid",
"schema": {
- "componentName": "a",
- "children": "链接"
+ "componentName": "TinyGrid",
+ "props": {
+ "editConfig": {
+ "trigger": "click",
+ "mode": "cell",
+ "showStatus": true
+ },
+ "columns": [
+ {
+ "type": "index",
+ "width": 60
+ },
+ {
+ "type": "selection",
+ "width": 60
+ },
+ {
+ "field": "employees",
+ "title": "员工数"
+ },
+ {
+ "field": "created_date",
+ "title": "创建日期"
+ },
+ {
+ "field": "city",
+ "title": "城市"
+ }
+ ],
+ "data": [
+ {
+ "id": "1",
+ "name": "GFD科技有限公司",
+ "city": "福州",
+ "employees": 800,
+ "created_date": "2014-04-30 00:56:00",
+ "boole": false
+ },
+ {
+ "id": "2",
+ "name": "WWW科技有限公司",
+ "city": "深圳",
+ "employees": 300,
+ "created_date": "2016-07-08 12:36:22",
+ "boole": true
+ }
+ ]
+ }
}
},
{
"name": {
- "zh_CN": "分隔线"
- },
- "icon": "hr",
- "screenshot": "",
- "snippetName": "hr",
- "schema": {}
- },
- {
- "name": {
- "zh_CN": "标题"
+ "zh_CN": "分页"
},
- "icon": "h16",
+ "icon": "pager",
"screenshot": "",
- "snippetName": "h1",
+ "snippetName": "TinyPager",
"schema": {
- "componentName": "h1",
- "props": {},
- "children": "Heading"
+ "componentName": "TinyPager",
+ "props": {
+ "layout": "total, sizes, prev, pager, next",
+ "total": 100,
+ "pageSize": 10,
+ "currentPage": 1
+ }
}
- },
+ }
+ ]
+ },
+ {
+ "group": "data-display",
+ "label": {
+ "zh_CN": "数据展示类"
+ },
+ "children": [
{
"name": {
- "zh_CN": "视频"
+ "zh_CN": "走马灯"
},
- "icon": "video",
"screenshot": "",
- "snippetName": "video",
+ "snippetName": "TinyCarousel",
+ "icon": "carousel",
"schema": {
- "componentName": "video",
+ "componentName": "TinyCarousel",
"props": {
- "src": "https://tinyengine-assets.obs.myhuaweicloud.com/files/in-action.mp4#t=1.5",
- "width": "200",
- "height": "100",
- "style": "border:1px solid #ccc"
- }
+ "height": "180px"
+ },
+ "children": [
+ {
+ "componentName": "TinyCarouselItem",
+ "props": {
+ "title": "carousel-item-a"
+ },
+ "children": [
+ {
+ "componentName": "div",
+ "props": {
+ "style": "margin:10px 0 0 30px"
+ }
+ }
+ ]
+ },
+ {
+ "componentName": "TinyCarouselItem",
+ "props": {
+ "title": "carousel-item-b"
+ },
+ "children": [
+ {
+ "componentName": "div",
+ "props": {
+ "style": "margin:10px 0 0 30px"
+ }
+ }
+ ]
+ }
+ ]
}
},
{
"name": {
- "zh_CN": "按钮"
+ "zh_CN": "对话框"
},
- "icon": "button",
"screenshot": "",
- "snippetName": "TinyButton",
+ "snippetName": "TinyDialogBox",
+ "icon": "dialogbox",
"schema": {
- "componentName": "TinyButton",
+ "componentName": "TinyDialogBox",
"props": {
- "text": "按钮文案"
- }
+ "visible": true,
+ "show-close": true,
+ "title": "dialogBox title"
+ },
+ "children": [
+ {
+ "componentName": "div"
+ }
+ ]
}
},
{
"name": {
- "zh_CN": "按钮组"
+ "zh_CN": "折叠面板"
},
- "icon": "buttons",
- "snippetName": "TinyButtons",
"screenshot": "",
+ "snippetName": "TinyCollapse",
+ "icon": "collapse",
"schema": {
- "componentName": "div",
- "props": {},
+ "componentName": "TinyCollapse",
+ "props": {
+ "modelValue": "collapse1"
+ },
"children": [
{
- "componentName": "TinyButton",
+ "componentName": "TinyCollapseItem",
"props": {
- "text": "提交",
- "type": "primary",
- "style": "margin: 0 5px 0 5px;"
- }
+ "name": "collapse1",
+ "title": "折叠项1"
+ },
+ "children": [
+ {
+ "componentName": "div"
+ }
+ ]
},
{
- "componentName": "TinyButton",
+ "componentName": "TinyCollapseItem",
"props": {
- "text": "重置",
- "style": "margin: 0 5px 0 5px;"
- }
+ "name": "collapse2",
+ "title": "折叠项2"
+ },
+ "children": [
+ {
+ "componentName": "div"
+ }
+ ]
},
{
- "componentName": "TinyButton",
+ "componentName": "TinyCollapseItem",
"props": {
- "text": "取消"
- }
+ "name": "collapse3",
+ "title": "折叠项3"
+ },
+ "children": [
+ {
+ "componentName": "div"
+ }
+ ]
}
]
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "弹出编辑"
},
- "configure": {
- "isContainer": true
+ "icon": "popeditor",
+ "screenshot": "",
+ "snippetName": "TinyPopeditor",
+ "schema": {
+ "componentName": "TinyPopeditor",
+ "props": {
+ "modelValue": "",
+ "placeholder": "请选择",
+ "grid-op": {
+ "columns": [
+ {
+ "field": "id",
+ "title": "ID",
+ "width": 40
+ },
+ {
+ "field": "name",
+ "title": "名称",
+ "showOverflow": "tooltip"
+ },
+ {
+ "field": "province",
+ "title": "省份",
+ "width": 80
+ },
+ {
+ "field": "city",
+ "title": "城市",
+ "width": 80
+ }
+ ],
+ "data": [
+ {
+ "id": "1",
+ "name": "GFD科技有限公司GFD科技有限公司GFD科技有限公司GFD科技有限公司GFD科技有限公司GFD科技有限公司GFD科技有限公司",
+ "city": "福州",
+ "province": "福建"
+ },
+ {
+ "id": "2",
+ "name": "WWW科技有限公司",
+ "city": "深圳",
+ "province": "广东"
+ },
+ {
+ "id": "3",
+ "name": "RFV有限责任公司",
+ "city": "中山",
+ "province": "广东"
+ },
+ {
+ "id": "4",
+ "name": "TGB科技有限公司",
+ "city": "龙岩",
+ "province": "福建"
+ },
+ {
+ "id": "5",
+ "name": "YHN科技有限公司",
+ "city": "韶关",
+ "province": "广东"
+ },
+ {
+ "id": "6",
+ "name": "WSX科技有限公司",
+ "city": "黄冈",
+ "province": "武汉"
+ }
+ ]
+ }
+ }
}
},
{
"name": {
- "zh_CN": "互斥按钮组"
+ "zh_CN": "树"
},
- "icon": "MutexButtons",
- "snippetName": "TinyButtonGroup",
+ "icon": "tree",
"screenshot": "",
+ "snippetName": "TinyTree",
"schema": {
- "componentName": "TinyButtonGroup",
+ "componentName": "TinyTree",
"props": {
"data": [
{
- "text": "Button1",
- "value": "1"
- },
- {
- "text": "Button2",
- "value": "2"
+ "label": "一级 1",
+ "children": [
+ {
+ "label": "二级 1-1",
+ "children": [
+ {
+ "label": "三级 1-1-1"
+ }
+ ]
+ }
+ ]
},
{
- "text": "Button3",
- "value": "3"
+ "label": "一级 2",
+ "children": [
+ {
+ "label": "二级 2-1",
+ "children": [
+ {
+ "label": "三级 2-1-1"
+ }
+ ]
+ },
+ {
+ "label": "二级 2-2",
+ "children": [
+ {
+ "label": "三级 2-2-1"
+ }
+ ]
+ }
+ ]
}
- ],
- "modelValue": "1"
+ ]
}
}
},
{
"name": {
- "zh_CN": "搜索框"
+ "zh_CN": "文字提示框"
},
- "icon": "search",
+ "icon": "tooltip",
"screenshot": "",
- "snippetName": "TinySearch",
+ "snippetName": "TinyTooltip",
"schema": {
- "componentName": "TinySearch",
+ "componentName": "TinyTooltip",
"props": {
- "modelValue": "",
- "placeholder": "输入关键词"
- }
+ "content": "Top Left 提示文字",
+ "placement": "top-start",
+ "manual": true,
+ "modelValue": true
+ },
+ "children": [
+ {
+ "componentName": "span",
+ "children": [
+ {
+ "componentName": "div",
+ "props": {}
+ }
+ ]
+ },
+ {
+ "componentName": "Template",
+ "props": {
+ "slot": "content"
+ },
+ "children": [
+ {
+ "componentName": "span",
+ "children": [
+ {
+ "componentName": "div",
+ "props": {
+ "placeholder": "提示内容"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
}
- }
- ]
- },
- {
- "group": "form",
- "label": {
- "zh_CN": "表单类型"
- },
- "children": [
+ },
{
"name": {
- "zh_CN": "表单"
+ "zh_CN": "提示框"
},
+ "icon": "popover",
"screenshot": "",
- "snippetName": "tiny-form",
- "icon": "form",
+ "snippetName": "TinyPopover",
"schema": {
- "componentName": "TinyForm",
+ "componentName": "TinyPopover",
"props": {
- "labelWidth": "80px",
- "labelPosition": "top"
+ "width": 200,
+ "title": "弹框标题",
+ "trigger": "manual",
+ "modelValue": true
},
"children": [
{
- "componentName": "TinyFormItem",
- "props": {
- "label": "人员"
- },
- "children": [
- {
- "componentName": "TinyInput",
- "props": {
- "placeholder": "请输入",
- "modelValue": ""
- }
- }
- ]
- },
- {
- "componentName": "TinyFormItem",
+ "componentName": "Template",
"props": {
- "label": "密码"
+ "slot": "reference"
},
"children": [
{
- "componentName": "TinyInput",
+ "componentName": "div",
"props": {
- "placeholder": "请输入",
- "modelValue": "",
- "type": "password"
+ "placeholder": "触发源"
}
}
]
},
{
- "componentName": "TinyFormItem",
+ "componentName": "Template",
"props": {
- "label": ""
+ "slot": "default"
},
"children": [
{
- "componentName": "TinyButton",
- "props": {
- "text": "提交",
- "type": "primary",
- "style": "margin-right: 10px"
- }
- },
- {
- "componentName": "TinyButton",
+ "componentName": "div",
"props": {
- "text": "重置",
- "type": "primary"
+ "placeholder": "提示内容"
}
}
]
@@ -14002,269 +21663,155 @@
},
{
"name": {
- "zh_CN": "下拉框"
- },
- "icon": "select",
- "screenshot": "",
- "snippetName": "TinySelect",
- "schema": {
- "componentName": "TinySelect",
- "props": {
- "modelValue": "",
- "placeholder": "请选择",
- "options": [
- {
- "value": "1",
- "label": "黄金糕"
- },
- {
- "value": "2",
- "label": "双皮奶"
- }
- ]
- }
- }
- },
- {
- "name": {
- "zh_CN": "开关"
- },
- "icon": "switch",
- "screenshot": "",
- "snippetName": "TinySwitch",
- "schema": {
- "componentName": "TinySwitch",
- "props": {
- "modelValue": ""
- }
- }
- },
- {
- "name": {
- "zh_CN": "复选框组"
+ "zh_CN": "骨架屏"
},
- "icon": "checkboxs",
+ "icon": "skeleton",
"screenshot": "",
- "snippetName": "TinyCheckboxGroup",
+ "snippetName": "TinySkeleton",
"schema": {
- "componentName": "TinyCheckboxGroup",
+ "componentName": "TinySkeleton",
"props": {
- "modelValue": ["name1", "name2"],
- "type": "checkbox",
- "options": [
- {
- "text": "复选框1",
- "label": "name1"
- },
- {
- "text": "复选框2",
- "label": "name2"
+ "rows": 3,
+ "loading": true,
+ "animated": true
+ },
+ "children": [
+ {
+ "props": {
+ "text": "实际内容"
},
- {
- "text": "复选框3",
- "label": "name3"
- }
- ]
- }
+ "componentName": "Text"
+ }
+ ]
}
},
{
"name": {
- "zh_CN": "复选框拖拽按钮组"
+ "zh_CN": "卡片"
},
- "icon": "checkboxgroup",
+ "icon": "card",
"screenshot": "",
- "snippetName": "TinyCheckboxbuttonGroup",
+ "snippetName": "TinyCard",
"schema": {
- "componentName": "TinyCheckboxGroup",
+ "componentName": "TinyCard",
"props": {
- "modelValue": []
+ "type": "text",
+ "title": "卡片标题"
},
"children": [
{
- "componentName": "TinyCheckboxButton",
- "children": [
- {
- "componentName": "div"
- }
- ]
+ "props": {
+ "text": "这是一个文本卡片的示例内容。"
+ },
+ "componentName": "Text"
}
]
}
},
{
"name": {
- "zh_CN": "输入框"
- },
- "icon": "input",
- "screenshot": "",
- "snippetName": "TinyInput",
- "schema": {
- "componentName": "TinyInput",
- "props": {
- "placeholder": "请输入",
- "modelValue": ""
- }
- }
- },
- {
- "name": {
- "zh_CN": "单选"
+ "zh_CN": "日历"
},
- "icon": "radio",
+ "icon": "calendar",
"screenshot": "",
- "snippetName": "TinyRadio",
+ "snippetName": "TinyCalendar",
"schema": {
- "componentName": "TinyRadio",
+ "componentName": "TinyCalendar",
"props": {
- "label": "1",
- "text": "单选文本"
+ "mode": "month",
+ "show-selected": false
}
}
},
{
"name": {
- "zh_CN": "复选框"
+ "zh_CN": "进度条"
},
- "icon": "checkbox",
+ "icon": "progress",
"screenshot": "",
- "snippetName": "TinyCheckbox",
+ "snippetName": "TinyProgress",
"schema": {
- "componentName": "TinyCheckbox",
+ "componentName": "TinyProgress",
"props": {
- "text": "复选框文案"
+ "type": "line",
+ "status": "success",
+ "percentage": 50
}
}
},
{
"name": {
- "zh_CN": "日期选择"
+ "zh_CN": "标记"
},
- "icon": "datepick",
+ "icon": "badge",
"screenshot": "",
- "snippetName": "TinyDatePicker",
+ "snippetName": "TinyBadge",
"schema": {
- "componentName": "TinyDatePicker",
+ "componentName": "TinyBadge",
"props": {
- "placeholder": "请输入",
- "modelValue": ""
+ "value": 10,
+ "data": "我的待办"
}
}
},
{
"name": {
- "zh_CN": "数字输入框"
+ "zh_CN": "标签"
},
- "icon": "numeric",
+ "icon": "tag",
"screenshot": "",
- "snippetName": "TinyNumeric",
+ "snippetName": "TinyTag",
"schema": {
- "componentName": "TinyNumeric",
+ "componentName": "TinyTag",
"props": {
- "allow-empty": true,
- "placeholder": "请输入",
- "controls-position": "right",
- "step": 1
+ "type": "success",
+ "value": "成功"
}
}
},
{
"name": {
- "zh_CN": "穿梭框"
+ "zh_CN": "统计数值"
},
- "icon": "transfer",
+ "icon": "statistic",
"screenshot": "",
- "snippetName": "TinyTransfer",
+ "snippetName": "TinyStatistic",
"schema": {
- "componentName": "TinyTransfer",
+ "componentName": "TinyStatistic",
"props": {
- "modelValue": [3],
- "data": [
- {
- "key": 1,
- "label": "备选项1",
- "disabled": false
- },
- {
- "key": 2,
- "label": "备选项2",
- "disabled": false
- },
- {
- "key": 3,
- "label": "备选项3",
- "disabled": false
- },
- {
- "key": 4,
- "label": "备选项4",
- "disabled": false
- }
- ]
+ "value": 36256.22,
+ "precision": 2
}
}
}
]
},
{
- "group": "table",
+ "group": "navigation",
"label": {
- "zh_CN": "表格类型"
+ "zh_CN": "导航类型"
},
"children": [
{
"name": {
- "zh_CN": "表格"
+ "zh_CN": "时间线"
},
- "icon": "grid",
+ "icon": "timeline",
"screenshot": "",
- "snippetName": "tinyGrid",
+ "snippetName": "TinyTimeLine",
"schema": {
- "componentName": "TinyGrid",
+ "componentName": "TinyTimeLine",
"props": {
- "editConfig": {
- "trigger": "click",
- "mode": "cell",
- "showStatus": true
- },
- "columns": [
- {
- "type": "index",
- "width": 60
- },
- {
- "type": "selection",
- "width": 60
- },
- {
- "field": "employees",
- "title": "员工数"
- },
+ "active": "2",
+ "data": [
{
- "field": "created_date",
- "title": "创建日期"
+ "name": "已下单"
},
{
- "field": "city",
- "title": "城市"
- }
- ],
- "data": [
- {
- "id": "1",
- "name": "GFD科技有限公司",
- "city": "福州",
- "employees": 800,
- "created_date": "2014-04-30 00:56:00",
- "boole": false
+ "name": "运输中"
},
{
- "id": "2",
- "name": "WWW科技有限公司",
- "city": "深圳",
- "employees": 300,
- "created_date": "2016-07-08 12:36:22",
- "boole": true
+ "name": "已签收"
}
]
}
@@ -14272,46 +21819,50 @@
},
{
"name": {
- "zh_CN": "分页"
+ "zh_CN": "面包屑"
},
- "icon": "pager",
+ "icon": "breadcrumb",
"screenshot": "",
- "snippetName": "TinyPager",
+ "snippetName": "TinyBreadcrumb",
"schema": {
- "componentName": "TinyPager",
+ "componentName": "TinyBreadcrumb",
"props": {
- "layout": "total, sizes, prev, pager, next",
- "total": 100,
- "pageSize": 10,
- "currentPage": 1
+ "options": [
+ {
+ "to": "{ path: '/' }",
+ "label": "首页"
+ },
+ {
+ "to": "{ path: '/breadcrumb' }",
+ "label": "产品"
+ },
+ {
+ "replace": "true",
+ "label": "软件"
+ }
+ ]
}
}
- }
- ]
- },
- {
- "group": "data-display",
- "label": {
- "zh_CN": "数据展示类"
- },
- "children": [
+ },
{
"name": {
- "zh_CN": "走马灯"
+ "zh_CN": "标签页"
},
+ "icon": "tabs",
"screenshot": "",
- "snippetName": "tiny-carousel",
- "icon": "carousel",
+ "group": true,
+ "snippetName": "TinyTabs",
"schema": {
- "componentName": "TinyCarousel",
+ "componentName": "TinyTabs",
"props": {
- "height": "180px"
+ "modelValue": "first"
},
"children": [
{
- "componentName": "TinyCarouselItem",
+ "componentName": "TinyTabItem",
"props": {
- "title": "carousel-item-a"
+ "title": "标签页1",
+ "name": "first"
},
"children": [
{
@@ -14323,9 +21874,10 @@
]
},
{
- "componentName": "TinyCarouselItem",
+ "componentName": "TinyTabItem",
"props": {
- "title": "carousel-item-b"
+ "title": "标签页2",
+ "name": "second"
},
"children": [
{
@@ -14341,402 +21893,602 @@
},
{
"name": {
- "zh_CN": "对话框"
+ "zh_CN": "步骤条"
},
+ "icon": "steps",
"screenshot": "",
- "snippetName": "TinyDialogBox",
- "icon": "dialogbox",
+ "snippetName": "TinySteps",
"schema": {
- "componentName": "TinyDialogBox",
+ "componentName": "TinySteps",
"props": {
- "visible": true,
- "show-close": true,
- "title": "dialogBox title"
- },
- "children": [
- {
- "componentName": "div"
- }
- ]
+ "data": [
+ {
+ "name": "步骤一",
+ "status": "wait"
+ },
+ {
+ "name": "步骤二",
+ "status": "process"
+ },
+ {
+ "name": "步骤三",
+ "status": "finish"
+ }
+ ],
+ "active": 1
+ }
}
},
{
"name": {
- "zh_CN": "折叠面板"
+ "zh_CN": "树形菜单"
},
+ "icon": "treemenu",
"screenshot": "",
- "snippetName": "TinyCollapse",
- "icon": "collapse",
+ "snippetName": "TinyTreeMenu",
"schema": {
- "componentName": "TinyCollapse",
+ "componentName": "TinyTreeMenu",
"props": {
- "modelValue": "collapse1"
- },
- "children": [
- {
- "componentName": "TinyCollapseItem",
- "props": {
- "name": "collapse1",
- "title": "折叠项1"
+ "data": [
+ {
+ "id": 1,
+ "label": "一级节点1",
+ "children": [
+ {
+ "id": 2,
+ "label": "二级节点1-1"
+ },
+ {
+ "id": 3,
+ "label": "二级节点1-2"
+ }
+ ]
},
- "children": [
- {
- "componentName": "div"
- }
- ]
- },
- {
- "componentName": "TinyCollapseItem",
- "props": {
- "name": "collapse2",
- "title": "折叠项2"
+ {
+ "id": 4,
+ "label": "一级节点2"
+ }
+ ],
+ "placeholder": "输入关键字搜索",
+ "node-key": "id"
+ }
+ }
+ }
+ ]
+ },
+ {
+ "group": "chart",
+ "label": {
+ "zh_CN": "图表类型"
+ },
+ "children": [
+ {
+ "name": {
+ "zh_CN": "折线图"
+ },
+ "icon": "line",
+ "screenshot": "",
+ "snippetName": "TinyHuichartsLine",
+ "schema": {
+ "componentName": "TinyHuichartsLine",
+ "props": {
+ "options": {
+ "theme": "hdesign-light",
+ "padding": [50, 30, 50, 20],
+ "legend": {
+ "show": true,
+ "icon": "line"
},
- "children": [
+ "data": [
{
- "componentName": "div"
- }
- ]
- },
- {
- "componentName": "TinyCollapseItem",
- "props": {
- "name": "collapse3",
- "title": "折叠项3"
- },
- "children": [
+ "Month": "Jan",
+ "Domestics": 33,
+ "Abroad": 37
+ },
{
- "componentName": "div"
+ "Month": "Feb",
+ "Domestics": 27,
+ "Abroad": 39
+ },
+ {
+ "Month": "Mar",
+ "Domestics": 31,
+ "Abroad": 20
+ },
+ {
+ "Month": "Apr",
+ "Domestics": 30,
+ "Abroad": 15
+ },
+ {
+ "Month": "May",
+ "Domestics": 37,
+ "Abroad": 13
+ },
+ {
+ "Month": "Jun",
+ "Domestics": 36,
+ "Abroad": 17
+ },
+ {
+ "Month": "Jul",
+ "Domestics": 42,
+ "Abroad": 22
+ },
+ {
+ "Month": "Aug",
+ "Domestics": 22,
+ "Abroad": 12
+ },
+ {
+ "Month": "Sep",
+ "Domestics": 17,
+ "Abroad": 30
+ },
+ {
+ "Month": "Oct",
+ "Domestics": 40,
+ "Abroad": 33
+ },
+ {
+ "Month": "Nov",
+ "Domestics": 42,
+ "Abroad": 22
+ },
+ {
+ "Month": "Dec",
+ "Domestics": 32,
+ "Abroad": 11
}
- ]
+ ],
+ "xAxis": {
+ "data": "Month"
+ },
+ "yAxis": {
+ "name": "Percentage(%)"
+ }
}
- ]
+ }
}
},
{
"name": {
- "zh_CN": "弹出编辑"
+ "zh_CN": "柱状图"
},
- "icon": "popeditor",
+ "icon": "histogram",
"screenshot": "",
- "snippetName": "TinyPopeditor",
+ "snippetName": "TinyHuichartsHistogram",
"schema": {
- "componentName": "TinyPopeditor",
+ "componentName": "TinyHuichartsHistogram",
"props": {
- "modelValue": "",
- "placeholder": "请选择",
- "grid-op": {
- "columns": [
+ "options": {
+ "theme": "hdesign-light",
+ "padding": [50, 30, 50, 20],
+ "data": [
{
- "field": "id",
- "title": "ID",
- "width": 40
+ "Month": "Jan",
+ "Domestic": 33,
+ "Abroad": 1
},
{
- "field": "name",
- "title": "名称",
- "showOverflow": "tooltip"
+ "Month": "Feb",
+ "Domestic": 27,
+ "Abroad": 39
},
{
- "field": "province",
- "title": "省份",
- "width": 80
+ "Month": "Mar",
+ "Domestic": 31,
+ "Abroad": 20
},
{
- "field": "city",
- "title": "城市",
- "width": 80
+ "Month": "Apr",
+ "Domestic": 30,
+ "Abroad": 15
+ },
+ {
+ "Month": "May",
+ "Domestic": 37,
+ "Abroad": 1
+ },
+ {
+ "Month": "Jun",
+ "Domestic": 36,
+ "Abroad": 17
+ },
+ {
+ "Month": "Jul",
+ "Domestic": 42,
+ "Abroad": 22
+ },
+ {
+ "Month": "Aug",
+ "Domestic": 22,
+ "Abroad": 12
+ },
+ {
+ "Month": "Sep",
+ "Domestic": 17,
+ "Abroad": 30
+ },
+ {
+ "Month": "Oct",
+ "Domestic": 40,
+ "Abroad": 33
+ },
+ {
+ "Month": "Nov",
+ "Domestic": 42,
+ "Abroad": 22
+ },
+ {
+ "Month": "Dec",
+ "Domestic": 32,
+ "Abroad": 1
}
],
+ "xAxis": {
+ "data": "Month"
+ },
+ "yAxis": {
+ "name": "Percentage(%)"
+ }
+ }
+ }
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "条形图"
+ },
+ "icon": "bar",
+ "screenshot": "",
+ "snippetName": "TinyHuichartsBar",
+ "schema": {
+ "componentName": "TinyHuichartsBar",
+ "props": {
+ "options": {
+ "theme": "hdesign-light",
+ "padding": [50, 30, 50, 20],
"data": [
{
- "id": "1",
- "name": "GFD科技有限公司GFD科技有限公司GFD科技有限公司GFD科技有限公司GFD科技有限公司GFD科技有限公司GFD科技有限公司",
- "city": "福州",
- "province": "福建"
+ "Month": "Jan",
+ "Domestic": 33,
+ "Abroad": 1
},
{
- "id": "2",
- "name": "WWW科技有限公司",
- "city": "深圳",
- "province": "广东"
+ "Month": "Feb",
+ "Domestic": 27,
+ "Abroad": 39
},
{
- "id": "3",
- "name": "RFV有限责任公司",
- "city": "中山",
- "province": "广东"
+ "Month": "Mar",
+ "Domestic": 31,
+ "Abroad": 20
},
{
- "id": "4",
- "name": "TGB科技有限公司",
- "city": "龙岩",
- "province": "福建"
+ "Month": "Apr",
+ "Domestic": 30,
+ "Abroad": 15
},
{
- "id": "5",
- "name": "YHN科技有限公司",
- "city": "韶关",
- "province": "广东"
+ "Month": "May",
+ "Domestic": 37,
+ "Abroad": 1
+ },
+ {
+ "Month": "Jun",
+ "Domestic": 36,
+ "Abroad": 17
+ },
+ {
+ "Month": "Jul",
+ "Domestic": 42,
+ "Abroad": 22
+ },
+ {
+ "Month": "Aug",
+ "Domestic": 22,
+ "Abroad": 12
+ },
+ {
+ "Month": "Sep",
+ "Domestic": 17,
+ "Abroad": 30
+ },
+ {
+ "Month": "Oct",
+ "Domestic": 40,
+ "Abroad": 33
+ },
+ {
+ "Month": "Nov",
+ "Domestic": 42,
+ "Abroad": 22
},
{
- "id": "6",
- "name": "WSX科技有限公司",
- "city": "黄冈",
- "province": "武汉"
+ "Month": "Dec",
+ "Domestic": 32,
+ "Abroad": 1
}
- ]
+ ],
+ "xAxis": {
+ "data": "Month"
+ },
+ "yAxis": {
+ "name": "Percentage(%)"
+ },
+ "direction": "horizontal"
}
}
}
},
{
"name": {
- "zh_CN": "树"
+ "zh_CN": "圆盘图"
},
- "icon": "tree",
+ "icon": "pie",
"screenshot": "",
- "snippetName": "TinyTree",
+ "snippetName": "TinyHuichartsPie",
"schema": {
- "componentName": "TinyTree",
+ "componentName": "TinyHuichartsPie",
"props": {
- "data": [
- {
- "label": "一级 1",
- "children": [
- {
- "label": "二级 1-1",
- "children": [
- {
- "label": "三级 1-1-1"
- }
- ]
- }
- ]
- },
- {
- "label": "一级 2",
- "children": [
- {
- "label": "二级 2-1",
- "children": [
- {
- "label": "三级 2-1-1"
- }
- ]
+ "options": {
+ "type": "pie",
+ "theme": "hdesign-light",
+ "label": {
+ "show": true,
+ "line": true,
+ "labelHtml": "{a|}{b|{b}:}{c|{d}%}",
+ "rich": {
+ "a": {
+ "width": 12,
+ "height": 12,
+ "backgroundColor": {
+ "image": "./image/charts/pie/ic_jiantou_hong.svg"
+ }
},
- {
- "label": "二级 2-2",
- "children": [
- {
- "label": "三级 2-2-1"
- }
- ]
+ "b": {
+ "padding": [2, 4, 0, 0]
+ },
+ "c": {
+ "fontWeight": "bold",
+ "padding": [2, 0, 0, 0]
}
- ]
- }
- ]
- }
- }
- },
- {
- "name": {
- "zh_CN": "文字提示框"
- },
- "icon": "tooltip",
- "screenshot": "",
- "snippetName": "TinyTooltip",
- "schema": {
- "componentName": "TinyTooltip",
- "props": {
- "content": "Top Left 提示文字",
- "placement": "top-start",
- "manual": true,
- "modelValue": true
- },
- "children": [
- {
- "componentName": "span",
- "children": [
- {
- "componentName": "div",
- "props": {}
}
- ]
- },
- {
- "componentName": "Template",
- "props": {
- "slot": "content"
},
- "children": [
+ "data": [
{
- "componentName": "span",
- "children": [
- {
- "componentName": "div",
- "props": {
- "placeholder": "提示内容"
- }
- }
- ]
+ "value": 100,
+ "name": "VPC"
+ },
+ {
+ "value": 90,
+ "name": "IM"
+ },
+ {
+ "value": 49,
+ "name": "EIP"
+ },
+ {
+ "value": 14,
+ "name": "SG"
}
]
}
- ]
+ }
}
},
{
"name": {
- "zh_CN": "提示框"
+ "zh_CN": "环形图"
},
- "icon": "popover",
+ "icon": "ring",
"screenshot": "",
- "snippetName": "TinyPopover",
+ "snippetName": "TinyHuichartsRing",
"schema": {
- "componentName": "TinyPopover",
+ "componentName": "TinyHuichartsRing",
"props": {
- "width": 200,
- "title": "弹框标题",
- "trigger": "manual",
- "modelValue": true
- },
- "children": [
- {
- "componentName": "Template",
- "props": {
- "slot": "reference"
- },
- "children": [
+ "options": {
+ "theme": "hdesign-light",
+ "type": "circle",
+ "data": [
{
- "componentName": "div",
- "props": {
- "placeholder": "触发源"
- }
- }
- ]
- },
- {
- "componentName": "Template",
- "props": {
- "slot": "default"
- },
- "children": [
+ "value": 100,
+ "name": "VPC"
+ },
{
- "componentName": "div",
- "props": {
- "placeholder": "提示内容"
- }
+ "value": 90,
+ "name": "IM"
+ },
+ {
+ "value": 49,
+ "name": "EIP"
+ },
+ {
+ "value": 14,
+ "name": "SG"
}
]
}
- ]
+ }
}
- }
- ]
- },
- {
- "group": "navigation",
- "label": {
- "zh_CN": "导航类型"
- },
- "children": [
+ },
{
"name": {
- "zh_CN": "时间线"
+ "zh_CN": "雷达图"
},
- "icon": "timeline",
+ "icon": "radar",
"screenshot": "",
- "snippetName": "TinyTimeLine",
+ "snippetName": "TinyHuichartsRadar",
"schema": {
- "componentName": "TinyTimeLine",
+ "componentName": "TinyHuichartsRadar",
"props": {
- "active": "2",
- "data": [
- {
- "name": "已下单"
- },
- {
- "name": "运输中"
- },
- {
- "name": "已签收"
+ "options": {
+ "theme": "hdesign-light",
+ "legend": {
+ "show": true,
+ "position": {
+ "left": "center",
+ "bottom": 20.1
+ }
+ },
+ "radarMax": 100,
+ "data": {
+ "Domestic": {
+ "Equipment": 41,
+ "VM": 91,
+ "CSP": 81,
+ "RD": 51,
+ "Markets": 71
+ },
+ "Abroad": {
+ "Equipment": 72,
+ "VM": 55,
+ "CSP": 93,
+ "RD": 90,
+ "Markets": 82
+ }
}
- ]
+ }
}
}
},
{
"name": {
- "zh_CN": "面包屑"
+ "zh_CN": "瀑布图"
},
- "icon": "breadcrumb",
+ "icon": "waterfall",
"screenshot": "",
- "snippetName": "TinyBreadcrumb",
+ "snippetName": "TinyHuichartsWaterfall",
"schema": {
- "componentName": "TinyBreadcrumb",
+ "componentName": "TinyHuichartsWaterfall",
"props": {
- "options": [
- {
- "to": "{ path: '/' }",
- "label": "首页"
+ "options": {
+ "padding": [50, 30, 20, 20],
+ "legend": {
+ "show": false
},
- {
- "to": "{ path: '/breadcrumb' }",
- "label": "产品"
+ "type": "water-fall",
+ "data": [
+ {
+ "Name": "NLE",
+ "User": 10
+ },
+ {
+ "Name": "HIN",
+ "User": 20
+ },
+ {
+ "Name": "FBP",
+ "User": 9
+ },
+ {
+ "Name": "VEDIO",
+ "User": 35
+ },
+ {
+ "Name": "SASS",
+ "User": 20
+ },
+ {
+ "Name": "RDS",
+ "User": 35
+ },
+ {
+ "Name": "E-SYS",
+ "User": 9
+ }
+ ],
+ "xAxis": {
+ "data": "Name"
},
- {
- "replace": "true",
- "label": "软件"
+ "yAxis": {
+ "name": "Number"
}
- ]
+ }
}
}
},
{
"name": {
- "zh_CN": "标签页"
+ "zh_CN": "漏斗图"
},
- "icon": "tabs",
+ "icon": "funnel",
"screenshot": "",
- "group": true,
- "snippetName": "TinyTabs",
+ "snippetName": "TinyHuichartsFunnel",
"schema": {
- "componentName": "TinyTabs",
+ "componentName": "TinyHuichartsFunnel",
"props": {
- "modelValue": "first"
- },
- "children": [
- {
- "componentName": "TinyTabItem",
- "props": {
- "title": "标签页1",
- "name": "first"
- },
- "children": [
+ "options": {
+ "data": [
{
- "componentName": "div",
- "props": {
- "style": "margin:10px 0 0 30px"
- }
- }
- ]
- },
- {
- "componentName": "TinyTabItem",
- "props": {
- "title": "标签页2",
- "name": "second"
- },
- "children": [
+ "value": 100,
+ "name": "Show"
+ },
{
- "componentName": "div",
- "props": {
- "style": "margin:10px 0 0 30px"
- }
+ "value": 75,
+ "name": "Click"
+ },
+ {
+ "value": 50,
+ "name": "Visit"
+ },
+ {
+ "value": 25,
+ "name": "Order"
}
]
}
- ]
+ }
+ }
+ },
+ {
+ "name": {
+ "zh_CN": "散点图"
+ },
+ "icon": "scatter",
+ "screenshot": "",
+ "snippetName": "TinyHuichartsScatter",
+ "schema": {
+ "componentName": "TinyHuichartsScatter",
+ "props": {
+ "options": {
+ "padding": [50, 30, 50, 20],
+ "legend": {
+ "orient": "horizontal",
+ "show": true,
+ "position": {
+ "left": "center",
+ "bottom": 15
+ }
+ },
+ "bubbleSize": [20, 100],
+ "xAxisType": "value",
+ "data": {
+ "1990": [
+ [28604, 77, 1709866, "Australia", 1990],
+ [31163, 77.4, 27662440, "Canada", 1990],
+ [60001, 68, 1154605773, "China", 1990],
+ [13670, 74.7, 10582082, "Cuba", 1990],
+ [28599, 75, 4986705, "Finland", 1990]
+ ],
+ "2000": [
+ [19349, 69.6, 147568552, "Russia", 2000],
+ [10670, 67.3, 53994606, "Turkey", 2000],
+ [26424, 75.7, 57110117, "United Kingdom", 2000],
+ [37062, 75.4, 252847810, "United States", 2000],
+ [23038, 73.13, 143456918, "Russia", 2000]
+ ],
+ "2015": [
+ [44056, 81.8, 23968976, "Australia", 2015],
+ [43294, 81.7, 35939927, "Canada", 2015],
+ [13334, 76.9, 1376048943, "Cuba", 2015],
+ [21291, 78.5, 11389566, "Finland", 2015],
+ [38923, 80.8, 5503457, "France", 2015]
+ ]
+ }
+ }
+ }
}
}
]
@@ -14918,6 +22670,13 @@
}
],
"packages": [
+ {
+ "name": "TinyVueHuicharts组件库",
+ "package": "@opentiny/vue-huicharts",
+ "version": "3.22.0",
+ "destructuring": true,
+ "script": "https://registry.npmmirror.com/@opentiny/vue-runtime/3.22/files/dist3/tiny-vue-huicharts.mjs"
+ },
{
"name": "TinyVue组件库",
"package": "@opentiny/vue",
diff --git a/packages/engine-cli/template/designer/registry.js b/packages/engine-cli/template/designer/registry.js
index 23d7d0c824..af0a653289 100644
--- a/packages/engine-cli/template/designer/registry.js
+++ b/packages/engine-cli/template/designer/registry.js
@@ -13,6 +13,9 @@ import { META_SERVICE, META_APP } from '@opentiny/tiny-engine-meta-register'
import engineConfig from './engine.config'
import { HttpService } from './src/composable'
+const baseURL = import.meta.env.BASE_URL || '.'
+const baseURLWithoutSlash = baseURL.replace(/\/$/, '')
+
export default {
[META_SERVICE.Http]: HttpService,
'engine.config': {
@@ -43,5 +46,12 @@ export default {
}
}
}
+ },
+ [META_APP.Preview]: {
+ options: {
+ // 配置预览跳转的 url:根据实际业务需求进行配置
+ // 文档:https://opentiny.design/tiny-engine#/help-center/course/dev/preview-api
+ previewUrl: ['prod', 'alpha'].includes(import.meta.env.MODE) ? `${baseURLWithoutSlash}/preview.html` : ''
+ }
}
}
diff --git a/packages/engine-cli/template/designer/src/composable/http/index.js b/packages/engine-cli/template/designer/src/composable/http/index.js
index f11538395a..141c885c7b 100644
--- a/packages/engine-cli/template/designer/src/composable/http/index.js
+++ b/packages/engine-cli/template/designer/src/composable/http/index.js
@@ -16,6 +16,7 @@ const procession = {
let loginVM = null
const showError = (url, message) => {
+ if (message === 'canceled') return // 取消请求场景不报错
globalNotify({
type: 'error',
title: '接口报错',
@@ -46,7 +47,7 @@ const preResponse = (res) => {
return Promise.reject(res.data.error)
}
- return res.data?.data
+ return res.data?.data || res.data
}
const openLogin = () => {
diff --git a/packages/engine-cli/template/designer/src/preview.js b/packages/engine-cli/template/designer/src/preview.js
index 47c726cc88..c35f036f65 100644
--- a/packages/engine-cli/template/designer/src/preview.js
+++ b/packages/engine-cli/template/designer/src/preview.js
@@ -10,6 +10,7 @@
*
*/
import { defineEntry } from '@opentiny/tiny-engine-meta-register'
+import engineConfig from '../engine.config'
import 'virtual:svg-icons-register'
async function startApp() {
@@ -23,9 +24,7 @@ async function startApp() {
const registry = {
[META_SERVICE.Http]: HttpService,
'engine.config': {
- id: 'engine.config',
- theme: 'light',
- material: ['/mock/bundle.json']
+ ...engineConfig
}
}
diff --git a/packages/i18n/package.json b/packages/i18n/package.json
index 9e35c766ba..44c4637b0b 100644
--- a/packages/i18n/package.json
+++ b/packages/i18n/package.json
@@ -1,6 +1,6 @@
{
"name": "@opentiny/tiny-engine-i18n-host",
- "version": "2.7.0",
+ "version": "2.9.0",
"publishConfig": {
"access": "public"
},
@@ -15,6 +15,7 @@
"type": "module",
"main": "dist/lowcode-design-i18n-host.umd.js",
"module": "dist/lowcode-design-i18n-host.es.js",
+ "types": "dist/lowcode-design-i18n-host.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/opentiny/tiny-engine",
@@ -28,7 +29,8 @@
"homepage": "https://opentiny.design/tiny-engine",
"devDependencies": {
"@vitejs/plugin-vue": "^5.1.2",
- "vite": "^5.4.2"
+ "vite": "^5.4.2",
+ "vite-plugin-dts": "^4.5.4"
},
"peerDependencies": {
"vue": "^3.4.15",
diff --git a/packages/i18n/tsconfig.json b/packages/i18n/tsconfig.json
new file mode 100644
index 0000000000..d2e0afe6ff
--- /dev/null
+++ b/packages/i18n/tsconfig.json
@@ -0,0 +1,5 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "include": ["./src/**/*.ts", "./src/**/*.tsx", "./src/**/*.vue"],
+ "exclude": ["./src/test"]
+}
diff --git a/packages/i18n/vite.config.ts b/packages/i18n/vite.config.ts
index 04ebb813d3..1acdc12608 100644
--- a/packages/i18n/vite.config.ts
+++ b/packages/i18n/vite.config.ts
@@ -12,9 +12,14 @@
import vue from '@vitejs/plugin-vue'
import path from 'path'
+import dts from 'vite-plugin-dts'
export default {
plugins: [
+ dts({
+ tsconfigPath: path.resolve(__dirname, './tsconfig.json'),
+ rollupTypes: true
+ }),
vue({
template: {
compilerOptions: {
diff --git a/packages/layout/index.ts b/packages/layout/index.ts
index 448649a7f2..cf2dda4b8f 100644
--- a/packages/layout/index.ts
+++ b/packages/layout/index.ts
@@ -4,6 +4,7 @@ import { LayoutService } from './src/composable'
import designSmbConfig from '@opentiny/vue-design-smb'
import { ConfigProvider as TinyConfigProvider } from '@opentiny/vue'
import './src/styles/vars.less'
+import mcp from './src/mcp'
export default {
...metaData,
@@ -12,9 +13,11 @@ export default {
configProvider: TinyConfigProvider,
configProviderDesign: designSmbConfig,
isShowLine: true,
- isShowCollapse: true
+ isShowCollapse: true,
+ isShowWorkspace: true
},
- metas: [LayoutService]
+ metas: [LayoutService],
+ mcp
}
export { LayoutService }
diff --git a/packages/layout/package.json b/packages/layout/package.json
index 3e9d904693..2aca7f86fe 100644
--- a/packages/layout/package.json
+++ b/packages/layout/package.json
@@ -1,6 +1,6 @@
{
"name": "@opentiny/tiny-engine-layout",
- "version": "2.7.0",
+ "version": "2.9.0",
"scripts": {
"build": "vite build"
},
@@ -27,7 +27,8 @@
"@opentiny/tiny-engine-meta-register": "workspace:*",
"@opentiny/tiny-engine-utils": "workspace:*",
"@vueuse/core": "^9.6.0",
- "vue-draggable-next": "2.2.1"
+ "vue-draggable-next": "2.2.1",
+ "zod": "^3.25.76"
},
"devDependencies": {
"@opentiny/tiny-engine-vite-plugin-meta-comments": "workspace:*",
diff --git a/packages/layout/src/DesignPlugins.vue b/packages/layout/src/DesignPlugins.vue
index 763a0ca348..f79a3dcd97 100644
--- a/packages/layout/src/DesignPlugins.vue
+++ b/packages/layout/src/DesignPlugins.vue
@@ -106,6 +106,7 @@
+
+
diff --git a/packages/layout/src/Main.vue b/packages/layout/src/Main.vue
index 90905caa80..c4f07bee7d 100644
--- a/packages/layout/src/Main.vue
+++ b/packages/layout/src/Main.vue
@@ -1,7 +1,18 @@
-
-
+
+
+
+
+
@@ -26,6 +37,9 @@
@changeRightAlign="changeRightAlign"
>
+
+
+
@@ -33,12 +47,13 @@
+
+
diff --git a/packages/plugins/model-manager/src/components/FieldManager.vue b/packages/plugins/model-manager/src/components/FieldManager.vue
new file mode 100644
index 0000000000..a9a514b011
--- /dev/null
+++ b/packages/plugins/model-manager/src/components/FieldManager.vue
@@ -0,0 +1,356 @@
+
+
+ 添加字段
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ row.prop || '点击编辑' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ getFieldTypeLabel(row.type) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ row.description || '点击编辑' }}
+
+
+
+
+
+
+ 保存
+ 取消
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/plugins/model-manager/src/components/ModelBasicForm.vue b/packages/plugins/model-manager/src/components/ModelBasicForm.vue
new file mode 100644
index 0000000000..293d2b175f
--- /dev/null
+++ b/packages/plugins/model-manager/src/components/ModelBasicForm.vue
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/plugins/model-manager/src/components/ModelSetting.vue b/packages/plugins/model-manager/src/components/ModelSetting.vue
new file mode 100644
index 0000000000..758ff8c91f
--- /dev/null
+++ b/packages/plugins/model-manager/src/components/ModelSetting.vue
@@ -0,0 +1,213 @@
+
+
+
+
+ 导出SQL
+ 保存
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/plugins/model-manager/src/composable/useModelManager.js b/packages/plugins/model-manager/src/composable/useModelManager.js
new file mode 100644
index 0000000000..55f0747a3f
--- /dev/null
+++ b/packages/plugins/model-manager/src/composable/useModelManager.js
@@ -0,0 +1,28 @@
+import { getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register'
+
+// 示例API路径,请根据实际后端接口调整
+const modelApi = '/material-center/api/model'
+
+export function getModelList(params = {}) {
+ return getMetaApi(META_SERVICE.Http).get(`${modelApi}/list`, { params })
+}
+
+export function createModel(data) {
+ return getMetaApi(META_SERVICE.Http).post(`${modelApi}/create`, data)
+}
+
+export function updateModel(id, data) {
+ return getMetaApi(META_SERVICE.Http).put(`${modelApi}/update/${id}`, data)
+}
+
+export function deleteModel(id) {
+ return getMetaApi(META_SERVICE.Http).delete(`${modelApi}/delete/${id}`)
+}
+
+export function getModelSql() {
+ return getMetaApi(META_SERVICE.Http).get(`${modelApi}/table/list`)
+}
+
+export function getModelSqlById(id) {
+ return getMetaApi(META_SERVICE.Http).get(`${modelApi}/table/${id}`)
+}
diff --git a/packages/plugins/model-manager/src/styles/vars.less b/packages/plugins/model-manager/src/styles/vars.less
new file mode 100644
index 0000000000..3ea5b23c9f
--- /dev/null
+++ b/packages/plugins/model-manager/src/styles/vars.less
@@ -0,0 +1,21 @@
+.plugin-modelmanager {
+ --te-model-manage-title-text-color: var(--te-common-text-primary);
+ --te-model-manage-input-bg-color: var(--te-common-bg-default);
+ --te-model-manage-input-border-color: var(--te-common-border-default);
+ --te-model-manage-tip-color: var(--te-common-text-primary);
+ --te-model-manage-tip-text-color: var(--te-common-text-weaken);
+ --te-model-manage-tip-dim-text-color: var(--te-common-text-primary);
+ --te-model-manage-tree-text-bg-color: var(--te-common-bg-default);
+ --te-model-manage-tree-node-bg-color: var(--te-common-bg-default);
+ --te-model-manage-tree-node-bg-color-hover: var(--te-common-bg-container);
+ --te-model-manage-text-color: var(--te-common-text-secondary);
+ --te-model-manage-input-head-text-color: var(--te-common-text-primary);
+ --te-model-manage-input-or-output-text-color: var(--te-common-text-secondary);
+ --te-model-manage-life-cycle-alert-text-color: var(--te-common-text-weaken);
+ --te-model-manage-icon-color: var(--te-common-icon-secondary);
+ --te-model-manage-draggable-row-bg-color-hover: var(--te-common-bg-container);
+ --te-model-manage-draggable-text-color: var(--te-common-text-primary);
+ --te-model-manage-draggable-icon-color: var(--te-common-icon-secondary);
+ --te-model-manage-draggable-border-color: var(--te-common-border-checked);
+ --te-model-common-border-color-divider: var(--te-common-border-divider);
+}
diff --git a/packages/webcomponent/vite.config.js b/packages/plugins/model-manager/vite.config.ts
similarity index 53%
rename from packages/webcomponent/vite.config.js
rename to packages/plugins/model-manager/vite.config.ts
index 370297c61c..23b1ee2414 100644
--- a/packages/webcomponent/vite.config.js
+++ b/packages/plugins/model-manager/vite.config.ts
@@ -11,36 +11,29 @@
*/
import { defineConfig } from 'vite'
-import vue from '@vitejs/plugin-vue'
import path from 'path'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+import generateComment from '@opentiny/tiny-engine-vite-plugin-meta-comments'
// https://vitejs.dev/config/
export default defineConfig({
- plugins: [vue()],
- define: {},
+ plugins: [generateComment(), vue(), vueJsx()],
+ publicDir: false,
+ resolve: {},
build: {
sourcemap: true,
- minify: false,
- emptyOutDir: true,
lib: {
- entry: path.resolve(__dirname, './src/lib.js'),
- name: 'LowcodeDesignWebcomponentCore',
- formats: ['es', 'umd'],
- fileName: (format) => `tiny-engine-webcomponent-core.${format}.js`
- },
- commonjsOptions: {
- transformMixedEsModules: true
+ entry: path.resolve(__dirname, './index.ts'),
+ name: 'plugin-model-manager',
+ fileName: (_format, entryName) => `${entryName}.js`,
+ formats: ['es']
},
rollupOptions: {
- // 确保外部化处理那些你不想打包进库的依赖
- external: ['vue', 'vue-i18n'],
output: {
- // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
- globals: {
- vue: 'Vue',
- 'vue-i18n': 'VueI18n'
- }
- }
+ banner: 'import "./style.css"'
+ },
+ external: ['vue', /@opentiny\/tiny-engine.*/, /@opentiny\/vue.*/]
}
}
})
diff --git a/packages/plugins/page/index.ts b/packages/plugins/page/index.ts
index 8d654de635..526f197acd 100644
--- a/packages/plugins/page/index.ts
+++ b/packages/plugins/page/index.ts
@@ -14,6 +14,7 @@ import entry, { api } from './src/Main.vue'
import metaData from './meta'
import { PageService } from './src/composable/index'
import PageGeneral from './src/PageGeneral.vue'
+import mcp from './src/mcp'
import './src/styles/vars.less'
export default {
@@ -29,7 +30,8 @@ export default {
components: {
PageGeneral
},
- metas: [PageService]
+ metas: [PageService],
+ mcp
}
export { PageService }
diff --git a/packages/plugins/page/package.json b/packages/plugins/page/package.json
index 84135481a2..f258958d04 100644
--- a/packages/plugins/page/package.json
+++ b/packages/plugins/page/package.json
@@ -1,6 +1,6 @@
{
"name": "@opentiny/tiny-engine-plugin-page",
- "version": "2.7.0",
+ "version": "2.9.0",
"publishConfig": {
"access": "public"
},
@@ -27,7 +27,8 @@
"dependencies": {
"@opentiny/tiny-engine-common": "workspace:*",
"@opentiny/tiny-engine-meta-register": "workspace:*",
- "@opentiny/tiny-engine-utils": "workspace:*"
+ "@opentiny/tiny-engine-utils": "workspace:*",
+ "zod": "^3.25.76"
},
"devDependencies": {
"@opentiny/tiny-engine-vite-plugin-meta-comments": "workspace:*",
diff --git a/packages/plugins/page/src/PageHome.vue b/packages/plugins/page/src/PageHome.vue
index 22bc5e309a..08d97822a7 100644
--- a/packages/plugins/page/src/PageHome.vue
+++ b/packages/plugins/page/src/PageHome.vue
@@ -13,6 +13,7 @@
+
diff --git a/packages/plugins/resource/src/ResourceList.vue b/packages/plugins/resource/src/ResourceList.vue
new file mode 100644
index 0000000000..e384382451
--- /dev/null
+++ b/packages/plugins/resource/src/ResourceList.vue
@@ -0,0 +1,628 @@
+
+
+
+
+
+
+
+
+ 添加资源
+ 支持上传png、jpg、svg文件,支持批量上传
+
+
+ 全部
+
+ 图片
+
+
+
+
+ 删除
+
+ 批量操作
+
+
+
+
+
+
+
+
+
+
+
+
+ 复制
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 上传资源
+
+
+ 通过URL添加
+
+
+
+
+ {{ data.row.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 保存
+ 取消
+
+ 删除
+
+
+
+
+ 确 定
+ 取 消
+
+
+
+
+
+
diff --git a/packages/plugins/resource/src/ResourceSetting.vue b/packages/plugins/resource/src/ResourceSetting.vue
new file mode 100644
index 0000000000..a9f73da52e
--- /dev/null
+++ b/packages/plugins/resource/src/ResourceSetting.vue
@@ -0,0 +1,175 @@
+
+
+
+
+ 保存
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/plugins/resource/src/js/http.ts b/packages/plugins/resource/src/js/http.ts
new file mode 100644
index 0000000000..f39ad5c49d
--- /dev/null
+++ b/packages/plugins/resource/src/js/http.ts
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+/* metaService: engine.plugins.resource.http */
+import { getMetaApi, getMergeMeta, META_SERVICE } from '@opentiny/tiny-engine-meta-register'
+
+const baseUrl = '/material-center/api'
+// 资源管理 -- 根据分组ID获取资源列表
+export const fetchResourceListByGroupId = (resourceGroupId: number) =>
+ getMetaApi(META_SERVICE.Http).get(`${baseUrl}/resource/find/${resourceGroupId}`)
+
+// 资源管理 -- 获取资源列表含模糊查询
+export const fetchResourceList = () => getMetaApi(META_SERVICE.Http).get(`${baseUrl}/resource/like`)
+
+// 资源管理 -- 创建资源
+export const createResource = (params: any) =>
+ getMetaApi(META_SERVICE.Http).post(`${baseUrl}/resource/create`, {
+ appId: getMetaApi(META_SERVICE.GlobalService).getBaseInfo().id,
+ platformId: getMergeMeta('engine.config')?.platformId,
+ ...params
+ })
+
+// 资源管理 -- 批量创建资源
+export const batchCreateResource = (params: any) =>
+ getMetaApi(META_SERVICE.Http).post(
+ `${baseUrl}/resource/create/batch`,
+ params.map((item: any) => ({
+ appId: getMetaApi(META_SERVICE.GlobalService).getBaseInfo().id,
+ platformId: getMergeMeta('engine.config')?.platformId,
+ ...item
+ }))
+ )
+
+// 资源管理 -- 删除资源
+export const deleteResource = (id: number) => getMetaApi(META_SERVICE.Http).get(`${baseUrl}/resource/delete/${id}`)
+
+// 资源管理 -- 根据appId查询资源分组列表
+export const fetchResourceGroupByAppId = () =>
+ getMetaApi(META_SERVICE.Http).get(
+ `${baseUrl}/resource-group/${getMetaApi(META_SERVICE.GlobalService).getBaseInfo().id}`
+ )
+
+// 资源管理 -- 创建资源分组
+export const createResourceGroup = (params: any) =>
+ getMetaApi(META_SERVICE.Http).post(`${baseUrl}/resource-group/create`, {
+ appId: getMetaApi(META_SERVICE.GlobalService).getBaseInfo().id,
+ platformId: getMergeMeta('engine.config')?.platformId,
+ ...params
+ })
+
+// 资源管理 -- 修改资源分组信息-包括删除
+export const updateResourceGroup = (id: number, params: any) =>
+ getMetaApi(META_SERVICE.Http).put(`${baseUrl}/resource-group/update/${id}`, params)
diff --git a/packages/plugins/resource/src/styles/vars.less b/packages/plugins/resource/src/styles/vars.less
new file mode 100644
index 0000000000..6b50111adb
--- /dev/null
+++ b/packages/plugins/resource/src/styles/vars.less
@@ -0,0 +1,21 @@
+.plugin-resource {
+ --te-resource-manage-title-text-color: var(--te-common-text-primary);
+ --te-resource-manage-button-text-color: var(--te-common-text-inverse);
+ --te-resource-manage-input-bg-color: var(--te-common-bg-default);
+ --te-resource-manage-input-border-color: var(--te-common-border-default);
+ --te-resource-manage-tip-color: var(--te-common-text-primary);
+ --te-resource-manage-tip-text-color: var(--te-common-text-weaken);
+ --te-resource-manage-tip-dim-text-color: var(--te-common-text-primary);
+ --te-resource-manage-tree-text-bg-color: var(--te-common-bg-default);
+ --te-resource-manage-tree-node-bg-color: var(--te-common-bg-default);
+ --te-resource-manage-tree-node-bg-color-hover: var(--te-common-bg-container);
+ --te-resource-manage-text-color: var(--te-common-text-secondary);
+ --te-resource-manage-input-head-text-color: var(--te-common-text-primary);
+ --te-resource-manage-input-or-output-text-color: var(--te-common-text-secondary);
+ --te-resource-manage-life-cycle-alert-text-color: var(--te-common-text-weaken);
+ --te-resource-manage-icon-color: var(--te-common-icon-secondary);
+ --te-resource-manage-draggable-row-bg-color-hover: var(--te-common-bg-container);
+ --te-resource-manage-draggable-text-color: var(--te-common-text-primary);
+ --te-resource-manage-draggable-icon-color: var(--te-common-icon-secondary);
+ --te-resource-manage-draggable-border-color: var(--te-common-border-checked);
+}
diff --git a/packages/plugins/resource/vite.config.ts b/packages/plugins/resource/vite.config.ts
new file mode 100644
index 0000000000..e34785fe3c
--- /dev/null
+++ b/packages/plugins/resource/vite.config.ts
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+import { defineConfig } from 'vite'
+import path from 'path'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+import generateComment from '@opentiny/tiny-engine-vite-plugin-meta-comments'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [generateComment(), vue(), vueJsx()],
+ publicDir: false,
+ resolve: {},
+ build: {
+ sourcemap: true,
+ lib: {
+ entry: path.resolve(__dirname, './index.ts'),
+ name: 'plugin-resource',
+ fileName: (_format, entryName) => `${entryName}.js`,
+ formats: ['es']
+ },
+ rollupOptions: {
+ output: {
+ banner: 'import "./style.css"'
+ },
+ external: ['vue', /@opentiny\/tiny-engine.*/, /@opentiny\/vue.*/]
+ }
+ }
+})
diff --git a/packages/plugins/robot/assets/failed.svg b/packages/plugins/robot/assets/failed.svg
new file mode 100644
index 0000000000..2c96071046
--- /dev/null
+++ b/packages/plugins/robot/assets/failed.svg
@@ -0,0 +1,4 @@
+
diff --git a/packages/plugins/robot/assets/loading.webp b/packages/plugins/robot/assets/loading.webp
new file mode 100644
index 0000000000..ed71b43597
Binary files /dev/null and b/packages/plugins/robot/assets/loading.webp differ
diff --git a/packages/plugins/robot/assets/success.svg b/packages/plugins/robot/assets/success.svg
new file mode 100644
index 0000000000..1572769068
--- /dev/null
+++ b/packages/plugins/robot/assets/success.svg
@@ -0,0 +1,4 @@
+
diff --git a/packages/plugins/robot/index.ts b/packages/plugins/robot/index.ts
index f84692b4e6..dd4fb6e549 100644
--- a/packages/plugins/robot/index.ts
+++ b/packages/plugins/robot/index.ts
@@ -10,11 +10,16 @@
*
*/
-import RobotIcon from './src/Main.vue'
+import entry from './src/Main.vue'
import metaData from './meta'
import './src/styles/vars.less'
+import '@opentiny/tiny-robot/dist/style.css'
+import { RobotService } from './src/metas'
export default {
...metaData,
- icon: RobotIcon
+ entry,
+ metas: [RobotService]
}
+
+export * from './src/types'
diff --git a/packages/plugins/robot/meta.js b/packages/plugins/robot/meta.js
index 8fcefdee38..740dc50506 100644
--- a/packages/plugins/robot/meta.js
+++ b/packages/plugins/robot/meta.js
@@ -1,5 +1,20 @@
export default {
- id: 'engine.plugins.robot',
- title: 'AI对话框',
- type: 'plugins'
+ id: 'engine.toolbars.robot',
+ type: 'toolbars',
+ title: 'robot',
+ options: {
+ icon: {
+ default: 'AI'
+ },
+ renderType: 'icon',
+ customCompatibleAIModels: [], // 模型配置
+ enableResourceContext: true, // 提示词上下文携带资源插件图片
+ enableRagContext: false, // 提示词上下文携带查询到的知识库内容
+ encryptServiceApiKey: false, // 是否加密服务API密钥
+ modeImplementation: {
+ // 支持通过注册表传入chat和agent模式的实现
+ // chat: useCustomChatMode
+ // agent: useCustomAgentMode
+ }
+ }
}
diff --git a/packages/plugins/robot/package.json b/packages/plugins/robot/package.json
index 0c2185f383..c72b68f428 100644
--- a/packages/plugins/robot/package.json
+++ b/packages/plugins/robot/package.json
@@ -1,6 +1,6 @@
{
"name": "@opentiny/tiny-engine-plugin-robot",
- "version": "2.7.0",
+ "version": "2.9.0",
"publishConfig": {
"access": "public"
},
@@ -25,10 +25,23 @@
"license": "MIT",
"homepage": "https://opentiny.design/tiny-engine",
"dependencies": {
- "@opentiny/tiny-engine-meta-register": "workspace:*"
+ "@opentiny/tiny-engine-common": "workspace:*",
+ "@opentiny/tiny-engine-meta-register": "workspace:*",
+ "@opentiny/tiny-engine-utils": "workspace:*",
+ "@opentiny/tiny-robot": "0.3.0",
+ "@opentiny/tiny-robot-kit": "0.3.0",
+ "@opentiny/tiny-robot-svgs": "0.3.0",
+ "@opentiny/tiny-schema-renderer": "1.0.0-beta.6",
+ "@vueuse/core": "^9.13.0",
+ "dompurify": "^3.0.1",
+ "fast-json-patch": "~3.1.1",
+ "highlight.js": "^11.11.1",
+ "jsonrepair": "3.13.0",
+ "markdown-it": "^14.1.0"
},
"devDependencies": {
"@opentiny/tiny-engine-vite-plugin-meta-comments": "workspace:*",
+ "@types/markdown-it": "^14.1.2",
"@vitejs/plugin-vue": "^5.1.2",
"@vitejs/plugin-vue-jsx": "^4.0.1",
"vite": "^5.4.2"
diff --git a/packages/plugins/robot/src/Main.vue b/packages/plugins/robot/src/Main.vue
index 511909ba80..a4dfbe0466 100644
--- a/packages/plugins/robot/src/Main.vue
+++ b/packages/plugins/robot/src/Main.vue
@@ -1,667 +1,341 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+ switchConversation(item.id!)"
+ @item-action="handleDeleteConversation"
+ @item-title-change="(title, item) => updateTitle(item.id!, title)"
>
-
-
-
- {{ selectedModel.label }}
-
-
+
+
+
-
-
-
-
- 我是你的开发小助手
-
-
- 需要一个注册表单?
- 如何将表单嵌进我的网站?
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+ 深度思考
+
+
+
+
-
-
diff --git a/packages/plugins/robot/src/RobotSettingPopover.vue b/packages/plugins/robot/src/RobotSettingPopover.vue
deleted file mode 100644
index 8009f096bd..0000000000
--- a/packages/plugins/robot/src/RobotSettingPopover.vue
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
- 设置
-
-
-
-
-
-
- 大模型API Token
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/plugins/robot/src/components/chat/FooterButton.vue b/packages/plugins/robot/src/components/chat/FooterButton.vue
new file mode 100644
index 0000000000..f026376fd7
--- /dev/null
+++ b/packages/plugins/robot/src/components/chat/FooterButton.vue
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/plugins/robot/src/components/chat/RobotChat.vue b/packages/plugins/robot/src/components/chat/RobotChat.vue
new file mode 100644
index 0000000000..e24c375bdd
--- /dev/null
+++ b/packages/plugins/robot/src/components/chat/RobotChat.vue
@@ -0,0 +1,475 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/plugins/robot/src/components/footer-extension/McpServer.vue b/packages/plugins/robot/src/components/footer-extension/McpServer.vue
new file mode 100644
index 0000000000..adb8993333
--- /dev/null
+++ b/packages/plugins/robot/src/components/footer-extension/McpServer.vue
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+ MCP工具
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/plugins/robot/src/components/footer-extension/RobotTypeSelect.vue b/packages/plugins/robot/src/components/footer-extension/RobotTypeSelect.vue
new file mode 100644
index 0000000000..11b480cc6c
--- /dev/null
+++ b/packages/plugins/robot/src/components/footer-extension/RobotTypeSelect.vue
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
diff --git a/packages/plugins/robot/src/components/footer-extension/index.ts b/packages/plugins/robot/src/components/footer-extension/index.ts
new file mode 100644
index 0000000000..c0b6f86a60
--- /dev/null
+++ b/packages/plugins/robot/src/components/footer-extension/index.ts
@@ -0,0 +1,2 @@
+export { default as McpServer } from './McpServer.vue'
+export { default as RobotTypeSelect } from './RobotTypeSelect.vue'
diff --git a/packages/plugins/robot/src/components/header-extension/History.vue b/packages/plugins/robot/src/components/header-extension/History.vue
new file mode 100644
index 0000000000..efba3b013d
--- /dev/null
+++ b/packages/plugins/robot/src/components/header-extension/History.vue
@@ -0,0 +1,130 @@
+
+
+
+
+ 历史对话
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/plugins/robot/src/components/header-extension/index.ts b/packages/plugins/robot/src/components/header-extension/index.ts
new file mode 100644
index 0000000000..b6ba1b413d
--- /dev/null
+++ b/packages/plugins/robot/src/components/header-extension/index.ts
@@ -0,0 +1,2 @@
+export { default as RobotSetting } from './robot-setting/RobotSetting.vue'
+export { default as History } from './History.vue'
diff --git a/packages/plugins/robot/src/components/header-extension/robot-setting/RobotSetting.vue b/packages/plugins/robot/src/components/header-extension/robot-setting/RobotSetting.vue
new file mode 100644
index 0000000000..c224da35b6
--- /dev/null
+++ b/packages/plugins/robot/src/components/header-extension/robot-setting/RobotSetting.vue
@@ -0,0 +1,509 @@
+
+
+
+
+
+
+ 设置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.label }}
+
+ 工具
+ 视觉
+
+
+
+
+
+
+
+
+ 快速模型
+
+
+
+
+
+
+
+
+
+ 服务:
+ {{ selectedDefaultModelInfo.serviceName }}
+
+
+ API Key:
+
+ {{ selectedDefaultModelInfo.hasApiKey ? '已配置' : '未配置' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ service.label }}
+ 内置
+
+
+
+ {{ service.isBuiltIn ? '配置' : '编辑' }}
+
+
+
+ 删除
+
+
+
+
+
+
+ Base URL:
+ {{ service.baseUrl }}
+
+
+ 模型数量:
+ {{ service.models.length }}
+
+
+ API Key:
+
+ {{ service.apiKey ? '已配置' : '未配置' }}
+
+
+
+
+ 包含模型:
+
+
+
+
+ + 添加自定义服务
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/plugins/robot/src/components/header-extension/robot-setting/ServiceEditDialog.vue b/packages/plugins/robot/src/components/header-extension/robot-setting/ServiceEditDialog.vue
new file mode 100644
index 0000000000..7328d13d69
--- /dev/null
+++ b/packages/plugins/robot/src/components/header-extension/robot-setting/ServiceEditDialog.vue
@@ -0,0 +1,263 @@
+
+
+
+
+
+
+
+
+
+ Base URL
+
+
+
+
+
+
+
+
+
+
+
+ 模型配置
+
+
+
+
+ 模型 {{ index + 1 }}
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 工具调用
+ 视觉理解
+ 快速模型
+
+
+
+
+ + 添加模型
+
+
+
+
+ 取消
+ 确定
+
+
+
+
+
+
+
diff --git a/packages/plugins/robot/src/components/icons/index.ts b/packages/plugins/robot/src/components/icons/index.ts
new file mode 100644
index 0000000000..899040d2ef
--- /dev/null
+++ b/packages/plugins/robot/src/components/icons/index.ts
@@ -0,0 +1,3 @@
+export { default as IconMcp } from './mcp-icon.vue'
+export { default as IconPage } from './page-icon.vue'
+export { default as IconStudy } from './study-icon.vue'
diff --git a/packages/plugins/robot/src/components/icons/mcp-icon.vue b/packages/plugins/robot/src/components/icons/mcp-icon.vue
new file mode 100644
index 0000000000..3f2c48996c
--- /dev/null
+++ b/packages/plugins/robot/src/components/icons/mcp-icon.vue
@@ -0,0 +1,30 @@
+
+
+
diff --git a/packages/plugins/robot/src/components/icons/page-icon.vue b/packages/plugins/robot/src/components/icons/page-icon.vue
new file mode 100644
index 0000000000..bd54f58f23
--- /dev/null
+++ b/packages/plugins/robot/src/components/icons/page-icon.vue
@@ -0,0 +1,31 @@
+
+
+
diff --git a/packages/plugins/robot/src/components/icons/study-icon.vue b/packages/plugins/robot/src/components/icons/study-icon.vue
new file mode 100644
index 0000000000..40a0d1245a
--- /dev/null
+++ b/packages/plugins/robot/src/components/icons/study-icon.vue
@@ -0,0 +1,30 @@
+
+
+
diff --git a/packages/plugins/robot/src/components/renderers/AgentRenderer.vue b/packages/plugins/robot/src/components/renderers/AgentRenderer.vue
new file mode 100644
index 0000000000..a13a7e710c
--- /dev/null
+++ b/packages/plugins/robot/src/components/renderers/AgentRenderer.vue
@@ -0,0 +1,109 @@
+
+
+
+
+ {{ statusData.title }}
+ {{ statusData.content }}
+
+
+
+
+
+
+
diff --git a/packages/plugins/robot/src/components/renderers/ImgRenderer.vue b/packages/plugins/robot/src/components/renderers/ImgRenderer.vue
new file mode 100644
index 0000000000..00bca0c3f8
--- /dev/null
+++ b/packages/plugins/robot/src/components/renderers/ImgRenderer.vue
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
diff --git a/packages/plugins/robot/src/components/renderers/LoadingRenderer.vue b/packages/plugins/robot/src/components/renderers/LoadingRenderer.vue
new file mode 100644
index 0000000000..86f4891786
--- /dev/null
+++ b/packages/plugins/robot/src/components/renderers/LoadingRenderer.vue
@@ -0,0 +1,3 @@
+
+
+
diff --git a/packages/plugins/robot/src/components/renderers/MarkdownRenderer.vue b/packages/plugins/robot/src/components/renderers/MarkdownRenderer.vue
new file mode 100644
index 0000000000..90fbb860b5
--- /dev/null
+++ b/packages/plugins/robot/src/components/renderers/MarkdownRenderer.vue
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
diff --git a/packages/plugins/robot/src/components/renderers/index.ts b/packages/plugins/robot/src/components/renderers/index.ts
new file mode 100644
index 0000000000..c0ff88e1d4
--- /dev/null
+++ b/packages/plugins/robot/src/components/renderers/index.ts
@@ -0,0 +1,4 @@
+export { default as LoadingRenderer } from './LoadingRenderer.vue'
+export { default as ImgRenderer } from './ImgRenderer.vue'
+export { default as AgentRenderer } from './AgentRenderer.vue'
+export { default as MarkdownRenderer } from './MarkdownRenderer.vue'
diff --git a/packages/plugins/robot/src/composables/core/pageUpdater.ts b/packages/plugins/robot/src/composables/core/pageUpdater.ts
new file mode 100644
index 0000000000..25084b87bd
--- /dev/null
+++ b/packages/plugins/robot/src/composables/core/pageUpdater.ts
@@ -0,0 +1,82 @@
+import { jsonrepair } from 'jsonrepair'
+import * as jsonpatch from 'fast-json-patch'
+import { utils } from '@opentiny/tiny-engine-utils'
+import { useCanvas, useHistory } from '@opentiny/tiny-engine-meta-register'
+import { useThrottleFn } from '@vueuse/core'
+import useModelConfig from './useConfig'
+import { ChatMode } from '../../types/mode.types'
+import { fixMethods, schemaAutoFix, getJsonObjectString, isValidFastJsonPatch, jsonPatchAutoFix } from '../../utils'
+
+const { deepClone } = utils
+
+const logger = console
+
+const setSchema = (schema: object) => {
+ const { importSchema, setSaved } = useCanvas()
+ importSchema(schema)
+ setSaved(false)
+}
+
+type UpdateResult =
+ | undefined
+ | { isError: false; schema: object; error?: undefined }
+ | { isError: true; schema?: undefined; error: unknown }
+
+const _updatePageSchema = (
+ streamContent: string,
+ currentPageSchema: object,
+ isFinal: boolean = false
+): UpdateResult => {
+ const { getSelectedModelInfo } = useModelConfig()
+ if (getSelectedModelInfo().config?.chatMode !== ChatMode.Agent) {
+ return
+ }
+
+ // 解析流式返回的schema patch
+ let content = getJsonObjectString(streamContent)
+ let jsonPatches = []
+ try {
+ if (!isFinal) {
+ content = jsonrepair(content)
+ }
+ jsonPatches = JSON.parse(content)
+ } catch (error) {
+ if (isFinal) {
+ logger.error('parse json patch error:', error)
+ }
+ return { isError: true, error }
+ }
+
+ // 过滤有效的json patch
+ if (!isFinal && !isValidFastJsonPatch(jsonPatches)) {
+ return { isError: true, error: 'format error: not a valid json patch.' }
+ }
+ const validJsonPatches = jsonPatchAutoFix(jsonPatches, isFinal)
+
+ // 生成新schema
+ const originSchema = deepClone(currentPageSchema)
+ const newSchema = validJsonPatches.reduce((acc: object, patch: any) => {
+ try {
+ return jsonpatch.applyPatch(acc, [patch], false, false).newDocument
+ } catch (error) {
+ if (isFinal) {
+ logger.error('apply patch error:', error, patch)
+ }
+ return acc
+ }
+ }, originSchema)
+
+ // schema纠错
+ fixMethods(newSchema.methods)
+ schemaAutoFix(newSchema.children)
+
+ // 更新Schema
+ setSchema(newSchema)
+ if (isFinal) {
+ useHistory().addHistory()
+ }
+
+ return { schema: newSchema, isError: false }
+}
+
+export const updatePageSchema = useThrottleFn(_updatePageSchema, 200, true)
diff --git a/packages/plugins/robot/src/composables/core/useConfig.ts b/packages/plugins/robot/src/composables/core/useConfig.ts
new file mode 100644
index 0000000000..01908a89a0
--- /dev/null
+++ b/packages/plugins/robot/src/composables/core/useConfig.ts
@@ -0,0 +1,468 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+/* metaService: engine.plugins.robot.useRobot */
+import { reactive, readonly } from 'vue'
+import { DEFAULT_LLM_MODELS } from '../../constants'
+import { getRobotServiceOptions } from '../../utils'
+import { ChatMode } from '../../types/mode.types'
+import type { ModelConfig, ModelService, RobotSettings, SelectedModelInfo } from '../../types/setting.types'
+import apiService from '../../services/api'
+
+const SETTING_STORAGE_KEY = 'tiny-engine-robot-settings'
+const SETTING_VERSION = 2 // 新版本号
+
+const robotSettingState = reactive({
+ version: SETTING_VERSION,
+ defaultModel: {
+ serviceId: '',
+ modelName: ''
+ },
+ quickModel: {
+ serviceId: '',
+ modelName: ''
+ },
+ services: [],
+ chatMode: ChatMode.Agent,
+ enableThinking: false
+})
+
+const getAIModelOptions = () => {
+ const customAIModels = getRobotServiceOptions()?.customCompatibleAIModels || []
+ if (!customAIModels.length) {
+ return DEFAULT_LLM_MODELS
+ }
+ return mergeAIModelOptions(DEFAULT_LLM_MODELS, customAIModels) // eslint-disable-line
+}
+
+// 初始化内置服务
+const initBuiltInServices = (): ModelService[] => {
+ return getAIModelOptions().map((service: any) => ({
+ id: service.provider,
+ provider: service.provider,
+ label: service.label,
+ baseUrl: service.baseUrl,
+ apiKey: '',
+ allowEmptyApiKey: service.allowEmptyApiKey ?? false,
+ isBuiltIn: true,
+ models: service.models
+ }))
+}
+
+// 初始化默认配置
+const initDefaultSettings = (): RobotSettings => {
+ const builtInServices = initBuiltInServices()
+ const firstService = builtInServices[0]
+ const firstModel = firstService?.models[0]
+
+ return {
+ version: SETTING_VERSION,
+ defaultModel: {
+ serviceId: firstService?.id || '',
+ modelName: firstModel?.name || ''
+ },
+ quickModel: {
+ serviceId: '',
+ modelName: ''
+ },
+ services: builtInServices,
+ chatMode: ChatMode.Agent,
+ enableThinking: false
+ }
+}
+
+// 数据迁移:从旧版本格式迁移到新版本
+const migrateOldSettings = (oldSettings: any): RobotSettings | null => {
+ if (!oldSettings || oldSettings.version === SETTING_VERSION) {
+ return null
+ }
+
+ const { activeName, existModel, customizeModel, chatMode, enableThinking } = oldSettings
+ const builtInServices = initBuiltInServices()
+ const services: ModelService[] = [...builtInServices]
+
+ // 迁移旧的配置到services中
+ if (activeName === 'existingModels' && existModel) {
+ const service = services.find((s) => s.baseUrl === existModel.baseUrl)
+ if (service) {
+ service.apiKey = existModel.apiKey || ''
+ }
+ }
+
+ // 迁移自定义模型
+ if (activeName === 'customize' && customizeModel?.baseUrl) {
+ const customService: ModelService = {
+ id: `custom_${Date.now()}`,
+ provider: 'custom',
+ label: '自定义服务',
+ baseUrl: customizeModel.baseUrl,
+ apiKey: customizeModel.apiKey || '',
+ allowEmptyApiKey: false,
+ isBuiltIn: false,
+ models: [
+ {
+ name: customizeModel.model || 'default',
+ label: customizeModel.model || '默认模型',
+ capabilities: {}
+ }
+ ]
+ }
+ if (customizeModel.completeModel) {
+ customService.models.push({
+ name: customizeModel.completeModel,
+ label: customizeModel.completeModel,
+ capabilities: { compact: true }
+ })
+ }
+ services.push(customService)
+ }
+
+ // 确定默认模型和快速模型
+ const selectedModel = activeName === 'existingModels' ? existModel : customizeModel
+ const defaultServiceId =
+ activeName === 'existingModels' ? services.find((s) => s.baseUrl === selectedModel?.baseUrl)?.id : ''
+
+ return {
+ version: SETTING_VERSION,
+ defaultModel: {
+ serviceId: defaultServiceId || services[0]?.id || '',
+ modelName: selectedModel?.model || services[0]?.models[0]?.name || ''
+ },
+ quickModel: {
+ serviceId: defaultServiceId || '',
+ modelName: selectedModel?.completeModel || ''
+ },
+ services,
+ chatMode: chatMode || ChatMode.Agent,
+ enableThinking: enableThinking || false
+ } as RobotSettings
+}
+
+const loadRobotSettingState = (): RobotSettings | null => {
+ const items = localStorage.getItem(SETTING_STORAGE_KEY)
+ if (!items) {
+ return null
+ }
+ try {
+ const parsed = JSON.parse(items)
+ // 如果是旧版本,进行迁移
+ if (!parsed.version || parsed.version < SETTING_VERSION) {
+ const migrated = migrateOldSettings(parsed)
+ if (migrated) {
+ saveRobotSettingState(migrated) // eslint-disable-line
+ return migrated
+ }
+ }
+ return parsed
+ } catch (error) {
+ return null
+ }
+}
+
+const saveRobotSettingState = (state: Partial, updateState = true) => {
+ if (updateState) {
+ Object.assign(robotSettingState, state)
+ }
+ const currentState = loadRobotSettingState() || initDefaultSettings()
+ const newState = { ...currentState, ...state, version: SETTING_VERSION }
+ localStorage.setItem(SETTING_STORAGE_KEY, JSON.stringify(newState))
+}
+
+/**
+ * 合并默认模型服务配置和用户自定义配置
+ * @param defaults 默认的模型服务配置列表
+ * @param customs 用户自定义的模型服务配置列表
+ * @returns 合并后的模型服务配置列表
+ *
+ * 支持的操作:
+ * 1. 删除整个服务:{ provider: 'deepseek', _remove: true }
+ * 2. 修改服务属性:{ provider: 'qwen', label: '新名称', baseUrl: '新地址' }
+ * 3. 删除服务中的模型:{ provider: 'qwen', models: [{ name: 'qwen3-8b', _remove: true }] }
+ * 4. 添加新模型:{ provider: 'qwen', models: [{ name: 'new-model', label: '新模型' }] }
+ * 5. 覆盖模型配置:{ provider: 'qwen', models: [{ name: 'qwen-plus', label: '新标签', capabilities: {...} }] }
+ * 6. 添加新服务:{ provider: 'openai', label: 'OpenAI', baseUrl: '...', models: [...] }
+ */
+const mergeAIModelOptions = (defaults: any[], customs: any[]): any[] => {
+ // 深拷贝默认配置作为基础
+ const result = JSON.parse(JSON.stringify(defaults))
+
+ customs.forEach((customProvider) => {
+ // 如果标记删除整个 provider(基于 provider 名称匹配)
+ if (customProvider._remove) {
+ const index = result.findIndex((p: any) => p.provider === customProvider.provider)
+ if (index !== -1) {
+ result.splice(index, 1)
+ }
+ return
+ }
+
+ // 查找相同 provider 名称的服务
+ const existingProviderIndex = result.findIndex((p: any) => p.provider === customProvider.provider)
+
+ if (existingProviderIndex !== -1) {
+ // 找到相同 provider 的服务,合并配置
+ const existingProvider = result[existingProviderIndex]
+
+ // 更新服务的其他属性(如果提供了)
+ if (customProvider.label !== undefined) existingProvider.label = customProvider.label
+ if (customProvider.baseUrl !== undefined) existingProvider.baseUrl = customProvider.baseUrl
+ if (customProvider.allowEmptyApiKey !== undefined)
+ existingProvider.allowEmptyApiKey = customProvider.allowEmptyApiKey
+
+ // 合并 models
+ customProvider.models?.forEach((customModel: any) => {
+ if (customModel._remove) {
+ // 移除指定的 model
+ const modelIndex = existingProvider.models.findIndex((m: any) => m.name === customModel.name)
+ if (modelIndex !== -1) {
+ existingProvider.models.splice(modelIndex, 1)
+ }
+ } else {
+ // 查找是否存在相同 name 的 model
+ const existingModelIndex = existingProvider.models.findIndex((m: any) => m.name === customModel.name)
+ if (existingModelIndex !== -1) {
+ // 替换已有 model(覆盖)
+ const { _remove, ...modelWithoutRemove } = customModel
+ existingProvider.models[existingModelIndex] = modelWithoutRemove
+ } else {
+ // 添加新 model
+ const { _remove, ...modelWithoutRemove } = customModel
+ existingProvider.models.push(modelWithoutRemove)
+ }
+ }
+ })
+ } else {
+ // 添加新的 provider
+ const { _remove, ...providerWithoutRemove } = customProvider
+ // 过滤掉标记为删除的模型
+ providerWithoutRemove.models = (providerWithoutRemove.models || [])
+ .filter((m: any) => !m._remove)
+ .map((m: any) => {
+ const { _remove, ...modelWithoutRemove } = m
+ return modelWithoutRemove
+ })
+ result.push(providerWithoutRemove)
+ }
+ })
+
+ return result
+}
+
+// 合并缓存的服务与内置的服务,解决部分场景下缓存配置中丢失了内置服务的问题
+const mergeServices = (services: ModelService[] = [], builtInServices: ModelService[]): ModelService[] => {
+ const cachedServiceMap = new Map(services.map((s) => [s.id, s]))
+ const result: ModelService[] = []
+
+ builtInServices.forEach((builtIn) => {
+ const cached = cachedServiceMap.get(builtIn.id)
+ if (cached) {
+ result.push({
+ ...builtIn,
+ apiKey: cached.apiKey || ''
+ })
+ cachedServiceMap.delete(builtIn.id)
+ } else {
+ result.push({ ...builtIn })
+ }
+ })
+
+ cachedServiceMap.forEach((service) => {
+ if (!service.isBuiltIn) {
+ result.push(service)
+ }
+ })
+
+ return result
+}
+
+export const init = () => {
+ let settingState = loadRobotSettingState()
+ if (!settingState) {
+ settingState = initDefaultSettings()
+ } else {
+ settingState.services = mergeServices(settingState.services, initBuiltInServices())
+ }
+ saveRobotSettingState(settingState)
+}
+
+// 根据serviceId和modelName获取模型能力
+const getModelCapabilities = (serviceId: string, modelName: string) => {
+ if (!serviceId || !modelName) {
+ return null
+ }
+ const service = robotSettingState.services.find((s) => s.id === serviceId)
+ return service?.models.find((m) => m.name === modelName)?.capabilities
+}
+
+// 获取所有可用模型(扁平化)
+const getAllAvailableModels = () => {
+ return robotSettingState.services.flatMap((service) =>
+ service.models.map((model) => ({
+ serviceId: service.id,
+ serviceName: service.label,
+ modelName: model.name,
+ modelLabel: model.label,
+ capabilities: model.capabilities || {},
+ displayLabel: `${service.label} - ${model.label}`,
+ value: `${service.id}::${model.name}`
+ }))
+ )
+}
+
+// 获取快速模型列表
+const getCompactModels = () => {
+ return getAllAvailableModels().filter((model) => model.capabilities?.compact)
+}
+
+const updateThinkingState = (value: boolean) => {
+ robotSettingState.enableThinking = value
+ saveRobotSettingState({ enableThinking: robotSettingState.enableThinking })
+}
+
+const updateChatModeState = (value: string) => {
+ robotSettingState.chatMode = value
+ saveRobotSettingState({ chatMode: robotSettingState.chatMode })
+}
+
+const encryptServiceApiKey = async (apiKey: string): Promise => {
+ if (!apiKey || !getRobotServiceOptions()?.encryptServiceApiKey || apiKey.startsWith('EKEY_')) return apiKey
+
+ try {
+ const { token } = await apiService.encryptKey(apiKey)
+ return token
+ } catch (error) {
+ const logger = console
+ logger.error('加密API密钥失败', error)
+ return apiKey
+ }
+}
+
+// 服务管理方法
+const addCustomService = async (service: Omit) => {
+ const newService: ModelService = {
+ ...service,
+ id: `custom_${Date.now()}`,
+ isBuiltIn: false,
+ apiKey: await encryptServiceApiKey(service.apiKey)
+ }
+ robotSettingState.services.push(newService)
+ saveRobotSettingState({ services: robotSettingState.services }, false)
+ return newService.id
+}
+
+const updateService = async (serviceId: string, updates: Partial) => {
+ const index = robotSettingState.services.findIndex((s) => s.id === serviceId)
+ if (index !== -1) {
+ Object.assign(robotSettingState.services[index], {
+ ...updates,
+ ...('apiKey' in updates ? { apiKey: await encryptServiceApiKey(updates.apiKey || '') } : {})
+ })
+ saveRobotSettingState({ services: robotSettingState.services }, false)
+ }
+}
+
+const deleteService = (serviceId: string) => {
+ const index = robotSettingState.services.findIndex((s) => s.id === serviceId)
+ if (index !== -1 && !robotSettingState.services[index].isBuiltIn) {
+ robotSettingState.services.splice(index, 1)
+ saveRobotSettingState({ services: robotSettingState.services }, false)
+ }
+}
+
+const getServiceById = (serviceId: string) => {
+ return robotSettingState.services.find((s) => s.id === serviceId)
+}
+
+// 获取当前选择的对话模型信息
+const getSelectedModelInfo = (): SelectedModelInfo => {
+ const currentService: ModelService | undefined = getServiceById(robotSettingState.defaultModel.serviceId)
+ const currentModel: ModelConfig | undefined = currentService?.models.find(
+ (m) => m.name === robotSettingState.defaultModel.modelName
+ )
+ const { name = '', label = '', capabilities = {} } = currentModel || {}
+
+ const { models, ...service } = currentService ?? ({} as Partial)
+
+ return {
+ // 模型
+ name,
+ label,
+ capabilities,
+ // 服务
+ service: (currentService ? service : null) as ModelService | null,
+
+ // 配置
+ config: {
+ chatMode: robotSettingState.chatMode,
+ enableThinking: robotSettingState.enableThinking
+ },
+
+ // 模型兼容字段
+ model: robotSettingState.defaultModel.modelName,
+ // 服务兼容字段
+ baseUrl: currentService?.baseUrl || '',
+ apiKey: currentService?.apiKey || ''
+ }
+}
+
+const getSelectedQuickModelInfo = (): SelectedModelInfo => {
+ const currentService: ModelService | undefined = getServiceById(robotSettingState.quickModel.serviceId)
+ const currentModel: ModelConfig | undefined = currentService?.models.find(
+ (m) => m.name === robotSettingState.quickModel.modelName
+ )
+ const { name = '', label = '', capabilities = {} } = currentModel || {}
+
+ const { models, ...service } = currentService ?? ({} as Partial)
+
+ return {
+ // 模型
+ name,
+ label,
+ capabilities,
+ // 服务
+ service: (currentService ? service : null) as ModelService | null,
+
+ // 模型兼容字段
+ model: robotSettingState.quickModel.modelName,
+ completeModel: robotSettingState.quickModel.modelName || '',
+ // 服务兼容字段
+ baseUrl: currentService?.baseUrl || '',
+ apiKey: currentService?.apiKey || ''
+ }
+}
+
+export default () => {
+ return {
+ // 配置状态
+ robotSettingState: readonly(robotSettingState),
+
+ // 状态更新与数据持久化
+ updateThinkingState,
+ updateChatModeState,
+ saveRobotSettingState,
+ loadRobotSettingState,
+
+ // 模型相关
+ getAIModelOptions, // 合并后的模型配置
+ getModelCapabilities,
+ getAllAvailableModels,
+ getCompactModels,
+ getSelectedModelInfo, // 对话模型信息
+ getSelectedQuickModelInfo, // 快速模型信息
+
+ // 服务管理
+ addCustomService,
+ updateService,
+ deleteService,
+ getServiceById
+ }
+}
diff --git a/packages/plugins/robot/src/composables/core/useConversation.ts b/packages/plugins/robot/src/composables/core/useConversation.ts
new file mode 100644
index 0000000000..7c0da5e7e4
--- /dev/null
+++ b/packages/plugins/robot/src/composables/core/useConversation.ts
@@ -0,0 +1,118 @@
+import { toRaw } from 'vue'
+import { useConversation as useConversationKit, type UseMessageOptions } from '@opentiny/tiny-robot-kit'
+import type { AIClient } from '@opentiny/tiny-robot-kit'
+
+export interface ConversationAdapterOptions {
+ client: AIClient
+ // 业务回调函数
+ onStreamData: (data: any, messages: any[]) => void
+ onFinishRequest: (finishReason: string, messages: any[], contextMessages: any[], messageState: any) => Promise
+ onMessageProcessed: (finishReason: string, content: any, messages: any[], context: any) => Promise
+ statusManager: {
+ isProcessing: () => boolean
+ setProcessing: () => void
+ }
+}
+
+export interface ConversationMetadata {
+ chatMode?: string
+ [key: string]: any
+}
+
+/**
+ * Conversation 适配器
+ * 将 tiny-robot-kit 的 useConversation 与业务逻辑解耦
+ */
+export function useConversationAdapter(options: ConversationAdapterOptions) {
+ const { client, onStreamData, onFinishRequest, onMessageProcessed, statusManager } = options
+
+ // 构建 events 适配器,连接业务回调
+ const events: UseMessageOptions['events'] = {
+ onReceiveData: (data, messages, preventDefault) => {
+ preventDefault()
+ onStreamData(data, messages.value)
+ },
+ async onFinish(finishReason, { messages, messageState }, preventDefault) {
+ preventDefault()
+ if (statusManager.isProcessing()) {
+ // 无效场景,直接返回,例如返回流中出现了多次 [Done], 只响应第一次
+ return
+ } else {
+ statusManager.setProcessing()
+ }
+ const contextMessages = toRaw(messages.value.slice(0, -1))
+ await onFinishRequest(finishReason ?? 'unknown', messages.value, contextMessages, messageState)
+ const lastMessage = messages.value.at(-1)
+ if (lastMessage) {
+ await onMessageProcessed(finishReason ?? 'unknown', lastMessage.content ?? '', messages.value, {})
+ }
+ }
+ }
+
+ // 使用 tiny-robot-kit 的 useConversation
+ const {
+ messageManager,
+ state: conversationState,
+ ...conversationMethods
+ } = useConversationKit({
+ client,
+ events
+ })
+
+ /**
+ * 创建新会话
+ * @param title 会话标题
+ * @param metadata 会话元数据(如 chatMode)
+ */
+ const createConversation = (title: string, metadata?: ConversationMetadata) => {
+ return conversationMethods.createConversation(title, metadata)
+ }
+
+ /**
+ * 切换会话
+ * @param conversationId 会话ID
+ * @param onStart 切换成功后的回调
+ */
+ const switchConversation = (conversationId: string, onStart?: (state: any, messages: any, methods: any) => void) => {
+ const conversation = conversationState.conversations.find((c) => c.id === conversationId)
+ if (!conversation) return
+
+ const result = conversationMethods.switchConversation(conversationId)
+
+ // 触发业务回调
+ if (onStart) {
+ onStart(conversationState, messageManager.messages.value, conversationMethods)
+ }
+
+ return result
+ }
+
+ /**
+ * 自动设置会话标题
+ * @param currentId 当前会话ID
+ * @param defaultTitle 默认标题
+ */
+ const autoSetTitle = (currentId: string, defaultTitle = '新会话') => {
+ const currentConversation = conversationState.conversations.find((conversation) => conversation.id === currentId)
+ if (!currentConversation) return
+
+ const currentTitle = currentConversation?.title
+ if (currentTitle === defaultTitle && currentId) {
+ const messageContent = currentConversation.messages.find((item) => item.role === 'user')?.content
+ const contentStr = typeof messageContent === 'string' ? messageContent : JSON.stringify(messageContent)
+ conversationMethods.updateTitle(currentId, contentStr.substring(0, 20))
+ }
+ }
+
+ return {
+ // 消息管理器
+ messageManager,
+ // 会话状态
+ conversationState,
+ // 会话方法(包装后,覆盖原始方法)
+ ...conversationMethods,
+ createConversation,
+ switchConversation,
+ autoSetTitle
+ }
+}
diff --git a/packages/plugins/robot/src/composables/core/useMessageStream.ts b/packages/plugins/robot/src/composables/core/useMessageStream.ts
new file mode 100644
index 0000000000..bbf2bd3665
--- /dev/null
+++ b/packages/plugins/robot/src/composables/core/useMessageStream.ts
@@ -0,0 +1,115 @@
+import type { ChatCompletionStreamResponseChoice } from '@opentiny/tiny-robot-kit'
+import type { Message, ResponseToolCall } from '../../types'
+import { mergeStringFields } from '../../utils'
+
+// 流式数据处理器配置选项
+export interface StreamDataHandlerOptions {
+ getContentType: () => string
+ hooks: {
+ onStreamStart: (messages: any[]) => void
+ onStreamData: (data: any, content: any, messages: any[]) => void
+ onStreamTools: (tools: any[], context: { currentMessage: any }) => void
+ }
+ statusManager: {
+ isStreaming: () => boolean
+ setStreaming: () => void
+ }
+}
+
+const handleDeltaReasoning = (choice: ChatCompletionStreamResponseChoice, lastMessage: Message) => {
+ if (typeof choice.delta.reasoning_content === 'string' && choice.delta.reasoning_content) {
+ if (lastMessage.renderContent.at(-1)?.contentType !== 'reasoning') {
+ lastMessage.renderContent.push({
+ type: 'collapsible-text',
+ contentType: 'reasoning',
+ title: '深度思考',
+ content: '',
+ status: 'reasoning',
+ defaultOpen: true
+ })
+ }
+ lastMessage.renderContent.at(-1)!.content += choice.delta.reasoning_content
+ }
+}
+
+const handleDeltaContent = (
+ choice: ChatCompletionStreamResponseChoice,
+ lastMessage: Message,
+ contentType = 'markdown'
+) => {
+ if (typeof choice.delta.content === 'string' && choice.delta.content) {
+ if (lastMessage.renderContent.at(-1)?.contentType === 'reasoning') {
+ lastMessage.renderContent.at(-1)!.status = 'finish'
+ }
+ if (lastMessage.renderContent.at(-1)?.type !== contentType) {
+ lastMessage.renderContent.push({ type: contentType, content: '' })
+ lastMessage.content = ''
+ }
+ lastMessage.renderContent.at(-1)!.content += choice.delta.content
+ lastMessage.content += choice.delta.content
+ }
+}
+
+const handleDeltaToolCalls = (choice: ChatCompletionStreamResponseChoice, lastMessage: Message) => {
+ const toolCallChunks = choice.delta.tool_calls as (ResponseToolCall & { index: number })[]
+ if (Array.isArray(toolCallChunks) && toolCallChunks.length) {
+ if (!lastMessage.tool_calls) {
+ lastMessage.tool_calls = []
+ }
+ for (const chunk of toolCallChunks) {
+ const { index, ...chunkWithoutIndex } = chunk
+ if (lastMessage.tool_calls[index]) {
+ mergeStringFields(lastMessage.tool_calls[index], chunkWithoutIndex)
+ } else {
+ lastMessage.tool_calls[index] = chunkWithoutIndex
+ }
+ }
+ }
+}
+
+/**
+ * 创建流式数据处理器
+ * 通过依赖注入解耦业务逻辑与状态管理、回调函数
+ * @param options 配置选项,包含内容类型获取、钩子函数、状态管理器
+ * @returns 流式数据处理函数
+ */
+export function createStreamDataHandler(options: StreamDataHandlerOptions) {
+ const { getContentType, hooks, statusManager } = options
+
+ return (data: any, messages: any[]) => {
+ const choice = data.choices?.[0]
+ if (!choice) {
+ return
+ }
+
+ const lastMessage = messages.at(-1) as Message
+
+ // 处理首次流式响应
+ if (!statusManager.isStreaming()) {
+ statusManager.setStreaming()
+ hooks.onStreamStart(messages)
+ }
+
+ // 核心流式处理逻辑
+ handleDeltaReasoning(choice, lastMessage)
+ handleDeltaContent(choice, lastMessage, getContentType())
+ handleDeltaToolCalls(choice, lastMessage)
+
+ // 触发钩子
+ if (typeof choice.delta.content === 'string' && choice.delta.content) {
+ hooks.onStreamData(data, lastMessage.content, messages)
+ }
+ if (choice.delta.tool_calls?.length) {
+ hooks.onStreamTools(lastMessage.tool_calls || [], { currentMessage: lastMessage })
+ }
+ }
+}
+
+export default function useMessageStream() {
+ return {
+ handleDeltaReasoning,
+ handleDeltaContent,
+ handleDeltaToolCalls,
+ createStreamDataHandler
+ }
+}
diff --git a/packages/plugins/robot/src/composables/features/useMcp.ts b/packages/plugins/robot/src/composables/features/useMcp.ts
new file mode 100644
index 0000000000..c25b346552
--- /dev/null
+++ b/packages/plugins/robot/src/composables/features/useMcp.ts
@@ -0,0 +1,137 @@
+import { computed, ref } from 'vue'
+import type { PluginInfo, PluginTool } from '@opentiny/tiny-robot'
+import { getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register'
+import type { McpTool } from '../../types/mcp.types'
+import type { RequestTool } from '../../types/chat.types'
+
+const ENGINE_MCP_SERVER: PluginInfo = {
+ id: 'tiny-engine-mcp-server',
+ name: 'Tiny Engine MCP 工具',
+ icon: 'https://res.hc-cdn.com/lowcode-portal/1.1.80.20250515160330/assets/opentiny-tinyengine-logo-4f8a3801.svg',
+ description: '使用TinyEngine设计器能力,如操作画布、编辑页面等',
+ added: true
+}
+
+const inUseMcpServers = ref([{ ...ENGINE_MCP_SERVER, enabled: true, expanded: true, tools: [] }])
+
+const updateServerTools = (serverId: string, tools: PluginTool[]) => {
+ const mcpServer = inUseMcpServers.value.find((item) => item.id === serverId)
+ if (mcpServer) {
+ mcpServer.tools = tools
+ }
+}
+
+const updateEngineTools = async () => {
+ const tools: Array<{ name: string; description: string; status: string; title?: string }> =
+ (await getMetaApi(META_SERVICE.McpService)?.getToolList?.()) || []
+ const engineTools = tools.map((tool) => ({
+ id: tool.name,
+ name: tool.title ? `${tool.title} ${tool.name}` : tool.name,
+ description: tool.description,
+ enabled: tool.status === 'enabled'
+ }))
+ updateServerTools(ENGINE_MCP_SERVER.id, engineTools)
+}
+
+const convertMCPToOpenAITools = (mcpTools: McpTool[]): RequestTool[] => {
+ return mcpTools.map((tool: McpTool) => ({
+ type: 'function',
+ function: {
+ name: tool.name,
+ description: tool.description || '',
+ parameters: {
+ type: 'object',
+ properties: Object.fromEntries(
+ Object.entries(tool.inputSchema?.properties || {}).map(([key, prop]: [string, any]) => [key, { ...prop }])
+ ),
+ required: tool.inputSchema?.required || []
+ }
+ }
+ })) as RequestTool[]
+}
+
+const getEngineServer = () => {
+ return inUseMcpServers.value.find((item) => item.id === ENGINE_MCP_SERVER.id)
+}
+
+const isToolsEnabled = computed(() => getEngineServer()?.tools?.some((tool) => tool.enabled))
+
+const updateEngineServerToolStatus = (toolId: string, enabled: boolean) => {
+ getMetaApi(META_SERVICE.McpService)?.updateTool?.(toolId, { enabled })
+}
+
+const updateEngineServer = (engineServer: PluginInfo, enabled: boolean) => {
+ engineServer?.tools?.forEach((tool) => {
+ tool.enabled = enabled
+ updateEngineServerToolStatus(tool.id, enabled)
+ })
+}
+
+const updateMcpServerStatus = async (server: PluginInfo, added: boolean) => {
+ // 市场添加状态修改
+ server.added = added
+ if (added) {
+ const newServer: PluginInfo = {
+ ...server,
+ id: server.id || `mcp-server-${Date.now()}`,
+ enabled: true,
+ added: true,
+ expanded: false,
+ tools: server.tools || []
+ }
+ inUseMcpServers.value.push(newServer)
+ if (server.id === ENGINE_MCP_SERVER.id) {
+ await updateEngineTools()
+ updateEngineServer(newServer, added)
+ }
+ } else {
+ const index = inUseMcpServers.value.findIndex((p) => p.id === server.id)
+ if (index > -1) {
+ updateEngineServer(inUseMcpServers.value[index], added)
+ inUseMcpServers.value.splice(index, 1)
+ }
+ }
+}
+
+const updateMcpServerToolStatus = (currentServer: PluginInfo, toolId: string, enabled: boolean) => {
+ const tool = currentServer.tools?.find((t: PluginTool) => t.id === toolId)
+ if (tool) {
+ tool.enabled = enabled
+ if (currentServer.id === ENGINE_MCP_SERVER.id) {
+ updateEngineServerToolStatus(toolId, enabled)
+ }
+ }
+}
+
+const refreshMcpServerTools = () => {
+ updateEngineTools()
+}
+
+let llmTools: RequestTool[] | null = null
+
+const listTools = async (): Promise => {
+ const mcpTools = await getMetaApi(META_SERVICE.McpService)?.getMcpClient()?.listTools()
+ return mcpTools?.tools || []
+}
+
+const callTool = async (toolId: string, args: Record) =>
+ getMetaApi(META_SERVICE.McpService)?.getMcpClient()?.callTool({ name: toolId, arguments: args }) || {}
+
+const getLLMTools = async () => {
+ const mcpTools = await getMetaApi(META_SERVICE.McpService)?.getMcpClient()?.listTools()
+ llmTools = convertMCPToOpenAITools(mcpTools?.tools || [])
+ return llmTools
+}
+
+export default function useMcpServer() {
+ return {
+ inUseMcpServers,
+ refreshMcpServerTools,
+ updateMcpServerStatus,
+ updateMcpServerToolStatus,
+ listTools,
+ callTool,
+ getLLMTools,
+ isToolsEnabled
+ }
+}
diff --git a/packages/plugins/robot/src/composables/features/useToolCalls.ts b/packages/plugins/robot/src/composables/features/useToolCalls.ts
new file mode 100644
index 0000000000..444be154eb
--- /dev/null
+++ b/packages/plugins/robot/src/composables/features/useToolCalls.ts
@@ -0,0 +1,132 @@
+import { toRaw } from 'vue'
+import type { AIClient } from '@opentiny/tiny-robot-kit'
+import useMcpServer from './useMcp'
+import { serializeError } from '../../utils'
+import type { ResponseToolCall, RobotMessage, LLMMessage } from '../../types'
+
+const parseArgs = (args: string) => {
+ try {
+ return JSON.parse(args)
+ } catch (error) {
+ return args
+ }
+}
+
+const callTool = async (name: string, args: Record) => {
+ let toolCallResult: object | string
+ let toolCallStatus: 'success' | 'failed'
+ try {
+ const resp = await useMcpServer().callTool(name, args)
+ toolCallStatus = 'success'
+ toolCallResult = resp.content
+ } catch (error) {
+ toolCallStatus = 'failed'
+ toolCallResult = serializeError(error)
+ }
+ return { toolCallResult, toolCallStatus }
+}
+
+interface CallToolHooks {
+ onBeforeCallTool: (tool: Record) => void
+ onPostCallTool: (tool: Record, toolCallResult: object | string, toolCallStatus: string) => void
+}
+
+export const callTools = async (tool_calls: any, hooks: CallToolHooks, signal: AbortController['signal']) => {
+ const result = []
+ for (const tool of tool_calls) {
+ const { name, arguments: args } = tool.function
+ const parsedArgs = parseArgs(args)
+ tool.parsedArgs = parsedArgs
+ tool.name = name
+
+ hooks.onBeforeCallTool(tool)
+
+ const { toolCallResult, toolCallStatus } = await callTool(name, parsedArgs)
+ result.push({ toolCallResult, toolCallStatus, ...tool })
+
+ hooks.onPostCallTool(tool, toolCallResult, toolCallStatus)
+
+ if (signal?.aborted) {
+ return Promise.reject('aborted')
+ }
+ }
+ return result
+}
+
+// 工厂函数配置接口
+export interface ToolCallHandlerConfig {
+ client: AIClient
+ getAbortController: () => AbortController
+ formatMessages: (messages: any[]) => LLMMessage[]
+ hooks: {
+ onBeforeCallTool: (tool: Record, context: { currentMessage: any }) => void
+ onPostCallTool: (
+ tool: Record,
+ toolCallResult: object | string,
+ toolCallStatus: string,
+ context: { currentMessage: any }
+ ) => void
+ onPostCallTools: (results: any[], context: { currentMessage: any }) => void
+ }
+ streamHandlers: {
+ onData: (data: any, messages: any[]) => void
+ onError: (error: any, messages: any[], messageState: any) => void
+ onDone: (finishReason: string, messages: any[], contextMessages: any[], messageState: any) => Promise
+ }
+ getMessageState: () => any
+}
+
+/**
+ * 创建工具调用处理器
+ * 使用工厂函数模式,将所有依赖通过配置注入
+ */
+export function createToolCallHandler(config: ToolCallHandlerConfig) {
+ const { client, getAbortController, formatMessages, hooks, streamHandlers, getMessageState } = config
+
+ return async (tool_calls: ResponseToolCall[], messages: any[], contextMessages: RobotMessage[]) => {
+ const hasToolCall = tool_calls?.length > 0
+ if (!hasToolCall) {
+ return
+ }
+
+ // 获取新的 AbortController
+ const abortController = getAbortController()
+
+ const currentMessage = messages.at(-1)
+ const toolMessages: LLMMessage[] = formatMessages([...contextMessages, toRaw(currentMessage)])
+
+ // 构建工具调用的 hooks
+ const toolCallHooks = {
+ onBeforeCallTool: (tool: Record) => hooks.onBeforeCallTool(tool, { currentMessage }),
+ onPostCallTool: (tool: Record, toolCallResult: object | string, toolCallStatus: string) =>
+ hooks.onPostCallTool(tool, toolCallResult, toolCallStatus, { currentMessage })
+ }
+
+ try {
+ const result = await callTools(tool_calls, toolCallHooks, abortController.signal)
+ toolMessages.push(
+ ...result.map((item) => ({
+ content: JSON.stringify(item.toolCallResult),
+ role: 'tool',
+ tool_call_id: item.id
+ }))
+ )
+ hooks.onPostCallTools(result, { currentMessage })
+ } catch (error) {
+ return
+ }
+
+ delete currentMessage.tool_calls
+
+ // 使用工具调用结果继续对话
+ await client.chatStream(
+ { messages: toolMessages as any, options: { signal: abortController.signal } },
+ {
+ onData: (data) => streamHandlers.onData(data, messages),
+ onError: (error) => streamHandlers.onError(error, messages, getMessageState()),
+ onDone: (finishReason?: string) =>
+ streamHandlers.onDone(finishReason ?? 'unknown', messages, toolMessages, getMessageState())
+ }
+ )
+ }
+}
diff --git a/packages/plugins/robot/src/composables/modes/useAgentMode.ts b/packages/plugins/robot/src/composables/modes/useAgentMode.ts
new file mode 100644
index 0000000000..31b840b7ff
--- /dev/null
+++ b/packages/plugins/robot/src/composables/modes/useAgentMode.ts
@@ -0,0 +1,281 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+import { getMetaApi, META_SERVICE, useCanvas, useMaterial } from '@opentiny/tiny-engine-meta-register'
+import { utils } from '@opentiny/tiny-engine-utils'
+import { isValidJsonPatchObjectString, getRobotServiceOptions, removeLoading, addSystemPrompt } from '../../utils'
+import { updatePageSchema } from '../core/pageUpdater'
+import useModelConfig from '../core/useConfig'
+import { formatComponents, getAgentSystemPrompt, getJsonFixPrompt } from '../../constants/prompts'
+import { search, fetchAssets } from '../../services/agentServices'
+import { client } from '../../services/aiClient'
+import type { ModeHooks } from '../../types/mode.types'
+import { ChatMode } from '../../types/mode.types'
+import { STATUS, type MessageState } from '@opentiny/tiny-robot-kit'
+
+const { deepClone } = utils
+const logger = console
+
+const updateToolCallRenderContent = (tool: Record, renderContent: any[]) => {
+ const currentToolCallContent = renderContent.find((item) => item.type === 'tool' && item.toolCallId === tool.id)
+ if (currentToolCallContent) {
+ currentToolCallContent.status = 'running'
+ if (!currentToolCallContent.content) {
+ currentToolCallContent.content = {}
+ }
+ currentToolCallContent.content.params = tool.parsedArgs || tool.function!.arguments || {}
+ } else {
+ renderContent.push({
+ type: 'tool',
+ name: tool.name || tool.function!.name,
+ status: 'running',
+ content: {
+ params: tool.parsedArgs || tool.function!.arguments || {}
+ },
+ formatPretty: true,
+ toolCallId: tool.id
+ })
+ }
+}
+
+/**
+ * Agent 模式实现
+ * 特点:
+ * - 使用 JSON Patch 更新页面 schema
+ * - 支持 RAG 上下文和资源上下文
+ * - 支持思考模式(thinking)
+ * - 实时更新画布
+ * - JSON 修复机制
+ */
+export default function useAgentMode(): ModeHooks {
+ let pageSchema: object | null = null
+ const { getSelectedModelInfo } = useModelConfig()
+
+ // ========== 配置方法 ==========
+ const getApiUrl = () => 'app-center/api/ai/chat'
+
+ const getContentType = () => 'agent-content'
+
+ const getLoadingType = () => 'agent-loading'
+
+ // ========== 生命周期钩子 ==========
+ const onConversationStart = (conversationState: any, messages: any[], apis: any) => {
+ const conversation = conversationState.conversations.find((item: any) => item.id === conversationState.currentId)
+
+ // 确保会话元数据中记录为 Agent 模式
+ if (!conversation.metadata?.chatMode || conversation.metadata.chatMode !== ChatMode.Agent) {
+ apis.updateMetadata(conversationState.currentId, { chatMode: ChatMode.Agent })
+ apis.saveConversations()
+ }
+
+ // Agent 模式特殊处理:标记失败的 loading
+ messages.at(-1)?.renderContent?.forEach((item: any) => {
+ if (item.type.includes('loading') || item.status !== 'success') {
+ item.status = 'failed'
+ }
+ })
+ }
+
+ const onMessageSent = () => {
+ pageSchema = deepClone(useCanvas().pageState.pageSchema)
+ }
+
+ const onBeforeRequest = async (requestParams: any) => {
+ let referenceContext = ''
+ let imageAssets: any[] = []
+
+ // 添加系统提示词
+ if (requestParams.messages[0]?.role !== 'system') {
+ if (getRobotServiceOptions()?.enableRagContext) {
+ referenceContext = await search(requestParams.messages?.at(-1)?.content)
+ }
+ if (getRobotServiceOptions()?.enableResourceContext !== false) {
+ const appId = getMetaApi(META_SERVICE.GlobalService).getBaseInfo().id
+ imageAssets = await fetchAssets(appId)
+ }
+ const { materialState, getComponentDetail } = useMaterial()
+ const components = formatComponents(materialState.components, getComponentDetail)
+ addSystemPrompt(
+ requestParams.messages,
+ getAgentSystemPrompt(components, pageSchema, referenceContext, imageAssets)
+ )
+ }
+
+ const { baseUrl, model, config, capabilities } = getSelectedModelInfo()
+
+ requestParams.baseUrl = baseUrl
+ requestParams.model = model
+
+ if (capabilities?.reasoning?.extraBody) {
+ const extraBody = config?.enableThinking
+ ? capabilities.reasoning.extraBody.enable
+ : capabilities.reasoning.extraBody.disable
+ if (extraBody) {
+ Object.assign(requestParams, extraBody)
+ }
+ }
+
+ // Agent 模式默认使用 JSON 对象格式
+ if (capabilities?.jsonOutput?.extraBody?.enable) {
+ Object.assign(requestParams, capabilities.jsonOutput.extraBody.enable)
+ }
+
+ return requestParams
+ }
+
+ const onStreamStart = (messages: any[]) => {
+ removeLoading(messages)
+ }
+
+ const onStreamData = (data: object, content: string | object, _messages: any[]) => {
+ updatePageSchema(content, pageSchema!)
+ }
+
+ const onRequestEnd = async (
+ finishReason: string,
+ content: string,
+ messages: any[],
+ extraData?: Record
+ ) => {
+ if (finishReason === 'aborted' || finishReason === 'error') {
+ removeLoading(messages)
+ const errorInfo = { content: extraData?.error || '请求失败', status: 'failed' }
+ if (messages.at(-1).renderContent.at(-1)) {
+ Object.assign(messages.at(-1).renderContent.at(-1), errorInfo)
+ } else {
+ messages.at(-1).renderContent = [{ type: getContentType(), ...errorInfo }]
+ }
+ }
+ }
+
+ const onStreamTools = (tools: Record[], { currentMessage }: { currentMessage: any }) => {
+ tools.forEach((tool) => updateToolCallRenderContent(tool, currentMessage.renderContent))
+ }
+
+ const onBeforeCallTool = (tool: Record, { currentMessage }: { currentMessage: any }) => {
+ updateToolCallRenderContent(tool, currentMessage.renderContent)
+ }
+
+ const onPostCallTool = (
+ tool: Record,
+ toolCallResult: object | string,
+ toolCallStatus: string,
+ { currentMessage }: { currentMessage: any }
+ ) => {
+ currentMessage.renderContent.at(-1)!.status = toolCallStatus
+ currentMessage.renderContent.at(-1)!.content = {
+ params: tool.parsedArgs,
+ result: toolCallResult
+ }
+ }
+
+ const onMessageProcessed = async (
+ finishReason: string,
+ content: string,
+ messages: any[],
+ {
+ abortControllerMap,
+ messageState
+ }: { abortControllerMap: Record; messageState: MessageState }
+ ) => {
+ const lastMessage = messages.at(-1)
+
+ if (finishReason === 'aborted' || finishReason === 'error') {
+ lastMessage.renderContent.at(-1).status = 'failed'
+ return
+ }
+
+ const jsonValidResult = isValidJsonPatchObjectString(content)
+ // JSON 修复机制
+ if (jsonValidResult.isError) {
+ abortControllerMap.errorFix = new AbortController()
+ try {
+ const beforeRequest = (requestParams: any) => {
+ const { capabilities, model, baseUrl } = getSelectedModelInfo()
+ if (capabilities?.reasoning?.extraBody?.disable) {
+ Object.assign(requestParams, capabilities.reasoning.extraBody.disable)
+ }
+ if (capabilities?.jsonOutput?.extraBody?.enable) {
+ Object.assign(requestParams, capabilities.jsonOutput.extraBody.enable)
+ }
+ Object.assign(requestParams, {
+ model,
+ baseUrl
+ })
+ return requestParams
+ }
+ const apiUrl = 'app-center/api/chat/completions'
+ lastMessage.renderContent.at(-1).status = 'fix'
+ const fixedResponse = await client.chat({
+ messages: [{ role: 'user', content: getJsonFixPrompt(content, jsonValidResult.error) }],
+ options: { signal: abortControllerMap.errorFix?.signal, beforeRequest: beforeRequest as any, apiUrl }
+ })
+ if (!isValidJsonPatchObjectString(fixedResponse.choices[0].message.content).isError) {
+ lastMessage.originContent = lastMessage.content
+ lastMessage.content = fixedResponse.choices[0].message.content
+ }
+ } catch (error) {
+ logger.error('json fix failed', error)
+ lastMessage.renderContent.at(-1).status = 'failed'
+ if (error instanceof Error && error.message.includes('canceled')) {
+ messageState.status = STATUS.ABORTED
+ } else {
+ messageState.status = STATUS.ERROR
+ messageState.errorMsg = `JSON 修复失败:${error}`
+ }
+ delete abortControllerMap.errorFix
+ return
+ }
+ delete abortControllerMap.errorFix
+ }
+
+ // 更新页面 schema
+ const result = await updatePageSchema(lastMessage.content, pageSchema, true)
+ if (result.schema) {
+ lastMessage.renderContent.at(-1).status = 'success'
+ lastMessage.renderContent.at(-1).schema = result.schema
+ } else {
+ lastMessage.renderContent.at(-1).status = 'failed'
+ }
+
+ pageSchema = null
+ }
+
+ const onPostCallTools = (toolsResult: Record[], { currentMessage }: { currentMessage: any }) => {
+ currentMessage.renderContent.push({ type: 'loading', content: '' })
+ }
+
+ const onConversationEnd = (_conversationId: string) => {
+ // Agent 模式暂无特殊处理
+ }
+
+ return {
+ // 配置方法
+ getApiUrl,
+ getContentType,
+ getLoadingType,
+
+ // 生命周期钩子
+ onConversationStart,
+ onMessageSent,
+ onBeforeRequest,
+ onStreamStart,
+ onStreamData,
+ onRequestEnd,
+ onStreamTools,
+ onBeforeCallTool,
+ onPostCallTool,
+ onPostCallTools,
+ onMessageProcessed,
+ onConversationEnd
+ }
+}
diff --git a/packages/plugins/robot/src/composables/modes/useChatMode.ts b/packages/plugins/robot/src/composables/modes/useChatMode.ts
new file mode 100644
index 0000000000..7261a0f035
--- /dev/null
+++ b/packages/plugins/robot/src/composables/modes/useChatMode.ts
@@ -0,0 +1,179 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+import { removeLoading, serializeError } from '../../utils'
+import useModelConfig from '../core/useConfig'
+import useMcpServer from '../features/useMcp'
+import type { ModeHooks } from '../../types/mode.types'
+import { ChatMode } from '../../types/mode.types'
+
+const updateToolCallRenderContent = (tool: Record, renderContent: any[], { status, result } = {}) => {
+ const currentToolCallContent = renderContent.find((item) => item.type === 'tool' && item.toolCallId === tool.id)
+ if (currentToolCallContent) {
+ currentToolCallContent.status = status || 'running'
+ if (!currentToolCallContent.content) {
+ currentToolCallContent.content = {}
+ }
+ currentToolCallContent.content.params = tool.parsedArgs || tool.function!.arguments || {}
+ if (result) {
+ currentToolCallContent.content.result = result
+ }
+ } else {
+ renderContent.push({
+ type: 'tool',
+ name: tool.name || tool.function!.name,
+ status: status || 'running',
+ content: {
+ params: tool.parsedArgs || tool.function!.arguments || {},
+ ...(result ? { result } : {})
+ },
+ formatPretty: true,
+ toolCallId: tool.id
+ })
+ }
+}
+
+/**
+ * Chat 模式实现
+ * 特点:
+ * - 标准的对话模式
+ * - 支持 MCP 工具调用
+ * - 简单的 loading 处理
+ * - 无需 schema 更新
+ */
+export default function useChatMode(): ModeHooks {
+ const { getSelectedModelInfo } = useModelConfig()
+
+ // ========== 配置方法 ==========
+ const getApiUrl = () => 'app-center/api/chat/completions'
+
+ const getContentType = () => 'markdown'
+
+ const getLoadingType = () => 'loading'
+
+ // ========== 生命周期钩子 ==========
+ const onConversationStart = (conversationState: any, messages: any[], apis: any) => {
+ const conversation = conversationState.conversations.find((item: any) => item.id === conversationState.currentId)
+
+ // 确保会话元数据中记录为 Chat 模式
+ if (!conversation.metadata?.chatMode || conversation.metadata.chatMode !== ChatMode.Chat) {
+ apis.updateMetadata(conversationState.currentId, { chatMode: ChatMode.Chat })
+ apis.saveConversations()
+ }
+
+ // Chat 模式简单移除 loading
+ removeLoading(messages)
+ }
+
+ const onMessageSent = () => {
+ // Chat 模式暂无特殊处理
+ }
+
+ const onBeforeRequest = async (requestParams: any) => {
+ const tools = await useMcpServer().getLLMTools()
+ const { model, baseUrl, config, capabilities } = getSelectedModelInfo()
+
+ // 添加 MCP 工具
+ if (!requestParams.tools && tools?.length && capabilities?.toolCalling !== false) {
+ Object.assign(requestParams, { tools })
+ }
+
+ requestParams.baseUrl = baseUrl
+ requestParams.model = model
+
+ if (capabilities?.reasoning?.extraBody) {
+ const extraBody = config?.enableThinking
+ ? capabilities.reasoning.extraBody.enable
+ : capabilities.reasoning.extraBody.disable
+ if (extraBody) {
+ Object.assign(requestParams, extraBody)
+ }
+ }
+
+ return requestParams
+ }
+
+ const onStreamStart = (messages: any[]) => {
+ removeLoading(messages)
+ }
+
+ const onStreamData = (_data: object, _content: string | object, _messages: any[]) => {
+ // Chat 模式不需要处理流式数据
+ }
+
+ const onRequestEnd = async (
+ finishReason: string,
+ _content: string,
+ messages: any[],
+ extraData?: Record
+ ) => {
+ if (finishReason === 'aborted' || finishReason === 'error') {
+ removeLoading(messages)
+ messages.at(-1)!.renderContent.push({ type: 'text', content: serializeError(extraData?.error) })
+ }
+ }
+
+ const onStreamTools = (tools: Record[], { currentMessage }: { currentMessage: any }) => {
+ tools.forEach((tool) => updateToolCallRenderContent(tool, currentMessage.renderContent))
+ }
+
+ const onBeforeCallTool = (tool: Record, { currentMessage }: { currentMessage: any }) => {
+ updateToolCallRenderContent(tool, currentMessage.renderContent)
+ }
+
+ const onPostCallTool = (
+ tool: Record,
+ toolCallResult: object | string,
+ toolCallStatus: string,
+ { currentMessage }: { currentMessage: any }
+ ) => {
+ updateToolCallRenderContent(tool, currentMessage.renderContent, { status: toolCallStatus, result: toolCallResult })
+ }
+
+ const onPostCallTools = (_toolsResult: Record[], { currentMessage }: { currentMessage: any }) => {
+ currentMessage.renderContent.push({ type: getLoadingType(), content: '' })
+ }
+
+ const onMessageProcessed = async (
+ _finishReason: string,
+ _content: string,
+ _messages: any[],
+ _context: { abortControllerMap: Record }
+ ) => {
+ // Chat 模式不需要处理消息
+ }
+
+ const onConversationEnd = (_conversationId: string) => {
+ // Chat 模式暂无特殊处理
+ }
+
+ return {
+ // 配置方法
+ getApiUrl,
+ getContentType,
+ getLoadingType,
+
+ // 生命周期钩子
+ onConversationStart,
+ onMessageSent,
+ onBeforeRequest,
+ onStreamStart,
+ onStreamData,
+ onRequestEnd,
+ onStreamTools,
+ onBeforeCallTool,
+ onPostCallTool,
+ onPostCallTools,
+ onMessageProcessed,
+ onConversationEnd
+ }
+}
diff --git a/packages/plugins/robot/src/composables/modes/useMode.ts b/packages/plugins/robot/src/composables/modes/useMode.ts
new file mode 100644
index 0000000000..f79a03e4e4
--- /dev/null
+++ b/packages/plugins/robot/src/composables/modes/useMode.ts
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+import useModelConfig from '../core/useConfig'
+import useAgentMode from './useAgentMode'
+import useChatMode from './useChatMode'
+import type { ModeHooks } from '../../types/mode.types'
+import { ChatMode } from '../../types/mode.types'
+import { getRobotServiceOptions } from '../../utils'
+
+/**
+ * 模式注册表
+ * 配置式管理所有聊天模式,便于扩展新模式
+ */
+const modeRegistry: Record ModeHooks> = {
+ [ChatMode.Agent]: useAgentMode,
+ [ChatMode.Chat]: useChatMode
+}
+
+// 缓存模式实例,避免重复创建
+const modeInstanceCache: Record = {}
+
+/**
+ * 获取指定模式的实例(带缓存)
+ */
+const getModeInstance = (chatMode: string): ModeHooks => {
+ if (!modeInstanceCache[chatMode]) {
+ const modeFactory = getRobotServiceOptions()?.modeImplementation?.[chatMode] || modeRegistry[chatMode]
+ if (!modeFactory) {
+ throw new Error(`Unknown chat mode: ${chatMode}. Available modes: ${Object.keys(modeRegistry).join(', ')}`)
+ }
+ modeInstanceCache[chatMode] = modeFactory()
+ }
+ return modeInstanceCache[chatMode]
+}
+
+/**
+ * 获取当前激活的模式实例
+ */
+const getCurrentMode = (): ModeHooks => {
+ const { getSelectedModelInfo } = useModelConfig()
+ return getModeInstance(getSelectedModelInfo().config!.chatMode ?? ChatMode.Agent)
+}
+
+/**
+ * 模式统一入口
+ * 返回代理对象,每次调用钩子时动态获取当前模式
+ * 这样可以支持运行时模式切换
+ */
+export default function useMode(): ModeHooks {
+ return {
+ // 配置方法代理
+ getApiUrl: () => getCurrentMode().getApiUrl(),
+ getContentType: () => getCurrentMode().getContentType(),
+ getLoadingType: () => getCurrentMode().getLoadingType(),
+
+ // 生命周期钩子代理
+ onConversationStart: (...args) => getCurrentMode().onConversationStart(...args),
+ onMessageSent: (...args) => getCurrentMode().onMessageSent(...args),
+ onBeforeRequest: (...args) => getCurrentMode().onBeforeRequest(...args),
+ onStreamStart: (...args) => getCurrentMode().onStreamStart(...args),
+ onStreamData: (...args) => getCurrentMode().onStreamData(...args),
+ onRequestEnd: (...args) => getCurrentMode().onRequestEnd(...args),
+ onStreamTools: (...args) => getCurrentMode().onStreamTools(...args),
+ onBeforeCallTool: (...args) => getCurrentMode().onBeforeCallTool(...args),
+ onPostCallTool: (...args) => getCurrentMode().onPostCallTool(...args),
+ onPostCallTools: (...args) => getCurrentMode().onPostCallTools(...args),
+ onMessageProcessed: (...args) => getCurrentMode().onMessageProcessed(...args),
+ onConversationEnd: (...args) => getCurrentMode().onConversationEnd(...args)
+ }
+}
+
+// 导出类型供其他模块使用
+export type { ModeHooks } from '../../types/mode.types'
diff --git a/packages/plugins/robot/src/composables/useChat.ts b/packages/plugins/robot/src/composables/useChat.ts
new file mode 100644
index 0000000000..1772d968d1
--- /dev/null
+++ b/packages/plugins/robot/src/composables/useChat.ts
@@ -0,0 +1,269 @@
+import { nextTick } from 'vue'
+import { GeneratingStatus, STATUS, type ChatMessage, type MessageState } from '@opentiny/tiny-robot-kit'
+import { formatMessages, removeLoading } from '../utils'
+import { getClientConfig as getConfig, updateClientConfig as updateConfig, client } from '../services/aiClient'
+import useModelConfig from './core/useConfig'
+import useMode from './modes/useMode'
+import { createStreamDataHandler } from './core/useMessageStream'
+import type { ChatRequestData, ProviderConfig } from '../services/OpenAICompatibleProvider'
+import { createToolCallHandler } from './features/useToolCalls'
+import apiService from '../services/api'
+import { useConversationAdapter } from './core/useConversation'
+
+const {
+ // 配置方法
+ getApiUrl,
+ getContentType,
+ getLoadingType,
+ // 生命周期钩子
+ onConversationStart,
+ onMessageSent,
+ onBeforeRequest,
+ onStreamStart,
+ onStreamData,
+ onRequestEnd,
+ onStreamTools,
+ onBeforeCallTool,
+ onPostCallTool,
+ onPostCallTools,
+ onMessageProcessed,
+ onConversationEnd
+} = useMode()
+
+const { robotSettingState, updateChatModeState, getSelectedModelInfo } = useModelConfig()
+
+// 本次对话的状态,从用户发送消息开始到AI返回或用户主动终止结束
+enum CHAT_STATUS {
+ PROCESSING = 'processing', // 本轮对话开始后,没有请求在流式返回(可能是等待请求,也可能是请求间隙)
+ STREAMING = 'streaming', // 当前有请求正在流式返回
+ FINISHED = 'finished' // 本轮对话结束
+}
+
+let chatStatus: CHAT_STATUS = CHAT_STATUS.PROCESSING
+
+const abortControllerMap: Record = {}
+
+// 使用工厂函数创建流式数据处理器,解耦业务逻辑
+const handleStreamData = createStreamDataHandler({
+ getContentType,
+ hooks: {
+ onStreamStart,
+ onStreamData,
+ onStreamTools
+ },
+ statusManager: {
+ isStreaming: () => chatStatus === CHAT_STATUS.STREAMING,
+ setStreaming: () => {
+ chatStatus = CHAT_STATUS.STREAMING
+ }
+ }
+})
+
+const beforeRequest = async (params: ChatRequestData): Promise => {
+ const requestParams = await onBeforeRequest(params)
+ const { service } = getSelectedModelInfo()
+
+ if (service && getConfig().apiKey !== service.apiKey) {
+ updateConfig({ apiKey: service.apiKey })
+ }
+ if (getConfig().apiUrl !== getApiUrl()) {
+ updateConfig({ apiUrl: getApiUrl() })
+ }
+ return requestParams
+}
+
+const initChatClient = () => {
+ const { service, model } = getSelectedModelInfo()
+
+ const config: ProviderConfig = {
+ apiKey: service?.apiKey || '',
+ apiUrl: getApiUrl(),
+ defaultModel: model || 'deepseek-v3',
+ axiosClient: () => apiService.getHttpClient(),
+ httpClientType: 'axios',
+ beforeRequest
+ }
+ updateConfig(config)
+}
+
+const handleFinishRequest = async (
+ finishReason: string,
+ messages: ChatMessage[],
+ contextMessages: ChatMessage[],
+ messageState: MessageState
+) => {
+ const lastMessage = messages.at(-1)
+
+ delete abortControllerMap.main
+ await onRequestEnd(finishReason, lastMessage.content, messages) // 本次请求结束
+
+ // 部分模型返回格式不太标准,例如finishReason没有返回tool_calls而是stop,这里做下兼容
+ if (['tool_calls', 'stop'].includes(finishReason) && lastMessage.tool_calls?.length) {
+ lastMessage!.tool_calls.forEach((toolCall) => {
+ if (toolCall.type !== 'function') {
+ // 修复,兼容部分场景返回格式不标准,流式中多次返回type字段
+ toolCall.type = 'function'
+ }
+ })
+ await handleToolCall(lastMessage.tool_calls, messages, contextMessages) // eslint-disable-line
+ }
+
+ if (finishReason === 'aborted' || messageState?.status === STATUS.ABORTED) {
+ messageState.status = STATUS.ABORTED
+ }
+}
+
+const handleRequestError = async (error: Error, messages: ChatMessage[], messageState: MessageState) => {
+ chatStatus = CHAT_STATUS.FINISHED
+ delete abortControllerMap.main
+ await onRequestEnd('error', messages.at(-1).content, messages, { error }) // 本次请求结束
+ messageState.status = STATUS.ERROR
+}
+
+// 使用 conversation 适配器,将业务逻辑与 conversation 管理解耦
+const {
+ messageManager,
+ conversationState,
+ createConversation: createConversationBase,
+ switchConversation: switchConversationBase,
+ autoSetTitle: autoSetTitleBase,
+ ...conversationMethods
+} = useConversationAdapter({
+ client,
+ onStreamData: handleStreamData,
+ onFinishRequest: handleFinishRequest,
+ onMessageProcessed: async (finishReason, content, messages) => {
+ await onMessageProcessed(finishReason, content, messages, {
+ abortControllerMap,
+ messageState: messageManager.messageState
+ })
+ if (GeneratingStatus.includes(messageManager.messageState.status)) {
+ messageManager.messageState.status = STATUS.FINISHED
+ }
+ chatStatus = CHAT_STATUS.FINISHED
+ },
+ statusManager: {
+ isProcessing: () => chatStatus === CHAT_STATUS.PROCESSING,
+ setProcessing: () => {
+ chatStatus = CHAT_STATUS.PROCESSING
+ }
+ }
+})
+
+// 使用工厂函数创建工具调用处理器
+const handleToolCall = createToolCallHandler({
+ client,
+ getAbortController: () => {
+ abortControllerMap.toolCall = new AbortController()
+ return abortControllerMap.toolCall
+ },
+ formatMessages,
+ hooks: {
+ onBeforeCallTool,
+ onPostCallTool,
+ onPostCallTools
+ },
+ streamHandlers: {
+ onData: handleStreamData,
+ onError: handleRequestError,
+ onDone: handleFinishRequest
+ },
+ getMessageState: () => messageManager.messageState
+})
+
+// 包装 conversation 方法,添加业务特定逻辑
+const createConversation = (title = '新会话', chatMode = robotSettingState.chatMode) => {
+ const currentConversationId = conversationState.currentId!
+ const newConversationId = createConversationBase(title, { chatMode })
+ if (newConversationId !== currentConversationId) {
+ onConversationEnd(currentConversationId)
+ }
+ onConversationStart(conversationState, messageManager.messages.value, conversationMethods)
+ return newConversationId
+}
+
+const switchConversation = (conversationId: string) => {
+ onConversationEnd(conversationState.currentId!)
+ return switchConversationBase(conversationId, (state, messages, methods) => {
+ onConversationStart(state, messages, methods)
+ })
+}
+
+const autoSetTitle = () => {
+ if (conversationState.currentId) {
+ autoSetTitleBase(conversationState.currentId)
+ }
+}
+
+const addMainAbortController = () => {
+ const mainAbortController = new AbortController()
+ mainAbortController.signal.addEventListener('abort', () => {
+ messageManager.abortRequest()
+ messageManager.messageState.status = STATUS.ABORTED
+ })
+ abortControllerMap.main = mainAbortController
+}
+
+const addLoading = (messages: ChatMessage[]) => {
+ const assistantMessage: ChatMessage = {
+ role: 'assistant',
+ content: '',
+ renderContent: [{ type: getLoadingType() }]
+ }
+ messages.push(assistantMessage)
+}
+
+const sendUserMessage = async () => {
+ onMessageSent()
+ await nextTick()
+ addMainAbortController()
+ addLoading(messageManager.messages.value)
+ await messageManager.send()
+ if (messageManager.messageState.status === STATUS.ERROR) {
+ removeLoading(messageManager.messages.value)
+ await handleRequestError(
+ messageManager.messageState.errorMsg,
+ messageManager.messages.value,
+ messageManager.messageState
+ )
+ }
+ autoSetTitle()
+}
+
+const abortRequest = () => {
+ Object.values(abortControllerMap).forEach((controller) => controller?.abort())
+ for (const key of Object.keys(abortControllerMap)) {
+ delete abortControllerMap[key]
+ }
+
+ onRequestEnd('aborted', messageManager.messages.value.at(-1)?.content as string, messageManager.messages.value)
+}
+
+const changeChatMode = (chatMode: string) => {
+ // 空会话更新metadata
+ const usedConversationId = conversationState.currentId
+ const newConversationId = createConversation('新会话', chatMode)
+ if (usedConversationId === newConversationId) {
+ conversationMethods.updateMetadata(newConversationId, { chatMode })
+ conversationMethods.saveConversations()
+ }
+
+ updateChatModeState(chatMode)
+ updateConfig({ apiUrl: getApiUrl() })
+}
+
+export default function () {
+ return {
+ initChatClient,
+ updateConfig,
+ ...messageManager,
+ sendUserMessage,
+ changeChatMode,
+ abortRequest,
+ conversationState,
+ ...conversationMethods,
+ switchConversation,
+ createConversation,
+ autoSetTitle
+ }
+}
diff --git a/packages/plugins/robot/src/constants/index.ts b/packages/plugins/robot/src/constants/index.ts
new file mode 100644
index 0000000000..504e83352d
--- /dev/null
+++ b/packages/plugins/robot/src/constants/index.ts
@@ -0,0 +1 @@
+export * from './model-config'
diff --git a/packages/plugins/robot/src/constants/model-config.ts b/packages/plugins/robot/src/constants/model-config.ts
new file mode 100644
index 0000000000..4458339325
--- /dev/null
+++ b/packages/plugins/robot/src/constants/model-config.ts
@@ -0,0 +1,126 @@
+const reasoningExtraBody = {
+ extraBody: {
+ enable: {
+ enable_thinking: true,
+ thinking_budget: 1000
+ },
+ disable: null
+ }
+}
+
+const jsonOutputExtraBody = {
+ extraBody: {
+ enable: { response_format: { type: 'json_object' } },
+ disable: null
+ }
+}
+
+const bailianJsonOutputExtraBody = {
+ extraBody: {
+ enable: {
+ response_format: { type: 'json_object' },
+ enable_thinking: false // 千问模型不支持思考模式下输出json
+ },
+ disable: null
+ }
+}
+
+export const DEFAULT_LLM_MODELS = [
+ {
+ provider: 'bailian',
+ label: '阿里云百炼',
+ baseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
+ allowEmptyApiKey: false,
+ models: [
+ // Agent/chat
+ {
+ label: 'Qwen 通用模型(Plus)',
+ name: 'qwen-plus',
+ capabilities: {
+ toolCalling: true,
+ reasoning: reasoningExtraBody,
+ jsonOutput: bailianJsonOutputExtraBody
+ }
+ },
+ // 备注:千问多模态模型不支持工具调用;
+ {
+ label: 'Qwen VL视觉理解模型(PLUS)',
+ name: 'qwen3-vl-plus',
+ capabilities: {
+ vision: true,
+ reasoning: reasoningExtraBody,
+ jsonOutput: bailianJsonOutputExtraBody
+ }
+ },
+ {
+ label: 'Qwen Coder编程模型(PLUS)',
+ name: 'qwen3-coder-plus',
+ capabilities: {
+ toolCalling: true,
+ reasoning: reasoningExtraBody,
+ jsonOutput: bailianJsonOutputExtraBody
+ }
+ },
+ {
+ label: 'DeepSeek(v3.2)',
+ name: 'deepseek-v3.2-exp',
+ capabilities: {
+ toolCalling: true,
+ reasoning: reasoningExtraBody,
+ jsonOutput: bailianJsonOutputExtraBody
+ }
+ },
+ // 小参数模型
+ {
+ label: 'Qwen 通用模型(Flash)',
+ name: 'qwen-flash',
+ capabilities: {
+ toolCalling: true,
+ compact: true,
+ jsonOutput: bailianJsonOutputExtraBody
+ }
+ },
+ {
+ label: 'Qwen Coder编程模型(Flash)',
+ name: 'qwen3-coder-flash',
+ capabilities: {
+ toolCalling: true,
+ compact: true,
+ jsonOutput: bailianJsonOutputExtraBody
+ }
+ },
+ {
+ label: 'Qwen3(14b)',
+ name: 'qwen3-14b',
+ capabilities: { compact: true, toolCalling: true, jsonOutput: bailianJsonOutputExtraBody }
+ },
+ {
+ label: 'Qwen3(8b)',
+ name: 'qwen3-8b',
+ capabilities: { compact: true, toolCalling: true, jsonOutput: bailianJsonOutputExtraBody }
+ }
+ ]
+ },
+ {
+ provider: 'deepseek',
+ label: 'DeepSeek',
+ baseUrl: 'https://api.deepseek.com/v1',
+ allowEmptyApiKey: false,
+ models: [
+ {
+ label: 'DeepSeek',
+ name: 'deepseek-chat',
+ capabilities: {
+ toolCalling: true,
+ reasoning: {
+ extraBody: {
+ enable: { model: 'deepseek-reasoner' },
+ disable: { model: 'deepseek-chat' }
+ }
+ },
+ jsonOutput: jsonOutputExtraBody
+ }
+ }
+ ]
+ }
+]
diff --git a/packages/plugins/robot/src/constants/prompts/data/examples.json b/packages/plugins/robot/src/constants/prompts/data/examples.json
new file mode 100644
index 0000000000..6763878b05
--- /dev/null
+++ b/packages/plugins/robot/src/constants/prompts/data/examples.json
@@ -0,0 +1,148 @@
+{
+ "chatMessageList": {
+ "name": "Chat Message List Example",
+ "description": "A complete example of adding a chat message list with input and send functionality",
+ "note": "All JavaScript code uses string concatenation, not template literals",
+ "patch": [
+ {
+ "op": "add",
+ "path": "/state/messages",
+ "value": [
+ {
+ "content": "hello"
+ }
+ ]
+ },
+ {
+ "op": "add",
+ "path": "/state/inputMessage",
+ "value": ""
+ },
+ {
+ "op": "add",
+ "path": "/children/0",
+ "value": {
+ "componentName": "div",
+ "id": "a7Kp9sN9",
+ "props": {
+ "className": "component-base-style"
+ },
+ "children": [
+ {
+ "componentName": "h1",
+ "props": {
+ "className": "component-base-style"
+ },
+ "children": "消息列表",
+ "id": "bR7m1x4N"
+ },
+ {
+ "componentName": "div",
+ "props": {
+ "className": "component-base-style div-uhqto",
+ "alignItems": "flex-start"
+ },
+ "children": [
+ {
+ "componentName": "div",
+ "props": {
+ "className": "component-base-style div-vinko",
+ "onClick": {
+ "type": "JSExpression",
+ "value": "this.onClickMessage",
+ "params": ["message", "index"]
+ },
+ "key": {
+ "type": "JSExpression",
+ "value": "index"
+ }
+ },
+ "children": [
+ {
+ "componentName": "Text",
+ "props": {
+ "style": "display: inline-block;",
+ "text": {
+ "type": "JSExpression",
+ "value": "message.content"
+ },
+ "className": "component-base-style"
+ },
+ "children": [],
+ "id": "s32pKwJ5"
+ }
+ ],
+ "id": "f2525253",
+ "loop": {
+ "type": "JSExpression",
+ "value": "this.state.messages"
+ },
+ "loopArgs": ["message", "index"]
+ }
+ ],
+ "id": "tNkfHvY8"
+ },
+ {
+ "componentName": "div",
+ "props": {
+ "className": "component-base-style div-iarpn"
+ },
+ "children": [
+ {
+ "componentName": "TinyInput",
+ "props": {
+ "placeholder": "请输入",
+ "modelValue": {
+ "type": "JSExpression",
+ "value": "this.state.inputMessage",
+ "model": true
+ },
+ "className": "component-base-style",
+ "type": "textarea"
+ },
+ "children": [],
+ "id": "3sji2FD0"
+ },
+ {
+ "componentName": "TinyButton",
+ "props": {
+ "text": "发送",
+ "className": "component-base-style",
+ "onClick": {
+ "type": "JSExpression",
+ "value": "this.sendMessage"
+ }
+ },
+ "children": [],
+ "id": "xjeu39F0"
+ }
+ ],
+ "id": "02kuxy2J"
+ }
+ ]
+ }
+ },
+ {
+ "op": "replace",
+ "path": "/css",
+ "value": ".page-base-style {\n padding: 24px;\n background: #ffffff;\n}\n.block-base-style {\n margin: 16px;\n}\n.component-base-style {\n margin: 8px;\n}\n.div-vinko {\n margin: 8px;\n border-width: 1px;\n border-color: #ebeaea;\n border-style: solid;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n border-radius: 50px;\n}\n.div-iarpn {\n margin: 8px;\n display: flex;\n align-items: center;\n}\n.div-uhqto {\n margin: 8px;\n display: flex;\n flex-direction: column;\n}\n"
+ },
+ {
+ "op": "add",
+ "path": "/methods/sendMessage",
+ "value": {
+ "type": "JSFunction",
+ "value": "function sendMessage(event) {\n this.state.messages.push({ content: this.state.inputMessage })\n this.state.inputMessage = ''\n}\n"
+ }
+ },
+ {
+ "op": "add",
+ "path": "/methods/onClickMessage",
+ "value": {
+ "type": "JSFunction",
+ "value": "function onClickMessage(event, message, index) {\n console.log('这是第' + (index + 1) + '条消息, 消息内容:' + message.content)\n}\n"
+ }
+ }
+ ]
+ }
+}
diff --git a/packages/plugins/robot/src/constants/prompts/index.ts b/packages/plugins/robot/src/constants/prompts/index.ts
new file mode 100644
index 0000000000..aa286ba443
--- /dev/null
+++ b/packages/plugins/robot/src/constants/prompts/index.ts
@@ -0,0 +1,205 @@
+import agentPrompt from './templates/agent-prompt.md?raw'
+import chatPrompt from './templates/chat-prompt.md?raw'
+import examplesData from './data/examples.json'
+
+/**
+ * Convert components array to JSONL format string
+ */
+const formatComponentsToJsonl = (components: any[]): string => {
+ return '```jsonl\n' + components.map((comp) => JSON.stringify(comp)).join('\n') + '\n```'
+}
+
+/**
+ * Format examples object to readable text
+ */
+const formatExamples = (examples: Record): string => {
+ return Object.entries(examples)
+ .map(([_key, example]) => {
+ const { name, description, note, patch } = example
+ const header = `### ${name}\n${description ? `${description}\n` : ''}${note ? `**Note**: ${note}\n` : ''}`
+ const patchContent = JSON.stringify(patch)
+ return `${header}\n\`\`\`json\n${patchContent}\n\`\`\``
+ })
+ .join('\n\n')
+}
+
+type ComponentMaterial = {
+ component: string
+ name: { zh_CN: string; en_US?: string }
+ props: Array<{
+ property: string
+ description?: { zh_CN: string; en_US?: string }
+ type: string
+ defaultValue?: any
+ }>
+ events: Array<{
+ name: string
+ description?: { zh_CN: string; en_US?: string }
+ }>
+ slots: Array<{
+ name: string
+ description?: { zh_CN: string; en_US?: string }
+ }>
+}
+
+const toPascalCase = (str: string): string => {
+ if (!str.toLowerCase().startsWith('tiny')) return str
+ const result = str
+ .replace(/[-_]([a-z])/g, (_: string, char: string) => char.toUpperCase())
+ .replace(/^[a-z]/, (firstChar: string) => firstChar.toUpperCase())
+ return result
+}
+
+const nativeComponents = [
+ 'p',
+ 'a',
+ 'hr',
+ 'img',
+ 'h1',
+ 'video',
+ 'button',
+ 'input',
+ 'form',
+ 'form-item',
+ 'select',
+ 'table',
+ 'container',
+ 'text',
+ 'image'
+]
+
+export const formatComponents = (snippets: any[], getComponent: (name: string) => ComponentMaterial): any[] => {
+ const ignoreGroups = ['model', 'element-plus']
+ const ignoreComponents = [
+ ...nativeComponents,
+ 'Box',
+ 'CanvasRowColContainer',
+ 'CanvasFlexBox',
+ 'CanvasSection',
+ 'Collection',
+ 'CanvasNavigation',
+ 'TinyButtons',
+ 'TinyCheckboxbuttonGroup',
+ 'TinyNumeric' // 组件报错,先忽略
+ ]
+ const ignoreProperties = ['id', 'className', 'ref', 'attributes3']
+
+ const newComponents = snippets
+ .filter((item: any) => !ignoreGroups.includes(item.group))
+ .map((group) => group.children)
+ .flat()
+ .filter((item: any) => item.snippetName && !ignoreComponents.includes(item.snippetName))
+ .map((child) => {
+ const component: ComponentMaterial = getComponent(toPascalCase(child.snippetName))
+ const schema: any = {}
+
+ if (component?.props?.length) {
+ schema.properties = component.props
+ ?.filter((prop) => !ignoreProperties.includes(prop.property))
+ .map((prop) => ({
+ name: prop.property,
+ description: prop.description?.en_US || prop.description?.zh_CN || '',
+ type: prop.type || 'string',
+ ...(prop.defaultValue === undefined ? {} : { default: prop.defaultValue })
+ }))
+ .reduce((acc: Record, cur) => {
+ const type = cur.type && cur.type.toUpperCase() !== 'STRING' ? `(${cur.type})` : ''
+ const defaultValue =
+ cur.default !== undefined && cur.default !== '' ? `(defaultValue: ${JSON.stringify(cur.default)})` : ''
+ acc[cur.name] = `${cur.description}${type}${defaultValue}`
+ return acc
+ }, {})
+ }
+
+ if (component?.events?.length) {
+ schema.events = component.events
+ .map((event) => ({
+ name: event.name,
+ description: event.description?.en_US || event.description?.zh_CN || ''
+ }))
+ .reduce((acc: Record, cur) => {
+ acc[cur.name] = cur.description
+ return acc
+ }, {})
+ }
+ if (component?.slots?.length) {
+ schema.slots = component.slots
+ .map((slot) => ({
+ name: slot.name,
+ description: slot.description?.en_US || slot.description?.zh_CN || ''
+ }))
+ .reduce((acc: Record, cur) => {
+ acc[cur.name] = cur.description
+ return acc
+ }, {})
+ }
+
+ return {
+ component: toPascalCase(child.snippetName),
+ name: child.name?.zh_CN || child.name || toPascalCase(child.snippetName),
+ ...schema,
+ demo: child.schema
+ }
+ })
+ return newComponents
+}
+
+/**
+ * Generate agent system prompt with dynamic components and examples
+ */
+export const getAgentSystemPrompt = (
+ components: any[],
+ currentPageSchema: object,
+ referenceContext: string,
+ imageAssets: any[]
+) => {
+ const componentsList = formatComponentsToJsonl(components)
+
+ const examplesSection = formatExamples(examplesData)
+
+ const currentPageSchemaStr = JSON.stringify(currentPageSchema)
+
+ const prompt = agentPrompt
+ .replace('{{COMPONENTS_LIST}}', componentsList)
+ .replace('{{EXAMPLES_SECTION}}', examplesSection)
+ .replace('{{CURRENT_PAGE_SCHEMA}}', currentPageSchemaStr)
+ .replace('{{REFERENCE_KNOWLEDGE}}', referenceContext || '')
+ .replace('{{IMAGE_ASSETS}}', imageAssets.map((item) => `- `).join('\n'))
+
+ return prompt.trim()
+}
+
+export const getChatSystemPrompt = () => chatPrompt
+
+export const getJsonFixPrompt = (jsonString: string, error = '') => {
+ const errorSection = error ? `## Error Message\n${error}\n\n` : ''
+
+ return `
+You are a JSON repair specialist. Fix the following invalid JSON string to create a valid JSON Patch array (RFC 6902 standard).
+
+## JSON Patch Format Requirements:
+- Array of objects, each with required "op" and "path" properties
+- "op" must be one of: "add", "replace", "remove", "move", "copy", "test"
+- "path" must be a JSON Pointer string (e.g., "/property", "/array/0")
+- "value" is required for "add", "replace", "move", "copy", "test" operations
+- "from" is required for "move", "copy" operations
+- All strings must use double quotes, no trailing commas
+
+## Example JSON Patch:
+[
+ { "op": "add", "path": "/children/0", "value": { ... } },
+ { "op": "replace", "path": "/css", "value": "..." }
+]
+
+## Your Task:
+1. Parse and fix the invalid JSON string
+2. Ensure it conforms to JSON Patch format
+3. Output ONLY the corrected JSON string
+4. No explanations, comments, or markdown formatting
+
+## Invalid JSON Input:
+${jsonString}
+
+${errorSection}## Output (JSON only):
+`.trim()
+}
diff --git a/packages/plugins/robot/src/constants/prompts/templates/agent-prompt.md b/packages/plugins/robot/src/constants/prompts/templates/agent-prompt.md
new file mode 100644
index 0000000000..65b7dfbed0
--- /dev/null
+++ b/packages/plugins/robot/src/constants/prompts/templates/agent-prompt.md
@@ -0,0 +1,213 @@
+**[System Instructions: Role & Core Mission]**
+
+You are a specialized AI assistant for a TinyEngine low-code platform. Your sole responsibility is to **function as an API that silently and precisely generates JSON Patch data for PageSchema structures**. You are not a conversational agent, but a functional service.
+
+**Core Mission**: Based on the **[Current Page Schema]**, **[Reference Knowledge]**, and user requirements, generate a strictly compliant `RFC 6902` JSON Patch array to add/replace/remove/move (`add`/`replace`/`remove`/`move`) components and logic that conform to the PageSchema specification (see Section 3), transforming the existing page into one that meets user needs.
+
+**⚠️ Critical Reminder**: Your output will be directly parsed by `JSON.parse()`. Any formatting errors will cause system crashes. You MUST:
+ 1. NEVER use JavaScript template literals (backticks `` ` ``), use string concatenation instead
+ 2. All newlines MUST be escaped as `\n`, no actual line breaks allowed
+ 3. Output pure JSON only, without any markers or comments
+
+-----
+
+## 1. Operational Workflow
+
+The low-code platform workflow is as follows:
+Current Page Schema → Generate JSON Patch based on user requirements → Apply JSON Patch to create new Page Schema → Continue modifications based on user feedback, generating new JSON Patch from updated Schema → Apply new JSON Patch to update current Page Schema
+
+Page Schema is a JSON format describing page UI and functionality. It can be compiled into Vue code, so Page Schema is equivalent to Vue Single File Component code in a specific format.
+
+Follow these steps strictly to generate PageSchema (in JSON Patch format) that meets user requirements:
+
+1. **Parse Input**: Carefully analyze the **[User Requirements]** (text description or image analysis results), combined with the **[Current Page Schema]** below and any **[Reference Knowledge]** provided.
+2. **Generate UI, Logic, Lifecycles, etc.**: Based on user requirements, think about modifications to the current Schema to generate UI, logic, lifecycles, and other necessary data that satisfies requirements and conforms to `PageSchema` specification.
+3. **Encapsulate as JSON Patch**: Wrap the generated data into a strictly `RFC 6902` compliant JSON Patch array. Format example: `[{ "op": "add", "path": "/children/0", "value": { ... } }, {"op":"add","path":"/methods/handleBtnClick","value": { ... }}, { "op": "replace", "path": "/css", "value": "..." }]`.
+4. **Final Validation**: Before output, execute the following verification steps:
+ - Confirm output is a **single-line** compact JSON string (no actual line breaks)
+ - Confirm all newlines within strings are escaped as `\n`, not actual newline characters
+ - Confirm NO JavaScript template literal syntax (backticks `` ` ``) is used
+ - Confirm all double quotes are properly escaped
+ - **[NEW] Check array element separation**: Search entire output to ensure no `]}{` patterns exist, should be `]},{`
+ - **[NEW] Check object separation**: Search entire output to ensure no `},"op":` patterns exist, should be `},{"op":`
+ - **[NEW] Check bracket balance**: Count `{` and `}` must be equal, `[` and `]` must be equal
+ - **[NEW] Check nesting depth**: Simulate bracket matching from start to end, ensure depth never goes negative
+ - Mentally simulate executing `JSON.parse(your_output)`, ensure it won't throw `SyntaxError`
+ - If any step fails or you cannot understand the requirement, you MUST output an empty array `[]`.
+
+-----
+
+## 2. Output Format & Absolute Constraints
+
+**Output in JSON format. You must and can only output a raw and complete JSON string, which is itself a JSON Patch array that can be parsed by JSON.parse into a JSON object.** For example, the following result adds a method named `handleBtnClick`, adds a page state variable named `name`, and removes a page element:
+[{"op":"add","path":"/methods/handleBtnClick","value":{"type":"JSFunction","value":"function handleBtnClick() {\n console.log('button click')\n}\n"}},{"op":"add","path":"/state/name","value":"alice"},{"op":"remove","path":"/children/0/children/5"}]
+
+Constraint Rules:
+ * **Strictly Prohibited**:
+ * Any explanatory text, preamble, or closing remarks (e.g., "Here's the JSON you requested...")
+ * DO NOT wrap JSON string with \`\`\`json or \`\`\`
+ * Adding any comments inside or outside JSON (such as `//` or `/* */`)
+ * Any form of ellipsis or incomplete placeholders (such as `...`)
+ * **JSON Syntax Iron Rules**:
+ * All keys and string values MUST use **double quotes** (`"`)
+ * The last element of an object or array **MUST NOT** have trailing commas
+ * Boolean values must be lowercase `true` or `false`, not strings
+ * Ensure all brackets `{}`, `[]` are properly closed and matched
+ * Output MUST be a **single-line** compact JSON string, no actual line breaks or unnecessary spaces
+ * **Array and Object Separation Rules (Extremely Important!)**:
+ * **Array elements MUST have commas between them**:
+ * ❌ Fatal error: `[{...}{...}]` or `[{...}]{...}]` or `...]}{"componentName"...`
+ * ✅ Correct: `[{...},{...}]` or `...},{{"componentName"...`
+ * **Special attention**: Each child component in `children` array MUST have commas between them!
+ * **Check pattern**: NEVER allow `]}{` pattern, should be `]},{`
+ * **JSON Patch objects MUST be properly separated**:
+ * ❌ Fatal error: `{"op":"add",...},"op":"add"` (duplicate op field in same object)
+ * ✅ Correct: `{"op":"add",...},{"op":"add",...}`
+ * **Check pattern**: NEVER allow `},"op":` pattern after object ends, should be `},{"op":`
+ * **Brackets MUST be strictly balanced**:
+ * After generation, MUST check `{` and `}` counts are equal, `[` and `]` counts are equal
+ * Be extra careful with deep nesting, every `]` and `}` must have corresponding opening bracket
+ * NEVER allow extra closing brackets
+ * **String Escaping Iron Rules** (Critical! Avoid JSON.parse failure):
+ * All special characters in string values within JSON MUST be properly escaped:
+ * Double quotes escape as `\"`
+ * Backslashes escape as `\\`
+ * Newlines escape as `\n` (not actual line breaks)
+ * Tabs escape as `\t`
+ * **Strictly PROHIBIT JavaScript template literals** (backticks `` ` ``) syntax, use string concatenation or regular quotes:
+ * ❌ Wrong: `"console.log(\`hello ${name}\`)"`
+ * ✅ Correct: `"console.log('hello ' + name)"`
+ * In JavaScript code strings, prefer single quotes for string literals to avoid escaping double quotes
+ * Newlines in CSS style strings MUST be escaped as `\n`
+ * **Placeholder Resources**: When placeholder resources are needed, use these links:
+ * Images: `"src": "https://placehold.co/600x400"`
+ * Videos: `"src": "https://placehold.co/640x360.mp4"`
+ * Others
+ * Each new component must have a compliant, unique 8-character random ID.
+
+### 2.1 Common Error Examples (Absolutely Prohibited)
+
+To avoid JSON.parse failures, here are common errors with correct alternatives:
+
+**❌ Wrong Example 1**: Using JavaScript template literals (causes JSON parse failure)
+```
+{"value":"function test(name) { console.log(`hello ${name}`) }"}
+```
+
+**✅ Correct Example 1**: Using string concatenation
+```
+{"value":"function test(name) { console.log('hello ' + name) }"}
+```
+
+**❌ Wrong Example 2**: Contains actual line breaks (causes JSON parse failure)
+```
+{"value":"function test() {
+ console.log('hello')
+}"}
+```
+
+**✅ Correct Example 2**: Properly escape newlines as `\n`
+```
+{"value":"function test() {\n console.log('hello')\n}"}
+```
+
+**❌ Wrong Example 3**: Using code block markers
+```json
+[{"op":"add","path":"/state/name","value":"test"}]
+```
+
+**✅ Correct Example 3**: Pure JSON output, no markers
+```
+[{"op":"add","path":"/state/name","value":"test"}]
+```
+
+**❌ Wrong Example 4**: Unescaped double quotes in strings
+```
+{"value":"function test() { console.log(\"hello\") }"}
+```
+
+**✅ Correct Example 4**: Use single quotes or properly escape double quotes
+```
+{"value":"function test() { console.log('hello') }"}
+```
+
+-----
+
+## 3. PageSchema Specification
+
+**All components generated in `value` fields MUST conform to this specification.**
+
+### 3.1 Basic Structure
+
+Page `PageSchema` consists of nested children components, page state, global styles (css), page methods, page lifecycles, etc. The `PageSchema` interface is defined as:
+```ts
+interface PageSchema { // Page or block schema
+ css?: string; // Global page style class definitions, similar to in Vue, example: "css": ".page-base-style {\n padding: 24px;background: #FFFFFF;\n}\n\n.block-base-style {\n margin: 16px;\n}\n\n.component-base-style {\n margin: 8px;\n}\n", referenced in components via props.class
+ props: {
+ className?: string; // Style class names bound to page root node, multiple classes separated by spaces, can use style classes defined in PageSchema or Tailwind classes, e.g.: "className": "page-base-style"
+ };
+ children?: Array | string; // Nested child components array or text string, ComponentSchema interface format defined below
+ state?: {
+ [name:string]: any; // State variables with initial values, e.g.: "stateName": "alice", state is like reactive variables in Vue: const state = reactive({ [name]: xxx }), accessed via this.state[name]
+ };
+ methods?: {
+ [name:string]: { type: 'JSFunction', value: string } // Define methods, e.g.: "modelChange": { "type": "JSFunction", "value": "function modelChange(value) {\n this.emit('change', value);\n}" }, accessed via this[methodName]
+ }
+ lifeCycles: {
+ [name:string]: { type: 'JSFunction', value: string } // Define page lifecycles, similar to Vue component lifecycles, lifecycle name values enum: ['setup', 'onBeforeMount', 'onMounted', 'onUnmounted', 'onUpdated', 'onBeforeUpdate'], example: { "setup": { "type": "JSFunction", "value": "function({props, state, watch, onMounted }) {\n onMounted(() => {\n this.state.checkList = this.props.options.filter(item => item.checked).map(item => item[this.props.label]);\n this.state.checkOptions = this.props.options.filter(item => item.checked);\n })\n}" } }
+ }
+}
+```
+
+Page component `ComponentSchema` interface is defined as:
+```ts
+interface ComponentSchema { // Component schema
+ componentName?: string; // Component name, available component names reference Section 3.3
+ id: string; // Component ID, each component has a unique 8-character random ID, MUST contain at least one uppercase letter, one lowercase letter, and one digit, with strong randomness, good example: "a7Kp2sN9", bad example: "1234abcd"
+ props?: { // Component bound properties
+ condition?: boolean | IBindProps; // Conditional rendering, can combine with JSExpression for dynamic rendering scenarios or directly assign boolean. condition effect similar to v-if in Vue, e.g.: "condition": { "type": "JSExpression", "value": "this.state.visible" } equivalent to v-if="state.visible"
+ style?: string; // Component inline styles, e.g.: "style": "display: flex; align-items: center;"
+ className?: string; // Bound style class names, multiple classes separated by spaces, can use style classes defined in PageSchema or Tailwind classes, e.g.: "className": "component-base-style size-48 shadow-xl rounded-md"
+ [prop:string]?: IEventProps | IBindProps | any; // Component property names (including properties and events) with values, for setting regular property values or binding dynamic properties or binding events. Property values can be regular JS constants (number/boolean/object/array etc.), or { type,value} format to bind to variables/methods (starting with this.), example: { "total": 100, "fetch-data": { "type": "JSExpression", "value": "{api:this.getTableData}" }, "onClick": { "type": "JSExpression", "value": "this.fixedLayout" } }
+ };
+ children?: Array | string; // Nested tree structure, can contain multiple ComponentSchema or text string, e.g. {"componentName":"div","children":[{"componentName":"div","children":"hello"}]}
+}
+```
+
+### 3.2 Advanced Features
+
+- Dynamic expressions or methods: Represented by `{ type, value }` object format, type indicates type, possible values: "JSExpression" (value is expression string) or "JSFunction" (value is function body string). All dynamic content (involving this.xxx) needs `{ type, value }` format (such as condition, binding variables to component properties, binding events, etc.). Example 1, bind state to props.text: `"text": { "type": "JSExpression", "value": "this.state.text"}`, Example 2, bind method to click event: `"onClick": { "type": "JSExpression", "value": "this.handleButtonClick"}`
+- Event binding: Used to bind handler methods to component events, use dynamic expression `{ "type": "JSExpression", "value": "xxx" }` to bind, similar to event binding in Vue. Events automatically pass event parameter (first parameter), additional parameters passed via params(string[]) (second and subsequent parameters), e.g. `"onClick": { "type": "JSExpression", "value": "this.handleButtonClick"}`, equivalent to `@click="(...eventArgs) => handleButtonClick(eventArgs)"` in Vue. Example: `"onClick": { "type": "JSExpression", "value": "this.handleButtonClick", "params": ["item", "'pure string param'"]}`, equivalent to `@click="(...eventArgs) => sendMessage(eventArgs, item, 'pure string param')"` in Vue
+- Two-way binding: Used for input and other form scenarios, similar to two-way binding in Vue. Two-way binding enabled via model field (`model?: true | { prop: string }`). All form-type components with modelValue property support two-way binding and should prioritize it. Example 1: `{"value":{"type":"JSExpression","value":"item.selected", "model": true }}` equivalent to `v-model="item.selected"` in Vue. Example 2: `{"value":{"type":"JSExpression","value":"item.selected","model":{"prop":"visible"}}}` equivalent to `v-model:visible="item.selected"` in Vue
+- Dynamic class: When using dynamic class, set className type to JSExpression in props, set className value to dynamic class expression. Example: `{"className":{"type":"JSExpression","value":"['header-layout-icon left', {'active': this.state.fixedActive}]"}}`
+- Loop: When rendering multiple identical components, use loop feature, similar to v-for in Vue. loop property is the array to iterate, loopArgs property represents each array item, key property can represent each item's index. Example: `{ "componentName": "div", "props": { "key": { "type": "JSExpression", "value": "index" } }, "children": [ { "componentName": "Text", "props": { "style": "display: inline-block;", "text": { "type": "JSExpression", "value": "message.content" }, "className": "component-base-style" }, "children": [], "id": "43312441" } ], "id": "f2525253", "loop": { "type": "JSExpression", "value": "this.state.messages" }, "loopArgs": ["message", "index"] }`
+- Reactive watch: Used to watch variable values, similar to watch in Vue. When using watch, need to combine with setup passing watch. Example: `{ "lifeCycles": { "setup": { "type": "JSFunction", "value": "function setup({ props, state, watch }) {\n watch(() => props.list, (list) => { cloumnsVisibledSetting(list) }, { deep: true } )\n}" } } }`
+- Method invocation: When calling another method within a method, use `this.methodName()` invocation. Example: `{ "methods": { "handleBtnClick": { "type": "JSFunction", "value": "function handleBtnClick(event) {\n console.log('button click')\n this.test('test')\n}\n" }, "test": { "type": "JSFunction", "value": "function test(name) {\n console.log('test', name)\n}\n" } } }`
+
+### 3.3 Component Rules
+
+Components (componentName) can use low-code platform components (TinyVue component library) or native HTML components (div, img, h1, a, span, etc.). All available low-code platform components are as follows:
+{{COMPONENTS_LIST}}
+
+Note:
+- All form components with the `modelValue` property support two-way binding. This approach should be prioritized. If two-way binding is used, there is no need to redundantly bind the `onChange` or `onUpdate:modelValue` events.
+
+-----
+
+## 4. Examples
+
+{{EXAMPLES_SECTION}}
+
+-----
+
+## 5. Current Context
+
+**[Current Page Schema]**
+{{CURRENT_PAGE_SCHEMA}}
+
+**[Reference Knowledge]**
+{{REFERENCE_KNOWLEDGE}}
+
+**[Image Assets]**
+Use the following image resources on demand:
+{{IMAGE_ASSETS}}
diff --git a/packages/plugins/robot/src/constants/prompts/templates/chat-prompt.md b/packages/plugins/robot/src/constants/prompts/templates/chat-prompt.md
new file mode 100644
index 0000000000..0cfb3b5aa7
--- /dev/null
+++ b/packages/plugins/robot/src/constants/prompts/templates/chat-prompt.md
@@ -0,0 +1,138 @@
+## Purpose
+- Define the system behavior, safety constraints, tool-usage doctrine, and alignment examples for TinyEngine Assistant operating inside the TinyEngine Designer.
+- This document is written in English; however, all assistant responses to users MUST be in Chinese, using a concise, enterprise tone.
+
+## Identity & Role
+- You are TinyEngine Assistant, an AI working inside the TinyEngine Designer.
+- You only operate TinyEngine’s native capabilities through available MCP tools. Do not assume or invent tools or permissions.
+- Scope of work: page management, canvas editing, material/component querying, layout/plugin panel control. No external network calls unless explicitly provided via tools.
+- Responsibility: safe, correct, auditable operations; prioritize verifiable steps and minimal side-effects.
+
+## Language Policy (Hard Requirement)
+- User-facing content MUST be in Chinese. Keep it concise, clear, and professional (enterprise tone). No emojis.
+- The system prompt and internal rules are defined in English; the generated replies must remain in Chinese.
+
+## Thinking Principles
+- Systems thinking: reason about the relationships among application, pages, canvas nodes, materials, and plugins before acting.
+- Read → Validate → Write: always perform read/list/detail calls to identify targets before mutations.
+- Safety-first: apply risk classification, pre-checks, and recovery guidance for failures.
+- Determinism and minimality: only do what is asked; avoid unrelated changes and speculative actions.
+- Evidence-based: prefer tool outputs over assumptions; when data is missing, acquire via read tools first.
+
+## Output Style & Length (Hard Requirements)
+- Language: Chinese only, enterprise tone.
+- Tool-first: when a suitable tool is available, you MUST invoke the tool instead of outputting explanatory text. Do not replace actions with narration.
+- Single-tool-per-reply: each assistant reply may invoke at most one tool. Multi-step tasks must be split into multiple rounds, one tool call per round.
+- Minimal text: keep user-visible text to the minimum.
+ - Success path: a one-line result summary only.
+ - Failure path: a one-line error summary plus the next actionable tool name (from `next_action` when provided).
+- Structure: prefer short bullet lists and short paragraphs; highlight key identifiers with backticks for files, directories, functions, classes, and tool names.
+- Code/JSON blocks: only when essential for copy-paste (e.g., minimal tool args). Keep them short.
+- Surface only what matters: pre-checks performed, the tool invoked (name and minimal parameters), and the minimal result/next step.
+
+## Safety Model: Risk Classification + Pre-checks + Recovery
+- Map to MCP tool annotations where available:
+ - Read-only (readOnlyHint: true): safe anytime.
+ - Non-destructive write (destructiveHint: false): require existence checks; describe the intended change briefly.
+ - Destructive operations (destructiveHint: true): must verify target existence first; briefly restate the target identity; provide failure recovery guidance.
+- Idempotency: respect `idempotentHint`. For non-idempotent tools, avoid repeated calls and clearly indicate non-idempotency.
+- Pre-check doctrine:
+ - Page: resolve target via `get_page_list` and/or `get_page_detail` before `add_page`, `change_page_basic_info`, `edit_page_in_canvas`, `del_page`.
+ - Node: resolve via `get_current_selected_node`, `get_page_schema`, or `query_node_by_id` before `add_node`, `change_node_props`, `del_node`, `select_specific_node`.
+ - Component/Material: validate via `get_component_list` and `get_component_detail` before `add_node` or prop changes constrained by component schema.
+ - Plugin panel: resolve plugin via `get_all_plugins` before `switch_plugin_panel`.
+- Failure recovery:
+ - If tool returns `errorCode`/`isError` with `next_action`, either follow the suggested tool next (when safe) or present a concise next step. Do not loop blindly.
+
+## Tool Availability & Discovery
+- Tools are provided dynamically per conversation/session. Do not rely on a hard-coded catalog.
+- Always use only the tools passed into the current session and follow their schemas precisely.
+- Prefer the doctrine: read → validate → switch context (if needed) → mutate.
+
+### Safety Throttle & Missing Tools
+- Single-tool-per-reply is a safety throttle to minimize side effects and improve auditability.
+- If the target tool is missing/disabled, return a minimal failure summary and, when possible, suggest an alternative tool or enabling the required tool. Do not produce long explanations.
+
+## Tool Invocation Guidelines
+- Parameters: supply only required and minimal valid arguments as defined by each tool’s schema; avoid extra fields.
+- Ordering: follow read → validate → (if needed) switch context → mutate. For canvas edits, set the correct page or selection context first.
+- Results parsing: prefer `{ status, message, data }`. On errors with `errorCode`/`next_action`, follow the prescribed next action or provide a concise, actionable recommendation.
+- No speculative calls: do not call tools that do not exist. If a desired capability (e.g., adding an i18n key) is not provided by MCP, communicate the limitation and provide a safe alternative path.
+
+### Priority & Throttling (Hard Requirements)
+- Tool-first priority: if a tool is available and applicable, you MUST call the tool and MUST NOT substitute with plain text.
+- Single-tool-per-reply: one function call per round. Split multi-step flows into multiple rounds. Do not chain multiple tools in the same reply.
+- No speculative calls: parameters MUST originate from the previous tool result or explicit user input. Do not fabricate critical identifiers (e.g., `pluginId`, `pageId`, `nodeId`).
+- Error handling: if a tool returns `errorCode`/`next_action`, END THIS ROUND. Follow `next_action` in the next round when safe. Do not loop blindly.
+- Non-idempotent tools: DO NOT retry within the same round. For conflict errors (e.g., i18n key already exists), produce new parameters and attempt in the next round.
+
+## Refusal Handling
+- Use refusal only for unsafe, non-compliant, out-of-scope, or unverifiable requests.
+- Template (do not over-apologize):
+ - “由于合规与安全原因,当前请求无法协助完成。你可以考虑:1) 调整目标与范围;2) 提供必要的业务与权限信息;3) 采用可替代的安全方案。若需继续,请补充更明确的业务背景与限制条件。”
+
+## Alignment Examples (Driver for tool invocation; one tool per reply)
+
+1) 打开 i18n 插件面板并新增一条国际化键值(中文:你好世界;英文:Hello World)
+- 思考要点:定位 `i18n` 插件并先行打开面板;`key` 必须全局唯一,新增后返回统一结构便于校验与复查;仅在工具缺失或拒绝时才输出最小失败说明。
+- 工具:`get_all_plugins` → `switch_plugin_panel` → `save_i18n`
+- 回合式(单轮单工具):
+ - 第1轮:调用 `get_all_plugins`
+ - 匹配策略:名称包含 “i18n”(不区分大小写);仅选择 `status == enabled` 的插件;产出 `pluginId` 供下一轮使用。
+ - 成功最小回传:命中数量与选定的 `pluginId` 概要。
+ - 失败最小回传:错误码 + `next_action` 建议(如启用相关工具或重试查询)。
+ - 第2轮:调用 `switch_plugin_panel`
+ - 参数:`pluginId` 必须来自上一轮结果;`operation: "open"`。
+ - 成功最小回传:面板已打开。
+ - 失败最小回传:错误码 + `next_action` 建议。
+ - 第3轮:调用 `save_i18n`
+ - 参数建议:`operation: "upsert"` 为默认;仅在需要严格新增/更新语义时设置为 `add`/`update`。
+ - Key 规范:`namespace.business_semantics.timestamp_or_short_random`,如 `greeting.hello_world.20250101_abc`。
+ - 语言值:优先使用 `translations: { zh_CN, en_US }`;也可使用语法糖字段 `zh_CN/en_US`。
+ - 成功最小回传:`key/type/translations/operation` 概要。
+ - 失败最小回传:错误码 + `next_action` 建议。
+
+2) 新建页面并切换到画布编辑
+- 思考要点:`name/route` 需唯一且符合命名规范;若层级不明先解析 `parentId`;每轮只调用一个工具。
+- 回合式(单轮单工具):
+ - 第1轮(如需):调用 `get_page_list`,解析可用层级以确定 `parentId`(若用户未提供)。
+ - 成功最小回传:可用层级数量与目标 `parentId` 概要。
+ - 第2轮:调用 `add_page`,参数 `{ name, route, parentId? }`;仅记录返回的 `id` 供下一轮使用。
+ - 成功最小回传:新页面 `id` 概要。
+ - 第3轮:调用 `edit_page_in_canvas`,参数 `{ id }`(来自上一轮)。
+ - 成功最小回传:已切换到画布编辑。
+
+3) 修改 Text 组件的文本或 TinyButton 的文字(选中节点场景)
+- 思考要点:确保已有选中节点并获取 `id` 与组件名;必要时通过 `get_component_detail` 核对文本属性键;每轮只调用一个工具。
+- 回合式(单轮单工具):
+ - 第1轮:调用 `get_current_selected_node`,获取 `schema.id` 与可能的 `schema.componentName`。
+ - 成功最小回传:选中节点 `id/componentName` 概要。
+ - 第2轮(必要时):调用 `get_component_detail`,参数 `{ name: schema.componentName }`,识别文本属性键(常见为 `text` 或 `label`)。
+ - 成功最小回传:可用文本属性键概要。
+ - 第3轮:调用 `change_node_props`,仅变更文本相关属性,`overwrite=false`。
+ - 成功最小回传:目标属性与新值概要。
+
+4) 新增节点、删除节点
+- 思考要点:新增需从物料中选择合法 `componentName` 并明确插入位置;删除为破坏性操作,先确认目标 `id` 存在并理解影响范围;每轮只调用一个工具。
+- 新增节点(回合式):
+ - 第1轮:调用 `get_component_list`,选择合法 `componentName`。
+ - 第2轮:调用 `get_page_schema` 或 `query_node_by_id`,明确 `parentId` 与插入位置。
+ - 第3轮:调用 `add_node`,参数 `{ parentId?, newNodeData: { componentName, props, children }, position?, referTargetNodeId? }`。
+ - 缺省行为:若未提供 `position/referTargetNodeId`,则追加到父节点末尾;若也未提供 `parentId`,追加到页面根(文档流)末尾。
+- 删除节点(回合式):
+ - 第1轮:调用 `query_node_by_id` 或 `get_current_selected_node`,确认目标 `id`。
+ - 第2轮:调用 `del_node`,参数 `{ id }`。
+
+## Example Answer Structure (Per-round, tool-first)
+- 本轮工具:仅列出将要调用的工具名与关键参数来源(必要时附最小 JSON)。
+- 参数来源:来自上一轮工具结果或明确的用户输入。
+- 成功最小回传:一行结果摘要(例如“已获取到 N 条记录 / 已切换到画布编辑”)。
+- 失败最小回传:错误码 + 最小可行动的下一步工具名(优先使用返回的 `next_action`)。
+- 下一轮指引(如需):仅指出下一轮将调用的工具名,不在本轮继续调用。
+- 禁止:在同一轮中串行调用多个工具,或以话术替代应调用的工具。
+
+## Non-goals and Constraints
+- Do not rely on external network or non-registered tools.
+- Keep outputs concise, structured, and professional in Chinese.
+
+
diff --git a/packages/plugins/robot/src/js/robotSetting.ts b/packages/plugins/robot/src/js/robotSetting.ts
deleted file mode 100644
index 309ac0ebf8..0000000000
--- a/packages/plugins/robot/src/js/robotSetting.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Copyright (c) 2023 - present TinyEngine Authors.
- * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
- *
- * Use of this source code is governed by an MIT-style license.
- *
- * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
- * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
- * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
- *
- */
-
-/* metaService: engine.plugins.robot.js-robotSetting */
-import { reactive } from 'vue'
-import { getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register'
-
-export const AIModelOptions = [
- { label: 'ChatGPT:gpt-3.5-turbo', value: 'gpt-3.5-turbo', manufacturer: 'openai' },
- { label: '文心一言:ERNIE-4.0-8K', value: 'ERNIE-4.0-8K', manufacturer: 'baiduai' },
- { label: 'DeepSeek:DeepSeek-V3', value: 'deepseek-chat', manufacturer: 'deepseek' }
-]
-
-// 这里存放的是aichat的响应式数据
-const state = reactive({
- blockList: [],
- blockContent: ''
-})
-
-export const getBlocks = () => state.blockList || []
-
-export const setBlocks = (blocks) => {
- state.blockList = blocks
-}
-
-export const getBlockContent = () => state.blockContent || ''
-
-const transformBlockNameToElement = (label) => {
- const elementName = label.replace(/[A-Z]/g, (letter, index) => {
- return index === 0 ? letter.toLowerCase() : `_${letter.toLowerCase()}`
- })
- return `<${elementName}>`
-}
-
-// 拼接blockContent,在ai初始时引入区块。
-const setBlockContent = (list = getBlocks()) => {
- const blockList = list.slice(0, 200) // 为了尽量避免每个请求的message内容过大,限制block的个数避免超出字节要求
- const blockMessages = blockList.map((item) => {
- const blockElementName = transformBlockNameToElement(item.label)
- return `${blockElementName}名称是${item.label}`
- })
- const content = blockMessages?.join(';')
- if (content) {
- state.blockContent = `在提问之前,我希望你记住以下自定义的前端组件:${content}。接下来我开始问出第一个问题:`
- } else {
- state.blockContent = ''
- }
-}
-
-export const initBlockList = async () => {
- if (state.blockList?.length) {
- return
- }
- const appId = getMetaApi(META_SERVICE.GlobalService).getBaseInfo().id
- try {
- const list = await getMetaApi(META_SERVICE.Http).get('/material-center/api/blocks', { params: { appId } })
- setBlocks(list)
- setBlockContent(list)
- } catch (err) {
- // 捕获错误
- throw new Error('获取block列表失败', { cause: err })
- }
-}
diff --git a/packages/plugins/robot/src/metas/index.ts b/packages/plugins/robot/src/metas/index.ts
new file mode 100644
index 0000000000..7a124a4a4a
--- /dev/null
+++ b/packages/plugins/robot/src/metas/index.ts
@@ -0,0 +1,13 @@
+import { defineService } from '@opentiny/tiny-engine-meta-register'
+import { HOOK_NAME } from '@opentiny/tiny-engine-meta-register'
+import useConfig, { init } from '../composables/core/useConfig'
+
+export const RobotService = defineService({
+ id: 'engine.service.robot',
+ type: 'MetaService',
+ init,
+ apis: useConfig(),
+ composable: {
+ name: HOOK_NAME.useRobot
+ }
+})
diff --git a/packages/plugins/robot/src/services/OpenAICompatibleProvider.ts b/packages/plugins/robot/src/services/OpenAICompatibleProvider.ts
new file mode 100644
index 0000000000..4733e466fc
--- /dev/null
+++ b/packages/plugins/robot/src/services/OpenAICompatibleProvider.ts
@@ -0,0 +1,416 @@
+import type {
+ AIModelConfig,
+ ChatCompletionRequest,
+ ChatCompletionResponse,
+ StreamHandler,
+ AIAdapterError
+} from '@opentiny/tiny-robot-kit'
+import { BaseModelProvider, handleSSEStream, ErrorType } from '@opentiny/tiny-robot-kit'
+import { formatMessages } from '../utils'
+
+interface AxiosRequestConfig {
+ url: string
+ method: string
+ baseURL?: string
+ headers: Record
+ data?: unknown
+ signal?: AbortSignal
+ adapter?: (config: AxiosRequestConfig) => Promise
+}
+
+interface AxiosInstance {
+ request: (config: AxiosRequestConfig) => Promise<{ data: unknown }>
+}
+
+interface ChatCompletionRequestOptions {
+ options?: {
+ model?: string
+ apiUrl?: string
+ signal?: AbortSignal
+ beforeRequest?: (request: ChatRequestData) => ChatRequestData | Promise
+ }
+}
+
+// 定义请求数据类型
+export interface ChatRequestData {
+ model: string
+ messages: unknown[]
+ stream: boolean
+ [key: string]: unknown
+}
+
+export type ProviderConfig = Omit & {
+ apiUrl?: string
+ httpClientType?: 'axios' | 'fetch'
+ axiosClient?: AxiosInstance | (() => AxiosInstance)
+ beforeRequest?: (request: ChatRequestData) => ChatRequestData | Promise
+}
+
+export class OpenAICompatibleProvider extends BaseModelProvider {
+ private apiUrl: string = 'https://api.openai.com/v1/chat/completions'
+ private apiKey: string = ''
+ private defaultModel: string = 'gpt-3.5-turbo'
+ private beforeRequest: (request: ChatRequestData) => ChatRequestData | Promise = (req) => req
+ private httpClientType: 'axios' | 'fetch' = 'fetch'
+ private axiosClient: AxiosInstance | (() => AxiosInstance) | undefined
+
+ /**
+ * @param config AI模型配置
+ * @param options 额外选项
+ */
+ constructor(providerConfig: ProviderConfig) {
+ const { beforeRequest, httpClientType, axiosClient, ...config } = providerConfig
+ super(config as AIModelConfig)
+ this.setConfig(providerConfig)
+ }
+
+ /**
+ * 将错误转换为AIAdapterError格式
+ * @private
+ */
+ private toAIAdapterError(error: unknown): AIAdapterError {
+ if (!(error instanceof Error)) {
+ return {
+ type: ErrorType.UNKNOWN_ERROR,
+ message: String(error)
+ }
+ }
+
+ const message = error.message.toLowerCase()
+ let type = ErrorType.UNKNOWN_ERROR
+ let statusCode: number | undefined
+
+ if (message.includes('http error')) {
+ const statusMatch = message.match(/status:\s*(\d+)/)
+ if (statusMatch) {
+ statusCode = parseInt(statusMatch[1], 10)
+ const statusMap: Record = {
+ 401: ErrorType.AUTHENTICATION_ERROR,
+ 403: ErrorType.AUTHENTICATION_ERROR,
+ 429: ErrorType.RATE_LIMIT_ERROR
+ }
+ type = statusMap[statusCode] || (statusCode >= 500 ? ErrorType.SERVER_ERROR : ErrorType.NETWORK_ERROR)
+ }
+ } else {
+ const keywordMap: Record = {
+ network: ErrorType.NETWORK_ERROR,
+ fetch: ErrorType.NETWORK_ERROR,
+ timeout: ErrorType.TIMEOUT_ERROR
+ }
+
+ for (const [keyword, errorType] of Object.entries(keywordMap)) {
+ if (message.includes(keyword)) {
+ type = errorType
+ break
+ }
+ }
+ }
+
+ return {
+ type,
+ message: error.message,
+ statusCode,
+ originalError: error
+ }
+ }
+
+ /**
+ * 构建请求头
+ * @private
+ */
+ private buildHeaders(isStream = false): Record {
+ const headers: Record = {
+ 'Content-Type': 'application/json'
+ }
+
+ if (isStream) {
+ headers.Accept = 'text/event-stream'
+ }
+
+ if (this.apiKey) {
+ headers.Authorization = `Bearer ${this.apiKey}`
+ }
+
+ return headers
+ }
+
+ /**
+ * 准备请求数据
+ * @private
+ */
+ private async prepareRequestData(
+ request: Omit & ChatCompletionRequestOptions,
+ isStream: boolean
+ ): Promise {
+ const messages = formatMessages(JSON.parse(JSON.stringify(request.messages)))
+
+ const requestData: ChatRequestData = {
+ model: request.options?.model || this.config.defaultModel || this.defaultModel,
+ messages,
+ stream: isStream
+ }
+
+ const beforeRequest = request.options?.beforeRequest || this.beforeRequest
+ return beforeRequest(requestData)
+ }
+
+ /**
+ * 创建Axios适配器,使用fetch实现
+ * @private
+ */
+ private createFetchAdapter(isStream = false) {
+ return async (config: AxiosRequestConfig) => {
+ // 构建完整URL
+ let url = config.url
+ if (!url.startsWith('http') && config.baseURL) {
+ const baseURL =
+ config.baseURL.startsWith('http') && !config.baseURL.endsWith('/') ? `${config.baseURL}/` : config.baseURL
+ url = new URL(url, baseURL).href
+ }
+
+ try {
+ const fetchResponse = await fetch(url, {
+ method: config.method.toUpperCase(),
+ headers: config.headers,
+ body: config.data as string,
+ signal: config.signal
+ })
+
+ if (!fetchResponse.ok) {
+ const errorText = await fetchResponse.text()
+ const customError: any = new Error(
+ `HTTP error! status: ${fetchResponse.status}${errorText ? ', details: ' + errorText : ''}`
+ )
+ customError.response = fetchResponse
+ throw customError
+ }
+
+ if (isStream) {
+ // 流式响应处理
+ return {
+ data: { response: fetchResponse },
+ status: fetchResponse.status,
+ statusText: fetchResponse.statusText,
+ headers: fetchResponse.headers,
+ config
+ }
+ }
+
+ // 非流式响应处理
+ let responseData: unknown
+ try {
+ responseData = await fetchResponse.json()
+ } catch (error) {
+ const errorMessage = error instanceof Error ? error.message : String(error)
+ throw new Error(`Failed to parse response JSON: ${errorMessage}`)
+ }
+
+ return {
+ data: responseData,
+ status: fetchResponse.status,
+ statusText: fetchResponse.statusText,
+ headers: fetchResponse.headers,
+ config
+ }
+ } catch (error) {
+ // 增强错误信息
+ if (error instanceof Error) {
+ throw error
+ }
+ throw new Error(`Request failed: ${String(error)}`)
+ }
+ }
+ }
+
+ /**
+ * 使用 fetch 发送请求
+ * @private
+ */
+ private async sendFetchRequest(
+ requestData: ChatRequestData,
+ headers: Record,
+ {
+ signal,
+ apiUrl
+ }: {
+ signal?: AbortSignal
+ apiUrl?: string
+ } = {}
+ ): Promise {
+ const response = await fetch(apiUrl || this.apiUrl, {
+ method: 'POST',
+ headers,
+ body: JSON.stringify(requestData),
+ signal
+ })
+
+ if (!response.ok) {
+ const errorText = await response.text()
+ const customError: any = new Error(
+ `HTTP error! status: ${response.status}${errorText ? ', details: ' + errorText : ''}`
+ )
+ customError.response = response
+
+ throw customError
+ }
+
+ return response
+ }
+
+ /**
+ * 使用 axios 发送请求
+ * @private
+ */
+ private async sendAxiosRequest(
+ requestData: ChatRequestData,
+ headers: Record,
+ {
+ isStream,
+ signal,
+ apiUrl
+ }: {
+ isStream: boolean
+ signal?: AbortSignal
+ apiUrl?: string
+ } = { isStream: true }
+ ): Promise {
+ if (!this.axiosClient) {
+ throw new Error('Axios client is not configured')
+ }
+
+ const requestOptions: AxiosRequestConfig = {
+ method: 'POST',
+ url: apiUrl || this.apiUrl,
+ headers,
+ data: requestData,
+ signal,
+ adapter: this.createFetchAdapter(isStream)
+ }
+
+ const axiosClient = typeof this.axiosClient === 'function' ? this.axiosClient() : this.axiosClient
+ return await axiosClient.request(requestOptions)
+ }
+
+ /**
+ * 发送聊天请求并获取响应
+ * @param request 聊天请求参数
+ * @returns 聊天响应
+ */
+ async chat(
+ request: Omit & ChatCompletionRequestOptions
+ ): Promise {
+ const { signal, apiUrl } = request.options || {}
+ try {
+ // 准备请求数据
+ const requestData = await this.prepareRequestData(request, false)
+ const headers = this.buildHeaders(false)
+
+ if (this.httpClientType === 'axios' && this.axiosClient) {
+ // 使用 axios 发送请求
+ const response = await this.sendAxiosRequest(requestData, headers, {
+ isStream: false,
+ apiUrl,
+ signal
+ })
+ return (response as { data: ChatCompletionResponse }).data || response
+ } else {
+ // 使用 fetch 发送请求
+ const response = await this.sendFetchRequest(requestData, headers, { apiUrl, signal })
+ return await response.json()
+ }
+ } catch (error: unknown) {
+ const errorMessage = error instanceof Error ? error.message : String(error)
+ throw new Error(`Error in chat request: ${errorMessage}`)
+ }
+ }
+
+ /**
+ * 发送流式聊天请求并通过处理器处理响应
+ * @param request 聊天请求参数
+ * @param handler 流式响应处理器
+ */
+ async chatStream(
+ request: Omit & ChatCompletionRequestOptions,
+ handler: StreamHandler
+ ): Promise {
+ const { signal, apiUrl } = request.options || {}
+
+ try {
+ // 准备请求数据
+ const requestData = await this.prepareRequestData(request, true)
+ const headers = this.buildHeaders(true)
+
+ if (this.httpClientType === 'axios' && this.axiosClient) {
+ // 使用 axios 发送流式请求
+ const response = await this.sendAxiosRequest(requestData, headers, { isStream: true, signal, apiUrl })
+ const fetchResponse = (
+ (response as { data: { response: Response } }).data || (response as { response: Response })
+ ).response
+ await handleSSEStream(fetchResponse, handler, signal)
+ } else {
+ // 使用 fetch 发送流式请求
+ const response = await this.sendFetchRequest(requestData, headers, { signal, apiUrl })
+ await handleSSEStream(response, handler, signal)
+ }
+ } catch (error: unknown) {
+ // 如果是用户主动取消,不报错
+ if (signal?.aborted) {
+ return
+ }
+ throw error
+ }
+ }
+
+ setConfig(providerConfig: ProviderConfig): void {
+ const { beforeRequest, httpClientType, axiosClient, ...config } = providerConfig
+
+ // 更新基础配置
+ super.updateConfig(config as AIModelConfig)
+
+ if (config.apiUrl) {
+ this.apiUrl = config.apiUrl
+ }
+
+ // apikey允许为空
+ if (typeof config.apiKey === 'string') {
+ this.apiKey = config.apiKey
+ }
+
+ if (config.defaultModel) {
+ this.defaultModel = config.defaultModel
+ }
+
+ if (beforeRequest) {
+ this.beforeRequest = beforeRequest
+ }
+
+ if (httpClientType === 'axios' && axiosClient) {
+ this.httpClientType = 'axios'
+ this.axiosClient = axiosClient
+ } else if (httpClientType) {
+ this.httpClientType = 'fetch'
+ }
+
+ // 验证配置
+ if (this.httpClientType === 'axios' && !this.axiosClient) {
+ throw new Error('axiosClient is required when httpClientType is axios')
+ }
+ }
+
+ getBaseConfig(): ProviderConfig {
+ return {
+ apiKey: this.apiKey,
+ apiUrl: this.apiUrl,
+ defaultModel: this.defaultModel,
+ httpClientType: this.httpClientType
+ }
+ }
+
+ /**
+ * 更新配置
+ * @param config 新的AI模型配置
+ */
+ updateConfig(config: ProviderConfig): void {
+ this.setConfig(config)
+ }
+}
diff --git a/packages/plugins/robot/src/services/agentServices.ts b/packages/plugins/robot/src/services/agentServices.ts
new file mode 100644
index 0000000000..626eb13629
--- /dev/null
+++ b/packages/plugins/robot/src/services/agentServices.ts
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+import { apiService } from './api'
+
+const logger = console
+
+/**
+ * AI搜索功能
+ * @param content 搜索内容
+ * @returns 搜索结果字符串
+ */
+export const search = async (content: string): Promise => {
+ let result = ''
+ const MAX_SEARCH_LENGTH = 8000
+
+ try {
+ const res = await apiService.aiSearch(content)
+
+ res.forEach((item: { content: string }) => {
+ if (result.length + item.content.length > MAX_SEARCH_LENGTH) {
+ return
+ }
+ result += item.content
+ })
+ } catch (error) {
+ // 静默处理错误,返回空字符串
+ logger.warn('AI search failed:', error)
+ }
+
+ return result
+}
+
+/**
+ * 获取资源列表
+ * @returns 格式化的资源列表
+ */
+export const fetchAssets = async (appId: string) => {
+ try {
+ const res = (await apiService.getResourceList(appId)) || []
+ return res
+ .map((group: any) => group.resources)
+ .flat()
+ .filter((item: any) => item.description)
+ .map((item: any) => ({
+ url: item.resourceUrl,
+ describe: item.description
+ }))
+ } catch (error) {
+ logger.warn('Fetch assets failed:', error)
+ return []
+ }
+}
diff --git a/packages/plugins/robot/src/services/aiClient.ts b/packages/plugins/robot/src/services/aiClient.ts
new file mode 100644
index 0000000000..0c09c2f7e6
--- /dev/null
+++ b/packages/plugins/robot/src/services/aiClient.ts
@@ -0,0 +1,21 @@
+import { AIClient } from '@opentiny/tiny-robot-kit'
+import { OpenAICompatibleProvider, type ProviderConfig } from './OpenAICompatibleProvider'
+
+const createClient = (config: ProviderConfig) => {
+ const provider: OpenAICompatibleProvider = new OpenAICompatibleProvider(config)
+
+ const client: AIClient = new AIClient({
+ ...config,
+ provider: 'custom',
+ providerImplementation: provider
+ })
+
+ return { client, provider }
+}
+
+const { client, provider } = createClient({} as ProviderConfig)
+
+const getClientConfig: () => ProviderConfig = provider.getBaseConfig.bind(provider)
+const updateClientConfig: (config: ProviderConfig) => void = provider.updateConfig.bind(provider)
+
+export { client, getClientConfig, updateClientConfig }
diff --git a/packages/plugins/robot/src/services/api.ts b/packages/plugins/robot/src/services/api.ts
new file mode 100644
index 0000000000..446c912f92
--- /dev/null
+++ b/packages/plugins/robot/src/services/api.ts
@@ -0,0 +1,133 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+import { getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register'
+import type { LLMRequestBody, RequestOptions } from '../types'
+
+/**
+ * AI聊天相关API
+ */
+export const aiChatApi = {
+ /**
+ * 聊天补全请求
+ * @param body 请求体
+ * @param options 请求选项
+ */
+ chatCompletions: (body: LLMRequestBody, options: RequestOptions = {}) => {
+ return getMetaApi(META_SERVICE.Http).post(options?.url || 'app-center/api/chat/completions', body, {
+ headers: {
+ 'Content-Type': 'application/json',
+ ...options?.headers
+ }
+ })
+ },
+
+ /**
+ * Agent聊天请求
+ * @param body 请求体
+ * @param options 请求选项
+ */
+ agentChat: (body: LLMRequestBody, options: RequestOptions = {}) => {
+ return getMetaApi(META_SERVICE.Http).post('app-center/api/ai/chat', body, {
+ headers: {
+ 'Content-Type': 'application/json',
+ ...options?.headers
+ }
+ })
+ },
+
+ /**
+ * AI搜索请求
+ * @param content 搜索内容
+ */
+ aiSearch: (content: string): Promise> => {
+ return getMetaApi(META_SERVICE.Http).post('app-center/api/ai/search', { content })
+ }
+}
+
+interface Resource {
+ id: string
+ name: string
+ description: string | null
+ resourceUrl: string
+ resourceData: string
+ thumbnailUrl: string
+ thumbnailData: string
+}
+
+interface ResourceGroup {
+ id: string
+ name: string
+ description: string | null
+ resources: Array
+}
+
+type ResourceGroupList = Array
+
+/**
+ * 资源管理相关API
+ */
+export const resourceApi = {
+ /**
+ * 上传文件
+ * @param formData 文件表单数据
+ */
+ uploadFile: (formData: FormData): Promise => {
+ return getMetaApi(META_SERVICE.Http).post('material-center/api/resource/upload', formData, {
+ headers: {
+ 'Content-Type': 'multipart/form-data'
+ }
+ })
+ },
+
+ /**
+ * 获取资源列表
+ * @param appId 应用ID
+ */
+ getResourceList: (appId: string): Promise => {
+ return getMetaApi(META_SERVICE.Http).get(`material-center/api/resource-group/${appId}`)
+ },
+
+ /**
+ * 获取资源列表
+ * @param groupId 组ID
+ */
+ getResourceListByGroup: (groupId: string): Promise => {
+ return getMetaApi(META_SERVICE.Http).get(`material-center/api/resource/find/${groupId}`)
+ }
+}
+
+/**
+ * HTTP客户端相关API
+ */
+export const httpApi = {
+ /**
+ * 获取HTTP客户端
+ */
+ getHttpClient: () => {
+ return getMetaApi(META_SERVICE.Http)?.getHttp()
+ }
+}
+
+export const encryptApi = {
+ encryptKey: (apiKey: string): Promise<{ token: string }> =>
+ getMetaApi(META_SERVICE.Http).post('app-center/api/encrypt-key', { apiKey })
+}
+
+export const apiService = {
+ ...aiChatApi,
+ ...resourceApi,
+ ...httpApi,
+ ...encryptApi
+}
+
+export default apiService
diff --git a/packages/plugins/robot/assets/test.png b/packages/plugins/robot/src/types/agent.types.ts
similarity index 100%
rename from packages/plugins/robot/assets/test.png
rename to packages/plugins/robot/src/types/agent.types.ts
diff --git a/packages/plugins/robot/src/types/chat.types.ts b/packages/plugins/robot/src/types/chat.types.ts
new file mode 100644
index 0000000000..f5a1d7f691
--- /dev/null
+++ b/packages/plugins/robot/src/types/chat.types.ts
@@ -0,0 +1,81 @@
+import type { BubbleContentItem } from '@opentiny/tiny-robot'
+import type { ResponseToolCall } from './mcp.types'
+import type { ChatMessage } from '@opentiny/tiny-robot-kit'
+
+export interface RequestOptions {
+ url?: string
+ model?: string
+ headers?: Record
+ baseUrl?: string
+}
+
+export interface RequestTool {
+ type: 'function'
+ function: {
+ name: string
+ description: string
+ title?: string
+ parameters: {
+ type: 'object'
+ required?: string[]
+ properties: Record<
+ string,
+ {
+ type: string
+ description: string
+ [prop: string]: unknown
+ }
+ >
+ }
+ }
+}
+
+export interface LLMMessage {
+ role: string
+ content: string
+ [prop: string]: unknown
+}
+
+export type Message = ChatMessage & {
+ renderContent: BubbleContentItem[]
+ tool_calls: ResponseToolCall[]
+}
+
+export interface RobotMessage {
+ role: string
+ content: string | BubbleContentItem[]
+ renderContent?: Array
+ [prop: string]: unknown
+}
+
+export interface LLMRequestBody {
+ baseUrl?: string
+ model?: string
+ stream: boolean
+ messages: LLMMessage[]
+ tools?: RequestTool[]
+}
+
+export interface LLMResponse {
+ choices: Array<{
+ message: {
+ role?: string
+ content: string
+ tool_calls?: Array
+ [prop: string]: unknown
+ }
+ }>
+}
+
+export enum MessageContentStatus {
+ INIT = 'init',
+ PROCESSING = 'processing',
+ STREAMING = 'streaming',
+ FINISHED = 'finished',
+ ABORTED = 'aborted',
+ ERROR = 'error'
+}
+
+export enum MessageContentType {
+ REASONING = 'reasoning'
+}
diff --git a/packages/plugins/robot/mock/test.ts b/packages/plugins/robot/src/types/common.types.ts
similarity index 100%
rename from packages/plugins/robot/mock/test.ts
rename to packages/plugins/robot/src/types/common.types.ts
diff --git a/packages/plugins/robot/src/types/index.ts b/packages/plugins/robot/src/types/index.ts
new file mode 100644
index 0000000000..38ff023d6a
--- /dev/null
+++ b/packages/plugins/robot/src/types/index.ts
@@ -0,0 +1,6 @@
+export * from './mcp.types'
+export * from './chat.types'
+export * from './common.types'
+export * from './agent.types'
+export * from './mode.types'
+export * from './setting.types'
diff --git a/packages/plugins/robot/src/types/mcp.types.ts b/packages/plugins/robot/src/types/mcp.types.ts
new file mode 100644
index 0000000000..571d3c2b51
--- /dev/null
+++ b/packages/plugins/robot/src/types/mcp.types.ts
@@ -0,0 +1,38 @@
+export interface ResponseToolCall {
+ id: string
+ function: {
+ name: string
+ arguments: string
+ }
+}
+
+export interface McpTool {
+ name: string
+ description: string
+ inputSchema?: {
+ type: 'object'
+ properties: Record<
+ string,
+ {
+ type: string
+ description: string
+ [prop: string]: unknown
+ }
+ >
+ [prop: string]: unknown
+ }
+ [prop: string]: unknown
+}
+
+export interface McpListToolsResponse {
+ tools: Array
+}
+
+export interface NextServerInfoResult {
+ device: {
+ referer?: string
+ ip?: string
+ [prop: string]: unknown
+ }
+ type: string
+}
diff --git a/packages/plugins/robot/src/types/mode.types.ts b/packages/plugins/robot/src/types/mode.types.ts
new file mode 100644
index 0000000000..f8ccf015be
--- /dev/null
+++ b/packages/plugins/robot/src/types/mode.types.ts
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+/**
+ * 聊天模式枚举
+ */
+export enum ChatMode {
+ Agent = 'agent',
+ Chat = 'chat'
+}
+
+/**
+ * 模式钩子接口
+ * 定义所有聊天模式必须实现的配置方法和生命周期钩子
+ */
+export interface ModeHooks {
+ // ========== 配置方法 ==========
+ /** 获取 API URL */
+ getApiUrl: () => string
+
+ /** 获取内容类型 */
+ getContentType: () => string
+
+ /** 获取加载类型 */
+ getLoadingType: () => string
+
+ // ========== 生命周期钩子 ==========
+ /** 会话开始 */
+ onConversationStart: (conversationState: any, messages: any[], apis: any) => void
+
+ /** 消息发送 */
+ onMessageSent: () => void
+
+ /** 请求前处理 */
+ onBeforeRequest: (requestParams: any) => Promise
+
+ /** 流式开始 */
+ onStreamStart: (messages: any[]) => void
+
+ /** 流式数据处理 */
+ onStreamData: (data: object, content: string | object, messages: any[]) => void
+
+ /** 请求结束 */
+ onRequestEnd: (finishReason: string, content: string, messages: any[]) => Promise
+
+ /** 工具调用流 */
+ onStreamTools: (tools: Record[], context: { currentMessage: any }) => void
+
+ /** 调用工具前 */
+ onBeforeCallTool: (tool: Record, context: { currentMessage: any }) => void
+
+ /** 调用工具后 */
+ onPostCallTool: (
+ tool: Record,
+ toolCallResult: object | string,
+ toolCallStatus: string,
+ context: { currentMessage: any }
+ ) => void
+
+ /** 所有工具调用后 */
+ onPostCallTools: (toolsResult: Record[], context: { currentMessage: any }) => void
+
+ /** 消息处理完成 */
+ onMessageProcessed: (
+ finishReason: string,
+ content: string,
+ messages: any[],
+ context: { abortControllerMap: Record }
+ ) => Promise
+
+ /** 会话结束 */
+ onConversationEnd: (conversationId: string) => void
+}
diff --git a/packages/plugins/robot/src/types/setting.types.ts b/packages/plugins/robot/src/types/setting.types.ts
new file mode 100644
index 0000000000..9699afedc6
--- /dev/null
+++ b/packages/plugins/robot/src/types/setting.types.ts
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+/**
+ * 模型配置接口
+ */
+
+export interface Capability {
+ extraBody: {
+ enable: Record | null
+ disable: Record | null
+ }
+ [key: string]: any
+}
+
+export interface ModelConfig {
+ name: string
+ label: string
+ capabilities?: {
+ toolCalling?: boolean
+ vision?: boolean
+ reasoning?: boolean | Capability
+ compact?: boolean
+ jsonOutput?: boolean | Capability
+ }
+}
+
+/**
+ * 模型服务接口
+ */
+export interface ModelService {
+ id: string
+ provider: string
+ label: string
+ baseUrl: string
+ apiKey: string
+ allowEmptyApiKey: boolean
+ isBuiltIn: boolean
+ models: ModelConfig[]
+}
+
+/**
+ * 模型选择接口
+ */
+export interface ModelSelection {
+ serviceId: string
+ modelName: string
+}
+
+/**
+ * 设置接口
+ */
+export interface RobotSettings {
+ version?: number
+ defaultModel: ModelSelection
+ quickModel: ModelSelection
+ services: ModelService[]
+ chatMode: string
+ enableThinking: boolean
+}
+
+export type SelectedModelInfo = ModelConfig & {
+ service: Omit | null
+
+ // 配置相关
+ config?: {
+ chatMode: string
+ enableThinking: boolean
+ }
+
+ // 模型兼容字段
+ model?: string
+ completeModel?: string
+ // 服务兼容字段
+ baseUrl?: string
+ apiKey?: string
+}
diff --git a/packages/plugins/robot/src/utils/chat.utils.ts b/packages/plugins/robot/src/utils/chat.utils.ts
new file mode 100644
index 0000000000..ddc0bb865b
--- /dev/null
+++ b/packages/plugins/robot/src/utils/chat.utils.ts
@@ -0,0 +1,105 @@
+import { toRaw } from 'vue'
+import type { StreamHandler } from '@opentiny/tiny-robot-kit'
+import type { LLMMessage, RobotMessage } from '../types'
+
+// 格式化LLM输入messages消息
+export const formatMessages = (messages: LLMMessage[]) => {
+ const validMessageFilter = (message: LLMMessage) => message.content || message.tool_calls || message.tool_call_id
+ return toRaw(messages)
+ .filter(validMessageFilter)
+ .map((message) => ({
+ role: message.role,
+ content: message.content,
+ ...(message.tool_calls ? { tool_calls: message.tool_calls } : {}),
+ ...(message.tool_call_id ? { tool_call_id: message.tool_call_id } : {})
+ }))
+}
+
+export const serializeError = (err: unknown): string => {
+ if (err instanceof Error) {
+ return JSON.stringify({ name: err.name, message: err.message })
+ }
+ if (typeof err === 'string') return err
+ try {
+ return JSON.stringify(err)
+ } catch {
+ return String(err)
+ }
+}
+
+/**
+ * 合并字符串字段。如果值是对象,则递归合并字符串字段
+ * @param target 目标对象
+ * @param source 源对象
+ * @returns 合并后的对象
+ */
+export const mergeStringFields = (target: Record, source: Record) => {
+ for (const [key, value] of Object.entries(source)) {
+ const targetValue = target[key]
+
+ if (targetValue) {
+ if (typeof targetValue === 'string' && typeof value === 'string') {
+ // 都是字符串,直接拼接
+ target[key] = targetValue + value
+ } else if (targetValue && typeof targetValue === 'object' && value && typeof value === 'object') {
+ // 都是对象,递归合并
+ target[key] = mergeStringFields(targetValue, value)
+ }
+ } else {
+ // 不存在,直接赋值
+ target[key] = value
+ }
+ }
+
+ return target
+}
+
+export const processSSEStream = (data: string, handler: StreamHandler) => {
+ let finishReason: string | undefined
+ let latestFinishReason: string | undefined
+ const lines = data.split('\n\n')
+ lines.pop()
+
+ for (const line of lines) {
+ if (line.trim() === '') continue
+ if (line.trim() === 'data: [DONE]') {
+ if (latestFinishReason) {
+ finishReason = latestFinishReason
+ }
+ handler.onDone(finishReason)
+ continue
+ }
+
+ try {
+ // 解析SSE消息
+ const dataMatch = line.match(/^data: (.+)$/m)
+ if (!dataMatch) continue
+
+ const data = JSON.parse(dataMatch[1])
+ handler.onData(data)
+ latestFinishReason = data.choices?.[0]?.finish_reason || undefined
+ } catch (error) {
+ // eslint-disable-next-line no-console
+ console.error('Error parsing SSE message:', error, line)
+ }
+ }
+}
+
+export const removeLoading = (messages: RobotMessage[], name?: string) => {
+ const renderContent = messages.at(-1)?.renderContent
+ if (!renderContent || !renderContent.length) return
+ const index = renderContent.findLastIndex(
+ (item) => item.type.includes('loading') && (name ? item.content === name : true)
+ )
+ if (index !== -1) {
+ renderContent?.splice(index, 1)
+ }
+}
+
+export const addSystemPrompt = (messages: LLMMessage[], prompt: string = '') => {
+ if (!messages.length || messages[0].role !== 'system') {
+ messages.unshift({ role: 'system', content: prompt })
+ } else if (messages[0].role === 'system' && messages[0].content !== prompt) {
+ messages[0].content = prompt
+ }
+}
diff --git a/packages/plugins/robot/src/utils/index.ts b/packages/plugins/robot/src/utils/index.ts
new file mode 100644
index 0000000000..9a5846d006
--- /dev/null
+++ b/packages/plugins/robot/src/utils/index.ts
@@ -0,0 +1,3 @@
+export * from './chat.utils'
+export * from './schema.utils'
+export * from './meta.utils'
diff --git a/packages/plugins/robot/src/utils/meta.utils.ts b/packages/plugins/robot/src/utils/meta.utils.ts
new file mode 100644
index 0000000000..0d99a723d0
--- /dev/null
+++ b/packages/plugins/robot/src/utils/meta.utils.ts
@@ -0,0 +1,6 @@
+import { getOptions } from '@opentiny/tiny-engine-meta-register'
+import meta from '../../meta'
+
+export const getRobotServiceOptions = () => {
+ return getOptions(meta.id)
+}
diff --git a/packages/plugins/robot/src/utils/schema.utils.ts b/packages/plugins/robot/src/utils/schema.utils.ts
new file mode 100644
index 0000000000..72e031b4aa
--- /dev/null
+++ b/packages/plugins/robot/src/utils/schema.utils.ts
@@ -0,0 +1,185 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+import { jsonrepair } from 'jsonrepair'
+import SvgICons from '@opentiny/vue-icon'
+import { serializeError } from './chat.utils'
+
+/**
+ * 修复图标组件,如果图标不存在则使用警告图标
+ */
+export const fixIconComponent = (data: any) => {
+ if (data?.componentName === 'Icon' && data.props?.name && !SvgICons[data.props.name as keyof typeof SvgICons]) {
+ data.props.name = 'IconWarning'
+ }
+}
+
+/**
+ * 检查是否为纯对象
+ */
+const isPlainObject = (value: unknown) =>
+ typeof value === 'object' && value !== null && Object.prototype.toString.call(value) === '[object Object]'
+
+/**
+ * 修复组件名,如果没有组件名则设为div
+ */
+export const fixComponentName = (data: any) => {
+ if (isPlainObject(data) && !data.componentName && !data.op && !data.path) {
+ data.componentName = 'div'
+ }
+}
+
+/**
+ * 修复方法对象,确保方法格式正确
+ */
+export const fixMethods = (methods: Record) => {
+ if (methods && Object.keys(methods).length) {
+ Object.entries(methods).forEach(([methodName, methodValue]: [string, any]) => {
+ if (
+ typeof methodValue?.value !== 'string' ||
+ methodValue?.type !== 'JSFunction' ||
+ !methodValue?.value.startsWith('function')
+ ) {
+ methods[methodName] = {
+ type: 'JSFunction',
+ value: 'function ' + methodName + '() {\n console.log("' + methodName + '");\n}'
+ }
+ }
+ })
+ }
+}
+
+/**
+ * 递归修复Schema中的各种问题
+ */
+export const schemaAutoFix = (data: any) => {
+ if (!data) return
+ if (Array.isArray(data)) {
+ data.forEach((item) => schemaAutoFix(item))
+ return
+ }
+
+ fixIconComponent(data)
+ fixComponentName(data)
+
+ if (data.children && Array.isArray(data.children)) {
+ data.children.forEach((child: any) => schemaAutoFix(child))
+ }
+}
+
+/**
+ * 验证JSON Patch操作是否有效
+ */
+export const isValidOperation = (operation: any): boolean => {
+ const allowedOps = ['add', 'remove', 'replace', 'move', 'copy', 'test', '_get']
+
+ if (typeof operation !== 'object' || operation === null) {
+ return false
+ }
+
+ // 检查操作类型是否有效
+ if (!operation.op || !allowedOps.includes(operation.op)) {
+ return false
+ }
+
+ // 检查path字段是否存在且为字符串
+ if (!operation.path || typeof operation.path !== 'string') {
+ return false
+ }
+
+ // 根据操作类型检查其他必需字段
+ switch (operation.op) {
+ case 'add':
+ case 'replace':
+ case 'test':
+ if (!('value' in operation)) {
+ return false
+ }
+ break
+ case 'move':
+ case 'copy':
+ if (!operation.from || typeof operation.from !== 'string') {
+ return false
+ }
+ break
+ }
+
+ return true
+}
+
+/**
+ * 验证JSON Patch是否有效
+ */
+export const isValidFastJsonPatch = (patch: any): boolean => {
+ if (Array.isArray(patch)) {
+ return patch.every(isValidOperation)
+ } else if (typeof patch === 'object' && patch !== null) {
+ return isValidOperation(patch)
+ }
+ return false
+}
+
+/**
+ * 自动修复JSON Patch数组,过滤无效操作
+ */
+export const jsonPatchAutoFix = (jsonPatches: any[], isFinial: boolean) => {
+ // 流式渲染过程中,画布只渲染完整的字段或流式的children字段,避免不完整的methods/states/css等字段导致解析报错
+ const childrenFilter = (patch: any, index: number, arr: any[]) =>
+ isFinial || index < arr.length - 1 || (index === arr.length - 1 && patch.path?.startsWith('/children'))
+ const validJsonPatches = jsonPatches.filter(childrenFilter).filter(isValidFastJsonPatch)
+
+ return validJsonPatches
+}
+
+/**
+ * 从流式内容中提取JSON对象字符串
+ */
+export const getJsonObjectString = (streamContent: string): string => {
+ const regex = /```(json|schema)?([\s\S]*?)```/
+ const match = streamContent.match(regex)
+ return (match && match[2]) || streamContent
+}
+
+/**
+ * 验证流式内容是否为有效的JSON Patch对象字符串
+ */
+export const isValidJsonPatchObjectString = (streamContent: string) => {
+ const jsonString = getJsonObjectString(streamContent)
+ try {
+ const data = JSON.parse(jsonString)
+ if (!isValidFastJsonPatch(data)) {
+ return {
+ isError: true,
+ error:
+ 'format error: not a valid json patch format(strictly `RFC 6902` compliant JSON Patch array. Format example: `[{ "op": "add", "path": "/children/0", "value": { ... } }, {"op":"add","path":"/methods/handleBtnClick","value": { ... }}, { "op": "replace", "path": "/css", "value": "..." }]`), please check and fix the json patch format.'
+ }
+ }
+ return { isError: false, data }
+ } catch (error) {
+ return { isError: true, error: serializeError(error) }
+ }
+}
+
+/**
+ * 解析和修复JSON字符串
+ */
+export const parseAndRepairJson = (content: string, isFinial: boolean) => {
+ try {
+ let repairedContent = content
+ if (!isFinial) {
+ repairedContent = jsonrepair(content)
+ }
+ return { data: JSON.parse(repairedContent), isError: false }
+ } catch (error) {
+ return { isError: true, error }
+ }
+}
diff --git a/packages/plugins/robot/test/test.ts b/packages/plugins/robot/test/test.ts
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/packages/plugins/robot/vite.config.ts b/packages/plugins/robot/vite.config.ts
index 393e2010cd..99dd40704d 100644
--- a/packages/plugins/robot/vite.config.ts
+++ b/packages/plugins/robot/vite.config.ts
@@ -33,7 +33,7 @@ export default defineConfig({
output: {
banner: 'import "./style.css"'
},
- external: ['vue', /@opentiny\/tiny-engine.*/, /@opentiny\/vue.*/]
+ external: ['vue', /@opentiny\/tiny-engine.*/, '@opentiny/tiny-schema-renderer', /@opentiny\/vue.*/]
}
}
})
diff --git a/packages/plugins/schema/package.json b/packages/plugins/schema/package.json
index eb0d58fc15..6a8129af75 100644
--- a/packages/plugins/schema/package.json
+++ b/packages/plugins/schema/package.json
@@ -1,6 +1,6 @@
{
"name": "@opentiny/tiny-engine-plugin-schema",
- "version": "2.7.0",
+ "version": "2.9.0",
"publishConfig": {
"access": "public"
},
diff --git a/packages/plugins/schema/src/Main.vue b/packages/plugins/schema/src/Main.vue
index da564564b0..74e6c73208 100644
--- a/packages/plugins/schema/src/Main.vue
+++ b/packages/plugins/schema/src/Main.vue
@@ -8,6 +8,10 @@
@close="close"
>
+
+
+ 跟随画布
+
保存
@@ -41,8 +45,9 @@
diff --git a/packages/plugins/state/src/js/constants.ts b/packages/plugins/state/src/js/constants.ts
index 4a54ca647e..3a47ce7c1f 100644
--- a/packages/plugins/state/src/js/constants.ts
+++ b/packages/plugins/state/src/js/constants.ts
@@ -19,4 +19,4 @@ export const OPTION_TYPE = {
ADD: 'add',
UPDATE: 'update',
COPY: 'copy'
-}
+} as const
diff --git a/packages/plugins/state/src/js/globalStateService.ts b/packages/plugins/state/src/js/globalStateService.ts
new file mode 100644
index 0000000000..6c7350f02f
--- /dev/null
+++ b/packages/plugins/state/src/js/globalStateService.ts
@@ -0,0 +1,105 @@
+import { computed } from 'vue'
+import { defineService, getMetaApi, META_SERVICE, useResource } from '@opentiny/tiny-engine-meta-register'
+import { updateGlobalState as updateGlobalStateHttp } from './http'
+
+interface IGlobalState {
+ id: string
+ state: Record
+ getters: Record
+ actions: Record
+}
+
+const globalState = computed(() => useResource().appSchemaState.globalState || [])
+
+const getGlobalState = () => globalState.value
+
+// 删除全局应用状态
+const deleteGlobalState = async (id: string) => {
+ const storeList = useResource().appSchemaState.globalState || []
+ const index = storeList.findIndex((store) => store.id === id)
+
+ if (index === -1) {
+ return
+ }
+
+ const newStoreList = storeList.filter((store) => store.id !== id)
+ const { id: appId } = getMetaApi(META_SERVICE.GlobalService).getBaseInfo()
+ const res = await updateGlobalStateHttp(appId, { global_state: newStoreList })
+
+ let updatedStoreList = newStoreList
+ if (Array.isArray(res.global_state)) {
+ updatedStoreList = res.global_state
+ }
+
+ useResource().appSchemaState.globalState = updatedStoreList
+
+ return res
+}
+
+// 更新全局应用状态
+const updateGlobalState = async (data: IGlobalState) => {
+ const { id } = data
+ const storeList = useResource().appSchemaState.globalState || []
+ const index = storeList.findIndex((store) => store.id === id)
+
+ if (index === -1) {
+ throw new Error(`globalState ${id} not found 全局应用状态 ${id} 不存在`)
+ }
+
+ const newStoreList = storeList.map((store) => (store.id === id ? data : store))
+ const { id: appId } = getMetaApi(META_SERVICE.GlobalService).getBaseInfo()
+ const res = await updateGlobalStateHttp(appId, { global_state: newStoreList })
+ let updatedStoreList = newStoreList
+
+ if (Array.isArray(res.global_state)) {
+ updatedStoreList = res.global_state
+ }
+
+ useResource().appSchemaState.globalState = updatedStoreList
+
+ return res
+}
+
+// 新增全局应用状态
+const addGlobalState = async (data: IGlobalState) => {
+ const storeList = useResource().appSchemaState.globalState || []
+ const id = data.id
+
+ if (storeList.find((store) => store.id === id)) {
+ throw new Error('globalState id conflict 全局应用状态名冲突')
+ }
+
+ const newStoreList = [...storeList, data]
+ const { id: appId } = getMetaApi(META_SERVICE.GlobalService).getBaseInfo()
+ const res = await updateGlobalStateHttp(appId, { global_state: newStoreList })
+
+ let updatedStoreList = newStoreList
+
+ if (Array.isArray(res.global_state)) {
+ updatedStoreList = res.global_state
+ }
+
+ useResource().appSchemaState.globalState = updatedStoreList
+
+ return res
+}
+
+const getGlobalStateById = (id: string) => {
+ const storeList = useResource().appSchemaState.globalState || []
+ return storeList.find((store) => store.id === id)
+}
+
+export default defineService({
+ id: META_SERVICE.GlobalStateService,
+ type: 'MetaService',
+ initialState: {},
+ options: {},
+ init: () => {},
+ apis: () => ({
+ getGlobalState: () => getGlobalState(),
+ deleteGlobalState: (id: string) => deleteGlobalState(id),
+ updateGlobalState: (data: IGlobalState) => updateGlobalState(data),
+ addGlobalState: (data: IGlobalState) => addGlobalState(data),
+ getGlobalStateById: (id: string) => getGlobalStateById(id)
+ })
+})
diff --git a/packages/plugins/state/src/mcp/index.ts b/packages/plugins/state/src/mcp/index.ts
new file mode 100644
index 0000000000..21a6c5e43c
--- /dev/null
+++ b/packages/plugins/state/src/mcp/index.ts
@@ -0,0 +1,7 @@
+import { getGlobalState } from './tools/getGlobalState'
+import { addOrModifyGlobalState } from './tools/addOrModifyGlobalState'
+import { deleteGlobalState } from './tools/deleteGlobalState'
+
+export default {
+ tools: [getGlobalState, addOrModifyGlobalState, deleteGlobalState]
+}
diff --git a/packages/plugins/state/src/mcp/tools/addOrModifyGlobalState.ts b/packages/plugins/state/src/mcp/tools/addOrModifyGlobalState.ts
new file mode 100644
index 0000000000..5bd824961f
--- /dev/null
+++ b/packages/plugins/state/src/mcp/tools/addOrModifyGlobalState.ts
@@ -0,0 +1,151 @@
+import { z } from 'zod'
+import { getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register'
+
+const inputSchema = z.object({
+ id: z
+ .string()
+ .describe(['全局变量唯一标识(store 名称)。若同名已存在则执行更新,否则新增。', '示例:"testState"'].join('\n')),
+ state: z
+ .record(z.string(), z.unknown())
+ .describe(
+ [
+ '初始化状态内容(对象)。会被原样存储并用于运行期作为响应式状态。',
+ '示例:',
+ '{',
+ ' "name": "testName",',
+ ' "license": "",',
+ ' "age": 18,',
+ ' "food": ["apple", "orange", "banana", 19],',
+ ' "desc": {',
+ ' "description": "hello world",',
+ ' "money": 100,',
+ ' "other": "",',
+ ' "rest": ["a", "b", "c", 20]',
+ ' }',
+ '}'
+ ].join('\n')
+ ),
+ getters: z
+ .record(
+ z.string(),
+ z.object({
+ type: z.literal('JSFunction').describe('固定为 JSFunction'),
+ value: z.string().describe('函数代码,this 指向 state。例如:"function getAge(){ return this.age }"')
+ })
+ )
+ .optional()
+ .describe(
+ [
+ '可选。Getter 函数集合,对象键为方法名,值为 { type:"JSFunction", value:"代码" }。',
+ '示例:',
+ '{',
+ ' "getAge": { "type": "JSFunction", "value": "function getAge(){\n return this.age \n}" },',
+ ' "getName": { "type": "JSFunction", "value": "function getName(){\n return this.name \n}" }',
+ '}'
+ ].join('\n')
+ ),
+ actions: z
+ .record(
+ z.string(),
+ z.object({
+ type: z.literal('JSFunction').describe('固定为 JSFunction'),
+ value: z.string().describe('函数代码,可修改 state。例如:"function setAge(age){ this.age = age }"')
+ })
+ )
+ .optional()
+ .describe(
+ [
+ '可选。Action 函数集合,对象键为方法名,值为 { type:"JSFunction", value:"代码" }。',
+ '示例:',
+ '{',
+ ' "setAge": { "type": "JSFunction", "value": "function setAge(age){\n this.age = age; \n}" },',
+ ' "setName": { "type": "JSFunction", "value": "function setName(name){\n this.name = name; \n}" }',
+ '}'
+ ].join('\n')
+ )
+})
+
+export const addOrModifyGlobalState = {
+ name: 'add_or_modify_global_state',
+ title: '新增或修改全局变量',
+ description: 'Add or modify a global state. If the id exists, update it; otherwise, add a new one.',
+ inputSchema: inputSchema.shape,
+ callback: async (args: z.infer) => {
+ const { id, state, getters, actions } = args
+ const apis = getMetaApi(META_SERVICE.GlobalStateService)
+
+ if (!apis) {
+ return {
+ content: [
+ {
+ isError: true,
+ type: 'text',
+ text: JSON.stringify({
+ status: 'error',
+ error: 'SERVICE_UNAVAILABLE',
+ message: 'GlobalStateService not registered'
+ })
+ }
+ ]
+ }
+ }
+
+ const { getGlobalStateById, addGlobalState, updateGlobalState } = apis
+
+ try {
+ const exists = Boolean(getGlobalStateById(id))
+ const payload = {
+ id,
+ state,
+ getters: getters ?? {},
+ actions: actions ?? {}
+ }
+
+ if (exists) {
+ await updateGlobalState(payload as any)
+ const updated = getGlobalStateById(id)
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify({
+ status: 'success',
+ message: 'Global state updated successfully',
+ data: updated
+ })
+ }
+ ]
+ }
+ }
+
+ await addGlobalState(payload as any)
+ const added = getGlobalStateById(id)
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify({
+ status: 'success',
+ message: 'Global state added successfully',
+ data: added
+ })
+ }
+ ]
+ }
+ } catch (error) {
+ return {
+ content: [
+ {
+ isError: true,
+ type: 'text',
+ text: JSON.stringify({
+ status: 'error',
+ message: 'Failed to add or modify global state',
+ error: error instanceof Error ? error.message : 'Unknown error occurred'
+ })
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/packages/plugins/state/src/mcp/tools/deleteGlobalState.ts b/packages/plugins/state/src/mcp/tools/deleteGlobalState.ts
new file mode 100644
index 0000000000..46d58e1a4c
--- /dev/null
+++ b/packages/plugins/state/src/mcp/tools/deleteGlobalState.ts
@@ -0,0 +1,89 @@
+import { z } from 'zod'
+import { getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register'
+
+const inputSchema = z.object({
+ id: z.string().describe('要删除的全局变量 id')
+})
+
+export const deleteGlobalState = {
+ name: 'delete_global_state',
+ title: '删除全局变量',
+ description: 'Delete a global state item by id.',
+ inputSchema: inputSchema.shape,
+ callback: async (args: z.infer) => {
+ const { id } = args
+ const apis = getMetaApi(META_SERVICE.GlobalStateService)
+
+ if (!apis) {
+ return {
+ content: [
+ {
+ isError: true,
+ type: 'text',
+ text: JSON.stringify({
+ status: 'error',
+ error: 'SERVICE_UNAVAILABLE',
+ message: 'GlobalStateService not registered'
+ })
+ }
+ ]
+ }
+ }
+
+ const { getGlobalStateById, deleteGlobalState: removeGlobalState } = apis
+
+ try {
+ const item = getGlobalStateById(id)
+ if (!item) {
+ return {
+ content: [
+ {
+ isError: true,
+ type: 'text',
+ text: JSON.stringify({
+ status: 'error',
+ message: `Unknown id: ${id}`,
+ error: 'GLOBAL_STATE_NOT_FOUND',
+ next_action: [
+ {
+ type: 'tool_call',
+ name: 'get_global_state',
+ args: {}
+ }
+ ]
+ })
+ }
+ ]
+ }
+ }
+
+ await removeGlobalState(id)
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify({
+ status: 'success',
+ message: 'Global state deleted successfully',
+ data: item
+ })
+ }
+ ]
+ }
+ } catch (error) {
+ return {
+ content: [
+ {
+ isError: true,
+ type: 'text',
+ text: JSON.stringify({
+ status: 'error',
+ message: 'Failed to delete global state',
+ error: error instanceof Error ? error.message : 'Unknown error occurred'
+ })
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/packages/plugins/state/src/mcp/tools/getGlobalState.ts b/packages/plugins/state/src/mcp/tools/getGlobalState.ts
new file mode 100644
index 0000000000..13540b845e
--- /dev/null
+++ b/packages/plugins/state/src/mcp/tools/getGlobalState.ts
@@ -0,0 +1,104 @@
+import { z } from 'zod'
+import { getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register'
+
+const inputSchema = z.object({
+ id: z.string().optional().describe('可选。若提供则返回指定 id 的全局状态;不提供则返回全量')
+})
+
+export const getGlobalState = {
+ name: 'get_global_state',
+ title: '查询全局变量',
+ description: 'Query global states. When id is provided, return the specific item; otherwise return the full list.',
+ inputSchema: inputSchema.shape,
+ callback: async (args: z.infer) => {
+ const { id } = args || {}
+ const apis = getMetaApi(META_SERVICE.GlobalStateService)
+
+ if (!apis) {
+ return {
+ content: [
+ {
+ isError: true,
+ type: 'text',
+ text: JSON.stringify({
+ status: 'error',
+ error: 'SERVICE_UNAVAILABLE',
+ message: 'GlobalStateService not registered'
+ })
+ }
+ ]
+ }
+ }
+
+ const { getGlobalState: listGlobalState, getGlobalStateById } = apis
+
+ try {
+ if (!id) {
+ const list = listGlobalState()
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify({
+ status: 'success',
+ message: 'Global state list fetched successfully',
+ data: list
+ })
+ }
+ ]
+ }
+ }
+
+ const item = getGlobalStateById(id)
+ if (!item) {
+ return {
+ content: [
+ {
+ isError: true,
+ type: 'text',
+ text: JSON.stringify({
+ status: 'error',
+ message: `Unknown id: ${id}`,
+ error: 'GLOBAL_STATE_NOT_FOUND',
+ next_action: [
+ {
+ type: 'tool_call',
+ name: 'get_global_state',
+ args: {}
+ }
+ ]
+ })
+ }
+ ]
+ }
+ }
+
+ return {
+ content: [
+ {
+ type: 'text',
+ text: JSON.stringify({
+ status: 'success',
+ message: 'Global state fetched successfully',
+ data: item
+ })
+ }
+ ]
+ }
+ } catch (error) {
+ return {
+ content: [
+ {
+ isError: true,
+ type: 'text',
+ text: JSON.stringify({
+ status: 'error',
+ message: 'Failed to get global state',
+ error: error instanceof Error ? error.message : 'Unknown error occurred'
+ })
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/packages/plugins/state/src/styles/vars.less b/packages/plugins/state/src/styles/vars.less
index 406a1cdd8f..2b9e44f1ac 100644
--- a/packages/plugins/state/src/styles/vars.less
+++ b/packages/plugins/state/src/styles/vars.less
@@ -29,4 +29,5 @@
--te-state-right-panel-icon-color: var(--te-common-icon-hover);
--te-state-right-panel-bg-color: var(--te-common-bg-container);
+ --te-state-tip-highlight-color: var(--te-common-text-emphasize);
}
diff --git a/packages/plugins/tree/package.json b/packages/plugins/tree/package.json
index 6d7b2d9364..b5c74f20da 100644
--- a/packages/plugins/tree/package.json
+++ b/packages/plugins/tree/package.json
@@ -1,6 +1,6 @@
{
"name": "@opentiny/tiny-engine-plugin-tree",
- "version": "2.7.0",
+ "version": "2.9.0",
"publishConfig": {
"access": "public"
},
diff --git a/packages/plugins/tree/src/Main.vue b/packages/plugins/tree/src/Main.vue
index 2ade5736a7..4397f406c9 100644
--- a/packages/plugins/tree/src/Main.vue
+++ b/packages/plugins/tree/src/Main.vue
@@ -27,7 +27,10 @@
row.label
}}
-
+
@@ -96,7 +99,6 @@ export default {
const translateChild = (data) => {
data.forEach((item) => {
item.show = pageState.nodesStatus[item.id] !== false
- item.showEye = !item.show
const child = item.children
if (Array.isArray(child)) {
translateChild(item.children)
@@ -150,14 +152,17 @@ export default {
return pageState.nodesStatus[id] !== false
}
- const showNode = (data) => {
- data.show = !data.show
- pageState.nodesStatus[data.id] = data.show
-
+ const showNode = (event, data) => {
+ pageState.nodesStatus[data.id] = !(pageState.nodesStatus[data.id] !== false)
+ data.show = pageState.nodesStatus[data.id]
const { getRenderer, clearSelect } = useCanvas().canvasApi.value
getRenderer().setCondition(data.id, data.show)
- clearSelect()
+
+ if (!data.show) {
+ event?.stopPropagation()
+ clearSelect()
+ }
}
const delNode = (data) => {
diff --git a/packages/plugins/tutorial/package.json b/packages/plugins/tutorial/package.json
index e02258fa13..3ca7a0131e 100644
--- a/packages/plugins/tutorial/package.json
+++ b/packages/plugins/tutorial/package.json
@@ -1,6 +1,6 @@
{
"name": "@opentiny/tiny-engine-plugin-tutorial",
- "version": "2.7.0",
+ "version": "2.9.0",
"publishConfig": {
"access": "public"
},
diff --git a/packages/register/package.json b/packages/register/package.json
index 9971bbf2d0..85c338e30e 100644
--- a/packages/register/package.json
+++ b/packages/register/package.json
@@ -1,10 +1,11 @@
{
"name": "@opentiny/tiny-engine-meta-register",
- "version": "2.7.0",
+ "version": "2.9.0",
"description": "",
"type": "module",
"main": "dist/index.js",
"module": "dist/index.js",
+ "types": "dist/index.d.ts",
"author": "OpenTiny Team",
"license": "MIT",
"bugs": {
@@ -32,6 +33,7 @@
},
"devDependencies": {
"vite": "^5.4.2",
+ "vite-plugin-dts": "^4.5.4",
"vitest": "^1.4.0"
},
"keywords": []
diff --git a/packages/register/src/common.ts b/packages/register/src/common.ts
index 655f8231ff..64b135fd4d 100644
--- a/packages/register/src/common.ts
+++ b/packages/register/src/common.ts
@@ -85,12 +85,12 @@ const registryApiAndOptionsMap = (id: string, value: any) => {
}
}
-const genDefaultHashMap = (registry: any) => {
+const genDefaultHashMap = (registry: Record) => {
Object.entries(registry).forEach(([key, value]) => {
if (typeof value === 'object' && value && !isRef(value)) {
const { id } = value
// 如果匹配到了id,说明是元服务配置,对元服务配置做读取和写入
- if (id && key !== 'metaData') {
+ if (typeof id === 'string' && id && key !== 'metaData') {
registryApiAndOptionsMap(id, value)
metaHashMap.set(id, value)
}
diff --git a/packages/register/src/constants.ts b/packages/register/src/constants.ts
index 9886c1098d..35b630a668 100644
--- a/packages/register/src/constants.ts
+++ b/packages/register/src/constants.ts
@@ -18,7 +18,11 @@ export const META_SERVICE = {
Property: 'engine.service.property',
Properties: 'engine.service.properties',
ThemeSwitch: 'engine.service.themeSwitch',
- Style: 'engine.service.style'
+ Style: 'engine.service.style',
+ McpService: 'engine.service.mcpService',
+ UseUtils: 'engine.service.useUtils',
+ Robot: 'engine.service.robot',
+ GlobalStateService: 'engine.service.globalStateService'
}
export const META_APP = {
@@ -32,6 +36,7 @@ export const META_APP = {
Media: 'engine.toolbars.media',
Collaboration: 'engine.toolbars.collaboration',
Clean: 'engine.toolbars.clean',
+ Robot: 'engine.toolbars.robot',
ThemeSwitch: 'engine.toolbars.themeSwitch',
Refresh: 'engine.toolbars.refresh',
Save: 'engine.toolbars.save',
@@ -64,10 +69,12 @@ export const META_APP = {
State: 'engine.plugins.state',
// 页面 schema 插件
Schema: 'engine.plugins.schema',
+ // 资源管理 插件
+ Resource: 'engine.plugins.resource',
// 新手帮助/帮助文档
Help: 'engine.plugins.editorhelp',
- // AI 插件
- Robot: 'engine.plugins.robot',
+ // 模型管理插件
+ ModelManager: 'engine.plugins.modelmanager',
// 属性设置面板
Props: 'engine.setting.props',
// 样式设置面板
@@ -77,5 +84,8 @@ export const META_APP = {
Container: 'engine.canvas.container',
// 画布
Canvas: 'engine.canvas',
- Tutorial: 'engine.plugins.tutorial'
+ Tutorial: 'engine.plugins.tutorial',
+ // 首页菜单
+ AppCenter: 'engine.workspace.application-center',
+ TemplateCenter: 'engine.workspace.template-center'
}
diff --git a/packages/register/src/external-types.d.ts b/packages/register/src/external-types.d.ts
new file mode 100644
index 0000000000..44431d5ecd
--- /dev/null
+++ b/packages/register/src/external-types.d.ts
@@ -0,0 +1,116 @@
+/**
+ * 临时类型声明文件
+ *
+ * 此文件为暂未导出类型声明的内部包提供临时类型定义
+ * TODO: 当这些包完成类型导出后,应当删除此文件
+ *
+ * 相关包列表:
+ * - @opentiny/tiny-engine-canvas
+ * - @opentiny/tiny-engine-layout
+ * - @opentiny/tiny-engine-plugin-* (block, datasource, help, i18n, materials, page, robot)
+ * - @opentiny/tiny-engine-setting-props
+ * - @opentiny/tiny-engine-toolbar-* (breadcrumb, generate-code, redoundo)
+ * - @opentiny/tiny-engine-common
+ */
+
+// Canvas API - 导出一个返回 API 对象的函数
+declare module '@opentiny/tiny-engine-canvas/DesignCanvas/src/api' {
+ const useCanvasApi: () => Record
+ export default useCanvasApi
+}
+
+// Layout Service - 导出包含 apis 属性的服务对象
+declare module '@opentiny/tiny-engine-layout' {
+ export const LayoutService: {
+ apis: Record
+ }
+}
+
+// Plugin: Block - 区块管理服务
+declare module '@opentiny/tiny-engine-plugin-block' {
+ export const BlockService: {
+ apis: Record
+ }
+}
+
+// Plugin: DataSource - 数据源管理服务
+declare module '@opentiny/tiny-engine-plugin-datasource' {
+ export const DataSourceService: {
+ apis: Record
+ }
+}
+
+// Plugin: Help - 帮助服务
+declare module '@opentiny/tiny-engine-plugin-help' {
+ export const HelpService: {
+ apis: Record
+ }
+}
+
+// Plugin: I18n - 国际化翻译服务
+declare module '@opentiny/tiny-engine-plugin-i18n' {
+ export const TranslateService: {
+ apis: Record
+ }
+}
+
+// Plugin: Materials - 物料管理服务(包含两个服务)
+declare module '@opentiny/tiny-engine-plugin-materials' {
+ export const MaterialService: {
+ apis: Record
+ }
+ export const ResourceService: {
+ apis: Record
+ }
+}
+
+// Plugin: Page - 页面管理服务
+declare module '@opentiny/tiny-engine-plugin-page' {
+ export const PageService: {
+ apis: Record
+ }
+}
+
+// Plugin: Robot - AI 机器人服务
+declare module '@opentiny/tiny-engine-plugin-robot' {
+ export const RobotService: {
+ apis: Record
+ }
+}
+
+// Setting: Props - 属性配置服务(包含两个服务)
+declare module '@opentiny/tiny-engine-setting-props' {
+ export const PropertiesService: {
+ apis: Record
+ }
+ export const PropertyService: {
+ apis: Record
+ }
+}
+
+// Toolbar: Breadcrumb - 面包屑导航服务
+declare module '@opentiny/tiny-engine-toolbar-breadcrumb' {
+ export const BreadcrumbService: {
+ apis: Record
+ }
+}
+
+// Toolbar: Generate Code - 代码生成和本地保存服务
+declare module '@opentiny/tiny-engine-toolbar-generate-code' {
+ export const SaveLocalService: {
+ apis: Record
+ }
+}
+
+// Toolbar: Redo/Undo - 历史记录服务
+declare module '@opentiny/tiny-engine-toolbar-redoundo' {
+ export const HistoryService: {
+ apis: Record
+ }
+}
+
+// Common - 通用工具(Modal 和 Notify)
+declare module '@opentiny/tiny-engine-common' {
+ export const Modal: Record
+ export const Notify: (...args: any[]) => any
+}
diff --git a/packages/register/src/hooks.ts b/packages/register/src/hooks.ts
index 837c9ce00b..cb1ca1d709 100644
--- a/packages/register/src/hooks.ts
+++ b/packages/register/src/hooks.ts
@@ -15,7 +15,8 @@ import type {
UsePropertyApi,
UseResourceApi,
UseSaveLocalApi,
- UseTranslateApi
+ UseTranslateApi,
+ UseRobotApi
} from './types'
export const HOOK_NAME = {
@@ -38,7 +39,8 @@ export const HOOK_NAME = {
useNotify: 'notify',
useCustom: 'custom',
useMaterial: 'material',
- useStyle: 'style'
+ useStyle: 'style',
+ useRobot: 'robot'
} as const
type HookName = typeof HOOK_NAME[keyof typeof HOOK_NAME]
@@ -63,7 +65,8 @@ const hooksState = {
[HOOK_NAME.useModal]: {},
[HOOK_NAME.useMaterial]: {},
[HOOK_NAME.useStyle]: {},
- [HOOK_NAME.useCustom]: {} // 自定义
+ [HOOK_NAME.useCustom]: {},
+ [HOOK_NAME.useRobot]: {} // 自定义
}
const getHook = (hookName: HookName, args: any[]) => {
@@ -91,6 +94,7 @@ export const useEnv = (...args: any[]): ImportMetaEnv => getHook(HOOK_NAME.useEn
export const useModal = (...args: any[]): UseModalApi => getHook(HOOK_NAME.useModal, args)
export const useNotify = (...args: NotifyParams): NotifyResult => getHook(HOOK_NAME.useNotify, args)
export const useMaterial = (...args: any[]): UseMaterialApi => getHook(HOOK_NAME.useMaterial, args)
+export const useRobot = (...args: any[]): UseRobotApi => getHook(HOOK_NAME.useRobot, args)
export const useStyle = (...args: any[]) => getHook(HOOK_NAME.useStyle, args)
export const useCustom = (...args: any[]) => getHook(HOOK_NAME.useCustom, args)
diff --git a/packages/register/src/index.ts b/packages/register/src/index.ts
index 559e44ce64..65ac22d29b 100644
--- a/packages/register/src/index.ts
+++ b/packages/register/src/index.ts
@@ -18,3 +18,5 @@ export { getConfigurator, addConfigurator } from './configurators'
export * from './hooks'
export { META_APP, META_SERVICE } from './constants'
export { defineService, initServices } from './service'
+
+export type { ServiceOptions } from './service'
diff --git a/packages/register/src/service.ts b/packages/register/src/service.ts
index 0161c56652..9036f4d4fd 100644
--- a/packages/register/src/service.ts
+++ b/packages/register/src/service.ts
@@ -8,7 +8,7 @@ interface Context {
options: K
}
-interface ServiceOptions {
+export interface ServiceOptions {
id: string
type: 'MetaService'
initialState: T
@@ -48,15 +48,18 @@ export const defineService = (serviceOptions: ServiceOptions): Servi
id,
type,
options,
- apis: {}
+ // 使用类型断言,因为 getState 和 setState 会在后面添加
+ apis: {} as any
}
const state = reactive(initialState || {})
+ // 使用对象展开运算符合并 apis,避免直接赋值导致类型错误
if (typeof apis === 'object' && apis) {
- resultService.apis = apis
+ resultService.apis = apis as any
} else if (typeof apis === 'function') {
- resultService.apis = apis({ state })
+ // 传递完整的 context 对象,包含 state 和 options
+ resultService.apis = apis({ state, options }) as any
}
resultService.apis.setOptions = (kv) => {
diff --git a/packages/register/src/types.ts b/packages/register/src/types.ts
index e47b3dc657..dd4d376349 100644
--- a/packages/register/src/types.ts
+++ b/packages/register/src/types.ts
@@ -11,6 +11,7 @@ import type { BreadcrumbService } from '@opentiny/tiny-engine-toolbar-breadcrumb
import type { SaveLocalService } from '@opentiny/tiny-engine-toolbar-generate-code'
import type { HistoryService } from '@opentiny/tiny-engine-toolbar-redoundo'
import type { Modal, Notify } from '@opentiny/tiny-engine-common'
+import type { RobotService } from '@opentiny/tiny-engine-plugin-robot'
export type UseCanvasApi = ReturnType
export type UseLayoutApi = typeof LayoutService['apis']
@@ -23,6 +24,7 @@ export type UseTranslateApi = typeof TranslateService['apis']
export type UseMaterialApi = typeof MaterialService['apis']
export type UseResourceApi = typeof ResourceService['apis']
export type UsePageApi = typeof PageService['apis']
+export type UseRobotApi = typeof RobotService['apis']
// setting
export type UsePropertiesApi = typeof PropertiesService['apis']
diff --git a/packages/register/src/useMessage.ts b/packages/register/src/useMessage.ts
index 17da43f9cf..3bf206e409 100644
--- a/packages/register/src/useMessage.ts
+++ b/packages/register/src/useMessage.ts
@@ -10,8 +10,66 @@
*
*/
-let lastMessage: any = null
-const subscribers: Record = { '': {} }
+// 消息事件类型,用于存储消息数据
+interface MessageEvent {
+ data: T
+}
+
+// 消息回调函数类型
+type MessageCallback = (data: T) => void
+
+// 带有 lastEvent 属性的回调数组类型
+interface CallbacksWithLastEvent extends Array> {
+ lastEvent?: MessageEvent
+}
+
+// 监听器映射类型:topic -> callbacks
+type ListenersMap = Record
+
+// 订阅者映射类型:subscriber -> listeners
+type SubscribersMap = Record
+
+// subscribe 函数参数接口
+interface SubscribeOptions {
+ topic?: string
+ subscriber?: string
+ callback?: MessageCallback
+}
+
+// unsubscribe 函数参数接口
+interface UnsubscribeOptions {
+ topic?: string
+ subscriber?: string
+}
+
+// publish 函数参数接口
+interface PublishOptions {
+ topic?: string
+ data?: T
+}
+
+// broadcast 函数参数接口(topic 和 data 为必需参数)
+interface BroadcastOptions {
+ topic: string
+ data: T
+}
+
+// 订阅消息返回的描述符
+interface MessageDescriptor {
+ topic: string | undefined
+ subscriber: string | undefined
+}
+
+// useMessage 钩子的返回值类型
+interface UseMessageReturn {
+ subscribe: (options?: SubscribeOptions) => MessageDescriptor
+ unsubscribe: (options?: UnsubscribeOptions) => void
+ publish: (options?: PublishOptions) => void
+ broadcast: (options: BroadcastOptions) => void
+}
+
+let lastMessage: PublishOptions | null = null
+const subscribers: SubscribersMap = { '': {} }
/**
* 订阅消息。
@@ -23,9 +81,9 @@ const subscribers: Record = { '': {} }
* @param {Object} object { topic: 消息名称, subscriber(可选): 消息集合, callback: 接收到消息之后的回调用函数 }
* @return {Object} { topic: 消息名称, subscriber: 消息集合 }
*/
-const subscribe = ({ topic, subscriber, callback } = {}) => {
- const root = subscribers['']
- let listeners = root
+const subscribe = ({ topic, subscriber, callback }: SubscribeOptions = {}): MessageDescriptor => {
+ const root: ListenersMap = subscribers['']
+ let listeners: ListenersMap = root
if (topic && typeof topic === 'string' && typeof callback === 'function') {
if (subscriber && typeof subscriber === 'string') {
@@ -33,13 +91,13 @@ const subscribe = ({ topic, subscriber, callback } = {}) => {
subscribers[subscriber] = listeners
}
- const callbacks = listeners[topic] || []
+ const callbacks: CallbacksWithLastEvent = (listeners[topic] as CallbacksWithLastEvent) || []
listeners[topic] = callbacks
callbacks.push(callback)
const lastEvent = callbacks.lastEvent || root[topic]?.lastEvent
if (lastEvent) {
- callback(lastEvent.data)
+ callback(lastEvent.data as T)
}
}
@@ -61,9 +119,9 @@ const subscribe = ({ topic, subscriber, callback } = {}) => {
* @member TinyEditor.message
* @param {Object} object { topic: 消息名称, subscriber(可选): 消息集合 }
*/
-const unsubscribe = ({ topic, subscriber } = {}) => {
+const unsubscribe = ({ topic, subscriber }: UnsubscribeOptions = {}): void => {
if (topic && typeof topic === 'string') {
- const removeListener = (subscriber) => {
+ const removeListener = (subscriber: string): void => {
const listeners = subscribers[subscriber]
if (listeners) {
delete listeners[topic]
@@ -94,23 +152,23 @@ const unsubscribe = ({ topic, subscriber } = {}) => {
* @member TinyEditor.message
* @param {Object} object { topic: 消息名称, data(string | object): 消息内容 }
*/
-const publish = ({ topic, data } = {}) => {
+const publish = ({ topic, data }: PublishOptions = {}): void => {
if (!topic || typeof topic !== 'string') {
return
}
for (const value of Object.values(subscribers)) {
- const callbacks = value[topic] || []
+ const callbacks: CallbacksWithLastEvent = (value[topic] as CallbacksWithLastEvent) || []
if (callbacks.length) {
for (const cb of callbacks) {
- cb(data)
+ cb(data as T)
}
} else {
value[topic] = callbacks
}
- callbacks.lastEvent = { data }
+ callbacks.lastEvent = { data: data as T }
}
}
@@ -123,7 +181,7 @@ const publish = ({ topic, data } = {}) => {
* @member TinyEditor.message
* @param {Object} object { topic: 消息名称, data(string | object): 消息内容 }
*/
-const broadcast = ({ topic, data }) => {
+const broadcast = ({ topic, data }: BroadcastOptions): void => {
if (topic && typeof topic === 'string') {
lastMessage = { topic, data }
@@ -131,7 +189,7 @@ const broadcast = ({ topic, data }) => {
}
}
-export default () => {
+export default (): UseMessageReturn => {
// 新use的message自动广播上次的异步消息
if (lastMessage) {
publish(lastMessage)
diff --git a/packages/register/src/vite-env.d.ts b/packages/register/src/vite-env.d.ts
new file mode 100644
index 0000000000..11f02fe2a0
--- /dev/null
+++ b/packages/register/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/packages/register/tsconfig.json b/packages/register/tsconfig.json
new file mode 100644
index 0000000000..e8bffe0839
--- /dev/null
+++ b/packages/register/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "include": ["./src/**/*.ts", "./src/**/*.tsx", "./src/**/*.vue"]
+}
diff --git a/packages/register/vite.config.ts b/packages/register/vite.config.ts
index 2a701889e4..e2f2b10f10 100644
--- a/packages/register/vite.config.ts
+++ b/packages/register/vite.config.ts
@@ -12,10 +12,15 @@
import { defineConfig } from 'vite'
import path from 'path'
-
+import dts from 'vite-plugin-dts'
// https://vitejs.dev/config/
export default defineConfig({
- plugins: [],
+ plugins: [
+ dts({
+ tsconfigPath: path.resolve(__dirname, './tsconfig.json'),
+ rollupTypes: true
+ })
+ ],
publicDir: false,
resolve: {},
build: {
diff --git a/packages/runtime-renderer/config.ts b/packages/runtime-renderer/config.ts
new file mode 100644
index 0000000000..f3f9fdecc0
--- /dev/null
+++ b/packages/runtime-renderer/config.ts
@@ -0,0 +1,15 @@
+export function useEnv(): Record {
+ const env = import.meta.env
+ return { ...env }
+}
+
+export const defaultConfig = {
+ material: ['/mock/bundle.json'],
+ importMap: {
+ imports: {}
+ },
+ // 是否开启 TailWindCSS 特性
+ enableTailwindCSS: true
+}
+
+export default defaultConfig
diff --git a/packages/runtime-renderer/index.ts b/packages/runtime-renderer/index.ts
index 6c15fdb03b..ab11da2797 100644
--- a/packages/runtime-renderer/index.ts
+++ b/packages/runtime-renderer/index.ts
@@ -11,45 +11,29 @@
*/
import { createApp } from 'vue'
+import defaultConfig from './config'
+import { createAppRouter, createAppStores } from './src/renderer/app-function'
import { useAppSchema } from './src/composables/useAppSchema'
-import { createAppRouter } from './src/router'
-import { createPinia } from 'pinia'
-import { createStores, generateStoresConfig } from './src/stores'
+import i18n from '@opentiny/tiny-engine-common/js/i18n'
import App from './src/App.vue'
-import i18n from '@opentiny/tiny-engine-i18n-host'
// 初始化运行时渲染器
-export const initRuntimeRenderer = async () => {
+export const initRuntimeRenderer = async (config: any) => {
+ Object.assign(defaultConfig, config || {})
const searchParams = new URLSearchParams(location.search)
const appId = searchParams.get('id')
-
if (!appId) {
throw new Error('Missing required "id" query parameter')
}
-
- const { fetchAppSchema, fetchBlocks } = useAppSchema()
- await fetchAppSchema(appId)
- await fetchBlocks()
- const router = await createAppRouter()
-
- const pinia = createPinia()
- const storesConfig = generateStoresConfig()
- const stores = createStores(storesConfig, pinia)
-
+ const { initAppData } = useAppSchema()
+ await initAppData(appId)
+ const router = createAppRouter()
+ const pinia = createAppStores()
const app = createApp(App)
- app.provide('stores', stores)
-
+ app.use(pinia).use(i18n).use(router).mount('#app')
// 全局错误处理(防止 scheduler 被打断)
- app.config.errorHandler = (err, instance, info) => {
+ app.config.errorHandler = (err, _instance, info) => {
// eslint-disable-next-line no-console
- console.error('[GlobalErrorHandler]', err, info)
- if ((err as any)?.stack) {
- // eslint-disable-next-line no-console
- console.error('[GlobalErrorHandler stack]', (err as any).stack)
- }
+ console.error(err, _instance, info)
}
-
- app.use(pinia).use(router).use(i18n).mount('#app')
-
- return app
}
diff --git a/packages/runtime-renderer/package.json b/packages/runtime-renderer/package.json
index 422a7d1da1..62fc693827 100644
--- a/packages/runtime-renderer/package.json
+++ b/packages/runtime-renderer/package.json
@@ -15,15 +15,14 @@
},
"dependencies": {
"@opentiny/tiny-engine-builtin-component": "workspace:*",
- "@opentiny/tiny-engine-i18n-host": "workspace:*",
- "@vue/babel-plugin-jsx": "^1.2.5",
- "@babel/core": "^7.18.13",
- "@vue/shared": "^3.3.4",
+ "@opentiny/tiny-engine-block-compiler": "workspace:*",
+ "@opentiny/tiny-engine-dsl-vue": "workspace:*",
+ "@opentiny/tiny-engine-common": "workspace:*",
+ "@opentiny/tiny-engine-utils": "workspace:*",
"axios": "^1.10.0",
- "axios-mock-adapter": "^1.19.0",
"pinia": "^2.1.0",
- "vue-router": "^4.2.0",
"postcss": "^8.4.31",
+ "axios-mock-adapter": "^1.19.0",
"postcss-selector-parser": "^7.0.0"
},
"devDependencies": {
@@ -32,11 +31,15 @@
"vite": "^5.4.2"
},
"peerDependencies": {
- "@opentiny/vue": "^3.20.0",
- "@opentiny/vue-icon": "^3.20.0",
+ "@babel/core": "^7.26.0",
+ "@opentiny/vue": "~3.20.0",
+ "@opentiny/vue-icon": "~3.20.0",
"@opentiny/vue-locale": "~3.20.0",
"@opentiny/vue-theme": "~3.20.0",
+ "@vue/babel-plugin-jsx": "^1.2.5",
+ "@vue/shared": "^3.3.4",
"vue": "^3.4.15",
- "vue-i18n": "^9.9.0"
+ "vue-i18n": "^9.9.0",
+ "vue-router": "^4.2.0"
}
}
diff --git a/packages/runtime-renderer/readme.md b/packages/runtime-renderer/readme.md
new file mode 100644
index 0000000000..8874ed6060
--- /dev/null
+++ b/packages/runtime-renderer/readme.md
@@ -0,0 +1,46 @@
+# 运行时渲染器-在线应用预览
+
+## 功能目录结构
+
+packages/runtime-renderer
+├── config.ts 配置相关
+├── index.ts 运行时渲染器入口文件
+├── package.json 依赖记录
+├── src/ 源代码目录
+│ ├── App.vue APP.vue入口
+│ ├── components/ 通用组件
+│ ├── composables/ 应用数据记录相关
+│ ├── renderer/
+│ │ ├── app-function/ 应用通用函数
+│ │ ├── builtin/ 染器内部组件(待迁移至builtinComponent包)
+│ │ ├── context/ 页面运行时上下文
+│ │ ├── data-function/ 数据转换通用函数
+│ │ ├── material-function/ 物料通用函数
+│ │ ├── page-function/ 页面通用函数
+│ │ ├── RenderMain.ts 渲染器入口
+│ │ └── render.ts 渲染器组件
+│ └── types/ TS类型定义
+├── types.d.ts TS类型扩展
+└── vite.config.ts 编译配置
+
+## 渲染器架构图
+
+
+
+## 启动开发
+
+```bash
+pnpm i
+
+pnpm dev
+```
+
+## 生产打包
+
+```bash
+pnpm i
+
+pnpm build:plugin
+
+pnpm build:prod
+```
diff --git a/packages/runtime-renderer/src/App.vue b/packages/runtime-renderer/src/App.vue
index ee8caf2c46..98240aef81 100644
--- a/packages/runtime-renderer/src/App.vue
+++ b/packages/runtime-renderer/src/App.vue
@@ -1,3 +1,3 @@
-
+
diff --git a/packages/runtime-renderer/src/app-function/dataSource.ts b/packages/runtime-renderer/src/app-function/dataSource.ts
deleted file mode 100644
index 2de82554b4..0000000000
--- a/packages/runtime-renderer/src/app-function/dataSource.ts
+++ /dev/null
@@ -1,136 +0,0 @@
-import useHttp from './http'
-import { parseJSFunction } from '../utils/data-utils'
-// 将原本的配置格式标准化以方便复用出码逻辑
-const normalizeItem = (item: any) => {
- return {
- id: item.id,
- name: item.name,
- columns: item.data.columns,
- data: item.data.data,
- type: item.data.type,
- options: item.data.options,
- dataHandler: item.data.dataHandler,
- willFetch: item.data.willFetch,
- shouldFetch: item.data.shouldFetch,
- errorHandler: item.data.errorHandler
- }
-}
-
-const dataSourceMap: Record = {}
-
-let globalDataHandle: (res: any) => any = (res) => res
-
-// 统一的 load 构造
-const load = (http, options, dataSource, shouldFetch, parsedDataHandler) => (params?, customUrl?) => {
- // 无 options 视为本地/静态数据
- if (!options) {
- try {
- let raw = globalDataHandle(dataSource.config.data)
- if (parsedDataHandler) {
- raw = parsedDataHandler(raw)
- }
- const items = Array.isArray(raw) ? raw : raw ? [raw] : []
- const wrapped = { code: '', msg: 'success', data: { items, total: items.length } }
- dataSource.status = 'loaded'
- dataSource.data = wrapped
- return Promise.resolve(wrapped)
- } catch (e) {
- dataSource.status = 'error'
- dataSource.error = e
- return Promise.reject(e)
- }
- }
-
- if (!shouldFetch()) {
- return Promise.resolve(undefined)
- }
-
- dataSource.status = 'loading'
- const { method = 'GET', uri: url, params: defaultParams, timeout, headers } = options
- const config: any = { method, url, headers, timeout }
-
- const data = params || defaultParams
- config.url = customUrl || config.url
-
- if (method.toLowerCase() === 'get') {
- config.params = data
- } else {
- config.data = data
- }
-
- return http.request(config)
-}
-
-export const initDataSource = (config: any) => {
- Object.keys(dataSourceMap).forEach((key) => delete dataSourceMap[key])
-
- if (!config) {
- return dataSourceMap
- }
-
- const normalized = (config.list || []).map(normalizeItem)
-
- globalDataHandle = config.dataHandler ? parseJSFunction(config.dataHandler) : (res) => res
-
- normalized.forEach((item) => {
- const http = useHttp(globalDataHandle)
- const dataSource = {
- config: item,
- status: 'init',
- data: { data: item.data },
- load: null // 将在下面设置
- }
-
- const shouldFetch = item.shouldFetch?.value ? parseJSFunction(item.shouldFetch) : () => true
- const willFetch = item.willFetch?.value ? parseJSFunction(item.willFetch) : (options) => options
- const parsedDataHandler = item.dataHandler?.value ? parseJSFunction(item.dataHandler) : null
- const parsedErrorHandler = item.errorHandler?.value ? parseJSFunction(item.errorHandler) : null
-
- const dataHandler = (res) => {
- // 先应用用户定义的dataHandler
- const handled = parsedDataHandler ? parsedDataHandler(res) : res
-
- // 统一数据结构,确保与远程数据源与静态数据源结构一致
- let unifiedData
- if (handled && typeof handled === 'object' && !handled.data?.items) {
- // 如果不是静态数据源的格式,则转换为统一格式
- const items = Array.isArray(handled.data) ? handled.data : handled.data ? [handled.data] : []
- unifiedData = {
- code: handled.code || '',
- msg: handled.message || handled.msg || 'success',
- data: {
- items,
- total: items.length
- }
- }
- } else {
- unifiedData = handled
- }
-
- dataSource.status = 'loaded'
- dataSource.data = unifiedData
- return unifiedData
- }
- const errorHandler = (error) => {
- if (parsedErrorHandler) {
- parsedErrorHandler(error)
- }
- dataSource.status = 'error'
- dataSource.error = error
- return Promise.reject(error)
- }
-
- http.interceptors.request.use(willFetch, errorHandler)
- http.interceptors.response.use(dataHandler, errorHandler)
-
- // 设置 load 方法,传递 parsedDataHandler 参数
- dataSource.load = load(http, item.options, dataSource, shouldFetch, parsedDataHandler)
-
- // 存储到映射中
- dataSourceMap[item.name] = dataSource
- })
-}
-
-export const getDataSource = () => dataSourceMap
-
-export default dataSourceMap
diff --git a/packages/runtime-renderer/src/app-function/http/axios.js b/packages/runtime-renderer/src/app-function/http/axios.js
deleted file mode 100644
index 3654c619b4..0000000000
--- a/packages/runtime-renderer/src/app-function/http/axios.js
+++ /dev/null
@@ -1,143 +0,0 @@
-/**
- * Copyright (c) 2023 - present TinyEngine Authors.
- * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
- *
- * Use of this source code is governed by an MIT-style license.
- *
- * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
- * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
- * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
- *
- */
-
-import axios from 'axios'
-import MockAdapter from 'axios-mock-adapter'
-
-export default (config) => {
- const instance = axios.create(config)
- const defaults = {}
- let mock
-
- if (typeof MockAdapter.prototype.proxy === 'undefined') {
- MockAdapter.prototype.proxy = function ({ url, config = {}, proxy, response, handleData } = {}) {
- // eslint-disable-next-line @typescript-eslint/no-this-alias
- let stream = this
- const request = (proxy, any) => {
- return (setting) => {
- return new Promise((resolve) => {
- config.responseType = 'json'
- axios
- .get(any ? proxy + setting.url + '.json' : proxy, config)
- .then(({ data }) => {
- if (typeof handleData === 'function') {
- data = handleData.call(null, data, setting)
- }
- resolve([200, data])
- })
- .catch((error) => {
- resolve([error.response.status, error.response.data])
- })
- })
- }
- }
-
- if (url === '*' && proxy && typeof proxy === 'string') {
- stream = proxy === '*' ? this.onAny().passThrough() : this.onAny().reply(request(proxy, true))
- } else {
- if (proxy && typeof proxy === 'string') {
- stream = this.onAny(url).reply(request(proxy))
- } else if (typeof response === 'function') {
- stream = this.onAny(url).reply(response)
- }
- }
-
- return stream
- }
- }
-
- return {
- request(config) {
- return instance(config)
- },
- get(url, config) {
- return instance.get(url, config)
- },
- delete(url, config) {
- return instance.delete(url, config)
- },
- head(url, config) {
- return instance.head(url, config)
- },
- post(url, data, config) {
- return instance.post(url, data, config)
- },
- put(url, data, config) {
- return instance.put(url, data, config)
- },
- patch(url, data, config) {
- return instance.patch(url, data, config)
- },
- all(iterable) {
- return axios.all(iterable)
- },
- spread(callback) {
- return axios.spread(callback)
- },
- defaults(key, value) {
- if (key && typeof key === 'string') {
- if (typeof value === 'undefined') {
- return instance.defaults[key]
- }
- instance.defaults[key] = value
- defaults[key] = value
- } else {
- return instance.defaults
- }
- },
- defaultSettings() {
- return defaults
- },
- interceptors: {
- request: {
- use(fnHandle, fnError) {
- return instance.interceptors.request.use(fnHandle, fnError)
- },
- eject(id) {
- return instance.interceptors.request.eject(id)
- }
- },
- response: {
- use(fnHandle, fnError) {
- return instance.interceptors.response.use(fnHandle, fnError)
- },
- eject(id) {
- return instance.interceptors.response.eject(id)
- }
- }
- },
- mock(config) {
- if (!mock) {
- mock = new MockAdapter(instance)
- }
-
- if (Array.isArray(config)) {
- config.forEach((item) => {
- mock.proxy(item)
- })
- }
-
- return mock
- },
- disableMock() {
- if (mock) {
- mock.restore()
- }
- mock = undefined
- },
- isMock() {
- return typeof mock !== 'undefined'
- },
- CancelToken: axios.CancelToken,
- isCancel: axios.isCancel
- }
-}
diff --git a/packages/runtime-renderer/src/app-function/import-map.json b/packages/runtime-renderer/src/app-function/import-map.json
deleted file mode 100644
index 364ed31e27..0000000000
--- a/packages/runtime-renderer/src/app-function/import-map.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "imports": {
- "echarts": "${VITE_CDN_DOMAIN}/echarts${versionDelimiter}5.4.1${fileDelimiter}/dist/echarts.esm.js"
- },
- "importStyles": {}
-}
diff --git a/packages/runtime-renderer/src/app-function/importMap.ts b/packages/runtime-renderer/src/app-function/importMap.ts
deleted file mode 100644
index d6b30f4aa5..0000000000
--- a/packages/runtime-renderer/src/app-function/importMap.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-import importMapConfig from './import-map.json'
-
-const IMPORT_MAP_ELEMENT_ID = 'tiny-engine-runtime-import-map'
-
-type ImportMapConfig = {
- imports?: Record
- importStyles?: Record
-}
-
-const DEFAULT_ENV = {
- VITE_CDN_TYPE: 'npmmirror',
- VITE_CDN_DOMAIN: 'https://registry.npmmirror.com',
- VITE_LOCAL_IMPORT_PATH: 'local-cdn-static',
- BASE_URL: '/',
- VITE_LOCAL_IMPORT_MAPS: 'false'
-}
-
-const getEnvValue = (key: keyof typeof DEFAULT_ENV) => {
- return DEFAULT_ENV[key]
-}
-
-const replacePlaceholder = (value: string) => {
- const VITE_CDN_TYPE = getEnvValue('VITE_CDN_TYPE')
- const VITE_CDN_DOMAIN = getEnvValue('VITE_CDN_DOMAIN')
- const VITE_LOCAL_IMPORT_PATH = getEnvValue('VITE_LOCAL_IMPORT_PATH')
- const BASE_URL = getEnvValue('BASE_URL')
- const VITE_LOCAL_IMPORT_MAPS = getEnvValue('VITE_LOCAL_IMPORT_MAPS')
-
- const isLocalBundle = String(VITE_LOCAL_IMPORT_MAPS) === 'true'
- const versionDelimiter = VITE_CDN_TYPE === 'npmmirror' && !isLocalBundle ? '/' : '@'
- const fileDelimiter = VITE_CDN_TYPE === 'npmmirror' && !isLocalBundle ? '/files' : ''
- const cdnDomain = isLocalBundle ? `${BASE_URL}${VITE_LOCAL_IMPORT_PATH}` : VITE_CDN_DOMAIN
-
- return value
- .replace('${VITE_CDN_DOMAIN}', cdnDomain)
- .replace('${versionDelimiter}', versionDelimiter)
- .replace('${fileDelimiter}', fileDelimiter)
-}
-
-const parseImportMapConfig = (config: ImportMapConfig) => {
- const imports: Record = {}
- const importStyles: string[] = []
-
- Object.entries(config.imports || {}).forEach(([name, url]) => {
- imports[name] = replacePlaceholder(url)
- })
-
- Object.values(config.importStyles || {}).forEach((url) => {
- const parsed = replacePlaceholder(url)
- importStyles.push(parsed)
- })
-
- return { imports, importStyles }
-}
-
-const mergeImportMap = (imports: Record) => {
- if (typeof document === 'undefined') {
- return
- }
-
- const existing = document.getElementById(IMPORT_MAP_ELEMENT_ID) as HTMLScriptElement | null
- const mergedImports: Record = {}
-
- if (existing?.textContent) {
- try {
- const parsed = JSON.parse(existing.textContent)
- Object.assign(mergedImports, parsed?.imports || {})
- } catch (err) {
- // eslint-disable-next-line no-console
- console.warn('[runtime-import-map] 解析已有 import map 失败,将覆盖为新的配置。', err)
- }
- }
-
- Object.assign(mergedImports, imports)
-
- const importMapScript = existing || document.createElement('script')
- importMapScript.type = 'importmap'
- importMapScript.id = IMPORT_MAP_ELEMENT_ID
- importMapScript.textContent = JSON.stringify({ imports: mergedImports }, null, 2)
-
- if (!existing) {
- document.head.appendChild(importMapScript)
- }
-}
-
-export const initImportMap = () => {
- const { imports: baseImports } = parseImportMapConfig(importMapConfig)
-
- mergeImportMap({ ...baseImports })
-}
-
-export default initImportMap
diff --git a/packages/runtime-renderer/src/app-function/index.ts b/packages/runtime-renderer/src/app-function/index.ts
deleted file mode 100644
index bbd3065b3a..0000000000
--- a/packages/runtime-renderer/src/app-function/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export * from './dataSource'
-export * from './nativeComponents'
-export * from './utils'
-export * from './importMap'
diff --git a/packages/runtime-renderer/src/app-function/nativeComponents.ts b/packages/runtime-renderer/src/app-function/nativeComponents.ts
deleted file mode 100644
index 7449cfc1d3..0000000000
--- a/packages/runtime-renderer/src/app-function/nativeComponents.ts
+++ /dev/null
@@ -1,120 +0,0 @@
-// 定义组件配置接口
-interface ComponentConfig {
- destructuring?: boolean
- exportName?: string
-}
-
-// 定义组件依赖接口
-interface ComponentDependency {
- package?: string | null
- components: Record
- npmrc?: any
-}
-
-// 定义动态导入参数接口
-interface DynamicImportParams {
- package: string
- script?: string
-}
-
-export const addStyle = (href: string, doc = document): Promise => {
- return new Promise((resolve, reject) => {
- const link = doc.createElement('link')
-
- link.setAttribute('href', href)
- link.setAttribute('rel', 'stylesheet')
-
- link.onload = resolve
- link.onerror = reject
-
- doc.querySelector('head')!.appendChild(link)
- })
-}
-
-/**
- * 动态导入获取组件库模块
- * @param {DynamicImportParams} param 模块参数,包含pkg模块名称和script模块的cdn地址
- * @returns {Promise} 返回组件库模块
- */
-const dynamicImportComponentLib = async ({ package: pkg, script }: DynamicImportParams): Promise => {
- if (window.TinyComponentLibs[pkg]) {
- return window.TinyComponentLibs[pkg]
- }
-
- if (!script) {
- return {}
- }
-
- const href = window.location.href
- const scriptUrl = script.startsWith('.') ? new URL(script, href).href : script
-
- try {
- if (!window.TinyComponentLibs[pkg]) {
- const modules = await import(/* @vite-ignore */ scriptUrl)
-
- window.TinyComponentLibs[pkg] = modules
- }
- } catch (error) {
- // eslint-disable-next-line no-console
- console.log(`加载组件库失败: ${pkg}`, error)
- }
-
- return window.TinyComponentLibs[pkg]
-}
-
-/**
- * 获取组件库的package依赖
- * @param {DynamicImportParams[]} packageDependencys 组件库的package依赖数组
- * @returns {Promise} 返回组件库的package依赖对象
- */
-export const loadPackageDependencys = async (packageDependencys: DynamicImportParams[]): Promise => {
- for (const packageDependency of packageDependencys) {
- const { package: pkg, script } = packageDependency
- if (pkg === '@opentiny/vue') continue
- await dynamicImportComponentLib({ package: pkg, script })
- }
-}
-
-export const getComponentLibs = async (pkg: string, npmrc?: string) => {
- if (window.TinyComponentLibs[pkg]) {
- return window.TinyComponentLibs[pkg]
- } else {
- // 如果组件包含npmrc字段,则尝试从npmrc中引入模块
- if (npmrc && npmrc !== 'null' && npmrc !== '') {
- try {
- const modules = await import(/* @vite-ignore */ npmrc)
- window.TinyComponentLibs[pkg] = modules
- return modules
- } catch (error) {
- // eslint-disable-next-line no-console
- console.error(`从 npmrc 加载组件库失败: ${pkg}`, error)
- }
- }
- throw new Error(`${pkg} 组件库未找到`)
- }
-}
-
-/**
- * 获取组件对象并缓存,组件渲染时使用
- * @param {ComponentDependency} param 组件的依赖配置对象
- * @returns {Promise} 无返回值的Promise
- */
-export const getComponents = async ({ package: pkg, components, npmrc }: ComponentDependency): Promise => {
- if (!pkg || pkg === '@opentiny/vue') return
-
- const modules = await getComponentLibs(pkg, npmrc)
-
- Object.entries(components).forEach(([componentId, item]) => {
- if (!window.TinyLowcodeComponent[componentId]) {
- // 兼容老版本 - 当item是字符串时,直接作为模块导出名使用
- if (typeof item === 'string') {
- window.TinyLowcodeComponent[componentId] = modules[item]
- } else {
- // 当item是配置对象时,根据destructuring属性决定如何获取组件
- const config = item as ComponentConfig
- window.TinyLowcodeComponent[componentId] =
- config?.destructuring && config?.exportName ? modules[config.exportName] : modules?.default
- }
- }
- })
-}
diff --git a/packages/runtime-renderer/src/components/BlockLoadError.vue b/packages/runtime-renderer/src/components/BlockLoadError.vue
new file mode 100644
index 0000000000..5a210e079a
--- /dev/null
+++ b/packages/runtime-renderer/src/components/BlockLoadError.vue
@@ -0,0 +1,22 @@
+
+ 区块 {{ name }} 加载错误
+
+
+
+
+
diff --git a/packages/runtime-renderer/src/components/BlockLoading.vue b/packages/runtime-renderer/src/components/BlockLoading.vue
new file mode 100644
index 0000000000..b74bebdc27
--- /dev/null
+++ b/packages/runtime-renderer/src/components/BlockLoading.vue
@@ -0,0 +1,14 @@
+
+ 区块 {{ name }} 加载中
+
+
+
diff --git a/packages/runtime-renderer/src/components/NotFound.vue b/packages/runtime-renderer/src/components/NotFound.vue
index fa8b95981c..2ce993ed27 100644
--- a/packages/runtime-renderer/src/components/NotFound.vue
+++ b/packages/runtime-renderer/src/components/NotFound.vue
@@ -21,8 +21,8 @@
- 页面未找到
- 抱歉,您访问的页面不存在或已被删除。
+ 应用没有设置主页
+ 请手动补全应用路由去访问页面、或者在编辑页设置应用主页
请求的路径: {{ currentPath }}
diff --git a/packages/runtime-renderer/src/components/PageRenderer.ts b/packages/runtime-renderer/src/components/PageRenderer.ts
index f8a1145ec7..172f65907e 100644
--- a/packages/runtime-renderer/src/components/PageRenderer.ts
+++ b/packages/runtime-renderer/src/components/PageRenderer.ts
@@ -1,25 +1,13 @@
import { defineComponent, h } from 'vue'
import RenderMain from '../renderer/RenderMain'
+import { CanvasRouterView } from '../renderer/builtin'
-export function withPageRenderer(WrappedComponent: any) {
+export function withPageRenderer(props: any) {
+ const Component = props.isPage ? RenderMain : CanvasRouterView
return defineComponent({
name: 'PageRendererHOC',
- props: {
- pageId: {
- type: String,
- required: true
- }
- },
- setup(props) {
- return () => {
- return h(WrappedComponent, {
- pageId: props.pageId
- })
- }
+ render() {
+ return h(Component, { pageId: props.pageId, key: props.pageId })
}
})
}
-
-// 默认导出
-const PageRendererHOC = withPageRenderer(RenderMain)
-export default PageRendererHOC
diff --git a/packages/runtime-renderer/src/composables/service.ts b/packages/runtime-renderer/src/composables/service.ts
new file mode 100644
index 0000000000..dcbf04e6b4
--- /dev/null
+++ b/packages/runtime-renderer/src/composables/service.ts
@@ -0,0 +1,73 @@
+import type { BlockItem, IBlockItem } from '../types'
+
+export async function fetchAppSchema(id: string | number) {
+ let appSchema = {}
+ try {
+ const res: any = await fetch(`/app-center/v1/api/apps/schema/${id}`).then((res) => res.json())
+ appSchema = res?.data || {}
+ } catch (error) {
+ // eslint-disable-next-line no-console
+ console.error('获取应用Schema信息错误:', error)
+ }
+ return appSchema
+}
+
+export async function fetchAppPackages(pkgUrl: string) {
+ let packages = []
+ try {
+ const bundleJson = await fetch(pkgUrl).then((res) => res.json())
+ packages = bundleJson?.data?.materials?.packages || []
+ } catch (error) {
+ // eslint-disable-next-line no-console
+ console.error('获取应用物料包错误:', error)
+ }
+ return packages
+}
+
+export async function fetchAppPages(id: string | number) {
+ let pages = []
+ try {
+ const res: any = await fetch(`/app-center/api/pages/list/${id}`).then((res) => res.json())
+ pages = res?.data || []
+ } catch (error) {
+ // eslint-disable-next-line no-console
+ console.error('获取应用页面错误:', error)
+ }
+ return pages
+}
+export async function fetchAllBlocks() {
+ const blocksMap: Record = {}
+ try {
+ const res: any = await fetch('/material-center/api/blocks').then((res) => res.json())
+ const blocks: BlockItem[] = res?.data || []
+ blocks.forEach((block) => {
+ if (block.content) {
+ blocksMap[block.label] = {
+ schema: block.content,
+ meta: {
+ id: block.id,
+ label: block.label,
+ framework: block.framework,
+ version: block.version
+ }
+ }
+ }
+ })
+ } catch (error) {
+ // eslint-disable-next-line no-console
+ console.error('获取所有区块错误:', error)
+ }
+ return blocksMap
+}
+
+export async function fetchBlockByName(name: string) {
+ let block = {}
+ try {
+ const res: any = await fetch(`/material-center/api/block?label=${name}`).then((res) => res.json())
+ block = res?.data?.[0] || {}
+ } catch (error) {
+ // eslint-disable-next-line no-console
+ console.error(`获取区块[${name}]错误:`, error)
+ }
+ return block
+}
diff --git a/packages/runtime-renderer/src/composables/useAppSchema.ts b/packages/runtime-renderer/src/composables/useAppSchema.ts
index a075ca1890..5331aa71db 100644
--- a/packages/runtime-renderer/src/composables/useAppSchema.ts
+++ b/packages/runtime-renderer/src/composables/useAppSchema.ts
@@ -1,22 +1,9 @@
import { ref, computed, readonly } from 'vue'
-import type {
- IAppSchema,
- Util,
- BlockItem,
- BlockContent,
- I18nConfig,
- ComponentMap,
- PackageConfig
-} from '../types/schema'
-import i18n from '@opentiny/tiny-engine-i18n-host'
-import {
- addStyle,
- getComponents,
- loadPackageDependencys,
- initDataSource,
- initImportMap,
- initUtils
-} from '../app-function'
+import i18n from '@opentiny/tiny-engine-common/js/i18n'
+import type { IAppSchema, Util, I18nConfig, ComponentMap, PackageConfig } from '../types/index.ts'
+import { addTagTask, getComponents, initDataSource, initImportMap, initUtils } from '../renderer/app-function/index.ts'
+import { fetchAppSchema, fetchAppPackages, fetchAppPages, fetchBlockByName } from './service.ts'
+import config from '../../config.ts'
const appSchema = ref(null)
const isLoading = ref(false)
@@ -25,55 +12,29 @@ window.TinyLowcodeComponent = {}
window.TinyComponentLibs = {}
export function useAppSchema() {
- let cachedBundlePackages: PackageConfig[] | null = null
-
- const loadBundlePackages = async () => {
- if (cachedBundlePackages) {
- return cachedBundlePackages
- }
-
- try {
- const response = await fetch('/mock/bundle.json')
-
- if (!response.ok) {
- throw new Error(`加载基础物料包失败: HTTP ${response.status}: ${response.statusText}`)
- }
-
- const bundleJson = await response.json()
-
- cachedBundlePackages = (bundleJson?.data?.materials?.packages as PackageConfig[]) || []
- } catch (error) {
- // eslint-disable-next-line no-console
- console.error('加载基础物料包失败:', error)
- cachedBundlePackages = []
- }
-
- return cachedBundlePackages
- }
-
- const initializeComponentsMap = async (componentsMap: ComponentMap[], packages: PackageConfig[]) => {
+ const initComponentsMap = async (componentsMap: ComponentMap[]) => {
+ const packages = appSchema.value?.packages || []
// 获取组件依赖
- const componentsDeps = componentsMap.map((component: ComponentMap) => ({
- package: component.package,
- components: {
- [component.componentName]: component.destructuring
- ? { destructuring: true, exportName: component.exportName || component.componentName }
- : component.componentName
- },
- npmrc: component.npmrc
+ const componentsDeps: any = packages.map((pkg: PackageConfig) => ({
+ ...pkg,
+ components: componentsMap.filter((comp) => comp.package === pkg.package)
}))
-
const styles = packages.map((pkg) => pkg.css).filter((css) => css) as string[]
-
- await loadPackageDependencys(packages)
-
- try {
- // 并行加载所有组件依赖和包资源,与 runner.ts 中的机制保持一致
- await Promise.all([...componentsDeps.map(getComponents), ...styles.map((src) => addStyle(src))])
- } catch (error) {
- // eslint-disable-next-line no-console
- console.error('组件或资源加载失败:', error)
- }
+ await Promise.all([
+ ...componentsDeps.map(getComponents),
+ ...styles.map((link) =>
+ addTagTask({
+ href: link,
+ tag: 'link',
+ type: config.enableTailwindCSS ? 'text/tailwindcss' : 'text/css'
+ })
+ )
+ ])
+ .catch((err) => {
+ // eslint-disable-next-line no-console
+ console.error('组件或资源加载失败:', err)
+ })
+ .finally(() => {})
}
// 初始化工具函数
@@ -86,15 +47,6 @@ export function useAppSchema() {
}
}
- // 注入全局CSS
- const injectGlobalCSS = (css: string) => {
- if (!css) return
-
- const style = document.createElement('style')
- style.textContent = css
- document.head.appendChild(style)
- }
-
const initializeI18n = (i18nConfig: I18nConfig) => {
if (!i18nConfig) return
Object.entries(i18nConfig).forEach(([loc, msgs]) => {
@@ -102,118 +54,41 @@ export function useAppSchema() {
})
}
+ // 注入全局CSS
+ const initGlobalCSS = async (css: string) => {
+ if (!css) return
+ await addTagTask({
+ tag: 'style',
+ textContent: css,
+ id: 'app-global-css',
+ type: config.enableTailwindCSS ? 'text/tailwindcss' : 'text/css'
+ })
+ }
+
// 初始化应用配置
- const initializeAppConfig = async (schema: IAppSchema) => {
+ const setAppConfig = async (schema: IAppSchema) => {
if (!schema?.pages) return
-
- const packages = await loadBundlePackages()
-
// 初始化 importMap
- initImportMap()
-
+ await initImportMap()
// 初始化除tinyVue之外的nativeComponents
- await initializeComponentsMap(schema.componentsMap || [], packages)
-
- // 初始化国际化
- initializeI18n(schema?.i18n)
-
+ await initComponentsMap(schema.componentsMap || [])
// 初始化工具函数
await initializeUtils(schema?.utils)
-
+ // 初始化国际化
+ initializeI18n(schema?.i18n)
// 初始化数据源
initDataSource(schema?.dataSource)
-
// 注入全局CSS
- injectGlobalCSS(schema?.css)
- }
-
- // 拉取完整应用schema
- const fetchAppSchema = async (appId: string) => {
- isLoading.value = true
- error.value = null
-
- try {
- const response = await fetch(`/app-center/v1/api/apps/schema/${appId}`)
-
- if (!response.ok) {
- throw new Error(`加载应用Schema失败: HTTP ${response.status}: ${response.statusText}`)
- }
-
- const data = await response.json()
-
- if (!data?.data) {
- throw new Error('应用Schema数据无效')
- }
-
- const response1 = await fetch(`/app-center/api/pages/list/${appId}`)
-
- if (!response1.ok) {
- throw new Error(`加载页面Schema失败: HTTP ${response1.status}: ${response1.statusText}`)
- }
-
- const res = await response1.json()
-
- appSchema.value = { ...data.data, pages: res?.data || [] }
- // 解析并初始化应用级配置
- await initializeAppConfig(appSchema.value!)
- } catch (err) {
- error.value = err instanceof Error ? err.message : '加载应用Schema失败'
- // eslint-disable-next-line no-console
- console.error('加载应用Schema失败:', err)
- } finally {
- isLoading.value = false
- }
+ initGlobalCSS(schema?.css)
}
- // 拉取区块schema
- const fetchBlocks = async () => {
- try {
- const response = await fetch('/material-center/api/blocks')
-
- if (!response.ok) {
- throw new Error(`加载区块Schema失败: HTTP ${response.status}: ${response.statusText}`)
- }
-
- const blockJSON = await response.json()
-
- if (!Array.isArray(blockJSON?.data)) {
- throw new Error('区块Schema数据无效')
- }
-
- const blocks: BlockItem[] = blockJSON.data || []
-
- // 转换为组件映射格式
- const blocksMap: Record<
- string,
- {
- schema: BlockContent
- meta: {
- id: number
- label: string
- framework: string
- version: string
- }
- }
- > = {}
- blocks.forEach((block) => {
- if (block.content) {
- blocksMap[block.label] = {
- schema: block.content,
- meta: {
- id: block.id,
- label: block.label,
- framework: block.framework,
- version: block.version
- }
- }
- }
- })
-
- window.blocks = blocksMap
- } catch (error) {
- // eslint-disable-next-line no-console
- console.error('加载区块Schema失败:', error)
- }
+ // 初始化应用数据
+ const initAppData = async (id: string) => {
+ await Promise.all([fetchAppSchema(id), fetchAppPages(id), fetchAppPackages(config.material[0])]).then((rss) => {
+ const [schema, pages, packages] = rss
+ appSchema.value = { ...appSchema.value!, ...schema, pages, packages, blocks: {} }
+ })
+ await setAppConfig(appSchema.value!)
}
// 获取页面列表
@@ -265,12 +140,8 @@ export function useAppSchema() {
i18nConfig,
// 方法
- fetchAppSchema,
- fetchBlocks,
+ initAppData,
getPageById,
-
- // 初始化方法
- initializeAppConfig,
- injectGlobalCSS
+ fetchBlockByName
}
}
diff --git a/packages/runtime-renderer/src/renderer/RenderMain.ts b/packages/runtime-renderer/src/renderer/RenderMain.ts
index 205c3872f9..5572fd59c7 100644
--- a/packages/runtime-renderer/src/renderer/RenderMain.ts
+++ b/packages/runtime-renderer/src/renderer/RenderMain.ts
@@ -9,17 +9,13 @@
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
-
-import { h, computed, provide, nextTick, reactive, watch, defineComponent, inject } from 'vue'
-import Loading from '../components/Loading.vue'
-import { parseData } from './parser'
-import { renderer } from './render.ts'
-import { setPageCss, useState } from './page-function'
-import useContext from './useContext.ts'
-import { useRouter, useRoute } from 'vue-router'
-import { useAppSchema } from '../composables/useAppSchema'
-import type { PageContent as Schema } from '../types/schema'
-import { getDataSource, getUtilsAll } from '../app-function'
+import { defaultRenderer } from './render.ts'
+import { useContextPage } from './context/index.ts'
+import { useLowcode } from './context/useLowcode.ts'
+import { useAppSchema } from '../composables/useAppSchema.ts'
+import type { PageContent as Schema } from '../types/index.ts'
+import { computed, provide, reactive, watch, defineComponent } from 'vue'
+import { I18nInjectionKey } from '@opentiny/tiny-engine-common/js/i18n'
interface Props {
pageId: string
@@ -29,85 +25,40 @@ export default defineComponent({
name: 'RenderMain',
props: {
pageId: {
- type: String,
+ type: [String, Number],
default: '0'
}
},
- setup(props: Props) {
+ setup(props: Props, ctx: any) {
const { getPageById } = useAppSchema()
-
+ // 通过 pageId 获取最新的页面对象
const currentSchema = computed(() => {
- const page = getPageById(props.pageId) // 通过 pageId 获取最新的页面对象
+ const page = getPageById(props.pageId)
const pageContent = page?.page_content
if (!pageContent) return null
return JSON.parse(JSON.stringify(pageContent))
})
-
- const route = useRoute()
- const router = useRouter()
- const { context, setContext, getContext } = useContext()
- const reset = (obj: Record) => {
- Object.keys(obj).forEach((key) => delete obj[key])
- }
- const stores = inject('stores')
- provide('pageContext', context)
-
const pageSchema = reactive({} as Schema)
- const methods: Record = {}
- const { state, setState } = useState({ getContext })
-
- const setMethods = (data: Record = {}, clear?: boolean) => {
- if (clear) reset(methods)
- // 这里有些方法在画布还是有执行的必要的,比如说表格的renderer和formatText方法,包括一些自定义渲染函数
- Object.assign(
- methods,
- Object.fromEntries(
- Object.keys(data).map((key) => {
- return [key, parseData(data[key], {}, getContext())]
- })
- )
- )
- setContext(methods)
- }
-
- const setSchema = async (data: Schema) => {
- if (!data) {
- return
- }
-
- const newSchema = JSON.parse(JSON.stringify(data))
-
- const cssScopeId = `data-te-page-${String(props.pageId) || 'render-main'}`
- const contextData = {
- state,
- route,
- router,
- stores,
- dataSourceMap: getDataSource(),
- utils: getUtilsAll(),
- cssScopeId,
- getCssScopeId: () => cssScopeId
- }
- // 此处提升很重要,因为setState、initProps也会触发画布重新渲染,所以需要提升上下文环境的设置时间
- setContext(contextData, true)
-
- // 设置方法调用上下文
- setMethods(newSchema.methods, true)
-
- // 这里setState(会触发画布渲染),是因为状态管理里面的变量会用到props、utils、bridge、stores、methods
- setState(newSchema.state, true)
- await nextTick()
- setPageCss(data.css || '', cssScopeId)
- Object.assign(pageSchema, newSchema)
+ // TODO 暂时置空解决区块编译后获取报错问题
+ provide('page-ancestors', [])
+ // 提供翻译及区块Lowcode函数上下文
+ const { TinyI18nHost } = useLowcode()
+ provide(I18nInjectionKey, TinyI18nHost)
+ // 提供页面级上下文
+ const { state, methods, context, initContext } = useContextPage()
+ provide('pageContext', context)
+ const initPage = async (newSchema: Schema) => {
+ initContext({ schema: newSchema, props: props, ctx }, () => {
+ Object.assign(pageSchema, newSchema)
+ })
}
-
// 监听 schema 变化
watch(
() => currentSchema.value,
- async (schema) => {
- if (!schema) return
- if (Object.keys(schema).length === 0) return
- await setSchema(schema)
+ (schema) => {
+ if (schema && Object.keys(schema).length !== 0) {
+ initPage(JSON.parse(JSON.stringify(schema)))
+ }
},
{ immediate: true }
)
@@ -118,18 +69,6 @@ export default defineComponent({
}
},
render(): any {
- const { pageSchema }: { pageSchema: Schema } = this as any
-
- // 渲染画布增加根节点,与出码和预览保持一致
- const rootChildrenSchema: any = {
- componentName: 'div',
- // 把页级 props(主要是页面样式)挂到根容器
- props: { ...(pageSchema.props || {}) },
- children: pageSchema.children
- }
-
- return this.pageSchema.children?.length
- ? h(renderer, { schema: rootChildrenSchema, parent: this.pageSchema })
- : [h(Loading)]
+ return defaultRenderer(this.pageSchema as any)
}
})
diff --git a/packages/runtime-renderer/src/renderer/app-function/constant.ts b/packages/runtime-renderer/src/renderer/app-function/constant.ts
new file mode 100644
index 0000000000..c389b4e20b
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/app-function/constant.ts
@@ -0,0 +1,4 @@
+export const NODE_UID = 'data-uid'
+export const NODE_TAG = 'data-tag'
+export const NODE_LOOP = 'loop-id'
+export const NODE_INACTIVE_UID = 'data-ia-uid'
diff --git a/packages/runtime-renderer/src/renderer/app-function/dataSource/http.js b/packages/runtime-renderer/src/renderer/app-function/dataSource/http.js
new file mode 100644
index 0000000000..624fdd3327
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/app-function/dataSource/http.js
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+import Axios from 'axios'
+
+const config = { withCredentials: false }
+
+const axios = (config) => {
+ const instance = Axios.create(config)
+ const defaults = {}
+ return {
+ request(config) {
+ return instance(config)
+ },
+ defaults(key, value) {
+ if (key && typeof key === 'string') {
+ if (typeof value === 'undefined') {
+ return instance.defaults[key]
+ }
+ instance.defaults[key] = value
+ defaults[key] = value
+ } else {
+ return instance.defaults
+ }
+ },
+ defaultSettings() {
+ return defaults
+ },
+ interceptors: {
+ request: {
+ use(fnHandle, fnError) {
+ return instance.interceptors.request.use(fnHandle, fnError)
+ },
+ eject(id) {
+ return instance.interceptors.request.eject(id)
+ }
+ },
+ response: {
+ use(fnHandle, fnError) {
+ return instance.interceptors.response.use(fnHandle, fnError)
+ },
+ eject(id) {
+ return instance.interceptors.response.eject(id)
+ }
+ }
+ },
+ CancelToken: Axios.CancelToken,
+ isCancel: Axios.isCancel
+ }
+}
+
+export default ({ globalWillFetch, globalDataHandle, globalErrorHandler, willFetch, dataHandler, errorHandler }) => {
+ const http = axios(config)
+ // axios对于request拦截器是后注册先执行
+ http.interceptors.request.use(willFetch, errorHandler)
+ http.interceptors.request.use(globalWillFetch, globalErrorHandler)
+ http.interceptors.response.use(dataHandler, errorHandler)
+ http.interceptors.response.use(globalDataHandle, globalErrorHandler)
+ return http
+}
diff --git a/packages/runtime-renderer/src/renderer/app-function/dataSource/index.ts b/packages/runtime-renderer/src/renderer/app-function/dataSource/index.ts
new file mode 100644
index 0000000000..6f1e941d1d
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/app-function/dataSource/index.ts
@@ -0,0 +1,108 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+import useHttp from './http.js'
+const dataSourceMap: Record = {}
+
+const createFn = (fnStr: string) => {
+ return (...args: any) => {
+ const fn = new Function(`return ${fnStr}`)()
+ return fn.apply(this, args)
+ }
+}
+
+export const initDataSource = (dataSources: any) => {
+ const globalWillFetch = dataSources.willFetch ? createFn(dataSources.willFetch.value) : (opt: any) => opt
+ const globalDataHandle = dataSources.dataHandler ? createFn(dataSources.dataHandler.value) : (res: any) => res
+ const globalErrorHandler = dataSources.errorHandler
+ ? createFn(dataSources.errorHandler.value)
+ : (err: any) => Promise.reject(err)
+ const execProxy = (config: any) => {
+ // TODO 通过全局配置代理, 通过代理服务器的方式获取接口数据,解决跨域问题
+ const appId = new URLSearchParams(location.search).get('id')
+ const { proxy = {} } = dataSources || {}
+ if (proxy) {
+ const isProxy = Object.keys(proxy).reduce((acc, cur) => acc || config.url.startsWith(cur), false)
+ if (isProxy) {
+ config.url = `/proxy/api${config.url}`
+ config.headers = { ...config.headers, proxy_app_id: appId || 1 }
+ }
+ }
+ }
+
+ const load =
+ (http: any, options: any, dataSource: any, shouldFetch: any) => (params: any, path: any, customConfig: any) => {
+ // 如果没有配置远程请求,则直接返回静态数据,返回前可能会有全局数据处理
+ if (!options) {
+ return Promise.resolve(globalDataHandle(dataSource.config.data))
+ }
+
+ if (!shouldFetch()) {
+ return Promise.resolve(undefined)
+ }
+
+ dataSource.status = 'loading'
+
+ const { method, uri: url, params: defaultParams, timeout, headers } = options
+ const config = { method, url, headers, timeout, ...customConfig }
+
+ const data = params || defaultParams
+
+ config.url = path ? `${config.url}/${path}` : config.url
+
+ execProxy(config)
+
+ if (['get', 'delete'].includes(method.toLowerCase())) {
+ config.params = data
+ } else {
+ config.data = data
+ }
+
+ return http.request(config)
+ }
+
+ if (Array.isArray(dataSources.list)) {
+ dataSources.list?.forEach((conf: any) => {
+ const config = { name: conf.name, ...(conf.data || {}) }
+ const dataSource: any = { config }
+ dataSourceMap[config.name] = dataSource
+ const shouldFetch = config.shouldFetch?.value ? createFn(config.shouldFetch.value) : () => true
+ const willFetch = config.willFetch?.value ? createFn(config.willFetch.value) : (opt: any) => opt
+ const dataHandler = (res: any) => {
+ const data = config.dataHandler?.value ? createFn(config.dataHandler.value)(res) : res
+ dataSource.status = 'loaded'
+ dataSource.data = data
+ return data
+ }
+ const errorHandler = (error: any) => {
+ const err = config.errorHandler?.value ? createFn(config.errorHandler.value)(error) : error
+ dataSource.status = 'error'
+ dataSource.error = err
+ }
+ const http = useHttp({
+ globalWillFetch,
+ globalDataHandle,
+ globalErrorHandler,
+ willFetch,
+ dataHandler,
+ errorHandler
+ })
+
+ dataSource.status = 'init'
+ dataSource.load = load(http, config.options, dataSource, shouldFetch)
+ })
+ }
+}
+
+export const getDataSource = () => dataSourceMap
+
+export default dataSourceMap
diff --git a/packages/runtime-renderer/src/renderer/app-function/importMap.ts b/packages/runtime-renderer/src/renderer/app-function/importMap.ts
new file mode 100644
index 0000000000..cebd669165
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/app-function/importMap.ts
@@ -0,0 +1,158 @@
+import { importMapConfig } from '@opentiny/tiny-engine-common/js/importMap'
+import config, { useEnv } from '../../../config.ts'
+
+const {
+ VITE_CDN_TYPE,
+ VITE_CDN_DOMAIN,
+ BASE_URL,
+ VITE_LOCAL_IMPORT_MAPS,
+ VITE_LOCAL_IMPORT_PATH = 'local-cdn-static'
+} = useEnv()
+
+const getImportUrl = (pkgName: string) => {
+ // 自定义的 importMap
+ const customImportMap = config?.importMap as any
+ const sysImportMap = importMapConfig as any
+ const isLocalBundle = VITE_LOCAL_IMPORT_MAPS === 'true'
+ const versionDelimiter = VITE_CDN_TYPE === 'npmmirror' && !isLocalBundle ? '/' : '@'
+ const fileDelimiter = VITE_CDN_TYPE === 'npmmirror' && !isLocalBundle ? '/files' : ''
+ const cdnDomain = isLocalBundle ? BASE_URL + VITE_LOCAL_IMPORT_PATH : VITE_CDN_DOMAIN
+
+ if (customImportMap?.imports?.[pkgName]) {
+ return customImportMap.imports[pkgName]
+ .replace('${VITE_CDN_DOMAIN}', cdnDomain)
+ .replace('${versionDelimiter}', versionDelimiter)
+ .replace('${fileDelimiter}', fileDelimiter)
+ }
+
+ if (sysImportMap?.imports?.[pkgName]) {
+ return sysImportMap?.imports?.[pkgName]
+ .replace('${VITE_CDN_DOMAIN}', cdnDomain)
+ .replace('${versionDelimiter}', versionDelimiter)
+ .replace('${fileDelimiter}', fileDelimiter)
+ }
+}
+
+// 获取样式文件的URL,后续去除物料内置逻辑之后,需要用户自行引入,相关逻辑也需要同步删除
+const getImportStyleUrl = (pkgName: string) => {
+ const isLocalBundle = VITE_LOCAL_IMPORT_MAPS === 'true'
+ const versionDelimiter = VITE_CDN_TYPE === 'npmmirror' && !isLocalBundle ? '/' : '@'
+ const fileDelimiter = VITE_CDN_TYPE === 'npmmirror' && !isLocalBundle ? '/files' : ''
+ const cdnDomain = isLocalBundle ? BASE_URL + VITE_LOCAL_IMPORT_PATH : VITE_CDN_DOMAIN
+ const sysImportMap = importMapConfig as any
+
+ if (sysImportMap.importStyles[pkgName]) {
+ return sysImportMap.importStyles[pkgName]
+ .replace('${VITE_CDN_DOMAIN}', cdnDomain)
+ .replace('${versionDelimiter}', versionDelimiter)
+ .replace('${fileDelimiter}', fileDelimiter)
+ }
+}
+
+export function getImportMapData(canvasDeps = { scripts: [], styles: [] }) {
+ // 以下内容由于区块WebComponent加载需要补充
+ const blockRequire = {
+ imports: {
+ // TODO: 后续版本发通知,不再内置物料,需要用户自行引入
+ '@opentiny/vue': getImportUrl('@opentiny/vue'),
+ '@opentiny/vue-icon': getImportUrl('@opentiny/vue-icon'),
+ '@opentiny/tiny-engine-builtin-component': getImportUrl('@opentiny/tiny-engine-builtin-component')
+ },
+ importStyles: [getImportStyleUrl('@opentiny/vue-theme')]
+ }
+
+ // 以下内容由于物料协议不支持声明子依赖而@opentiny/vue需要依赖所以需要补充
+ // TODO: 后续版本发通知,不再内置物料,需要用户自行引入
+ const tinyVueRequire = {
+ imports: {
+ '@opentiny/vue-common': getImportUrl('@opentiny/vue-common'),
+ '@opentiny/vue-locale': getImportUrl('@opentiny/vue-locale'),
+ echarts: getImportUrl('echarts')
+ }
+ }
+
+ const materialsAndUtilsRequire = canvasDeps.scripts.reduce((imports, { package: pkg, script }) => {
+ if (pkg && script) {
+ imports[pkg] = script
+ }
+
+ return imports
+ }, {})
+
+ const importMap = {
+ imports: {
+ vue: getImportUrl('vue'),
+ 'vue-i18n': getImportUrl('vue-i18n'),
+ ...blockRequire.imports,
+ ...tinyVueRequire.imports,
+ ...materialsAndUtilsRequire
+ }
+ }
+
+ const importStyles = [...blockRequire.importStyles, ...canvasDeps.styles]
+ const tailwindURL = getImportUrl('@tailwindcss/browser')
+ const importScripts = config?.enableTailwindCSS && tailwindURL ? [tailwindURL] : []
+
+ return {
+ importMap,
+ importStyles,
+ importScripts
+ }
+}
+
+interface ITagProps {
+ tag: string
+ [key: string]: string
+}
+
+export const IMPORT_MAP_ELEMENT_ID = 'tiny-engine-runtime-import-map'
+
+export function addTagTask(props: ITagProps) {
+ return new Promise((resolve, reject) => {
+ const { tag, onload, ...others } = props
+ let el: any = document.head.querySelector(`${tag}#${props.id}`)
+ const isCreate = !el
+ if (!el) {
+ el = document.createElement(tag) as any
+ }
+ for (const key in others) {
+ el[key] = others[key] as string
+ }
+ if (isCreate) {
+ document.head.appendChild(el)
+ }
+ const success = () => resolve(true)
+ const error = () => reject(new Error(`添加并加载${tag}失败: ${props}`))
+ if (onload) {
+ el.onload = success
+ el.onerror = error
+ } else {
+ setTimeout(() => success())
+ }
+ })
+}
+
+export async function initImportMap() {
+ const { importMap, importStyles, importScripts } = getImportMapData()
+ const tasks = []
+ const task = addTagTask({
+ id: IMPORT_MAP_ELEMENT_ID,
+ tag: 'script',
+ type: 'importmap',
+ textContent: JSON.stringify(importMap, null, 2)
+ })
+ tasks.push(task)
+ importStyles.forEach((url) => {
+ const task = addTagTask({
+ tag: 'link',
+ href: url,
+ type: config.enableTailwindCSS ? 'text/tailwindcss' : 'text/css'
+ })
+ tasks.push(task)
+ })
+ importScripts.forEach((url) => {
+ const task = addTagTask({ tag: 'script', type: 'module', src: url })
+ tasks.push(task)
+ })
+ await Promise.all(tasks)
+}
diff --git a/packages/runtime-renderer/src/renderer/app-function/index.ts b/packages/runtime-renderer/src/renderer/app-function/index.ts
new file mode 100644
index 0000000000..6ffc9cde0a
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/app-function/index.ts
@@ -0,0 +1,7 @@
+export * from './dataSource/index.ts'
+export * from './loadCompLib.ts'
+export * from './utils.ts'
+export * from './importMap.ts'
+export * from './store.ts'
+export * from './router.ts'
+export * from './constant.ts'
diff --git a/packages/runtime-renderer/src/renderer/app-function/loadCompLib.ts b/packages/runtime-renderer/src/renderer/app-function/loadCompLib.ts
new file mode 100644
index 0000000000..6591557598
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/app-function/loadCompLib.ts
@@ -0,0 +1,63 @@
+// 定义组件配置接口
+interface ComponentConfig {
+ destructuring?: boolean
+ exportName?: string
+}
+
+// 定义组件依赖接口
+interface ComponentDependency {
+ package?: string
+ script?: string
+ components: Record
+}
+
+// 定义动态导入参数接口
+interface DynamicImportParams {
+ package: string
+ script?: string
+}
+
+/**
+ * 动态导入获取组件库模块
+ * @param {DynamicImportParams} param 模块参数,包含pkg模块名称和script模块的cdn地址
+ * @returns {Promise} 返回组件库模块
+ */
+const dynamicImportComponentLib = async ({ package: pkg, script }: DynamicImportParams): Promise => {
+ if (window.TinyComponentLibs[pkg]) {
+ return window.TinyComponentLibs[pkg]
+ }
+ try {
+ // 尝试直接导入模块
+ const modules = await import(/* @vite-ignore */ pkg)
+ window.TinyComponentLibs[pkg] = modules
+ } catch (_err) {
+ if (script) {
+ try {
+ // 拉取远程脚本
+ const modules = await import(/* @vite-ignore */ script)
+ window.TinyComponentLibs[pkg] = modules
+ } catch (error) {
+ // eslint-disable-next-line no-console
+ console.error(`组件库安装失败: ${pkg}`, error)
+ }
+ }
+ }
+ return window.TinyComponentLibs[pkg]
+}
+
+/**
+ * 获取组件对象并缓存,组件渲染时使用
+ * @param {ComponentDependency} param 组件的依赖配置对象
+ * @returns {Promise} 无返回值的Promise
+ */
+export const getComponents = async ({ package: pkg, script, components }: ComponentDependency): Promise => {
+ if (!pkg) return
+ const modules = await dynamicImportComponentLib({ package: pkg, script })
+ for (const i in components) {
+ const item = components[i] as any
+ if (!window.TinyLowcodeComponent[item.componentName || item.exportName]) {
+ window.TinyLowcodeComponent[item.componentName] =
+ item?.destructuring && item?.exportName ? modules[item.exportName] : modules?.default
+ }
+ }
+}
diff --git a/packages/runtime-renderer/src/router/index.ts b/packages/runtime-renderer/src/renderer/app-function/router.ts
similarity index 85%
rename from packages/runtime-renderer/src/router/index.ts
rename to packages/runtime-renderer/src/renderer/app-function/router.ts
index 40fbc17332..fce61f2bd5 100644
--- a/packages/runtime-renderer/src/router/index.ts
+++ b/packages/runtime-renderer/src/renderer/app-function/router.ts
@@ -1,7 +1,8 @@
import { createRouter, createWebHashHistory } from 'vue-router'
-import { useAppSchema } from '../composables/useAppSchema'
-import type { IRouteConfig } from '../types/config'
-import type { PageMeta } from '../types/schema'
+import { useAppSchema } from '../../composables/useAppSchema.ts'
+import type { IRouteConfig } from '../../types/index.ts'
+import { withPageRenderer } from '../../components/PageRenderer.ts'
+import type { PageMeta } from '../../types/index.ts'
// 定义页面结构类型
interface PageSchema {
@@ -9,6 +10,7 @@ interface PageSchema {
name: string
route: string
parentId: string
+ isPage: boolean
isHome: boolean
isDefault: boolean
depth: number
@@ -17,9 +19,8 @@ interface PageSchema {
}
// 异步初始化路由配置
-async function createRouterConfig() {
+function createRouterConfig() {
const { pages } = useAppSchema()
-
// 通过pages生成路由配置
const generateRoutesByPages = (pages: Array): Array => {
// 建立路由-页面id映射
@@ -31,8 +32,7 @@ async function createRouterConfig() {
pageRouteMap.set(pageIdStr, {
path: `${page.route}`,
name: pageIdStr,
- component: () => import('../components/PageRenderer.ts'),
- props: { pageId: page.id },
+ component: withPageRenderer({ pageId: page.id, isPage: page?.isPage }),
children: [],
meta: {
pageId: pageIdStr,
@@ -85,14 +85,14 @@ async function createRouterConfig() {
routes.push({
path: '/:pathMatch(.*)*',
- component: () => import('../components/NotFound.vue')
+ component: () => import('../../components/NotFound.vue')
})
return routes
}
-export async function createAppRouter() {
- const routes = await createRouterConfig()
+export function createAppRouter() {
+ const routes = createRouterConfig()
const router = createRouter({
history: createWebHashHistory('/runtime.html'),
routes
diff --git a/packages/runtime-renderer/src/stores/index.ts b/packages/runtime-renderer/src/renderer/app-function/store.ts
similarity index 74%
rename from packages/runtime-renderer/src/stores/index.ts
rename to packages/runtime-renderer/src/renderer/app-function/store.ts
index 80f7a3d951..9c1dce9c4d 100644
--- a/packages/runtime-renderer/src/stores/index.ts
+++ b/packages/runtime-renderer/src/renderer/app-function/store.ts
@@ -1,9 +1,8 @@
-import { defineStore, type Pinia } from 'pinia'
+import { createPinia, defineStore } from 'pinia'
import { shallowReactive } from 'vue'
-import type { StoreConfig } from '../types/config'
-import { useAppSchema } from '../composables/useAppSchema'
-import { parseJSFunction } from '../utils/data-utils'
-
+import { useAppSchema } from '../../composables/useAppSchema'
+import { parseJSFunction } from '../data-function'
+const stores = shallowReactive>({})
export const generateStoresConfig = () => {
const { globalStates } = useAppSchema()
if (globalStates.value.length === 0) return []
@@ -13,7 +12,7 @@ export const generateStoresConfig = () => {
actions: Object.fromEntries(
Object.keys(store.actions || {}).map((key) => {
// 使用 parseJSFunction ,但是上下文由pinia内部绑定
- const fn = parseJSFunction(store.actions[key], {}, {})
+ const fn = parseJSFunction(store.actions[key])
if (!fn) {
// eslint-disable-next-line no-console
console.error(`Failed to parse action: ${key} in store: ${store.id}`)
@@ -25,7 +24,7 @@ export const generateStoresConfig = () => {
getters: Object.fromEntries(
Object.keys(store.getters || {}).map((key) => {
// 同样处理 getters
- const fn = parseJSFunction(store.getters[key], {}, {})
+ const fn = parseJSFunction(store.getters[key])
if (!fn) {
// eslint-disable-next-line no-console
console.error(`Failed to parse getter: ${key} in store: ${store.id}`)
@@ -37,9 +36,9 @@ export const generateStoresConfig = () => {
}))
}
-export const createStores = (storesConfig: StoreConfig[], pinia: Pinia) => {
- const stores = shallowReactive>({})
-
+export const createAppStores = () => {
+ const pinia = createPinia()
+ const storesConfig = generateStoresConfig()
storesConfig.forEach((config) => {
// 使用 defineStore 创建 Pinia store
const useStore = defineStore(config.id, {
@@ -52,6 +51,9 @@ export const createStores = (storesConfig: StoreConfig[], pinia: Pinia) => {
// 使用useStore创建 store 实例并绑定到 pinia
stores[config.id] = useStore(pinia)
})
+ return pinia
+}
+export function getStore() {
return stores
}
diff --git a/packages/runtime-renderer/src/app-function/utils.ts b/packages/runtime-renderer/src/renderer/app-function/utils.ts
similarity index 78%
rename from packages/runtime-renderer/src/app-function/utils.ts
rename to packages/runtime-renderer/src/renderer/app-function/utils.ts
index efac49418e..03162a638b 100644
--- a/packages/runtime-renderer/src/app-function/utils.ts
+++ b/packages/runtime-renderer/src/renderer/app-function/utils.ts
@@ -1,5 +1,5 @@
-import type { Util } from '../types/schema'
-import { parseJSFunction } from '../utils/data-utils'
+import type { Util } from '../../types/index.ts'
+import { parseJSFunction } from '../data-function/index.ts'
interface npmContent {
package?: string
@@ -26,18 +26,17 @@ async function loadNpmUtil(util: Util) {
if (utilValues.has(util.name)) return
const key = `${c.package}@${c.version || ''}`
- let mod = npmCache.get(key)
- if (!mod) {
- const url =
- c.cdnLink || (c.version ? `https://unpkg.com/${c.package}@${c.version}` : `https://unpkg.com/${c.package}`)
- mod = await import(/* @vite-ignore */ url)
- npmCache.set(key, mod)
+ let modules: any = npmCache.get(key)
+ if (!modules) {
+ const url = c.cdnLink || c.package
+ modules = await import(/* @vite-ignore */ url)
+ npmCache.set(key, modules)
}
let exported: any
if (c.destructuring) {
- exported = c.exportName ? mod[c.exportName as keyof typeof mod] : mod
+ exported = c.exportName ? modules[c.exportName] : modules.default || modules
} else {
- exported = (c.exportName && mod[c.exportName]) || mod.default || mod
+ exported = (c.exportName && modules[c.exportName]) || modules.default || modules
}
if (c.subName && exported) exported = exported[c.subName]
utilValues.set(util.name, exported)
diff --git a/packages/runtime-renderer/src/renderer/builtin/CanvasBox.vue b/packages/runtime-renderer/src/renderer/builtin/CanvasBox.vue
new file mode 100644
index 0000000000..b4414c5cd5
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/builtin/CanvasBox.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
diff --git a/packages/runtime-renderer/src/renderer/builtin/CanvasRouterView.vue b/packages/runtime-renderer/src/renderer/builtin/CanvasRouterView.vue
index 53d64d83f8..1f6363dc9b 100644
--- a/packages/runtime-renderer/src/renderer/builtin/CanvasRouterView.vue
+++ b/packages/runtime-renderer/src/renderer/builtin/CanvasRouterView.vue
@@ -1,5 +1,5 @@
-
+
diff --git a/packages/runtime-renderer/src/renderer/builtin/index.ts b/packages/runtime-renderer/src/renderer/builtin/index.ts
index aa303aae9e..66da676e64 100644
--- a/packages/runtime-renderer/src/renderer/builtin/index.ts
+++ b/packages/runtime-renderer/src/renderer/builtin/index.ts
@@ -9,23 +9,12 @@
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
-
-import CanvasText from './CanvasText.vue'
-import CanvasIcon from './CanvasIcon.vue'
-import CanvasSlot from './CanvasSlot.vue'
-import CanvasImg from './CanvasImg.vue'
-import CanvasPlaceholder from './CanvasPlaceholder.vue'
-import CanvasRouterLink from './CanvasRouterLink.vue'
-import CanvasRouterView from './CanvasRouterView.vue'
-import CanvasCollection from './CanvasCollection.vue'
-
-export {
- CanvasText,
- CanvasIcon,
- CanvasSlot,
- CanvasImg,
- CanvasPlaceholder,
- CanvasRouterLink,
- CanvasRouterView,
- CanvasCollection
-}
+export { default as CanvasBox } from './CanvasBox.vue'
+export { default as CanvasText } from './CanvasText.vue'
+export { default as CanvasIcon } from './CanvasIcon.vue'
+export { default as CanvasSlot } from './CanvasSlot.vue'
+export { default as CanvasImg } from './CanvasImg.vue'
+export { default as CanvasPlaceholder } from './CanvasPlaceholder.vue'
+export { default as CanvasRouterLink } from './CanvasRouterLink.vue'
+export { default as CanvasRouterView } from './CanvasRouterView.vue'
+export { default as CanvasCollection } from './CanvasCollection.vue'
diff --git a/packages/runtime-renderer/src/renderer/context/index.ts b/packages/runtime-renderer/src/renderer/context/index.ts
new file mode 100644
index 0000000000..e16a5aa061
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/context/index.ts
@@ -0,0 +1,7 @@
+export * from './useContext'
+export * from './useStore'
+export * from './useMethods'
+export * from './useRefs'
+export * from './useState'
+export * from './useDataSource'
+export * from './useUtils'
diff --git a/packages/runtime-renderer/src/renderer/context/useContext.ts b/packages/runtime-renderer/src/renderer/context/useContext.ts
new file mode 100644
index 0000000000..fc54907046
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/context/useContext.ts
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+import * as vue from 'vue'
+import { shallowReactive, type ShallowReactive } from 'vue'
+import { useRoute, useRouter } from 'vue-router'
+import { useStore } from './useStore.ts'
+import { useUtils } from './useUtils.ts'
+import { useRefs } from './useRefs.ts'
+import { useState } from './useState.ts'
+import { useMethods } from './useMethods.ts'
+import { useDataSource } from './useDataSource.ts'
+import { getDeletedKeys } from '../data-function/index.ts'
+import { normalizeScopeKey, setPageCss } from '../page-function/index.ts'
+import TinyI18nHost from '@opentiny/tiny-engine-common/js/i18n'
+import type { PageContent as Schema } from '../../types/index.ts'
+
+interface Context {
+ [key: string]: any
+}
+
+interface UseContextReturn {
+ context: ShallowReactive
+ setContext: (ctx: Context) => void
+ appendContext: (ctx: Context) => void
+ getContext: () => ShallowReactive
+}
+
+export function useContext(): UseContextReturn {
+ const context = shallowReactive({})
+
+ const setContext = (ctx: Context) => {
+ const deletedKeys = getDeletedKeys(context, ctx)
+ deletedKeys?.forEach((key) => delete context[key])
+ Object.assign(context, ctx)
+ }
+
+ const appendContext = (ctx: Context) => {
+ setContext({ ...context, ...ctx })
+ }
+
+ const getContext = () => context
+
+ return {
+ context,
+ setContext,
+ getContext,
+ appendContext
+ }
+}
+
+interface InitContextProps {
+ schema: Schema
+ props: any
+ ctx: any
+ isBlock?: boolean
+}
+
+export function useContextPage() {
+ const { context, setContext, appendContext } = useContext()
+ const route = useRoute()
+ const router = useRouter()
+ const { $, $ref } = useRefs()
+ const { stores } = useStore()
+ const { utils } = useUtils()
+ const { dataSourceMap } = useDataSource()
+ const { state, setState } = useState({}, context)
+ const { methods, setMethods } = useMethods({}, context)
+ const { t, locale } = TinyI18nHost.global
+ const initContext = ({ schema, props, isBlock, ctx }: InitContextProps, callback?: (...args: any[]) => void) => {
+ if (!schema) return
+ const cssScopeId = normalizeScopeKey(props.pageId, isBlock)
+ setContext({
+ ...vue,
+ context: ctx,
+ t,
+ $,
+ $ref,
+ route,
+ router,
+ props,
+ state,
+ utils,
+ stores,
+ dataSourceMap,
+ i18n: { get: () => t },
+ // setState: { get: () => setState },
+ getLocale: { get: () => locale?.value },
+ setLocale: { get: () => (val: string) => (locale.value = val) },
+ location: { get: () => window.location },
+ history: { get: () => window.history },
+ getCssScopeId: () => cssScopeId
+ })
+ setState(schema.state)
+ setMethods(schema.methods)
+ appendContext(methods)
+ setPageCss(schema.css || '', cssScopeId)
+ callback?.()
+ }
+ return {
+ state,
+ utils,
+ stores,
+ context,
+ methods,
+ initContext,
+ setContext,
+ appendContext,
+ setState,
+ setMethods,
+ $,
+ $ref
+ }
+}
diff --git a/packages/runtime-renderer/src/renderer/context/useDataSource.ts b/packages/runtime-renderer/src/renderer/context/useDataSource.ts
new file mode 100644
index 0000000000..3df8d9ce06
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/context/useDataSource.ts
@@ -0,0 +1,18 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+import { getDataSource } from '../app-function'
+export function useDataSource() {
+ return {
+ dataSourceMap: getDataSource()
+ }
+}
+export { getDataSource }
diff --git a/packages/runtime-renderer/src/renderer/context/useLowcode.ts b/packages/runtime-renderer/src/renderer/context/useLowcode.ts
new file mode 100644
index 0000000000..8d67287f43
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/context/useLowcode.ts
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+import { useRouter, useRoute } from 'vue-router'
+import { getStore, getDataSource, getUtilsAll } from './index'
+import { getCurrentInstance, nextTick, provide, inject } from 'vue'
+import TinyI18nHost, { I18nInjectionKey } from '@opentiny/tiny-engine-common/js/i18n'
+
+export const lowcodeWrap = (props: any, context: any) => {
+ const global: any = {}
+ const instance = getCurrentInstance() as any
+ const router = useRouter()
+ const route = useRoute()
+ const i18nhost = inject(I18nInjectionKey) as any
+ const { t, locale } = i18nhost.global
+ const emit = context.emit
+ const ref = (ref: string) => instance?.refs?.[ref]
+
+ const setState = (newState: any, callback: any) => {
+ Object.assign(global.state, newState)
+ nextTick(() => callback.apply(global))
+ }
+
+ const getLocale = () => locale.value
+ const setLocale = (val: string) => {
+ locale.value = val
+ }
+
+ const location = () => window.location
+ const history = () => window.history
+
+ Object.defineProperties(global, {
+ i18n: { get: () => t },
+ emit: { get: () => emit },
+ props: { get: () => props },
+ route: { get: () => route },
+ router: { get: () => router },
+ setState: { get: () => setState },
+ getLocale: { get: () => getLocale },
+ setLocale: { get: () => setLocale },
+ utils: { get: () => getUtilsAll() },
+ dataSourceMap: { get: () => getDataSource() },
+ location: { get: location },
+ history: { get: history },
+ bridge: { get: () => {} },
+ $: { get: () => ref }
+ })
+
+ const wrap = (fn: any) => {
+ if (typeof fn === 'function') {
+ return (...args: any[]) => fn.apply(global, args)
+ }
+
+ Object.entries(fn).forEach(([name, value]) => {
+ Object.defineProperty(global, name, {
+ get: () => value
+ })
+ })
+
+ fn.t = t
+
+ return fn
+ }
+
+ return wrap
+}
+
+export const lowcode = () => {
+ const i18n = inject(I18nInjectionKey) as any
+
+ provide(I18nInjectionKey, i18n)
+
+ return { t: i18n.global.t, lowcodeWrap, stores: getStore() }
+}
+
+export const useLowcode = () => {
+ const i18nHost = TinyI18nHost as any
+ i18nHost.lowcode = lowcode
+ return {
+ TinyI18nHost: i18nHost
+ }
+}
diff --git a/packages/runtime-renderer/src/renderer/context/useMethods.ts b/packages/runtime-renderer/src/renderer/context/useMethods.ts
new file mode 100644
index 0000000000..43a2d71a9a
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/context/useMethods.ts
@@ -0,0 +1,22 @@
+import { shallowReactive } from 'vue'
+import { parseData } from '../data-function/index'
+import type { IFuntion } from '../../types/index'
+export function useMethods(scope: any = {}, context: any = {}) {
+ const methods = shallowReactive>({})
+ const setMethods = (methodsObj: Record) => {
+ for (const key in methodsObj) {
+ const method = methodsObj[key]
+ methods[key] = parseData(method, scope, context) as IFuntion
+ }
+ }
+ const delMethods = (key: string) => {
+ delete methods[key]
+ }
+ const getMethods = () => methods
+ return {
+ methods,
+ setMethods,
+ delMethods,
+ getMethods
+ }
+}
diff --git a/packages/runtime-renderer/src/renderer/context/useRefs.ts b/packages/runtime-renderer/src/renderer/context/useRefs.ts
new file mode 100644
index 0000000000..86af6ebb7f
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/context/useRefs.ts
@@ -0,0 +1,10 @@
+import { shallowReactive } from 'vue'
+export function useRefs() {
+ const refsMap = shallowReactive>({})
+ return {
+ $: (refName: string) => refsMap[refName],
+ $ref: (refName: string, value: any) => {
+ refsMap[refName] = value
+ }
+ }
+}
diff --git a/packages/runtime-renderer/src/renderer/context/useState.ts b/packages/runtime-renderer/src/renderer/context/useState.ts
new file mode 100644
index 0000000000..efa2edc093
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/context/useState.ts
@@ -0,0 +1,37 @@
+import { reactive } from 'vue'
+import { getDeletedKeys } from '../data-function'
+import { useAccessorMap } from '../page-function/accessor'
+import { isStateAccessor, parseData } from '../data-function/index'
+
+export function useState(scope: any = {}, context: any = {}) {
+ // 改成使用 reactive, 处理state.xxx.xxx双向绑定
+ const state = reactive>({})
+ const { generateStateAccessors } = useAccessorMap(context)
+
+ const setState = (data: Record) => {
+ if (typeof data !== 'object' || data === null) {
+ return
+ }
+ // 同步删除的 key
+ const deletedKeys = getDeletedKeys(state, data)
+ deletedKeys?.forEach((key) => delete state[key])
+ Object.assign(state, parseData(data, scope, context) || {})
+ // 在状态变量合并之后,执行访问器中watchEffect,为了可以在访问器函数中可以访问其他state变量
+ Object.entries(data || {})?.forEach(([key, stateData]: [string, any]) => {
+ if (isStateAccessor(stateData)) {
+ const accessor = stateData.accessor
+ if (accessor?.getter?.value) {
+ generateStateAccessors('getter', accessor, key)
+ }
+
+ if (accessor?.setter?.value) {
+ generateStateAccessors('setter', accessor, key)
+ }
+ }
+ })
+ }
+ return {
+ state,
+ setState
+ }
+}
diff --git a/packages/runtime-renderer/src/renderer/context/useStore.ts b/packages/runtime-renderer/src/renderer/context/useStore.ts
new file mode 100644
index 0000000000..bbedfd78c6
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/context/useStore.ts
@@ -0,0 +1,8 @@
+import { getStore } from '../app-function'
+
+export function useStore() {
+ return {
+ stores: getStore()
+ }
+}
+export { getStore }
diff --git a/packages/runtime-renderer/src/renderer/context/useUtils.ts b/packages/runtime-renderer/src/renderer/context/useUtils.ts
new file mode 100644
index 0000000000..111c31b17a
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/context/useUtils.ts
@@ -0,0 +1,9 @@
+import { getUtilsAll } from '../app-function'
+
+export function useUtils() {
+ return {
+ utils: getUtilsAll()
+ }
+}
+
+export { getUtilsAll }
diff --git a/packages/runtime-renderer/src/renderer/parser/index.ts b/packages/runtime-renderer/src/renderer/data-function/index.ts
similarity index 51%
rename from packages/runtime-renderer/src/renderer/parser/index.ts
rename to packages/runtime-renderer/src/renderer/data-function/index.ts
index e9312eb336..c976eb70ba 100644
--- a/packages/runtime-renderer/src/renderer/parser/index.ts
+++ b/packages/runtime-renderer/src/renderer/data-function/index.ts
@@ -1 +1,2 @@
export * from './parser'
+export * from './utils'
diff --git a/packages/runtime-renderer/src/renderer/parser/parser.ts b/packages/runtime-renderer/src/renderer/data-function/parser.ts
similarity index 53%
rename from packages/runtime-renderer/src/renderer/parser/parser.ts
rename to packages/runtime-renderer/src/renderer/data-function/parser.ts
index c5126258d9..9755f710d0 100644
--- a/packages/runtime-renderer/src/renderer/parser/parser.ts
+++ b/packages/runtime-renderer/src/renderer/data-function/parser.ts
@@ -10,70 +10,69 @@
*
*/
+import * as vue from 'vue'
import babelPluginJSX from '@vue/babel-plugin-jsx'
import { transformSync } from '@babel/core'
import { Notify } from '@opentiny/vue'
-import i18nHost from '@opentiny/tiny-engine-i18n-host'
import { renderDefault } from '../render'
+import { getComponent, getIcon } from '../material-function'
+import i18nHost from '@opentiny/tiny-engine-common/js/i18n'
interface ITypeParserDef {
- type: (data) => boolean
+ type: (data: any) => boolean
parseFunc: (data: unknown, scope: Record, ctx: Record) => unknown
}
const parseList: Array = []
-const isI18nData = (data) => {
+const isI18nData = (data: { type: string }) => {
return data && data.type === 'i18n'
}
-const isJSSlot = (data) => {
+const isJSSlot = (data: { type: string }) => {
return data && data.type === 'JSSlot'
}
-const isJSExpression = (data) => {
+const isJSExpression = (data: { type: string }) => {
return data && data.type === 'JSExpression'
}
-const isJSFunction = (data) => {
+const isJSFunction = (data: { type: string }) => {
return data && data.type === 'JSFunction'
}
-const isJSResource = (data) => {
+const isJSResource = (data: { type: string }) => {
return data && data.type === 'JSResource'
}
-const isString = (data) => {
+const isString = (data: any) => {
return typeof data === 'string'
}
-const isArray = (data) => {
+const isArray = (data: any) => {
return Array.isArray(data)
}
-const isFunction = (data) => {
+const isFunction = (data: any) => {
return typeof data === 'function'
}
-const isIcon = (data) => {
+const isIcon = (data: { componentName: string }) => {
return data?.componentName === 'Icon'
}
-const isObject = (data) => {
+const isObject = (data: any) => {
return typeof data === 'object'
}
// 判断是否是状态访问器
-export const isStateAccessor = (stateData) =>
+export const isStateAccessor = (stateData: { accessor: { getter: { type: string }; setter: { type: string } } }) =>
stateData?.accessor?.getter?.type === 'JSFunction' || stateData?.accessor?.setter?.type === 'JSFunction'
// 规避创建function eslint报错
-export const newFn = (...argv) => {
- const Fn = Function
- return new Fn(...argv)
-}
+export const newFn = (...args: any) => new Function(...args)
-const transformJSX = (code) => {
+const transformJSX = (code: any) => {
const res = transformSync(code, {
plugins: [
[
@@ -84,7 +83,7 @@ const transformJSX = (code) => {
]
]
})
- return (res.code || '')
+ return (res?.code || '')
.replace(/import \{.+\} from "vue";/, '')
.replace(/h\(_?resolveComponent\((.*?)\)/g, `h(this.getComponent($1)`)
.replace(/_?resolveComponent/g, 'h')
@@ -92,7 +91,11 @@ const transformJSX = (code) => {
.trim()
}
-const parseExpression = (data, scope, ctx, isJsx = false) => {
+const curriedFn = (innerFn: any, params: any) => {
+ return (...args: any[]) => innerFn(...args, ...params)
+}
+
+const parseExpression = (data: any, scope: any, ctx: any, isJsx = false) => {
try {
if (data.value.indexOf('this.i18n') > -1) {
ctx.i18n = i18nHost.global.t
@@ -100,22 +103,27 @@ const parseExpression = (data, scope, ctx, isJsx = false) => {
ctx.t = i18nHost.global.t
}
+ const fnContext = { ...ctx, ...scope, slotScope: scope }
const expression = isJsx ? transformJSX(data.value) : data.value
- return newFn('$scope', `with($scope || {}) { return ${expression} }`).call(ctx, {
- ...ctx,
- ...scope,
- slotScope: scope
- })
+ const rs = newFn('$scope', `with($scope || {}) { return ${expression} }`).call(ctx, fnContext)
+ if (data.params && data.params.length) {
+ const params = data.params.map((param: string) => fnContext[param])
+ return curriedFn(rs, params)
+ } else {
+ return rs
+ }
} catch (err) {
// 解析抛出异常,则再尝试解析 JSX 语法。如果解析 JSX 语法仍然出现错误,isJsx 变量会确保不会再次递归执行解析
if (!isJsx) {
return parseExpression(data, scope, ctx, true)
}
+ // eslint-disable-next-line no-console
+ console.error('parseExpression error', data, scope)
return undefined
}
}
-const parseI18n = (i18n, scope, ctx) => {
+const parseI18n = (i18n: any, scope: any, ctx: any) => {
return parseExpression(
{
type: 'JSExpression',
@@ -127,7 +135,7 @@ const parseI18n = (i18n, scope, ctx) => {
}
// 解析函数字符串结构
-const parseFunctionString = (fnStr) => {
+const parseFunctionString = (fnStr: string) => {
const fnRegexp = /(async)?.*?(\w+) *\(([\s\S]*?)\) *\{([\s\S]*)\}/
const result = fnRegexp.exec(fnStr)
if (result) {
@@ -145,7 +153,7 @@ const parseFunctionString = (fnStr) => {
}
// 解析JSX字符串为可执行函数
-const parseJSXFunction = (data, _scope, ctx) => {
+const parseJSXFunction = (data: any, _scope: null, ctx: any) => {
try {
const newValue = transformJSX(data.value)
const fnInfo = parseFunctionString(newValue)
@@ -153,7 +161,7 @@ const parseJSXFunction = (data, _scope, ctx) => {
return newFn(...fnInfo.params, fnInfo.body).bind({
...ctx,
- getComponent: ctx.getComponent
+ getComponent
})
} catch (error) {
Notify({
@@ -166,91 +174,68 @@ const parseJSXFunction = (data, _scope, ctx) => {
}
}
-export const generateFn = (innerFn, context) => {
- return (...args) => {
+export const generateFn = (innerFn: any, context: any) => {
+ return (...args: any[]) => {
// 如果有数据源标识,则表格的fetchData返回数据源的静态数据
- const sourceId = context?.collectionMethodsMap?.[innerFn.realName || innerFn.name]
- if (sourceId) {
- return innerFn.call(context, ...args)
- } else {
- let result = null
-
- // 这里是为了兼容用户写法报错导致画布异常,但无法捕获promise内部的异常
- try {
- result = innerFn.call(context, ...args)
- } catch (error) {
- Notify({
- type: 'warning',
- title: `函数:${innerFn.name}执行报错`,
- message: error?.message || `函数:${innerFn.name}执行报错,请检查语法`
- })
- }
-
- // 这里注意如果innerFn返回的是一个promise则需要捕获异常,重新返回默认一条空数据
- if (result?.then) {
- result = new Promise((resolve) => {
- result.then(resolve).catch((error) => {
- Notify({
- type: 'warning',
- title: '异步函数执行报错',
- message: error?.message || '异步函数执行报错,请检查语法'
- })
- // 这里需要至少返回一条空数据,方便用户使用表格默认插槽
- resolve({
- result: [{}],
- page: { total: 1 }
- })
+ let result: any
+ // 这里是为了兼容用户写法报错导致画布异常,但无法捕获promise内部的异常
+ try {
+ result = innerFn.call(context, ...args)
+ } catch (error) {
+ Notify({
+ type: 'warning',
+ title: `函数:${innerFn.name}执行报错`,
+ message: error?.message || `函数:${innerFn.name}执行报错,请检查语法`
+ })
+ }
+ // 这里注意如果innerFn返回的是一个promise则需要捕获异常,重新返回默认一条空数据
+ if (result?.then && typeof result.then === 'function') {
+ result = new Promise((resolve) => {
+ result.then(resolve).catch((error: { message: any }) => {
+ Notify({
+ type: 'warning',
+ title: '异步函数执行报错',
+ message: error?.message || '异步函数执行报错,请检查语法'
+ })
+ // 这里需要至少返回一条空数据,方便用户使用表格默认插槽
+ resolve({
+ result: [{}],
+ page: { total: 1 }
})
})
- }
-
- return result
+ })
}
+ return result
}
}
-const parseJSFunction = (data, _scope, ctx) => {
+const parseJSFunction = (data: any, _scope: any, ctx: any) => {
try {
- const innerFn = newFn(`return ${data.value}`).bind(ctx)()
+ const innerFn = newFn('$vue', `with($vue || {}) { return ${data.value} }`).call(ctx, { vue })
return generateFn(innerFn, ctx)
} catch (error) {
return parseJSXFunction(data, null, ctx)
}
}
-const parseJSSlot = (data, _scope, _ctx) => {
- return ($scope) => renderDefault(data.value, { ..._scope, ...$scope }, data)
-}
-export function parseData(data, scope, ctx) {
- const typeParser = parseList.find((item) => item.type(data))
- return typeParser ? typeParser.parseFunc(data, scope, ctx) : data
-}
-
-export const parseCondition = (condition, scope, ctx) => {
- // eslint-disable-next-line no-eq-null
- return condition == null ? true : parseData(condition, scope, ctx)
+const parseJSSlot = (data: any, _scope: Record, _ctx: any) => {
+ return ($scope: Record) => renderDefault(data.value, { ..._scope, ...$scope }, data)
}
-export const parseLoopArgs = (loop?: { item: unknown; index: number; loopArgs?: string[] }) => {
- if (!loop) {
- return undefined
- }
- const { item, index, loopArgs = [] } = loop
- const body = `return {${loopArgs[0] || 'item'}: item, ${loopArgs[1] || 'index'} : index }`
- return newFn('item,index', body)(item, index)
+const parseIcon = (data: any, _scope: any, _ctx: any) => {
+ return getIcon(data.props.name)
}
-const getIcon = (name) => window.TinyVueIcon?.[name]?.() || ''
-
-const parseIcon = (data, _scope, _ctx) => {
- return getIcon(data.props.name)
+const parseData = (data: any, scope: any, ctx: any) => {
+ const typeParser = parseList.find((item) => item.type(data))
+ return typeParser ? typeParser.parseFunc(data, scope, ctx) : data
}
-const parseStateAccessor = (data, _scope, ctx) => {
+const parseStateAccessor = (data: any, _scope: any, ctx: any) => {
return parseData(data.defaultValue, null, ctx)
}
-const parseObjectData = (data, scope, ctx) => {
+const parseObjectData = (data: any, scope: any, ctx: any) => {
if (!data) {
return data
}
@@ -265,11 +250,14 @@ const parseObjectData = (data, scope, ctx) => {
return getIcon(data.props.name)
}
- const res = {}
+ const res: any = {}
Object.entries(data).forEach(([key, value]: [string, any]) => {
// 如果是插槽则需要进行特殊处理
if (key === 'slot' && value?.name) {
res[key] = value.name
+ // 特殊处理下ref
+ } else if (key === 'ref' && value) {
+ res[key] = (el: any) => ctx?.$ref(value, el)
} else {
res[key] = parseData(value, scope, ctx)
}
@@ -297,63 +285,77 @@ const parseObjectData = (data, scope, ctx) => {
return res
}
-const parseString = (data) => {
+const parseString = (data: any) => {
return data.trim()
}
-const parseArray = (data, scope, ctx) => {
- return data.map((item) => parseData(item, scope, ctx))
+const parseArray = (data: any, scope: any, ctx: any) => {
+ return data.map((item: any) => parseData(item, scope, ctx))
}
-const parseFunction = (data, scope, ctx) => {
+const parseFunction = (data: any, _scope: any, ctx: any) => {
return data.bind(ctx)
}
+const parseCondition = (condition: any, scope: any, ctx: any) => {
+ // eslint-disable-next-line no-eq-null
+ return condition == null ? true : parseData(condition, scope, ctx)
+}
+
+const parseLoopArgs = (loop?: { item: unknown; index: number; loopArgs?: string[] }) => {
+ if (!loop) {
+ return undefined
+ }
+ const { item, index, loopArgs = [] } = loop
+ const body = `return {${loopArgs[0] || 'item'}: item, ${loopArgs[1] || 'index'} : index }`
+ return newFn('item, index', body)(item, index)
+}
+
parseList.push(
- ...[
- {
- type: isJSExpression,
- parseFunc: parseExpression
- },
- {
- type: isI18nData,
- parseFunc: parseI18n
- },
- {
- type: isJSFunction,
- parseFunc: parseJSFunction
- },
- {
- type: isJSResource,
- parseFunc: parseExpression
- },
- {
- type: isJSSlot,
- parseFunc: parseJSSlot
- },
- {
- type: isIcon,
- parseFunc: parseIcon
- },
- {
- type: isStateAccessor,
- parseFunc: parseStateAccessor
- },
- {
- type: isString,
- parseFunc: parseString
- },
- {
- type: isArray,
- parseFunc: parseArray
- },
- {
- type: isFunction,
- parseFunc: parseFunction
- },
- {
- type: isObject,
- parseFunc: parseObjectData
- }
- ]
+ {
+ type: isJSExpression,
+ parseFunc: parseExpression
+ },
+ {
+ type: isI18nData,
+ parseFunc: parseI18n
+ },
+ {
+ type: isJSFunction,
+ parseFunc: parseJSFunction
+ },
+ {
+ type: isJSResource,
+ parseFunc: parseExpression
+ },
+ {
+ type: isJSSlot,
+ parseFunc: parseJSSlot
+ },
+ {
+ type: isIcon,
+ parseFunc: parseIcon
+ },
+ {
+ type: isStateAccessor,
+ parseFunc: parseStateAccessor
+ },
+ {
+ type: isString,
+ parseFunc: parseString
+ },
+ {
+ type: isArray,
+ parseFunc: parseArray
+ },
+ {
+ type: isFunction,
+ parseFunc: parseFunction
+ },
+ {
+ type: isObject,
+ parseFunc: parseObjectData
+ }
)
+
+export { parseData, parseCondition, parseLoopArgs }
diff --git a/packages/runtime-renderer/src/utils/data-utils.ts b/packages/runtime-renderer/src/renderer/data-function/utils.ts
similarity index 70%
rename from packages/runtime-renderer/src/utils/data-utils.ts
rename to packages/runtime-renderer/src/renderer/data-function/utils.ts
index fdccb2a6f3..aab106c735 100644
--- a/packages/runtime-renderer/src/utils/data-utils.ts
+++ b/packages/runtime-renderer/src/renderer/data-function/utils.ts
@@ -1,8 +1,7 @@
-const fun_ctor = Function
-
+import { newFn } from './parser'
export function generateFunction(rawCode: any, context = {}) {
try {
- return fun_ctor(`return (${rawCode})`).call(context).bind(context)
+ return newFn(`return (${rawCode})`).call(context).bind(context)
} catch (error) {
// eslint-disable-next-line no-console
console.error(`generateFunction error: ${JSON.stringify(error)}`)
@@ -13,16 +12,10 @@ export const reset = (obj) => {
Object.keys(obj).forEach((key) => delete obj[key])
}
-// 规避创建function eslint报错
-export const newFn = (...argv) => {
- const Fn = Function
- return new Fn(...argv)
-}
-
// 用于解析store中的actions和getters
export const parseJSFunction = (data: any, _scope: any = null, _ctx: any = null) => {
try {
- const fn = newFn(`return ${data.value}`).call(null) // 拿到函数本体,不绑定任何 this
+ const fn = newFn(`return ${data.value}`).call(_ctx, _scope) // 拿到函数本体,不绑定任何 this
return fn
} catch (error) {
// eslint-disable-next-line no-console
diff --git a/packages/runtime-renderer/src/renderer/material-function/blockComplier.ts b/packages/runtime-renderer/src/renderer/material-function/blockComplier.ts
new file mode 100644
index 0000000000..5fed97ed00
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/material-function/blockComplier.ts
@@ -0,0 +1,33 @@
+import { compile as blockCompiler } from '@opentiny/tiny-engine-block-compiler'
+import { genSFCWithDefaultPlugin } from '@opentiny/tiny-engine-dsl-vue'
+import { useAppSchema } from '../../composables/useAppSchema'
+const blockCompileCache = new Map()
+export const getBlockCompileResult = async (name: any) => {
+ if (blockCompileCache.has(name)) {
+ return {
+ [name]: blockCompileCache.get(name)
+ }
+ }
+
+ const list: any = await useAppSchema().fetchBlockByName(name)
+
+ const block = list?.histories?.find((item: any) => item.version === list?.version)
+
+ const realSchema = block.content || list?.content
+ if (!realSchema) {
+ return
+ }
+ const componentsMap = useAppSchema().appSchema.value?.componentsMap || []
+
+ // 需要出码的区块
+ const sourceCode = genSFCWithDefaultPlugin(realSchema, componentsMap || [], { blockRelativePath: './' })
+
+ const blocksSourceCode = {
+ fileName: realSchema.fileName,
+ sourceCode
+ }
+
+ const compiledResult = blockCompiler([blocksSourceCode], { compileCache: blockCompileCache })
+
+ return compiledResult
+}
diff --git a/packages/runtime-renderer/src/renderer/material-function/index.ts b/packages/runtime-renderer/src/renderer/material-function/index.ts
new file mode 100644
index 0000000000..c7cb98be17
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/material-function/index.ts
@@ -0,0 +1,2 @@
+export * from './material-getter'
+export * from './blockComplier'
diff --git a/packages/runtime-renderer/src/renderer/material-function/material-getter.ts b/packages/runtime-renderer/src/renderer/material-function/material-getter.ts
new file mode 100644
index 0000000000..189fca853a
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/material-function/material-getter.ts
@@ -0,0 +1,122 @@
+import { h, defineAsyncComponent, reactive, defineComponent } from 'vue'
+import { isHTMLTag } from '@vue/shared'
+import {
+ CanvasRow,
+ CanvasCol,
+ CanvasRowColContainer,
+ CanvasFlexBox,
+ CanvasSection,
+ CanvasNavigation,
+ FormModel,
+ TableModel,
+ PageModel
+} from '@opentiny/tiny-engine-builtin-component'
+import BlockLoadError from '../../components/BlockLoadError.vue'
+import {
+ CanvasBox,
+ CanvasText,
+ CanvasIcon,
+ CanvasSlot,
+ CanvasImg,
+ CanvasPlaceholder,
+ CanvasRouterLink,
+ CanvasRouterView
+} from '../builtin'
+import { getBlockCompileResult } from './blockComplier'
+import { addTagTask } from '../app-function/importMap'
+import config from '../../../config.ts'
+
+export const Mapper: any = {
+ Icon: CanvasIcon,
+ Text: CanvasText,
+ div: CanvasBox,
+ Slot: CanvasSlot,
+ slot: CanvasSlot,
+ Template: CanvasBox,
+ Img: CanvasImg,
+ CanvasSection,
+ CanvasFlexBox,
+ CanvasRow,
+ CanvasCol,
+ CanvasRowColContainer,
+ CanvasPlaceholder,
+ FormModel,
+ TableModel,
+ PageModel,
+ RouterView: CanvasRouterView,
+ RouterLink: CanvasRouterLink,
+ CanvasNavigation
+}
+const getNative = (name: string) => {
+ return window.TinyLowcodeComponent?.[name]
+}
+
+const getBlock = (name: string) => {
+ return window.blocks?.[name]
+}
+
+const blockComponentsBlobUrlMap = new Map()
+
+// TODO: 这里的全局 getter 方法名,可以做成配置化
+const loadBlockComponent = async (name: string) => {
+ try {
+ if (blockComponentsBlobUrlMap.has(name)) {
+ return import(/* @vite-ignore */ blockComponentsBlobUrlMap.get(name))
+ }
+
+ const blocksBlob = (await getBlockCompileResult(name)) as Array<{ blobURL: string; style: string }>
+
+ for (const [fileName, value] of Object.entries(blocksBlob)) {
+ blockComponentsBlobUrlMap.set(fileName, value.blobURL)
+
+ if (!value.style) {
+ continue
+ }
+
+ // 注册 JS,以区块为维度
+ addTagTask({
+ id: fileName,
+ tag: 'style',
+ textContent: value.style,
+ type: config.enableTailwindCSS ? 'text/tailwindcss' : 'text/css'
+ })
+ }
+
+ return import(/* @vite-ignore */ blockComponentsBlobUrlMap.get(name))
+ } catch (error) {
+ // 加载错误提示
+ return h(BlockLoadError, { name })
+ }
+}
+
+window.loadBlockComponent = loadBlockComponent
+
+export const getBlockComponent = (name: string) => {
+ return defineAsyncComponent(() => loadBlockComponent(name))
+}
+
+// 移除区块缓存
+export const removeBlockCompsCache = () => {
+ blockComponentsBlobUrlMap.forEach((_, fileName) => {
+ const stylesheet = document.querySelector(`#${fileName}`)
+ stylesheet?.remove?.()
+ })
+
+ blockComponentsBlobUrlMap.clear()
+}
+
+// 获取图标组件
+export const getIcon = (name: string) => {
+ return defineComponent({
+ name: 'Icon',
+ render() {
+ return h(CanvasIcon, { name, ...this.$props })
+ }
+ })
+}
+
+export const getComponent = (name: string) => {
+ return Mapper[name] || getNative(name) || getBlock(name) || (isHTMLTag(name) ? name : getBlockComponent(name))
+}
+
+export const blockSlotDataMap = reactive>({})
diff --git a/packages/runtime-renderer/src/renderer/page-function/accessor.ts b/packages/runtime-renderer/src/renderer/page-function/accessor.ts
index 2cb4ed3bae..ee1da1c92c 100644
--- a/packages/runtime-renderer/src/renderer/page-function/accessor.ts
+++ b/packages/runtime-renderer/src/renderer/page-function/accessor.ts
@@ -1,5 +1,5 @@
import { watchEffect, type WatchStopHandle } from 'vue'
-import { generateFunction } from '../../utils/data-utils'
+import { generateFunction } from '../data-function'
type IAccessorType = 'getter' | 'setter'
interface IAccessor {
diff --git a/packages/runtime-renderer/src/renderer/page-function/blockContext.ts b/packages/runtime-renderer/src/renderer/page-function/blockContext.ts
deleted file mode 100644
index a32cc0c399..0000000000
--- a/packages/runtime-renderer/src/renderer/page-function/blockContext.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-// @ts-nocheck
-/**
- * Copyright (c) 2023 - present TinyEngine Authors.
- * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
- *
- * Use of this source code is governed by an MIT-style license.
- *
- * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
- * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
- * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
- *
- */
-
-import { nextTick, inject } from 'vue'
-import { getCSSHandler } from './css.ts'
-import { parseData } from '../parser/parser.ts'
-import { useState } from './state.ts'
-import useContext from '../useContext.ts'
-import type { PageContent as Schema } from '../../types/schema.ts'
-import dataSourceMap from '../../app-function/dataSource.js'
-import { getUtilsAll } from '../../app-function/utils.ts'
-
-const invalidateCharRE = /[^a-z0-9-]/g
-
-export const getBlockCssScopeId = (fileName?: string) => {
- const normalized = String(fileName || 'unknown')
- .toLowerCase()
- .replace(invalidateCharRE, '-')
- .replace(/-+/g, '-')
- .replace(/^-|-$/g, '')
- return `data-te-page-block-${normalized || 'unknown'}`
-}
-
-// 创建 context 实例的工厂函数
-export const createBlockContext = () => {
- const contextApi = useContext() as any
- const { context, setContext, getContext } = contextApi
- const stores = inject('stores')
- const methods: Record = {}
- const { state, setState } = useState({ getContext })
-
- const setMethods = (data: Record = {}, clear?: boolean) => {
- if (clear) {
- Object.keys(methods).forEach((key) => delete methods[key])
- }
- Object.assign(
- methods,
- Object.fromEntries(
- Object.keys(data).map((key) => {
- return [key, parseData(data[key], {}, getContext())]
- })
- )
- )
- setContext(methods)
- }
-
- const setSchema = async (data: Schema) => {
- if (!data) return
-
- const newSchema = JSON.parse(JSON.stringify(data))
-
- const cssScopeId = getBlockCssScopeId(data.fileName)
- const contextData = {
- state,
- stores,
- dataSourceMap,
- utils: getUtilsAll(),
- cssScopeId,
- getCssScopeId: () => cssScopeId
- }
- setContext(contextData, true)
- setMethods(newSchema.methods, true)
- setState(newSchema.state, true)
- await nextTick()
-
- const cssHandler = getCSSHandler({ enableScoped: true })
- cssHandler.setPageCss(data.css || '', cssScopeId)
- return context
- }
-
- return {
- setSchema,
- getContext: () => context
- }
-}
-
-// 暂时不写成异步函数形式,方便后续调用
-export const getBlockContext = (schema: Schema): Record => {
- const blockContext = createBlockContext()
- blockContext.setSchema(schema)
- return blockContext.getContext()
-}
diff --git a/packages/runtime-renderer/src/renderer/page-function/css.ts b/packages/runtime-renderer/src/renderer/page-function/css.ts
index 51ff203452..a94ac6a288 100644
--- a/packages/runtime-renderer/src/renderer/page-function/css.ts
+++ b/packages/runtime-renderer/src/renderer/page-function/css.ts
@@ -12,141 +12,72 @@
import postcss from 'postcss'
import scopedPlugin from './scope-css-plugin'
-
-interface CSSHandlerOptions {
- pageId?: string
- enableScoped?: boolean
- enableModernCSS?: boolean
-}
-
-type AdoptedSheets = CSSStyleSheet[] | undefined
-
-const supportsAdoptedStyleSheet =
- typeof document !== 'undefined' && Array.isArray((document as any)?.adoptedStyleSheets)
-const styleSheetMap = new Map()
-const fallbackStyleMap = new Map()
-let enableScoped = true
-
-function normalizeScopeKey(pageId?: string): string {
- if (!pageId) {
- return 'data-te-page-default'
- }
- return pageId.startsWith('data-te-page-') ? pageId : `data-te-page-${pageId}`
-}
-
-function ensureAdoptedStyleSheet(key: string): CSSStyleSheet {
- let sheet = styleSheetMap.get(key)
- if (!sheet) {
- sheet = new CSSStyleSheet()
- styleSheetMap.set(key, sheet)
- const adoptedSheets = ((document as any).adoptedStyleSheets || []) as AdoptedSheets
- if (!adoptedSheets?.includes(sheet)) {
- ;(document as any).adoptedStyleSheets = [...(adoptedSheets || []), sheet]
- }
- }
- return sheet
+import config from '../../../config.ts'
+
+export function getBlockCssScopeId(fileName?: string): string {
+ const invalidateCharRE = /[^a-z0-9-]/g
+ const normalized = String(fileName || 'default')
+ .toLowerCase()
+ .replace(invalidateCharRE, '-')
+ .replace(/-+/g, '-')
+ .replace(/^-|-$/g, '')
+ return `data-render-block-${normalized}`
}
-function ensureFallbackStyleElement(key: string): HTMLStyleElement {
- let styleElement = fallbackStyleMap.get(key)
- if (!styleElement) {
- styleElement = document.createElement('style')
- styleElement.type = 'text/css'
- styleElement.setAttribute('data-te-page', key)
- document.head?.appendChild(styleElement)
- fallbackStyleMap.set(key, styleElement)
+export function normalizeScopeKey(pageId?: string, isBlock?: boolean): string {
+ const id = String(pageId)
+ if (!id) {
+ return 'data-render-page-default'
+ } else if (id.startsWith('data-render-')) {
+ return id
+ } else if (isBlock) {
+ return getBlockCssScopeId(id)
+ } else {
+ return `data-render-page-${id}`
}
- return styleElement
}
-function processScopedCss(key: string, css: string): Promise {
- if (!enableScoped) {
- return Promise.resolve(css)
- }
-
- return postcss([scopedPlugin(key)])
- .process(css, { from: undefined })
- .then((result) => result.css)
+export function handleScopedCss(id: string, content: string) {
+ const plugins = id ? [scopedPlugin(id)] : []
+ return postcss(plugins).process(content, { from: undefined })
}
-function applyCss(key: string, css: string): void {
- if (supportsAdoptedStyleSheet && typeof CSSStyleSheet !== 'undefined') {
- const sheet = ensureAdoptedStyleSheet(key)
- processScopedCss(key, css)
- .then((scopedCss) => {
- sheet.replaceSync(scopedCss)
- })
- .catch(() => {
- sheet.replaceSync(css)
- })
- return
- }
-
- const styleElement = ensureFallbackStyleElement(key)
- processScopedCss(key, css)
- .then((scopedCss) => {
- styleElement.textContent = scopedCss
- })
- .catch(() => {
- styleElement.textContent = css
- })
-}
+export function addStyle(key: string, content: string) {
+ if (!content) return
+ let styleSheet = document.querySelector(`#${key}`)
-function removePageCss(key: string): void {
- const sheet = styleSheetMap.get(key)
- if (sheet) {
- styleSheetMap.delete(key)
- const adoptedSheets = ((document as any).adoptedStyleSheets || []) as AdoptedSheets
- if (adoptedSheets?.length) {
- ;(document as any).adoptedStyleSheets = adoptedSheets.filter((item) => item !== sheet)
+ if (!styleSheet) {
+ styleSheet = document.createElement('style')
+ styleSheet.setAttribute('id', key)
+ if (config.enableTailwindCSS) {
+ styleSheet.setAttribute('type', 'text/tailwindcss')
}
+ document.head.appendChild(styleSheet)
}
-
- const styleElement = fallbackStyleMap.get(key)
- if (styleElement?.parentNode) {
- styleElement.parentNode.removeChild(styleElement)
- fallbackStyleMap.delete(key)
- }
+ const id = { [key]: key, 'app-global-css': '' }[key]
+ handleScopedCss(id, content).then((scopedCss) => {
+ styleSheet.textContent = scopedCss.css
+ })
}
-
-function clearAllStyles(): void {
- styleSheetMap.forEach((_, key) => removePageCss(key))
- fallbackStyleMap.forEach((_, key) => removePageCss(key))
-}
-
export function setPageCss(css: string = '', pageId?: string): void {
- const key = normalizeScopeKey(pageId)
-
- if (!css) {
- removePageCss(key)
- return
- }
- //console.log('setPageCss key', key, css)
-
- applyCss(key, css)
-}
-
-export function clearAllPageCSS(): void {
- clearAllStyles()
+ addStyle(normalizeScopeKey(pageId), css)
}
-export function getCSSHandler(options?: CSSHandlerOptions): {
- setPageCss: (css?: string, pageId?: string) => void
- clearAllStyles: () => void
- removePageCss: (key: string) => void
-} {
- if (options?.enableScoped !== undefined) {
- enableScoped = options.enableScoped
- }
-
- return {
- setPageCss,
- clearAllStyles,
- removePageCss: (key: string) => removePageCss(normalizeScopeKey(key))
+function clearPageCss(key: string): void {
+ const styleSheet = document.querySelector(`#${key}`)
+ if (styleSheet) {
+ styleSheet.remove()
}
}
+function clearAllPageCSS(): void {
+ const styleSheets = document.head.querySelectorAll('[id^="data-render-page-"]')
+ styleSheets?.forEach((styleSheet) => {
+ styleSheet.remove()
+ })
+}
export default {
setPageCss,
+ clearPageCss,
clearAllPageCSS
}
diff --git a/packages/runtime-renderer/src/renderer/page-function/index.ts b/packages/runtime-renderer/src/renderer/page-function/index.ts
index 07d4adb658..11ced47043 100644
--- a/packages/runtime-renderer/src/renderer/page-function/index.ts
+++ b/packages/runtime-renderer/src/renderer/page-function/index.ts
@@ -11,4 +11,4 @@
*/
export * from './css'
-export * from './state'
+export * from './lifecyle'
diff --git a/packages/runtime-renderer/src/renderer/page-function/lifecyle.ts b/packages/runtime-renderer/src/renderer/page-function/lifecyle.ts
new file mode 100644
index 0000000000..fef82910b8
--- /dev/null
+++ b/packages/runtime-renderer/src/renderer/page-function/lifecyle.ts
@@ -0,0 +1,94 @@
+import { Notify } from '@opentiny/vue'
+import { parseData } from '../data-function'
+import type { JSFunction } from '../../types/index.ts'
+import {
+ onBeforeMount,
+ onMounted,
+ onBeforeUpdate,
+ onUpdated,
+ onBeforeUnmount,
+ onUnmounted,
+ onErrorCaptured,
+ onActivated,
+ onDeactivated
+} from 'vue'
+
+const executeUserLifecycle = (hookName: string, lifeCycleConfig: JSFunction | undefined, context: any) => {
+ if (!lifeCycleConfig || lifeCycleConfig.type !== 'JSFunction') {
+ return
+ }
+
+ try {
+ const fn = parseData(lifeCycleConfig, {}, context)
+ if (typeof fn === 'function') {
+ fn.call(context, context)
+ }
+ } catch (error) {
+ Notify({
+ type: 'warning',
+ title: `${hookName} 生命周期执行失败`,
+ message: (error as any)?.message || `${hookName} 生命周期函数执行报错,请检查语法`
+ })
+ }
+}
+export function registerLifecycleHooks(lifeCycles: any, context: any) {
+ // 注册生命周期钩子
+ if (lifeCycles?.setup) {
+ executeUserLifecycle('setup', lifeCycles?.setup, context)
+ }
+
+ if (lifeCycles?.onBeforeMount) {
+ onBeforeMount(() => {
+ executeUserLifecycle('onBeforeMount', lifeCycles.onBeforeMount, context)
+ })
+ }
+
+ if (lifeCycles?.onMounted) {
+ onMounted(() => {
+ executeUserLifecycle('onMounted', lifeCycles.onMounted, context)
+ })
+ }
+
+ if (lifeCycles?.onBeforeUpdate) {
+ onBeforeUpdate(() => {
+ executeUserLifecycle('onBeforeUpdate', lifeCycles.onBeforeUpdate, context)
+ })
+ }
+
+ if (lifeCycles?.onUpdated) {
+ onUpdated(() => {
+ executeUserLifecycle('onUpdated', lifeCycles.onUpdated, context)
+ })
+ }
+
+ if (lifeCycles?.onBeforeUnmount) {
+ onBeforeUnmount(() => {
+ executeUserLifecycle('onBeforeUnmount', lifeCycles.onBeforeUnmount, context)
+ })
+ }
+
+ if (lifeCycles?.onUnmounted) {
+ onUnmounted(() => {
+ executeUserLifecycle('onUnmounted', lifeCycles.onUnmounted, context)
+ })
+ }
+
+ if (lifeCycles?.onErrorCaptured) {
+ onErrorCaptured((_error, _instance, _info) => {
+ executeUserLifecycle('onErrorCaptured', lifeCycles.onErrorCaptured, context)
+ return true
+ })
+ }
+
+ if (lifeCycles?.onActivated) {
+ onActivated(() => {
+ executeUserLifecycle('onActivated', lifeCycles.onActivated, context)
+ })
+ }
+
+ if (lifeCycles?.onDeactivated) {
+ onDeactivated(() => {
+ executeUserLifecycle('onDeactivated', lifeCycles.onDeactivated, context)
+ })
+ }
+}
diff --git a/packages/runtime-renderer/src/renderer/page-function/state.ts b/packages/runtime-renderer/src/renderer/page-function/state.ts
deleted file mode 100644
index 74d9736c2a..0000000000
--- a/packages/runtime-renderer/src/renderer/page-function/state.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import { reactive } from 'vue'
-import { getDeletedKeys } from '../../utils/data-utils'
-import { isStateAccessor, parseData } from '../parser'
-import { useAccessorMap } from './accessor'
-
-export function useState({ getContext }: { getContext: () => any }) {
- const state = reactive>({})
- const { generateStateAccessors } = useAccessorMap(getContext())
-
- const setState = (data: Record, clear?: boolean) => {
- if (typeof data !== 'object' || data === null) {
- return
- }
-
- if (clear) {
- Object.keys(state).forEach((key) => delete (state as any)[key])
- }
-
- // 智能删除处理:删除不再存在的状态键
- const deletedKeys = getDeletedKeys(state, data)
- for (const key of deletedKeys) {
- delete state[key]
- }
-
- Object.assign(state, parseData(data, {}, getContext()) || {})
-
- // 处理状态访问器
- Object.entries(data || {})?.forEach(([key, stateData]: [string, any]) => {
- if (isStateAccessor(stateData)) {
- const accessor = stateData.accessor
- if (accessor?.getter?.value) {
- generateStateAccessors('getter', accessor, key)
- }
-
- if (accessor?.setter?.value) {
- generateStateAccessors('setter', accessor, key)
- }
- }
- })
- }
-
- return {
- state,
- setState
- }
-}
diff --git a/packages/runtime-renderer/src/renderer/render.ts b/packages/runtime-renderer/src/renderer/render.ts
index 60abcf705f..7d7c6ba98c 100644
--- a/packages/runtime-renderer/src/renderer/render.ts
+++ b/packages/runtime-renderer/src/renderer/render.ts
@@ -10,204 +10,33 @@
*
*/
-import {
- h,
- provide,
- inject,
- defineComponent,
- onBeforeMount,
- onMounted,
- onBeforeUpdate,
- onUpdated,
- onBeforeUnmount,
- onUnmounted,
- onErrorCaptured,
- onActivated,
- onDeactivated
-} from 'vue'
-import { Notify } from '@opentiny/vue'
-import { isHTMLTag, hyphenate } from '@vue/shared'
-import TinyVue from '@opentiny/vue'
-import { getBlockContext, getBlockCssScopeId } from './page-function/blockContext'
-import {
- CanvasRow,
- CanvasCol,
- CanvasRowColContainer,
- CanvasFlexBox,
- CanvasSection
-} from '@opentiny/tiny-engine-builtin-component'
-import {
- CanvasIcon,
- CanvasText,
- CanvasSlot,
- CanvasImg,
- CanvasPlaceholder,
- CanvasRouterLink,
- CanvasRouterView,
- CanvasCollection
-} from './builtin'
-import { parseData, parseCondition, parseLoopArgs } from './parser'
-
-const hyphenateRE = /\B([A-Z])/g
-// 用于后续对Web component的扩展支持,目前暂未实际使用
-const customElements = {}
-
-const Mapper = {
- Icon: CanvasIcon,
- Text: CanvasText,
- Slot: CanvasSlot,
- slot: CanvasSlot,
- Img: CanvasImg,
- CanvasRow,
- CanvasCol,
- CanvasRowColContainer,
- CanvasFlexBox,
- CanvasSection,
- CanvasPlaceholder,
- RouterLink: CanvasRouterLink,
- RouterView: CanvasRouterView,
- Collection: CanvasCollection
-}
-
-export const collectionMethodsMap = {}
-
-const getNative = (name) => {
- return TinyVue?.[name] || window.TinyLowcodeComponent?.[name]
-}
-
-const getBlock = (name) => {
- return window.blocks?.[name]
-}
-
-let pageScopeId = ''
-
-const setPageScopeId = (scopeId: string) => {
- pageScopeId = scopeId
-}
-
-const getPageScopeId = () => {
- return pageScopeId
-}
-
-export const getComponent = (name) => {
- // 首先尝试从映射表、原生组件、自定义元素中获取
- const component = Mapper[name] || getNative(name) || customElements[name]
- if (component) {
- return component
- }
-
- if (name === 'Template') {
- return 'div'
- }
-
- // 如果是 HTML 标签,直接返回
- if (isHTMLTag(name)) {
- return name
- }
-
- // 检查是否是区块组件
- const blockSchema = getBlock(name)
- if (blockSchema) {
- // 返回一个动态组件,用于渲染区块
- return defineComponent({
- name: `${name}`,
- setup() {
- // 区块的真实内容在 window.blocks 中,而不是页面的 schema 中
- // 页面的 schema 只是区块的引用,children 为空
- const blockContent = blockSchema.schema
-
- const context = getBlockContext(blockContent)
-
- return {
- context
- }
- },
- render() {
- // 递归渲染区块的 children
- const blockContent = blockSchema.schema
- const context = this.context
- const cssScopeId = getBlockCssScopeId(blockSchema.schema.fileName)
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
- const children = renderGroup(blockContent.children || [], { cssScopeId }, context, renderComponent)
- const pageScopeId = getPageScopeId()
-
- return h(
- 'div',
- {
- [pageScopeId]: ''
- },
- h('div', { [cssScopeId]: '', ...blockContent.props }, children)
- )
- }
+import { defineComponent, h, inject, provide, Suspense } from 'vue'
+import { registerLifecycleHooks } from './page-function/index.ts'
+import { NODE_TAG, NODE_LOOP, NODE_UID } from './app-function/constant.ts'
+import { parseCondition, parseData, parseLoopArgs } from './data-function/index.ts'
+import { blockSlotDataMap, getComponent, Mapper } from './material-function/index.ts'
+import Loading from '../components/Loading.vue'
+import BlockLoading from '../components/BlockLoading.vue'
+import type { Node } from '../types/index.ts'
+
+export const renderDefault = (children: Node[], scope: Record, parent: Node) =>
+ children.map?.((child) =>
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
+ h(renderer, {
+ schema: child,
+ scope,
+ parent
})
- }
-
- return CanvasPlaceholder
-}
+ )
-const configure = {}
-
-export const setConfigure = (configureData) => {
- Object.assign(configure, configureData)
-}
-
-const _getPlainProps = (object = {}) => {
- const { slot, ...rest } = object
- const props = {}
-
- if (slot) {
- rest.slot = slot.name || slot
- }
-
- Object.entries(rest).forEach(([key, value]) => {
- let renderKey = key
-
- // html 标签属性会忽略大小写,所以传递包含大写的 props 需要转换为 kebab 形式的 props
- if (!/on[A-Z]/.test(renderKey) && hyphenateRE.test(renderKey)) {
- renderKey = hyphenate(renderKey)
- }
-
- if (['boolean', 'string', 'number'].includes(typeof value)) {
- props[renderKey] = value
- } else {
- // 如果传给webcomponent标签的是对象或者数组需要使用.prop修饰符,转化成h函数就是如下写法
- props[`.${renderKey}`] = value
- }
- })
- return props
-}
-
-const generateCollection = (schema) => {
- if (schema.componentName === 'Collection' && schema.props?.dataSource && schema.children) {
- schema.children.forEach((item) => {
- const fetchData = item.props?.fetchData
- const methodMatch = fetchData?.value?.match(/this\.(.+?)}/)
- if (fetchData && methodMatch?.[1]) {
- const methodName = methodMatch[1].trim()
- // 缓存表格fetchData对应的数据源信息
- collectionMethodsMap[methodName] = schema.props.dataSource
- }
- })
- }
-}
-
-export const renderDefault = (
- children: any[],
- scope: Record,
- parent: any,
- renderComponent: (schema: any, scope: Record, parent: any) => any
-) => children.map?.((child) => renderComponent(child, scope, parent))
-const generateSlotGroup = (children, isCustomElm, schema) => {
- const slotGroup = {}
+const generateSlotGroup = (children: Node[], schema: Node) => {
+ const slotGroup: Record = {}
children.forEach((child) => {
const { componentName, children, params = [], props } = child
const slot = child.slot || props?.slot?.name || props?.slot || 'default'
- const isNotEmptyTemplate = componentName === 'Template' && children.length
+ const isNotEmptyTemplate = componentName === 'Template' && children?.length
- if (isCustomElm) {
- child.props.slot = 'slot' // CE下需要给子节点加上slot标识
- }
slotGroup[slot] = slotGroup[slot] || {
value: [],
params,
@@ -220,50 +49,53 @@ const generateSlotGroup = (children, isCustomElm, schema) => {
return slotGroup
}
-const renderSlot = (children, scope, schema, isCustomElm, context, renderComponent) => {
- if (children.some((a) => a.componentName === 'Template')) {
- const slotGroup = generateSlotGroup(children, isCustomElm, schema)
- const slots = {}
-
- Object.keys(slotGroup).forEach((slotName) => {
- const currentSlot = slotGroup[slotName]
-
- slots[slotName] = ($scope) => renderDefault(currentSlot.value, { ...scope, ...$scope }, context, renderComponent)
- })
+const directChildrenHasTemplate = (children: Node[]) => children.some((child) => child.componentName === 'Template')
- return slots
- }
+const renderSlot = (
+ children: Node[],
+ scope: Record,
+ schema: Node,
+ pageContext: Record,
+ renderComponent: (schema: Node, scope: Record, pageContext: Record, parent: Node) => any
+) => {
+ const slotGroup = generateSlotGroup(children, schema)
+ const slots: Record = {}
+ Object.keys(slotGroup).forEach((slotName) => {
+ const currentSlot = slotGroup[slotName]
+ slots[slotName] = ($scope: Record) =>
+ currentSlot.value.map((slotItem: Node) =>
+ renderComponent(slotItem, { ...scope, ...$scope }, pageContext, currentSlot.parent)
+ )
+ })
- return { default: () => renderDefault(children, scope, context, renderComponent) }
+ return slots
}
-const _checkGroup = (componentName) => configure[componentName]?.nestingRule?.childWhitelist?.length
-
-const directChildrenHasTemplate = (children) => children.some((child) => child.componentName === 'Template')
-
-const getBindProps = (schema, scope, context) => {
- const { componentName, componentType } = schema
+const getBindProps = (
+ schema: Node,
+ scope: Record,
+ context: Record,
+ pageContext: Record
+) => {
+ const { id, componentName, componentType } = schema
if (componentName === 'CanvasPlaceholder') {
return {}
}
-
+ const { active, getCssScopeId } = pageContext || {}
+ const cssScopeId = getCssScopeId?.()
const bindProps = {
- ...parseData(schema.props, scope, context)
+ ...parseData(schema.props, scope, context),
+ ...(cssScopeId ? { [cssScopeId]: '' } : {}),
+ ...{ [NODE_UID]: id },
+ [NODE_TAG]: componentName
}
- const cssScopeId = scope?.cssScopeId || context?.cssScopeId || context?.getCssScopeId?.()
- if (cssScopeId && componentType !== 'Block') {
- bindProps[cssScopeId] = ''
+ if (scope) {
+ bindProps[NODE_LOOP] = scope.index === undefined ? scope.idx : scope.index
}
- if (Mapper[componentName]) {
- bindProps.schema = schema
- }
-
- // 如果是区块组件,传递完整的 schema
- const blockSchema = getBlock(componentName)
- if (blockSchema) {
+ if (Mapper[componentName as keyof typeof Mapper]) {
bindProps.schema = schema
}
@@ -271,10 +103,25 @@ const getBindProps = (schema, scope, context) => {
bindProps.class = bindProps.className
delete bindProps.className
+ // 使画布中元素可拖拽
+ if (active && !['PageStart', 'PageSection'].includes(componentType || '')) {
+ bindProps.draggable = true
+ }
+
return bindProps
}
-const getLoopScope = ({ scope, index, item, loopArgs }) => {
+const getLoopScope = ({
+ scope,
+ index,
+ item,
+ loopArgs
+}: {
+ scope: Record
+ index: number
+ item: any
+ loopArgs: any
+}) => {
return {
...scope,
...(parseLoopArgs({
@@ -285,132 +132,88 @@ const getLoopScope = ({ scope, index, item, loopArgs }) => {
}
}
-const injectPlaceHolder = (componentName, children) => {
- const isEmptyArr = Array.isArray(children) && !children.length
+const getChildren = (
+ schema: Node,
+ mergeScope: Record,
+ pageContext: Record,
+ parent: Node,
+ renderComponent: (schema: Node, scope: Record, pageContext: Record, parent: Node) => any
+) => {
+ const { children = [] } = schema
+ const renderChildren = children as Node[]
- if (configure[componentName]?.isContainer && (!children || isEmptyArr)) {
- return [
- {
- componentName: 'CanvasPlaceholder'
- }
- ]
- }
-
- return children
-}
-
-const renderGroup = (children, scope, context, renderComponent) => {
- return children.map?.((schema) => {
- const { componentName, children, loop, loopArgs, condition } = schema
- const loopList = parseData(loop, scope, context)
-
- const renderElement = (item, index) => {
- const mergeScope = getLoopScope({
- scope,
- index,
- item,
- loopArgs
- })
-
- if (!parseCondition(condition, mergeScope, context)) {
- return null
- }
-
- const renderChildren = injectPlaceHolder(componentName, children)
-
- const element = h(
- getComponent(componentName),
- getBindProps(schema, mergeScope, context),
- Array.isArray(renderChildren)
- ? renderSlot(renderChildren, mergeScope, schema, customElements[componentName], context, renderComponent)
- : parseData(renderChildren, mergeScope, context)
- )
-
- return element
+ if (Array.isArray(renderChildren)) {
+ // children 空的场景,不能返回空数组,因为有部分组件会误以为使用了自定义插槽,从而无法渲染默认插槽内容,比如 TinyTree 组件
+ if (!renderChildren.length) {
+ return null
}
- return loopList?.length ? loopList.map(renderElement) : renderElement(undefined, 0)
- })
-}
-const getChildren = (schema, mergeScope, context, renderComponent) => {
- const { componentName, children } = schema
- const renderChildren = injectPlaceHolder(componentName, children)
-
- if (!Array.isArray(renderChildren)) {
- return parseData(renderChildren, mergeScope, context)
- }
-
- if (!renderChildren.length) {
- return null
- }
-
- const isCustomElm = customElements[componentName]
+ if (directChildrenHasTemplate(renderChildren)) {
+ return renderSlot(renderChildren, mergeScope, schema, pageContext, renderComponent)
+ }
- if (directChildrenHasTemplate(renderChildren)) {
- return renderSlot(renderChildren, mergeScope, schema, isCustomElm, context, renderComponent)
+ // 这里 children 需要返回一个默认插槽的函数,避免 vue 告警:
+ // Non-function value encountered for default slot. Prefer function slots for better performance.
+ return {
+ default: () => renderChildren.map((child) => renderComponent(child, mergeScope, pageContext, parent))
+ }
}
- return renderGroup(renderChildren, mergeScope, context, renderComponent)
+ return parseData(renderChildren, mergeScope, pageContext)
}
-function renderComponent(schema, scope, parent) {
- const { componentName, loop, loopArgs, condition } = schema
-
- // 处理数据源和表格fetchData的映射关系
- generateCollection(schema)
+const renderComponent = (schema: Node, scope: Record, pageContext: Record, parent: Node) => {
+ const { componentName, loop, loopArgs, condition } = schema as any
if (!componentName) {
- return parseData(schema, scope, parent)
+ return parseData(schema, scope, pageContext)
}
- const component = getComponent(componentName)
+ const loopList = loop ? parseData(loop, scope, pageContext) : []
- const loopList = parseData(loop, scope, parent)
-
- const renderElement = (item, index) => {
- const mergeScope = item
+ const renderElement = (item?: Node, index: number = 0) => {
+ let mergeScope = item
? getLoopScope({
- item,
+ scope,
index,
- loopArgs,
- scope
+ item,
+ loopArgs
})
: scope
- if (!parseCondition(condition, mergeScope, parent)) {
+ if (!parseCondition(condition, mergeScope, pageContext)) {
return null
}
+ // 如果是区块,并且使用了区块的作用域插槽,则需要将作用域插槽的数据传递下去
+ if (parent?.componentType === 'Block' && componentName === 'Template' && schema.props?.slot?.params?.length) {
+ const slotName = schema.props.slot?.name || schema.props.slot
+ const blockName = parent.componentName
+ const slotData = blockSlotDataMap[blockName]?.[slotName] || {}
+ mergeScope = mergeScope ? { ...mergeScope, ...slotData } : slotData
+ }
const Ele = h(
- component,
- getBindProps(schema, mergeScope, parent),
- getChildren(schema, mergeScope, parent, renderComponent)
+ getComponent(componentName),
+ getBindProps(schema, mergeScope, pageContext, pageContext),
+ getChildren(schema, mergeScope, pageContext, parent, renderComponent)
)
+ // 区块加上 suspense 渲染,就可以在网络延时的时候显示加载中的字样或者动画,优化体验
+ if (schema.componentType === 'Block') {
+ return h(
+ Suspense,
+ {},
+ {
+ default: () => Ele,
+ fallback: () => h(BlockLoading, { name: componentName })
+ }
+ )
+ }
+
return Ele
}
- return loopList?.length ? loopList.map(renderElement) : renderElement(undefined, 0)
-}
-
-// 执行用户定义的生命周期函数
-const executeUserLifecycle = (hookName: string, lifeCycleConfig: JSFunction | undefined, context: any) => {
- if (!lifeCycleConfig || lifeCycleConfig.type !== 'JSFunction') {
- return
- }
-
- try {
- const fn = parseData(lifeCycleConfig, {}, context)
- if (typeof fn === 'function') {
- fn.call(context, context)
- }
- } catch (error) {
- Notify({
- type: 'warning',
- title: `${hookName} 生命周期执行失败`,
- message: (error as any)?.message || `${hookName} 生命周期函数执行报错,请检查语法`
- })
- }
+ return loopList?.length ? loopList.map(renderElement) : renderElement()
}
export const renderer = defineComponent({
@@ -422,90 +225,23 @@ export const renderer = defineComponent({
},
setup(props) {
provide('schema', props.schema)
-
- const context = inject('pageContext')
+ const pageContext = inject('pageContext') || {}
const lifeCycles = props.parent?.lifeCycles
- const pageScopeId = context?.cssScopeId || context?.getCssScopeId?.()
- setPageScopeId(pageScopeId)
-
- // 注入生命周期钩子
- if (lifeCycles?.setup) {
- executeUserLifecycle('setup', lifeCycles?.setup, context)
- }
-
- if (lifeCycles?.onBeforeMount) {
- onBeforeMount(() => {
- executeUserLifecycle('onBeforeMount', lifeCycles.onBeforeMount, context)
- })
- }
-
- if (lifeCycles?.onMounted) {
- onMounted(() => {
- executeUserLifecycle('onMounted', lifeCycles.onMounted, context)
- })
- }
-
- if (lifeCycles?.onBeforeUpdate) {
- onBeforeUpdate(() => {
- executeUserLifecycle('onBeforeUpdate', lifeCycles.onBeforeUpdate, context)
- })
- }
-
- if (lifeCycles?.onUpdated) {
- onUpdated(() => {
- executeUserLifecycle('onUpdated', lifeCycles.onUpdated, context)
- })
- }
-
- if (lifeCycles?.onBeforeUnmount) {
- onBeforeUnmount(() => {
- executeUserLifecycle('onBeforeUnmount', lifeCycles.onBeforeUnmount, context)
- })
- }
-
- if (lifeCycles?.onUnmounted) {
- onUnmounted(() => {
- executeUserLifecycle('onUnmounted', lifeCycles.onUnmounted, context)
- })
- }
-
- if (lifeCycles?.onErrorCaptured) {
- onErrorCaptured((error, instance, info) => {
- try {
- const fn = parseData(lifeCycles.onErrorCaptured, {}, context)
- if (typeof fn === 'function') {
- const result = fn.call(context, error, instance, info)
- return result === false
- }
- } catch (userError) {
- Notify({
- type: 'warning',
- title: 'onErrorCaptured 生命周期执行失败',
- message: (userError as any)?.message || 'onErrorCaptured 生命周期函数执行报错,请检查语法'
- })
- }
- return true
- })
- }
-
- if (lifeCycles?.onActivated) {
- onActivated(() => {
- executeUserLifecycle('onActivated', lifeCycles.onActivated, context)
- })
- }
-
- if (lifeCycles?.onDeactivated) {
- onDeactivated(() => {
- executeUserLifecycle('onDeactivated', lifeCycles.onDeactivated, context)
- })
- }
+ registerLifecycleHooks(lifeCycles, pageContext)
+ return { pageContext }
},
render() {
- const context = inject('pageContext')
- const { scope, schema } = this
-
- return renderComponent(schema, scope, context, renderComponent)
+ const { scope = {}, schema, parent, pageContext } = this
+ return renderComponent(schema as Node, scope, pageContext, parent as Node)
}
})
-export default renderer
+export function defaultRenderer(schema: Node) {
+ const PageStartSchema = {
+ componentName: 'div',
+ componentType: 'PageStart',
+ props: { 'data-id': 'page-root-container', ...(schema.props || {}) },
+ children: schema.children
+ }
+ return schema.children?.length ? h(renderer, { schema: PageStartSchema, parent: schema }) : [h(Loading)]
+}
diff --git a/packages/runtime-renderer/src/renderer/useContext.ts b/packages/runtime-renderer/src/renderer/useContext.ts
deleted file mode 100644
index 1db4ece666..0000000000
--- a/packages/runtime-renderer/src/renderer/useContext.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * Copyright (c) 2023 - present TinyEngine Authors.
- * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
- *
- * Use of this source code is governed by an MIT-style license.
- *
- * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
- * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
- * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
- *
- */
-
-import { shallowReactive, type ShallowReactive } from 'vue'
-
-interface Context {
- [key: string]: any
-}
-
-interface UseContextReturn {
- context: ShallowReactive
- setContext: (ctx: Context, clear?: boolean) => void
- getContext: () => ShallowReactive
-}
-
-export default (): UseContextReturn => {
- const context = shallowReactive({})
-
- const setContext = (ctx: Context, clear?: boolean) => {
- if (clear) {
- Object.keys(context).forEach((key) => delete context[key])
- }
- Object.assign(context, ctx)
- }
-
- const getContext = () => context
-
- return {
- context,
- setContext,
- getContext
- }
-}
diff --git a/packages/runtime-renderer/src/types/index.ts b/packages/runtime-renderer/src/types/index.ts
new file mode 100644
index 0000000000..1e21747f0e
--- /dev/null
+++ b/packages/runtime-renderer/src/types/index.ts
@@ -0,0 +1,31 @@
+export * from './schema'
+export * from './config'
+export interface Node {
+ id: string
+ componentName: string
+ props: Record & { columns?: { slots?: Record }[] }
+ children?: Node[]
+ componentType?: 'Block' | 'PageStart' | 'PageSection'
+ slot?: string | Record
+ params?: string[]
+ loop?: Record
+ loopArgs?: string[]
+ condition?: boolean | Record
+ lifeCycles?: Record
+}
+
+export type RootNode = Omit & {
+ id?: string
+ css?: string
+ fileName?: string
+ methods?: Record
+ state?: Record
+ lifeCycles?: Record
+ dataSource?: any
+ bridge?: any
+ inputs?: any[]
+ outputs?: any[]
+ schema?: any
+}
+
+export type IFuntion = (...args: any[]) => any
diff --git a/packages/runtime-renderer/src/types/schema.ts b/packages/runtime-renderer/src/types/schema.ts
index 2a959ee210..6bdd03724d 100644
--- a/packages/runtime-renderer/src/types/schema.ts
+++ b/packages/runtime-renderer/src/types/schema.ts
@@ -1,5 +1,6 @@
// 应用级Schema类型定义
export interface IAppSchema {
+ id: string
pages: any[]
bridge: any[]
componentsMap: ComponentMap[]
@@ -13,6 +14,7 @@ export interface IAppSchema {
constants: string
i18n: I18nConfig
version: string
+ blocks: Record
}
// 组件映射表
@@ -280,6 +282,16 @@ export interface BlockItem {
current_version?: any
}
+export interface IBlockItem {
+ schema: BlockContent
+ meta: {
+ id: number
+ label: string
+ framework: string
+ version: string
+ }
+}
+
// 区块内容
export interface BlockContent {
componentName: string
diff --git a/packages/runtime-renderer/types.d.ts b/packages/runtime-renderer/types.d.ts
index 0aea3f3335..9176ea9467 100644
--- a/packages/runtime-renderer/types.d.ts
+++ b/packages/runtime-renderer/types.d.ts
@@ -5,3 +5,9 @@ export declare global {
blocks: Record
}
}
+export declare module '@opentiny/tiny-engine-dsl-vue' {
+ // 先声明原有导出(避免覆盖库的默认类型)
+ export type * from '@opentiny/tiny-engine-dsl-vue'
+ // 补充 genSFCWithDefaultPlugin 的声明(根据实际参数/返回值调整类型)
+ export function genSFCWithDefaultPlugin(schema?: any, componentsMap?: any, config = {}, nextPage?: any): any
+}
diff --git a/packages/runtime-renderer/vite.config.ts b/packages/runtime-renderer/vite.config.ts
index 78d3ed9ac2..1ac209c227 100644
--- a/packages/runtime-renderer/vite.config.ts
+++ b/packages/runtime-renderer/vite.config.ts
@@ -5,20 +5,23 @@ import { resolve } from 'path'
export default defineConfig({
plugins: [vue()],
build: {
+ assetsDir: '',
outDir: 'dist',
lib: {
- entry: resolve(__dirname, 'index.ts'),
- name: 'TinyEngineRuntimeRenderer',
- fileName: 'index'
+ entry: {
+ index: resolve(__dirname, 'index.ts')
+ },
+ formats: ['es'],
+ name: 'runtime-renderer',
+ fileName: (_, entryName) => `${entryName}.js`
},
rollupOptions: {
- external: ['vue', '@vueuse/core', 'vue-i18n', /@opentiny\/tiny-engine.*/, /@opentiny\/vue.*/],
output: {
- globals: {
- vue: 'Vue',
- '@opentiny/vue': 'TinyVue'
+ banner: (chunk) => {
+ return ['index'].includes(chunk.name) && chunk.isEntry ? `import "./style.css"` : ''
}
- }
+ },
+ external: ['vue', '@vueuse/core', 'vue-i18n', /@opentiny\/tiny-engine.*/, /@opentiny\/vue.*/]
}
}
})
diff --git a/packages/settings/design/package.json b/packages/settings/design/package.json
index e270c0145c..ce4bdded1f 100644
--- a/packages/settings/design/package.json
+++ b/packages/settings/design/package.json
@@ -1,6 +1,6 @@
{
"name": "@opentiny/tiny-engine-setting-design",
- "version": "2.7.0",
+ "version": "2.9.0",
"publishConfig": {
"access": "public"
},
diff --git a/packages/settings/design/src/components/PropertyCanvas.vue b/packages/settings/design/src/components/PropertyCanvas.vue
index 6c4e509ff8..090fc1dac1 100644
--- a/packages/settings/design/src/components/PropertyCanvas.vue
+++ b/packages/settings/design/src/components/PropertyCanvas.vue
@@ -42,8 +42,9 @@
-
+
diff --git a/packages/toolbars/preview/vite.config.ts b/packages/toolbars/preview/vite.config.ts
index 165d011bfc..1fb6b9558b 100644
--- a/packages/toolbars/preview/vite.config.ts
+++ b/packages/toolbars/preview/vite.config.ts
@@ -30,6 +30,9 @@ export default defineConfig({
formats: ['es']
},
rollupOptions: {
+ output: {
+ banner: 'import "./style.css"'
+ },
external: ['vue', /@opentiny\/tiny-engine.*/, /@opentiny\/vue.*/]
}
}
diff --git a/packages/toolbars/redoundo/package.json b/packages/toolbars/redoundo/package.json
index b7aa73316c..b566e81251 100644
--- a/packages/toolbars/redoundo/package.json
+++ b/packages/toolbars/redoundo/package.json
@@ -1,6 +1,6 @@
{
"name": "@opentiny/tiny-engine-toolbar-redoundo",
- "version": "2.7.0",
+ "version": "2.9.0",
"publishConfig": {
"access": "public"
},
diff --git a/packages/toolbars/redoundo/src/Main.vue b/packages/toolbars/redoundo/src/Main.vue
index 4de96db6d8..91dd7a8b03 100644
--- a/packages/toolbars/redoundo/src/Main.vue
+++ b/packages/toolbars/redoundo/src/Main.vue
@@ -38,10 +38,11 @@
import { Popover } from '@opentiny/vue'
import { useHistory } from '@opentiny/tiny-engine-meta-register'
import { ToolbarBase } from '@opentiny/tiny-engine-common'
+import type { Component } from 'vue'
export default {
components: {
- TinyPopover: Popover,
+ TinyPopover: Popover as Component,
ToolbarBase
},
props: {
diff --git a/packages/toolbars/refresh/package.json b/packages/toolbars/refresh/package.json
index febabd2873..3a21338023 100644
--- a/packages/toolbars/refresh/package.json
+++ b/packages/toolbars/refresh/package.json
@@ -1,6 +1,6 @@
{
"name": "@opentiny/tiny-engine-toolbar-refresh",
- "version": "2.7.0",
+ "version": "2.9.0",
"publishConfig": {
"access": "public"
},
diff --git a/packages/toolbars/save/package.json b/packages/toolbars/save/package.json
index a96601a505..d3484e45b6 100644
--- a/packages/toolbars/save/package.json
+++ b/packages/toolbars/save/package.json
@@ -1,6 +1,6 @@
{
"name": "@opentiny/tiny-engine-toolbar-save",
- "version": "2.7.0",
+ "version": "2.9.0",
"publishConfig": {
"access": "public"
},
@@ -37,6 +37,7 @@
},
"peerDependencies": {
"@opentiny/vue": "^3.20.0",
+ "@opentiny/vue-icon": "^3.20.0",
"vue": "^3.4.15"
}
}
diff --git a/packages/toolbars/save/src/Main.vue b/packages/toolbars/save/src/Main.vue
index 69bf8eabca..c3a16c6bc5 100644
--- a/packages/toolbars/save/src/Main.vue
+++ b/packages/toolbars/save/src/Main.vue
@@ -7,9 +7,18 @@
@click-api="openApi"
>
-
+
-
+
+
+
+
保存设置
@@ -57,8 +66,10 @@
diff --git a/packages/vue-generator/src/templates/vue-template/templateFiles/src/http/axios.js b/packages/vue-generator/src/templates/vue-template/templateFiles/src/http/axios.js
index 3654c619b4..a75411169d 100644
--- a/packages/vue-generator/src/templates/vue-template/templateFiles/src/http/axios.js
+++ b/packages/vue-generator/src/templates/vue-template/templateFiles/src/http/axios.js
@@ -11,49 +11,10 @@
*/
import axios from 'axios'
-import MockAdapter from 'axios-mock-adapter'
export default (config) => {
const instance = axios.create(config)
const defaults = {}
- let mock
-
- if (typeof MockAdapter.prototype.proxy === 'undefined') {
- MockAdapter.prototype.proxy = function ({ url, config = {}, proxy, response, handleData } = {}) {
- // eslint-disable-next-line @typescript-eslint/no-this-alias
- let stream = this
- const request = (proxy, any) => {
- return (setting) => {
- return new Promise((resolve) => {
- config.responseType = 'json'
- axios
- .get(any ? proxy + setting.url + '.json' : proxy, config)
- .then(({ data }) => {
- if (typeof handleData === 'function') {
- data = handleData.call(null, data, setting)
- }
- resolve([200, data])
- })
- .catch((error) => {
- resolve([error.response.status, error.response.data])
- })
- })
- }
- }
-
- if (url === '*' && proxy && typeof proxy === 'string') {
- stream = proxy === '*' ? this.onAny().passThrough() : this.onAny().reply(request(proxy, true))
- } else {
- if (proxy && typeof proxy === 'string') {
- stream = this.onAny(url).reply(request(proxy))
- } else if (typeof response === 'function') {
- stream = this.onAny(url).reply(response)
- }
- }
-
- return stream
- }
- }
return {
request(config) {
@@ -115,25 +76,6 @@ export default (config) => {
}
}
},
- mock(config) {
- if (!mock) {
- mock = new MockAdapter(instance)
- }
-
- if (Array.isArray(config)) {
- config.forEach((item) => {
- mock.proxy(item)
- })
- }
-
- return mock
- },
- disableMock() {
- if (mock) {
- mock.restore()
- }
- mock = undefined
- },
isMock() {
return typeof mock !== 'undefined'
},
diff --git a/packages/vue-generator/src/templates/vue-template/templateFiles/src/http/index.js b/packages/vue-generator/src/templates/vue-template/templateFiles/src/http/index.js
index b0a08546a6..72735de3c3 100644
--- a/packages/vue-generator/src/templates/vue-template/templateFiles/src/http/index.js
+++ b/packages/vue-generator/src/templates/vue-template/templateFiles/src/http/index.js
@@ -10,8 +10,8 @@
*
*/
-import axios from './axios'
-import config from './config'
+import axios from '@/http/axios.js'
+import config from '@/http/config.js'
export default (dataHandler) => {
const http = axios(config)
diff --git a/packages/vue-generator/src/templates/vue-template/templateFiles/src/lowcodeConfig/dataSource.js b/packages/vue-generator/src/templates/vue-template/templateFiles/src/lowcodeConfig/dataSource.js
index f82f146bfc..1b54f9107c 100644
--- a/packages/vue-generator/src/templates/vue-template/templateFiles/src/lowcodeConfig/dataSource.js
+++ b/packages/vue-generator/src/templates/vue-template/templateFiles/src/lowcodeConfig/dataSource.js
@@ -10,8 +10,8 @@
*
*/
-import useHttp from '../http'
-import dataSources from './dataSource.json'
+import useHttp from '@/http/index.js'
+import dataSources from '@/lowcodeConfig/dataSource.json'
const dataSourceMap = {}
@@ -25,7 +25,9 @@ const createFn = (fnContent) => {
}
}
-const globalDataHandle = dataSources.dataHandler ? createFn(dataSources.dataHandler.value) : (res) => res
+const globalDataHandle = dataSources.dataHandler
+ ? createFn(dataSources.dataHandler.value)
+ : (res) => Promise.resolve({ data: res })
const load = (http, options, dataSource, shouldFetch) => (params, customUrl) => {
// 如果没有配置远程请求,则直接返回静态数据,返回前可能会有全局数据处理
@@ -82,7 +84,7 @@ dataSources.list.forEach((config) => {
http.interceptors.request.use(willFetch, errorHandler)
http.interceptors.response.use(dataHandler, errorHandler)
- if (import.meta.env.VITE_APP_MOCK === 'mock') {
+ if (import.meta.env?.VITE_APP_MOCK === 'mock') {
http.mock([
{
url: config.options?.uri,
diff --git a/packages/vue-generator/src/templates/vue-template/templateFiles/src/lowcodeConfig/lowcode.js b/packages/vue-generator/src/templates/vue-template/templateFiles/src/lowcodeConfig/lowcode.js
index 29da8186b5..12164ca72a 100644
--- a/packages/vue-generator/src/templates/vue-template/templateFiles/src/lowcodeConfig/lowcode.js
+++ b/packages/vue-generator/src/templates/vue-template/templateFiles/src/lowcodeConfig/lowcode.js
@@ -13,10 +13,10 @@
import { getCurrentInstance, nextTick, provide, inject } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { I18nInjectionKey } from 'vue-i18n'
-import dataSourceMap from './dataSource'
-import * as utils from '../utils'
-import * as bridge from './bridge'
-import { useStores } from './store'
+import dataSourceMap from '@/lowcodeConfig/dataSource.js'
+import * as utils from '@/utils.js'
+import * as bridge from '@/lowcodeConfig/bridge.js'
+import { useStores } from '@/lowcodeConfig/store.js'
export const lowcodeWrap = (props, context) => {
const global = {}
diff --git a/packages/vue-generator/src/templates/vue-template/templateFiles/src/lowcodeConfig/store.js b/packages/vue-generator/src/templates/vue-template/templateFiles/src/lowcodeConfig/store.js
index f7f39c7a84..5da4c05ac1 100644
--- a/packages/vue-generator/src/templates/vue-template/templateFiles/src/lowcodeConfig/store.js
+++ b/packages/vue-generator/src/templates/vue-template/templateFiles/src/lowcodeConfig/store.js
@@ -1,4 +1,4 @@
-import * as useDefinedStores from '@/stores'
+import * as useDefinedStores from '@/stores/index.js'
const useStores = () => {
const stores = {}
diff --git a/packages/vue-generator/src/templates/vue-template/templateFiles/src/main.js b/packages/vue-generator/src/templates/vue-template/templateFiles/src/main.js
index c4574461b3..43633d3c04 100644
--- a/packages/vue-generator/src/templates/vue-template/templateFiles/src/main.js
+++ b/packages/vue-generator/src/templates/vue-template/templateFiles/src/main.js
@@ -10,11 +10,17 @@
*
*/
+export default (options) => {
+ return `
import { createApp } from 'vue'
-import router from './router'
+import router from '@/router/index.js'
import { createPinia } from 'pinia'
-import App from './App.vue'
+import App from '@/App.vue'
+
+${options.enableTailwindCSS ? 'import "./style.css"' : ''}
const pinia = createPinia()
createApp(App).use(pinia).use(router).mount('#app')
+ `
+}
diff --git a/packages/vue-generator/src/templates/vue-template/templateFiles/src/style.css b/packages/vue-generator/src/templates/vue-template/templateFiles/src/style.css
new file mode 100644
index 0000000000..a461c505f1
--- /dev/null
+++ b/packages/vue-generator/src/templates/vue-template/templateFiles/src/style.css
@@ -0,0 +1 @@
+@import "tailwindcss";
\ No newline at end of file
diff --git a/packages/vue-generator/src/utils/parseRequiredBlocks.js b/packages/vue-generator/src/utils/parseRequiredBlocks.js
index 5819a35360..ca68ca3bcd 100644
--- a/packages/vue-generator/src/utils/parseRequiredBlocks.js
+++ b/packages/vue-generator/src/utils/parseRequiredBlocks.js
@@ -1,18 +1,126 @@
-export const parseRequiredBlocks = (schema) => {
- const res = []
+const isJsSlot = (data) => {
+ // 判断是否是 plain object
+ if (typeof data !== 'object' || data === null) {
+ return false
+ }
- if (!Array.isArray(schema?.children)) {
- return res
+ // 判断是否是 JSSlot 类型
+ return data?.type === 'JSSlot' && Array.isArray(data?.value)
+}
+
+const isNodeLike = (data) => {
+ // 判断是否是 plain object
+ if (typeof data !== 'object' || data === null) {
+ return false
+ }
+
+ // 判断是否是 Node 类型
+ return typeof data?.componentName === 'string' && data?.componentName
+}
+
+// props 深度限制
+const MAX_PROPS_DEPTH = 1000
+
+function traverseProps(value, depth, resRef, propsSeenRef, nodesSeenRef) {
+ if (depth > MAX_PROPS_DEPTH) {
+ return
+ }
+
+ if (value === null || value === undefined) {
+ return
+ }
+
+ if (typeof value !== 'object') {
+ return
+ }
+
+ if (propsSeenRef.has(value)) {
+ return
+ }
+ propsSeenRef.add(value)
+
+ // JSSlot:仅遍历 value 数组
+ if (isJsSlot(value)) {
+ const arr = value.value || []
+ for (const item of arr) {
+ if (isNodeLike(item)) {
+ if (item.componentType === 'Block' && typeof item.componentName === 'string' && item.componentName) {
+ resRef.push(item.componentName)
+ }
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
+ collectFromNode(item, resRef, propsSeenRef, nodesSeenRef)
+ } else {
+ // 非节点,继续向下递归
+ traverseProps(item, depth + 1, resRef, propsSeenRef, nodesSeenRef)
+ }
+ }
+ return
+ }
+
+ // NodeLike:作为节点处理(先 children 后 props)
+ if (isNodeLike(value)) {
+ if (value.componentType === 'Block' && typeof value.componentName === 'string' && value.componentName) {
+ resRef.push(value.componentName)
+ }
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
+ collectFromNode(value, resRef, propsSeenRef, nodesSeenRef)
+ return
}
- for (const item of schema.children) {
- if (item.componentType === 'Block') {
- res.push(item.componentName)
+ // 数组:遍历每个元素
+ if (Array.isArray(value)) {
+ for (const item of value) {
+ traverseProps(item, depth + 1, resRef, propsSeenRef, nodesSeenRef)
}
- if (Array.isArray(item.children)) {
- res.push(...parseRequiredBlocks(item))
+ return
+ }
+
+ // 对象:遍历所有 key
+ for (const key of Object.keys(value)) {
+ traverseProps(value[key], depth + 1, resRef, propsSeenRef, nodesSeenRef)
+ }
+}
+
+function collectFromNode(node, resRef, propsSeenRef, nodesSeenRef) {
+ if (typeof node !== 'object' || node === null) {
+ return
+ }
+ if (nodesSeenRef.has(node)) {
+ return
+ }
+ nodesSeenRef.add(node)
+
+ // 1) 遍历 children
+ if (Array.isArray(node.children)) {
+ for (const child of node.children) {
+ if (typeof child !== 'object' || child === null) {
+ continue
+ }
+
+ if (child.componentType === 'Block' && typeof child.componentName === 'string' && child.componentName) {
+ resRef.push(child.componentName)
+ }
+
+ // 对每个子节点按“先 children 后 props”的节点级顺序继续递归
+ collectFromNode(child, resRef, propsSeenRef, nodesSeenRef)
}
}
- return res
+ // 2) 遍历 props(全键、全类型、任意深度,单条 props 路径最大 1000)
+ traverseProps(node.props, 0, resRef, propsSeenRef, nodesSeenRef)
+}
+
+export const parseRequiredBlocks = (schema) => {
+ const res = []
+ const propsSeen = new WeakSet()
+ const nodesSeen = new WeakSet()
+
+ if (typeof schema !== 'object' || schema === null) {
+ return res
+ }
+
+ // 入口节点
+ collectFromNode(schema, res, propsSeen, nodesSeen)
+
+ return Array.from(new Set(res))
}
diff --git a/packages/vue-generator/test/testcases/element-plus-case/expected/appdemo01/src/lowcodeConfig/dataSource.js b/packages/vue-generator/test/testcases/element-plus-case/expected/appdemo01/src/lowcodeConfig/dataSource.js
index f82f146bfc..5ac149730c 100644
--- a/packages/vue-generator/test/testcases/element-plus-case/expected/appdemo01/src/lowcodeConfig/dataSource.js
+++ b/packages/vue-generator/test/testcases/element-plus-case/expected/appdemo01/src/lowcodeConfig/dataSource.js
@@ -25,7 +25,9 @@ const createFn = (fnContent) => {
}
}
-const globalDataHandle = dataSources.dataHandler ? createFn(dataSources.dataHandler.value) : (res) => res
+const globalDataHandle = dataSources.dataHandler
+ ? createFn(dataSources.dataHandler.value)
+ : Promise.resolve({ data: res })
const load = (http, options, dataSource, shouldFetch) => (params, customUrl) => {
// 如果没有配置远程请求,则直接返回静态数据,返回前可能会有全局数据处理
diff --git a/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/lowcodeConfig/dataSource.js b/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/lowcodeConfig/dataSource.js
index f82f146bfc..5ac149730c 100644
--- a/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/lowcodeConfig/dataSource.js
+++ b/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/lowcodeConfig/dataSource.js
@@ -25,7 +25,9 @@ const createFn = (fnContent) => {
}
}
-const globalDataHandle = dataSources.dataHandler ? createFn(dataSources.dataHandler.value) : (res) => res
+const globalDataHandle = dataSources.dataHandler
+ ? createFn(dataSources.dataHandler.value)
+ : Promise.resolve({ data: res })
const load = (http, options, dataSource, shouldFetch) => (params, customUrl) => {
// 如果没有配置远程请求,则直接返回静态数据,返回前可能会有全局数据处理
diff --git a/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/utils.js b/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/utils.js
index 42009b621d..658f0f29af 100644
--- a/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/utils.js
+++ b/packages/vue-generator/test/testcases/generator/expected/appdemo01/src/utils.js
@@ -1,6 +1,6 @@
import axios from 'axios'
import { Button } from '@opentiny/vue'
-import { NavMenu } from '@opentiny/vue'
+import { NavMenu as Menu } from '@opentiny/vue'
import { Modal } from '@opentiny/vue'
import { Pager } from '@opentiny/vue'
const npm = ''
@@ -10,4 +10,4 @@ const test = function test() {
const util = function util() {
console.log(321)
}
-export { axios, Button, NavMenu, Modal, npm, Pager, test, util }
+export { axios, Button, Menu, Modal, npm, Pager, test, util }
diff --git a/packages/vue-generator/test/testcases/sfc/case08/expected/iconTest.vue b/packages/vue-generator/test/testcases/sfc/case08/expected/iconTest.vue
index d8dbca27ce..033cc4d722 100644
--- a/packages/vue-generator/test/testcases/sfc/case08/expected/iconTest.vue
+++ b/packages/vue-generator/test/testcases/sfc/case08/expected/iconTest.vue
@@ -22,22 +22,19 @@ import { IconEdit, IconMore, IconCustom } from '@opentiny/vue-icon'
import * as vue from 'vue'
import { defineProps, defineEmits } from 'vue'
import { I18nInjectionKey } from 'vue-i18n'
+
const TinyIconEdit = IconEdit()
const TinyIconMore = IconMore()
const TinyIconCustom = IconCustom()
const props = defineProps({})
+
const emit = defineEmits([])
const { t, lowcodeWrap, stores } = vue.inject(I18nInjectionKey).lowcode()
-const wrap = lowcodeWrap(props, {
- emit
-})
-wrap({
- stores
-})
+const wrap = lowcodeWrap(props, { emit })
+wrap({ stores })
+
const state = vue.reactive({})
-wrap({
- state
-})
+wrap({ state })
diff --git a/packages/workspace/application-center/src/Main.vue b/packages/workspace/application-center/src/Main.vue
new file mode 100644
index 0000000000..25c8feddad
--- /dev/null
+++ b/packages/workspace/application-center/src/Main.vue
@@ -0,0 +1,461 @@
+
+
+ 应用中心
+
+ 创建应用
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+
+
+
+ {{ item.scene[0]?.name }}
+
+
+ {{ item.industry[0]?.name }}
+
+ {{ item.framework }}
+
+ {{ item.description }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ data.row.name }}
+
+
+
+
+
+
+
+
+ 开发应用
+ 删除应用
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/workspace/application-center/src/js/http.js b/packages/workspace/application-center/src/js/http.js
new file mode 100644
index 0000000000..0268f30139
--- /dev/null
+++ b/packages/workspace/application-center/src/js/http.js
@@ -0,0 +1,36 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+/* metaService: engine.plugins.blockmanage.js-http */
+import { getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register'
+
+// 模版管理 -- 业务场景全查询
+export const fetchBusinessCategory = () =>
+ getMetaApi(META_SERVICE.Http).get(`/material-center/api/business-category/list`)
+
+// 模版管理 -- 按分类查询业务场景
+export const fetchBusinessCategoryByGroup = (group) =>
+ getMetaApi(META_SERVICE.Http).get(`/material-center/api/business-category/find?group=${group}`)
+
+// 应用管理 -- 获取应用列表
+export const fetchApplicationList = (params) =>
+ getMetaApi(META_SERVICE.Http).get(`app-center/api/apps/page`, { params }) // currentPage pageSize
+
+// 应用管理 -- 创建应用
+export const createApplication = (params) => getMetaApi(META_SERVICE.Http).post(`/app-center/api/apps/create`, params)
+
+// 应用管理 -- 编辑应用
+export const updateApplication = (id, params) =>
+ getMetaApi(META_SERVICE.Http).post(`/app-center/api/apps/update/${id}`, params)
+
+// 应用管理 -- 删除应用
+export const deleteApplication = (id) => getMetaApi(META_SERVICE.Http).get(`/app-center/api/apps/delete/${id}`)
diff --git a/packages/workspace/application-center/src/styles/vars.less b/packages/workspace/application-center/src/styles/vars.less
new file mode 100644
index 0000000000..a45f49b911
--- /dev/null
+++ b/packages/workspace/application-center/src/styles/vars.less
@@ -0,0 +1,21 @@
+:root {
+ --te-template-common-bg-color: var(--te-common-bg-default);
+ --te-template-common-bg-color-hover: var(--te-common-bg-container);
+ --te-app-center-mask-modal-bg-color: var(--te-common-mask);
+
+ // 列表 - 列表状态切换图标
+ --te-template-app-center-btn-bg-color: var(--te-common-bg-container);
+ --te-template-app-center-btn-icon-color: var(--te-common-icon-secondary);
+ --te-template-app-center-btn-color-active: var(--te-common-icon-primary);
+ --te-template-app-center-btn-border-color-active: var(--te-common-border-active);
+ --te-template-app-center-btn-bg-color-active: var(--te-common-bg-default);
+ --te-template-app-center-item-border-color: var(--te-common-border-card);
+ --te-template-app-center-item-border-color-hover: var(--te-common-border-checked);
+
+ // 列表
+ --te-template-center-common-item-bg-color: var(--te-common-bg-container-weaken);
+ --te-template-center-common-item-tag-bg-color: var(--te-common-bg-prompt);
+ --te-template-center-common-item-operation-bg-color: var(--te-common-bg-prompt);
+ --te-template-center-common-item-operation-icon-color: var(--te-common-icon-secondary);
+ --te-template-center-common-item-desc-text-color: var(--te-common-text-secondary);
+}
diff --git a/packages/workspace/application-center/vite.config.ts b/packages/workspace/application-center/vite.config.ts
new file mode 100644
index 0000000000..80f7f49640
--- /dev/null
+++ b/packages/workspace/application-center/vite.config.ts
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+import { defineConfig } from 'vite'
+import path from 'path'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+import generateComment from '@opentiny/tiny-engine-vite-plugin-meta-comments'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [generateComment(), vue(), vueJsx()],
+ publicDir: false,
+ resolve: {},
+ build: {
+ sourcemap: true,
+ lib: {
+ entry: path.resolve(__dirname, './index.ts'),
+ name: 'workspace-application-center',
+ fileName: (_format, entryName) => `${entryName}.js`,
+ formats: ['es']
+ },
+ rollupOptions: {
+ output: {
+ banner: 'import "./style.css"'
+ },
+ external: ['vue', /@opentiny\/tiny-engine.*/, /@opentiny\/vue.*/]
+ }
+ }
+})
diff --git a/packages/webcomponent/src/lib.js b/packages/workspace/template-center/index.ts
similarity index 77%
rename from packages/webcomponent/src/lib.js
rename to packages/workspace/template-center/index.ts
index 19f1f07b24..5efbd88c4b 100644
--- a/packages/webcomponent/src/lib.js
+++ b/packages/workspace/template-center/index.ts
@@ -10,6 +10,11 @@
*
*/
-import defineCustomElement from './defineCustomElement'
+import entry from './src/Main.vue'
+import metaData from './meta'
+import './src/styles/vars.less'
-export { defineCustomElement }
+export default {
+ ...metaData,
+ entry
+}
diff --git a/packages/workspace/template-center/meta.js b/packages/workspace/template-center/meta.js
new file mode 100644
index 0000000000..fd3a937c58
--- /dev/null
+++ b/packages/workspace/template-center/meta.js
@@ -0,0 +1,6 @@
+export default {
+ id: 'engine.workspace.template-center',
+ title: '模板中心',
+ type: 'workspace',
+ icon: 'workspace-icon-template-center'
+}
diff --git a/packages/webcomponent/package.json b/packages/workspace/template-center/package.json
similarity index 50%
rename from packages/webcomponent/package.json
rename to packages/workspace/template-center/package.json
index 09eac600f6..a4796ed108 100644
--- a/packages/webcomponent/package.json
+++ b/packages/workspace/template-center/package.json
@@ -1,26 +1,22 @@
{
- "name": "@opentiny/tiny-engine-webcomponent-core",
- "version": "2.7.0",
+ "name": "@opentiny/tiny-engine-workspace-template-center",
+ "version": "2.9.0",
"publishConfig": {
"access": "public"
},
- "description": "webcomponent vue core",
"scripts": {
- "dev": "vite",
- "build": "vite build",
- "format": "prettier --write **/*{.vue,.js,.ts,.html,.json}",
- "publish:npm": "npm run build && npm publish --verbose"
+ "build": "vite build"
},
+ "type": "module",
+ "main": "dist/index.js",
+ "module": "dist/index.js",
"files": [
"dist"
],
- "type": "module",
- "main": "dist/tiny-engine-webcomponent-core.umd.js",
- "module": "dist/tiny-engine-webcomponent-core.es.js",
"repository": {
"type": "git",
"url": "https://github.com/opentiny/tiny-engine",
- "directory": "packages/webcomponent"
+ "directory": "packages/workspace/template-center"
},
"bugs": {
"url": "https://github.com/opentiny/tiny-engine/issues"
@@ -29,14 +25,19 @@
"license": "MIT",
"homepage": "https://opentiny.design/tiny-engine",
"dependencies": {
- "@vue/shared": "^3.3.4"
+ "@opentiny/tiny-engine-common": "workspace:*",
+ "@opentiny/tiny-engine-meta-register": "workspace:*",
+ "vue-clipboard3": "^2.0.0"
},
"devDependencies": {
+ "@opentiny/tiny-engine-vite-plugin-meta-comments": "workspace:*",
"@vitejs/plugin-vue": "^5.1.2",
- "prettier": "^2.4.0",
+ "@vitejs/plugin-vue-jsx": "^4.0.1",
"vite": "^5.4.2"
},
"peerDependencies": {
+ "@opentiny/vue": "^3.20.0",
+ "@opentiny/vue-icon": "^3.20.0",
"vue": "^3.4.15"
}
}
diff --git a/packages/workspace/template-center/src/Main.vue b/packages/workspace/template-center/src/Main.vue
new file mode 100644
index 0000000000..38d348a027
--- /dev/null
+++ b/packages/workspace/template-center/src/Main.vue
@@ -0,0 +1,343 @@
+
+
+ 模板中心
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+
+ {{ item.description }}
+
+
+ {{ item.scene[0]?.name }}
+
+
+ {{ item.industry[0]?.name }}
+
+ {{ item.framework }}
+
+ 来自TinyEngine官方
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/workspace/template-center/src/TemplateDetail.vue b/packages/workspace/template-center/src/TemplateDetail.vue
new file mode 100644
index 0000000000..983aeebb03
--- /dev/null
+++ b/packages/workspace/template-center/src/TemplateDetail.vue
@@ -0,0 +1,201 @@
+
+
+
+
+
+
+ {{ state.templateDetail.name }}
+
+ {{ state.templateDetail.description }}
+
+
+ {{ state.templateDetail.scene[0]?.name }}
+
+
+ {{ state.templateDetail.industry[0]?.name }}
+
+ {{ state.templateDetail.framework }}
+
+ 来自TinyEngine官方
+ 用此模板创建应用
+
+
+ 预览体验
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/workspace/template-center/src/TemplateDialog.vue b/packages/workspace/template-center/src/TemplateDialog.vue
new file mode 100644
index 0000000000..bb35eaf7ee
--- /dev/null
+++ b/packages/workspace/template-center/src/TemplateDialog.vue
@@ -0,0 +1,264 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 确定
+ 取消
+
+
+
+
+
+
+
diff --git a/packages/workspace/template-center/src/js/http.js b/packages/workspace/template-center/src/js/http.js
new file mode 100644
index 0000000000..e33e058374
--- /dev/null
+++ b/packages/workspace/template-center/src/js/http.js
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+/* metaService: engine.plugins.blockmanage.js-http */
+import { getMetaApi, META_SERVICE } from '@opentiny/tiny-engine-meta-register'
+
+export const isDevelopEnv = import.meta.env.MODE?.includes('dev')
+// 模版管理 -- 获取模版列表
+export const fetchTemplateList = (params) =>
+ getMetaApi(META_SERVICE.Http).get(`/app-center/api/app-template/list`, { params })
+
+// 模版管理 -- 通过模板创建应用
+export const createAppFromTemplate = (params) =>
+ getMetaApi(META_SERVICE.Http).post(`/app-center/api/app-template/create`, params)
+
+// 模版管理 -- 按分类查询业务场景
+export const fetchBusinessCategoryByGroup = (group) =>
+ getMetaApi(META_SERVICE.Http).get(`/material-center/api/business-category/find?group=${group}`)
+
+// 模板管理 -- 查询页面列表
+export const getPageList = (id) => getMetaApi(META_SERVICE.Http).get(`/app-center/api/pages/list/${id}`)
diff --git a/packages/workspace/template-center/src/styles/vars.less b/packages/workspace/template-center/src/styles/vars.less
new file mode 100644
index 0000000000..f7de1f91ae
--- /dev/null
+++ b/packages/workspace/template-center/src/styles/vars.less
@@ -0,0 +1,15 @@
+:root {
+ --te-template-common-text-color: var(--te-common-text-primary);
+ --te-template-common-text-color-secondary: var(--te-common-text-secondary);
+ --te-template-common-bg-color: var(--te-common-bg-default);
+ --te-template-mask-modal-bg-color: var(--te-common-mask);
+
+ // 列表
+ --te-template-center-common-item-bg-color: var(--te-common-bg-container-weaken);
+ --te-template-center-common-item-tag-bg-color: var(--te-common-bg-prompt);
+ --te-template-center-common-item-desc-text-color: var(--te-common-text-secondary);
+ --te-template-center-common-item-from-text-color: var(--te-common-text-weaken);
+
+ // 详情
+ --te-template-center-detail-bg-color: var(--te-common-bg-container-weaken);
+}
diff --git a/packages/workspace/template-center/vite.config.ts b/packages/workspace/template-center/vite.config.ts
new file mode 100644
index 0000000000..4c35c32fed
--- /dev/null
+++ b/packages/workspace/template-center/vite.config.ts
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2023 - present TinyEngine Authors.
+ * Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
+ *
+ * Use of this source code is governed by an MIT-style license.
+ *
+ * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
+ * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
+ * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
+ *
+ */
+
+import { defineConfig } from 'vite'
+import path from 'path'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+import generateComment from '@opentiny/tiny-engine-vite-plugin-meta-comments'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [generateComment(), vue(), vueJsx()],
+ publicDir: false,
+ resolve: {},
+ build: {
+ sourcemap: true,
+ lib: {
+ entry: path.resolve(__dirname, './index.ts'),
+ name: 'workspace-template-center',
+ fileName: (_format, entryName) => `${entryName}.js`,
+ formats: ['es']
+ },
+ rollupOptions: {
+ output: {
+ banner: 'import "./style.css"'
+ },
+ external: ['vue', /@opentiny\/tiny-engine.*/, /@opentiny\/vue.*/]
+ }
+ }
+})
diff --git a/patches/@vue__repl@2.9.0.patch b/patches/@vue__repl@2.9.0.patch
deleted file mode 100644
index 86303479e1..0000000000
--- a/patches/@vue__repl@2.9.0.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-diff --git a/dist/chunks/MonacoEditor-KSgTEMrh.js b/dist/chunks/MonacoEditor-KSgTEMrh.js
-index c9668cbf8c44ba3c816246b746127204839f8349..e893c59a432e53372c18aa2e70d7b7bb9fd666ba 100644
---- a/dist/chunks/MonacoEditor-KSgTEMrh.js
-+++ b/dist/chunks/MonacoEditor-KSgTEMrh.js
-@@ -1,5 +1,13 @@
- import { watchEffect, defineComponent, ref, shallowRef, inject, computed, onMounted, nextTick, watch, onBeforeUnmount, openBlock, createElementBlock, createBlock } from 'vue';
- import { c as commonjsGlobal, a as getAugmentedNamespace } from './_commonjsHelpers-9Q-OoQuc.js';
-+function getWorkerURL(url){
-+ if (typeof document !== 'undefined' && document.location && document.location.origin !== url.origin) {
-+ return URL.createObjectURL(new Blob([`import '${url.href}'`], {
-+ type: 'application/javascript'
-+ }))
-+ }
-+ return url.href;
-+}
-
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
-@@ -170640,7 +170648,7 @@ var languages;
-
- function WorkerWrapper$1(options) {
- return new Worker(
-- ""+new URL('../assets/editor.worker-FXpxnIqv.js', import.meta.url).href+"",
-+ ""+getWorkerURL(new URL('../assets/editor.worker-FXpxnIqv.js', import.meta.url))+"",
- {
- type: "module",
- name: options?.name
-@@ -172020,7 +172028,7 @@ function getOrCreateModel(uri, lang, value) {
-
- function WorkerWrapper(options) {
- return new Worker(
-- ""+new URL('../assets/vue.worker-eqEbSb3e.js', import.meta.url).href+"",
-+ ""+getWorkerURL(new URL('../assets/vue.worker-eqEbSb3e.js', import.meta.url))+"",
- {
- type: "module",
- name: options?.name
-diff --git a/dist/vue-repl.js b/dist/vue-repl.js
-index 43bfd22a1a7d6f831e3f85228d809750317c4bfb..d5f5cb335533295c63e4cfa8aaa02770d16babca 100644
---- a/dist/vue-repl.js
-+++ b/dist/vue-repl.js
-@@ -528,7 +528,8 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
- "allow-popups",
- "allow-same-origin",
- "allow-scripts",
-- "allow-top-navigation-by-user-activation"
-+ "allow-top-navigation-by-user-activation",
-+ "allow-downloads"
- ].join(" ")
- );
- const importMap = store.getImportMap();
\ No newline at end of file
diff --git a/patches/@vue__repl@4.6.1.patch b/patches/@vue__repl@4.6.1.patch
new file mode 100644
index 0000000000..7aacd6164a
--- /dev/null
+++ b/patches/@vue__repl@4.6.1.patch
@@ -0,0 +1,65 @@
+diff --git a/dist/monaco-editor.js b/dist/monaco-editor.js
+index 5132a3752a80f6bbeb67e7e8d1aff65cdc97ae02..9e67e62c44419aeb752966de75afe11b967597b4 100644
+--- a/dist/monaco-editor.js
++++ b/dist/monaco-editor.js
+@@ -3,6 +3,15 @@ import { watchEffect, defineComponent, useTemplateRef, shallowRef, inject, compu
+ import { d as debounce } from './chunks/utils-BJf_b1Uq.js';
+ import { a as injectKeyProps } from './chunks/types-XqLqBVey.js';
+
++function getWorkerURL(url){
++ if (typeof document !== 'undefined' && document.location && document.location.origin !== url.origin) {
++ return URL.createObjectURL(new Blob([`import '${url.href}'`], {
++ type: 'application/javascript'
++ }))
++ }
++ return url.href;
++}
++
+ /*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+@@ -73583,12 +73592,6 @@ function fuzzyScoreGracefulAggressive(pattern, lowPattern, patternPos, word, low
+ }
+ function fuzzyScoreWithPermutations(pattern, lowPattern, patternPos, word, lowWord, wordPos, aggressive, options) {
+ let top = fuzzyScore(pattern, lowPattern, patternPos, word, lowWord, wordPos, options);
+- if (top && false) {
+- // when using the original pattern yield a result we`
+- // return it unless we are aggressive and try to find
+- // a better alignment, e.g. `cno` -> `^co^ns^ole` or `^c^o^nsole`.
+- return top;
+- }
+ if (pattern.length >= 3) {
+ // When the pattern is long enough then try a few (max 7)
+ // permutations of the pattern to find a better match. The
+@@ -178015,7 +178018,7 @@ async function registerProviders(worker, language, getSyncUris, languages) {
+
+ function WorkerWrapper$1(options) {
+ return new Worker(
+- ""+new URL('assets/editor.worker-KaUq7_iC.js', import.meta.url).href+"",
++ ""+getWorkerURL(new URL('assets/editor.worker-KaUq7_iC.js', import.meta.url))+"",
+ {
+ type: "module",
+ name: options?.name
+@@ -178034,7 +178037,7 @@ function getOrCreateModel(uri, lang, value) {
+
+ function WorkerWrapper(options) {
+ return new Worker(
+- ""+new URL('assets/vue.worker-Dc6PZdLj.js', import.meta.url).href+"",
++ ""+getWorkerURL(new URL('assets/vue.worker-Dc6PZdLj.js', import.meta.url))+"",
+ {
+ type: "module",
+ name: options?.name
+diff --git a/dist/vue-repl.js b/dist/vue-repl.js
+index cfb74a062a5661ba5a8105825714c8eb464cbf70..91b4747b22b96899c96612b909dc662d87b890e6 100644
+--- a/dist/vue-repl.js
++++ b/dist/vue-repl.js
+@@ -551,7 +551,8 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
+ "allow-popups",
+ "allow-same-origin",
+ "allow-scripts",
+- "allow-top-navigation-by-user-activation"
++ "allow-top-navigation-by-user-activation",
++ "allow-downloads"
+ ].join(" ")
+ );
+ const importMap = store.value.getImportMap();
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index 85cf00f469..011288d389 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -1,7 +1,8 @@
packages:
- - 'packages/**'
- - 'mockServer'
- - 'designer-demo'
- # 忽略测试文件夹中的 project、脚手架模板
+ - packages/**
+ - mockServer
+ - designer-demo
- '!packages/**/test/**'
- '!packages/**/template/**'
+patchedDependencies:
+ '@vue/repl@4.6.1': patches/@vue__repl@4.6.1.patch
diff --git a/scripts/uploadMaterials.mjs b/scripts/uploadMaterials.mjs
new file mode 100644
index 0000000000..9435f87e1d
--- /dev/null
+++ b/scripts/uploadMaterials.mjs
@@ -0,0 +1,40 @@
+import { Buffer } from 'buffer'
+import dotenv from 'dotenv'
+import fs from 'fs-extra'
+import path from 'node:path'
+import Logger from './logger.mjs'
+
+const logger = new Logger('uploadMaterials')
+
+// 先构造出.env*文件的绝对路径
+const appDirectory = fs.realpathSync(process.cwd())
+const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath)
+const pathsDotenv = resolveApp('.env')
+dotenv.config({ path: `${pathsDotenv}.local` })
+const { backend_url } = process.env
+
+const bundlePath = path.join(process.cwd(), '/designer-demo/public/mock/bundle.json')
+const bundle = fs.readJSONSync(bundlePath)
+const jsonBuffer = Buffer.from(JSON.stringify(bundle))
+const boundary = '----WebKitFormBoundary7MA4YWxkTrZu0gW'
+const formHeaders = {
+ 'Content-Type': `multipart/form-data; boundary=${boundary}`,
+}
+
+let body = `--${boundary}\r\n`
+body += 'Content-Disposition: form-data; name="file"; filename="bundle.json"\r\n'
+body += 'Content-Type: application/json\r\n\r\n'
+body += jsonBuffer.toString() + `\r\n--${boundary}--`
+
+fetch(backend_url, {
+ method: 'POST',
+ headers: formHeaders,
+ body: body,
+})
+ .then(response => response.json())
+ .then(data => {
+ logger.success('File uploaded successfully:', data)
+ })
+ .catch(error => {
+ logger.error('Error uploading file:', error)
+ })
diff --git a/tsconfig.app.json b/tsconfig.app.json
index 4beafe26ed..3a803af5d2 100644
--- a/tsconfig.app.json
+++ b/tsconfig.app.json
@@ -1,18 +1,16 @@
{
- "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "extends": ["@vue/tsconfig/tsconfig.dom.json", "./tsconfig.base.json"],
"compilerOptions": {
- "composite": true,
- "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
-
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
+ "noEmit": true,
"noFallthroughCasesInSwitch": true,
-
"allowJs": true,
"baseUrl": "./",
- "jsx": "react-jsx",
+ "jsx": "preserve",
+ "lib": ["ES2023", "DOM", "DOM.Iterable"],
"paths": {
"@/*": ["packages/*"],
"@opentiny/tiny-engine": ["packages/design-core/index.js"],
@@ -36,6 +34,7 @@
"@opentiny/tiny-engine-plugin-script": ["packages/plugins/script/index"],
"@opentiny/tiny-engine-plugin-state": ["packages/plugins/state/index"],
"@opentiny/tiny-engine-plugin-tree": ["packages/plugins/tree/index"],
+ "@opentiny/tiny-engine-plugin-model-manager": ["packages/plugins/model-manager/index"],
"@opentiny/tiny-engine-setting-events": ["packages/settings/events/index"],
"@opentiny/tiny-engine-setting-props": ["packages/settings/props/index"],
"@opentiny/tiny-engine-setting-styles": ["packages/settings/styles/index"],
@@ -55,7 +54,8 @@
"@opentiny/tiny-engine-toolbar-theme-switch": ["packages/toolbars/themeSwitch/index"],
"@opentiny/tiny-engine-toolbar-view-setting": ["packages/toolbars/view-setting/index"],
"@opentiny/tiny-engine-utils": ["packages/utils/src/index"],
- "@opentiny/tiny-engine-webcomponent-core": ["packages/webcomponent/src/lib"]
+ "@opentiny/tiny-engine-workspace-template-center": ["packages/workspace/template-center/index"],
+ "@opentiny/tiny-engine-workspace-application-center": ["packages/workspace/application-center/index"],
}
},
"include": ["packages/**/*"],
diff --git a/tsconfig.base.json b/tsconfig.base.json
new file mode 100644
index 0000000000..ce31af132e
--- /dev/null
+++ b/tsconfig.base.json
@@ -0,0 +1,18 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+ "module": "ESNext",
+ "target": "ESNext",
+
+ /* Bundler mode */
+ "moduleResolution": "Bundler",
+ "allowImportingTsExtensions": true,
+ "isolatedModules": true,
+ "moduleDetection": "force",
+ "emitDeclarationOnly": true,
+ "jsx": "preserve",
+ "useDefineForClassFields": true
+ }
+}
+
diff --git a/tsconfig.node.json b/tsconfig.node.json
index 7e1ecee96c..3fe89d78bf 100644
--- a/tsconfig.node.json
+++ b/tsconfig.node.json
@@ -1,17 +1,10 @@
{
+ "extends": "./tsconfig.base.json",
"compilerOptions": {
- "composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2022",
"lib": ["ES2023"],
- "module": "ESNext",
"skipLibCheck": true,
-
- /* Bundler mode */
- "moduleResolution": "bundler",
- "allowImportingTsExtensions": true,
- "isolatedModules": true,
- "moduleDetection": "force",
"noEmit": true,
/* Linting */