@anaralabs/lector 3.7.2 → 3.8.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.
@@ -1,4 +1,5 @@
1
1
  import { ComponentPropsWithoutRef } from 'react';
2
+ import { Context } from 'react';
2
3
  import type { DocumentInitParameters } from 'pdfjs-dist/types/src/display/api';
3
4
  import { ForwardRefExoticComponent } from 'react';
4
5
  import { FunctionComponent } from 'react';
@@ -287,6 +288,8 @@ export declare const Pages: ({ children, gap, virtualizerOptions, initialOffset,
287
288
  onOffsetChange?: (offset: number) => void;
288
289
  }) => JSX.Element;
289
290
 
291
+ export declare const PDFLinkServiceContext: Context<LinkService>;
292
+
290
293
  declare interface PDFState {
291
294
  pdfDocumentProxy: PDFDocumentProxy;
292
295
  zoom: number;
@@ -414,6 +417,8 @@ declare interface UseAnnotationTooltipReturn {
414
417
  getReferenceProps: ReturnType<typeof useInteractions>["getReferenceProps"];
415
418
  }
416
419
 
420
+ export declare const useCreatePDFLinkService: (pdfDocumentProxy: PDFDocumentProxy | null) => LinkService;
421
+
417
422
  declare const usePdf: <T>(selector: (state: PDFState) => T) => T;
418
423
  export { usePdf }
419
424
  export { usePdf as usePdf_alias_1 }
@@ -447,6 +452,8 @@ export declare const usePdfJump: () => {
447
452
  scrollToHighlightRects: (rects: HighlightRect[], type: "pixels" | "percent", align?: "start" | "center", additionalOffset?: number) => void;
448
453
  };
449
454
 
455
+ export declare const usePDFLinkService: () => LinkService;
456
+
450
457
  declare const usePDFOutline: () => {
451
458
  title: string;
452
459
  bold: boolean;
package/dist/index.d.ts CHANGED
@@ -32,6 +32,9 @@ export { calculateHighlightRects } from './_tsup-dts-rollup.js';
32
32
  export { Annotation } from './_tsup-dts-rollup.js';
33
33
  export { useAnnotations } from './_tsup-dts-rollup.js';
34
34
  export { LinkService } from './_tsup-dts-rollup.js';
35
+ export { PDFLinkServiceContext } from './_tsup-dts-rollup.js';
36
+ export { useCreatePDFLinkService } from './_tsup-dts-rollup.js';
37
+ export { usePDFLinkService } from './_tsup-dts-rollup.js';
35
38
  export { usePDFPageNumber } from './_tsup-dts-rollup.js';
36
39
  export { useSelectionDimensions } from './_tsup-dts-rollup.js';
37
40
  export { ColoredHighlight } from './_tsup-dts-rollup.js';
package/dist/index.js CHANGED
@@ -863,6 +863,16 @@ var LinkService = class {
863
863
  this._pageNavigationCallback = void 0;
864
864
  }
865
865
  };
866
+ var useCreatePDFLinkService = (pdfDocumentProxy) => {
867
+ const linkService = useRef(new LinkService());
868
+ useEffect(() => {
869
+ if (pdfDocumentProxy) {
870
+ linkService.current._pdfDocumentProxy = pdfDocumentProxy;
871
+ linkService.current.setDocument(pdfDocumentProxy);
872
+ }
873
+ }, [pdfDocumentProxy]);
874
+ return linkService.current;
875
+ };
866
876
  var defaultLinkService = new LinkService();
867
877
  var PDFLinkServiceContext = createContext(defaultLinkService);
868
878
  var usePDFLinkService = () => {
@@ -4587,12 +4597,21 @@ var firstMemo = (first, memo, initializer) => {
4587
4597
  };
4588
4598
 
4589
4599
  // src/hooks/viewport/useViewportContainer.tsx
4600
+ var WHEEL_ZOOM_SENSITIVITY = 0.01;
4601
+ var WHEEL_INERTIA_GAP_MS = 140;
4602
+ var WHEEL_INERTIA_ESCAPE_FACTOR = 1.35;
4590
4603
  var useViewportContainer = ({
4591
4604
  containerRef,
4592
4605
  elementWrapperRef,
4593
4606
  elementRef
4594
4607
  }) => {
4595
4608
  const [origin, setOrigin] = useState([0, 0]);
4609
+ const wheelInertia = useRef({
4610
+ active: false,
4611
+ lastTime: 0,
4612
+ lastAbsDeltaY: 0,
4613
+ lastSign: 0
4614
+ });
4596
4615
  const { maxZoom, minZoom } = usePdf((state) => state.zoomOptions);
4597
4616
  const zoom = usePdf((state) => state.zoom);
4598
4617
  const viewportRef = usePdf((state) => state.viewportRef);
@@ -4628,7 +4647,17 @@ var useViewportContainer = ({
4628
4647
  if (transformations.current.zoom === zoom || !containerRef.current) {
4629
4648
  return;
4630
4649
  }
4631
- const dZoom = zoom / transformations.current.zoom;
4650
+ const prevZoom = transformations.current.zoom;
4651
+ if (!prevZoom || !Number.isFinite(prevZoom)) {
4652
+ transformations.current = {
4653
+ translateX: containerRef.current.scrollLeft,
4654
+ translateY: containerRef.current.scrollTop,
4655
+ zoom
4656
+ };
4657
+ updateTransform();
4658
+ return;
4659
+ }
4660
+ const dZoom = zoom / prevZoom;
4632
4661
  transformations.current = {
4633
4662
  translateX: containerRef.current.scrollLeft * dZoom,
4634
4663
  translateY: containerRef.current.scrollTop * dZoom,
@@ -4645,16 +4674,67 @@ var useViewportContainer = ({
4645
4674
  document.removeEventListener("gesturechange", preventDefault);
4646
4675
  };
4647
4676
  }, []);
4677
+ useEffect(() => {
4678
+ const container = containerRef.current;
4679
+ if (!container) return;
4680
+ const sign = (n) => n === 0 ? 0 : n > 0 ? 1 : -1;
4681
+ const handleWheelCapture = (event) => {
4682
+ const st = wheelInertia.current;
4683
+ const now = Date.now();
4684
+ const ctrl = event.ctrlKey || event.metaKey;
4685
+ const abs = Math.abs(event.deltaY);
4686
+ const s = sign(event.deltaY);
4687
+ if (ctrl) {
4688
+ st.active = true;
4689
+ st.lastTime = now;
4690
+ st.lastAbsDeltaY = abs;
4691
+ st.lastSign = s;
4692
+ event.preventDefault();
4693
+ return;
4694
+ }
4695
+ if (!st.active) {
4696
+ return;
4697
+ }
4698
+ if (now - st.lastTime > WHEEL_INERTIA_GAP_MS) {
4699
+ st.active = false;
4700
+ return;
4701
+ }
4702
+ if (st.lastSign !== 0 && s !== 0 && s !== st.lastSign) {
4703
+ st.active = false;
4704
+ return;
4705
+ }
4706
+ if (st.lastAbsDeltaY > 0 && abs > st.lastAbsDeltaY * WHEEL_INERTIA_ESCAPE_FACTOR + 1) {
4707
+ st.active = false;
4708
+ return;
4709
+ }
4710
+ st.lastTime = now;
4711
+ st.lastAbsDeltaY = abs;
4712
+ st.lastSign = s;
4713
+ event.preventDefault();
4714
+ };
4715
+ container.addEventListener("wheel", handleWheelCapture, {
4716
+ passive: false,
4717
+ capture: true
4718
+ });
4719
+ return () => {
4720
+ container.removeEventListener("wheel", handleWheelCapture, {
4721
+ capture: true
4722
+ });
4723
+ };
4724
+ }, [containerRef]);
4648
4725
  useGesture(
4649
4726
  {
4650
- onPinch: ({ origin: origin2, first, movement: [ms], memo }) => {
4727
+ onPinch: (state) => {
4728
+ const { origin: origin2, first, movement, delta, event, memo } = state;
4729
+ const [ms] = movement;
4730
+ const [deltaScale] = delta;
4651
4731
  const currentElement = elementRef.current;
4652
4732
  const currentContainer = containerRef.current;
4653
4733
  if (!currentElement || !currentContainer) return;
4654
- if (!elementRef.current || !containerRef.current) return;
4655
4734
  const newMemo = firstMemo(first, memo, () => {
4656
4735
  const elementRect = currentElement.getBoundingClientRect();
4657
4736
  const containerRect = currentContainer.getBoundingClientRect();
4737
+ const currentZoom = transformations.current.zoom;
4658
4738
  const contentPosition = [
4659
4739
  origin2[0] - elementRect.left,
4660
4740
  origin2[1] - elementRect.top
@@ -4664,17 +4744,37 @@ var useViewportContainer = ({
4664
4744
  origin2[1] - containerRect.top
4665
4745
  ];
4666
4746
  setOrigin([
4667
- contentPosition[0] / transformations.current.zoom,
4668
- contentPosition[1] / transformations.current.zoom
4747
+ contentPosition[0] / currentZoom,
4748
+ contentPosition[1] / currentZoom
4669
4749
  ]);
4670
4750
  return {
4671
4751
  contentPosition,
4672
4752
  containerPosition,
4673
- originZoom: transformations.current.zoom,
4674
- originTranslate: transformations.current.translateY
4753
+ originZoom: currentZoom,
4754
+ lastZoom: currentZoom
4675
4755
  };
4676
4756
  });
4677
- const newZoom = clamp(ms * newMemo.originZoom, minZoom, maxZoom);
4757
+ if (first) {
4758
+ return newMemo;
4759
+ }
4760
+ const gestureValuesValid = Number.isFinite(ms) && ms > 0;
4761
+ let effectiveScale = ms;
4762
+ if (!gestureValuesValid) {
4763
+ const wheelEvent = event;
4764
+ if (wheelEvent?.deltaY !== void 0) {
4765
+ const wheelDelta = -wheelEvent.deltaY * WHEEL_ZOOM_SENSITIVITY;
4766
+ effectiveScale = newMemo.lastZoom / newMemo.originZoom * (1 + wheelDelta);
4767
+ } else if (Number.isFinite(deltaScale) && deltaScale !== 0) {
4768
+ effectiveScale = newMemo.lastZoom / newMemo.originZoom * (1 + deltaScale);
4769
+ } else {
4770
+ return newMemo;
4771
+ }
4772
+ }
4773
+ const newZoom = clamp(
4774
+ effectiveScale * newMemo.originZoom,
4775
+ minZoom,
4776
+ maxZoom
4777
+ );
4678
4778
  const realMs = newZoom / newMemo.originZoom;
4679
4779
  const newTranslateX = newMemo.contentPosition[0] * realMs - newMemo.containerPosition[0];
4680
4780
  const newTranslateY = newMemo.contentPosition[1] * realMs - newMemo.containerPosition[1];
@@ -4683,6 +4783,7 @@ var useViewportContainer = ({
4683
4783
  translateX: newTranslateX,
4684
4784
  translateY: newTranslateY
4685
4785
  };
4786
+ newMemo.lastZoom = newZoom;
4686
4787
  updateTransform(true);
4687
4788
  return newMemo;
4688
4789
  },
@@ -4949,7 +5050,10 @@ var Root = forwardRef(
4949
5050
  zoom,
4950
5051
  zoomOptions
4951
5052
  });
4952
- return /* @__PURE__ */ jsx(Primitive.div, { ref, ...props, children: initialState ? /* @__PURE__ */ jsx(PDFStore.Provider, { initialValue: initialState, children }) : loader || "Loading..." });
5053
+ const linkService = useCreatePDFLinkService(
5054
+ initialState?.pdfDocumentProxy ?? null
5055
+ );
5056
+ return /* @__PURE__ */ jsx(Primitive.div, { ref, ...props, children: initialState ? /* @__PURE__ */ jsx(PDFStore.Provider, { initialValue: initialState, children: /* @__PURE__ */ jsx(PDFLinkServiceContext.Provider, { value: linkService, children }) }) : loader || "Loading..." });
4953
5057
  }
4954
5058
  );
4955
5059
  Root.displayName = "Root";
@@ -5363,4 +5467,4 @@ function mergeAdjacentRects(rects) {
5363
5467
  return merged;
5364
5468
  }
5365
5469
 
5366
- export { AnnotationHighlightLayer, AnnotationLayer2 as AnnotationLayer, AnnotationTooltip, CanvasLayer, ColoredHighlightLayer, CurrentPage, CurrentZoom, CustomLayer, HighlightLayer, LinkService, NextPage, Outline, OutlineChildItems, OutlineItem, Page, Pages, PreviousPage, Root, Search, SelectionTooltip, TextLayer2 as TextLayer, Thumbnail, Thumbnails, TotalPages, ZoomIn, ZoomOut, calculateHighlightRects, useAnnotations, usePDFPageNumber, usePdf, usePdfJump, useSearch, useSelectionDimensions };
5470
+ export { AnnotationHighlightLayer, AnnotationLayer2 as AnnotationLayer, AnnotationTooltip, CanvasLayer, ColoredHighlightLayer, CurrentPage, CurrentZoom, CustomLayer, HighlightLayer, LinkService, NextPage, Outline, OutlineChildItems, OutlineItem, PDFLinkServiceContext, Page, Pages, PreviousPage, Root, Search, SelectionTooltip, TextLayer2 as TextLayer, Thumbnail, Thumbnails, TotalPages, ZoomIn, ZoomOut, calculateHighlightRects, useAnnotations, useCreatePDFLinkService, usePDFLinkService, usePDFPageNumber, usePdf, usePdfJump, useSearch, useSelectionDimensions };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anaralabs/lector",
3
- "version": "3.7.2",
3
+ "version": "3.8.0",
4
4
  "description": "Headless PDF viewer for React",
5
5
  "author": "andrewdr (https://github.com/andrewdoro)",
6
6
  "license": "MIT",