Fixed indent state in editor
X-Lovable-Edit-ID: edt-3f8c8588-8d67-4be2-a84a-6691637e0d58 Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import StarterKit from "@tiptap/starter-kit";
|
||||
import Underline from "@tiptap/extension-underline";
|
||||
import TextAlign from "@tiptap/extension-text-align";
|
||||
import Paragraph from "@tiptap/extension-paragraph";
|
||||
import Heading from "@tiptap/extension-heading";
|
||||
import { Table } from "@tiptap/extension-table";
|
||||
import { TableRow } from "@tiptap/extension-table-row";
|
||||
import { TableCell } from "@tiptap/extension-table-cell";
|
||||
@@ -121,6 +122,29 @@ const PaddedParagraph = Paragraph.extend({
|
||||
},
|
||||
});
|
||||
|
||||
// Heading with same indent attribute so indent works on H1-H3 too
|
||||
const PaddedHeading = Heading.extend({
|
||||
addAttributes() {
|
||||
return {
|
||||
...this.parent?.(),
|
||||
indent: {
|
||||
default: 0,
|
||||
parseHTML: (el) => {
|
||||
const pl = (el as HTMLElement).style.paddingLeft;
|
||||
if (!pl) return 0;
|
||||
const n = parseInt(pl, 10);
|
||||
return isNaN(n) ? 0 : n;
|
||||
},
|
||||
renderHTML: (attrs) => {
|
||||
const i = Number(attrs.indent ?? 0);
|
||||
if (!i) return {};
|
||||
return { style: `padding-left: ${i}px` };
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
const FONT_FAMILIES = [
|
||||
{ value: "Bookman Old Style", label: "Bookman Old Style", pdf: "times" },
|
||||
{ value: "Times New Roman", label: "Times New Roman", pdf: "times" },
|
||||
@@ -268,8 +292,9 @@ export function CustomFormBuilder() {
|
||||
|
||||
const editor = useEditor({
|
||||
extensions: [
|
||||
StarterKit.configure({ heading: { levels: [1, 2, 3] }, paragraph: false }),
|
||||
StarterKit.configure({ heading: false, paragraph: false }),
|
||||
PaddedParagraph,
|
||||
PaddedHeading.configure({ levels: [1, 2, 3] }),
|
||||
Underline,
|
||||
TextAlign.configure({ types: ["heading", "paragraph"] }),
|
||||
Table.configure({ resizable: true, HTMLAttributes: { class: "cf-table" } }),
|
||||
@@ -331,19 +356,39 @@ export function CustomFormBuilder() {
|
||||
|
||||
const INDENT_STEP = 36; // ~0.5"
|
||||
|
||||
const activeIndentNode = (): "heading" | "paragraph" | null => {
|
||||
if (!editor) return null;
|
||||
if (editor.isActive("heading")) return "heading";
|
||||
if (editor.isActive("paragraph")) return "paragraph";
|
||||
return null;
|
||||
};
|
||||
|
||||
const indent = () => {
|
||||
if (!editor) return;
|
||||
const cur = Number(editor.getAttributes("paragraph").indent ?? 0);
|
||||
editor.chain().focus().updateAttributes("paragraph", { indent: cur + INDENT_STEP }).run();
|
||||
// Lists: nest the item instead of changing padding
|
||||
if (editor.isActive("listItem")) {
|
||||
editor.chain().focus().sinkListItem("listItem").run();
|
||||
return;
|
||||
}
|
||||
const node = activeIndentNode();
|
||||
if (!node) return;
|
||||
const cur = Number(editor.getAttributes(node).indent ?? 0);
|
||||
editor.chain().focus().updateAttributes(node, { indent: cur + INDENT_STEP }).run();
|
||||
};
|
||||
|
||||
const outdent = () => {
|
||||
if (!editor) return;
|
||||
const cur = Number(editor.getAttributes("paragraph").indent ?? 0);
|
||||
if (editor.isActive("listItem")) {
|
||||
editor.chain().focus().liftListItem("listItem").run();
|
||||
return;
|
||||
}
|
||||
const node = activeIndentNode();
|
||||
if (!node) return;
|
||||
const cur = Number(editor.getAttributes(node).indent ?? 0);
|
||||
editor
|
||||
.chain()
|
||||
.focus()
|
||||
.updateAttributes("paragraph", { indent: Math.max(0, cur - INDENT_STEP) })
|
||||
.updateAttributes(node, { indent: Math.max(0, cur - INDENT_STEP) })
|
||||
.run();
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user