formlift 0.1.0 → 0.2.0
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/CHANGELOG.md +19 -3
- package/README.md +206 -2
- package/dist/{chunk-5VHPTLLV.cjs → chunk-33XWO4KB.cjs} +156 -34
- package/dist/chunk-33XWO4KB.cjs.map +1 -0
- package/dist/chunk-7NZPYWL3.cjs.map +1 -1
- package/dist/{chunk-BQAVPA7Q.js → chunk-NUKLGHKS.js} +157 -35
- package/dist/chunk-NUKLGHKS.js.map +1 -0
- package/dist/filters-Yzd4tG8r.d.ts +201 -0
- package/dist/filters-q6gqilzw.d.cts +201 -0
- package/dist/index.cjs +24 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -56
- package/dist/index.d.ts +5 -56
- package/dist/index.js +27 -5
- package/dist/react/index.cjs +1052 -836
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +528 -45
- package/dist/react/index.d.ts +528 -45
- package/dist/react/index.js +1278 -1062
- package/dist/react/index.js.map +1 -1
- package/dist/server/index.cjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-5VHPTLLV.cjs.map +0 -1
- package/dist/chunk-BQAVPA7Q.js.map +0 -1
- package/dist/layout-ExhBeO6b.d.cts +0 -27
- package/dist/layout-ExhBeO6b.d.ts +0 -27
package/dist/react/index.cjs
CHANGED
|
@@ -23,8 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
var _chunk5VHPTLLVcjs = require('../chunk-5VHPTLLV.cjs');
|
|
26
|
+
var _chunk33XWO4KBcjs = require('../chunk-33XWO4KB.cjs');
|
|
28
27
|
|
|
29
28
|
|
|
30
29
|
|
|
@@ -56,15 +55,11 @@ var _chunk7NZPYWL3cjs = require('../chunk-7NZPYWL3.cjs');
|
|
|
56
55
|
|
|
57
56
|
|
|
58
57
|
var _lucidereact = require('lucide-react');
|
|
58
|
+
var _react = require('react');
|
|
59
59
|
|
|
60
|
+
// src/react/ui/slots.tsx
|
|
60
61
|
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
var _react = require('react');
|
|
67
|
-
|
|
68
63
|
// src/react/ui/Button.tsx
|
|
69
64
|
var _jsxruntime = require('react/jsx-runtime');
|
|
70
65
|
var variants = {
|
|
@@ -103,6 +98,143 @@ function Button({
|
|
|
103
98
|
);
|
|
104
99
|
}
|
|
105
100
|
|
|
101
|
+
// src/react/ui/Checkbox.tsx
|
|
102
|
+
|
|
103
|
+
function Checkbox({
|
|
104
|
+
label,
|
|
105
|
+
className = "",
|
|
106
|
+
...rest
|
|
107
|
+
}) {
|
|
108
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
109
|
+
"input",
|
|
110
|
+
{
|
|
111
|
+
type: "checkbox",
|
|
112
|
+
"aria-label": label,
|
|
113
|
+
className: `h-[18px] w-[18px] flex-none cursor-pointer accent-primary ${className}`,
|
|
114
|
+
...rest
|
|
115
|
+
}
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// src/react/ui/Chip.tsx
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
function Chip({
|
|
123
|
+
label,
|
|
124
|
+
count,
|
|
125
|
+
active,
|
|
126
|
+
onClick
|
|
127
|
+
}) {
|
|
128
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
129
|
+
"button",
|
|
130
|
+
{
|
|
131
|
+
type: "button",
|
|
132
|
+
"aria-pressed": !!active,
|
|
133
|
+
onClick,
|
|
134
|
+
className: `inline-flex cursor-pointer items-center gap-1.5 rounded-full border px-3 py-1 text-[12.5px] whitespace-nowrap transition-colors ${active ? "border-primary bg-primary-tint font-semibold text-primary" : "border-line-strong bg-white text-ink-2 hover:border-faint hover:bg-surface"}`,
|
|
135
|
+
children: [
|
|
136
|
+
label,
|
|
137
|
+
count != null && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
138
|
+
"span",
|
|
139
|
+
{
|
|
140
|
+
className: `rounded-full px-1.5 text-[11px] font-semibold ${active ? "bg-primary text-white" : "bg-hover text-muted"}`,
|
|
141
|
+
children: count
|
|
142
|
+
}
|
|
143
|
+
)
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
function ChipGroup({
|
|
149
|
+
title,
|
|
150
|
+
options,
|
|
151
|
+
value,
|
|
152
|
+
onChange
|
|
153
|
+
}) {
|
|
154
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { role: "group", "aria-label": title, className: "flex flex-wrap items-center gap-1.5", children: [
|
|
155
|
+
title && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "mr-1 min-w-28 text-[11.5px] max-sm:basis-full font-semibold tracking-wide text-muted uppercase", children: title }),
|
|
156
|
+
options.map((o) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
157
|
+
Chip,
|
|
158
|
+
{
|
|
159
|
+
label: o.label,
|
|
160
|
+
count: o.count,
|
|
161
|
+
active: value === o.value,
|
|
162
|
+
onClick: () => onChange(value === o.value ? null : o.value)
|
|
163
|
+
},
|
|
164
|
+
o.value
|
|
165
|
+
))
|
|
166
|
+
] });
|
|
167
|
+
}
|
|
168
|
+
function RemovableChip({ label, onRemove }) {
|
|
169
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "inline-flex items-center gap-1 rounded-full bg-primary-tint py-0.5 pr-1 pl-2.5 text-[12px] font-medium text-primary", children: [
|
|
170
|
+
label,
|
|
171
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
172
|
+
"button",
|
|
173
|
+
{
|
|
174
|
+
type: "button",
|
|
175
|
+
"aria-label": `Remove ${label}`,
|
|
176
|
+
onClick: onRemove,
|
|
177
|
+
className: "inline-flex h-4.5 w-4.5 cursor-pointer items-center justify-center rounded-full hover:bg-primary hover:text-white",
|
|
178
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.X, { size: 12 })
|
|
179
|
+
}
|
|
180
|
+
)
|
|
181
|
+
] });
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// src/react/ui/FormField.tsx
|
|
185
|
+
|
|
186
|
+
var inputClass = "w-full rounded-md border border-line-strong bg-white px-3 py-2 text-[13.5px] outline-none focus:border-primary";
|
|
187
|
+
function FormField({
|
|
188
|
+
label,
|
|
189
|
+
required,
|
|
190
|
+
error,
|
|
191
|
+
children
|
|
192
|
+
}) {
|
|
193
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "label", { className: "block text-[13.5px]", children: [
|
|
194
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "mb-1 block font-semibold", children: [
|
|
195
|
+
label,
|
|
196
|
+
" ",
|
|
197
|
+
required && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-danger", children: "*" })
|
|
198
|
+
] }),
|
|
199
|
+
children,
|
|
200
|
+
error && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "small", { className: "text-danger", children: error })
|
|
201
|
+
] });
|
|
202
|
+
}
|
|
203
|
+
var TextInput = ({ className = "", ...rest }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { className: `${inputClass} ${className}`, ...rest });
|
|
204
|
+
var Select = ({ className = "", ...rest }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
205
|
+
"select",
|
|
206
|
+
{
|
|
207
|
+
className: `rounded-md border border-line-strong bg-white px-2.5 py-1.5 text-[13px] outline-none ${className}`,
|
|
208
|
+
...rest
|
|
209
|
+
}
|
|
210
|
+
);
|
|
211
|
+
var TextArea = ({ className = "", ...rest }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "textarea", { className: `${inputClass} resize-none ${className}`, ...rest });
|
|
212
|
+
|
|
213
|
+
// src/react/ui/IconButton.tsx
|
|
214
|
+
|
|
215
|
+
function IconButton({
|
|
216
|
+
title,
|
|
217
|
+
icon: Icon,
|
|
218
|
+
danger,
|
|
219
|
+
iconSize = 18,
|
|
220
|
+
light,
|
|
221
|
+
className = "",
|
|
222
|
+
...rest
|
|
223
|
+
}) {
|
|
224
|
+
const tone = light ? "text-white opacity-90 hover:bg-white/15 hover:opacity-100" : `text-muted hover:bg-line-soft ${danger ? "hover:text-danger" : "hover:text-primary"}`;
|
|
225
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
226
|
+
"button",
|
|
227
|
+
{
|
|
228
|
+
type: "button",
|
|
229
|
+
title,
|
|
230
|
+
"aria-label": title,
|
|
231
|
+
className: `inline-flex cursor-pointer items-center justify-center rounded p-1.5 transition disabled:cursor-not-allowed disabled:opacity-40 ${tone} ${className}`,
|
|
232
|
+
...rest,
|
|
233
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Icon, { size: iconSize })
|
|
234
|
+
}
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
106
238
|
// src/react/ui/Modal.tsx
|
|
107
239
|
|
|
108
240
|
function Modal({ children, onClose, width }) {
|
|
@@ -154,31 +286,6 @@ function ConfirmModal({
|
|
|
154
286
|
] });
|
|
155
287
|
}
|
|
156
288
|
|
|
157
|
-
// src/react/ui/IconButton.tsx
|
|
158
|
-
|
|
159
|
-
function IconButton({
|
|
160
|
-
title,
|
|
161
|
-
icon: Icon,
|
|
162
|
-
danger,
|
|
163
|
-
iconSize = 18,
|
|
164
|
-
light,
|
|
165
|
-
className = "",
|
|
166
|
-
...rest
|
|
167
|
-
}) {
|
|
168
|
-
const tone = light ? "text-white opacity-90 hover:bg-white/15 hover:opacity-100" : `text-muted hover:bg-line-soft ${danger ? "hover:text-danger" : "hover:text-primary"}`;
|
|
169
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
170
|
-
"button",
|
|
171
|
-
{
|
|
172
|
-
type: "button",
|
|
173
|
-
title,
|
|
174
|
-
"aria-label": title,
|
|
175
|
-
className: `inline-flex cursor-pointer items-center justify-center rounded p-1.5 transition disabled:cursor-not-allowed disabled:opacity-40 ${tone} ${className}`,
|
|
176
|
-
...rest,
|
|
177
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Icon, { size: iconSize })
|
|
178
|
-
}
|
|
179
|
-
);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
289
|
// src/react/ui/Panel.tsx
|
|
183
290
|
|
|
184
291
|
var PanelHeading = ({ children, actions }) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-between bg-heading px-3.5 py-[11px] text-[13px] font-bold tracking-[0.02em] text-white", children: [
|
|
@@ -187,6 +294,65 @@ var PanelHeading = ({ children, actions }) => /* @__PURE__ */ _jsxruntime.jsxs.c
|
|
|
187
294
|
] });
|
|
188
295
|
var EmptyText = ({ children, className = "" }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: `m-0 px-3.5 py-3 text-[13px] text-muted ${className}`, children });
|
|
189
296
|
|
|
297
|
+
// src/react/ui/Popover.tsx
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
// src/react/ui/useOutsideClose.ts
|
|
301
|
+
|
|
302
|
+
function useOutsideClose(ref, open, onClose) {
|
|
303
|
+
_react.useEffect.call(void 0, () => {
|
|
304
|
+
if (!open) return;
|
|
305
|
+
const onClick = (e) => ref.current && e.composedPath().includes(ref.current) || onClose();
|
|
306
|
+
const onKey = (e) => e.key === "Escape" && onClose();
|
|
307
|
+
document.addEventListener("mousedown", onClick);
|
|
308
|
+
document.addEventListener("keydown", onKey);
|
|
309
|
+
return () => {
|
|
310
|
+
document.removeEventListener("mousedown", onClick);
|
|
311
|
+
document.removeEventListener("keydown", onKey);
|
|
312
|
+
};
|
|
313
|
+
}, [ref, open, onClose]);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// src/react/ui/Popover.tsx
|
|
317
|
+
|
|
318
|
+
function Popover({
|
|
319
|
+
label,
|
|
320
|
+
icon: Icon,
|
|
321
|
+
badge,
|
|
322
|
+
align = "left",
|
|
323
|
+
children
|
|
324
|
+
}) {
|
|
325
|
+
const [open, setOpen] = _react.useState.call(void 0, false);
|
|
326
|
+
const box2 = _react.useRef.call(void 0, null);
|
|
327
|
+
useOutsideClose(box2, open, () => setOpen(false));
|
|
328
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { ref: box2, className: "relative", children: [
|
|
329
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
330
|
+
"button",
|
|
331
|
+
{
|
|
332
|
+
type: "button",
|
|
333
|
+
"aria-expanded": open,
|
|
334
|
+
"aria-haspopup": "dialog",
|
|
335
|
+
onClick: () => setOpen((o) => !o),
|
|
336
|
+
className: `inline-flex cursor-pointer items-center gap-1.5 rounded-md border px-3 py-1.5 text-[13px] font-medium ${open || badge ? "border-primary bg-primary-soft text-primary" : "border-line-strong bg-white text-ink-2 hover:border-faint"}`,
|
|
337
|
+
children: [
|
|
338
|
+
Icon && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Icon, { size: 15 }),
|
|
339
|
+
label,
|
|
340
|
+
!!badge && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-full bg-primary px-1 text-[11px] font-bold text-white", children: badge })
|
|
341
|
+
]
|
|
342
|
+
}
|
|
343
|
+
),
|
|
344
|
+
open && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
345
|
+
"div",
|
|
346
|
+
{
|
|
347
|
+
role: "dialog",
|
|
348
|
+
"aria-label": label,
|
|
349
|
+
className: `absolute z-30 mt-1.5 w-[min(560px,calc(100vw-24px))] max-sm:fixed max-sm:inset-x-3 max-sm:max-h-[70dvh] max-sm:w-auto max-sm:overflow-y-auto rounded-lg border border-line bg-white p-4 shadow-xl ${align === "right" ? "right-0" : "left-0"}`,
|
|
350
|
+
children
|
|
351
|
+
}
|
|
352
|
+
)
|
|
353
|
+
] });
|
|
354
|
+
}
|
|
355
|
+
|
|
190
356
|
// src/react/ui/SegmentedTabs.tsx
|
|
191
357
|
|
|
192
358
|
function SegmentedTabs({
|
|
@@ -209,52 +375,156 @@ function SegmentedTabs({
|
|
|
209
375
|
)) });
|
|
210
376
|
}
|
|
211
377
|
|
|
212
|
-
// src/react/ui/
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
378
|
+
// src/react/ui/SignaturePad.tsx
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
function SignaturePad({
|
|
382
|
+
onSave,
|
|
383
|
+
onCancel,
|
|
384
|
+
maxWidth = 600
|
|
385
|
+
}) {
|
|
386
|
+
const canvas = _react.useRef.call(void 0, null);
|
|
387
|
+
const last = _react.useRef.call(void 0, null);
|
|
388
|
+
const [empty, setEmpty] = _react.useState.call(void 0, true);
|
|
389
|
+
const point = (e) => {
|
|
390
|
+
const r = e.currentTarget.getBoundingClientRect();
|
|
391
|
+
return {
|
|
392
|
+
x: (e.clientX - r.left) / r.width * e.currentTarget.width,
|
|
393
|
+
y: (e.clientY - r.top) / r.height * e.currentTarget.height
|
|
394
|
+
};
|
|
395
|
+
};
|
|
396
|
+
const draw = (e) => {
|
|
397
|
+
const ctx = _optionalChain([canvas, 'access', _2 => _2.current, 'optionalAccess', _3 => _3.getContext, 'call', _4 => _4("2d")]);
|
|
398
|
+
if (!ctx || !last.current) return;
|
|
399
|
+
const p = point(e);
|
|
400
|
+
ctx.lineWidth = 3;
|
|
401
|
+
ctx.lineCap = "round";
|
|
402
|
+
ctx.strokeStyle = "#111827";
|
|
403
|
+
ctx.beginPath();
|
|
404
|
+
ctx.moveTo(last.current.x, last.current.y);
|
|
405
|
+
ctx.lineTo(p.x, p.y);
|
|
406
|
+
ctx.stroke();
|
|
407
|
+
last.current = p;
|
|
408
|
+
setEmpty(false);
|
|
409
|
+
};
|
|
410
|
+
const clear = () => {
|
|
411
|
+
const c = canvas.current;
|
|
412
|
+
_optionalChain([c, 'optionalAccess', _5 => _5.getContext, 'call', _6 => _6("2d"), 'optionalAccess', _7 => _7.clearRect, 'call', _8 => _8(0, 0, c.width, c.height)]);
|
|
413
|
+
setEmpty(true);
|
|
414
|
+
};
|
|
415
|
+
const save = () => {
|
|
416
|
+
const c = canvas.current;
|
|
417
|
+
if (!c) return;
|
|
418
|
+
const scale = Math.min(1, maxWidth / c.width);
|
|
419
|
+
const out = document.createElement("canvas");
|
|
420
|
+
out.width = Math.round(c.width * scale);
|
|
421
|
+
out.height = Math.round(c.height * scale);
|
|
422
|
+
_optionalChain([out, 'access', _9 => _9.getContext, 'call', _10 => _10("2d"), 'optionalAccess', _11 => _11.drawImage, 'call', _12 => _12(c, 0, 0, out.width, out.height)]);
|
|
423
|
+
onSave(out.toDataURL("image/png"));
|
|
424
|
+
};
|
|
425
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-3", children: [
|
|
426
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
427
|
+
"canvas",
|
|
428
|
+
{
|
|
429
|
+
ref: canvas,
|
|
430
|
+
width: 800,
|
|
431
|
+
height: 260,
|
|
432
|
+
"aria-label": "Signature drawing area",
|
|
433
|
+
className: "h-[200px] w-full touch-none rounded-md border border-dashed border-line-strong bg-surface",
|
|
434
|
+
onPointerDown: (e) => {
|
|
435
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
436
|
+
last.current = point(e);
|
|
437
|
+
},
|
|
438
|
+
onPointerMove: draw,
|
|
439
|
+
onPointerUp: () => last.current = null
|
|
440
|
+
}
|
|
441
|
+
),
|
|
442
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-end gap-2", children: [
|
|
443
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { variant: "secondary", onClick: clear, children: "Clear" }),
|
|
444
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { variant: "secondary", onClick: onCancel, children: "Cancel" }),
|
|
445
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { disabled: empty, onClick: save, children: "Use signature" })
|
|
446
|
+
] })
|
|
447
|
+
] });
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// src/react/ui/Tag.tsx
|
|
229
451
|
|
|
230
|
-
|
|
452
|
+
var tones = {
|
|
453
|
+
success: "bg-success/15 text-success",
|
|
454
|
+
info: "bg-heading/20 text-primary",
|
|
455
|
+
muted: "bg-hover text-muted"
|
|
456
|
+
};
|
|
457
|
+
var Tag = ({ tone = "info", children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
458
|
+
"span",
|
|
459
|
+
{
|
|
460
|
+
className: `inline-block rounded-full px-2.5 py-0.5 text-[11px] font-semibold whitespace-nowrap ${tones[tone]}`,
|
|
461
|
+
children
|
|
462
|
+
}
|
|
463
|
+
);
|
|
231
464
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
465
|
+
// src/react/ui/slots.tsx
|
|
466
|
+
|
|
467
|
+
var base = {
|
|
468
|
+
Button,
|
|
469
|
+
IconButton,
|
|
470
|
+
Checkbox,
|
|
471
|
+
FormField,
|
|
472
|
+
TextInput,
|
|
473
|
+
Select,
|
|
474
|
+
TextArea,
|
|
475
|
+
Modal,
|
|
476
|
+
ModalHeader,
|
|
477
|
+
ModalBody,
|
|
478
|
+
ModalFooter,
|
|
479
|
+
ConfirmModal,
|
|
480
|
+
PanelHeading,
|
|
481
|
+
EmptyText,
|
|
482
|
+
SegmentedTabs,
|
|
483
|
+
Chip,
|
|
484
|
+
ChipGroup,
|
|
485
|
+
RemovableChip,
|
|
486
|
+
Popover,
|
|
487
|
+
Tag,
|
|
488
|
+
SignaturePad
|
|
489
|
+
};
|
|
490
|
+
var defaultComponents = base;
|
|
491
|
+
var UIContext = _react.createContext.call(void 0, {});
|
|
492
|
+
function FormliftProvider({
|
|
493
|
+
components,
|
|
237
494
|
children
|
|
238
495
|
}) {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
label,
|
|
242
|
-
" ",
|
|
243
|
-
required && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-danger", children: "*" })
|
|
244
|
-
] }),
|
|
245
|
-
children,
|
|
246
|
-
error && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "small", { className: "text-danger", children: error })
|
|
247
|
-
] });
|
|
496
|
+
const outer = _react.useContext.call(void 0, UIContext);
|
|
497
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, UIContext.Provider, { value: components ? { ...outer, ...components } : outer, children });
|
|
248
498
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
var
|
|
499
|
+
function slot(name) {
|
|
500
|
+
const Slot = (props) => {
|
|
501
|
+
const C = _nullishCoalesce(_react.useContext.call(void 0, UIContext)[name], () => ( base[name]));
|
|
502
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, C, { ...props });
|
|
503
|
+
};
|
|
504
|
+
Slot.displayName = `formlift.${name}`;
|
|
505
|
+
return Slot;
|
|
506
|
+
}
|
|
507
|
+
var Button2 = slot("Button");
|
|
508
|
+
var IconButton2 = slot("IconButton");
|
|
509
|
+
var Checkbox2 = slot("Checkbox");
|
|
510
|
+
var FormField2 = slot("FormField");
|
|
511
|
+
var TextInput2 = slot("TextInput");
|
|
512
|
+
var Select2 = slot("Select");
|
|
513
|
+
var TextArea2 = slot("TextArea");
|
|
514
|
+
var Modal2 = slot("Modal");
|
|
515
|
+
var ModalHeader2 = slot("ModalHeader");
|
|
516
|
+
var ModalBody2 = slot("ModalBody");
|
|
517
|
+
var ModalFooter2 = slot("ModalFooter");
|
|
518
|
+
var ConfirmModal2 = slot("ConfirmModal");
|
|
519
|
+
var PanelHeading2 = slot("PanelHeading");
|
|
520
|
+
var EmptyText2 = slot("EmptyText");
|
|
521
|
+
var SegmentedTabs2 = slot("SegmentedTabs");
|
|
522
|
+
var Chip2 = slot("Chip");
|
|
523
|
+
var ChipGroup2 = slot("ChipGroup");
|
|
524
|
+
var RemovableChip2 = slot("RemovableChip");
|
|
525
|
+
var Popover2 = slot("Popover");
|
|
526
|
+
var Tag2 = slot("Tag");
|
|
527
|
+
var SignaturePad2 = slot("SignaturePad");
|
|
258
528
|
|
|
259
529
|
// src/react/components/ElementProperties.tsx
|
|
260
530
|
|
|
@@ -270,7 +540,7 @@ function ColorField({
|
|
|
270
540
|
onChange,
|
|
271
541
|
allowNone
|
|
272
542
|
}) {
|
|
273
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
543
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "flex items-center gap-2", children: [
|
|
274
544
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
275
545
|
"input",
|
|
276
546
|
{
|
|
@@ -283,7 +553,7 @@ function ColorField({
|
|
|
283
553
|
),
|
|
284
554
|
allowNone && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "label", { className: "inline-flex items-center gap-1.5 text-[12.5px]", children: [
|
|
285
555
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
286
|
-
|
|
556
|
+
Checkbox2,
|
|
287
557
|
{
|
|
288
558
|
label: `No ${label.toLowerCase()}`,
|
|
289
559
|
checked: !value,
|
|
@@ -307,7 +577,7 @@ function ElementProperties({
|
|
|
307
577
|
if (e.type === "line")
|
|
308
578
|
set({ position: { ...p, width: Math.min(p.width, 1 - p.x), height: Math.min(p.height, 1 - p.y) } });
|
|
309
579
|
else {
|
|
310
|
-
const { page: _page, ...fitted } =
|
|
580
|
+
const { page: _page, ...fitted } = _chunk33XWO4KBcjs.fitInPage.call(void 0, { page: e.page, ...p });
|
|
311
581
|
void _page;
|
|
312
582
|
set({ position: fitted });
|
|
313
583
|
}
|
|
@@ -320,7 +590,7 @@ function ElementProperties({
|
|
|
320
590
|
"\u201D"
|
|
321
591
|
] }),
|
|
322
592
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
323
|
-
|
|
593
|
+
TextArea2,
|
|
324
594
|
{
|
|
325
595
|
rows: 4,
|
|
326
596
|
"aria-label": "Text",
|
|
@@ -331,8 +601,8 @@ function ElementProperties({
|
|
|
331
601
|
}
|
|
332
602
|
),
|
|
333
603
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "grid grid-cols-2 gap-2", children: [
|
|
334
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
335
|
-
|
|
604
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label: "Font", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
605
|
+
Select2,
|
|
336
606
|
{
|
|
337
607
|
className: "w-full",
|
|
338
608
|
value: _nullishCoalesce(e.font, () => ( "sans")),
|
|
@@ -340,8 +610,8 @@ function ElementProperties({
|
|
|
340
610
|
children: _chunk7NZPYWL3cjs.FONTS.map((f) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "option", { value: f, children: { sans: "Sans (Helvetica)", serif: "Serif (Times)", mono: "Mono (Courier)" }[f] }, f))
|
|
341
611
|
}
|
|
342
612
|
) }),
|
|
343
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
344
|
-
|
|
613
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label: "Size (pt)", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
614
|
+
TextInput2,
|
|
345
615
|
{
|
|
346
616
|
type: "number",
|
|
347
617
|
min: 3,
|
|
@@ -357,11 +627,11 @@ function ElementProperties({
|
|
|
357
627
|
] }),
|
|
358
628
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-wrap items-center gap-4", children: [
|
|
359
629
|
["bold", "italic"].map((k) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "label", { className: "inline-flex items-center gap-1.5", children: [
|
|
360
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
630
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, Checkbox2, { label: k, checked: !!e[k], onChange: (ev) => set({ [k]: ev.target.checked || void 0 }) }),
|
|
361
631
|
k === "bold" ? "Bold" : "Italic"
|
|
362
632
|
] }, k)),
|
|
363
633
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
364
|
-
|
|
634
|
+
Select2,
|
|
365
635
|
{
|
|
366
636
|
"aria-label": "Alignment",
|
|
367
637
|
value: _nullishCoalesce(e.align, () => ( "left")),
|
|
@@ -388,8 +658,8 @@ function ElementProperties({
|
|
|
388
658
|
onChange: (v) => set({ stroke: v })
|
|
389
659
|
}
|
|
390
660
|
),
|
|
391
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
392
|
-
|
|
661
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label: "Line width (pt)", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
662
|
+
TextInput2,
|
|
393
663
|
{
|
|
394
664
|
type: "number",
|
|
395
665
|
min: 0,
|
|
@@ -406,8 +676,8 @@ function ElementProperties({
|
|
|
406
676
|
e.fill === "#ffffff" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "m-0 text-[12px] text-muted", children: "A white background hides the original under it." })
|
|
407
677
|
] }),
|
|
408
678
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, Section, { title: "Position (% of page)", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "grid grid-cols-2 gap-2", children: [
|
|
409
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
410
|
-
|
|
679
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label: "Page", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
680
|
+
TextInput2,
|
|
411
681
|
{
|
|
412
682
|
type: "number",
|
|
413
683
|
min: 1,
|
|
@@ -420,8 +690,8 @@ function ElementProperties({
|
|
|
420
690
|
}
|
|
421
691
|
) }),
|
|
422
692
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", {}),
|
|
423
|
-
["x", "y", "width", "height"].map((k) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
424
|
-
|
|
693
|
+
["x", "y", "width", "height"].map((k) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label: { x: "Left", y: "Top", width: "Width", height: "Height" }[k], children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
694
|
+
TextInput2,
|
|
425
695
|
{
|
|
426
696
|
type: "number",
|
|
427
697
|
step: 0.1,
|
|
@@ -437,80 +707,6 @@ function ElementProperties({
|
|
|
437
707
|
|
|
438
708
|
|
|
439
709
|
|
|
440
|
-
// src/react/ui/SignaturePad.tsx
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
function SignaturePad({
|
|
444
|
-
onSave,
|
|
445
|
-
onCancel,
|
|
446
|
-
maxWidth = 600
|
|
447
|
-
}) {
|
|
448
|
-
const canvas = _react.useRef.call(void 0, null);
|
|
449
|
-
const last = _react.useRef.call(void 0, null);
|
|
450
|
-
const [empty, setEmpty] = _react.useState.call(void 0, true);
|
|
451
|
-
const point = (e) => {
|
|
452
|
-
const r = e.currentTarget.getBoundingClientRect();
|
|
453
|
-
return {
|
|
454
|
-
x: (e.clientX - r.left) / r.width * e.currentTarget.width,
|
|
455
|
-
y: (e.clientY - r.top) / r.height * e.currentTarget.height
|
|
456
|
-
};
|
|
457
|
-
};
|
|
458
|
-
const draw = (e) => {
|
|
459
|
-
const ctx = _optionalChain([canvas, 'access', _2 => _2.current, 'optionalAccess', _3 => _3.getContext, 'call', _4 => _4("2d")]);
|
|
460
|
-
if (!ctx || !last.current) return;
|
|
461
|
-
const p = point(e);
|
|
462
|
-
ctx.lineWidth = 3;
|
|
463
|
-
ctx.lineCap = "round";
|
|
464
|
-
ctx.strokeStyle = "#111827";
|
|
465
|
-
ctx.beginPath();
|
|
466
|
-
ctx.moveTo(last.current.x, last.current.y);
|
|
467
|
-
ctx.lineTo(p.x, p.y);
|
|
468
|
-
ctx.stroke();
|
|
469
|
-
last.current = p;
|
|
470
|
-
setEmpty(false);
|
|
471
|
-
};
|
|
472
|
-
const clear = () => {
|
|
473
|
-
const c = canvas.current;
|
|
474
|
-
_optionalChain([c, 'optionalAccess', _5 => _5.getContext, 'call', _6 => _6("2d"), 'optionalAccess', _7 => _7.clearRect, 'call', _8 => _8(0, 0, c.width, c.height)]);
|
|
475
|
-
setEmpty(true);
|
|
476
|
-
};
|
|
477
|
-
const save = () => {
|
|
478
|
-
const c = canvas.current;
|
|
479
|
-
if (!c) return;
|
|
480
|
-
const scale = Math.min(1, maxWidth / c.width);
|
|
481
|
-
const out = document.createElement("canvas");
|
|
482
|
-
out.width = Math.round(c.width * scale);
|
|
483
|
-
out.height = Math.round(c.height * scale);
|
|
484
|
-
_optionalChain([out, 'access', _9 => _9.getContext, 'call', _10 => _10("2d"), 'optionalAccess', _11 => _11.drawImage, 'call', _12 => _12(c, 0, 0, out.width, out.height)]);
|
|
485
|
-
onSave(out.toDataURL("image/png"));
|
|
486
|
-
};
|
|
487
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-3", children: [
|
|
488
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
489
|
-
"canvas",
|
|
490
|
-
{
|
|
491
|
-
ref: canvas,
|
|
492
|
-
width: 800,
|
|
493
|
-
height: 260,
|
|
494
|
-
"aria-label": "Signature drawing area",
|
|
495
|
-
className: "h-[200px] w-full touch-none rounded-md border border-dashed border-line-strong bg-surface",
|
|
496
|
-
onPointerDown: (e) => {
|
|
497
|
-
e.currentTarget.setPointerCapture(e.pointerId);
|
|
498
|
-
last.current = point(e);
|
|
499
|
-
},
|
|
500
|
-
onPointerMove: draw,
|
|
501
|
-
onPointerUp: () => last.current = null
|
|
502
|
-
}
|
|
503
|
-
),
|
|
504
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-end gap-2", children: [
|
|
505
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { variant: "secondary", onClick: clear, children: "Clear" }),
|
|
506
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { variant: "secondary", onClick: onCancel, children: "Cancel" }),
|
|
507
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { disabled: empty, onClick: save, children: "Use signature" })
|
|
508
|
-
] })
|
|
509
|
-
] });
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
// src/react/components/FieldControl.tsx
|
|
513
|
-
|
|
514
710
|
var box = "h-full w-full rounded-sm border bg-primary-soft/70 px-1 text-[clamp(8px,62cqh,15px)] text-navy outline-none focus:border-primary focus:bg-white disabled:cursor-not-allowed";
|
|
515
711
|
function pngFile(dataUrl, name) {
|
|
516
712
|
const bin = atob(dataUrl.slice(dataUrl.indexOf(",") + 1));
|
|
@@ -616,14 +812,14 @@ function FieldControl({
|
|
|
616
812
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `min-w-0 ${field.type === "textarea" ? "line-clamp-[8] whitespace-pre-wrap" : "truncate"}`, children: text || /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-faint", children: field.placeholder || "" }) })
|
|
617
813
|
}
|
|
618
814
|
),
|
|
619
|
-
editing && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
620
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
621
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
815
|
+
editing && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Modal2, { onClose: () => setEditing(false), width: "w-[480px]", children: [
|
|
816
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, ModalHeader2, { title: name, onClose: () => setEditing(false) }),
|
|
817
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, ModalBody2, { children: [
|
|
622
818
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, SheetInput, { field, text, onChange, onDone: () => setEditing(false) }),
|
|
623
819
|
field.helpText && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mt-2 mb-0 text-[13px] text-muted", children: field.helpText }),
|
|
624
820
|
error && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mt-2 mb-0 text-[13px] text-danger", children: error })
|
|
625
821
|
] }),
|
|
626
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
822
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, ModalFooter2, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button2, { onClick: () => setEditing(false), children: "Done" }) })
|
|
627
823
|
] })
|
|
628
824
|
] });
|
|
629
825
|
}
|
|
@@ -707,10 +903,10 @@ function FieldControl({
|
|
|
707
903
|
] })
|
|
708
904
|
}
|
|
709
905
|
),
|
|
710
|
-
signing && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
711
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
712
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
713
|
-
|
|
906
|
+
signing && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Modal2, { onClose: () => setSigning(false), width: "w-[640px]", children: [
|
|
907
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, ModalHeader2, { title: `Sign: ${field.label || field.key}`, onClose: () => setSigning(false) }),
|
|
908
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, ModalBody2, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
909
|
+
SignaturePad2,
|
|
714
910
|
{
|
|
715
911
|
onCancel: () => setSigning(false),
|
|
716
912
|
onSave: (url) => {
|
|
@@ -780,6 +976,10 @@ function FieldControl({
|
|
|
780
976
|
}
|
|
781
977
|
}
|
|
782
978
|
}
|
|
979
|
+
function AnswerControl({ components, ...props }) {
|
|
980
|
+
const C = _nullishCoalesce(_nullishCoalesce(_optionalChain([components, 'optionalAccess', _20 => _20.fields, 'optionalAccess', _21 => _21[props.field.type]]), () => ( _optionalChain([components, 'optionalAccess', _22 => _22.FieldControl]))), () => ( FieldControl));
|
|
981
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, C, { ...props });
|
|
982
|
+
}
|
|
783
983
|
|
|
784
984
|
// src/react/components/FieldProperties.tsx
|
|
785
985
|
|
|
@@ -825,12 +1025,12 @@ function ConditionBuilder({
|
|
|
825
1025
|
}) {
|
|
826
1026
|
const setRule = (i, r) => onChange({ ...value, rules: value.rules.map((x, j) => j === i ? r : x) });
|
|
827
1027
|
const remove = (i) => onChange({ ...value, rules: value.rules.filter((_, j) => j !== i) });
|
|
828
|
-
const newRule = () => ({ fieldKey: _nullishCoalesce(_optionalChain([fields, 'access',
|
|
1028
|
+
const newRule = () => ({ fieldKey: _nullishCoalesce(_optionalChain([fields, 'access', _23 => _23[0], 'optionalAccess', _24 => _24.key]), () => ( "")), op: "equals", value: "" });
|
|
829
1029
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: `space-y-2 ${depth ? "rounded-md border border-line bg-surface p-2" : ""}`, children: [
|
|
830
1030
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2 text-[12px]", children: [
|
|
831
1031
|
"Match",
|
|
832
1032
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
833
|
-
|
|
1033
|
+
Select2,
|
|
834
1034
|
{
|
|
835
1035
|
"aria-label": "Match all or any",
|
|
836
1036
|
value: value.logic,
|
|
@@ -845,10 +1045,10 @@ function ConditionBuilder({
|
|
|
845
1045
|
value.rules.map(
|
|
846
1046
|
(r, i) => isGroup(r) ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-start gap-1", children: [
|
|
847
1047
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ConditionBuilder, { value: r, onChange: (c) => setRule(i, c), fields, depth: depth + 1 }) }),
|
|
848
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1048
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, IconButton2, { icon: _lucidereact.X, title: "Remove group", danger: true, iconSize: 14, onClick: () => remove(i) })
|
|
849
1049
|
] }, i) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
850
1050
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
851
|
-
|
|
1051
|
+
Select2,
|
|
852
1052
|
{
|
|
853
1053
|
"aria-label": "Field",
|
|
854
1054
|
value: r.fieldKey,
|
|
@@ -860,7 +1060,7 @@ function ConditionBuilder({
|
|
|
860
1060
|
}
|
|
861
1061
|
),
|
|
862
1062
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
863
|
-
|
|
1063
|
+
Select2,
|
|
864
1064
|
{
|
|
865
1065
|
"aria-label": "Operator",
|
|
866
1066
|
value: r.op,
|
|
@@ -869,7 +1069,7 @@ function ConditionBuilder({
|
|
|
869
1069
|
}
|
|
870
1070
|
),
|
|
871
1071
|
r.op !== "isEmpty" && r.op !== "isNotEmpty" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
872
|
-
|
|
1072
|
+
TextInput2,
|
|
873
1073
|
{
|
|
874
1074
|
"aria-label": "Value",
|
|
875
1075
|
className: "!w-24 !py-1",
|
|
@@ -878,7 +1078,7 @@ function ConditionBuilder({
|
|
|
878
1078
|
}
|
|
879
1079
|
),
|
|
880
1080
|
r.op === "between" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
881
|
-
|
|
1081
|
+
TextInput2,
|
|
882
1082
|
{
|
|
883
1083
|
"aria-label": "Upper value",
|
|
884
1084
|
className: "!w-24 !py-1",
|
|
@@ -886,12 +1086,12 @@ function ConditionBuilder({
|
|
|
886
1086
|
onChange: (e) => setRule(i, { ...r, value2: e.target.value })
|
|
887
1087
|
}
|
|
888
1088
|
),
|
|
889
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1089
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, IconButton2, { icon: _lucidereact.X, title: "Remove rule", danger: true, iconSize: 14, onClick: () => remove(i) })
|
|
890
1090
|
] }, i)
|
|
891
1091
|
),
|
|
892
1092
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-2", children: [
|
|
893
1093
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
894
|
-
|
|
1094
|
+
Button2,
|
|
895
1095
|
{
|
|
896
1096
|
size: "sm",
|
|
897
1097
|
variant: "secondary",
|
|
@@ -902,7 +1102,7 @@ function ConditionBuilder({
|
|
|
902
1102
|
}
|
|
903
1103
|
),
|
|
904
1104
|
depth < 2 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
905
|
-
|
|
1105
|
+
Button2,
|
|
906
1106
|
{
|
|
907
1107
|
size: "sm",
|
|
908
1108
|
variant: "secondary",
|
|
@@ -942,7 +1142,7 @@ function FieldProperties({
|
|
|
942
1142
|
const textual = !["checkbox", "file", "signature", "dropdown", "radio"].includes(field.type);
|
|
943
1143
|
const setPos = (k, v) => {
|
|
944
1144
|
const n = num2(v);
|
|
945
|
-
if (n != null) set({ position:
|
|
1145
|
+
if (n != null) set({ position: _chunk33XWO4KBcjs.fitInPage.call(void 0, { ...field.position, [k]: n / 100 }) });
|
|
946
1146
|
};
|
|
947
1147
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-[13px]", children: [
|
|
948
1148
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Section2, { title: "Field", children: [
|
|
@@ -955,38 +1155,38 @@ function FieldProperties({
|
|
|
955
1155
|
"ID ",
|
|
956
1156
|
field.id
|
|
957
1157
|
] }),
|
|
958
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
959
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
960
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
961
|
-
textual && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
962
|
-
|
|
1158
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label: "Label", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TextInput2, { value: field.label, onChange: (e) => set({ label: e.target.value }) }) }),
|
|
1159
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label: "Key (automatic, from the label)", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TextInput2, { value: field.key, readOnly: true, className: "text-faint" }) }),
|
|
1160
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label: "Type", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Select2, { className: "w-full", value: field.type, onChange: (e) => set({ type: e.target.value }), children: _chunk7NZPYWL3cjs.FIELD_TYPES.map((t) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "option", { value: t, children: TYPE_LABEL[t] }, t)) }) }),
|
|
1161
|
+
textual && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label: "Placeholder", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1162
|
+
TextInput2,
|
|
963
1163
|
{
|
|
964
1164
|
value: _nullishCoalesce(field.placeholder, () => ( "")),
|
|
965
1165
|
onChange: (e) => set({ placeholder: e.target.value || void 0 })
|
|
966
1166
|
}
|
|
967
1167
|
) }),
|
|
968
|
-
field.type !== "file" && field.type !== "signature" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
969
|
-
|
|
1168
|
+
field.type !== "file" && field.type !== "signature" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label: field.type === "checkbox" ? "Checked by default" : "Default value", children: field.type === "checkbox" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1169
|
+
Checkbox2,
|
|
970
1170
|
{
|
|
971
1171
|
label: "Checked by default",
|
|
972
1172
|
checked: field.defaultValue === "true",
|
|
973
1173
|
onChange: (e) => set({ defaultValue: e.target.checked ? "true" : void 0 })
|
|
974
1174
|
}
|
|
975
1175
|
) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
976
|
-
|
|
1176
|
+
TextInput2,
|
|
977
1177
|
{
|
|
978
1178
|
value: _nullishCoalesce(field.defaultValue, () => ( "")),
|
|
979
1179
|
onChange: (e) => set({ defaultValue: e.target.value || void 0 })
|
|
980
1180
|
}
|
|
981
1181
|
) }),
|
|
982
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1182
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label: "Help text (shown as tooltip)", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TextInput2, { value: _nullishCoalesce(field.helpText, () => ( "")), onChange: (e) => set({ helpText: e.target.value || void 0 }) }) }),
|
|
983
1183
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex flex-wrap gap-4", children: ["required", "readOnly", "hidden"].map((k) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "label", { className: "inline-flex items-center gap-1.5", children: [
|
|
984
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1184
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, Checkbox2, { label: k, checked: !!field[k], onChange: (e) => set({ [k]: e.target.checked || void 0 }) }),
|
|
985
1185
|
{ required: "Required", readOnly: "Read-only", hidden: "Hidden" }[k]
|
|
986
1186
|
] }, k)) })
|
|
987
1187
|
] }),
|
|
988
1188
|
hasOptions && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Section2, { title: "Options (one per line)", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
989
|
-
|
|
1189
|
+
TextArea2,
|
|
990
1190
|
{
|
|
991
1191
|
rows: 4,
|
|
992
1192
|
value: optionsText,
|
|
@@ -1004,8 +1204,8 @@ function FieldProperties({
|
|
|
1004
1204
|
) }),
|
|
1005
1205
|
textual && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Section2, { title: "Validation", children: [
|
|
1006
1206
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "grid grid-cols-2 gap-2", children: [
|
|
1007
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1008
|
-
|
|
1207
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label: "Min length", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1208
|
+
TextInput2,
|
|
1009
1209
|
{
|
|
1010
1210
|
type: "number",
|
|
1011
1211
|
min: 0,
|
|
@@ -1013,8 +1213,8 @@ function FieldProperties({
|
|
|
1013
1213
|
onChange: (e) => set({ minLength: num2(e.target.value) })
|
|
1014
1214
|
}
|
|
1015
1215
|
) }),
|
|
1016
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1017
|
-
|
|
1216
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label: "Max length", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1217
|
+
TextInput2,
|
|
1018
1218
|
{
|
|
1019
1219
|
type: "number",
|
|
1020
1220
|
min: 0,
|
|
@@ -1023,16 +1223,16 @@ function FieldProperties({
|
|
|
1023
1223
|
}
|
|
1024
1224
|
) }),
|
|
1025
1225
|
field.type === "number" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
1026
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1027
|
-
|
|
1226
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label: "Min value", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1227
|
+
TextInput2,
|
|
1028
1228
|
{
|
|
1029
1229
|
type: "number",
|
|
1030
1230
|
value: _nullishCoalesce(field.min, () => ( "")),
|
|
1031
1231
|
onChange: (e) => set({ min: num2(e.target.value) })
|
|
1032
1232
|
}
|
|
1033
1233
|
) }),
|
|
1034
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1035
|
-
|
|
1234
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label: "Max value", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1235
|
+
TextInput2,
|
|
1036
1236
|
{
|
|
1037
1237
|
type: "number",
|
|
1038
1238
|
value: _nullishCoalesce(field.max, () => ( "")),
|
|
@@ -1041,8 +1241,8 @@ function FieldProperties({
|
|
|
1041
1241
|
) })
|
|
1042
1242
|
] })
|
|
1043
1243
|
] }),
|
|
1044
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1045
|
-
|
|
1244
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label: "Regex (whole value must match)", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1245
|
+
TextInput2,
|
|
1046
1246
|
{
|
|
1047
1247
|
className: "font-mono",
|
|
1048
1248
|
value: _nullishCoalesce(field.pattern, () => ( "")),
|
|
@@ -1071,8 +1271,8 @@ function FieldProperties({
|
|
|
1071
1271
|
) }, key);
|
|
1072
1272
|
}),
|
|
1073
1273
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, Section2, { title: "Position (% of page)", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "grid grid-cols-2 gap-2", children: [
|
|
1074
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1075
|
-
|
|
1274
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label: "Page", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1275
|
+
TextInput2,
|
|
1076
1276
|
{
|
|
1077
1277
|
type: "number",
|
|
1078
1278
|
min: 1,
|
|
@@ -1086,8 +1286,8 @@ function FieldProperties({
|
|
|
1086
1286
|
}
|
|
1087
1287
|
) }),
|
|
1088
1288
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", {}),
|
|
1089
|
-
["x", "y", "width", "height"].map((k) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1090
|
-
|
|
1289
|
+
["x", "y", "width", "height"].map((k) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormField2, { label: { x: "Left", y: "Top", width: "Width", height: "Height" }[k], children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1290
|
+
TextInput2,
|
|
1091
1291
|
{
|
|
1092
1292
|
type: "number",
|
|
1093
1293
|
step: 0.1,
|
|
@@ -1114,9 +1314,9 @@ function LayoutElementView({
|
|
|
1114
1314
|
style
|
|
1115
1315
|
}) {
|
|
1116
1316
|
const stroke = ptToCqh(_nullishCoalesce(e.strokeWidth, () => ( 1)), pageHeight);
|
|
1117
|
-
const
|
|
1317
|
+
const base2 = { ..._chunk33XWO4KBcjs.boxStyle.call(void 0, { page: e.page, ...e.position }), ...style };
|
|
1118
1318
|
if (e.type === "line")
|
|
1119
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: `absolute overflow-visible ${className}`, style:
|
|
1319
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { className: `absolute overflow-visible ${className}`, style: base2, "aria-hidden": true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1120
1320
|
"line",
|
|
1121
1321
|
{
|
|
1122
1322
|
x1: "0",
|
|
@@ -1132,7 +1332,7 @@ function LayoutElementView({
|
|
|
1132
1332
|
{
|
|
1133
1333
|
className: `absolute overflow-hidden whitespace-pre-wrap ${className}`,
|
|
1134
1334
|
style: {
|
|
1135
|
-
...
|
|
1335
|
+
...base2,
|
|
1136
1336
|
background: e.fill,
|
|
1137
1337
|
border: e.type === "box" && e.stroke ? `${stroke} solid ${e.stroke}` : void 0,
|
|
1138
1338
|
color: _nullishCoalesce(e.color, () => ( "#000000")),
|
|
@@ -1198,7 +1398,7 @@ function PagesPanel({
|
|
|
1198
1398
|
}
|
|
1199
1399
|
),
|
|
1200
1400
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1201
|
-
|
|
1401
|
+
IconButton2,
|
|
1202
1402
|
{
|
|
1203
1403
|
icon: _lucidereact.ArrowUp,
|
|
1204
1404
|
title: "Move page up",
|
|
@@ -1208,7 +1408,7 @@ function PagesPanel({
|
|
|
1208
1408
|
}
|
|
1209
1409
|
),
|
|
1210
1410
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1211
|
-
|
|
1411
|
+
IconButton2,
|
|
1212
1412
|
{
|
|
1213
1413
|
icon: _lucidereact.ArrowDown,
|
|
1214
1414
|
title: "Move page down",
|
|
@@ -1218,7 +1418,7 @@ function PagesPanel({
|
|
|
1218
1418
|
}
|
|
1219
1419
|
),
|
|
1220
1420
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1221
|
-
|
|
1421
|
+
IconButton2,
|
|
1222
1422
|
{
|
|
1223
1423
|
icon: _lucidereact.FilePlus2,
|
|
1224
1424
|
title: "Add blank page after",
|
|
@@ -1227,7 +1427,7 @@ function PagesPanel({
|
|
|
1227
1427
|
}
|
|
1228
1428
|
),
|
|
1229
1429
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1230
|
-
|
|
1430
|
+
IconButton2,
|
|
1231
1431
|
{
|
|
1232
1432
|
icon: _lucidereact.Trash2,
|
|
1233
1433
|
title: "Delete page",
|
|
@@ -1302,11 +1502,11 @@ function PdfPages({
|
|
|
1302
1502
|
if (!live) return;
|
|
1303
1503
|
setSizes(list);
|
|
1304
1504
|
setDoc(pdf);
|
|
1305
|
-
_optionalChain([callbacks, 'access',
|
|
1306
|
-
}).catch((err) => live && _optionalChain([callbacks, 'access',
|
|
1505
|
+
_optionalChain([callbacks, 'access', _25 => _25.current, 'access', _26 => _26.onLoaded, 'optionalCall', _27 => _27(list, pdf)]);
|
|
1506
|
+
}).catch((err) => live && _optionalChain([callbacks, 'access', _28 => _28.current, 'access', _29 => _29.onError, 'optionalCall', _30 => _30(err)]));
|
|
1307
1507
|
return () => {
|
|
1308
1508
|
live = false;
|
|
1309
|
-
void _optionalChain([opened, 'optionalAccess',
|
|
1509
|
+
void _optionalChain([opened, 'optionalAccess', _31 => _31.destroy, 'call', _32 => _32()]);
|
|
1310
1510
|
};
|
|
1311
1511
|
}, []);
|
|
1312
1512
|
if (!doc) return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "p-6 text-center text-[13px] text-muted", children: "Loading document\u2026" });
|
|
@@ -1367,22 +1567,22 @@ function PdfPage({
|
|
|
1367
1567
|
});
|
|
1368
1568
|
return () => {
|
|
1369
1569
|
live = false;
|
|
1370
|
-
_optionalChain([task, 'optionalAccess',
|
|
1570
|
+
_optionalChain([task, 'optionalAccess', _33 => _33.cancel, 'call', _34 => _34()]);
|
|
1371
1571
|
};
|
|
1372
1572
|
}, [doc, source, visible, zoom]);
|
|
1373
1573
|
_react.useEffect.call(void 0, () => {
|
|
1374
|
-
if (!withText || !visible || !source || _optionalChain([lines, 'optionalAccess',
|
|
1574
|
+
if (!withText || !visible || !source || _optionalChain([lines, 'optionalAccess', _35 => _35.source]) === source) return;
|
|
1375
1575
|
let live = true;
|
|
1376
1576
|
void doc.getPage(source).then(async (page) => {
|
|
1377
1577
|
const content = await page.getTextContent();
|
|
1378
1578
|
const fontOf = (id) => {
|
|
1379
1579
|
try {
|
|
1380
|
-
return page.commonObjs.has(id) ? _optionalChain([page, 'access',
|
|
1580
|
+
return page.commonObjs.has(id) ? _optionalChain([page, 'access', _36 => _36.commonObjs, 'access', _37 => _37.get, 'call', _38 => _38(id), 'optionalAccess', _39 => _39.name]) : void 0;
|
|
1381
1581
|
} catch (e2) {
|
|
1382
1582
|
return void 0;
|
|
1383
1583
|
}
|
|
1384
1584
|
};
|
|
1385
|
-
if (live) setLines({ source, lines:
|
|
1585
|
+
if (live) setLines({ source, lines: _chunk33XWO4KBcjs.toLines.call(void 0, content.items, page.view, fontOf) });
|
|
1386
1586
|
}).catch(() => live && setLines({ source, lines: [] }));
|
|
1387
1587
|
return () => {
|
|
1388
1588
|
live = false;
|
|
@@ -1397,7 +1597,7 @@ function PdfPage({
|
|
|
1397
1597
|
style: { width, height },
|
|
1398
1598
|
children: [
|
|
1399
1599
|
source && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "canvas", { ref: canvas, className: "absolute inset-0 h-full w-full", "aria-label": `Page ${pageNo}` }),
|
|
1400
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute inset-0 [container-type:size]", children: _optionalChain([overlay, 'optionalCall',
|
|
1600
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute inset-0 [container-type:size]", children: _optionalChain([overlay, 'optionalCall', _40 => _40(pageNo, withText && _optionalChain([lines, 'optionalAccess', _41 => _41.source]) === source ? lines.lines : void 0)]) })
|
|
1401
1601
|
]
|
|
1402
1602
|
}
|
|
1403
1603
|
);
|
|
@@ -1410,12 +1610,12 @@ function ZoomControls({ zoom, onChange }) {
|
|
|
1410
1610
|
const lower = [...ZOOMS].reverse().find((z) => z < zoom - 0.01);
|
|
1411
1611
|
const higher = ZOOMS.find((z) => z > zoom + 0.01);
|
|
1412
1612
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "inline-flex items-center gap-1 text-[13px]", children: [
|
|
1413
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1613
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, IconButton2, { icon: _lucidereact.Minus, title: "Zoom out", disabled: lower == null, onClick: () => onChange(lower) }),
|
|
1414
1614
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "w-12 text-center tabular-nums", children: [
|
|
1415
1615
|
Math.round(zoom * 100),
|
|
1416
1616
|
"%"
|
|
1417
1617
|
] }),
|
|
1418
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1618
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, IconButton2, { icon: _lucidereact.Plus, title: "Zoom in", disabled: higher == null, onClick: () => onChange(higher) })
|
|
1419
1619
|
] });
|
|
1420
1620
|
}
|
|
1421
1621
|
|
|
@@ -1442,10 +1642,10 @@ function useFitZoom(pageWidthPt) {
|
|
|
1442
1642
|
}
|
|
1443
1643
|
function useCompact() {
|
|
1444
1644
|
const query = "(max-width: 767px), (pointer: coarse)";
|
|
1445
|
-
const get = () => typeof window !== "undefined" && !!_optionalChain([window, 'access',
|
|
1645
|
+
const get = () => typeof window !== "undefined" && !!_optionalChain([window, 'access', _42 => _42.matchMedia, 'optionalCall', _43 => _43(query), 'access', _44 => _44.matches]);
|
|
1446
1646
|
const [compact, setCompact] = _react.useState.call(void 0, get);
|
|
1447
1647
|
_react.useEffect.call(void 0, () => {
|
|
1448
|
-
const m = _optionalChain([window, 'access',
|
|
1648
|
+
const m = _optionalChain([window, 'access', _45 => _45.matchMedia, 'optionalCall', _46 => _46(query)]);
|
|
1449
1649
|
if (!m) return;
|
|
1450
1650
|
const on = () => setCompact(m.matches);
|
|
1451
1651
|
m.addEventListener("change", on);
|
|
@@ -1454,6 +1654,9 @@ function useCompact() {
|
|
|
1454
1654
|
return compact;
|
|
1455
1655
|
}
|
|
1456
1656
|
|
|
1657
|
+
// src/react/hooks/useFormEditor.ts
|
|
1658
|
+
|
|
1659
|
+
|
|
1457
1660
|
// src/react/hooks/useUndo.ts
|
|
1458
1661
|
|
|
1459
1662
|
var LIMIT = 100;
|
|
@@ -1495,57 +1698,45 @@ function useUndo(initial) {
|
|
|
1495
1698
|
};
|
|
1496
1699
|
}
|
|
1497
1700
|
|
|
1498
|
-
// src/react/
|
|
1499
|
-
|
|
1701
|
+
// src/react/hooks/useFormEditor.ts
|
|
1500
1702
|
var GRID = 5e-3;
|
|
1501
|
-
var DRAG_TYPE = "application/x-doc-item";
|
|
1502
1703
|
var EMPTY = { fields: [], layout: null };
|
|
1503
1704
|
var isDefault = (l, sizes2) => !l.elements.length && l.pages.length === sizes2.length && l.pages.every((p, i) => p.source === i + 1);
|
|
1504
|
-
function
|
|
1505
|
-
pdf: pdfSource,
|
|
1705
|
+
function useFormEditor({
|
|
1506
1706
|
initialValue = EMPTY,
|
|
1507
1707
|
onSave,
|
|
1508
1708
|
onChange,
|
|
1509
|
-
title,
|
|
1510
|
-
onBack,
|
|
1511
|
-
toolbar,
|
|
1512
|
-
banner,
|
|
1513
|
-
tabs = [],
|
|
1514
1709
|
autoDetect,
|
|
1710
|
+
onDetected,
|
|
1711
|
+
keyboard = true,
|
|
1712
|
+
warnUnsaved = true,
|
|
1713
|
+
fieldTypes = _chunk7NZPYWL3cjs.FIELD_TYPES,
|
|
1714
|
+
elementTools = Object.keys(_chunk33XWO4KBcjs.ELEMENT_TOOLS),
|
|
1515
1715
|
notify = () => {
|
|
1516
1716
|
},
|
|
1517
|
-
onError: notifyError = (e) => console.error(e)
|
|
1518
|
-
className = "h-full",
|
|
1519
|
-
ref
|
|
1717
|
+
onError: notifyError = (e) => console.error(e)
|
|
1520
1718
|
}) {
|
|
1521
1719
|
const [sizes2, setSizes] = _react.useState.call(void 0, null);
|
|
1522
1720
|
const history = useUndo(initialValue);
|
|
1523
1721
|
const { value: doc, set } = history;
|
|
1524
1722
|
const [saved, setSaved] = _react.useState.call(void 0, initialValue);
|
|
1525
1723
|
const [selection, setSelection] = _react.useState.call(void 0, null);
|
|
1526
|
-
const [tab, setTab] = _react.useState.call(void 0, "props");
|
|
1527
|
-
const [drawer, setDrawer] = _react.useState.call(void 0, null);
|
|
1528
1724
|
const [armed, setArmed] = _react.useState.call(void 0, null);
|
|
1529
|
-
const compact = useCompact();
|
|
1530
1725
|
const [snapOn, setSnapOn] = _react.useState.call(void 0, true);
|
|
1531
1726
|
const [editText, setEditText] = _react.useState.call(void 0, false);
|
|
1532
|
-
const [preview,
|
|
1727
|
+
const [preview, setPreviewState] = _react.useState.call(void 0, false);
|
|
1533
1728
|
const [previewAnswers, setPreviewAnswers] = _react.useState.call(void 0, {});
|
|
1534
1729
|
const [busy, setBusy] = _react.useState.call(void 0, false);
|
|
1535
|
-
const [confirmDeletePage, setConfirmDeletePage] = _react.useState.call(void 0, null);
|
|
1536
|
-
const [loadError, setLoadError] = _react.useState.call(void 0, "");
|
|
1537
1730
|
const [pdf, setPdf] = _react.useState.call(void 0, null);
|
|
1538
1731
|
const [detecting, setDetecting] = _react.useState.call(void 0, null);
|
|
1539
1732
|
const autoDetected = _react.useRef.call(void 0, false);
|
|
1540
1733
|
const drag = _react.useRef.call(void 0, null);
|
|
1541
|
-
const scroller = _react.useRef.call(void 0, null);
|
|
1542
|
-
const { zoom, setZoom, ref: fitRef } = useFitZoom(Math.max(...(_nullishCoalesce(sizes2, () => ( [{ width: 595 }]))).map((p) => p.width)));
|
|
1543
1734
|
const { fields } = doc;
|
|
1544
1735
|
const layout = _nullishCoalesce(doc.layout, () => ( (sizes2 ? _chunk7NZPYWL3cjs.defaultLayout.call(void 0, sizes2) : null)));
|
|
1545
|
-
const pageCount = _nullishCoalesce(_optionalChain([layout, 'optionalAccess',
|
|
1736
|
+
const pageCount = _nullishCoalesce(_optionalChain([layout, 'optionalAccess', _47 => _47.pages, 'access', _48 => _48.length]), () => ( 1));
|
|
1546
1737
|
const grid = snapOn ? GRID : 0;
|
|
1547
|
-
const selectedField = _optionalChain([selection, 'optionalAccess',
|
|
1548
|
-
const selectedElement = _optionalChain([selection, 'optionalAccess',
|
|
1738
|
+
const selectedField = _optionalChain([selection, 'optionalAccess', _49 => _49.kind]) === "field" ? _nullishCoalesce(fields.find((f) => f.id === selection.id), () => ( null)) : null;
|
|
1739
|
+
const selectedElement = _optionalChain([selection, 'optionalAccess', _50 => _50.kind]) === "element" ? _nullishCoalesce(_optionalChain([layout, 'optionalAccess', _51 => _51.elements, 'access', _52 => _52.find, 'call', _53 => _53((e) => e.id === selection.id)]), () => ( null)) : null;
|
|
1549
1740
|
const dirty = JSON.stringify(doc) !== JSON.stringify(saved);
|
|
1550
1741
|
const problems = _react.useMemo.call(void 0,
|
|
1551
1742
|
() => sizes2 ? [...doc.layout ? _chunk7NZPYWL3cjs.validateLayout.call(void 0, doc.layout, sizes2.length) : [], ..._chunk7NZPYWL3cjs.validateFields.call(void 0, fields, pageCount)] : [],
|
|
@@ -1558,13 +1749,13 @@ function FormEditor({
|
|
|
1558
1749
|
const first = _react.useRef.call(void 0, true);
|
|
1559
1750
|
_react.useEffect.call(void 0, () => {
|
|
1560
1751
|
if (first.current) first.current = false;
|
|
1561
|
-
else _optionalChain([onChangeRef, 'access',
|
|
1752
|
+
else _optionalChain([onChangeRef, 'access', _54 => _54.current, 'optionalCall', _55 => _55(doc)]);
|
|
1562
1753
|
}, [doc]);
|
|
1563
1754
|
const withDoc = _react.useCallback.call(void 0,
|
|
1564
1755
|
(fn, record = true) => set((cur) => {
|
|
1565
|
-
const
|
|
1566
|
-
if (!
|
|
1567
|
-
return fn({ fields: cur.fields, layout:
|
|
1756
|
+
const base2 = _nullishCoalesce(cur.layout, () => ( (sizes2 ? _chunk7NZPYWL3cjs.defaultLayout.call(void 0, sizes2) : null)));
|
|
1757
|
+
if (!base2) return cur;
|
|
1758
|
+
return fn({ fields: cur.fields, layout: base2 });
|
|
1568
1759
|
}, record),
|
|
1569
1760
|
[set, sizes2]
|
|
1570
1761
|
);
|
|
@@ -1576,15 +1767,11 @@ function FormEditor({
|
|
|
1576
1767
|
(fn, record = true) => withDoc((d) => ({ ...d, layout: { ...d.layout, elements: fn(d.layout.elements) } }), record),
|
|
1577
1768
|
[withDoc]
|
|
1578
1769
|
);
|
|
1579
|
-
const
|
|
1580
|
-
setSelection(s);
|
|
1581
|
-
if (s) setTab("props");
|
|
1582
|
-
};
|
|
1583
|
-
const updateField = _react.useCallback.call(void 0, (f) => setFields((l) => _chunk5VHPTLLVcjs.withField.call(void 0, l, f)), [setFields]);
|
|
1770
|
+
const updateField = _react.useCallback.call(void 0, (f) => setFields((l) => _chunk33XWO4KBcjs.withField.call(void 0, l, f)), [setFields]);
|
|
1584
1771
|
const updateElement = _react.useCallback.call(void 0,
|
|
1585
1772
|
(e) => {
|
|
1586
|
-
const pageWidth = _nullishCoalesce(_optionalChain([layout, 'optionalAccess',
|
|
1587
|
-
setElements((l) => l.map((x) => x.id === e.id ?
|
|
1773
|
+
const pageWidth = _nullishCoalesce(_optionalChain([layout, 'optionalAccess', _56 => _56.pages, 'access', _57 => _57[e.page - 1], 'optionalAccess', _58 => _58.width]), () => ( 595));
|
|
1774
|
+
setElements((l) => l.map((x) => x.id === e.id ? _chunk33XWO4KBcjs.fitTextWidth.call(void 0, e, pageWidth) : x));
|
|
1588
1775
|
},
|
|
1589
1776
|
[setElements, layout]
|
|
1590
1777
|
);
|
|
@@ -1596,16 +1783,28 @@ function FormEditor({
|
|
|
1596
1783
|
}, [selection, setFields, setElements]);
|
|
1597
1784
|
const duplicateSelected = _react.useCallback.call(void 0, () => {
|
|
1598
1785
|
if (selectedField) {
|
|
1599
|
-
const copy =
|
|
1786
|
+
const copy = _chunk33XWO4KBcjs.duplicate.call(void 0, selectedField, fields);
|
|
1600
1787
|
setFields((l) => [...l, copy]);
|
|
1601
1788
|
setSelection({ kind: "field", id: copy.id });
|
|
1602
1789
|
} else if (selectedElement) {
|
|
1603
|
-
const copy =
|
|
1790
|
+
const copy = _chunk33XWO4KBcjs.duplicateElement.call(void 0, selectedElement);
|
|
1604
1791
|
setElements((l) => [...l, copy]);
|
|
1605
1792
|
setSelection({ kind: "element", id: copy.id });
|
|
1606
1793
|
}
|
|
1607
1794
|
}, [selectedField, selectedElement, fields, setFields, setElements]);
|
|
1795
|
+
const nudge = _react.useCallback.call(void 0,
|
|
1796
|
+
(dx, dy) => {
|
|
1797
|
+
if (selectedField) updateField({ ...selectedField, position: _chunk33XWO4KBcjs.moveBy.call(void 0, selectedField.position, dx, dy) });
|
|
1798
|
+
if (selectedElement) {
|
|
1799
|
+
const { page: _p, ...position } = _chunk33XWO4KBcjs.moveBy.call(void 0, { page: selectedElement.page, ...selectedElement.position }, dx, dy);
|
|
1800
|
+
void _p;
|
|
1801
|
+
updateElement({ ...selectedElement, position });
|
|
1802
|
+
}
|
|
1803
|
+
},
|
|
1804
|
+
[selectedField, selectedElement, updateField, updateElement]
|
|
1805
|
+
);
|
|
1608
1806
|
_react.useEffect.call(void 0, () => {
|
|
1807
|
+
if (!keyboard) return;
|
|
1609
1808
|
const onKey = (e) => {
|
|
1610
1809
|
const t = e.target;
|
|
1611
1810
|
if (preview || t.closest("input, textarea, select, [contenteditable]")) return;
|
|
@@ -1627,42 +1826,27 @@ function FormEditor({
|
|
|
1627
1826
|
else if (e.key.startsWith("Arrow")) {
|
|
1628
1827
|
e.preventDefault();
|
|
1629
1828
|
const step = e.shiftKey ? 0.01 : 2e-3;
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
const { page: _p, ...position } = _chunk5VHPTLLVcjs.moveBy.call(void 0, { page: selectedElement.page, ...selectedElement.position }, dx, dy);
|
|
1635
|
-
void _p;
|
|
1636
|
-
updateElement({ ...selectedElement, position });
|
|
1637
|
-
}
|
|
1829
|
+
nudge(
|
|
1830
|
+
e.key === "ArrowLeft" ? -step : e.key === "ArrowRight" ? step : 0,
|
|
1831
|
+
e.key === "ArrowUp" ? -step : e.key === "ArrowDown" ? step : 0
|
|
1832
|
+
);
|
|
1638
1833
|
}
|
|
1639
1834
|
};
|
|
1640
1835
|
window.addEventListener("keydown", onKey);
|
|
1641
1836
|
return () => window.removeEventListener("keydown", onKey);
|
|
1642
|
-
}, [
|
|
1643
|
-
preview,
|
|
1644
|
-
armed,
|
|
1645
|
-
selection,
|
|
1646
|
-
selectedField,
|
|
1647
|
-
selectedElement,
|
|
1648
|
-
history,
|
|
1649
|
-
removeSelected,
|
|
1650
|
-
duplicateSelected,
|
|
1651
|
-
updateField,
|
|
1652
|
-
updateElement
|
|
1653
|
-
]);
|
|
1837
|
+
}, [keyboard, preview, armed, selection, history, removeSelected, duplicateSelected, nudge]);
|
|
1654
1838
|
_react.useEffect.call(void 0, () => {
|
|
1655
|
-
if (!dirty) return;
|
|
1839
|
+
if (!dirty || !warnUnsaved) return;
|
|
1656
1840
|
const warn = (e) => e.preventDefault();
|
|
1657
1841
|
window.addEventListener("beforeunload", warn);
|
|
1658
1842
|
return () => window.removeEventListener("beforeunload", warn);
|
|
1659
|
-
}, [dirty]);
|
|
1843
|
+
}, [dirty, warnUnsaved]);
|
|
1660
1844
|
function startDrag(e, sel, start, mode) {
|
|
1661
1845
|
if (e.button !== 0) return;
|
|
1662
1846
|
e.stopPropagation();
|
|
1663
1847
|
const pageEl = e.currentTarget.closest("[data-page]");
|
|
1664
1848
|
if (!pageEl) return;
|
|
1665
|
-
|
|
1849
|
+
setSelection(sel);
|
|
1666
1850
|
history.checkpoint();
|
|
1667
1851
|
drag.current = { sel, mode, x: e.clientX, y: e.clientY, start, rect: pageEl.getBoundingClientRect() };
|
|
1668
1852
|
e.currentTarget.setPointerCapture(e.pointerId);
|
|
@@ -1673,7 +1857,7 @@ function FormEditor({
|
|
|
1673
1857
|
const dx = (e.clientX - d.x) / d.rect.width;
|
|
1674
1858
|
const dy = (e.clientY - d.y) / d.rect.height;
|
|
1675
1859
|
if (d.sel.kind === "field") {
|
|
1676
|
-
const position = d.mode === "move" ?
|
|
1860
|
+
const position = d.mode === "move" ? _chunk33XWO4KBcjs.moveBy.call(void 0, d.start, dx, dy, grid) : _chunk33XWO4KBcjs.resizeBy.call(void 0, d.start, dx, dy, grid);
|
|
1677
1861
|
setFields((l) => l.map((x) => x.id === d.sel.id ? { ...x, position } : x), false);
|
|
1678
1862
|
return;
|
|
1679
1863
|
}
|
|
@@ -1681,48 +1865,52 @@ function FormEditor({
|
|
|
1681
1865
|
(l) => l.map((x) => {
|
|
1682
1866
|
if (x.id !== d.sel.id) return x;
|
|
1683
1867
|
if (d.mode === "move") {
|
|
1684
|
-
const { page: _p2, ...position2 } =
|
|
1868
|
+
const { page: _p2, ...position2 } = _chunk33XWO4KBcjs.moveBy.call(void 0, d.start, dx, dy, grid);
|
|
1685
1869
|
void _p2;
|
|
1686
1870
|
return { ...x, position: position2 };
|
|
1687
1871
|
}
|
|
1688
1872
|
if (x.type === "line") {
|
|
1689
1873
|
const flat = (n) => n < 4e-3 ? 0 : n;
|
|
1690
|
-
const width = flat(Math.min(1 - d.start.x, Math.max(0,
|
|
1691
|
-
const height = flat(Math.min(1 - d.start.y, Math.max(0,
|
|
1874
|
+
const width = flat(Math.min(1 - d.start.x, Math.max(0, _chunk33XWO4KBcjs.snap.call(void 0, d.start.width + dx, grid))));
|
|
1875
|
+
const height = flat(Math.min(1 - d.start.y, Math.max(0, _chunk33XWO4KBcjs.snap.call(void 0, d.start.height + dy, grid))));
|
|
1692
1876
|
return { ...x, position: { ...x.position, width, height } };
|
|
1693
1877
|
}
|
|
1694
|
-
const { page: _p, ...position } =
|
|
1878
|
+
const { page: _p, ...position } = _chunk33XWO4KBcjs.resizeBy.call(void 0, d.start, dx, dy, grid);
|
|
1695
1879
|
void _p;
|
|
1696
1880
|
return { ...x, position };
|
|
1697
1881
|
}),
|
|
1698
1882
|
false
|
|
1699
1883
|
);
|
|
1700
1884
|
}
|
|
1701
|
-
const endDrag = () =>
|
|
1885
|
+
const endDrag = () => {
|
|
1886
|
+
drag.current = null;
|
|
1887
|
+
};
|
|
1702
1888
|
function placeNew(key, page, clientX, clientY, rect) {
|
|
1703
1889
|
const [kind, what] = key.split(":");
|
|
1704
|
-
const { x, y } =
|
|
1705
|
-
if (kind === "field" &&
|
|
1706
|
-
const f =
|
|
1890
|
+
const { x, y } = _chunk33XWO4KBcjs.toPage.call(void 0, clientX, clientY, rect);
|
|
1891
|
+
if (kind === "field" && fieldTypes.includes(what)) {
|
|
1892
|
+
const f = _chunk33XWO4KBcjs.newField.call(void 0, what, page, x, y, fields);
|
|
1707
1893
|
setFields((l) => [...l, f]);
|
|
1708
|
-
|
|
1894
|
+
setSelection({ kind: "field", id: f.id });
|
|
1709
1895
|
return true;
|
|
1710
1896
|
}
|
|
1711
|
-
if (kind === "element" && what
|
|
1712
|
-
const el =
|
|
1897
|
+
if (kind === "element" && elementTools.includes(what)) {
|
|
1898
|
+
const el = _chunk33XWO4KBcjs.newElement.call(void 0, what, page, x, y);
|
|
1713
1899
|
setElements((l) => [...l, el]);
|
|
1714
|
-
|
|
1900
|
+
setSelection({ kind: "element", id: el.id });
|
|
1715
1901
|
return true;
|
|
1716
1902
|
}
|
|
1717
1903
|
return false;
|
|
1718
1904
|
}
|
|
1719
|
-
function
|
|
1720
|
-
const
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
function goToPage(n) {
|
|
1724
|
-
_optionalChain([scroller, 'access', _56 => _56.current, 'optionalAccess', _57 => _57.querySelector, 'call', _58 => _58(`[data-page="${n}"]`), 'optionalAccess', _59 => _59.scrollIntoView, 'call', _60 => _60({ block: "start" })]);
|
|
1905
|
+
function editLine(line, page) {
|
|
1906
|
+
const el = _chunk33XWO4KBcjs.replaceLine.call(void 0, line, page);
|
|
1907
|
+
setElements((l) => [...l, el]);
|
|
1908
|
+
setSelection({ kind: "element", id: el.id });
|
|
1725
1909
|
}
|
|
1910
|
+
const onDetectedRef = _react.useRef.call(void 0, onDetected);
|
|
1911
|
+
_react.useEffect.call(void 0, () => {
|
|
1912
|
+
onDetectedRef.current = onDetected;
|
|
1913
|
+
});
|
|
1726
1914
|
const detect = _react.useCallback.call(void 0,
|
|
1727
1915
|
async (auto = false) => {
|
|
1728
1916
|
if (!pdf || !layout || detecting) return;
|
|
@@ -1730,7 +1918,7 @@ function FormEditor({
|
|
|
1730
1918
|
setDetecting({ done: 0, total: layout.pages.length, stop });
|
|
1731
1919
|
try {
|
|
1732
1920
|
const lib = await loadPdfJs();
|
|
1733
|
-
const found = await
|
|
1921
|
+
const found = await _chunk33XWO4KBcjs.detectDocument.call(void 0,
|
|
1734
1922
|
pdf,
|
|
1735
1923
|
lib.OPS,
|
|
1736
1924
|
layout.pages,
|
|
@@ -1740,7 +1928,7 @@ function FormEditor({
|
|
|
1740
1928
|
);
|
|
1741
1929
|
if (found.length) {
|
|
1742
1930
|
setFields((l) => [...l, ...found]);
|
|
1743
|
-
|
|
1931
|
+
_optionalChain([onDetectedRef, 'access', _59 => _59.current, 'optionalCall', _60 => _60(found)]);
|
|
1744
1932
|
}
|
|
1745
1933
|
notify(
|
|
1746
1934
|
found.length ? `${found.length} fields suggested${stop.signal.aborted ? " (stopped early)" : ""}. Check the dashed ones, then Save.` : auto ? "No fields found automatically. Drag them in from the left." : "No new fields found"
|
|
@@ -1786,25 +1974,144 @@ function FormEditor({
|
|
|
1786
1974
|
setBusy(false);
|
|
1787
1975
|
}
|
|
1788
1976
|
}
|
|
1789
|
-
const
|
|
1977
|
+
const counts = {};
|
|
1978
|
+
for (const f of fields) counts[f.position.page] = (_nullishCoalesce(counts[f.position.page], () => ( 0))) + 1;
|
|
1979
|
+
for (const el of _nullishCoalesce(_optionalChain([layout, 'optionalAccess', _61 => _61.elements]), () => ( []))) counts[el.page] = (_nullishCoalesce(counts[el.page], () => ( 0))) + 1;
|
|
1980
|
+
return {
|
|
1981
|
+
doc,
|
|
1982
|
+
fields,
|
|
1983
|
+
/** The layout as shown (the original pages until changed); null until the PDF has loaded. */
|
|
1984
|
+
layout,
|
|
1985
|
+
pageCount,
|
|
1986
|
+
/** Page size in PDF points, for drawing layout text at the right size. */
|
|
1987
|
+
pageHeight: (page) => _nullishCoalesce(_optionalChain([layout, 'optionalAccess', _62 => _62.pages, 'access', _63 => _63[page - 1], 'optionalAccess', _64 => _64.height]), () => ( 842)),
|
|
1988
|
+
/** Fields + layout items per page. */
|
|
1989
|
+
counts,
|
|
1990
|
+
dirty,
|
|
1991
|
+
/** Validation messages; save() refuses while there are any. */
|
|
1992
|
+
problems,
|
|
1993
|
+
busy,
|
|
1994
|
+
save,
|
|
1995
|
+
undo: history.undo,
|
|
1996
|
+
redo: history.redo,
|
|
1997
|
+
canUndo: history.canUndo,
|
|
1998
|
+
canRedo: history.canRedo,
|
|
1999
|
+
/** Changes the document; `record: false` = no undo step (live drags). */
|
|
2000
|
+
setFields,
|
|
2001
|
+
setElements,
|
|
2002
|
+
updateField,
|
|
2003
|
+
updateElement,
|
|
2004
|
+
reorderField: (id, step) => setFields((l) => _chunk33XWO4KBcjs.reorder.call(void 0, l, id, step)),
|
|
2005
|
+
movePage: (n, step) => withDoc((d) => _chunk33XWO4KBcjs.movePage.call(void 0, d, n, step)),
|
|
2006
|
+
insertBlankPage: (n) => withDoc((d) => _chunk33XWO4KBcjs.insertBlankPage.call(void 0, d, n)),
|
|
2007
|
+
deletePage: (n) => {
|
|
2008
|
+
setSelection(null);
|
|
2009
|
+
withDoc((d) => _chunk33XWO4KBcjs.deletePage.call(void 0, d, n));
|
|
2010
|
+
},
|
|
2011
|
+
selection,
|
|
2012
|
+
setSelection,
|
|
2013
|
+
selectedField,
|
|
2014
|
+
selectedElement,
|
|
2015
|
+
removeSelected,
|
|
2016
|
+
duplicateSelected,
|
|
2017
|
+
nudge,
|
|
2018
|
+
startDrag,
|
|
2019
|
+
onDrag,
|
|
2020
|
+
endDrag,
|
|
2021
|
+
/** Tools for a palette: drag with `dataTransfer` / tap to arm, then placeNew. */
|
|
2022
|
+
fieldTools: fieldTypes.map((t) => `field:${t}`),
|
|
2023
|
+
elementTools: elementTools.map((t) => `element:${t}`),
|
|
2024
|
+
armed,
|
|
2025
|
+
setArmed,
|
|
2026
|
+
placeNew,
|
|
2027
|
+
editText,
|
|
2028
|
+
setEditText,
|
|
2029
|
+
editLine,
|
|
2030
|
+
snapOn,
|
|
2031
|
+
setSnapOn,
|
|
2032
|
+
preview,
|
|
2033
|
+
/** Preview starts with empty answers; leaving it ends Edit text. */
|
|
2034
|
+
setPreview: (on) => {
|
|
2035
|
+
setPreviewState(on);
|
|
2036
|
+
setPreviewAnswers({});
|
|
2037
|
+
setEditText(false);
|
|
2038
|
+
},
|
|
2039
|
+
previewAnswers,
|
|
2040
|
+
setPreviewAnswers,
|
|
2041
|
+
previewStates: _chunk7NZPYWL3cjs.fieldStates.call(void 0, fields, previewAnswers),
|
|
2042
|
+
pdf,
|
|
2043
|
+
/** Pass to PdfPages' onLoaded. */
|
|
2044
|
+
onPdfLoaded: (s, d) => {
|
|
2045
|
+
setSizes(s);
|
|
2046
|
+
setPdf(d);
|
|
2047
|
+
},
|
|
2048
|
+
pageSizes: sizes2,
|
|
2049
|
+
detect,
|
|
2050
|
+
/** Progress while detecting; `stop.abort()` keeps what was found so far. */
|
|
2051
|
+
detecting
|
|
2052
|
+
};
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
// src/react/FormEditor.tsx
|
|
2056
|
+
|
|
2057
|
+
var DRAG_TYPE = "application/x-doc-item";
|
|
2058
|
+
function FormEditor({
|
|
2059
|
+
pdf: pdfSource,
|
|
2060
|
+
title,
|
|
2061
|
+
onBack,
|
|
2062
|
+
toolbar,
|
|
2063
|
+
banner,
|
|
2064
|
+
tabs = [],
|
|
2065
|
+
components,
|
|
2066
|
+
hide = [],
|
|
2067
|
+
className = "h-full",
|
|
2068
|
+
ref,
|
|
2069
|
+
...options
|
|
2070
|
+
}) {
|
|
2071
|
+
const shows = (p) => !hide.includes(p);
|
|
2072
|
+
const panelTabs = [
|
|
2073
|
+
...shows("propertiesTab") ? ["props"] : [],
|
|
2074
|
+
...shows("fieldsTab") ? ["fields"] : [],
|
|
2075
|
+
...shows("pagesTab") ? ["pages"] : [],
|
|
2076
|
+
...tabs.map((t) => t.id)
|
|
2077
|
+
];
|
|
2078
|
+
const [tab, setTabState] = _react.useState.call(void 0, _nullishCoalesce(panelTabs[0], () => ( "props")));
|
|
2079
|
+
const setTab = (t) => panelTabs.includes(t) && setTabState(t);
|
|
2080
|
+
const ed = useFormEditor({
|
|
2081
|
+
...options,
|
|
2082
|
+
onDetected: (found) => {
|
|
2083
|
+
setTab("fields");
|
|
2084
|
+
_optionalChain([options, 'access', _65 => _65.onDetected, 'optionalCall', _66 => _66(found)]);
|
|
2085
|
+
}
|
|
2086
|
+
});
|
|
2087
|
+
const { fields, layout, pageCount, selection, selectedField, selectedElement, preview, armed, snapOn, editText } = ed;
|
|
2088
|
+
const [drawer, setDrawer] = _react.useState.call(void 0, null);
|
|
2089
|
+
const compact = useCompact();
|
|
2090
|
+
const [confirmDeletePage, setConfirmDeletePage] = _react.useState.call(void 0, null);
|
|
2091
|
+
const [loadError, setLoadError] = _react.useState.call(void 0, "");
|
|
2092
|
+
const scroller = _react.useRef.call(void 0, null);
|
|
2093
|
+
const { zoom, setZoom, ref: fitRef } = useFitZoom(Math.max(...(_nullishCoalesce(ed.pageSizes, () => ( [{ width: 595 }]))).map((p) => p.width)));
|
|
2094
|
+
_react.useEffect.call(void 0, () => {
|
|
2095
|
+
if (selection) setTab("props");
|
|
2096
|
+
}, [selection]);
|
|
2097
|
+
function goToPage(n) {
|
|
2098
|
+
_optionalChain([scroller, 'access', _67 => _67.current, 'optionalAccess', _68 => _68.querySelector, 'call', _69 => _69(`[data-page="${n}"]`), 'optionalAccess', _70 => _70.scrollIntoView, 'call', _71 => _71({ block: "start" })]);
|
|
2099
|
+
}
|
|
2100
|
+
const saveRef = _react.useRef.call(void 0, ed.save);
|
|
1790
2101
|
_react.useEffect.call(void 0, () => {
|
|
1791
|
-
saveRef.current = save;
|
|
2102
|
+
saveRef.current = ed.save;
|
|
1792
2103
|
});
|
|
1793
2104
|
_react.useImperativeHandle.call(void 0,
|
|
1794
2105
|
ref,
|
|
1795
2106
|
() => ({
|
|
1796
|
-
save: () => dirty ? saveRef.current() : Promise.resolve(problems.length === 0),
|
|
1797
|
-
dirty,
|
|
1798
|
-
value: doc
|
|
2107
|
+
save: () => ed.dirty ? saveRef.current() : Promise.resolve(ed.problems.length === 0),
|
|
2108
|
+
dirty: ed.dirty,
|
|
2109
|
+
value: ed.doc
|
|
1799
2110
|
}),
|
|
1800
|
-
[dirty, doc, problems]
|
|
2111
|
+
[ed.dirty, ed.doc, ed.problems]
|
|
1801
2112
|
);
|
|
1802
2113
|
if (loadError) return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "fl-root p-6 text-center text-sm text-danger", children: loadError });
|
|
1803
|
-
const previewStates
|
|
1804
|
-
const counts = {};
|
|
1805
|
-
for (const f of fields) counts[f.position.page] = (_nullishCoalesce(counts[f.position.page], () => ( 0))) + 1;
|
|
1806
|
-
for (const el of _nullishCoalesce(_optionalChain([layout, 'optionalAccess', _61 => _61.elements]), () => ( []))) counts[el.page] = (_nullishCoalesce(counts[el.page], () => ( 0))) + 1;
|
|
1807
|
-
const pageHeight = (page) => _nullishCoalesce(_optionalChain([layout, 'optionalAccess', _62 => _62.pages, 'access', _63 => _63[page - 1], 'optionalAccess', _64 => _64.height]), () => ( 842));
|
|
2114
|
+
const { previewStates, previewAnswers, counts, pageHeight } = ed;
|
|
1808
2115
|
const toolItem = (key, label) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1809
2116
|
"button",
|
|
1810
2117
|
{
|
|
@@ -1812,7 +2119,7 @@ function FormEditor({
|
|
|
1812
2119
|
draggable: true,
|
|
1813
2120
|
onDragStart: (e) => e.dataTransfer.setData(DRAG_TYPE, key),
|
|
1814
2121
|
onClick: () => {
|
|
1815
|
-
setArmed(
|
|
2122
|
+
ed.setArmed(armed === key ? null : key);
|
|
1816
2123
|
setDrawer(null);
|
|
1817
2124
|
},
|
|
1818
2125
|
"aria-pressed": armed === key,
|
|
@@ -1821,12 +2128,12 @@ function FormEditor({
|
|
|
1821
2128
|
},
|
|
1822
2129
|
key
|
|
1823
2130
|
);
|
|
1824
|
-
const armedLabel = armed ? armed.startsWith("field:") ? TYPE_LABEL[armed.slice(6)] : _optionalChain([
|
|
1825
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: `fl-root flex min-h-[640px] flex-col bg-white text-ink ${className}`, children: [
|
|
2131
|
+
const armedLabel = armed ? armed.startsWith("field:") ? TYPE_LABEL[armed.slice(6)] : _optionalChain([_chunk33XWO4KBcjs.ELEMENT_TOOLS, 'access', _72 => _72[armed.slice(8)], 'optionalAccess', _73 => _73.label]) : "";
|
|
2132
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormliftProvider, { components, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: `fl-root flex min-h-[640px] flex-col bg-white text-ink ${className}`, children: [
|
|
1826
2133
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-wrap items-center gap-2 border-b border-line bg-white px-4 py-2.5", children: [
|
|
1827
|
-
onBack && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1828
|
-
!preview && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1829
|
-
|
|
2134
|
+
onBack && shows("back") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button2, { variant: "secondary", size: "sm", icon: _lucidereact.ArrowLeft, onClick: onBack, children: "Back" }),
|
|
2135
|
+
!preview && shows("tools") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2136
|
+
Button2,
|
|
1830
2137
|
{
|
|
1831
2138
|
variant: drawer === "tools" ? "primary" : "secondary",
|
|
1832
2139
|
size: "sm",
|
|
@@ -1836,8 +2143,8 @@ function FormEditor({
|
|
|
1836
2143
|
children: "Add"
|
|
1837
2144
|
}
|
|
1838
2145
|
),
|
|
1839
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1840
|
-
|
|
2146
|
+
shows("panel") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2147
|
+
Button2,
|
|
1841
2148
|
{
|
|
1842
2149
|
variant: drawer === "panel" ? "primary" : "secondary",
|
|
1843
2150
|
size: "sm",
|
|
@@ -1847,91 +2154,73 @@ function FormEditor({
|
|
|
1847
2154
|
children: selection ? "Properties" : "Panel"
|
|
1848
2155
|
}
|
|
1849
2156
|
),
|
|
1850
|
-
title != null && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "m-0 min-w-0 truncate text-[17px] font-semibold", children: title }),
|
|
1851
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-[12px] text-muted", children: dirty ? "Unsaved changes" : "All changes saved" }),
|
|
2157
|
+
title != null && shows("title") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "m-0 min-w-0 truncate text-[17px] font-semibold", children: title }),
|
|
2158
|
+
shows("status") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-[12px] text-muted", children: ed.dirty ? "Unsaved changes" : "All changes saved" }),
|
|
1852
2159
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "ml-auto flex flex-wrap items-center gap-1.5", children: [
|
|
1853
|
-
/* @__PURE__ */ _jsxruntime.
|
|
1854
|
-
|
|
1855
|
-
{
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
onClick: history.undo
|
|
1860
|
-
}
|
|
1861
|
-
),
|
|
1862
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1863
|
-
IconButton,
|
|
1864
|
-
{
|
|
1865
|
-
icon: _lucidereact.Redo2,
|
|
1866
|
-
title: "Redo (Ctrl+Y)",
|
|
1867
|
-
disabled: !history.canRedo || preview,
|
|
1868
|
-
onClick: history.redo
|
|
1869
|
-
}
|
|
1870
|
-
),
|
|
1871
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1872
|
-
IconButton,
|
|
2160
|
+
shows("undo") && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
2161
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, IconButton2, { icon: _lucidereact.Undo2, title: "Undo (Ctrl+Z)", disabled: !ed.canUndo || preview, onClick: ed.undo }),
|
|
2162
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, IconButton2, { icon: _lucidereact.Redo2, title: "Redo (Ctrl+Y)", disabled: !ed.canRedo || preview, onClick: ed.redo })
|
|
2163
|
+
] }),
|
|
2164
|
+
shows("snap") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2165
|
+
IconButton2,
|
|
1873
2166
|
{
|
|
1874
2167
|
icon: _lucidereact.Grid3x3,
|
|
1875
2168
|
title: snapOn ? "Snap to grid: on" : "Snap to grid: off",
|
|
1876
2169
|
className: snapOn ? "!text-primary" : "",
|
|
1877
|
-
onClick: () => setSnapOn(
|
|
2170
|
+
onClick: () => ed.setSnapOn(!snapOn)
|
|
1878
2171
|
}
|
|
1879
2172
|
),
|
|
1880
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, ZoomControls, { zoom, onChange: setZoom }),
|
|
1881
|
-
!preview && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1882
|
-
|
|
2173
|
+
shows("zoom") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ZoomControls, { zoom, onChange: setZoom }),
|
|
2174
|
+
!preview && shows("editText") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2175
|
+
Button2,
|
|
1883
2176
|
{
|
|
1884
2177
|
variant: editText ? "primary" : "secondary",
|
|
1885
2178
|
size: "sm",
|
|
1886
2179
|
icon: _lucidereact.Type,
|
|
1887
2180
|
disabled: !layout,
|
|
1888
2181
|
title: "Click any line of the document to change its text",
|
|
1889
|
-
onClick: () => setEditText(
|
|
2182
|
+
onClick: () => ed.setEditText(!editText),
|
|
1890
2183
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "max-sm:hidden", children: "Edit text" })
|
|
1891
2184
|
}
|
|
1892
2185
|
),
|
|
1893
|
-
!preview && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1894
|
-
|
|
2186
|
+
!preview && shows("autoDetect") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2187
|
+
Button2,
|
|
1895
2188
|
{
|
|
1896
2189
|
variant: "secondary",
|
|
1897
2190
|
size: "sm",
|
|
1898
2191
|
icon: _lucidereact.Wand2,
|
|
1899
|
-
disabled: !pdf || !layout || !!detecting,
|
|
2192
|
+
disabled: !ed.pdf || !layout || !!ed.detecting,
|
|
1900
2193
|
title: "Find answer lines, checkboxes and table cells and suggest fields for them",
|
|
1901
|
-
onClick: () => void detect(),
|
|
2194
|
+
onClick: () => void ed.detect(),
|
|
1902
2195
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "max-sm:hidden", children: "Auto-detect" })
|
|
1903
2196
|
}
|
|
1904
2197
|
),
|
|
1905
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1906
|
-
|
|
2198
|
+
shows("preview") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2199
|
+
Button2,
|
|
1907
2200
|
{
|
|
1908
2201
|
variant: "secondary",
|
|
1909
2202
|
size: "sm",
|
|
1910
2203
|
icon: preview ? _lucidereact.Pencil : _lucidereact.Eye,
|
|
1911
2204
|
title: preview ? "Back to editing" : "Preview",
|
|
1912
|
-
onClick: () =>
|
|
1913
|
-
setPreview((p) => !p);
|
|
1914
|
-
setPreviewAnswers({});
|
|
1915
|
-
setEditText(false);
|
|
1916
|
-
},
|
|
2205
|
+
onClick: () => ed.setPreview(!preview),
|
|
1917
2206
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "max-sm:hidden", children: preview ? "Edit" : "Preview" })
|
|
1918
2207
|
}
|
|
1919
2208
|
),
|
|
1920
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2209
|
+
shows("save") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button2, { size: "sm", icon: _lucidereact.Save, title: "Save", disabled: !ed.dirty || ed.busy, onClick: () => void ed.save(), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "max-sm:hidden", children: "Save" }) }),
|
|
1921
2210
|
toolbar
|
|
1922
2211
|
] })
|
|
1923
2212
|
] }),
|
|
1924
2213
|
banner,
|
|
1925
|
-
detecting && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-3 bg-folder/15 px-4 py-1.5 text-[12.5px] text-ink-2", role: "status", children: [
|
|
2214
|
+
ed.detecting && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-3 bg-folder/15 px-4 py-1.5 text-[12.5px] text-ink-2", role: "status", children: [
|
|
1926
2215
|
"Detecting fields\u2026 page ",
|
|
1927
|
-
detecting.done,
|
|
2216
|
+
ed.detecting.done,
|
|
1928
2217
|
" of ",
|
|
1929
|
-
detecting.total,
|
|
2218
|
+
ed.detecting.total,
|
|
1930
2219
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-1.5 w-40 overflow-hidden rounded bg-white", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1931
2220
|
"div",
|
|
1932
2221
|
{
|
|
1933
2222
|
className: "h-full bg-folder",
|
|
1934
|
-
style: { width: `${100 * detecting.done / Math.max(1, detecting.total)}%` }
|
|
2223
|
+
style: { width: `${100 * ed.detecting.done / Math.max(1, ed.detecting.total)}%` }
|
|
1935
2224
|
}
|
|
1936
2225
|
) }),
|
|
1937
2226
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
@@ -1939,7 +2228,7 @@ function FormEditor({
|
|
|
1939
2228
|
{
|
|
1940
2229
|
type: "button",
|
|
1941
2230
|
className: "cursor-pointer text-primary hover:underline",
|
|
1942
|
-
onClick: () => detecting.stop.abort(),
|
|
2231
|
+
onClick: () => _optionalChain([ed, 'access', _74 => _74.detecting, 'optionalAccess', _75 => _75.stop, 'access', _76 => _76.abort, 'call', _77 => _77()]),
|
|
1943
2232
|
children: "Stop"
|
|
1944
2233
|
}
|
|
1945
2234
|
)
|
|
@@ -1948,22 +2237,32 @@ function FormEditor({
|
|
|
1948
2237
|
"Tap the page where the ",
|
|
1949
2238
|
armedLabel,
|
|
1950
2239
|
" should go.",
|
|
1951
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2240
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2241
|
+
"button",
|
|
2242
|
+
{
|
|
2243
|
+
type: "button",
|
|
2244
|
+
className: "cursor-pointer text-primary hover:underline",
|
|
2245
|
+
onClick: () => ed.setArmed(null),
|
|
2246
|
+
children: "Cancel"
|
|
2247
|
+
}
|
|
2248
|
+
)
|
|
1952
2249
|
] }),
|
|
1953
2250
|
editText && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "m-0 bg-folder/15 px-4 py-1.5 text-[12.5px] text-ink-2", children: "Edit text: click a line of the document to replace it with an editable copy (same place and size). The uploaded file itself never changes." }),
|
|
1954
2251
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative flex min-h-0 flex-1", children: [
|
|
1955
|
-
!preview && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2252
|
+
!preview && shows("tools") && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1956
2253
|
"aside",
|
|
1957
2254
|
{
|
|
1958
2255
|
className: `w-[170px] flex-none overflow-y-auto border-r border-line bg-white max-lg:absolute max-lg:inset-y-0 max-lg:left-0 max-lg:z-30 max-lg:w-[220px] max-lg:shadow-xl ${drawer === "tools" ? "" : "max-lg:hidden"}`,
|
|
1959
2256
|
children: [
|
|
1960
|
-
/* @__PURE__ */ _jsxruntime.
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
2257
|
+
shows("fieldTools") && ed.fieldTools.length > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
2258
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, PanelHeading2, { children: "FIELDS" }),
|
|
2259
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "m-0 px-3 pt-2 text-[11.5px] text-muted", children: "Drag onto the document, or tap one, then the page" }),
|
|
2260
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "space-y-1 p-2", children: ed.fieldTools.map((k) => toolItem(k, TYPE_LABEL[k.slice(6)])) })
|
|
2261
|
+
] }),
|
|
2262
|
+
shows("layoutTools") && ed.elementTools.length > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
2263
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, PanelHeading2, { children: "LAYOUT" }),
|
|
2264
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "space-y-1 p-2", children: ed.elementTools.map((k) => toolItem(k, _chunk33XWO4KBcjs.ELEMENT_TOOLS[k.slice(8)].label)) })
|
|
2265
|
+
] })
|
|
1967
2266
|
]
|
|
1968
2267
|
}
|
|
1969
2268
|
),
|
|
@@ -1976,7 +2275,7 @@ function FormEditor({
|
|
|
1976
2275
|
},
|
|
1977
2276
|
className: "min-w-0 flex-1 overflow-auto bg-hover",
|
|
1978
2277
|
onPointerDown: () => {
|
|
1979
|
-
if (!preview) setSelection(null);
|
|
2278
|
+
if (!preview) ed.setSelection(null);
|
|
1980
2279
|
setDrawer(null);
|
|
1981
2280
|
},
|
|
1982
2281
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
@@ -1984,12 +2283,9 @@ function FormEditor({
|
|
|
1984
2283
|
{
|
|
1985
2284
|
load: pdfSource,
|
|
1986
2285
|
zoom,
|
|
1987
|
-
pages: _optionalChain([layout, 'optionalAccess',
|
|
2286
|
+
pages: _optionalChain([layout, 'optionalAccess', _78 => _78.pages]),
|
|
1988
2287
|
withText: editText && !preview,
|
|
1989
|
-
onLoaded:
|
|
1990
|
-
setSizes(s);
|
|
1991
|
-
setPdf(doc2);
|
|
1992
|
-
},
|
|
2288
|
+
onLoaded: ed.onPdfLoaded,
|
|
1993
2289
|
onError: () => setLoadError("The document could not be shown"),
|
|
1994
2290
|
overlay: (page, lines) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1995
2291
|
"div",
|
|
@@ -2000,41 +2296,41 @@ function FormEditor({
|
|
|
2000
2296
|
backgroundSize: "2% 2%"
|
|
2001
2297
|
} : void 0,
|
|
2002
2298
|
onDragOver: (e) => !preview && e.preventDefault(),
|
|
2003
|
-
onDrop: (e) =>
|
|
2299
|
+
onDrop: (e) => {
|
|
2300
|
+
const key = e.dataTransfer.getData(DRAG_TYPE);
|
|
2301
|
+
if (ed.placeNew(key, page, e.clientX, e.clientY, e.currentTarget.getBoundingClientRect()))
|
|
2302
|
+
e.preventDefault();
|
|
2303
|
+
},
|
|
2004
2304
|
onClick: (e) => {
|
|
2005
2305
|
if (!armed || preview) return;
|
|
2006
|
-
placeNew(armed, page, e.clientX, e.clientY, e.currentTarget.getBoundingClientRect());
|
|
2007
|
-
setArmed(null);
|
|
2306
|
+
ed.placeNew(armed, page, e.clientX, e.clientY, e.currentTarget.getBoundingClientRect());
|
|
2307
|
+
ed.setArmed(null);
|
|
2008
2308
|
},
|
|
2009
2309
|
children: [
|
|
2010
|
-
_optionalChain([lines, 'optionalAccess',
|
|
2310
|
+
_optionalChain([lines, 'optionalAccess', _79 => _79.map, 'call', _80 => _80((line, i) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2011
2311
|
"button",
|
|
2012
2312
|
{
|
|
2013
2313
|
type: "button",
|
|
2014
2314
|
title: `Edit: ${line.text}`,
|
|
2015
2315
|
className: "absolute cursor-text rounded-[1px] outline-1 outline-folder/60 hover:bg-folder/25 hover:outline-folder",
|
|
2016
|
-
style:
|
|
2316
|
+
style: _chunk33XWO4KBcjs.boxStyle.call(void 0, { page, ...line }),
|
|
2017
2317
|
onPointerDown: (e) => e.stopPropagation(),
|
|
2018
|
-
onClick: () =>
|
|
2019
|
-
const el = _chunk5VHPTLLVcjs.replaceLine.call(void 0, line, page);
|
|
2020
|
-
setElements((l) => [...l, el]);
|
|
2021
|
-
select({ kind: "element", id: el.id });
|
|
2022
|
-
}
|
|
2318
|
+
onClick: () => ed.editLine(line, page)
|
|
2023
2319
|
},
|
|
2024
2320
|
i
|
|
2025
2321
|
))]),
|
|
2026
|
-
_optionalChain([layout, 'optionalAccess',
|
|
2322
|
+
_optionalChain([layout, 'optionalAccess', _81 => _81.elements, 'access', _82 => _82.filter, 'call', _83 => _83((el) => el.page === page), 'access', _84 => _84.map, 'call', _85 => _85(
|
|
2027
2323
|
(el) => preview ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, LayoutElementView, { element: el, pageHeight: pageHeight(page) }, el.id) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2028
2324
|
"div",
|
|
2029
2325
|
{
|
|
2030
2326
|
role: "button",
|
|
2031
2327
|
tabIndex: 0,
|
|
2032
2328
|
"aria-label": `${el.type} ${_nullishCoalesce(el.text, () => ( ""))}`,
|
|
2033
|
-
className: `absolute cursor-move touch-none select-none ${_optionalChain([selection, 'optionalAccess',
|
|
2034
|
-
style:
|
|
2035
|
-
onPointerDown: (e) => startDrag(e, { kind: "element", id: el.id }, { page, ...el.position }, "move"),
|
|
2036
|
-
onPointerMove: onDrag,
|
|
2037
|
-
onPointerUp: endDrag,
|
|
2329
|
+
className: `absolute cursor-move touch-none select-none ${_optionalChain([selection, 'optionalAccess', _86 => _86.id]) === el.id ? "z-10 outline-2 outline-primary" : "hover:outline-1 hover:outline-primary/50"}`,
|
|
2330
|
+
style: _chunk33XWO4KBcjs.boxStyle.call(void 0, { page, ...el.position, height: Math.max(el.position.height, 4e-3) }),
|
|
2331
|
+
onPointerDown: (e) => ed.startDrag(e, { kind: "element", id: el.id }, { page, ...el.position }, "move"),
|
|
2332
|
+
onPointerMove: ed.onDrag,
|
|
2333
|
+
onPointerUp: ed.endDrag,
|
|
2038
2334
|
onClick: (e) => e.stopPropagation(),
|
|
2039
2335
|
children: [
|
|
2040
2336
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
@@ -2045,14 +2341,14 @@ function FormEditor({
|
|
|
2045
2341
|
style: { left: 0, top: 0, width: "100%", height: "100%" }
|
|
2046
2342
|
}
|
|
2047
2343
|
),
|
|
2048
|
-
_optionalChain([selection, 'optionalAccess',
|
|
2344
|
+
_optionalChain([selection, 'optionalAccess', _87 => _87.id]) === el.id && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2049
2345
|
"span",
|
|
2050
2346
|
{
|
|
2051
2347
|
"aria-label": "Resize",
|
|
2052
2348
|
className: "absolute -right-1 -bottom-1 h-2.5 w-2.5 cursor-se-resize rounded-sm border border-white bg-primary",
|
|
2053
|
-
onPointerDown: (e) => startDrag(e, { kind: "element", id: el.id }, { page, ...el.position }, "resize"),
|
|
2054
|
-
onPointerMove: onDrag,
|
|
2055
|
-
onPointerUp: endDrag
|
|
2349
|
+
onPointerDown: (e) => ed.startDrag(e, { kind: "element", id: el.id }, { page, ...el.position }, "resize"),
|
|
2350
|
+
onPointerMove: ed.onDrag,
|
|
2351
|
+
onPointerUp: ed.endDrag
|
|
2056
2352
|
}
|
|
2057
2353
|
)
|
|
2058
2354
|
]
|
|
@@ -2061,14 +2357,15 @@ function FormEditor({
|
|
|
2061
2357
|
)
|
|
2062
2358
|
)]),
|
|
2063
2359
|
fields.filter((f) => f.position.page === page).map(
|
|
2064
|
-
(f) => preview ? _optionalChain([previewStates, 'access',
|
|
2065
|
-
|
|
2360
|
+
(f) => preview ? _optionalChain([previewStates, 'access', _88 => _88[f.key], 'optionalAccess', _89 => _89.visible]) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute [container-type:size]", style: _chunk33XWO4KBcjs.boxStyle.call(void 0, f.position), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2361
|
+
AnswerControl,
|
|
2066
2362
|
{
|
|
2363
|
+
components,
|
|
2067
2364
|
field: f,
|
|
2068
2365
|
value: previewAnswers[f.key],
|
|
2069
2366
|
readOnly: previewStates[f.key].readOnly,
|
|
2070
2367
|
compact,
|
|
2071
|
-
onChange: (v) => setPreviewAnswers((a) => ({ ...a, [f.key]: v }))
|
|
2368
|
+
onChange: (v) => ed.setPreviewAnswers((a) => ({ ...a, [f.key]: v }))
|
|
2072
2369
|
}
|
|
2073
2370
|
) }, f.id) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2074
2371
|
"div",
|
|
@@ -2077,25 +2374,25 @@ function FormEditor({
|
|
|
2077
2374
|
tabIndex: 0,
|
|
2078
2375
|
"aria-label": `${TYPE_LABEL[f.type]} field ${f.label || f.key}`,
|
|
2079
2376
|
title: `${f.label || f.key} (${TYPE_LABEL[f.type]})`,
|
|
2080
|
-
className: `absolute cursor-move touch-none rounded-sm border text-[10px] select-none [container-type:size] ${_optionalChain([selection, 'optionalAccess',
|
|
2081
|
-
style:
|
|
2082
|
-
onPointerDown: (e) => startDrag(e, { kind: "field", id: f.id }, f.position, "move"),
|
|
2083
|
-
onPointerMove: onDrag,
|
|
2084
|
-
onPointerUp: endDrag,
|
|
2377
|
+
className: `absolute cursor-move touch-none rounded-sm border text-[10px] select-none [container-type:size] ${_optionalChain([selection, 'optionalAccess', _90 => _90.id]) === f.id ? "z-10 border-primary bg-primary/20 ring-2 ring-primary/40" : f.source === "ai" ? "border-dashed border-folder bg-folder/15" : "border-primary/60 bg-primary/10 hover:bg-primary/15"}`,
|
|
2378
|
+
style: _chunk33XWO4KBcjs.boxStyle.call(void 0, f.position),
|
|
2379
|
+
onPointerDown: (e) => ed.startDrag(e, { kind: "field", id: f.id }, f.position, "move"),
|
|
2380
|
+
onPointerMove: ed.onDrag,
|
|
2381
|
+
onPointerUp: ed.endDrag,
|
|
2085
2382
|
onClick: (e) => e.stopPropagation(),
|
|
2086
2383
|
children: [
|
|
2087
2384
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "pointer-events-none block truncate px-0.5 text-[clamp(7px,55cqh,12px)] leading-tight text-primary", children: [
|
|
2088
2385
|
f.label || f.key,
|
|
2089
2386
|
f.required && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "b", { className: "text-danger", children: " *" })
|
|
2090
2387
|
] }),
|
|
2091
|
-
_optionalChain([selection, 'optionalAccess',
|
|
2388
|
+
_optionalChain([selection, 'optionalAccess', _91 => _91.id]) === f.id && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2092
2389
|
"span",
|
|
2093
2390
|
{
|
|
2094
2391
|
"aria-label": "Resize",
|
|
2095
2392
|
className: "absolute -right-1 -bottom-1 h-2.5 w-2.5 cursor-se-resize rounded-sm border border-white bg-primary",
|
|
2096
|
-
onPointerDown: (e) => startDrag(e, { kind: "field", id: f.id }, f.position, "resize"),
|
|
2097
|
-
onPointerMove: onDrag,
|
|
2098
|
-
onPointerUp: endDrag
|
|
2393
|
+
onPointerDown: (e) => ed.startDrag(e, { kind: "field", id: f.id }, f.position, "resize"),
|
|
2394
|
+
onPointerMove: ed.onDrag,
|
|
2395
|
+
onPointerUp: ed.endDrag
|
|
2099
2396
|
}
|
|
2100
2397
|
)
|
|
2101
2398
|
]
|
|
@@ -2110,42 +2407,51 @@ function FormEditor({
|
|
|
2110
2407
|
)
|
|
2111
2408
|
}
|
|
2112
2409
|
),
|
|
2113
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2410
|
+
shows("panel") && panelTabs.length > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2114
2411
|
"aside",
|
|
2115
2412
|
{
|
|
2116
2413
|
className: `flex w-[350px] flex-none flex-col border-l border-line bg-white max-lg:absolute max-lg:inset-y-0 max-lg:right-0 max-lg:z-30 max-lg:w-[min(350px,92vw)] max-lg:shadow-xl ${drawer === "panel" ? "" : "max-lg:hidden"}`,
|
|
2117
2414
|
children: [
|
|
2118
2415
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "overflow-x-auto border-b border-line p-2 [&_button]:px-2.5", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2119
|
-
|
|
2416
|
+
SegmentedTabs2,
|
|
2120
2417
|
{
|
|
2121
2418
|
options: [
|
|
2122
2419
|
{ value: "props", label: "Properties" },
|
|
2123
2420
|
{ value: "fields", label: `Fields (${fields.length})` },
|
|
2124
2421
|
{ value: "pages", label: `Pages (${pageCount})` },
|
|
2125
2422
|
...tabs.map((t) => ({ value: t.id, label: t.label }))
|
|
2126
|
-
],
|
|
2423
|
+
].filter((o) => panelTabs.includes(o.value)),
|
|
2127
2424
|
value: tab,
|
|
2128
2425
|
onChange: setTab
|
|
2129
2426
|
}
|
|
2130
2427
|
) }),
|
|
2131
|
-
problems.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "m-0 border-b border-danger/30 bg-danger/5 py-2 pr-3 pl-7 text-[12px] text-danger", children: problems.slice(0, 6).map((p) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { children: p }, p)) }),
|
|
2428
|
+
ed.problems.length > 0 && shows("problems") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "m-0 border-b border-danger/30 bg-danger/5 py-2 pr-3 pl-7 text-[12px] text-danger", children: ed.problems.slice(0, 6).map((p) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { children: p }, p)) }),
|
|
2132
2429
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "min-h-0 flex-1 overflow-y-auto", children: [
|
|
2133
2430
|
tab === "props" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
2134
2431
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2135
|
-
|
|
2432
|
+
PanelHeading2,
|
|
2136
2433
|
{
|
|
2137
2434
|
actions: selection && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
2138
2435
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2139
|
-
|
|
2436
|
+
IconButton2,
|
|
2140
2437
|
{
|
|
2141
2438
|
icon: _lucidereact.Copy,
|
|
2142
2439
|
title: "Duplicate (Ctrl+D)",
|
|
2143
2440
|
light: true,
|
|
2144
2441
|
iconSize: 16,
|
|
2145
|
-
onClick: duplicateSelected
|
|
2442
|
+
onClick: ed.duplicateSelected
|
|
2146
2443
|
}
|
|
2147
2444
|
),
|
|
2148
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2445
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2446
|
+
IconButton2,
|
|
2447
|
+
{
|
|
2448
|
+
icon: _lucidereact.Trash2,
|
|
2449
|
+
title: "Delete (Del)",
|
|
2450
|
+
light: true,
|
|
2451
|
+
iconSize: 16,
|
|
2452
|
+
onClick: ed.removeSelected
|
|
2453
|
+
}
|
|
2454
|
+
)
|
|
2149
2455
|
] }),
|
|
2150
2456
|
children: selectedField ? "FIELD" : selectedElement ? selectedElement.type.toUpperCase() : "PROPERTIES"
|
|
2151
2457
|
}
|
|
@@ -2156,7 +2462,7 @@ function FormEditor({
|
|
|
2156
2462
|
field: selectedField,
|
|
2157
2463
|
fields,
|
|
2158
2464
|
pageCount,
|
|
2159
|
-
onChange: updateField
|
|
2465
|
+
onChange: ed.updateField
|
|
2160
2466
|
},
|
|
2161
2467
|
selectedField.id
|
|
2162
2468
|
) : selectedElement ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
@@ -2164,10 +2470,10 @@ function FormEditor({
|
|
|
2164
2470
|
{
|
|
2165
2471
|
element: selectedElement,
|
|
2166
2472
|
pageCount,
|
|
2167
|
-
onChange: updateElement
|
|
2473
|
+
onChange: ed.updateElement
|
|
2168
2474
|
},
|
|
2169
2475
|
selectedElement.id
|
|
2170
|
-
) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2476
|
+
) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, EmptyText2, { children: [
|
|
2171
2477
|
"Select something on the document, drag a field or layout item in from the left, or use",
|
|
2172
2478
|
" ",
|
|
2173
2479
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "b", { children: "Edit text" }),
|
|
@@ -2175,12 +2481,12 @@ function FormEditor({
|
|
|
2175
2481
|
] })
|
|
2176
2482
|
] }),
|
|
2177
2483
|
tab === "fields" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
2178
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2179
|
-
!fields.length && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2484
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, PanelHeading2, { children: "FILL ORDER" }),
|
|
2485
|
+
!fields.length && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, EmptyText2, { children: "No fields yet." }),
|
|
2180
2486
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ol", { className: "m-0 list-none p-0", children: fields.map((f, i) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2181
2487
|
"li",
|
|
2182
2488
|
{
|
|
2183
|
-
className: `flex items-center gap-1 border-b border-line-soft px-2 py-1 text-[12.5px] ${_optionalChain([selection, 'optionalAccess',
|
|
2489
|
+
className: `flex items-center gap-1 border-b border-line-soft px-2 py-1 text-[12.5px] ${_optionalChain([selection, 'optionalAccess', _92 => _92.id]) === f.id ? "bg-primary-tint" : ""}`,
|
|
2184
2490
|
children: [
|
|
2185
2491
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2186
2492
|
"button",
|
|
@@ -2188,7 +2494,7 @@ function FormEditor({
|
|
|
2188
2494
|
type: "button",
|
|
2189
2495
|
className: "min-w-0 flex-1 cursor-pointer truncate text-left",
|
|
2190
2496
|
onClick: () => {
|
|
2191
|
-
|
|
2497
|
+
ed.setSelection({ kind: "field", id: f.id });
|
|
2192
2498
|
goToPage(f.position.page);
|
|
2193
2499
|
},
|
|
2194
2500
|
children: [
|
|
@@ -2208,23 +2514,23 @@ function FormEditor({
|
|
|
2208
2514
|
}
|
|
2209
2515
|
),
|
|
2210
2516
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2211
|
-
|
|
2517
|
+
IconButton2,
|
|
2212
2518
|
{
|
|
2213
2519
|
icon: _lucidereact.ArrowUp,
|
|
2214
2520
|
title: "Move up",
|
|
2215
2521
|
iconSize: 13,
|
|
2216
2522
|
disabled: i === 0,
|
|
2217
|
-
onClick: () =>
|
|
2523
|
+
onClick: () => ed.reorderField(f.id, -1)
|
|
2218
2524
|
}
|
|
2219
2525
|
),
|
|
2220
2526
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2221
|
-
|
|
2527
|
+
IconButton2,
|
|
2222
2528
|
{
|
|
2223
2529
|
icon: _lucidereact.ArrowDown,
|
|
2224
2530
|
title: "Move down",
|
|
2225
2531
|
iconSize: 13,
|
|
2226
2532
|
disabled: i === fields.length - 1,
|
|
2227
|
-
onClick: () =>
|
|
2533
|
+
onClick: () => ed.reorderField(f.id, 1)
|
|
2228
2534
|
}
|
|
2229
2535
|
)
|
|
2230
2536
|
]
|
|
@@ -2238,19 +2544,19 @@ function FormEditor({
|
|
|
2238
2544
|
pages: layout.pages,
|
|
2239
2545
|
counts,
|
|
2240
2546
|
onGoTo: goToPage,
|
|
2241
|
-
onMove:
|
|
2242
|
-
onInsertBlank:
|
|
2243
|
-
onDelete: (n) => counts[n] ? setConfirmDeletePage(n) :
|
|
2547
|
+
onMove: ed.movePage,
|
|
2548
|
+
onInsertBlank: ed.insertBlankPage,
|
|
2549
|
+
onDelete: (n) => counts[n] ? setConfirmDeletePage(n) : ed.deletePage(n)
|
|
2244
2550
|
}
|
|
2245
|
-
) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2246
|
-
_optionalChain([tabs, 'access',
|
|
2551
|
+
) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, EmptyText2, { children: "Loading pages\u2026" })),
|
|
2552
|
+
_optionalChain([tabs, 'access', _93 => _93.find, 'call', _94 => _94((t) => t.id === tab), 'optionalAccess', _95 => _95.content])
|
|
2247
2553
|
] })
|
|
2248
2554
|
]
|
|
2249
2555
|
}
|
|
2250
2556
|
)
|
|
2251
2557
|
] }),
|
|
2252
2558
|
confirmDeletePage != null && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2253
|
-
|
|
2559
|
+
ConfirmModal2,
|
|
2254
2560
|
{
|
|
2255
2561
|
danger: true,
|
|
2256
2562
|
confirmLabel: "Delete page",
|
|
@@ -2258,8 +2564,7 @@ function FormEditor({
|
|
|
2258
2564
|
onConfirm: () => {
|
|
2259
2565
|
const n = confirmDeletePage;
|
|
2260
2566
|
setConfirmDeletePage(null);
|
|
2261
|
-
|
|
2262
|
-
withDoc((d) => _chunk5VHPTLLVcjs.deletePage.call(void 0, d, n));
|
|
2567
|
+
ed.deletePage(n);
|
|
2263
2568
|
},
|
|
2264
2569
|
children: [
|
|
2265
2570
|
"Delete page ",
|
|
@@ -2270,7 +2575,7 @@ function FormEditor({
|
|
|
2270
2575
|
]
|
|
2271
2576
|
}
|
|
2272
2577
|
)
|
|
2273
|
-
] });
|
|
2578
|
+
] }) });
|
|
2274
2579
|
}
|
|
2275
2580
|
|
|
2276
2581
|
// src/react/FormFiller.tsx
|
|
@@ -2281,145 +2586,75 @@ function FormEditor({
|
|
|
2281
2586
|
|
|
2282
2587
|
|
|
2283
2588
|
|
|
2284
|
-
// src/react/
|
|
2285
|
-
|
|
2589
|
+
// src/react/hooks/useQuestionFilter.ts
|
|
2286
2590
|
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
}) {
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2591
|
+
var defaultFilters = _chunk33XWO4KBcjs.builtinFilters.call(void 0, { type: (t) => TYPE_LABEL[t] });
|
|
2592
|
+
var byId = (id) => {
|
|
2593
|
+
if (id === "tags") return defaultFilters.find((s) => typeof s === "function");
|
|
2594
|
+
return defaultFilters.find((s) => typeof s !== "function" && s.id === id);
|
|
2595
|
+
};
|
|
2596
|
+
function useQuestionFilter(questions, answers, { filters = defaultFilters, search: searchOn = true, initial, predicate, onChange } = {}) {
|
|
2597
|
+
const [values, setValues] = _react.useState.call(void 0, _nullishCoalesce(_optionalChain([initial, 'optionalAccess', _96 => _96.values]), () => ( {})));
|
|
2598
|
+
const [search, setSearchState] = _react.useState.call(void 0, _nullishCoalesce(_optionalChain([initial, 'optionalAccess', _97 => _97.search]), () => ( "")));
|
|
2599
|
+
const [seen, setSeen] = _react.useState.call(void 0, answers);
|
|
2600
|
+
const [version, setVersion] = _react.useState.call(void 0, 0);
|
|
2601
|
+
const update = (nextSearch, nextValues) => {
|
|
2602
|
+
setSearchState(nextSearch);
|
|
2603
|
+
setValues(nextValues);
|
|
2604
|
+
setSeen(answers);
|
|
2605
|
+
setVersion((v) => v + 1);
|
|
2606
|
+
_optionalChain([onChange, 'optionalCall', _98 => _98({ search: nextSearch, values: nextValues })]);
|
|
2607
|
+
};
|
|
2608
|
+
const key = filters.map((f) => typeof f === "string" ? f : typeof f === "function" ? "fn" : f.id).join();
|
|
2609
|
+
const defs = _react.useMemo.call(void 0,
|
|
2610
|
+
() => _chunk33XWO4KBcjs.resolveFilters.call(void 0,
|
|
2611
|
+
filters.map((f) => typeof f === "string" ? byId(f) : f).filter((f) => !!f),
|
|
2612
|
+
questions
|
|
2613
|
+
),
|
|
2614
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- re-resolve when the list's ids change, not on every render
|
|
2615
|
+
[key, questions]
|
|
2311
2616
|
);
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
active: value === o.value,
|
|
2327
|
-
onClick: () => onChange(value === o.value ? null : o.value)
|
|
2328
|
-
},
|
|
2329
|
-
o.value
|
|
2330
|
-
))
|
|
2331
|
-
] });
|
|
2332
|
-
}
|
|
2333
|
-
function RemovableChip({ label, onRemove }) {
|
|
2334
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "inline-flex items-center gap-1 rounded-full bg-primary-tint py-0.5 pr-1 pl-2.5 text-[12px] font-medium text-primary", children: [
|
|
2335
|
-
label,
|
|
2336
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2337
|
-
"button",
|
|
2338
|
-
{
|
|
2339
|
-
type: "button",
|
|
2340
|
-
"aria-label": `Remove ${label}`,
|
|
2341
|
-
onClick: onRemove,
|
|
2342
|
-
className: "inline-flex h-4.5 w-4.5 cursor-pointer items-center justify-center rounded-full hover:bg-primary hover:text-white",
|
|
2343
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.X, { size: 12 })
|
|
2344
|
-
}
|
|
2345
|
-
)
|
|
2346
|
-
] });
|
|
2347
|
-
}
|
|
2348
|
-
|
|
2349
|
-
// src/react/ui/Popover.tsx
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
// src/react/ui/useOutsideClose.ts
|
|
2353
|
-
|
|
2354
|
-
function useOutsideClose(ref, open, onClose) {
|
|
2355
|
-
_react.useEffect.call(void 0, () => {
|
|
2356
|
-
if (!open) return;
|
|
2357
|
-
const onClick = (e) => ref.current && e.composedPath().includes(ref.current) || onClose();
|
|
2358
|
-
const onKey = (e) => e.key === "Escape" && onClose();
|
|
2359
|
-
document.addEventListener("mousedown", onClick);
|
|
2360
|
-
document.addEventListener("keydown", onKey);
|
|
2361
|
-
return () => {
|
|
2362
|
-
document.removeEventListener("mousedown", onClick);
|
|
2363
|
-
document.removeEventListener("keydown", onKey);
|
|
2617
|
+
const list = _react.useMemo.call(void 0, () => {
|
|
2618
|
+
const shown = _chunk33XWO4KBcjs.filterQuestions.call(void 0, questions, seen, defs, values, searchOn ? search : "");
|
|
2619
|
+
return predicate ? shown.filter((q) => predicate(q, seen)) : shown;
|
|
2620
|
+
}, [questions, seen, defs, values, search, searchOn, predicate]);
|
|
2621
|
+
const groups = defs.map((d) => {
|
|
2622
|
+
const options = d.options(questions, answers);
|
|
2623
|
+
return {
|
|
2624
|
+
id: d.id,
|
|
2625
|
+
title: d.title,
|
|
2626
|
+
section: d.section,
|
|
2627
|
+
options,
|
|
2628
|
+
available: options.length > 0,
|
|
2629
|
+
value: _nullishCoalesce(values[d.id], () => ( null)),
|
|
2630
|
+
set: (v) => update(search, { ...values, [d.id]: v })
|
|
2364
2631
|
};
|
|
2365
|
-
}
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
children: [
|
|
2390
|
-
Icon && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Icon, { size: 15 }),
|
|
2391
|
-
label,
|
|
2392
|
-
!!badge && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-full bg-primary px-1 text-[11px] font-bold text-white", children: badge })
|
|
2393
|
-
]
|
|
2394
|
-
}
|
|
2395
|
-
),
|
|
2396
|
-
open && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2397
|
-
"div",
|
|
2398
|
-
{
|
|
2399
|
-
role: "dialog",
|
|
2400
|
-
"aria-label": label,
|
|
2401
|
-
className: `absolute z-30 mt-1.5 w-[min(560px,calc(100vw-24px))] max-sm:fixed max-sm:inset-x-3 max-sm:max-h-[70dvh] max-sm:w-auto max-sm:overflow-y-auto rounded-lg border border-line bg-white p-4 shadow-xl ${align === "right" ? "right-0" : "left-0"}`,
|
|
2402
|
-
children
|
|
2403
|
-
}
|
|
2404
|
-
)
|
|
2405
|
-
] });
|
|
2632
|
+
});
|
|
2633
|
+
const picked = groups.filter((g) => g.value != null);
|
|
2634
|
+
return {
|
|
2635
|
+
groups,
|
|
2636
|
+
/** One group by id (undefined when not in `filters`). */
|
|
2637
|
+
group: (id) => groups.find((g) => g.id === id),
|
|
2638
|
+
/** The search text; null when search is off. */
|
|
2639
|
+
search: searchOn ? search : null,
|
|
2640
|
+
setSearch: (text) => update(text, values),
|
|
2641
|
+
values,
|
|
2642
|
+
/** Filters in use, as chips to take off one by one. */
|
|
2643
|
+
inUse: picked.map((g) => ({
|
|
2644
|
+
id: g.id,
|
|
2645
|
+
label: `${g.title}: ${_nullishCoalesce(_optionalChain([g, 'access', _99 => _99.options, 'access', _100 => _100.find, 'call', _101 => _101((o) => o.value === g.value), 'optionalAccess', _102 => _102.label]), () => ( g.value))}`,
|
|
2646
|
+
clear: () => g.set(null)
|
|
2647
|
+
})),
|
|
2648
|
+
active: !!search || picked.length > 0,
|
|
2649
|
+
clear: () => update("", {}),
|
|
2650
|
+
/** The questions that match, in form order. */
|
|
2651
|
+
list,
|
|
2652
|
+
total: questions.length,
|
|
2653
|
+
/** Bumps on every change (reset paging / scroll on it). */
|
|
2654
|
+
version
|
|
2655
|
+
};
|
|
2406
2656
|
}
|
|
2407
2657
|
|
|
2408
|
-
// src/react/ui/Tag.tsx
|
|
2409
|
-
|
|
2410
|
-
var tones = {
|
|
2411
|
-
success: "bg-success/15 text-success",
|
|
2412
|
-
info: "bg-heading/20 text-primary",
|
|
2413
|
-
muted: "bg-hover text-muted"
|
|
2414
|
-
};
|
|
2415
|
-
var Tag = ({ tone = "info", children }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2416
|
-
"span",
|
|
2417
|
-
{
|
|
2418
|
-
className: `inline-block rounded-full px-2.5 py-0.5 text-[11px] font-semibold whitespace-nowrap ${tones[tone]}`,
|
|
2419
|
-
children
|
|
2420
|
-
}
|
|
2421
|
-
);
|
|
2422
|
-
|
|
2423
2658
|
// src/react/components/QuestionList.tsx
|
|
2424
2659
|
|
|
2425
2660
|
var PAGE = 100;
|
|
@@ -2430,75 +2665,32 @@ var SIZE = {
|
|
|
2430
2665
|
file: "h-9 w-full sm:w-72",
|
|
2431
2666
|
radio: "h-9 w-full"
|
|
2432
2667
|
};
|
|
2433
|
-
var gridSize = (q) => _nullishCoalesce(_optionalChain([q, 'access',
|
|
2668
|
+
var gridSize = (q) => _nullishCoalesce(_optionalChain([q, 'access', _103 => _103.rows, 'optionalAccess', _104 => _104.reduce, 'call', _105 => _105((a, b) => a + b, 0)]), () => ( 0));
|
|
2434
2669
|
var wide = (t) => t === "textarea" || t === "radio" || t === "file";
|
|
2435
2670
|
function QuestionList({
|
|
2436
2671
|
questions,
|
|
2437
2672
|
answers,
|
|
2438
|
-
control
|
|
2673
|
+
control,
|
|
2674
|
+
filter: external,
|
|
2675
|
+
filters,
|
|
2676
|
+
search,
|
|
2677
|
+
hideUnavailable = true,
|
|
2678
|
+
toolbar = true,
|
|
2679
|
+
renderToolbar
|
|
2439
2680
|
}) {
|
|
2440
|
-
const
|
|
2681
|
+
const own = useQuestionFilter(questions, answers, { filters, search });
|
|
2682
|
+
const fs = _nullishCoalesce(external, () => ( own));
|
|
2683
|
+
const { list } = fs;
|
|
2441
2684
|
const [shown, setShown] = _react.useState.call(void 0, PAGE);
|
|
2442
|
-
|
|
2443
|
-
const
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
};
|
|
2448
|
-
const list = _react.useMemo.call(void 0, () => questions.filter((q) => _chunk5VHPTLLVcjs.matches.call(void 0, q, seen, filter)), [questions, seen, filter]);
|
|
2449
|
-
const count = (f) => questions.filter(f).length;
|
|
2450
|
-
const types = _react.useMemo.call(void 0, () => [...new Set(questions.flatMap((q) => q.parts.map((p) => p.field.type)))], [questions]);
|
|
2451
|
-
const categories = _react.useMemo.call(void 0,
|
|
2452
|
-
() => [...new Set(questions.map((q) => q.category).filter((c) => !!c))],
|
|
2453
|
-
[questions]
|
|
2454
|
-
);
|
|
2455
|
-
const tagValues = _react.useMemo.call(void 0, () => {
|
|
2456
|
-
const m = /* @__PURE__ */ new Map();
|
|
2457
|
-
for (const q of questions)
|
|
2458
|
-
for (const [k, v] of Object.entries(_nullishCoalesce(q.tags, () => ( {})))) m.set(k, (_nullishCoalesce(m.get(k), () => ( /* @__PURE__ */ new Set()))).add(v));
|
|
2459
|
-
return [...m].map(
|
|
2460
|
-
([k, vs]) => [k, [...vs].sort((a, b) => a.localeCompare(b, void 0, { numeric: true }))]
|
|
2461
|
-
);
|
|
2462
|
-
}, [questions]);
|
|
2463
|
-
const has = (re) => questions.some((q) => q.parts.some((p) => re.test(p.name) || re.test(p.field.label)));
|
|
2464
|
-
const progress = [
|
|
2465
|
-
["answered", "Answered", "Answered", "Not answered"],
|
|
2466
|
-
["remarks", "Remarks", "Written", "Empty"],
|
|
2467
|
-
["comments", "Comments", "Written", "Empty"]
|
|
2468
|
-
].filter(([key]) => key === "answered" || has(key === "remarks" ? /remark/i : /comment/i));
|
|
2469
|
-
const setTag = (key, value) => {
|
|
2470
|
-
const tags = { ...filter.tags };
|
|
2471
|
-
if (value == null) delete tags[key];
|
|
2472
|
-
else tags[key] = value;
|
|
2473
|
-
set({ tags });
|
|
2474
|
-
};
|
|
2475
|
-
const choiceCount = _react.useMemo.call(void 0, () => {
|
|
2476
|
-
const m = /* @__PURE__ */ new Map();
|
|
2477
|
-
for (const q of questions) for (const c of new Set(_chunk5VHPTLLVcjs.choicesOf.call(void 0, q))) m.set(c, (_nullishCoalesce(m.get(c), () => ( 0))) + 1);
|
|
2478
|
-
return [...m].filter(([, n]) => n >= 2).slice(0, 40);
|
|
2479
|
-
}, [questions]);
|
|
2480
|
-
const [choiceMode, setChoiceMode] = _react.useState.call(void 0, "offered");
|
|
2481
|
-
const choiceValue = choiceMode === "picked" ? filter.picked : filter.choices;
|
|
2482
|
-
const pickedCount = _react.useMemo.call(void 0, () => {
|
|
2483
|
-
const m = /* @__PURE__ */ new Map();
|
|
2484
|
-
for (const q of questions) for (const c of new Set(_chunk5VHPTLLVcjs.pickedOf.call(void 0, q, answers))) m.set(c, (_nullishCoalesce(m.get(c), () => ( 0))) + 1);
|
|
2485
|
-
return m;
|
|
2486
|
-
}, [questions, answers]);
|
|
2487
|
-
const inUse = [
|
|
2488
|
-
...progress.filter(([key]) => filter[key] !== "all").map(([key, title, yes, no]) => ({
|
|
2489
|
-
label: `${title}: ${filter[key] === "filled" ? yes : no}`,
|
|
2490
|
-
clear: () => set({ [key]: "all" })
|
|
2491
|
-
})),
|
|
2492
|
-
...filter.type !== "all" ? [{ label: `Type: ${TYPE_LABEL[filter.type]}`, clear: () => set({ type: "all" }) }] : [],
|
|
2493
|
-
...Object.entries(filter.tags).map(([k, v]) => ({ label: `${k}: ${v}`, clear: () => setTag(k, null) })),
|
|
2494
|
-
...filter.choices !== "all" ? [{ label: `Has option: ${filter.choices}`, clear: () => set({ choices: "all" }) }] : [],
|
|
2495
|
-
...filter.picked !== "all" ? [{ label: `Answered: ${filter.picked}`, clear: () => set({ picked: "all" }) }] : []
|
|
2496
|
-
];
|
|
2497
|
-
const active = JSON.stringify(filter) !== JSON.stringify(_chunk5VHPTLLVcjs.NO_FILTER);
|
|
2685
|
+
_react.useEffect.call(void 0, () => setShown(PAGE), [fs.version]);
|
|
2686
|
+
const groups = fs.groups.filter((g) => g.available || !hideUnavailable);
|
|
2687
|
+
const bar = groups.filter((g) => g.section === "bar");
|
|
2688
|
+
const menu = groups.filter((g) => g.section !== "bar");
|
|
2689
|
+
const sections = [...new Set(menu.map((g) => _nullishCoalesce(g.section, () => ( ""))))];
|
|
2498
2690
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "w-full p-3 sm:p-4 lg:px-6", children: [
|
|
2499
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "sticky top-0 z-10 -mx-3 mb-3 flex flex-col gap-2 border-b border-line bg-white/95 px-3 py-2.5 shadow-sm backdrop-blur sm:-mx-4 sm:px-4 lg:-mx-6 lg:px-6", children: [
|
|
2691
|
+
renderToolbar ? renderToolbar(fs) : toolbar && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "sticky top-0 z-10 -mx-3 mb-3 flex flex-col gap-2 border-b border-line bg-white/95 px-3 py-2.5 shadow-sm backdrop-blur sm:-mx-4 sm:px-4 lg:-mx-6 lg:px-6", children: [
|
|
2500
2692
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
2501
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "label", { className: "relative min-w-0 flex-1 basis-full sm:basis-72", children: [
|
|
2693
|
+
fs.search != null && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "label", { className: "relative min-w-0 flex-1 basis-full sm:basis-72", children: [
|
|
2502
2694
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Search, { size: 15, className: "absolute top-1/2 left-3 -translate-y-1/2 text-muted" }),
|
|
2503
2695
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2504
2696
|
"input",
|
|
@@ -2506,132 +2698,62 @@ function QuestionList({
|
|
|
2506
2698
|
type: "search",
|
|
2507
2699
|
"aria-label": "Search questions",
|
|
2508
2700
|
placeholder: "Search questions, sections, answers\u2026",
|
|
2509
|
-
value:
|
|
2510
|
-
onChange: (e) =>
|
|
2701
|
+
value: fs.search,
|
|
2702
|
+
onChange: (e) => fs.setSearch(e.target.value),
|
|
2511
2703
|
className: "w-full rounded-full border border-line-strong bg-surface py-1.5 pr-3 pl-9 text-[13px] outline-none focus:border-primary focus:bg-white max-sm:text-base"
|
|
2512
2704
|
}
|
|
2513
2705
|
)
|
|
2514
2706
|
] }),
|
|
2515
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
]
|
|
2526
|
-
},
|
|
2527
|
-
key
|
|
2528
|
-
)) }),
|
|
2529
|
-
choiceCount.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2530
|
-
FilterSection,
|
|
2531
|
-
{
|
|
2532
|
-
title: "Answers",
|
|
2533
|
-
action: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2534
|
-
SegmentedTabs,
|
|
2535
|
-
{
|
|
2536
|
-
size: "sm",
|
|
2537
|
-
value: choiceMode,
|
|
2538
|
-
onChange: (m) => {
|
|
2539
|
-
setChoiceMode(m);
|
|
2540
|
-
const c = filter.choices !== "all" ? filter.choices : filter.picked;
|
|
2541
|
-
if (c !== "all")
|
|
2542
|
-
set(m === "picked" ? { picked: c, choices: "all" } : { choices: c, picked: "all" });
|
|
2543
|
-
},
|
|
2544
|
-
options: [
|
|
2545
|
-
{ value: "offered", label: "Has option" },
|
|
2546
|
-
{ value: "picked", label: "Answered" }
|
|
2547
|
-
]
|
|
2548
|
-
}
|
|
2549
|
-
),
|
|
2550
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2551
|
-
ChipGroup,
|
|
2552
|
-
{
|
|
2553
|
-
value: choiceValue === "all" ? null : choiceValue,
|
|
2554
|
-
onChange: (v) => set(choiceMode === "picked" ? { picked: _nullishCoalesce(v, () => ( "all")) } : { choices: _nullishCoalesce(v, () => ( "all")) }),
|
|
2555
|
-
options: choiceCount.map(([c, n]) => ({
|
|
2556
|
-
value: c,
|
|
2557
|
-
label: c,
|
|
2558
|
-
count: choiceMode === "picked" ? _nullishCoalesce(pickedCount.get(c), () => ( 0)) : n
|
|
2559
|
-
}))
|
|
2560
|
-
}
|
|
2561
|
-
)
|
|
2562
|
-
}
|
|
2563
|
-
),
|
|
2564
|
-
tagValues.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FilterSection, { title: "Question details", children: tagValues.map(([key, values]) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2565
|
-
ChipGroup,
|
|
2566
|
-
{
|
|
2567
|
-
title: key,
|
|
2568
|
-
value: _nullishCoalesce(filter.tags[key], () => ( null)),
|
|
2569
|
-
onChange: (v) => setTag(key, v),
|
|
2570
|
-
options: values.map((v) => ({ value: v, label: v, count: count((q) => _optionalChain([q, 'access', _88 => _88.tags, 'optionalAccess', _89 => _89[key]]) === v) }))
|
|
2571
|
-
},
|
|
2572
|
-
key
|
|
2573
|
-
)) }),
|
|
2574
|
-
types.length > 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FilterSection, { title: "Answer type", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2575
|
-
ChipGroup,
|
|
2576
|
-
{
|
|
2577
|
-
value: filter.type === "all" ? null : filter.type,
|
|
2578
|
-
onChange: (v) => set({ type: _nullishCoalesce(v, () => ( "all")) }),
|
|
2579
|
-
options: types.map((t) => ({
|
|
2580
|
-
value: t,
|
|
2581
|
-
label: TYPE_LABEL[t],
|
|
2582
|
-
count: count((q) => q.parts.some((p) => p.field.type === t))
|
|
2583
|
-
}))
|
|
2584
|
-
}
|
|
2585
|
-
) })
|
|
2586
|
-
] }) }),
|
|
2707
|
+
menu.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Popover2, { label: "Filters", icon: _lucidereact.SlidersHorizontal, badge: fs.inUse.length, align: "right", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex flex-col gap-4", children: sections.map((sec) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FilterSection, { title: sec, children: menu.filter((g) => (_nullishCoalesce(g.section, () => ( ""))) === sec).map((g) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2708
|
+
ChipGroup2,
|
|
2709
|
+
{
|
|
2710
|
+
title: g.title,
|
|
2711
|
+
value: g.value,
|
|
2712
|
+
onChange: g.set,
|
|
2713
|
+
options: g.options
|
|
2714
|
+
},
|
|
2715
|
+
g.id
|
|
2716
|
+
)) }, sec)) }) }),
|
|
2587
2717
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "text-[12.5px] text-muted sm:ml-auto", "aria-live": "polite", children: [
|
|
2588
2718
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "b", { className: "font-semibold text-ink-2", children: list.length }),
|
|
2589
2719
|
" of ",
|
|
2590
|
-
|
|
2720
|
+
fs.total,
|
|
2591
2721
|
" questions"
|
|
2592
2722
|
] }),
|
|
2593
|
-
active && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2723
|
+
fs.active && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button2, { variant: "secondary", size: "sm", onClick: fs.clear, children: "Clear all" })
|
|
2594
2724
|
] }),
|
|
2595
|
-
|
|
2596
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "mr-1 text-[11.5px] font-semibold tracking-wide text-muted uppercase", children:
|
|
2597
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
label: "All",
|
|
2601
|
-
count: questions.length,
|
|
2602
|
-
active: filter.category === "all",
|
|
2603
|
-
onClick: () => set({ category: "all" })
|
|
2604
|
-
}
|
|
2605
|
-
),
|
|
2606
|
-
categories.map((c) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2607
|
-
Chip,
|
|
2725
|
+
bar.map((g) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { role: "group", "aria-label": g.title, className: "flex flex-wrap items-center gap-1.5", children: [
|
|
2726
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "mr-1 text-[11.5px] font-semibold tracking-wide text-muted uppercase", children: g.title }),
|
|
2727
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, Chip2, { label: "All", count: fs.total, active: g.value == null, onClick: () => g.set(null) }),
|
|
2728
|
+
g.options.map((o) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2729
|
+
Chip2,
|
|
2608
2730
|
{
|
|
2609
|
-
label:
|
|
2610
|
-
count: count
|
|
2611
|
-
active:
|
|
2612
|
-
onClick: () => set(
|
|
2731
|
+
label: o.label,
|
|
2732
|
+
count: o.count,
|
|
2733
|
+
active: g.value === o.value,
|
|
2734
|
+
onClick: () => g.set(g.value === o.value ? null : o.value)
|
|
2613
2735
|
},
|
|
2614
|
-
|
|
2736
|
+
o.value
|
|
2615
2737
|
))
|
|
2616
|
-
] }),
|
|
2617
|
-
inUse.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex flex-wrap items-center gap-1.5", children: inUse.map((f) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2738
|
+
] }, g.id)),
|
|
2739
|
+
fs.inUse.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex flex-wrap items-center gap-1.5", children: fs.inUse.map((f) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, RemovableChip2, { label: f.label, onRemove: f.clear }, f.id)) })
|
|
2618
2740
|
] }),
|
|
2619
|
-
list.length === 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2741
|
+
list.length === 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, EmptyText2, { children: "No question matches these filters." }),
|
|
2620
2742
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "m-0 flex list-none flex-col gap-2 p-0", children: list.slice(0, shown).map((q, i, all) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _react.Fragment, { children: [
|
|
2621
|
-
q.section && q.section !== _optionalChain([all, 'access',
|
|
2743
|
+
q.section && q.section !== _optionalChain([all, 'access', _106 => _106[i - 1], 'optionalAccess', _107 => _107.section]) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "li", { className: "mt-2 flex flex-wrap items-center gap-x-2 gap-y-1 border-b border-line pb-1", children: [
|
|
2622
2744
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-[13.5px] font-semibold text-primary lg:text-[15px]", children: q.section }),
|
|
2623
|
-
Object.entries(_nullishCoalesce(q.tags, () => ( {}))).map(([k, v]) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2745
|
+
Object.entries(_nullishCoalesce(q.tags, () => ( {}))).map(([k, v]) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Tag2, { tone: "muted", children: [
|
|
2624
2746
|
k,
|
|
2625
2747
|
": ",
|
|
2626
2748
|
v
|
|
2627
2749
|
] }, k))
|
|
2628
2750
|
] }),
|
|
2629
|
-
q.intro && (q.intro !== _optionalChain([all, 'access',
|
|
2751
|
+
q.intro && (q.intro !== _optionalChain([all, 'access', _108 => _108[i - 1], 'optionalAccess', _109 => _109.intro]) || q.section !== _optionalChain([all, 'access', _110 => _110[i - 1], 'optionalAccess', _111 => _111.section])) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { className: "rounded-md border-l-4 border-primary bg-primary-soft px-3 py-2 text-[13px] font-medium text-ink-2 lg:text-[14px]", children: q.intro }),
|
|
2630
2752
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "li", { className: "rounded-lg border border-line bg-white p-3", children: [
|
|
2631
2753
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mb-2 flex items-start gap-2", children: [
|
|
2632
2754
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "m-0 min-w-0 flex-1 text-[13.5px] font-semibold whitespace-pre-line text-ink-2 lg:text-[15px]", children: q.title }),
|
|
2633
|
-
q.category && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2634
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2755
|
+
q.category && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Tag2, { tone: "muted", children: q.category }),
|
|
2756
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Tag2, { tone: "muted", children: [
|
|
2635
2757
|
"p.",
|
|
2636
2758
|
q.page
|
|
2637
2759
|
] })
|
|
@@ -2658,7 +2780,7 @@ function QuestionList({
|
|
|
2658
2780
|
] })
|
|
2659
2781
|
] })
|
|
2660
2782
|
] }, q.id)) }),
|
|
2661
|
-
list.length > shown && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "mt-3 text-center", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2783
|
+
list.length > shown && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "mt-3 text-center", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Button2, { variant: "secondary", size: "sm", onClick: () => setShown((n) => n + PAGE), children: [
|
|
2662
2784
|
"Show more (",
|
|
2663
2785
|
list.length - shown,
|
|
2664
2786
|
" left)"
|
|
@@ -2686,7 +2808,7 @@ function OptionGrid({
|
|
|
2686
2808
|
"span",
|
|
2687
2809
|
{
|
|
2688
2810
|
className: "min-w-0 cursor-pointer break-words",
|
|
2689
|
-
onClick: (e) => _optionalChain([e, 'access',
|
|
2811
|
+
onClick: (e) => _optionalChain([e, 'access', _112 => _112.currentTarget, 'access', _113 => _113.parentElement, 'optionalAccess', _114 => _114.querySelector, 'call', _115 => _115("input"), 'optionalAccess', _116 => _116.click, 'call', _117 => _117()]),
|
|
2690
2812
|
children: name
|
|
2691
2813
|
}
|
|
2692
2814
|
)
|
|
@@ -2733,18 +2855,8 @@ function FilterSection({ title, action, children }) {
|
|
|
2733
2855
|
] });
|
|
2734
2856
|
}
|
|
2735
2857
|
|
|
2736
|
-
// src/react/
|
|
2858
|
+
// src/react/hooks/useFormFiller.ts
|
|
2737
2859
|
|
|
2738
|
-
var humanSize = (n) => {
|
|
2739
|
-
if (!n) return "";
|
|
2740
|
-
const units = ["B", "KB", "MB", "GB"];
|
|
2741
|
-
let i = 0;
|
|
2742
|
-
while (n >= 1024 && i < units.length - 1) {
|
|
2743
|
-
n /= 1024;
|
|
2744
|
-
i++;
|
|
2745
|
-
}
|
|
2746
|
-
return `${n.toFixed(i ? 1 : 0)} ${units[i]}`;
|
|
2747
|
-
};
|
|
2748
2860
|
function download(blob, name) {
|
|
2749
2861
|
const url = URL.createObjectURL(blob);
|
|
2750
2862
|
const a = document.createElement("a");
|
|
@@ -2753,11 +2865,9 @@ function download(blob, name) {
|
|
|
2753
2865
|
a.click();
|
|
2754
2866
|
setTimeout(() => URL.revokeObjectURL(url), 1e3);
|
|
2755
2867
|
}
|
|
2756
|
-
function
|
|
2757
|
-
pdf: pdfSource,
|
|
2868
|
+
function useFormFiller({
|
|
2758
2869
|
fields,
|
|
2759
2870
|
layout = null,
|
|
2760
|
-
title,
|
|
2761
2871
|
initialAnswers,
|
|
2762
2872
|
files: initialFiles = [],
|
|
2763
2873
|
readOnly = false,
|
|
@@ -2766,61 +2876,54 @@ function FormFiller({
|
|
|
2766
2876
|
autosave = 2500,
|
|
2767
2877
|
onUpload,
|
|
2768
2878
|
loadFile,
|
|
2769
|
-
|
|
2770
|
-
toolbar,
|
|
2879
|
+
toQuestions: toQuestions2 = _chunk33XWO4KBcjs.toQuestions,
|
|
2771
2880
|
notify = () => {
|
|
2772
2881
|
},
|
|
2773
|
-
onError: notifyError = (e) => console.error(e)
|
|
2774
|
-
className = "h-full"
|
|
2882
|
+
onError: notifyError = (e) => console.error(e)
|
|
2775
2883
|
}) {
|
|
2776
2884
|
const [answers, setAnswers] = _react.useState.call(void 0, () => _nullishCoalesce(initialAnswers, () => ( _chunk7NZPYWL3cjs.defaultAnswers.call(void 0, fields))));
|
|
2777
2885
|
const [files, setFiles] = _react.useState.call(void 0, initialFiles);
|
|
2778
2886
|
const [signatures, setSignatures] = _react.useState.call(void 0, {});
|
|
2779
2887
|
const [errors, setErrors] = _react.useState.call(void 0, {});
|
|
2780
|
-
const [pdfWidth, setPdfWidth] = _react.useState.call(void 0, 595);
|
|
2781
|
-
const pageWidth = Math.max(..._nullishCoalesce(_optionalChain([layout, 'optionalAccess', _102 => _102.pages, 'access', _103 => _103.map, 'call', _104 => _104((p) => p.width)]), () => ( [pdfWidth])));
|
|
2782
|
-
const { zoom, setZoom, ref: fitRef } = useFitZoom(pageWidth);
|
|
2783
|
-
const compact = useCompact();
|
|
2784
2888
|
const [saveState, setSaveState] = _react.useState.call(void 0, "saved");
|
|
2785
2889
|
const [hasSaved, setHasSaved] = _react.useState.call(void 0, !!initialAnswers);
|
|
2786
|
-
const [
|
|
2787
|
-
const [
|
|
2890
|
+
const [pdf, setPdf] = _react.useState.call(void 0, null);
|
|
2891
|
+
const [pdfSizes, setPdfSizes] = _react.useState.call(void 0, []);
|
|
2788
2892
|
const queue = _react.useRef.call(void 0, Promise.resolve());
|
|
2789
2893
|
const latest = _react.useRef.call(void 0, answers);
|
|
2790
2894
|
_react.useEffect.call(void 0, () => {
|
|
2791
2895
|
latest.current = answers;
|
|
2792
2896
|
}, [answers]);
|
|
2793
2897
|
const states = _react.useMemo.call(void 0, () => _chunk7NZPYWL3cjs.fieldStates.call(void 0, fields, answers), [fields, answers]);
|
|
2794
|
-
const [
|
|
2795
|
-
const [pdf, setPdf] = _react.useState.call(void 0, null);
|
|
2898
|
+
const [wantText, setWantText] = _react.useState.call(void 0, false);
|
|
2796
2899
|
const [pageText, setPageText] = _react.useState.call(void 0, null);
|
|
2797
2900
|
_react.useEffect.call(void 0, () => {
|
|
2798
|
-
if (
|
|
2901
|
+
if (!wantText || !pdf || pageText) return;
|
|
2799
2902
|
let live = true;
|
|
2800
2903
|
(async () => {
|
|
2801
2904
|
const out = {};
|
|
2802
2905
|
for (let i = 1; i <= pdf.numPages; i++) {
|
|
2803
2906
|
const page = await pdf.getPage(i);
|
|
2804
|
-
out[i] =
|
|
2907
|
+
out[i] = _chunk33XWO4KBcjs.toLines.call(void 0, (await page.getTextContent()).items, page.view);
|
|
2805
2908
|
}
|
|
2806
2909
|
if (live) setPageText(out);
|
|
2807
2910
|
})().catch(() => live && setPageText({}));
|
|
2808
2911
|
return () => {
|
|
2809
2912
|
live = false;
|
|
2810
2913
|
};
|
|
2811
|
-
}, [
|
|
2812
|
-
const visibleKeys = fields.filter((f) => _optionalChain([states, 'access',
|
|
2914
|
+
}, [wantText, pdf, pageText]);
|
|
2915
|
+
const visibleKeys = fields.filter((f) => _optionalChain([states, 'access', _118 => _118[f.key], 'optionalAccess', _119 => _119.visible])).map((f) => f.key).join(",");
|
|
2813
2916
|
const questions = _react.useMemo.call(void 0, () => {
|
|
2814
2917
|
const keys = new Set(visibleKeys.split(","));
|
|
2815
2918
|
const textOf = (page) => {
|
|
2816
|
-
const source = layout ? _optionalChain([layout, 'access',
|
|
2817
|
-
return source ? _optionalChain([pageText, 'optionalAccess',
|
|
2919
|
+
const source = layout ? _optionalChain([layout, 'access', _120 => _120.pages, 'access', _121 => _121[page - 1], 'optionalAccess', _122 => _122.source]) : page;
|
|
2920
|
+
return source ? _optionalChain([pageText, 'optionalAccess', _123 => _123[source]]) : void 0;
|
|
2818
2921
|
};
|
|
2819
|
-
return
|
|
2922
|
+
return toQuestions2(
|
|
2820
2923
|
fields.filter((f) => keys.has(f.key)),
|
|
2821
2924
|
textOf
|
|
2822
2925
|
);
|
|
2823
|
-
}, [fields, layout, visibleKeys, pageText]);
|
|
2926
|
+
}, [fields, layout, visibleKeys, pageText, toQuestions2]);
|
|
2824
2927
|
const loading = _react.useRef.call(void 0, /* @__PURE__ */ new Set());
|
|
2825
2928
|
_react.useEffect.call(void 0, () => {
|
|
2826
2929
|
if (!loadFile) return;
|
|
@@ -2849,7 +2952,7 @@ function FormFiller({
|
|
|
2849
2952
|
return true;
|
|
2850
2953
|
} catch (err) {
|
|
2851
2954
|
setSaveState("error");
|
|
2852
|
-
const fieldErrors = _optionalChain([err, 'optionalAccess',
|
|
2955
|
+
const fieldErrors = _optionalChain([err, 'optionalAccess', _124 => _124.errors]);
|
|
2853
2956
|
if (fieldErrors && typeof fieldErrors === "object") setErrors(fieldErrors);
|
|
2854
2957
|
notifyError(err);
|
|
2855
2958
|
return false;
|
|
@@ -2869,7 +2972,7 @@ function FormFiller({
|
|
|
2869
2972
|
setAnswers((a) => ({ ...a, [f.key]: v }));
|
|
2870
2973
|
setSaveState("dirty");
|
|
2871
2974
|
if (errors[f.key]) {
|
|
2872
|
-
const err = _chunk7NZPYWL3cjs.checkAnswer.call(void 0, f, v, _optionalChain([states, 'access',
|
|
2975
|
+
const err = _chunk7NZPYWL3cjs.checkAnswer.call(void 0, f, v, _optionalChain([states, 'access', _125 => _125[f.key], 'optionalAccess', _126 => _126.required]));
|
|
2873
2976
|
setErrors((all) => {
|
|
2874
2977
|
const rest = { ...all };
|
|
2875
2978
|
delete rest[f.key];
|
|
@@ -2888,88 +2991,171 @@ function FormFiller({
|
|
|
2888
2991
|
notifyError(err);
|
|
2889
2992
|
}
|
|
2890
2993
|
}
|
|
2891
|
-
const fetchFile = (id, then) => _optionalChain([loadFile, 'optionalCall',
|
|
2994
|
+
const fetchFile = (id, then) => _optionalChain([loadFile, 'optionalCall', _127 => _127(id), 'access', _128 => _128.then, 'call', _129 => _129(then, () => notifyError("Unable to open the file"))]);
|
|
2995
|
+
const openFile = (id) => fetchFile(id, (blob) => {
|
|
2996
|
+
const url = URL.createObjectURL(blob);
|
|
2997
|
+
window.open(url, "_blank");
|
|
2998
|
+
setTimeout(() => URL.revokeObjectURL(url), 6e4);
|
|
2999
|
+
});
|
|
3000
|
+
const downloadFile = (id, name) => fetchFile(id, (blob) => download(blob, name));
|
|
2892
3001
|
async function submit() {
|
|
2893
|
-
setConfirmSubmit(false);
|
|
2894
3002
|
const found = _chunk7NZPYWL3cjs.validateAnswers.call(void 0, fields, answers);
|
|
2895
3003
|
setErrors(found);
|
|
2896
|
-
if (Object.keys(found).length)
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
_optionalChain([onSubmitted, 'optionalCall', _117 => _117(latest.current)]);
|
|
3004
|
+
if (Object.keys(found).length) {
|
|
3005
|
+
notifyError("Some answers need attention");
|
|
3006
|
+
return false;
|
|
2900
3007
|
}
|
|
3008
|
+
if (!await save(true)) return false;
|
|
3009
|
+
notify("Submitted");
|
|
3010
|
+
_optionalChain([onSubmitted, 'optionalCall', _130 => _130(latest.current)]);
|
|
3011
|
+
return true;
|
|
2901
3012
|
}
|
|
2902
|
-
if (loadError) return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "fl-root p-6 text-center text-sm text-danger", children: loadError });
|
|
2903
3013
|
const fileOf = (id) => files.find((x) => x.id === id);
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
3014
|
+
return {
|
|
3015
|
+
answers,
|
|
3016
|
+
/** Visible / required / readOnly per field key, from the conditions and current answers. */
|
|
3017
|
+
states,
|
|
3018
|
+
/** Field key → message. */
|
|
3019
|
+
errors,
|
|
3020
|
+
setErrors,
|
|
3021
|
+
/** Fields with an error, in form order. */
|
|
3022
|
+
errorList: fields.filter((f) => errors[f.key]),
|
|
3023
|
+
change,
|
|
3024
|
+
save,
|
|
3025
|
+
submit,
|
|
3026
|
+
saveState,
|
|
3027
|
+
hasSaved,
|
|
3028
|
+
readOnly,
|
|
3029
|
+
files,
|
|
3030
|
+
fileOf,
|
|
3031
|
+
/** Files of upload fields that are answers now. */
|
|
3032
|
+
attachments: files.filter(
|
|
3033
|
+
(x) => fields.some((f) => f.type === "file" && f.key === x.fieldKey && answers[f.key] === x.id)
|
|
3034
|
+
),
|
|
3035
|
+
attach,
|
|
3036
|
+
canUpload: !!onUpload,
|
|
3037
|
+
canLoadFiles: !!loadFile,
|
|
3038
|
+
openFile,
|
|
3039
|
+
downloadFile,
|
|
3040
|
+
/** Image src of a signature answer (stored file or data URL). */
|
|
3041
|
+
signatureSrc: (f) => signatures[String(answers[f.key])],
|
|
3042
|
+
/** Visible fields grouped as questions (tables, option groups), titled from the PDF text once loaded. */
|
|
3043
|
+
questions,
|
|
3044
|
+
/** Reads the PDF text so `questions` get real titles (call when you first show them). */
|
|
3045
|
+
loadPageText: () => setWantText(true),
|
|
3046
|
+
pdf,
|
|
3047
|
+
pdfSizes,
|
|
3048
|
+
/** Pass to PdfPages' onLoaded. */
|
|
3049
|
+
onPdfLoaded: (sizes2, doc) => {
|
|
3050
|
+
setPdf(doc);
|
|
3051
|
+
setPdfSizes(sizes2);
|
|
3052
|
+
}
|
|
3053
|
+
};
|
|
3054
|
+
}
|
|
3055
|
+
|
|
3056
|
+
// src/react/FormFiller.tsx
|
|
3057
|
+
|
|
3058
|
+
var humanSize = (n) => {
|
|
3059
|
+
if (!n) return "";
|
|
3060
|
+
const units = ["B", "KB", "MB", "GB"];
|
|
3061
|
+
let i = 0;
|
|
3062
|
+
while (n >= 1024 && i < units.length - 1) {
|
|
3063
|
+
n /= 1024;
|
|
3064
|
+
i++;
|
|
3065
|
+
}
|
|
3066
|
+
return `${n.toFixed(i ? 1 : 0)} ${units[i]}`;
|
|
3067
|
+
};
|
|
3068
|
+
function FormFiller({
|
|
3069
|
+
pdf: pdfSource,
|
|
3070
|
+
title,
|
|
3071
|
+
onBack,
|
|
3072
|
+
toolbar,
|
|
3073
|
+
components,
|
|
3074
|
+
hide = [],
|
|
3075
|
+
views = ["document", "list"],
|
|
3076
|
+
listFilters,
|
|
3077
|
+
listSearch,
|
|
3078
|
+
hideUnavailableFilters,
|
|
3079
|
+
renderFilters,
|
|
3080
|
+
confirmSubmit: askFirst = true,
|
|
3081
|
+
className = "h-full",
|
|
3082
|
+
...options
|
|
3083
|
+
}) {
|
|
3084
|
+
const shows = (p) => !hide.includes(p);
|
|
3085
|
+
const ff = useFormFiller(options);
|
|
3086
|
+
const { fields, readOnly = false, onSave } = options;
|
|
3087
|
+
const layout = _nullishCoalesce(options.layout, () => ( null));
|
|
3088
|
+
const { answers, states, errors } = ff;
|
|
3089
|
+
const pdfWidth = ff.pdfSizes.length ? Math.max(...ff.pdfSizes.map((p) => p.width)) : 595;
|
|
3090
|
+
const { zoom, setZoom, ref: fitRef } = useFitZoom(Math.max(..._nullishCoalesce(_optionalChain([layout, 'optionalAccess', _131 => _131.pages, 'access', _132 => _132.map, 'call', _133 => _133((p) => p.width)]), () => ( [pdfWidth]))));
|
|
3091
|
+
const compact = useCompact();
|
|
3092
|
+
const [confirmSubmit, setConfirmSubmit] = _react.useState.call(void 0, false);
|
|
3093
|
+
const [loadError, setLoadError] = _react.useState.call(void 0, "");
|
|
3094
|
+
const [view, setView] = _react.useState.call(void 0, _nullishCoalesce(views[0], () => ( "document")));
|
|
3095
|
+
const { loadPageText } = ff;
|
|
3096
|
+
_react.useEffect.call(void 0, () => {
|
|
3097
|
+
if (view === "list") loadPageText();
|
|
3098
|
+
}, [view, loadPageText]);
|
|
3099
|
+
if (loadError) return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "fl-root p-6 text-center text-sm text-danger", children: loadError });
|
|
2908
3100
|
const control = (f) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
2909
3101
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2910
|
-
|
|
3102
|
+
AnswerControl,
|
|
2911
3103
|
{
|
|
3104
|
+
components,
|
|
2912
3105
|
field: f,
|
|
2913
3106
|
value: answers[f.key],
|
|
2914
|
-
readOnly: readOnly || states[f.key].readOnly || f.type === "file" && !
|
|
3107
|
+
readOnly: readOnly || states[f.key].readOnly || f.type === "file" && !ff.canUpload,
|
|
2915
3108
|
compact,
|
|
2916
3109
|
error: errors[f.key],
|
|
2917
|
-
onChange: (v) => change(f, v),
|
|
2918
|
-
fileName: _optionalChain([fileOf, 'call',
|
|
2919
|
-
signatureSrc:
|
|
2920
|
-
onFile:
|
|
2921
|
-
onOpenFile: () =>
|
|
2922
|
-
const url = URL.createObjectURL(blob);
|
|
2923
|
-
window.open(url, "_blank");
|
|
2924
|
-
setTimeout(() => URL.revokeObjectURL(url), 6e4);
|
|
2925
|
-
})
|
|
3110
|
+
onChange: (v) => ff.change(f, v),
|
|
3111
|
+
fileName: _optionalChain([ff, 'access', _134 => _134.fileOf, 'call', _135 => _135(answers[f.key]), 'optionalAccess', _136 => _136.fileName]),
|
|
3112
|
+
signatureSrc: ff.signatureSrc(f),
|
|
3113
|
+
onFile: ff.canUpload ? (file) => void ff.attach(f, file) : void 0,
|
|
3114
|
+
onOpenFile: () => ff.openFile(String(answers[f.key]))
|
|
2926
3115
|
}
|
|
2927
3116
|
),
|
|
2928
|
-
states[f.key].required && !readOnly && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "pointer-events-none absolute -top-1.5 -right-1.5 text-[12px] font-bold text-danger", children: "*" })
|
|
3117
|
+
states[f.key].required && !readOnly && shows("requiredMark") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "pointer-events-none absolute -top-1.5 -right-1.5 text-[12px] font-bold text-danger", children: "*" })
|
|
2929
3118
|
] });
|
|
2930
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: `fl-root flex min-h-[min(600px,100dvh)] flex-col bg-white text-ink ${className}`, children: [
|
|
3119
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormliftProvider, { components, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: `fl-root flex min-h-[min(600px,100dvh)] flex-col bg-white text-ink ${className}`, children: [
|
|
2931
3120
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-wrap items-center gap-3 border-b border-line bg-white px-4 py-2.5", children: [
|
|
2932
|
-
onBack && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2933
|
-
title != null && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "m-0 min-w-0 flex-1 truncate text-[17px] font-semibold max-sm:text-[15px] sm:flex-none", children: title }),
|
|
2934
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2935
|
-
|
|
3121
|
+
onBack && shows("back") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button2, { variant: "secondary", size: "sm", icon: _lucidereact.ArrowLeft, onClick: onBack, children: "Back" }),
|
|
3122
|
+
title != null && shows("title") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "m-0 min-w-0 flex-1 truncate text-[17px] font-semibold max-sm:text-[15px] sm:flex-none", children: title }),
|
|
3123
|
+
views.length > 1 && shows("views") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3124
|
+
SegmentedTabs2,
|
|
2936
3125
|
{
|
|
2937
|
-
options:
|
|
2938
|
-
{ value: "document", label: "Document" },
|
|
2939
|
-
{ value: "list", label: "List" }
|
|
2940
|
-
],
|
|
3126
|
+
options: views.map((v) => ({ value: v, label: v === "document" ? "Document" : "List" })),
|
|
2941
3127
|
value: view,
|
|
2942
3128
|
onChange: setView
|
|
2943
3129
|
}
|
|
2944
3130
|
),
|
|
2945
3131
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "ml-auto flex flex-wrap items-center gap-2 max-sm:w-full max-sm:justify-end", children: [
|
|
2946
|
-
view === "document" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ZoomControls, { zoom, onChange: setZoom }),
|
|
3132
|
+
view === "document" && shows("zoom") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ZoomControls, { zoom, onChange: setZoom }),
|
|
2947
3133
|
!readOnly && onSave && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
2948
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-right text-[12px] text-muted sm:w-24", "aria-live": "polite", children: {
|
|
2949
|
-
saved: hasSaved ? "Draft saved" : "",
|
|
3134
|
+
shows("saveStatus") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-right text-[12px] text-muted sm:w-24", "aria-live": "polite", children: {
|
|
3135
|
+
saved: ff.hasSaved ? "Draft saved" : "",
|
|
2950
3136
|
dirty: "Unsaved",
|
|
2951
3137
|
saving: "Saving\u2026",
|
|
2952
3138
|
error: "Not saved"
|
|
2953
|
-
}[saveState] }),
|
|
2954
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2955
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3139
|
+
}[ff.saveState] }),
|
|
3140
|
+
shows("saveDraft") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button2, { variant: "secondary", size: "sm", icon: _lucidereact.Save, title: "Save draft", onClick: () => void ff.save(), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "max-sm:hidden", children: "Save draft" }) }),
|
|
3141
|
+
shows("submit") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button2, { size: "sm", icon: _lucidereact.Send, onClick: () => askFirst ? setConfirmSubmit(true) : void ff.submit(), children: "Submit" })
|
|
2956
3142
|
] }),
|
|
2957
3143
|
toolbar
|
|
2958
3144
|
] })
|
|
2959
3145
|
] }),
|
|
2960
|
-
attachments.length > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1 border-b border-line bg-white px-4 py-1.5 text-[12.5px]", children: [
|
|
3146
|
+
ff.attachments.length > 0 && shows("attachments") && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-wrap items-center gap-x-3 gap-y-1 border-b border-line bg-white px-4 py-1.5 text-[12.5px]", children: [
|
|
2961
3147
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "inline-flex items-center gap-1 font-semibold text-ink-2", children: [
|
|
2962
3148
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Paperclip, { size: 13 }),
|
|
2963
3149
|
" Attachments"
|
|
2964
3150
|
] }),
|
|
2965
|
-
attachments.map((x) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3151
|
+
ff.attachments.map((x) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2966
3152
|
"button",
|
|
2967
3153
|
{
|
|
2968
3154
|
type: "button",
|
|
2969
3155
|
title: `Download ${x.fileName}`,
|
|
2970
|
-
disabled: !
|
|
3156
|
+
disabled: !ff.canLoadFiles,
|
|
2971
3157
|
className: "inline-flex max-w-full cursor-pointer items-center gap-1 text-primary hover:underline disabled:cursor-default",
|
|
2972
|
-
onClick: () =>
|
|
3158
|
+
onClick: () => ff.downloadFile(x.id, x.fileName),
|
|
2973
3159
|
children: [
|
|
2974
3160
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "truncate", children: x.fileName }),
|
|
2975
3161
|
x.fileSize ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "text-muted", children: [
|
|
@@ -2977,39 +3163,58 @@ function FormFiller({
|
|
|
2977
3163
|
humanSize(x.fileSize),
|
|
2978
3164
|
")"
|
|
2979
3165
|
] }) : null,
|
|
2980
|
-
|
|
3166
|
+
ff.canLoadFiles && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Download, { size: 12 })
|
|
2981
3167
|
]
|
|
2982
3168
|
},
|
|
2983
3169
|
x.id
|
|
2984
3170
|
))
|
|
2985
3171
|
] }),
|
|
2986
|
-
errorList.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "m-0 border-b border-danger/30 bg-danger/5 px-6 py-2 text-[13px] text-danger", children: errorList.map((f) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "li", { children: [
|
|
3172
|
+
ff.errorList.length > 0 && shows("errors") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "m-0 border-b border-danger/30 bg-danger/5 px-6 py-2 text-[13px] text-danger", children: ff.errorList.map((f) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "li", { children: [
|
|
2987
3173
|
"Page ",
|
|
2988
3174
|
f.position.page,
|
|
2989
3175
|
": ",
|
|
2990
3176
|
errors[f.key]
|
|
2991
3177
|
] }, f.key)) }),
|
|
2992
|
-
view === "list" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 overflow-auto bg-hover", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3178
|
+
view === "list" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex-1 overflow-auto bg-hover", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3179
|
+
QuestionList,
|
|
3180
|
+
{
|
|
3181
|
+
questions: ff.questions,
|
|
3182
|
+
answers,
|
|
3183
|
+
control,
|
|
3184
|
+
filters: listFilters,
|
|
3185
|
+
search: listSearch,
|
|
3186
|
+
hideUnavailable: hideUnavailableFilters,
|
|
3187
|
+
renderToolbar: renderFilters
|
|
3188
|
+
}
|
|
3189
|
+
) }),
|
|
2993
3190
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref: fitRef, className: `flex-1 overflow-auto bg-hover ${view === "list" ? "hidden" : ""}`, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2994
3191
|
PdfPages,
|
|
2995
3192
|
{
|
|
2996
3193
|
load: pdfSource,
|
|
2997
3194
|
zoom,
|
|
2998
|
-
pages: _optionalChain([layout, 'optionalAccess',
|
|
2999
|
-
onLoaded:
|
|
3000
|
-
setPdf(doc);
|
|
3001
|
-
if (sizes2.length) setPdfWidth(Math.max(...sizes2.map((p) => p.width)));
|
|
3002
|
-
},
|
|
3195
|
+
pages: _optionalChain([layout, 'optionalAccess', _137 => _137.pages]),
|
|
3196
|
+
onLoaded: ff.onPdfLoaded,
|
|
3003
3197
|
onError: () => setLoadError("The document could not be shown"),
|
|
3004
3198
|
overlay: (page) => [
|
|
3005
3199
|
// The admin's text / boxes / lines first, the answer controls on top.
|
|
3006
|
-
...(_nullishCoalesce(_optionalChain([layout, 'optionalAccess',
|
|
3007
|
-
...fields.filter((f) => f.position.page === page && _optionalChain([states, 'access',
|
|
3200
|
+
...(_nullishCoalesce(_optionalChain([layout, 'optionalAccess', _138 => _138.elements]), () => ( []))).filter((el) => el.page === page).map((el) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, LayoutElementView, { element: el, pageHeight: _nullishCoalesce(_optionalChain([layout, 'access', _139 => _139.pages, 'access', _140 => _140[page - 1], 'optionalAccess', _141 => _141.height]), () => ( 842)) }, el.id)),
|
|
3201
|
+
...fields.filter((f) => f.position.page === page && _optionalChain([states, 'access', _142 => _142[f.key], 'optionalAccess', _143 => _143.visible])).map((f) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute [container-type:size]", style: _chunk33XWO4KBcjs.boxStyle.call(void 0, f.position), children: control(f) }, f.id))
|
|
3008
3202
|
]
|
|
3009
3203
|
}
|
|
3010
3204
|
) }),
|
|
3011
|
-
confirmSubmit && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3012
|
-
|
|
3205
|
+
confirmSubmit && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3206
|
+
ConfirmModal2,
|
|
3207
|
+
{
|
|
3208
|
+
confirmLabel: "Submit",
|
|
3209
|
+
onConfirm: () => {
|
|
3210
|
+
setConfirmSubmit(false);
|
|
3211
|
+
void ff.submit();
|
|
3212
|
+
},
|
|
3213
|
+
onCancel: () => setConfirmSubmit(false),
|
|
3214
|
+
children: "Submit this form? You cannot change the answers afterwards."
|
|
3215
|
+
}
|
|
3216
|
+
)
|
|
3217
|
+
] }) });
|
|
3013
3218
|
}
|
|
3014
3219
|
|
|
3015
3220
|
|
|
@@ -3019,5 +3224,16 @@ function FormFiller({
|
|
|
3019
3224
|
|
|
3020
3225
|
|
|
3021
3226
|
|
|
3022
|
-
|
|
3227
|
+
|
|
3228
|
+
|
|
3229
|
+
|
|
3230
|
+
|
|
3231
|
+
|
|
3232
|
+
|
|
3233
|
+
|
|
3234
|
+
|
|
3235
|
+
|
|
3236
|
+
|
|
3237
|
+
|
|
3238
|
+
exports.AnswerControl = AnswerControl; exports.FieldControl = FieldControl; exports.FormEditor = FormEditor; exports.FormFiller = FormFiller; exports.FormliftProvider = FormliftProvider; exports.LayoutElementView = LayoutElementView; exports.PdfPages = PdfPages; exports.QuestionList = QuestionList; exports.TYPE_LABEL = TYPE_LABEL; exports.defaultComponents = defaultComponents; exports.defaultFilters = defaultFilters; exports.readPdf = readPdf; exports.setPdfWorker = setPdfWorker; exports.useFitZoom = useFitZoom; exports.useFormEditor = useFormEditor; exports.useFormFiller = useFormFiller; exports.useQuestionFilter = useQuestionFilter; exports.useUndo = useUndo;
|
|
3023
3239
|
//# sourceMappingURL=index.cjs.map
|