@embedpdf/plugin-redaction 1.5.0 → 2.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.
Files changed (63) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +573 -207
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/actions.d.ts +48 -13
  6. package/dist/lib/index.d.ts +1 -1
  7. package/dist/lib/redaction-plugin.d.ts +22 -8
  8. package/dist/lib/reducer.d.ts +4 -2
  9. package/dist/lib/selectors.d.ts +5 -3
  10. package/dist/lib/types.d.ts +68 -20
  11. package/dist/preact/index.cjs +1 -1
  12. package/dist/preact/index.cjs.map +1 -1
  13. package/dist/preact/index.js +86 -37
  14. package/dist/preact/index.js.map +1 -1
  15. package/dist/react/index.cjs +1 -1
  16. package/dist/react/index.cjs.map +1 -1
  17. package/dist/react/index.js +86 -37
  18. package/dist/react/index.js.map +1 -1
  19. package/dist/shared/components/marquee-redact.d.ts +4 -2
  20. package/dist/shared/components/pending-redactions.d.ts +4 -3
  21. package/dist/shared/components/redaction-layer.d.ts +11 -5
  22. package/dist/shared/components/selection-redact.d.ts +2 -1
  23. package/dist/shared/components/types.d.ts +6 -7
  24. package/dist/shared/hooks/use-redaction.d.ts +4 -4
  25. package/dist/shared-preact/components/marquee-redact.d.ts +4 -2
  26. package/dist/shared-preact/components/pending-redactions.d.ts +4 -3
  27. package/dist/shared-preact/components/redaction-layer.d.ts +11 -5
  28. package/dist/shared-preact/components/selection-redact.d.ts +2 -1
  29. package/dist/shared-preact/components/types.d.ts +6 -7
  30. package/dist/shared-preact/hooks/use-redaction.d.ts +4 -4
  31. package/dist/shared-react/components/marquee-redact.d.ts +4 -2
  32. package/dist/shared-react/components/pending-redactions.d.ts +4 -3
  33. package/dist/shared-react/components/redaction-layer.d.ts +11 -5
  34. package/dist/shared-react/components/selection-redact.d.ts +2 -1
  35. package/dist/shared-react/components/types.d.ts +6 -7
  36. package/dist/shared-react/hooks/use-redaction.d.ts +4 -4
  37. package/dist/svelte/components/highlight.svelte.d.ts +14 -0
  38. package/dist/svelte/components/index.d.ts +5 -0
  39. package/dist/svelte/components/marquee-redact.svelte.d.ts +16 -0
  40. package/dist/svelte/components/pending-redactions.svelte.d.ts +15 -0
  41. package/dist/svelte/components/redaction-layer.svelte.d.ts +20 -0
  42. package/dist/svelte/components/selection-redact.svelte.d.ts +8 -0
  43. package/dist/svelte/hooks/index.d.ts +1 -0
  44. package/dist/svelte/hooks/use-redaction.svelte.d.ts +21 -0
  45. package/dist/svelte/index.cjs +2 -0
  46. package/dist/svelte/index.cjs.map +1 -0
  47. package/dist/svelte/index.d.ts +4 -0
  48. package/dist/svelte/index.js +554 -0
  49. package/dist/svelte/index.js.map +1 -0
  50. package/dist/svelte/types.d.ts +10 -0
  51. package/dist/vue/components/highlight.vue.d.ts +2 -1
  52. package/dist/vue/components/marquee-redact.vue.d.ts +5 -2
  53. package/dist/vue/components/pending-redactions.vue.d.ts +18 -13
  54. package/dist/vue/components/redaction-layer.vue.d.ts +13 -4
  55. package/dist/vue/components/selection-redact.vue.d.ts +3 -1
  56. package/dist/vue/components/types.d.ts +9 -0
  57. package/dist/vue/hooks/use-redaction.d.ts +9 -102
  58. package/dist/vue/index.cjs +1 -1
  59. package/dist/vue/index.cjs.map +1 -1
  60. package/dist/vue/index.d.ts +1 -0
  61. package/dist/vue/index.js +219 -125
  62. package/dist/vue/index.js.map +1 -1
  63. package/package.json +18 -10
@@ -1,33 +1,38 @@
1
1
  import { Rotation } from '@embedpdf/models';
2
+ import { RedactionSelectionMenuRenderFn } from './types';
2
3
  interface PendingRedactionsProps {
4
+ documentId: string;
3
5
  pageIndex: number;
4
6
  scale: number;
5
- rotation?: Rotation;
7
+ rotation: Rotation;
6
8
  bboxStroke?: string;
9
+ /** Render function for selection menu (schema-driven approach) */
10
+ selectionMenu?: RedactionSelectionMenuRenderFn;
7
11
  }
8
- declare var __VLS_7: {
9
- item: any;
12
+ declare var __VLS_12: {
13
+ context: any;
10
14
  selected: boolean;
11
- pageIndex: any;
12
- menuWrapperProps: any;
13
15
  rect: any;
14
- }, __VLS_19: {
15
- item: any;
16
- selected: boolean;
17
- pageIndex: any;
16
+ placement: any;
18
17
  menuWrapperProps: any;
18
+ }, __VLS_29: {
19
+ context: any;
20
+ selected: boolean;
19
21
  rect: any;
22
+ placement: any;
23
+ menuWrapperProps: any;
20
24
  };
21
25
  type __VLS_Slots = {} & {
22
- 'selection-menu'?: (props: typeof __VLS_7) => any;
26
+ 'selection-menu'?: (props: typeof __VLS_12) => any;
23
27
  } & {
24
- 'selection-menu'?: (props: typeof __VLS_19) => any;
28
+ 'selection-menu'?: (props: typeof __VLS_29) => any;
25
29
  };
26
- declare const __VLS_component: import('vue').DefineComponent<PendingRedactionsProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<PendingRedactionsProps> & Readonly<{}>, {
30
+ declare const __VLS_base: import('vue').DefineComponent<PendingRedactionsProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<PendingRedactionsProps> & Readonly<{}>, {
27
31
  rotation: Rotation;
28
32
  bboxStroke: string;
29
33
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
30
- declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
34
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
35
+ declare const _default: typeof __VLS_export;
31
36
  export default _default;
32
37
  type __VLS_WithSlots<T, S> = T & {
33
38
  new (): {
@@ -1,19 +1,28 @@
1
1
  import { Rotation } from '@embedpdf/models';
2
+ import { RedactionSelectionMenuRenderFn } from './types';
2
3
  interface RedactionLayerProps {
4
+ /** The ID of the document this layer belongs to */
5
+ documentId: string;
6
+ /** Index of the page this layer lives on */
3
7
  pageIndex: number;
4
- scale: number;
8
+ /** Current render scale for this page */
9
+ scale?: number;
10
+ /** Page rotation (for counter-rotating menus, etc.) */
5
11
  rotation?: Rotation;
12
+ /** Optional bbox stroke color */
6
13
  bboxStroke?: string;
14
+ /** Optional menu renderer for a selected redaction */
15
+ selectionMenu?: RedactionSelectionMenuRenderFn;
7
16
  }
8
17
  declare var __VLS_6: any;
9
18
  type __VLS_Slots = {} & {
10
19
  'selection-menu'?: (props: typeof __VLS_6) => any;
11
20
  };
12
- declare const __VLS_component: import('vue').DefineComponent<RedactionLayerProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<RedactionLayerProps> & Readonly<{}>, {
13
- rotation: Rotation;
21
+ declare const __VLS_base: import('vue').DefineComponent<RedactionLayerProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<RedactionLayerProps> & Readonly<{}>, {
14
22
  bboxStroke: string;
15
23
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
16
- declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
24
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
25
+ declare const _default: typeof __VLS_export;
17
26
  export default _default;
18
27
  type __VLS_WithSlots<T, S> = T & {
19
28
  new (): {
@@ -1,6 +1,8 @@
1
1
  interface SelectionRedactProps {
2
+ documentId: string;
2
3
  pageIndex: number;
3
4
  scale: number;
4
5
  }
5
- declare const _default: import('vue').DefineComponent<SelectionRedactProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<SelectionRedactProps> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
6
+ declare const __VLS_export: import('vue').DefineComponent<SelectionRedactProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<SelectionRedactProps> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
7
+ declare const _default: typeof __VLS_export;
6
8
  export default _default;
@@ -0,0 +1,9 @@
1
+ import { SelectionMenuPropsBase, SelectionMenuRenderFn } from '@embedpdf/utils/vue';
2
+ import { RedactionItem } from '../../lib/index.ts';
3
+ export interface RedactionSelectionContext {
4
+ type: 'redaction';
5
+ item: RedactionItem;
6
+ pageIndex: number;
7
+ }
8
+ export type RedactionSelectionMenuProps = SelectionMenuPropsBase<RedactionSelectionContext>;
9
+ export type RedactionSelectionMenuRenderFn = SelectionMenuRenderFn<RedactionSelectionContext>;
@@ -1,105 +1,12 @@
1
- import { RedactionPlugin } from '../../lib/index.ts';
1
+ import { MaybeRefOrGetter, ComputedRef, Ref } from 'vue';
2
+ import { RedactionPlugin, RedactionDocumentState, RedactionScope } from '../../lib/index.ts';
2
3
  export declare const useRedactionPlugin: () => import('@embedpdf/core/vue').PluginState<RedactionPlugin>;
3
4
  export declare const useRedactionCapability: () => import('@embedpdf/core/vue').CapabilityState<Readonly<import('../../lib/index.ts').RedactionCapability>>;
4
- export declare const useRedaction: () => {
5
- state: Readonly<import('vue').Ref<{
6
- readonly isRedacting: boolean;
7
- readonly activeType: import('../../lib/index.ts').RedactionMode | null;
8
- readonly pending: {
9
- readonly [x: number]: readonly ({
10
- readonly id: string;
11
- readonly kind: "text";
12
- readonly page: number;
13
- readonly rect: {
14
- readonly origin: {
15
- readonly x: number;
16
- readonly y: number;
17
- };
18
- readonly size: {
19
- readonly width: number;
20
- readonly height: number;
21
- };
22
- };
23
- readonly rects: readonly {
24
- readonly origin: {
25
- readonly x: number;
26
- readonly y: number;
27
- };
28
- readonly size: {
29
- readonly width: number;
30
- readonly height: number;
31
- };
32
- }[];
33
- } | {
34
- readonly id: string;
35
- readonly kind: "area";
36
- readonly page: number;
37
- readonly rect: {
38
- readonly origin: {
39
- readonly x: number;
40
- readonly y: number;
41
- };
42
- readonly size: {
43
- readonly width: number;
44
- readonly height: number;
45
- };
46
- };
47
- })[];
48
- };
49
- readonly pendingCount: number;
50
- readonly selected: {
51
- readonly page: number;
52
- readonly id: string | null;
53
- } | null;
54
- }, {
55
- readonly isRedacting: boolean;
56
- readonly activeType: import('../../lib/index.ts').RedactionMode | null;
57
- readonly pending: {
58
- readonly [x: number]: readonly ({
59
- readonly id: string;
60
- readonly kind: "text";
61
- readonly page: number;
62
- readonly rect: {
63
- readonly origin: {
64
- readonly x: number;
65
- readonly y: number;
66
- };
67
- readonly size: {
68
- readonly width: number;
69
- readonly height: number;
70
- };
71
- };
72
- readonly rects: readonly {
73
- readonly origin: {
74
- readonly x: number;
75
- readonly y: number;
76
- };
77
- readonly size: {
78
- readonly width: number;
79
- readonly height: number;
80
- };
81
- }[];
82
- } | {
83
- readonly id: string;
84
- readonly kind: "area";
85
- readonly page: number;
86
- readonly rect: {
87
- readonly origin: {
88
- readonly x: number;
89
- readonly y: number;
90
- };
91
- readonly size: {
92
- readonly width: number;
93
- readonly height: number;
94
- };
95
- };
96
- })[];
97
- };
98
- readonly pendingCount: number;
99
- readonly selected: {
100
- readonly page: number;
101
- readonly id: string | null;
102
- } | null;
103
- }>>;
104
- provides: import('vue').Ref<Readonly<import('../../lib/index.ts').RedactionCapability> | null, Readonly<import('../../lib/index.ts').RedactionCapability> | null>;
5
+ /**
6
+ * Hook for redaction state for a specific document
7
+ * @param documentId Document ID (can be ref, computed, getter, or plain value)
8
+ */
9
+ export declare const useRedaction: (documentId: MaybeRefOrGetter<string>) => {
10
+ state: Readonly<Ref<RedactionDocumentState>>;
11
+ provides: ComputedRef<RedactionScope | null>;
105
12
  };
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),t=require("@embedpdf/core/vue"),o=require("@embedpdf/plugin-redaction"),n=require("@embedpdf/utils/vue"),r=()=>t.usePlugin(o.RedactionPlugin.id),l=()=>t.useCapability(o.RedactionPlugin.id),a=e.defineComponent({__name:"highlight",props:{color:{default:"#FFFF00"},opacity:{default:1},border:{default:"1px solid red"},rects:{},rect:{},scale:{},onClick:{}},setup(t){const o=t.rect;return(t,n)=>(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.rects,((r,l)=>(e.openBlock(),e.createElementBlock("div",e.mergeProps({key:l,onPointerdown:n[0]||(n[0]=(...e)=>t.onClick&&t.onClick(...e)),onTouchstart:n[1]||(n[1]=(...e)=>t.onClick&&t.onClick(...e)),style:{position:"absolute",border:t.border,left:(e.unref(o)?r.origin.x-e.unref(o).origin.x:r.origin.x)*t.scale+"px",top:(e.unref(o)?r.origin.y-e.unref(o).origin.y:r.origin.y)*t.scale+"px",width:r.size.width*t.scale+"px",height:r.size.height*t.scale+"px",background:t.color,opacity:t.opacity,pointerEvents:t.onClick?"auto":"none",cursor:t.onClick?"pointer":"default",zIndex:t.onClick?1:void 0}},{ref_for:!0},t.$attrs),null,16)))),128))}}),i=e.defineComponent({__name:"marquee-redact",props:{pageIndex:{},scale:{},className:{},stroke:{default:"red"},fill:{default:"transparent"}},setup(t){const o=t,{plugin:n}=r(),l=e.ref(null);let a;return e.onMounted((()=>{n.value&&(a=n.value.registerMarqueeOnPage({pageIndex:o.pageIndex,scale:o.scale,callback:{onPreview:e=>{l.value=e}}}))})),e.onUnmounted((()=>{null==a||a()})),(t,o)=>l.value?(e.openBlock(),e.createElementBlock("div",{key:0,style:e.normalizeStyle({position:"absolute",pointerEvents:"none",left:l.value.origin.x*t.scale+"px",top:l.value.origin.y*t.scale+"px",width:l.value.size.width*t.scale+"px",height:l.value.size.height*t.scale+"px",border:`1px solid ${t.stroke}`,background:t.fill,boxSizing:"border-box"}),class:e.normalizeClass(t.className)},null,6)):e.createCommentVNode("",!0)}}),c={key:0,style:{mixBlendMode:"normal",pointerEvents:"none",position:"absolute",inset:0}},s=e.defineComponent({__name:"selection-redact",props:{pageIndex:{},scale:{}},setup(t){const o=t,{plugin:n}=r(),l=e.ref([]),i=e.ref(null);let s;return e.onMounted((()=>{n.value&&(s=n.value.onRedactionSelectionChange((e=>{const t=e.find((e=>e.pageIndex===o.pageIndex));l.value=(null==t?void 0:t.segmentRects)??[],i.value=(null==t?void 0:t.rect)??null})))})),e.onUnmounted((()=>{null==s||s()})),(t,o)=>i.value?(e.openBlock(),e.createElementBlock("div",c,[e.createVNode(a,{color:"transparent",opacity:1,rects:l.value,scale:t.scale,border:"1px solid red"},null,8,["rects","scale"])])):e.createCommentVNode("",!0)}}),d={key:0,style:{position:"absolute",inset:0,pointerEvents:"none"}},p=["onPointerdown","onTouchstart"],u=e.defineComponent({__name:"pending-redactions",props:{pageIndex:{},scale:{},rotation:{default:0},bboxStroke:{default:"rgba(0,0,0,0.8)"}},setup(t){const o=t,{provides:r}=l(),i=e.ref([]),c=e.ref(null),s=(e,t)=>{e.stopPropagation(),r.value&&r.value.selectPending(o.pageIndex,t)};let u,g;return e.onMounted((()=>{r.value&&(u=r.value.onPendingChange((e=>{i.value=e[o.pageIndex]??[]})),g=r.value.onSelectedChange((e=>{c.value=e&&e.page===o.pageIndex?e.id:null})))})),e.onUnmounted((()=>{null==u||u(),null==g||g()})),(t,o)=>i.value.length?(e.openBlock(),e.createElementBlock("div",d,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(i.value,(o=>(e.openBlock(),e.createElementBlock(e.Fragment,{key:o.id},["area"===o.kind?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createElementVNode("div",{style:e.normalizeStyle({position:"absolute",left:o.rect.origin.x*t.scale+"px",top:o.rect.origin.y*t.scale+"px",width:o.rect.size.width*t.scale+"px",height:o.rect.size.height*t.scale+"px",background:"transparent",outline:c.value===o.id?`1px solid ${t.bboxStroke}`:"none",outlineOffset:"2px",border:"1px solid red",pointerEvents:"auto",cursor:"pointer"}),onPointerdown:e=>s(e,o.id),onTouchstart:e=>s(e,o.id)},null,44,p),e.createVNode(e.unref(n.CounterRotate),{rect:{origin:{x:o.rect.origin.x*t.scale,y:o.rect.origin.y*t.scale},size:{width:o.rect.size.width*t.scale,height:o.rect.size.height*t.scale}},rotation:t.rotation},{default:e.withCtx((({rect:n,menuWrapperProps:r})=>[e.renderSlot(t.$slots,"selection-menu",{item:o,selected:c.value===o.id,pageIndex:t.pageIndex,menuWrapperProps:r,rect:n})])),_:2},1032,["rect","rotation"])],64)):(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.createElementVNode("div",{style:e.normalizeStyle({position:"absolute",left:o.rect.origin.x*t.scale+"px",top:o.rect.origin.y*t.scale+"px",width:o.rect.size.width*t.scale+"px",height:o.rect.size.height*t.scale+"px",background:"transparent",outline:c.value===o.id?`1px solid ${t.bboxStroke}`:"none",outlineOffset:"2px",pointerEvents:"auto",cursor:c.value===o.id?"pointer":"default"})},[e.createVNode(a,{rect:o.rect,rects:o.rects,color:"transparent",border:"1px solid red",scale:t.scale,"on-click":e=>s(e,o.id)},null,8,["rect","rects","scale","on-click"])],4),e.createVNode(e.unref(n.CounterRotate),{rect:{origin:{x:o.rect.origin.x*t.scale,y:o.rect.origin.y*t.scale},size:{width:o.rect.size.width*t.scale,height:o.rect.size.height*t.scale}},rotation:t.rotation},{default:e.withCtx((({rect:n,menuWrapperProps:r})=>[e.renderSlot(t.$slots,"selection-menu",{item:o,selected:c.value===o.id,pageIndex:t.pageIndex,menuWrapperProps:r,rect:n})])),_:2},1032,["rect","rotation"])],64))],64)))),128))])):e.createCommentVNode("",!0)}}),g=e.defineComponent({__name:"redaction-layer",props:{pageIndex:{},scale:{},rotation:{default:0},bboxStroke:{default:"rgba(0,0,0,0.8)"}},setup:t=>(t,o)=>(e.openBlock(),e.createElementBlock(e.Fragment,null,[e.createVNode(u,{"page-index":t.pageIndex,scale:t.scale,rotation:t.rotation,"bbox-stroke":t.bboxStroke},{"selection-menu":e.withCtx((o=>[e.renderSlot(t.$slots,"selection-menu",e.normalizeProps(e.guardReactiveProps(o)))])),_:3},8,["page-index","scale","rotation","bbox-stroke"]),e.createVNode(i,{"page-index":t.pageIndex,scale:t.scale},null,8,["page-index","scale"]),e.createVNode(s,{"page-index":t.pageIndex,scale:t.scale},null,8,["page-index","scale"])],64))});exports.Highlight=a,exports.MarqueeRedact=i,exports.PendingRedactions=u,exports.RedactionLayer=g,exports.SelectionRedact=s,exports.useRedaction=()=>{const{provides:t}=l(),n=e.ref(o.initialState);return e.watchEffect((e=>{if(!t.value)return;e(t.value.onStateChange((e=>{n.value=e})))})),{state:e.readonly(n),provides:t}},exports.useRedactionCapability=l,exports.useRedactionPlugin=r,Object.keys(o).forEach((e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>o[e]})}));
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),t=require("@embedpdf/core/vue"),o=require("@embedpdf/plugin-redaction"),n=require("@embedpdf/models"),l=require("@embedpdf/utils/vue"),r=()=>t.usePlugin(o.RedactionPlugin.id),a=()=>t.useCapability(o.RedactionPlugin.id),i=e.defineComponent({__name:"highlight",props:{color:{default:"#FFFF00"},opacity:{default:1},border:{default:"1px solid red"},rects:{},rect:{},scale:{},onClick:{}},setup(t){const o=t.rect;return(n,l)=>(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.rects,(r,a)=>(e.openBlock(),e.createElementBlock("div",e.mergeProps({key:a,onPointerdown:l[0]||(l[0]=(...e)=>t.onClick&&t.onClick(...e)),onTouchstart:l[1]||(l[1]=(...e)=>t.onClick&&t.onClick(...e)),style:{position:"absolute",border:t.border,left:(e.unref(o)?r.origin.x-e.unref(o).origin.x:r.origin.x)*t.scale+"px",top:(e.unref(o)?r.origin.y-e.unref(o).origin.y:r.origin.y)*t.scale+"px",width:r.size.width*t.scale+"px",height:r.size.height*t.scale+"px",background:t.color,opacity:t.opacity,pointerEvents:t.onClick?"auto":"none",cursor:t.onClick?"pointer":"default",zIndex:t.onClick?1:void 0}},{ref_for:!0},n.$attrs),null,16))),128))}}),c=e.defineComponent({__name:"marquee-redact",props:{documentId:{},pageIndex:{},scale:{},className:{},stroke:{default:"red"},fill:{default:"transparent"}},setup(o){const n=o,{plugin:l}=r(),a=t.useDocumentState(()=>n.documentId),i=e.ref(null),c=e.computed(()=>{var e;return void 0!==n.scale?n.scale:(null==(e=a.value)?void 0:e.scale)??1});return e.watch([l,()=>n.documentId,()=>n.pageIndex,c],([e,t,o,n],l,r)=>{if(!e||!t)return;r(e.registerMarqueeOnPage({documentId:t,pageIndex:o,scale:n,callback:{onPreview:e=>{i.value=e}}}))},{immediate:!0}),(t,n)=>i.value?(e.openBlock(),e.createElementBlock("div",{key:0,style:e.normalizeStyle({position:"absolute",pointerEvents:"none",left:i.value.origin.x*c.value+"px",top:i.value.origin.y*c.value+"px",width:i.value.size.width*c.value+"px",height:i.value.size.height*c.value+"px",border:`1px solid ${o.stroke}`,background:o.fill,boxSizing:"border-box"}),class:e.normalizeClass(o.className)},null,6)):e.createCommentVNode("",!0)}}),s={key:0,style:{mixBlendMode:"normal",pointerEvents:"none",position:"absolute",inset:0}},d=e.defineComponent({__name:"selection-redact",props:{documentId:{},pageIndex:{},scale:{}},setup(t){const o=t,{plugin:n}=r(),l=e.ref([]),a=e.ref(null);return e.watch([n,()=>o.documentId,()=>o.pageIndex],([e,t,o],n,r)=>{if(!e)return l.value=[],void(a.value=null);r(e.onRedactionSelectionChange(t,e=>{const t=e.find(e=>e.pageIndex===o);l.value=(null==t?void 0:t.segmentRects)??[],a.value=(null==t?void 0:t.rect)??null}))},{immediate:!0}),(o,n)=>a.value?(e.openBlock(),e.createElementBlock("div",s,[e.createVNode(i,{color:"transparent",opacity:1,rects:l.value,scale:t.scale,border:"1px solid red"},null,8,["rects","scale"])])):e.createCommentVNode("",!0)}}),u={key:0,style:{position:"absolute",inset:0,pointerEvents:"none"}},p=["onPointerdown","onTouchstart"],m=e.defineComponent({__name:"pending-redactions",props:{documentId:{},pageIndex:{},scale:{},rotation:{default:n.Rotation.Degree0},bboxStroke:{default:"rgba(0,0,0,0.8)"},selectionMenu:{}},setup(t){const o=t,n=e.useSlots(),{provides:r}=a(),c=e.ref([]),s=e.ref(null);e.watch([r,()=>o.documentId,()=>o.pageIndex],([e,t,o],n,l)=>{if(!e)return c.value=[],void(s.value=null);const r=e.forDocument(t),a=r.getState();c.value=a.pending[o]??[],s.value=a.selected&&a.selected.page===o?a.selected.id:null;const i=r.onPendingChange(e=>{c.value=e[o]??[]}),d=r.onSelectedChange(e=>{s.value=e&&e.page===o?e.id:null});l(()=>{null==i||i(),null==d||d()})},{immediate:!0});const d=(e,t)=>{e.stopPropagation();const n=r.value;n&&n.forDocument(o.documentId).selectPending(o.pageIndex,t)},m=e=>s.value===e&&(!!o.selectionMenu||!!n["selection-menu"]),g=e=>({type:"redaction",item:e,pageIndex:o.pageIndex}),v={suggestTop:!1,spaceAbove:0,spaceBelow:0},x=(e,t,n)=>o.selectionMenu?o.selectionMenu({rect:t,menuWrapperProps:n,selected:s.value===e.id,placement:v,context:g(e)}):null;return(o,n)=>c.value.length?(e.openBlock(),e.createElementBlock("div",u,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(c.value,n=>(e.openBlock(),e.createElementBlock(e.Fragment,{key:n.id},["area"===n.kind?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createElementVNode("div",{style:e.normalizeStyle({position:"absolute",left:n.rect.origin.x*t.scale+"px",top:n.rect.origin.y*t.scale+"px",width:n.rect.size.width*t.scale+"px",height:n.rect.size.height*t.scale+"px",background:"transparent",outline:s.value===n.id?`1px solid ${t.bboxStroke}`:"none",outlineOffset:"2px",border:"1px solid red",pointerEvents:"auto",cursor:"pointer"}),onPointerdown:e=>d(e,n.id),onTouchstart:e=>d(e,n.id)},null,44,p),m(n.id)?(e.openBlock(),e.createBlock(e.unref(l.CounterRotate),{key:0,rect:{origin:{x:n.rect.origin.x*t.scale,y:n.rect.origin.y*t.scale},size:{width:n.rect.size.width*t.scale,height:n.rect.size.height*t.scale}},rotation:t.rotation},{default:e.withCtx(({rect:l,menuWrapperProps:r})=>[t.selectionMenu?(e.openBlock(),e.createBlock(e.resolveDynamicComponent(x(n,l,r)),{key:0})):e.renderSlot(o.$slots,"selection-menu",{key:1,context:g(n),selected:s.value===n.id,rect:l,placement:v,menuWrapperProps:r})]),_:2},1032,["rect","rotation"])):e.createCommentVNode("",!0)],64)):(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.createElementVNode("div",{style:e.normalizeStyle({position:"absolute",left:n.rect.origin.x*t.scale+"px",top:n.rect.origin.y*t.scale+"px",width:n.rect.size.width*t.scale+"px",height:n.rect.size.height*t.scale+"px",background:"transparent",outline:s.value===n.id?`1px solid ${t.bboxStroke}`:"none",outlineOffset:"2px",pointerEvents:"auto",cursor:s.value===n.id?"pointer":"default"})},[e.createVNode(i,{rect:n.rect,rects:n.rects,color:"transparent",border:"1px solid red",scale:t.scale,"on-click":e=>d(e,n.id)},null,8,["rect","rects","scale","on-click"])],4),m(n.id)?(e.openBlock(),e.createBlock(e.unref(l.CounterRotate),{key:0,rect:{origin:{x:n.rect.origin.x*t.scale,y:n.rect.origin.y*t.scale},size:{width:n.rect.size.width*t.scale,height:n.rect.size.height*t.scale}},rotation:t.rotation},{default:e.withCtx(({rect:l,menuWrapperProps:r})=>[t.selectionMenu?(e.openBlock(),e.createBlock(e.resolveDynamicComponent(x(n,l,r)),{key:0})):e.renderSlot(o.$slots,"selection-menu",{key:1,context:g(n),selected:s.value===n.id,rect:l,placement:v,menuWrapperProps:r})]),_:2},1032,["rect","rotation"])):e.createCommentVNode("",!0)],64))],64))),128))])):e.createCommentVNode("",!0)}}),g=e.defineComponent({__name:"redaction-layer",props:{documentId:{},pageIndex:{},scale:{},rotation:{},bboxStroke:{default:"rgba(0,0,0,0.8)"},selectionMenu:{}},setup(o){const l=o,r=t.useDocumentState(()=>l.documentId),a=e.computed(()=>{var e;return void 0!==l.scale?l.scale:(null==(e=r.value)?void 0:e.scale)??1}),i=e.computed(()=>{var e;return void 0!==l.rotation?l.rotation:(null==(e=r.value)?void 0:e.rotation)??n.Rotation.Degree0});return(t,n)=>(e.openBlock(),e.createElementBlock(e.Fragment,null,[e.createVNode(m,{"document-id":o.documentId,"page-index":o.pageIndex,scale:a.value,rotation:i.value,"bbox-stroke":o.bboxStroke,"selection-menu":o.selectionMenu},{"selection-menu":e.withCtx(o=>[e.renderSlot(t.$slots,"selection-menu",e.normalizeProps(e.guardReactiveProps(o)))]),_:3},8,["document-id","page-index","scale","rotation","bbox-stroke","selection-menu"]),e.createVNode(c,{"document-id":o.documentId,"page-index":o.pageIndex,scale:a.value},null,8,["document-id","page-index","scale"]),e.createVNode(d,{"document-id":o.documentId,"page-index":o.pageIndex,scale:a.value},null,8,["document-id","page-index","scale"])],64))}});exports.Highlight=i,exports.MarqueeRedact=c,exports.PendingRedactions=m,exports.RedactionLayer=g,exports.SelectionRedact=d,exports.useRedaction=t=>{const{provides:n}=a(),l=e.ref(o.initialDocumentState);e.watch([n,()=>e.toValue(t)],([e,t],n,r)=>{if(!e)return void(l.value=o.initialDocumentState);const a=e.forDocument(t);try{l.value=a.getState()}catch(i){l.value=o.initialDocumentState}r(a.onStateChange(e=>{l.value=e}))},{immediate:!0});const r=e.computed(()=>{var o;const l=e.toValue(t);return(null==(o=n.value)?void 0:o.forDocument(l))??null});return{state:l,provides:r}},exports.useRedactionCapability=a,exports.useRedactionPlugin=r,Object.keys(o).forEach(e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>o[e]})});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/vue/hooks/use-redaction.ts","../../src/vue/components/highlight.vue","../../src/vue/components/marquee-redact.vue","../../src/vue/components/selection-redact.vue","../../src/vue/components/pending-redactions.vue","../../src/vue/components/redaction-layer.vue"],"sourcesContent":["import { ref, watchEffect, readonly } from 'vue';\nimport { useCapability, usePlugin } from '@embedpdf/core/vue';\nimport { RedactionPlugin, initialState, RedactionState } from '@embedpdf/plugin-redaction';\n\nexport const useRedactionPlugin = () => usePlugin<RedactionPlugin>(RedactionPlugin.id);\nexport const useRedactionCapability = () => useCapability<RedactionPlugin>(RedactionPlugin.id);\n\nexport const useRedaction = () => {\n const { provides } = useRedactionCapability();\n const state = ref<RedactionState>(initialState);\n\n watchEffect((onCleanup) => {\n if (!provides.value) return;\n\n const unsubscribe = provides.value.onStateChange((newState) => {\n state.value = newState;\n });\n onCleanup(unsubscribe);\n });\n\n return {\n state: readonly(state),\n provides,\n };\n};\n","<template>\n <div\n v-for=\"(rect, i) in rects\"\n :key=\"i\"\n @pointerdown=\"onClick\"\n @touchstart=\"onClick\"\n :style=\"{\n position: 'absolute',\n border,\n left: `${(boundingRect ? rect.origin.x - boundingRect.origin.x : rect.origin.x) * scale}px`,\n top: `${(boundingRect ? rect.origin.y - boundingRect.origin.y : rect.origin.y) * scale}px`,\n width: `${rect.size.width * scale}px`,\n height: `${rect.size.height * scale}px`,\n background: color,\n opacity: opacity,\n pointerEvents: onClick ? 'auto' : 'none',\n cursor: onClick ? 'pointer' : 'default',\n zIndex: onClick ? 1 : undefined,\n }\"\n v-bind=\"$attrs\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport type { Rect } from '@embedpdf/models';\n\ninterface HighlightProps {\n color?: string;\n opacity?: number;\n border?: string;\n rects: Rect[];\n rect?: Rect;\n scale: number;\n onClick?: (e: PointerEvent | TouchEvent) => void;\n}\n\nconst props = withDefaults(defineProps<HighlightProps>(), {\n color: '#FFFF00',\n opacity: 1,\n border: '1px solid red',\n});\n\n// Rename rect to boundingRect for clarity in template\nconst boundingRect = props.rect;\n</script>\n","<template>\n <div\n v-if=\"rect\"\n :style=\"{\n position: 'absolute',\n pointerEvents: 'none',\n left: `${rect.origin.x * scale}px`,\n top: `${rect.origin.y * scale}px`,\n width: `${rect.size.width * scale}px`,\n height: `${rect.size.height * scale}px`,\n border: `1px solid ${stroke}`,\n background: fill,\n boxSizing: 'border-box',\n }\"\n :class=\"className\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted } from 'vue';\nimport type { Rect } from '@embedpdf/models';\nimport { useRedactionPlugin } from '../hooks/use-redaction';\n\ninterface MarqueeRedactProps {\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Scale of the page */\n scale: number;\n /** Optional CSS class applied to the marquee rectangle */\n className?: string;\n /** Stroke / fill colours (defaults below) */\n stroke?: string;\n fill?: string;\n}\n\nconst props = withDefaults(defineProps<MarqueeRedactProps>(), {\n stroke: 'red',\n fill: 'transparent',\n});\n\nconst { plugin: redactionPlugin } = useRedactionPlugin();\nconst rect = ref<Rect | null>(null);\n\nlet unregister: (() => void) | undefined;\n\nonMounted(() => {\n if (!redactionPlugin.value) return;\n\n unregister = redactionPlugin.value.registerMarqueeOnPage({\n pageIndex: props.pageIndex,\n scale: props.scale,\n callback: {\n onPreview: (newRect) => {\n rect.value = newRect;\n },\n },\n });\n});\n\nonUnmounted(() => {\n unregister?.();\n});\n</script>\n","<template>\n <div\n v-if=\"boundingRect\"\n :style=\"{\n mixBlendMode: 'normal',\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n }\"\n >\n <Highlight\n :color=\"'transparent'\"\n :opacity=\"1\"\n :rects=\"rects\"\n :scale=\"scale\"\n border=\"1px solid red\"\n />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted } from 'vue';\nimport type { Rect } from '@embedpdf/models';\nimport { useRedactionPlugin } from '../hooks/use-redaction';\nimport Highlight from './highlight.vue';\n\ninterface SelectionRedactProps {\n pageIndex: number;\n scale: number;\n}\n\nconst props = defineProps<SelectionRedactProps>();\n\nconst { plugin: redactionPlugin } = useRedactionPlugin();\nconst rects = ref<Rect[]>([]);\nconst boundingRect = ref<Rect | null>(null);\n\nlet unsubscribe: (() => void) | undefined;\n\nonMounted(() => {\n if (!redactionPlugin.value) return;\n\n unsubscribe = redactionPlugin.value.onRedactionSelectionChange((formattedSelection) => {\n const selection = formattedSelection.find((s) => s.pageIndex === props.pageIndex);\n rects.value = selection?.segmentRects ?? [];\n boundingRect.value = selection?.rect ?? null;\n });\n});\n\nonUnmounted(() => {\n unsubscribe?.();\n});\n</script>\n","<template>\n <div v-if=\"items.length\" :style=\"{ position: 'absolute', inset: 0, pointerEvents: 'none' }\">\n <template v-for=\"item in items\" :key=\"item.id\">\n <!-- Area redaction -->\n <template v-if=\"item.kind === 'area'\">\n <div\n :style=\"{\n position: 'absolute',\n left: `${item.rect.origin.x * scale}px`,\n top: `${item.rect.origin.y * scale}px`,\n width: `${item.rect.size.width * scale}px`,\n height: `${item.rect.size.height * scale}px`,\n background: 'transparent',\n outline: selectedId === item.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n border: `1px solid red`,\n pointerEvents: 'auto',\n cursor: 'pointer',\n }\"\n @pointerdown=\"(e: PointerEvent) => select(e, item.id)\"\n @touchstart=\"(e: TouchEvent) => select(e, item.id)\"\n />\n <CounterRotate\n :rect=\"{\n origin: { x: item.rect.origin.x * scale, y: item.rect.origin.y * scale },\n size: { width: item.rect.size.width * scale, height: item.rect.size.height * scale },\n }\"\n :rotation=\"rotation\"\n >\n <template #default=\"{ rect, menuWrapperProps }\">\n <slot\n name=\"selection-menu\"\n :item=\"item\"\n :selected=\"selectedId === item.id\"\n :page-index=\"pageIndex\"\n :menu-wrapper-props=\"menuWrapperProps\"\n :rect=\"rect\"\n />\n </template>\n </CounterRotate>\n </template>\n\n <!-- Text redaction -->\n <template v-else>\n <div\n :style=\"{\n position: 'absolute',\n left: `${item.rect.origin.x * scale}px`,\n top: `${item.rect.origin.y * scale}px`,\n width: `${item.rect.size.width * scale}px`,\n height: `${item.rect.size.height * scale}px`,\n background: 'transparent',\n outline: selectedId === item.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n pointerEvents: 'auto',\n cursor: selectedId === item.id ? 'pointer' : 'default',\n }\"\n >\n <Highlight\n :rect=\"item.rect\"\n :rects=\"item.rects\"\n color=\"transparent\"\n border=\"1px solid red\"\n :scale=\"scale\"\n :on-click=\"(e: PointerEvent | TouchEvent) => select(e, item.id)\"\n />\n </div>\n <CounterRotate\n :rect=\"{\n origin: {\n x: item.rect.origin.x * scale,\n y: item.rect.origin.y * scale,\n },\n size: {\n width: item.rect.size.width * scale,\n height: item.rect.size.height * scale,\n },\n }\"\n :rotation=\"rotation\"\n >\n <template #default=\"{ rect, menuWrapperProps }\">\n <slot\n name=\"selection-menu\"\n :item=\"item\"\n :selected=\"selectedId === item.id\"\n :page-index=\"pageIndex\"\n :menu-wrapper-props=\"menuWrapperProps\"\n :rect=\"rect\"\n />\n </template>\n </CounterRotate>\n </template>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted } from 'vue';\nimport { CounterRotate } from '@embedpdf/utils/vue';\nimport type { Rotation } from '@embedpdf/models';\nimport type { RedactionItem } from '@embedpdf/plugin-redaction';\nimport { useRedactionCapability } from '../hooks/use-redaction';\nimport Highlight from './highlight.vue';\n\ninterface PendingRedactionsProps {\n pageIndex: number;\n scale: number;\n rotation?: Rotation;\n bboxStroke?: string;\n}\n\nconst props = withDefaults(defineProps<PendingRedactionsProps>(), {\n rotation: 0,\n bboxStroke: 'rgba(0,0,0,0.8)',\n});\n\nconst { provides: redaction } = useRedactionCapability();\nconst items = ref<RedactionItem[]>([]);\nconst selectedId = ref<string | null>(null);\n\nconst select = (e: PointerEvent | TouchEvent, id: string) => {\n e.stopPropagation();\n if (!redaction.value) return;\n redaction.value.selectPending(props.pageIndex, id);\n};\n\nlet unsubscribePending: (() => void) | undefined;\nlet unsubscribeSelection: (() => void) | undefined;\n\nonMounted(() => {\n if (!redaction.value) return;\n\n unsubscribePending = redaction.value.onPendingChange((map) => {\n items.value = map[props.pageIndex] ?? [];\n });\n\n unsubscribeSelection = redaction.value.onSelectedChange((sel) => {\n selectedId.value = sel && sel.page === props.pageIndex ? sel.id : null;\n });\n});\n\nonUnmounted(() => {\n unsubscribePending?.();\n unsubscribeSelection?.();\n});\n</script>\n","<template>\n <PendingRedactions\n :page-index=\"pageIndex\"\n :scale=\"scale\"\n :rotation=\"rotation\"\n :bbox-stroke=\"bboxStroke\"\n >\n <template #selection-menu=\"slotProps\">\n <slot name=\"selection-menu\" v-bind=\"slotProps\" />\n </template>\n </PendingRedactions>\n <MarqueeRedact :page-index=\"pageIndex\" :scale=\"scale\" />\n <SelectionRedact :page-index=\"pageIndex\" :scale=\"scale\" />\n</template>\n\n<script setup lang=\"ts\">\nimport type { Rotation } from '@embedpdf/models';\nimport PendingRedactions from './pending-redactions.vue';\nimport MarqueeRedact from './marquee-redact.vue';\nimport SelectionRedact from './selection-redact.vue';\n\ninterface RedactionLayerProps {\n pageIndex: number;\n scale: number;\n rotation?: Rotation;\n bboxStroke?: string;\n}\n\nwithDefaults(defineProps<RedactionLayerProps>(), {\n rotation: 0,\n bboxStroke: 'rgba(0,0,0,0.8)',\n});\n</script>\n"],"names":["useRedactionPlugin","usePlugin","RedactionPlugin","id","useRedactionCapability","useCapability","boundingRect","__props","rect","_openBlock","_createElementBlock","_Fragment","rects","i","_mergeProps","key","onPointerdown","_cache","_ctx","onClick","args","onTouchstart","style","border","left","_unref","origin","x","unref","scale","top","y","width","size","height","color","opacity","$attrs","props","plugin","redactionPlugin","ref","unregister","onMounted","value","registerMarqueeOnPage","pageIndex","callback","onPreview","newRect","onUnmounted","_normalizeStyle","stroke","fill","class","className","unsubscribe","onRedactionSelectionChange","formattedSelection","selection","find","s","segmentRects","createElementBlock","_hoisted_1","_createVNode","Highlight","provides","redaction","items","selectedId","select","e","stopPropagation","selectPending","unsubscribePending","unsubscribeSelection","onPendingChange","map","onSelectedChange","sel","page","length","Fragment","_renderList","item","kind","_createElementVNode","outline","bboxStroke","CounterRotate","rotation","default","_withCtx","menuWrapperProps","_renderSlot","$slots","selected","PendingRedactions","slotProps","renderSlot","MarqueeRedact","SelectionRedact","state","initialState","vue$1","watchEffect","onCleanup","onStateChange","newState","readonly"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/vue/hooks/use-redaction.ts","../../src/vue/components/highlight.vue","../../src/vue/components/marquee-redact.vue","../../src/vue/components/selection-redact.vue","../../src/vue/components/pending-redactions.vue","../../src/vue/components/redaction-layer.vue"],"sourcesContent":["import { ref, watch, computed, toValue, type MaybeRefOrGetter, ComputedRef, Ref } from 'vue';\nimport { useCapability, usePlugin } from '@embedpdf/core/vue';\nimport {\n RedactionPlugin,\n initialDocumentState,\n RedactionDocumentState,\n RedactionScope,\n} from '@embedpdf/plugin-redaction';\n\nexport const useRedactionPlugin = () => usePlugin<RedactionPlugin>(RedactionPlugin.id);\nexport const useRedactionCapability = () => useCapability<RedactionPlugin>(RedactionPlugin.id);\n\n/**\n * Hook for redaction state for a specific document\n * @param documentId Document ID (can be ref, computed, getter, or plain value)\n */\nexport const useRedaction = (\n documentId: MaybeRefOrGetter<string>,\n): {\n state: Readonly<Ref<RedactionDocumentState>>;\n provides: ComputedRef<RedactionScope | null>;\n} => {\n const { provides } = useRedactionCapability();\n const state = ref<RedactionDocumentState>(initialDocumentState);\n\n watch(\n [provides, () => toValue(documentId)],\n ([providesValue, docId], _, onCleanup) => {\n if (!providesValue) {\n state.value = initialDocumentState;\n return;\n }\n\n const scope = providesValue.forDocument(docId);\n\n // Set initial state\n try {\n state.value = scope.getState();\n } catch (e) {\n // Handle case where state might not be ready\n state.value = initialDocumentState;\n }\n\n // Subscribe to changes\n const unsubscribe = scope.onStateChange((newState) => {\n state.value = newState;\n });\n\n onCleanup(unsubscribe);\n },\n { immediate: true },\n );\n\n const scopedProvides = computed(() => {\n const docId = toValue(documentId);\n return provides.value?.forDocument(docId) ?? null;\n });\n\n return {\n state,\n provides: scopedProvides,\n };\n};\n","<template>\n <div\n v-for=\"(rect, i) in rects\"\n :key=\"i\"\n @pointerdown=\"onClick\"\n @touchstart=\"onClick\"\n :style=\"{\n position: 'absolute',\n border,\n left: `${(boundingRect ? rect.origin.x - boundingRect.origin.x : rect.origin.x) * scale}px`,\n top: `${(boundingRect ? rect.origin.y - boundingRect.origin.y : rect.origin.y) * scale}px`,\n width: `${rect.size.width * scale}px`,\n height: `${rect.size.height * scale}px`,\n background: color,\n opacity: opacity,\n pointerEvents: onClick ? 'auto' : 'none',\n cursor: onClick ? 'pointer' : 'default',\n zIndex: onClick ? 1 : undefined,\n }\"\n v-bind=\"$attrs\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport type { Rect } from '@embedpdf/models';\n\ninterface HighlightProps {\n color?: string;\n opacity?: number;\n border?: string;\n rects: Rect[];\n rect?: Rect;\n scale: number;\n onClick?: (e: PointerEvent | TouchEvent) => void;\n}\n\nconst props = withDefaults(defineProps<HighlightProps>(), {\n color: '#FFFF00',\n opacity: 1,\n border: '1px solid red',\n});\n\n// Rename rect to boundingRect for clarity in template\nconst boundingRect = props.rect;\n</script>\n","<template>\n <div\n v-if=\"rect\"\n :style=\"{\n position: 'absolute',\n pointerEvents: 'none',\n left: `${rect.origin.x * actualScale}px`,\n top: `${rect.origin.y * actualScale}px`,\n width: `${rect.size.width * actualScale}px`,\n height: `${rect.size.height * actualScale}px`,\n border: `1px solid ${stroke}`,\n background: fill,\n boxSizing: 'border-box',\n }\"\n :class=\"className\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch, computed } from 'vue';\nimport { useDocumentState } from '@embedpdf/core/vue';\nimport type { Rect } from '@embedpdf/models';\nimport { useRedactionPlugin } from '../hooks/use-redaction';\n\ninterface MarqueeRedactProps {\n /** The ID of the document */\n documentId: string;\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Scale of the page */\n scale?: number;\n /** Optional CSS class applied to the marquee rectangle */\n className?: string;\n /** Stroke / fill colours (defaults below) */\n stroke?: string;\n fill?: string;\n}\n\nconst props = withDefaults(defineProps<MarqueeRedactProps>(), {\n stroke: 'red',\n fill: 'transparent',\n});\n\nconst { plugin: redactionPlugin } = useRedactionPlugin();\nconst documentState = useDocumentState(() => props.documentId);\nconst rect = ref<Rect | null>(null);\n\nconst actualScale = computed(() => {\n if (props.scale !== undefined) return props.scale;\n return documentState.value?.scale ?? 1;\n});\n\nwatch(\n [redactionPlugin, () => props.documentId, () => props.pageIndex, actualScale],\n ([plugin, docId, pageIdx, scale], _, onCleanup) => {\n if (!plugin || !docId) return;\n\n const unregister = plugin.registerMarqueeOnPage({\n documentId: docId,\n pageIndex: pageIdx,\n scale,\n callback: {\n onPreview: (newRect) => {\n rect.value = newRect;\n },\n },\n });\n\n onCleanup(unregister);\n },\n { immediate: true },\n);\n</script>\n","<template>\n <div\n v-if=\"boundingRect\"\n :style=\"{\n mixBlendMode: 'normal',\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n }\"\n >\n <Highlight\n :color=\"'transparent'\"\n :opacity=\"1\"\n :rects=\"rects\"\n :scale=\"scale\"\n border=\"1px solid red\"\n />\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from 'vue';\nimport type { Rect } from '@embedpdf/models';\nimport { useRedactionPlugin } from '../hooks/use-redaction';\nimport Highlight from './highlight.vue';\n\ninterface SelectionRedactProps {\n documentId: string;\n pageIndex: number;\n scale: number;\n}\n\nconst props = defineProps<SelectionRedactProps>();\n\nconst { plugin: redactionPlugin } = useRedactionPlugin();\nconst rects = ref<Rect[]>([]);\nconst boundingRect = ref<Rect | null>(null);\n\nwatch(\n [redactionPlugin, () => props.documentId, () => props.pageIndex],\n ([plugin, docId, pageIdx], _, onCleanup) => {\n if (!plugin) {\n rects.value = [];\n boundingRect.value = null;\n return;\n }\n\n const unsubscribe = plugin.onRedactionSelectionChange(docId, (formattedSelection) => {\n const selection = formattedSelection.find((s) => s.pageIndex === pageIdx);\n rects.value = selection?.segmentRects ?? [];\n boundingRect.value = selection?.rect ?? null;\n });\n\n onCleanup(unsubscribe);\n },\n { immediate: true },\n);\n</script>\n","<template>\n <div v-if=\"items.length\" :style=\"{ position: 'absolute', inset: 0, pointerEvents: 'none' }\">\n <template v-for=\"item in items\" :key=\"item.id\">\n <!-- Area redaction -->\n <template v-if=\"item.kind === 'area'\">\n <div\n :style=\"{\n position: 'absolute',\n left: `${item.rect.origin.x * scale}px`,\n top: `${item.rect.origin.y * scale}px`,\n width: `${item.rect.size.width * scale}px`,\n height: `${item.rect.size.height * scale}px`,\n background: 'transparent',\n outline: selectedId === item.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n border: `1px solid red`,\n pointerEvents: 'auto',\n cursor: 'pointer',\n }\"\n @pointerdown=\"(e: PointerEvent) => select(e, item.id)\"\n @touchstart=\"(e: TouchEvent) => select(e, item.id)\"\n />\n\n <!-- Selection Menu: Supports BOTH render function and slot -->\n <CounterRotate\n v-if=\"shouldShowMenu(item.id)\"\n :rect=\"{\n origin: { x: item.rect.origin.x * scale, y: item.rect.origin.y * scale },\n size: { width: item.rect.size.width * scale, height: item.rect.size.height * scale },\n }\"\n :rotation=\"rotation\"\n >\n <template #default=\"{ rect, menuWrapperProps }\">\n <!-- Priority 1: Render function prop (schema-driven) -->\n <component\n v-if=\"selectionMenu\"\n :is=\"renderSelectionMenu(item, rect, menuWrapperProps)\"\n />\n\n <!-- Priority 2: Slot (manual customization) -->\n <slot\n v-else\n name=\"selection-menu\"\n :context=\"buildContext(item)\"\n :selected=\"selectedId === item.id\"\n :rect=\"rect\"\n :placement=\"menuPlacement\"\n :menuWrapperProps=\"menuWrapperProps\"\n />\n </template>\n </CounterRotate>\n </template>\n\n <!-- Text redaction -->\n <template v-else>\n <div\n :style=\"{\n position: 'absolute',\n left: `${item.rect.origin.x * scale}px`,\n top: `${item.rect.origin.y * scale}px`,\n width: `${item.rect.size.width * scale}px`,\n height: `${item.rect.size.height * scale}px`,\n background: 'transparent',\n outline: selectedId === item.id ? `1px solid ${bboxStroke}` : 'none',\n outlineOffset: '2px',\n pointerEvents: 'auto',\n cursor: selectedId === item.id ? 'pointer' : 'default',\n }\"\n >\n <Highlight\n :rect=\"item.rect\"\n :rects=\"item.rects\"\n color=\"transparent\"\n border=\"1px solid red\"\n :scale=\"scale\"\n :on-click=\"(e: PointerEvent | TouchEvent) => select(e, item.id)\"\n />\n </div>\n\n <!-- Selection Menu: Supports BOTH render function and slot -->\n <CounterRotate\n v-if=\"shouldShowMenu(item.id)\"\n :rect=\"{\n origin: {\n x: item.rect.origin.x * scale,\n y: item.rect.origin.y * scale,\n },\n size: {\n width: item.rect.size.width * scale,\n height: item.rect.size.height * scale,\n },\n }\"\n :rotation=\"rotation\"\n >\n <template #default=\"{ rect, menuWrapperProps }\">\n <!-- Priority 1: Render function prop (schema-driven) -->\n <component\n v-if=\"selectionMenu\"\n :is=\"renderSelectionMenu(item, rect, menuWrapperProps)\"\n />\n\n <!-- Priority 2: Slot (manual customization) -->\n <slot\n v-else\n name=\"selection-menu\"\n :context=\"buildContext(item)\"\n :selected=\"selectedId === item.id\"\n :rect=\"rect\"\n :placement=\"menuPlacement\"\n :menuWrapperProps=\"menuWrapperProps\"\n />\n </template>\n </CounterRotate>\n </template>\n </template>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch, useSlots, type VNode } from 'vue';\nimport type { Rect } from '@embedpdf/models';\nimport { Rotation } from '@embedpdf/models';\nimport { CounterRotate } from '@embedpdf/utils/vue';\nimport type { MenuWrapperProps, SelectionMenuPlacement } from '@embedpdf/utils/vue';\nimport type { RedactionItem } from '@embedpdf/plugin-redaction';\nimport { useRedactionCapability } from '../hooks/use-redaction';\nimport Highlight from './highlight.vue';\nimport type { RedactionSelectionContext, RedactionSelectionMenuRenderFn } from './types';\n\ninterface PendingRedactionsProps {\n documentId: string;\n pageIndex: number;\n scale: number;\n rotation: Rotation;\n bboxStroke?: string;\n /** Render function for selection menu (schema-driven approach) */\n selectionMenu?: RedactionSelectionMenuRenderFn;\n}\n\nconst props = withDefaults(defineProps<PendingRedactionsProps>(), {\n rotation: Rotation.Degree0,\n bboxStroke: 'rgba(0,0,0,0.8)',\n});\n\nconst slots = useSlots();\nconst { provides: redaction } = useRedactionCapability();\nconst items = ref<RedactionItem[]>([]);\nconst selectedId = ref<string | null>(null);\n\nwatch(\n [redaction, () => props.documentId, () => props.pageIndex],\n ([redactionValue, docId, pageIdx], _, onCleanup) => {\n if (!redactionValue) {\n items.value = [];\n selectedId.value = null;\n return;\n }\n\n const scoped = redactionValue.forDocument(docId);\n\n // Initialize with current state\n const currentState = scoped.getState();\n items.value = currentState.pending[pageIdx] ?? [];\n selectedId.value =\n currentState.selected && currentState.selected.page === pageIdx\n ? currentState.selected.id\n : null;\n\n // Subscribe to future changes\n const off1 = scoped.onPendingChange((map) => {\n items.value = map[pageIdx] ?? [];\n });\n\n const off2 = scoped.onSelectedChange((sel) => {\n selectedId.value = sel && sel.page === pageIdx ? sel.id : null;\n });\n\n onCleanup(() => {\n off1?.();\n off2?.();\n });\n },\n { immediate: true },\n);\n\nconst select = (e: PointerEvent | TouchEvent, id: string) => {\n e.stopPropagation();\n const redactionValue = redaction.value;\n if (!redactionValue) return;\n redactionValue.forDocument(props.documentId).selectPending(props.pageIndex, id);\n};\n\n// --- Selection Menu Logic ---\n\n// Check if we should show menu for this item\nconst shouldShowMenu = (itemId: string): boolean => {\n const isSelected = selectedId.value === itemId;\n return isSelected && (!!props.selectionMenu || !!slots['selection-menu']);\n};\n\n// Build context object for selection menu\nconst buildContext = (item: RedactionItem): RedactionSelectionContext => ({\n type: 'redaction',\n item,\n pageIndex: props.pageIndex,\n});\n\n// Placement hints (could be computed based on position)\nconst menuPlacement: SelectionMenuPlacement = {\n suggestTop: false,\n spaceAbove: 0,\n spaceBelow: 0,\n};\n\n// Render via function (for schema-driven approach)\nconst renderSelectionMenu = (\n item: RedactionItem,\n rect: Rect,\n menuWrapperProps: MenuWrapperProps,\n): VNode | null => {\n if (!props.selectionMenu) return null;\n\n return props.selectionMenu({\n rect,\n menuWrapperProps,\n selected: selectedId.value === item.id,\n placement: menuPlacement,\n context: buildContext(item),\n });\n};\n</script>\n","<template>\n <PendingRedactions\n :document-id=\"documentId\"\n :page-index=\"pageIndex\"\n :scale=\"actualScale\"\n :rotation=\"actualRotation\"\n :bbox-stroke=\"bboxStroke\"\n :selection-menu=\"selectionMenu\"\n >\n <template #selection-menu=\"slotProps\">\n <slot name=\"selection-menu\" v-bind=\"slotProps\" />\n </template>\n </PendingRedactions>\n <MarqueeRedact :document-id=\"documentId\" :page-index=\"pageIndex\" :scale=\"actualScale\" />\n <SelectionRedact :document-id=\"documentId\" :page-index=\"pageIndex\" :scale=\"actualScale\" />\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { useDocumentState } from '@embedpdf/core/vue';\nimport { Rotation } from '@embedpdf/models';\nimport PendingRedactions from './pending-redactions.vue';\nimport MarqueeRedact from './marquee-redact.vue';\nimport SelectionRedact from './selection-redact.vue';\nimport { RedactionSelectionMenuRenderFn } from './types';\n\ninterface RedactionLayerProps {\n /** The ID of the document this layer belongs to */\n documentId: string;\n /** Index of the page this layer lives on */\n pageIndex: number;\n /** Current render scale for this page */\n scale?: number;\n /** Page rotation (for counter-rotating menus, etc.) */\n rotation?: Rotation;\n /** Optional bbox stroke color */\n bboxStroke?: string;\n /** Optional menu renderer for a selected redaction */\n selectionMenu?: RedactionSelectionMenuRenderFn;\n}\n\nconst props = withDefaults(defineProps<RedactionLayerProps>(), {\n bboxStroke: 'rgba(0,0,0,0.8)',\n});\n\nconst documentState = useDocumentState(() => props.documentId);\n\nconst actualScale = computed(() => {\n if (props.scale !== undefined) return props.scale;\n return documentState.value?.scale ?? 1;\n});\n\nconst actualRotation = computed(() => {\n if (props.rotation !== undefined) return props.rotation;\n return documentState.value?.rotation ?? Rotation.Degree0;\n});\n</script>\n"],"names":["useRedactionPlugin","usePlugin","RedactionPlugin","id","useRedactionCapability","useCapability","boundingRect","__props","rect","_openBlock","_createElementBlock","_Fragment","_renderList","rects","i","_mergeProps","key","onPointerdown","_cache","onClick","args","onTouchstart","style","border","left","_unref","origin","x","scale","top","y","width","size","height","color","opacity","zIndex","$attrs","props","plugin","redactionPlugin","documentState","useDocumentState","documentId","ref","actualScale","computed","_a","value","watch","pageIndex","docId","pageIdx","_","onCleanup","registerMarqueeOnPage","callback","onPreview","newRect","immediate","_normalizeStyle","stroke","fill","class","className","onRedactionSelectionChange","formattedSelection","selection","find","s","segmentRects","_hoisted_1","_createVNode","Highlight","slots","useSlots","provides","redaction","items","selectedId","redactionValue","scoped","forDocument","currentState","getState","pending","selected","page","off1","onPendingChange","map","off2","onSelectedChange","sel","select","e","stopPropagation","selectPending","shouldShowMenu","itemId","selectionMenu","buildContext","item","type","menuPlacement","suggestTop","spaceAbove","spaceBelow","renderSelectionMenu","menuWrapperProps","placement","context","length","kind","_createElementVNode","outline","bboxStroke","_createBlock","CounterRotate","rotation","default","_withCtx","_resolveDynamicComponent","_renderSlot","_ctx","$slots","actualRotation","Rotation","Degree0","PendingRedactions","slotProps","MarqueeRedact","SelectionRedact","state","initialDocumentState","toValue","providesValue","scope","onStateChange","newState","scopedProvides"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
1
  export * from './hooks';
2
2
  export * from './components';
3
+ export * from './components/types';
3
4
  export * from '../lib/index.ts';