diff --git a/src/App.vue b/src/App.vue index 0434bf6..a3246da 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,7 +1,8 @@ - + diff --git a/src/engineer/components/ConfigCurrentView.vue b/src/engineer/components/ConfigCurrentView.vue index 2e672fc..5b5fcfd 100644 --- a/src/engineer/components/ConfigCurrentView.vue +++ b/src/engineer/components/ConfigCurrentView.vue @@ -32,12 +32,14 @@ const label = computed(()=>{ - {{ ctx.activeViewId }} + {{ ctx.activeBlockId }} + {{ ctx.activeViewId }} + {{styles}} {{ label }}设置 - + diff --git a/src/engineer/configs/ListConfig.vue b/src/engineer/configs/ListConfig.vue index 51b2d7b..a302601 100644 --- a/src/engineer/configs/ListConfig.vue +++ b/src/engineer/configs/ListConfig.vue @@ -14,6 +14,7 @@ const props = defineProps<{ help?: string required?: boolean configs: ModuleConfig[] + addable?: boolean }>() // const ctx = useContext() @@ -53,7 +54,7 @@ const minus = () => { - + +增加 -减少 diff --git a/src/engineer/configs/TextConfig.vue b/src/engineer/configs/TextConfig.vue index 430fc76..bdcea6a 100644 --- a/src/engineer/configs/TextConfig.vue +++ b/src/engineer/configs/TextConfig.vue @@ -17,7 +17,7 @@ const data = useSource(props.field) - + {{ label }} * diff --git a/src/engineer/types.ts b/src/engineer/types.ts index e48f3f2..03fabfb 100644 --- a/src/engineer/types.ts +++ b/src/engineer/types.ts @@ -142,7 +142,7 @@ export type TextAlign = */ export type Axis = 'x' | 'y' -export type Attach = { +export type Attach = { [p in keyof Data]: Data[p] | Append } @@ -157,7 +157,7 @@ export interface Textual { /** 字体大小 */ fontSize?: number /** 字体粗细 */ - fontWeight?: 400|500|600|700|800|900 + fontWeight?: 400 | 500 | 600 | 700 | 800 | 900 /** 文本方向 */ textAlign?: TextAlign /** 行高,行高比较特殊,需要转换单位 */ @@ -217,7 +217,7 @@ export interface Decoration { * */ export interface BoxBlock { - display?: 'block' | 'inline-block' + display?: 'block' | 'inline-block' | 'flex' whiteSpace?: 'nowrap' | 'pre' } @@ -236,7 +236,6 @@ export interface Spatial { } - /** * 盒子策略 * @@ -294,7 +293,7 @@ export type ClipBehavior = * * 描述了视图的基本布局和外观表现。 */ -export interface Theme extends Textual, Flexible,BoxBlock, Boxed, Decoration, Spatial, Flexible, Stacked { +export interface Theme extends Textual, Flexible, BoxBlock, Boxed, Decoration, Spatial, Flexible, Stacked { /** * 是否强制开启弹性布局 * @@ -419,10 +418,10 @@ export interface View { // theme?: Theme | Widget theme?: DynamicTheme title?: string - /** - * 关联数据源 - */ - source?: string + // /** + // * 关联数据源 + // */ + // source?: string /** 子视图 */ children?: ViewChildren } diff --git a/src/engineer/utils/hash.ts b/src/engineer/utils/hash.ts index 4691630..f69b4d6 100644 --- a/src/engineer/utils/hash.ts +++ b/src/engineer/utils/hash.ts @@ -15,3 +15,9 @@ export function hash(str: string): string { // Convert to 8 digit hex string return (`0000000${(hval >>> 0).toString(16)}`).slice(-8) } + +let nextId = Date.now() + +export function createUniqueId() { + return hash(`${++nextId}`) +} diff --git a/src/engineer/utils/index.ts b/src/engineer/utils/index.ts index da7dbd5..4fb869a 100644 --- a/src/engineer/utils/index.ts +++ b/src/engineer/utils/index.ts @@ -13,4 +13,4 @@ export * from './shadow' export * from './size' export * from './stack' export * from './unit' -export {dynamic} from "./dynamic.ts"; +export * from "./dynamic"; diff --git a/src/modules/image-cube.ts b/src/modules/image-cube.ts new file mode 100644 index 0000000..5cef1c7 --- /dev/null +++ b/src/modules/image-cube.ts @@ -0,0 +1,232 @@ +import { createUniqueId } from '../engineer/utils' +import type { Module } from '../engineer' + +const module: Module = { + title: '图片魔方', + vid: createUniqueId(), + mid: createUniqueId(), + maxReferenceCount: -1, + referenceCount: 0, + image: undefined, + init: { + setting:{ + style: '#two' + }, + items:[ + {image:''}, + {image:''}, + {image:''}, + {image:''}, + ] + }, + templates:{ + '#one':{ + theme: { + color: 'white', + padding: 5, + width: '100%', + height: 375, + flexible: true, + mainAlign: 'center', + crossAlign: 'center', + }, + children: { + type: 'text', + key: 'items.0.link' +} + }, + '#two':{ + theme: { + color: 'white', + padding: 5, + width: '100%', + height: 200, + flexible: true, + mainAlign: 'between', + crossAlign: 'center', + }, + children: [{ + theme:{width:'49%',flexible: true, + mainAlign: 'center', + crossAlign: 'center',}, + children: { type: 'text', key: 'items.0.link' } + },{ + children: { + type: 'text', + key: 'items.1.link' + }, + theme:{width:'49%',flexible: true, + mainAlign: 'center', + crossAlign: 'center',} + }] + }, + '#four':{ + theme: { + color: 'white', + padding: 5, + width: '100%', + height: 375, + flexible: true, + mainAlign: 'between', + crossAlign: 'center', + }, + children: [{ + theme:{width:'49%',flexible: true, + mainAlign: 'center', + crossAlign: 'center',height:'100%'}, + children: { type: 'text', key: 'items.0.link' } + },{ + children: [ + { + theme:{width:'100%',flexible: true, + mainAlign: 'center', + crossAlign: 'center',height:'49%'}, + children: { type: 'text', key: 'items.1.link' } + }, + { + theme:{width:'100%',flexible: true, + mainAlign: 'center', + crossAlign: 'center',height:'49%'}, + children: { type: 'text', key: 'items.2.link' } + }, + ], + theme:{width:'49%',flexible:true, + mainAlign: 'between',axis:"y", + height:'100%'} + }] + }, + '#three':{ + theme: { + color: 'white', + padding: 5, + width: '100%', + height: 200, + flexible: true, + mainAlign: 'between', + crossAlign: 'center', + }, + children: [{ + theme:{width:'32%',flexible: true, + mainAlign: 'center', + crossAlign: 'center',height:'100%'}, + children: { type: 'text', key: 'items.0.link' } + }, + {theme:{width:'32%',flexible: true, + mainAlign: 'center', + crossAlign: 'center',height:'100%'}, + children: { type: 'text', key: 'items.1.link' }}, + {theme:{width:'32%',flexible: true, + mainAlign: 'center', + crossAlign: 'center',height:'100%'}, + children: { type: 'text', key: 'items.2.link' }}, + ] + }, + '#five':{ + theme: { + color: 'white', + padding: 5, + width: '100%', + height: 375, + flexible: true, + mainAlign: 'between', + crossAlign: 'center', + }, + children: [ + { + theme:{width:'49%',flexible:true, + mainAlign: 'between',axis:"y", + height:'100%'}, + children: [ + { + theme:{width:'100%',flexible: true, + mainAlign: 'center', + crossAlign: 'center',height:'49%'}, + children: { type: 'text', key: 'items.1.link' } + }, + { + theme:{width:'100%',flexible: true, + mainAlign: 'center', + crossAlign: 'center',height:'49%'}, + children: { type: 'text', key: 'items.2.link' } + }, + ], + }, + { + theme: { + width: '49%', flexible: true, + mainAlign: 'between', axis: "y", + height: '100%' + }, + children: [ + { + theme: { + width: '100%', flexible: true, + mainAlign: 'center', + crossAlign: 'center', height: '49%' + }, + children: { type: 'text', key: 'items.1.link' } + }, + { + theme: { + width: '100%', flexible: true, + mainAlign: 'center', + crossAlign: 'center', height: '49%' + }, + children: { type: 'text', key: 'items.2.link' } + }, + ], + }, + ] + }, + }, + configs:[ + { + type: 'object', + field: 'setting', + label: '图片魔方样式选择', + configs: [{ + type: 'mark', + field: 'style', + label: '', + values: [ + { label: '口', value: '#one' }, + { label: '口口', value: '#two' }, + { label: '口口口', value: '#three' }, + { label: '口日', value: '#four' }, + { label: '田', value: '#five' }, + ], + }] + }, + { + addable: false, + type: 'list', + field: 'items', + label: '图片', + configs: [ + { + type: 'image', + label: '产品图片', + field: 'image', + // 表示内联数据 + inlines: [{ + type: 'text', + field: 'link', + label: '链接', + help: '请输入链接', // 自动生成:"请输入${label}" + }] + }, + + ] + }, + ], + theme:{ + padding:5, + color:'white', + height: 375 + }, + children: { + type: 'template', + key: 'setting.style' + }, +} +export default module diff --git a/src/modules/index.ts b/src/modules/index.ts new file mode 100644 index 0000000..741b1d2 --- /dev/null +++ b/src/modules/index.ts @@ -0,0 +1,446 @@ +import productGroup from "./prduct-group" +import imageCube from './image-cube.ts' +import { createUniqueId } from '../engineer/utils' +import { Category } from '../engineer' + +export default { + icon: 'trash', + text: '基础', + modules: [ + { + vid: createUniqueId(), + mid: createUniqueId(), + title: '轮播图', + maxReferenceCount: -1, + referenceCount: 0, + image: undefined, + configs: [ + { + type: 'list', + field: 'items', + label: '轮播图设置', + help: '最多可添加10张图片,建议宽度750px;鼠标拖拽左侧圆点可调整图片顺序', + addable: true, + configs: [{ + type: 'image', + field: 'image', + label: '图片', + required: true, + // 表示内联数据 + inlines: [{ + type: 'text', + field: 'title', + label: '标题', + help: '选填,不超过 4 个字', + }, { + type: 'text', + field: 'link', + label: '链接', + help: '请输入链接', // 自动生成:"请输入${label}" + }], + }], + }, + { + type: 'object', + field: 'indicator', + label: '指示器', + configs: [{ + type: 'mark', + field: 'style', + label: '指示器样式', + values: [ + { label: '圆形', value: '#circle' }, + { label: '直线', value: '#line' }, + { label: '数字', value: '#number' }, + ], + }, { + type: 'mark', + field: 'position', + label: '指示器位置', + values: [ + { label: '居左', value: 'start' }, + { label: '居中', value: 'center' }, + { label: '居右', value: 'end' }, + ], + }, + { + type: 'color', + field: 'color', + label: '指示器颜色', + }], + }, + { + type: 'object', + field: 'background', + label: '背景', + configs: [{ + type: 'boolean', + field: 'enabled', + label: '是否显示背景色', + }, { + type: 'background', + field: 'value', + // 背景的不同实现方式,可以在里面添加 image 选项来支持图片 + // 这里只能支持颜色和渐变, + features: ['color', 'gradient'], + label: '背景', + }], + } + ], + init: { + items: [ + { + image: '', + title: '123', + link: '123', + } + ], + indicator: { + style: '#circle', + color: 'green', + position: 'start', + }, + background: { + enabled: true, + value: "#ffffff", + }, + theme: { + color: 'white', + radius: 24 + } + }, + templates: { + '#circle': { + theme: { + gap: 20, + }, + children: { + type: 'each', + key: 'items', + handle: { + theme: { + width: 20, + height: 20, + radius: 10, + color: '@@indicator.color', + }, + } + } + }, + '#line': { + theme: { + gap: 20, + }, + children: { + type: 'each', + key: 'items', + handle: { + theme: { + width: 40, + height: 20, + color: '@@indicator.color', + }, + } + } + }, + "#number": { + theme: { + color: 'rgba(0,0,0,0.4)', + textColor: '#fff' + }, + children: '1/len(items)' + } + }, + theme: { + position: 'relative', + height: 200, + padding: { + horizontal: 12.0, + vertical: 12, + }, + color: 'cyan', + }, + children: [ + { + vid: createUniqueId(), + theme: { + width: '100%', + height: '100%', + color: '@@theme.color', + radius: "@@theme.radius", + textAlign: 'center', + }, + children: '设置轮播图', + }, + { + theme: { + position: 'absolute', + flexible: true, + mainAlign: '@@indicator.position', + bottom: 20, + left: 20, + right: 20, + height: 20, + color: 'red', + }, + children: { + type: 'template', + key: 'indicator.style' + } + }], + }, + productGroup, + { + title: '产品分类', + vid: createUniqueId(), + mid: createUniqueId(), + maxReferenceCount: -1, + referenceCount: 0, + image: undefined, + configs: [ + { + help: '帮助', + addable: true, + type: 'list', + field: 'items', + label: '产品分类列表', + configs: [ + { + type: 'image', + label: '分类图片', + field: 'itemImage', + // 表示内联数据 + inlines: [{ + type: 'text', + field: 'link', + label: '链接', + help: '请输入链接', // 自动生成:"请输入${label}" + }, + { + type: 'text', + label: '自定义标题', + field: 'title', + }, + ] + }, + ] + }, + ], + init: { + theme: { + color: '#fff', + }, + items: [ + { + title: '标题', + link: 'link' + } + ] + }, + theme: { + padding: 12, + color: '@@theme.color', + }, + children: { + theme: { + width: '100%', + clip: 'autoX', + whiteSpace: 'nowrap', + }, + children: { + type: 'each', + key: 'items', + handle: { + theme: { + width: '60px', + height: '60px', + display: 'inline-block', + radius: 40, + color: 'pink', + textColor: '#fff', + margin: { + right: 10 + }, + }, + children: '图片', + } + }, + } + }, + { + title: '两列产品卡片', + vid: createUniqueId(), + mid: createUniqueId(), + maxReferenceCount: -1, + referenceCount: 0, + image: undefined, + configs: [], + init: {}, + theme: { + color: 'pink', + padding: { + top: 12.5, + left: 12.5, + right: 12.5 + }, + gap: 10, + }, + children: [ + { + theme: { + width: 170, + height: 200, + color: 'white' + }, + children: '产品' + }, + { + theme: { + width: 170, + height: 200, + color: 'white' + }, + children: '产品' + } + ] + }, + { + title: '自定义标题', + vid: createUniqueId(), + mid: createUniqueId(), + maxReferenceCount: -1, + referenceCount: 0, + image: undefined, + configs: [ + { + type: 'text', + field: 'Title', + label: '标题', + help: '自定义标题', // 自动生成:"请输入${label}" + }, + ], + init: { + Title: '猜你喜欢', + }, + theme: { + padding: { + vertical: 15, + horizontal: 15, + }, + color: '#fff', + textColor: '#333', + fontSize: '@@theme.fontSize', + fontWeight: 900, + }, + children: { + type: 'text', + key: 'Title' + } + + }, + { + title: '搜索框', + vid: createUniqueId(), + mid: createUniqueId(), + maxReferenceCount: -1, + referenceCount: 0, + image: undefined, + configs: [ + { + type: 'object', + field: 'search', + label: '搜索框', + configs: [ + { + required: true, + type: 'text', + label: '搜索框内容', + field: 'innerText' + }, + { + type: 'boolean', + field: 'showLogo', + label: '是否展示左侧logo', + }, { + type: 'image', + field: 'logoImg', + label: '左侧logo', + } + ] + }, + ], + init: {}, + templates: { + 'true': { + theme: {}, + children: 'logo' + }, + 'false': { + theme: {}, + children: '' + } + }, + theme: { + display: 'flex', + crossAlign: 'center', + padding: { + horizontal: 15, + vertical: 8, + }, + color: 'cyan' + }, + children: [ + { + children: { + type: 'template', + key: 'search.showLogo' + }, + }, + { + theme: { width: 10 }, + }, + { + theme: { + width: '60%', + color: 'white', + radius: 30.0, + padding: { + horizontal: 10, + vertical: 5, + }, + fontSize: 14, + }, + children: '猜你喜欢' + } + ] + }, + imageCube, + { + title: '商品分类', + vid: createUniqueId(), + mid: createUniqueId(), + maxReferenceCount: -1, + referenceCount: 0, + image: undefined, + init: {}, + templates:{}, + configs:[], + theme:{ + color: 'white', + gap: 15, + fontSize:14, + fontWeight: 400, + padding:10, + }, + children:[ + {children:'产品分类',theme:{fontWeight:600}}, + {children:'产品分类'}, + {children:'产品分类'}, + {children:'产品分类'}, + {children:'产品分类'}, + ], + } + + + ], +} as Category diff --git a/src/modules/prduct-group.ts b/src/modules/prduct-group.ts new file mode 100644 index 0000000..6c23b3d --- /dev/null +++ b/src/modules/prduct-group.ts @@ -0,0 +1,234 @@ +import { createUniqueId } from '../engineer/utils' +import type { Module } from '../engineer' + +const module: Module = { + title: '产品组', + vid: createUniqueId(), + mid: createUniqueId(), + maxReferenceCount: -1, + referenceCount: 0, + image: undefined, + configs: [ + { + type: 'object', + field: 'titleAndDesc', + label: '产品标题及说明', + configs: [ + { + type: 'text', + label: '产品标题', + field: 'mainTitle' + }, + { + type: 'text', + label: '说明', + field: 'content', + }, + { + type: 'text', + label: '提示', + field: 'more', + }, + ] + }, + { + help: '帮助', + addable: true, + type: 'list', + field: 'groups', + label: '产品组列表', + configs: [ + { + type: 'image', + label: '产品图片', + field: 'image', + // 表示内联数据 + inlines: [{ + type: 'text', + field: 'link', + label: '链接', + help: '请输入链接', // 自动生成:"请输入${label}" + }, + { + type: 'text', + label: '自定义标题', + field: 'title', + }, + + ] + }, + ] + }, + ], + init: { + titleAndDesc: { + mainTitle: '标题123', + content: '说明123', + more: '查看更多', + }, + groups: [ + { + title: '111', + } + ], + theme: { + color: 'pink', + moreColor: "#5d35b0", + }, + children: { + theme: { + radius: 12 + }, + } + }, + theme: { + // height: 200, + padding: 10, + color: '@@theme.color', + }, + children: { + vid: createUniqueId(), + theme: { + width: '100%', + height: '100%', + color: 'white', + clip: 'hidden', + radius: '@@children.theme.radius', + textAlign: 'center', + }, + children: [ + { + theme: { + flexible: true, + gap: 12, + crossAlign: 'center', + }, + children: [ + { + theme: { + padding: { + horizontal: 5 + }, + }, + children: [ + { + theme: { + flexible: true, + gap: 5, + crossAlign: 'center', + }, + children: [ + { + theme: { + fontSize: 16, + }, + children: { + type: 'text', + key: 'titleAndDesc.mainTitle' + }, + }, + { + theme: { + fontSize: 16, + }, + children: { + type: 'text', + key: 'titleAndDesc.content' + }, + } + ] + }, + ] + }, + { + theme: { + grow: 1, + } + }, + { + vid: createUniqueId(), + theme: { + width: 'auto', + margin: { + horizontal: 5, + }, + fontSize: 12, + padding: { + vertical: 1, + horizontal: 5, + }, + color: '@@theme.moreColor', + textColor: '#fff', + radius: 16, + }, + children: { + type: 'text', + key: 'titleAndDesc.more' + }, + }, + + ], + }, + { + vid: createUniqueId(), + theme: { + width: "94%", + height: "70%", + color: 'pink', + radius: 12.0, + flexible: true, + gap: 12, + margin: { + top: '1%', + left: '3%', + right: '3%', + bottom: '2%', + }, + padding: 2, + clip: 'autoX', + textAlign: 'left', + }, + children: { + type: 'each', + key: "groups", + handle: { + theme: { + width: 100, + height: '100%', + radius: 10, + color: 'red', + }, + children: [ + { + theme: { + width: 100, + height: 100, + border: { + color: "black", + width: 2, + }, + }, + children: { + type: 'image', + key: ".image" + }, + }, + { + theme: { + textColor: "white", + fontSize: 18 + }, + children: { + type: "text", + key: ".title" + }, + } + ] + }, + } + }, + ] + } +} + +export default module