@printwithsynergy/lens-pdf 0.3.0-beta.81
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.
- package/LICENSE +661 -0
- package/README.md +344 -0
- package/dist/browser/codexOverlay.d.ts +109 -0
- package/dist/browser/codexOverlay.d.ts.map +1 -0
- package/dist/browser/codexOverlay.js +256 -0
- package/dist/browser/codexOverlay.js.map +1 -0
- package/dist/browser/constants.d.ts +13 -0
- package/dist/browser/constants.d.ts.map +1 -0
- package/dist/browser/constants.js +13 -0
- package/dist/browser/constants.js.map +1 -0
- package/dist/browser/index.d.ts +211 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +1190 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/pantone-gold.d.ts +59 -0
- package/dist/browser/pantone-gold.d.ts.map +1 -0
- package/dist/browser/pantone-gold.js +237 -0
- package/dist/browser/pantone-gold.js.map +1 -0
- package/dist/components/AnnotationCanvas.d.ts +27 -0
- package/dist/components/AnnotationCanvas.d.ts.map +1 -0
- package/dist/components/AnnotationCanvas.js +401 -0
- package/dist/components/AnnotationCanvas.js.map +1 -0
- package/dist/components/AnnotationNotesPanel.d.ts +15 -0
- package/dist/components/AnnotationNotesPanel.d.ts.map +1 -0
- package/dist/components/AnnotationNotesPanel.js +235 -0
- package/dist/components/AnnotationNotesPanel.js.map +1 -0
- package/dist/components/AnnotationThread.d.ts +18 -0
- package/dist/components/AnnotationThread.d.ts.map +1 -0
- package/dist/components/AnnotationThread.js +163 -0
- package/dist/components/AnnotationThread.js.map +1 -0
- package/dist/components/AnnotationToolbar.d.ts +39 -0
- package/dist/components/AnnotationToolbar.d.ts.map +1 -0
- package/dist/components/AnnotationToolbar.js +258 -0
- package/dist/components/AnnotationToolbar.js.map +1 -0
- package/dist/components/BoxOverlay.d.ts +20 -0
- package/dist/components/BoxOverlay.d.ts.map +1 -0
- package/dist/components/BoxOverlay.js +107 -0
- package/dist/components/BoxOverlay.js.map +1 -0
- package/dist/components/ColorPickerTool.d.ts +11 -0
- package/dist/components/ColorPickerTool.d.ts.map +1 -0
- package/dist/components/ColorPickerTool.js +220 -0
- package/dist/components/ColorPickerTool.js.map +1 -0
- package/dist/components/DensitometerTool.d.ts +25 -0
- package/dist/components/DensitometerTool.d.ts.map +1 -0
- package/dist/components/DensitometerTool.js +246 -0
- package/dist/components/DensitometerTool.js.map +1 -0
- package/dist/components/DielineInfoPanel.d.ts +27 -0
- package/dist/components/DielineInfoPanel.d.ts.map +1 -0
- package/dist/components/DielineInfoPanel.js +23 -0
- package/dist/components/DielineInfoPanel.js.map +1 -0
- package/dist/components/DielineOverlay.d.ts +10 -0
- package/dist/components/DielineOverlay.d.ts.map +1 -0
- package/dist/components/DielineOverlay.js +57 -0
- package/dist/components/DielineOverlay.js.map +1 -0
- package/dist/components/FindingsSidebar.d.ts +50 -0
- package/dist/components/FindingsSidebar.d.ts.map +1 -0
- package/dist/components/FindingsSidebar.js +78 -0
- package/dist/components/FindingsSidebar.js.map +1 -0
- package/dist/components/LayerCanvas.d.ts +30 -0
- package/dist/components/LayerCanvas.d.ts.map +1 -0
- package/dist/components/LayerCanvas.js +84 -0
- package/dist/components/LayerCanvas.js.map +1 -0
- package/dist/components/LayerPanel.d.ts +9 -0
- package/dist/components/LayerPanel.d.ts.map +1 -0
- package/dist/components/LayerPanel.js +144 -0
- package/dist/components/LayerPanel.js.map +1 -0
- package/dist/components/LensPDF.d.ts +61 -0
- package/dist/components/LensPDF.d.ts.map +1 -0
- package/dist/components/LensPDF.js +49 -0
- package/dist/components/LensPDF.js.map +1 -0
- package/dist/components/LensPDFDemo.d.ts +160 -0
- package/dist/components/LensPDFDemo.d.ts.map +1 -0
- package/dist/components/LensPDFDemo.js +1060 -0
- package/dist/components/LensPDFDemo.js.map +1 -0
- package/dist/components/LensPDFDemo.styles.d.ts +38 -0
- package/dist/components/LensPDFDemo.styles.d.ts.map +1 -0
- package/dist/components/LensPDFDemo.styles.js +282 -0
- package/dist/components/LensPDFDemo.styles.js.map +1 -0
- package/dist/components/LensPDFViewer.d.ts +79 -0
- package/dist/components/LensPDFViewer.d.ts.map +1 -0
- package/dist/components/LensPDFViewer.js +254 -0
- package/dist/components/LensPDFViewer.js.map +1 -0
- package/dist/components/MeasureTool.d.ts +16 -0
- package/dist/components/MeasureTool.d.ts.map +1 -0
- package/dist/components/MeasureTool.js +137 -0
- package/dist/components/MeasureTool.js.map +1 -0
- package/dist/components/MobileBottomSheet.d.ts +12 -0
- package/dist/components/MobileBottomSheet.d.ts.map +1 -0
- package/dist/components/MobileBottomSheet.js +113 -0
- package/dist/components/MobileBottomSheet.js.map +1 -0
- package/dist/components/MobileDrawer.d.ts +31 -0
- package/dist/components/MobileDrawer.d.ts.map +1 -0
- package/dist/components/MobileDrawer.js +67 -0
- package/dist/components/MobileDrawer.js.map +1 -0
- package/dist/components/PageCanvas.d.ts +33 -0
- package/dist/components/PageCanvas.d.ts.map +1 -0
- package/dist/components/PageCanvas.js +385 -0
- package/dist/components/PageCanvas.js.map +1 -0
- package/dist/components/PageNavigator.d.ts +18 -0
- package/dist/components/PageNavigator.d.ts.map +1 -0
- package/dist/components/PageNavigator.js +44 -0
- package/dist/components/PageNavigator.js.map +1 -0
- package/dist/components/SeparationCanvas.d.ts +12 -0
- package/dist/components/SeparationCanvas.d.ts.map +1 -0
- package/dist/components/SeparationCanvas.js +174 -0
- package/dist/components/SeparationCanvas.js.map +1 -0
- package/dist/components/TACHeatmapOverlay.d.ts +17 -0
- package/dist/components/TACHeatmapOverlay.d.ts.map +1 -0
- package/dist/components/TACHeatmapOverlay.js +119 -0
- package/dist/components/TACHeatmapOverlay.js.map +1 -0
- package/dist/components/ZoomControls.d.ts +11 -0
- package/dist/components/ZoomControls.d.ts.map +1 -0
- package/dist/components/ZoomControls.js +26 -0
- package/dist/components/ZoomControls.js.map +1 -0
- package/dist/components/defaultShellPlugins.d.ts +3 -0
- package/dist/components/defaultShellPlugins.d.ts.map +1 -0
- package/dist/components/defaultShellPlugins.js +273 -0
- package/dist/components/defaultShellPlugins.js.map +1 -0
- package/dist/components/index.d.ts +32 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +32 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/presets.d.ts +8 -0
- package/dist/components/presets.d.ts.map +1 -0
- package/dist/components/presets.js +14 -0
- package/dist/components/presets.js.map +1 -0
- package/dist/components/shellPlugins.d.ts +105 -0
- package/dist/components/shellPlugins.d.ts.map +1 -0
- package/dist/components/shellPlugins.js +52 -0
- package/dist/components/shellPlugins.js.map +1 -0
- package/dist/components/useIsMobile.d.ts +16 -0
- package/dist/components/useIsMobile.d.ts.map +1 -0
- package/dist/components/useIsMobile.js +30 -0
- package/dist/components/useIsMobile.js.map +1 -0
- package/dist/fallback-pdfjs/index.d.ts +60 -0
- package/dist/fallback-pdfjs/index.d.ts.map +1 -0
- package/dist/fallback-pdfjs/index.js +163 -0
- package/dist/fallback-pdfjs/index.js.map +1 -0
- package/dist/host/LensPDFProvider.d.ts +36 -0
- package/dist/host/LensPDFProvider.d.ts.map +1 -0
- package/dist/host/LensPDFProvider.js +12 -0
- package/dist/host/LensPDFProvider.js.map +1 -0
- package/dist/host/index.d.ts +167 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/host/index.js +173 -0
- package/dist/host/index.js.map +1 -0
- package/dist/host/pdfFallback.d.ts +50 -0
- package/dist/host/pdfFallback.d.ts.map +1 -0
- package/dist/host/pdfFallback.js +171 -0
- package/dist/host/pdfFallback.js.map +1 -0
- package/dist/host/pdfValidation.d.ts +45 -0
- package/dist/host/pdfValidation.d.ts.map +1 -0
- package/dist/host/pdfValidation.js +78 -0
- package/dist/host/pdfValidation.js.map +1 -0
- package/dist/host/shareLink.d.ts +80 -0
- package/dist/host/shareLink.d.ts.map +1 -0
- package/dist/host/shareLink.js +114 -0
- package/dist/host/shareLink.js.map +1 -0
- package/dist/host/useLensPDF.d.ts +73 -0
- package/dist/host/useLensPDF.d.ts.map +1 -0
- package/dist/host/useLensPDF.js +213 -0
- package/dist/host/useLensPDF.js.map +1 -0
- package/dist/index.d.ts +68 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +62 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin/context.d.ts +70 -0
- package/dist/plugin/context.d.ts.map +1 -0
- package/dist/plugin/context.js +16 -0
- package/dist/plugin/context.js.map +1 -0
- package/dist/plugin/findings-location.d.ts +53 -0
- package/dist/plugin/findings-location.d.ts.map +1 -0
- package/dist/plugin/findings-location.js +72 -0
- package/dist/plugin/findings-location.js.map +1 -0
- package/dist/plugin/index.d.ts +19 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +16 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/registry.d.ts +61 -0
- package/dist/plugin/registry.d.ts.map +1 -0
- package/dist/plugin/registry.js +102 -0
- package/dist/plugin/registry.js.map +1 -0
- package/dist/plugin/services.d.ts +380 -0
- package/dist/plugin/services.d.ts.map +1 -0
- package/dist/plugin/services.js +104 -0
- package/dist/plugin/services.js.map +1 -0
- package/dist/plugin/types.d.ts +198 -0
- package/dist/plugin/types.d.ts.map +1 -0
- package/dist/plugin/types.js +24 -0
- package/dist/plugin/types.js.map +1 -0
- package/dist/types/index.d.ts +191 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +95 -0
- package/dist/types/index.js.map +1 -0
- package/dist/units/index.d.ts +64 -0
- package/dist/units/index.d.ts.map +1 -0
- package/dist/units/index.js +98 -0
- package/dist/units/index.js.map +1 -0
- package/docs/architecture.md +90 -0
- package/docs/components.md +569 -0
- package/docs/contributing.md +78 -0
- package/docs/fallback.md +174 -0
- package/docs/lens-pdf-viewer.md +128 -0
- package/docs/licensing.md +78 -0
- package/docs/measurement-units.md +87 -0
- package/docs/plugins.md +256 -0
- package/docs/security.md +69 -0
- package/docs/server.md +212 -0
- package/docs/services.md +210 -0
- package/docs/share-links.md +111 -0
- package/docs/theming.md +164 -0
- package/docs/validation.md +83 -0
- package/package.json +139 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Fragment, useCallback, useEffect, useMemo, useRef, useState, } from "react";
|
|
4
|
+
import { defaultThemeTokens } from "../plugin/services.js";
|
|
5
|
+
import { ViewerHostContext, ViewerServicesContext } from "../host/index.js";
|
|
6
|
+
import { createPdfJsFallback } from "../fallback-pdfjs/index.js";
|
|
7
|
+
import { ColorPickerTool } from "./ColorPickerTool.js";
|
|
8
|
+
import { LayerPanel } from "./LayerPanel.js";
|
|
9
|
+
import { MeasureTool } from "./MeasureTool.js";
|
|
10
|
+
import { PageCanvas } from "./PageCanvas.js";
|
|
11
|
+
import { ZoomControls } from "./ZoomControls.js";
|
|
12
|
+
const DEFAULT_TOOLS = [
|
|
13
|
+
"zoom",
|
|
14
|
+
"layers",
|
|
15
|
+
"color-picker",
|
|
16
|
+
"measure",
|
|
17
|
+
];
|
|
18
|
+
const MOBILE_BREAKPOINT_PX = 768;
|
|
19
|
+
/**
|
|
20
|
+
* One-line responsive PDF viewer.
|
|
21
|
+
*
|
|
22
|
+
* ```tsx
|
|
23
|
+
* <LensPDFViewer pdfUrl="https://example.com/file.pdf" />
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
export function LensPDFViewer(props) {
|
|
29
|
+
const { pdfUrl, workerSrc, services, tokens = defaultThemeTokens, className, mode = "scroll", tools = DEFAULT_TOOLS, initialZoom = 100, brand, } = props;
|
|
30
|
+
const fallback = useMemo(() => createPdfJsFallback({ pdfUrl, workerSrc }), [pdfUrl, workerSrc]);
|
|
31
|
+
const [pageCount, setPageCount] = useState(null);
|
|
32
|
+
const [pageDimsByNum, setPageDimsByNum] = useState(new Map());
|
|
33
|
+
const [zoom, setZoom] = useState(initialZoom);
|
|
34
|
+
const [enabledLayers, setEnabledLayers] = useState(new Set());
|
|
35
|
+
const [layersDiscovered, setLayersDiscovered] = useState(false);
|
|
36
|
+
const [hasLayers, setHasLayers] = useState(false);
|
|
37
|
+
const [currentPage, setCurrentPage] = useState(1);
|
|
38
|
+
const [activeTool, setActiveTool] = useState("none");
|
|
39
|
+
const [layersOpen, setLayersOpen] = useState(false);
|
|
40
|
+
const [menuOpen, setMenuOpen] = useState(false);
|
|
41
|
+
const [errorMessage, setErrorMessage] = useState(null);
|
|
42
|
+
const isMobile = useMediaQueryMaxWidth(MOBILE_BREAKPOINT_PX - 1);
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
let cancelled = false;
|
|
45
|
+
fallback
|
|
46
|
+
.getPageCount()
|
|
47
|
+
.then((n) => {
|
|
48
|
+
if (!cancelled)
|
|
49
|
+
setPageCount(n);
|
|
50
|
+
})
|
|
51
|
+
.catch((err) => {
|
|
52
|
+
if (!cancelled)
|
|
53
|
+
setErrorMessage(err.message);
|
|
54
|
+
});
|
|
55
|
+
return () => {
|
|
56
|
+
cancelled = true;
|
|
57
|
+
};
|
|
58
|
+
}, [fallback]);
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
let cancelled = false;
|
|
61
|
+
fallback.listLayers().then((layers) => {
|
|
62
|
+
if (cancelled)
|
|
63
|
+
return;
|
|
64
|
+
setHasLayers(layers.length > 0);
|
|
65
|
+
setEnabledLayers(new Set(layers.filter((l) => l.default_on).map((l) => l.ocg_index)));
|
|
66
|
+
setLayersDiscovered(true);
|
|
67
|
+
});
|
|
68
|
+
return () => {
|
|
69
|
+
cancelled = true;
|
|
70
|
+
};
|
|
71
|
+
}, [fallback]);
|
|
72
|
+
const showLayersControl = layersDiscovered && hasLayers && tools.includes("layers");
|
|
73
|
+
const showColorPicker = tools.includes("color-picker");
|
|
74
|
+
const showMeasure = tools.includes("measure");
|
|
75
|
+
const showZoom = tools.includes("zoom");
|
|
76
|
+
const onToggleLayer = useCallback((ocgIndex) => {
|
|
77
|
+
setEnabledLayers((prev) => {
|
|
78
|
+
const next = new Set(prev);
|
|
79
|
+
if (next.has(ocgIndex))
|
|
80
|
+
next.delete(ocgIndex);
|
|
81
|
+
else
|
|
82
|
+
next.add(ocgIndex);
|
|
83
|
+
return next;
|
|
84
|
+
});
|
|
85
|
+
}, []);
|
|
86
|
+
const onSetAllLayers = useCallback((enabled) => {
|
|
87
|
+
if (enabled) {
|
|
88
|
+
fallback.listLayers().then((layers) => {
|
|
89
|
+
setEnabledLayers(new Set(layers.map((l) => l.ocg_index)));
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
setEnabledLayers(new Set());
|
|
94
|
+
}
|
|
95
|
+
}, [fallback]);
|
|
96
|
+
const hostValue = useMemo(() => ({
|
|
97
|
+
apiBase: "",
|
|
98
|
+
jobApiBase: "",
|
|
99
|
+
readOnly: true,
|
|
100
|
+
pdfUrl,
|
|
101
|
+
pdfFallback: fallback,
|
|
102
|
+
}), [pdfUrl, fallback]);
|
|
103
|
+
const accent = tokens.accent;
|
|
104
|
+
const stage = (_jsx(Stage, { mode: mode, pageCount: pageCount, pageDimsByNum: pageDimsByNum, setPageDimsByNum: setPageDimsByNum, fallback: fallback, zoom: zoom, currentPage: currentPage, onCurrentPageChange: setCurrentPage, activeTool: activeTool, errorMessage: errorMessage }));
|
|
105
|
+
const layersBody = showLayersControl ? (_jsx(LayerPanel, { jobId: "lens-pdf-viewer", enabledLayers: enabledLayers, onToggleLayer: onToggleLayer, onSetAllLayers: onSetAllLayers })) : null;
|
|
106
|
+
// Selecting a tool from the mobile drawer should close the drawer
|
|
107
|
+
// so the page is visible to actually use the tool.
|
|
108
|
+
const handleToolPick = useCallback((next) => {
|
|
109
|
+
setActiveTool((t) => (t === next ? "none" : next));
|
|
110
|
+
setMenuOpen(false);
|
|
111
|
+
}, []);
|
|
112
|
+
const handleLayersPick = useCallback(() => {
|
|
113
|
+
setLayersOpen((v) => !v);
|
|
114
|
+
setMenuOpen(false);
|
|
115
|
+
}, []);
|
|
116
|
+
// Desktop toolbar — show all tools inline.
|
|
117
|
+
const desktopToolbarRight = (_jsxs("div", { className: "flex items-center gap-1.5", children: [showZoom && _jsx(ZoomControls, { zoom: zoom, onZoomChange: setZoom, compact: true, dark: true }), showColorPicker && (_jsx(ToolButton, { label: "Color", active: activeTool === "color-picker", accent: accent, onClick: () => setActiveTool((t) => (t === "color-picker" ? "none" : "color-picker")) })), showMeasure && (_jsx(ToolButton, { label: "Measure", active: activeTool === "measure", accent: accent, onClick: () => setActiveTool((t) => (t === "measure" ? "none" : "measure")) })), showLayersControl && (_jsx(ToolButton, { label: "Layers", active: layersOpen, accent: accent, onClick: () => setLayersOpen((v) => !v) }))] }));
|
|
118
|
+
// Mobile toolbar — ZoomControls live on the right; the hamburger
|
|
119
|
+
// moved to the header's left cluster (beside the brand) so it sits
|
|
120
|
+
// next to the host logo where users expect a primary menu trigger.
|
|
121
|
+
const mobileToolbarRight = (_jsx("div", { className: "flex items-center gap-1.5", children: showZoom && _jsx(ZoomControls, { zoom: zoom, onZoomChange: setZoom, compact: true, dark: true }) }));
|
|
122
|
+
// Reusable hamburger trigger. Rendered in the header's left cluster
|
|
123
|
+
// on mobile so the menu lives at top-left, beside the brand/logo —
|
|
124
|
+
// mirrors the iOS / Material pattern of "primary action top-left".
|
|
125
|
+
const mobileMenuTrigger = isMobile ? (_jsx("button", { type: "button", onClick: () => setMenuOpen(true), className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-white/10 text-slate-300 hover:bg-slate-800 hover:text-white", "aria-label": "Open tools menu", children: _jsx("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: _jsx("path", { d: "M4 6h16M4 12h16M4 18h16" }) }) })) : null;
|
|
126
|
+
const headerLeft = (_jsxs("div", { className: "flex min-w-0 items-center gap-3", children: [mobileMenuTrigger, brand !== undefined && (_jsx("span", { className: "truncate text-sm font-bold text-white", children: brand })), mode === "single" && pageCount !== null && (_jsx(PageNav, { page: currentPage, total: pageCount, onChange: setCurrentPage }))] }));
|
|
127
|
+
const content = (_jsxs("div", { className: `flex h-full min-h-[480px] flex-col bg-slate-900 text-slate-100 ${className ?? ""}`, children: [_jsxs("header", { className: "flex h-12 flex-shrink-0 items-center justify-between gap-2 border-b border-white/[0.06] bg-slate-900 px-3", children: [headerLeft, isMobile ? mobileToolbarRight : desktopToolbarRight] }), _jsxs("div", { className: "flex min-h-0 flex-1", children: [!isMobile && layersOpen && layersBody && (_jsx("aside", { className: "w-[260px] flex-shrink-0 overflow-y-auto border-r border-white/[0.06] bg-slate-900", children: layersBody })), _jsx("main", { className: "min-h-0 flex-1 bg-slate-800", children: stage })] }), isMobile && menuOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-50 bg-black/50 transition-opacity duration-300", onClick: () => setMenuOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-[60] flex w-[280px] flex-col bg-slate-900 shadow-xl", children: [_jsxs("div", { className: "flex h-12 flex-shrink-0 items-center justify-between border-b border-white/[0.06] px-4", children: [_jsx("span", { className: "text-sm font-bold text-white", children: brand ?? "Tools" }), _jsx("button", { type: "button", onClick: () => setMenuOpen(false), className: "rounded p-1 text-slate-400 hover:bg-slate-800 hover:text-white", "aria-label": "Close menu", children: _jsx("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: _jsx("path", { d: "M6 18L18 6M6 6l12 12" }) }) })] }), _jsxs("div", { className: "flex flex-1 flex-col overflow-y-auto py-2", children: [(showColorPicker || showMeasure) && (_jsxs(DrawerSection, { title: "Tools", children: [showColorPicker && (_jsx(DrawerItem, { label: "Color picker", icon: _jsx(ColorPickerIcon, {}), active: activeTool === "color-picker", onClick: () => handleToolPick("color-picker") })), showMeasure && (_jsx(DrawerItem, { label: "Measure", icon: _jsx(RulerIcon, {}), active: activeTool === "measure", onClick: () => handleToolPick("measure") }))] })), showLayersControl && (_jsx(DrawerSection, { title: "View", children: _jsx(DrawerItem, { label: "Layers", icon: _jsx(LayersIcon, {}), active: layersOpen, onClick: handleLayersPick }) }))] })] })] })), isMobile && layersOpen && layersBody && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-50 bg-black/50 transition-opacity duration-300", onClick: () => setLayersOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-[60] flex w-[280px] flex-col bg-slate-900 shadow-xl", children: [_jsxs("div", { className: "flex h-12 flex-shrink-0 items-center justify-between border-b border-white/[0.06] px-4", children: [_jsx("span", { className: "text-sm font-bold text-white", children: "Layers" }), _jsx("button", { type: "button", onClick: () => setLayersOpen(false), className: "rounded p-1 text-slate-400 hover:bg-slate-800 hover:text-white", "aria-label": "Close layers", children: _jsx("svg", { className: "h-5 w-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: _jsx("path", { d: "M6 18L18 6M6 6l12 12" }) }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto", children: layersBody })] })] }))] }));
|
|
128
|
+
return (_jsx(ViewerHostContext.Provider, { value: hostValue, children: services ? (_jsx(ViewerServicesContext.Provider, { value: services, children: content })) : (content) }));
|
|
129
|
+
}
|
|
130
|
+
function Stage({ mode, pageCount, pageDimsByNum, setPageDimsByNum, fallback, zoom, currentPage, onCurrentPageChange, activeTool, errorMessage, }) {
|
|
131
|
+
const containerRef = useRef(null);
|
|
132
|
+
if (errorMessage) {
|
|
133
|
+
return _jsxs("div", { className: "p-6 text-sm text-red-400", children: ["Failed to load PDF: ", errorMessage] });
|
|
134
|
+
}
|
|
135
|
+
if (pageCount === null) {
|
|
136
|
+
return (_jsxs("div", { className: "flex h-full items-center justify-center text-xs text-slate-400", children: [_jsxs("svg", { className: "mr-2 h-5 w-5 animate-spin", fill: "none", viewBox: "0 0 24 24", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })] }), "Loading PDF\u2026"] }));
|
|
137
|
+
}
|
|
138
|
+
const pages = mode === "single"
|
|
139
|
+
? [currentPage]
|
|
140
|
+
: Array.from({ length: pageCount }, (_, i) => i + 1);
|
|
141
|
+
return (_jsx("div", { ref: containerRef, className: "h-full overflow-auto p-4", children: _jsx("div", { className: "flex flex-col items-center gap-4", children: pages.map((pageNum) => (_jsx(PageSlot, { pageNum: pageNum, dims: pageDimsByNum.get(pageNum) ?? null, onDimsResolved: (dims) => setPageDimsByNum((prev) => {
|
|
142
|
+
if (prev.get(pageNum))
|
|
143
|
+
return prev;
|
|
144
|
+
const next = new Map(prev);
|
|
145
|
+
next.set(pageNum, dims);
|
|
146
|
+
return next;
|
|
147
|
+
}), fallback: fallback, zoom: zoom, activeTool: activeTool, onVisible: () => {
|
|
148
|
+
if (mode === "scroll")
|
|
149
|
+
onCurrentPageChange(pageNum);
|
|
150
|
+
} }, pageNum))) }) }));
|
|
151
|
+
}
|
|
152
|
+
function PageSlot({ pageNum, dims, onDimsResolved, fallback, zoom, activeTool, onVisible, }) {
|
|
153
|
+
const ref = useRef(null);
|
|
154
|
+
const [visible, setVisible] = useState(false);
|
|
155
|
+
const [resolvedDims, setResolvedDims] = useState(dims);
|
|
156
|
+
useEffect(() => {
|
|
157
|
+
if (resolvedDims)
|
|
158
|
+
return;
|
|
159
|
+
let cancelled = false;
|
|
160
|
+
fallback.getPageDimensions(pageNum).then((d) => {
|
|
161
|
+
if (cancelled)
|
|
162
|
+
return;
|
|
163
|
+
setResolvedDims(d);
|
|
164
|
+
onDimsResolved(d);
|
|
165
|
+
});
|
|
166
|
+
return () => {
|
|
167
|
+
cancelled = true;
|
|
168
|
+
};
|
|
169
|
+
}, [pageNum, fallback, resolvedDims, onDimsResolved]);
|
|
170
|
+
useEffect(() => {
|
|
171
|
+
const el = ref.current;
|
|
172
|
+
if (!el)
|
|
173
|
+
return;
|
|
174
|
+
if (typeof IntersectionObserver === "undefined") {
|
|
175
|
+
setVisible(true);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const obs = new IntersectionObserver((entries) => {
|
|
179
|
+
for (const entry of entries) {
|
|
180
|
+
if (entry.isIntersecting) {
|
|
181
|
+
setVisible(true);
|
|
182
|
+
onVisible?.();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}, { rootMargin: "400px" });
|
|
186
|
+
obs.observe(el);
|
|
187
|
+
return () => obs.disconnect();
|
|
188
|
+
}, [onVisible]);
|
|
189
|
+
const ptsToPx = 96 / 72;
|
|
190
|
+
const scale = zoom / 100;
|
|
191
|
+
const widthPts = resolvedDims?.widthPts ?? 612;
|
|
192
|
+
const heightPts = resolvedDims?.heightPts ?? 792;
|
|
193
|
+
const canvasWidth = Math.round(widthPts * ptsToPx * scale);
|
|
194
|
+
const canvasHeight = Math.round(heightPts * ptsToPx * scale);
|
|
195
|
+
const page = {
|
|
196
|
+
page_num: pageNum,
|
|
197
|
+
width_pts: widthPts,
|
|
198
|
+
height_pts: heightPts,
|
|
199
|
+
media_box: { x0: 0, y0: 0, x1: widthPts, y1: heightPts },
|
|
200
|
+
crop_box: null,
|
|
201
|
+
trim_box: null,
|
|
202
|
+
bleed_box: null,
|
|
203
|
+
rotation: 0,
|
|
204
|
+
};
|
|
205
|
+
return (_jsx("div", { ref: ref, className: "relative bg-white shadow-lg", style: { width: canvasWidth, height: canvasHeight }, children: visible && resolvedDims ? (_jsxs(Fragment, { children: [_jsx(PageCanvas, { jobId: "lens-pdf-viewer", page: page, zoom: scale, items: [], selectedItem: null, onItemClick: () => { }, onZoomChange: undefined }), activeTool === "color-picker" && (_jsx(ColorPickerTool, { jobId: "lens-pdf-viewer", pageNum: pageNum, pageWidthPts: widthPts, pageHeightPts: heightPts, canvasWidth: canvasWidth, canvasHeight: canvasHeight })), activeTool === "measure" && (_jsx(MeasureTool, { pageWidthPts: widthPts, pageHeightPts: heightPts, canvasWidth: canvasWidth, canvasHeight: canvasHeight }))] })) : (_jsxs("div", { className: "absolute inset-0 flex items-center justify-center text-xs text-slate-400", children: ["Page ", pageNum] })) }));
|
|
206
|
+
}
|
|
207
|
+
// ---------------------------------------------------------------------------
|
|
208
|
+
// Toolbar bits
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
function ToolButton({ label, active, accent, onClick, }) {
|
|
211
|
+
return (_jsx("button", { type: "button", onClick: onClick, className: `rounded-md border px-2.5 py-1 text-xs font-medium transition-colors ${active
|
|
212
|
+
? "text-white"
|
|
213
|
+
: "border-white/10 bg-slate-900 text-slate-300 hover:bg-slate-800 hover:text-white"}`, style: active ? { backgroundColor: accent, borderColor: accent } : undefined, children: label }));
|
|
214
|
+
}
|
|
215
|
+
function PageNav({ page, total, onChange }) {
|
|
216
|
+
return (_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("button", { type: "button", onClick: () => onChange(Math.max(1, page - 1)), disabled: page <= 1, className: "flex h-7 w-7 items-center justify-center rounded border border-white/10 text-base text-slate-300 hover:bg-slate-800 hover:text-white disabled:opacity-30 disabled:hover:bg-transparent", "aria-label": "Previous page", children: "\u2039" }), _jsxs("span", { className: "text-xs tabular-nums text-slate-300", children: [page, " / ", total] }), _jsx("button", { type: "button", onClick: () => onChange(Math.min(total, page + 1)), disabled: page >= total, className: "flex h-7 w-7 items-center justify-center rounded border border-white/10 text-base text-slate-300 hover:bg-slate-800 hover:text-white disabled:opacity-30 disabled:hover:bg-transparent", "aria-label": "Next page", children: "\u203A" })] }));
|
|
217
|
+
}
|
|
218
|
+
// ---------------------------------------------------------------------------
|
|
219
|
+
// Mobile drawer pieces — match MobileDrawer's design language so the
|
|
220
|
+
// hamburger menu feels consistent with the rest of the package.
|
|
221
|
+
// ---------------------------------------------------------------------------
|
|
222
|
+
function DrawerSection({ title, children }) {
|
|
223
|
+
return (_jsxs("div", { className: "mb-2", children: [_jsx("div", { className: "px-4 py-2 text-[10px] font-semibold uppercase tracking-wider text-slate-500", children: title }), _jsx("div", { className: "px-1", children: children })] }));
|
|
224
|
+
}
|
|
225
|
+
function DrawerItem({ label, icon, active, onClick, }) {
|
|
226
|
+
return (_jsxs("button", { type: "button", onClick: onClick, className: "flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left text-sm text-slate-200 transition-colors hover:bg-slate-800", children: [_jsx("span", { className: "flex h-5 w-5 shrink-0 items-center justify-center text-slate-400", children: icon }), _jsx("span", { className: active ? "font-medium text-white" : "", children: label }), active && _jsx("span", { className: "ml-auto h-2 w-2 shrink-0 rounded-full bg-blue-400" })] }));
|
|
227
|
+
}
|
|
228
|
+
function ColorPickerIcon() {
|
|
229
|
+
return (_jsxs("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: [_jsx("path", { d: "M16.5 3.5l4 4-10 10-4 1 1-4 10-10z" }), _jsx("path", { d: "M12.5 7.5l4 4" })] }));
|
|
230
|
+
}
|
|
231
|
+
function RulerIcon() {
|
|
232
|
+
return (_jsx("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: _jsx("path", { d: "M2 12h20M6 8v8M10 9v6M14 8v8M18 9v6" }) }));
|
|
233
|
+
}
|
|
234
|
+
function LayersIcon() {
|
|
235
|
+
return (_jsx("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: _jsx("path", { d: "M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5" }) }));
|
|
236
|
+
}
|
|
237
|
+
// ---------------------------------------------------------------------------
|
|
238
|
+
// useMediaQuery
|
|
239
|
+
// ---------------------------------------------------------------------------
|
|
240
|
+
function useMediaQueryMaxWidth(maxPx) {
|
|
241
|
+
const [matches, setMatches] = useState(false);
|
|
242
|
+
useEffect(() => {
|
|
243
|
+
if (typeof window === "undefined" || typeof window.matchMedia === "undefined") {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const mq = window.matchMedia(`(max-width: ${maxPx}px)`);
|
|
247
|
+
setMatches(mq.matches);
|
|
248
|
+
const listener = (e) => setMatches(e.matches);
|
|
249
|
+
mq.addEventListener("change", listener);
|
|
250
|
+
return () => mq.removeEventListener("change", listener);
|
|
251
|
+
}, [maxPx]);
|
|
252
|
+
return matches;
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=LensPDFViewer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LensPDFViewer.js","sourceRoot":"","sources":["../../components/LensPDFViewer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { MeasurementUnit } from "../plugin/types";
|
|
2
|
+
interface MeasureToolProps {
|
|
3
|
+
pageWidthPts: number;
|
|
4
|
+
pageHeightPts: number;
|
|
5
|
+
canvasWidth: number;
|
|
6
|
+
canvasHeight: number;
|
|
7
|
+
/**
|
|
8
|
+
* Measurement units to display in the readout. Defaults to
|
|
9
|
+
* `[mmUnit, inchUnit, pointUnit]`. Pass `allMeasurementUnits` to
|
|
10
|
+
* include pica + agate, or any custom subset/extension.
|
|
11
|
+
*/
|
|
12
|
+
units?: ReadonlyArray<MeasurementUnit>;
|
|
13
|
+
}
|
|
14
|
+
export declare function MeasureTool({ pageWidthPts, pageHeightPts, canvasWidth, canvasHeight, units, }: MeasureToolProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=MeasureTool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MeasureTool.d.ts","sourceRoot":"","sources":["../../components/MeasureTool.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGvD,UAAU,gBAAgB;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;CACxC;AAaD,wBAAgB,WAAW,CAAC,EAC1B,YAAY,EACZ,aAAa,EACb,WAAW,EACX,YAAY,EACZ,KAA+B,GAChC,EAAE,gBAAgB,2CAuNlB"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback, useRef, useState } from "react";
|
|
4
|
+
import { defaultMeasurementUnits } from "../units/index.js";
|
|
5
|
+
export function MeasureTool({ pageWidthPts, pageHeightPts, canvasWidth, canvasHeight, units = defaultMeasurementUnits, }) {
|
|
6
|
+
const [measuring, setMeasuring] = useState(false);
|
|
7
|
+
const [start, setStart] = useState(null);
|
|
8
|
+
const [end, setEnd] = useState(null);
|
|
9
|
+
const [measurement, setMeasurement] = useState(null);
|
|
10
|
+
const overlayRef = useRef(null);
|
|
11
|
+
const pixelToPts = useCallback((px, py) => {
|
|
12
|
+
const ptsX = (px / canvasWidth) * pageWidthPts;
|
|
13
|
+
const ptsY = (py / canvasHeight) * pageHeightPts;
|
|
14
|
+
return { x: ptsX, y: ptsY };
|
|
15
|
+
}, [canvasWidth, canvasHeight, pageWidthPts, pageHeightPts]);
|
|
16
|
+
const beginMeasure = useCallback((clientX, clientY, el) => {
|
|
17
|
+
const rect = el.getBoundingClientRect();
|
|
18
|
+
const x = clientX - rect.left;
|
|
19
|
+
const y = clientY - rect.top;
|
|
20
|
+
setStart({ x, y });
|
|
21
|
+
setEnd(null);
|
|
22
|
+
setMeasurement(null);
|
|
23
|
+
setMeasuring(true);
|
|
24
|
+
}, []);
|
|
25
|
+
const moveMeasure = useCallback((clientX, clientY, el, shiftKey) => {
|
|
26
|
+
if (!measuring || !start)
|
|
27
|
+
return;
|
|
28
|
+
const rect = el.getBoundingClientRect();
|
|
29
|
+
let x = clientX - rect.left;
|
|
30
|
+
let y = clientY - rect.top;
|
|
31
|
+
if (shiftKey) {
|
|
32
|
+
const dx = Math.abs(x - start.x);
|
|
33
|
+
const dy = Math.abs(y - start.y);
|
|
34
|
+
if (dx > dy)
|
|
35
|
+
y = start.y;
|
|
36
|
+
else
|
|
37
|
+
x = start.x;
|
|
38
|
+
}
|
|
39
|
+
setEnd({ x, y });
|
|
40
|
+
}, [measuring, start]);
|
|
41
|
+
const finishMeasure = useCallback(() => {
|
|
42
|
+
if (!measuring || !start || !end) {
|
|
43
|
+
setMeasuring(false);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const p1 = pixelToPts(start.x, start.y);
|
|
47
|
+
const p2 = pixelToPts(end.x, end.y);
|
|
48
|
+
const dx = p2.x - p1.x;
|
|
49
|
+
const dy = p2.y - p1.y;
|
|
50
|
+
const distancePts = Math.sqrt(dx * dx + dy * dy);
|
|
51
|
+
setMeasurement({
|
|
52
|
+
x1: start.x,
|
|
53
|
+
y1: start.y,
|
|
54
|
+
x2: end.x,
|
|
55
|
+
y2: end.y,
|
|
56
|
+
distancePts,
|
|
57
|
+
});
|
|
58
|
+
setMeasuring(false);
|
|
59
|
+
}, [measuring, start, end, pixelToPts]);
|
|
60
|
+
// Mouse handlers
|
|
61
|
+
const handleMouseDown = useCallback((e) => beginMeasure(e.clientX, e.clientY, e.currentTarget), [beginMeasure]);
|
|
62
|
+
const handleMouseMove = useCallback((e) => moveMeasure(e.clientX, e.clientY, e.currentTarget, e.shiftKey), [moveMeasure]);
|
|
63
|
+
const handleMouseUp = useCallback(() => finishMeasure(), [finishMeasure]);
|
|
64
|
+
// Touch handlers
|
|
65
|
+
const handleTouchStart = useCallback((e) => {
|
|
66
|
+
if (e.touches.length !== 1)
|
|
67
|
+
return;
|
|
68
|
+
e.preventDefault();
|
|
69
|
+
const t = e.touches[0];
|
|
70
|
+
beginMeasure(t.clientX, t.clientY, e.currentTarget);
|
|
71
|
+
}, [beginMeasure]);
|
|
72
|
+
const handleTouchMove = useCallback((e) => {
|
|
73
|
+
if (e.touches.length !== 1)
|
|
74
|
+
return;
|
|
75
|
+
e.preventDefault();
|
|
76
|
+
const t = e.touches[0];
|
|
77
|
+
moveMeasure(t.clientX, t.clientY, e.currentTarget);
|
|
78
|
+
}, [moveMeasure]);
|
|
79
|
+
const handleTouchEnd = useCallback((e) => {
|
|
80
|
+
e.preventDefault();
|
|
81
|
+
finishMeasure();
|
|
82
|
+
}, [finishMeasure]);
|
|
83
|
+
const isTouch = typeof window !== "undefined" && "ontouchstart" in window;
|
|
84
|
+
const midX = start && end ? (start.x + end.x) / 2 : 0;
|
|
85
|
+
const midY = start && end ? (start.y + end.y) / 2 : 0;
|
|
86
|
+
return (_jsxs("div", { ref: overlayRef, onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseUp: handleMouseUp, onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchEnd: handleTouchEnd, style: {
|
|
87
|
+
position: "absolute",
|
|
88
|
+
inset: 0,
|
|
89
|
+
cursor: "crosshair",
|
|
90
|
+
zIndex: 25,
|
|
91
|
+
touchAction: "none",
|
|
92
|
+
}, children: [start && end && (_jsxs("svg", { style: {
|
|
93
|
+
position: "absolute",
|
|
94
|
+
inset: 0,
|
|
95
|
+
pointerEvents: "none",
|
|
96
|
+
}, width: canvasWidth, height: canvasHeight, children: [_jsx("line", { x1: start.x, y1: start.y, x2: end.x, y2: end.y, stroke: "#22c55e", strokeWidth: 2, strokeDasharray: "6 3" }), _jsx("circle", { cx: start.x, cy: start.y, r: 4, fill: "#22c55e" }), _jsx("circle", { cx: end.x, cy: end.y, r: 4, fill: "#22c55e" })] })), measurement && (_jsx("div", { style: {
|
|
97
|
+
position: "absolute",
|
|
98
|
+
left: midX + 8,
|
|
99
|
+
top: midY - 24,
|
|
100
|
+
zIndex: 30,
|
|
101
|
+
pointerEvents: "none",
|
|
102
|
+
padding: "4px 8px",
|
|
103
|
+
borderRadius: 4,
|
|
104
|
+
border: "1px solid rgba(34, 197, 94, 0.6)",
|
|
105
|
+
background: "rgba(15, 23, 42, 0.95)",
|
|
106
|
+
color: "#bbf7d0",
|
|
107
|
+
fontSize: 12,
|
|
108
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
|
|
109
|
+
fontWeight: 500,
|
|
110
|
+
whiteSpace: "nowrap",
|
|
111
|
+
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.4)",
|
|
112
|
+
}, children: units
|
|
113
|
+
.map((u) => {
|
|
114
|
+
const value = u.fromPoints(measurement.distancePts);
|
|
115
|
+
const rounded = u.id === "in"
|
|
116
|
+
? Math.round(value * 1000) / 1000
|
|
117
|
+
: Math.round(value * 100) / 100;
|
|
118
|
+
return `${rounded} ${u.label}`;
|
|
119
|
+
})
|
|
120
|
+
.join(" · ") })), !start && (_jsx("div", { style: {
|
|
121
|
+
position: "absolute",
|
|
122
|
+
left: "50%",
|
|
123
|
+
top: 16,
|
|
124
|
+
transform: "translateX(-50%)",
|
|
125
|
+
zIndex: 30,
|
|
126
|
+
pointerEvents: "none",
|
|
127
|
+
padding: "4px 12px",
|
|
128
|
+
borderRadius: 4,
|
|
129
|
+
background: "rgba(0, 0, 0, 0.75)",
|
|
130
|
+
color: "#fff",
|
|
131
|
+
fontSize: 12,
|
|
132
|
+
whiteSpace: "nowrap",
|
|
133
|
+
}, children: isTouch
|
|
134
|
+
? "Tap and drag to measure distance."
|
|
135
|
+
: "Click and drag to measure distance. Hold Shift to snap." }))] }));
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=MeasureTool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MeasureTool.js","sourceRoot":"","sources":["../../components/MeasureTool.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type SnapPosition = "collapsed" | "half" | "full";
|
|
2
|
+
interface MobileBottomSheetProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
summary: React.ReactNode;
|
|
5
|
+
/** Controlled snap position from parent. */
|
|
6
|
+
snap?: SnapPosition;
|
|
7
|
+
/** Notify parent when snap changes (drag or tap). */
|
|
8
|
+
onSnapChange?: (snap: SnapPosition) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function MobileBottomSheet({ children, summary, snap: controlledSnap, onSnapChange }: MobileBottomSheetProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=MobileBottomSheet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MobileBottomSheet.d.ts","sourceRoot":"","sources":["../../components/MobileBottomSheet.tsx"],"names":[],"mappings":"AAIA,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzD,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,qDAAqD;IACrD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;CAC7C;AAQD,wBAAgB,iBAAiB,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,EAAE,sBAAsB,2CA0JlH"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
|
+
const COLLAPSED_H = 56;
|
|
5
|
+
const HALF_MAX_VH = 0.3;
|
|
6
|
+
const FULL_VH = 0.8;
|
|
7
|
+
const SNAP_ORDER = ["collapsed", "half", "full"];
|
|
8
|
+
export function MobileBottomSheet({ children, summary, snap: controlledSnap, onSnapChange }) {
|
|
9
|
+
const [internalSnap, setInternalSnap] = useState("collapsed");
|
|
10
|
+
const [dragging, setDragging] = useState(false);
|
|
11
|
+
const [dragOffset, setDragOffset] = useState(null);
|
|
12
|
+
const [contentHeight, setContentHeight] = useState(200);
|
|
13
|
+
const sheetRef = useRef(null);
|
|
14
|
+
const contentRef = useRef(null);
|
|
15
|
+
const startYRef = useRef(0);
|
|
16
|
+
const startHeightRef = useRef(0);
|
|
17
|
+
const snap = controlledSnap ?? internalSnap;
|
|
18
|
+
// Measure content to auto-size the "half" snap
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (!contentRef.current)
|
|
21
|
+
return;
|
|
22
|
+
const observer = new ResizeObserver((entries) => {
|
|
23
|
+
for (const entry of entries) {
|
|
24
|
+
setContentHeight(entry.contentRect.height);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
observer.observe(contentRef.current);
|
|
28
|
+
return () => observer.disconnect();
|
|
29
|
+
}, []);
|
|
30
|
+
const getSnapHeights = useCallback(() => {
|
|
31
|
+
const vh = typeof window !== "undefined" ? window.innerHeight : 800;
|
|
32
|
+
// "half" = just enough for content, capped at 30vh
|
|
33
|
+
const halfH = Math.min(contentHeight + COLLAPSED_H + 16, vh * HALF_MAX_VH);
|
|
34
|
+
return {
|
|
35
|
+
collapsed: COLLAPSED_H,
|
|
36
|
+
half: Math.max(halfH, COLLAPSED_H + 60),
|
|
37
|
+
full: vh * FULL_VH,
|
|
38
|
+
};
|
|
39
|
+
}, [contentHeight]);
|
|
40
|
+
const updateSnap = useCallback((next) => {
|
|
41
|
+
setInternalSnap(next);
|
|
42
|
+
onSnapChange?.(next);
|
|
43
|
+
}, [onSnapChange]);
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (controlledSnap !== undefined) {
|
|
46
|
+
setInternalSnap(controlledSnap);
|
|
47
|
+
}
|
|
48
|
+
}, [controlledSnap]);
|
|
49
|
+
const handleTouchStart = useCallback((e) => {
|
|
50
|
+
const touch = e.touches[0];
|
|
51
|
+
if (!touch)
|
|
52
|
+
return;
|
|
53
|
+
startYRef.current = touch.clientY;
|
|
54
|
+
const el = sheetRef.current;
|
|
55
|
+
if (el) {
|
|
56
|
+
startHeightRef.current = el.getBoundingClientRect().height;
|
|
57
|
+
}
|
|
58
|
+
setDragging(true);
|
|
59
|
+
}, []);
|
|
60
|
+
const handleTouchMove = useCallback((e) => {
|
|
61
|
+
if (!dragging)
|
|
62
|
+
return;
|
|
63
|
+
const touch = e.touches[0];
|
|
64
|
+
if (!touch)
|
|
65
|
+
return;
|
|
66
|
+
const delta = startYRef.current - touch.clientY;
|
|
67
|
+
const newHeight = startHeightRef.current + delta;
|
|
68
|
+
const vh = window.innerHeight;
|
|
69
|
+
const clamped = Math.max(COLLAPSED_H, Math.min(vh * 0.9, newHeight));
|
|
70
|
+
setDragOffset(clamped);
|
|
71
|
+
}, [dragging]);
|
|
72
|
+
const handleTouchEnd = useCallback(() => {
|
|
73
|
+
setDragging(false);
|
|
74
|
+
if (dragOffset === null)
|
|
75
|
+
return;
|
|
76
|
+
const snapValues = getSnapHeights();
|
|
77
|
+
let closest = "collapsed";
|
|
78
|
+
let minDist = Infinity;
|
|
79
|
+
for (const pos of SNAP_ORDER) {
|
|
80
|
+
// pos is a SnapPosition union key — safe index.
|
|
81
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
82
|
+
const dist = Math.abs(dragOffset - snapValues[pos]);
|
|
83
|
+
if (dist < minDist) {
|
|
84
|
+
minDist = dist;
|
|
85
|
+
closest = pos;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const currentIdx = SNAP_ORDER.indexOf(snap);
|
|
89
|
+
if (currentIdx === 1 && dragOffset < snapValues.half - 30) {
|
|
90
|
+
closest = "collapsed";
|
|
91
|
+
}
|
|
92
|
+
else if (currentIdx === 1 && dragOffset > snapValues.half + 30) {
|
|
93
|
+
closest = "full";
|
|
94
|
+
}
|
|
95
|
+
updateSnap(closest);
|
|
96
|
+
setDragOffset(null);
|
|
97
|
+
}, [dragOffset, snap, updateSnap, getSnapHeights]);
|
|
98
|
+
const isCollapsed = snap === "collapsed" && dragOffset === null;
|
|
99
|
+
const snapPx = getSnapHeights();
|
|
100
|
+
const heightStr = dragOffset !== null
|
|
101
|
+
? `${dragOffset}px`
|
|
102
|
+
// snap is a SnapPosition union key — safe index.
|
|
103
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
104
|
+
: `${snapPx[snap]}px`;
|
|
105
|
+
return (_jsxs("div", { ref: sheetRef, className: "fixed inset-x-0 bottom-0 z-50 flex flex-col rounded-t-2xl bg-slate-900 shadow-2xl", style: {
|
|
106
|
+
height: heightStr,
|
|
107
|
+
transition: dragging ? "none" : "height 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
|
|
108
|
+
}, children: [_jsx("div", { className: "flex shrink-0 cursor-grab touch-none flex-col items-center pb-1 pt-2 active:cursor-grabbing", onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchEnd: handleTouchEnd, children: _jsx("div", { className: "h-1 w-10 rounded-full bg-slate-600" }) }), _jsx("div", { className: "flex shrink-0 items-center px-4 pb-1", onClick: () => {
|
|
109
|
+
if (isCollapsed)
|
|
110
|
+
updateSnap("half");
|
|
111
|
+
}, children: summary }), !isCollapsed && (_jsx("div", { className: "flex-1 overflow-y-auto", children: _jsx("div", { ref: contentRef, children: children }) }))] }));
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=MobileBottomSheet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MobileBottomSheet.js","sourceRoot":"","sources":["../../components/MobileBottomSheet.tsx"],"names":[],"mappings":"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"}
|