mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-22 16:27:22 +00:00
EZQMS-342: Add text editor configurable active highlighted node (#4019)
Signed-off-by: Anna No <anna.no@xored.com>
This commit is contained in:
parent
d36dcdc7da
commit
0e11cc704d
@ -3,7 +3,7 @@ import { type Node as ProseMirrorNode, type MarkType } from '@tiptap/pm/model'
|
|||||||
import { Plugin, PluginKey, TextSelection } from '@tiptap/pm/state'
|
import { Plugin, PluginKey, TextSelection } from '@tiptap/pm/state'
|
||||||
import { AddMarkStep, RemoveMarkStep } from '@tiptap/pm/transform'
|
import { AddMarkStep, RemoveMarkStep } from '@tiptap/pm/transform'
|
||||||
import { Decoration, DecorationSet } from '@tiptap/pm/view'
|
import { Decoration, DecorationSet } from '@tiptap/pm/view'
|
||||||
import { NodeUuidExtension, type NodeUuidOptions, type NodeUuidStorage, findNodeUuidMark } from './nodeUuid'
|
import { NodeUuidExtension, type NodeUuidOptions, findNodeUuidMark } from './nodeUuid'
|
||||||
import { type TextEditorCommand } from '../../types'
|
import { type TextEditorCommand } from '../../types'
|
||||||
|
|
||||||
export enum NodeHighlightType {
|
export enum NodeHighlightType {
|
||||||
@ -17,7 +17,7 @@ export function highlightUpdateCommand (): TextEditorCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface NodeHighlightExtensionOptions extends NodeUuidOptions {
|
export interface NodeHighlightExtensionOptions extends NodeUuidOptions {
|
||||||
getNodeHighlightType: (uuid: string) => NodeHighlightType | undefined | null
|
getNodeHighlight: (uuid: string) => { type: NodeHighlightType, isActive?: boolean } | undefined | null
|
||||||
isHighlightModeOn: () => boolean
|
isHighlightModeOn: () => boolean
|
||||||
isAutoSelect?: () => boolean
|
isAutoSelect?: () => boolean
|
||||||
}
|
}
|
||||||
@ -32,21 +32,23 @@ const generateAttributes = (uuid: string, options: NodeHighlightExtensionOptions
|
|||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
const type = options.getNodeHighlightType(uuid)
|
const highlight = options.getNodeHighlight(uuid)
|
||||||
if (type === null || type === undefined) {
|
if (highlight === null || highlight === undefined) {
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
const classAttrs: { class?: string } = {}
|
const classAttrs: { class?: string } = {}
|
||||||
|
|
||||||
if (type === NodeHighlightType.WARNING) {
|
if (highlight.type === NodeHighlightType.WARNING) {
|
||||||
classAttrs.class = 'text-editor-highlighted-node-warning'
|
classAttrs.class = 'text-editor-highlighted-node-warning'
|
||||||
} else if (type === NodeHighlightType.ADD) {
|
} else if (highlight.type === NodeHighlightType.ADD) {
|
||||||
classAttrs.class = 'text-editor-highlighted-node-add'
|
classAttrs.class = 'text-editor-highlighted-node-add'
|
||||||
} else if (type === NodeHighlightType.DELETE) {
|
} else if (highlight.type === NodeHighlightType.DELETE) {
|
||||||
classAttrs.class = 'text-editor-highlighted-node-delete'
|
classAttrs.class = 'text-editor-highlighted-node-delete'
|
||||||
}
|
}
|
||||||
|
|
||||||
return classAttrs
|
return highlight.isActive === true
|
||||||
|
? mergeAttributes(classAttrs, { class: 'text-editor-highlighted-node-selected' })
|
||||||
|
: classAttrs
|
||||||
}
|
}
|
||||||
|
|
||||||
const NodeHighlight = 'node-highlight'
|
const NodeHighlight = 'node-highlight'
|
||||||
@ -69,17 +71,12 @@ declare module '@tiptap/core' {
|
|||||||
/**
|
/**
|
||||||
* Extension allows to highlight nodes based on uuid
|
* Extension allows to highlight nodes based on uuid
|
||||||
*/
|
*/
|
||||||
export const NodeHighlightExtension: Extension<NodeHighlightExtensionOptions, NodeUuidStorage> =
|
export const NodeHighlightExtension: Extension<NodeHighlightExtensionOptions> =
|
||||||
Extension.create<NodeHighlightExtensionOptions>({
|
Extension.create<NodeHighlightExtensionOptions>({
|
||||||
name: NodeHighlight,
|
name: NodeHighlight,
|
||||||
|
|
||||||
addStorage (): NodeUuidStorage {
|
|
||||||
return { activeNodeUuid: null }
|
|
||||||
},
|
|
||||||
|
|
||||||
addProseMirrorPlugins () {
|
addProseMirrorPlugins () {
|
||||||
const options = this.options
|
const options = this.options
|
||||||
const storage: NodeUuidStorage = this.storage
|
|
||||||
|
|
||||||
const plugins = [
|
const plugins = [
|
||||||
...(this.parent?.() ?? []),
|
...(this.parent?.() ?? []),
|
||||||
@ -114,14 +111,14 @@ export const NodeHighlightExtension: Extension<NodeHighlightExtensionOptions, No
|
|||||||
init (_config, state): DecorationSet {
|
init (_config, state): DecorationSet {
|
||||||
const { doc, schema } = state
|
const { doc, schema } = state
|
||||||
const markType = schema.marks[NodeUuidExtension.name]
|
const markType = schema.marks[NodeUuidExtension.name]
|
||||||
return createDecorations(doc, markType, storage, options)
|
return createDecorations(doc, markType, options)
|
||||||
},
|
},
|
||||||
|
|
||||||
apply (tr, decorations, oldState, newState) {
|
apply (tr, decorations, oldState, newState) {
|
||||||
const markType = newState.schema.marks[NodeUuidExtension.name]
|
const markType = newState.schema.marks[NodeUuidExtension.name]
|
||||||
|
|
||||||
if (tr.getMeta(NodeHighlightMeta) !== undefined) {
|
if (tr.getMeta(NodeHighlightMeta) !== undefined) {
|
||||||
return createDecorations(tr.doc, markType, storage, options)
|
return createDecorations(tr.doc, markType, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tr.docChanged) {
|
if (!tr.docChanged) {
|
||||||
@ -136,7 +133,7 @@ export const NodeHighlightExtension: Extension<NodeHighlightExtensionOptions, No
|
|||||||
(step instanceof RemoveMarkStep && step.mark.type === markType)
|
(step instanceof RemoveMarkStep && step.mark.type === markType)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
return createDecorations(tr.doc, markType, storage, options)
|
return createDecorations(tr.doc, markType, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
// update all decorations when changed content has mark changes
|
// update all decorations when changed content has mark changes
|
||||||
@ -157,7 +154,7 @@ export const NodeHighlightExtension: Extension<NodeHighlightExtensionOptions, No
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (hasMarkChanges) {
|
if (hasMarkChanges) {
|
||||||
return createDecorations(tr.doc, markType, storage, options)
|
return createDecorations(tr.doc, markType, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return decorations.map(tr.mapping, tr.doc)
|
return decorations.map(tr.mapping, tr.doc)
|
||||||
@ -189,17 +186,12 @@ export const NodeHighlightExtension: Extension<NodeHighlightExtensionOptions, No
|
|||||||
|
|
||||||
addExtensions () {
|
addExtensions () {
|
||||||
const options: NodeHighlightExtensionOptions = this.options
|
const options: NodeHighlightExtensionOptions = this.options
|
||||||
const storage: NodeUuidStorage = this.storage
|
|
||||||
return [
|
return [
|
||||||
NodeUuidExtension.extend({
|
NodeUuidExtension.extend({
|
||||||
addOptions (): NodeUuidOptions {
|
addOptions (): NodeUuidOptions {
|
||||||
return {
|
return {
|
||||||
...this.parent?.(),
|
...this.parent?.(),
|
||||||
...options,
|
...options
|
||||||
onNodeSelected: (uuid: string) => {
|
|
||||||
storage.activeNodeUuid = uuid
|
|
||||||
options.onNodeSelected?.(uuid)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -210,7 +202,6 @@ export const NodeHighlightExtension: Extension<NodeHighlightExtensionOptions, No
|
|||||||
const createDecorations = (
|
const createDecorations = (
|
||||||
doc: ProseMirrorNode,
|
doc: ProseMirrorNode,
|
||||||
markType: MarkType,
|
markType: MarkType,
|
||||||
storage: NodeUuidStorage,
|
|
||||||
options: NodeHighlightExtensionOptions
|
options: NodeHighlightExtensionOptions
|
||||||
): DecorationSet => {
|
): DecorationSet => {
|
||||||
const decorations: Decoration[] = []
|
const decorations: Decoration[] = []
|
||||||
@ -231,16 +222,7 @@ const createDecorations = (
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
decorations.push(
|
decorations.push(Decoration.inline(range.from, range.to, attributes))
|
||||||
Decoration.inline(
|
|
||||||
range.from,
|
|
||||||
range.to,
|
|
||||||
mergeAttributes(
|
|
||||||
attributes,
|
|
||||||
nodeUuid === storage.activeNodeUuid ? { class: 'text-editor-highlighted-node-selected' } : {}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user