@page-speed/lightbox 0.1.5 → 0.1.7

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.
@@ -18069,7 +18069,7 @@ var require_pdf = __commonJS({
18069
18069
  }
18070
18070
  });
18071
18071
 
18072
- // node_modules/.pnpm/@page-speed+pdf-viewer@0.1.3_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js
18072
+ // node_modules/.pnpm/@page-speed+pdf-viewer@0.1.5_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js
18073
18073
  var dist_exports = {};
18074
18074
  __export(dist_exports, {
18075
18075
  PDFCanvas: () => PDFCanvas,
@@ -18686,7 +18686,7 @@ function createProgressiveFetchHandler(onProgress) {
18686
18686
  }
18687
18687
  var DEFAULT_SCALE, CACHE_SIZE, MIN_ZOOM, MAX_ZOOM, ZOOM_STEP, PDFViewer_default, linearizedPDFConfig;
18688
18688
  var init_dist = __esm({
18689
- "node_modules/.pnpm/@page-speed+pdf-viewer@0.1.3_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js"() {
18689
+ "node_modules/.pnpm/@page-speed+pdf-viewer@0.1.5_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js"() {
18690
18690
  "use client";
18691
18691
  DEFAULT_SCALE = 1.5;
18692
18692
  CACHE_SIZE = 50 * 1024 * 1024;
@@ -22559,13 +22559,29 @@ function loadPDFViewer() {
22559
22559
  }
22560
22560
  var LazyPDFViewer = React.lazy(loadPDFViewer);
22561
22561
  var AnyPDFViewer = LazyPDFViewer;
22562
- function PDFRenderer({ item }) {
22562
+ function PDFRenderer({ item, layout }) {
22563
22563
  if (!item.src) return null;
22564
- return /* @__PURE__ */ jsx5("div", { className: "w-full h-full flex items-center justify-center p-4", children: /* @__PURE__ */ jsx5(
22564
+ const config = {
22565
+ showControls: true,
22566
+ enableDownload: true,
22567
+ enablePrint: true,
22568
+ enableFullscreen: true,
22569
+ initialZoom: layout === "inline" ? "page-width" : 1.5
22570
+ };
22571
+ return /* @__PURE__ */ jsx5("div", { className: "w-full h-full flex items-center justify-center", children: /* @__PURE__ */ jsx5(
22565
22572
  Suspense,
22566
22573
  {
22567
22574
  fallback: /* @__PURE__ */ jsx5("div", { className: "flex items-center justify-center text-neutral-500 text-sm", children: "Loading document..." }),
22568
- children: /* @__PURE__ */ jsx5(AnyPDFViewer, { url: item.src })
22575
+ children: /* @__PURE__ */ jsx5(
22576
+ AnyPDFViewer,
22577
+ {
22578
+ url: item.src,
22579
+ config,
22580
+ height: "100%",
22581
+ width: "100%",
22582
+ title: item.title
22583
+ }
22584
+ )
22569
22585
  }
22570
22586
  ) });
22571
22587
  }
@@ -22604,6 +22620,7 @@ function LightboxContent({ item, layout, optixFlowConfig }) {
22604
22620
  }
22605
22621
 
22606
22622
  // src/components/LightboxChrome.tsx
22623
+ import React2 from "react";
22607
22624
  import { Fragment, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
22608
22625
  var DEFAULT_CONTROLS = {
22609
22626
  navigation: true,
@@ -22668,6 +22685,73 @@ function LightboxChrome({
22668
22685
  variant = "floating"
22669
22686
  }) {
22670
22687
  const resolved = mergeControls(controls);
22688
+ const [isFullscreen, setIsFullscreen] = React2.useState(false);
22689
+ const handleFullscreen = React2.useCallback(() => {
22690
+ if (!document.fullscreenElement) {
22691
+ document.documentElement.requestFullscreen().then(() => {
22692
+ setIsFullscreen(true);
22693
+ }).catch((err) => {
22694
+ console.error("Failed to enter fullscreen:", err);
22695
+ });
22696
+ } else {
22697
+ document.exitFullscreen().then(() => {
22698
+ setIsFullscreen(false);
22699
+ }).catch((err) => {
22700
+ console.error("Failed to exit fullscreen:", err);
22701
+ });
22702
+ }
22703
+ }, []);
22704
+ React2.useEffect(() => {
22705
+ const handleFullscreenChange = () => {
22706
+ setIsFullscreen(!!document.fullscreenElement);
22707
+ };
22708
+ document.addEventListener("fullscreenchange", handleFullscreenChange);
22709
+ return () => {
22710
+ document.removeEventListener("fullscreenchange", handleFullscreenChange);
22711
+ };
22712
+ }, []);
22713
+ const handleShare = React2.useCallback(async () => {
22714
+ if (!currentItem) return;
22715
+ const shareData = {
22716
+ title: currentItem.title || "Shared item",
22717
+ text: currentItem.caption || "",
22718
+ url: window.location.href
22719
+ };
22720
+ if (navigator.share) {
22721
+ try {
22722
+ await navigator.share(shareData);
22723
+ } catch (err) {
22724
+ if (err instanceof Error && err.name !== "AbortError") {
22725
+ console.error("Error sharing:", err);
22726
+ }
22727
+ }
22728
+ } else {
22729
+ try {
22730
+ await navigator.clipboard.writeText(window.location.href);
22731
+ console.log("Link copied to clipboard");
22732
+ } catch (err) {
22733
+ console.error("Failed to copy to clipboard:", err);
22734
+ }
22735
+ }
22736
+ }, [currentItem]);
22737
+ const handleDownload = React2.useCallback(async () => {
22738
+ if (!currentItem?.src) return;
22739
+ try {
22740
+ const response = await fetch(currentItem.src);
22741
+ const blob = await response.blob();
22742
+ const url = window.URL.createObjectURL(blob);
22743
+ const link = document.createElement("a");
22744
+ link.href = url;
22745
+ link.download = currentItem.title || "download";
22746
+ document.body.appendChild(link);
22747
+ link.click();
22748
+ document.body.removeChild(link);
22749
+ window.URL.revokeObjectURL(url);
22750
+ } catch (err) {
22751
+ console.error("Download failed:", err);
22752
+ window.open(currentItem.src, "_blank");
22753
+ }
22754
+ }, [currentItem]);
22671
22755
  if (variant === "toolbar") {
22672
22756
  return /* @__PURE__ */ jsxs4("div", { className: cn(
22673
22757
  "flex items-center justify-between",
@@ -22685,6 +22769,9 @@ function LightboxChrome({
22685
22769
  currentItem.caption && /* @__PURE__ */ jsx8("div", { className: "text-xs text-white/70", children: currentItem.caption })
22686
22770
  ] }) }),
22687
22771
  /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
22772
+ resolved.share && "share" in navigator && /* @__PURE__ */ jsx8(IconButton, { onClick: handleShare, ariaLabel: "Share", children: /* @__PURE__ */ jsx8(ShareIcon, {}) }),
22773
+ resolved.fullscreen && /* @__PURE__ */ jsx8(IconButton, { onClick: handleFullscreen, ariaLabel: isFullscreen ? "Exit fullscreen" : "Fullscreen", children: /* @__PURE__ */ jsx8(FullscreenIcon, {}) }),
22774
+ resolved.download && currentItem?.src && /* @__PURE__ */ jsx8(IconButton, { onClick: handleDownload, ariaLabel: "Download", children: /* @__PURE__ */ jsx8(DownloadIcon, {}) }),
22688
22775
  resolved.counter && totalItems > 0 && /* @__PURE__ */ jsxs4("span", { className: "text-xs text-white/70", children: [
22689
22776
  currentIndex + 1,
22690
22777
  " / ",
@@ -22700,9 +22787,9 @@ function LightboxChrome({
22700
22787
  "flex items-center gap-2",
22701
22788
  className
22702
22789
  ), children: [
22703
- resolved.share && /* @__PURE__ */ jsx8(IconButton, { ariaLabel: "Share", children: /* @__PURE__ */ jsx8(ShareIcon, {}) }),
22704
- resolved.fullscreen && /* @__PURE__ */ jsx8(IconButton, { ariaLabel: "Fullscreen", children: /* @__PURE__ */ jsx8(FullscreenIcon, {}) }),
22705
- resolved.download && /* @__PURE__ */ jsx8(IconButton, { ariaLabel: "Download", children: /* @__PURE__ */ jsx8(DownloadIcon, {}) }),
22790
+ resolved.share && "share" in navigator && /* @__PURE__ */ jsx8(IconButton, { onClick: handleShare, ariaLabel: "Share", children: /* @__PURE__ */ jsx8(ShareIcon, {}) }),
22791
+ resolved.fullscreen && /* @__PURE__ */ jsx8(IconButton, { onClick: handleFullscreen, ariaLabel: isFullscreen ? "Exit fullscreen" : "Fullscreen", children: /* @__PURE__ */ jsx8(FullscreenIcon, {}) }),
22792
+ resolved.download && currentItem?.src && /* @__PURE__ */ jsx8(IconButton, { onClick: handleDownload, ariaLabel: "Download", children: /* @__PURE__ */ jsx8(DownloadIcon, {}) }),
22706
22793
  resolved.closeButton && /* @__PURE__ */ jsx8(IconButton, { onClick: onClose, ariaLabel: "Close lightbox", children: /* @__PURE__ */ jsx8(CloseIcon, {}) })
22707
22794
  ] }),
22708
22795
  resolved.navigation && /* @__PURE__ */ jsxs4("div", { className: "fixed bottom-6 right-6 z-50 flex items-center gap-3", children: [
package/dist/index.cjs CHANGED
@@ -18065,7 +18065,7 @@ var require_pdf = __commonJS({
18065
18065
  }
18066
18066
  });
18067
18067
 
18068
- // node_modules/.pnpm/@page-speed+pdf-viewer@0.1.3_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js
18068
+ // node_modules/.pnpm/@page-speed+pdf-viewer@0.1.5_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js
18069
18069
  var dist_exports = {};
18070
18070
  __export(dist_exports, {
18071
18071
  PDFCanvas: () => PDFCanvas,
@@ -18670,7 +18670,7 @@ function createProgressiveFetchHandler(onProgress) {
18670
18670
  }
18671
18671
  var import_react8, import_react9, import_react10, import_react11, import_react12, import_react13, import_react14, import_jsx_runtime5, import_jsx_runtime6, import_react15, import_jsx_runtime7, import_jsx_runtime8, DEFAULT_SCALE, CACHE_SIZE, MIN_ZOOM, MAX_ZOOM, ZOOM_STEP, PDFViewer_default, linearizedPDFConfig;
18672
18672
  var init_dist = __esm({
18673
- "node_modules/.pnpm/@page-speed+pdf-viewer@0.1.3_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js"() {
18673
+ "node_modules/.pnpm/@page-speed+pdf-viewer@0.1.5_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js"() {
18674
18674
  "use client";
18675
18675
  import_react8 = require("react");
18676
18676
  import_react9 = require("react");
@@ -18741,7 +18741,7 @@ __export(index_exports, {
18741
18741
  module.exports = __toCommonJS(index_exports);
18742
18742
 
18743
18743
  // src/components/Lightbox.tsx
18744
- var import_react17 = require("react");
18744
+ var import_react18 = require("react");
18745
18745
  var import_react_dom = require("react-dom");
18746
18746
 
18747
18747
  // src/hooks/useGalleryState.ts
@@ -22573,13 +22573,29 @@ function loadPDFViewer() {
22573
22573
  }
22574
22574
  var LazyPDFViewer = import_react16.default.lazy(loadPDFViewer);
22575
22575
  var AnyPDFViewer = LazyPDFViewer;
22576
- function PDFRenderer({ item }) {
22576
+ function PDFRenderer({ item, layout }) {
22577
22577
  if (!item.src) return null;
22578
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "w-full h-full flex items-center justify-center p-4", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
22578
+ const config = {
22579
+ showControls: true,
22580
+ enableDownload: true,
22581
+ enablePrint: true,
22582
+ enableFullscreen: true,
22583
+ initialZoom: layout === "inline" ? "page-width" : 1.5
22584
+ };
22585
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "w-full h-full flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
22579
22586
  import_react16.Suspense,
22580
22587
  {
22581
22588
  fallback: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex items-center justify-center text-neutral-500 text-sm", children: "Loading document..." }),
22582
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AnyPDFViewer, { url: item.src })
22589
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
22590
+ AnyPDFViewer,
22591
+ {
22592
+ url: item.src,
22593
+ config,
22594
+ height: "100%",
22595
+ width: "100%",
22596
+ title: item.title
22597
+ }
22598
+ )
22583
22599
  }
22584
22600
  ) });
22585
22601
  }
@@ -22618,6 +22634,7 @@ function LightboxContent({ item, layout, optixFlowConfig }) {
22618
22634
  }
22619
22635
 
22620
22636
  // src/components/LightboxChrome.tsx
22637
+ var import_react17 = __toESM(require("react"));
22621
22638
  var import_jsx_runtime12 = require("react/jsx-runtime");
22622
22639
  var DEFAULT_CONTROLS = {
22623
22640
  navigation: true,
@@ -22682,6 +22699,73 @@ function LightboxChrome({
22682
22699
  variant = "floating"
22683
22700
  }) {
22684
22701
  const resolved = mergeControls(controls);
22702
+ const [isFullscreen, setIsFullscreen] = import_react17.default.useState(false);
22703
+ const handleFullscreen = import_react17.default.useCallback(() => {
22704
+ if (!document.fullscreenElement) {
22705
+ document.documentElement.requestFullscreen().then(() => {
22706
+ setIsFullscreen(true);
22707
+ }).catch((err) => {
22708
+ console.error("Failed to enter fullscreen:", err);
22709
+ });
22710
+ } else {
22711
+ document.exitFullscreen().then(() => {
22712
+ setIsFullscreen(false);
22713
+ }).catch((err) => {
22714
+ console.error("Failed to exit fullscreen:", err);
22715
+ });
22716
+ }
22717
+ }, []);
22718
+ import_react17.default.useEffect(() => {
22719
+ const handleFullscreenChange = () => {
22720
+ setIsFullscreen(!!document.fullscreenElement);
22721
+ };
22722
+ document.addEventListener("fullscreenchange", handleFullscreenChange);
22723
+ return () => {
22724
+ document.removeEventListener("fullscreenchange", handleFullscreenChange);
22725
+ };
22726
+ }, []);
22727
+ const handleShare = import_react17.default.useCallback(async () => {
22728
+ if (!currentItem) return;
22729
+ const shareData = {
22730
+ title: currentItem.title || "Shared item",
22731
+ text: currentItem.caption || "",
22732
+ url: window.location.href
22733
+ };
22734
+ if (navigator.share) {
22735
+ try {
22736
+ await navigator.share(shareData);
22737
+ } catch (err) {
22738
+ if (err instanceof Error && err.name !== "AbortError") {
22739
+ console.error("Error sharing:", err);
22740
+ }
22741
+ }
22742
+ } else {
22743
+ try {
22744
+ await navigator.clipboard.writeText(window.location.href);
22745
+ console.log("Link copied to clipboard");
22746
+ } catch (err) {
22747
+ console.error("Failed to copy to clipboard:", err);
22748
+ }
22749
+ }
22750
+ }, [currentItem]);
22751
+ const handleDownload = import_react17.default.useCallback(async () => {
22752
+ if (!currentItem?.src) return;
22753
+ try {
22754
+ const response = await fetch(currentItem.src);
22755
+ const blob = await response.blob();
22756
+ const url = window.URL.createObjectURL(blob);
22757
+ const link = document.createElement("a");
22758
+ link.href = url;
22759
+ link.download = currentItem.title || "download";
22760
+ document.body.appendChild(link);
22761
+ link.click();
22762
+ document.body.removeChild(link);
22763
+ window.URL.revokeObjectURL(url);
22764
+ } catch (err) {
22765
+ console.error("Download failed:", err);
22766
+ window.open(currentItem.src, "_blank");
22767
+ }
22768
+ }, [currentItem]);
22685
22769
  if (variant === "toolbar") {
22686
22770
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: cn(
22687
22771
  "flex items-center justify-between",
@@ -22699,6 +22783,9 @@ function LightboxChrome({
22699
22783
  currentItem.caption && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "text-xs text-white/70", children: currentItem.caption })
22700
22784
  ] }) }),
22701
22785
  /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-2", children: [
22786
+ resolved.share && "share" in navigator && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconButton, { onClick: handleShare, ariaLabel: "Share", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ShareIcon, {}) }),
22787
+ resolved.fullscreen && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconButton, { onClick: handleFullscreen, ariaLabel: isFullscreen ? "Exit fullscreen" : "Fullscreen", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(FullscreenIcon, {}) }),
22788
+ resolved.download && currentItem?.src && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconButton, { onClick: handleDownload, ariaLabel: "Download", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DownloadIcon, {}) }),
22702
22789
  resolved.counter && totalItems > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "text-xs text-white/70", children: [
22703
22790
  currentIndex + 1,
22704
22791
  " / ",
@@ -22714,9 +22801,9 @@ function LightboxChrome({
22714
22801
  "flex items-center gap-2",
22715
22802
  className
22716
22803
  ), children: [
22717
- resolved.share && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconButton, { ariaLabel: "Share", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ShareIcon, {}) }),
22718
- resolved.fullscreen && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconButton, { ariaLabel: "Fullscreen", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(FullscreenIcon, {}) }),
22719
- resolved.download && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconButton, { ariaLabel: "Download", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DownloadIcon, {}) }),
22804
+ resolved.share && "share" in navigator && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconButton, { onClick: handleShare, ariaLabel: "Share", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ShareIcon, {}) }),
22805
+ resolved.fullscreen && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconButton, { onClick: handleFullscreen, ariaLabel: isFullscreen ? "Exit fullscreen" : "Fullscreen", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(FullscreenIcon, {}) }),
22806
+ resolved.download && currentItem?.src && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconButton, { onClick: handleDownload, ariaLabel: "Download", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DownloadIcon, {}) }),
22720
22807
  resolved.closeButton && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconButton, { onClick: onClose, ariaLabel: "Close lightbox", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CloseIcon, {}) })
22721
22808
  ] }),
22722
22809
  resolved.navigation && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "fixed bottom-6 right-6 z-50 flex items-center gap-3", children: [
@@ -22961,18 +23048,18 @@ function Lightbox(props) {
22961
23048
  onSelect: props.onSelect
22962
23049
  });
22963
23050
  const { breakpoint } = useResponsiveness();
22964
- const layout = (0, import_react17.useMemo)(() => {
23051
+ const layout = (0, import_react18.useMemo)(() => {
22965
23052
  if (props.layout) return props.layout;
22966
23053
  if (breakpoint === "mobile") return "fullscreen";
22967
23054
  if (breakpoint === "tablet") return "vertical-split";
22968
23055
  return "horizontal";
22969
23056
  }, [props.layout, breakpoint]);
22970
- const didCloseRef = (0, import_react17.useRef)(false);
22971
- const [isMounted, setIsMounted] = (0, import_react17.useState)(false);
22972
- (0, import_react17.useEffect)(() => {
23057
+ const didCloseRef = (0, import_react18.useRef)(false);
23058
+ const [isMounted, setIsMounted] = (0, import_react18.useState)(false);
23059
+ (0, import_react18.useEffect)(() => {
22973
23060
  setIsMounted(true);
22974
23061
  }, []);
22975
- (0, import_react17.useEffect)(() => {
23062
+ (0, import_react18.useEffect)(() => {
22976
23063
  props.onOpen?.();
22977
23064
  if (props.disableScroll === false) {
22978
23065
  return;
@@ -22986,17 +23073,17 @@ function Lightbox(props) {
22986
23073
  document.body.style.overflow = previousOverflow;
22987
23074
  };
22988
23075
  }, [props.disableScroll, props.onOpen]);
22989
- const handleClose = (0, import_react17.useCallback)(() => {
23076
+ const handleClose = (0, import_react18.useCallback)(() => {
22990
23077
  if (didCloseRef.current) return;
22991
23078
  didCloseRef.current = true;
22992
23079
  props.onClose?.();
22993
23080
  }, [props.onClose]);
22994
- const handleNext = (0, import_react17.useCallback)(() => {
23081
+ const handleNext = (0, import_react18.useCallback)(() => {
22995
23082
  if (!gallery.canNext) return;
22996
23083
  gallery.next();
22997
23084
  props.onNext?.();
22998
23085
  }, [gallery, props.onNext]);
22999
- const handlePrev = (0, import_react17.useCallback)(() => {
23086
+ const handlePrev = (0, import_react18.useCallback)(() => {
23000
23087
  if (!gallery.canPrev) return;
23001
23088
  gallery.prev();
23002
23089
  props.onPrev?.();
@@ -23088,28 +23175,28 @@ function Lightbox(props) {
23088
23175
  }
23089
23176
 
23090
23177
  // src/hooks/useLightboxState.ts
23091
- var import_react18 = require("react");
23178
+ var import_react19 = require("react");
23092
23179
  function useLightboxState({
23093
23180
  onOpen,
23094
23181
  onClose,
23095
23182
  disableScroll = true
23096
23183
  }) {
23097
- const [isOpen, setIsOpen] = (0, import_react18.useState)(false);
23098
- const open = (0, import_react18.useCallback)(() => {
23184
+ const [isOpen, setIsOpen] = (0, import_react19.useState)(false);
23185
+ const open = (0, import_react19.useCallback)(() => {
23099
23186
  setIsOpen(true);
23100
23187
  onOpen?.();
23101
23188
  if (disableScroll) {
23102
23189
  document.body.style.overflow = "hidden";
23103
23190
  }
23104
23191
  }, [onOpen, disableScroll]);
23105
- const close = (0, import_react18.useCallback)(() => {
23192
+ const close = (0, import_react19.useCallback)(() => {
23106
23193
  setIsOpen(false);
23107
23194
  onClose?.();
23108
23195
  if (disableScroll) {
23109
23196
  document.body.style.overflow = "";
23110
23197
  }
23111
23198
  }, [onClose, disableScroll]);
23112
- (0, import_react18.useEffect)(() => {
23199
+ (0, import_react19.useEffect)(() => {
23113
23200
  return () => {
23114
23201
  if (disableScroll) {
23115
23202
  document.body.style.overflow = "";
package/dist/index.js CHANGED
@@ -18069,7 +18069,7 @@ var require_pdf = __commonJS({
18069
18069
  }
18070
18070
  });
18071
18071
 
18072
- // node_modules/.pnpm/@page-speed+pdf-viewer@0.1.3_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js
18072
+ // node_modules/.pnpm/@page-speed+pdf-viewer@0.1.5_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js
18073
18073
  var dist_exports = {};
18074
18074
  __export(dist_exports, {
18075
18075
  PDFCanvas: () => PDFCanvas,
@@ -18686,7 +18686,7 @@ function createProgressiveFetchHandler(onProgress) {
18686
18686
  }
18687
18687
  var DEFAULT_SCALE, CACHE_SIZE, MIN_ZOOM, MAX_ZOOM, ZOOM_STEP, PDFViewer_default, linearizedPDFConfig;
18688
18688
  var init_dist = __esm({
18689
- "node_modules/.pnpm/@page-speed+pdf-viewer@0.1.3_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js"() {
18689
+ "node_modules/.pnpm/@page-speed+pdf-viewer@0.1.5_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js"() {
18690
18690
  "use client";
18691
18691
  DEFAULT_SCALE = 1.5;
18692
18692
  CACHE_SIZE = 50 * 1024 * 1024;
@@ -22559,13 +22559,29 @@ function loadPDFViewer() {
22559
22559
  }
22560
22560
  var LazyPDFViewer = React.lazy(loadPDFViewer);
22561
22561
  var AnyPDFViewer = LazyPDFViewer;
22562
- function PDFRenderer({ item }) {
22562
+ function PDFRenderer({ item, layout }) {
22563
22563
  if (!item.src) return null;
22564
- return /* @__PURE__ */ jsx5("div", { className: "w-full h-full flex items-center justify-center p-4", children: /* @__PURE__ */ jsx5(
22564
+ const config = {
22565
+ showControls: true,
22566
+ enableDownload: true,
22567
+ enablePrint: true,
22568
+ enableFullscreen: true,
22569
+ initialZoom: layout === "inline" ? "page-width" : 1.5
22570
+ };
22571
+ return /* @__PURE__ */ jsx5("div", { className: "w-full h-full flex items-center justify-center", children: /* @__PURE__ */ jsx5(
22565
22572
  Suspense,
22566
22573
  {
22567
22574
  fallback: /* @__PURE__ */ jsx5("div", { className: "flex items-center justify-center text-neutral-500 text-sm", children: "Loading document..." }),
22568
- children: /* @__PURE__ */ jsx5(AnyPDFViewer, { url: item.src })
22575
+ children: /* @__PURE__ */ jsx5(
22576
+ AnyPDFViewer,
22577
+ {
22578
+ url: item.src,
22579
+ config,
22580
+ height: "100%",
22581
+ width: "100%",
22582
+ title: item.title
22583
+ }
22584
+ )
22569
22585
  }
22570
22586
  ) });
22571
22587
  }
@@ -22604,6 +22620,7 @@ function LightboxContent({ item, layout, optixFlowConfig }) {
22604
22620
  }
22605
22621
 
22606
22622
  // src/components/LightboxChrome.tsx
22623
+ import React2 from "react";
22607
22624
  import { Fragment, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
22608
22625
  var DEFAULT_CONTROLS = {
22609
22626
  navigation: true,
@@ -22668,6 +22685,73 @@ function LightboxChrome({
22668
22685
  variant = "floating"
22669
22686
  }) {
22670
22687
  const resolved = mergeControls(controls);
22688
+ const [isFullscreen, setIsFullscreen] = React2.useState(false);
22689
+ const handleFullscreen = React2.useCallback(() => {
22690
+ if (!document.fullscreenElement) {
22691
+ document.documentElement.requestFullscreen().then(() => {
22692
+ setIsFullscreen(true);
22693
+ }).catch((err) => {
22694
+ console.error("Failed to enter fullscreen:", err);
22695
+ });
22696
+ } else {
22697
+ document.exitFullscreen().then(() => {
22698
+ setIsFullscreen(false);
22699
+ }).catch((err) => {
22700
+ console.error("Failed to exit fullscreen:", err);
22701
+ });
22702
+ }
22703
+ }, []);
22704
+ React2.useEffect(() => {
22705
+ const handleFullscreenChange = () => {
22706
+ setIsFullscreen(!!document.fullscreenElement);
22707
+ };
22708
+ document.addEventListener("fullscreenchange", handleFullscreenChange);
22709
+ return () => {
22710
+ document.removeEventListener("fullscreenchange", handleFullscreenChange);
22711
+ };
22712
+ }, []);
22713
+ const handleShare = React2.useCallback(async () => {
22714
+ if (!currentItem) return;
22715
+ const shareData = {
22716
+ title: currentItem.title || "Shared item",
22717
+ text: currentItem.caption || "",
22718
+ url: window.location.href
22719
+ };
22720
+ if (navigator.share) {
22721
+ try {
22722
+ await navigator.share(shareData);
22723
+ } catch (err) {
22724
+ if (err instanceof Error && err.name !== "AbortError") {
22725
+ console.error("Error sharing:", err);
22726
+ }
22727
+ }
22728
+ } else {
22729
+ try {
22730
+ await navigator.clipboard.writeText(window.location.href);
22731
+ console.log("Link copied to clipboard");
22732
+ } catch (err) {
22733
+ console.error("Failed to copy to clipboard:", err);
22734
+ }
22735
+ }
22736
+ }, [currentItem]);
22737
+ const handleDownload = React2.useCallback(async () => {
22738
+ if (!currentItem?.src) return;
22739
+ try {
22740
+ const response = await fetch(currentItem.src);
22741
+ const blob = await response.blob();
22742
+ const url = window.URL.createObjectURL(blob);
22743
+ const link = document.createElement("a");
22744
+ link.href = url;
22745
+ link.download = currentItem.title || "download";
22746
+ document.body.appendChild(link);
22747
+ link.click();
22748
+ document.body.removeChild(link);
22749
+ window.URL.revokeObjectURL(url);
22750
+ } catch (err) {
22751
+ console.error("Download failed:", err);
22752
+ window.open(currentItem.src, "_blank");
22753
+ }
22754
+ }, [currentItem]);
22671
22755
  if (variant === "toolbar") {
22672
22756
  return /* @__PURE__ */ jsxs4("div", { className: cn(
22673
22757
  "flex items-center justify-between",
@@ -22685,6 +22769,9 @@ function LightboxChrome({
22685
22769
  currentItem.caption && /* @__PURE__ */ jsx8("div", { className: "text-xs text-white/70", children: currentItem.caption })
22686
22770
  ] }) }),
22687
22771
  /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
22772
+ resolved.share && "share" in navigator && /* @__PURE__ */ jsx8(IconButton, { onClick: handleShare, ariaLabel: "Share", children: /* @__PURE__ */ jsx8(ShareIcon, {}) }),
22773
+ resolved.fullscreen && /* @__PURE__ */ jsx8(IconButton, { onClick: handleFullscreen, ariaLabel: isFullscreen ? "Exit fullscreen" : "Fullscreen", children: /* @__PURE__ */ jsx8(FullscreenIcon, {}) }),
22774
+ resolved.download && currentItem?.src && /* @__PURE__ */ jsx8(IconButton, { onClick: handleDownload, ariaLabel: "Download", children: /* @__PURE__ */ jsx8(DownloadIcon, {}) }),
22688
22775
  resolved.counter && totalItems > 0 && /* @__PURE__ */ jsxs4("span", { className: "text-xs text-white/70", children: [
22689
22776
  currentIndex + 1,
22690
22777
  " / ",
@@ -22700,9 +22787,9 @@ function LightboxChrome({
22700
22787
  "flex items-center gap-2",
22701
22788
  className
22702
22789
  ), children: [
22703
- resolved.share && /* @__PURE__ */ jsx8(IconButton, { ariaLabel: "Share", children: /* @__PURE__ */ jsx8(ShareIcon, {}) }),
22704
- resolved.fullscreen && /* @__PURE__ */ jsx8(IconButton, { ariaLabel: "Fullscreen", children: /* @__PURE__ */ jsx8(FullscreenIcon, {}) }),
22705
- resolved.download && /* @__PURE__ */ jsx8(IconButton, { ariaLabel: "Download", children: /* @__PURE__ */ jsx8(DownloadIcon, {}) }),
22790
+ resolved.share && "share" in navigator && /* @__PURE__ */ jsx8(IconButton, { onClick: handleShare, ariaLabel: "Share", children: /* @__PURE__ */ jsx8(ShareIcon, {}) }),
22791
+ resolved.fullscreen && /* @__PURE__ */ jsx8(IconButton, { onClick: handleFullscreen, ariaLabel: isFullscreen ? "Exit fullscreen" : "Fullscreen", children: /* @__PURE__ */ jsx8(FullscreenIcon, {}) }),
22792
+ resolved.download && currentItem?.src && /* @__PURE__ */ jsx8(IconButton, { onClick: handleDownload, ariaLabel: "Download", children: /* @__PURE__ */ jsx8(DownloadIcon, {}) }),
22706
22793
  resolved.closeButton && /* @__PURE__ */ jsx8(IconButton, { onClick: onClose, ariaLabel: "Close lightbox", children: /* @__PURE__ */ jsx8(CloseIcon, {}) })
22707
22794
  ] }),
22708
22795
  resolved.navigation && /* @__PURE__ */ jsxs4("div", { className: "fixed bottom-6 right-6 z-50 flex items-center gap-3", children: [
@@ -7,5 +7,5 @@ interface PDFRendererProps {
7
7
  * Thin wrapper around @page-speed/pdf-viewer, loaded lazily so that the
8
8
  * heavy PDF runtime is only fetched when a PDF item is actually viewed.
9
9
  */
10
- export declare function PDFRenderer({ item }: PDFRendererProps): import("react/jsx-runtime").JSX.Element | null;
10
+ export declare function PDFRenderer({ item, layout }: PDFRendererProps): import("react/jsx-runtime").JSX.Element | null;
11
11
  export {};
@@ -18069,7 +18069,7 @@ var require_pdf = __commonJS({
18069
18069
  }
18070
18070
  });
18071
18071
 
18072
- // node_modules/.pnpm/@page-speed+pdf-viewer@0.1.3_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js
18072
+ // node_modules/.pnpm/@page-speed+pdf-viewer@0.1.5_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js
18073
18073
  var dist_exports = {};
18074
18074
  __export(dist_exports, {
18075
18075
  PDFCanvas: () => PDFCanvas,
@@ -18686,7 +18686,7 @@ function createProgressiveFetchHandler(onProgress) {
18686
18686
  }
18687
18687
  var DEFAULT_SCALE, CACHE_SIZE, MIN_ZOOM, MAX_ZOOM, ZOOM_STEP, PDFViewer_default, linearizedPDFConfig;
18688
18688
  var init_dist = __esm({
18689
- "node_modules/.pnpm/@page-speed+pdf-viewer@0.1.3_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js"() {
18689
+ "node_modules/.pnpm/@page-speed+pdf-viewer@0.1.5_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js"() {
18690
18690
  "use client";
18691
18691
  DEFAULT_SCALE = 1.5;
18692
18692
  CACHE_SIZE = 50 * 1024 * 1024;
@@ -19415,13 +19415,29 @@ function loadPDFViewer() {
19415
19415
  }
19416
19416
  var LazyPDFViewer = React.lazy(loadPDFViewer);
19417
19417
  var AnyPDFViewer = LazyPDFViewer;
19418
- function PDFRenderer({ item }) {
19418
+ function PDFRenderer({ item, layout }) {
19419
19419
  if (!item.src) return null;
19420
- return /* @__PURE__ */ jsx5("div", { className: "w-full h-full flex items-center justify-center p-4", children: /* @__PURE__ */ jsx5(
19420
+ const config = {
19421
+ showControls: true,
19422
+ enableDownload: true,
19423
+ enablePrint: true,
19424
+ enableFullscreen: true,
19425
+ initialZoom: layout === "inline" ? "page-width" : 1.5
19426
+ };
19427
+ return /* @__PURE__ */ jsx5("div", { className: "w-full h-full flex items-center justify-center", children: /* @__PURE__ */ jsx5(
19421
19428
  Suspense,
19422
19429
  {
19423
19430
  fallback: /* @__PURE__ */ jsx5("div", { className: "flex items-center justify-center text-neutral-500 text-sm", children: "Loading document..." }),
19424
- children: /* @__PURE__ */ jsx5(AnyPDFViewer, { url: item.src })
19431
+ children: /* @__PURE__ */ jsx5(
19432
+ AnyPDFViewer,
19433
+ {
19434
+ url: item.src,
19435
+ config,
19436
+ height: "100%",
19437
+ width: "100%",
19438
+ title: item.title
19439
+ }
19440
+ )
19425
19441
  }
19426
19442
  ) });
19427
19443
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@page-speed/lightbox",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "High-performance, feature-rich lightbox for OpenSite platform",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -80,7 +80,7 @@
80
80
  },
81
81
  "dependencies": {
82
82
  "@page-speed/img": "^0.4.3",
83
- "@page-speed/pdf-viewer": "0.1.3",
83
+ "@page-speed/pdf-viewer": "0.1.5",
84
84
  "clsx": "^2.1.1",
85
85
  "tailwind-merge": "^3.4.0"
86
86
  }