@embedpdf/viewer-chrome 3.0.0-next.13 → 3.0.0-next.15
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/README.md +175 -132
- package/dist/annotation-fonts-BqoLZ4Mp.js +80 -0
- package/dist/annotation-fonts-BqoLZ4Mp.js.map +1 -0
- package/dist/annotation-fonts-Dt0IQXhz.cjs +91 -0
- package/dist/annotation-fonts-Dt0IQXhz.cjs.map +1 -0
- package/dist/annotation-style--rPIZsuP.js +879 -0
- package/dist/annotation-style--rPIZsuP.js.map +1 -0
- package/dist/annotation-style-Bzvvp8-N.cjs +879 -0
- package/dist/annotation-style-Bzvvp8-N.cjs.map +1 -0
- package/dist/ar-D9XKAmDx.js +567 -0
- package/dist/ar-D9XKAmDx.js.map +1 -0
- package/dist/ar-DnEj5vbP.cjs +567 -0
- package/dist/ar-DnEj5vbP.cjs.map +1 -0
- package/dist/chrome.cjs +378 -221
- package/dist/chrome.cjs.map +1 -1
- package/dist/chrome.d.cts +5 -34
- package/dist/chrome.d.ts +5 -34
- package/dist/chrome.js +377 -218
- package/dist/chrome.js.map +1 -1
- package/dist/commands-BmgxhJ8B.js +953 -0
- package/dist/commands-BmgxhJ8B.js.map +1 -0
- package/dist/commands-CYt4SFUX.cjs +1060 -0
- package/dist/commands-CYt4SFUX.cjs.map +1 -0
- package/dist/commands.cjs +12 -595
- package/dist/commands.d.cts +29 -4
- package/dist/commands.d.ts +29 -4
- package/dist/commands.js +2 -593
- package/dist/comments-panel-MUVgLCBI.js +514 -0
- package/dist/comments-panel-MUVgLCBI.js.map +1 -0
- package/dist/comments-panel-pEcQg4Vs.cjs +514 -0
- package/dist/comments-panel-pEcQg4Vs.cjs.map +1 -0
- package/dist/de-Bdr4aWzm.js +566 -0
- package/dist/de-Bdr4aWzm.js.map +1 -0
- package/dist/de-Dv6zvbnd.cjs +566 -0
- package/dist/de-Dv6zvbnd.cjs.map +1 -0
- package/dist/dialog-B5GBisKv.js +55 -0
- package/dist/dialog-B5GBisKv.js.map +1 -0
- package/dist/dialog-t8F13BL_.cjs +60 -0
- package/dist/dialog-t8F13BL_.cjs.map +1 -0
- package/dist/es-BP09DR9w.cjs +566 -0
- package/dist/es-BP09DR9w.cjs.map +1 -0
- package/dist/es-BSXz5tBv.js +566 -0
- package/dist/es-BSXz5tBv.js.map +1 -0
- package/dist/form-design-panel-B5MXTZ96.cjs +418 -0
- package/dist/form-design-panel-B5MXTZ96.cjs.map +1 -0
- package/dist/form-design-panel-vWWU9uB-.js +418 -0
- package/dist/form-design-panel-vWWU9uB-.js.map +1 -0
- package/dist/fr-BBQQn7tJ.cjs +566 -0
- package/dist/fr-BBQQn7tJ.cjs.map +1 -0
- package/dist/fr-Ckn3K9v1.js +566 -0
- package/dist/fr-Ckn3K9v1.js.map +1 -0
- package/dist/he-DRsG7bH7.cjs +567 -0
- package/dist/he-DRsG7bH7.cjs.map +1 -0
- package/dist/he-wdGU5PkU.js +567 -0
- package/dist/he-wdGU5PkU.js.map +1 -0
- package/dist/icons-BrK5iVL8.js +856 -0
- package/dist/icons-BrK5iVL8.js.map +1 -0
- package/dist/icons-x0Tc05bs.cjs +1010 -0
- package/dist/icons-x0Tc05bs.cjs.map +1 -0
- package/dist/index.cjs +3162 -5106
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +636 -143
- package/dist/index.d.ts +636 -143
- package/dist/index.js +3083 -4975
- package/dist/index.js.map +1 -1
- package/dist/it-BuP4o0xQ.cjs +566 -0
- package/dist/it-BuP4o0xQ.cjs.map +1 -0
- package/dist/it-Us-VmvIu.js +566 -0
- package/dist/it-Us-VmvIu.js.map +1 -0
- package/dist/ja-Cizj0-5O.js +566 -0
- package/dist/ja-Cizj0-5O.js.map +1 -0
- package/dist/ja-DovEd6ts.cjs +566 -0
- package/dist/ja-DovEd6ts.cjs.map +1 -0
- package/dist/ko-B-qJEol2.cjs +566 -0
- package/dist/ko-B-qJEol2.cjs.map +1 -0
- package/dist/ko-DlrXliE1.js +566 -0
- package/dist/ko-DlrXliE1.js.map +1 -0
- package/dist/labels-BiM9wp9K.cjs +21 -0
- package/dist/labels-BiM9wp9K.cjs.map +1 -0
- package/dist/labels-C6_i87Oj.js +16 -0
- package/dist/labels-C6_i87Oj.js.map +1 -0
- package/dist/link-editor-CSjqPnj1.cjs +125 -0
- package/dist/link-editor-CSjqPnj1.cjs.map +1 -0
- package/dist/link-editor-SxM1nnJU.js +125 -0
- package/dist/link-editor-SxM1nnJU.js.map +1 -0
- package/dist/measurement-Bs61XWbJ.js +325 -0
- package/dist/measurement-Bs61XWbJ.js.map +1 -0
- package/dist/measurement-CcCsHPOX.cjs +326 -0
- package/dist/measurement-CcCsHPOX.cjs.map +1 -0
- package/dist/nl-0aF7M_0h.js +566 -0
- package/dist/nl-0aF7M_0h.js.map +1 -0
- package/dist/nl-D3KZDDiJ.cjs +566 -0
- package/dist/nl-D3KZDDiJ.cjs.map +1 -0
- package/dist/pl-BW--AaCI.js +566 -0
- package/dist/pl-BW--AaCI.js.map +1 -0
- package/dist/pl-DSFhAUqx.cjs +566 -0
- package/dist/pl-DSFhAUqx.cjs.map +1 -0
- package/dist/pt-C5S-8MC5.cjs +566 -0
- package/dist/pt-C5S-8MC5.cjs.map +1 -0
- package/dist/pt-DIhpU5pT.js +566 -0
- package/dist/pt-DIhpU5pT.js.map +1 -0
- package/dist/redact-confirm-B6j36TPw.js +83 -0
- package/dist/redact-confirm-B6j36TPw.js.map +1 -0
- package/dist/redact-confirm-CX_SY2ZN.cjs +83 -0
- package/dist/redact-confirm-CX_SY2ZN.cjs.map +1 -0
- package/dist/redaction-panel-BmoIl-Ll.cjs +96 -0
- package/dist/redaction-panel-BmoIl-Ll.cjs.map +1 -0
- package/dist/redaction-panel-IJDshSJI.js +96 -0
- package/dist/redaction-panel-IJDshSJI.js.map +1 -0
- package/dist/search-panel-HfIhJm1M.js +249 -0
- package/dist/search-panel-HfIhJm1M.js.map +1 -0
- package/dist/search-panel-s9IoiOtv.cjs +249 -0
- package/dist/search-panel-s9IoiOtv.cjs.map +1 -0
- package/dist/sheet-BDsa_Sup.cjs +442 -0
- package/dist/sheet-BDsa_Sup.cjs.map +1 -0
- package/dist/sheet-R6XDgyEf.js +365 -0
- package/dist/sheet-R6XDgyEf.js.map +1 -0
- package/dist/sign-dialog-CgnR7akj.cjs +155 -0
- package/dist/sign-dialog-CgnR7akj.cjs.map +1 -0
- package/dist/sign-dialog-GDqCoQhA.js +155 -0
- package/dist/sign-dialog-GDqCoQhA.js.map +1 -0
- package/dist/signature-inspector-DyO313Qf.cjs +166 -0
- package/dist/signature-inspector-DyO313Qf.cjs.map +1 -0
- package/dist/signature-inspector-okFz8do6.js +166 -0
- package/dist/signature-inspector-okFz8do6.js.map +1 -0
- package/dist/signature-maker-BhCmYyHD.js +393 -0
- package/dist/signature-maker-BhCmYyHD.js.map +1 -0
- package/dist/signature-maker-BoYa8vgA.cjs +393 -0
- package/dist/signature-maker-BoYa8vgA.cjs.map +1 -0
- package/dist/signatures-panel-B56PC6d9.cjs +300 -0
- package/dist/signatures-panel-B56PC6d9.cjs.map +1 -0
- package/dist/signatures-panel-CgnFfhFm.js +300 -0
- package/dist/signatures-panel-CgnFfhFm.js.map +1 -0
- package/dist/stamp-store-BHvRs-Do.cjs +147 -0
- package/dist/stamp-store-BHvRs-Do.cjs.map +1 -0
- package/dist/stamp-store-WuF-L3Jj.js +112 -0
- package/dist/stamp-store-WuF-L3Jj.js.map +1 -0
- package/dist/stamps-panel-B9NYGayn.cjs +231 -0
- package/dist/stamps-panel-B9NYGayn.cjs.map +1 -0
- package/dist/stamps-panel-CDO0FPyK.js +231 -0
- package/dist/stamps-panel-CDO0FPyK.js.map +1 -0
- package/dist/toolbar-CJu2wKTU.cjs +1659 -0
- package/dist/toolbar-CJu2wKTU.cjs.map +1 -0
- package/dist/toolbar-z9od3tKl.js +1564 -0
- package/dist/toolbar-z9od3tKl.js.map +1 -0
- package/dist/zh-cn-3tmMeHqv.cjs +566 -0
- package/dist/zh-cn-3tmMeHqv.cjs.map +1 -0
- package/dist/zh-cn-CxkUUBct.js +566 -0
- package/dist/zh-cn-CxkUUBct.js.map +1 -0
- package/package.json +6 -4
- package/src/styles.css +153 -89
- package/dist/commands.cjs.map +0 -1
- package/dist/commands.js.map +0 -1
- package/dist/es-DYwzfxyt.cjs +0 -293
- package/dist/es-DYwzfxyt.cjs.map +0 -1
- package/dist/es-sN6uqBgD.js +0 -293
- package/dist/es-sN6uqBgD.js.map +0 -1
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { t as Dialog } from "./dialog-B5GBisKv.js";
|
|
2
|
+
import { useId, useState } from "react";
|
|
3
|
+
import { useRedaction } from "@embedpdf/react/redaction";
|
|
4
|
+
import { useT } from "@embedpdf/react/i18n";
|
|
5
|
+
import { useSurface } from "@embedpdf/react/shell";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
//#region src/ui/redact-confirm.tsx
|
|
8
|
+
/**
|
|
9
|
+
* The apply-all confirm modal (`redact-confirm` shell surface, `exclusive:
|
|
10
|
+
* 'modal'` via the command router). Shows the pending count and the
|
|
11
|
+
* client-side collateral estimate — other annotations the apply will destroy —
|
|
12
|
+
* before anything irreversible happens. The authoritative collateral count
|
|
13
|
+
* comes back on the result. Escape cancels, unless the apply is running.
|
|
14
|
+
*/
|
|
15
|
+
function RedactConfirmModal() {
|
|
16
|
+
const t = useT();
|
|
17
|
+
const surface = useSurface("redact-confirm");
|
|
18
|
+
const redaction = useRedaction();
|
|
19
|
+
const [busy, setBusy] = useState(false);
|
|
20
|
+
const [error, setError] = useState(null);
|
|
21
|
+
const titleId = useId();
|
|
22
|
+
if (!surface.isOpen) return null;
|
|
23
|
+
const count = redaction.getPendingCount();
|
|
24
|
+
const collateral = redaction.estimateCollateral().count;
|
|
25
|
+
const apply = async () => {
|
|
26
|
+
setBusy(true);
|
|
27
|
+
setError(null);
|
|
28
|
+
try {
|
|
29
|
+
await redaction.applyAll();
|
|
30
|
+
surface.close();
|
|
31
|
+
} catch (error) {
|
|
32
|
+
setError(error instanceof Error ? error.message : String(error));
|
|
33
|
+
} finally {
|
|
34
|
+
setBusy(false);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
return /* @__PURE__ */ jsxs(Dialog, {
|
|
38
|
+
labelledBy: titleId,
|
|
39
|
+
onClose: () => {
|
|
40
|
+
if (!busy) surface.close();
|
|
41
|
+
},
|
|
42
|
+
className: "border-border bg-surface w-96 rounded-lg border p-4 shadow-xl",
|
|
43
|
+
children: [
|
|
44
|
+
/* @__PURE__ */ jsx("h2", {
|
|
45
|
+
id: titleId,
|
|
46
|
+
className: "text-fg text-base font-semibold",
|
|
47
|
+
children: t("demo.redactConfirmTitle")
|
|
48
|
+
}),
|
|
49
|
+
/* @__PURE__ */ jsx("p", {
|
|
50
|
+
className: "text-fg-muted mt-2 text-sm",
|
|
51
|
+
children: t("demo.redactConfirmBody", { params: { count } })
|
|
52
|
+
}),
|
|
53
|
+
collateral > 0 ? /* @__PURE__ */ jsx("p", {
|
|
54
|
+
className: "mt-2 text-sm font-medium text-red-600",
|
|
55
|
+
children: t("demo.redactConfirmCollateral", { params: { count: collateral } })
|
|
56
|
+
}) : null,
|
|
57
|
+
error ? /* @__PURE__ */ jsx("p", {
|
|
58
|
+
className: "mt-2 text-sm text-red-600",
|
|
59
|
+
children: error
|
|
60
|
+
}) : null,
|
|
61
|
+
/* @__PURE__ */ jsxs("div", {
|
|
62
|
+
className: "mt-4 flex justify-end gap-2",
|
|
63
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
64
|
+
type: "button",
|
|
65
|
+
disabled: busy,
|
|
66
|
+
onClick: surface.close,
|
|
67
|
+
className: "border-border text-fg hover:bg-hover rounded-md border px-3 py-1.5 text-sm",
|
|
68
|
+
children: t("demo.cancel")
|
|
69
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
70
|
+
type: "button",
|
|
71
|
+
disabled: busy,
|
|
72
|
+
onClick: () => void apply(),
|
|
73
|
+
className: "rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-60",
|
|
74
|
+
children: busy ? t("demo.redactApplying") : t("demo.redactApply")
|
|
75
|
+
})]
|
|
76
|
+
})
|
|
77
|
+
]
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
export { RedactConfirmModal };
|
|
82
|
+
|
|
83
|
+
//# sourceMappingURL=redact-confirm-B6j36TPw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact-confirm-B6j36TPw.js","names":[],"sources":["../src/ui/redact-confirm.tsx"],"sourcesContent":["import { useId, useState } from 'react';\nimport { useRedaction } from '@embedpdf/react/redaction';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Dialog } from './dialog';\n\n/**\n * The apply-all confirm modal (`redact-confirm` shell surface, `exclusive:\n * 'modal'` via the command router). Shows the pending count and the\n * client-side collateral estimate — other annotations the apply will destroy —\n * before anything irreversible happens. The authoritative collateral count\n * comes back on the result. Escape cancels, unless the apply is running.\n */\nexport function RedactConfirmModal() {\n const t = useT();\n const surface = useSurface('redact-confirm');\n const redaction = useRedaction();\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const titleId = useId();\n\n if (!surface.isOpen) return null;\n\n const count = redaction.getPendingCount();\n const collateral = redaction.estimateCollateral().count;\n\n const apply = async () => {\n setBusy(true);\n setError(null);\n try {\n await redaction.applyAll();\n surface.close();\n } catch (error) {\n setError(error instanceof Error ? error.message : String(error));\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Dialog\n labelledBy={titleId}\n onClose={() => {\n if (!busy) surface.close();\n }}\n className=\"border-border bg-surface w-96 rounded-lg border p-4 shadow-xl\"\n >\n <h2 id={titleId} className=\"text-fg text-base font-semibold\">\n {t('demo.redactConfirmTitle')}\n </h2>\n <p className=\"text-fg-muted mt-2 text-sm\">\n {t('demo.redactConfirmBody', { params: { count } })}\n </p>\n {collateral > 0 ? (\n <p className=\"mt-2 text-sm font-medium text-red-600\">\n {t('demo.redactConfirmCollateral', { params: { count: collateral } })}\n </p>\n ) : null}\n {error ? <p className=\"mt-2 text-sm text-red-600\">{error}</p> : null}\n <div className=\"mt-4 flex justify-end gap-2\">\n <button\n type=\"button\"\n disabled={busy}\n onClick={surface.close}\n className=\"border-border text-fg hover:bg-hover rounded-md border px-3 py-1.5 text-sm\"\n >\n {t('demo.cancel')}\n </button>\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => void apply()}\n className=\"rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-60\"\n >\n {busy ? t('demo.redactApplying') : t('demo.redactApply')}\n </button>\n </div>\n </Dialog>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAaA,SAAgB,qBAAqB;CACnC,MAAM,IAAI,KAAK;CACf,MAAM,UAAU,WAAW,gBAAgB;CAC3C,MAAM,YAAY,aAAa;CAC/B,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,CAAC,OAAO,YAAY,SAAwB,IAAI;CACtD,MAAM,UAAU,MAAM;CAEtB,IAAI,CAAC,QAAQ,QAAQ,OAAO;CAE5B,MAAM,QAAQ,UAAU,gBAAgB;CACxC,MAAM,aAAa,UAAU,mBAAmB,CAAC,CAAC;CAElD,MAAM,QAAQ,YAAY;EACxB,QAAQ,IAAI;EACZ,SAAS,IAAI;EACb,IAAI;GACF,MAAM,UAAU,SAAS;GACzB,QAAQ,MAAM;EAChB,SAAS,OAAO;GACd,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;EACjE,UAAU;GACR,QAAQ,KAAK;EACf;CACF;CAEA,OACE,qBAAC,QAAD;EACE,YAAY;EACZ,eAAe;GACb,IAAI,CAAC,MAAM,QAAQ,MAAM;EAC3B;EACA,WAAU;EALZ,UAAA;GAOE,oBAAC,MAAD;IAAI,IAAI;IAAS,WAAU;IACxB,UAAA,EAAE,yBAAyB;GAC1B,CAAA;GACJ,oBAAC,KAAD;IAAG,WAAU;IACV,UAAA,EAAE,0BAA0B,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;GACjD,CAAA;GACF,aAAa,IACZ,oBAAC,KAAD;IAAG,WAAU;IACV,UAAA,EAAE,gCAAgC,EAAE,QAAQ,EAAE,OAAO,WAAW,EAAE,CAAC;GACnE,CAAA,IACD;GACH,QAAQ,oBAAC,KAAD;IAAG,WAAU;IAA6B,UAAA;GAAS,CAAA,IAAI;GAChE,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,UAAD;KACE,MAAK;KACL,UAAU;KACV,SAAS,QAAQ;KACjB,WAAU;KAET,UAAA,EAAE,aAAa;IACV,CAAA,GACR,oBAAC,UAAD;KACE,MAAK;KACL,UAAU;KACV,eAAe,KAAK,MAAM;KAC1B,WAAU;KAET,UAAA,OAAO,EAAE,qBAAqB,IAAI,EAAE,kBAAkB;IACjD,CAAA,CACL;;EACC;;AAEZ"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
const require_dialog = require("./dialog-t8F13BL_.cjs");
|
|
2
|
+
let react = require("react");
|
|
3
|
+
let _embedpdf_react_redaction = require("@embedpdf/react/redaction");
|
|
4
|
+
let _embedpdf_react_i18n = require("@embedpdf/react/i18n");
|
|
5
|
+
let _embedpdf_react_shell = require("@embedpdf/react/shell");
|
|
6
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
7
|
+
//#region src/ui/redact-confirm.tsx
|
|
8
|
+
/**
|
|
9
|
+
* The apply-all confirm modal (`redact-confirm` shell surface, `exclusive:
|
|
10
|
+
* 'modal'` via the command router). Shows the pending count and the
|
|
11
|
+
* client-side collateral estimate — other annotations the apply will destroy —
|
|
12
|
+
* before anything irreversible happens. The authoritative collateral count
|
|
13
|
+
* comes back on the result. Escape cancels, unless the apply is running.
|
|
14
|
+
*/
|
|
15
|
+
function RedactConfirmModal() {
|
|
16
|
+
const t = (0, _embedpdf_react_i18n.useT)();
|
|
17
|
+
const surface = (0, _embedpdf_react_shell.useSurface)("redact-confirm");
|
|
18
|
+
const redaction = (0, _embedpdf_react_redaction.useRedaction)();
|
|
19
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
20
|
+
const [error, setError] = (0, react.useState)(null);
|
|
21
|
+
const titleId = (0, react.useId)();
|
|
22
|
+
if (!surface.isOpen) return null;
|
|
23
|
+
const count = redaction.getPendingCount();
|
|
24
|
+
const collateral = redaction.estimateCollateral().count;
|
|
25
|
+
const apply = async () => {
|
|
26
|
+
setBusy(true);
|
|
27
|
+
setError(null);
|
|
28
|
+
try {
|
|
29
|
+
await redaction.applyAll();
|
|
30
|
+
surface.close();
|
|
31
|
+
} catch (error) {
|
|
32
|
+
setError(error instanceof Error ? error.message : String(error));
|
|
33
|
+
} finally {
|
|
34
|
+
setBusy(false);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_dialog.Dialog, {
|
|
38
|
+
labelledBy: titleId,
|
|
39
|
+
onClose: () => {
|
|
40
|
+
if (!busy) surface.close();
|
|
41
|
+
},
|
|
42
|
+
className: "border-border bg-surface w-96 rounded-lg border p-4 shadow-xl",
|
|
43
|
+
children: [
|
|
44
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
45
|
+
id: titleId,
|
|
46
|
+
className: "text-fg text-base font-semibold",
|
|
47
|
+
children: t("demo.redactConfirmTitle")
|
|
48
|
+
}),
|
|
49
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
50
|
+
className: "text-fg-muted mt-2 text-sm",
|
|
51
|
+
children: t("demo.redactConfirmBody", { params: { count } })
|
|
52
|
+
}),
|
|
53
|
+
collateral > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
54
|
+
className: "mt-2 text-sm font-medium text-red-600",
|
|
55
|
+
children: t("demo.redactConfirmCollateral", { params: { count: collateral } })
|
|
56
|
+
}) : null,
|
|
57
|
+
error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
58
|
+
className: "mt-2 text-sm text-red-600",
|
|
59
|
+
children: error
|
|
60
|
+
}) : null,
|
|
61
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
62
|
+
className: "mt-4 flex justify-end gap-2",
|
|
63
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
64
|
+
type: "button",
|
|
65
|
+
disabled: busy,
|
|
66
|
+
onClick: surface.close,
|
|
67
|
+
className: "border-border text-fg hover:bg-hover rounded-md border px-3 py-1.5 text-sm",
|
|
68
|
+
children: t("demo.cancel")
|
|
69
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
70
|
+
type: "button",
|
|
71
|
+
disabled: busy,
|
|
72
|
+
onClick: () => void apply(),
|
|
73
|
+
className: "rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-60",
|
|
74
|
+
children: busy ? t("demo.redactApplying") : t("demo.redactApply")
|
|
75
|
+
})]
|
|
76
|
+
})
|
|
77
|
+
]
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
exports.RedactConfirmModal = RedactConfirmModal;
|
|
82
|
+
|
|
83
|
+
//# sourceMappingURL=redact-confirm-CX_SY2ZN.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact-confirm-CX_SY2ZN.cjs","names":["Dialog"],"sources":["../src/ui/redact-confirm.tsx"],"sourcesContent":["import { useId, useState } from 'react';\nimport { useRedaction } from '@embedpdf/react/redaction';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Dialog } from './dialog';\n\n/**\n * The apply-all confirm modal (`redact-confirm` shell surface, `exclusive:\n * 'modal'` via the command router). Shows the pending count and the\n * client-side collateral estimate — other annotations the apply will destroy —\n * before anything irreversible happens. The authoritative collateral count\n * comes back on the result. Escape cancels, unless the apply is running.\n */\nexport function RedactConfirmModal() {\n const t = useT();\n const surface = useSurface('redact-confirm');\n const redaction = useRedaction();\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const titleId = useId();\n\n if (!surface.isOpen) return null;\n\n const count = redaction.getPendingCount();\n const collateral = redaction.estimateCollateral().count;\n\n const apply = async () => {\n setBusy(true);\n setError(null);\n try {\n await redaction.applyAll();\n surface.close();\n } catch (error) {\n setError(error instanceof Error ? error.message : String(error));\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Dialog\n labelledBy={titleId}\n onClose={() => {\n if (!busy) surface.close();\n }}\n className=\"border-border bg-surface w-96 rounded-lg border p-4 shadow-xl\"\n >\n <h2 id={titleId} className=\"text-fg text-base font-semibold\">\n {t('demo.redactConfirmTitle')}\n </h2>\n <p className=\"text-fg-muted mt-2 text-sm\">\n {t('demo.redactConfirmBody', { params: { count } })}\n </p>\n {collateral > 0 ? (\n <p className=\"mt-2 text-sm font-medium text-red-600\">\n {t('demo.redactConfirmCollateral', { params: { count: collateral } })}\n </p>\n ) : null}\n {error ? <p className=\"mt-2 text-sm text-red-600\">{error}</p> : null}\n <div className=\"mt-4 flex justify-end gap-2\">\n <button\n type=\"button\"\n disabled={busy}\n onClick={surface.close}\n className=\"border-border text-fg hover:bg-hover rounded-md border px-3 py-1.5 text-sm\"\n >\n {t('demo.cancel')}\n </button>\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => void apply()}\n className=\"rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-60\"\n >\n {busy ? t('demo.redactApplying') : t('demo.redactApply')}\n </button>\n </div>\n </Dialog>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAaA,SAAgB,qBAAqB;CACnC,MAAM,KAAA,GAAA,qBAAA,KAAA,CAAS;CACf,MAAM,WAAA,GAAA,sBAAA,WAAA,CAAqB,gBAAgB;CAC3C,MAAM,aAAA,GAAA,0BAAA,aAAA,CAAyB;CAC/B,MAAM,CAAC,MAAM,YAAA,GAAA,MAAA,SAAA,CAAoB,KAAK;CACtC,MAAM,CAAC,OAAO,aAAA,GAAA,MAAA,SAAA,CAAoC,IAAI;CACtD,MAAM,WAAA,GAAA,MAAA,MAAA,CAAgB;CAEtB,IAAI,CAAC,QAAQ,QAAQ,OAAO;CAE5B,MAAM,QAAQ,UAAU,gBAAgB;CACxC,MAAM,aAAa,UAAU,mBAAmB,CAAC,CAAC;CAElD,MAAM,QAAQ,YAAY;EACxB,QAAQ,IAAI;EACZ,SAAS,IAAI;EACb,IAAI;GACF,MAAM,UAAU,SAAS;GACzB,QAAQ,MAAM;EAChB,SAAS,OAAO;GACd,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;EACjE,UAAU;GACR,QAAQ,KAAK;EACf;CACF;CAEA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAACA,eAAAA,QAAD;EACE,YAAY;EACZ,eAAe;GACb,IAAI,CAAC,MAAM,QAAQ,MAAM;EAC3B;EACA,WAAU;EALZ,UAAA;GAOE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;IAAI,IAAI;IAAS,WAAU;IACxB,UAAA,EAAE,yBAAyB;GAC1B,CAAA;GACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;IAAG,WAAU;IACV,UAAA,EAAE,0BAA0B,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;GACjD,CAAA;GACF,aAAa,IACZ,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;IAAG,WAAU;IACV,UAAA,EAAE,gCAAgC,EAAE,QAAQ,EAAE,OAAO,WAAW,EAAE,CAAC;GACnE,CAAA,IACD;GACH,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;IAAG,WAAU;IAA6B,UAAA;GAAS,CAAA,IAAI;GAChE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACE,MAAK;KACL,UAAU;KACV,SAAS,QAAQ;KACjB,WAAU;KAET,UAAA,EAAE,aAAa;IACV,CAAA,GACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACE,MAAK;KACL,UAAU;KACV,eAAe,KAAK,MAAM;KAC1B,WAAU;KAET,UAAA,OAAO,EAAE,qBAAqB,IAAI,EAAE,kBAAkB;IACjD,CAAA,CACL;;EACC;;AAEZ"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const require_icons = require("./icons-x0Tc05bs.cjs");
|
|
2
|
+
let _embedpdf_react_runtime = require("@embedpdf/react/runtime");
|
|
3
|
+
let _embedpdf_react_annotation = require("@embedpdf/react/annotation");
|
|
4
|
+
let _embedpdf_react_redaction = require("@embedpdf/react/redaction");
|
|
5
|
+
let _embedpdf_react_i18n = require("@embedpdf/react/i18n");
|
|
6
|
+
let _embedpdf_react_shell = require("@embedpdf/react/shell");
|
|
7
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
|
+
//#region src/ui/redaction-panel.tsx
|
|
9
|
+
/**
|
|
10
|
+
* The pending-redactions review panel (right sidebar). The list is a live view
|
|
11
|
+
* over the annotation plane — deleting a mark here is deleting the annotation.
|
|
12
|
+
* "Apply all" routes through the confirm modal: the apply is irreversible.
|
|
13
|
+
*/
|
|
14
|
+
function RedactionPanel() {
|
|
15
|
+
const t = (0, _embedpdf_react_i18n.useT)();
|
|
16
|
+
const redaction = (0, _embedpdf_react_redaction.useRedaction)();
|
|
17
|
+
const applying = (0, _embedpdf_react_redaction.useRedactionState)((state) => state.applying);
|
|
18
|
+
const pending = (0, _embedpdf_react_redaction.usePendingRedactions)();
|
|
19
|
+
const anno = (0, _embedpdf_react_runtime.useCapability)(_embedpdf_react_annotation.AnnotationToken);
|
|
20
|
+
const confirm = (0, _embedpdf_react_shell.useSurface)("redact-confirm");
|
|
21
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
22
|
+
className: "flex min-h-0 flex-1 flex-col",
|
|
23
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
24
|
+
className: "min-h-0 flex-1 overflow-y-auto p-2",
|
|
25
|
+
children: pending.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
26
|
+
className: "flex flex-col items-center gap-3 px-4 py-10 text-center",
|
|
27
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons.Icon, {
|
|
28
|
+
name: "redactionSidebar",
|
|
29
|
+
size: 32,
|
|
30
|
+
className: "text-fg-muted"
|
|
31
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
32
|
+
className: "text-fg-muted text-sm",
|
|
33
|
+
children: t("demo.redactionEmpty")
|
|
34
|
+
})]
|
|
35
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
36
|
+
className: "flex flex-col gap-1",
|
|
37
|
+
children: pending.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38
|
+
role: "button",
|
|
39
|
+
tabIndex: 0,
|
|
40
|
+
onClick: () => anno.selection.set([item.ref]),
|
|
41
|
+
onKeyDown: (event) => event.key === "Enter" && anno.selection.set([item.ref]),
|
|
42
|
+
className: "hover:bg-hover group flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-start",
|
|
43
|
+
children: [
|
|
44
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons.Icon, {
|
|
45
|
+
name: item.kind === "area" ? "redactArea" : "redact",
|
|
46
|
+
size: 16,
|
|
47
|
+
className: "text-fg-muted shrink-0"
|
|
48
|
+
}),
|
|
49
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
50
|
+
className: "text-fg min-w-0 flex-1 truncate text-sm",
|
|
51
|
+
children: item.overlayText ?? t(item.kind === "area" ? "demo.redactionArea" : "demo.redactionText")
|
|
52
|
+
}),
|
|
53
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
54
|
+
className: "text-fg-muted shrink-0 text-xs",
|
|
55
|
+
children: t("demo.pageBadge", { params: { page: item.pageIndex >= 0 ? String(item.pageIndex + 1) : "?" } })
|
|
56
|
+
}),
|
|
57
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
58
|
+
type: "button",
|
|
59
|
+
onClick: (event) => {
|
|
60
|
+
event.stopPropagation();
|
|
61
|
+
anno.delete(item.ref);
|
|
62
|
+
},
|
|
63
|
+
className: "text-fg-muted hover:text-fg grid h-6 w-6 shrink-0 place-items-center rounded opacity-0 group-hover:opacity-100",
|
|
64
|
+
title: t("demo.redactionRemove"),
|
|
65
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_icons.Icon, {
|
|
66
|
+
name: "trash",
|
|
67
|
+
size: 14
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
]
|
|
71
|
+
}) }, (0, _embedpdf_react_annotation.annotationKey)(item.ref)))
|
|
72
|
+
})
|
|
73
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
74
|
+
className: "border-border-subtle flex shrink-0 gap-2 border-t p-3",
|
|
75
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
76
|
+
type: "button",
|
|
77
|
+
disabled: pending.length === 0,
|
|
78
|
+
onClick: () => {
|
|
79
|
+
for (const item of pending) anno.delete(item.ref);
|
|
80
|
+
},
|
|
81
|
+
className: "border-border text-fg hover:bg-hover flex-1 rounded-md border px-3 py-1.5 text-sm disabled:opacity-40",
|
|
82
|
+
children: t("commands.redact.clearAll")
|
|
83
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
84
|
+
type: "button",
|
|
85
|
+
disabled: pending.length === 0 || !redaction.canApply() || applying,
|
|
86
|
+
onClick: () => confirm.open(),
|
|
87
|
+
className: "flex-1 rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-40",
|
|
88
|
+
children: t("commands.redact.applyAll")
|
|
89
|
+
})]
|
|
90
|
+
})]
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
//#endregion
|
|
94
|
+
exports.RedactionPanel = RedactionPanel;
|
|
95
|
+
|
|
96
|
+
//# sourceMappingURL=redaction-panel-BmoIl-Ll.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redaction-panel-BmoIl-Ll.cjs","names":["AnnotationToken","Icon"],"sources":["../src/ui/redaction-panel.tsx"],"sourcesContent":["import { useCapability } from '@embedpdf/react/runtime';\nimport { AnnotationToken } from '@embedpdf/react/annotation';\nimport { annotationKey } from '@embedpdf/react/annotation';\nimport { usePendingRedactions, useRedaction, useRedactionState } from '@embedpdf/react/redaction';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\n\n/**\n * The pending-redactions review panel (right sidebar). The list is a live view\n * over the annotation plane — deleting a mark here is deleting the annotation.\n * \"Apply all\" routes through the confirm modal: the apply is irreversible.\n */\nexport function RedactionPanel() {\n const t = useT();\n const redaction = useRedaction();\n const applying = useRedactionState((state) => state.applying);\n const pending = usePendingRedactions();\n const anno = useCapability(AnnotationToken);\n const confirm = useSurface('redact-confirm');\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"min-h-0 flex-1 overflow-y-auto p-2\">\n {pending.length === 0 ? (\n <div className=\"flex flex-col items-center gap-3 px-4 py-10 text-center\">\n <Icon name=\"redactionSidebar\" size={32} className=\"text-fg-muted\" />\n <p className=\"text-fg-muted text-sm\">{t('demo.redactionEmpty')}</p>\n </div>\n ) : (\n <ul className=\"flex flex-col gap-1\">\n {pending.map((item) => (\n <li key={annotationKey(item.ref)}>\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => anno.selection.set([item.ref])}\n onKeyDown={(event) => event.key === 'Enter' && anno.selection.set([item.ref])}\n className=\"hover:bg-hover group flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-start\"\n >\n <Icon\n name={item.kind === 'area' ? 'redactArea' : 'redact'}\n size={16}\n className=\"text-fg-muted shrink-0\"\n />\n <span className=\"text-fg min-w-0 flex-1 truncate text-sm\">\n {item.overlayText ??\n t(item.kind === 'area' ? 'demo.redactionArea' : 'demo.redactionText')}\n </span>\n <span className=\"text-fg-muted shrink-0 text-xs\">\n {t('demo.pageBadge', {\n params: { page: item.pageIndex >= 0 ? String(item.pageIndex + 1) : '?' },\n })}\n </span>\n <button\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n void anno.delete(item.ref);\n }}\n className=\"text-fg-muted hover:text-fg grid h-6 w-6 shrink-0 place-items-center rounded opacity-0 group-hover:opacity-100\"\n title={t('demo.redactionRemove')}\n >\n <Icon name=\"trash\" size={14} />\n </button>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n <div className=\"border-border-subtle flex shrink-0 gap-2 border-t p-3\">\n <button\n type=\"button\"\n disabled={pending.length === 0}\n onClick={() => {\n for (const item of pending) void anno.delete(item.ref);\n }}\n className=\"border-border text-fg hover:bg-hover flex-1 rounded-md border px-3 py-1.5 text-sm disabled:opacity-40\"\n >\n {t('commands.redact.clearAll')}\n </button>\n <button\n type=\"button\"\n disabled={pending.length === 0 || !redaction.canApply() || applying}\n onClick={() => confirm.open()}\n className=\"flex-1 rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-40\"\n >\n {t('commands.redact.applyAll')}\n </button>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,SAAgB,iBAAiB;CAC/B,MAAM,KAAA,GAAA,qBAAA,KAAA,CAAS;CACf,MAAM,aAAA,GAAA,0BAAA,aAAA,CAAyB;CAC/B,MAAM,YAAA,GAAA,0BAAA,kBAAA,EAA8B,UAAU,MAAM,QAAQ;CAC5D,MAAM,WAAA,GAAA,0BAAA,qBAAA,CAA+B;CACrC,MAAM,QAAA,GAAA,wBAAA,cAAA,CAAqBA,2BAAAA,eAAe;CAC1C,MAAM,WAAA,GAAA,sBAAA,WAAA,CAAqB,gBAAgB;CAE3C,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;GAAK,WAAU;GACZ,UAAA,QAAQ,WAAW,IAClB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,cAAAA,MAAD;KAAM,MAAK;KAAmB,MAAM;KAAI,WAAU;IAAiB,CAAA,GACnE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;KAAG,WAAU;KAAyB,UAAA,EAAE,qBAAqB;IAAK,CAAA,CAC/D;GAEL,CAAA,IAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;IAAI,WAAU;IACX,UAAA,QAAQ,KAAK,SACZ,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KACE,MAAK;KACL,UAAU;KACV,eAAe,KAAK,UAAU,IAAI,CAAC,KAAK,GAAG,CAAC;KAC5C,YAAY,UAAU,MAAM,QAAQ,WAAW,KAAK,UAAU,IAAI,CAAC,KAAK,GAAG,CAAC;KAC5E,WAAU;KALZ,UAAA;MAOE,iBAAA,GAAA,kBAAA,IAAA,CAACA,cAAAA,MAAD;OACE,MAAM,KAAK,SAAS,SAAS,eAAe;OAC5C,MAAM;OACN,WAAU;MACX,CAAA;MACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAU;OACb,UAAA,KAAK,eACJ,EAAE,KAAK,SAAS,SAAS,uBAAuB,oBAAoB;MAClE,CAAA;MACN,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAU;OACb,UAAA,EAAE,kBAAkB,EACnB,QAAQ,EAAE,MAAM,KAAK,aAAa,IAAI,OAAO,KAAK,YAAY,CAAC,IAAI,IAAI,EACzE,CAAC;MACG,CAAA;MACN,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OACE,MAAK;OACL,UAAU,UAAU;QAClB,MAAM,gBAAgB;QACtB,KAAU,OAAO,KAAK,GAAG;OAC3B;OACA,WAAU;OACV,OAAO,EAAE,sBAAsB;OAE/B,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACA,cAAAA,MAAD;QAAM,MAAK;QAAQ,MAAM;OAAK,CAAA;MACxB,CAAA;KACL;IACH,CAAA,EAAA,IAAA,GAAA,2BAAA,cAAA,CAlCmB,KAAK,GAAG,CAkC3B,CACL;GACC,CAAA;EAEH,CAAA,GACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;IACE,MAAK;IACL,UAAU,QAAQ,WAAW;IAC7B,eAAe;KACb,KAAK,MAAM,QAAQ,SAAS,KAAU,OAAO,KAAK,GAAG;IACvD;IACA,WAAU;IAET,UAAA,EAAE,0BAA0B;GACvB,CAAA,GACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;IACE,MAAK;IACL,UAAU,QAAQ,WAAW,KAAK,CAAC,UAAU,SAAS,KAAK;IAC3D,eAAe,QAAQ,KAAK;IAC5B,WAAU;IAET,UAAA,EAAE,0BAA0B;GACvB,CAAA,CACL;EACF,CAAA,CAAA;;AAET"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { n as Icon } from "./icons-BrK5iVL8.js";
|
|
2
|
+
import { useCapability } from "@embedpdf/react/runtime";
|
|
3
|
+
import { AnnotationToken, annotationKey } from "@embedpdf/react/annotation";
|
|
4
|
+
import { usePendingRedactions, useRedaction, useRedactionState } from "@embedpdf/react/redaction";
|
|
5
|
+
import { useT } from "@embedpdf/react/i18n";
|
|
6
|
+
import { useSurface } from "@embedpdf/react/shell";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
//#region src/ui/redaction-panel.tsx
|
|
9
|
+
/**
|
|
10
|
+
* The pending-redactions review panel (right sidebar). The list is a live view
|
|
11
|
+
* over the annotation plane — deleting a mark here is deleting the annotation.
|
|
12
|
+
* "Apply all" routes through the confirm modal: the apply is irreversible.
|
|
13
|
+
*/
|
|
14
|
+
function RedactionPanel() {
|
|
15
|
+
const t = useT();
|
|
16
|
+
const redaction = useRedaction();
|
|
17
|
+
const applying = useRedactionState((state) => state.applying);
|
|
18
|
+
const pending = usePendingRedactions();
|
|
19
|
+
const anno = useCapability(AnnotationToken);
|
|
20
|
+
const confirm = useSurface("redact-confirm");
|
|
21
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
22
|
+
className: "flex min-h-0 flex-1 flex-col",
|
|
23
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
24
|
+
className: "min-h-0 flex-1 overflow-y-auto p-2",
|
|
25
|
+
children: pending.length === 0 ? /* @__PURE__ */ jsxs("div", {
|
|
26
|
+
className: "flex flex-col items-center gap-3 px-4 py-10 text-center",
|
|
27
|
+
children: [/* @__PURE__ */ jsx(Icon, {
|
|
28
|
+
name: "redactionSidebar",
|
|
29
|
+
size: 32,
|
|
30
|
+
className: "text-fg-muted"
|
|
31
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
32
|
+
className: "text-fg-muted text-sm",
|
|
33
|
+
children: t("demo.redactionEmpty")
|
|
34
|
+
})]
|
|
35
|
+
}) : /* @__PURE__ */ jsx("ul", {
|
|
36
|
+
className: "flex flex-col gap-1",
|
|
37
|
+
children: pending.map((item) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("div", {
|
|
38
|
+
role: "button",
|
|
39
|
+
tabIndex: 0,
|
|
40
|
+
onClick: () => anno.selection.set([item.ref]),
|
|
41
|
+
onKeyDown: (event) => event.key === "Enter" && anno.selection.set([item.ref]),
|
|
42
|
+
className: "hover:bg-hover group flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-start",
|
|
43
|
+
children: [
|
|
44
|
+
/* @__PURE__ */ jsx(Icon, {
|
|
45
|
+
name: item.kind === "area" ? "redactArea" : "redact",
|
|
46
|
+
size: 16,
|
|
47
|
+
className: "text-fg-muted shrink-0"
|
|
48
|
+
}),
|
|
49
|
+
/* @__PURE__ */ jsx("span", {
|
|
50
|
+
className: "text-fg min-w-0 flex-1 truncate text-sm",
|
|
51
|
+
children: item.overlayText ?? t(item.kind === "area" ? "demo.redactionArea" : "demo.redactionText")
|
|
52
|
+
}),
|
|
53
|
+
/* @__PURE__ */ jsx("span", {
|
|
54
|
+
className: "text-fg-muted shrink-0 text-xs",
|
|
55
|
+
children: t("demo.pageBadge", { params: { page: item.pageIndex >= 0 ? String(item.pageIndex + 1) : "?" } })
|
|
56
|
+
}),
|
|
57
|
+
/* @__PURE__ */ jsx("button", {
|
|
58
|
+
type: "button",
|
|
59
|
+
onClick: (event) => {
|
|
60
|
+
event.stopPropagation();
|
|
61
|
+
anno.delete(item.ref);
|
|
62
|
+
},
|
|
63
|
+
className: "text-fg-muted hover:text-fg grid h-6 w-6 shrink-0 place-items-center rounded opacity-0 group-hover:opacity-100",
|
|
64
|
+
title: t("demo.redactionRemove"),
|
|
65
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
|
66
|
+
name: "trash",
|
|
67
|
+
size: 14
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
]
|
|
71
|
+
}) }, annotationKey(item.ref)))
|
|
72
|
+
})
|
|
73
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
74
|
+
className: "border-border-subtle flex shrink-0 gap-2 border-t p-3",
|
|
75
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
76
|
+
type: "button",
|
|
77
|
+
disabled: pending.length === 0,
|
|
78
|
+
onClick: () => {
|
|
79
|
+
for (const item of pending) anno.delete(item.ref);
|
|
80
|
+
},
|
|
81
|
+
className: "border-border text-fg hover:bg-hover flex-1 rounded-md border px-3 py-1.5 text-sm disabled:opacity-40",
|
|
82
|
+
children: t("commands.redact.clearAll")
|
|
83
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
84
|
+
type: "button",
|
|
85
|
+
disabled: pending.length === 0 || !redaction.canApply() || applying,
|
|
86
|
+
onClick: () => confirm.open(),
|
|
87
|
+
className: "flex-1 rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-40",
|
|
88
|
+
children: t("commands.redact.applyAll")
|
|
89
|
+
})]
|
|
90
|
+
})]
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
//#endregion
|
|
94
|
+
export { RedactionPanel };
|
|
95
|
+
|
|
96
|
+
//# sourceMappingURL=redaction-panel-IJDshSJI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redaction-panel-IJDshSJI.js","names":[],"sources":["../src/ui/redaction-panel.tsx"],"sourcesContent":["import { useCapability } from '@embedpdf/react/runtime';\nimport { AnnotationToken } from '@embedpdf/react/annotation';\nimport { annotationKey } from '@embedpdf/react/annotation';\nimport { usePendingRedactions, useRedaction, useRedactionState } from '@embedpdf/react/redaction';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\n\n/**\n * The pending-redactions review panel (right sidebar). The list is a live view\n * over the annotation plane — deleting a mark here is deleting the annotation.\n * \"Apply all\" routes through the confirm modal: the apply is irreversible.\n */\nexport function RedactionPanel() {\n const t = useT();\n const redaction = useRedaction();\n const applying = useRedactionState((state) => state.applying);\n const pending = usePendingRedactions();\n const anno = useCapability(AnnotationToken);\n const confirm = useSurface('redact-confirm');\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"min-h-0 flex-1 overflow-y-auto p-2\">\n {pending.length === 0 ? (\n <div className=\"flex flex-col items-center gap-3 px-4 py-10 text-center\">\n <Icon name=\"redactionSidebar\" size={32} className=\"text-fg-muted\" />\n <p className=\"text-fg-muted text-sm\">{t('demo.redactionEmpty')}</p>\n </div>\n ) : (\n <ul className=\"flex flex-col gap-1\">\n {pending.map((item) => (\n <li key={annotationKey(item.ref)}>\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => anno.selection.set([item.ref])}\n onKeyDown={(event) => event.key === 'Enter' && anno.selection.set([item.ref])}\n className=\"hover:bg-hover group flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-start\"\n >\n <Icon\n name={item.kind === 'area' ? 'redactArea' : 'redact'}\n size={16}\n className=\"text-fg-muted shrink-0\"\n />\n <span className=\"text-fg min-w-0 flex-1 truncate text-sm\">\n {item.overlayText ??\n t(item.kind === 'area' ? 'demo.redactionArea' : 'demo.redactionText')}\n </span>\n <span className=\"text-fg-muted shrink-0 text-xs\">\n {t('demo.pageBadge', {\n params: { page: item.pageIndex >= 0 ? String(item.pageIndex + 1) : '?' },\n })}\n </span>\n <button\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n void anno.delete(item.ref);\n }}\n className=\"text-fg-muted hover:text-fg grid h-6 w-6 shrink-0 place-items-center rounded opacity-0 group-hover:opacity-100\"\n title={t('demo.redactionRemove')}\n >\n <Icon name=\"trash\" size={14} />\n </button>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n <div className=\"border-border-subtle flex shrink-0 gap-2 border-t p-3\">\n <button\n type=\"button\"\n disabled={pending.length === 0}\n onClick={() => {\n for (const item of pending) void anno.delete(item.ref);\n }}\n className=\"border-border text-fg hover:bg-hover flex-1 rounded-md border px-3 py-1.5 text-sm disabled:opacity-40\"\n >\n {t('commands.redact.clearAll')}\n </button>\n <button\n type=\"button\"\n disabled={pending.length === 0 || !redaction.canApply() || applying}\n onClick={() => confirm.open()}\n className=\"flex-1 rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-40\"\n >\n {t('commands.redact.applyAll')}\n </button>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,SAAgB,iBAAiB;CAC/B,MAAM,IAAI,KAAK;CACf,MAAM,YAAY,aAAa;CAC/B,MAAM,WAAW,mBAAmB,UAAU,MAAM,QAAQ;CAC5D,MAAM,UAAU,qBAAqB;CACrC,MAAM,OAAO,cAAc,eAAe;CAC1C,MAAM,UAAU,WAAW,gBAAgB;CAE3C,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,OAAD;GAAK,WAAU;GACZ,UAAA,QAAQ,WAAW,IAClB,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,MAAD;KAAM,MAAK;KAAmB,MAAM;KAAI,WAAU;IAAiB,CAAA,GACnE,oBAAC,KAAD;KAAG,WAAU;KAAyB,UAAA,EAAE,qBAAqB;IAAK,CAAA,CAC/D;GAEL,CAAA,IAAA,oBAAC,MAAD;IAAI,WAAU;IACX,UAAA,QAAQ,KAAK,SACZ,oBAAC,MAAD,EAAA,UACE,qBAAC,OAAD;KACE,MAAK;KACL,UAAU;KACV,eAAe,KAAK,UAAU,IAAI,CAAC,KAAK,GAAG,CAAC;KAC5C,YAAY,UAAU,MAAM,QAAQ,WAAW,KAAK,UAAU,IAAI,CAAC,KAAK,GAAG,CAAC;KAC5E,WAAU;KALZ,UAAA;MAOE,oBAAC,MAAD;OACE,MAAM,KAAK,SAAS,SAAS,eAAe;OAC5C,MAAM;OACN,WAAU;MACX,CAAA;MACD,oBAAC,QAAD;OAAM,WAAU;OACb,UAAA,KAAK,eACJ,EAAE,KAAK,SAAS,SAAS,uBAAuB,oBAAoB;MAClE,CAAA;MACN,oBAAC,QAAD;OAAM,WAAU;OACb,UAAA,EAAE,kBAAkB,EACnB,QAAQ,EAAE,MAAM,KAAK,aAAa,IAAI,OAAO,KAAK,YAAY,CAAC,IAAI,IAAI,EACzE,CAAC;MACG,CAAA;MACN,oBAAC,UAAD;OACE,MAAK;OACL,UAAU,UAAU;QAClB,MAAM,gBAAgB;QACtB,KAAU,OAAO,KAAK,GAAG;OAC3B;OACA,WAAU;OACV,OAAO,EAAE,sBAAsB;OAE/B,UAAA,oBAAC,MAAD;QAAM,MAAK;QAAQ,MAAM;OAAK,CAAA;MACxB,CAAA;KACL;IACH,CAAA,EAAA,GAlCK,cAAc,KAAK,GAAG,CAkC3B,CACL;GACC,CAAA;EAEH,CAAA,GACL,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,UAAD;IACE,MAAK;IACL,UAAU,QAAQ,WAAW;IAC7B,eAAe;KACb,KAAK,MAAM,QAAQ,SAAS,KAAU,OAAO,KAAK,GAAG;IACvD;IACA,WAAU;IAET,UAAA,EAAE,0BAA0B;GACvB,CAAA,GACR,oBAAC,UAAD;IACE,MAAK;IACL,UAAU,QAAQ,WAAW,KAAK,CAAC,UAAU,SAAS,KAAK;IAC3D,eAAe,QAAQ,KAAK;IAC5B,WAAU;IAET,UAAA,EAAE,0BAA0B;GACvB,CAAA,CACL;EACF,CAAA,CAAA;;AAET"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { n as Icon } from "./icons-BrK5iVL8.js";
|
|
2
|
+
import { r as buttonClass } from "./toolbar-z9od3tKl.js";
|
|
3
|
+
import { i as useCloseOnPick } from "./sheet-R6XDgyEf.js";
|
|
4
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
5
|
+
import { useSearch, useSearchHits, useSearchState, validateSearchQuery } from "@embedpdf/react/search";
|
|
6
|
+
import { useT } from "@embedpdf/react/i18n";
|
|
7
|
+
import { useSurfaceFocus } from "@embedpdf/react/shell";
|
|
8
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
//#region src/ui/search-panel.tsx
|
|
10
|
+
/**
|
|
11
|
+
* The search panel — the search sidebar on the plugin-search capability. One
|
|
12
|
+
* shape end to end: the flat `SearchQuery` {text, regex, matchCase, wholeWord}
|
|
13
|
+
* is what the engine matches, what the plugin stores (document-scoped,
|
|
14
|
+
* survives the sidebar closing), and what this box renders.
|
|
15
|
+
* The panel keeps only a draft of it for keystroke/debounce echo.
|
|
16
|
+
*
|
|
17
|
+
* Data flow:
|
|
18
|
+
* type / toggle → validateSearchQuery → (debounced) search(draftQuery)
|
|
19
|
+
* useSearchState() → query / status / hitCount / activeHitIndex (reactive)
|
|
20
|
+
* useSearchHits() → the streamed hit list
|
|
21
|
+
* click a hit / prev / next → goTo/prev/next (capability reveals it on-page)
|
|
22
|
+
*
|
|
23
|
+
* The look: a magnifier input with a clear button, option checkboxes, a
|
|
24
|
+
* results-found counter with prev/next, and a per-page grouped snippet list
|
|
25
|
+
* with the match bolded and the active hit accented, in this app's semantic
|
|
26
|
+
* tokens. matchDiacritics exists in the engine but is deliberately not
|
|
27
|
+
* exposed here.
|
|
28
|
+
*/
|
|
29
|
+
const DEBOUNCE_MS = 300;
|
|
30
|
+
/** Field-wise equality on the flat query — the mount/echo no-op guard. */
|
|
31
|
+
const sameQuery = (left, right) => left != null && left.text === right.text && !!left.regex === !!right.regex && !!left.matchCase === !!right.matchCase && !!left.wholeWord === !!right.wholeWord;
|
|
32
|
+
function Checkbox({ label, checked, onChange }) {
|
|
33
|
+
return /* @__PURE__ */ jsxs("label", {
|
|
34
|
+
className: "text-fg-secondary flex cursor-pointer select-none items-center gap-2 text-xs font-medium",
|
|
35
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
36
|
+
className: "relative flex h-4 w-4 items-center justify-center",
|
|
37
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
38
|
+
type: "checkbox",
|
|
39
|
+
checked,
|
|
40
|
+
onChange: (event) => onChange(event.target.checked),
|
|
41
|
+
className: "border-border bg-surface checked:border-accent checked:bg-accent rounded-xs peer h-4 w-4 shrink-0 appearance-none border transition-colors"
|
|
42
|
+
}), /* @__PURE__ */ jsx("svg", {
|
|
43
|
+
viewBox: "0 0 24 24",
|
|
44
|
+
className: "text-on-accent pointer-events-none absolute h-3 w-3 opacity-0 peer-checked:opacity-100",
|
|
45
|
+
fill: "none",
|
|
46
|
+
stroke: "currentColor",
|
|
47
|
+
strokeWidth: 3,
|
|
48
|
+
strokeLinecap: "round",
|
|
49
|
+
strokeLinejoin: "round",
|
|
50
|
+
children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" })
|
|
51
|
+
})]
|
|
52
|
+
}), label]
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function renderSnippet(snippet) {
|
|
56
|
+
if (!snippet) return null;
|
|
57
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
58
|
+
snippet.before,
|
|
59
|
+
/* @__PURE__ */ jsx("span", {
|
|
60
|
+
className: "text-accent font-semibold",
|
|
61
|
+
children: snippet.match
|
|
62
|
+
}),
|
|
63
|
+
snippet.after
|
|
64
|
+
] });
|
|
65
|
+
}
|
|
66
|
+
function HitLine({ hit, active, onClick }) {
|
|
67
|
+
const ref = useRef(null);
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (active) ref.current?.scrollIntoView({
|
|
70
|
+
behavior: "smooth",
|
|
71
|
+
block: "nearest"
|
|
72
|
+
});
|
|
73
|
+
}, [active]);
|
|
74
|
+
return /* @__PURE__ */ jsx("button", {
|
|
75
|
+
ref,
|
|
76
|
+
type: "button",
|
|
77
|
+
onClick,
|
|
78
|
+
className: `w-full rounded border p-2 text-left text-sm transition-colors ${active ? "border-accent bg-accent-light text-fg" : "border-border-subtle bg-surface text-fg-secondary hover:bg-hover"}`,
|
|
79
|
+
children: /* @__PURE__ */ jsx("span", { children: renderSnippet(hit.snippet) })
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function SearchPanel() {
|
|
83
|
+
const t = useT();
|
|
84
|
+
const search = useSearch();
|
|
85
|
+
const { query, status, hitCount, activeHitIndex } = useSearchState();
|
|
86
|
+
const hits = useSearchHits();
|
|
87
|
+
const closeOnPick = useCloseOnPick();
|
|
88
|
+
const [draft, setDraft] = useState(() => query?.text ?? "");
|
|
89
|
+
const [matchCase, setMatchCase] = useState(() => query?.matchCase ?? false);
|
|
90
|
+
const [wholeWord, setWholeWord] = useState(() => query?.wholeWord ?? false);
|
|
91
|
+
const [regex, setRegex] = useState(() => query?.regex ?? false);
|
|
92
|
+
const inputRef = useRef(null);
|
|
93
|
+
useSurfaceFocus("search", inputRef, { select: true });
|
|
94
|
+
const draftQuery = {
|
|
95
|
+
text: draft,
|
|
96
|
+
regex,
|
|
97
|
+
matchCase,
|
|
98
|
+
wholeWord
|
|
99
|
+
};
|
|
100
|
+
const validation = draft && regex ? validateSearchQuery(draftQuery) : { ok: true };
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
if (!validation.ok || sameQuery(query, draftQuery)) return;
|
|
103
|
+
if (draft === "" && query === null) return;
|
|
104
|
+
const id = setTimeout(() => search.search(draftQuery), DEBOUNCE_MS);
|
|
105
|
+
return () => clearTimeout(id);
|
|
106
|
+
}, [
|
|
107
|
+
draft,
|
|
108
|
+
matchCase,
|
|
109
|
+
wholeWord,
|
|
110
|
+
regex,
|
|
111
|
+
query,
|
|
112
|
+
validation.ok,
|
|
113
|
+
search
|
|
114
|
+
]);
|
|
115
|
+
const grouped = useMemo(() => {
|
|
116
|
+
const map = /* @__PURE__ */ new Map();
|
|
117
|
+
hits.forEach((hit, index) => {
|
|
118
|
+
const arr = map.get(hit.pageIndex);
|
|
119
|
+
if (arr) arr.push({
|
|
120
|
+
hit,
|
|
121
|
+
index
|
|
122
|
+
});
|
|
123
|
+
else map.set(hit.pageIndex, [{
|
|
124
|
+
hit,
|
|
125
|
+
index
|
|
126
|
+
}]);
|
|
127
|
+
});
|
|
128
|
+
return [...map.entries()].sort((left, right) => left[0] - right[0]);
|
|
129
|
+
}, [hits]);
|
|
130
|
+
const searching = status === "searching";
|
|
131
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
132
|
+
className: "flex min-h-0 flex-1 flex-col",
|
|
133
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
134
|
+
className: "p-3",
|
|
135
|
+
children: [
|
|
136
|
+
/* @__PURE__ */ jsxs("div", {
|
|
137
|
+
className: "relative",
|
|
138
|
+
children: [
|
|
139
|
+
/* @__PURE__ */ jsx("div", {
|
|
140
|
+
className: "text-fg-muted pointer-events-none absolute inset-y-0 start-0 flex items-center ps-2.5",
|
|
141
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
|
142
|
+
name: "search",
|
|
143
|
+
size: 16
|
|
144
|
+
})
|
|
145
|
+
}),
|
|
146
|
+
/* @__PURE__ */ jsx("input", {
|
|
147
|
+
ref: inputRef,
|
|
148
|
+
type: "text",
|
|
149
|
+
value: draft,
|
|
150
|
+
placeholder: t("demo.searchPlaceholder"),
|
|
151
|
+
onChange: (event) => setDraft(event.target.value),
|
|
152
|
+
className: `bg-surface text-fg w-full rounded-md border py-1.5 pe-9 ps-8 text-sm outline-none focus:ring-1 ${validation.ok ? "border-border focus:border-accent focus:ring-accent" : "border-red-400 focus:border-red-400 focus:ring-red-400"}`
|
|
153
|
+
}),
|
|
154
|
+
draft && /* @__PURE__ */ jsx("button", {
|
|
155
|
+
type: "button",
|
|
156
|
+
onClick: () => {
|
|
157
|
+
setDraft("");
|
|
158
|
+
inputRef.current?.focus();
|
|
159
|
+
},
|
|
160
|
+
className: "text-fg-muted hover:text-fg-secondary absolute inset-y-0 end-0 flex items-center pe-2.5",
|
|
161
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
|
162
|
+
name: "x",
|
|
163
|
+
size: 16
|
|
164
|
+
})
|
|
165
|
+
})
|
|
166
|
+
]
|
|
167
|
+
}),
|
|
168
|
+
!validation.ok && /* @__PURE__ */ jsx("p", {
|
|
169
|
+
className: "mt-1.5 text-xs text-red-500",
|
|
170
|
+
children: validation.message
|
|
171
|
+
}),
|
|
172
|
+
/* @__PURE__ */ jsxs("div", {
|
|
173
|
+
className: "mt-3 flex flex-col gap-2",
|
|
174
|
+
children: [
|
|
175
|
+
/* @__PURE__ */ jsx(Checkbox, {
|
|
176
|
+
label: t("demo.searchCaseSensitive"),
|
|
177
|
+
checked: matchCase,
|
|
178
|
+
onChange: setMatchCase
|
|
179
|
+
}),
|
|
180
|
+
/* @__PURE__ */ jsx(Checkbox, {
|
|
181
|
+
label: t("demo.searchWholeWord"),
|
|
182
|
+
checked: wholeWord,
|
|
183
|
+
onChange: setWholeWord
|
|
184
|
+
}),
|
|
185
|
+
/* @__PURE__ */ jsx(Checkbox, {
|
|
186
|
+
label: t("demo.searchRegex"),
|
|
187
|
+
checked: regex,
|
|
188
|
+
onChange: setRegex
|
|
189
|
+
})
|
|
190
|
+
]
|
|
191
|
+
}),
|
|
192
|
+
/* @__PURE__ */ jsx("hr", { className: "border-border-subtle mb-2 mt-4" }),
|
|
193
|
+
status !== "idle" && /* @__PURE__ */ jsxs("div", {
|
|
194
|
+
className: "flex h-8 items-center justify-between",
|
|
195
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
196
|
+
className: "text-fg-muted text-xs",
|
|
197
|
+
children: hitCount === 0 ? t(searching ? "demo.searchSearching" : "demo.searchNoResults") : t("demo.searchResults", { params: { count: hitCount } })
|
|
198
|
+
}), hitCount > 1 && /* @__PURE__ */ jsxs("div", {
|
|
199
|
+
className: "flex items-center",
|
|
200
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
201
|
+
type: "button",
|
|
202
|
+
title: t("demo.searchPrevious"),
|
|
203
|
+
className: buttonClass(false),
|
|
204
|
+
onClick: () => search.previousHit(),
|
|
205
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
|
206
|
+
name: "chevronLeft",
|
|
207
|
+
size: 20,
|
|
208
|
+
className: "rtl:-scale-x-100"
|
|
209
|
+
})
|
|
210
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
211
|
+
type: "button",
|
|
212
|
+
title: t("demo.searchNext"),
|
|
213
|
+
className: buttonClass(false),
|
|
214
|
+
onClick: () => search.nextHit(),
|
|
215
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
|
216
|
+
name: "chevronRight",
|
|
217
|
+
size: 20,
|
|
218
|
+
className: "rtl:-scale-x-100"
|
|
219
|
+
})
|
|
220
|
+
})]
|
|
221
|
+
})]
|
|
222
|
+
})
|
|
223
|
+
]
|
|
224
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
225
|
+
className: "flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto px-3 pb-3",
|
|
226
|
+
children: grouped.map(([pageIndex, items]) => /* @__PURE__ */ jsxs("div", {
|
|
227
|
+
className: "mt-2 first:mt-0",
|
|
228
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
229
|
+
className: "bg-surface/80 text-fg-muted py-2 text-xs backdrop-blur",
|
|
230
|
+
children: t("demo.searchPage", { params: { page: pageIndex + 1 } })
|
|
231
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
232
|
+
className: "flex flex-col gap-2",
|
|
233
|
+
children: items.map(({ hit, index }) => /* @__PURE__ */ jsx(HitLine, {
|
|
234
|
+
hit,
|
|
235
|
+
active: index === activeHitIndex,
|
|
236
|
+
onClick: () => {
|
|
237
|
+
search.goToHit(index);
|
|
238
|
+
closeOnPick();
|
|
239
|
+
}
|
|
240
|
+
}, index))
|
|
241
|
+
})]
|
|
242
|
+
}, pageIndex))
|
|
243
|
+
})]
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
//#endregion
|
|
247
|
+
export { SearchPanel };
|
|
248
|
+
|
|
249
|
+
//# sourceMappingURL=search-panel-HfIhJm1M.js.map
|