@embedpdf/react 3.0.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +192 -0
- package/dist/AnnotationListSnapshot-W0RCsyDE-dWna4TTJ.d.cts +2593 -0
- package/dist/AnnotationListSnapshot-W0RCsyDE-dWna4TTJ.d.ts +2593 -0
- package/dist/annotation-B6jwfTCh.d.cts +173 -0
- package/dist/annotation-Ct6dFtzJ.cjs +913 -0
- package/dist/annotation-Ct6dFtzJ.cjs.map +1 -0
- package/dist/annotation-DjGWJljY.js +829 -0
- package/dist/annotation-DjGWJljY.js.map +1 -0
- package/dist/annotation-menu.cjs +115 -0
- package/dist/annotation-menu.cjs.map +1 -0
- package/dist/annotation-menu.d.cts +7 -0
- package/dist/annotation-menu.d.ts +7 -0
- package/dist/annotation-menu.js +99 -0
- package/dist/annotation-menu.js.map +1 -0
- package/dist/annotation-nUMefyjw.d.ts +173 -0
- package/dist/annotation.cjs +25 -0
- package/dist/annotation.d.cts +3 -0
- package/dist/annotation.d.ts +3 -0
- package/dist/annotation.js +4 -0
- package/dist/commands.cjs +59 -0
- package/dist/commands.cjs.map +1 -0
- package/dist/commands.d.cts +20 -0
- package/dist/commands.d.ts +20 -0
- package/dist/commands.js +47 -0
- package/dist/commands.js.map +1 -0
- package/dist/form.cjs +560 -0
- package/dist/form.cjs.map +1 -0
- package/dist/form.d.cts +52 -0
- package/dist/form.d.ts +52 -0
- package/dist/form.js +545 -0
- package/dist/form.js.map +1 -0
- package/dist/i18n.cjs +52 -0
- package/dist/i18n.cjs.map +1 -0
- package/dist/i18n.d.cts +30 -0
- package/dist/i18n.d.ts +30 -0
- package/dist/i18n.js +42 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.cjs +240 -0
- package/dist/index.d.cts +37 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +37 -0
- package/dist/interaction.cjs +152 -0
- package/dist/interaction.cjs.map +1 -0
- package/dist/interaction.d.cts +46 -0
- package/dist/interaction.d.ts +46 -0
- package/dist/interaction.js +139 -0
- package/dist/interaction.js.map +1 -0
- package/dist/link.cjs +108 -0
- package/dist/link.cjs.map +1 -0
- package/dist/link.d.cts +16 -0
- package/dist/link.d.ts +16 -0
- package/dist/link.js +98 -0
- package/dist/link.js.map +1 -0
- package/dist/metadata.cjs +25 -0
- package/dist/metadata.cjs.map +1 -0
- package/dist/metadata.d.cts +11 -0
- package/dist/metadata.d.ts +11 -0
- package/dist/metadata.js +16 -0
- package/dist/metadata.js.map +1 -0
- package/dist/page-edit.cjs +20 -0
- package/dist/page-edit.cjs.map +1 -0
- package/dist/page-edit.d.cts +7 -0
- package/dist/page-edit.d.ts +7 -0
- package/dist/page-edit.js +11 -0
- package/dist/page-edit.js.map +1 -0
- package/dist/page-view.cjs +107 -0
- package/dist/page-view.cjs.map +1 -0
- package/dist/page-view.d.cts +23 -0
- package/dist/page-view.d.ts +23 -0
- package/dist/page-view.js +95 -0
- package/dist/page-view.js.map +1 -0
- package/dist/redaction.cjs +35 -0
- package/dist/redaction.cjs.map +1 -0
- package/dist/redaction.d.cts +14 -0
- package/dist/redaction.d.ts +14 -0
- package/dist/redaction.js +25 -0
- package/dist/redaction.js.map +1 -0
- package/dist/render.cjs +142 -0
- package/dist/render.cjs.map +1 -0
- package/dist/render.d.cts +32 -0
- package/dist/render.d.ts +32 -0
- package/dist/render.js +131 -0
- package/dist/render.js.map +1 -0
- package/dist/rolldown-runtime-DDXJien1.cjs +50 -0
- package/dist/runtime-CMxIuF2O.d.cts +195 -0
- package/dist/runtime-DV98q7I0.d.ts +195 -0
- package/dist/runtime.cjs +314 -0
- package/dist/runtime.cjs.map +1 -0
- package/dist/runtime.d.cts +3 -0
- package/dist/runtime.d.ts +3 -0
- package/dist/runtime.js +287 -0
- package/dist/runtime.js.map +1 -0
- package/dist/scrollbar.cjs +241 -0
- package/dist/scrollbar.cjs.map +1 -0
- package/dist/scrollbar.d.cts +42 -0
- package/dist/scrollbar.d.ts +42 -0
- package/dist/scrollbar.js +213 -0
- package/dist/scrollbar.js.map +1 -0
- package/dist/search.cjs +70 -0
- package/dist/search.cjs.map +1 -0
- package/dist/search.d.cts +35 -0
- package/dist/search.d.ts +35 -0
- package/dist/search.js +58 -0
- package/dist/search.js.map +1 -0
- package/dist/selection.cjs +60 -0
- package/dist/selection.cjs.map +1 -0
- package/dist/selection.d.cts +12 -0
- package/dist/selection.d.ts +12 -0
- package/dist/selection.js +49 -0
- package/dist/selection.js.map +1 -0
- package/dist/shell.cjs +57 -0
- package/dist/shell.cjs.map +1 -0
- package/dist/shell.d.cts +27 -0
- package/dist/shell.d.ts +27 -0
- package/dist/shell.js +46 -0
- package/dist/shell.js.map +1 -0
- package/dist/stage.cjs +343 -0
- package/dist/stage.cjs.map +1 -0
- package/dist/stage.d.cts +104 -0
- package/dist/stage.d.ts +104 -0
- package/dist/stage.js +327 -0
- package/dist/stage.js.map +1 -0
- package/dist/stamp.cjs +76 -0
- package/dist/stamp.cjs.map +1 -0
- package/dist/stamp.d.cts +28 -0
- package/dist/stamp.d.ts +28 -0
- package/dist/stamp.js +63 -0
- package/dist/stamp.js.map +1 -0
- package/dist/toolbar.cjs +515 -0
- package/dist/toolbar.cjs.map +1 -0
- package/dist/toolbar.d.cts +100 -0
- package/dist/toolbar.d.ts +100 -0
- package/dist/toolbar.js +505 -0
- package/dist/toolbar.js.map +1 -0
- package/dist/views.cjs +35 -0
- package/dist/views.cjs.map +1 -0
- package/dist/views.d.cts +21 -0
- package/dist/views.d.ts +21 -0
- package/dist/views.js +26 -0
- package/dist/views.js.map +1 -0
- package/package.json +158 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stamp.cjs","names":["useCapability","StampToken","useSelector","shallowArray","useDocumentId"],"sources":["../src/stamp.tsx"],"sourcesContent":["/**\n * The React view of @embedpdf/plugin-stamp.\n *\n * Thin by design: the plugin owns the store (libraries/assets) and the binary\n * sidecar (bytes + cached previews); this file only exposes hooks and owns the\n * DOM-side object-URL lifetime for gallery thumbnails. Placement UI needs no\n * component here — arming rides the annotation plugin, whose `<AnnotationLayer>`\n * already renders the hover ghost.\n */\n\n// One-line-per-feature: registration travels with the UI.\nexport * from '@embedpdf/plugin-stamp';\nimport { useEffect, useState } from 'react';\nimport { StampToken, type StampAsset, type StampLibrary } from '@embedpdf/plugin-stamp';\nimport { shallowArray, useCapability, useDocumentId, useSelector } from './runtime';\n\n/** The stamp capability (workspace-scoped: one library set for every document). */\nexport function useStamp() {\n return useCapability(StampToken);\n}\n\nexport function useStampLibraries(): StampLibrary[] {\n return useSelector(StampToken, (c) => c.libraries(), shallowArray);\n}\n\n/** Assets of one library, or every asset when `libraryId` is omitted. */\nexport function useStampAssets(libraryId?: string): StampAsset[] {\n return useSelector(StampToken, (c) => c.assets(libraryId), shallowArray);\n}\n\n/**\n * Object URL for an asset's cached preview (gallery thumbnails). The plugin\n * holds the preview BYTES; the URL — a DOM resource — is created here and\n * revoked on unmount/asset change, mirroring `<AnnotationLayer>`'s rule that\n * object-URL lifetime belongs to the framework layer.\n */\nexport function useStampAssetPreviewUrl(assetId: string | null): string | null {\n const stamp = useCapability(StampToken);\n const [url, setUrl] = useState<string | null>(null);\n useEffect(() => {\n const preview = assetId ? stamp.assetPreview(assetId) : null;\n if (!preview) {\n setUrl(null);\n return;\n }\n // Copy into an EXACT ArrayBuffer (the engine idiom) before Blob-wrapping.\n const body = new ArrayBuffer(preview.bytes.byteLength);\n new Uint8Array(body).set(preview.bytes);\n const obj = URL.createObjectURL(new Blob([body], { type: preview.mimeType }));\n setUrl(obj);\n return () => {\n URL.revokeObjectURL(obj);\n setUrl(null);\n };\n }, [stamp, assetId]);\n return url;\n}\n\n/**\n * Arm/disarm assets against the nearest `<DocumentScope>` (or the active\n * document) — the one-liner a gallery item's onClick needs.\n */\nexport function useArmStampAsset(): {\n armAsset: (assetId: string, opts?: { targetWidth?: number }) => Promise<void>;\n disarm: () => void;\n} {\n const stamp = useCapability(StampToken);\n const documentId = useDocumentId();\n return {\n armAsset: (assetId, opts) => {\n if (!documentId) return Promise.reject(new Error('[stamp] no document in scope'));\n return stamp.armAsset(documentId, assetId, opts);\n },\n disarm: () => {\n if (documentId) stamp.disarm(documentId);\n },\n };\n}\n"],"mappings":";;;;;;;AAiBA,SAAgB,WAAW;CACzB,OAAOA,gBAAAA,cAAcC,uBAAAA,UAAU;AACjC;AAEA,SAAgB,oBAAoC;CAClD,OAAOC,gBAAAA,YAAYD,uBAAAA,aAAa,MAAM,EAAE,UAAU,GAAGE,gBAAAA,YAAY;AACnE;;AAGA,SAAgB,eAAe,WAAkC;CAC/D,OAAOD,gBAAAA,YAAYD,uBAAAA,aAAa,MAAM,EAAE,OAAO,SAAS,GAAGE,gBAAAA,YAAY;AACzE;;;;;;;AAQA,SAAgB,wBAAwB,SAAuC;CAC7E,MAAM,QAAQH,gBAAAA,cAAcC,uBAAAA,UAAU;CACtC,MAAM,CAAC,KAAK,WAAA,GAAA,MAAA,SAAA,CAAkC,IAAI;CAClD,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,MAAM,UAAU,UAAU,MAAM,aAAa,OAAO,IAAI;EACxD,IAAI,CAAC,SAAS;GACZ,OAAO,IAAI;GACX;EACF;EAEA,MAAM,OAAO,IAAI,YAAY,QAAQ,MAAM,UAAU;EACrD,IAAI,WAAW,IAAI,CAAC,CAAC,IAAI,QAAQ,KAAK;EACtC,MAAM,MAAM,IAAI,gBAAgB,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,MAAM,QAAQ,SAAS,CAAC,CAAC;EAC5E,OAAO,GAAG;EACV,aAAa;GACX,IAAI,gBAAgB,GAAG;GACvB,OAAO,IAAI;EACb;CACF,GAAG,CAAC,OAAO,OAAO,CAAC;CACnB,OAAO;AACT;;;;;AAMA,SAAgB,mBAGd;CACA,MAAM,QAAQD,gBAAAA,cAAcC,uBAAAA,UAAU;CACtC,MAAM,aAAaG,gBAAAA,cAAc;CACjC,OAAO;EACL,WAAW,SAAS,SAAS;GAC3B,IAAI,CAAC,YAAY,OAAO,QAAQ,uBAAO,IAAI,MAAM,8BAA8B,CAAC;GAChF,OAAO,MAAM,SAAS,YAAY,SAAS,IAAI;EACjD;EACA,cAAc;GACZ,IAAI,YAAY,MAAM,OAAO,UAAU;EACzC;CACF;AACF"}
|
package/dist/stamp.d.cts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { StampAsset, StampLibrary } from "@embedpdf/plugin-stamp";
|
|
2
|
+
export * from "@embedpdf/plugin-stamp";
|
|
3
|
+
//#region src/stamp.d.ts
|
|
4
|
+
/** The stamp capability (workspace-scoped: one library set for every document). */
|
|
5
|
+
declare function useStamp(): import("@embedpdf/plugin-stamp").StampCapability;
|
|
6
|
+
declare function useStampLibraries(): StampLibrary[];
|
|
7
|
+
/** Assets of one library, or every asset when `libraryId` is omitted. */
|
|
8
|
+
declare function useStampAssets(libraryId?: string): StampAsset[];
|
|
9
|
+
/**
|
|
10
|
+
* Object URL for an asset's cached preview (gallery thumbnails). The plugin
|
|
11
|
+
* holds the preview BYTES; the URL — a DOM resource — is created here and
|
|
12
|
+
* revoked on unmount/asset change, mirroring `<AnnotationLayer>`'s rule that
|
|
13
|
+
* object-URL lifetime belongs to the framework layer.
|
|
14
|
+
*/
|
|
15
|
+
declare function useStampAssetPreviewUrl(assetId: string | null): string | null;
|
|
16
|
+
/**
|
|
17
|
+
* Arm/disarm assets against the nearest `<DocumentScope>` (or the active
|
|
18
|
+
* document) — the one-liner a gallery item's onClick needs.
|
|
19
|
+
*/
|
|
20
|
+
declare function useArmStampAsset(): {
|
|
21
|
+
armAsset: (assetId: string, opts?: {
|
|
22
|
+
targetWidth?: number;
|
|
23
|
+
}) => Promise<void>;
|
|
24
|
+
disarm: () => void;
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { useArmStampAsset, useStamp, useStampAssetPreviewUrl, useStampAssets, useStampLibraries };
|
|
28
|
+
//# sourceMappingURL=stamp.d.cts.map
|
package/dist/stamp.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { StampAsset, StampLibrary } from "@embedpdf/plugin-stamp";
|
|
2
|
+
export * from "@embedpdf/plugin-stamp";
|
|
3
|
+
//#region src/stamp.d.ts
|
|
4
|
+
/** The stamp capability (workspace-scoped: one library set for every document). */
|
|
5
|
+
declare function useStamp(): import("@embedpdf/plugin-stamp").StampCapability;
|
|
6
|
+
declare function useStampLibraries(): StampLibrary[];
|
|
7
|
+
/** Assets of one library, or every asset when `libraryId` is omitted. */
|
|
8
|
+
declare function useStampAssets(libraryId?: string): StampAsset[];
|
|
9
|
+
/**
|
|
10
|
+
* Object URL for an asset's cached preview (gallery thumbnails). The plugin
|
|
11
|
+
* holds the preview BYTES; the URL — a DOM resource — is created here and
|
|
12
|
+
* revoked on unmount/asset change, mirroring `<AnnotationLayer>`'s rule that
|
|
13
|
+
* object-URL lifetime belongs to the framework layer.
|
|
14
|
+
*/
|
|
15
|
+
declare function useStampAssetPreviewUrl(assetId: string | null): string | null;
|
|
16
|
+
/**
|
|
17
|
+
* Arm/disarm assets against the nearest `<DocumentScope>` (or the active
|
|
18
|
+
* document) — the one-liner a gallery item's onClick needs.
|
|
19
|
+
*/
|
|
20
|
+
declare function useArmStampAsset(): {
|
|
21
|
+
armAsset: (assetId: string, opts?: {
|
|
22
|
+
targetWidth?: number;
|
|
23
|
+
}) => Promise<void>;
|
|
24
|
+
disarm: () => void;
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { useArmStampAsset, useStamp, useStampAssetPreviewUrl, useStampAssets, useStampLibraries };
|
|
28
|
+
//# sourceMappingURL=stamp.d.ts.map
|
package/dist/stamp.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { shallowArray, useCapability, useDocumentId, useSelector } from "./runtime.js";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { StampToken } from "@embedpdf/plugin-stamp";
|
|
4
|
+
export * from "@embedpdf/plugin-stamp";
|
|
5
|
+
//#region src/stamp.tsx
|
|
6
|
+
/** The stamp capability (workspace-scoped: one library set for every document). */
|
|
7
|
+
function useStamp() {
|
|
8
|
+
return useCapability(StampToken);
|
|
9
|
+
}
|
|
10
|
+
function useStampLibraries() {
|
|
11
|
+
return useSelector(StampToken, (c) => c.libraries(), shallowArray);
|
|
12
|
+
}
|
|
13
|
+
/** Assets of one library, or every asset when `libraryId` is omitted. */
|
|
14
|
+
function useStampAssets(libraryId) {
|
|
15
|
+
return useSelector(StampToken, (c) => c.assets(libraryId), shallowArray);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Object URL for an asset's cached preview (gallery thumbnails). The plugin
|
|
19
|
+
* holds the preview BYTES; the URL — a DOM resource — is created here and
|
|
20
|
+
* revoked on unmount/asset change, mirroring `<AnnotationLayer>`'s rule that
|
|
21
|
+
* object-URL lifetime belongs to the framework layer.
|
|
22
|
+
*/
|
|
23
|
+
function useStampAssetPreviewUrl(assetId) {
|
|
24
|
+
const stamp = useCapability(StampToken);
|
|
25
|
+
const [url, setUrl] = useState(null);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
const preview = assetId ? stamp.assetPreview(assetId) : null;
|
|
28
|
+
if (!preview) {
|
|
29
|
+
setUrl(null);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const body = new ArrayBuffer(preview.bytes.byteLength);
|
|
33
|
+
new Uint8Array(body).set(preview.bytes);
|
|
34
|
+
const obj = URL.createObjectURL(new Blob([body], { type: preview.mimeType }));
|
|
35
|
+
setUrl(obj);
|
|
36
|
+
return () => {
|
|
37
|
+
URL.revokeObjectURL(obj);
|
|
38
|
+
setUrl(null);
|
|
39
|
+
};
|
|
40
|
+
}, [stamp, assetId]);
|
|
41
|
+
return url;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Arm/disarm assets against the nearest `<DocumentScope>` (or the active
|
|
45
|
+
* document) — the one-liner a gallery item's onClick needs.
|
|
46
|
+
*/
|
|
47
|
+
function useArmStampAsset() {
|
|
48
|
+
const stamp = useCapability(StampToken);
|
|
49
|
+
const documentId = useDocumentId();
|
|
50
|
+
return {
|
|
51
|
+
armAsset: (assetId, opts) => {
|
|
52
|
+
if (!documentId) return Promise.reject(/* @__PURE__ */ new Error("[stamp] no document in scope"));
|
|
53
|
+
return stamp.armAsset(documentId, assetId, opts);
|
|
54
|
+
},
|
|
55
|
+
disarm: () => {
|
|
56
|
+
if (documentId) stamp.disarm(documentId);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { useArmStampAsset, useStamp, useStampAssetPreviewUrl, useStampAssets, useStampLibraries };
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=stamp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stamp.js","names":[],"sources":["../src/stamp.tsx"],"sourcesContent":["/**\n * The React view of @embedpdf/plugin-stamp.\n *\n * Thin by design: the plugin owns the store (libraries/assets) and the binary\n * sidecar (bytes + cached previews); this file only exposes hooks and owns the\n * DOM-side object-URL lifetime for gallery thumbnails. Placement UI needs no\n * component here — arming rides the annotation plugin, whose `<AnnotationLayer>`\n * already renders the hover ghost.\n */\n\n// One-line-per-feature: registration travels with the UI.\nexport * from '@embedpdf/plugin-stamp';\nimport { useEffect, useState } from 'react';\nimport { StampToken, type StampAsset, type StampLibrary } from '@embedpdf/plugin-stamp';\nimport { shallowArray, useCapability, useDocumentId, useSelector } from './runtime';\n\n/** The stamp capability (workspace-scoped: one library set for every document). */\nexport function useStamp() {\n return useCapability(StampToken);\n}\n\nexport function useStampLibraries(): StampLibrary[] {\n return useSelector(StampToken, (c) => c.libraries(), shallowArray);\n}\n\n/** Assets of one library, or every asset when `libraryId` is omitted. */\nexport function useStampAssets(libraryId?: string): StampAsset[] {\n return useSelector(StampToken, (c) => c.assets(libraryId), shallowArray);\n}\n\n/**\n * Object URL for an asset's cached preview (gallery thumbnails). The plugin\n * holds the preview BYTES; the URL — a DOM resource — is created here and\n * revoked on unmount/asset change, mirroring `<AnnotationLayer>`'s rule that\n * object-URL lifetime belongs to the framework layer.\n */\nexport function useStampAssetPreviewUrl(assetId: string | null): string | null {\n const stamp = useCapability(StampToken);\n const [url, setUrl] = useState<string | null>(null);\n useEffect(() => {\n const preview = assetId ? stamp.assetPreview(assetId) : null;\n if (!preview) {\n setUrl(null);\n return;\n }\n // Copy into an EXACT ArrayBuffer (the engine idiom) before Blob-wrapping.\n const body = new ArrayBuffer(preview.bytes.byteLength);\n new Uint8Array(body).set(preview.bytes);\n const obj = URL.createObjectURL(new Blob([body], { type: preview.mimeType }));\n setUrl(obj);\n return () => {\n URL.revokeObjectURL(obj);\n setUrl(null);\n };\n }, [stamp, assetId]);\n return url;\n}\n\n/**\n * Arm/disarm assets against the nearest `<DocumentScope>` (or the active\n * document) — the one-liner a gallery item's onClick needs.\n */\nexport function useArmStampAsset(): {\n armAsset: (assetId: string, opts?: { targetWidth?: number }) => Promise<void>;\n disarm: () => void;\n} {\n const stamp = useCapability(StampToken);\n const documentId = useDocumentId();\n return {\n armAsset: (assetId, opts) => {\n if (!documentId) return Promise.reject(new Error('[stamp] no document in scope'));\n return stamp.armAsset(documentId, assetId, opts);\n },\n disarm: () => {\n if (documentId) stamp.disarm(documentId);\n },\n };\n}\n"],"mappings":";;;;;;AAiBA,SAAgB,WAAW;CACzB,OAAO,cAAc,UAAU;AACjC;AAEA,SAAgB,oBAAoC;CAClD,OAAO,YAAY,aAAa,MAAM,EAAE,UAAU,GAAG,YAAY;AACnE;;AAGA,SAAgB,eAAe,WAAkC;CAC/D,OAAO,YAAY,aAAa,MAAM,EAAE,OAAO,SAAS,GAAG,YAAY;AACzE;;;;;;;AAQA,SAAgB,wBAAwB,SAAuC;CAC7E,MAAM,QAAQ,cAAc,UAAU;CACtC,MAAM,CAAC,KAAK,UAAU,SAAwB,IAAI;CAClD,gBAAgB;EACd,MAAM,UAAU,UAAU,MAAM,aAAa,OAAO,IAAI;EACxD,IAAI,CAAC,SAAS;GACZ,OAAO,IAAI;GACX;EACF;EAEA,MAAM,OAAO,IAAI,YAAY,QAAQ,MAAM,UAAU;EACrD,IAAI,WAAW,IAAI,CAAC,CAAC,IAAI,QAAQ,KAAK;EACtC,MAAM,MAAM,IAAI,gBAAgB,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,MAAM,QAAQ,SAAS,CAAC,CAAC;EAC5E,OAAO,GAAG;EACV,aAAa;GACX,IAAI,gBAAgB,GAAG;GACvB,OAAO,IAAI;EACb;CACF,GAAG,CAAC,OAAO,OAAO,CAAC;CACnB,OAAO;AACT;;;;;AAMA,SAAgB,mBAGd;CACA,MAAM,QAAQ,cAAc,UAAU;CACtC,MAAM,aAAa,cAAc;CACjC,OAAO;EACL,WAAW,SAAS,SAAS;GAC3B,IAAI,CAAC,YAAY,OAAO,QAAQ,uBAAO,IAAI,MAAM,8BAA8B,CAAC;GAChF,OAAO,MAAM,SAAS,YAAY,SAAS,IAAI;EACjD;EACA,cAAc;GACZ,IAAI,YAAY,MAAM,OAAO,UAAU;EACzC;CACF;AACF"}
|
package/dist/toolbar.cjs
ADDED
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_rolldown_runtime = require("./rolldown-runtime-DDXJien1.cjs");
|
|
3
|
+
const require_runtime = require("./runtime.cjs");
|
|
4
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
|
+
let react = require("react");
|
|
6
|
+
react = require_rolldown_runtime.__toESM(react, 1);
|
|
7
|
+
let _embedpdf_plugin_commands = require("@embedpdf/plugin-commands");
|
|
8
|
+
let _embedpdf_core_ui = require("@embedpdf/core-ui");
|
|
9
|
+
//#region src/toolbar.tsx
|
|
10
|
+
const stripGroupsEqual = (a, b) => a.length === b.length && a.every((g, i) => g.id === b[i].id && g.commands.length === b[i].commands.length && g.commands.every((c, j) => (0, _embedpdf_plugin_commands.resolvedCommandsEqual)(c, b[i].commands[j])));
|
|
11
|
+
const NO_STRIP_GROUPS = [];
|
|
12
|
+
/**
|
|
13
|
+
* The live projection of a bar through the command registry — <Toolbar>'s
|
|
14
|
+
* un-measured sibling, for contextual strips (ChromeSchema.strips). The schema
|
|
15
|
+
* declares what COULD appear; each command's `visible` derivation decides what
|
|
16
|
+
* DOES; null means nothing currently applies, so `if (!view) return null` is
|
|
17
|
+
* the caller's entire show/hide logic. `execute` is pre-bound to this
|
|
18
|
+
* subtree's document. Reads are value-equal (resolvedCommandsEqual), so
|
|
19
|
+
* consumers re-render on real change, not on every store action.
|
|
20
|
+
*/
|
|
21
|
+
function useStripView(bar) {
|
|
22
|
+
const commands = require_runtime.useCapability(_embedpdf_plugin_commands.CommandsToken);
|
|
23
|
+
const documentId = require_runtime.useDocumentId();
|
|
24
|
+
const normalized = (0, react.useMemo)(() => bar ? (0, _embedpdf_core_ui.normalizeBar)(bar) : null, [bar]);
|
|
25
|
+
const groups = require_runtime.useKernelValue(() => {
|
|
26
|
+
if (!normalized) return NO_STRIP_GROUPS;
|
|
27
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
28
|
+
const visible = (id) => {
|
|
29
|
+
const cmd = commands.resolve(id, documentId ?? void 0);
|
|
30
|
+
if (cmd) resolved.set(id, cmd);
|
|
31
|
+
return cmd?.visible === true;
|
|
32
|
+
};
|
|
33
|
+
return (0, _embedpdf_core_ui.projectStrip)(normalized, visible).map((g) => ({
|
|
34
|
+
id: g.id,
|
|
35
|
+
labelKey: g.labelKey,
|
|
36
|
+
commands: g.commands.map((id) => resolved.get(id))
|
|
37
|
+
}));
|
|
38
|
+
}, stripGroupsEqual);
|
|
39
|
+
return (0, react.useMemo)(() => groups.length === 0 ? null : {
|
|
40
|
+
groups,
|
|
41
|
+
execute: (id) => commands.execute(id, documentId ?? void 0)
|
|
42
|
+
}, [
|
|
43
|
+
groups,
|
|
44
|
+
commands,
|
|
45
|
+
documentId
|
|
46
|
+
]);
|
|
47
|
+
}
|
|
48
|
+
/** Report this node's border-box width under `k`, live, via ResizeObserver. */
|
|
49
|
+
function Measured({ k, onWidth, children }) {
|
|
50
|
+
const ref = (0, react.useRef)(null);
|
|
51
|
+
(0, react.useLayoutEffect)(() => {
|
|
52
|
+
const el = ref.current;
|
|
53
|
+
if (!el) return;
|
|
54
|
+
const report = () => onWidth(k, el.getBoundingClientRect().width);
|
|
55
|
+
report();
|
|
56
|
+
const observer = new ResizeObserver(report);
|
|
57
|
+
observer.observe(el);
|
|
58
|
+
return () => observer.disconnect();
|
|
59
|
+
}, [k, onWidth]);
|
|
60
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
61
|
+
ref,
|
|
62
|
+
style: {
|
|
63
|
+
display: "inline-flex",
|
|
64
|
+
flexShrink: 0
|
|
65
|
+
},
|
|
66
|
+
children
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The socket for an unregistered custom unit: a real `<slot>` element. Inside
|
|
71
|
+
* the <embedpdf-viewer> shadow root the browser projects same-named light-DOM
|
|
72
|
+
* children into it; anywhere else it just displays its fallback (the terminal
|
|
73
|
+
* command). Measured live — the projected content lives in the HOST's world,
|
|
74
|
+
* so its width can only be observed where it actually renders.
|
|
75
|
+
*/
|
|
76
|
+
function NativeSlotSocket({ name, k, onWidth, children }) {
|
|
77
|
+
const ref = (0, react.useRef)(null);
|
|
78
|
+
(0, react.useLayoutEffect)(() => {
|
|
79
|
+
const el = ref.current;
|
|
80
|
+
if (!el) return;
|
|
81
|
+
const report = () => onWidth(k, el.getBoundingClientRect().width);
|
|
82
|
+
report();
|
|
83
|
+
const observer = new ResizeObserver(report);
|
|
84
|
+
observer.observe(el);
|
|
85
|
+
return () => observer.disconnect();
|
|
86
|
+
}, [k, onWidth]);
|
|
87
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("slot", {
|
|
88
|
+
ref,
|
|
89
|
+
name,
|
|
90
|
+
style: {
|
|
91
|
+
display: "inline-flex",
|
|
92
|
+
alignItems: "center",
|
|
93
|
+
flexShrink: 0
|
|
94
|
+
},
|
|
95
|
+
children
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
const measureLayerStyle = {
|
|
99
|
+
position: "absolute",
|
|
100
|
+
left: 0,
|
|
101
|
+
top: 0,
|
|
102
|
+
height: 0,
|
|
103
|
+
overflow: "hidden",
|
|
104
|
+
visibility: "hidden",
|
|
105
|
+
pointerEvents: "none",
|
|
106
|
+
display: "flex",
|
|
107
|
+
whiteSpace: "nowrap"
|
|
108
|
+
};
|
|
109
|
+
const defaultRenderCommand = (cmd, variant, run) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
110
|
+
type: "button",
|
|
111
|
+
onClick: run,
|
|
112
|
+
disabled: !cmd.enabled,
|
|
113
|
+
"aria-pressed": cmd.active || void 0,
|
|
114
|
+
"aria-haspopup": cmd.menu ? "menu" : void 0,
|
|
115
|
+
title: cmd.label,
|
|
116
|
+
style: {
|
|
117
|
+
display: "inline-flex",
|
|
118
|
+
alignItems: "center",
|
|
119
|
+
gap: 4,
|
|
120
|
+
padding: "4px 8px",
|
|
121
|
+
whiteSpace: "nowrap",
|
|
122
|
+
background: cmd.active ? "rgba(0,0,0,0.12)" : "transparent",
|
|
123
|
+
border: "1px solid rgba(0,0,0,0.15)",
|
|
124
|
+
borderRadius: 4,
|
|
125
|
+
cursor: cmd.enabled ? "pointer" : "default",
|
|
126
|
+
opacity: cmd.enabled ? 1 : .4
|
|
127
|
+
},
|
|
128
|
+
children: [variant === "label" ? cmd.label : cmd.icon ?? cmd.label, variant === "icon+label" ? ` ${cmd.label}` : null]
|
|
129
|
+
});
|
|
130
|
+
const defaultRenderSeparator = () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: {
|
|
131
|
+
width: 1,
|
|
132
|
+
alignSelf: "stretch",
|
|
133
|
+
background: "currentColor",
|
|
134
|
+
opacity: .2
|
|
135
|
+
} });
|
|
136
|
+
const defaultRenderOverflowTrigger = (isOpen, toggle) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
137
|
+
type: "button",
|
|
138
|
+
onClick: toggle,
|
|
139
|
+
"aria-haspopup": "menu",
|
|
140
|
+
"aria-expanded": isOpen,
|
|
141
|
+
title: "More",
|
|
142
|
+
style: {
|
|
143
|
+
display: "inline-flex",
|
|
144
|
+
alignItems: "center",
|
|
145
|
+
padding: "4px 8px",
|
|
146
|
+
border: "1px solid rgba(0,0,0,0.15)",
|
|
147
|
+
borderRadius: 4,
|
|
148
|
+
background: isOpen ? "rgba(0,0,0,0.12)" : "transparent",
|
|
149
|
+
cursor: "pointer"
|
|
150
|
+
},
|
|
151
|
+
children: "⋯"
|
|
152
|
+
});
|
|
153
|
+
function DefaultOverflowMenu({ view }) {
|
|
154
|
+
if (!view.isOpen) return null;
|
|
155
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
156
|
+
style: {
|
|
157
|
+
position: "fixed",
|
|
158
|
+
inset: 0,
|
|
159
|
+
zIndex: 40
|
|
160
|
+
},
|
|
161
|
+
onClick: view.close
|
|
162
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
163
|
+
role: "menu",
|
|
164
|
+
style: {
|
|
165
|
+
position: "absolute",
|
|
166
|
+
right: 0,
|
|
167
|
+
top: "100%",
|
|
168
|
+
zIndex: 41,
|
|
169
|
+
minWidth: 200,
|
|
170
|
+
padding: 4,
|
|
171
|
+
background: "white",
|
|
172
|
+
border: "1px solid rgba(0,0,0,0.15)",
|
|
173
|
+
borderRadius: 6,
|
|
174
|
+
boxShadow: "0 4px 16px rgba(0,0,0,0.15)"
|
|
175
|
+
},
|
|
176
|
+
children: view.sections.map((section, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [i > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: {
|
|
177
|
+
height: 1,
|
|
178
|
+
background: "rgba(0,0,0,0.1)",
|
|
179
|
+
margin: "4px 0"
|
|
180
|
+
} }), section.rows.map((row) => {
|
|
181
|
+
const cmd = view.resolve(row.command);
|
|
182
|
+
if (!cmd) return null;
|
|
183
|
+
const isSubmenu = row.type === "submenu";
|
|
184
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
185
|
+
type: "button",
|
|
186
|
+
role: section.role === "radio" ? "menuitemradio" : "menuitem",
|
|
187
|
+
"aria-checked": section.role === "radio" ? cmd.active : void 0,
|
|
188
|
+
disabled: !cmd.enabled,
|
|
189
|
+
onClick: () => {
|
|
190
|
+
view.execute(row.command);
|
|
191
|
+
if (!isSubmenu) view.close();
|
|
192
|
+
},
|
|
193
|
+
style: {
|
|
194
|
+
display: "flex",
|
|
195
|
+
width: "100%",
|
|
196
|
+
alignItems: "center",
|
|
197
|
+
justifyContent: "space-between",
|
|
198
|
+
gap: 16,
|
|
199
|
+
padding: "6px 8px",
|
|
200
|
+
border: "none",
|
|
201
|
+
background: "transparent",
|
|
202
|
+
cursor: cmd.enabled ? "pointer" : "default",
|
|
203
|
+
opacity: cmd.enabled ? 1 : .4,
|
|
204
|
+
whiteSpace: "nowrap"
|
|
205
|
+
},
|
|
206
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [cmd.active && section.role === "radio" ? "• " : "", cmd.label] }), isSubmenu ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "▸" }) : null]
|
|
207
|
+
}, row.command);
|
|
208
|
+
})] }, i))
|
|
209
|
+
})] });
|
|
210
|
+
}
|
|
211
|
+
function DefaultCollapsed({ view }) {
|
|
212
|
+
if (view.collapse === "select") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
213
|
+
value: view.commands.find((c) => c.active)?.id ?? "",
|
|
214
|
+
onChange: (e) => view.execute(e.target.value),
|
|
215
|
+
style: {
|
|
216
|
+
padding: "4px 6px",
|
|
217
|
+
borderRadius: 4
|
|
218
|
+
},
|
|
219
|
+
children: view.commands.map((c) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
220
|
+
value: c.id,
|
|
221
|
+
disabled: !c.enabled,
|
|
222
|
+
children: c.label
|
|
223
|
+
}, c.id))
|
|
224
|
+
});
|
|
225
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CollapsedMenuButton, { view });
|
|
226
|
+
}
|
|
227
|
+
function CollapsedMenuButton({ view }) {
|
|
228
|
+
const [isOpen, setOpen] = (0, react.useState)(false);
|
|
229
|
+
const sections = [{
|
|
230
|
+
labelKey: view.labelKey,
|
|
231
|
+
role: view.role === "tabs" ? "radio" : void 0,
|
|
232
|
+
rows: view.commands.map((c) => ({
|
|
233
|
+
type: "command",
|
|
234
|
+
command: c.id
|
|
235
|
+
}))
|
|
236
|
+
}];
|
|
237
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
238
|
+
style: {
|
|
239
|
+
position: "relative",
|
|
240
|
+
display: "inline-flex"
|
|
241
|
+
},
|
|
242
|
+
children: [defaultRenderOverflowTrigger(isOpen, () => setOpen((o) => !o)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultOverflowMenu, { view: {
|
|
243
|
+
sections,
|
|
244
|
+
isOpen,
|
|
245
|
+
close: () => setOpen(false),
|
|
246
|
+
resolve: (id) => view.commands.find((c) => c.id === id) ?? null,
|
|
247
|
+
execute: view.execute
|
|
248
|
+
} })]
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
/** Default shed-group disclosure: a chevron opening a radio menu of the
|
|
252
|
+
* hidden children — v2's overflow-tabs-button, derived. */
|
|
253
|
+
function DefaultGroupTrigger({ view }) {
|
|
254
|
+
const [isOpen, setOpen] = (0, react.useState)(false);
|
|
255
|
+
const someActive = view.commands.some((c) => c.active);
|
|
256
|
+
const sections = [{
|
|
257
|
+
labelKey: view.labelKey,
|
|
258
|
+
role: view.role === "tabs" ? "radio" : void 0,
|
|
259
|
+
rows: view.commands.map((c) => ({
|
|
260
|
+
type: "command",
|
|
261
|
+
command: c.id
|
|
262
|
+
}))
|
|
263
|
+
}];
|
|
264
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
265
|
+
style: {
|
|
266
|
+
position: "relative",
|
|
267
|
+
display: "inline-flex"
|
|
268
|
+
},
|
|
269
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
270
|
+
type: "button",
|
|
271
|
+
onClick: () => setOpen((o) => !o),
|
|
272
|
+
"aria-haspopup": "menu",
|
|
273
|
+
"aria-expanded": isOpen,
|
|
274
|
+
title: "More",
|
|
275
|
+
style: {
|
|
276
|
+
display: "inline-flex",
|
|
277
|
+
alignItems: "center",
|
|
278
|
+
padding: "4px 6px",
|
|
279
|
+
border: "1px solid rgba(0,0,0,0.15)",
|
|
280
|
+
borderRadius: 4,
|
|
281
|
+
background: isOpen || someActive ? "rgba(0,0,0,0.12)" : "transparent",
|
|
282
|
+
cursor: "pointer"
|
|
283
|
+
},
|
|
284
|
+
children: "▾"
|
|
285
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultOverflowMenu, { view: {
|
|
286
|
+
sections,
|
|
287
|
+
isOpen,
|
|
288
|
+
close: () => setOpen(false),
|
|
289
|
+
resolve: (id) => view.commands.find((c) => c.id === id) ?? null,
|
|
290
|
+
execute: view.execute
|
|
291
|
+
} })]
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
const unitKey = (u, variant) => `u:${u.key}@${variant}`;
|
|
295
|
+
const groupKey = (id) => `g:${id}`;
|
|
296
|
+
const groupTriggerKey = (id) => `gt:${id}`;
|
|
297
|
+
const TRIGGER_KEY = "t:";
|
|
298
|
+
function Toolbar({ bar, gap = 8, separatorWidth = 1, className, style, renderCommand = defaultRenderCommand, renderCustom, renderCollapsed, renderGroupTrigger, renderSeparator = defaultRenderSeparator, renderOverflowTrigger = defaultRenderOverflowTrigger, renderOverflowMenu }) {
|
|
299
|
+
const kernel = require_runtime.useKernel();
|
|
300
|
+
const commands = require_runtime.useCapability(_embedpdf_plugin_commands.CommandsToken);
|
|
301
|
+
const documentId = require_runtime.useDocumentId();
|
|
302
|
+
const [, force] = (0, react.useReducer)((x) => x + 1, 0);
|
|
303
|
+
(0, react.useEffect)(() => kernel.subscribe(force), [kernel]);
|
|
304
|
+
const containerRef = (0, react.useRef)(null);
|
|
305
|
+
const [containerWidth, setContainerWidth] = (0, react.useState)(0);
|
|
306
|
+
(0, react.useLayoutEffect)(() => {
|
|
307
|
+
const el = containerRef.current;
|
|
308
|
+
if (!el) return;
|
|
309
|
+
const observer = new ResizeObserver((entries) => {
|
|
310
|
+
const w = entries[entries.length - 1]?.contentRect.width;
|
|
311
|
+
if (w !== void 0) setContainerWidth((prev) => Math.abs(prev - w) > .5 ? w : prev);
|
|
312
|
+
});
|
|
313
|
+
observer.observe(el);
|
|
314
|
+
setContainerWidth(el.clientWidth);
|
|
315
|
+
return () => observer.disconnect();
|
|
316
|
+
}, []);
|
|
317
|
+
const widthsRef = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
318
|
+
const [, bumpMeasureVersion] = (0, react.useReducer)((x) => x + 1, 0);
|
|
319
|
+
const onWidth = (0, react.useMemo)(() => (key, width) => {
|
|
320
|
+
const prev = widthsRef.current.get(key);
|
|
321
|
+
if (prev !== void 0 && Math.abs(prev - width) <= .5) return;
|
|
322
|
+
widthsRef.current.set(key, width);
|
|
323
|
+
bumpMeasureVersion();
|
|
324
|
+
}, []);
|
|
325
|
+
const resolveCmd = (id) => commands.resolve(id, documentId ?? void 0);
|
|
326
|
+
const executeCmd = (id) => commands.execute(id, documentId ?? void 0);
|
|
327
|
+
const commandOf = (u) => u.kind === "command" ? u.command : u.terminal;
|
|
328
|
+
const visibleBar = (0, _embedpdf_core_ui.filterBar)((0, react.useMemo)(() => (0, _embedpdf_core_ui.normalizeBar)(bar), [bar]), (u) => resolveCmd(commandOf(u))?.visible === true);
|
|
329
|
+
const fit = (0, _embedpdf_core_ui.solve)(visibleBar, {
|
|
330
|
+
unit: (key, variant) => widthsRef.current.get(`u:${key}@${variant}`),
|
|
331
|
+
groupCollapsed: (id) => widthsRef.current.get(groupKey(id)),
|
|
332
|
+
groupTrigger: (id) => widthsRef.current.get(groupTriggerKey(id)),
|
|
333
|
+
overflowTrigger: widthsRef.current.get(TRIGGER_KEY) ?? 32,
|
|
334
|
+
gap,
|
|
335
|
+
separator: separatorWidth + gap
|
|
336
|
+
}, containerWidth);
|
|
337
|
+
const overflowSections = (0, _embedpdf_core_ui.projectOverflow)(visibleBar, fit, (id) => commands.menuTarget(id));
|
|
338
|
+
const [overflowOpen, setOverflowOpen] = (0, react.useState)(false);
|
|
339
|
+
(0, react.useEffect)(() => {
|
|
340
|
+
if (!fit.hasOverflow) setOverflowOpen(false);
|
|
341
|
+
}, [fit.hasOverflow]);
|
|
342
|
+
/** External = custom unit with no registered renderer → native socket,
|
|
343
|
+
* live-measured (it must NOT appear in the measurement layer: only the
|
|
344
|
+
* first same-named <slot> in tree order receives the projected nodes). */
|
|
345
|
+
const isExternalSlot = (u) => u.kind === "custom" && !renderCustom?.[u.slot];
|
|
346
|
+
const renderUnitAt = (u, variant, layer) => {
|
|
347
|
+
if (u.kind === "custom") {
|
|
348
|
+
const registered = renderCustom?.[u.slot];
|
|
349
|
+
if (registered) {
|
|
350
|
+
const custom = registered(variant, {
|
|
351
|
+
layer,
|
|
352
|
+
measure: (width) => onWidth(unitKey(u, variant), width)
|
|
353
|
+
});
|
|
354
|
+
if (custom !== void 0) return custom;
|
|
355
|
+
} else if (layer === "live") {
|
|
356
|
+
const cmd = resolveCmd(u.terminal);
|
|
357
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NativeSlotSocket, {
|
|
358
|
+
name: u.slot,
|
|
359
|
+
k: unitKey(u, variant),
|
|
360
|
+
onWidth,
|
|
361
|
+
children: cmd ? renderCommand(cmd, "icon", () => executeCmd(u.terminal)) : null
|
|
362
|
+
});
|
|
363
|
+
} else return null;
|
|
364
|
+
const cmd = resolveCmd(u.terminal);
|
|
365
|
+
return cmd ? renderCommand(cmd, "icon", () => executeCmd(u.terminal)) : null;
|
|
366
|
+
}
|
|
367
|
+
const cmd = resolveCmd(u.command);
|
|
368
|
+
if (!cmd) return renderCommand({
|
|
369
|
+
id: u.command,
|
|
370
|
+
label: u.command,
|
|
371
|
+
shortcuts: [],
|
|
372
|
+
enabled: false,
|
|
373
|
+
active: false,
|
|
374
|
+
visible: true,
|
|
375
|
+
categories: []
|
|
376
|
+
}, variant, () => {});
|
|
377
|
+
return renderCommand(cmd, variant, () => executeCmd(u.command));
|
|
378
|
+
};
|
|
379
|
+
const collapsedView = (g) => ({
|
|
380
|
+
id: g.id,
|
|
381
|
+
labelKey: g.labelKey,
|
|
382
|
+
collapse: g.collapse ?? "menu",
|
|
383
|
+
role: g.role,
|
|
384
|
+
commands: g.units.map((u) => resolveCmd(commandOf(u))).filter((c) => c !== null && c.visible),
|
|
385
|
+
execute: executeCmd
|
|
386
|
+
});
|
|
387
|
+
const renderCollapsedGroup = (g) => renderCollapsed ? renderCollapsed(collapsedView(g)) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultCollapsed, { view: collapsedView(g) });
|
|
388
|
+
/** The disclosure view: shed children for the live trigger; the WHOLE group
|
|
389
|
+
* for the measured trigger, so width is budgeted at its fullest content. */
|
|
390
|
+
const disclosureView = (g, allChildren) => ({
|
|
391
|
+
id: g.id,
|
|
392
|
+
labelKey: g.labelKey,
|
|
393
|
+
role: g.role,
|
|
394
|
+
commands: g.units.filter((u) => allChildren || fit.units.get(u.key)?.kind === "shed").map((u) => resolveCmd(commandOf(u))).filter((c) => c !== null && c.visible),
|
|
395
|
+
execute: executeCmd
|
|
396
|
+
});
|
|
397
|
+
const renderDisclosure = (g, allChildren) => renderGroupTrigger ? renderGroupTrigger(disclosureView(g, allChildren)) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultGroupTrigger, { view: disclosureView(g, allChildren) });
|
|
398
|
+
const renderLiveGroup = (g) => {
|
|
399
|
+
const assignment = fit.groups.get(g.id);
|
|
400
|
+
if (!assignment || assignment.overflowed) return [];
|
|
401
|
+
if (assignment.collapsed) return [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderCollapsedGroup(g) }, g.id)];
|
|
402
|
+
const nodes = [];
|
|
403
|
+
for (const u of g.units) {
|
|
404
|
+
const a = fit.units.get(u.key);
|
|
405
|
+
if (a?.kind !== "variant") continue;
|
|
406
|
+
nodes.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderUnitAt(u, a.variant, "live") }, u.key));
|
|
407
|
+
}
|
|
408
|
+
if (assignment.shedCount > 0) nodes.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderDisclosure(g, false) }, `${g.id}::trigger`));
|
|
409
|
+
return nodes.length ? [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: nodes }, g.id)] : [];
|
|
410
|
+
};
|
|
411
|
+
const renderLiveSection = (section) => {
|
|
412
|
+
if (!section) return null;
|
|
413
|
+
return section.groups.map((g) => ({
|
|
414
|
+
id: g.id,
|
|
415
|
+
nodes: renderLiveGroup(g)
|
|
416
|
+
})).filter((g) => g.nodes.length > 0).map((g, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [i > 0 && renderSeparator(), g.nodes] }, g.id));
|
|
417
|
+
};
|
|
418
|
+
const sectionByName = (name) => visibleBar.sections.find((s) => s.name === name);
|
|
419
|
+
/**
|
|
420
|
+
* Segment layout — v2's spacer model, natively. The center segment carries
|
|
421
|
+
* auto margins: it BALANCES in the leftover space (true center when the
|
|
422
|
+
* flanks are symmetric) and yields when they aren't, collapsing to zero
|
|
423
|
+
* before anything can overlap. The container itself has NO gap — segments
|
|
424
|
+
* space themselves — so the solver's global budget (sum of unit widths +
|
|
425
|
+
* per-unit gaps) is exactly the layout's minimum width: what the solver
|
|
426
|
+
* says fits, fits. Its cross-segment gap allowance (≤ 2×gap) becomes slack
|
|
427
|
+
* the auto margins absorb, keeping ≥ gap between segments at the floor.
|
|
428
|
+
* Segments never grow or shrink: fit is the SOLVER's job, not flexbox's.
|
|
429
|
+
*/
|
|
430
|
+
const sectionStyle = (position) => ({
|
|
431
|
+
display: "flex",
|
|
432
|
+
alignItems: "center",
|
|
433
|
+
gap,
|
|
434
|
+
flex: "0 0 auto",
|
|
435
|
+
...position === "center" ? {
|
|
436
|
+
marginLeft: "auto",
|
|
437
|
+
marginRight: "auto"
|
|
438
|
+
} : null
|
|
439
|
+
});
|
|
440
|
+
const overflowView = {
|
|
441
|
+
sections: overflowSections,
|
|
442
|
+
isOpen: overflowOpen,
|
|
443
|
+
close: () => setOverflowOpen(false),
|
|
444
|
+
resolve: resolveCmd,
|
|
445
|
+
execute: executeCmd
|
|
446
|
+
};
|
|
447
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
448
|
+
ref: containerRef,
|
|
449
|
+
className,
|
|
450
|
+
style: {
|
|
451
|
+
position: "relative",
|
|
452
|
+
display: "flex",
|
|
453
|
+
alignItems: "center",
|
|
454
|
+
...style
|
|
455
|
+
},
|
|
456
|
+
children: [
|
|
457
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
458
|
+
style: sectionStyle("start"),
|
|
459
|
+
children: renderLiveSection(sectionByName("start"))
|
|
460
|
+
}),
|
|
461
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
462
|
+
style: sectionStyle("center"),
|
|
463
|
+
children: renderLiveSection(sectionByName("center"))
|
|
464
|
+
}),
|
|
465
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
466
|
+
style: sectionStyle("end"),
|
|
467
|
+
children: [renderLiveSection(sectionByName("end")), fit.hasOverflow && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
468
|
+
style: {
|
|
469
|
+
position: "relative",
|
|
470
|
+
display: "inline-flex"
|
|
471
|
+
},
|
|
472
|
+
children: [renderOverflowTrigger(overflowOpen, () => setOverflowOpen((o) => !o)), renderOverflowMenu ? renderOverflowMenu(overflowView) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultOverflowMenu, { view: overflowView })]
|
|
473
|
+
})]
|
|
474
|
+
}),
|
|
475
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
476
|
+
"aria-hidden": true,
|
|
477
|
+
style: measureLayerStyle,
|
|
478
|
+
children: [visibleBar.sections.flatMap((s) => s.groups.flatMap((g) => [
|
|
479
|
+
...g.units.filter((u) => !isExternalSlot(u)).flatMap((u) => u.variants.map((variant) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Measured, {
|
|
480
|
+
k: unitKey(u, variant),
|
|
481
|
+
onWidth,
|
|
482
|
+
children: renderUnitAt(u, variant, "measure")
|
|
483
|
+
}, unitKey(u, variant)))),
|
|
484
|
+
...g.collapse ? [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Measured, {
|
|
485
|
+
k: groupKey(g.id),
|
|
486
|
+
onWidth,
|
|
487
|
+
children: renderCollapsedGroup(g)
|
|
488
|
+
}, groupKey(g.id))] : [],
|
|
489
|
+
...g.shed ? [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Measured, {
|
|
490
|
+
k: groupTriggerKey(g.id),
|
|
491
|
+
onWidth,
|
|
492
|
+
children: renderDisclosure(g, true)
|
|
493
|
+
}, groupTriggerKey(g.id))] : []
|
|
494
|
+
])), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Measured, {
|
|
495
|
+
k: TRIGGER_KEY,
|
|
496
|
+
onWidth,
|
|
497
|
+
children: renderOverflowTrigger(false, () => {})
|
|
498
|
+
})]
|
|
499
|
+
})
|
|
500
|
+
]
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
//#endregion
|
|
504
|
+
exports.Toolbar = Toolbar;
|
|
505
|
+
exports.useStripView = useStripView;
|
|
506
|
+
Object.keys(_embedpdf_core_ui).forEach(function(k) {
|
|
507
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
508
|
+
enumerable: true,
|
|
509
|
+
get: function() {
|
|
510
|
+
return _embedpdf_core_ui[k];
|
|
511
|
+
}
|
|
512
|
+
});
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
//# sourceMappingURL=toolbar.cjs.map
|