Skip to content

Commit 8020027

Browse files
authored
Refactor Form Creator Examples (#170)
1 parent 7852335 commit 8020027

File tree

6 files changed

+194
-0
lines changed

6 files changed

+194
-0
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import type { Instance } from "@nutrient-sdk/viewer";
2+
import { baseOptions } from "../../shared/base-options";
3+
4+
// Display grid overlay when focusing on annotations in Form Creator mode
5+
6+
window.NutrientViewer.load({
7+
...baseOptions,
8+
theme: window.NutrientViewer.Theme.DARK,
9+
toolbarItems: [
10+
...window.NutrientViewer.defaultToolbarItems,
11+
{ type: "form-creator" },
12+
],
13+
}).then(async (instance: Instance) => {
14+
const pageIndex = instance.viewState.currentPageIndex;
15+
const pageInfo = await instance.pageInfoForIndex(pageIndex);
16+
if (!pageInfo) return;
17+
18+
const { width, height } = pageInfo;
19+
20+
instance.addEventListener("annotations.focus", () => {
21+
attachGridOverlayToggle(instance, width, height, pageIndex);
22+
});
23+
24+
instance.addEventListener("page.press", () => {
25+
setTimeout(() => {
26+
try {
27+
instance.removeCustomOverlayItem("grid-overlay");
28+
} catch (_) {
29+
// Ignore if overlay doesn't exist
30+
}
31+
}, 50);
32+
});
33+
});
34+
35+
function attachGridOverlayToggle(
36+
instance: Instance,
37+
width: number,
38+
height: number,
39+
pageIndex: number,
40+
) {
41+
try {
42+
instance.removeCustomOverlayItem("grid-overlay");
43+
} catch (_) {
44+
// Ignore if overlay doesn't exist
45+
}
46+
47+
const grid = document.createElement("div");
48+
grid.style.width = width + "px";
49+
grid.style.height = height + "px";
50+
grid.style.pointerEvents = "none";
51+
grid.style.backgroundImage = `linear-gradient(to right, rgba(18,0,18,0.1) 1px, transparent 0.1px),
52+
linear-gradient(to bottom, rgba(18,0,18,0.1) 1px, transparent 0.1px)`;
53+
grid.style.backgroundSize = "25px 25px";
54+
grid.style.zIndex = "-1";
55+
56+
const overlayItem = new window.NutrientViewer.CustomOverlayItem({
57+
id: "grid-overlay",
58+
node: grid,
59+
pageIndex,
60+
position: new window.NutrientViewer.Geometry.Point({ x: 0, y: 0 }),
61+
});
62+
63+
instance.setCustomOverlayItem(overlayItem);
64+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
category: form-creator
3+
title: Grid Overlay for Form Creator
4+
description: Display a grid overlay when focusing on annotations in Form Creator mode to help with precise widget placement.
5+
keywords: [form-creator, grid, overlay, alignment, CustomOverlayItem]
6+
---
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.grid-overlay {
2+
position: absolute;
3+
top: 0;
4+
left: 0;
5+
width: 100%;
6+
height: 100%;
7+
pointer-events: none;
8+
z-index: 9999;
9+
background-image:
10+
linear-gradient(0deg, black 1px, transparent 1px),
11+
linear-gradient(90deg, black 1px, transparent 1px);
12+
background-size: 50px 50px;
13+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import type { Instance, ViewState } from "@nutrient-sdk/viewer";
2+
import { baseOptions } from "../../shared/base-options";
3+
4+
// Custom floating menu for Form Creator with quick access to all widget types
5+
6+
window.NutrientViewer.load({
7+
...baseOptions,
8+
theme: window.NutrientViewer.Theme.DARK,
9+
toolbarItems: [
10+
...window.NutrientViewer.defaultToolbarItems,
11+
{ type: "form-creator" },
12+
],
13+
}).then((instance: Instance) => {
14+
attachFormCreatorListener(instance);
15+
});
16+
17+
function attachFormCreatorListener(instance: Instance) {
18+
const doc = instance.contentDocument;
19+
const button = doc.querySelector(
20+
".NutrientViewer-Toolbar-Button-Form-Creator",
21+
);
22+
if (!button) return;
23+
24+
const OVERLAY_ID = "form-creator-floating";
25+
26+
function renderFloating() {
27+
const old = document.getElementById(OVERLAY_ID);
28+
if (old) old.remove();
29+
30+
if (!button || button.getAttribute("aria-pressed") !== "true") return;
31+
32+
const overlay = document.createElement("div");
33+
overlay.id = OVERLAY_ID;
34+
overlay.style.cssText =
35+
"position:fixed;display:flex;flex-wrap:wrap;gap:4px;" +
36+
"background:rgba(0,0,0,0.7);padding:8px;border-radius:4px;" +
37+
"font-family:sans-serif;color:white;z-index:10000;";
38+
39+
const modes = [
40+
{
41+
label: "Button",
42+
mode: window.NutrientViewer.InteractionMode.BUTTON_WIDGET,
43+
},
44+
{
45+
label: "Text",
46+
mode: window.NutrientViewer.InteractionMode.TEXT_WIDGET,
47+
},
48+
{
49+
label: "Checkbox",
50+
mode: window.NutrientViewer.InteractionMode.CHECKBOX_WIDGET,
51+
},
52+
{
53+
label: "Radio",
54+
mode: window.NutrientViewer.InteractionMode.RADIO_BUTTON_WIDGET,
55+
},
56+
{
57+
label: "Combo",
58+
mode: window.NutrientViewer.InteractionMode.COMBO_BOX_WIDGET,
59+
},
60+
{
61+
label: "List",
62+
mode: window.NutrientViewer.InteractionMode.LIST_BOX_WIDGET,
63+
},
64+
{
65+
label: "Signature",
66+
mode: window.NutrientViewer.InteractionMode.SIGNATURE_WIDGET,
67+
},
68+
{
69+
label: "Date",
70+
mode: window.NutrientViewer.InteractionMode.DATE_WIDGET,
71+
},
72+
];
73+
74+
modes.forEach((item) => {
75+
const btn = document.createElement("button");
76+
btn.textContent = item.label;
77+
btn.style.padding = "4px 8px";
78+
btn.addEventListener("click", () => {
79+
instance.setViewState((vs: ViewState) =>
80+
vs.set("interactionMode", item.mode),
81+
);
82+
});
83+
overlay.appendChild(btn);
84+
});
85+
86+
const toolbar = doc.querySelector(".NutrientViewer-Toolbar");
87+
if (!toolbar) return;
88+
const r = toolbar.getBoundingClientRect();
89+
overlay.style.top = r.bottom + window.scrollY + "px";
90+
overlay.style.left = r.left + window.scrollX + "px";
91+
92+
document.body.appendChild(overlay);
93+
}
94+
95+
button.addEventListener("click", () => {
96+
setTimeout(renderFloating, 0);
97+
});
98+
instance.addEventListener("viewState.currentPageIndex.change", () => {
99+
setTimeout(renderFloating, 0);
100+
});
101+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
category: form-creator
3+
title: Custom Form Creator Menu
4+
description: Create a floating menu with quick access buttons for all Form Creator widget types (Button, Text, Checkbox, Radio, Combo, List, Signature, Date).
5+
keywords: [form-creator, widget, toolbar, floating menu, InteractionMode]
6+
---
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/* Add your CSS here */
2+
.PSPDFKit-Form-Creator-Toolbar {
3+
display: none !important;
4+
}

0 commit comments

Comments
 (0)