ultisuite-client/lib/drive/docs-indent-actions.ts
R3D347HR4Y 303b2b1074
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
wow
2026-06-11 01:22:40 +02:00

91 lines
3.0 KiB
TypeScript

import type { Editor } from "@tiptap/react"
import type { Node as ProseMirrorNode } from "@tiptap/pm/model"
import { getDocsBlockTargets } from "@/lib/drive/docs-block-targets"
import {
clampIndentLevel,
nextIndentLevel,
} from "@/lib/drive/docs-indent"
function applyBlockIndentDelta(editor: Editor, delta: number): boolean {
const { state } = editor
const targets = getDocsBlockTargets(state.doc, state.selection.from, state.selection.to)
if (targets.length === 0) return false
let tr = state.tr
let changed = false
for (const { pos, node } of targets) {
const current = clampIndentLevel((node.attrs.indentLevel as number | undefined) ?? 0)
const next = nextIndentLevel(current, delta)
if (next === current) continue
tr = tr.setNodeMarkup(pos, undefined, { ...node.attrs, indentLevel: next })
changed = true
}
if (!changed) return false
editor.view.dispatch(tr.scrollIntoView())
return true
}
export function increaseDocsIndent(editor: Editor | null): boolean {
if (!editor || editor.isDestroyed) return false
if (editor.isActive("taskItem")) {
return editor.can().sinkListItem("taskItem")
? editor.chain().focus().sinkListItem("taskItem").run()
: false
}
if (editor.isActive("listItem")) {
return editor.can().sinkListItem("listItem")
? editor.chain().focus().sinkListItem("listItem").run()
: false
}
return applyBlockIndentDelta(editor, 1)
}
export function decreaseDocsIndent(editor: Editor | null): boolean {
if (!editor || editor.isDestroyed) return false
if (editor.isActive("taskItem")) {
return editor.can().liftListItem("taskItem")
? editor.chain().focus().liftListItem("taskItem").run()
: false
}
if (editor.isActive("listItem")) {
return editor.can().liftListItem("listItem")
? editor.chain().focus().liftListItem("listItem").run()
: false
}
return applyBlockIndentDelta(editor, -1)
}
export function canIncreaseDocsIndent(editor: Editor | null): boolean {
if (!editor || editor.isDestroyed) return false
if (editor.isActive("taskItem")) return editor.can().sinkListItem("taskItem")
if (editor.isActive("listItem")) return editor.can().sinkListItem("listItem")
return getDocsBlockTargets(
editor.state.doc,
editor.state.selection.from,
editor.state.selection.to
).some(
({ node }) =>
nextIndentLevel((node.attrs.indentLevel as number | undefined) ?? 0, 1) !==
clampIndentLevel((node.attrs.indentLevel as number | undefined) ?? 0)
)
}
export function canDecreaseDocsIndent(editor: Editor | null): boolean {
if (!editor || editor.isDestroyed) return false
if (editor.isActive("taskItem")) return editor.can().liftListItem("taskItem")
if (editor.isActive("listItem")) return editor.can().liftListItem("listItem")
return getDocsBlockTargets(
editor.state.doc,
editor.state.selection.from,
editor.state.selection.to
).some(({ node }) => clampIndentLevel((node.attrs.indentLevel as number | undefined) ?? 0) > 0)
}