diff --git a/app/javascript/template_builder/dynamic_block_menu.vue b/app/javascript/template_builder/dynamic_block_menu.vue index d2e9e8ffc..73d7aa67a 100644 --- a/app/javascript/template_builder/dynamic_block_menu.vue +++ b/app/javascript/template_builder/dynamic_block_menu.vue @@ -4,56 +4,43 @@ :style="{ top: coords.top + 'px', left: coords.left + 'px', width: coords.width + 'px', height: coords.height + 'px' }" >
- -
- - + + +
@@ -89,9 +76,6 @@ const IconSplitCell = (props) => h('svg', { xmlns: 'http://www.w3.org/2000/svg', export default { name: 'DynamicBlockMenu', - components: { - IconTrash - }, inject: ['t'], props: { coords: { @@ -102,34 +86,55 @@ export default { emits: ['command', 'resize'], data () { return { - size: null + size: null, + toolbarHeight: 38 } }, computed: { - alignIcons () { - return { - left: IconAlignLeft, - center: IconAlignCenter, - right: IconAlignRight + actionRows () { + const alignActions = [ + { command: 'setBlockAlign', arg: 'left', icon: IconAlignLeft, title: 'align_left', active: this.coords.align === 'left' }, + { command: 'setBlockAlign', arg: 'center', icon: IconAlignCenter, title: 'align_center', active: this.coords.align === 'center' }, + { command: 'setBlockAlign', arg: 'right', icon: IconAlignRight, title: 'align_right', active: this.coords.align === 'right' } + ] + + if (this.coords.type !== 'table') { + return [[alignActions, [{ command: 'deleteSelection', icon: IconTrash, title: 'delete_image', danger: true }]]] } - }, - tableActions () { + return [ - { command: 'addTableRow', arg: false, icon: IconRowInsertTop, title: 'insert_row_above', structural: true }, - { command: 'addTableRow', arg: true, icon: IconRowInsertBottom, title: 'insert_row_below', structural: true }, - { command: 'addTableColumn', arg: false, icon: IconColumnInsertLeft, title: 'insert_column_left', structural: true }, - { command: 'addTableColumn', arg: true, icon: IconColumnInsertRight, title: 'insert_column_right', structural: true }, - { command: 'mergeTableCells', icon: IconMergeCells, title: 'merge_cells', structural: true, enabled: 'canMerge' }, - { command: 'splitTableCell', icon: IconSplitCell, title: 'split_cell', structural: true, enabled: 'canSplit' }, - { command: 'deleteTableRow', icon: IconRowRemove, title: 'delete_row', danger: true, structural: true }, - { command: 'deleteTableColumn', icon: IconColumnRemove, title: 'delete_column', danger: true, structural: true }, - { command: 'deleteTable', icon: IconTrash, title: 'delete_table', danger: true } + [ + alignActions, + [ + { command: 'addTableRow', arg: false, icon: IconRowInsertTop, title: 'insert_row_above', structural: true }, + { command: 'addTableRow', arg: true, icon: IconRowInsertBottom, title: 'insert_row_below', structural: true }, + { command: 'addTableColumn', arg: false, icon: IconColumnInsertLeft, title: 'insert_column_left', structural: true }, + { command: 'addTableColumn', arg: true, icon: IconColumnInsertRight, title: 'insert_column_right', structural: true } + ] + ], + [ + [ + { command: 'mergeTableCells', icon: IconMergeCells, title: 'merge_cells', structural: true, enabled: 'canMerge' }, + { command: 'splitTableCell', icon: IconSplitCell, title: 'split_cell', structural: true, enabled: 'canSplit' } + ], + [ + { command: 'deleteTableRow', icon: IconRowRemove, title: 'delete_row', danger: true, structural: true }, + { command: 'deleteTableColumn', icon: IconColumnRemove, title: 'delete_column', danger: true, structural: true }, + { command: 'deleteTable', icon: IconTrash, title: 'delete_table', danger: true } + ] + ] ] } }, + mounted () { + this.toolbarHeight = this.$refs.toolbar.offsetHeight + }, + updated () { + this.toolbarHeight = this.$refs.toolbar.offsetHeight + }, beforeUnmount () { - window.removeEventListener('mousemove', this.onResizeMove) - window.removeEventListener('mouseup', this.onResizeEnd) + window.removeEventListener('pointermove', this.onResizeMove) + window.removeEventListener('pointerup', this.onResizeEnd) }, methods: { isDisabled (action) { @@ -139,8 +144,8 @@ export default { this.resizeStart = { x: event.clientX, y: event.clientY, width: this.coords.width, height: this.coords.height } this.size = { width: this.coords.width, height: this.coords.height } - window.addEventListener('mousemove', this.onResizeMove) - window.addEventListener('mouseup', this.onResizeEnd) + window.addEventListener('pointermove', this.onResizeMove) + window.addEventListener('pointerup', this.onResizeEnd) }, onResizeMove (event) { const { x, y, width, height } = this.resizeStart @@ -150,8 +155,8 @@ export default { } }, onResizeEnd () { - window.removeEventListener('mousemove', this.onResizeMove) - window.removeEventListener('mouseup', this.onResizeEnd) + window.removeEventListener('pointermove', this.onResizeMove) + window.removeEventListener('pointerup', this.onResizeEnd) if (this.size.width !== this.coords.width || this.size.height !== this.coords.height) { this.$emit('resize', this.size) diff --git a/app/javascript/template_builder/dynamic_editor.js b/app/javascript/template_builder/dynamic_editor.js index c1475fd64..ef25279c6 100644 --- a/app/javascript/template_builder/dynamic_editor.js +++ b/app/javascript/template_builder/dynamic_editor.js @@ -104,15 +104,24 @@ img.ProseMirror-separator { } [data-resize-handle] { + --handle-size: calc(10px / var(--zoom, 1)); display: none; - width: 10px; - height: 10px; + width: var(--handle-size); + height: var(--handle-size); background: #ffffff; - border: 2px solid #3b82f6; + border: calc(2px / var(--zoom, 1)) solid #3b82f6; border-radius: 2px; z-index: 1; } +@media (pointer: coarse) { + [data-resize-handle]::after { + content: ""; + position: absolute; + inset: calc(-8px / var(--zoom, 1)); + } +} + .ProseMirror-selectednode [data-resize-wrapper] { outline: 2px solid #3b82f6; } @@ -121,10 +130,10 @@ img.ProseMirror-separator { display: block; } -[data-resize-handle="top-left"] { margin: -5px 0 0 -5px; cursor: nwse-resize; } -[data-resize-handle="top-right"] { margin: -5px -5px 0 0; cursor: nesw-resize; } -[data-resize-handle="bottom-left"] { margin: 0 0 -5px -5px; cursor: nesw-resize; } -[data-resize-handle="bottom-right"] { margin: 0 -5px -5px 0; cursor: nwse-resize; } +[data-resize-handle="top-left"] { margin: calc(var(--handle-size) / -2) 0 0 calc(var(--handle-size) / -2); cursor: nwse-resize; } +[data-resize-handle="top-right"] { margin: calc(var(--handle-size) / -2) calc(var(--handle-size) / -2) 0 0; cursor: nesw-resize; } +[data-resize-handle="bottom-left"] { margin: 0 0 calc(var(--handle-size) / -2) calc(var(--handle-size) / -2); cursor: nesw-resize; } +[data-resize-handle="bottom-right"] { margin: 0 calc(var(--handle-size) / -2) calc(var(--handle-size) / -2) 0; cursor: nwse-resize; } .ProseMirror .selectedCell { position: relative; diff --git a/app/javascript/template_builder/dynamic_menu.vue b/app/javascript/template_builder/dynamic_menu.vue index 059243512..a4b0c2335 100644 --- a/app/javascript/template_builder/dynamic_menu.vue +++ b/app/javascript/template_builder/dynamic_menu.vue @@ -9,7 +9,7 @@