@embedpdf/react 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/dist/AnnotationList-CkijRHet-HEFNUIZe.d.cts +877 -0
- package/dist/AnnotationList-CkijRHet-HEFNUIZe.d.ts +877 -0
- package/dist/actions.cjs +25 -5
- package/dist/actions.cjs.map +1 -1
- package/dist/actions.d.cts +18 -5
- package/dist/actions.d.ts +18 -5
- package/dist/actions.js +22 -6
- package/dist/actions.js.map +1 -1
- package/dist/anchored-DeX95xSd.d.ts +85 -0
- package/dist/anchored-DzN3JywS.d.cts +85 -0
- package/dist/anchored.cjs +71 -28
- package/dist/anchored.cjs.map +1 -1
- package/dist/anchored.d.cts +2 -45
- package/dist/anchored.d.ts +2 -45
- package/dist/anchored.js +56 -19
- package/dist/anchored.js.map +1 -1
- package/dist/annotation-B48UT2ln.d.ts +302 -0
- package/dist/annotation-C1ttM8Wj.js +708 -0
- package/dist/annotation-C1ttM8Wj.js.map +1 -0
- package/dist/annotation-C9dVwo9b.d.cts +302 -0
- package/dist/annotation-Dex5EBda.cjs +830 -0
- package/dist/annotation-Dex5EBda.cjs.map +1 -0
- package/dist/annotation.cjs +20 -783
- package/dist/annotation.d.cts +2 -2
- package/dist/annotation.d.ts +2 -2
- package/dist/annotation.js +2 -768
- package/dist/commands.cjs +68 -28
- package/dist/commands.cjs.map +1 -1
- package/dist/commands.d.cts +37 -10
- package/dist/commands.d.ts +37 -10
- package/dist/commands.js +68 -31
- package/dist/commands.js.map +1 -1
- package/dist/form-55izw0jS.js +511 -0
- package/dist/form-55izw0jS.js.map +1 -0
- package/dist/form-BNqQfGGH.cjs +548 -0
- package/dist/form-BNqQfGGH.cjs.map +1 -0
- package/dist/form.cjs +5 -5
- package/dist/form.d.cts +32 -25
- package/dist/form.d.ts +32 -25
- package/dist/form.js +2 -3
- package/dist/history.cjs +38 -0
- package/dist/history.cjs.map +1 -0
- package/dist/history.d.cts +27 -0
- package/dist/history.d.ts +27 -0
- package/dist/history.js +27 -0
- package/dist/history.js.map +1 -0
- package/dist/i18n.cjs +26 -30
- package/dist/i18n.cjs.map +1 -1
- package/dist/i18n.d.cts +24 -21
- package/dist/i18n.d.ts +24 -21
- package/dist/i18n.js +24 -31
- package/dist/i18n.js.map +1 -1
- package/dist/index.cjs +213 -57
- package/dist/index.d.cts +32 -31
- package/dist/index.d.ts +32 -31
- package/dist/index.js +33 -29
- package/dist/inert-CmBEbKCn.cjs +19 -0
- package/dist/inert-CmBEbKCn.cjs.map +1 -0
- package/dist/inert-D8fkennb.js +14 -0
- package/dist/inert-D8fkennb.js.map +1 -0
- package/dist/interaction.cjs +48 -102
- package/dist/interaction.cjs.map +1 -1
- package/dist/interaction.d.cts +23 -32
- package/dist/interaction.d.ts +23 -32
- package/dist/interaction.js +33 -102
- package/dist/interaction.js.map +1 -1
- package/dist/link.cjs +65 -104
- package/dist/link.cjs.map +1 -1
- package/dist/link.d.cts +21 -16
- package/dist/link.d.ts +22 -17
- package/dist/link.js +67 -107
- package/dist/link.js.map +1 -1
- package/dist/measurement.cjs +56 -0
- package/dist/measurement.cjs.map +1 -0
- package/dist/measurement.d.cts +38 -0
- package/dist/measurement.d.ts +38 -0
- package/dist/measurement.js +42 -0
- package/dist/measurement.js.map +1 -0
- package/dist/metadata.cjs +20 -7
- package/dist/metadata.cjs.map +1 -1
- package/dist/metadata.d.cts +22 -7
- package/dist/metadata.d.ts +22 -7
- package/dist/metadata.js +20 -10
- package/dist/metadata.js.map +1 -1
- package/dist/page-edit.cjs +7 -3
- package/dist/page-edit.cjs.map +1 -1
- package/dist/page-edit.d.cts +6 -2
- package/dist/page-edit.d.ts +6 -2
- package/dist/page-edit.js +7 -4
- package/dist/page-edit.js.map +1 -1
- package/dist/page-layers-Bkaaz8Zf.js +26 -0
- package/dist/page-layers-Bkaaz8Zf.js.map +1 -0
- package/dist/page-layers-BloZDoOV.cjs +37 -0
- package/dist/page-layers-BloZDoOV.cjs.map +1 -0
- package/dist/page-view.cjs +89 -82
- package/dist/page-view.cjs.map +1 -1
- package/dist/page-view.d.cts +14 -7
- package/dist/page-view.d.ts +18 -11
- package/dist/page-view.js +86 -81
- package/dist/page-view.js.map +1 -1
- package/dist/redaction.cjs +30 -15
- package/dist/redaction.cjs.map +1 -1
- package/dist/redaction.d.cts +27 -9
- package/dist/redaction.d.ts +27 -9
- package/dist/redaction.js +29 -18
- package/dist/redaction.js.map +1 -1
- package/dist/render.cjs +71 -46
- package/dist/render.cjs.map +1 -1
- package/dist/render.d.cts +17 -5
- package/dist/render.d.ts +17 -5
- package/dist/render.js +70 -49
- package/dist/render.js.map +1 -1
- package/dist/runtime-B6xcPsEb.js +398 -0
- package/dist/runtime-B6xcPsEb.js.map +1 -0
- package/dist/runtime-DBEBlpQV.d.cts +237 -0
- package/dist/runtime-V3MVMb91.d.ts +237 -0
- package/dist/runtime-fzpGv78v.cjs +555 -0
- package/dist/runtime-fzpGv78v.cjs.map +1 -0
- package/dist/runtime.cjs +45 -324
- package/dist/runtime.d.cts +2 -2
- package/dist/runtime.d.ts +2 -2
- package/dist/runtime.js +2 -306
- package/dist/search.cjs +81 -50
- package/dist/search.cjs.map +1 -1
- package/dist/search.d.cts +36 -24
- package/dist/search.d.ts +36 -24
- package/dist/search.js +81 -53
- package/dist/search.js.map +1 -1
- package/dist/selection.cjs +105 -108
- package/dist/selection.cjs.map +1 -1
- package/dist/selection.d.cts +54 -26
- package/dist/selection.d.ts +56 -28
- package/dist/selection.js +103 -110
- package/dist/selection.js.map +1 -1
- package/dist/shell.cjs +36 -21
- package/dist/shell.cjs.map +1 -1
- package/dist/shell.d.cts +32 -17
- package/dist/shell.d.ts +32 -17
- package/dist/shell.js +36 -24
- package/dist/shell.js.map +1 -1
- package/dist/signature.cjs +29 -48
- package/dist/signature.cjs.map +1 -1
- package/dist/signature.d.cts +26 -26
- package/dist/signature.d.ts +26 -26
- package/dist/signature.js +30 -48
- package/dist/signature.js.map +1 -1
- package/dist/stage-BIG6aeVd.cjs +369 -0
- package/dist/stage-BIG6aeVd.cjs.map +1 -0
- package/dist/stage-ByFPD-Fv.d.cts +117 -0
- package/dist/stage-DaboaheR.d.ts +117 -0
- package/dist/stage-DoVekb83.js +302 -0
- package/dist/stage-DoVekb83.js.map +1 -0
- package/dist/stage-scope-CQgCuf1w.cjs +46 -0
- package/dist/stage-scope-CQgCuf1w.cjs.map +1 -0
- package/dist/stage-scope-D7ZeNduT.js +23 -0
- package/dist/stage-scope-D7ZeNduT.js.map +1 -0
- package/dist/stage.cjs +12 -235
- package/dist/stage.d.cts +2 -116
- package/dist/stage.d.ts +2 -116
- package/dist/stage.js +3 -228
- package/dist/stamp.cjs +41 -35
- package/dist/stamp.cjs.map +1 -1
- package/dist/stamp.d.cts +25 -18
- package/dist/stamp.d.ts +25 -18
- package/dist/stamp.js +40 -37
- package/dist/stamp.js.map +1 -1
- package/dist/state-0K1I5cM4.d.cts +29 -0
- package/dist/state-0K1I5cM4.d.ts +29 -0
- package/dist/state-CbgxhwLA.js +62 -0
- package/dist/state-CbgxhwLA.js.map +1 -0
- package/dist/state-CsfZy_Eq.cjs +73 -0
- package/dist/state-CsfZy_Eq.cjs.map +1 -0
- package/dist/svg-shapes-Dm1yTR1b.js +40 -0
- package/dist/svg-shapes-Dm1yTR1b.js.map +1 -0
- package/dist/svg-shapes-zo0GNkc9.cjs +53 -0
- package/dist/svg-shapes-zo0GNkc9.cjs.map +1 -0
- package/dist/toolbar.cjs +297 -295
- package/dist/toolbar.cjs.map +1 -1
- package/dist/toolbar.d.cts +58 -68
- package/dist/toolbar.d.ts +67 -77
- package/dist/toolbar.js +271 -293
- package/dist/toolbar.js.map +1 -1
- package/dist/view-manager.cjs +34 -0
- package/dist/view-manager.cjs.map +1 -0
- package/dist/view-manager.d.cts +21 -0
- package/dist/view-manager.d.ts +21 -0
- package/dist/view-manager.js +23 -0
- package/dist/view-manager.js.map +1 -0
- package/package.json +41 -38
- package/dist/AnnotationListSnapshot-D3mFut1e-C_GMpK25.d.cts +0 -546
- package/dist/AnnotationListSnapshot-D3mFut1e-C_GMpK25.d.ts +0 -546
- package/dist/annotation-BCED_p9H.d.cts +0 -160
- package/dist/annotation-anchors-CetwM1g7.js +0 -15
- package/dist/annotation-anchors-CetwM1g7.js.map +0 -1
- package/dist/annotation-anchors-DuYRBJLl.cjs +0 -26
- package/dist/annotation-anchors-DuYRBJLl.cjs.map +0 -1
- package/dist/annotation-hooks-BB5ZhPpf.cjs +0 -16
- package/dist/annotation-hooks-BB5ZhPpf.cjs.map +0 -1
- package/dist/annotation-hooks-Df8EmzDO.js +0 -11
- package/dist/annotation-hooks-Df8EmzDO.js.map +0 -1
- package/dist/annotation-k38KDlIZ.d.ts +0 -160
- package/dist/annotation-menu.cjs +0 -64
- package/dist/annotation-menu.cjs.map +0 -1
- package/dist/annotation-menu.d.cts +0 -33
- package/dist/annotation-menu.d.ts +0 -33
- package/dist/annotation-menu.js +0 -48
- package/dist/annotation-menu.js.map +0 -1
- package/dist/annotation.cjs.map +0 -1
- package/dist/annotation.js.map +0 -1
- package/dist/form-BVumS7up.cjs +0 -926
- package/dist/form-BVumS7up.cjs.map +0 -1
- package/dist/form-CK3mp99m.js +0 -895
- package/dist/form-CK3mp99m.js.map +0 -1
- package/dist/rolldown-runtime-BBjsoOtd.js +0 -27
- package/dist/runtime-DE76hlnl.d.ts +0 -216
- package/dist/runtime-umHA_xHt.d.cts +0 -216
- package/dist/runtime.cjs.map +0 -1
- package/dist/runtime.js.map +0 -1
- package/dist/scrollbar.cjs +0 -241
- package/dist/scrollbar.cjs.map +0 -1
- package/dist/scrollbar.d.cts +0 -42
- package/dist/scrollbar.d.ts +0 -42
- package/dist/scrollbar.js +0 -213
- package/dist/scrollbar.js.map +0 -1
- package/dist/stage.cjs.map +0 -1
- package/dist/stage.js.map +0 -1
- package/dist/views.cjs +0 -35
- package/dist/views.cjs.map +0 -1
- package/dist/views.d.cts +0 -21
- package/dist/views.d.ts +0 -21
- package/dist/views.js +0 -27
- package/dist/views.js.map +0 -1
package/dist/link.d.ts
CHANGED
|
@@ -1,25 +1,30 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { EventHook } from "@embedpdf/core";
|
|
2
|
+
import * as React$1 from "react";
|
|
3
|
+
import { Link, LinkCapability } from "@embedpdf/plugin-link";
|
|
3
4
|
export * from "@embedpdf/plugin-link";
|
|
4
5
|
//#region src/link.d.ts
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
*/
|
|
13
|
-
declare function openLinkTarget(link: LinkCapability, target: PdfLinkTarget, context?: LinkActivateContext): LinkActivation;
|
|
6
|
+
/** What `renderLink` receives for each link. */
|
|
7
|
+
interface LinkRenderProps {
|
|
8
|
+
/** The link: its `id`, its `bounds` on the page and its `target`. */
|
|
9
|
+
link: Link;
|
|
10
|
+
/** The layer's own clickable area: wrap it to keep what a click does. */
|
|
11
|
+
native: React$1.ReactNode;
|
|
12
|
+
}
|
|
14
13
|
interface LinkLayerProps {
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Draw a link yourself, usually around `native`. Return `undefined` for a
|
|
16
|
+
* link you don't want to change.
|
|
17
|
+
*/
|
|
18
|
+
renderLink?: (props: LinkRenderProps) => React$1.ReactNode | undefined;
|
|
20
19
|
}
|
|
21
20
|
declare function LinkLayer({ renderLink }?: LinkLayerProps): import("react/jsx-runtime").JSX.Element | null;
|
|
21
|
+
/**
|
|
22
|
+
* The link capability (`listLinks`, `activate`, …) for app code. While a
|
|
23
|
+
* component uses it, `activate()` opens a website in a new tab.
|
|
24
|
+
*/
|
|
22
25
|
declare function useLink(): LinkCapability;
|
|
26
|
+
/** Subscribe to one link event for the mounted lifetime: `useLinkEvent((link) => link.onActivated, handler)`. */
|
|
27
|
+
declare function useLinkEvent<T>(select: (link: LinkCapability) => EventHook<T>, handler: (event: T) => void): void;
|
|
23
28
|
//#endregion
|
|
24
|
-
export { LinkLayer, LinkLayerProps,
|
|
29
|
+
export { LinkLayer, LinkLayerProps, LinkRenderProps, useLink, useLinkEvent };
|
|
25
30
|
//# sourceMappingURL=link.d.ts.map
|
package/dist/link.js
CHANGED
|
@@ -1,71 +1,55 @@
|
|
|
1
|
-
import "./
|
|
2
|
-
import {
|
|
1
|
+
import { C as useOptionalSelector, E as useSelector, S as useOptionalCapability, f as useCapability, p as useCapabilityEvent, u as shallowArray, w as usePage } from "./runtime-B6xcPsEb.js";
|
|
2
|
+
import { n as useStageToken } from "./stage-scope-D7ZeNduT.js";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import { InteractionToken } from "@embedpdf/plugin-interaction/contract";
|
|
4
|
+
import { hoverLink, isModifiedClick, isolatePointerDown, linkActivateContextOf, linkAnchorOf, navigableLinksOf, openExternalUri, sendLinkEvent } from "@embedpdf/web";
|
|
5
|
+
import * as React$1 from "react";
|
|
6
|
+
import { useEffect, useMemo, useRef } from "react";
|
|
7
|
+
import { InteractionToken } from "@embedpdf/plugin-interaction/contract/host";
|
|
8
8
|
import { LinkToken } from "@embedpdf/plugin-link";
|
|
9
9
|
import { ActionsToken, createHoverPump } from "@embedpdf/plugin-actions/contract";
|
|
10
|
+
import { LinkToken as LinkToken$1 } from "@embedpdf/plugin-link/contract/host";
|
|
10
11
|
export * from "@embedpdf/plugin-link";
|
|
11
12
|
//#region src/link.tsx
|
|
12
13
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* anchors below, the selection menu's "Open link", the style editor's "Go to
|
|
18
|
-
* link" — goes through here, so none of them can drop the uri outcome again.
|
|
14
|
+
* A link's anchor. A press inside it must not reach the Stage's native listener (it would start
|
|
15
|
+
* the active tool's gesture, or end an edit as a click outside), so it stops with a native
|
|
16
|
+
* listener on the anchor itself: React's own `onPointerDown` runs from the root, after the Stage
|
|
17
|
+
* has already seen the press. The same listener sends the link's "mouse down" action.
|
|
19
18
|
*/
|
|
20
|
-
function
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
/** Content rect → view px (the page wrapper's own space) — the same idiom as
|
|
29
|
-
* the annotation and form layers: never re-derive `x * scale`. */
|
|
30
|
-
function boxOf(item, page) {
|
|
31
|
-
const tl = page.transform.toPixels({
|
|
32
|
-
x: item.rect.x,
|
|
33
|
-
y: item.rect.y
|
|
34
|
-
});
|
|
35
|
-
const br = page.transform.toPixels({
|
|
36
|
-
x: item.rect.x + item.rect.width,
|
|
37
|
-
y: item.rect.y + item.rect.height
|
|
19
|
+
function LinkAnchor({ onPress, ...props }) {
|
|
20
|
+
const ref = useRef(null);
|
|
21
|
+
const press = useRef(onPress);
|
|
22
|
+
press.current = onPress;
|
|
23
|
+
useEffect(() => ref.current ? isolatePointerDown(ref.current, () => press.current()) : void 0, []);
|
|
24
|
+
return /* @__PURE__ */ jsx("a", {
|
|
25
|
+
ref,
|
|
26
|
+
...props
|
|
38
27
|
});
|
|
39
|
-
return {
|
|
40
|
-
left: tl.x,
|
|
41
|
-
top: tl.y,
|
|
42
|
-
width: br.x - tl.x,
|
|
43
|
-
height: br.y - tl.y
|
|
44
|
-
};
|
|
45
28
|
}
|
|
46
|
-
/**
|
|
47
|
-
*
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
29
|
+
/**
|
|
30
|
+
* Hand the link plugin this binding's website opener (`openExternalUri`)
|
|
31
|
+
* while the component is mounted: an allowed address opens in a new tab,
|
|
32
|
+
* anything else is refused and the plugin reports it.
|
|
33
|
+
*/
|
|
34
|
+
function useUriOpener() {
|
|
35
|
+
const host = useOptionalCapability(LinkToken$1);
|
|
36
|
+
useEffect(() => host?.registerUriOpener(openExternalUri), [host]);
|
|
55
37
|
}
|
|
56
38
|
function LinkLayer({ renderLink } = {}) {
|
|
57
39
|
const page = usePage();
|
|
58
40
|
const link = useCapability(LinkToken);
|
|
41
|
+
useUriOpener();
|
|
42
|
+
const stage = useOptionalCapability(useStageToken());
|
|
59
43
|
const actions = useOptionalCapability(ActionsToken);
|
|
60
44
|
const linkPump = useMemo(() => actions ? createHoverPump(actions.dispatch) : null, [actions]);
|
|
61
|
-
const items = useSelector(LinkToken, (
|
|
62
|
-
const engaged = useSelector(LinkToken, (
|
|
63
|
-
const editEnabled = useOptionalSelector(InteractionToken, (
|
|
45
|
+
const items = useSelector(LinkToken, (link) => link.listLinks(page.ref), shallowArray);
|
|
46
|
+
const engaged = useSelector(LinkToken$1, (link) => link.isNavigationEngaged());
|
|
47
|
+
const editEnabled = useOptionalSelector(InteractionToken, (interaction) => interaction.activeToolEnables("annotation-edit"), false);
|
|
64
48
|
useEffect(() => {
|
|
65
|
-
link.
|
|
66
|
-
}, [link, page.
|
|
49
|
+
link.ensureLoaded(page.ref);
|
|
50
|
+
}, [link, page.ref]);
|
|
67
51
|
if (!engaged || !items.length) return null;
|
|
68
|
-
const visible =
|
|
52
|
+
const visible = navigableLinksOf(items, editEnabled);
|
|
69
53
|
if (!visible.length) return null;
|
|
70
54
|
return /* @__PURE__ */ jsx("div", {
|
|
71
55
|
style: {
|
|
@@ -74,66 +58,33 @@ function LinkLayer({ renderLink } = {}) {
|
|
|
74
58
|
pointerEvents: "none"
|
|
75
59
|
},
|
|
76
60
|
children: visible.map((item) => {
|
|
77
|
-
const box =
|
|
78
|
-
const
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
activate: item.activate,
|
|
82
|
-
ref: item.ref,
|
|
83
|
-
pon: page.pon
|
|
84
|
-
};
|
|
85
|
-
const linkSource = item.ref ? {
|
|
86
|
-
kind: "link",
|
|
87
|
-
annotation: item.ref,
|
|
88
|
-
pon: page.pon
|
|
89
|
-
} : null;
|
|
90
|
-
const notify = (event) => {
|
|
91
|
-
if (!actions || !item.ref || !linkSource) return;
|
|
92
|
-
actions.dispatch({
|
|
93
|
-
scope: "annotation",
|
|
94
|
-
event,
|
|
95
|
-
ref: item.ref,
|
|
96
|
-
pon: page.pon,
|
|
97
|
-
source: linkSource
|
|
98
|
-
});
|
|
99
|
-
};
|
|
100
|
-
const native = /* @__PURE__ */ jsx("a", {
|
|
61
|
+
const { box, href, label } = linkAnchorOf(item, page.transform, (each) => link.getLabel(each));
|
|
62
|
+
const context = linkActivateContextOf(item, page.ref, stage);
|
|
63
|
+
const native = /* @__PURE__ */ jsx(LinkAnchor, {
|
|
64
|
+
onPress: () => sendLinkEvent(actions, item, page.ref, "mouseDown"),
|
|
101
65
|
href: href ?? void 0,
|
|
102
66
|
target: "_blank",
|
|
103
67
|
rel: "noopener noreferrer",
|
|
104
68
|
role: "link",
|
|
105
69
|
tabIndex: 0,
|
|
106
|
-
title:
|
|
107
|
-
"aria-label":
|
|
108
|
-
onClick: (
|
|
109
|
-
if (
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
openLinkTarget(link, item.target, context);
|
|
70
|
+
title: label,
|
|
71
|
+
"aria-label": label,
|
|
72
|
+
onClick: (event) => {
|
|
73
|
+
if (href && isModifiedClick(event)) return;
|
|
74
|
+
event.preventDefault();
|
|
75
|
+
link.activate(item, context);
|
|
113
76
|
},
|
|
114
|
-
onKeyDown: (
|
|
115
|
-
if (
|
|
116
|
-
|
|
117
|
-
|
|
77
|
+
onKeyDown: (event) => {
|
|
78
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
79
|
+
event.preventDefault();
|
|
80
|
+
link.activate(item, context);
|
|
118
81
|
}
|
|
119
82
|
},
|
|
120
|
-
onPointerEnter: () =>
|
|
121
|
-
if (!linkPump || !item.ref || !item.hoverEvents) return;
|
|
122
|
-
linkPump.hover({
|
|
123
|
-
ref: item.ref,
|
|
124
|
-
pon: page.pon,
|
|
125
|
-
...linkSource ? { source: linkSource } : {},
|
|
126
|
-
events: item.hoverEvents
|
|
127
|
-
});
|
|
128
|
-
},
|
|
83
|
+
onPointerEnter: () => hoverLink(linkPump, item, page.ref),
|
|
129
84
|
onPointerLeave: () => linkPump?.hover(null),
|
|
130
|
-
onPointerUp: () =>
|
|
131
|
-
onFocus: () =>
|
|
132
|
-
onBlur: () =>
|
|
133
|
-
onPointerDown: (e) => {
|
|
134
|
-
e.stopPropagation();
|
|
135
|
-
notify("mouseDown");
|
|
136
|
-
},
|
|
85
|
+
onPointerUp: () => sendLinkEvent(actions, item, page.ref, "mouseUp"),
|
|
86
|
+
onFocus: () => sendLinkEvent(actions, item, page.ref, "focus"),
|
|
87
|
+
onBlur: () => sendLinkEvent(actions, item, page.ref, "blur"),
|
|
137
88
|
style: {
|
|
138
89
|
position: "absolute",
|
|
139
90
|
left: box.left,
|
|
@@ -144,18 +95,27 @@ function LinkLayer({ renderLink } = {}) {
|
|
|
144
95
|
pointerEvents: "auto"
|
|
145
96
|
}
|
|
146
97
|
});
|
|
147
|
-
const
|
|
148
|
-
item,
|
|
149
|
-
|
|
98
|
+
const drawn = renderLink?.({
|
|
99
|
+
link: item,
|
|
100
|
+
native
|
|
150
101
|
}) ?? native;
|
|
151
|
-
return /* @__PURE__ */ jsx(React.Fragment, { children:
|
|
102
|
+
return /* @__PURE__ */ jsx(React$1.Fragment, { children: drawn }, item.id);
|
|
152
103
|
})
|
|
153
104
|
});
|
|
154
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* The link capability (`listLinks`, `activate`, …) for app code. While a
|
|
108
|
+
* component uses it, `activate()` opens a website in a new tab.
|
|
109
|
+
*/
|
|
155
110
|
function useLink() {
|
|
111
|
+
useUriOpener();
|
|
156
112
|
return useCapability(LinkToken);
|
|
157
113
|
}
|
|
114
|
+
/** Subscribe to one link event for the mounted lifetime: `useLinkEvent((link) => link.onActivated, handler)`. */
|
|
115
|
+
function useLinkEvent(select, handler) {
|
|
116
|
+
useCapabilityEvent(LinkToken, select, handler);
|
|
117
|
+
}
|
|
158
118
|
//#endregion
|
|
159
|
-
export { LinkLayer,
|
|
119
|
+
export { LinkLayer, useLink, useLinkEvent };
|
|
160
120
|
|
|
161
121
|
//# sourceMappingURL=link.js.map
|
package/dist/link.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link.js","names":[],"sources":["../src/link.tsx"],"sourcesContent":["/**\n * The React view of @embedpdf/plugin-link — the navigation plane's paint.\n *\n * One absolutely-positioned <a> per clickable link area, real anchors on\n * purpose: URIs get an `href` (middle-click, copy-link, status-bar preview\n * and keyboard focus for free), internal destinations activate through the\n * plugin (stage reveal). The layer stands down entirely while the active\n * tool doesn't enable `link-nav` — the annotation plane owns links then\n * (select / move / resize / retarget through the selection editor).\n */\n\n// One-line-per-feature: registration travels with the UI.\nexport * from '@embedpdf/plugin-link';\nimport * as React from 'react';\nimport { useEffect, useMemo } from 'react';\nimport { ActionsToken, createHoverPump } from '@embedpdf/plugin-actions/contract';\nimport type {\n ActionSource,\n PdfAnnotationEventKind,\n} from '@embedpdf/plugin-actions/contract';\nimport { InteractionToken } from '@embedpdf/plugin-interaction/contract';\nimport {\n LinkToken,\n type LinkActivateContext,\n type LinkActivation,\n type LinkCapability,\n type LinkNavItem,\n type PdfLinkTarget,\n} from '@embedpdf/plugin-link';\nimport { sanitizeExternalUri } from '@embedpdf/web';\n\nimport {\n shallowArray,\n useCapability,\n useOptionalCapability,\n useOptionalSelector,\n usePage,\n useSelector,\n} from './runtime';\nimport type { PageContextValue } from './runtime';\n\n/**\n * Resolve a target through the plugin and PERFORM the `uri` outcome — the ONE\n * place in the codebase that turns a link target into a browser tab. The\n * plugin owns resolution (goto → stage reveal, policy, analytics) and stays\n * DOM-free; opening is this framework layer's job. Every click path — the nav\n * anchors below, the selection menu's \"Open link\", the style editor's \"Go to\n * link\" — goes through here, so none of them can drop the uri outcome again.\n */\nexport function openLinkTarget(\n link: LinkCapability,\n target: PdfLinkTarget,\n context?: LinkActivateContext,\n): LinkActivation {\n const activation = link.activate(target, context);\n if (activation.outcome === 'uri') {\n const href = sanitizeExternalUri(activation.uri);\n if (href && typeof window !== 'undefined') window.open(href, '_blank', 'noopener,noreferrer');\n }\n // 'dispatched': the action engine took it — the actions UI adapter owns any\n // URI open (the no-double-open rule); this opener must do NOTHING.\n return activation;\n}\n\n/** Content rect → view px (the page wrapper's own space) — the same idiom as\n * the annotation and form layers: never re-derive `x * scale`. */\nfunction boxOf(item: LinkNavItem, page: PageContextValue) {\n const tl = page.transform.toPixels({ x: item.rect.x, y: item.rect.y });\n const br = page.transform.toPixels({\n x: item.rect.x + item.rect.width,\n y: item.rect.y + item.rect.height,\n });\n return { left: tl.x, top: tl.y, width: br.x - tl.x, height: br.y - tl.y };\n}\n\n/** A human label for the hover tooltip. Apps with i18n render their own via\n * `renderLink`; this is the sensible default. */\nfunction labelOf(item: LinkNavItem): string {\n switch (item.target.kind) {\n case 'uri':\n return item.target.uri;\n case 'goto':\n return 'Go to destination';\n case 'named':\n return item.target.name;\n default:\n return 'Link';\n }\n}\n\nexport interface LinkLayerProps {\n /** Wrap or replace a link's native anchor (badging, custom tooltips). */\n renderLink?: (args: {\n item: LinkNavItem;\n nativeComponent: React.ReactNode;\n }) => React.ReactNode | undefined;\n}\n\nexport function LinkLayer({ renderLink }: LinkLayerProps = {}) {\n const page = usePage();\n const link = useCapability(LinkToken);\n // The link plane's /AA event feed: links are behavior-inert to the\n // annotation plane's hover feed while navigable (their pixels are THESE\n // anchors), so E/X/D/U/Fo/Bl can only fire from here. One shared pump per\n // layer — crossing layers still orders Exit before Enter because both\n // sides submit synchronously in DOM event order.\n const actions = useOptionalCapability(ActionsToken);\n const linkPump = useMemo(() => (actions ? createHoverPump(actions.dispatch) : null), [actions]);\n const items = useSelector(LinkToken, (c) => c.linksOn(page.pon), shallowArray);\n const engaged = useSelector(LinkToken, (c) => c.engaged());\n // One owner per pixel: an ATTACHED link is a property of its parent — while\n // the active tool can edit annotations, the parent owns those pixels and\n // the anchor stands down (select/move/resize work; no tooltip, no swallowed\n // pointer). Standalone document links navigate under any link-nav tool.\n const editEnabled = useOptionalSelector(\n InteractionToken,\n (c) => c.activeTool()?.enables.has('annotation-edit') ?? false,\n false,\n );\n\n useEffect(() => {\n link.ensurePage(page.pon);\n }, [link, page.pon]);\n\n // An authoring tool is active → the annotation plane owns links (they're\n // plain editable rects there); no nav anchors, no swallowed pointer events.\n if (!engaged || !items.length) return null;\n const visible = editEnabled ? items.filter((i) => !i.attached) : items;\n if (!visible.length) return null;\n\n return (\n <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>\n {visible.map((item) => {\n const box = boxOf(item, page);\n // Real href ONLY for a chain-free sanitized external URI; blocked\n // schemes, internal targets, and chain-bearing trees (/Next after the\n // URI) activate through the plugin instead — a native navigation\n // would perform the first action and silently drop the rest.\n const chained = (item.activate?.root?.next.length ?? 0) > 0;\n const href =\n item.target.kind === 'uri' && !chained ? sanitizeExternalUri(item.target.uri) : null;\n const context: LinkActivateContext = { activate: item.activate, ref: item.ref, pon: page.pon };\n const linkSource: ActionSource | null = item.ref\n ? { kind: 'link', annotation: item.ref, pon: page.pon }\n : null;\n const notify = (event: Exclude<PdfAnnotationEventKind, 'cursorEnter' | 'cursorExit'>) => {\n if (!actions || !item.ref || !linkSource) return;\n void actions.dispatch({\n scope: 'annotation',\n event,\n ref: item.ref,\n pon: page.pon,\n source: linkSource,\n });\n };\n const native = (\n <a\n href={href ?? undefined}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n role=\"link\"\n tabIndex={0}\n title={labelOf(item)}\n aria-label={labelOf(item)}\n onClick={(e) => {\n // Modified clicks and middle-clicks on a real href keep their\n // native browser behaviour (new tab / copy link).\n if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;\n // A plain left-click on a real href: let the anchor be an\n // anchor — native navigation, target=_blank, status bar. Only\n // non-href targets (goto / named / blocked schemes) route\n // through the plugin, whose uri outcome the opener PERFORMS\n // (the old code preventDefault-ed AND dropped the outcome, so\n // clicking a URL link did nothing at all).\n if (href) return;\n e.preventDefault();\n openLinkTarget(link, item.target, context);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n openLinkTarget(link, item.target, context);\n }\n }}\n onPointerEnter={() => {\n if (!linkPump || !item.ref || !item.hoverEvents) return;\n linkPump.hover({\n ref: item.ref,\n pon: page.pon,\n ...(linkSource ? { source: linkSource } : {}),\n events: item.hoverEvents,\n });\n }}\n onPointerLeave={() => linkPump?.hover(null)}\n onPointerUp={() => notify('mouseUp')}\n onFocus={() => notify('focus')}\n onBlur={() => notify('blur')}\n // Keep the hub out of it: a down inside the anchor must not reach\n // the Stage's native listener (same isolation idiom as FreeText).\n onPointerDown={(e) => {\n e.stopPropagation();\n notify('mouseDown');\n }}\n style={{\n position: 'absolute',\n left: box.left,\n top: box.top,\n width: box.width,\n height: box.height,\n cursor: 'pointer',\n pointerEvents: 'auto',\n }}\n />\n );\n const out = renderLink?.({ item, nativeComponent: native }) ?? native;\n return <React.Fragment key={item.id}>{out}</React.Fragment>;\n })}\n </div>\n );\n}\n\nexport function useLink() {\n return useCapability(LinkToken);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"link.js","names":["LinkHostToken","React"],"sources":["../src/link.tsx"],"sourcesContent":["/**\n * The React view of @embedpdf/plugin-link — the navigation plane's paint.\n *\n * One absolutely-positioned <a> per clickable link area, real anchors on\n * purpose: URIs get an `href` (middle-click, copy-link, status-bar preview\n * and keyboard focus for free). A click or a key follows the link through\n * the plugin's `activate()`, so every way of following one fires\n * `onActivated`; the plugin opens websites through the opener this binding\n * registers. The layer stands down entirely while the active tool doesn't\n * enable `link-nav` — the annotation plane owns links then (select / move /\n * resize / retarget through the selection editor).\n */\n\n// One-line-per-feature: registration travels with the UI.\nexport * from '@embedpdf/plugin-link';\nimport * as React from 'react';\nimport { useEffect, useMemo, useRef } from 'react';\nimport { ActionsToken, createHoverPump } from '@embedpdf/plugin-actions/contract';\nimport { InteractionToken } from '@embedpdf/plugin-interaction/contract/host';\nimport { LinkToken, type Link, type LinkCapability } from '@embedpdf/plugin-link';\n// The layer paints anchors only while a navigation tool is active, and opens\n// websites for the plugin: both host facts.\nimport { LinkToken as LinkHostToken } from '@embedpdf/plugin-link/contract/host';\nimport {\n hoverLink,\n isolatePointerDown,\n isModifiedClick,\n linkActivateContextOf,\n linkAnchorOf,\n navigableLinksOf,\n openExternalUri,\n sendLinkEvent,\n} from '@embedpdf/web';\nimport type { EventHook } from '@embedpdf/core';\n\nimport {\n shallowArray,\n useCapability,\n useCapabilityEvent,\n useOptionalCapability,\n useOptionalSelector,\n usePage,\n useSelector,\n} from './runtime';\nimport { useStageToken } from './stage-scope';\n\n/**\n * A link's anchor. A press inside it must not reach the Stage's native listener (it would start\n * the active tool's gesture, or end an edit as a click outside), so it stops with a native\n * listener on the anchor itself: React's own `onPointerDown` runs from the root, after the Stage\n * has already seen the press. The same listener sends the link's \"mouse down\" action.\n */\nfunction LinkAnchor({\n onPress,\n ...props\n}: { onPress: () => void } & React.AnchorHTMLAttributes<HTMLAnchorElement>) {\n const ref = useRef<HTMLAnchorElement>(null);\n const press = useRef(onPress);\n press.current = onPress;\n useEffect(\n () => (ref.current ? isolatePointerDown(ref.current, () => press.current()) : undefined),\n [],\n );\n return <a ref={ref} {...props} />;\n}\n\n/**\n * Hand the link plugin this binding's website opener (`openExternalUri`)\n * while the component is mounted: an allowed address opens in a new tab,\n * anything else is refused and the plugin reports it.\n */\nfunction useUriOpener(): void {\n const host = useOptionalCapability(LinkHostToken);\n useEffect(() => host?.registerUriOpener(openExternalUri), [host]);\n}\n\n/** What `renderLink` receives for each link. */\nexport interface LinkRenderProps {\n /** The link: its `id`, its `bounds` on the page and its `target`. */\n link: Link;\n /** The layer's own clickable area: wrap it to keep what a click does. */\n native: React.ReactNode;\n}\n\nexport interface LinkLayerProps {\n /**\n * Draw a link yourself, usually around `native`. Return `undefined` for a\n * link you don't want to change.\n */\n renderLink?: (props: LinkRenderProps) => React.ReactNode | undefined;\n}\n\nexport function LinkLayer({ renderLink }: LinkLayerProps = {}) {\n const page = usePage();\n const link = useCapability(LinkToken);\n useUriOpener();\n // A page destination moves the view this page is shown in.\n const stage = useOptionalCapability(useStageToken());\n // The link plane's /AA event feed: links are behavior-inert to the\n // annotation plane's hover feed while navigable (their pixels are these\n // anchors), so E/X/D/U/Fo/Bl can only fire from here. One shared pump per\n // layer — crossing layers still orders Exit before Enter because both\n // sides submit synchronously in DOM event order.\n const actions = useOptionalCapability(ActionsToken);\n const linkPump = useMemo(() => (actions ? createHoverPump(actions.dispatch) : null), [actions]);\n const items = useSelector(LinkToken, (link) => link.listLinks(page.ref), shallowArray);\n const engaged = useSelector(LinkHostToken, (link) => link.isNavigationEngaged());\n // One owner per pixel: an attached link is a property of its parent — while\n // the active tool can edit annotations, the parent owns those pixels and\n // the anchor stands down (select/move/resize work; no tooltip, no swallowed\n // pointer). Standalone document links navigate under any link-nav tool.\n const editEnabled = useOptionalSelector(\n InteractionToken,\n (interaction) => interaction.activeToolEnables('annotation-edit'),\n false,\n );\n\n useEffect(() => {\n void link.ensureLoaded(page.ref);\n }, [link, page.ref]);\n\n // An authoring tool is active → the annotation plane owns links (they're\n // plain editable rects there); no nav anchors, no swallowed pointer events.\n if (!engaged || !items.length) return null;\n const visible = navigableLinksOf(items, editEnabled);\n if (!visible.length) return null;\n\n return (\n <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>\n {visible.map((item) => {\n // Its box, its label, and a native href only for a website with nothing chained after it.\n const { box, href, label } = linkAnchorOf(item, page.transform, (each) =>\n link.getLabel(each),\n );\n const context = linkActivateContextOf(item, page.ref, stage);\n const native = (\n <LinkAnchor\n onPress={() => sendLinkEvent(actions, item, page.ref, 'mouseDown')}\n href={href ?? undefined}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n role=\"link\"\n tabIndex={0}\n title={label}\n aria-label={label}\n onClick={(event) => {\n // A modified click on a real href keeps the browser's own\n // behaviour (a background tab, a new window).\n if (href && isModifiedClick(event)) return;\n // Every other click follows the link through the plugin, which\n // opens a website through this binding's opener.\n event.preventDefault();\n link.activate(item, context);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n link.activate(item, context);\n }\n }}\n onPointerEnter={() => hoverLink(linkPump, item, page.ref)}\n onPointerLeave={() => linkPump?.hover(null)}\n onPointerUp={() => sendLinkEvent(actions, item, page.ref, 'mouseUp')}\n onFocus={() => sendLinkEvent(actions, item, page.ref, 'focus')}\n onBlur={() => sendLinkEvent(actions, item, page.ref, 'blur')}\n style={{\n position: 'absolute',\n left: box.left,\n top: box.top,\n width: box.width,\n height: box.height,\n cursor: 'pointer',\n pointerEvents: 'auto',\n }}\n />\n );\n const drawn = renderLink?.({ link: item, native }) ?? native;\n return <React.Fragment key={item.id}>{drawn}</React.Fragment>;\n })}\n </div>\n );\n}\n\n/**\n * The link capability (`listLinks`, `activate`, …) for app code. While a\n * component uses it, `activate()` opens a website in a new tab.\n */\nexport function useLink(): LinkCapability {\n useUriOpener();\n return useCapability(LinkToken);\n}\n\n/** Subscribe to one link event for the mounted lifetime: `useLinkEvent((link) => link.onActivated, handler)`. */\nexport function useLinkEvent<T>(\n select: (link: LinkCapability) => EventHook<T>,\n handler: (event: T) => void,\n): void {\n useCapabilityEvent(LinkToken, select, handler);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("./rolldown-runtime-DDXJien1.cjs");
|
|
3
|
+
const require_runtime = require("./runtime-fzpGv78v.cjs");
|
|
4
|
+
const require_state = require("./state-CsfZy_Eq.cjs");
|
|
5
|
+
let _embedpdf_plugin_measurement = require("@embedpdf/plugin-measurement");
|
|
6
|
+
//#region src/measurement.tsx
|
|
7
|
+
/** The measurement capability: scales, calibration, readouts and creating measurements. */
|
|
8
|
+
function useMeasurement() {
|
|
9
|
+
return require_runtime.useCapability(_embedpdf_plugin_measurement.MeasurementToken);
|
|
10
|
+
}
|
|
11
|
+
/** Subscribe to one measurement event for the mounted lifetime: `useMeasurementEvent((measurement) => measurement.onScaleChanged, handler)`. */
|
|
12
|
+
function useMeasurementEvent(select, handler) {
|
|
13
|
+
require_runtime.useCapabilityEvent(_embedpdf_plugin_measurement.MeasurementToken, select, handler);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The measurement state: whether a scale change runs, the calibration
|
|
17
|
+
* request waiting for its length, and the last change's reports (the page's
|
|
18
|
+
* State table, declared once in `measurementState`). Takes a selector, and
|
|
19
|
+
* re-renders only when what it returns changes.
|
|
20
|
+
*/
|
|
21
|
+
const useMeasurementState = require_state.stateHook(_embedpdf_plugin_measurement.measurementState);
|
|
22
|
+
/** The measurement settings (`defaultScale`, `presets`), with or without a document. Takes a selector. */
|
|
23
|
+
const useMeasurementSettings = require_state.settingsHook(_embedpdf_plugin_measurement.MeasurementToken);
|
|
24
|
+
function usePageScale(page) {
|
|
25
|
+
const scoped = require_runtime.useDocumentScope();
|
|
26
|
+
return require_runtime.useKernelValue((kernel) => {
|
|
27
|
+
if (page === null) return null;
|
|
28
|
+
return kernel.tryCapability(_embedpdf_plugin_measurement.MeasurementToken, scoped ?? void 0)?.getPageScale(page) ?? _embedpdf_plugin_measurement.NO_PAGE_SCALE;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A measurement's `{ kind, value, label }`, or `{ unavailable }` with why there's none.
|
|
33
|
+
* Readouts are reference-stable in the plugin, so this re-renders only when the measurement's
|
|
34
|
+
* changes.
|
|
35
|
+
*/
|
|
36
|
+
function useMeasurementReadout(ref) {
|
|
37
|
+
const scoped = require_runtime.useDocumentScope();
|
|
38
|
+
return require_runtime.useKernelValue((kernel) => kernel.tryCapability(_embedpdf_plugin_measurement.MeasurementToken, scoped ?? void 0)?.getReadout(ref) ?? _embedpdf_plugin_measurement.NO_READOUT);
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
exports.useMeasurement = useMeasurement;
|
|
42
|
+
exports.useMeasurementEvent = useMeasurementEvent;
|
|
43
|
+
exports.useMeasurementReadout = useMeasurementReadout;
|
|
44
|
+
exports.useMeasurementSettings = useMeasurementSettings;
|
|
45
|
+
exports.useMeasurementState = useMeasurementState;
|
|
46
|
+
exports.usePageScale = usePageScale;
|
|
47
|
+
Object.keys(_embedpdf_plugin_measurement).forEach(function(k) {
|
|
48
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function() {
|
|
51
|
+
return _embedpdf_plugin_measurement[k];
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
//# sourceMappingURL=measurement.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measurement.cjs","names":["useCapability","MeasurementToken","stateHook","measurementState","settingsHook","useDocumentScope","useKernelValue","NO_PAGE_SCALE","NO_READOUT"],"sources":["../src/measurement.tsx"],"sourcesContent":["/**\n * The React view of @embedpdf/plugin-measurement: the four hooks every\n * plugin has, plus one per page scale and one per measurement, so a\n * component re-renders only for its own page or measurement. Every hook\n * works before a document opens.\n */\n\n// One-line-per-feature: registration travels with the UI.\nexport * from '@embedpdf/plugin-measurement';\nimport type { EventHook, PageRef } from '@embedpdf/core';\nimport {\n MeasurementToken,\n measurementState,\n NO_PAGE_SCALE,\n NO_READOUT,\n} from '@embedpdf/plugin-measurement';\nimport type {\n AnnotationRef,\n MeasurementCapability,\n MeasurementReadout,\n MeasurementUnavailable,\n PageScale,\n} from '@embedpdf/plugin-measurement';\nimport { useCapability, useCapabilityEvent, useDocumentScope, useKernelValue } from './runtime';\nimport { settingsHook, stateHook } from './state';\n\n/** The measurement capability: scales, calibration, readouts and creating measurements. */\nexport function useMeasurement(): MeasurementCapability {\n return useCapability(MeasurementToken);\n}\n\n/** Subscribe to one measurement event for the mounted lifetime: `useMeasurementEvent((measurement) => measurement.onScaleChanged, handler)`. */\nexport function useMeasurementEvent<T>(\n select: (measurement: MeasurementCapability) => EventHook<T>,\n handler: (event: T) => void,\n): void {\n useCapabilityEvent(MeasurementToken, select, handler);\n}\n\n/**\n * The measurement state: whether a scale change runs, the calibration\n * request waiting for its length, and the last change's reports (the page's\n * State table, declared once in `measurementState`). Takes a selector, and\n * re-renders only when what it returns changes.\n */\nexport const useMeasurementState = stateHook(measurementState);\n\n/** The measurement settings (`defaultScale`, `presets`), with or without a document. Takes a selector. */\nexport const useMeasurementSettings = settingsHook(MeasurementToken);\n\n/**\n * A page's measurement scale (its ref or its index), for a scale bar or a\n * \"1:100\" badge. Accepts `null` (no current page) and answers `null` then,\n * so chrome can stay mounted without inventing a page.\n */\nexport function usePageScale(page: PageRef | number): PageScale;\nexport function usePageScale(page: PageRef | number | null): PageScale | null;\nexport function usePageScale(page: PageRef | number | null): PageScale | null {\n const scoped = useDocumentScope();\n // Scales are reference-stable in the plugin, so this re-renders only when this page's changes.\n return useKernelValue((kernel) => {\n if (page === null) return null;\n return (\n kernel.tryCapability(MeasurementToken, scoped ?? undefined)?.getPageScale(page) ??\n NO_PAGE_SCALE\n );\n });\n}\n\n/**\n * A measurement's `{ kind, value, label }`, or `{ unavailable }` with why there's none.\n * Readouts are reference-stable in the plugin, so this re-renders only when the measurement's\n * changes.\n */\nexport function useMeasurementReadout(\n ref: AnnotationRef,\n): MeasurementReadout | MeasurementUnavailable {\n const scoped = useDocumentScope();\n return useKernelValue(\n (kernel) =>\n kernel.tryCapability(MeasurementToken, scoped ?? undefined)?.getReadout(ref) ?? NO_READOUT,\n );\n}\n"],"mappings":";;;;;;;AA2BA,SAAgB,iBAAwC;CACtD,OAAOA,gBAAAA,cAAcC,6BAAAA,gBAAgB;AACvC;;AAGA,SAAgB,oBACd,QACA,SACM;CACN,gBAAA,mBAAmBA,6BAAAA,kBAAkB,QAAQ,OAAO;AACtD;;;;;;;AAQA,MAAa,sBAAsBC,cAAAA,UAAUC,6BAAAA,gBAAgB;;AAG7D,MAAa,yBAAyBC,cAAAA,aAAaH,6BAAAA,gBAAgB;AASnE,SAAgB,aAAa,MAAiD;CAC5E,MAAM,SAASI,gBAAAA,iBAAiB;CAEhC,OAAOC,gBAAAA,gBAAgB,WAAW;EAChC,IAAI,SAAS,MAAM,OAAO;EAC1B,OACE,OAAO,cAAcL,6BAAAA,kBAAkB,UAAU,KAAA,CAAS,CAAC,EAAE,aAAa,IAAI,KAC9EM,6BAAAA;CAEJ,CAAC;AACH;;;;;;AAOA,SAAgB,sBACd,KAC6C;CAC7C,MAAM,SAASF,gBAAAA,iBAAiB;CAChC,OAAOC,gBAAAA,gBACJ,WACC,OAAO,cAAcL,6BAAAA,kBAAkB,UAAU,KAAA,CAAS,CAAC,EAAE,WAAW,GAAG,KAAKO,6BAAAA,UACpF;AACF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { n as StateHook, t as SettingsHook } from "./state-0K1I5cM4.cjs";
|
|
2
|
+
import { EventHook, PageRef } from "@embedpdf/core";
|
|
3
|
+
import { AnnotationRef, MeasurementCapability, MeasurementReadout, MeasurementUnavailable, PageScale } from "@embedpdf/plugin-measurement";
|
|
4
|
+
export * from "@embedpdf/plugin-measurement";
|
|
5
|
+
//#region src/measurement.d.ts
|
|
6
|
+
/** The measurement capability: scales, calibration, readouts and creating measurements. */
|
|
7
|
+
declare function useMeasurement(): MeasurementCapability;
|
|
8
|
+
/** Subscribe to one measurement event for the mounted lifetime: `useMeasurementEvent((measurement) => measurement.onScaleChanged, handler)`. */
|
|
9
|
+
declare function useMeasurementEvent<T>(select: (measurement: MeasurementCapability) => EventHook<T>, handler: (event: T) => void): void;
|
|
10
|
+
/**
|
|
11
|
+
* The measurement state: whether a scale change runs, the calibration
|
|
12
|
+
* request waiting for its length, and the last change's reports (the page's
|
|
13
|
+
* State table, declared once in `measurementState`). Takes a selector, and
|
|
14
|
+
* re-renders only when what it returns changes.
|
|
15
|
+
*/
|
|
16
|
+
declare const useMeasurementState: StateHook<{
|
|
17
|
+
busy: boolean;
|
|
18
|
+
calibrationRequest: import("@embedpdf/plugin-measurement").CalibrationRequest | null;
|
|
19
|
+
lastReports: readonly import("@embedpdf/plugin-measurement").ScaleChangeReport[];
|
|
20
|
+
}>;
|
|
21
|
+
/** The measurement settings (`defaultScale`, `presets`), with or without a document. Takes a selector. */
|
|
22
|
+
declare const useMeasurementSettings: SettingsHook<import("@embedpdf/plugin-measurement").MeasurementSettings>;
|
|
23
|
+
/**
|
|
24
|
+
* A page's measurement scale (its ref or its index), for a scale bar or a
|
|
25
|
+
* "1:100" badge. Accepts `null` (no current page) and answers `null` then,
|
|
26
|
+
* so chrome can stay mounted without inventing a page.
|
|
27
|
+
*/
|
|
28
|
+
declare function usePageScale(page: PageRef | number): PageScale;
|
|
29
|
+
declare function usePageScale(page: PageRef | number | null): PageScale | null;
|
|
30
|
+
/**
|
|
31
|
+
* A measurement's `{ kind, value, label }`, or `{ unavailable }` with why there's none.
|
|
32
|
+
* Readouts are reference-stable in the plugin, so this re-renders only when the measurement's
|
|
33
|
+
* changes.
|
|
34
|
+
*/
|
|
35
|
+
declare function useMeasurementReadout(ref: AnnotationRef): MeasurementReadout | MeasurementUnavailable;
|
|
36
|
+
//#endregion
|
|
37
|
+
export { useMeasurement, useMeasurementEvent, useMeasurementReadout, useMeasurementSettings, useMeasurementState, usePageScale };
|
|
38
|
+
//# sourceMappingURL=measurement.d.cts.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { n as StateHook, t as SettingsHook } from "./state-0K1I5cM4.js";
|
|
2
|
+
import { EventHook, PageRef } from "@embedpdf/core";
|
|
3
|
+
import { AnnotationRef, MeasurementCapability, MeasurementReadout, MeasurementUnavailable, PageScale } from "@embedpdf/plugin-measurement";
|
|
4
|
+
export * from "@embedpdf/plugin-measurement";
|
|
5
|
+
//#region src/measurement.d.ts
|
|
6
|
+
/** The measurement capability: scales, calibration, readouts and creating measurements. */
|
|
7
|
+
declare function useMeasurement(): MeasurementCapability;
|
|
8
|
+
/** Subscribe to one measurement event for the mounted lifetime: `useMeasurementEvent((measurement) => measurement.onScaleChanged, handler)`. */
|
|
9
|
+
declare function useMeasurementEvent<T>(select: (measurement: MeasurementCapability) => EventHook<T>, handler: (event: T) => void): void;
|
|
10
|
+
/**
|
|
11
|
+
* The measurement state: whether a scale change runs, the calibration
|
|
12
|
+
* request waiting for its length, and the last change's reports (the page's
|
|
13
|
+
* State table, declared once in `measurementState`). Takes a selector, and
|
|
14
|
+
* re-renders only when what it returns changes.
|
|
15
|
+
*/
|
|
16
|
+
declare const useMeasurementState: StateHook<{
|
|
17
|
+
busy: boolean;
|
|
18
|
+
calibrationRequest: import("@embedpdf/plugin-measurement").CalibrationRequest | null;
|
|
19
|
+
lastReports: readonly import("@embedpdf/plugin-measurement").ScaleChangeReport[];
|
|
20
|
+
}>;
|
|
21
|
+
/** The measurement settings (`defaultScale`, `presets`), with or without a document. Takes a selector. */
|
|
22
|
+
declare const useMeasurementSettings: SettingsHook<import("@embedpdf/plugin-measurement").MeasurementSettings>;
|
|
23
|
+
/**
|
|
24
|
+
* A page's measurement scale (its ref or its index), for a scale bar or a
|
|
25
|
+
* "1:100" badge. Accepts `null` (no current page) and answers `null` then,
|
|
26
|
+
* so chrome can stay mounted without inventing a page.
|
|
27
|
+
*/
|
|
28
|
+
declare function usePageScale(page: PageRef | number): PageScale;
|
|
29
|
+
declare function usePageScale(page: PageRef | number | null): PageScale | null;
|
|
30
|
+
/**
|
|
31
|
+
* A measurement's `{ kind, value, label }`, or `{ unavailable }` with why there's none.
|
|
32
|
+
* Readouts are reference-stable in the plugin, so this re-renders only when the measurement's
|
|
33
|
+
* changes.
|
|
34
|
+
*/
|
|
35
|
+
declare function useMeasurementReadout(ref: AnnotationRef): MeasurementReadout | MeasurementUnavailable;
|
|
36
|
+
//#endregion
|
|
37
|
+
export { useMeasurement, useMeasurementEvent, useMeasurementReadout, useMeasurementSettings, useMeasurementState, usePageScale };
|
|
38
|
+
//# sourceMappingURL=measurement.d.ts.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { f as useCapability, g as useDocumentScope, p as useCapabilityEvent, x as useKernelValue } from "./runtime-B6xcPsEb.js";
|
|
2
|
+
import { n as stateHook, t as settingsHook } from "./state-CbgxhwLA.js";
|
|
3
|
+
import { MeasurementToken, NO_PAGE_SCALE, NO_READOUT, measurementState } from "@embedpdf/plugin-measurement";
|
|
4
|
+
export * from "@embedpdf/plugin-measurement";
|
|
5
|
+
//#region src/measurement.tsx
|
|
6
|
+
/** The measurement capability: scales, calibration, readouts and creating measurements. */
|
|
7
|
+
function useMeasurement() {
|
|
8
|
+
return useCapability(MeasurementToken);
|
|
9
|
+
}
|
|
10
|
+
/** Subscribe to one measurement event for the mounted lifetime: `useMeasurementEvent((measurement) => measurement.onScaleChanged, handler)`. */
|
|
11
|
+
function useMeasurementEvent(select, handler) {
|
|
12
|
+
useCapabilityEvent(MeasurementToken, select, handler);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The measurement state: whether a scale change runs, the calibration
|
|
16
|
+
* request waiting for its length, and the last change's reports (the page's
|
|
17
|
+
* State table, declared once in `measurementState`). Takes a selector, and
|
|
18
|
+
* re-renders only when what it returns changes.
|
|
19
|
+
*/
|
|
20
|
+
const useMeasurementState = stateHook(measurementState);
|
|
21
|
+
/** The measurement settings (`defaultScale`, `presets`), with or without a document. Takes a selector. */
|
|
22
|
+
const useMeasurementSettings = settingsHook(MeasurementToken);
|
|
23
|
+
function usePageScale(page) {
|
|
24
|
+
const scoped = useDocumentScope();
|
|
25
|
+
return useKernelValue((kernel) => {
|
|
26
|
+
if (page === null) return null;
|
|
27
|
+
return kernel.tryCapability(MeasurementToken, scoped ?? void 0)?.getPageScale(page) ?? NO_PAGE_SCALE;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A measurement's `{ kind, value, label }`, or `{ unavailable }` with why there's none.
|
|
32
|
+
* Readouts are reference-stable in the plugin, so this re-renders only when the measurement's
|
|
33
|
+
* changes.
|
|
34
|
+
*/
|
|
35
|
+
function useMeasurementReadout(ref) {
|
|
36
|
+
const scoped = useDocumentScope();
|
|
37
|
+
return useKernelValue((kernel) => kernel.tryCapability(MeasurementToken, scoped ?? void 0)?.getReadout(ref) ?? NO_READOUT);
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { useMeasurement, useMeasurementEvent, useMeasurementReadout, useMeasurementSettings, useMeasurementState, usePageScale };
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=measurement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measurement.js","names":[],"sources":["../src/measurement.tsx"],"sourcesContent":["/**\n * The React view of @embedpdf/plugin-measurement: the four hooks every\n * plugin has, plus one per page scale and one per measurement, so a\n * component re-renders only for its own page or measurement. Every hook\n * works before a document opens.\n */\n\n// One-line-per-feature: registration travels with the UI.\nexport * from '@embedpdf/plugin-measurement';\nimport type { EventHook, PageRef } from '@embedpdf/core';\nimport {\n MeasurementToken,\n measurementState,\n NO_PAGE_SCALE,\n NO_READOUT,\n} from '@embedpdf/plugin-measurement';\nimport type {\n AnnotationRef,\n MeasurementCapability,\n MeasurementReadout,\n MeasurementUnavailable,\n PageScale,\n} from '@embedpdf/plugin-measurement';\nimport { useCapability, useCapabilityEvent, useDocumentScope, useKernelValue } from './runtime';\nimport { settingsHook, stateHook } from './state';\n\n/** The measurement capability: scales, calibration, readouts and creating measurements. */\nexport function useMeasurement(): MeasurementCapability {\n return useCapability(MeasurementToken);\n}\n\n/** Subscribe to one measurement event for the mounted lifetime: `useMeasurementEvent((measurement) => measurement.onScaleChanged, handler)`. */\nexport function useMeasurementEvent<T>(\n select: (measurement: MeasurementCapability) => EventHook<T>,\n handler: (event: T) => void,\n): void {\n useCapabilityEvent(MeasurementToken, select, handler);\n}\n\n/**\n * The measurement state: whether a scale change runs, the calibration\n * request waiting for its length, and the last change's reports (the page's\n * State table, declared once in `measurementState`). Takes a selector, and\n * re-renders only when what it returns changes.\n */\nexport const useMeasurementState = stateHook(measurementState);\n\n/** The measurement settings (`defaultScale`, `presets`), with or without a document. Takes a selector. */\nexport const useMeasurementSettings = settingsHook(MeasurementToken);\n\n/**\n * A page's measurement scale (its ref or its index), for a scale bar or a\n * \"1:100\" badge. Accepts `null` (no current page) and answers `null` then,\n * so chrome can stay mounted without inventing a page.\n */\nexport function usePageScale(page: PageRef | number): PageScale;\nexport function usePageScale(page: PageRef | number | null): PageScale | null;\nexport function usePageScale(page: PageRef | number | null): PageScale | null {\n const scoped = useDocumentScope();\n // Scales are reference-stable in the plugin, so this re-renders only when this page's changes.\n return useKernelValue((kernel) => {\n if (page === null) return null;\n return (\n kernel.tryCapability(MeasurementToken, scoped ?? undefined)?.getPageScale(page) ??\n NO_PAGE_SCALE\n );\n });\n}\n\n/**\n * A measurement's `{ kind, value, label }`, or `{ unavailable }` with why there's none.\n * Readouts are reference-stable in the plugin, so this re-renders only when the measurement's\n * changes.\n */\nexport function useMeasurementReadout(\n ref: AnnotationRef,\n): MeasurementReadout | MeasurementUnavailable {\n const scoped = useDocumentScope();\n return useKernelValue(\n (kernel) =>\n kernel.tryCapability(MeasurementToken, scoped ?? undefined)?.getReadout(ref) ?? NO_READOUT,\n );\n}\n"],"mappings":";;;;;;AA2BA,SAAgB,iBAAwC;CACtD,OAAO,cAAc,gBAAgB;AACvC;;AAGA,SAAgB,oBACd,QACA,SACM;CACN,mBAAmB,kBAAkB,QAAQ,OAAO;AACtD;;;;;;;AAQA,MAAa,sBAAsB,UAAU,gBAAgB;;AAG7D,MAAa,yBAAyB,aAAa,gBAAgB;AASnE,SAAgB,aAAa,MAAiD;CAC5E,MAAM,SAAS,iBAAiB;CAEhC,OAAO,gBAAgB,WAAW;EAChC,IAAI,SAAS,MAAM,OAAO;EAC1B,OACE,OAAO,cAAc,kBAAkB,UAAU,KAAA,CAAS,CAAC,EAAE,aAAa,IAAI,KAC9E;CAEJ,CAAC;AACH;;;;;;AAOA,SAAgB,sBACd,KAC6C;CAC7C,MAAM,SAAS,iBAAiB;CAChC,OAAO,gBACJ,WACC,OAAO,cAAc,kBAAkB,UAAU,KAAA,CAAS,CAAC,EAAE,WAAW,GAAG,KAAK,UACpF;AACF"}
|
package/dist/metadata.cjs
CHANGED
|
@@ -1,18 +1,31 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require("./rolldown-runtime-DDXJien1.cjs");
|
|
3
|
-
const require_runtime = require("./runtime.cjs");
|
|
3
|
+
const require_runtime = require("./runtime-fzpGv78v.cjs");
|
|
4
|
+
const require_state = require("./state-CsfZy_Eq.cjs");
|
|
4
5
|
let _embedpdf_plugin_metadata = require("@embedpdf/plugin-metadata");
|
|
5
6
|
//#region src/metadata.ts
|
|
7
|
+
/**
|
|
8
|
+
* The metadata capability (update, custom.update, refresh, canUpdate) of the
|
|
9
|
+
* surrounding `<DocumentScope>`'s document, else the active one. Outside a
|
|
10
|
+
* document, every method throws `not-ready`.
|
|
11
|
+
*/
|
|
6
12
|
function useMetadata() {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
return require_runtime.useCapability(_embedpdf_plugin_metadata.MetadataToken);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The metadata's state: the standard fields, your own fields and the load
|
|
17
|
+
* state (the page's State table, declared once in `metadataState`). Takes a
|
|
18
|
+
* selector, and re-renders only when what it returns changes.
|
|
19
|
+
*/
|
|
20
|
+
const useMetadataState = require_state.stateHook(_embedpdf_plugin_metadata.metadataState);
|
|
21
|
+
/** Subscribe to one metadata event for the mounted lifetime: `useMetadataEvent((metadata) => metadata.onUpdated, handler)`. */
|
|
22
|
+
function useMetadataEvent(select, handler) {
|
|
23
|
+
require_runtime.useCapabilityEvent(_embedpdf_plugin_metadata.MetadataToken, select, handler);
|
|
13
24
|
}
|
|
14
25
|
//#endregion
|
|
15
26
|
exports.useMetadata = useMetadata;
|
|
27
|
+
exports.useMetadataEvent = useMetadataEvent;
|
|
28
|
+
exports.useMetadataState = useMetadataState;
|
|
16
29
|
Object.keys(_embedpdf_plugin_metadata).forEach(function(k) {
|
|
17
30
|
if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
18
31
|
enumerable: true,
|
package/dist/metadata.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.cjs","names":["useCapability","MetadataToken","
|
|
1
|
+
{"version":3,"file":"metadata.cjs","names":["useCapability","MetadataToken","stateHook","metadataState"],"sources":["../src/metadata.ts"],"sourcesContent":["/**\n * The React surface for @embedpdf/plugin-metadata: the capability, the state\n * declared once in `metadataState`, and its events. The plugin keeps the\n * metadata live off the document event stream, so the state updates after\n * your own edits and after other sessions'.\n *\n * const metadata = useMetadata();\n * const { metadata: fields, custom, status } = useMetadataState();\n * await metadata.update({ title: 'New title' }); // resolves once the state shows it\n */\n\n// One-line-per-feature: registration travels with the UI.\nexport * from '@embedpdf/plugin-metadata';\nimport { MetadataToken, metadataState, type MetadataCapability } from '@embedpdf/plugin-metadata';\nimport type { EventHook } from '@embedpdf/core';\nimport { useCapability, useCapabilityEvent } from './runtime';\nimport { stateHook } from './state';\n\n/**\n * The metadata capability (update, custom.update, refresh, canUpdate) of the\n * surrounding `<DocumentScope>`'s document, else the active one. Outside a\n * document, every method throws `not-ready`.\n */\nexport function useMetadata(): MetadataCapability {\n return useCapability(MetadataToken);\n}\n\n/**\n * The metadata's state: the standard fields, your own fields and the load\n * state (the page's State table, declared once in `metadataState`). Takes a\n * selector, and re-renders only when what it returns changes.\n */\nexport const useMetadataState = stateHook(metadataState);\n\n/** Subscribe to one metadata event for the mounted lifetime: `useMetadataEvent((metadata) => metadata.onUpdated, handler)`. */\nexport function useMetadataEvent<T>(\n select: (metadata: MetadataCapability) => EventHook<T>,\n handler: (event: T) => void,\n): void {\n useCapabilityEvent(MetadataToken, select, handler);\n}\n"],"mappings":";;;;;;;;;;;AAuBA,SAAgB,cAAkC;CAChD,OAAOA,gBAAAA,cAAcC,0BAAAA,aAAa;AACpC;;;;;;AAOA,MAAa,mBAAmBC,cAAAA,UAAUC,0BAAAA,aAAa;;AAGvD,SAAgB,iBACd,QACA,SACM;CACN,gBAAA,mBAAmBF,0BAAAA,eAAe,QAAQ,OAAO;AACnD"}
|
package/dist/metadata.d.cts
CHANGED
|
@@ -1,11 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as StateHook } from "./state-0K1I5cM4.cjs";
|
|
2
|
+
import { EventHook } from "@embedpdf/core";
|
|
3
|
+
import { MetadataCapability } from "@embedpdf/plugin-metadata";
|
|
2
4
|
export * from "@embedpdf/plugin-metadata";
|
|
3
5
|
//#region src/metadata.d.ts
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
/**
|
|
7
|
+
* The metadata capability (update, custom.update, refresh, canUpdate) of the
|
|
8
|
+
* surrounding `<DocumentScope>`'s document, else the active one. Outside a
|
|
9
|
+
* document, every method throws `not-ready`.
|
|
10
|
+
*/
|
|
11
|
+
declare function useMetadata(): MetadataCapability;
|
|
12
|
+
/**
|
|
13
|
+
* The metadata's state: the standard fields, your own fields and the load
|
|
14
|
+
* state (the page's State table, declared once in `metadataState`). Takes a
|
|
15
|
+
* selector, and re-renders only when what it returns changes.
|
|
16
|
+
*/
|
|
17
|
+
declare const useMetadataState: StateHook<{
|
|
18
|
+
metadata: import("@embedpdf/core").DocumentMetadata | null;
|
|
19
|
+
custom: import("@embedpdf/core").CustomMetadata | null;
|
|
20
|
+
status: import("@embedpdf/core").ResourceStatus;
|
|
21
|
+
}>;
|
|
22
|
+
/** Subscribe to one metadata event for the mounted lifetime: `useMetadataEvent((metadata) => metadata.onUpdated, handler)`. */
|
|
23
|
+
declare function useMetadataEvent<T>(select: (metadata: MetadataCapability) => EventHook<T>, handler: (event: T) => void): void;
|
|
9
24
|
//#endregion
|
|
10
|
-
export { useMetadata };
|
|
25
|
+
export { useMetadata, useMetadataEvent, useMetadataState };
|
|
11
26
|
//# sourceMappingURL=metadata.d.cts.map
|