diff --git a/apps/client/src/features/editor/components/slash-menu/menu-items.ts b/apps/client/src/features/editor/components/slash-menu/menu-items.ts index f56d7f04..14f26b9b 100644 --- a/apps/client/src/features/editor/components/slash-menu/menu-items.ts +++ b/apps/client/src/features/editor/components/slash-menu/menu-items.ts @@ -20,6 +20,7 @@ import { IconCalendar, IconAppWindow, IconSitemap, + IconPageBreak, } from "@tabler/icons-react"; import { CommandProps, @@ -153,6 +154,19 @@ const CommandGroups: SlashMenuGroupedItemsType = { command: ({ editor, range }: CommandProps) => editor.chain().focus().deleteRange(range).setHorizontalRule().run(), }, + { + title: "Page break", + description: "Insert page break", + searchTerms: ["page break", "hr"], + icon: IconPageBreak, + command: ({ editor, range }: CommandProps) => + editor + .chain() + .focus() + .deleteRange(range) + .insertContent('

') + .run(), + }, { title: "Image", description: "Upload any image from your device.", diff --git a/apps/client/src/features/editor/extensions/extensions.ts b/apps/client/src/features/editor/extensions/extensions.ts index ecdea2e7..2739fbca 100644 --- a/apps/client/src/features/editor/extensions/extensions.ts +++ b/apps/client/src/features/editor/extensions/extensions.ts @@ -46,6 +46,7 @@ import { Heading, Highlight, UniqueID, + HorizontalRule, } from "@docmost/editor-ext"; import { randomElement, @@ -108,7 +109,9 @@ export const mainExtensions = [ spellcheck: false, }, }, + horizontalRule: false, }), + HorizontalRule, Heading, UniqueID.configure({ types: ["heading", "paragraph"], diff --git a/apps/client/src/features/editor/styles/core.css b/apps/client/src/features/editor/styles/core.css index 0aed878e..77443102 100644 --- a/apps/client/src/features/editor/styles/core.css +++ b/apps/client/src/features/editor/styles/core.css @@ -110,6 +110,14 @@ border-top: 1px solid #68cef8; } + hr[data-type="pagebreak"] { + border-top: 1px dashed var(--mantine-color-dark-2) !important; + } + + .ProseMirror[contenteditable="false"] hr[data-type="pagebreak"] { + display: none !important; + } + .ProseMirror-selectednode { outline: 2px solid #70cff8; } @@ -186,7 +194,6 @@ margin-left: auto; margin-right: auto; } - } .ProseMirror > h1, @@ -195,13 +202,11 @@ .ProseMirror > h4, .ProseMirror > h5, .ProseMirror > h6 { - > .link-btn { cursor: pointer; position: relative; - } - + > .link-btn > .link-btn-content { opacity: 0; position: absolute; @@ -213,7 +218,7 @@ justify-content: center; flex-direction: column; } - + &:hover > .link-btn > .link-btn-content { opacity: 1; } diff --git a/apps/client/src/features/editor/styles/print.css b/apps/client/src/features/editor/styles/print.css index c63e376b..de71700d 100644 --- a/apps/client/src/features/editor/styles/print.css +++ b/apps/client/src/features/editor/styles/print.css @@ -20,4 +20,10 @@ .tableWrapper { overflow: hidden !important; } + + hr[data-type="pagebreak"] { + break-before: always; + page-break-before: always; + visibility: hidden; + } } diff --git a/apps/server/src/collaboration/collaboration.util.ts b/apps/server/src/collaboration/collaboration.util.ts index 06133c3f..5d31b1af 100644 --- a/apps/server/src/collaboration/collaboration.util.ts +++ b/apps/server/src/collaboration/collaboration.util.ts @@ -36,6 +36,7 @@ import { Highlight, UniqueID, addUniqueIdsToDoc, + HorizontalRule, } from '@docmost/editor-ext'; import { generateText, getSchema, JSONContent } from '@tiptap/core'; import { generateHTML, generateJSON } from '../common/helpers/prosemirror/html'; @@ -48,7 +49,9 @@ export const tiptapExtensions = [ StarterKit.configure({ codeBlock: false, heading: false, + horizontalRule: false, }), + HorizontalRule, Heading, UniqueID.configure({ types: ['heading', 'paragraph'], diff --git a/package.json b/package.json index 30d29a58..a52d0b86 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "@tiptap/extension-heading": "2.27.1", "@tiptap/extension-highlight": "2.27.1", "@tiptap/extension-history": "2.27.1", + "@tiptap/extension-horizontal-rule": "2.27.1", "@tiptap/extension-image": "2.27.1", "@tiptap/extension-link": "2.27.1", "@tiptap/extension-list-item": "2.27.1", diff --git a/packages/editor-ext/src/index.ts b/packages/editor-ext/src/index.ts index 3ff99083..c1ce3503 100644 --- a/packages/editor-ext/src/index.ts +++ b/packages/editor-ext/src/index.ts @@ -23,3 +23,4 @@ export * from "./lib/subpages"; export * from "./lib/highlight"; export * from "./lib/heading/heading"; export * from "./lib/unique-id"; +export * from "./lib/hr"; diff --git a/packages/editor-ext/src/lib/hr.ts b/packages/editor-ext/src/lib/hr.ts new file mode 100644 index 00000000..fe32f111 --- /dev/null +++ b/packages/editor-ext/src/lib/hr.ts @@ -0,0 +1,21 @@ +import { HorizontalRule as TiptapHorizontalRule } from "@tiptap/extension-horizontal-rule"; + +export type HorizontalRuleType = "pageBreak"; + +export const HorizontalRule = TiptapHorizontalRule.extend({ + addAttributes() { + return { + type: { + default: null, + parseHTML: (element) => element.getAttribute("data-type"), + renderHTML: (attributes) => { + if (attributes.type) { + return { + "data-type": attributes.type, + }; + } + }, + }, + }; + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e04b7d17..fb148502 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -77,6 +77,9 @@ importers: '@tiptap/extension-history': specifier: 2.27.1 version: 2.27.1(@tiptap/core@2.27.1(@tiptap/pm@2.27.1))(@tiptap/pm@2.27.1) + '@tiptap/extension-horizontal-rule': + specifier: 2.27.1 + version: 2.27.1(@tiptap/core@2.27.1(@tiptap/pm@2.27.1))(@tiptap/pm@2.27.1) '@tiptap/extension-image': specifier: 2.27.1 version: 2.27.1(@tiptap/core@2.27.1(@tiptap/pm@2.27.1))