vxe-pc-ui
Version:
A vue based PC component library
146 lines (134 loc) • 5.43 kB
text/typescript
import { defineComponent, h, inject, VNode } from 'vue'
import XEUtils from 'xe-utils'
import { getIcon, getI18n, renderer } from '@vxe-ui/core'
import { getSlotVNs } from '../../ui/src/vn'
import { getWidgetConfig, getWidgetConfigTitle } from './widget-info'
import type { VxeFormDesignConstructor, VxeFormDesignPrivateMethods, VxeFormDesignDefines } from '../../../types'
export default defineComponent({
props: {},
emits: [],
setup () {
const $xeFormDesign = inject<(VxeFormDesignConstructor & VxeFormDesignPrivateMethods) | null>('$xeFormDesign', null)
if (!$xeFormDesign) {
return () => []
}
const { reactData: formDesignReactData } = $xeFormDesign
const dragstartEvent = (evnt: DragEvent) => {
const divEl = evnt.currentTarget as HTMLDivElement
const dataTransfer = evnt.dataTransfer
const widgetName = divEl.getAttribute('data-widget-name') || ''
if ($xeFormDesign.validWidgetUnique(widgetName)) {
const dragWidget = $xeFormDesign.createWidget(widgetName)
if (dataTransfer) {
dataTransfer.setData('text/plain', widgetName)
}
formDesignReactData.sortWidget = null
formDesignReactData.dragWidget = dragWidget
} else {
evnt.preventDefault()
}
}
const dragendEvent = (evnt: DragEvent) => {
evnt.preventDefault()
if (formDesignReactData.dragWidget) {
const newWidget = formDesignReactData.dragWidget
formDesignReactData.activeWidget = newWidget
$xeFormDesign.dispatchEvent('add-widget', { newWidget }, evnt)
}
formDesignReactData.dragWidget = null
formDesignReactData.sortWidget = null
}
const cancelDragoverItem = (evnt: DragEvent, group: VxeFormDesignDefines.WidgetConfigGroup) => {
const { widgetObjList, dragWidget } = formDesignReactData
if (dragWidget) {
if (group.children.some(widget => widget.name === dragWidget.name)) {
const rest = XEUtils.findTree(widgetObjList, item => item && item.id === dragWidget.id, { children: 'children' })
if (rest) {
rest.items.splice(rest.index, 1)
}
}
}
}
const addNewWidget = (evnt: KeyboardEvent, widgetName: string) => {
if ($xeFormDesign.validWidgetUnique(widgetName)) {
const { widgetObjList } = formDesignReactData
const dragWidget = $xeFormDesign.createWidget(widgetName)
widgetObjList.push(dragWidget)
formDesignReactData.activeWidget = dragWidget
formDesignReactData.sortWidget = null
formDesignReactData.dragWidget = null
$xeFormDesign.dispatchEvent('add-widget', { newWidget: dragWidget }, evnt)
}
}
const renderWidgetList = (group: VxeFormDesignDefines.WidgetConfigGroup) => {
const widgetVNs: VNode[] = []
if (group.children) {
group.children.forEach((widget, index) => {
const { name } = widget
const configTitle = getWidgetConfigTitle(name, $xeFormDesign)
const compConf = renderer.get(name) || {}
const widgetConf = getWidgetConfig(name)
const renderWidgetItem = compConf.renderFormDesignWidgetItem
widgetVNs.push(
h('div', {
key: index,
class: 'vxe-form-design--widget-item'
}, h('div', {
class: 'vxe-form-design--widget-box',
'data-widget-name': name,
title: configTitle,
draggable: true,
onDragstart: dragstartEvent,
onDragend: dragendEvent
}, renderWidgetItem
? getSlotVNs(renderWidgetItem({}, { $formDesign: $xeFormDesign }))
: [
h('i', {
class: ['vxe-form-design--widget-item-icon', widgetConf ? (widgetConf.icon || '') : '']
}),
h('span', {
class: 'vxe-form-design--widget-item-name'
}, configTitle),
h('span', {
class: 'vxe-form-design--widget-item-add',
onClick (evnt: KeyboardEvent) {
addNewWidget(evnt, name)
}
}, [
h('i', {
class: getIcon().FORM_DESIGN_WIDGET_ADD
})
])
]))
)
})
}
return widgetVNs
}
const renderWidgetGroups = () => {
const { widgetConfigs } = formDesignReactData
return widgetConfigs.map((config, gIndex) => {
const { title, group } = config
return h('div', {
key: gIndex,
class: 'vxe-form-design--widget-group'
}, [
h('div', {
class: 'vxe-form-design--widget-title'
}, group ? getI18n(`vxe.formDesign.widget.group.${group}`) : `${title || ''}`),
h('div', {
class: 'vxe-form-design--widget-list',
onDragover (evnt: DragEvent) {
cancelDragoverItem(evnt, config)
}
}, renderWidgetList(config))
])
})
}
return () => {
return h('div', {
class: 'vxe-form-design--widget'
}, renderWidgetGroups())
}
}
})