mirror of
https://github.com/docusealco/docuseal
synced 2026-11-04 14:42:32 -05:00
simplify dynamic editor code
This commit is contained in:
1 parent
4f5e72f983
commit
a70ac571e3
3 files changed
+34
-57
No files matched your search
@@ -43,7 +43,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="size && coords.type === 'table'"
|
||||
v-if="size"
|
||||
class="absolute top-0 left-0 border border-dashed border-blue-500"
|
||||
:style="{ width: size.width + 'px', height: size.height + 'px' }"
|
||||
/>
|
||||
@@ -114,8 +114,8 @@ export default {
|
||||
],
|
||||
[
|
||||
[
|
||||
{ command: 'mergeTableCells', icon: IconMergeCells, title: 'merge_cells', structural: true, enabled: 'canMerge' },
|
||||
{ command: 'splitTableCell', icon: IconSplitCell, title: 'split_cell', structural: true, enabled: 'canSplit' }
|
||||
{ command: 'mergeTableCells', icon: IconMergeCells, title: 'merge_cells', structural: true, disabled: !this.coords.canMerge },
|
||||
{ command: 'splitTableCell', icon: IconSplitCell, title: 'split_cell', structural: true, disabled: !this.coords.canSplit }
|
||||
],
|
||||
[
|
||||
{ command: 'deleteTableRow', icon: IconRowRemove, title: 'delete_row', danger: true, structural: true },
|
||||
@@ -138,7 +138,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
isDisabled (action) {
|
||||
return (action.structural && !this.coords.isRegular) || (action.enabled && !this.coords[action.enabled])
|
||||
return (action.structural && !this.coords.isRegular) || action.disabled
|
||||
},
|
||||
startResize (event) {
|
||||
this.resizeStart = { x: event.clientX, y: event.clientY, width: this.coords.width, height: this.coords.height }
|
||||
|
||||
@@ -1058,8 +1058,6 @@ function tableCellNodes (table) {
|
||||
function styleNewCells (tr, existingCells) {
|
||||
const table = findTable(tr.selection.$head)
|
||||
|
||||
if (!table) return
|
||||
|
||||
const map = TableMap.get(table.node)
|
||||
const cellPositions = [...new Set(map.map)]
|
||||
const isNew = (pos) => !existingCells.has(table.node.nodeAt(pos))
|
||||
@@ -1098,15 +1096,7 @@ function styleNewCells (tr, existingCells) {
|
||||
})
|
||||
}
|
||||
|
||||
function updateTableCols (tr, tablePos, update) {
|
||||
const table = tr.doc.nodeAt(tablePos)
|
||||
|
||||
if (!table.attrs.cols.length) return
|
||||
|
||||
tr.setNodeMarkup(tablePos, null, { ...table.attrs, cols: update([...table.attrs.cols]) })
|
||||
}
|
||||
|
||||
function runTableCommand (command, { state, tr, dispatch }, { colsUpdate } = {}) {
|
||||
function runTableCommand (command, { state, tr, dispatch }, colsUpdate) {
|
||||
const table = findEditableTable(state)
|
||||
|
||||
if (!table) return false
|
||||
@@ -1122,7 +1112,13 @@ function runTableCommand (command, { state, tr, dispatch }, { colsUpdate } = {})
|
||||
styleNewCells(tr, existingCells)
|
||||
|
||||
if (colsUpdate && colsMatch) {
|
||||
updateTableCols(tr, tr.mapping.map(table.pos), (cols) => colsUpdate(cols, rect))
|
||||
const tablePos = tr.mapping.map(table.pos)
|
||||
const { attrs } = tr.doc.nodeAt(tablePos)
|
||||
const cols = [...attrs.cols]
|
||||
|
||||
colsUpdate(cols, rect)
|
||||
|
||||
tr.setNodeMarkup(tablePos, null, { ...attrs, cols })
|
||||
}
|
||||
|
||||
return true
|
||||
@@ -1142,9 +1138,10 @@ const TableCommands = Extension.create({
|
||||
plugin.props.handlePaste = (view, event, slice) => {
|
||||
const table = findTable(view.state.selection.$head)
|
||||
|
||||
if (table && !isRegularTable(table.node)) return view.state.selection instanceof CellSelection
|
||||
if (!table) return false
|
||||
if (!isRegularTable(table.node)) return view.state.selection instanceof CellSelection
|
||||
|
||||
const existingCells = table ? tableCellNodes(table.node) : new Set()
|
||||
const existingCells = tableCellNodes(table.node)
|
||||
|
||||
const dispatch = (tr) => {
|
||||
styleNewCells(tr, existingCells)
|
||||
@@ -1181,14 +1178,10 @@ const TableCommands = Extension.create({
|
||||
addCommands () {
|
||||
return {
|
||||
addTableRow: (after) => (props) => runTableCommand(after ? addRowAfter : addRowBefore, props),
|
||||
addTableColumn: (after) => (props) => runTableCommand(after ? addColumnAfter : addColumnBefore, props, {
|
||||
colsUpdate: (cols, rect) => {
|
||||
const index = after ? rect.right : rect.left
|
||||
addTableColumn: (after) => (props) => runTableCommand(after ? addColumnAfter : addColumnBefore, props, (cols, rect) => {
|
||||
const index = after ? rect.right : rect.left
|
||||
|
||||
cols.splice(index, 0, { ...cols[after ? rect.right - 1 : rect.left] })
|
||||
|
||||
return cols
|
||||
}
|
||||
cols.splice(index, 0, { ...cols[after ? index - 1 : index] })
|
||||
}),
|
||||
deleteTableRow: () => (props) => {
|
||||
const table = findEditableTable(props.state)
|
||||
@@ -1218,13 +1211,7 @@ const TableCommands = Extension.create({
|
||||
return true
|
||||
}
|
||||
|
||||
return runTableCommand(deleteColumn, props, {
|
||||
colsUpdate: (cols, { left, right }) => {
|
||||
cols.splice(left, right - left)
|
||||
|
||||
return cols
|
||||
}
|
||||
})
|
||||
return runTableCommand(deleteColumn, props, (cols, { left, right }) => cols.splice(left, right - left))
|
||||
},
|
||||
mergeTableCells: () => (props) => runTableCommand(mergeCells, props),
|
||||
splitTableCell: () => (props) => runTableCommand(splitCell, props),
|
||||
@@ -1247,7 +1234,7 @@ const TableCommands = Extension.create({
|
||||
let htmlAttrs = table.node.attrs.htmlAttrs
|
||||
|
||||
if (isFloating && align !== 'center') {
|
||||
const gap = [el.style.marginLeft, el.style.marginRight].find((value) => value && value !== 'auto' && parseFloat(value)) || '0'
|
||||
const gap = [el.style.marginLeft, el.style.marginRight].find((value) => parseFloat(value)) || '0'
|
||||
|
||||
margins = align === 'left' ? ['0', gap] : [gap, '0']
|
||||
htmlAttrs = withStyle(htmlAttrs, 'float', align)
|
||||
@@ -1593,7 +1580,7 @@ export function buildEditor ({ dynamicAreaProps, attachmentsIndex, renderHtmlFor
|
||||
const MIN_SIZE_PX = 16
|
||||
|
||||
function findResizeTarget (view, event) {
|
||||
const cellDom = event.target.closest?.('td, th')
|
||||
const cellDom = event.target.closest('td, th')
|
||||
|
||||
if (!cellDom) return null
|
||||
|
||||
@@ -1671,7 +1658,7 @@ export function buildEditor ({ dynamicAreaProps, attachmentsIndex, renderHtmlFor
|
||||
guide.remove()
|
||||
document.body.style.cursor = ''
|
||||
|
||||
const delta = ((isColumn ? e.clientX - event.clientX : e.clientY - event.clientY)) / dynamicAreaProps.getZoom()
|
||||
const delta = (isColumn ? e.clientX - event.clientX : e.clientY - event.clientY) / dynamicAreaProps.getZoom()
|
||||
|
||||
if (!delta) return
|
||||
|
||||
@@ -1795,7 +1782,7 @@ export function buildEditor ({ dynamicAreaProps, attachmentsIndex, renderHtmlFor
|
||||
onUpdate: (updatedNode) => updatedNode.attrs.htmlAttrs === node.attrs.htmlAttrs,
|
||||
options: {
|
||||
directions: ['top-left', 'top-right', 'bottom-left', 'bottom-right'],
|
||||
min: { width: 16, height: 16 },
|
||||
min: { width: MIN_SIZE_PX, height: MIN_SIZE_PX },
|
||||
preserveAspectRatio: true
|
||||
}
|
||||
})
|
||||
|
||||
@@ -192,13 +192,13 @@
|
||||
class="absolute z-10 top-full mt-1 w-28 p-1 bg-white border border-neutral-200 rounded-lg shadow-lg"
|
||||
>
|
||||
<button
|
||||
v-for="(label, style) in listStyles"
|
||||
v-for="({ label, marker }, style) in listStyles"
|
||||
:key="style"
|
||||
class="flex items-center gap-2 w-full text-left px-2 py-1 rounded-md hover:bg-neutral-100"
|
||||
class="flex items-center gap-2 w-full px-2 py-1 rounded-md hover:bg-neutral-100"
|
||||
:class="{ 'bg-neutral-200': style === listStyle }"
|
||||
@click="toggleList(style)"
|
||||
>
|
||||
<span class="w-4 text-center">{{ listMarkers[style] }}</span>
|
||||
<span class="w-4 text-center">{{ marker }}</span>
|
||||
{{ label }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -379,10 +379,7 @@ export default {
|
||||
IconList,
|
||||
IconX
|
||||
},
|
||||
inject: {
|
||||
t: 't',
|
||||
documentFonts: { default: () => [] }
|
||||
},
|
||||
inject: ['t', 'documentFonts'],
|
||||
props: {
|
||||
editor: {
|
||||
type: Object,
|
||||
@@ -445,16 +442,9 @@ export default {
|
||||
},
|
||||
listStyles () {
|
||||
return {
|
||||
disc: this.t('dots'),
|
||||
dash: this.t('dash'),
|
||||
decimal: this.t('numbers')
|
||||
}
|
||||
},
|
||||
listMarkers () {
|
||||
return {
|
||||
disc: '•',
|
||||
dash: '–',
|
||||
decimal: '1.'
|
||||
disc: { label: this.t('dots'), marker: '•' },
|
||||
dash: { label: this.t('dash'), marker: '–' },
|
||||
decimal: { label: this.t('numbers'), marker: '1.' }
|
||||
}
|
||||
},
|
||||
colors () {
|
||||
@@ -514,12 +504,12 @@ export default {
|
||||
})
|
||||
},
|
||||
toggleBold () {
|
||||
this.toggleStyledMark('bold', 'font-weight', 'bold', this.isBold, (style) => parseInt(style.fontWeight) >= 600)
|
||||
this.toggleStyledMark('bold', 'font-weight', this.isBold, (style) => parseInt(style.fontWeight) >= 600)
|
||||
},
|
||||
toggleItalic () {
|
||||
this.toggleStyledMark('italic', 'font-style', 'italic', this.isItalic, (style) => style.fontStyle === 'italic')
|
||||
this.toggleStyledMark('italic', 'font-style', this.isItalic, (style) => style.fontStyle === 'italic')
|
||||
},
|
||||
toggleStyledMark (markName, property, value, isActive, isStyled) {
|
||||
toggleStyledMark (markName, property, isActive, isStyled) {
|
||||
const isSegmentStyled = ({ from }) => isStyled(getComputedStyle(this.textElementAt(from)))
|
||||
|
||||
if (isActive) {
|
||||
@@ -540,7 +530,7 @@ export default {
|
||||
|
||||
if (tr.docChanged) view.dispatch(tr)
|
||||
|
||||
this.editor.commands.setListMarkerStyle(property, value)
|
||||
this.editor.commands.setListMarkerStyle(property, markName)
|
||||
}
|
||||
},
|
||||
selectedTextSegments () {
|
||||
|
||||
Reference in new issue
Block a user