diff --git a/packages/builtinComponent/README.md b/packages/builtinComponent/README.md new file mode 100644 index 000000000..5670a81d8 --- /dev/null +++ b/packages/builtinComponent/README.md @@ -0,0 +1,9 @@ +# 内置组件 + +## 目前内置的组件 + +### CanvasRow + +### CanvasCol + +### CanvasRowColContainer diff --git a/packages/builtinComponent/index.js b/packages/builtinComponent/index.js new file mode 100644 index 000000000..99242b77a --- /dev/null +++ b/packages/builtinComponent/index.js @@ -0,0 +1,4 @@ +export { default as CanvasCol } from './src/components/CanvasCol.vue' +export { default as CanvasRow } from './src/components/CanvasRow.vue' +export { default as CanvasRowColContainer } from './src/components/CanvasRowColContainer.vue' +export { default as meta } from './src/meta' diff --git a/packages/builtinComponent/package.json b/packages/builtinComponent/package.json new file mode 100644 index 000000000..9ca16bed9 --- /dev/null +++ b/packages/builtinComponent/package.json @@ -0,0 +1,26 @@ +{ + "name": "@opentiny/tiny-engine-builtin-component", + "version": "0.1.0", + "description": "", + "main": "dist/index.js", + "module": "dist/index.js", + "files": [ + "dist" + ], + "repository": { + "type": "git", + "url": "https://github.com/opentiny/tiny-engine", + "directory": "packages/builtinComponent" + }, + "scripts": { + "build": "vite build" + }, + "dependencies": { + "@opentiny/vue": "~3.10.0" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^4.2.3", + "@vitejs/plugin-vue-jsx": "^3.0.2", + "vite": "^4.5.0" + } +} diff --git a/packages/builtinComponent/src/components/CanvasCol.vue b/packages/builtinComponent/src/components/CanvasCol.vue new file mode 100644 index 000000000..7bbaeb4be --- /dev/null +++ b/packages/builtinComponent/src/components/CanvasCol.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/packages/builtinComponent/src/components/CanvasRow.vue b/packages/builtinComponent/src/components/CanvasRow.vue new file mode 100644 index 000000000..5c7ba54d5 --- /dev/null +++ b/packages/builtinComponent/src/components/CanvasRow.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/packages/builtinComponent/src/components/CanvasRowColContainer.vue b/packages/builtinComponent/src/components/CanvasRowColContainer.vue new file mode 100644 index 000000000..ad46e409d --- /dev/null +++ b/packages/builtinComponent/src/components/CanvasRowColContainer.vue @@ -0,0 +1,29 @@ + + + + + diff --git a/packages/builtinComponent/src/components/helper.js b/packages/builtinComponent/src/components/helper.js new file mode 100644 index 000000000..59200272e --- /dev/null +++ b/packages/builtinComponent/src/components/helper.js @@ -0,0 +1,46 @@ +/** + * 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 const getStyleValue = (value) => { + if (typeof value === 'number' || /^\d+\.?\d*$/.test(value)) { + return `${value}px` + } + + if (/^\d+\.?\d*(px|%|pt|em|rem|vw|vh)$/.test(value)) { + return value + } + + return '' +} + +export const alignMap = { + 'flex-start': 'flex-start', + 'flex-end': 'flex-end', + center: 'center', + stretch: 'stretch', + start: 'start', + end: 'end' +} + +export const justAlignMap = { + 'space-between': 'space-between', + 'space-around': 'space-around', + 'space-evenly': 'space-evenly', + 'flex-start': 'flex-start', + 'flex-end': 'flex-end', + stretch: 'stretch', + center: 'center', + start: 'start', + end: 'end', + left: 'left', + right: 'right' +} diff --git a/packages/builtinComponent/src/meta/CanvasCol.json b/packages/builtinComponent/src/meta/CanvasCol.json new file mode 100644 index 000000000..33c68b5df --- /dev/null +++ b/packages/builtinComponent/src/meta/CanvasCol.json @@ -0,0 +1,196 @@ +{ + "components": { + "icon": "Box", + "name": { + "zh_CN": "CanvasCol" + }, + "component": "CanvasCol", + "schema": { + "slots": {}, + "properties": [ + { + "label": { + "zh_CN": "基础信息" + }, + "description": { + "zh_CN": "基础信息" + }, + "collapse": { + "number": 6, + "text": { + "zh_CN": "显示更多" + } + }, + "content": [ + { + "property": "widthType", + "type": "String", + "defaultValue": "auto", + "label": { + "text": { + "zh_CN": "宽度类型" + } + }, + "cols": 12, + "rules": [], + "widget": { + "component": "MetaRadioGroup", + "props": { + "options": [ + { "label": "auto", "text": "自适应" }, + { "label": "fixed", "text": "固定" } + ], + "type": "button" + } + } + }, + { + "property": "flexBasis", + "type": "String", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "固定宽度" + } + }, + "cols": 12, + "rules": [], + "widget": { + "component": "MetaInput", + "props": {} + } + }, + { + "property": "rowGap", + "type": "String", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "行间距" + } + }, + "cols": 12, + "rules": [], + "widget": { + "component": "MetaInput", + "props": {} + } + }, + { + "property": "colGap", + "type": "String", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "列间距" + } + }, + "cols": 12, + "rules": [], + "widget": { + "component": "MetaInput", + "props": {} + } + }, + { + "property": "align", + "type": "String", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "副轴对齐" + } + }, + "cols": 12, + "rules": [], + "widget": { + "component": "MetaSelect", + "props": { + "options": [ + { "value": "flex-start", "label": "头部对齐" }, + { "value": "center", "label": "中间对齐" }, + { "value": "flex-end", "label": "尾端对齐" }, + { "value": "stretch", "label": "拉伸对齐" } + ], + "type": "button" + } + } + }, + { + "property": "justAlign", + "type": "String", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "主轴对齐" + } + }, + "cols": 12, + "rules": [], + "widget": { + "component": "MetaSelect", + "props": { + "options": [ + { "value": "flex-start", "label": "头部对齐" }, + { "value": "center", "label": "中间对齐" }, + { "value": "flex-end", "label": "尾端对齐" }, + { "value": "space-between", "label": "两端对齐" }, + { "value": "space-evenly", "label": "均分对齐" } + ], + "type": "button" + } + } + }, + { + "property": "grow", + "type": "String", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "增长" + } + }, + "cols": 12, + "rules": [], + "widget": { + "component": "MetaSwitch", + "props": {} + } + }, + { + "property": "shrink", + "type": "String", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "收缩" + } + }, + "cols": 12, + "rules": [], + "widget": { + "component": "MetaSwitch", + "props": {} + } + } + ] + } + ], + "events": {}, + "shortcuts": { + "properties": [] + }, + "contentMenu": { + "actions": [] + } + }, + "configure": { + "loop": true, + "isContainer": true, + "nestingRule": { + "childWhitelist": [], + "descendantBlacklist": [] + } + } + } +} diff --git a/packages/builtinComponent/src/meta/CanvasRow.json b/packages/builtinComponent/src/meta/CanvasRow.json new file mode 100644 index 000000000..5033b30ba --- /dev/null +++ b/packages/builtinComponent/src/meta/CanvasRow.json @@ -0,0 +1,142 @@ +{ + "components": { + "icon": "Box", + "name": { + "zh_CN": "CanvasRow" + }, + "component": "CanvasRow", + "schema": { + "slots": {}, + "properties": [ + { + "label": { + "zh_CN": "基础信息" + }, + "description": { + "zh_CN": "基础信息" + }, + "collapse": { + "number": 6, + "text": { + "zh_CN": "显示更多" + } + }, + "content": [ + { + "property": "minHeight", + "type": "String", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "最小高度" + } + }, + "cols": 12, + "rules": [], + "widget": { + "component": "MetaInput", + "props": {} + } + }, + { + "property": "rowGap", + "type": "String", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "行间距" + } + }, + "cols": 12, + "rules": [], + "widget": { + "component": "MetaInput", + "props": {} + } + }, + { + "property": "colGap", + "type": "String", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "列间距" + } + }, + "cols": 12, + "rules": [], + "widget": { + "component": "MetaInput", + "props": {} + } + }, + { + "property": "align", + "type": "String", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "副轴对齐" + } + }, + "cols": 12, + "rules": [], + "widget": { + "component": "MetaSelect", + "props": { + "options": [ + { "value": "flex-start", "label": "头部对齐" }, + { "value": "center", "label": "中间对齐" }, + { "value": "flex-end", "label": "尾端对齐" }, + { "value": "stretch", "label": "拉伸对齐" } + ], + "type": "button" + } + } + }, + { + "property": "justAlign", + "type": "String", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "主轴对齐" + } + }, + "cols": 12, + "rules": [], + "widget": { + "component": "MetaSelect", + "props": { + "options": [ + { "value": "flex-start", "label": "头部对齐" }, + { "value": "center", "label": "中间对齐" }, + { "value": "flex-end", "label": "尾端对齐" }, + { "value": "space-between", "label": "两端对齐" }, + { "value": "space-evenly", "label": "均分对齐" } + ], + "type": "button" + } + } + } + ] + } + ], + "events": {}, + "shortcuts": { + "properties": [] + }, + "contentMenu": { + "actions": [] + } + }, + "configure": { + "loop": true, + "isContainer": true, + "nestingRule": { + "childWhitelist": [], + "descendantBlacklist": [] + } + } + } +} diff --git a/packages/builtinComponent/src/meta/CanvasRowColContainer.json b/packages/builtinComponent/src/meta/CanvasRowColContainer.json new file mode 100644 index 000000000..e363530f6 --- /dev/null +++ b/packages/builtinComponent/src/meta/CanvasRowColContainer.json @@ -0,0 +1,96 @@ +{ + "components": { + "icon": "Box", + "name": { + "zh_CN": "行列容器" + }, + "component": "CanvasRowColContainer", + "schema": { + "slots": {}, + "properties": [ + { + "label": { + "zh_CN": "基础信息" + }, + "description": { + "zh_CN": "基础信息" + }, + "collapse": { + "number": 6, + "text": { + "zh_CN": "显示更多" + } + }, + "content": [ + { + "property": "rowGap", + "type": "String", + "defaultValue": "", + "label": { + "text": { + "zh_CN": "行间距" + } + }, + "cols": 12, + "rules": [], + "widget": { + "component": "MetaInput", + "props": {} + } + } + ] + } + ], + "events": {}, + "shortcuts": { + "properties": [] + }, + "contentMenu": { + "actions": [] + } + }, + "configure": { + "loop": true, + "isContainer": true, + "nestingRule": { + "childWhitelist": [], + "descendantBlacklist": [] + } + } + }, + "snippets": { + "name": { + "zh_CN": "行列容器" + }, + "screenshot": "", + "snippetName": "CanvasRowColContainer", + "icon": "Box", + "schema": { + "componentName": "CanvasRowColContainer", + "props": { + "rowGap": "20px" + }, + "children": [ + { + "componentName": "CanvasRow", + "props": { + "rowGap": "20px", + "colGap": "20px" + }, + "children": [ + { + "componentName": "CanvasCol", + "props": { + "rowGap": "20px", + "colGap": "20px", + "grow": true, + "shrink": true, + "widthType": "auto" + } + } + ] + } + ] + } + } +} diff --git a/packages/builtinComponent/src/meta/index.js b/packages/builtinComponent/src/meta/index.js new file mode 100644 index 000000000..fa2fca60d --- /dev/null +++ b/packages/builtinComponent/src/meta/index.js @@ -0,0 +1,18 @@ +import CanvasCol from './CanvasCol.json' +import CanvasRow from './CanvasRow.json' +import CanvasRowColContainer from './CanvasRowColContainer.json' + +export default { + components: [ + { + group: '内置组件', + children: [{ ...CanvasCol.components }, { ...CanvasRow.components }, { ...CanvasRowColContainer.components }] + } + ], + snippets: [ + { + group: '内置组件', + children: [{ ...CanvasRowColContainer.snippets }] + } + ] +} diff --git a/packages/builtinComponent/vite.config.js b/packages/builtinComponent/vite.config.js new file mode 100644 index 000000000..62ca318c0 --- /dev/null +++ b/packages/builtinComponent/vite.config.js @@ -0,0 +1,35 @@ +/** + * 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' + +export default defineConfig({ + plugins: [vue(), vueJsx()], + publicDir: false, + build: { + cssCodeSplit: false, + lib: { + entry: path.resolve(__dirname, './index.js'), + name: 'builtinComponent', + fileName: () => 'index.js', + formats: ['es'] + }, + rollupOptions: { + output: { + banner: 'import "./style.css"' + }, + external: ['vue'] + } + } +}) diff --git a/packages/canvas/package.json b/packages/canvas/package.json index 46d96690a..50205d607 100644 --- a/packages/canvas/package.json +++ b/packages/canvas/package.json @@ -32,6 +32,7 @@ "@opentiny/tiny-engine-i18n-host": "workspace:^1.0.0", "@opentiny/tiny-engine-utils": "workspace:^1.0.0", "@opentiny/tiny-engine-webcomponent-core": "workspace:^1.0.0", + "@opentiny/tiny-engine-builtin-component": "workspace:*", "@opentiny/vue": "~3.10.0", "@opentiny/vue-icon": "~3.10.0", "@opentiny/vue-renderless": "~3.10.0", diff --git a/packages/canvas/src/components/builtin/builtin.json b/packages/canvas/src/components/builtin/builtin.json index 44aaa49f3..9673698c8 100644 --- a/packages/canvas/src/components/builtin/builtin.json +++ b/packages/canvas/src/components/builtin/builtin.json @@ -432,399 +432,6 @@ "configure": { "loop": true } - }, - { - "icon": "Box", - "name": { - "zh_CN": "CanvasRow" - }, - "component": "CanvasRow", - "schema": { - "slots": {}, - "properties": [ - { - "label": { - "zh_CN": "基础信息" - }, - "description": { - "zh_CN": "基础信息" - }, - "collapse": { - "number": 6, - "text": { - "zh_CN": "显示更多" - } - }, - "content": [ - { - "property": "minHeight", - "type": "String", - "defaultValue": "", - "label": { - "text": { - "zh_CN": "最小高度" - } - }, - "cols": 12, - "rules": [], - "widget": { - "component": "MetaInput", - "props": {} - } - }, - { - "property": "rowGap", - "type": "String", - "defaultValue": "", - "label": { - "text": { - "zh_CN": "行间距" - } - }, - "cols": 12, - "rules": [], - "widget": { - "component": "MetaInput", - "props": {} - } - }, - { - "property": "colGap", - "type": "String", - "defaultValue": "", - "label": { - "text": { - "zh_CN": "列间距" - } - }, - "cols": 12, - "rules": [], - "widget": { - "component": "MetaInput", - "props": {} - } - }, - { - "property": "align", - "type": "String", - "defaultValue": "", - "label": { - "text": { - "zh_CN": "副轴对齐" - } - }, - "cols": 12, - "rules": [], - "widget": { - "component": "MetaSelect", - "props": { - "options": [ - { "value": "flex-start", "label": "头部对齐" }, - { "value": "center", "label": "中间对齐" }, - { "value": "flex-end", "label": "尾端对齐" }, - { "value": "stretch", "label": "拉伸对齐" } - ], - "type": "button" - } - } - }, - { - "property": "justAlign", - "type": "String", - "defaultValue": "", - "label": { - "text": { - "zh_CN": "主轴对齐" - } - }, - "cols": 12, - "rules": [], - "widget": { - "component": "MetaSelect", - "props": { - "options": [ - { "value": "flex-start", "label": "头部对齐" }, - { "value": "center", "label": "中间对齐" }, - { "value": "flex-end", "label": "尾端对齐" }, - { "value": "space-between", "label": "两端对齐" }, - { "value": "space-evenly", "label": "均分对齐" } - ], - "type": "button" - } - } - } - ] - } - ], - "events": {}, - "shortcuts": { - "properties": [] - }, - "contentMenu": { - "actions": [] - } - }, - "configure": { - "loop": true, - "isContainer": true, - "nestingRule": { - "childWhitelist": [], - "descendantBlacklist": [] - } - } - }, - { - "icon": "Box", - "name": { - "zh_CN": "CanvasCol" - }, - "component": "CanvasCol", - "schema": { - "slots": {}, - "properties": [ - { - "label": { - "zh_CN": "基础信息" - }, - "description": { - "zh_CN": "基础信息" - }, - "collapse": { - "number": 6, - "text": { - "zh_CN": "显示更多" - } - }, - "content": [ - { - "property": "widthType", - "type": "String", - "defaultValue": "auto", - "label": { - "text": { - "zh_CN": "宽度类型" - } - }, - "cols": 12, - "rules": [], - "widget": { - "component": "MetaRadioGroup", - "props": { - "options": [ - { "label": "auto", "text": "自适应" }, - { "label": "fixed", "text": "固定" } - ], - "type": "button" - } - } - }, - { - "property": "flexBasis", - "type": "String", - "defaultValue": "", - "label": { - "text": { - "zh_CN": "固定宽度" - } - }, - "cols": 12, - "rules": [], - "widget": { - "component": "MetaInput", - "props": {} - } - }, - { - "property": "rowGap", - "type": "String", - "defaultValue": "", - "label": { - "text": { - "zh_CN": "行间距" - } - }, - "cols": 12, - "rules": [], - "widget": { - "component": "MetaInput", - "props": {} - } - }, - { - "property": "colGap", - "type": "String", - "defaultValue": "", - "label": { - "text": { - "zh_CN": "列间距" - } - }, - "cols": 12, - "rules": [], - "widget": { - "component": "MetaInput", - "props": {} - } - }, - { - "property": "align", - "type": "String", - "defaultValue": "", - "label": { - "text": { - "zh_CN": "副轴对齐" - } - }, - "cols": 12, - "rules": [], - "widget": { - "component": "MetaSelect", - "props": { - "options": [ - { "value": "flex-start", "label": "头部对齐" }, - { "value": "center", "label": "中间对齐" }, - { "value": "flex-end", "label": "尾端对齐" }, - { "value": "stretch", "label": "拉伸对齐" } - ], - "type": "button" - } - } - }, - { - "property": "justAlign", - "type": "String", - "defaultValue": "", - "label": { - "text": { - "zh_CN": "主轴对齐" - } - }, - "cols": 12, - "rules": [], - "widget": { - "component": "MetaSelect", - "props": { - "options": [ - { "value": "flex-start", "label": "头部对齐" }, - { "value": "center", "label": "中间对齐" }, - { "value": "flex-end", "label": "尾端对齐" }, - { "value": "space-between", "label": "两端对齐" }, - { "value": "space-evenly", "label": "均分对齐" } - ], - "type": "button" - } - } - }, - { - "property": "grow", - "type": "String", - "defaultValue": "", - "label": { - "text": { - "zh_CN": "增长" - } - }, - "cols": 12, - "rules": [], - "widget": { - "component": "MetaSwitch", - "props": {} - } - }, - { - "property": "shrink", - "type": "String", - "defaultValue": "", - "label": { - "text": { - "zh_CN": "收缩" - } - }, - "cols": 12, - "rules": [], - "widget": { - "component": "MetaSwitch", - "props": {} - } - } - ] - } - ], - "events": {}, - "shortcuts": { - "properties": [] - }, - "contentMenu": { - "actions": [] - } - }, - "configure": { - "loop": true, - "isContainer": true, - "nestingRule": { - "childWhitelist": [], - "descendantBlacklist": [] - } - } - }, - { - "icon": "Box", - "name": { - "zh_CN": "行列容器" - }, - "component": "CanvasRowColContainer", - "schema": { - "slots": {}, - "properties": [ - { - "label": { - "zh_CN": "基础信息" - }, - "description": { - "zh_CN": "基础信息" - }, - "collapse": { - "number": 6, - "text": { - "zh_CN": "显示更多" - } - }, - "content": [ - { - "property": "rowGap", - "type": "String", - "defaultValue": "", - "label": { - "text": { - "zh_CN": "行间距" - } - }, - "cols": 12, - "rules": [], - "widget": { - "component": "MetaInput", - "props": {} - } - } - ] - } - ], - "events": {}, - "shortcuts": { - "properties": [] - }, - "contentMenu": { - "actions": [] - } - }, - "configure": { - "loop": true, - "isContainer": true, - "nestingRule": { - "childWhitelist": [], - "descendantBlacklist": [] - } - } } ] } @@ -911,41 +518,6 @@ "style": "width: 200px; height: 200px" } } - }, - { - "name": { - "zh_CN": "行列容器" - }, - "screenshot": "", - "snippetName": "CanvasRowColContainer", - "icon": "Box", - "schema": { - "componentName": "CanvasRowColContainer", - "props": { - "rowGap": "20px" - }, - "children": [ - { - "componentName": "CanvasRow", - "props": { - "rowGap": "20px", - "colGap": "20px" - }, - "children": [ - { - "componentName": "CanvasCol", - "props": { - "rowGap": "20px", - "colGap": "20px", - "grow": true, - "shrink": true, - "widthType": "auto" - } - } - ] - } - ] - } } ] } diff --git a/packages/canvas/src/components/builtin/index.js b/packages/canvas/src/components/builtin/index.js index 42be89f5c..f857ff1a1 100644 --- a/packages/canvas/src/components/builtin/index.js +++ b/packages/canvas/src/components/builtin/index.js @@ -1,14 +1,14 @@ /** -* 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. -* -*/ + * 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 CanvasText from './CanvasText.vue' import CanvasBox from './CanvasBox.vue' @@ -16,18 +16,6 @@ import CanvasCollection from './CanvasCollection.vue' import CanvasIcon from './CanvasIcon.vue' import CanvasSlot from './CanvasSlot.vue' import CanvasImg from './CanvasImg.vue' -import CanvasRow from './CanvasRow.vue' -import CanvasCol from './CanvasCol.vue' -import CanvasRowColContainer from './CanvasRowColContainer.vue' +import CanvasPlaceholder from './CanvasPlaceholder.vue' -export { - CanvasText, - CanvasBox, - CanvasCollection, - CanvasIcon, - CanvasSlot, - CanvasImg, - CanvasRow, - CanvasCol, - CanvasRowColContainer -} +export { CanvasText, CanvasBox, CanvasCollection, CanvasIcon, CanvasSlot, CanvasImg, CanvasPlaceholder } diff --git a/packages/canvas/src/components/render/render.js b/packages/canvas/src/components/render/render.js index dacd2a9f6..f6d36f9ba 100644 --- a/packages/canvas/src/components/render/render.js +++ b/packages/canvas/src/components/render/render.js @@ -17,6 +17,7 @@ import { constants, utils } from '@opentiny/tiny-engine-utils' import babelPluginJSX from '@vue/babel-plugin-jsx' import { transformSync } from '@babel/core' import i18nHost from '@opentiny/tiny-engine-i18n-host' +import { CanvasRow, CanvasCol, CanvasRowColContainer } from '@opentiny/tiny-engine-builtin-component' import { context, conditions, setNode } from './context' import { CanvasBox, @@ -25,9 +26,7 @@ import { CanvasText, CanvasSlot, CanvasImg, - CanvasRow, - CanvasCol, - CanvasRowColContainer + CanvasPlaceholder } from '../builtin' import { NODE_UID as DESIGN_UIDKEY, NODE_TAG as DESIGN_TAGKEY, NODE_LOOP as DESIGN_LOOPID } from '../common' @@ -61,7 +60,8 @@ const Mapper = { Img: CanvasImg, CanvasRow, CanvasCol, - CanvasRowColContainer + CanvasRowColContainer, + CanvasPlaceholder } const { post } = useBroadcastChannel({ name: BROADCAST_CHANNEL.Notify }) @@ -495,7 +495,6 @@ const stopEvent = (event) => { return false } - const generateSlotGroup = (children, isCustomElm) => { const slotGroup = {} @@ -538,6 +537,10 @@ const getBindProps = (schema, scope) => { const { id, componentName } = schema const invalidity = configure[componentName]?.invalidity || [] + if (componentName === 'CanvasPlaceholder') { + return {} + } + const bindProps = { ...parseData(schema.props, scope), [DESIGN_UIDKEY]: id, @@ -612,21 +615,34 @@ const renderGroup = (children, scope, parent) => { }) } +const ContainerComponent = ['CanvasCol', 'CanvasRow', 'CanvasRowColContainer'] + const getChildren = (schema, mergeScope) => { const { componentName, children } = schema + let renderChildren = children + + if (ContainerComponent.includes(componentName) && !renderChildren?.length) { + renderChildren = [ + { + componentName: 'CanvasPlaceholder' + } + ] + } const isNative = typeof component === 'string' const isCustomElm = customElements[componentName] const isGroup = checkGroup(componentName) - if (Array.isArray(children)) { + if (Array.isArray(renderChildren)) { if (isNative || isCustomElm) { - return renderDefault(children, mergeScope, schema) + return renderDefault(renderChildren, mergeScope, schema) } else { - return isGroup ? renderGroup(children, mergeScope, schema) : renderSlot(children, mergeScope, schema, isCustomElm) + return isGroup + ? renderGroup(renderChildren, mergeScope, schema) + : renderSlot(renderChildren, mergeScope, schema, isCustomElm) } } else { - return parseData(children, mergeScope) + return parseData(renderChildren, mergeScope) } } diff --git a/packages/controller/package.json b/packages/controller/package.json index 52711a182..195ef2baa 100644 --- a/packages/controller/package.json +++ b/packages/controller/package.json @@ -33,6 +33,7 @@ "@opentiny/tiny-engine-common": "workspace:^1.0.0", "@opentiny/tiny-engine-http": "workspace:^1.0.0", "@opentiny/tiny-engine-utils": "workspace:^1.0.0", + "@opentiny/tiny-engine-builtin-component": "workspace:*", "@opentiny/vue": "~3.10.0", "@opentiny/vue-renderless": "~3.10.0", "@vue/shared": "^3.3.4", diff --git a/packages/controller/src/useResource.js b/packages/controller/src/useResource.js index 597a7489c..cce041c57 100644 --- a/packages/controller/src/useResource.js +++ b/packages/controller/src/useResource.js @@ -15,13 +15,14 @@ import { getGlobalConfig } from './globalConfig' import { useHttp } from '@opentiny/tiny-engine-http' import { utils, constants } from '@opentiny/tiny-engine-utils' import { Builtin, addScript, addStyle, canvasDispatch } from '@opentiny/tiny-engine-canvas' +import { getCanvasStatus } from '@opentiny/tiny-engine-common/js/index' +import { meta as BuiltinComponentMaterials } from '@opentiny/tiny-engine-builtin-component' import useApp from './useApp' import useCanvas from './useCanvas' import useTranslate from './useTranslate' import useEditorInfo from './useEditorInfo' import useBreadcrumb from './useBreadcrumb' import useLayout from './useLayout' -import { getCanvasStatus } from '@opentiny/tiny-engine-common/js/index' import useBlock from './useBlock' import useNotify from './useNotify' @@ -371,8 +372,15 @@ const fetchResource = async ({ isInit = true } = {}) => { const { id, type } = useEditorInfo().useInfo() useApp().appInfoState.selectedId = id - Builtin.data.materials.components[0]?.children.map(registerComponent) - resState.components.push(...Builtin.data.materials.snippets) + Builtin.data.materials.components[0].children.map(registerComponent) + BuiltinComponentMaterials.components[0].children.map(registerComponent) + + const builtinSnippets = { + group: '内置组件', + children: [...Builtin.data.materials.snippets[0].children, ...BuiltinComponentMaterials.snippets[0].children] + } + + resState.components.push(builtinSnippets) const appData = await useHttp().get(`/app-center/v1/api/apps/schema/${id}`) resState.pageTree = appData.componentsTree diff --git a/packages/design-core/vite.config.js b/packages/design-core/vite.config.js index 6c9c858f8..24599c9df 100644 --- a/packages/design-core/vite.config.js +++ b/packages/design-core/vite.config.js @@ -171,7 +171,8 @@ const devAlias = { '@opentiny/tiny-engine-theme': path.resolve(__dirname, `../theme/${lowcodeConfig.theme}/index.less`), '@opentiny/tiny-engine-utils': path.resolve(__dirname, '../utils/src/index.js'), '@opentiny/tiny-engine-webcomponent-core': path.resolve(__dirname, '../webcomponent/src/lib.js'), - '@opentiny/tiny-engine-i18n-host': path.resolve(__dirname, '../i18n/src/lib.js') + '@opentiny/tiny-engine-i18n-host': path.resolve(__dirname, '../i18n/src/lib.js'), + '@opentiny/tiny-engine-builtin-component': path.resolve(__dirname, '../builtinComponent/index.js') } const devVueAlias = { diff --git a/packages/vue-generator/.gitignore b/packages/vue-generator/.gitignore new file mode 100644 index 000000000..d180ec5e2 --- /dev/null +++ b/packages/vue-generator/.gitignore @@ -0,0 +1 @@ +test/testcases/full/**/result/* diff --git a/packages/vue-generator/package.json b/packages/vue-generator/package.json index db8abc3e8..742c1b98b 100644 --- a/packages/vue-generator/package.json +++ b/packages/vue-generator/package.json @@ -26,6 +26,7 @@ "license": "MIT", "homepage": "https://opentiny.design/tiny-engine", "dependencies": { + "@opentiny/tiny-engine-builtin-component": "workspace:*", "@vue/compiler-sfc": "3.2.45", "@vue/shared": "^3.3.4", "vue": "3.2.45", diff --git a/packages/vue-generator/src/constant/index.js b/packages/vue-generator/src/constant/index.js index 987a5c26f..e0d66e209 100644 --- a/packages/vue-generator/src/constant/index.js +++ b/packages/vue-generator/src/constant/index.js @@ -1,14 +1,14 @@ /** -* 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. -* -*/ + * 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. + * + */ /** * 组件映射关系,默认使用 Tiny Vue 组件,支持传入其它组件库的映射关系 @@ -2173,6 +2173,31 @@ const DEFAULT_COMPONENTS_MAP = [ } ] +// 内置组件映射关系 +const BUILTIN_COMPONENTS_MAP = [ + { + componentName: 'CanvasRow', + exportName: 'CanvasRow', + package: '@opentiny/tiny-engine-builtin-component', + version: '^0.1.0', + destructuring: true + }, + { + componentName: 'CanvasCol', + exportName: 'CanvasCol', + package: '@opentiny/tiny-engine-builtin-component', + version: '^0.1.0', + destructuring: true + }, + { + componentName: 'CanvasRowColContainer', + exportName: 'CanvasRowColContainer', + package: '@opentiny/tiny-engine-builtin-component', + version: '^0.1.0', + destructuring: true + } +] + /** * 内部保留组件名称,出码时可能需要特殊处理 */ @@ -2210,4 +2235,4 @@ export const [JS_EXPRESSION, JS_FUNCTION, JS_I18N, JS_RESOURCE, JS_SLOT] = [ 'JSSlot' ] -export { DEFAULT_COMPONENTS_MAP, BUILTIN_COMPONENT_NAME, TINY_ICON, UNWRAP_QUOTES } +export { DEFAULT_COMPONENTS_MAP, BUILTIN_COMPONENT_NAME, TINY_ICON, UNWRAP_QUOTES, BUILTIN_COMPONENTS_MAP } diff --git a/packages/vue-generator/src/generator/page.js b/packages/vue-generator/src/generator/page.js index 2bf835f81..d331e20a8 100644 --- a/packages/vue-generator/src/generator/page.js +++ b/packages/vue-generator/src/generator/page.js @@ -31,7 +31,8 @@ import { JS_FUNCTION, JS_RESOURCE, JS_SLOT, - TINY_ICON + TINY_ICON, + BUILTIN_COMPONENTS_MAP } from '../constant' function recurseChildren(children, state, description, result) { @@ -269,7 +270,7 @@ const generateImports = (description, moduleName, type, componentsMap) => { return exportName } - return exportName ? `${exportName} as ${componentName}` : `${componentName}` + return exportName && exportName !== componentName ? `${exportName} as ${componentName}` : `${componentName}` }) imports.push(`import { ${items.join(',')} } from '${pkgName}'`) @@ -496,7 +497,7 @@ const generateCode = ({ pageInfo, componentsMap = [], blocksData = [] }) => { const validComponents = componentsMap.filter( ({ componentName, package: pkg, main }) => componentName && (pkg || typeof main === 'string') ) - const allComponents = [...validComponents, ...DEFAULT_COMPONENTS_MAP] + const allComponents = [...validComponents, ...DEFAULT_COMPONENTS_MAP, ...BUILTIN_COMPONENTS_MAP] // 对象数组,去重 const allComponentsMap = new Map() diff --git a/packages/vue-generator/test/testcases/full/case4_canvasrow-component/input/blocks.schema.json b/packages/vue-generator/test/testcases/full/case4_canvasrow-component/input/blocks.schema.json new file mode 100644 index 000000000..fe51488c7 --- /dev/null +++ b/packages/vue-generator/test/testcases/full/case4_canvasrow-component/input/blocks.schema.json @@ -0,0 +1 @@ +[] diff --git a/packages/vue-generator/test/testcases/full/case4_canvasrow-component/input/components-map.json b/packages/vue-generator/test/testcases/full/case4_canvasrow-component/input/components-map.json new file mode 100644 index 000000000..fe51488c7 --- /dev/null +++ b/packages/vue-generator/test/testcases/full/case4_canvasrow-component/input/components-map.json @@ -0,0 +1 @@ +[] diff --git a/packages/vue-generator/test/testcases/full/case4_canvasrow-component/input/page.schema.json b/packages/vue-generator/test/testcases/full/case4_canvasrow-component/input/page.schema.json new file mode 100644 index 000000000..a66f018a3 --- /dev/null +++ b/packages/vue-generator/test/testcases/full/case4_canvasrow-component/input/page.schema.json @@ -0,0 +1,161 @@ +{ + "state": {}, + "methods": {}, + "componentName": "Page", + "fileName": "createVm", + "css": "", + "props": {}, + "lifeCycles": {}, + "children": [ + { + "componentName": "CanvasRowColContainer", + "props": { + "rowGap": "20px" + }, + "children": [ + { + "componentName": "CanvasRow", + "props": { + "rowGap": "20px", + "colGap": "20px" + }, + "children": [ + { + "componentName": "CanvasCol", + "props": { + "rowGap": "20px", + "colGap": "20px", + "grow": true, + "shrink": true, + "widthType": "auto" + }, + "id": "4514b344" + }, + { + "componentName": "CanvasCol", + "props": { + "rowGap": "20px", + "colGap": "20px", + "grow": true, + "shrink": true, + "widthType": "auto" + }, + "children": [], + "id": "3664a254" + } + ], + "id": "63553246" + }, + { + "componentName": "CanvasRow", + "props": { + "rowGap": "20px", + "colGap": "20px" + }, + "children": [ + { + "componentName": "CanvasCol", + "props": { + "rowGap": "20px", + "colGap": "20px", + "grow": true, + "shrink": true, + "widthType": "auto" + }, + "id": "2c13444f", + "children": [ + { + "componentName": "CanvasRow", + "props": { + "rowGap": "20px", + "colGap": "20px" + }, + "children": [ + { + "componentName": "CanvasCol", + "props": { + "rowGap": "20px", + "colGap": "20px", + "grow": true, + "shrink": true, + "widthType": "auto" + }, + "children": [], + "id": "24256327" + } + ], + "id": "56453426" + }, + { + "componentName": "CanvasRow", + "props": { + "rowGap": "20px", + "colGap": "20px" + }, + "children": [ + { + "componentName": "CanvasCol", + "props": { + "rowGap": "20px", + "colGap": "20px", + "grow": true, + "shrink": true, + "widthType": "auto" + }, + "id": "5451f224" + } + ], + "id": "26364626" + }, + { + "componentName": "CanvasRow", + "props": { + "rowGap": "20px", + "colGap": "20px" + }, + "children": [ + { + "componentName": "CanvasCol", + "props": { + "rowGap": "20px", + "colGap": "20px", + "grow": true, + "shrink": true, + "widthType": "auto" + }, + "children": [], + "id": "26232436" + } + ], + "id": "52555445" + } + ] + }, + { + "componentName": "CanvasCol", + "props": { + "rowGap": "20px", + "colGap": "20px", + "grow": true, + "shrink": true, + "widthType": "auto" + }, + "children": [], + "id": "53553563" + } + ], + "id": "53b5fe13" + } + ], + "id": "25452c43" + } + ], + "dataSource": { + "list": [] + }, + "bridge": { + "imports": [] + }, + "inputs": [], + "outputs": [] +} diff --git a/packages/vue-generator/test/testcases/full/case4_canvasrow-component/output/BuiltInComponent.vue b/packages/vue-generator/test/testcases/full/case4_canvasrow-component/output/BuiltInComponent.vue new file mode 100644 index 000000000..4ac5f6aad --- /dev/null +++ b/packages/vue-generator/test/testcases/full/case4_canvasrow-component/output/BuiltInComponent.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/packages/vue-generator/test/testcases/full/index.config.js b/packages/vue-generator/test/testcases/full/index.config.js index 2a6ccea62..6d6c8a064 100644 --- a/packages/vue-generator/test/testcases/full/index.config.js +++ b/packages/vue-generator/test/testcases/full/index.config.js @@ -1,14 +1,14 @@ /** -* 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. -* -*/ + * 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. + * + */ module.exports = { description: @@ -28,6 +28,11 @@ module.exports = { name: 'case3_state-accessor', pageName: 'UseStateAccessor', description: '测试区块的 state 支持 accessor 协议' + }, + { + name: 'case4_canvasrow-component', + pageName: 'BuiltInComponent', + description: '测试内置组件 CanvasRow、CanvasCol、CanvasRowColContainer' } ], input: { diff --git a/packages/vue-generator/test/testcases/full/index.js b/packages/vue-generator/test/testcases/full/index.js index bddead547..7f9d2b8ea 100644 --- a/packages/vue-generator/test/testcases/full/index.js +++ b/packages/vue-generator/test/testcases/full/index.js @@ -1,20 +1,20 @@ /** -* 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. -* -*/ + * 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. + * + */ const path = require('path') const fs = require('fs-extra') const prettier = require('prettier') const { execSync } = require('child_process') -const { generateCode } = require('../../../dist/lowcode-dsl-vue.cjs.js') +const { generateCode } = require('../../../dist/tiny-engine-dsl-vue.cjs') const { logger } = require('../../utils/logger') const getPageData = (testCaseFile) => {