@embedpdf/plugin-search 1.4.1 → 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 (38) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +324 -199
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/actions.d.ts +58 -22
  6. package/dist/lib/index.d.ts +2 -2
  7. package/dist/lib/reducer.d.ts +2 -1
  8. package/dist/lib/search-plugin.d.ts +8 -8
  9. package/dist/lib/types.d.ts +76 -63
  10. package/dist/preact/adapter.d.ts +1 -1
  11. package/dist/preact/index.cjs +1 -1
  12. package/dist/preact/index.cjs.map +1 -1
  13. package/dist/preact/index.js +49 -18
  14. package/dist/preact/index.js.map +1 -1
  15. package/dist/react/adapter.d.ts +1 -1
  16. package/dist/react/index.cjs +1 -1
  17. package/dist/react/index.cjs.map +1 -1
  18. package/dist/react/index.js +49 -18
  19. package/dist/react/index.js.map +1 -1
  20. package/dist/shared/components/search-layer.d.ts +3 -2
  21. package/dist/shared/hooks/use-search.d.ts +4 -4
  22. package/dist/shared-preact/components/search-layer.d.ts +3 -2
  23. package/dist/shared-preact/hooks/use-search.d.ts +4 -4
  24. package/dist/shared-react/components/search-layer.d.ts +3 -2
  25. package/dist/shared-react/hooks/use-search.d.ts +4 -4
  26. package/dist/svelte/components/SearchLayer.svelte.d.ts +4 -3
  27. package/dist/svelte/hooks/use-search.svelte.d.ts +11 -5
  28. package/dist/svelte/index.cjs +1 -1
  29. package/dist/svelte/index.cjs.map +1 -1
  30. package/dist/svelte/index.js +69 -35
  31. package/dist/svelte/index.js.map +1 -1
  32. package/dist/vue/components/search-layer.vue.d.ts +4 -2
  33. package/dist/vue/hooks/use-search.d.ts +9 -64
  34. package/dist/vue/index.cjs +1 -1
  35. package/dist/vue/index.cjs.map +1 -1
  36. package/dist/vue/index.js +77 -32
  37. package/dist/vue/index.js.map +1 -1
  38. package/package.json +5 -7
@@ -1,25 +1,32 @@
1
- import { usePlugin, useCapability } from "@embedpdf/core/preact";
2
- import { SearchPlugin, initialState } from "@embedpdf/plugin-search";
1
+ import { usePlugin, useCapability, useDocumentState } from "@embedpdf/core/preact";
2
+ import { SearchPlugin, initialSearchDocumentState } from "@embedpdf/plugin-search";
3
3
  export * from "@embedpdf/plugin-search";
4
4
  import "preact";
5
- import { useState, useEffect } from "preact/hooks";
5
+ import { useState, useMemo, useEffect } from "preact/hooks";
6
6
  import { jsx } from "preact/jsx-runtime";
7
7
  const useSearchPlugin = () => usePlugin(SearchPlugin.id);
8
8
  const useSearchCapability = () => useCapability(SearchPlugin.id);
9
- const useSearch = () => {
9
+ const useSearch = (documentId) => {
10
10
  const { provides } = useSearchCapability();
11
- const [searchState, setSearchState] = useState(initialState);
11
+ const [searchState, setSearchState] = useState(initialSearchDocumentState);
12
+ const scope = useMemo(() => provides == null ? void 0 : provides.forDocument(documentId), [provides, documentId]);
12
13
  useEffect(() => {
13
- return provides == null ? void 0 : provides.onStateChange((state) => setSearchState(state));
14
- }, [provides]);
14
+ if (!scope) {
15
+ setSearchState(initialSearchDocumentState);
16
+ return;
17
+ }
18
+ setSearchState(scope.getState());
19
+ return scope.onStateChange((state) => setSearchState(state));
20
+ }, [scope]);
15
21
  return {
16
22
  state: searchState,
17
- provides
23
+ provides: scope ?? null
18
24
  };
19
25
  };
20
26
  function SearchLayer({
27
+ documentId,
21
28
  pageIndex,
22
- scale,
29
+ scale: scaleOverride,
23
30
  style,
24
31
  highlightColor = "#FFFF00",
25
32
  activeHighlightColor = "#FFBF00",
@@ -27,32 +34,56 @@ function SearchLayer({
27
34
  }) {
28
35
  const { provides: searchProvides } = useSearchCapability();
29
36
  const [searchResultState, setSearchResultState] = useState(null);
37
+ const documentState = useDocumentState(documentId);
38
+ const scope = useMemo(
39
+ () => searchProvides == null ? void 0 : searchProvides.forDocument(documentId),
40
+ [searchProvides, documentId]
41
+ );
42
+ const actualScale = useMemo(() => {
43
+ if (scaleOverride !== void 0) return scaleOverride;
44
+ return (documentState == null ? void 0 : documentState.scale) ?? 1;
45
+ }, [scaleOverride, documentState == null ? void 0 : documentState.scale]);
30
46
  useEffect(() => {
31
- return searchProvides == null ? void 0 : searchProvides.onSearchResultStateChange((state) => {
47
+ if (!scope) {
48
+ setSearchResultState(null);
49
+ return;
50
+ }
51
+ const currentState = scope.getState();
52
+ setSearchResultState({
53
+ results: currentState.results,
54
+ activeResultIndex: currentState.activeResultIndex,
55
+ showAllResults: currentState.showAllResults,
56
+ active: currentState.active
57
+ });
58
+ return scope.onSearchResultStateChange((state) => {
32
59
  setSearchResultState(state);
33
60
  });
34
- }, [searchProvides]);
35
- if (!searchResultState) {
61
+ }, [scope]);
62
+ if (!searchResultState || !searchResultState.active) {
36
63
  return null;
37
64
  }
38
65
  const pageResults = searchResultState.results.map((result, originalIndex) => ({ result, originalIndex })).filter(({ result }) => result.pageIndex === pageIndex);
66
+ const resultsToShow = pageResults.filter(
67
+ ({ originalIndex }) => searchResultState.showAllResults || originalIndex === searchResultState.activeResultIndex
68
+ );
39
69
  return /* @__PURE__ */ jsx(
40
70
  "div",
41
71
  {
42
72
  style: {
43
- ...style
73
+ ...style,
74
+ pointerEvents: "none"
44
75
  },
45
76
  ...props,
46
- children: pageResults.map(
77
+ children: resultsToShow.map(
47
78
  ({ result, originalIndex }) => result.rects.map((rect, rectIndex) => /* @__PURE__ */ jsx(
48
79
  "div",
49
80
  {
50
81
  style: {
51
82
  position: "absolute",
52
- top: rect.origin.y * scale,
53
- left: rect.origin.x * scale,
54
- width: rect.size.width * scale,
55
- height: rect.size.height * scale,
83
+ top: rect.origin.y * actualScale,
84
+ left: rect.origin.x * actualScale,
85
+ width: rect.size.width * actualScale,
86
+ height: rect.size.height * actualScale,
56
87
  backgroundColor: originalIndex === searchResultState.activeResultIndex ? activeHighlightColor : highlightColor,
57
88
  mixBlendMode: "multiply",
58
89
  transform: "scale(1.02)",
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-search.ts","../../src/shared/components/search-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { initialState, SearchPlugin, SearchState } from '@embedpdf/plugin-search';\nimport { useEffect, useState } from '@framework';\n\nexport const useSearchPlugin = () => usePlugin<SearchPlugin>(SearchPlugin.id);\nexport const useSearchCapability = () => useCapability<SearchPlugin>(SearchPlugin.id);\n\nexport const useSearch = () => {\n const { provides } = useSearchCapability();\n const [searchState, setSearchState] = useState<SearchState>(initialState);\n\n useEffect(() => {\n return provides?.onStateChange((state) => setSearchState(state));\n }, [provides]);\n\n return {\n state: searchState,\n provides,\n };\n};\n","import { useEffect, useState, HTMLAttributes, CSSProperties } from '@framework';\nimport { SearchResultState } from '@embedpdf/plugin-search';\n\nimport { useSearchCapability } from '../hooks';\n\ntype SearchLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n style?: CSSProperties;\n};\n\nexport function SearchLayer({\n pageIndex,\n scale,\n style,\n highlightColor = '#FFFF00',\n activeHighlightColor = '#FFBF00',\n ...props\n}: SearchLayoutProps) {\n const { provides: searchProvides } = useSearchCapability();\n const [searchResultState, setSearchResultState] = useState<SearchResultState | null>(null);\n\n useEffect(() => {\n return searchProvides?.onSearchResultStateChange((state) => {\n setSearchResultState(state);\n });\n }, [searchProvides]);\n\n if (!searchResultState) {\n return null;\n }\n\n // Filter results for current page while preserving original indices\n const pageResults = searchResultState.results\n .map((result, originalIndex) => ({ result, originalIndex }))\n .filter(({ result }) => result.pageIndex === pageIndex);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {pageResults.map(({ result, originalIndex }) =>\n result.rects.map((rect, rectIndex) => (\n <div\n key={`${originalIndex}-${rectIndex}`}\n style={{\n position: 'absolute',\n top: rect.origin.y * scale,\n left: rect.origin.x * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n backgroundColor:\n originalIndex === searchResultState.activeResultIndex\n ? activeHighlightColor\n : highlightColor,\n mixBlendMode: 'multiply',\n transform: 'scale(1.02)',\n transformOrigin: 'center',\n transition: 'opacity .3s ease-in-out',\n opacity: 1,\n }}\n ></div>\n )),\n )}\n </div>\n );\n}\n"],"names":[],"mappings":";;;;;;AAIO,MAAM,kBAAkB,MAAM,UAAwB,aAAa,EAAE;AACrE,MAAM,sBAAsB,MAAM,cAA4B,aAAa,EAAE;AAE7E,MAAM,YAAY,MAAM;AACvB,QAAA,EAAE,SAAS,IAAI,oBAAoB;AACzC,QAAM,CAAC,aAAa,cAAc,IAAI,SAAsB,YAAY;AAExE,YAAU,MAAM;AACd,WAAO,qCAAU,cAAc,CAAC,UAAU,eAAe,KAAK;AAAA,EAAC,GAC9D,CAAC,QAAQ,CAAC;AAEN,SAAA;AAAA,IACL,OAAO;AAAA,IACP;AAAA,EACF;AACF;ACNO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,uBAAuB;AAAA,EACvB,GAAG;AACL,GAAsB;AACpB,QAAM,EAAE,UAAU,eAAe,IAAI,oBAAoB;AACzD,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,SAAmC,IAAI;AAEzF,YAAU,MAAM;AACP,WAAA,iDAAgB,0BAA0B,CAAC,UAAU;AAC1D,2BAAqB,KAAK;AAAA,IAAA;AAAA,EAC3B,GACA,CAAC,cAAc,CAAC;AAEnB,MAAI,CAAC,mBAAmB;AACf,WAAA;AAAA,EAAA;AAIT,QAAM,cAAc,kBAAkB,QACnC,IAAI,CAAC,QAAQ,mBAAmB,EAAE,QAAQ,gBAAgB,EAC1D,OAAO,CAAC,EAAE,aAAa,OAAO,cAAc,SAAS;AAGtD,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA,MAEH,UAAY,YAAA;AAAA,QAAI,CAAC,EAAE,QAAQ,cAAc,MACxC,OAAO,MAAM,IAAI,CAAC,MAAM,cACtB;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,KAAK,KAAK,OAAO,IAAI;AAAA,cACrB,MAAM,KAAK,OAAO,IAAI;AAAA,cACtB,OAAO,KAAK,KAAK,QAAQ;AAAA,cACzB,QAAQ,KAAK,KAAK,SAAS;AAAA,cAC3B,iBACE,kBAAkB,kBAAkB,oBAChC,uBACA;AAAA,cACN,cAAc;AAAA,cACd,WAAW;AAAA,cACX,iBAAiB;AAAA,cACjB,YAAY;AAAA,cACZ,SAAS;AAAA,YAAA;AAAA,UACX;AAAA,UAhBK,GAAG,aAAa,IAAI,SAAS;AAAA,QAkBrC,CAAA;AAAA,MAAA;AAAA,IACH;AAAA,EACF;AAEJ;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-search.ts","../../src/shared/components/search-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n SearchPlugin,\n SearchDocumentState,\n SearchScope,\n initialSearchDocumentState,\n} from '@embedpdf/plugin-search';\nimport { useEffect, useMemo, useState } from '@framework';\n\nexport const useSearchPlugin = () => usePlugin<SearchPlugin>(SearchPlugin.id);\nexport const useSearchCapability = () => useCapability<SearchPlugin>(SearchPlugin.id);\n\nexport const useSearch = (\n documentId: string,\n): {\n state: SearchDocumentState;\n provides: SearchScope | null;\n} => {\n const { provides } = useSearchCapability();\n const [searchState, setSearchState] = useState<SearchDocumentState>(initialSearchDocumentState);\n\n const scope = useMemo(() => provides?.forDocument(documentId), [provides, documentId]);\n\n useEffect(() => {\n if (!scope) {\n setSearchState(initialSearchDocumentState);\n return;\n }\n // Set initial state\n setSearchState(scope.getState());\n // Subscribe to changes\n return scope.onStateChange((state) => setSearchState(state));\n }, [scope]);\n\n return {\n state: searchState,\n provides: scope ?? null,\n };\n};\n","import { useEffect, useMemo, useState, HTMLAttributes, CSSProperties } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { SearchResultState } from '@embedpdf/plugin-search';\n\nimport { useSearchCapability } from '../hooks';\n\ntype SearchLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n documentId: string;\n pageIndex: number;\n scale?: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n style?: CSSProperties;\n};\n\nexport function SearchLayer({\n documentId,\n pageIndex,\n scale: scaleOverride,\n style,\n highlightColor = '#FFFF00',\n activeHighlightColor = '#FFBF00',\n ...props\n}: SearchLayoutProps) {\n const { provides: searchProvides } = useSearchCapability();\n const [searchResultState, setSearchResultState] = useState<SearchResultState | null>(null);\n const documentState = useDocumentState(documentId);\n\n const scope = useMemo(\n () => searchProvides?.forDocument(documentId),\n [searchProvides, documentId],\n );\n\n const actualScale = useMemo(() => {\n if (scaleOverride !== undefined) return scaleOverride;\n return documentState?.scale ?? 1;\n }, [scaleOverride, documentState?.scale]);\n\n useEffect(() => {\n if (!scope) {\n setSearchResultState(null);\n return;\n }\n // Set initial state\n const currentState = scope.getState();\n setSearchResultState({\n results: currentState.results,\n activeResultIndex: currentState.activeResultIndex,\n showAllResults: currentState.showAllResults,\n active: currentState.active,\n });\n // Subscribe to changes\n return scope.onSearchResultStateChange((state) => {\n setSearchResultState(state);\n });\n }, [scope]);\n\n if (!searchResultState || !searchResultState.active) {\n return null;\n }\n\n // Filter results for current page while preserving original indices\n const pageResults = searchResultState.results\n .map((result, originalIndex) => ({ result, originalIndex }))\n .filter(({ result }) => result.pageIndex === pageIndex);\n\n // Decide which results to show\n const resultsToShow = pageResults.filter(\n ({ originalIndex }) =>\n searchResultState.showAllResults || originalIndex === searchResultState.activeResultIndex,\n );\n\n return (\n <div\n style={{\n ...style,\n pointerEvents: 'none',\n }}\n {...props}\n >\n {resultsToShow.map(({ result, originalIndex }) =>\n result.rects.map((rect, rectIndex) => (\n <div\n key={`${originalIndex}-${rectIndex}`}\n style={{\n position: 'absolute',\n top: rect.origin.y * actualScale,\n left: rect.origin.x * actualScale,\n width: rect.size.width * actualScale,\n height: rect.size.height * actualScale,\n backgroundColor:\n originalIndex === searchResultState.activeResultIndex\n ? activeHighlightColor\n : highlightColor,\n mixBlendMode: 'multiply',\n transform: 'scale(1.02)',\n transformOrigin: 'center',\n transition: 'opacity .3s ease-in-out',\n opacity: 1,\n }}\n ></div>\n )),\n )}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export { Fragment, useEffect, useRef, useState } from 'react';
1
+ export { Fragment, useEffect, useRef, useState, useMemo } from 'react';
2
2
  export type { ReactNode, HTMLAttributes, CSSProperties } from 'react';
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/react"),t=require("@embedpdf/plugin-search"),r=require("react"),i=require("react/jsx-runtime"),s=()=>e.useCapability(t.SearchPlugin.id);exports.SearchLayer=function({pageIndex:e,scale:t,style:a,highlightColor:o="#FFFF00",activeHighlightColor:n="#FFBF00",...l}){const{provides:u}=s(),[c,p]=r.useState(null);if(r.useEffect((()=>null==u?void 0:u.onSearchResultStateChange((e=>{p(e)}))),[u]),!c)return null;const d=c.results.map(((e,t)=>({result:e,originalIndex:t}))).filter((({result:t})=>t.pageIndex===e));return i.jsx("div",{style:{...a},...l,children:d.map((({result:e,originalIndex:r})=>e.rects.map(((e,s)=>i.jsx("div",{style:{position:"absolute",top:e.origin.y*t,left:e.origin.x*t,width:e.size.width*t,height:e.size.height*t,backgroundColor:r===c.activeResultIndex?n:o,mixBlendMode:"multiply",transform:"scale(1.02)",transformOrigin:"center",transition:"opacity .3s ease-in-out",opacity:1}},`${r}-${s}`)))))})},exports.useSearch=()=>{const{provides:e}=s(),[i,a]=r.useState(t.initialState);return r.useEffect((()=>null==e?void 0:e.onStateChange((e=>a(e)))),[e]),{state:i,provides:e}},exports.useSearchCapability=s,exports.useSearchPlugin=()=>e.usePlugin(t.SearchPlugin.id),Object.keys(t).forEach((e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})}));
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/react"),t=require("@embedpdf/plugin-search"),r=require("react"),i=require("react/jsx-runtime"),s=()=>e.useCapability(t.SearchPlugin.id);exports.SearchLayer=function({documentId:t,pageIndex:l,scale:n,style:o,highlightColor:a="#FFFF00",activeHighlightColor:u="#FFBF00",...c}){const{provides:d}=s(),[p,h]=r.useState(null),g=e.useDocumentState(t),f=r.useMemo(()=>null==d?void 0:d.forDocument(t),[d,t]),m=r.useMemo(()=>void 0!==n?n:(null==g?void 0:g.scale)??1,[n,null==g?void 0:g.scale]);if(r.useEffect(()=>{if(!f)return void h(null);const e=f.getState();return h({results:e.results,activeResultIndex:e.activeResultIndex,showAllResults:e.showAllResults,active:e.active}),f.onSearchResultStateChange(e=>{h(e)})},[f]),!p||!p.active)return null;const v=p.results.map((e,t)=>({result:e,originalIndex:t})).filter(({result:e})=>e.pageIndex===l).filter(({originalIndex:e})=>p.showAllResults||e===p.activeResultIndex);return i.jsx("div",{style:{...o,pointerEvents:"none"},...c,children:v.map(({result:e,originalIndex:t})=>e.rects.map((e,r)=>i.jsx("div",{style:{position:"absolute",top:e.origin.y*m,left:e.origin.x*m,width:e.size.width*m,height:e.size.height*m,backgroundColor:t===p.activeResultIndex?u:a,mixBlendMode:"multiply",transform:"scale(1.02)",transformOrigin:"center",transition:"opacity .3s ease-in-out",opacity:1}},`${t}-${r}`)))})},exports.useSearch=e=>{const{provides:i}=s(),[l,n]=r.useState(t.initialSearchDocumentState),o=r.useMemo(()=>null==i?void 0:i.forDocument(e),[i,e]);return r.useEffect(()=>{if(o)return n(o.getState()),o.onStateChange(e=>n(e));n(t.initialSearchDocumentState)},[o]),{state:l,provides:o??null}},exports.useSearchCapability=s,exports.useSearchPlugin=()=>e.usePlugin(t.SearchPlugin.id),Object.keys(t).forEach(e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-search.ts","../../src/shared/components/search-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { initialState, SearchPlugin, SearchState } from '@embedpdf/plugin-search';\nimport { useEffect, useState } from '@framework';\n\nexport const useSearchPlugin = () => usePlugin<SearchPlugin>(SearchPlugin.id);\nexport const useSearchCapability = () => useCapability<SearchPlugin>(SearchPlugin.id);\n\nexport const useSearch = () => {\n const { provides } = useSearchCapability();\n const [searchState, setSearchState] = useState<SearchState>(initialState);\n\n useEffect(() => {\n return provides?.onStateChange((state) => setSearchState(state));\n }, [provides]);\n\n return {\n state: searchState,\n provides,\n };\n};\n","import { useEffect, useState, HTMLAttributes, CSSProperties } from '@framework';\nimport { SearchResultState } from '@embedpdf/plugin-search';\n\nimport { useSearchCapability } from '../hooks';\n\ntype SearchLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n style?: CSSProperties;\n};\n\nexport function SearchLayer({\n pageIndex,\n scale,\n style,\n highlightColor = '#FFFF00',\n activeHighlightColor = '#FFBF00',\n ...props\n}: SearchLayoutProps) {\n const { provides: searchProvides } = useSearchCapability();\n const [searchResultState, setSearchResultState] = useState<SearchResultState | null>(null);\n\n useEffect(() => {\n return searchProvides?.onSearchResultStateChange((state) => {\n setSearchResultState(state);\n });\n }, [searchProvides]);\n\n if (!searchResultState) {\n return null;\n }\n\n // Filter results for current page while preserving original indices\n const pageResults = searchResultState.results\n .map((result, originalIndex) => ({ result, originalIndex }))\n .filter(({ result }) => result.pageIndex === pageIndex);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {pageResults.map(({ result, originalIndex }) =>\n result.rects.map((rect, rectIndex) => (\n <div\n key={`${originalIndex}-${rectIndex}`}\n style={{\n position: 'absolute',\n top: rect.origin.y * scale,\n left: rect.origin.x * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n backgroundColor:\n originalIndex === searchResultState.activeResultIndex\n ? activeHighlightColor\n : highlightColor,\n mixBlendMode: 'multiply',\n transform: 'scale(1.02)',\n transformOrigin: 'center',\n transition: 'opacity .3s ease-in-out',\n opacity: 1,\n }}\n ></div>\n )),\n )}\n </div>\n );\n}\n"],"names":["useSearchCapability","useCapability","SearchPlugin","id","pageIndex","scale","style","highlightColor","activeHighlightColor","props","provides","searchProvides","searchResultState","setSearchResultState","useState","useEffect","onSearchResultStateChange","state","pageResults","results","map","result","originalIndex","filter","jsxRuntime","jsx","children","rects","rect","rectIndex","position","top","origin","y","left","x","width","size","height","backgroundColor","activeResultIndex","mixBlendMode","transform","transformOrigin","transition","opacity","searchState","setSearchState","initialState","onStateChange","usePlugin"],"mappings":"+MAKaA,EAAsB,IAAMC,gBAA4BC,EAAAA,aAAaC,wBCQ3E,UAAqBC,UAC1BA,EAAAC,MACAA,EAAAC,MACAA,EAAAC,eACAA,EAAiB,UAAAC,qBACjBA,EAAuB,aACpBC,IAEH,MAAQC,SAAUC,GAAmBX,KAC9BY,EAAmBC,GAAwBC,EAAAA,SAAmC,MAQrF,GANAC,EAAAA,WAAU,IACD,MAAAJ,OAAA,EAAAA,EAAgBK,2BAA2BC,IAChDJ,EAAqBI,EAAK,KAE3B,CAACN,KAECC,EACI,OAAA,KAIT,MAAMM,EAAcN,EAAkBO,QACnCC,KAAI,CAACC,EAAQC,MAAqBD,SAAQC,oBAC1CC,QAAO,EAAGF,YAAaA,EAAOjB,YAAcA,IAG7C,OAAAoB,EAAAC,IAAC,MAAA,CACCnB,MAAO,IACFA,MAEDG,EAEHiB,SAAYR,EAAAE,KAAI,EAAGC,SAAQC,mBAC1BD,EAAOM,MAAMP,KAAI,CAACQ,EAAMC,IACtBL,EAAAC,IAAC,MAAA,CAECnB,MAAO,CACLwB,SAAU,WACVC,IAAKH,EAAKI,OAAOC,EAAI5B,EACrB6B,KAAMN,EAAKI,OAAOG,EAAI9B,EACtB+B,MAAOR,EAAKS,KAAKD,MAAQ/B,EACzBiC,OAAQV,EAAKS,KAAKC,OAASjC,EAC3BkC,gBACEjB,IAAkBV,EAAkB4B,kBAChChC,EACAD,EACNkC,aAAc,WACdC,UAAW,cACXC,gBAAiB,SACjBC,WAAY,0BACZC,QAAS,IAfN,GAAGvB,KAAiBO,UAsBrC,oBDhEyB,KACjB,MAAAnB,SAAEA,GAAaV,KACd8C,EAAaC,GAAkBjC,EAAAA,SAAsBkC,EAAAA,cAMrD,OAJPjC,EAAAA,WAAU,IACS,MAAVL,OAAU,EAAAA,EAAAuC,eAAehC,GAAU8B,EAAe9B,MACxD,CAACP,IAEG,CACLO,MAAO6B,EACPpC,WACF,wDAd6B,IAAMwC,YAAwBhD,EAAAA,aAAaC"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-search.ts","../../src/shared/components/search-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n SearchPlugin,\n SearchDocumentState,\n SearchScope,\n initialSearchDocumentState,\n} from '@embedpdf/plugin-search';\nimport { useEffect, useMemo, useState } from '@framework';\n\nexport const useSearchPlugin = () => usePlugin<SearchPlugin>(SearchPlugin.id);\nexport const useSearchCapability = () => useCapability<SearchPlugin>(SearchPlugin.id);\n\nexport const useSearch = (\n documentId: string,\n): {\n state: SearchDocumentState;\n provides: SearchScope | null;\n} => {\n const { provides } = useSearchCapability();\n const [searchState, setSearchState] = useState<SearchDocumentState>(initialSearchDocumentState);\n\n const scope = useMemo(() => provides?.forDocument(documentId), [provides, documentId]);\n\n useEffect(() => {\n if (!scope) {\n setSearchState(initialSearchDocumentState);\n return;\n }\n // Set initial state\n setSearchState(scope.getState());\n // Subscribe to changes\n return scope.onStateChange((state) => setSearchState(state));\n }, [scope]);\n\n return {\n state: searchState,\n provides: scope ?? null,\n };\n};\n","import { useEffect, useMemo, useState, HTMLAttributes, CSSProperties } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { SearchResultState } from '@embedpdf/plugin-search';\n\nimport { useSearchCapability } from '../hooks';\n\ntype SearchLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n documentId: string;\n pageIndex: number;\n scale?: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n style?: CSSProperties;\n};\n\nexport function SearchLayer({\n documentId,\n pageIndex,\n scale: scaleOverride,\n style,\n highlightColor = '#FFFF00',\n activeHighlightColor = '#FFBF00',\n ...props\n}: SearchLayoutProps) {\n const { provides: searchProvides } = useSearchCapability();\n const [searchResultState, setSearchResultState] = useState<SearchResultState | null>(null);\n const documentState = useDocumentState(documentId);\n\n const scope = useMemo(\n () => searchProvides?.forDocument(documentId),\n [searchProvides, documentId],\n );\n\n const actualScale = useMemo(() => {\n if (scaleOverride !== undefined) return scaleOverride;\n return documentState?.scale ?? 1;\n }, [scaleOverride, documentState?.scale]);\n\n useEffect(() => {\n if (!scope) {\n setSearchResultState(null);\n return;\n }\n // Set initial state\n const currentState = scope.getState();\n setSearchResultState({\n results: currentState.results,\n activeResultIndex: currentState.activeResultIndex,\n showAllResults: currentState.showAllResults,\n active: currentState.active,\n });\n // Subscribe to changes\n return scope.onSearchResultStateChange((state) => {\n setSearchResultState(state);\n });\n }, [scope]);\n\n if (!searchResultState || !searchResultState.active) {\n return null;\n }\n\n // Filter results for current page while preserving original indices\n const pageResults = searchResultState.results\n .map((result, originalIndex) => ({ result, originalIndex }))\n .filter(({ result }) => result.pageIndex === pageIndex);\n\n // Decide which results to show\n const resultsToShow = pageResults.filter(\n ({ originalIndex }) =>\n searchResultState.showAllResults || originalIndex === searchResultState.activeResultIndex,\n );\n\n return (\n <div\n style={{\n ...style,\n pointerEvents: 'none',\n }}\n {...props}\n >\n {resultsToShow.map(({ result, originalIndex }) =>\n result.rects.map((rect, rectIndex) => (\n <div\n key={`${originalIndex}-${rectIndex}`}\n style={{\n position: 'absolute',\n top: rect.origin.y * actualScale,\n left: rect.origin.x * actualScale,\n width: rect.size.width * actualScale,\n height: rect.size.height * actualScale,\n backgroundColor:\n originalIndex === searchResultState.activeResultIndex\n ? activeHighlightColor\n : highlightColor,\n mixBlendMode: 'multiply',\n transform: 'scale(1.02)',\n transformOrigin: 'center',\n transition: 'opacity .3s ease-in-out',\n opacity: 1,\n }}\n ></div>\n )),\n )}\n </div>\n );\n}\n"],"names":["useSearchCapability","useCapability","SearchPlugin","id","documentId","pageIndex","scale","scaleOverride","style","highlightColor","activeHighlightColor","props","provides","searchProvides","searchResultState","setSearchResultState","useState","documentState","useDocumentState","scope","useMemo","forDocument","actualScale","useEffect","currentState","getState","results","activeResultIndex","showAllResults","active","onSearchResultStateChange","state","resultsToShow","map","result","originalIndex","filter","jsx","pointerEvents","children","rects","rect","rectIndex","position","top","origin","y","left","x","width","size","height","backgroundColor","mixBlendMode","transform","transformOrigin","transition","opacity","searchState","setSearchState","initialSearchDocumentState","onStateChange","usePlugin"],"mappings":"+MAUaA,EAAsB,IAAMC,gBAA4BC,EAAAA,aAAaC,wBCK3E,UAAqBC,WAC1BA,EAAAC,UACAA,EACAC,MAAOC,EAAAC,MACPA,EAAAC,eACAA,EAAiB,UAAAC,qBACjBA,EAAuB,aACpBC,IAEH,MAAQC,SAAUC,GAAmBb,KAC9Bc,EAAmBC,GAAwBC,EAAAA,SAAmC,MAC/EC,EAAgBC,EAAAA,iBAAiBd,GAEjCe,EAAQC,EAAAA,QACZ,UAAMP,WAAgBQ,YAAYjB,GAClC,CAACS,EAAgBT,IAGbkB,EAAcF,EAAAA,QAAQ,SACJ,IAAlBb,EAAoCA,SACjCU,WAAeX,QAAS,EAC9B,CAACC,EAAe,MAAAU,OAAA,EAAAA,EAAeX,QAqBlC,GAnBAiB,EAAAA,UAAU,KACR,IAAKJ,EAEH,YADAJ,EAAqB,MAIvB,MAAMS,EAAeL,EAAMM,WAQ3B,OAPAV,EAAqB,CACnBW,QAASF,EAAaE,QACtBC,kBAAmBH,EAAaG,kBAChCC,eAAgBJ,EAAaI,eAC7BC,OAAQL,EAAaK,SAGhBV,EAAMW,0BAA2BC,IACtChB,EAAqBgB,MAEtB,CAACZ,KAECL,IAAsBA,EAAkBe,OAC3C,OAAO,KAIT,MAKMG,EALclB,EAAkBY,QACnCO,IAAI,CAACC,EAAQC,MAAqBD,SAAQC,mBAC1CC,OAAO,EAAGF,YAAaA,EAAO7B,YAAcA,GAGb+B,OAChC,EAAGD,mBACDrB,EAAkBc,gBAAkBO,IAAkBrB,EAAkBa,mBAG5E,OACEU,EAAAA,IAAC,MAAA,CACC7B,MAAO,IACFA,EACH8B,cAAe,WAEb3B,EAEH4B,SAAAP,EAAcC,IAAI,EAAGC,SAAQC,mBAC5BD,EAAOM,MAAMP,IAAI,CAACQ,EAAMC,IACtBL,EAAAA,IAAC,MAAA,CAEC7B,MAAO,CACLmC,SAAU,WACVC,IAAKH,EAAKI,OAAOC,EAAIxB,EACrByB,KAAMN,EAAKI,OAAOG,EAAI1B,EACtB2B,MAAOR,EAAKS,KAAKD,MAAQ3B,EACzB6B,OAAQV,EAAKS,KAAKC,OAAS7B,EAC3B8B,gBACEjB,IAAkBrB,EAAkBa,kBAChCjB,EACAD,EACN4C,aAAc,WACdC,UAAW,cACXC,gBAAiB,SACjBC,WAAY,0BACZC,QAAS,IAfN,GAAGtB,KAAiBO,QAsBrC,oBD5FEtC,IAKA,MAAMQ,SAAEA,GAAaZ,KACd0D,EAAaC,GAAkB3C,EAAAA,SAA8B4C,EAAAA,4BAE9DzC,EAAQC,UAAQ,IAAM,MAAAR,OAAA,EAAAA,EAAUS,YAAYjB,GAAa,CAACQ,EAAUR,IAa1E,OAXAmB,EAAAA,UAAU,KACR,GAAKJ,EAOL,OAFAwC,EAAexC,EAAMM,YAEdN,EAAM0C,cAAe9B,GAAU4B,EAAe5B,IANnD4B,EAAeC,EAAAA,6BAOhB,CAACzC,IAEG,CACLY,MAAO2B,EACP9C,SAAUO,GAAS,6DA3BQ,IAAM2C,YAAwB5D,EAAAA,aAAaC"}
@@ -1,24 +1,31 @@
1
- import { usePlugin, useCapability } from "@embedpdf/core/react";
2
- import { SearchPlugin, initialState } from "@embedpdf/plugin-search";
1
+ import { usePlugin, useCapability, useDocumentState } from "@embedpdf/core/react";
2
+ import { SearchPlugin, initialSearchDocumentState } from "@embedpdf/plugin-search";
3
3
  export * from "@embedpdf/plugin-search";
4
- import { useState, useEffect } from "react";
4
+ import { useState, useMemo, useEffect } from "react";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  const useSearchPlugin = () => usePlugin(SearchPlugin.id);
7
7
  const useSearchCapability = () => useCapability(SearchPlugin.id);
8
- const useSearch = () => {
8
+ const useSearch = (documentId) => {
9
9
  const { provides } = useSearchCapability();
10
- const [searchState, setSearchState] = useState(initialState);
10
+ const [searchState, setSearchState] = useState(initialSearchDocumentState);
11
+ const scope = useMemo(() => provides == null ? void 0 : provides.forDocument(documentId), [provides, documentId]);
11
12
  useEffect(() => {
12
- return provides == null ? void 0 : provides.onStateChange((state) => setSearchState(state));
13
- }, [provides]);
13
+ if (!scope) {
14
+ setSearchState(initialSearchDocumentState);
15
+ return;
16
+ }
17
+ setSearchState(scope.getState());
18
+ return scope.onStateChange((state) => setSearchState(state));
19
+ }, [scope]);
14
20
  return {
15
21
  state: searchState,
16
- provides
22
+ provides: scope ?? null
17
23
  };
18
24
  };
19
25
  function SearchLayer({
26
+ documentId,
20
27
  pageIndex,
21
- scale,
28
+ scale: scaleOverride,
22
29
  style,
23
30
  highlightColor = "#FFFF00",
24
31
  activeHighlightColor = "#FFBF00",
@@ -26,32 +33,56 @@ function SearchLayer({
26
33
  }) {
27
34
  const { provides: searchProvides } = useSearchCapability();
28
35
  const [searchResultState, setSearchResultState] = useState(null);
36
+ const documentState = useDocumentState(documentId);
37
+ const scope = useMemo(
38
+ () => searchProvides == null ? void 0 : searchProvides.forDocument(documentId),
39
+ [searchProvides, documentId]
40
+ );
41
+ const actualScale = useMemo(() => {
42
+ if (scaleOverride !== void 0) return scaleOverride;
43
+ return (documentState == null ? void 0 : documentState.scale) ?? 1;
44
+ }, [scaleOverride, documentState == null ? void 0 : documentState.scale]);
29
45
  useEffect(() => {
30
- return searchProvides == null ? void 0 : searchProvides.onSearchResultStateChange((state) => {
46
+ if (!scope) {
47
+ setSearchResultState(null);
48
+ return;
49
+ }
50
+ const currentState = scope.getState();
51
+ setSearchResultState({
52
+ results: currentState.results,
53
+ activeResultIndex: currentState.activeResultIndex,
54
+ showAllResults: currentState.showAllResults,
55
+ active: currentState.active
56
+ });
57
+ return scope.onSearchResultStateChange((state) => {
31
58
  setSearchResultState(state);
32
59
  });
33
- }, [searchProvides]);
34
- if (!searchResultState) {
60
+ }, [scope]);
61
+ if (!searchResultState || !searchResultState.active) {
35
62
  return null;
36
63
  }
37
64
  const pageResults = searchResultState.results.map((result, originalIndex) => ({ result, originalIndex })).filter(({ result }) => result.pageIndex === pageIndex);
65
+ const resultsToShow = pageResults.filter(
66
+ ({ originalIndex }) => searchResultState.showAllResults || originalIndex === searchResultState.activeResultIndex
67
+ );
38
68
  return /* @__PURE__ */ jsx(
39
69
  "div",
40
70
  {
41
71
  style: {
42
- ...style
72
+ ...style,
73
+ pointerEvents: "none"
43
74
  },
44
75
  ...props,
45
- children: pageResults.map(
76
+ children: resultsToShow.map(
46
77
  ({ result, originalIndex }) => result.rects.map((rect, rectIndex) => /* @__PURE__ */ jsx(
47
78
  "div",
48
79
  {
49
80
  style: {
50
81
  position: "absolute",
51
- top: rect.origin.y * scale,
52
- left: rect.origin.x * scale,
53
- width: rect.size.width * scale,
54
- height: rect.size.height * scale,
82
+ top: rect.origin.y * actualScale,
83
+ left: rect.origin.x * actualScale,
84
+ width: rect.size.width * actualScale,
85
+ height: rect.size.height * actualScale,
55
86
  backgroundColor: originalIndex === searchResultState.activeResultIndex ? activeHighlightColor : highlightColor,
56
87
  mixBlendMode: "multiply",
57
88
  transform: "scale(1.02)",
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-search.ts","../../src/shared/components/search-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { initialState, SearchPlugin, SearchState } from '@embedpdf/plugin-search';\nimport { useEffect, useState } from '@framework';\n\nexport const useSearchPlugin = () => usePlugin<SearchPlugin>(SearchPlugin.id);\nexport const useSearchCapability = () => useCapability<SearchPlugin>(SearchPlugin.id);\n\nexport const useSearch = () => {\n const { provides } = useSearchCapability();\n const [searchState, setSearchState] = useState<SearchState>(initialState);\n\n useEffect(() => {\n return provides?.onStateChange((state) => setSearchState(state));\n }, [provides]);\n\n return {\n state: searchState,\n provides,\n };\n};\n","import { useEffect, useState, HTMLAttributes, CSSProperties } from '@framework';\nimport { SearchResultState } from '@embedpdf/plugin-search';\n\nimport { useSearchCapability } from '../hooks';\n\ntype SearchLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n style?: CSSProperties;\n};\n\nexport function SearchLayer({\n pageIndex,\n scale,\n style,\n highlightColor = '#FFFF00',\n activeHighlightColor = '#FFBF00',\n ...props\n}: SearchLayoutProps) {\n const { provides: searchProvides } = useSearchCapability();\n const [searchResultState, setSearchResultState] = useState<SearchResultState | null>(null);\n\n useEffect(() => {\n return searchProvides?.onSearchResultStateChange((state) => {\n setSearchResultState(state);\n });\n }, [searchProvides]);\n\n if (!searchResultState) {\n return null;\n }\n\n // Filter results for current page while preserving original indices\n const pageResults = searchResultState.results\n .map((result, originalIndex) => ({ result, originalIndex }))\n .filter(({ result }) => result.pageIndex === pageIndex);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {pageResults.map(({ result, originalIndex }) =>\n result.rects.map((rect, rectIndex) => (\n <div\n key={`${originalIndex}-${rectIndex}`}\n style={{\n position: 'absolute',\n top: rect.origin.y * scale,\n left: rect.origin.x * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n backgroundColor:\n originalIndex === searchResultState.activeResultIndex\n ? activeHighlightColor\n : highlightColor,\n mixBlendMode: 'multiply',\n transform: 'scale(1.02)',\n transformOrigin: 'center',\n transition: 'opacity .3s ease-in-out',\n opacity: 1,\n }}\n ></div>\n )),\n )}\n </div>\n );\n}\n"],"names":[],"mappings":";;;;;AAIO,MAAM,kBAAkB,MAAM,UAAwB,aAAa,EAAE;AACrE,MAAM,sBAAsB,MAAM,cAA4B,aAAa,EAAE;AAE7E,MAAM,YAAY,MAAM;AACvB,QAAA,EAAE,SAAS,IAAI,oBAAoB;AACzC,QAAM,CAAC,aAAa,cAAc,IAAI,SAAsB,YAAY;AAExE,YAAU,MAAM;AACd,WAAO,qCAAU,cAAc,CAAC,UAAU,eAAe,KAAK;AAAA,EAAC,GAC9D,CAAC,QAAQ,CAAC;AAEN,SAAA;AAAA,IACL,OAAO;AAAA,IACP;AAAA,EACF;AACF;ACNO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,uBAAuB;AAAA,EACvB,GAAG;AACL,GAAsB;AACpB,QAAM,EAAE,UAAU,eAAe,IAAI,oBAAoB;AACzD,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,SAAmC,IAAI;AAEzF,YAAU,MAAM;AACP,WAAA,iDAAgB,0BAA0B,CAAC,UAAU;AAC1D,2BAAqB,KAAK;AAAA,IAAA;AAAA,EAC3B,GACA,CAAC,cAAc,CAAC;AAEnB,MAAI,CAAC,mBAAmB;AACf,WAAA;AAAA,EAAA;AAIT,QAAM,cAAc,kBAAkB,QACnC,IAAI,CAAC,QAAQ,mBAAmB,EAAE,QAAQ,gBAAgB,EAC1D,OAAO,CAAC,EAAE,aAAa,OAAO,cAAc,SAAS;AAGtD,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA,MAEH,UAAY,YAAA;AAAA,QAAI,CAAC,EAAE,QAAQ,cAAc,MACxC,OAAO,MAAM,IAAI,CAAC,MAAM,cACtB;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,KAAK,KAAK,OAAO,IAAI;AAAA,cACrB,MAAM,KAAK,OAAO,IAAI;AAAA,cACtB,OAAO,KAAK,KAAK,QAAQ;AAAA,cACzB,QAAQ,KAAK,KAAK,SAAS;AAAA,cAC3B,iBACE,kBAAkB,kBAAkB,oBAChC,uBACA;AAAA,cACN,cAAc;AAAA,cACd,WAAW;AAAA,cACX,iBAAiB;AAAA,cACjB,YAAY;AAAA,cACZ,SAAS;AAAA,YAAA;AAAA,UACX;AAAA,UAhBK,GAAG,aAAa,IAAI,SAAS;AAAA,QAkBrC,CAAA;AAAA,MAAA;AAAA,IACH;AAAA,EACF;AAEJ;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-search.ts","../../src/shared/components/search-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n SearchPlugin,\n SearchDocumentState,\n SearchScope,\n initialSearchDocumentState,\n} from '@embedpdf/plugin-search';\nimport { useEffect, useMemo, useState } from '@framework';\n\nexport const useSearchPlugin = () => usePlugin<SearchPlugin>(SearchPlugin.id);\nexport const useSearchCapability = () => useCapability<SearchPlugin>(SearchPlugin.id);\n\nexport const useSearch = (\n documentId: string,\n): {\n state: SearchDocumentState;\n provides: SearchScope | null;\n} => {\n const { provides } = useSearchCapability();\n const [searchState, setSearchState] = useState<SearchDocumentState>(initialSearchDocumentState);\n\n const scope = useMemo(() => provides?.forDocument(documentId), [provides, documentId]);\n\n useEffect(() => {\n if (!scope) {\n setSearchState(initialSearchDocumentState);\n return;\n }\n // Set initial state\n setSearchState(scope.getState());\n // Subscribe to changes\n return scope.onStateChange((state) => setSearchState(state));\n }, [scope]);\n\n return {\n state: searchState,\n provides: scope ?? null,\n };\n};\n","import { useEffect, useMemo, useState, HTMLAttributes, CSSProperties } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { SearchResultState } from '@embedpdf/plugin-search';\n\nimport { useSearchCapability } from '../hooks';\n\ntype SearchLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n documentId: string;\n pageIndex: number;\n scale?: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n style?: CSSProperties;\n};\n\nexport function SearchLayer({\n documentId,\n pageIndex,\n scale: scaleOverride,\n style,\n highlightColor = '#FFFF00',\n activeHighlightColor = '#FFBF00',\n ...props\n}: SearchLayoutProps) {\n const { provides: searchProvides } = useSearchCapability();\n const [searchResultState, setSearchResultState] = useState<SearchResultState | null>(null);\n const documentState = useDocumentState(documentId);\n\n const scope = useMemo(\n () => searchProvides?.forDocument(documentId),\n [searchProvides, documentId],\n );\n\n const actualScale = useMemo(() => {\n if (scaleOverride !== undefined) return scaleOverride;\n return documentState?.scale ?? 1;\n }, [scaleOverride, documentState?.scale]);\n\n useEffect(() => {\n if (!scope) {\n setSearchResultState(null);\n return;\n }\n // Set initial state\n const currentState = scope.getState();\n setSearchResultState({\n results: currentState.results,\n activeResultIndex: currentState.activeResultIndex,\n showAllResults: currentState.showAllResults,\n active: currentState.active,\n });\n // Subscribe to changes\n return scope.onSearchResultStateChange((state) => {\n setSearchResultState(state);\n });\n }, [scope]);\n\n if (!searchResultState || !searchResultState.active) {\n return null;\n }\n\n // Filter results for current page while preserving original indices\n const pageResults = searchResultState.results\n .map((result, originalIndex) => ({ result, originalIndex }))\n .filter(({ result }) => result.pageIndex === pageIndex);\n\n // Decide which results to show\n const resultsToShow = pageResults.filter(\n ({ originalIndex }) =>\n searchResultState.showAllResults || originalIndex === searchResultState.activeResultIndex,\n );\n\n return (\n <div\n style={{\n ...style,\n pointerEvents: 'none',\n }}\n {...props}\n >\n {resultsToShow.map(({ result, originalIndex }) =>\n result.rects.map((rect, rectIndex) => (\n <div\n key={`${originalIndex}-${rectIndex}`}\n style={{\n position: 'absolute',\n top: rect.origin.y * actualScale,\n left: rect.origin.x * actualScale,\n width: rect.size.width * actualScale,\n height: rect.size.height * actualScale,\n backgroundColor:\n originalIndex === searchResultState.activeResultIndex\n ? activeHighlightColor\n : highlightColor,\n mixBlendMode: 'multiply',\n transform: 'scale(1.02)',\n transformOrigin: 'center',\n transition: 'opacity .3s ease-in-out',\n opacity: 1,\n }}\n ></div>\n )),\n )}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -1,10 +1,11 @@
1
1
  import { HTMLAttributes, CSSProperties } from '../../react/adapter.ts';
2
2
  type SearchLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {
3
+ documentId: string;
3
4
  pageIndex: number;
4
- scale: number;
5
+ scale?: number;
5
6
  highlightColor?: string;
6
7
  activeHighlightColor?: string;
7
8
  style?: CSSProperties;
8
9
  };
9
- export declare function SearchLayer({ pageIndex, scale, style, highlightColor, activeHighlightColor, ...props }: SearchLayoutProps): import("react/jsx-runtime").JSX.Element | null;
10
+ export declare function SearchLayer({ documentId, pageIndex, scale: scaleOverride, style, highlightColor, activeHighlightColor, ...props }: SearchLayoutProps): import("react/jsx-runtime").JSX.Element | null;
10
11
  export {};
@@ -1,4 +1,4 @@
1
- import { SearchPlugin, SearchState } from '../../index.ts';
1
+ import { SearchPlugin, SearchDocumentState, SearchScope } from '../../index.ts';
2
2
  export declare const useSearchPlugin: () => {
3
3
  plugin: SearchPlugin | null;
4
4
  isLoading: boolean;
@@ -9,7 +9,7 @@ export declare const useSearchCapability: () => {
9
9
  isLoading: boolean;
10
10
  ready: Promise<void>;
11
11
  };
12
- export declare const useSearch: () => {
13
- state: SearchState;
14
- provides: Readonly<import('../../index.ts').SearchCapability> | null;
12
+ export declare const useSearch: (documentId: string) => {
13
+ state: SearchDocumentState;
14
+ provides: SearchScope | null;
15
15
  };
@@ -1,10 +1,11 @@
1
1
  import { HTMLAttributes, CSSProperties } from '../../preact/adapter.ts';
2
2
  type SearchLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {
3
+ documentId: string;
3
4
  pageIndex: number;
4
- scale: number;
5
+ scale?: number;
5
6
  highlightColor?: string;
6
7
  activeHighlightColor?: string;
7
8
  style?: CSSProperties;
8
9
  };
9
- export declare function SearchLayer({ pageIndex, scale, style, highlightColor, activeHighlightColor, ...props }: SearchLayoutProps): import("preact").JSX.Element | null;
10
+ export declare function SearchLayer({ documentId, pageIndex, scale: scaleOverride, style, highlightColor, activeHighlightColor, ...props }: SearchLayoutProps): import("preact").JSX.Element | null;
10
11
  export {};
@@ -1,4 +1,4 @@
1
- import { SearchPlugin, SearchState } from '../../lib/index.ts';
1
+ import { SearchPlugin, SearchDocumentState, SearchScope } from '../../lib/index.ts';
2
2
  export declare const useSearchPlugin: () => {
3
3
  plugin: SearchPlugin | null;
4
4
  isLoading: boolean;
@@ -9,7 +9,7 @@ export declare const useSearchCapability: () => {
9
9
  isLoading: boolean;
10
10
  ready: Promise<void>;
11
11
  };
12
- export declare const useSearch: () => {
13
- state: SearchState;
14
- provides: Readonly<import('../../lib/index.ts').SearchCapability> | null;
12
+ export declare const useSearch: (documentId: string) => {
13
+ state: SearchDocumentState;
14
+ provides: SearchScope | null;
15
15
  };
@@ -1,10 +1,11 @@
1
1
  import { HTMLAttributes, CSSProperties } from '../../react/adapter.ts';
2
2
  type SearchLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {
3
+ documentId: string;
3
4
  pageIndex: number;
4
- scale: number;
5
+ scale?: number;
5
6
  highlightColor?: string;
6
7
  activeHighlightColor?: string;
7
8
  style?: CSSProperties;
8
9
  };
9
- export declare function SearchLayer({ pageIndex, scale, style, highlightColor, activeHighlightColor, ...props }: SearchLayoutProps): import("react/jsx-runtime").JSX.Element | null;
10
+ export declare function SearchLayer({ documentId, pageIndex, scale: scaleOverride, style, highlightColor, activeHighlightColor, ...props }: SearchLayoutProps): import("react/jsx-runtime").JSX.Element | null;
10
11
  export {};
@@ -1,4 +1,4 @@
1
- import { SearchPlugin, SearchState } from '../../lib/index.ts';
1
+ import { SearchPlugin, SearchDocumentState, SearchScope } from '../../lib/index.ts';
2
2
  export declare const useSearchPlugin: () => {
3
3
  plugin: SearchPlugin | null;
4
4
  isLoading: boolean;
@@ -9,7 +9,7 @@ export declare const useSearchCapability: () => {
9
9
  isLoading: boolean;
10
10
  ready: Promise<void>;
11
11
  };
12
- export declare const useSearch: () => {
13
- state: SearchState;
14
- provides: Readonly<import('../../lib/index.ts').SearchCapability> | null;
12
+ export declare const useSearch: (documentId: string) => {
13
+ state: SearchDocumentState;
14
+ provides: SearchScope | null;
15
15
  };
@@ -1,10 +1,11 @@
1
1
  import { HTMLAttributes } from 'svelte/elements';
2
- interface Props extends HTMLAttributes<HTMLDivElement> {
2
+ interface SearchLayerProps extends HTMLAttributes<HTMLDivElement> {
3
+ documentId: string;
3
4
  pageIndex: number;
4
- scale: number;
5
+ scale?: number;
5
6
  highlightColor?: string;
6
7
  activeHighlightColor?: string;
7
8
  }
8
- declare const SearchLayer: import('svelte', { with: { "resolution-mode": "import" } }).Component<Props, {}, "">;
9
+ declare const SearchLayer: import('svelte', { with: { "resolution-mode": "import" } }).Component<SearchLayerProps, {}, "">;
9
10
  type SearchLayer = ReturnType<typeof SearchLayer>;
10
11
  export default SearchLayer;
@@ -1,4 +1,4 @@
1
- import { SearchPlugin, SearchState } from '../../lib/index.ts';
1
+ import { SearchPlugin, SearchDocumentState, SearchScope } from '../../lib/index.ts';
2
2
  export declare const useSearchPlugin: () => {
3
3
  plugin: SearchPlugin | null;
4
4
  isLoading: boolean;
@@ -9,7 +9,13 @@ export declare const useSearchCapability: () => {
9
9
  isLoading: boolean;
10
10
  ready: Promise<void>;
11
11
  };
12
- export declare const useSearch: () => {
13
- readonly provides: Readonly<import('../../lib/index.ts').SearchCapability> | null;
14
- state: SearchState;
15
- };
12
+ interface UseSearchReturn {
13
+ provides: SearchScope | null;
14
+ state: SearchDocumentState;
15
+ }
16
+ /**
17
+ * Hook for search state for a specific document
18
+ * @param getDocumentId Function that returns the document ID
19
+ */
20
+ export declare const useSearch: (getDocumentId: () => string | null) => UseSearchReturn;
21
+ export {};
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("svelte/internal/client"),t=require("@embedpdf/core/svelte"),r=require("@embedpdf/plugin-search");function i(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const r in e)if("default"!==r){const i=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,i.get?i:{enumerable:!0,get:()=>e[r]})}return t.default=e,Object.freeze(t)}require("svelte/internal/disclose-version");const o=i(e),s=()=>t.useCapability(r.SearchPlugin.id);var a=o.from_html("<div></div>"),n=o.from_html("<div></div>");exports.SearchLayer=function(e,t){o.push(t,!0);const r=o.prop(t,"highlightColor",3,"#FFFF00"),i=o.prop(t,"activeHighlightColor",3,"#FFBF00"),l=o.rest_props(t,["$$slots","$$events","$$legacy","pageIndex","scale","highlightColor","activeHighlightColor"]),c=s();let p=o.state(null);o.user_effect((()=>{if(c.provides)return c.provides.onSearchResultStateChange((e=>{o.set(p,e,!0)}))}));const g=o.derived((()=>o.get(p)?o.get(p).results.map(((e,t)=>({result:e,originalIndex:t}))).filter((({result:e})=>e.pageIndex===t.pageIndex)):[]));var u=o.comment(),d=o.first_child(u),h=e=>{var s=n();o.attribute_effect(s,(()=>({...l}))),o.each(s,21,(()=>o.get(g)),o.index,((e,s)=>{var n=o.comment(),l=o.first_child(n);o.each(l,17,(()=>o.get(s).result.rects),o.index,((e,n)=>{var l=a();let c;o.template_effect((e=>c=o.set_style(l,"",c,e)),[()=>({position:"absolute",top:o.get(n).origin.y*t.scale+"px",left:o.get(n).origin.x*t.scale+"px",width:o.get(n).size.width*t.scale+"px",height:o.get(n).size.height*t.scale+"px","background-color":o.get(s).originalIndex===o.get(p).activeResultIndex?i():r(),"mix-blend-mode":"multiply",transform:"scale(1.02)","transform-origin":"center",transition:"opacity .3s ease-in-out",opacity:"1"})]),o.append(e,l)})),o.append(e,n)})),o.reset(s),o.append(e,s)};o.if(d,(e=>{o.get(p)&&e(h)})),o.append(e,u),o.pop()},exports.useSearch=()=>{const e=s(),t=o.proxy({get provides(){return e.provides},state:r.initialState});return o.user_effect((()=>{if(e.provides)return e.provides.onStateChange((e=>{t.state=e}))})),t},exports.useSearchCapability=s,exports.useSearchPlugin=()=>t.usePlugin(r.SearchPlugin.id),Object.keys(r).forEach((e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>r[e]})}));
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("svelte/internal/client"),t=require("@embedpdf/core/svelte"),r=require("@embedpdf/plugin-search");function i(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const r in e)if("default"!==r){const i=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,i.get?i:{enumerable:!0,get:()=>e[r]})}return t.default=e,Object.freeze(t)}require("svelte/internal/disclose-version");const n=i(e),o=()=>t.useCapability(r.SearchPlugin.id);var s=n.from_html("<div></div>"),l=n.from_html("<div></div>");exports.SearchLayer=function(e,r){n.push(r,!0);let i=n.prop(r,"highlightColor",3,"#FFFF00"),a=n.prop(r,"activeHighlightColor",3,"#FFBF00"),c=n.rest_props(r,["$$slots","$$events","$$legacy","documentId","pageIndex","scale","highlightColor","activeHighlightColor"]);const u=o(),g=t.useDocumentState(()=>r.documentId);let d=n.state(null);const p=n.derived(()=>{var e;return(null==(e=u.provides)?void 0:e.forDocument(r.documentId))??null}),v=n.derived(()=>{var e;return void 0!==r.scale?r.scale:(null==(e=g.current)?void 0:e.scale)??1});n.user_effect(()=>{if(!n.get(p))return void n.set(d,null);const e=n.get(p).getState();return n.set(d,{results:e.results,activeResultIndex:e.activeResultIndex,showAllResults:e.showAllResults,active:e.active},!0),n.get(p).onSearchResultStateChange(e=>{n.set(d,e,!0)})});const h=n.derived(()=>n.get(d)?n.get(d).results.map((e,t)=>({result:e,originalIndex:t})).filter(({result:e})=>e.pageIndex===r.pageIndex):[]),f=n.derived(()=>n.get(d)?n.get(h).filter(({originalIndex:e})=>n.get(d).showAllResults||e===n.get(d).activeResultIndex):[]);var m=n.comment(),x=n.first_child(m),S=e=>{var t=l();n.attribute_effect(t,()=>({...c,[n.STYLE]:{"pointer-events":"none"}})),n.each(t,23,()=>n.get(f),({result:e,originalIndex:t},r)=>`result-${r}`,(e,t,r)=>{var o=n.comment(),l=n.first_child(o);n.each(l,19,()=>n.get(t).result.rects,(e,t)=>`rect-${n.get(r)}-${t}`,(e,r)=>{var o=s();let l;n.template_effect(()=>l=n.set_style(o,"",l,{position:"absolute",top:n.get(r).origin.y*n.get(v)+"px",left:n.get(r).origin.x*n.get(v)+"px",width:n.get(r).size.width*n.get(v)+"px",height:n.get(r).size.height*n.get(v)+"px","background-color":n.get(t).originalIndex===n.get(d).activeResultIndex?a():i(),"mix-blend-mode":"multiply",transform:"scale(1.02)","transform-origin":"center",transition:"opacity .3s ease-in-out",opacity:"1"})),n.append(e,o)}),n.append(e,o)}),n.reset(t),n.append(e,t)};n.if(x,e=>{n.get(d)&&n.get(d).active&&e(S)}),n.append(e,m),n.pop()},exports.useSearch=e=>{const t=o();let i=n.state(n.proxy(r.initialSearchDocumentState));const s=n.derived(e),l=n.derived(()=>t.provides&&n.get(s)?t.provides.forDocument(n.get(s)):null);return n.user_effect(()=>{const e=t.provides,o=n.get(s);if(!e||!o)return void n.set(i,r.initialSearchDocumentState,!0);const l=e.forDocument(o);return n.set(i,l.getState(),!0),l.onStateChange(e=>{n.set(i,e,!0)})}),{get provides(){return n.get(l)},get state(){return n.get(i)}}},exports.useSearchCapability=o,exports.useSearchPlugin=()=>t.usePlugin(r.SearchPlugin.id),Object.keys(r).forEach(e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>r[e]})});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/svelte/hooks/use-search.svelte.ts","../../src/svelte/components/SearchLayer.svelte"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/svelte';\nimport { initialState, SearchPlugin, SearchState } from '@embedpdf/plugin-search';\n\nexport const useSearchPlugin = () => usePlugin<SearchPlugin>(SearchPlugin.id);\nexport const useSearchCapability = () => useCapability<SearchPlugin>(SearchPlugin.id);\n\nexport const useSearch = () => {\n const capability = useSearchCapability();\n\n const state = $state({\n get provides() {\n return capability.provides;\n },\n state: initialState as SearchState,\n });\n\n $effect(() => {\n if (!capability.provides) return;\n return capability.provides.onStateChange((newState) => {\n state.state = newState;\n });\n });\n\n return state;\n};\n","<script lang=\"ts\">\n import type { SearchResultState } from '@embedpdf/plugin-search';\n import { useSearchCapability } from '../hooks';\n import type { HTMLAttributes } from 'svelte/elements';\n\n interface Props extends HTMLAttributes<HTMLDivElement> {\n pageIndex: number;\n scale: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n }\n\n const {\n pageIndex,\n scale,\n highlightColor = '#FFFF00',\n activeHighlightColor = '#FFBF00',\n ...divProps\n }: Props = $props();\n\n const searchCapability = useSearchCapability();\n let searchResultState = $state<SearchResultState | null>(null);\n\n $effect(() => {\n if (!searchCapability.provides) return;\n return searchCapability.provides.onSearchResultStateChange((state) => {\n searchResultState = state;\n });\n });\n\n const pageResults = $derived(\n searchResultState\n ? searchResultState.results\n .map((result, originalIndex) => ({ result, originalIndex }))\n .filter(({ result }) => result.pageIndex === pageIndex)\n : [],\n );\n</script>\n\n{#if searchResultState}\n <div {...divProps}>\n {#each pageResults as { result, originalIndex }}\n {#each result.rects as rect}\n <div\n style:position=\"absolute\"\n style:top=\"{rect.origin.y * scale}px\"\n style:left=\"{rect.origin.x * scale}px\"\n style:width=\"{rect.size.width * scale}px\"\n style:height=\"{rect.size.height * scale}px\"\n style:background-color={originalIndex === searchResultState.activeResultIndex\n ? activeHighlightColor\n : highlightColor}\n style:mix-blend-mode=\"multiply\"\n style:transform=\"scale(1.02)\"\n style:transform-origin=\"center\"\n style:transition=\"opacity .3s ease-in-out\"\n style:opacity=\"1\"\n ></div>\n {/each}\n {/each}\n </div>\n{/if}\n"],"names":["useSearchCapability","useCapability","SearchPlugin","id","highlightColor","activeHighlightColor","divProps","$","rest_props","$$props","searchCapability","searchResultState","user_effect","provides","onSearchResultStateChange","state","$__namespace","set","pageResults","get","results","map","result","originalIndex","filter","pageIndex","index","$$anchor","$$item","rects","rect","origin","y","scale","x","size","width","height","activeResultIndex","consequent","capability","initialState","onStateChange","newState","usePlugin"],"mappings":"sgBAIaA,EAA4B,IAAAC,gBAA4BC,EAAAA,aAAaC,iHCW9E,MAAAC,8BAAiB,WACjBC,oCAAuB,WACpBC,EAAOC,EAAAC,WAAAC,EAAA,+FAGNC,EAAmBV,IACrB,IAAAW,UAAqD,MAEzDJ,EAAAK,aAAc,KACP,GAAAF,EAAiBG,SACf,OAAAH,EAAiBG,SAASC,2BAA2BC,IAC1DC,EAAAC,IAAAN,EAAoBI,GAAK,EAAA,GAC1B,IAGG,MAAAG,uBACJP,GACIJ,EAAAY,IAAAR,GAAkBS,QACfC,KAAK,CAAAC,EAAQC,KAAa,CAAQD,SAAQC,oBAC1CC,QAAM,EAAIF,YAAaA,EAAOG,YAAShB,EAAAgB,qGAMvCnB,6BACAY,IAAWX,EAAAmB,OAAA,CAAAC,EAAAC,oEAAON,OACTO,OAAKtB,EAAAmB,OAAA,CAAAC,EAAIG,yGAGPA,GAAKC,OAAOC,EAACvB,EAAAwB,sBACZH,GAAKC,OAAOG,EAACzB,EAAAwB,uBACZH,GAAKK,KAAKC,MAAK3B,EAAAwB,wBACdH,GAAKK,KAAKE,OAAM5B,EAAAwB,WACP,4BARGV,sBAQeZ,GAAkB2B,kBACxDjC,IACAD,uNAZTO,MAAiB4B,EAAA,yBAFtB,yBD9BQ,MAAAC,EAAaxC,IAEbe,WACA,YAAAF,GACK,OAAA2B,EAAW3B,QACpB,EACAE,MAAO0B,EAAAA,eAUF,OAPPlC,EAAAK,kBACO,GAAA4B,EAAW3B,SACT,OAAA2B,EAAW3B,SAAS6B,eAAeC,IACxC5B,EAAMA,MAAQ4B,CAAA,GACf,IAGI5B,CAAA,wDApB4B,IAAA6B,YAAwB1C,EAAAA,aAAaC"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/svelte/hooks/use-search.svelte.ts","../../src/svelte/components/SearchLayer.svelte"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/svelte';\nimport {\n SearchPlugin,\n SearchDocumentState,\n SearchScope,\n initialSearchDocumentState,\n} from '@embedpdf/plugin-search';\n\nexport const useSearchPlugin = () => usePlugin<SearchPlugin>(SearchPlugin.id);\nexport const useSearchCapability = () => useCapability<SearchPlugin>(SearchPlugin.id);\n\n// Define the return type explicitly to maintain type safety\ninterface UseSearchReturn {\n provides: SearchScope | null;\n state: SearchDocumentState;\n}\n\n/**\n * Hook for search state for a specific document\n * @param getDocumentId Function that returns the document ID\n */\nexport const useSearch = (getDocumentId: () => string | null): UseSearchReturn => {\n const capability = useSearchCapability();\n\n let searchState = $state<SearchDocumentState>(initialSearchDocumentState);\n\n // Reactive documentId\n const documentId = $derived(getDocumentId());\n\n // Scoped capability for current docId\n const scopedProvides = $derived(\n capability.provides && documentId ? capability.provides.forDocument(documentId) : null,\n );\n\n $effect(() => {\n const provides = capability.provides;\n const docId = documentId;\n\n if (!provides || !docId) {\n searchState = initialSearchDocumentState;\n return;\n }\n\n const scope = provides.forDocument(docId);\n\n // Set initial state\n searchState = scope.getState();\n\n // Subscribe to changes\n return scope.onStateChange((state) => {\n searchState = state;\n });\n });\n\n return {\n get provides() {\n return scopedProvides;\n },\n get state() {\n return searchState;\n },\n };\n};\n","<script lang=\"ts\">\n import type { SearchResultState } from '@embedpdf/plugin-search';\n import { useDocumentState } from '@embedpdf/core/svelte';\n import { useSearchCapability } from '../hooks';\n import type { HTMLAttributes } from 'svelte/elements';\n\n interface SearchLayerProps extends HTMLAttributes<HTMLDivElement> {\n documentId: string;\n pageIndex: number;\n scale?: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n }\n\n let {\n documentId,\n pageIndex,\n scale: scaleOverride,\n highlightColor = '#FFFF00',\n activeHighlightColor = '#FFBF00',\n ...divProps\n }: SearchLayerProps = $props();\n\n const searchCapability = useSearchCapability();\n const documentState = useDocumentState(() => documentId);\n\n let searchResultState = $state<SearchResultState | null>(null);\n\n const scope = $derived(searchCapability.provides?.forDocument(documentId) ?? null);\n\n const actualScale = $derived(\n scaleOverride !== undefined ? scaleOverride : (documentState.current?.scale ?? 1),\n );\n\n $effect(() => {\n if (!scope) {\n searchResultState = null;\n return;\n }\n\n // Set initial state\n const currentState = scope.getState();\n searchResultState = {\n results: currentState.results,\n activeResultIndex: currentState.activeResultIndex,\n showAllResults: currentState.showAllResults,\n active: currentState.active,\n };\n\n // Subscribe to changes\n return scope.onSearchResultStateChange((state) => {\n searchResultState = state;\n });\n });\n\n // Filter results for current page while preserving original indices\n const pageResults = $derived(\n searchResultState\n ? searchResultState.results\n .map((result, originalIndex) => ({ result, originalIndex }))\n .filter(({ result }) => result.pageIndex === pageIndex)\n : [],\n );\n\n // Decide which results to show\n const resultsToShow = $derived(\n searchResultState\n ? pageResults.filter(\n ({ originalIndex }) =>\n searchResultState!.showAllResults ||\n originalIndex === searchResultState!.activeResultIndex,\n )\n : [],\n );\n</script>\n\n{#if searchResultState && searchResultState.active}\n <div style:pointer-events=\"none\" {...divProps}>\n {#each resultsToShow as { result, originalIndex }, idx (`result-${idx}`)}\n {#each result.rects as rect, rectIdx (`rect-${idx}-${rectIdx}`)}\n <div\n style:position=\"absolute\"\n style:top=\"{rect.origin.y * actualScale}px\"\n style:left=\"{rect.origin.x * actualScale}px\"\n style:width=\"{rect.size.width * actualScale}px\"\n style:height=\"{rect.size.height * actualScale}px\"\n style:background-color={originalIndex === searchResultState.activeResultIndex\n ? activeHighlightColor\n : highlightColor}\n style:mix-blend-mode=\"multiply\"\n style:transform=\"scale(1.02)\"\n style:transform-origin=\"center\"\n style:transition=\"opacity .3s ease-in-out\"\n style:opacity=\"1\"\n ></div>\n {/each}\n {/each}\n </div>\n{/if}\n"],"names":["useSearchCapability","useCapability","SearchPlugin","id","highlightColor","activeHighlightColor","divProps","$","rest_props","$$props","searchCapability","documentState","useDocumentState","documentId","searchResultState","scope","_a","provides","forDocument","actualScale","derived","scale","current","user_effect","get","set","currentState","getState","results","activeResultIndex","showAllResults","active","onSearchResultStateChange","state","pageResults","map","result","originalIndex","filter","pageIndex","resultsToShow","STYLE","each","div","idx","$$anchor","$$item","rects","rect","rectIdx","top","origin","y","left","x","width","size","height","$$render","consequent","getDocumentId","capability","searchState","initialSearchDocumentState","scopedProvides","docId","onStateChange","usePlugin"],"mappings":"sgBASaA,EAAA,IAA4BC,gBAA4BC,EAAAA,aAAaC,iHCS9E,IAAAC,8BAAiB,WACjBC,oCAAuB,WACpBC,EAAOC,EAAAC,WAAAC,EAAA,4GAGN,MAAAC,EAAmBV,IACnBW,EAAgBC,EAAAA,iBAAgB,IAAAH,EAAAI,YAElC,IAAAC,UAAqD,MAEnD,MAAAC,uBAAiB,OAAA,OAAAC,EAAAN,EAAiBO,eAAjB,EAAAD,EAA2BE,4BAA2B,OAEvEC,EAAWZ,EAAAa,QAAA,WAAA,YACG,IADHX,EAAAY,MACYZ,EAAAY,OAAoB,OAAAL,EAAAL,EAAcW,kBAASD,QAAS,IAGjFd,EAAAgB,YAAO,KACA,IAAAhB,EAAAiB,IAAAT,eACHR,EAAAkB,IAAAX,EAAoB,YAKhBY,EAAYnB,EAAAiB,IAAGT,GAAMY,WASpB,aARPb,GACEc,QAASF,EAAaE,QACtBC,kBAAmBH,EAAaG,kBAChCC,eAAgBJ,EAAaI,eAC7BC,OAAQL,EAAaK,YAIhBxB,EAAAiB,IAAAT,GAAMiB,0BAA2BC,IACtC1B,EAAAkB,IAAAX,EAAoBmB,GAAK,OAKvB,MAAAC,sBACJpB,GACIP,EAAAiB,IAAAV,GAAkBc,QACfO,IAAG,CAAEC,EAAQC,KAAA,CAAqBD,SAAQC,mBAC1CC,OAAM,EAAIF,YAAaA,EAAOG,YAAS9B,EAAA8B,eAK1CC,sBACJ1B,GACIP,EAAAiB,IAAAU,GAAYI,OAAM,EACbD,mBAAa9B,EAAAiB,IACdV,GAAmBgB,gBACnBO,IAAa9B,EAAAiB,IAAKV,GAAmBe,0GAOVvB,EAAQ,CAAAC,EAAAkC,OAAA,CAAA,iBAAA,WACpClC,EAAAmC,KAAAC,EAAA,GAAA,IAAApC,EAAAiB,IAAAgB,GAAa,EAAOJ,SAAQC,+BAA+BO,IAAG,CAAAC,EAAAC,EAAAF,mEAA1CR,OACXW,MAAK,CAAIC,oBAAuBJ,MAAOK,IAAO,CAAAJ,EAArCG,qFAGPE,IAAA3C,EAAAiB,IAAAwB,GAAKG,OAAOC,QAAIjC,GAAhB,KACCkC,KAAA9C,EAAAiB,IAAAwB,GAAKG,OAAOG,QAAInC,GAAhB,KACCoC,MAAAhD,EAAAiB,IAAAwB,GAAKQ,KAAKD,YAAQpC,GAAlB,KACCsC,OAAAlD,EAAAiB,IAAAwB,GAAKQ,KAAKC,aAAStC,GAAnB,KACS,4BARKkB,sBAQavB,GAAkBe,kBACxDxB,IACAD,mNAZTU,IAAiBP,EAAAiB,IAAIV,GAAkBiB,QAAM2B,EAAAC,0BAFlD,oBDrD0BC,IAClB,MAAAC,EAAa7D,IAEf,IAAA8D,kBAA0CC,EAAAA,6BAGxC,MAAAlD,YAAsB+C,GAGtBI,EAAAzD,EAAAa,QAAA,IACJyC,EAAW5C,gBAAYJ,GAAagD,EAAW5C,SAASC,kBAAYL,IAAc,aAGpFN,EAAAgB,uBACQN,EAAW4C,EAAW5C,SACtBgD,QAAQpD,OAETI,IAAagD,cAChB1D,EAAAkB,IAAAqC,EAAcC,EAAAA,4BAAA,GAIV,MAAAhD,EAAQE,EAASC,YAAY+C,GAM5B,aAHPH,EAAc/C,EAAMY,YAAA,GAGbZ,EAAMmD,cAAejC,IAC1B1B,EAAAkB,IAAAqC,EAAc7B,GAAA,QAKZ,YAAAhB,gBACK+C,EACT,EACI,SAAA/B,gBACK6B,EACT,0DApDS,IAAwBK,YAAwBjE,EAAAA,aAAaC"}