Files
docuseal/app/javascript/template_builder/area.vue
T

630 lines
18 KiB
Vue
Raw Normal View History

2023-05-21 17:59:36 +03:00
<template>
<div
2023-06-03 00:53:46 +03:00
class="absolute overflow-visible group"
2023-05-21 17:59:36 +03:00
:style="positionStyle"
2023-06-03 00:53:46 +03:00
@pointerdown.stop
@mousedown.stop="startDrag"
2023-10-06 03:21:14 +03:00
@touchstart="startTouchDrag"
2023-05-21 17:59:36 +03:00
>
<div
2023-06-27 00:57:29 +03:00
v-if="isSelected || isDraw"
2023-06-07 01:16:43 +03:00
class="top-0 bottom-0 right-0 left-0 absolute border border-1.5 pointer-events-none"
:class="borderColors[submitterIndex]"
/>
2023-06-27 00:57:29 +03:00
<div
v-if="field.type === 'cells' && (isSelected || isDraw)"
class="top-0 bottom-0 right-0 left-0 absolute"
>
<div
v-for="(cellW, index) in cells"
:key="index"
class="absolute top-0 bottom-0 border-r"
:class="borderColors[submitterIndex]"
:style="{ left: (cellW / area.w * 100) + '%' }"
>
<span
2023-11-04 01:19:32 +02:00
v-if="index === 0 && editable"
2023-06-27 00:57:29 +03:00
class="h-2.5 w-2.5 rounded-full -bottom-1 border-gray-400 bg-white shadow-md border absolute cursor-ew-resize z-10"
style="left: -4px"
@mousedown.stop="startResizeCell"
/>
</div>
</div>
2023-06-07 01:16:43 +03:00
<div
v-if="field?.type"
2023-06-04 01:08:45 +03:00
class="absolute bg-white rounded-t border overflow-visible whitespace-nowrap group-hover:flex group-hover:z-10"
2023-10-06 03:21:14 +03:00
:class="{ 'flex z-10': isNameFocus || isSelected, invisible: !isNameFocus && !isSelected }"
2023-06-03 00:53:46 +03:00
style="top: -25px; height: 25px"
@mousedown.stop
@pointerdown.stop
2023-05-21 17:59:36 +03:00
>
2023-06-07 01:16:43 +03:00
<FieldSubmitter
v-model="field.submitter_uuid"
class="border-r"
:compact="true"
2024-03-19 01:21:44 +02:00
:editable="editable && (!defaultField || defaultField.role !== submitter?.name)"
2024-01-23 23:20:19 +02:00
:allow-add-new="!defaultSubmitters.length"
:menu-classes="'dropdown-content bg-white menu menu-xs p-2 shadow rounded-box w-52 rounded-t-none -left-[1px] mt-[1px]'"
2023-06-07 01:16:43 +03:00
:submitters="template.submitters"
2023-06-24 16:17:07 +03:00
@update:model-value="save"
2023-06-07 01:16:43 +03:00
@click="selectedAreaRef.value = area"
/>
2023-06-04 01:08:45 +03:00
<FieldType
v-model="field.type"
:button-width="27"
2023-11-27 20:24:58 +02:00
:editable="editable && !defaultField"
2023-06-04 01:08:45 +03:00
:button-classes="'px-1'"
:menu-classes="'bg-white rounded-t-none'"
2023-06-24 16:17:07 +03:00
@update:model-value="[maybeUpdateOptions(), save()]"
2023-06-04 01:08:45 +03:00
@click="selectedAreaRef.value = area"
/>
<span
2023-06-16 00:04:05 +03:00
v-if="field.type !== 'checkbox' || field.name"
2023-06-04 01:08:45 +03:00
ref="name"
2023-11-27 20:24:58 +02:00
:contenteditable="editable && !defaultField"
2024-01-07 14:19:21 +02:00
dir="auto"
2023-06-04 01:08:45 +03:00
class="pr-1 cursor-text outline-none block"
style="min-width: 2px"
@keydown.enter.prevent="onNameEnter"
@focus="onNameFocus"
@blur="onNameBlur"
2024-04-15 16:34:44 +03:00
>{{ optionIndexText }} {{ (defaultField ? (field.title || field.name) : field.name) || defaultName }}</span>
2023-06-20 00:24:39 +03:00
<div
2024-05-05 16:57:04 +03:00
v-if="isSettingsFocus || (isNameFocus && !['checkbox', 'phone'].includes(field.type))"
2023-06-20 00:24:39 +03:00
class="flex items-center ml-1.5"
>
<input
:id="`required-checkbox-${field.uuid}`"
v-model="field.required"
type="checkbox"
class="checkbox checkbox-xs no-animation rounded"
@mousedown.prevent
>
<label
:for="`required-checkbox-${field.uuid}`"
class="label text-xs"
@click.prevent="field.required = !field.required"
@mousedown.prevent
2024-01-07 14:19:21 +02:00
>{{ t('required') }}</label>
2024-05-05 16:57:04 +03:00
<span
v-if="field.type !== 'payment'"
class="dropdown dropdown-end"
@mouseenter="renderDropdown = true"
@touchstart="renderDropdown = true"
>
<label
ref="settingsButton"
tabindex="0"
:title="t('settings')"
class="cursor-pointer flex items-center"
style="height: 25px"
@focus="isSettingsFocus = true"
@blur="maybeBlurSettings"
>
<IconDotsVertical class="w-5 h-5" />
</label>
<ul
v-if="renderDropdown"
ref="settingsDropdown"
tabindex="0"
class="dropdown-content menu menu-xs px-2 pb-2 pt-1 shadow rounded-box w-52 z-10 rounded-t-none"
:style="{ backgroundColor: 'white' }"
@dragstart.prevent.stop
@click="closeDropdown"
@focusout="maybeBlurSettings"
>
<FieldSettings
:field="field"
:default-field="defaultField"
:editable="editable"
:background-color="'white'"
:with-required="false"
:with-areas="false"
@click-formula="isShowFormulaModal = true"
@click-description="isShowDescriptionModal = true"
@click-condition="isShowConditionsModal = true"
@scroll-to="[selectedAreaRef.value = $event, $emit('scroll-to', $event)]"
/>
</ul>
</span>
2023-06-20 00:24:39 +03:00
</div>
2023-06-03 00:53:46 +03:00
<button
2023-11-04 01:19:32 +02:00
v-else-if="editable"
2023-06-08 00:20:42 +03:00
class="pr-1"
2024-02-19 23:52:47 +02:00
:title="t('remove')"
2023-06-04 01:08:45 +03:00
@click.prevent="$emit('remove')"
2023-06-03 00:53:46 +03:00
>
2023-06-08 00:20:42 +03:00
<IconX width="14" />
2023-06-03 00:53:46 +03:00
</button>
</div>
<div
2023-11-05 01:41:54 +02:00
class="flex items-center h-full w-full"
2024-02-05 23:03:45 +02:00
dir="auto"
2024-03-17 19:06:00 +02:00
:class="[bgColors[submitterIndex], field?.default_value ? (alignClasses[field.preferences?.align] || '') : 'justify-center']"
2023-06-03 00:53:46 +03:00
>
2023-06-04 01:08:45 +03:00
<span
v-if="field"
2023-06-08 00:20:42 +03:00
class="flex justify-center items-center space-x-1 h-full"
2024-02-05 23:03:45 +02:00
:class="{'w-full h-full': field.type == 'checkbox'}"
2023-06-04 01:08:45 +03:00
>
2023-11-05 01:41:54 +02:00
<div
v-if="field?.default_value"
2024-02-05 23:03:45 +02:00
:class="{ 'w-full h-full': field.type == 'checkbox', 'text-[1.5vw] lg:text-base': !textOverflowChars, 'text-[1.0vw] lg:text-xs': textOverflowChars }"
2023-11-05 01:41:54 +02:00
>
2023-11-07 11:36:11 +02:00
<div
ref="textContainer"
class="flex items-center px-0.5"
2024-02-05 23:03:45 +02:00
:class="{'w-full h-full': field.type == 'checkbox'}"
2023-11-07 11:36:11 +02:00
>
2024-02-05 23:03:45 +02:00
<IconCheck
v-if="field.type == 'checkbox'"
class="aspect-square mx-auto"
:class="{ '!w-auto !h-full': area.w > area.h, '!w-full !h-auto': area.w <= area.h }"
/>
<span
v-else
class="whitespace-pre-wrap"
>{{ field.default_value }}</span>
2023-11-05 01:41:54 +02:00
</div>
</div>
2023-06-08 00:20:42 +03:00
<component
:is="fieldIcons[field.type]"
2023-11-05 01:41:54 +02:00
v-else
2023-06-08 00:20:42 +03:00
width="100%"
height="100%"
2023-11-05 01:41:54 +02:00
class="max-h-10 opacity-50"
2023-06-08 00:20:42 +03:00
/>
2023-06-04 01:08:45 +03:00
</span>
2023-05-21 17:59:36 +03:00
</div>
2023-06-04 01:08:45 +03:00
<div
2023-10-06 03:21:14 +03:00
ref="touchTarget"
2023-06-07 01:16:43 +03:00
class="absolute top-0 bottom-0 right-0 left-0 cursor-pointer"
2023-06-04 01:08:45 +03:00
/>
2023-05-21 17:59:36 +03:00
<span
2023-11-04 01:19:32 +02:00
v-if="field?.type && editable"
2023-10-06 03:21:14 +03:00
class="h-4 w-4 md:h-2.5 md:w-2.5 -right-1 rounded-full -bottom-1 border-gray-400 bg-white shadow-md border absolute cursor-nwse-resize"
2023-05-21 17:59:36 +03:00
@mousedown.stop="startResize"
2023-10-06 03:21:14 +03:00
@touchstart="startTouchResize"
2023-05-21 17:59:36 +03:00
/>
2024-05-05 16:57:04 +03:00
<Teleport
v-if="isShowFormulaModal"
:to="modalContainerEl"
>
<FormulaModal
:field="field"
:editable="editable && !defaultField"
:build-default-name="buildDefaultName"
@close="isShowFormulaModal = false"
/>
</Teleport>
<Teleport
v-if="isShowConditionsModal"
:to="modalContainerEl"
>
<ConditionsModal
:field="field"
:build-default-name="buildDefaultName"
@close="isShowConditionsModal = false"
/>
</Teleport>
<Teleport
v-if="isShowDescriptionModal"
:to="modalContainerEl"
>
<DescriptionModal
:field="field"
:editable="editable && !defaultField"
:build-default-name="buildDefaultName"
@close="isShowDescriptionModal = false"
/>
</Teleport>
2023-05-21 17:59:36 +03:00
</div>
</template>
<script>
2023-06-07 01:16:43 +03:00
import FieldSubmitter from './field_submitter'
2023-06-04 01:08:45 +03:00
import FieldType from './field_type'
import Field from './field'
2024-05-05 16:57:04 +03:00
import FieldSettings from './field_settings'
import FormulaModal from './formula_modal'
import ConditionsModal from './conditions_modal'
import DescriptionModal from './description_modal'
import { IconX, IconCheck, IconDotsVertical } from '@tabler/icons-vue'
2023-11-13 01:46:28 +02:00
import { v4 } from 'uuid'
2023-06-03 00:53:46 +03:00
2023-05-21 17:59:36 +03:00
export default {
name: 'FieldArea',
2023-06-04 01:08:45 +03:00
components: {
2023-06-07 01:16:43 +03:00
FieldType,
2024-02-05 23:03:45 +02:00
IconCheck,
2024-05-05 16:57:04 +03:00
FieldSettings,
FormulaModal,
IconDotsVertical,
DescriptionModal,
ConditionsModal,
2023-06-08 00:20:42 +03:00
FieldSubmitter,
IconX
2023-06-04 01:08:45 +03:00
},
2024-01-04 01:05:36 +02:00
inject: ['template', 'selectedAreaRef', 'save', 't'],
2023-05-21 17:59:36 +03:00
props: {
2023-06-04 01:08:45 +03:00
area: {
2023-05-21 17:59:36 +03:00
type: Object,
2023-06-04 01:08:45 +03:00
required: true
2023-05-21 17:59:36 +03:00
},
2023-06-27 00:57:29 +03:00
isDraw: {
type: Boolean,
required: false,
default: false
},
2023-11-27 20:24:58 +02:00
defaultField: {
type: Object,
required: false,
default: null
},
2024-01-23 23:20:19 +02:00
defaultSubmitters: {
type: Array,
required: false,
default: () => []
},
2023-11-04 01:19:32 +02:00
editable: {
type: Boolean,
required: false,
default: true
},
2023-05-21 17:59:36 +03:00
field: {
type: Object,
required: false,
default: null
}
},
2024-05-05 16:57:04 +03:00
emits: ['start-resize', 'stop-resize', 'start-drag', 'stop-drag', 'remove', 'scroll-to'],
2023-05-21 17:59:36 +03:00
data () {
return {
2024-05-05 16:57:04 +03:00
isShowFormulaModal: false,
isShowConditionsModal: false,
isSettingsFocus: false,
isShowDescriptionModal: false,
2023-05-21 17:59:36 +03:00
isResize: false,
2023-06-24 16:17:07 +03:00
isDragged: false,
2024-05-05 16:57:04 +03:00
renderDropdown: false,
2023-06-04 01:08:45 +03:00
isNameFocus: false,
2023-11-07 11:36:11 +02:00
textOverflowChars: 0,
2023-05-21 17:59:36 +03:00
dragFrom: { x: 0, y: 0 }
}
},
computed: {
2023-06-27 00:57:29 +03:00
fieldNames: FieldType.computed.fieldNames,
2023-06-04 01:08:45 +03:00
fieldIcons: FieldType.computed.fieldIcons,
2024-05-05 16:57:04 +03:00
modalContainerEl () {
return this.$el.getRootNode().querySelector('#docuseal_modal_container')
},
2024-02-24 01:01:36 +02:00
defaultName () {
return this.buildDefaultName(this.field, this.template.fields)
},
2024-03-17 19:06:00 +02:00
alignClasses () {
return {
center: 'justify-center',
left: 'justify-start',
right: 'justify-end'
}
},
2023-11-14 01:30:00 +02:00
optionIndexText () {
if (this.area.option_uuid && this.field.options) {
return `${this.field.options.findIndex((o) => o.uuid === this.area.option_uuid) + 1}.`
} else {
return ''
}
},
2023-06-27 00:57:29 +03:00
cells () {
const cells = []
let currentWidth = 0
while (currentWidth + (this.area.cell_w + this.area.cell_w / 4) < this.area.w) {
currentWidth += this.area.cell_w || 9999999
cells.push(currentWidth)
}
return cells
},
2023-06-07 01:16:43 +03:00
submitter () {
return this.template.submitters.find((s) => s.uuid === this.field.submitter_uuid)
},
submitterIndex () {
return this.template.submitters.indexOf(this.submitter)
},
borderColors () {
return [
2023-12-13 17:50:13 +02:00
'border-red-500/80',
'border-sky-500/80',
'border-emerald-500/80',
'border-yellow-300/80',
'border-purple-600/80',
'border-pink-500/80',
'border-cyan-500/80',
'border-orange-500/80',
'border-lime-500/80',
2024-02-08 11:54:54 +02:00
'border-indigo-500/80',
'border-red-500/80',
'border-sky-500/80',
'border-emerald-500/80',
'border-yellow-300/80',
'border-purple-600/80',
'border-pink-500/80',
'border-cyan-500/80',
2024-02-10 01:19:02 +02:00
'border-orange-500/80',
'border-lime-500/80',
'border-indigo-500/80'
2023-06-07 01:16:43 +03:00
]
},
bgColors () {
return [
2023-12-13 17:50:13 +02:00
'bg-red-100/80',
'bg-sky-100/80',
'bg-emerald-100/80',
'bg-yellow-100/80',
'bg-purple-100/80',
'bg-pink-100/80',
'bg-cyan-100/80',
'bg-orange-100/80',
'bg-lime-100/80',
2024-02-08 11:54:54 +02:00
'bg-indigo-100/80',
'bg-red-100/80',
'bg-sky-100/80',
'bg-emerald-100/80',
'bg-yellow-100/80',
'bg-purple-100/80',
'bg-pink-100/80',
'bg-cyan-100/80',
2024-02-10 01:19:02 +02:00
'bg-orange-100/80',
'bg-lime-100/80',
'bg-indigo-100/80'
2023-06-07 01:16:43 +03:00
]
},
2023-06-04 01:08:45 +03:00
isSelected () {
return this.selectedAreaRef.value === this.area
2023-06-03 00:53:46 +03:00
},
2023-05-21 17:59:36 +03:00
positionStyle () {
2023-06-04 01:08:45 +03:00
const { x, y, w, h } = this.area
2023-05-21 17:59:36 +03:00
return {
2023-05-23 00:22:17 +03:00
top: y * 100 + '%',
left: x * 100 + '%',
width: w * 100 + '%',
height: h * 100 + '%'
2023-05-21 17:59:36 +03:00
}
}
},
2023-11-07 11:36:11 +02:00
watch: {
'field.default_value' () {
this.$nextTick(() => {
2024-03-17 17:04:39 +02:00
if (['date', 'text', 'number'].includes(this.field.type) && this.field.default_value && this.$refs.textContainer && (this.textOverflowChars === 0 || (this.textOverflowChars - 4) > `${this.field.default_value}`.length)) {
this.textOverflowChars = this.$el.clientHeight < this.$refs.textContainer.clientHeight ? `${this.field.default_value}`.length : 0
2024-03-15 22:46:07 +02:00
}
2023-11-07 11:36:11 +02:00
})
}
},
2024-03-15 22:46:07 +02:00
mounted () {
this.$nextTick(() => {
2024-03-17 17:04:39 +02:00
if (['date', 'text', 'number'].includes(this.field.type) && this.field.default_value && this.$refs.textContainer && (this.textOverflowChars === 0 || (this.textOverflowChars - 4) > `${this.field.default_value}`.length)) {
this.textOverflowChars = this.$el.clientHeight < this.$refs.textContainer.clientHeight ? `${this.field.default_value}`.length : 0
2024-03-15 22:46:07 +02:00
}
})
},
2023-05-21 17:59:36 +03:00
methods: {
2024-02-24 01:01:36 +02:00
buildDefaultName: Field.methods.buildDefaultName,
2024-05-05 16:57:04 +03:00
closeDropdown () {
document.activeElement.blur()
},
maybeBlurSettings (e) {
if (!e.relatedTarget || !this.$refs.settingsDropdown.contains(e.relatedTarget)) {
this.isSettingsFocus = false
}
},
2023-06-04 01:08:45 +03:00
onNameFocus (e) {
this.selectedAreaRef.value = this.area
this.isNameFocus = true
this.$refs.name.style.minWidth = this.$refs.name.clientWidth + 'px'
if (!this.field.name) {
setTimeout(() => {
this.$refs.name.innerText = ' '
}, 1)
}
},
2023-06-27 00:57:29 +03:00
startResizeCell (e) {
2023-08-19 21:05:54 +03:00
this.$el.getRootNode().addEventListener('mousemove', this.onResizeCell)
this.$el.getRootNode().addEventListener('mouseup', this.stopResizeCell)
2023-06-27 00:57:29 +03:00
this.$emit('start-resize', 'ew')
},
stopResizeCell (e) {
2023-08-19 21:05:54 +03:00
this.$el.getRootNode().removeEventListener('mousemove', this.onResizeCell)
this.$el.getRootNode().removeEventListener('mouseup', this.stopResizeCell)
2023-06-27 00:57:29 +03:00
this.$emit('stop-resize')
this.save()
},
onResizeCell (e) {
2023-06-30 23:22:57 +03:00
if (e.target.id === 'mask') {
2024-03-05 20:53:54 +02:00
const positionX = e.offsetX / (e.target.clientWidth - 1)
2023-06-27 00:57:29 +03:00
if (positionX > this.area.x) {
this.area.cell_w = positionX - this.area.x
}
}
},
2023-06-08 00:20:42 +03:00
maybeUpdateOptions () {
2023-11-05 01:41:54 +02:00
delete this.field.default_value
2023-06-16 00:04:05 +03:00
if (!['radio', 'multiple', 'select'].includes(this.field.type)) {
2023-06-07 01:16:43 +03:00
delete this.field.options
}
2023-06-08 00:20:42 +03:00
2023-06-16 00:04:05 +03:00
if (['select', 'multiple', 'radio'].includes(this.field.type)) {
2023-11-13 01:46:28 +02:00
this.field.options ||= [{ value: '', uuid: v4() }]
2023-06-08 00:20:42 +03:00
}
2023-06-27 00:57:29 +03:00
(this.field.areas || []).forEach((area) => {
if (this.field.type === 'cells') {
area.cell_w = area.w * 2 / Math.floor(area.w / area.h)
} else {
delete area.cell_w
}
})
2023-06-07 01:16:43 +03:00
},
2023-06-04 01:08:45 +03:00
onNameBlur (e) {
2024-05-05 16:57:04 +03:00
if (e.relatedTarget === this.$refs.settingsButton) {
this.isSettingsFocus = true
}
2023-08-19 21:05:54 +03:00
const text = this.$refs.name.innerText.trim()
2023-06-04 01:08:45 +03:00
this.isNameFocus = false
this.$refs.name.style.minWidth = ''
2023-08-19 21:05:54 +03:00
if (text) {
this.field.name = text
2023-06-04 01:08:45 +03:00
} else {
this.field.name = ''
this.$refs.name.innerText = this.defaultName
}
2023-06-24 16:17:07 +03:00
this.save()
2023-06-04 01:08:45 +03:00
},
onNameEnter (e) {
this.$refs.name.blur()
2023-06-03 00:53:46 +03:00
},
2023-05-21 17:59:36 +03:00
resize (e) {
2023-06-30 23:22:57 +03:00
if (e.target.id === 'mask') {
2024-03-05 20:53:54 +02:00
this.area.w = e.offsetX / e.target.clientWidth - this.area.x
this.area.h = e.offsetY / e.target.clientHeight - this.area.y
2023-06-03 00:53:46 +03:00
}
2023-05-21 17:59:36 +03:00
},
drag (e) {
2023-06-30 23:22:57 +03:00
if (e.target.id === 'mask') {
2023-06-24 16:17:07 +03:00
this.isDragged = true
2024-03-05 20:53:54 +02:00
this.area.x = (e.offsetX - this.dragFrom.x) / e.target.clientWidth
this.area.y = (e.offsetY - this.dragFrom.y) / e.target.clientHeight
2023-05-21 17:59:36 +03:00
}
},
startDrag (e) {
2023-06-04 01:08:45 +03:00
this.selectedAreaRef.value = this.area
2023-11-04 01:19:32 +02:00
if (!this.editable) {
return
}
2023-05-21 17:59:36 +03:00
const rect = e.target.getBoundingClientRect()
this.dragFrom = { x: e.clientX - rect.left, y: e.clientY - rect.top }
2023-08-19 21:05:54 +03:00
this.$el.getRootNode().addEventListener('mousemove', this.drag)
this.$el.getRootNode().addEventListener('mouseup', this.stopDrag)
2023-05-21 17:59:36 +03:00
this.$emit('start-drag')
},
2023-10-06 03:21:14 +03:00
startTouchDrag (e) {
if (e.target !== this.$refs.touchTarget) {
return
}
this.$refs?.name?.blur()
e.preventDefault()
this.isDragged = true
const rect = e.target.getBoundingClientRect()
this.selectedAreaRef.value = this.area
this.dragFrom = { x: rect.left - e.touches[0].clientX, y: rect.top - e.touches[0].clientY }
this.$el.getRootNode().addEventListener('touchmove', this.touchDrag)
this.$el.getRootNode().addEventListener('touchend', this.stopTouchDrag)
this.$emit('start-drag')
},
touchDrag (e) {
const page = this.$parent.$refs.mask.previousSibling
const rect = page.getBoundingClientRect()
this.area.x = (this.dragFrom.x + e.touches[0].clientX - rect.left) / rect.width
this.area.y = (this.dragFrom.y + e.touches[0].clientY - rect.top) / rect.height
},
stopTouchDrag () {
this.$el.getRootNode().removeEventListener('touchmove', this.touchDrag)
this.$el.getRootNode().removeEventListener('touchend', this.stopTouchDrag)
if (this.isDragged) {
this.save()
}
this.isDragged = false
this.$emit('stop-drag')
},
2023-05-21 17:59:36 +03:00
stopDrag () {
2023-08-19 21:05:54 +03:00
this.$el.getRootNode().removeEventListener('mousemove', this.drag)
this.$el.getRootNode().removeEventListener('mouseup', this.stopDrag)
2023-05-21 17:59:36 +03:00
2023-06-24 16:17:07 +03:00
if (this.isDragged) {
this.save()
}
this.isDragged = false
2023-05-21 17:59:36 +03:00
this.$emit('stop-drag')
},
startResize () {
2023-06-04 01:08:45 +03:00
this.selectedAreaRef.value = this.area
2023-08-19 21:05:54 +03:00
this.$el.getRootNode().addEventListener('mousemove', this.resize)
this.$el.getRootNode().addEventListener('mouseup', this.stopResize)
2023-05-21 17:59:36 +03:00
2023-06-27 00:57:29 +03:00
this.$emit('start-resize', 'nwse')
2023-05-21 17:59:36 +03:00
},
stopResize () {
2023-08-19 21:05:54 +03:00
this.$el.getRootNode().removeEventListener('mousemove', this.resize)
this.$el.getRootNode().removeEventListener('mouseup', this.stopResize)
2023-05-21 17:59:36 +03:00
this.$emit('stop-resize')
2023-06-24 16:17:07 +03:00
2023-10-06 03:21:14 +03:00
this.save()
},
startTouchResize (e) {
this.selectedAreaRef.value = this.area
this.$refs?.name?.blur()
e.preventDefault()
this.$el.getRootNode().addEventListener('touchmove', this.touchResize)
this.$el.getRootNode().addEventListener('touchend', this.stopTouchResize)
this.$emit('start-resize', 'nwse')
},
touchResize (e) {
const page = this.$parent.$refs.mask.previousSibling
const rect = page.getBoundingClientRect()
this.area.w = (e.touches[0].clientX - rect.left) / rect.width - this.area.x
this.area.h = (e.touches[0].clientY - rect.top) / rect.height - this.area.y
},
stopTouchResize () {
this.$el.getRootNode().removeEventListener('touchmove', this.touchResize)
this.$el.getRootNode().removeEventListener('touchend', this.stopTouchResize)
this.$emit('stop-resize')
2023-06-24 16:17:07 +03:00
this.save()
2023-05-21 17:59:36 +03:00
}
}
}
</script>