mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-19 23:00:13 +00:00
Table selection type & table deletion shortcut (#7627)
Some checks are pending
CI / test (push) Blocked by required conditions
CI / build (push) Waiting to run
CI / svelte-check (push) Blocked by required conditions
CI / formatting (push) Blocked by required conditions
CI / uitest (push) Waiting to run
CI / uitest-pg (push) Waiting to run
CI / uitest-qms (push) Waiting to run
CI / docker-build (push) Blocked by required conditions
CI / dist-build (push) Blocked by required conditions
Some checks are pending
CI / test (push) Blocked by required conditions
CI / build (push) Waiting to run
CI / svelte-check (push) Blocked by required conditions
CI / formatting (push) Blocked by required conditions
CI / uitest (push) Waiting to run
CI / uitest-pg (push) Waiting to run
CI / uitest-qms (push) Waiting to run
CI / docker-build (push) Blocked by required conditions
CI / dist-build (push) Blocked by required conditions
Signed-off-by: Victor Ilyushchenko <alt13ri@gmail.com>
This commit is contained in:
parent
24b66777ea
commit
c9416ed852
@ -65,6 +65,7 @@
|
|||||||
--highlight-red-hover: #ff967e;
|
--highlight-red-hover: #ff967e;
|
||||||
--highlight-red-press: #f96f50bd;
|
--highlight-red-press: #f96f50bd;
|
||||||
|
|
||||||
|
--text-editor-selected-node-background: rgba(43, 81, 144, 0.1);
|
||||||
--text-editor-selected-node-color: #93CAF3;
|
--text-editor-selected-node-color: #93CAF3;
|
||||||
|
|
||||||
--text-editor-highlighted-node-warning-active-background-color: #F2D7AE;
|
--text-editor-highlighted-node-warning-active-background-color: #F2D7AE;
|
||||||
|
@ -390,6 +390,12 @@ table.proseTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table-node-selected {
|
||||||
|
.proseTable {
|
||||||
|
background-color: var(--text-editor-selected-node-background);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.proseBlockQuote {
|
.proseBlockQuote {
|
||||||
margin-inline: 1px 0;
|
margin-inline: 1px 0;
|
||||||
padding-left: 1.5em;
|
padding-left: 1.5em;
|
||||||
|
@ -29,23 +29,66 @@ import AddRowBefore from '../../icons/table/AddRowBefore.svelte'
|
|||||||
import DeleteCol from '../../icons/table/DeleteCol.svelte'
|
import DeleteCol from '../../icons/table/DeleteCol.svelte'
|
||||||
import DeleteRow from '../../icons/table/DeleteRow.svelte'
|
import DeleteRow from '../../icons/table/DeleteRow.svelte'
|
||||||
import DeleteTable from '../../icons/table/DeleteTable.svelte'
|
import DeleteTable from '../../icons/table/DeleteTable.svelte'
|
||||||
|
import { Plugin } from '@tiptap/pm/state'
|
||||||
|
import { TableSelection } from './types'
|
||||||
|
import { Decoration, DecorationSet } from '@tiptap/pm/view'
|
||||||
|
|
||||||
export const Table = TiptapTable.extend({
|
export const Table = TiptapTable.extend({
|
||||||
draggable: true,
|
draggable: true,
|
||||||
|
|
||||||
addKeyboardShortcuts () {
|
addKeyboardShortcuts () {
|
||||||
return {
|
return {
|
||||||
'Mod-Backspace': () => handleDelete(this.editor),
|
Backspace: () => handleDelete(this.editor),
|
||||||
'Mod-Delete': () => handleDelete(this.editor)
|
Delete: () => handleDelete(this.editor),
|
||||||
|
'Mod-Backspace': () => handleModDelete(this.editor),
|
||||||
|
'Mod-Delete': () => handleModDelete(this.editor)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addNodeView () {
|
addNodeView () {
|
||||||
return SvelteNodeViewRenderer(TableNodeView, {})
|
return SvelteNodeViewRenderer(TableNodeView, {})
|
||||||
|
},
|
||||||
|
addProseMirrorPlugins () {
|
||||||
|
return [...(this.parent?.() ?? []), tableSelectionHighlight()]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function handleDelete (editor: Editor): boolean {
|
function handleDelete (editor: Editor): boolean {
|
||||||
const { selection } = editor.state
|
const { selection } = editor.state.tr
|
||||||
|
if (selection instanceof TableSelection && isTableSelected(selection)) {
|
||||||
|
return editor.commands.deleteTable()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
export const tableSelectionHighlight = (): Plugin<DecorationSet> => {
|
||||||
|
return new Plugin<DecorationSet>({
|
||||||
|
props: {
|
||||||
|
decorations (state) {
|
||||||
|
return this.getState(state)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
init: () => {
|
||||||
|
return DecorationSet.empty
|
||||||
|
},
|
||||||
|
apply (tr, value, oldState, newState) {
|
||||||
|
const selection = newState.selection
|
||||||
|
if (!(selection instanceof TableSelection)) return DecorationSet.empty
|
||||||
|
|
||||||
|
const table = findTable(newState.selection)
|
||||||
|
if (table === undefined) return DecorationSet.empty
|
||||||
|
|
||||||
|
const decorations: Decoration[] = [
|
||||||
|
Decoration.node(table.pos, table.pos + table.node.nodeSize, { class: 'table-node-selected' })
|
||||||
|
]
|
||||||
|
return DecorationSet.create(newState.doc, decorations)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleModDelete (editor: Editor): boolean {
|
||||||
|
const { selection } = editor.state.tr
|
||||||
if (selection instanceof CellSelection) {
|
if (selection instanceof CellSelection) {
|
||||||
if (isTableSelected(selection)) {
|
if (isTableSelected(selection)) {
|
||||||
return editor.commands.deleteTable()
|
return editor.commands.deleteTable()
|
||||||
|
@ -14,9 +14,15 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import { type Node as ProseMirrorNode } from '@tiptap/pm/model'
|
import { type Node as ProseMirrorNode } from '@tiptap/pm/model'
|
||||||
|
import { CellSelection } from '@tiptap/pm/tables'
|
||||||
|
|
||||||
export interface TableNodeLocation {
|
export interface TableNodeLocation {
|
||||||
pos: number
|
pos: number
|
||||||
start: number
|
start: number
|
||||||
node: ProseMirrorNode
|
node: ProseMirrorNode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This subclass serves as a tag to distinguish between situations where
|
||||||
|
// the table is selected as a node and when all cells in the table are selected,
|
||||||
|
// the deletion behavior depends on this.
|
||||||
|
export class TableSelection extends CellSelection {}
|
||||||
|
@ -17,7 +17,7 @@ import { findParentNode } from '@tiptap/core'
|
|||||||
import { type Selection, type Transaction } from '@tiptap/pm/state'
|
import { type Selection, type Transaction } from '@tiptap/pm/state'
|
||||||
import { CellSelection, type Rect, TableMap, addColumn, addRow } from '@tiptap/pm/tables'
|
import { CellSelection, type Rect, TableMap, addColumn, addRow } from '@tiptap/pm/tables'
|
||||||
|
|
||||||
import { type TableNodeLocation } from './types'
|
import { TableSelection, type TableNodeLocation } from './types'
|
||||||
|
|
||||||
export function insertColumn (table: TableNodeLocation, index: number, tr: Transaction): Transaction {
|
export function insertColumn (table: TableNodeLocation, index: number, tr: Transaction): Transaction {
|
||||||
const map = TableMap.get(table.node)
|
const map = TableMap.get(table.node)
|
||||||
@ -71,7 +71,7 @@ export function selectTable (table: TableNodeLocation, tr: Transaction): Transac
|
|||||||
const $head = tr.doc.resolve(table.start + map[0])
|
const $head = tr.doc.resolve(table.start + map[0])
|
||||||
const $anchor = tr.doc.resolve(table.start + map[map.length - 1])
|
const $anchor = tr.doc.resolve(table.start + map[map.length - 1])
|
||||||
|
|
||||||
return tr.setSelection(new CellSelection($anchor, $head))
|
return tr.setSelection(new TableSelection($anchor, $head))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isColumnSelected = (columnIndex: number, selection: Selection): boolean => {
|
export const isColumnSelected = (columnIndex: number, selection: Selection): boolean => {
|
||||||
|
Loading…
Reference in New Issue
Block a user