@page-speed/lightbox 0.1.7 → 0.1.8

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.5_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.6_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,
@@ -18079,11 +18079,14 @@ __export(dist_exports, {
18079
18079
  calculateScaleForPageFit: () => calculateScaleForPageFit,
18080
18080
  createProgressiveFetchHandler: () => createProgressiveFetchHandler,
18081
18081
  downloadPDF: () => downloadPDF,
18082
+ extractPDFFilename: () => extractPDFFilename,
18082
18083
  extractPageText: () => extractPageText,
18083
18084
  formatFileSize: () => formatFileSize,
18084
18085
  getOptimalRangeHeader: () => getOptimalRangeHeader,
18086
+ injectPDFViewerStyles: () => injectPDFViewerStyles,
18085
18087
  isLinearizedPDF: () => isLinearizedPDF,
18086
18088
  linearizedPDFConfig: () => linearizedPDFConfig,
18089
+ pdfViewerStyles: () => pdfViewerStyles,
18087
18090
  usePDFDocument: () => usePDFDocument,
18088
18091
  usePageRenderer: () => usePageRenderer,
18089
18092
  usePageState: () => usePageState,
@@ -18336,6 +18339,20 @@ function useSearch(pdfDoc) {
18336
18339
  prevResult
18337
18340
  };
18338
18341
  }
18342
+ function injectPDFViewerStyles() {
18343
+ if (typeof document === "undefined") return;
18344
+ if (stylesInjected) return;
18345
+ const styleId = "page-speed-pdf-viewer-styles";
18346
+ if (document.getElementById(styleId)) {
18347
+ stylesInjected = true;
18348
+ return;
18349
+ }
18350
+ const styleElement = document.createElement("style");
18351
+ styleElement.id = styleId;
18352
+ styleElement.textContent = PDF_VIEWER_STYLES;
18353
+ document.head.appendChild(styleElement);
18354
+ stylesInjected = true;
18355
+ }
18339
18356
  function PDFCanvas({
18340
18357
  pdfDoc,
18341
18358
  pageNumber,
@@ -18359,7 +18376,68 @@ function PDFCanvas({
18359
18376
  render();
18360
18377
  }
18361
18378
  }, [pdfDoc, pageNumber, scale, onRender]);
18362
- return /* @__PURE__ */ jsx4("div", { ref: containerRef, className: PDFViewer_default.canvas });
18379
+ return /* @__PURE__ */ jsx4("div", { ref: containerRef, className: pdfViewerStyles.canvas });
18380
+ }
18381
+ async function isLinearizedPDF(url) {
18382
+ try {
18383
+ const response = await fetch(url, { headers: { Range: "bytes=0-1024" } });
18384
+ const buffer = await response.arrayBuffer();
18385
+ const view = new Uint8Array(buffer);
18386
+ const text = new TextDecoder().decode(view);
18387
+ return text.includes("Linearized");
18388
+ } catch {
18389
+ return false;
18390
+ }
18391
+ }
18392
+ function extractPDFFilename(url, fallbackName) {
18393
+ try {
18394
+ const urlObj = new URL(url, window.location.origin);
18395
+ const pathname = urlObj.pathname;
18396
+ const segments = pathname.split("/").filter(Boolean);
18397
+ const lastSegment = segments[segments.length - 1] || "";
18398
+ if (lastSegment && lastSegment.includes(".")) {
18399
+ if (lastSegment.toLowerCase().endsWith(".pdf")) {
18400
+ return lastSegment;
18401
+ }
18402
+ const nameWithoutExt = lastSegment.substring(0, lastSegment.lastIndexOf("."));
18403
+ return `${nameWithoutExt}.pdf`;
18404
+ }
18405
+ if (lastSegment) {
18406
+ return `${lastSegment}.pdf`;
18407
+ }
18408
+ } catch {
18409
+ }
18410
+ const name = fallbackName || "document";
18411
+ return name.toLowerCase().endsWith(".pdf") ? name : `${name}.pdf`;
18412
+ }
18413
+ function downloadPDF(url, filename) {
18414
+ const link = document.createElement("a");
18415
+ link.href = url;
18416
+ link.download = filename || extractPDFFilename(url);
18417
+ document.body.appendChild(link);
18418
+ link.click();
18419
+ document.body.removeChild(link);
18420
+ }
18421
+ function calculateScaleForPageFit(pageWidth, pageHeight, containerWidth, containerHeight) {
18422
+ const widthRatio = containerWidth / pageWidth;
18423
+ const heightRatio = containerHeight / pageHeight;
18424
+ return Math.min(widthRatio, heightRatio);
18425
+ }
18426
+ function formatFileSize(bytes) {
18427
+ if (bytes === 0) return "0 Bytes";
18428
+ const k = 1024;
18429
+ const sizes = ["Bytes", "KB", "MB", "GB"];
18430
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
18431
+ return Math.round(bytes / Math.pow(k, i) * 100) / 100 + " " + sizes[i];
18432
+ }
18433
+ async function extractPageText(pdfDoc, pageNumber) {
18434
+ try {
18435
+ const page = await pdfDoc.getPage(pageNumber);
18436
+ const textContent = await page.getTextContent();
18437
+ return textContent.items.filter((item) => "str" in item).map((item) => item.str).join(" ");
18438
+ } catch {
18439
+ return "";
18440
+ }
18363
18441
  }
18364
18442
  function PDFControls({
18365
18443
  pageState,
@@ -18372,7 +18450,7 @@ function PDFControls({
18372
18450
  url
18373
18451
  }) {
18374
18452
  if (!pdfDocument) return null;
18375
- return /* @__PURE__ */ jsxs("div", { className: PDFViewer_default.controls, children: [
18453
+ return /* @__PURE__ */ jsxs("div", { className: pdfViewerStyles.controls, children: [
18376
18454
  /* @__PURE__ */ jsx22(
18377
18455
  "button",
18378
18456
  {
@@ -18390,10 +18468,10 @@ function PDFControls({
18390
18468
  max: pdfDocument.numPages,
18391
18469
  value: pageState.currentPage,
18392
18470
  onChange: (e) => pageState.goToPage(parseInt(e.target.value, 10) || 1),
18393
- className: PDFViewer_default.pageInput
18471
+ className: pdfViewerStyles.pageInput
18394
18472
  }
18395
18473
  ),
18396
- /* @__PURE__ */ jsxs("span", { className: PDFViewer_default.pageTotal, children: [
18474
+ /* @__PURE__ */ jsxs("span", { className: pdfViewerStyles.pageTotal, children: [
18397
18475
  "of ",
18398
18476
  pdfDocument.numPages
18399
18477
  ] }),
@@ -18415,7 +18493,7 @@ function PDFControls({
18415
18493
  children: "-"
18416
18494
  }
18417
18495
  ),
18418
- /* @__PURE__ */ jsxs("span", { className: PDFViewer_default.zoomLevel, children: [
18496
+ /* @__PURE__ */ jsxs("span", { className: pdfViewerStyles.zoomLevel, children: [
18419
18497
  Math.round(zoom.zoomLevel * 100),
18420
18498
  "%"
18421
18499
  ] }),
@@ -18435,14 +18513,22 @@ function PDFControls({
18435
18513
  placeholder: "Search...",
18436
18514
  value: search.query,
18437
18515
  onChange: (e) => search.search(e.target.value),
18438
- className: PDFViewer_default.searchInput
18516
+ className: pdfViewerStyles.searchInput
18439
18517
  }
18440
18518
  ),
18441
- search.results.length > 0 && /* @__PURE__ */ jsxs("span", { className: PDFViewer_default.searchResults, children: [
18519
+ search.results.length > 0 && /* @__PURE__ */ jsxs("span", { className: pdfViewerStyles.searchResults, children: [
18442
18520
  search.results.length,
18443
18521
  " results"
18444
18522
  ] }),
18445
- enableDownload && /* @__PURE__ */ jsx22("a", { href: url, download: true, className: PDFViewer_default.button, title: "Download", children: "Download" }),
18523
+ enableDownload && /* @__PURE__ */ jsx22(
18524
+ "button",
18525
+ {
18526
+ onClick: () => downloadPDF(url),
18527
+ className: pdfViewerStyles.button,
18528
+ title: "Download",
18529
+ children: "Download"
18530
+ }
18531
+ ),
18446
18532
  enablePrint && /* @__PURE__ */ jsx22("button", { onClick: () => window.print(), title: "Print", children: "Print" }),
18447
18533
  enableFullscreen && typeof document !== "undefined" && /* @__PURE__ */ jsx22(
18448
18534
  "button",
@@ -18496,10 +18582,10 @@ function PDFThumbnails({
18496
18582
  };
18497
18583
  generateThumbnails();
18498
18584
  }, [pdfDoc, numPages]);
18499
- return /* @__PURE__ */ jsx32("div", { className: PDFViewer_default.thumbnails, children: thumbnails.map((thumb, idx) => /* @__PURE__ */ jsxs2(
18585
+ return /* @__PURE__ */ jsx32("div", { className: pdfViewerStyles.thumbnails, children: thumbnails.map((thumb, idx) => /* @__PURE__ */ jsxs2(
18500
18586
  "div",
18501
18587
  {
18502
- className: `${PDFViewer_default.thumbnail} ${idx + 1 === currentPage ? PDFViewer_default.active : ""}`,
18588
+ className: `${pdfViewerStyles.thumbnail} ${idx + 1 === currentPage ? pdfViewerStyles.active : ""}`,
18503
18589
  onClick: () => onSelectPage(idx + 1),
18504
18590
  children: [
18505
18591
  /* @__PURE__ */ jsx32(
@@ -18517,7 +18603,7 @@ function PDFThumbnails({
18517
18603
  }
18518
18604
  }
18519
18605
  ),
18520
- /* @__PURE__ */ jsx32("span", { className: PDFViewer_default.pageNumber, children: idx + 1 })
18606
+ /* @__PURE__ */ jsx32("span", { className: pdfViewerStyles.pageNumber, children: idx + 1 })
18521
18607
  ]
18522
18608
  },
18523
18609
  idx
@@ -18547,6 +18633,9 @@ function PDFViewer({
18547
18633
  initialZoom = "auto",
18548
18634
  withCredentials = false
18549
18635
  } = config;
18636
+ useEffect42(() => {
18637
+ injectPDFViewerStyles();
18638
+ }, []);
18550
18639
  const { document: document2, pdfDoc, loading, error } = usePDFDocument(url, onError, withCredentials);
18551
18640
  const pageState = usePageState({
18552
18641
  totalPages: document2?.numPages || 0,
@@ -18569,18 +18658,18 @@ function PDFViewer({
18569
18658
  }
18570
18659
  }, [search.results, onSearchResults]);
18571
18660
  if (error) {
18572
- return /* @__PURE__ */ jsx42("div", { className: PDFViewer_default.error, style: { height, width }, children: /* @__PURE__ */ jsxs3("p", { children: [
18661
+ return /* @__PURE__ */ jsx42("div", { className: pdfViewerStyles.error, style: { height, width }, children: /* @__PURE__ */ jsxs3("p", { children: [
18573
18662
  "Failed to load PDF: ",
18574
18663
  error.message
18575
18664
  ] }) });
18576
18665
  }
18577
18666
  if (loading) {
18578
- return /* @__PURE__ */ jsx42("div", { className: PDFViewer_default.loading, style: { height, width }, children: /* @__PURE__ */ jsx42("p", { children: "Loading PDF..." }) });
18667
+ return /* @__PURE__ */ jsx42("div", { className: pdfViewerStyles.loading, style: { height, width }, children: /* @__PURE__ */ jsx42("p", { children: "Loading PDF..." }) });
18579
18668
  }
18580
18669
  return /* @__PURE__ */ jsxs3(
18581
18670
  "div",
18582
18671
  {
18583
- className: `${PDFViewer_default.viewer} ${className || ""}`,
18672
+ className: `${pdfViewerStyles.viewer} ${className || ""}`,
18584
18673
  style: { height, width, ...style },
18585
18674
  children: [
18586
18675
  showControls && /* @__PURE__ */ jsx42(
@@ -18596,7 +18685,7 @@ function PDFViewer({
18596
18685
  url
18597
18686
  }
18598
18687
  ),
18599
- /* @__PURE__ */ jsxs3("div", { className: PDFViewer_default.content, children: [
18688
+ /* @__PURE__ */ jsxs3("div", { className: pdfViewerStyles.content, children: [
18600
18689
  showThumbnails && document2 && /* @__PURE__ */ jsx42(
18601
18690
  PDFThumbnails,
18602
18691
  {
@@ -18620,46 +18709,6 @@ function PDFViewer({
18620
18709
  }
18621
18710
  );
18622
18711
  }
18623
- async function isLinearizedPDF(url) {
18624
- try {
18625
- const response = await fetch(url, { headers: { Range: "bytes=0-1024" } });
18626
- const buffer = await response.arrayBuffer();
18627
- const view = new Uint8Array(buffer);
18628
- const text = new TextDecoder().decode(view);
18629
- return text.includes("Linearized");
18630
- } catch {
18631
- return false;
18632
- }
18633
- }
18634
- function downloadPDF(url, filename) {
18635
- const link = document.createElement("a");
18636
- link.href = url;
18637
- link.download = filename || "document.pdf";
18638
- document.body.appendChild(link);
18639
- link.click();
18640
- document.body.removeChild(link);
18641
- }
18642
- function calculateScaleForPageFit(pageWidth, pageHeight, containerWidth, containerHeight) {
18643
- const widthRatio = containerWidth / pageWidth;
18644
- const heightRatio = containerHeight / pageHeight;
18645
- return Math.min(widthRatio, heightRatio);
18646
- }
18647
- function formatFileSize(bytes) {
18648
- if (bytes === 0) return "0 Bytes";
18649
- const k = 1024;
18650
- const sizes = ["Bytes", "KB", "MB", "GB"];
18651
- const i = Math.floor(Math.log(bytes) / Math.log(k));
18652
- return Math.round(bytes / Math.pow(k, i) * 100) / 100 + " " + sizes[i];
18653
- }
18654
- async function extractPageText(pdfDoc, pageNumber) {
18655
- try {
18656
- const page = await pdfDoc.getPage(pageNumber);
18657
- const textContent = await page.getTextContent();
18658
- return textContent.items.filter((item) => "str" in item).map((item) => item.str).join(" ");
18659
- } catch {
18660
- return "";
18661
- }
18662
- }
18663
18712
  function getOptimalRangeHeader(fileSize) {
18664
18713
  const chunkSize = Math.min(65536, Math.ceil(fileSize * 0.1));
18665
18714
  return {
@@ -18684,16 +18733,65 @@ function createProgressiveFetchHandler(onProgress) {
18684
18733
  return response.arrayBuffer();
18685
18734
  };
18686
18735
  }
18687
- var DEFAULT_SCALE, CACHE_SIZE, MIN_ZOOM, MAX_ZOOM, ZOOM_STEP, PDFViewer_default, linearizedPDFConfig;
18736
+ var DEFAULT_SCALE, CACHE_SIZE, MIN_ZOOM, MAX_ZOOM, ZOOM_STEP, PDF_VIEWER_STYLES, stylesInjected, pdfViewerStyles, linearizedPDFConfig;
18688
18737
  var init_dist = __esm({
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"() {
18738
+ "node_modules/.pnpm/@page-speed+pdf-viewer@0.1.6_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@page-speed/pdf-viewer/dist/index.js"() {
18690
18739
  "use client";
18691
18740
  DEFAULT_SCALE = 1.5;
18692
18741
  CACHE_SIZE = 50 * 1024 * 1024;
18693
18742
  MIN_ZOOM = 0.5;
18694
18743
  MAX_ZOOM = 3;
18695
18744
  ZOOM_STEP = 0.25;
18696
- PDFViewer_default = {
18745
+ PDF_VIEWER_STYLES = `
18746
+ /* Core viewer layout */
18747
+ .PDFViewer_viewer { display: flex; flex-direction: column; background: #f5f5f5; font-family: system-ui, -apple-system, sans-serif; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.1); height: 100%; width: 100%; }
18748
+
18749
+ /* Controls */
18750
+ .PDFViewer_controls { display: flex; align-items: center; gap: 8px; padding: 12px 16px; background: #fff; border-bottom: 1px solid #e0e0e0; overflow-x: auto; flex-wrap: wrap; flex-shrink: 0; z-index: 10; position: relative; }
18751
+ .PDFViewer_controls button { padding: 8px 14px; background: #007bff; color: #fff; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; font-weight: 500; transition: background 150ms, box-shadow 150ms; white-space: nowrap; }
18752
+ .PDFViewer_controls button:hover:not(:disabled) { background: #0056b3; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
18753
+ .PDFViewer_controls button:disabled { opacity: 0.5; cursor: not-allowed; background: #6c757d; }
18754
+
18755
+ .PDFViewer_pageInput { width: 60px; padding: 8px; border: 1px solid #ccc; border-radius: 4px; font-size: 14px; text-align: center; font-weight: 500; }
18756
+ .PDFViewer_pageInput:focus { outline: none; border-color: #007bff; box-shadow: 0 0 0 2px rgba(0,123,255,0.1); }
18757
+ .PDFViewer_pageTotal { font-size: 14px; color: #666; font-weight: 500; white-space: nowrap; }
18758
+ .PDFViewer_zoomLevel { font-size: 14px; color: #333; min-width: 60px; text-align: center; font-weight: 600; }
18759
+
18760
+ .PDFViewer_searchInput { padding: 6px 12px; border: 1px solid #ccc; border-radius: 4px; font-size: 14px; }
18761
+ .PDFViewer_searchResults { font-size: 12px; color: #666; }
18762
+
18763
+ .PDFViewer_button { padding: 6px 12px; background: #28a745; color: #fff; border: none; border-radius: 4px; text-decoration: none; cursor: pointer; transition: background 150ms; font-size: 14px; font-weight: 500; }
18764
+ .PDFViewer_button:hover { background: #218838; }
18765
+
18766
+ /* Main content */
18767
+ .PDFViewer_content { display: flex; flex: 1; overflow: hidden; min-height: 0; }
18768
+ .PDFViewer_canvas { flex: 1; overflow: auto; display: flex; align-items: center; justify-content: center; background: #fff; padding: 20px; }
18769
+ .PDFViewer_canvas canvas { max-width: 100%; height: auto !important; box-shadow: 0 2px 8px rgba(0,0,0,0.15); display: block; }
18770
+
18771
+ /* Thumbnails */
18772
+ .PDFViewer_thumbnails { width: 120px; overflow-y: auto; background: #fff; border-right: 1px solid #e0e0e0; padding: 8px; display: flex; flex-direction: column; gap: 8px; }
18773
+ .PDFViewer_thumbnail { position: relative; cursor: pointer; border: 2px solid transparent; border-radius: 4px; overflow: hidden; transition: border-color 150ms, box-shadow 150ms; }
18774
+ .PDFViewer_thumbnail:hover { border-color: #007bff; box-shadow: 0 2px 4px rgba(0,123,255,0.2); }
18775
+ .PDFViewer_thumbnail.PDFViewer_active { border-color: #007bff; box-shadow: 0 2px 8px rgba(0,123,255,0.4); }
18776
+ .PDFViewer_thumbnail canvas { width: 100%; height: auto; display: block; }
18777
+ .PDFViewer_pageNumber { position: absolute; bottom: 4px; right: 4px; font-size: 11px; background: rgba(0,0,0,0.7); color: #fff; padding: 2px 4px; border-radius: 2px; }
18778
+
18779
+ /* Loading & error */
18780
+ .PDFViewer_loading, .PDFViewer_error { display: flex; align-items: center; justify-content: center; background: #fff; border-radius: 8px; }
18781
+ .PDFViewer_loading p, .PDFViewer_error p { font-size: 16px; color: #666; }
18782
+ .PDFViewer_error p { color: #dc3545; }
18783
+
18784
+ /* Responsive tweaks */
18785
+ @media (max-width: 768px) {
18786
+ .PDFViewer_controls { gap: 6px; padding: 8px 12px; }
18787
+ .PDFViewer_controls button { padding: 4px 8px; font-size: 12px; }
18788
+ .PDFViewer_pageInput { width: 50px; }
18789
+ .PDFViewer_thumbnails { width: 80px; }
18790
+ .PDFViewer_searchInput { padding: 4px 8px; font-size: 12px; }
18791
+ }
18792
+ `;
18793
+ stylesInjected = false;
18794
+ pdfViewerStyles = {
18697
18795
  viewer: "PDFViewer_viewer",
18698
18796
  controls: "PDFViewer_controls",
18699
18797
  pageInput: "PDFViewer_pageInput",
@@ -22739,10 +22837,56 @@ function LightboxChrome({
22739
22837
  try {
22740
22838
  const response = await fetch(currentItem.src);
22741
22839
  const blob = await response.blob();
22840
+ const getFileExtension = () => {
22841
+ const contentType = response.headers.get("Content-Type");
22842
+ if (contentType) {
22843
+ const mimeToExt = {
22844
+ "application/pdf": ".pdf",
22845
+ "image/jpeg": ".jpg",
22846
+ "image/jpg": ".jpg",
22847
+ "image/png": ".png",
22848
+ "image/gif": ".gif",
22849
+ "image/webp": ".webp",
22850
+ "image/svg+xml": ".svg",
22851
+ "video/mp4": ".mp4",
22852
+ "video/webm": ".webm",
22853
+ "video/quicktime": ".mov"
22854
+ };
22855
+ const baseMime = contentType.split(";")[0].trim().toLowerCase();
22856
+ if (mimeToExt[baseMime]) {
22857
+ return mimeToExt[baseMime];
22858
+ }
22859
+ }
22860
+ try {
22861
+ const urlObj = new URL(currentItem.src, window.location.origin);
22862
+ const pathname = urlObj.pathname;
22863
+ const lastDotIndex = pathname.lastIndexOf(".");
22864
+ if (lastDotIndex > pathname.lastIndexOf("/")) {
22865
+ const ext = pathname.substring(lastDotIndex).toLowerCase();
22866
+ if (ext.length >= 2 && ext.length <= 6) {
22867
+ return ext;
22868
+ }
22869
+ }
22870
+ } catch {
22871
+ }
22872
+ const typeToExt = {
22873
+ "pdf": ".pdf",
22874
+ "image": ".jpg",
22875
+ "video": ".mp4"
22876
+ };
22877
+ if (currentItem.type && typeToExt[currentItem.type]) {
22878
+ return typeToExt[currentItem.type];
22879
+ }
22880
+ return "";
22881
+ };
22882
+ const baseName = currentItem.title || "download";
22883
+ const extension = getFileExtension();
22884
+ const hasExtension = baseName.includes(".") && baseName.lastIndexOf(".") > baseName.length - 6;
22885
+ const filename = hasExtension ? baseName : `${baseName}${extension}`;
22742
22886
  const url = window.URL.createObjectURL(blob);
22743
22887
  const link = document.createElement("a");
22744
22888
  link.href = url;
22745
- link.download = currentItem.title || "download";
22889
+ link.download = filename;
22746
22890
  document.body.appendChild(link);
22747
22891
  link.click();
22748
22892
  document.body.removeChild(link);