From c88cd34ed9dfc10e2f38e856b68a78cf5e7eea6d Mon Sep 17 00:00:00 2001 From: Artem Nistuley Date: Mon, 26 May 2025 22:51:02 +0300 Subject: [PATCH] floating page breaks --- package-lock.json | 29 ++++- packages/super-editor/package.json | 6 +- .../assets/styles/extensions/pagination.css | 20 ++- .../src/components/pagination-helpers.js | 4 +- packages/super-editor/src/core/Editor.js | 1 + .../dev/components/DeveloperPlayground.vue | 9 ++ .../src/extensions/pagination/pagination.js | 114 ++++++++++++++++-- packages/super-editor/vite.config.js | 2 +- packages/superdoc/src/SuperDoc.vue | 1 + packages/superdoc/src/core/SuperDoc.js | 1 + .../src/dev/components/SuperdocDev.vue | 5 + 11 files changed, 178 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index a66aa47525..34a0e1dd97 100644 --- a/package-lock.json +++ b/package-lock.json @@ -675,6 +675,31 @@ "node": ">=12" } }, + "node_modules/@floating-ui/core": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.0.tgz", + "integrity": "sha512-FRdBLykrPPA6P76GGGqlex/e7fbe0F1ykgxHYNXQsH/iTEtjMj/f9bpY5oQqbjt5VgZvgz/uKXbGuROijh3VLA==", + "dev": true, + "dependencies": { + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.0.tgz", + "integrity": "sha512-lGTor4VlXcesUMh1cupTUTDoCxMb0V6bm3CnxHzQcw8Eaf1jQbgQX4i02fYgT0vJ82tb5MZ4CZk1LRGkktJCzg==", + "dev": true, + "dependencies": { + "@floating-ui/core": "^1.7.0", + "@floating-ui/utils": "^0.2.9" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", + "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==", + "dev": true + }, "node_modules/@harbour-enterprises/common": { "resolved": "shared/common", "link": true @@ -14938,6 +14963,7 @@ "xml-js": "^1.6.11" }, "devDependencies": { + "@floating-ui/dom": "^1.7.0", "@playwright/test": "^1.51.0", "@vitejs/plugin-vue": "^5.0.4", "@vue/test-utils": "^2.4.6", @@ -14952,6 +14978,7 @@ "which": "^5.0.0" }, "peerDependencies": { + "@floating-ui/dom": "^1.7.0", "naive-ui": "^2.38.2", "tippy.js": "^6.3.7", "vite-plugin-node-polyfills": "^0.22.0", @@ -15265,7 +15292,7 @@ }, "packages/superdoc": { "name": "@harbour-enterprises/superdoc", - "version": "0.11.32", + "version": "0.11.37", "license": "AGPL-3.0", "dependencies": { "buffer-crc32": "^1.0.0", diff --git a/packages/super-editor/package.json b/packages/super-editor/package.json index e0ed687d72..5d2d635b25 100644 --- a/packages/super-editor/package.json +++ b/packages/super-editor/package.json @@ -73,7 +73,8 @@ "tippy.js": "^6.3.7", "vite-plugin-node-polyfills": "^0.22.0", "y-prosemirror": "^1.2.12", - "yjs": "13.6.19" + "yjs": "13.6.19", + "@floating-ui/dom": "^1.7.0" }, "devDependencies": { "@playwright/test": "^1.51.0", @@ -87,6 +88,7 @@ "vite": "^5.4.12", "vitest": "^1.6.1", "vue-draggable-next": "^2.2.1", - "which": "^5.0.0" + "which": "^5.0.0", + "@floating-ui/dom": "^1.7.0" } } diff --git a/packages/super-editor/src/assets/styles/extensions/pagination.css b/packages/super-editor/src/assets/styles/extensions/pagination.css index e0e59b33c5..ba463816be 100644 --- a/packages/super-editor/src/assets/styles/extensions/pagination.css +++ b/packages/super-editor/src/assets/styles/extensions/pagination.css @@ -1,3 +1,7 @@ +:root { + --sd-editor-separator-height: 18px; +} + .pagination-section-header { cursor: default; } @@ -23,8 +27,8 @@ .pagination-separator { position: relative; display: block; - height: 18px; - min-height: 18px; + height: var(--sd-editor-separator-height); + min-height: var(--sd-editor-separator-height); min-width: 100%; width: 100%; border-top: 1px solid #DBDBDB; @@ -32,6 +36,18 @@ cursor: default; } +.pagination-separator--table { + border: 0; +} + +.pagination-separator-floating { + position: fixed; + height: var(--sd-editor-separator-height); + border-top: 1px solid #DBDBDB; + border-bottom: 1px solid #DBDBDB; + pointer-events: none; +} + .pagination-inner { position: absolute; top: 0; diff --git a/packages/super-editor/src/components/pagination-helpers.js b/packages/super-editor/src/components/pagination-helpers.js index 9514badc5c..4dba7f511a 100644 --- a/packages/super-editor/src/components/pagination-helpers.js +++ b/packages/super-editor/src/components/pagination-helpers.js @@ -23,7 +23,9 @@ export function adjustPaginationBreaks(editorElem, editor) { if (!firstLeft) firstLeft = left; if (left !== firstLeft) { const diff = left - firstLeft; + // Note: elements with "position: fixed" do not work correctly with transform style. + // node.style.left = `${diff}px`; node.style.transform = `translateX(${diff}px)`; } }); -}; \ No newline at end of file +}; diff --git a/packages/super-editor/src/core/Editor.js b/packages/super-editor/src/core/Editor.js index c72e40543e..3d9677dc3c 100644 --- a/packages/super-editor/src/core/Editor.js +++ b/packages/super-editor/src/core/Editor.js @@ -191,6 +191,7 @@ export class Editor extends EventEmitter { lastSelection: null, suppressDefaultDocxStyles: false, jsonOverride: false, + paginationFloatingClass: null, onBeforeCreate: () => null, onCreate: () => null, onUpdate: () => null, diff --git a/packages/super-editor/src/dev/components/DeveloperPlayground.vue b/packages/super-editor/src/dev/components/DeveloperPlayground.vue index 6891e254df..5e7b9fcee6 100644 --- a/packages/super-editor/src/dev/components/DeveloperPlayground.vue +++ b/packages/super-editor/src/dev/components/DeveloperPlayground.vue @@ -178,6 +178,13 @@ onMounted(async () => {