|
|
@@ -7,8 +7,10 @@ import type {
|
|
|
} from '@/types/event'
|
|
|
import type { OptionType } from './type'
|
|
|
|
|
|
+import { get } from 'lodash-es'
|
|
|
import { klona } from 'klona'
|
|
|
import { bfsWalk } from 'simple-mind-map/src/utils'
|
|
|
+
|
|
|
import LvglWidgets from '@/lvgl-widgets'
|
|
|
import { flagOptions, stateOptions } from '@/constants'
|
|
|
|
|
|
@@ -17,25 +19,38 @@ type SchemaActionDescriptor = {
|
|
|
defaultValue: any
|
|
|
label: string
|
|
|
schemas: ComponentSchema[]
|
|
|
+ groupKey?: string
|
|
|
+ groupLabel?: string
|
|
|
+ groupOrder?: number
|
|
|
+}
|
|
|
+
|
|
|
+type EventSettableSchema = ComponentSchema & {
|
|
|
+ canUseEventSet?: boolean
|
|
|
+ dependency?: (values: Record<string, any>) => ComponentSchema[] | ComponentSchema
|
|
|
+ name?: string[]
|
|
|
+}
|
|
|
+
|
|
|
+type EventStyleSchema = ComponentSchema & {
|
|
|
+ key: string
|
|
|
}
|
|
|
|
|
|
const pageLoadAnimationOptions = [
|
|
|
- { label: 'None', value: 'none' },
|
|
|
- { label: 'Over Left', value: 'over_left' },
|
|
|
- { label: 'Over Right', value: 'over_right' },
|
|
|
- { label: 'Over Top', value: 'over_top' },
|
|
|
- { label: 'Over Bottom', value: 'over_bottom' },
|
|
|
- { label: 'Move Left', value: 'move_left' },
|
|
|
- { label: 'Move Right', value: 'move_right' },
|
|
|
- { label: 'Move Top', value: 'move_top' },
|
|
|
- { label: 'Move Bottom', value: 'move_bottom' },
|
|
|
- { label: 'Fade In', value: 'fade_in' },
|
|
|
- { label: 'Fade On', value: 'fade_on' },
|
|
|
- { label: 'Fade Out', value: 'fade_out' },
|
|
|
- { label: 'Out Left', value: 'out_left' },
|
|
|
- { label: 'Out Right', value: 'out_right' },
|
|
|
- { label: 'Out Top', value: 'out_top' },
|
|
|
- { label: 'Out Bottom', value: 'out_bottom' }
|
|
|
+ { label: '无', value: 'none' },
|
|
|
+ { label: '覆盖左侧', value: 'over_left' },
|
|
|
+ { label: '覆盖右侧', value: 'over_right' },
|
|
|
+ { label: '覆盖顶部', value: 'over_top' },
|
|
|
+ { label: '覆盖底部', value: 'over_bottom' },
|
|
|
+ { label: '左移', value: 'move_left' },
|
|
|
+ { label: '右移', value: 'move_right' },
|
|
|
+ { label: '上移', value: 'move_top' },
|
|
|
+ { label: '下移', value: 'move_bottom' },
|
|
|
+ { label: '淡入', value: 'fade_in' },
|
|
|
+ { label: '淡开', value: 'fade_on' },
|
|
|
+ { label: '淡出', value: 'fade_out' },
|
|
|
+ { label: '退出左侧', value: 'out_left' },
|
|
|
+ { label: '退出右侧', value: 'out_right' },
|
|
|
+ { label: '退出顶部', value: 'out_top' },
|
|
|
+ { label: '退出底部', value: 'out_bottom' }
|
|
|
]
|
|
|
|
|
|
const eventOption = (
|
|
|
@@ -95,6 +110,656 @@ const commonEventOptions = [
|
|
|
eventOption('Cancel', 'LV_EVENT_CANCEL')
|
|
|
]
|
|
|
|
|
|
+/**
|
|
|
+ * 事件编辑统一样式配置
|
|
|
+ * 仅在控件自身存在 config.styles 时启用
|
|
|
+ */
|
|
|
+const styleSchemas: EventStyleSchema[] = [
|
|
|
+ {
|
|
|
+ key: 'background.color',
|
|
|
+ label: '背景颜色',
|
|
|
+ field: 'background.color',
|
|
|
+ valueType: 'color',
|
|
|
+ defaultValue: '#000000ff'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'background.alpha',
|
|
|
+ label: '背景透明度',
|
|
|
+ field: 'background.alpha',
|
|
|
+ valueType: 'color',
|
|
|
+ defaultValue: '#000000ff'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'background.gradient.direction',
|
|
|
+ label: '背景渐变方向',
|
|
|
+ field: 'background.alpha',
|
|
|
+ valueType: 'select',
|
|
|
+ defaultValue: 'none',
|
|
|
+ componentProps: {
|
|
|
+ options: [
|
|
|
+ { label: 'None', value: 'none' },
|
|
|
+ { label: 'Horizontal', value: 'horizontal' },
|
|
|
+ { label: 'Vertical', value: 'vertical' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'background.gradient.color',
|
|
|
+ label: '背景渐变颜色',
|
|
|
+ field: 'background.gradient.color',
|
|
|
+ valueType: 'color',
|
|
|
+ defaultValue: '#000000ff'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'background.gradient.alpha',
|
|
|
+ label: '背景渐变透明度',
|
|
|
+ field: 'background.gradient.alpha',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 255,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 255
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'background.gradient.start',
|
|
|
+ label: '背景渐变起始点',
|
|
|
+ field: 'background.gradient.start',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 255
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'background.gradient.end',
|
|
|
+ label: '背景渐变结束点',
|
|
|
+ field: 'background.gradient.end',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 255,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 255
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'background.image.imgId',
|
|
|
+ label: '背景图',
|
|
|
+ field: 'background.image.imgId',
|
|
|
+ valueType: 'image'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'background.image.recolor',
|
|
|
+ label: '背景图片遮罩',
|
|
|
+ field: 'background.image.recolor',
|
|
|
+ valueType: 'color',
|
|
|
+ defaultValue: '#ffffff00'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'background.image.alpha',
|
|
|
+ label: '背景透明度',
|
|
|
+ field: 'background.image.alpha',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 255,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 255
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'text.color',
|
|
|
+ label: '字体颜色',
|
|
|
+ field: 'text.color',
|
|
|
+ valueType: 'color',
|
|
|
+ defaultValue: '#000000ff'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'text.alpha',
|
|
|
+ label: '字体透明度',
|
|
|
+ field: 'text.alpha',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 255,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 255
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'text.family',
|
|
|
+ label: '字体',
|
|
|
+ field: 'text.family',
|
|
|
+ valueType: 'family',
|
|
|
+ defaultValue: 'montserratMedium'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'text.align',
|
|
|
+ label: '字体对齐',
|
|
|
+ field: 'text.align',
|
|
|
+ valueType: 'select',
|
|
|
+ defaultValue: 'left',
|
|
|
+ componentProps: {
|
|
|
+ options: [
|
|
|
+ { label: '左对齐', value: 'left' },
|
|
|
+ { label: '居中对齐', value: 'center' },
|
|
|
+ { label: '右对齐', value: 'right' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'text.decoration',
|
|
|
+ label: '字体装饰',
|
|
|
+ field: 'text.decoration',
|
|
|
+ valueType: 'select',
|
|
|
+ defaultValue: 'none',
|
|
|
+ componentProps: {
|
|
|
+ options: [
|
|
|
+ { label: 'None', value: 'none' },
|
|
|
+ { label: 'Underline', value: 'underline' },
|
|
|
+ { label: 'Strikethrough', value: 'line-through' },
|
|
|
+ { label: 'Underline&Strikethrough', value: 'underline line-through' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'spacer.letterSpacing',
|
|
|
+ label: '字间距',
|
|
|
+ field: 'spacer.letterSpacing',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: -10000,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'spacer.lineHeight',
|
|
|
+ label: '行间距',
|
|
|
+ field: 'spacer.lineHeight',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: -10000,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'border.color',
|
|
|
+ label: '边框颜色',
|
|
|
+ field: 'border.color',
|
|
|
+ valueType: 'color',
|
|
|
+ defaultValue: '#000000ff'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'border.alpha',
|
|
|
+ label: '边框透明度',
|
|
|
+ field: 'border.alpha',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 255,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 255
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'border.width',
|
|
|
+ label: '边框宽度',
|
|
|
+ field: 'border.width',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'border.radius',
|
|
|
+ label: '边框圆角',
|
|
|
+ field: 'border.radius',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'border.side',
|
|
|
+ label: '边框选择',
|
|
|
+ field: 'border.side',
|
|
|
+ valueType: 'checkbox',
|
|
|
+ defaultValue: ['all'],
|
|
|
+ componentProps: {
|
|
|
+ options: [
|
|
|
+ { label: '所有边框', value: 'all' },
|
|
|
+ { label: '左边框', value: 'left' },
|
|
|
+ { label: '上边框', value: 'top' },
|
|
|
+ { label: '下边框', value: 'bottom' },
|
|
|
+ { label: '右边框', value: 'right' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'outline.color',
|
|
|
+ label: '轮廓颜色',
|
|
|
+ field: 'outline.color',
|
|
|
+ valueType: 'color',
|
|
|
+ defaultValue: '#000000ff'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'outline.alpha',
|
|
|
+ label: '轮廓透明度',
|
|
|
+ field: 'outline.alpha',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 255,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 255
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'outline.width',
|
|
|
+ label: '轮廓宽度',
|
|
|
+ field: 'outline.width',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'outline.pad',
|
|
|
+ label: '轮廓间距',
|
|
|
+ field: 'outline.pad',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'padding.top',
|
|
|
+ label: '内上边距',
|
|
|
+ field: 'padding.top',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'padding.bottom',
|
|
|
+ label: '内下边距',
|
|
|
+ field: 'padding.bottom',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'padding.left',
|
|
|
+ label: '内左边距',
|
|
|
+ field: 'padding.left',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'padding.right',
|
|
|
+ label: '内右边距',
|
|
|
+ field: 'padding.right',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'padding.row',
|
|
|
+ label: '内行边距',
|
|
|
+ field: 'padding.row',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'padding.column',
|
|
|
+ label: '内列边距',
|
|
|
+ field: 'padding.column',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'margin.top',
|
|
|
+ label: '外上边距',
|
|
|
+ field: 'margin.top',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'margin.bottom',
|
|
|
+ label: '外下边距',
|
|
|
+ field: 'margin.bottom',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'margin.left',
|
|
|
+ label: '外左边距',
|
|
|
+ field: 'margin.left',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'margin.right',
|
|
|
+ label: '外右边距',
|
|
|
+ field: 'margin.right',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'shadow.color',
|
|
|
+ label: '阴影颜色',
|
|
|
+ field: 'shadow.color',
|
|
|
+ valueType: 'color',
|
|
|
+ defaultValue: '#000000ff'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'shadow.alpha',
|
|
|
+ label: '阴影透明度',
|
|
|
+ field: 'shadow.alpha',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 255,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 255
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'shadow.offsetX',
|
|
|
+ label: '阴影偏移X',
|
|
|
+ field: 'shadow.offsetX',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: -10000,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'shadow.offsetY',
|
|
|
+ label: '阴影偏移Y',
|
|
|
+ field: 'shadow.offsetY',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: -10000,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'shadow.spread',
|
|
|
+ label: '阴影扩散',
|
|
|
+ field: 'shadow.spread',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'shadow.width',
|
|
|
+ label: '阴影宽度',
|
|
|
+ field: 'shadow.width',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'transform.width',
|
|
|
+ label: '宽变换',
|
|
|
+ field: 'transform.width',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: -10000,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'transform.height',
|
|
|
+ label: '高变换',
|
|
|
+ field: 'transform.height',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: -10000,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'transform.translateX',
|
|
|
+ label: 'X变换',
|
|
|
+ field: 'transform.translateX',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: -10000,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'transform.translateY',
|
|
|
+ label: 'Y变换',
|
|
|
+ field: 'transform.translateY',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: -10000,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'transform.originX',
|
|
|
+ label: '中心X',
|
|
|
+ field: 'transform.originX',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: -10000,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'transform.originY',
|
|
|
+ label: '中心Y',
|
|
|
+ field: 'transform.originY',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: -10000,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'transform.rotate',
|
|
|
+ label: '旋转角度',
|
|
|
+ field: 'transform.rotate',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: -3600,
|
|
|
+ max: 3600
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'transform.scale',
|
|
|
+ label: '缩放',
|
|
|
+ field: 'transform.scale',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 256,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'imageStyle.alpha',
|
|
|
+ label: '图片透明度',
|
|
|
+ field: 'imageStyle.alpha',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 255,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 255
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'imageStyle.recolor',
|
|
|
+ label: '图片遮罩',
|
|
|
+ field: 'imageStyle.recolor',
|
|
|
+ valueType: 'color',
|
|
|
+ defaultValue: '#ffffff00'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'line.color',
|
|
|
+ label: '直线颜色',
|
|
|
+ field: 'line.color',
|
|
|
+ valueType: 'color',
|
|
|
+ defaultValue: '#000000ff'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'line.width',
|
|
|
+ label: '直线宽度',
|
|
|
+ field: 'line.width',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'line.radius',
|
|
|
+ label: '直线圆角',
|
|
|
+ field: 'line.radius',
|
|
|
+ valueType: 'switch',
|
|
|
+ defaultValue: false
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'line.dashWidth',
|
|
|
+ label: '虚线宽度',
|
|
|
+ field: 'line.dashWidth',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'line.dashGap',
|
|
|
+ label: '虚线间隔',
|
|
|
+ field: 'line.dashGap',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'curve.color',
|
|
|
+ label: '曲线颜色',
|
|
|
+ field: 'curve.color',
|
|
|
+ valueType: 'color',
|
|
|
+ defaultValue: '#000000ff'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'curve.image',
|
|
|
+ label: '曲线图片',
|
|
|
+ field: 'curve.image',
|
|
|
+ valueType: 'image',
|
|
|
+ defaultValue: ''
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'curve.width',
|
|
|
+ label: '曲线宽度',
|
|
|
+ field: 'curve.width',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'curve.radius',
|
|
|
+ label: '曲线圆角',
|
|
|
+ field: 'curve.radius',
|
|
|
+ valueType: 'switch',
|
|
|
+ defaultValue: false
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'other.length',
|
|
|
+ label: '长度',
|
|
|
+ field: 'other.length',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 10000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: 'animation.time',
|
|
|
+ label: '动画时间',
|
|
|
+ field: 'animation.time',
|
|
|
+ valueType: 'number',
|
|
|
+ defaultValue: 0,
|
|
|
+ componentProps: {
|
|
|
+ min: 0,
|
|
|
+ max: 100000
|
|
|
+ }
|
|
|
+ }
|
|
|
+]
|
|
|
+
|
|
|
export const widgetEventOptions = [...commonEventOptions]
|
|
|
|
|
|
export const pageEventOptions = [
|
|
|
@@ -105,20 +770,6 @@ export const pageEventOptions = [
|
|
|
eventOption('Unloaded', 'LV_EVENT_SCREEN_UNLOADED')
|
|
|
]
|
|
|
|
|
|
-const builtinVisibleAction: SchemaActionDescriptor = {
|
|
|
- actionKey: 'builtin.visible',
|
|
|
- label: '显示',
|
|
|
- defaultValue: true,
|
|
|
- schemas: [
|
|
|
- {
|
|
|
- label: '显示',
|
|
|
- field: 'payload',
|
|
|
- labelWidth: '120px',
|
|
|
- valueType: 'switch'
|
|
|
- }
|
|
|
- ]
|
|
|
-}
|
|
|
-
|
|
|
function getSchemaLabel(schema: ComponentSchema): string {
|
|
|
if (schema.label) return schema.label
|
|
|
|
|
|
@@ -182,55 +833,109 @@ function createDefaultValue(schema: ComponentSchema): any {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-function cloneActionSchema(schema: ComponentSchema): ComponentSchema {
|
|
|
+function createSchemaDefaultValue(defaultRoot: any, schema: ComponentSchema) {
|
|
|
+ if (schema.field) {
|
|
|
+ const currentValue = get(defaultRoot, schema.field)
|
|
|
+ if (currentValue !== undefined) return klona(currentValue)
|
|
|
+ }
|
|
|
+
|
|
|
+ return createDefaultValue(schema)
|
|
|
+}
|
|
|
+
|
|
|
+function cloneActionSchema(schema: ComponentSchema, targetField = 'payload'): ComponentSchema {
|
|
|
const cloned = klona(schema)
|
|
|
- cloned.field = 'payload'
|
|
|
+ cloned.field = targetField
|
|
|
return cloned
|
|
|
}
|
|
|
|
|
|
-function flattenComponentSchemas(items: ComponentSchema[] = []): SchemaActionDescriptor[] {
|
|
|
+function buildDependencyValues(names: string[] = [], defaultRoot: any) {
|
|
|
+ return names.reduce<Record<string, any>>((result, key) => {
|
|
|
+ result[key] = get(defaultRoot, key)
|
|
|
+ return result
|
|
|
+ }, {})
|
|
|
+}
|
|
|
+
|
|
|
+function flattenEventSettableSchemas(
|
|
|
+ items: EventSettableSchema[] = [],
|
|
|
+ defaultRoot: any
|
|
|
+): SchemaActionDescriptor[] {
|
|
|
const result: SchemaActionDescriptor[] = []
|
|
|
|
|
|
items.forEach((item) => {
|
|
|
if (!item) return
|
|
|
|
|
|
if (item.valueType === 'group') {
|
|
|
- if (!isSchemaActionable(item)) {
|
|
|
- result.push(...flattenComponentSchemas(item.children || []))
|
|
|
- return
|
|
|
- }
|
|
|
+ result.push(
|
|
|
+ ...flattenEventSettableSchemas((item.children || []) as EventSettableSchema[], defaultRoot)
|
|
|
+ )
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
- result.push({
|
|
|
- actionKey: item.field!,
|
|
|
- label: getSchemaLabel(item),
|
|
|
- schemas: [cloneActionSchema(item)],
|
|
|
- defaultValue: createDefaultValue(item)
|
|
|
- })
|
|
|
+ if (item.valueType === 'dependency' && typeof item.dependency === 'function') {
|
|
|
+ const dependencySchemas = item.dependency(buildDependencyValues(item.name, defaultRoot))
|
|
|
+ const schemaList = Array.isArray(dependencySchemas) ? dependencySchemas : [dependencySchemas]
|
|
|
+ result.push(...flattenEventSettableSchemas(schemaList as EventSettableSchema[], defaultRoot))
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+ if (item.canUseEventSet !== true) return
|
|
|
if (!isSchemaActionable(item)) return
|
|
|
|
|
|
result.push({
|
|
|
actionKey: item.field!,
|
|
|
label: getSchemaLabel(item),
|
|
|
+ groupKey: 'property',
|
|
|
+ groupLabel: '属性',
|
|
|
+ groupOrder: 1,
|
|
|
schemas: [cloneActionSchema(item)],
|
|
|
- defaultValue: createDefaultValue(item)
|
|
|
+ defaultValue: createSchemaDefaultValue(defaultRoot, item)
|
|
|
})
|
|
|
})
|
|
|
|
|
|
return result
|
|
|
}
|
|
|
|
|
|
-function getStyleActionDescriptors(items: ComponentSchema[] = []): SchemaActionDescriptor[] {
|
|
|
- return items
|
|
|
- .filter((item) => !!item && isSchemaActionable(item))
|
|
|
- .map((item) => ({
|
|
|
- actionKey: `style.${item.field}`,
|
|
|
- label: item.label || item.field || '样式',
|
|
|
- schemas: [cloneActionSchema(item)],
|
|
|
- defaultValue: createDefaultValue(item)
|
|
|
- }))
|
|
|
+function createStyleStateSchema(): ComponentSchema {
|
|
|
+ return {
|
|
|
+ label: '状态',
|
|
|
+ field: 'payload.state',
|
|
|
+ labelWidth: '120px',
|
|
|
+ valueType: 'select',
|
|
|
+ defaultValue: 'LV_STATE_DEFAULT',
|
|
|
+ componentProps: {
|
|
|
+ options: stateOptions,
|
|
|
+ clearable: true,
|
|
|
+ placeholder: '请选择状态'
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function getStyleActionDescriptors(targetData?: WidgetEventTargetData): SchemaActionDescriptor[] {
|
|
|
+ const model = getTargetModel(targetData)
|
|
|
+ const styleDefaults = model?.defaultSchema?.styles?.[0] || {}
|
|
|
+ const widgetStyleSchemas = model?.config?.styles || []
|
|
|
+
|
|
|
+ if (!widgetStyleSchemas.length) return []
|
|
|
+
|
|
|
+ return styleSchemas.map((item) => {
|
|
|
+ const defaultValue =
|
|
|
+ get(styleDefaults, item.field!) !== undefined
|
|
|
+ ? createSchemaDefaultValue(styleDefaults, item)
|
|
|
+ : klona(item.defaultValue)
|
|
|
+
|
|
|
+ return {
|
|
|
+ actionKey: `style.${item.key}`,
|
|
|
+ label: item.label || item.key || '样式',
|
|
|
+ groupKey: 'style',
|
|
|
+ groupLabel: '样式',
|
|
|
+ groupOrder: 2,
|
|
|
+ schemas: [createStyleStateSchema(), cloneActionSchema(item, 'payload.style')],
|
|
|
+ defaultValue: {
|
|
|
+ state: '',
|
|
|
+ style: defaultValue
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
function getTargetModel(targetData?: WidgetEventTargetData) {
|
|
|
@@ -245,10 +950,15 @@ function getSchemaActionDescriptors(targetData?: WidgetEventTargetData): SchemaA
|
|
|
if (!model) return []
|
|
|
|
|
|
return [
|
|
|
- builtinVisibleAction,
|
|
|
- ...flattenComponentSchemas(model.config.props || []),
|
|
|
- ...flattenComponentSchemas(model.config.coreProps || []),
|
|
|
- ...getStyleActionDescriptors(model.config.styles || [])
|
|
|
+ ...flattenEventSettableSchemas(
|
|
|
+ (model.config.props || []) as EventSettableSchema[],
|
|
|
+ model.defaultSchema
|
|
|
+ ),
|
|
|
+ ...flattenEventSettableSchemas(
|
|
|
+ (model.config.coreProps || []) as EventSettableSchema[],
|
|
|
+ model.defaultSchema
|
|
|
+ ),
|
|
|
+ ...getStyleActionDescriptors(targetData)
|
|
|
]
|
|
|
}
|
|
|
|
|
|
@@ -269,6 +979,9 @@ function getLoadPageActionDescriptor(
|
|
|
return {
|
|
|
actionKey: 'builtin.load_page',
|
|
|
label: '加载页面',
|
|
|
+ groupKey: 'builtin',
|
|
|
+ groupLabel: '动作',
|
|
|
+ groupOrder: 1,
|
|
|
defaultValue: {
|
|
|
pageId: pageOptions[0]?.value || '',
|
|
|
animationType: 'none',
|
|
|
@@ -340,6 +1053,9 @@ function getLanguageSwitchActionDescriptor(project?: IProject): SchemaActionDesc
|
|
|
return {
|
|
|
actionKey: 'builtin.language_switch',
|
|
|
label: '语言切换',
|
|
|
+ groupKey: 'builtin',
|
|
|
+ groupLabel: '动作',
|
|
|
+ groupOrder: 1,
|
|
|
defaultValue: {
|
|
|
languageKey: languageOptions[0]?.value || '',
|
|
|
refreshPage: true
|
|
|
@@ -381,6 +1097,9 @@ function getThemeSwitchActionDescriptor(project?: IProject): SchemaActionDescrip
|
|
|
return {
|
|
|
actionKey: 'builtin.theme_switch',
|
|
|
label: '主题切换',
|
|
|
+ groupKey: 'builtin',
|
|
|
+ groupLabel: '动作',
|
|
|
+ groupOrder: 1,
|
|
|
defaultValue: {
|
|
|
screen1Theme: preferredTheme,
|
|
|
...(isDualScreen ? { screen2Theme: preferredTheme } : {})
|
|
|
@@ -498,7 +1217,7 @@ export function getTargetOptions(project?: IProject): OptionType[] {
|
|
|
project?.screens.forEach((screen) => {
|
|
|
screen.pages.forEach((page) => {
|
|
|
options.push({
|
|
|
- label: `[${screen.name}] [Page] ${page.name}`,
|
|
|
+ label: `[${screen.name}] ${page.name}`,
|
|
|
value: `page:${page.id}`,
|
|
|
data: {
|
|
|
kind: 'page',
|
|
|
@@ -540,6 +1259,9 @@ export function getActionOptions(
|
|
|
return descriptors.map((item) => ({
|
|
|
label: item.label,
|
|
|
value: item.actionKey,
|
|
|
+ groupKey: item.groupKey,
|
|
|
+ groupLabel: item.groupLabel,
|
|
|
+ groupOrder: item.groupOrder,
|
|
|
data: {
|
|
|
actionKey: item.actionKey
|
|
|
} satisfies WidgetEventActionData,
|
|
|
@@ -566,5 +1288,5 @@ export const optionMap = {
|
|
|
{ label: '隐藏', value: false }
|
|
|
],
|
|
|
flags: flagOptions,
|
|
|
- states: stateOptions
|
|
|
+ states: [{ label: 'Default', value: 'LV_STATE_DEFAULT' }, ...stateOptions]
|
|
|
}
|