73 lines
1.9 KiB
Vue
73 lines
1.9 KiB
Vue
<template>
|
|
<div
|
|
class="z-[1] select-none touch-none"
|
|
:class="selected ? 'outline outline-2 outline-accent outline-offset-2' : ''"
|
|
:style="computedStyle"
|
|
@click.stop="$emit('select')"
|
|
>
|
|
<!-- Children widgets inside the tab page -->
|
|
<WidgetElement
|
|
v-for="child in children"
|
|
:key="child.id"
|
|
:widget="child"
|
|
:scale="scale"
|
|
:selected="store.selectedWidgetId === child.id"
|
|
@select="store.selectedWidgetId = child.id"
|
|
@drag-start="$emit('drag-start', $event)"
|
|
@resize-start="$emit('resize-start', $event)"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed, defineAsyncComponent } from 'vue';
|
|
import { useEditorStore } from '../../../stores/editor';
|
|
import { fontSizes } from '../../../constants';
|
|
import { clamp, hexToRgba, getBorderStyle } from '../shared/utils';
|
|
|
|
const WidgetElement = defineAsyncComponent(() => import('../../WidgetElement.vue'));
|
|
|
|
const props = defineProps({
|
|
widget: { type: Object, required: true },
|
|
scale: { type: Number, default: 1 },
|
|
selected: { type: Boolean, default: false }
|
|
});
|
|
|
|
defineEmits(['select', 'drag-start', 'resize-start']);
|
|
|
|
const store = useEditorStore();
|
|
|
|
const children = computed(() => {
|
|
if (!store.activeScreen) return [];
|
|
return store.activeScreen.widgets.filter(w => w.parentId === props.widget.id);
|
|
});
|
|
|
|
const computedStyle = computed(() => {
|
|
const w = props.widget;
|
|
const s = props.scale;
|
|
|
|
const style = {
|
|
position: 'relative',
|
|
width: '100%',
|
|
height: '100%',
|
|
left: '0',
|
|
top: '0',
|
|
fontSize: `${(fontSizes[w.fontSize] || 14) * s}px`,
|
|
color: w.textColor,
|
|
zIndex: 1,
|
|
userSelect: 'none',
|
|
touchAction: 'none'
|
|
};
|
|
|
|
if ((w.bgOpacity ?? 0) > 0) {
|
|
style.background = hexToRgba(w.bgColor, clamp((w.bgOpacity ?? 255) / 255, 0, 1));
|
|
}
|
|
if ((w.radius || 0) > 0) {
|
|
style.borderRadius = `${(w.radius || 0) * s}px`;
|
|
}
|
|
Object.assign(style, getBorderStyle(w, s));
|
|
|
|
return style;
|
|
});
|
|
</script>
|