@zerohive/hive-viewer 0.2.3 → 0.2.5
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 +219 -96
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +200 -77
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +200 -77
- package/dist/styles.css +383 -22
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -35,7 +35,7 @@ __export(index_exports, {
|
|
|
35
35
|
module.exports = __toCommonJS(index_exports);
|
|
36
36
|
|
|
37
37
|
// src/components/DocumentViewer.tsx
|
|
38
|
-
var
|
|
38
|
+
var import_react7 = require("react");
|
|
39
39
|
|
|
40
40
|
// src/editors/RichTextEditor.tsx
|
|
41
41
|
var import_html2canvas = __toESM(require("html2canvas"), 1);
|
|
@@ -596,12 +596,12 @@ function PdfRenderer(props) {
|
|
|
596
596
|
props.onThumbs(thumbs);
|
|
597
597
|
}, [thumbs]);
|
|
598
598
|
const pagesToShow = (0, import_react4.useMemo)(() => {
|
|
599
|
-
if (props.layout === "side-by-side") {
|
|
600
|
-
const left = props.currentPage;
|
|
601
|
-
const right = Math.min(
|
|
602
|
-
return [left, right];
|
|
599
|
+
if (props.layout === "side-by-side" && pageCount > 1) {
|
|
600
|
+
const left = Math.max(1, Math.min(props.currentPage, pageCount));
|
|
601
|
+
const right = Math.max(1, Math.min(left + 1, pageCount));
|
|
602
|
+
return left === right ? [left] : [left, right];
|
|
603
603
|
}
|
|
604
|
-
return [props.currentPage];
|
|
604
|
+
return [Math.max(1, Math.min(props.currentPage, pageCount))];
|
|
605
605
|
}, [props.currentPage, props.layout, pageCount]);
|
|
606
606
|
(0, import_react4.useEffect)(() => {
|
|
607
607
|
if (!doc) {
|
|
@@ -777,12 +777,13 @@ function PptxRenderer(props) {
|
|
|
777
777
|
props.onThumbs(thumbs);
|
|
778
778
|
}, [thumbs]);
|
|
779
779
|
const pagesToShow = (0, import_react5.useMemo)(() => {
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
];
|
|
785
|
-
|
|
780
|
+
const total = slides.length;
|
|
781
|
+
if (props.layout === "side-by-side" && total > 1) {
|
|
782
|
+
const left = Math.max(1, Math.min(props.currentPage, total));
|
|
783
|
+
const right = Math.max(1, Math.min(left + 1, total));
|
|
784
|
+
return left === right ? [left] : [left, right];
|
|
785
|
+
}
|
|
786
|
+
return [Math.max(1, Math.min(props.currentPage, total))];
|
|
786
787
|
}, [props.currentPage, props.layout, slides.length]);
|
|
787
788
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "hv-doc", children: [
|
|
788
789
|
loading && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hv-loading", children: "Loading PPTX\u2026" }),
|
|
@@ -841,87 +842,209 @@ var defaultLocale = {
|
|
|
841
842
|
};
|
|
842
843
|
|
|
843
844
|
// src/components/SignaturePanel.tsx
|
|
845
|
+
var import_react6 = __toESM(require("react"), 1);
|
|
844
846
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
845
847
|
function SignaturePanel(props) {
|
|
846
848
|
const title = props.locale["signatures.title"] ?? "Signatures";
|
|
847
|
-
|
|
848
|
-
/* @__PURE__ */ (
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
849
|
+
const deduped = import_react6.default.useMemo(() => {
|
|
850
|
+
const seen = /* @__PURE__ */ new Set();
|
|
851
|
+
return props.signatures.filter((s) => {
|
|
852
|
+
const key = `${s.signedBy}|${s.dateSigned}|${s.signatureImageUrl}`;
|
|
853
|
+
if (seen.has(key)) return false;
|
|
854
|
+
seen.add(key);
|
|
855
|
+
return true;
|
|
856
|
+
});
|
|
857
|
+
}, [props.signatures]);
|
|
858
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
859
|
+
"aside",
|
|
860
|
+
{
|
|
861
|
+
className: props.collapsed ? "hv-side hv-side--collapsed" : "hv-side",
|
|
862
|
+
"aria-label": title,
|
|
863
|
+
children: [
|
|
864
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hv-sidebar-header", children: [
|
|
865
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
866
|
+
"button",
|
|
867
|
+
{
|
|
868
|
+
type: "button",
|
|
869
|
+
className: "hv-icon",
|
|
870
|
+
onClick: props.onToggle,
|
|
871
|
+
"aria-label": props.locale["toolbar.signatures"] ?? "Signatures",
|
|
872
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { "aria-hidden": true, children: "\u270D" })
|
|
873
|
+
}
|
|
874
|
+
),
|
|
875
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hv-sidebar-title", children: title })
|
|
876
|
+
] }),
|
|
877
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hv-sidebar-body", children: [
|
|
878
|
+
deduped.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hv-signature-empty", "aria-live": "polite", children: props.locale["signatures.empty"] ?? "No signatures yet." }),
|
|
879
|
+
deduped.map((s, idx) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
880
|
+
"div",
|
|
881
|
+
{
|
|
882
|
+
className: "hv-signature-card",
|
|
883
|
+
tabIndex: 0,
|
|
884
|
+
"aria-label": `Signature by ${s.signedBy}`,
|
|
885
|
+
children: [
|
|
886
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
887
|
+
"img",
|
|
888
|
+
{
|
|
889
|
+
src: s.signatureImageUrl,
|
|
890
|
+
alt: props.locale["signatures.imgAlt"] ? props.locale["signatures.imgAlt"].replace(
|
|
891
|
+
"{name}",
|
|
892
|
+
s.signedBy
|
|
893
|
+
) : `Signature by ${s.signedBy}`,
|
|
894
|
+
className: "hv-signature-img"
|
|
895
|
+
}
|
|
896
|
+
),
|
|
897
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "hv-signature-meta", children: [
|
|
898
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hv-signature-name", children: s.signedBy }),
|
|
899
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hv-signature-date", children: new Date(s.dateSigned).toLocaleString() }),
|
|
900
|
+
s.comment ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hv-signature-comment", children: s.comment }) : null
|
|
901
|
+
] })
|
|
902
|
+
]
|
|
903
|
+
},
|
|
904
|
+
`${s.signedBy}-${s.dateSigned}-${s.signatureImageUrl}`
|
|
905
|
+
))
|
|
906
|
+
] })
|
|
907
|
+
]
|
|
908
|
+
}
|
|
909
|
+
);
|
|
861
910
|
}
|
|
862
911
|
|
|
863
912
|
// src/components/ThumbnailsSidebar.tsx
|
|
864
913
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
865
914
|
function ThumbnailsSidebar(props) {
|
|
866
915
|
const t = props.locale["thumbnails.title"] ?? "Thumbnails";
|
|
867
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
{
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
916
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
917
|
+
"aside",
|
|
918
|
+
{
|
|
919
|
+
className: props.collapsed ? "hv-thumbs hv-thumbs--collapsed" : "hv-thumbs",
|
|
920
|
+
"aria-label": t,
|
|
921
|
+
children: [
|
|
922
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "hv-thumbs-header", children: [
|
|
923
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
924
|
+
"button",
|
|
925
|
+
{
|
|
926
|
+
type: "button",
|
|
927
|
+
className: "hv-thumbs-toggle",
|
|
928
|
+
onClick: props.onToggle,
|
|
929
|
+
"aria-label": props.collapsed ? props.locale["thumbnails.open"] ?? "Open thumbnails" : props.locale["thumbnails.close"] ?? "Close thumbnails",
|
|
930
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "hv-thumbs-toggle-icon", children: props.collapsed ? "\u25B8" : "\u25BE" })
|
|
931
|
+
}
|
|
932
|
+
),
|
|
933
|
+
!props.collapsed && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hv-thumbs-title", children: t })
|
|
934
|
+
] }),
|
|
935
|
+
!props.collapsed && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hv-thumbs-list", role: "list", children: props.thumbnails.map((th, idx) => {
|
|
936
|
+
const p = idx + 1;
|
|
937
|
+
const active = p === props.currentPage;
|
|
938
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
939
|
+
"button",
|
|
940
|
+
{
|
|
941
|
+
type: "button",
|
|
942
|
+
role: "listitem",
|
|
943
|
+
className: active ? "hv-thumb hv-thumb--active" : "hv-thumb",
|
|
944
|
+
onClick: () => props.onSelectPage(p),
|
|
945
|
+
"aria-current": active ? "page" : void 0,
|
|
946
|
+
tabIndex: 0,
|
|
947
|
+
children: [
|
|
948
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hv-thumb-img", "aria-hidden": true, children: th.dataUrl ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("img", { src: th.dataUrl, alt: "" }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hv-thumb-placeholder" }) }),
|
|
949
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "hv-thumb-label", children: th.label })
|
|
950
|
+
]
|
|
951
|
+
},
|
|
952
|
+
th.id
|
|
953
|
+
);
|
|
954
|
+
}) })
|
|
955
|
+
]
|
|
956
|
+
}
|
|
957
|
+
);
|
|
901
958
|
}
|
|
902
959
|
|
|
903
960
|
// src/components/Toolbar.tsx
|
|
904
961
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
905
962
|
function Toolbar(props) {
|
|
906
963
|
const t = (k, fallback) => props.locale[k] ?? fallback;
|
|
907
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
964
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
965
|
+
"div",
|
|
966
|
+
{
|
|
967
|
+
className: "hv-toolbar",
|
|
968
|
+
role: "toolbar",
|
|
969
|
+
"aria-label": t("a11y.toolbar", "Document toolbar"),
|
|
970
|
+
children: [
|
|
971
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hv-toolbar__left gap-2", children: [
|
|
972
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
973
|
+
"button",
|
|
974
|
+
{
|
|
975
|
+
type: "button",
|
|
976
|
+
className: "hv-btn",
|
|
977
|
+
onClick: props.onToggleThumbnails,
|
|
978
|
+
"aria-pressed": props.showThumbnails,
|
|
979
|
+
children: t("toolbar.thumbs", "Thumbnails")
|
|
980
|
+
}
|
|
981
|
+
),
|
|
982
|
+
props.mode !== "create" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
983
|
+
"button",
|
|
984
|
+
{
|
|
985
|
+
type: "button",
|
|
986
|
+
className: "hv-btn",
|
|
987
|
+
onClick: props.onToggleSignatures,
|
|
988
|
+
"aria-pressed": props.showSignatures,
|
|
989
|
+
children: t("toolbar.signatures", "Signatures")
|
|
990
|
+
}
|
|
991
|
+
),
|
|
992
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "hv-sep" }),
|
|
993
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
994
|
+
"button",
|
|
995
|
+
{
|
|
996
|
+
type: "button",
|
|
997
|
+
className: props.layout === "single" ? "hv-btn hv-btn--active" : "hv-btn",
|
|
998
|
+
onClick: () => props.onChangeLayout("single"),
|
|
999
|
+
children: t("toolbar.layout.single", "Single")
|
|
1000
|
+
}
|
|
1001
|
+
),
|
|
1002
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1003
|
+
"button",
|
|
1004
|
+
{
|
|
1005
|
+
type: "button",
|
|
1006
|
+
className: props.layout === "side-by-side" ? "hv-btn hv-btn--active" : "hv-btn",
|
|
1007
|
+
onClick: () => props.onChangeLayout("side-by-side"),
|
|
1008
|
+
children: t("toolbar.layout.two", "Two")
|
|
1009
|
+
}
|
|
1010
|
+
)
|
|
1011
|
+
] }),
|
|
1012
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "hv-toolbar__right", children: [
|
|
1013
|
+
props.showHeaderFooterToggle && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "hv-toggle", children: [
|
|
1014
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1015
|
+
"input",
|
|
1016
|
+
{
|
|
1017
|
+
type: "checkbox",
|
|
1018
|
+
checked: props.headerFooterEnabled,
|
|
1019
|
+
onChange: props.onToggleHeaderFooter
|
|
1020
|
+
}
|
|
1021
|
+
),
|
|
1022
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: t("toolbar.letterhead", "Letterhead") })
|
|
1023
|
+
] }),
|
|
1024
|
+
props.allowSigning && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1025
|
+
"button",
|
|
1026
|
+
{
|
|
1027
|
+
type: "button",
|
|
1028
|
+
className: "hv-btn hv-btn--primary",
|
|
1029
|
+
onClick: props.onSign,
|
|
1030
|
+
disabled: props.signingDisabled,
|
|
1031
|
+
children: t("toolbar.sign", "Sign Document")
|
|
1032
|
+
}
|
|
1033
|
+
),
|
|
1034
|
+
props.canExportPdf && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "hv-btn", onClick: props.onExportPdf, children: t("toolbar.exportPdf", "Export as PDF") }),
|
|
1035
|
+
props.canSave && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1036
|
+
"button",
|
|
1037
|
+
{
|
|
1038
|
+
type: "button",
|
|
1039
|
+
className: "hv-btn hv-btn--primary",
|
|
1040
|
+
onClick: props.onSave,
|
|
1041
|
+
children: t("toolbar.save", "Save")
|
|
1042
|
+
}
|
|
1043
|
+
)
|
|
1044
|
+
] })
|
|
1045
|
+
]
|
|
1046
|
+
}
|
|
1047
|
+
);
|
|
925
1048
|
}
|
|
926
1049
|
|
|
927
1050
|
// src/components/DocumentViewer.tsx
|
|
@@ -929,24 +1052,24 @@ var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
|
929
1052
|
function DocumentViewer(props) {
|
|
930
1053
|
const mode = props.mode ?? "view";
|
|
931
1054
|
const theme = props.theme ?? "light";
|
|
932
|
-
const locale = (0,
|
|
933
|
-
const [layout, setLayout] = (0,
|
|
934
|
-
const [showThumbnails, setShowThumbnails] = (0,
|
|
935
|
-
const [showSignatures, setShowSignatures] = (0,
|
|
936
|
-
const [headerFooterEnabled, setHeaderFooterEnabled] = (0,
|
|
1055
|
+
const locale = (0, import_react7.useMemo)(() => ({ ...defaultLocale, ...props.locale ?? {} }), [props.locale]);
|
|
1056
|
+
const [layout, setLayout] = (0, import_react7.useState)(props.defaultLayout ?? "single");
|
|
1057
|
+
const [showThumbnails, setShowThumbnails] = (0, import_react7.useState)(true);
|
|
1058
|
+
const [showSignatures, setShowSignatures] = (0, import_react7.useState)(true);
|
|
1059
|
+
const [headerFooterEnabled, setHeaderFooterEnabled] = (0, import_react7.useState)(true);
|
|
937
1060
|
const allowSigning = props.allowSigning ?? false;
|
|
938
|
-
const [signingBusy, setSigningBusy] = (0,
|
|
939
|
-
const [resolved, setResolved] = (0,
|
|
940
|
-
const [error, setError] = (0,
|
|
941
|
-
const [pageCount, setPageCount] = (0,
|
|
942
|
-
const [currentPage, setCurrentPage] = (0,
|
|
943
|
-
const [thumbs, setThumbs] = (0,
|
|
944
|
-
const [localSignatures, setLocalSignatures] = (0,
|
|
945
|
-
(0,
|
|
946
|
-
const [sigPlacements, setSigPlacements] = (0,
|
|
947
|
-
const [armedSignatureUrl, setArmedSignatureUrl] = (0,
|
|
948
|
-
const editorRef = (0,
|
|
949
|
-
(0,
|
|
1061
|
+
const [signingBusy, setSigningBusy] = (0, import_react7.useState)(false);
|
|
1062
|
+
const [resolved, setResolved] = (0, import_react7.useState)(null);
|
|
1063
|
+
const [error, setError] = (0, import_react7.useState)("");
|
|
1064
|
+
const [pageCount, setPageCount] = (0, import_react7.useState)(1);
|
|
1065
|
+
const [currentPage, setCurrentPage] = (0, import_react7.useState)(1);
|
|
1066
|
+
const [thumbs, setThumbs] = (0, import_react7.useState)([]);
|
|
1067
|
+
const [localSignatures, setLocalSignatures] = (0, import_react7.useState)(props.signatures ?? []);
|
|
1068
|
+
(0, import_react7.useEffect)(() => setLocalSignatures(props.signatures ?? []), [props.signatures]);
|
|
1069
|
+
const [sigPlacements, setSigPlacements] = (0, import_react7.useState)([]);
|
|
1070
|
+
const [armedSignatureUrl, setArmedSignatureUrl] = (0, import_react7.useState)(null);
|
|
1071
|
+
const editorRef = (0, import_react7.useRef)(null);
|
|
1072
|
+
(0, import_react7.useEffect)(() => {
|
|
950
1073
|
let cancelled = false;
|
|
951
1074
|
(async () => {
|
|
952
1075
|
setError("");
|
|
@@ -984,7 +1107,7 @@ function DocumentViewer(props) {
|
|
|
984
1107
|
cancelled = true;
|
|
985
1108
|
};
|
|
986
1109
|
}, [mode, props.fileUrl, props.base64, props.blob, props.fileName, props.fileType]);
|
|
987
|
-
const thumbnails = (0,
|
|
1110
|
+
const thumbnails = (0, import_react7.useMemo)(() => {
|
|
988
1111
|
const n = Math.max(1, pageCount);
|
|
989
1112
|
return Array.from({ length: n }, (_, i) => ({
|
|
990
1113
|
id: `p-${i + 1}`,
|