formanitor 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +120 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +120 -58
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -353,10 +353,13 @@ var FormStore = class {
|
|
|
353
353
|
if (field.type === "image_upload" || field.type === "signature") {
|
|
354
354
|
const raw = values[field.id];
|
|
355
355
|
if (raw !== void 0 && raw !== null && raw !== "") {
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
356
|
+
const key = typeof raw === "string" ? raw : raw.s3_key || raw.value || null;
|
|
357
|
+
if (key && typeof key === "string") {
|
|
358
|
+
result[field.id] = {
|
|
359
|
+
_type: "s3_key",
|
|
360
|
+
value: key
|
|
361
|
+
};
|
|
362
|
+
}
|
|
360
363
|
}
|
|
361
364
|
}
|
|
362
365
|
});
|
|
@@ -1539,8 +1542,15 @@ var smoothPoint = (prev, curr, smoothing = 0.75) => {
|
|
|
1539
1542
|
y: prev.y * smoothing + curr.y * (1 - smoothing)
|
|
1540
1543
|
};
|
|
1541
1544
|
};
|
|
1545
|
+
function extractDisplayUrl(value) {
|
|
1546
|
+
if (!value || typeof value !== "object") return null;
|
|
1547
|
+
if (typeof value.presigned_url === "string" && value.presigned_url) {
|
|
1548
|
+
return value.presigned_url;
|
|
1549
|
+
}
|
|
1550
|
+
return null;
|
|
1551
|
+
}
|
|
1542
1552
|
var SignatureUploadWidget = ({ fieldId }) => {
|
|
1543
|
-
const { fieldDef, setValue, setTouched, error, disabled, touched } = useField(fieldId);
|
|
1553
|
+
const { fieldDef, setValue, setTouched, error, disabled, touched, value } = useField(fieldId);
|
|
1544
1554
|
const store = useFormStore();
|
|
1545
1555
|
const { state } = useForm();
|
|
1546
1556
|
const canvasRef = React11.useRef(null);
|
|
@@ -1549,13 +1559,14 @@ var SignatureUploadWidget = ({ fieldId }) => {
|
|
|
1549
1559
|
const lastTimeRef = React11.useRef(null);
|
|
1550
1560
|
const lastWidthRef = React11.useRef(2);
|
|
1551
1561
|
const [isDrawing, setIsDrawing] = React11.useState(false);
|
|
1552
|
-
const [
|
|
1562
|
+
const [hasDrawing, setHasDrawing] = React11.useState(false);
|
|
1553
1563
|
const [isUploading, setIsUploading] = React11.useState(false);
|
|
1564
|
+
const [isConfirmed, setIsConfirmed] = React11.useState(false);
|
|
1554
1565
|
const showError = !!error && (touched || state.submitAttempted);
|
|
1555
|
-
|
|
1556
|
-
const
|
|
1557
|
-
if (!uploadHandler) return null;
|
|
1566
|
+
const displayUrl = React11.useMemo(() => extractDisplayUrl(value), [value]);
|
|
1567
|
+
const showPreview = displayUrl !== null;
|
|
1558
1568
|
React11.useEffect(() => {
|
|
1569
|
+
if (showPreview) return;
|
|
1559
1570
|
const canvas = canvasRef.current;
|
|
1560
1571
|
if (!canvas) return;
|
|
1561
1572
|
const ctx = canvas.getContext("2d");
|
|
@@ -1573,7 +1584,9 @@ var SignatureUploadWidget = ({ fieldId }) => {
|
|
|
1573
1584
|
ctx.strokeStyle = "#000";
|
|
1574
1585
|
ctx.fillStyle = "#fff";
|
|
1575
1586
|
ctx.fillRect(0, 0, width, height);
|
|
1576
|
-
}, []);
|
|
1587
|
+
}, [showPreview]);
|
|
1588
|
+
const uploadHandler = store.getUploadHandler();
|
|
1589
|
+
if (!fieldDef || !uploadHandler) return null;
|
|
1577
1590
|
const getPoint = (event) => {
|
|
1578
1591
|
const canvas = canvasRef.current;
|
|
1579
1592
|
const rect = canvas.getBoundingClientRect();
|
|
@@ -1586,6 +1599,7 @@ var SignatureUploadWidget = ({ fieldId }) => {
|
|
|
1586
1599
|
const startDrawing = (event) => {
|
|
1587
1600
|
if (disabled) return;
|
|
1588
1601
|
setIsDrawing(true);
|
|
1602
|
+
setIsConfirmed(false);
|
|
1589
1603
|
setTouched();
|
|
1590
1604
|
const ctx = canvasRef.current?.getContext("2d");
|
|
1591
1605
|
if (!ctx) return;
|
|
@@ -1627,23 +1641,31 @@ var SignatureUploadWidget = ({ fieldId }) => {
|
|
|
1627
1641
|
lastPointRef.current = smoothed;
|
|
1628
1642
|
lastTimeRef.current = now;
|
|
1629
1643
|
lastWidthRef.current = width;
|
|
1630
|
-
|
|
1644
|
+
setHasDrawing(true);
|
|
1631
1645
|
};
|
|
1632
1646
|
const stopDrawing = () => {
|
|
1633
1647
|
setIsDrawing(false);
|
|
1634
1648
|
lastPointRef.current = null;
|
|
1635
1649
|
lastTimeRef.current = null;
|
|
1636
1650
|
};
|
|
1637
|
-
const
|
|
1651
|
+
const clearSignature = () => {
|
|
1652
|
+
if (showPreview) {
|
|
1653
|
+
setValue(null);
|
|
1654
|
+
setTouched();
|
|
1655
|
+
return;
|
|
1656
|
+
}
|
|
1638
1657
|
const canvas = canvasRef.current;
|
|
1639
1658
|
const ctx = canvas?.getContext("2d");
|
|
1640
|
-
if (
|
|
1641
|
-
|
|
1642
|
-
|
|
1659
|
+
if (canvas && ctx) {
|
|
1660
|
+
ctx.fillStyle = "#fff";
|
|
1661
|
+
ctx.fillRect(0, 0, 400, 200);
|
|
1662
|
+
}
|
|
1643
1663
|
pathRef.current = "";
|
|
1644
1664
|
lastPointRef.current = null;
|
|
1645
|
-
|
|
1665
|
+
setHasDrawing(false);
|
|
1666
|
+
setIsConfirmed(false);
|
|
1646
1667
|
setValue(null);
|
|
1668
|
+
setTouched();
|
|
1647
1669
|
};
|
|
1648
1670
|
const generateSVG = () => `
|
|
1649
1671
|
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg">
|
|
@@ -1656,7 +1678,7 @@ var SignatureUploadWidget = ({ fieldId }) => {
|
|
|
1656
1678
|
fill="none"/>
|
|
1657
1679
|
</svg>`.trim();
|
|
1658
1680
|
const confirmSignature = async () => {
|
|
1659
|
-
if (!
|
|
1681
|
+
if (!hasDrawing) return;
|
|
1660
1682
|
setIsUploading(true);
|
|
1661
1683
|
setTouched();
|
|
1662
1684
|
try {
|
|
@@ -1665,55 +1687,95 @@ var SignatureUploadWidget = ({ fieldId }) => {
|
|
|
1665
1687
|
const filename = `signature_${Date.now()}.svg`;
|
|
1666
1688
|
const key = await uploadHandler(blob, filename);
|
|
1667
1689
|
setValue(key);
|
|
1690
|
+
setIsConfirmed(true);
|
|
1691
|
+
setHasDrawing(false);
|
|
1692
|
+
} catch (err) {
|
|
1693
|
+
console.error("[SignatureUpload] Upload failed:", err);
|
|
1668
1694
|
} finally {
|
|
1669
1695
|
setIsUploading(false);
|
|
1670
1696
|
}
|
|
1671
1697
|
};
|
|
1698
|
+
const canClear = showPreview ? !disabled : hasDrawing || isConfirmed;
|
|
1672
1699
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
1673
1700
|
/* @__PURE__ */ jsxRuntime.jsxs(Label, { children: [
|
|
1674
1701
|
fieldDef.label,
|
|
1675
1702
|
fieldDef.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500", children: "*" })
|
|
1676
1703
|
] }),
|
|
1677
|
-
|
|
1678
|
-
/*
|
|
1679
|
-
|
|
1680
|
-
{
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1704
|
+
showPreview ? (
|
|
1705
|
+
/* ── Preview mode: existing signature from backend ── */
|
|
1706
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
1707
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border border-gray-200 rounded bg-white flex items-center justify-start p-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1708
|
+
"img",
|
|
1709
|
+
{
|
|
1710
|
+
src: displayUrl,
|
|
1711
|
+
alt: "Signature",
|
|
1712
|
+
className: "object-contain max-w-full",
|
|
1713
|
+
style: { width: 400, height: 200 }
|
|
1714
|
+
}
|
|
1715
|
+
) }),
|
|
1716
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1717
|
+
Button,
|
|
1718
|
+
{
|
|
1719
|
+
type: "button",
|
|
1720
|
+
size: "icon",
|
|
1721
|
+
variant: "ghost",
|
|
1722
|
+
className: "absolute top-2 left-2 bg-white/80 hover:bg-red-50",
|
|
1723
|
+
onClick: clearSignature,
|
|
1724
|
+
disabled: !canClear,
|
|
1725
|
+
title: "Delete signature and draw a new one",
|
|
1726
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-4 w-4" })
|
|
1727
|
+
}
|
|
1728
|
+
)
|
|
1729
|
+
] })
|
|
1730
|
+
) : (
|
|
1731
|
+
/* ── Canvas mode: drawing / confirmed ── */
|
|
1732
|
+
/* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1733
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
1734
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1735
|
+
"canvas",
|
|
1736
|
+
{
|
|
1737
|
+
ref: canvasRef,
|
|
1738
|
+
className: `border rounded touch-none ${isConfirmed ? "border-green-300 cursor-default" : "border-gray-200 cursor-crosshair"}`,
|
|
1739
|
+
onMouseDown: startDrawing,
|
|
1740
|
+
onMouseMove: draw,
|
|
1741
|
+
onMouseUp: stopDrawing,
|
|
1742
|
+
onMouseLeave: stopDrawing,
|
|
1743
|
+
onTouchStart: startDrawing,
|
|
1744
|
+
onTouchMove: draw,
|
|
1745
|
+
onTouchEnd: stopDrawing
|
|
1746
|
+
}
|
|
1747
|
+
),
|
|
1748
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1749
|
+
Button,
|
|
1750
|
+
{
|
|
1751
|
+
type: "button",
|
|
1752
|
+
size: "icon",
|
|
1753
|
+
variant: "ghost",
|
|
1754
|
+
className: "absolute top-2 left-2 bg-white/80",
|
|
1755
|
+
onClick: clearSignature,
|
|
1756
|
+
disabled: !canClear,
|
|
1757
|
+
title: isConfirmed ? "Clear saved signature" : "Clear canvas",
|
|
1758
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-4 w-4" })
|
|
1759
|
+
}
|
|
1760
|
+
)
|
|
1761
|
+
] }),
|
|
1762
|
+
isConfirmed ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm text-green-600", children: [
|
|
1763
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4" }),
|
|
1764
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Signature saved" })
|
|
1765
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1766
|
+
Button,
|
|
1767
|
+
{
|
|
1768
|
+
type: "button",
|
|
1769
|
+
onClick: confirmSignature,
|
|
1770
|
+
disabled: !hasDrawing || isUploading,
|
|
1771
|
+
className: "text-xs",
|
|
1772
|
+
children: [
|
|
1773
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4 mr-1" }),
|
|
1774
|
+
isUploading ? "Saving\u2026" : "Confirm"
|
|
1775
|
+
]
|
|
1776
|
+
}
|
|
1777
|
+
)
|
|
1778
|
+
] })
|
|
1717
1779
|
),
|
|
1718
1780
|
showError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-red-500", children: error })
|
|
1719
1781
|
] });
|
|
@@ -2271,7 +2333,7 @@ var ReadOnlyText = ({ fieldDef, value }) => {
|
|
|
2271
2333
|
className: "prose prose-sm max-w-none text-gray-900 border border-gray-200 rounded-md p-3 bg-gray-50",
|
|
2272
2334
|
dangerouslySetInnerHTML: { __html: displayValue }
|
|
2273
2335
|
}
|
|
2274
|
-
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-gray-900 border border-gray-200 rounded-md p-3 bg-gray-50 min-h-[2.5rem]
|
|
2336
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-gray-900 border border-gray-200 rounded-md p-3 bg-gray-50 min-h-[2.5rem] whitespace-pre-wrap", children: displayValue || /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-400 italic", children: "No value" }) })
|
|
2275
2337
|
] });
|
|
2276
2338
|
};
|
|
2277
2339
|
var ReadOnlySelect = ({ fieldDef, value }) => {
|