@sethumadhavan004/ink-editor 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.css +5 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +15 -2
- package/dist/index.d.ts +15 -2
- package/dist/index.js +122 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +120 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2224,6 +2224,103 @@ var TabIndent = Extension.create({
|
|
|
2224
2224
|
}
|
|
2225
2225
|
});
|
|
2226
2226
|
|
|
2227
|
+
// src/extensions/SinglePageOverflow.ts
|
|
2228
|
+
import { Plugin as Plugin3, PluginKey as PluginKey3 } from "@tiptap/pm/state";
|
|
2229
|
+
var pluginKey2 = new PluginKey3("singlePageOverflow");
|
|
2230
|
+
function getBodyHeightPx2(view, pageSize) {
|
|
2231
|
+
const card = view.dom.closest(".ink-page-card");
|
|
2232
|
+
if (card) {
|
|
2233
|
+
const style = window.getComputedStyle(card);
|
|
2234
|
+
const paddingTop = parseFloat(style.paddingTop);
|
|
2235
|
+
const paddingBottom = parseFloat(style.paddingBottom);
|
|
2236
|
+
const totalHeight = card.offsetHeight || 0;
|
|
2237
|
+
const bodyPx = totalHeight - paddingTop - paddingBottom;
|
|
2238
|
+
if (bodyPx > 0) return Math.floor(bodyPx / 28) * 28;
|
|
2239
|
+
}
|
|
2240
|
+
const d = PAGE_DIMENSIONS[pageSize];
|
|
2241
|
+
const PX_PER_MM2 = 3.7795;
|
|
2242
|
+
return Math.floor((d.heightMm - d.paddingTopMm - d.paddingBottomMm) * PX_PER_MM2 / 28) * 28;
|
|
2243
|
+
}
|
|
2244
|
+
function splitAtOverflow(doc, view, bodyHeightPx) {
|
|
2245
|
+
let baseY = null;
|
|
2246
|
+
let splitPos = null;
|
|
2247
|
+
doc.forEach((node, offset) => {
|
|
2248
|
+
if (splitPos !== null) return;
|
|
2249
|
+
const pos = offset + 1;
|
|
2250
|
+
if (pos >= doc.content.size) return;
|
|
2251
|
+
let bottom;
|
|
2252
|
+
try {
|
|
2253
|
+
const coords = view.coordsAtPos(pos);
|
|
2254
|
+
if (baseY === null) baseY = coords.top;
|
|
2255
|
+
const endPos = offset + node.nodeSize - 1;
|
|
2256
|
+
bottom = endPos > pos ? view.coordsAtPos(endPos).bottom : coords.bottom;
|
|
2257
|
+
} catch {
|
|
2258
|
+
return;
|
|
2259
|
+
}
|
|
2260
|
+
const relBottom = bottom - (baseY ?? bottom);
|
|
2261
|
+
if (relBottom > bodyHeightPx) {
|
|
2262
|
+
splitPos = offset;
|
|
2263
|
+
}
|
|
2264
|
+
});
|
|
2265
|
+
if (splitPos === null) return null;
|
|
2266
|
+
const schema = doc.type.schema;
|
|
2267
|
+
const fitsContent = doc.slice(0, splitPos).content;
|
|
2268
|
+
const overflowContent = doc.slice(splitPos).content;
|
|
2269
|
+
const fitsJson = schema.nodeFromJSON({ type: "doc", content: fitsContent.toJSON() ?? [] }).toJSON();
|
|
2270
|
+
const overflowJson = schema.nodeFromJSON({ type: "doc", content: overflowContent.toJSON() ?? [] }).toJSON();
|
|
2271
|
+
return { fitsJson, overflowJson };
|
|
2272
|
+
}
|
|
2273
|
+
var SinglePageOverflow = Extension.create({
|
|
2274
|
+
name: "singlePageOverflow",
|
|
2275
|
+
addOptions() {
|
|
2276
|
+
return {
|
|
2277
|
+
pageSize: "A4",
|
|
2278
|
+
onOverflow: () => {
|
|
2279
|
+
}
|
|
2280
|
+
};
|
|
2281
|
+
},
|
|
2282
|
+
addProseMirrorPlugins() {
|
|
2283
|
+
const { pageSize, onOverflow } = this.options;
|
|
2284
|
+
let rafId = null;
|
|
2285
|
+
function scheduleCheck(view) {
|
|
2286
|
+
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
2287
|
+
rafId = requestAnimationFrame(() => {
|
|
2288
|
+
rafId = null;
|
|
2289
|
+
if (view.isDestroyed) return;
|
|
2290
|
+
const bodyHeightPx = getBodyHeightPx2(view, pageSize);
|
|
2291
|
+
const result = splitAtOverflow(view.state.doc, view, bodyHeightPx);
|
|
2292
|
+
if (!result) return;
|
|
2293
|
+
const { fitsJson, overflowJson } = result;
|
|
2294
|
+
const schema = view.state.schema;
|
|
2295
|
+
const fitsDoc = schema.nodeFromJSON(fitsJson);
|
|
2296
|
+
const tr = view.state.tr.replaceWith(0, view.state.doc.content.size, fitsDoc.content);
|
|
2297
|
+
tr.setMeta("addToHistory", false);
|
|
2298
|
+
tr.setMeta("singlePageTrim", true);
|
|
2299
|
+
view.dispatch(tr);
|
|
2300
|
+
onOverflow(fitsJson, overflowJson);
|
|
2301
|
+
});
|
|
2302
|
+
}
|
|
2303
|
+
return [
|
|
2304
|
+
new Plugin3({
|
|
2305
|
+
key: pluginKey2,
|
|
2306
|
+
view(editorView) {
|
|
2307
|
+
return {
|
|
2308
|
+
update(view, prevState) {
|
|
2309
|
+
if (view.state.doc.eq(prevState.doc) || view.state.tr?.getMeta?.("singlePageTrim")) return;
|
|
2310
|
+
if (view.state.doc.content.size !== prevState.doc.content.size || !view.state.doc.eq(prevState.doc)) {
|
|
2311
|
+
scheduleCheck(view);
|
|
2312
|
+
}
|
|
2313
|
+
},
|
|
2314
|
+
destroy() {
|
|
2315
|
+
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
2316
|
+
}
|
|
2317
|
+
};
|
|
2318
|
+
}
|
|
2319
|
+
})
|
|
2320
|
+
];
|
|
2321
|
+
}
|
|
2322
|
+
});
|
|
2323
|
+
|
|
2227
2324
|
// src/components/PagedEditorContent.tsx
|
|
2228
2325
|
import { EditorContent } from "@tiptap/react";
|
|
2229
2326
|
|
|
@@ -2559,7 +2656,8 @@ function PagedEditorContent({
|
|
|
2559
2656
|
colors,
|
|
2560
2657
|
onColorsChange,
|
|
2561
2658
|
toolbarStart,
|
|
2562
|
-
toolbarEnd
|
|
2659
|
+
toolbarEnd,
|
|
2660
|
+
singlePage = false
|
|
2563
2661
|
}) {
|
|
2564
2662
|
const widthPx = getPageWidthPx(pageSize);
|
|
2565
2663
|
const bodyWidthPx = getBodyWidthPx(pageSize);
|
|
@@ -2570,7 +2668,7 @@ function PagedEditorContent({
|
|
|
2570
2668
|
return /* @__PURE__ */ jsxs4(
|
|
2571
2669
|
"div",
|
|
2572
2670
|
{
|
|
2573
|
-
className: "ink-page-wrap"
|
|
2671
|
+
className: `ink-page-wrap${singlePage ? " ink-page-wrap--single" : ""}`,
|
|
2574
2672
|
"data-theme": theme,
|
|
2575
2673
|
style: {
|
|
2576
2674
|
"--ink-bg": colors.canvasBg,
|
|
@@ -2602,7 +2700,8 @@ function PagedEditorContent({
|
|
|
2602
2700
|
className: `ink-page-card${ruled ? " ink-ruled" : ""}`,
|
|
2603
2701
|
style: {
|
|
2604
2702
|
width: widthPx,
|
|
2605
|
-
|
|
2703
|
+
// In singlePage mode: fixed height + overflow hidden so content never visually spills
|
|
2704
|
+
...singlePage ? { height: pageHeightPx, overflow: "hidden" } : { minHeight: pageHeightPx },
|
|
2606
2705
|
padding: `${dims.paddingTopMm}mm ${dims.paddingRightMm}mm ${dims.paddingBottomMm}mm ${dims.paddingLeftMm}mm`,
|
|
2607
2706
|
["--ink-padding-top"]: `${dims.paddingTopMm}mm`,
|
|
2608
2707
|
["--ink-padding-right"]: `${dims.paddingRightMm}mm`,
|
|
@@ -2629,7 +2728,10 @@ function InkEditor({
|
|
|
2629
2728
|
initialFont = "cursive",
|
|
2630
2729
|
initialColors,
|
|
2631
2730
|
toolbarStart,
|
|
2632
|
-
toolbarEnd
|
|
2731
|
+
toolbarEnd,
|
|
2732
|
+
singlePage = false,
|
|
2733
|
+
onOverflow,
|
|
2734
|
+
initialContent
|
|
2633
2735
|
}) {
|
|
2634
2736
|
const [ruled, setRuled] = useState2(false);
|
|
2635
2737
|
const [font, setFont] = useState2(initialFont);
|
|
@@ -2637,14 +2739,17 @@ function InkEditor({
|
|
|
2637
2739
|
...theme === "minimal" ? MINIMAL_DEFAULTS : PARCHMENT_DEFAULTS,
|
|
2638
2740
|
...initialColors
|
|
2639
2741
|
});
|
|
2742
|
+
const extensions = [
|
|
2743
|
+
StarterKit,
|
|
2744
|
+
TextAlign.configure({ types: ["heading", "paragraph"] }),
|
|
2745
|
+
Underline2,
|
|
2746
|
+
TabIndent,
|
|
2747
|
+
...singlePage ? [SinglePageOverflow.configure({ pageSize, onOverflow: onOverflow ?? (() => {
|
|
2748
|
+
}) })] : [PageLayout.configure({ pageSize })]
|
|
2749
|
+
];
|
|
2640
2750
|
const editor = useEditor({
|
|
2641
|
-
extensions
|
|
2642
|
-
|
|
2643
|
-
PageLayout.configure({ pageSize }),
|
|
2644
|
-
TextAlign.configure({ types: ["heading", "paragraph"] }),
|
|
2645
|
-
Underline2,
|
|
2646
|
-
TabIndent
|
|
2647
|
-
],
|
|
2751
|
+
extensions,
|
|
2752
|
+
content: initialContent ?? void 0,
|
|
2648
2753
|
onUpdate({ editor: editor2 }) {
|
|
2649
2754
|
onChange?.(editor2.getJSON());
|
|
2650
2755
|
}
|
|
@@ -2668,13 +2773,15 @@ function InkEditor({
|
|
|
2668
2773
|
colors,
|
|
2669
2774
|
onColorsChange: setColors,
|
|
2670
2775
|
toolbarStart,
|
|
2671
|
-
toolbarEnd
|
|
2776
|
+
toolbarEnd,
|
|
2777
|
+
singlePage
|
|
2672
2778
|
}
|
|
2673
2779
|
);
|
|
2674
2780
|
}
|
|
2675
2781
|
export {
|
|
2676
2782
|
InkEditor,
|
|
2677
2783
|
MINIMAL_DEFAULTS,
|
|
2678
|
-
PARCHMENT_DEFAULTS
|
|
2784
|
+
PARCHMENT_DEFAULTS,
|
|
2785
|
+
SinglePageOverflow
|
|
2679
2786
|
};
|
|
2680
2787
|
//# sourceMappingURL=index.mjs.map
|