73 lines
2.0 KiB
TypeScript
73 lines
2.0 KiB
TypeScript
import { Extension } from "@tiptap/core"
|
|
import {
|
|
decreaseDocsIndent,
|
|
increaseDocsIndent,
|
|
} from "@/lib/drive/docs-indent-actions"
|
|
import { clampIndentLevel, indentLevelToMarginPx } from "@/lib/drive/docs-indent"
|
|
|
|
declare module "@tiptap/core" {
|
|
interface Commands<ReturnType> {
|
|
docsIndent: {
|
|
increaseDocsIndent: () => ReturnType
|
|
decreaseDocsIndent: () => ReturnType
|
|
}
|
|
}
|
|
}
|
|
|
|
export const DocsParagraphIndent = Extension.create({
|
|
name: "docsParagraphIndent",
|
|
|
|
addGlobalAttributes() {
|
|
return [
|
|
{
|
|
types: ["paragraph", "heading"],
|
|
attributes: {
|
|
indentLevel: {
|
|
default: 0,
|
|
parseHTML: (element) => {
|
|
const raw = element.getAttribute("data-indent-level")
|
|
if (raw != null) return clampIndentLevel(Number.parseInt(raw, 10))
|
|
const marginLeft = (element as HTMLElement).style?.marginLeft
|
|
if (marginLeft?.endsWith("px")) {
|
|
const px = Number.parseFloat(marginLeft)
|
|
if (Number.isFinite(px) && px > 0) {
|
|
return clampIndentLevel(Math.round(px / 36))
|
|
}
|
|
}
|
|
return 0
|
|
},
|
|
renderHTML: (attributes) => {
|
|
const level = clampIndentLevel((attributes.indentLevel as number | undefined) ?? 0)
|
|
if (level <= 0) return {}
|
|
return {
|
|
"data-indent-level": String(level),
|
|
style: `margin-left: ${indentLevelToMarginPx(level)}px`,
|
|
}
|
|
},
|
|
},
|
|
},
|
|
},
|
|
]
|
|
},
|
|
|
|
addCommands() {
|
|
return {
|
|
increaseDocsIndent:
|
|
() =>
|
|
({ editor }) =>
|
|
increaseDocsIndent(editor),
|
|
decreaseDocsIndent:
|
|
() =>
|
|
({ editor }) =>
|
|
decreaseDocsIndent(editor),
|
|
}
|
|
},
|
|
|
|
addKeyboardShortcuts() {
|
|
return {
|
|
"Mod-]": () => this.editor.commands.increaseDocsIndent(),
|
|
"Mod-[": () => this.editor.commands.decreaseDocsIndent(),
|
|
}
|
|
},
|
|
})
|