You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
1.7 KiB
83 lines
1.7 KiB
<script lang="ts" setup>
|
|
import type { Component } from 'vue'
|
|
import { provideParentViewId, useBlockId, useContext, useCurrentViewDOMRect, useParentViewId } from '../context'
|
|
|
|
defineOptions({
|
|
name: 'DddView',
|
|
})
|
|
|
|
const props = defineProps<{
|
|
is?: string | Component
|
|
vid?: string
|
|
}>()
|
|
|
|
const ctx = useContext()
|
|
const parentId = useParentViewId()
|
|
const blockId = useBlockId()
|
|
const domRect = useCurrentViewDOMRect()
|
|
|
|
function handleMousedown(e: Event, id: string | undefined): void {
|
|
ctx.activeBlockId = blockId
|
|
ctx.hoverViewId = parentId
|
|
ctx.canvas.focused = false
|
|
if (blockId) {
|
|
ctx.configurator = 'block'
|
|
}
|
|
|
|
if (id) {
|
|
e.stopPropagation()
|
|
ctx!.activeViewId = id
|
|
|
|
Object.assign(domRect, (e.target as HTMLElement).getBoundingClientRect().toJSON())
|
|
|
|
if (blockId !== id) {
|
|
switch (id) {
|
|
case '#canvas':
|
|
ctx.configurator = 'page'
|
|
break
|
|
case '#header':
|
|
case '#footer':
|
|
ctx.configurator = 'block'
|
|
break
|
|
default:
|
|
ctx.configurator = 'view'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function handleMouseleave(id: string | undefined): void {
|
|
if (id && ctx.hoverViewId === id && !ctx.draggingViewId) {
|
|
ctx.hoverViewId = undefined
|
|
}
|
|
}
|
|
|
|
provideParentViewId(props.vid)
|
|
</script>
|
|
|
|
<template>
|
|
<component
|
|
:is="is ?? 'div'"
|
|
:class="{
|
|
'is-active': vid && ctx.activeViewId === vid,
|
|
'is-hover': vid && ctx.hoverViewId === vid,
|
|
}"
|
|
:data-view-id="vid"
|
|
class="ddd-view"
|
|
@mouseleave="handleMouseleave(vid)"
|
|
@mousedown.left="handleMousedown($event, vid)"
|
|
>
|
|
<slot />
|
|
</component>
|
|
</template>
|
|
|
|
<style lang="less" scoped>
|
|
.ddd-view {
|
|
z-index: 1;
|
|
position: relative;
|
|
|
|
&.is-ghost {
|
|
opacity: 0.3;
|
|
}
|
|
}
|
|
</style>
|
|
|