mirror of
https://github.com/docusealco/docuseal
synced 2026-11-04 06:42:32 -05:00
optimize add list style
This commit is contained in:
1 parent
a990d22831
commit
bef825c4e0
4 files changed
+218
-234
No files matched your search
@@ -51,6 +51,7 @@
|
||||
@add-custom-field="$emit('add-custom-field', $event)"
|
||||
@set-draw="$emit('set-draw', $event)"
|
||||
@add-attachment="document.attachments.push($event)"
|
||||
@add-list="ensureListsStyle"
|
||||
/>
|
||||
</Teleport>
|
||||
</div>
|
||||
@@ -189,15 +190,8 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
bodyDom: {
|
||||
immediate: true,
|
||||
handler () {
|
||||
this.listsStyle = this.bodyDom.querySelector('body > style[data-lists]')?.textContent || null
|
||||
|
||||
this.ensureListsStyle(this.bodyDom)
|
||||
}
|
||||
}
|
||||
created () {
|
||||
this.loadListsStyle()
|
||||
},
|
||||
mounted () {
|
||||
this.isMounted = true
|
||||
@@ -244,6 +238,8 @@ export default {
|
||||
}
|
||||
},
|
||||
reloadContent () {
|
||||
this.loadListsStyle()
|
||||
|
||||
this.sectionRefs.forEach((ref) => ref.reloadContent())
|
||||
},
|
||||
onBeforeUnload (event) {
|
||||
@@ -269,8 +265,6 @@ export default {
|
||||
})
|
||||
},
|
||||
onSectionUpdate (section, { editor }) {
|
||||
this.ensureListsStyle(editor.view.dom)
|
||||
|
||||
clearTimeout(this.saveTimer)
|
||||
|
||||
this.saveTimer = setTimeout(async () => {
|
||||
@@ -279,8 +273,11 @@ export default {
|
||||
delete this.saveTimer
|
||||
}, 1000)
|
||||
},
|
||||
ensureListsStyle (root) {
|
||||
if (this.listsStyle || !root.querySelector('[class*="doc-list-"]')) return
|
||||
loadListsStyle () {
|
||||
this.listsStyle = this.bodyDom.querySelector('body > style[data-lists]')?.textContent || null
|
||||
},
|
||||
ensureListsStyle () {
|
||||
if (this.listsStyle) return
|
||||
|
||||
const style = this.bodyDom.createElement('style')
|
||||
|
||||
|
||||
@@ -1,185 +1,159 @@
|
||||
<template>
|
||||
<div
|
||||
class="absolute z-10 select-none text-sm"
|
||||
:style="{ top: coords.top - 12 + 'px', left: coords.left - 12 + 'px' }"
|
||||
@mousedown.prevent
|
||||
>
|
||||
<button
|
||||
class="flex items-center justify-center w-6 h-6 rounded-md border border-neutral-200"
|
||||
:class="isOpen ? 'bg-neutral-100 text-base-content' : 'bg-white text-base-content/40 hover:bg-neutral-100 hover:text-base-content'"
|
||||
:title="t('insert')"
|
||||
@click="isOpen = !isOpen"
|
||||
>
|
||||
<IconX
|
||||
v-if="isOpen"
|
||||
:width="14"
|
||||
:height="14"
|
||||
/>
|
||||
<IconPlus
|
||||
v-else
|
||||
:width="14"
|
||||
:height="14"
|
||||
/>
|
||||
</button>
|
||||
<div class="absolute top-7 left-0 min-w-36 p-1 bg-white border border-neutral-200 rounded-lg shadow-lg">
|
||||
<div
|
||||
v-if="isOpen"
|
||||
class="absolute top-7 left-0 min-w-36 p-1 bg-white border border-neutral-200 rounded-lg shadow-lg"
|
||||
class="relative"
|
||||
@pointerenter="$event.pointerType === 'mouse' ? submenu = 'field' : null"
|
||||
>
|
||||
<div
|
||||
class="relative"
|
||||
@pointerenter="$event.pointerType === 'mouse' ? submenu = 'field' : null"
|
||||
>
|
||||
<button
|
||||
class="flex items-center gap-2 w-full px-2 py-1 rounded-md"
|
||||
:class="{ 'bg-neutral-100': submenu === 'field' }"
|
||||
@click="submenu = submenu === 'field' ? null : 'field'"
|
||||
>
|
||||
<IconForms
|
||||
:width="16"
|
||||
:height="16"
|
||||
:stroke-width="1.6"
|
||||
/>
|
||||
{{ t('field') }}
|
||||
<IconChevronRight
|
||||
:width="14"
|
||||
:height="14"
|
||||
class="ml-auto"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
v-if="submenu === 'field'"
|
||||
class="absolute top-0 left-full min-w-40 p-1 bg-white border border-neutral-200 rounded-lg shadow-lg"
|
||||
>
|
||||
<button
|
||||
v-for="(icon, type) in fieldTypesList"
|
||||
:key="type"
|
||||
class="flex items-center gap-2 w-full px-2 py-1 rounded-md hover:bg-neutral-100"
|
||||
@click="[$emit('insert-field', type), isOpen = false]"
|
||||
>
|
||||
<component
|
||||
:is="icon"
|
||||
:width="16"
|
||||
:height="16"
|
||||
:stroke-width="1.6"
|
||||
/>
|
||||
{{ fieldNames[type] }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="relative"
|
||||
@pointerenter="$event.pointerType === 'mouse' ? submenu = 'table' : null"
|
||||
>
|
||||
<button
|
||||
class="flex items-center gap-2 w-full px-2 py-1 rounded-md"
|
||||
:class="{ 'bg-neutral-100': submenu === 'table' }"
|
||||
@click="submenu = submenu === 'table' ? null : 'table'"
|
||||
>
|
||||
<IconTable
|
||||
:width="16"
|
||||
:height="16"
|
||||
:stroke-width="1.6"
|
||||
/>
|
||||
{{ t('table') }}
|
||||
<IconChevronRight
|
||||
:width="14"
|
||||
:height="14"
|
||||
class="ml-auto"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
v-if="submenu === 'table'"
|
||||
class="absolute top-0 left-full w-max p-2 bg-white border border-neutral-200 rounded-lg shadow-lg"
|
||||
>
|
||||
<div
|
||||
v-if="!isMobile"
|
||||
class="grid grid-cols-8 gap-0.5 mb-2"
|
||||
>
|
||||
<template
|
||||
v-for="row in 8"
|
||||
:key="row"
|
||||
>
|
||||
<button
|
||||
v-for="col in 8"
|
||||
:key="col"
|
||||
class="w-4 h-4 border rounded-sm"
|
||||
:class="row <= tableSize.rows && col <= tableSize.cols ? 'bg-neutral-200 border-neutral-400' : 'bg-white border-neutral-200'"
|
||||
:aria-label="`${row} × ${col}`"
|
||||
@pointerenter="$event.pointerType === 'mouse' ? tableSize = { rows: row, cols: col } : null"
|
||||
@click="[$emit('insert-table', { rows: row, cols: col }), isOpen = false]"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
<div class="flex items-center justify-center gap-1 text-xs">
|
||||
<template
|
||||
v-for="key in ['rows', 'cols']"
|
||||
:key="key"
|
||||
>
|
||||
<span v-if="key === 'cols'">×</span>
|
||||
<div class="flex items-center border border-neutral-200 rounded-md">
|
||||
<button
|
||||
class="inline-flex items-center justify-center w-6 h-6 rounded-md hover:bg-neutral-100"
|
||||
:aria-label="t(`decrease_${key}`)"
|
||||
@click="tableSize[key] = Math.max(tableSize[key] - 1, 1)"
|
||||
>
|
||||
<IconMinus
|
||||
:width="12"
|
||||
:height="12"
|
||||
/>
|
||||
</button>
|
||||
<span class="w-5 text-center">{{ tableSize[key] }}</span>
|
||||
<button
|
||||
class="inline-flex items-center justify-center w-6 h-6 rounded-md hover:bg-neutral-100"
|
||||
:aria-label="t(`increase_${key}`)"
|
||||
@click="tableSize[key] = Math.min(tableSize[key] + 1, 20)"
|
||||
>
|
||||
<IconPlus
|
||||
:width="12"
|
||||
:height="12"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<button
|
||||
v-if="isMobile || tableSize.rows > 8 || tableSize.cols > 8"
|
||||
class="w-full mt-2 px-2 py-1 rounded-md bg-neutral-100 hover:bg-neutral-200"
|
||||
@click="[$emit('insert-table', { ...tableSize }), isOpen = false]"
|
||||
>
|
||||
{{ t('insert') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="flex items-center gap-2 w-full px-2 py-1 rounded-md hover:bg-neutral-100"
|
||||
@mouseenter="submenu = null"
|
||||
@click="[$emit('insert-variable'), isOpen = false]"
|
||||
class="flex items-center gap-2 w-full px-2 py-1 rounded-md"
|
||||
:class="{ 'bg-neutral-100': submenu === 'field' }"
|
||||
@click="submenu = submenu === 'field' ? null : 'field'"
|
||||
>
|
||||
<IconBracketsContain
|
||||
<IconForms
|
||||
:width="16"
|
||||
:height="16"
|
||||
:stroke-width="1.6"
|
||||
/>
|
||||
{{ t('variable') }}
|
||||
</button>
|
||||
<button
|
||||
class="flex items-center gap-2 w-full px-2 py-1 rounded-md hover:bg-neutral-100"
|
||||
@mouseenter="submenu = null"
|
||||
@click="[$emit('insert-image'), isOpen = false]"
|
||||
>
|
||||
<IconPhoto
|
||||
:width="16"
|
||||
:height="16"
|
||||
:stroke-width="1.6"
|
||||
{{ t('field') }}
|
||||
<IconChevronRight
|
||||
:width="14"
|
||||
:height="14"
|
||||
class="ml-auto"
|
||||
/>
|
||||
{{ t('image') }}
|
||||
</button>
|
||||
<div
|
||||
v-if="submenu === 'field'"
|
||||
class="absolute top-0 left-full min-w-40 p-1 bg-white border border-neutral-200 rounded-lg shadow-lg"
|
||||
>
|
||||
<button
|
||||
v-for="(icon, type) in fieldTypesList"
|
||||
:key="type"
|
||||
class="flex items-center gap-2 w-full px-2 py-1 rounded-md hover:bg-neutral-100"
|
||||
@click="[$emit('insert-field', type), $emit('close')]"
|
||||
>
|
||||
<component
|
||||
:is="icon"
|
||||
:width="16"
|
||||
:height="16"
|
||||
:stroke-width="1.6"
|
||||
/>
|
||||
{{ fieldNames[type] }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="relative"
|
||||
@pointerenter="$event.pointerType === 'mouse' ? submenu = 'table' : null"
|
||||
>
|
||||
<button
|
||||
class="flex items-center gap-2 w-full px-2 py-1 rounded-md"
|
||||
:class="{ 'bg-neutral-100': submenu === 'table' }"
|
||||
@click="submenu = submenu === 'table' ? null : 'table'"
|
||||
>
|
||||
<IconTable
|
||||
:width="16"
|
||||
:height="16"
|
||||
:stroke-width="1.6"
|
||||
/>
|
||||
{{ t('table') }}
|
||||
<IconChevronRight
|
||||
:width="14"
|
||||
:height="14"
|
||||
class="ml-auto"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
v-if="submenu === 'table'"
|
||||
class="absolute top-0 left-full w-max p-2 bg-white border border-neutral-200 rounded-lg shadow-lg"
|
||||
>
|
||||
<div
|
||||
v-if="!isMobile"
|
||||
class="grid grid-cols-8 gap-0.5 mb-2"
|
||||
>
|
||||
<template
|
||||
v-for="row in 8"
|
||||
:key="row"
|
||||
>
|
||||
<button
|
||||
v-for="col in 8"
|
||||
:key="col"
|
||||
class="w-4 h-4 border rounded-sm"
|
||||
:class="row <= tableSize.rows && col <= tableSize.cols ? 'bg-neutral-200 border-neutral-400' : 'bg-white border-neutral-200'"
|
||||
:aria-label="`${row} × ${col}`"
|
||||
@pointerenter="$event.pointerType === 'mouse' ? tableSize = { rows: row, cols: col } : null"
|
||||
@click="[$emit('insert-table', { rows: row, cols: col }), $emit('close')]"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
<div class="flex items-center justify-center gap-1 text-xs">
|
||||
<template
|
||||
v-for="key in ['rows', 'cols']"
|
||||
:key="key"
|
||||
>
|
||||
<span v-if="key === 'cols'">×</span>
|
||||
<div class="flex items-center border border-neutral-200 rounded-md">
|
||||
<button
|
||||
class="inline-flex items-center justify-center w-6 h-6 rounded-md hover:bg-neutral-100"
|
||||
:aria-label="t(`decrease_${key}`)"
|
||||
@click="tableSize[key] = Math.max(tableSize[key] - 1, 1)"
|
||||
>
|
||||
<IconMinus
|
||||
:width="12"
|
||||
:height="12"
|
||||
/>
|
||||
</button>
|
||||
<span class="w-5 text-center">{{ tableSize[key] }}</span>
|
||||
<button
|
||||
class="inline-flex items-center justify-center w-6 h-6 rounded-md hover:bg-neutral-100"
|
||||
:aria-label="t(`increase_${key}`)"
|
||||
@click="tableSize[key] = Math.min(tableSize[key] + 1, 20)"
|
||||
>
|
||||
<IconPlus
|
||||
:width="12"
|
||||
:height="12"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<button
|
||||
v-if="isMobile || tableSize.rows > 8 || tableSize.cols > 8"
|
||||
class="w-full mt-2 px-2 py-1 rounded-md bg-neutral-100 hover:bg-neutral-200"
|
||||
@click="[$emit('insert-table', { ...tableSize }), $emit('close')]"
|
||||
>
|
||||
{{ t('insert') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="flex items-center gap-2 w-full px-2 py-1 rounded-md hover:bg-neutral-100"
|
||||
@mouseenter="submenu = null"
|
||||
@click="[$emit('insert-variable'), $emit('close')]"
|
||||
>
|
||||
<IconBracketsContain
|
||||
:width="16"
|
||||
:height="16"
|
||||
:stroke-width="1.6"
|
||||
/>
|
||||
{{ t('variable') }}
|
||||
</button>
|
||||
<button
|
||||
class="flex items-center gap-2 w-full px-2 py-1 rounded-md hover:bg-neutral-100"
|
||||
@mouseenter="submenu = null"
|
||||
@click="[$emit('insert-image'), $emit('close')]"
|
||||
>
|
||||
<IconPhoto
|
||||
:width="16"
|
||||
:height="16"
|
||||
:stroke-width="1.6"
|
||||
/>
|
||||
{{ t('image') }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { IconPlus, IconMinus, IconX, IconForms, IconTable, IconPhoto, IconChevronRight, IconBracketsContain } from '@tabler/icons-vue'
|
||||
import { IconPlus, IconMinus, IconForms, IconTable, IconPhoto, IconChevronRight, IconBracketsContain } from '@tabler/icons-vue'
|
||||
import FieldType from './field_type.vue'
|
||||
|
||||
export default {
|
||||
@@ -187,7 +161,6 @@ export default {
|
||||
components: {
|
||||
IconPlus,
|
||||
IconMinus,
|
||||
IconX,
|
||||
IconForms,
|
||||
IconTable,
|
||||
IconPhoto,
|
||||
@@ -195,16 +168,9 @@ export default {
|
||||
IconBracketsContain
|
||||
},
|
||||
inject: ['withPhone', 'withPayment', 'withVerification', 'withKba', 't', 'fieldTypes', 'isMobile'],
|
||||
props: {
|
||||
coords: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
emits: ['insert-field', 'insert-table', 'insert-variable', 'insert-image'],
|
||||
emits: ['insert-field', 'insert-table', 'insert-variable', 'insert-image', 'close'],
|
||||
data () {
|
||||
return {
|
||||
isOpen: false,
|
||||
submenu: null,
|
||||
tableSize: { rows: 3, cols: 3 }
|
||||
}
|
||||
@@ -220,24 +186,18 @@ export default {
|
||||
}))
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
isOpen (value) {
|
||||
this.submenu = null
|
||||
|
||||
if (value) {
|
||||
document.addEventListener('mousedown', this.onDocumentMouseDown)
|
||||
} else {
|
||||
document.removeEventListener('mousedown', this.onDocumentMouseDown)
|
||||
}
|
||||
}
|
||||
mounted () {
|
||||
document.addEventListener('mousedown', this.onDocumentMouseDown)
|
||||
},
|
||||
beforeUnmount () {
|
||||
document.removeEventListener('mousedown', this.onDocumentMouseDown)
|
||||
|
||||
this.$emit('close')
|
||||
},
|
||||
methods: {
|
||||
onDocumentMouseDown (event) {
|
||||
if (!event.composedPath().includes(this.$el)) {
|
||||
this.isOpen = false
|
||||
if (!event.composedPath().includes(this.$el.parentElement)) {
|
||||
this.$emit('close')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,7 +385,7 @@ export default {
|
||||
default: null
|
||||
}
|
||||
},
|
||||
emits: ['add-variable', 'add-condition'],
|
||||
emits: ['add-variable', 'add-condition', 'add-list'],
|
||||
data () {
|
||||
return {
|
||||
isMouseDown: false,
|
||||
@@ -576,6 +576,8 @@ export default {
|
||||
toggleList (style) {
|
||||
this.dropdown = null
|
||||
|
||||
if (style !== this.listStyle) this.$emit('add-list')
|
||||
|
||||
this.editor.chain().focus().toggleList(style).run()
|
||||
},
|
||||
wrapVariable () {
|
||||
|
||||
@@ -51,19 +51,44 @@
|
||||
v-if="editable"
|
||||
v-show="!selectedAreasRef.value.length"
|
||||
:editor="editor"
|
||||
:coords="dynamicMenuCoords"
|
||||
:coords="isInsertMenuOpen ? null : dynamicMenuCoords"
|
||||
@add-variable="dynamicMenuCoords = null"
|
||||
@add-condition="dynamicMenuCoords = null"
|
||||
@add-list="$emit('add-list')"
|
||||
/>
|
||||
<DynamicInsertMenu
|
||||
v-if="editable && insertMenuCoords && !isDrawMode && !selectedAreasRef.value.length"
|
||||
:key="insertMenuCoords.top"
|
||||
:coords="insertMenuCoords"
|
||||
@insert-field="onInsertField"
|
||||
@insert-table="onInsertTable"
|
||||
@insert-variable="editor.chain().focus().insertContent('[[variable]]').run()"
|
||||
@insert-image="$refs.imageInput.click()"
|
||||
/>
|
||||
<div
|
||||
v-if="editable && insertMenuCoords && !isDrawMode"
|
||||
class="absolute z-10 select-none text-sm"
|
||||
:style="{ top: insertMenuCoords.top - 12 + 'px', left: insertMenuCoords.left - 12 + 'px' }"
|
||||
@mousedown.prevent
|
||||
>
|
||||
<button
|
||||
class="flex items-center justify-center w-6 h-6 rounded-md border border-neutral-200"
|
||||
:class="isInsertMenuOpen ? 'bg-neutral-100 text-base-content' : 'bg-white text-base-content/40 hover:bg-neutral-100 hover:text-base-content'"
|
||||
:title="t('insert')"
|
||||
@click="isInsertMenuOpen = !isInsertMenuOpen"
|
||||
>
|
||||
<IconX
|
||||
v-if="isInsertMenuOpen"
|
||||
:width="14"
|
||||
:height="14"
|
||||
/>
|
||||
<IconPlus
|
||||
v-else
|
||||
:width="14"
|
||||
:height="14"
|
||||
/>
|
||||
</button>
|
||||
<DynamicInsertMenu
|
||||
v-if="isInsertMenuOpen"
|
||||
:key="insertMenuCoords.top"
|
||||
@close="isInsertMenuOpen = false"
|
||||
@insert-field="onInsertField"
|
||||
@insert-table="onInsertTable"
|
||||
@insert-variable="editor.chain().focus().insertContent('[[variable]]').run()"
|
||||
@insert-image="$refs.imageInput.click()"
|
||||
/>
|
||||
</div>
|
||||
<DynamicBlockMenu
|
||||
v-if="editable && blockMenuCoords && !isDrawMode"
|
||||
:coords="blockMenuCoords"
|
||||
@@ -90,8 +115,9 @@
|
||||
<script>
|
||||
import { shallowRef } from 'vue'
|
||||
import { DOMSerializer, Fragment } from '@tiptap/pm/model'
|
||||
import { findTable } from '@tiptap/pm/tables'
|
||||
import { findTable, CellSelection } from '@tiptap/pm/tables'
|
||||
import { v4 } from 'uuid'
|
||||
import { IconPlus, IconX } from '@tabler/icons-vue'
|
||||
import FieldContextMenu from './field_context_menu.vue'
|
||||
import AreaTitle from './area_title.vue'
|
||||
import DynamicMenu from './dynamic_menu.vue'
|
||||
@@ -106,7 +132,9 @@ export default {
|
||||
DynamicInsertMenu,
|
||||
DynamicBlockMenu,
|
||||
FieldContextMenu,
|
||||
AreaTitle
|
||||
AreaTitle,
|
||||
IconPlus,
|
||||
IconX
|
||||
},
|
||||
inject: ['template', 'save', 'baseFetch', 't', 'fieldsDragFieldRef', 'customDragFieldRef', 'selectedAreasRef', 'getFieldTypeIndex', 'fieldTypes', 'withPhone', 'withPayment', 'withVerification', 'withKba', 'backgroundColor'],
|
||||
props: {
|
||||
@@ -178,13 +206,14 @@ export default {
|
||||
default: null
|
||||
}
|
||||
},
|
||||
emits: ['update', 'draw', 'set-draw', 'add-custom-field', 'add-attachment'],
|
||||
emits: ['update', 'draw', 'set-draw', 'add-custom-field', 'add-attachment', 'add-list'],
|
||||
data () {
|
||||
return {
|
||||
isAreaDrag: false,
|
||||
areaToolbarCoords: null,
|
||||
dynamicMenuCoords: null,
|
||||
insertMenuCoords: null,
|
||||
isInsertMenuOpen: false,
|
||||
blockMenuCoords: null,
|
||||
contextMenu: null,
|
||||
cursorHighlightCoords: null
|
||||
@@ -455,7 +484,6 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
this.insertMenuCoords = null
|
||||
this.blockMenuCoords = null
|
||||
} else {
|
||||
this.areaToolbarCoords = null
|
||||
@@ -463,25 +491,18 @@ export default {
|
||||
|
||||
this.setBlockMenuCoords(editor)
|
||||
|
||||
if (selection.node) {
|
||||
if (selection.node || selection.empty || !editor.isFocused) {
|
||||
this.dynamicMenuCoords = null
|
||||
this.insertMenuCoords = null
|
||||
} else if (selection.empty) {
|
||||
this.dynamicMenuCoords = null
|
||||
|
||||
if (editor.isFocused) {
|
||||
this.setInsertMenuCoords(editor)
|
||||
}
|
||||
} else {
|
||||
this.insertMenuCoords = null
|
||||
|
||||
if (editor.isFocused) {
|
||||
this.setDynamicMenuCoords(editor)
|
||||
} else {
|
||||
this.dynamicMenuCoords = null
|
||||
}
|
||||
this.setDynamicMenuCoords(editor)
|
||||
}
|
||||
}
|
||||
|
||||
if (selection instanceof CellSelection) {
|
||||
this.insertMenuCoords = null
|
||||
} else if (editor.isFocused) {
|
||||
this.setInsertMenuCoords(editor)
|
||||
}
|
||||
},
|
||||
setInsertMenuCoords (editor) {
|
||||
const coords = editor.view.coordsAtPos(editor.state.selection.head)
|
||||
@@ -562,10 +583,12 @@ export default {
|
||||
this.$nextTick(() => this.setBlockMenuCoords(this.editor))
|
||||
},
|
||||
onInsertField (type) {
|
||||
this.insertFieldAtRange({ sourceField: { type }, from: this.editor.state.selection.head })
|
||||
const { from, to } = this.editor.state.selection
|
||||
|
||||
this.insertFieldAtRange({ sourceField: { type }, from, to })
|
||||
},
|
||||
onInsertTable ({ rows, cols }) {
|
||||
const $pos = this.editor.state.selection.$head
|
||||
const $pos = this.editor.state.tr.deleteSelection().selection.$head
|
||||
const cell = '<td style="border: 1px solid #000000; padding: 4pt; vertical-align: top"><p style="margin: 0"></p></td>'
|
||||
const html = `<table style="width: 100%; border-collapse: collapse"><tbody>${`<tr>${cell.repeat(cols)}</tr>`.repeat(rows)}</tbody></table>`
|
||||
const isEmpty = $pos.parent.isTextblock && !$pos.parent.content.size
|
||||
@@ -573,13 +596,13 @@ export default {
|
||||
const to = isEmpty ? $pos.after() : from
|
||||
|
||||
this.editor.chain().focus()
|
||||
.deleteSelection()
|
||||
.insertContentAt({ from, to }, html)
|
||||
.setTextSelection(from + 4)
|
||||
.run()
|
||||
},
|
||||
async onImageSelected (event) {
|
||||
const file = event.target.files[0]
|
||||
const pos = this.editor.state.selection.head
|
||||
|
||||
event.target.value = ''
|
||||
|
||||
@@ -603,7 +626,7 @@ export default {
|
||||
await this.$nextTick()
|
||||
|
||||
this.editor.chain().focus()
|
||||
.insertContentAt(pos, { type: 'image', attrs: { htmlAttrs: { src: `blob:${data.uuid}`, style: 'max-width: 100%' } } })
|
||||
.insertContent({ type: 'image', attrs: { htmlAttrs: { src: `blob:${data.uuid}`, style: 'max-width: 100%' } } })
|
||||
.run()
|
||||
},
|
||||
setDynamicMenuCoords (editor) {
|
||||
@@ -835,6 +858,8 @@ export default {
|
||||
const text = clipboardData.getData('text/plain')
|
||||
const clipboardHtml = html || (text.includes('<dynamic-field') ? text : '')
|
||||
|
||||
if (/class="[^"]*doc-list-/.test(html)) this.$emit('add-list')
|
||||
|
||||
if (!clipboardHtml || !clipboardHtml.includes('data-field=')) {
|
||||
return
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user