@cyber-harbour/ui 2.2.42 → 2.2.43
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/dist/{PdfDriver-WC4VPQWZ.js → PdfDriver-54FN6DBI.js} +2 -2
- package/dist/{PdfDriver-WC4VPQWZ.js.map → PdfDriver-54FN6DBI.js.map} +1 -1
- package/dist/{PdfDriver-GLFIED7A.mjs → PdfDriver-AVC3OSKE.mjs} +2 -2
- package/dist/{PdfDriver-GLFIED7A.mjs.map → PdfDriver-AVC3OSKE.mjs.map} +1 -1
- package/dist/{chunk-T6XGVEPQ.mjs → chunk-EGCG27KL.mjs} +3 -3
- package/dist/{chunk-T6XGVEPQ.mjs.map → chunk-EGCG27KL.mjs.map} +1 -1
- package/dist/{chunk-3MGYAJ6C.js → chunk-WRBRJBUL.js} +3 -3
- package/dist/{chunk-3MGYAJ6C.js.map → chunk-WRBRJBUL.js.map} +1 -1
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.js +44 -44
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/styles/tailwind.css +1 -1
- package/dist/styles/tailwind.css.map +1 -1
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var
|
|
2
|
-
//# sourceMappingURL=PdfDriver-
|
|
1
|
+
'use strict';var chunkWRBRJBUL_js=require('./chunk-WRBRJBUL.js'),react=require('react'),S=require('lodash.debounce'),reactPdf=require('react-pdf');require('react-pdf/dist/Page/AnnotationLayer.css'),require('react-pdf/dist/Page/TextLayer.css');var reactVirtuoso=require('react-virtuoso'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var S__default=/*#__PURE__*/_interopDefault(S);var f="/pdfjs";typeof window<"u"&&typeof document<"u"&&(reactPdf.pdfjs.GlobalWorkerOptions.workerSrc=`${f}/pdf.worker.min.js`);var te=1e3,re=400,oe=150,ne=70,se=1.414,D=400,ve=chunkWRBRJBUL_js.a(({url:_,initialPage:l,seamless:O=false})=>{let[s,C]=react.useState(0),[d,b]=react.useState(1),[U,E]=react.useState(true),[I,M]=react.useState(null),[v,k]=react.useState(D),[H,Z]=react.useState(D),[a,R]=react.useState(1),[p,$]=react.useState(D),[T,F]=react.useState(se),c=react.useRef(null),y=react.useRef(null),N=react.useRef(false),u=react.useRef(null),x=react.useRef(false),i=react.useCallback((e,t=true)=>{e<1||e>s||(N.current=true,y.current?.scrollToIndex({index:e-1,align:"start",behavior:t?"smooth":"auto"}),u.current&&clearTimeout(u.current),u.current=setTimeout(()=>{x.current&&(N.current=false);},te));},[s]),P=react.useMemo(()=>S__default.default((e,t=false)=>{i(e,t);},re),[i]),j=react.useCallback(()=>{R(e=>Math.min(e+.25,4));},[]),V=react.useCallback(()=>{R(e=>Math.max(e-.25,.25));},[]);react.useEffect(()=>{if(!c.current)return;let e=S__default.default(()=>{c.current&&(k(c.current.offsetWidth-ne),Z(c.current.clientHeight));},oe);e();let t=new ResizeObserver(e);return t.observe(c.current),()=>{t.disconnect(),e.cancel();}},[]);let z=react.useMemo(()=>({cMapPacked:true,cMapUrl:`${f}/cmaps/`,standardFontDataUrl:`${f}/standard_fonts/`,wasmUrl:`${f}/wasm/`,iccUrl:`${f}/icc/`}),[]),B=react.useCallback(({numPages:e})=>{C(e),E(false);},[]),G=react.useCallback(e=>{M(`Failed to load PDF: ${e.message}`),E(false);},[]),g=react.useCallback(e=>{let t=d+e;b(t),i(t);},[d,i]),W=react.useCallback(()=>{g(-1);},[g]),Y=react.useCallback(()=>{g(1);},[g]),J=react.useCallback(e=>{if(N.current)return;let t=e.startIndex+1;t!==d&&b(t);},[d]);return react.useEffect(()=>(x.current=true,()=>{x.current=false,P.cancel(),u.current&&clearTimeout(u.current);}),[P]),react.useEffect(()=>{!l||s===0||l>s||(b(l),i(l,false));},[l,s,i]),react.useEffect(()=>{$(v*a*T);},[v,a,T]),I?jsxRuntime.jsx("div",{className:"flex items-center justify-center h-full w-full px-8.5",children:jsxRuntime.jsx("div",{className:"text-red-500 text-center",children:jsxRuntime.jsx("p",{children:I})})}):jsxRuntime.jsxs("div",{className:"h-full w-full flex flex-col overflow-hidden",children:[U&&jsxRuntime.jsx("div",{className:"flex items-center justify-center h-full px-8.5",children:jsxRuntime.jsx("div",{className:"text-gray-500 dark:text-gray-400",children:"Loading PDF..."})}),jsxRuntime.jsx("div",{ref:c,className:"flex-1 overflow-hidden min-h-0",children:jsxRuntime.jsx(reactPdf.Document,{options:z,file:_,onLoadSuccess:B,onLoadError:G,loading:jsxRuntime.jsx("div",{className:"flex items-center justify-center",style:{height:p},children:jsxRuntime.jsx("div",{className:"h-10 w-10 rounded-full border border-2 border-gray-200 dark:border-neutral-700 animate-spin border-s-transparent"})}),children:jsxRuntime.jsx(reactVirtuoso.Virtuoso,{ref:y,style:{height:H||"calc(100dvh - 190px)",width:"100%",scrollbarGutter:"stable both-edges"},totalCount:s,rangeChanged:J,defaultItemHeight:p,itemContent:e=>jsxRuntime.jsx("div",{className:`mx-auto w-fit${O?"":" mb-4 border border-1 border-gray-100 dark:border-neutral-800"}`,children:jsxRuntime.jsx(reactPdf.Page,{pageNumber:e+1,renderTextLayer:true,renderAnnotationLayer:true,width:v*a,onLoadSuccess:t=>{if(e===0){let q=t.height/t.width;F(q);}},loading:jsxRuntime.jsx("div",{className:"flex items-center justify-center",style:{height:p},children:jsxRuntime.jsx("div",{className:"h-10 w-10 rounded-full border border-2 border-gray-200 dark:border-neutral-700 animate-spin border-s-transparent"})}),className:"h-auto w-full transition-[width] duration-[600ms] ease-in-out"})})})})}),s>0&&jsxRuntime.jsx(chunkWRBRJBUL_js.c,{zoom:{displayText:`${Math.round(a*100)}%`,onZoomIn:j,onZoomOut:V,canZoomIn:a<4,canZoomOut:a>.25},pagination:{page:d,total:s,onPrev:W,onNext:Y,onPageChange:chunkWRBRJBUL_js.a(e=>{b(e),P(e,false);},"onPageChange")}})]})},"PdfDriver");exports.PdfDriver=ve;//# sourceMappingURL=PdfDriver-54FN6DBI.js.map
|
|
2
|
+
//# sourceMappingURL=PdfDriver-54FN6DBI.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/FileViewer/drivers/PdfDriver/PdfDriver.tsx"],"names":["BASE_DIR","pdfjs","SCROLL_ANIMATION_DURATION","INPUT_DEBOUNCE_DELAY","RESIZE_DEBOUNCE_DELAY","CONTAINER_PADDING","DEFAULT_RATIO_A4","DEFAULT_MIN_SIZE","PdfDriver","__name","url","initialPage","seamless","numPages","setNumPages","useState","pageNumber","setPageNumber","loading","setLoading","error","setError","width","setWidth","height","setHeight","scale","setScale","defaultPageHeight","setDefaultPageHeight","pageAspectRatio","setPageAspectRatio","containerRef","useRef","virtuosoRef","isUserScrollingRef","scrollTimeoutRef","isMountedRef","scrollToPage","useCallback","page","smooth","debouncedScroll","useMemo","debounce","handleZoomIn","prev","handleZoomOut","useEffect","updateSize","observer","options","onDocumentLoadSuccess","onDocumentLoadError","changePage","offset","newPage","previousPage","nextPage","handleRangeChanged","range","visiblePage","jsx","jsxs","Document","Virtuoso","index","Page","ratio","ViewerToolbar"],"mappings":"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","file":"PdfDriver-WC4VPQWZ.js","sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport debounce from 'lodash.debounce';\nimport { Document, Page, pdfjs } from 'react-pdf';\nimport 'react-pdf/dist/Page/AnnotationLayer.css';\nimport 'react-pdf/dist/Page/TextLayer.css';\nimport { Virtuoso, VirtuosoHandle } from 'react-virtuoso';\nimport { ViewerToolbar } from '../../ViewerToolbar';\n\nconst BASE_DIR = '/pdfjs';\n\n// Set up the worker - self-hosted configuration (client-side only)\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\n pdfjs.GlobalWorkerOptions.workerSrc = `${BASE_DIR}/pdf.worker.min.js`;\n}\n\ninterface PdfDriverProps {\n url: string;\n initialPage?: number;\n /** Render pages flush — no gap/border between pages (e.g. website-to-PDF). */\n seamless?: boolean;\n}\nconst SCROLL_ANIMATION_DURATION = 1000;\nconst INPUT_DEBOUNCE_DELAY = 400;\nconst RESIZE_DEBOUNCE_DELAY = 150;\nconst CONTAINER_PADDING = 70;\nconst DEFAULT_RATIO_A4 = 1.414;\nconst DEFAULT_MIN_SIZE = 400;\n\nexport const PdfDriver: React.FC<PdfDriverProps> = ({ url, initialPage, seamless = false }) => {\n const [numPages, setNumPages] = useState<number>(0);\n const [pageNumber, setPageNumber] = useState<number>(1);\n const [loading, setLoading] = useState<boolean>(true);\n const [error, setError] = useState<string | null>(null);\n const [width, setWidth] = useState<number>(DEFAULT_MIN_SIZE);\n const [height, setHeight] = useState<number>(DEFAULT_MIN_SIZE);\n const [scale, setScale] = useState(1);\n const [defaultPageHeight, setDefaultPageHeight] = useState(DEFAULT_MIN_SIZE);\n const [pageAspectRatio, setPageAspectRatio] = useState(DEFAULT_RATIO_A4);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const virtuosoRef = useRef<VirtuosoHandle>(null);\n const isUserScrollingRef = useRef<boolean>(false);\n const scrollTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const isMountedRef = useRef(false);\n\n const scrollToPage = useCallback(\n (page: number, smooth = true) => {\n if (page < 1 || page > numPages) return;\n\n isUserScrollingRef.current = true;\n virtuosoRef.current?.scrollToIndex({\n index: page - 1,\n align: 'start',\n behavior: smooth ? 'smooth' : 'auto',\n });\n\n if (scrollTimeoutRef.current) {\n clearTimeout(scrollTimeoutRef.current);\n }\n\n scrollTimeoutRef.current = setTimeout(() => {\n if (isMountedRef.current) isUserScrollingRef.current = false;\n }, SCROLL_ANIMATION_DURATION);\n },\n [numPages]\n );\n\n const debouncedScroll = useMemo(() => {\n return debounce((page: number, smooth = false) => {\n scrollToPage(page, smooth);\n }, INPUT_DEBOUNCE_DELAY);\n }, [scrollToPage]);\n\n const handleZoomIn = useCallback(() => {\n setScale((prev) => Math.min(prev + 0.25, 4));\n }, []);\n\n const handleZoomOut = useCallback(() => {\n setScale((prev) => Math.max(prev - 0.25, 0.25));\n }, []);\n\n useEffect(() => {\n if (!containerRef.current) return;\n const updateSize = debounce(() => {\n if (containerRef.current) {\n setWidth(containerRef.current.offsetWidth - CONTAINER_PADDING);\n setHeight(containerRef.current.clientHeight);\n }\n }, RESIZE_DEBOUNCE_DELAY);\n updateSize();\n const observer = new ResizeObserver(updateSize);\n observer.observe(containerRef.current);\n return () => {\n observer.disconnect();\n updateSize.cancel();\n };\n }, []);\n\n const options = useMemo(\n () => ({\n cMapPacked: true,\n cMapUrl: `${BASE_DIR}/cmaps/`,\n standardFontDataUrl: `${BASE_DIR}/standard_fonts/`,\n wasmUrl: `${BASE_DIR}/wasm/`,\n iccUrl: `${BASE_DIR}/icc/`,\n }),\n []\n );\n\n const onDocumentLoadSuccess = useCallback(({ numPages }: { numPages: number }): void => {\n setNumPages(numPages);\n setLoading(false);\n }, []);\n\n const onDocumentLoadError = useCallback((error: Error): void => {\n setError(`Failed to load PDF: ${error.message}`);\n setLoading(false);\n }, []);\n\n const changePage = useCallback(\n (offset: number): void => {\n const newPage = pageNumber + offset;\n setPageNumber(newPage);\n scrollToPage(newPage);\n },\n [pageNumber, scrollToPage]\n );\n\n const previousPage = useCallback((): void => {\n changePage(-1);\n }, [changePage]);\n\n const nextPage = useCallback((): void => {\n changePage(1);\n }, [changePage]);\n\n const handleRangeChanged = useCallback(\n (range: { startIndex: number; endIndex: number }) => {\n if (isUserScrollingRef.current) {\n return;\n }\n const visiblePage = range.startIndex + 1;\n if (visiblePage !== pageNumber) {\n setPageNumber(visiblePage);\n }\n },\n [pageNumber]\n );\n\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n debouncedScroll.cancel();\n if (scrollTimeoutRef.current) {\n clearTimeout(scrollTimeoutRef.current);\n }\n };\n }, [debouncedScroll]);\n\n useEffect(() => {\n if (!initialPage || numPages === 0 || initialPage > numPages) return;\n setPageNumber(initialPage);\n scrollToPage(initialPage, false);\n }, [initialPage, numPages, scrollToPage]);\n\n useEffect(() => {\n setDefaultPageHeight(width * scale * pageAspectRatio);\n }, [width, scale, pageAspectRatio]);\n\n if (error) {\n return (\n <div className=\"flex items-center justify-center h-full w-full px-8.5\">\n <div className=\"text-red-500 text-center\">\n <p>{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"h-full w-full flex flex-col overflow-hidden\">\n {loading && (\n <div className=\"flex items-center justify-center h-full px-8.5\">\n <div className=\"text-gray-500 dark:text-gray-400\">Loading PDF...</div>\n </div>\n )}\n <div ref={containerRef} className=\"flex-1 overflow-hidden min-h-0\">\n <Document\n options={options}\n file={url}\n onLoadSuccess={onDocumentLoadSuccess}\n onLoadError={onDocumentLoadError}\n loading={\n <div className=\"flex items-center justify-center\" style={{ height: defaultPageHeight }}>\n <div className=\"h-10 w-10 rounded-full border border-2 border-gray-200 dark:border-neutral-700 animate-spin border-s-transparent\" />\n </div>\n }\n >\n <Virtuoso\n ref={virtuosoRef}\n style={{ height: height || 'calc(100dvh - 190px)', width: '100%', scrollbarGutter: 'stable both-edges' }}\n totalCount={numPages}\n rangeChanged={handleRangeChanged}\n defaultItemHeight={defaultPageHeight}\n itemContent={(index) => (\n <div className={`mx-auto w-fit${seamless ? '' : ' mb-4 border border-1 border-gray-100 dark:border-neutral-800'}`}>\n <Page\n pageNumber={index + 1}\n renderTextLayer={true}\n renderAnnotationLayer={true}\n width={width * scale}\n onLoadSuccess={(page) => {\n if (index === 0) {\n const ratio = page.height / page.width;\n setPageAspectRatio(ratio);\n }\n }}\n loading={\n <div className=\"flex items-center justify-center\" style={{ height: defaultPageHeight }}>\n <div className=\"h-10 w-10 rounded-full border border-2 border-gray-200 dark:border-neutral-700 animate-spin border-s-transparent\" />\n </div>\n }\n className=\"h-auto w-full transition-[width] duration-[600ms] ease-in-out\"\n />\n </div>\n )}\n />\n </Document>\n </div>\n {numPages > 0 && (\n <ViewerToolbar\n zoom={{\n displayText: `${Math.round(scale * 100)}%`,\n onZoomIn: handleZoomIn,\n onZoomOut: handleZoomOut,\n canZoomIn: scale < 4,\n canZoomOut: scale > 0.25,\n }}\n pagination={{\n page: pageNumber,\n total: numPages,\n onPrev: previousPage,\n onNext: nextPage,\n onPageChange: (page) => {\n setPageNumber(page);\n debouncedScroll(page, false);\n },\n }}\n />\n )}\n </div>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/FileViewer/drivers/PdfDriver/PdfDriver.tsx"],"names":["BASE_DIR","pdfjs","SCROLL_ANIMATION_DURATION","INPUT_DEBOUNCE_DELAY","RESIZE_DEBOUNCE_DELAY","CONTAINER_PADDING","DEFAULT_RATIO_A4","DEFAULT_MIN_SIZE","PdfDriver","__name","url","initialPage","seamless","numPages","setNumPages","useState","pageNumber","setPageNumber","loading","setLoading","error","setError","width","setWidth","height","setHeight","scale","setScale","defaultPageHeight","setDefaultPageHeight","pageAspectRatio","setPageAspectRatio","containerRef","useRef","virtuosoRef","isUserScrollingRef","scrollTimeoutRef","isMountedRef","scrollToPage","useCallback","page","smooth","debouncedScroll","useMemo","debounce","handleZoomIn","prev","handleZoomOut","useEffect","updateSize","observer","options","onDocumentLoadSuccess","onDocumentLoadError","changePage","offset","newPage","previousPage","nextPage","handleRangeChanged","range","visiblePage","jsx","jsxs","Document","Virtuoso","index","Page","ratio","ViewerToolbar"],"mappings":"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","file":"PdfDriver-54FN6DBI.js","sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport debounce from 'lodash.debounce';\nimport { Document, Page, pdfjs } from 'react-pdf';\nimport 'react-pdf/dist/Page/AnnotationLayer.css';\nimport 'react-pdf/dist/Page/TextLayer.css';\nimport { Virtuoso, VirtuosoHandle } from 'react-virtuoso';\nimport { ViewerToolbar } from '../../ViewerToolbar';\n\nconst BASE_DIR = '/pdfjs';\n\n// Set up the worker - self-hosted configuration (client-side only)\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\n pdfjs.GlobalWorkerOptions.workerSrc = `${BASE_DIR}/pdf.worker.min.js`;\n}\n\ninterface PdfDriverProps {\n url: string;\n initialPage?: number;\n /** Render pages flush — no gap/border between pages (e.g. website-to-PDF). */\n seamless?: boolean;\n}\nconst SCROLL_ANIMATION_DURATION = 1000;\nconst INPUT_DEBOUNCE_DELAY = 400;\nconst RESIZE_DEBOUNCE_DELAY = 150;\nconst CONTAINER_PADDING = 70;\nconst DEFAULT_RATIO_A4 = 1.414;\nconst DEFAULT_MIN_SIZE = 400;\n\nexport const PdfDriver: React.FC<PdfDriverProps> = ({ url, initialPage, seamless = false }) => {\n const [numPages, setNumPages] = useState<number>(0);\n const [pageNumber, setPageNumber] = useState<number>(1);\n const [loading, setLoading] = useState<boolean>(true);\n const [error, setError] = useState<string | null>(null);\n const [width, setWidth] = useState<number>(DEFAULT_MIN_SIZE);\n const [height, setHeight] = useState<number>(DEFAULT_MIN_SIZE);\n const [scale, setScale] = useState(1);\n const [defaultPageHeight, setDefaultPageHeight] = useState(DEFAULT_MIN_SIZE);\n const [pageAspectRatio, setPageAspectRatio] = useState(DEFAULT_RATIO_A4);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const virtuosoRef = useRef<VirtuosoHandle>(null);\n const isUserScrollingRef = useRef<boolean>(false);\n const scrollTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const isMountedRef = useRef(false);\n\n const scrollToPage = useCallback(\n (page: number, smooth = true) => {\n if (page < 1 || page > numPages) return;\n\n isUserScrollingRef.current = true;\n virtuosoRef.current?.scrollToIndex({\n index: page - 1,\n align: 'start',\n behavior: smooth ? 'smooth' : 'auto',\n });\n\n if (scrollTimeoutRef.current) {\n clearTimeout(scrollTimeoutRef.current);\n }\n\n scrollTimeoutRef.current = setTimeout(() => {\n if (isMountedRef.current) isUserScrollingRef.current = false;\n }, SCROLL_ANIMATION_DURATION);\n },\n [numPages]\n );\n\n const debouncedScroll = useMemo(() => {\n return debounce((page: number, smooth = false) => {\n scrollToPage(page, smooth);\n }, INPUT_DEBOUNCE_DELAY);\n }, [scrollToPage]);\n\n const handleZoomIn = useCallback(() => {\n setScale((prev) => Math.min(prev + 0.25, 4));\n }, []);\n\n const handleZoomOut = useCallback(() => {\n setScale((prev) => Math.max(prev - 0.25, 0.25));\n }, []);\n\n useEffect(() => {\n if (!containerRef.current) return;\n const updateSize = debounce(() => {\n if (containerRef.current) {\n setWidth(containerRef.current.offsetWidth - CONTAINER_PADDING);\n setHeight(containerRef.current.clientHeight);\n }\n }, RESIZE_DEBOUNCE_DELAY);\n updateSize();\n const observer = new ResizeObserver(updateSize);\n observer.observe(containerRef.current);\n return () => {\n observer.disconnect();\n updateSize.cancel();\n };\n }, []);\n\n const options = useMemo(\n () => ({\n cMapPacked: true,\n cMapUrl: `${BASE_DIR}/cmaps/`,\n standardFontDataUrl: `${BASE_DIR}/standard_fonts/`,\n wasmUrl: `${BASE_DIR}/wasm/`,\n iccUrl: `${BASE_DIR}/icc/`,\n }),\n []\n );\n\n const onDocumentLoadSuccess = useCallback(({ numPages }: { numPages: number }): void => {\n setNumPages(numPages);\n setLoading(false);\n }, []);\n\n const onDocumentLoadError = useCallback((error: Error): void => {\n setError(`Failed to load PDF: ${error.message}`);\n setLoading(false);\n }, []);\n\n const changePage = useCallback(\n (offset: number): void => {\n const newPage = pageNumber + offset;\n setPageNumber(newPage);\n scrollToPage(newPage);\n },\n [pageNumber, scrollToPage]\n );\n\n const previousPage = useCallback((): void => {\n changePage(-1);\n }, [changePage]);\n\n const nextPage = useCallback((): void => {\n changePage(1);\n }, [changePage]);\n\n const handleRangeChanged = useCallback(\n (range: { startIndex: number; endIndex: number }) => {\n if (isUserScrollingRef.current) {\n return;\n }\n const visiblePage = range.startIndex + 1;\n if (visiblePage !== pageNumber) {\n setPageNumber(visiblePage);\n }\n },\n [pageNumber]\n );\n\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n debouncedScroll.cancel();\n if (scrollTimeoutRef.current) {\n clearTimeout(scrollTimeoutRef.current);\n }\n };\n }, [debouncedScroll]);\n\n useEffect(() => {\n if (!initialPage || numPages === 0 || initialPage > numPages) return;\n setPageNumber(initialPage);\n scrollToPage(initialPage, false);\n }, [initialPage, numPages, scrollToPage]);\n\n useEffect(() => {\n setDefaultPageHeight(width * scale * pageAspectRatio);\n }, [width, scale, pageAspectRatio]);\n\n if (error) {\n return (\n <div className=\"flex items-center justify-center h-full w-full px-8.5\">\n <div className=\"text-red-500 text-center\">\n <p>{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"h-full w-full flex flex-col overflow-hidden\">\n {loading && (\n <div className=\"flex items-center justify-center h-full px-8.5\">\n <div className=\"text-gray-500 dark:text-gray-400\">Loading PDF...</div>\n </div>\n )}\n <div ref={containerRef} className=\"flex-1 overflow-hidden min-h-0\">\n <Document\n options={options}\n file={url}\n onLoadSuccess={onDocumentLoadSuccess}\n onLoadError={onDocumentLoadError}\n loading={\n <div className=\"flex items-center justify-center\" style={{ height: defaultPageHeight }}>\n <div className=\"h-10 w-10 rounded-full border border-2 border-gray-200 dark:border-neutral-700 animate-spin border-s-transparent\" />\n </div>\n }\n >\n <Virtuoso\n ref={virtuosoRef}\n style={{ height: height || 'calc(100dvh - 190px)', width: '100%', scrollbarGutter: 'stable both-edges' }}\n totalCount={numPages}\n rangeChanged={handleRangeChanged}\n defaultItemHeight={defaultPageHeight}\n itemContent={(index) => (\n <div className={`mx-auto w-fit${seamless ? '' : ' mb-4 border border-1 border-gray-100 dark:border-neutral-800'}`}>\n <Page\n pageNumber={index + 1}\n renderTextLayer={true}\n renderAnnotationLayer={true}\n width={width * scale}\n onLoadSuccess={(page) => {\n if (index === 0) {\n const ratio = page.height / page.width;\n setPageAspectRatio(ratio);\n }\n }}\n loading={\n <div className=\"flex items-center justify-center\" style={{ height: defaultPageHeight }}>\n <div className=\"h-10 w-10 rounded-full border border-2 border-gray-200 dark:border-neutral-700 animate-spin border-s-transparent\" />\n </div>\n }\n className=\"h-auto w-full transition-[width] duration-[600ms] ease-in-out\"\n />\n </div>\n )}\n />\n </Document>\n </div>\n {numPages > 0 && (\n <ViewerToolbar\n zoom={{\n displayText: `${Math.round(scale * 100)}%`,\n onZoomIn: handleZoomIn,\n onZoomOut: handleZoomOut,\n canZoomIn: scale < 4,\n canZoomOut: scale > 0.25,\n }}\n pagination={{\n page: pageNumber,\n total: numPages,\n onPrev: previousPage,\n onNext: nextPage,\n onPageChange: (page) => {\n setPageNumber(page);\n debouncedScroll(page, false);\n },\n }}\n />\n )}\n </div>\n );\n};\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {a,c}from'./chunk-
|
|
2
|
-
//# sourceMappingURL=PdfDriver-
|
|
1
|
+
import {a,c}from'./chunk-EGCG27KL.mjs';import {useState,useRef,useCallback,useMemo,useEffect}from'react';import S from'lodash.debounce';import {pdfjs,Document,Page}from'react-pdf';import'react-pdf/dist/Page/AnnotationLayer.css';import'react-pdf/dist/Page/TextLayer.css';import {Virtuoso}from'react-virtuoso';import {jsx,jsxs}from'react/jsx-runtime';var f="/pdfjs";typeof window<"u"&&typeof document<"u"&&(pdfjs.GlobalWorkerOptions.workerSrc=`${f}/pdf.worker.min.js`);var te=1e3,re=400,oe=150,ne=70,se=1.414,D=400,he=a(({url:_,initialPage:l,seamless:O=false})=>{let[s,C]=useState(0),[d,b]=useState(1),[U,E]=useState(true),[I,M]=useState(null),[v,k]=useState(D),[H,Z]=useState(D),[a$1,R]=useState(1),[p,$]=useState(D),[T,F]=useState(se),c$1=useRef(null),y=useRef(null),N=useRef(false),u=useRef(null),x=useRef(false),i=useCallback((e,t=true)=>{e<1||e>s||(N.current=true,y.current?.scrollToIndex({index:e-1,align:"start",behavior:t?"smooth":"auto"}),u.current&&clearTimeout(u.current),u.current=setTimeout(()=>{x.current&&(N.current=false);},te));},[s]),P=useMemo(()=>S((e,t=false)=>{i(e,t);},re),[i]),j=useCallback(()=>{R(e=>Math.min(e+.25,4));},[]),V=useCallback(()=>{R(e=>Math.max(e-.25,.25));},[]);useEffect(()=>{if(!c$1.current)return;let e=S(()=>{c$1.current&&(k(c$1.current.offsetWidth-ne),Z(c$1.current.clientHeight));},oe);e();let t=new ResizeObserver(e);return t.observe(c$1.current),()=>{t.disconnect(),e.cancel();}},[]);let z=useMemo(()=>({cMapPacked:true,cMapUrl:`${f}/cmaps/`,standardFontDataUrl:`${f}/standard_fonts/`,wasmUrl:`${f}/wasm/`,iccUrl:`${f}/icc/`}),[]),B=useCallback(({numPages:e})=>{C(e),E(false);},[]),G=useCallback(e=>{M(`Failed to load PDF: ${e.message}`),E(false);},[]),g=useCallback(e=>{let t=d+e;b(t),i(t);},[d,i]),W=useCallback(()=>{g(-1);},[g]),Y=useCallback(()=>{g(1);},[g]),J=useCallback(e=>{if(N.current)return;let t=e.startIndex+1;t!==d&&b(t);},[d]);return useEffect(()=>(x.current=true,()=>{x.current=false,P.cancel(),u.current&&clearTimeout(u.current);}),[P]),useEffect(()=>{!l||s===0||l>s||(b(l),i(l,false));},[l,s,i]),useEffect(()=>{$(v*a$1*T);},[v,a$1,T]),I?jsx("div",{className:"flex items-center justify-center h-full w-full px-8.5",children:jsx("div",{className:"text-red-500 text-center",children:jsx("p",{children:I})})}):jsxs("div",{className:"h-full w-full flex flex-col overflow-hidden",children:[U&&jsx("div",{className:"flex items-center justify-center h-full px-8.5",children:jsx("div",{className:"text-gray-500 dark:text-gray-400",children:"Loading PDF..."})}),jsx("div",{ref:c$1,className:"flex-1 overflow-hidden min-h-0",children:jsx(Document,{options:z,file:_,onLoadSuccess:B,onLoadError:G,loading:jsx("div",{className:"flex items-center justify-center",style:{height:p},children:jsx("div",{className:"h-10 w-10 rounded-full border border-2 border-gray-200 dark:border-neutral-700 animate-spin border-s-transparent"})}),children:jsx(Virtuoso,{ref:y,style:{height:H||"calc(100dvh - 190px)",width:"100%",scrollbarGutter:"stable both-edges"},totalCount:s,rangeChanged:J,defaultItemHeight:p,itemContent:e=>jsx("div",{className:`mx-auto w-fit${O?"":" mb-4 border border-1 border-gray-100 dark:border-neutral-800"}`,children:jsx(Page,{pageNumber:e+1,renderTextLayer:true,renderAnnotationLayer:true,width:v*a$1,onLoadSuccess:t=>{if(e===0){let q=t.height/t.width;F(q);}},loading:jsx("div",{className:"flex items-center justify-center",style:{height:p},children:jsx("div",{className:"h-10 w-10 rounded-full border border-2 border-gray-200 dark:border-neutral-700 animate-spin border-s-transparent"})}),className:"h-auto w-full transition-[width] duration-[600ms] ease-in-out"})})})})}),s>0&&jsx(c,{zoom:{displayText:`${Math.round(a$1*100)}%`,onZoomIn:j,onZoomOut:V,canZoomIn:a$1<4,canZoomOut:a$1>.25},pagination:{page:d,total:s,onPrev:W,onNext:Y,onPageChange:a(e=>{b(e),P(e,false);},"onPageChange")}})]})},"PdfDriver");export{he as PdfDriver};//# sourceMappingURL=PdfDriver-AVC3OSKE.mjs.map
|
|
2
|
+
//# sourceMappingURL=PdfDriver-AVC3OSKE.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/FileViewer/drivers/PdfDriver/PdfDriver.tsx"],"names":["BASE_DIR","pdfjs","SCROLL_ANIMATION_DURATION","INPUT_DEBOUNCE_DELAY","RESIZE_DEBOUNCE_DELAY","CONTAINER_PADDING","DEFAULT_RATIO_A4","DEFAULT_MIN_SIZE","PdfDriver","__name","url","initialPage","seamless","numPages","setNumPages","useState","pageNumber","setPageNumber","loading","setLoading","error","setError","width","setWidth","height","setHeight","scale","setScale","defaultPageHeight","setDefaultPageHeight","pageAspectRatio","setPageAspectRatio","containerRef","useRef","virtuosoRef","isUserScrollingRef","scrollTimeoutRef","isMountedRef","scrollToPage","useCallback","page","smooth","debouncedScroll","useMemo","debounce","handleZoomIn","prev","handleZoomOut","useEffect","updateSize","observer","options","onDocumentLoadSuccess","onDocumentLoadError","changePage","offset","newPage","previousPage","nextPage","handleRangeChanged","range","visiblePage","jsx","jsxs","Document","Virtuoso","index","Page","ratio","ViewerToolbar"],"mappings":"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","file":"PdfDriver-GLFIED7A.mjs","sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport debounce from 'lodash.debounce';\nimport { Document, Page, pdfjs } from 'react-pdf';\nimport 'react-pdf/dist/Page/AnnotationLayer.css';\nimport 'react-pdf/dist/Page/TextLayer.css';\nimport { Virtuoso, VirtuosoHandle } from 'react-virtuoso';\nimport { ViewerToolbar } from '../../ViewerToolbar';\n\nconst BASE_DIR = '/pdfjs';\n\n// Set up the worker - self-hosted configuration (client-side only)\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\n pdfjs.GlobalWorkerOptions.workerSrc = `${BASE_DIR}/pdf.worker.min.js`;\n}\n\ninterface PdfDriverProps {\n url: string;\n initialPage?: number;\n /** Render pages flush — no gap/border between pages (e.g. website-to-PDF). */\n seamless?: boolean;\n}\nconst SCROLL_ANIMATION_DURATION = 1000;\nconst INPUT_DEBOUNCE_DELAY = 400;\nconst RESIZE_DEBOUNCE_DELAY = 150;\nconst CONTAINER_PADDING = 70;\nconst DEFAULT_RATIO_A4 = 1.414;\nconst DEFAULT_MIN_SIZE = 400;\n\nexport const PdfDriver: React.FC<PdfDriverProps> = ({ url, initialPage, seamless = false }) => {\n const [numPages, setNumPages] = useState<number>(0);\n const [pageNumber, setPageNumber] = useState<number>(1);\n const [loading, setLoading] = useState<boolean>(true);\n const [error, setError] = useState<string | null>(null);\n const [width, setWidth] = useState<number>(DEFAULT_MIN_SIZE);\n const [height, setHeight] = useState<number>(DEFAULT_MIN_SIZE);\n const [scale, setScale] = useState(1);\n const [defaultPageHeight, setDefaultPageHeight] = useState(DEFAULT_MIN_SIZE);\n const [pageAspectRatio, setPageAspectRatio] = useState(DEFAULT_RATIO_A4);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const virtuosoRef = useRef<VirtuosoHandle>(null);\n const isUserScrollingRef = useRef<boolean>(false);\n const scrollTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const isMountedRef = useRef(false);\n\n const scrollToPage = useCallback(\n (page: number, smooth = true) => {\n if (page < 1 || page > numPages) return;\n\n isUserScrollingRef.current = true;\n virtuosoRef.current?.scrollToIndex({\n index: page - 1,\n align: 'start',\n behavior: smooth ? 'smooth' : 'auto',\n });\n\n if (scrollTimeoutRef.current) {\n clearTimeout(scrollTimeoutRef.current);\n }\n\n scrollTimeoutRef.current = setTimeout(() => {\n if (isMountedRef.current) isUserScrollingRef.current = false;\n }, SCROLL_ANIMATION_DURATION);\n },\n [numPages]\n );\n\n const debouncedScroll = useMemo(() => {\n return debounce((page: number, smooth = false) => {\n scrollToPage(page, smooth);\n }, INPUT_DEBOUNCE_DELAY);\n }, [scrollToPage]);\n\n const handleZoomIn = useCallback(() => {\n setScale((prev) => Math.min(prev + 0.25, 4));\n }, []);\n\n const handleZoomOut = useCallback(() => {\n setScale((prev) => Math.max(prev - 0.25, 0.25));\n }, []);\n\n useEffect(() => {\n if (!containerRef.current) return;\n const updateSize = debounce(() => {\n if (containerRef.current) {\n setWidth(containerRef.current.offsetWidth - CONTAINER_PADDING);\n setHeight(containerRef.current.clientHeight);\n }\n }, RESIZE_DEBOUNCE_DELAY);\n updateSize();\n const observer = new ResizeObserver(updateSize);\n observer.observe(containerRef.current);\n return () => {\n observer.disconnect();\n updateSize.cancel();\n };\n }, []);\n\n const options = useMemo(\n () => ({\n cMapPacked: true,\n cMapUrl: `${BASE_DIR}/cmaps/`,\n standardFontDataUrl: `${BASE_DIR}/standard_fonts/`,\n wasmUrl: `${BASE_DIR}/wasm/`,\n iccUrl: `${BASE_DIR}/icc/`,\n }),\n []\n );\n\n const onDocumentLoadSuccess = useCallback(({ numPages }: { numPages: number }): void => {\n setNumPages(numPages);\n setLoading(false);\n }, []);\n\n const onDocumentLoadError = useCallback((error: Error): void => {\n setError(`Failed to load PDF: ${error.message}`);\n setLoading(false);\n }, []);\n\n const changePage = useCallback(\n (offset: number): void => {\n const newPage = pageNumber + offset;\n setPageNumber(newPage);\n scrollToPage(newPage);\n },\n [pageNumber, scrollToPage]\n );\n\n const previousPage = useCallback((): void => {\n changePage(-1);\n }, [changePage]);\n\n const nextPage = useCallback((): void => {\n changePage(1);\n }, [changePage]);\n\n const handleRangeChanged = useCallback(\n (range: { startIndex: number; endIndex: number }) => {\n if (isUserScrollingRef.current) {\n return;\n }\n const visiblePage = range.startIndex + 1;\n if (visiblePage !== pageNumber) {\n setPageNumber(visiblePage);\n }\n },\n [pageNumber]\n );\n\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n debouncedScroll.cancel();\n if (scrollTimeoutRef.current) {\n clearTimeout(scrollTimeoutRef.current);\n }\n };\n }, [debouncedScroll]);\n\n useEffect(() => {\n if (!initialPage || numPages === 0 || initialPage > numPages) return;\n setPageNumber(initialPage);\n scrollToPage(initialPage, false);\n }, [initialPage, numPages, scrollToPage]);\n\n useEffect(() => {\n setDefaultPageHeight(width * scale * pageAspectRatio);\n }, [width, scale, pageAspectRatio]);\n\n if (error) {\n return (\n <div className=\"flex items-center justify-center h-full w-full px-8.5\">\n <div className=\"text-red-500 text-center\">\n <p>{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"h-full w-full flex flex-col overflow-hidden\">\n {loading && (\n <div className=\"flex items-center justify-center h-full px-8.5\">\n <div className=\"text-gray-500 dark:text-gray-400\">Loading PDF...</div>\n </div>\n )}\n <div ref={containerRef} className=\"flex-1 overflow-hidden min-h-0\">\n <Document\n options={options}\n file={url}\n onLoadSuccess={onDocumentLoadSuccess}\n onLoadError={onDocumentLoadError}\n loading={\n <div className=\"flex items-center justify-center\" style={{ height: defaultPageHeight }}>\n <div className=\"h-10 w-10 rounded-full border border-2 border-gray-200 dark:border-neutral-700 animate-spin border-s-transparent\" />\n </div>\n }\n >\n <Virtuoso\n ref={virtuosoRef}\n style={{ height: height || 'calc(100dvh - 190px)', width: '100%', scrollbarGutter: 'stable both-edges' }}\n totalCount={numPages}\n rangeChanged={handleRangeChanged}\n defaultItemHeight={defaultPageHeight}\n itemContent={(index) => (\n <div className={`mx-auto w-fit${seamless ? '' : ' mb-4 border border-1 border-gray-100 dark:border-neutral-800'}`}>\n <Page\n pageNumber={index + 1}\n renderTextLayer={true}\n renderAnnotationLayer={true}\n width={width * scale}\n onLoadSuccess={(page) => {\n if (index === 0) {\n const ratio = page.height / page.width;\n setPageAspectRatio(ratio);\n }\n }}\n loading={\n <div className=\"flex items-center justify-center\" style={{ height: defaultPageHeight }}>\n <div className=\"h-10 w-10 rounded-full border border-2 border-gray-200 dark:border-neutral-700 animate-spin border-s-transparent\" />\n </div>\n }\n className=\"h-auto w-full transition-[width] duration-[600ms] ease-in-out\"\n />\n </div>\n )}\n />\n </Document>\n </div>\n {numPages > 0 && (\n <ViewerToolbar\n zoom={{\n displayText: `${Math.round(scale * 100)}%`,\n onZoomIn: handleZoomIn,\n onZoomOut: handleZoomOut,\n canZoomIn: scale < 4,\n canZoomOut: scale > 0.25,\n }}\n pagination={{\n page: pageNumber,\n total: numPages,\n onPrev: previousPage,\n onNext: nextPage,\n onPageChange: (page) => {\n setPageNumber(page);\n debouncedScroll(page, false);\n },\n }}\n />\n )}\n </div>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/FileViewer/drivers/PdfDriver/PdfDriver.tsx"],"names":["BASE_DIR","pdfjs","SCROLL_ANIMATION_DURATION","INPUT_DEBOUNCE_DELAY","RESIZE_DEBOUNCE_DELAY","CONTAINER_PADDING","DEFAULT_RATIO_A4","DEFAULT_MIN_SIZE","PdfDriver","__name","url","initialPage","seamless","numPages","setNumPages","useState","pageNumber","setPageNumber","loading","setLoading","error","setError","width","setWidth","height","setHeight","scale","setScale","defaultPageHeight","setDefaultPageHeight","pageAspectRatio","setPageAspectRatio","containerRef","useRef","virtuosoRef","isUserScrollingRef","scrollTimeoutRef","isMountedRef","scrollToPage","useCallback","page","smooth","debouncedScroll","useMemo","debounce","handleZoomIn","prev","handleZoomOut","useEffect","updateSize","observer","options","onDocumentLoadSuccess","onDocumentLoadError","changePage","offset","newPage","previousPage","nextPage","handleRangeChanged","range","visiblePage","jsx","jsxs","Document","Virtuoso","index","Page","ratio","ViewerToolbar"],"mappings":"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","file":"PdfDriver-AVC3OSKE.mjs","sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport debounce from 'lodash.debounce';\nimport { Document, Page, pdfjs } from 'react-pdf';\nimport 'react-pdf/dist/Page/AnnotationLayer.css';\nimport 'react-pdf/dist/Page/TextLayer.css';\nimport { Virtuoso, VirtuosoHandle } from 'react-virtuoso';\nimport { ViewerToolbar } from '../../ViewerToolbar';\n\nconst BASE_DIR = '/pdfjs';\n\n// Set up the worker - self-hosted configuration (client-side only)\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\n pdfjs.GlobalWorkerOptions.workerSrc = `${BASE_DIR}/pdf.worker.min.js`;\n}\n\ninterface PdfDriverProps {\n url: string;\n initialPage?: number;\n /** Render pages flush — no gap/border between pages (e.g. website-to-PDF). */\n seamless?: boolean;\n}\nconst SCROLL_ANIMATION_DURATION = 1000;\nconst INPUT_DEBOUNCE_DELAY = 400;\nconst RESIZE_DEBOUNCE_DELAY = 150;\nconst CONTAINER_PADDING = 70;\nconst DEFAULT_RATIO_A4 = 1.414;\nconst DEFAULT_MIN_SIZE = 400;\n\nexport const PdfDriver: React.FC<PdfDriverProps> = ({ url, initialPage, seamless = false }) => {\n const [numPages, setNumPages] = useState<number>(0);\n const [pageNumber, setPageNumber] = useState<number>(1);\n const [loading, setLoading] = useState<boolean>(true);\n const [error, setError] = useState<string | null>(null);\n const [width, setWidth] = useState<number>(DEFAULT_MIN_SIZE);\n const [height, setHeight] = useState<number>(DEFAULT_MIN_SIZE);\n const [scale, setScale] = useState(1);\n const [defaultPageHeight, setDefaultPageHeight] = useState(DEFAULT_MIN_SIZE);\n const [pageAspectRatio, setPageAspectRatio] = useState(DEFAULT_RATIO_A4);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const virtuosoRef = useRef<VirtuosoHandle>(null);\n const isUserScrollingRef = useRef<boolean>(false);\n const scrollTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const isMountedRef = useRef(false);\n\n const scrollToPage = useCallback(\n (page: number, smooth = true) => {\n if (page < 1 || page > numPages) return;\n\n isUserScrollingRef.current = true;\n virtuosoRef.current?.scrollToIndex({\n index: page - 1,\n align: 'start',\n behavior: smooth ? 'smooth' : 'auto',\n });\n\n if (scrollTimeoutRef.current) {\n clearTimeout(scrollTimeoutRef.current);\n }\n\n scrollTimeoutRef.current = setTimeout(() => {\n if (isMountedRef.current) isUserScrollingRef.current = false;\n }, SCROLL_ANIMATION_DURATION);\n },\n [numPages]\n );\n\n const debouncedScroll = useMemo(() => {\n return debounce((page: number, smooth = false) => {\n scrollToPage(page, smooth);\n }, INPUT_DEBOUNCE_DELAY);\n }, [scrollToPage]);\n\n const handleZoomIn = useCallback(() => {\n setScale((prev) => Math.min(prev + 0.25, 4));\n }, []);\n\n const handleZoomOut = useCallback(() => {\n setScale((prev) => Math.max(prev - 0.25, 0.25));\n }, []);\n\n useEffect(() => {\n if (!containerRef.current) return;\n const updateSize = debounce(() => {\n if (containerRef.current) {\n setWidth(containerRef.current.offsetWidth - CONTAINER_PADDING);\n setHeight(containerRef.current.clientHeight);\n }\n }, RESIZE_DEBOUNCE_DELAY);\n updateSize();\n const observer = new ResizeObserver(updateSize);\n observer.observe(containerRef.current);\n return () => {\n observer.disconnect();\n updateSize.cancel();\n };\n }, []);\n\n const options = useMemo(\n () => ({\n cMapPacked: true,\n cMapUrl: `${BASE_DIR}/cmaps/`,\n standardFontDataUrl: `${BASE_DIR}/standard_fonts/`,\n wasmUrl: `${BASE_DIR}/wasm/`,\n iccUrl: `${BASE_DIR}/icc/`,\n }),\n []\n );\n\n const onDocumentLoadSuccess = useCallback(({ numPages }: { numPages: number }): void => {\n setNumPages(numPages);\n setLoading(false);\n }, []);\n\n const onDocumentLoadError = useCallback((error: Error): void => {\n setError(`Failed to load PDF: ${error.message}`);\n setLoading(false);\n }, []);\n\n const changePage = useCallback(\n (offset: number): void => {\n const newPage = pageNumber + offset;\n setPageNumber(newPage);\n scrollToPage(newPage);\n },\n [pageNumber, scrollToPage]\n );\n\n const previousPage = useCallback((): void => {\n changePage(-1);\n }, [changePage]);\n\n const nextPage = useCallback((): void => {\n changePage(1);\n }, [changePage]);\n\n const handleRangeChanged = useCallback(\n (range: { startIndex: number; endIndex: number }) => {\n if (isUserScrollingRef.current) {\n return;\n }\n const visiblePage = range.startIndex + 1;\n if (visiblePage !== pageNumber) {\n setPageNumber(visiblePage);\n }\n },\n [pageNumber]\n );\n\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n debouncedScroll.cancel();\n if (scrollTimeoutRef.current) {\n clearTimeout(scrollTimeoutRef.current);\n }\n };\n }, [debouncedScroll]);\n\n useEffect(() => {\n if (!initialPage || numPages === 0 || initialPage > numPages) return;\n setPageNumber(initialPage);\n scrollToPage(initialPage, false);\n }, [initialPage, numPages, scrollToPage]);\n\n useEffect(() => {\n setDefaultPageHeight(width * scale * pageAspectRatio);\n }, [width, scale, pageAspectRatio]);\n\n if (error) {\n return (\n <div className=\"flex items-center justify-center h-full w-full px-8.5\">\n <div className=\"text-red-500 text-center\">\n <p>{error}</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"h-full w-full flex flex-col overflow-hidden\">\n {loading && (\n <div className=\"flex items-center justify-center h-full px-8.5\">\n <div className=\"text-gray-500 dark:text-gray-400\">Loading PDF...</div>\n </div>\n )}\n <div ref={containerRef} className=\"flex-1 overflow-hidden min-h-0\">\n <Document\n options={options}\n file={url}\n onLoadSuccess={onDocumentLoadSuccess}\n onLoadError={onDocumentLoadError}\n loading={\n <div className=\"flex items-center justify-center\" style={{ height: defaultPageHeight }}>\n <div className=\"h-10 w-10 rounded-full border border-2 border-gray-200 dark:border-neutral-700 animate-spin border-s-transparent\" />\n </div>\n }\n >\n <Virtuoso\n ref={virtuosoRef}\n style={{ height: height || 'calc(100dvh - 190px)', width: '100%', scrollbarGutter: 'stable both-edges' }}\n totalCount={numPages}\n rangeChanged={handleRangeChanged}\n defaultItemHeight={defaultPageHeight}\n itemContent={(index) => (\n <div className={`mx-auto w-fit${seamless ? '' : ' mb-4 border border-1 border-gray-100 dark:border-neutral-800'}`}>\n <Page\n pageNumber={index + 1}\n renderTextLayer={true}\n renderAnnotationLayer={true}\n width={width * scale}\n onLoadSuccess={(page) => {\n if (index === 0) {\n const ratio = page.height / page.width;\n setPageAspectRatio(ratio);\n }\n }}\n loading={\n <div className=\"flex items-center justify-center\" style={{ height: defaultPageHeight }}>\n <div className=\"h-10 w-10 rounded-full border border-2 border-gray-200 dark:border-neutral-700 animate-spin border-s-transparent\" />\n </div>\n }\n className=\"h-auto w-full transition-[width] duration-[600ms] ease-in-out\"\n />\n </div>\n )}\n />\n </Document>\n </div>\n {numPages > 0 && (\n <ViewerToolbar\n zoom={{\n displayText: `${Math.round(scale * 100)}%`,\n onZoomIn: handleZoomIn,\n onZoomOut: handleZoomOut,\n canZoomIn: scale < 4,\n canZoomOut: scale > 0.25,\n }}\n pagination={{\n page: pageNumber,\n total: numPages,\n onPrev: previousPage,\n onNext: nextPage,\n onPageChange: (page) => {\n setPageNumber(page);\n debouncedScroll(page, false);\n },\n }}\n />\n )}\n </div>\n );\n};\n"]}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {useState,useEffect}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var f=Object.defineProperty;var n=(e,t)=>f(e,"name",{value:t,configurable:true});var g=n(e=>jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:jsx("path",{d:"M3.33301 8.66732V7.33398H12.6663V8.66732H3.33301Z",fill:"currentColor"})}),"RemoveIcon"),p=n(e=>jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:jsx("path",{d:"M7.33333 14V8.66667H2V7.33333H7.33333V2H8.66667V7.33333H14V8.66667H8.66667V14H7.33333Z",fill:"currentColor"})}),"Add2Icon"),x=n(e=>jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:jsx("path",{d:"M12.7803 17.5303C12.4874 17.8232 12.0126 17.8232 11.7197 17.5303L7.46967 13.2803C7.17678 12.9874 7.17678 12.5126 7.46967 12.2197L11.7197 7.96967C12.0126 7.67678 12.4874 7.67678 12.7803 7.96967C13.0732 8.26256 13.0732 8.73744 12.7803 9.03033L9.81066 12H17.25C17.6642 12 18 12.3358 18 12.75C18 13.1642 17.6642 13.5 17.25 13.5H9.81066L12.7803 16.4697C13.0732 16.7626 13.0732 17.2374 12.7803 17.5303Z",fill:"currentColor"})}),"ArrowLeftLineIcon"),v=n(e=>jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:jsx("path",{d:"M12.2197 6.96967C12.5126 6.67678 12.9874 6.67678 13.2803 6.96967L17.5303 11.2197C17.8232 11.5126 17.8232 11.9874 17.5303 12.2803L13.2803 16.5303C12.9874 16.8232 12.5126 16.8232 12.2197 16.5303C11.9268 16.2374 11.9268 15.7626 12.2197 15.4697L15.1893 12.5H7.75C7.33579 12.5 7 12.1642 7 11.75C7 11.3358 7.33579 11 7.75 11H15.1893L12.2197 8.03033C11.9268 7.73744 11.9268 7.26256 12.2197 6.96967Z",fill:"currentColor"})}),"ArrowRightLineIcon");var k="inline-flex items-center justify-center w-
|
|
2
|
-
export{n as a,c as b,R as c};//# sourceMappingURL=chunk-
|
|
3
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
import {useState,useEffect}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var f=Object.defineProperty;var n=(e,t)=>f(e,"name",{value:t,configurable:true});var g=n(e=>jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:jsx("path",{d:"M3.33301 8.66732V7.33398H12.6663V8.66732H3.33301Z",fill:"currentColor"})}),"RemoveIcon"),p=n(e=>jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:jsx("path",{d:"M7.33333 14V8.66667H2V7.33333H7.33333V2H8.66667V7.33333H14V8.66667H8.66667V14H7.33333Z",fill:"currentColor"})}),"Add2Icon"),x=n(e=>jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:jsx("path",{d:"M12.7803 17.5303C12.4874 17.8232 12.0126 17.8232 11.7197 17.5303L7.46967 13.2803C7.17678 12.9874 7.17678 12.5126 7.46967 12.2197L11.7197 7.96967C12.0126 7.67678 12.4874 7.67678 12.7803 7.96967C13.0732 8.26256 13.0732 8.73744 12.7803 9.03033L9.81066 12H17.25C17.6642 12 18 12.3358 18 12.75C18 13.1642 17.6642 13.5 17.25 13.5H9.81066L12.7803 16.4697C13.0732 16.7626 13.0732 17.2374 12.7803 17.5303Z",fill:"currentColor"})}),"ArrowLeftLineIcon"),v=n(e=>jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:jsx("path",{d:"M12.2197 6.96967C12.5126 6.67678 12.9874 6.67678 13.2803 6.96967L17.5303 11.2197C17.8232 11.5126 17.8232 11.9874 17.5303 12.2803L13.2803 16.5303C12.9874 16.8232 12.5126 16.8232 12.2197 16.5303C11.9268 16.2374 11.9268 15.7626 12.2197 15.4697L15.1893 12.5H7.75C7.33579 12.5 7 12.1642 7 11.75C7 11.3358 7.33579 11 7.75 11H15.1893L12.2197 8.03033C11.9268 7.73744 11.9268 7.26256 12.2197 6.96967Z",fill:"currentColor"})}),"ArrowRightLineIcon");var k="inline-flex items-center justify-center w-7 h-7 rounded-[4px] border border-gray-400 dark:border-neutral-600 bg-transparent text-gray-700 dark:text-neutral-200 transition-colors shrink-0 enabled:hover:bg-black/5 enabled:dark:hover:bg-white/10 enabled:cursor-pointer disabled:border-gray-300 dark:disabled:border-neutral-700 disabled:text-gray-300 dark:disabled:text-neutral-600 disabled:cursor-not-allowed",u="inline-flex items-center justify-center gap-0.5 h-7 px-2 rounded-[4px] border border-gray-400 dark:border-neutral-600 bg-transparent text-[14px] font-normal leading-none text-gray-900 dark:text-neutral-100 select-none shrink-0",c=n(({icon:e,label:t,onClick:a,disabled:l,active:r,className:b})=>jsx("button",{type:"button","aria-label":t,onClick:a,disabled:l,className:`${k} ${r?"bg-blue-50! dark:bg-neutral-700! text-blue-600! dark:text-blue-400!":""} ${b??""}`,children:e}),"ToolbarIconButton"),w=n(({children:e,onClick:t,active:a,label:l,className:r})=>t?jsx("button",{type:"button","aria-label":l??"reset zoom",onClick:t,className:`${u} cursor-pointer transition-colors hover:bg-blue-50 dark:hover:bg-neutral-700 ${a?"bg-blue-50! dark:bg-neutral-700! text-blue-600! dark:text-blue-400! border-blue-200! dark:border-neutral-500!":""} ${r??""}`,children:e}):jsx("span",{className:`${u} ${r??""}`,children:e}),"ToolbarValueBox"),h={width:15,height:15},L=n(({page:e,total:t,onPageChange:a})=>{let[l,r]=useState(String(e));return useEffect(()=>{r(String(e));},[e]),a?jsxs("span",{className:`${u} min-w-11`,children:[jsx("input",{type:"number",min:1,max:t,value:l,"aria-label":"page number",onChange:b=>{r(b.target.value);let d=parseInt(b.target.value,10);!Number.isNaN(d)&&d>=1&&d<=t&&a(d);},onBlur:()=>r(String(e)),style:{width:`${String(t).length+1}ch`},className:"bg-transparent text-end outline-none [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"}),jsxs("span",{className:"text-gray-400 dark:text-neutral-500",children:["/",t]})]}):jsxs(w,{className:"min-w-11",children:[e,"/",t]})},"PageBox"),R=n(({zoom:e,pagination:t,leftExtra:a,rightExtra:l,className:r})=>!e&&!t&&!a&&!l?null:jsxs("div",{className:`flex items-center justify-between gap-3 px-4 py-2.5 shrink-0 border-t border-[var(--section-border,#aeadac)] bg-[var(--sidebar-bg,#f7f6f5)] ${r??""}`,children:[jsxs("div",{className:"flex items-center gap-2",children:[e&&jsxs(Fragment,{children:[jsx(c,{icon:jsx(g,{style:{width:15,height:15}}),label:e.zoomOutLabel??"zoom out",onClick:e.onZoomOut,disabled:e.canZoomOut===false}),jsx(w,{onClick:e.onReset,active:e.resetActive,label:e.resetLabel,children:e.displayText}),jsx(c,{icon:jsx(p,{style:{width:15,height:15}}),label:e.zoomInLabel??"zoom in",onClick:e.onZoomIn,disabled:e.canZoomIn===false})]}),a]}),jsxs("div",{className:"flex items-center gap-2",children:[l,t&&jsxs(Fragment,{children:[jsx(c,{icon:jsx(x,{style:h}),label:t.prevLabel??"previous page",onClick:t.onPrev,disabled:t.page<=1}),jsx(L,{page:t.page,total:t.total,onPageChange:t.onPageChange}),jsx(c,{icon:jsx(v,{style:h}),label:t.nextLabel??"next page",onClick:t.onNext,disabled:t.page>=t.total})]})]})]}),"ViewerToolbar");
|
|
2
|
+
export{n as a,c as b,R as c};//# sourceMappingURL=chunk-EGCG27KL.mjs.map
|
|
3
|
+
//# sourceMappingURL=chunk-EGCG27KL.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/FileViewer/ViewerToolbar/ViewerToolbar.tsx","../src/FileViewer/ViewerToolbar/icons.tsx"],"names":["RemoveIcon","__name","props","jsx","Add2Icon","ArrowLeftLineIcon","ArrowRightLineIcon","ICON_BUTTON_CLASS","VALUE_BOX_CLASS","ToolbarIconButton","icon","label","onClick","disabled","active","className","ToolbarValueBox","children","ARROW_STYLE","PageBox","page","total","onPageChange","draft","setDraft","useState","useEffect","jsxs","e","next","ViewerToolbar","zoom","pagination","leftExtra","rightExtra","Fragment"],"mappings":"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","file":"chunk-T6XGVEPQ.mjs","sourcesContent":["import { ReactNode, useEffect, useState } from 'react';\nimport { Add2Icon, ArrowLeftLineIcon, ArrowRightLineIcon, RemoveIcon } from './icons';\n\nexport interface ViewerToolbarZoom {\n /** Text shown in the value box, e.g. \"100%\" or \"Fit\". */\n displayText: string;\n onZoomIn: () => void;\n onZoomOut: () => void;\n /** Optional click handler on the value box (e.g. fit-to-screen / reset). */\n onReset?: () => void;\n /** Visual highlight of the value box (e.g. adaptive/fit mode active). */\n resetActive?: boolean;\n canZoomIn?: boolean;\n canZoomOut?: boolean;\n zoomOutLabel?: string;\n zoomInLabel?: string;\n resetLabel?: string;\n}\n\nexport interface ViewerToolbarPagination {\n page: number;\n total: number;\n onPrev: () => void;\n onNext: () => void;\n /** When provided the current page becomes an editable input. */\n onPageChange?: (page: number) => void;\n prevLabel?: string;\n nextLabel?: string;\n}\n\nexport interface ViewerToolbarProps {\n zoom?: ViewerToolbarZoom;\n pagination?: ViewerToolbarPagination;\n /** Extra controls rendered next to the zoom group (left side). */\n leftExtra?: ReactNode;\n /** Extra controls rendered next to the pagination group (right side). */\n rightExtra?: ReactNode;\n className?: string;\n}\n\nconst ICON_BUTTON_CLASS =\n 'inline-flex items-center justify-center w-6 h-6 rounded-[4px] border border-gray-400 dark:border-neutral-600 ' +\n 'bg-transparent text-gray-700 dark:text-neutral-200 transition-colors shrink-0 ' +\n 'enabled:hover:bg-black/5 enabled:dark:hover:bg-white/10 enabled:cursor-pointer ' +\n 'disabled:border-gray-300 dark:disabled:border-neutral-700 disabled:text-gray-300 dark:disabled:text-neutral-600 disabled:cursor-not-allowed';\n\nconst VALUE_BOX_CLASS =\n 'inline-flex items-center justify-center gap-0.5 h-9 px-2 rounded-[4px] border ' +\n 'border-gray-400 dark:border-neutral-600 bg-transparent ' +\n 'text-[14px] font-normal leading-none text-gray-900 dark:text-neutral-100 select-none shrink-0';\n\ninterface ToolbarIconButtonProps {\n icon: ReactNode;\n label: string;\n onClick?: () => void;\n disabled?: boolean;\n active?: boolean;\n className?: string;\n}\n\n/** Bordered square icon button — the single visual language for all viewer controls. */\nexport const ToolbarIconButton = ({ icon, label, onClick, disabled, active, className }: ToolbarIconButtonProps) => (\n <button\n type=\"button\"\n aria-label={label}\n onClick={onClick}\n disabled={disabled}\n className={`${ICON_BUTTON_CLASS} ${active ? 'bg-blue-50! dark:bg-neutral-700! text-blue-600! dark:text-blue-400!' : ''} ${className ?? ''}`}\n >\n {icon}\n </button>\n);\n\ninterface ToolbarValueBoxProps {\n children: ReactNode;\n onClick?: () => void;\n active?: boolean;\n label?: string;\n className?: string;\n}\n\n/** Bordered value box (zoom %, page indicator). Becomes a button when onClick is set. */\nexport const ToolbarValueBox = ({ children, onClick, active, label, className }: ToolbarValueBoxProps) => {\n if (onClick) {\n return (\n <button\n type=\"button\"\n aria-label={label ?? 'reset zoom'}\n onClick={onClick}\n className={`${VALUE_BOX_CLASS} cursor-pointer transition-colors hover:bg-blue-50 dark:hover:bg-neutral-700 ${active ? 'bg-blue-50! dark:bg-neutral-700! text-blue-600! dark:text-blue-400! border-blue-200! dark:border-neutral-500!' : ''} ${className ?? ''}`}\n >\n {children}\n </button>\n );\n }\n return <span className={`${VALUE_BOX_CLASS} ${className ?? ''}`}>{children}</span>;\n};\n\nconst ARROW_STYLE = { width: 16, height: 16 } as const;\n\nconst PageBox = ({ page, total, onPageChange }: Required<Pick<ViewerToolbarPagination, 'page' | 'total'>> & Pick<ViewerToolbarPagination, 'onPageChange'>) => {\n const [draft, setDraft] = useState(String(page));\n\n // Keep the input in sync when the page changes from scrolling / prev-next.\n useEffect(() => {\n setDraft(String(page));\n }, [page]);\n\n if (!onPageChange) {\n return (\n <ToolbarValueBox className=\"min-w-11\">\n {page}/{total}\n </ToolbarValueBox>\n );\n }\n\n return (\n <span className={`${VALUE_BOX_CLASS} min-w-11`}>\n <input\n type=\"number\"\n min={1}\n max={total}\n value={draft}\n aria-label=\"page number\"\n onChange={(e) => {\n setDraft(e.target.value);\n const next = parseInt(e.target.value, 10);\n if (!Number.isNaN(next) && next >= 1 && next <= total) onPageChange(next);\n }}\n // Valid values are already dispatched on change; on blur just snap the\n // draft back to the confirmed page (reverts an out-of-range entry).\n onBlur={() => setDraft(String(page))}\n style={{ width: `${String(total).length + 1}ch` }}\n className=\"bg-transparent text-end outline-none [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none\"\n />\n <span className=\"text-gray-400 dark:text-neutral-500\">/{total}</span>\n </span>\n );\n};\n\n/**\n * Unified bottom toolbar for all file viewer drivers.\n * Zoom controls live on the left, pagination on the right; each driver opts into\n * only the groups it supports (adaptive per capability).\n */\nexport const ViewerToolbar = ({ zoom, pagination, leftExtra, rightExtra, className }: ViewerToolbarProps) => {\n if (!zoom && !pagination && !leftExtra && !rightExtra) return null;\n\n return (\n <div\n className={`flex items-center justify-between gap-3 px-4 py-2.5 shrink-0 border-t border-[var(--section-border,#aeadac)] bg-[var(--sidebar-bg,#f7f6f5)] ${className ?? ''}`}\n >\n <div className=\"flex items-center gap-2\">\n {zoom && (\n <>\n <ToolbarIconButton\n icon={<RemoveIcon style={{ width: 16, height: 16 }} />}\n label={zoom.zoomOutLabel ?? 'zoom out'}\n onClick={zoom.onZoomOut}\n disabled={zoom.canZoomOut === false}\n />\n <ToolbarValueBox onClick={zoom.onReset} active={zoom.resetActive} label={zoom.resetLabel}>\n {zoom.displayText}\n </ToolbarValueBox>\n <ToolbarIconButton\n icon={<Add2Icon style={{ width: 16, height: 16 }} />}\n label={zoom.zoomInLabel ?? 'zoom in'}\n onClick={zoom.onZoomIn}\n disabled={zoom.canZoomIn === false}\n />\n </>\n )}\n {leftExtra}\n </div>\n\n <div className=\"flex items-center gap-2\">\n {rightExtra}\n {pagination && (\n <>\n <ToolbarIconButton\n icon={<ArrowLeftLineIcon style={ARROW_STYLE} />}\n label={pagination.prevLabel ?? 'previous page'}\n onClick={pagination.onPrev}\n disabled={pagination.page <= 1}\n />\n <PageBox page={pagination.page} total={pagination.total} onPageChange={pagination.onPageChange} />\n <ToolbarIconButton\n icon={<ArrowRightLineIcon style={ARROW_STYLE} />}\n label={pagination.nextLabel ?? 'next page'}\n onClick={pagination.onNext}\n disabled={pagination.page >= pagination.total}\n />\n </>\n )}\n </div>\n </div>\n );\n};\n","import { SVGProps } from 'react';\n\n/** Material Symbols \"remove\" (zoom-out) — extracted 1:1 from the Figma design. */\nexport const RemoveIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path d=\"M3.33301 8.66732V7.33398H12.6663V8.66732H3.33301Z\" fill=\"currentColor\" />\n </svg>\n);\n\n/** Material Symbols \"add_2\" (zoom-in) — extracted 1:1 from the Figma design. */\nexport const Add2Icon = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M7.33333 14V8.66667H2V7.33333H7.33333V2H8.66667V7.33333H14V8.66667H8.66667V14H7.33333Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\n/** Line \"arrow-left\" (previous page) — extracted 1:1 from the Figma design. */\nexport const ArrowLeftLineIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M12.7803 17.5303C12.4874 17.8232 12.0126 17.8232 11.7197 17.5303L7.46967 13.2803C7.17678 12.9874 7.17678 12.5126 7.46967 12.2197L11.7197 7.96967C12.0126 7.67678 12.4874 7.67678 12.7803 7.96967C13.0732 8.26256 13.0732 8.73744 12.7803 9.03033L9.81066 12H17.25C17.6642 12 18 12.3358 18 12.75C18 13.1642 17.6642 13.5 17.25 13.5H9.81066L12.7803 16.4697C13.0732 16.7626 13.0732 17.2374 12.7803 17.5303Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\n/** Line \"arrow-right\" (next page) — extracted 1:1 from the Figma design. */\nexport const ArrowRightLineIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M12.2197 6.96967C12.5126 6.67678 12.9874 6.67678 13.2803 6.96967L17.5303 11.2197C17.8232 11.5126 17.8232 11.9874 17.5303 12.2803L13.2803 16.5303C12.9874 16.8232 12.5126 16.8232 12.2197 16.5303C11.9268 16.2374 11.9268 15.7626 12.2197 15.4697L15.1893 12.5H7.75C7.33579 12.5 7 12.1642 7 11.75C7 11.3358 7.33579 11 7.75 11H15.1893L12.2197 8.03033C11.9268 7.73744 11.9268 7.26256 12.2197 6.96967Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/FileViewer/ViewerToolbar/ViewerToolbar.tsx","../src/FileViewer/ViewerToolbar/icons.tsx"],"names":["RemoveIcon","__name","props","jsx","Add2Icon","ArrowLeftLineIcon","ArrowRightLineIcon","ICON_BUTTON_CLASS","VALUE_BOX_CLASS","ToolbarIconButton","icon","label","onClick","disabled","active","className","ToolbarValueBox","children","ARROW_STYLE","PageBox","page","total","onPageChange","draft","setDraft","useState","useEffect","jsxs","e","next","ViewerToolbar","zoom","pagination","leftExtra","rightExtra","Fragment"],"mappings":"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","file":"chunk-EGCG27KL.mjs","sourcesContent":["import { ReactNode, useEffect, useState } from 'react';\nimport { Add2Icon, ArrowLeftLineIcon, ArrowRightLineIcon, RemoveIcon } from './icons';\n\nexport interface ViewerToolbarZoom {\n /** Text shown in the value box, e.g. \"100%\" or \"Fit\". */\n displayText: string;\n onZoomIn: () => void;\n onZoomOut: () => void;\n /** Optional click handler on the value box (e.g. fit-to-screen / reset). */\n onReset?: () => void;\n /** Visual highlight of the value box (e.g. adaptive/fit mode active). */\n resetActive?: boolean;\n canZoomIn?: boolean;\n canZoomOut?: boolean;\n zoomOutLabel?: string;\n zoomInLabel?: string;\n resetLabel?: string;\n}\n\nexport interface ViewerToolbarPagination {\n page: number;\n total: number;\n onPrev: () => void;\n onNext: () => void;\n /** When provided the current page becomes an editable input. */\n onPageChange?: (page: number) => void;\n prevLabel?: string;\n nextLabel?: string;\n}\n\nexport interface ViewerToolbarProps {\n zoom?: ViewerToolbarZoom;\n pagination?: ViewerToolbarPagination;\n /** Extra controls rendered next to the zoom group (left side). */\n leftExtra?: ReactNode;\n /** Extra controls rendered next to the pagination group (right side). */\n rightExtra?: ReactNode;\n className?: string;\n}\n\nconst ICON_BUTTON_CLASS =\n 'inline-flex items-center justify-center w-7 h-7 rounded-[4px] border border-gray-400 dark:border-neutral-600 ' +\n 'bg-transparent text-gray-700 dark:text-neutral-200 transition-colors shrink-0 ' +\n 'enabled:hover:bg-black/5 enabled:dark:hover:bg-white/10 enabled:cursor-pointer ' +\n 'disabled:border-gray-300 dark:disabled:border-neutral-700 disabled:text-gray-300 dark:disabled:text-neutral-600 disabled:cursor-not-allowed';\n\nconst VALUE_BOX_CLASS =\n 'inline-flex items-center justify-center gap-0.5 h-7 px-2 rounded-[4px] border ' +\n 'border-gray-400 dark:border-neutral-600 bg-transparent ' +\n 'text-[14px] font-normal leading-none text-gray-900 dark:text-neutral-100 select-none shrink-0';\n\ninterface ToolbarIconButtonProps {\n icon: ReactNode;\n label: string;\n onClick?: () => void;\n disabled?: boolean;\n active?: boolean;\n className?: string;\n}\n\n/** Bordered square icon button — the single visual language for all viewer controls. */\nexport const ToolbarIconButton = ({ icon, label, onClick, disabled, active, className }: ToolbarIconButtonProps) => (\n <button\n type=\"button\"\n aria-label={label}\n onClick={onClick}\n disabled={disabled}\n className={`${ICON_BUTTON_CLASS} ${active ? 'bg-blue-50! dark:bg-neutral-700! text-blue-600! dark:text-blue-400!' : ''} ${className ?? ''}`}\n >\n {icon}\n </button>\n);\n\ninterface ToolbarValueBoxProps {\n children: ReactNode;\n onClick?: () => void;\n active?: boolean;\n label?: string;\n className?: string;\n}\n\n/** Bordered value box (zoom %, page indicator). Becomes a button when onClick is set. */\nexport const ToolbarValueBox = ({ children, onClick, active, label, className }: ToolbarValueBoxProps) => {\n if (onClick) {\n return (\n <button\n type=\"button\"\n aria-label={label ?? 'reset zoom'}\n onClick={onClick}\n className={`${VALUE_BOX_CLASS} cursor-pointer transition-colors hover:bg-blue-50 dark:hover:bg-neutral-700 ${active ? 'bg-blue-50! dark:bg-neutral-700! text-blue-600! dark:text-blue-400! border-blue-200! dark:border-neutral-500!' : ''} ${className ?? ''}`}\n >\n {children}\n </button>\n );\n }\n return <span className={`${VALUE_BOX_CLASS} ${className ?? ''}`}>{children}</span>;\n};\n\nconst ARROW_STYLE = { width: 15, height: 15 } as const;\n\nconst PageBox = ({ page, total, onPageChange }: Required<Pick<ViewerToolbarPagination, 'page' | 'total'>> & Pick<ViewerToolbarPagination, 'onPageChange'>) => {\n const [draft, setDraft] = useState(String(page));\n\n // Keep the input in sync when the page changes from scrolling / prev-next.\n useEffect(() => {\n setDraft(String(page));\n }, [page]);\n\n if (!onPageChange) {\n return (\n <ToolbarValueBox className=\"min-w-11\">\n {page}/{total}\n </ToolbarValueBox>\n );\n }\n\n return (\n <span className={`${VALUE_BOX_CLASS} min-w-11`}>\n <input\n type=\"number\"\n min={1}\n max={total}\n value={draft}\n aria-label=\"page number\"\n onChange={(e) => {\n setDraft(e.target.value);\n const next = parseInt(e.target.value, 10);\n if (!Number.isNaN(next) && next >= 1 && next <= total) onPageChange(next);\n }}\n // Valid values are already dispatched on change; on blur just snap the\n // draft back to the confirmed page (reverts an out-of-range entry).\n onBlur={() => setDraft(String(page))}\n style={{ width: `${String(total).length + 1}ch` }}\n className=\"bg-transparent text-end outline-none [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none\"\n />\n <span className=\"text-gray-400 dark:text-neutral-500\">/{total}</span>\n </span>\n );\n};\n\n/**\n * Unified bottom toolbar for all file viewer drivers.\n * Zoom controls live on the left, pagination on the right; each driver opts into\n * only the groups it supports (adaptive per capability).\n */\nexport const ViewerToolbar = ({ zoom, pagination, leftExtra, rightExtra, className }: ViewerToolbarProps) => {\n if (!zoom && !pagination && !leftExtra && !rightExtra) return null;\n\n return (\n <div\n className={`flex items-center justify-between gap-3 px-4 py-2.5 shrink-0 border-t border-[var(--section-border,#aeadac)] bg-[var(--sidebar-bg,#f7f6f5)] ${className ?? ''}`}\n >\n <div className=\"flex items-center gap-2\">\n {zoom && (\n <>\n <ToolbarIconButton\n icon={<RemoveIcon style={{ width: 15, height: 15 }} />}\n label={zoom.zoomOutLabel ?? 'zoom out'}\n onClick={zoom.onZoomOut}\n disabled={zoom.canZoomOut === false}\n />\n <ToolbarValueBox onClick={zoom.onReset} active={zoom.resetActive} label={zoom.resetLabel}>\n {zoom.displayText}\n </ToolbarValueBox>\n <ToolbarIconButton\n icon={<Add2Icon style={{ width: 15, height: 15 }} />}\n label={zoom.zoomInLabel ?? 'zoom in'}\n onClick={zoom.onZoomIn}\n disabled={zoom.canZoomIn === false}\n />\n </>\n )}\n {leftExtra}\n </div>\n\n <div className=\"flex items-center gap-2\">\n {rightExtra}\n {pagination && (\n <>\n <ToolbarIconButton\n icon={<ArrowLeftLineIcon style={ARROW_STYLE} />}\n label={pagination.prevLabel ?? 'previous page'}\n onClick={pagination.onPrev}\n disabled={pagination.page <= 1}\n />\n <PageBox page={pagination.page} total={pagination.total} onPageChange={pagination.onPageChange} />\n <ToolbarIconButton\n icon={<ArrowRightLineIcon style={ARROW_STYLE} />}\n label={pagination.nextLabel ?? 'next page'}\n onClick={pagination.onNext}\n disabled={pagination.page >= pagination.total}\n />\n </>\n )}\n </div>\n </div>\n );\n};\n","import { SVGProps } from 'react';\n\n/** Material Symbols \"remove\" (zoom-out) — extracted 1:1 from the Figma design. */\nexport const RemoveIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path d=\"M3.33301 8.66732V7.33398H12.6663V8.66732H3.33301Z\" fill=\"currentColor\" />\n </svg>\n);\n\n/** Material Symbols \"add_2\" (zoom-in) — extracted 1:1 from the Figma design. */\nexport const Add2Icon = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M7.33333 14V8.66667H2V7.33333H7.33333V2H8.66667V7.33333H14V8.66667H8.66667V14H7.33333Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\n/** Line \"arrow-left\" (previous page) — extracted 1:1 from the Figma design. */\nexport const ArrowLeftLineIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M12.7803 17.5303C12.4874 17.8232 12.0126 17.8232 11.7197 17.5303L7.46967 13.2803C7.17678 12.9874 7.17678 12.5126 7.46967 12.2197L11.7197 7.96967C12.0126 7.67678 12.4874 7.67678 12.7803 7.96967C13.0732 8.26256 13.0732 8.73744 12.7803 9.03033L9.81066 12H17.25C17.6642 12 18 12.3358 18 12.75C18 13.1642 17.6642 13.5 17.25 13.5H9.81066L12.7803 16.4697C13.0732 16.7626 13.0732 17.2374 12.7803 17.5303Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\n/** Line \"arrow-right\" (next page) — extracted 1:1 from the Figma design. */\nexport const ArrowRightLineIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M12.2197 6.96967C12.5126 6.67678 12.9874 6.67678 13.2803 6.96967L17.5303 11.2197C17.8232 11.5126 17.8232 11.9874 17.5303 12.2803L13.2803 16.5303C12.9874 16.8232 12.5126 16.8232 12.2197 16.5303C11.9268 16.2374 11.9268 15.7626 12.2197 15.4697L15.1893 12.5H7.75C7.33579 12.5 7 12.1642 7 11.75C7 11.3358 7.33579 11 7.75 11H15.1893L12.2197 8.03033C11.9268 7.73744 11.9268 7.26256 12.2197 6.96967Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n"]}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
'use strict';var react=require('react'),jsxRuntime=require('react/jsx-runtime');var V=Object.defineProperty;var n=(e,t)=>V(e,"name",{value:t,configurable:true});var p=n(e=>jsxRuntime.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:jsxRuntime.jsx("path",{d:"M3.33301 8.66732V7.33398H12.6663V8.66732H3.33301Z",fill:"currentColor"})}),"RemoveIcon"),x=n(e=>jsxRuntime.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:jsxRuntime.jsx("path",{d:"M7.33333 14V8.66667H2V7.33333H7.33333V2H8.66667V7.33333H14V8.66667H8.66667V14H7.33333Z",fill:"currentColor"})}),"Add2Icon"),v=n(e=>jsxRuntime.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:jsxRuntime.jsx("path",{d:"M12.7803 17.5303C12.4874 17.8232 12.0126 17.8232 11.7197 17.5303L7.46967 13.2803C7.17678 12.9874 7.17678 12.5126 7.46967 12.2197L11.7197 7.96967C12.0126 7.67678 12.4874 7.67678 12.7803 7.96967C13.0732 8.26256 13.0732 8.73744 12.7803 9.03033L9.81066 12H17.25C17.6642 12 18 12.3358 18 12.75C18 13.1642 17.6642 13.5 17.25 13.5H9.81066L12.7803 16.4697C13.0732 16.7626 13.0732 17.2374 12.7803 17.5303Z",fill:"currentColor"})}),"ArrowLeftLineIcon"),h=n(e=>jsxRuntime.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:jsxRuntime.jsx("path",{d:"M12.2197 6.96967C12.5126 6.67678 12.9874 6.67678 13.2803 6.96967L17.5303 11.2197C17.8232 11.5126 17.8232 11.9874 17.5303 12.2803L13.2803 16.5303C12.9874 16.8232 12.5126 16.8232 12.2197 16.5303C11.9268 16.2374 11.9268 15.7626 12.2197 15.4697L15.1893 12.5H7.75C7.33579 12.5 7 12.1642 7 11.75C7 11.3358 7.33579 11 7.75 11H15.1893L12.2197 8.03033C11.9268 7.73744 11.9268 7.26256 12.2197 6.96967Z",fill:"currentColor"})}),"ArrowRightLineIcon");var L="inline-flex items-center justify-center w-
|
|
2
|
-
exports.a=n;exports.b=c;exports.c=G;//# sourceMappingURL=chunk-
|
|
3
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
'use strict';var react=require('react'),jsxRuntime=require('react/jsx-runtime');var V=Object.defineProperty;var n=(e,t)=>V(e,"name",{value:t,configurable:true});var p=n(e=>jsxRuntime.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:jsxRuntime.jsx("path",{d:"M3.33301 8.66732V7.33398H12.6663V8.66732H3.33301Z",fill:"currentColor"})}),"RemoveIcon"),x=n(e=>jsxRuntime.jsx("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:jsxRuntime.jsx("path",{d:"M7.33333 14V8.66667H2V7.33333H7.33333V2H8.66667V7.33333H14V8.66667H8.66667V14H7.33333Z",fill:"currentColor"})}),"Add2Icon"),v=n(e=>jsxRuntime.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:jsxRuntime.jsx("path",{d:"M12.7803 17.5303C12.4874 17.8232 12.0126 17.8232 11.7197 17.5303L7.46967 13.2803C7.17678 12.9874 7.17678 12.5126 7.46967 12.2197L11.7197 7.96967C12.0126 7.67678 12.4874 7.67678 12.7803 7.96967C13.0732 8.26256 13.0732 8.73744 12.7803 9.03033L9.81066 12H17.25C17.6642 12 18 12.3358 18 12.75C18 13.1642 17.6642 13.5 17.25 13.5H9.81066L12.7803 16.4697C13.0732 16.7626 13.0732 17.2374 12.7803 17.5303Z",fill:"currentColor"})}),"ArrowLeftLineIcon"),h=n(e=>jsxRuntime.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",...e,children:jsxRuntime.jsx("path",{d:"M12.2197 6.96967C12.5126 6.67678 12.9874 6.67678 13.2803 6.96967L17.5303 11.2197C17.8232 11.5126 17.8232 11.9874 17.5303 12.2803L13.2803 16.5303C12.9874 16.8232 12.5126 16.8232 12.2197 16.5303C11.9268 16.2374 11.9268 15.7626 12.2197 15.4697L15.1893 12.5H7.75C7.33579 12.5 7 12.1642 7 11.75C7 11.3358 7.33579 11 7.75 11H15.1893L12.2197 8.03033C11.9268 7.73744 11.9268 7.26256 12.2197 6.96967Z",fill:"currentColor"})}),"ArrowRightLineIcon");var L="inline-flex items-center justify-center w-7 h-7 rounded-[4px] border border-gray-400 dark:border-neutral-600 bg-transparent text-gray-700 dark:text-neutral-200 transition-colors shrink-0 enabled:hover:bg-black/5 enabled:dark:hover:bg-white/10 enabled:cursor-pointer disabled:border-gray-300 dark:disabled:border-neutral-700 disabled:text-gray-300 dark:disabled:text-neutral-600 disabled:cursor-not-allowed",u="inline-flex items-center justify-center gap-0.5 h-7 px-2 rounded-[4px] border border-gray-400 dark:border-neutral-600 bg-transparent text-[14px] font-normal leading-none text-gray-900 dark:text-neutral-100 select-none shrink-0",c=n(({icon:e,label:t,onClick:a,disabled:l,active:r,className:b})=>jsxRuntime.jsx("button",{type:"button","aria-label":t,onClick:a,disabled:l,className:`${L} ${r?"bg-blue-50! dark:bg-neutral-700! text-blue-600! dark:text-blue-400!":""} ${b??""}`,children:e}),"ToolbarIconButton"),f=n(({children:e,onClick:t,active:a,label:l,className:r})=>t?jsxRuntime.jsx("button",{type:"button","aria-label":l??"reset zoom",onClick:t,className:`${u} cursor-pointer transition-colors hover:bg-blue-50 dark:hover:bg-neutral-700 ${a?"bg-blue-50! dark:bg-neutral-700! text-blue-600! dark:text-blue-400! border-blue-200! dark:border-neutral-500!":""} ${r??""}`,children:e}):jsxRuntime.jsx("span",{className:`${u} ${r??""}`,children:e}),"ToolbarValueBox"),m={width:15,height:15},N=n(({page:e,total:t,onPageChange:a})=>{let[l,r]=react.useState(String(e));return react.useEffect(()=>{r(String(e));},[e]),a?jsxRuntime.jsxs("span",{className:`${u} min-w-11`,children:[jsxRuntime.jsx("input",{type:"number",min:1,max:t,value:l,"aria-label":"page number",onChange:b=>{r(b.target.value);let d=parseInt(b.target.value,10);!Number.isNaN(d)&&d>=1&&d<=t&&a(d);},onBlur:()=>r(String(e)),style:{width:`${String(t).length+1}ch`},className:"bg-transparent text-end outline-none [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"}),jsxRuntime.jsxs("span",{className:"text-gray-400 dark:text-neutral-500",children:["/",t]})]}):jsxRuntime.jsxs(f,{className:"min-w-11",children:[e,"/",t]})},"PageBox"),G=n(({zoom:e,pagination:t,leftExtra:a,rightExtra:l,className:r})=>!e&&!t&&!a&&!l?null:jsxRuntime.jsxs("div",{className:`flex items-center justify-between gap-3 px-4 py-2.5 shrink-0 border-t border-[var(--section-border,#aeadac)] bg-[var(--sidebar-bg,#f7f6f5)] ${r??""}`,children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[e&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(c,{icon:jsxRuntime.jsx(p,{style:{width:15,height:15}}),label:e.zoomOutLabel??"zoom out",onClick:e.onZoomOut,disabled:e.canZoomOut===false}),jsxRuntime.jsx(f,{onClick:e.onReset,active:e.resetActive,label:e.resetLabel,children:e.displayText}),jsxRuntime.jsx(c,{icon:jsxRuntime.jsx(x,{style:{width:15,height:15}}),label:e.zoomInLabel??"zoom in",onClick:e.onZoomIn,disabled:e.canZoomIn===false})]}),a]}),jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[l,t&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(c,{icon:jsxRuntime.jsx(v,{style:m}),label:t.prevLabel??"previous page",onClick:t.onPrev,disabled:t.page<=1}),jsxRuntime.jsx(N,{page:t.page,total:t.total,onPageChange:t.onPageChange}),jsxRuntime.jsx(c,{icon:jsxRuntime.jsx(h,{style:m}),label:t.nextLabel??"next page",onClick:t.onNext,disabled:t.page>=t.total})]})]})]}),"ViewerToolbar");
|
|
2
|
+
exports.a=n;exports.b=c;exports.c=G;//# sourceMappingURL=chunk-WRBRJBUL.js.map
|
|
3
|
+
//# sourceMappingURL=chunk-WRBRJBUL.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/FileViewer/ViewerToolbar/ViewerToolbar.tsx","../src/FileViewer/ViewerToolbar/icons.tsx"],"names":["RemoveIcon","__name","props","jsx","Add2Icon","ArrowLeftLineIcon","ArrowRightLineIcon","ICON_BUTTON_CLASS","VALUE_BOX_CLASS","ToolbarIconButton","icon","label","onClick","disabled","active","className","ToolbarValueBox","children","ARROW_STYLE","PageBox","page","total","onPageChange","draft","setDraft","useState","useEffect","jsxs","e","next","ViewerToolbar","zoom","pagination","leftExtra","rightExtra","Fragment"],"mappings":"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","file":"chunk-3MGYAJ6C.js","sourcesContent":["import { ReactNode, useEffect, useState } from 'react';\nimport { Add2Icon, ArrowLeftLineIcon, ArrowRightLineIcon, RemoveIcon } from './icons';\n\nexport interface ViewerToolbarZoom {\n /** Text shown in the value box, e.g. \"100%\" or \"Fit\". */\n displayText: string;\n onZoomIn: () => void;\n onZoomOut: () => void;\n /** Optional click handler on the value box (e.g. fit-to-screen / reset). */\n onReset?: () => void;\n /** Visual highlight of the value box (e.g. adaptive/fit mode active). */\n resetActive?: boolean;\n canZoomIn?: boolean;\n canZoomOut?: boolean;\n zoomOutLabel?: string;\n zoomInLabel?: string;\n resetLabel?: string;\n}\n\nexport interface ViewerToolbarPagination {\n page: number;\n total: number;\n onPrev: () => void;\n onNext: () => void;\n /** When provided the current page becomes an editable input. */\n onPageChange?: (page: number) => void;\n prevLabel?: string;\n nextLabel?: string;\n}\n\nexport interface ViewerToolbarProps {\n zoom?: ViewerToolbarZoom;\n pagination?: ViewerToolbarPagination;\n /** Extra controls rendered next to the zoom group (left side). */\n leftExtra?: ReactNode;\n /** Extra controls rendered next to the pagination group (right side). */\n rightExtra?: ReactNode;\n className?: string;\n}\n\nconst ICON_BUTTON_CLASS =\n 'inline-flex items-center justify-center w-6 h-6 rounded-[4px] border border-gray-400 dark:border-neutral-600 ' +\n 'bg-transparent text-gray-700 dark:text-neutral-200 transition-colors shrink-0 ' +\n 'enabled:hover:bg-black/5 enabled:dark:hover:bg-white/10 enabled:cursor-pointer ' +\n 'disabled:border-gray-300 dark:disabled:border-neutral-700 disabled:text-gray-300 dark:disabled:text-neutral-600 disabled:cursor-not-allowed';\n\nconst VALUE_BOX_CLASS =\n 'inline-flex items-center justify-center gap-0.5 h-9 px-2 rounded-[4px] border ' +\n 'border-gray-400 dark:border-neutral-600 bg-transparent ' +\n 'text-[14px] font-normal leading-none text-gray-900 dark:text-neutral-100 select-none shrink-0';\n\ninterface ToolbarIconButtonProps {\n icon: ReactNode;\n label: string;\n onClick?: () => void;\n disabled?: boolean;\n active?: boolean;\n className?: string;\n}\n\n/** Bordered square icon button — the single visual language for all viewer controls. */\nexport const ToolbarIconButton = ({ icon, label, onClick, disabled, active, className }: ToolbarIconButtonProps) => (\n <button\n type=\"button\"\n aria-label={label}\n onClick={onClick}\n disabled={disabled}\n className={`${ICON_BUTTON_CLASS} ${active ? 'bg-blue-50! dark:bg-neutral-700! text-blue-600! dark:text-blue-400!' : ''} ${className ?? ''}`}\n >\n {icon}\n </button>\n);\n\ninterface ToolbarValueBoxProps {\n children: ReactNode;\n onClick?: () => void;\n active?: boolean;\n label?: string;\n className?: string;\n}\n\n/** Bordered value box (zoom %, page indicator). Becomes a button when onClick is set. */\nexport const ToolbarValueBox = ({ children, onClick, active, label, className }: ToolbarValueBoxProps) => {\n if (onClick) {\n return (\n <button\n type=\"button\"\n aria-label={label ?? 'reset zoom'}\n onClick={onClick}\n className={`${VALUE_BOX_CLASS} cursor-pointer transition-colors hover:bg-blue-50 dark:hover:bg-neutral-700 ${active ? 'bg-blue-50! dark:bg-neutral-700! text-blue-600! dark:text-blue-400! border-blue-200! dark:border-neutral-500!' : ''} ${className ?? ''}`}\n >\n {children}\n </button>\n );\n }\n return <span className={`${VALUE_BOX_CLASS} ${className ?? ''}`}>{children}</span>;\n};\n\nconst ARROW_STYLE = { width: 16, height: 16 } as const;\n\nconst PageBox = ({ page, total, onPageChange }: Required<Pick<ViewerToolbarPagination, 'page' | 'total'>> & Pick<ViewerToolbarPagination, 'onPageChange'>) => {\n const [draft, setDraft] = useState(String(page));\n\n // Keep the input in sync when the page changes from scrolling / prev-next.\n useEffect(() => {\n setDraft(String(page));\n }, [page]);\n\n if (!onPageChange) {\n return (\n <ToolbarValueBox className=\"min-w-11\">\n {page}/{total}\n </ToolbarValueBox>\n );\n }\n\n return (\n <span className={`${VALUE_BOX_CLASS} min-w-11`}>\n <input\n type=\"number\"\n min={1}\n max={total}\n value={draft}\n aria-label=\"page number\"\n onChange={(e) => {\n setDraft(e.target.value);\n const next = parseInt(e.target.value, 10);\n if (!Number.isNaN(next) && next >= 1 && next <= total) onPageChange(next);\n }}\n // Valid values are already dispatched on change; on blur just snap the\n // draft back to the confirmed page (reverts an out-of-range entry).\n onBlur={() => setDraft(String(page))}\n style={{ width: `${String(total).length + 1}ch` }}\n className=\"bg-transparent text-end outline-none [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none\"\n />\n <span className=\"text-gray-400 dark:text-neutral-500\">/{total}</span>\n </span>\n );\n};\n\n/**\n * Unified bottom toolbar for all file viewer drivers.\n * Zoom controls live on the left, pagination on the right; each driver opts into\n * only the groups it supports (adaptive per capability).\n */\nexport const ViewerToolbar = ({ zoom, pagination, leftExtra, rightExtra, className }: ViewerToolbarProps) => {\n if (!zoom && !pagination && !leftExtra && !rightExtra) return null;\n\n return (\n <div\n className={`flex items-center justify-between gap-3 px-4 py-2.5 shrink-0 border-t border-[var(--section-border,#aeadac)] bg-[var(--sidebar-bg,#f7f6f5)] ${className ?? ''}`}\n >\n <div className=\"flex items-center gap-2\">\n {zoom && (\n <>\n <ToolbarIconButton\n icon={<RemoveIcon style={{ width: 16, height: 16 }} />}\n label={zoom.zoomOutLabel ?? 'zoom out'}\n onClick={zoom.onZoomOut}\n disabled={zoom.canZoomOut === false}\n />\n <ToolbarValueBox onClick={zoom.onReset} active={zoom.resetActive} label={zoom.resetLabel}>\n {zoom.displayText}\n </ToolbarValueBox>\n <ToolbarIconButton\n icon={<Add2Icon style={{ width: 16, height: 16 }} />}\n label={zoom.zoomInLabel ?? 'zoom in'}\n onClick={zoom.onZoomIn}\n disabled={zoom.canZoomIn === false}\n />\n </>\n )}\n {leftExtra}\n </div>\n\n <div className=\"flex items-center gap-2\">\n {rightExtra}\n {pagination && (\n <>\n <ToolbarIconButton\n icon={<ArrowLeftLineIcon style={ARROW_STYLE} />}\n label={pagination.prevLabel ?? 'previous page'}\n onClick={pagination.onPrev}\n disabled={pagination.page <= 1}\n />\n <PageBox page={pagination.page} total={pagination.total} onPageChange={pagination.onPageChange} />\n <ToolbarIconButton\n icon={<ArrowRightLineIcon style={ARROW_STYLE} />}\n label={pagination.nextLabel ?? 'next page'}\n onClick={pagination.onNext}\n disabled={pagination.page >= pagination.total}\n />\n </>\n )}\n </div>\n </div>\n );\n};\n","import { SVGProps } from 'react';\n\n/** Material Symbols \"remove\" (zoom-out) — extracted 1:1 from the Figma design. */\nexport const RemoveIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path d=\"M3.33301 8.66732V7.33398H12.6663V8.66732H3.33301Z\" fill=\"currentColor\" />\n </svg>\n);\n\n/** Material Symbols \"add_2\" (zoom-in) — extracted 1:1 from the Figma design. */\nexport const Add2Icon = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M7.33333 14V8.66667H2V7.33333H7.33333V2H8.66667V7.33333H14V8.66667H8.66667V14H7.33333Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\n/** Line \"arrow-left\" (previous page) — extracted 1:1 from the Figma design. */\nexport const ArrowLeftLineIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M12.7803 17.5303C12.4874 17.8232 12.0126 17.8232 11.7197 17.5303L7.46967 13.2803C7.17678 12.9874 7.17678 12.5126 7.46967 12.2197L11.7197 7.96967C12.0126 7.67678 12.4874 7.67678 12.7803 7.96967C13.0732 8.26256 13.0732 8.73744 12.7803 9.03033L9.81066 12H17.25C17.6642 12 18 12.3358 18 12.75C18 13.1642 17.6642 13.5 17.25 13.5H9.81066L12.7803 16.4697C13.0732 16.7626 13.0732 17.2374 12.7803 17.5303Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\n/** Line \"arrow-right\" (next page) — extracted 1:1 from the Figma design. */\nexport const ArrowRightLineIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M12.2197 6.96967C12.5126 6.67678 12.9874 6.67678 13.2803 6.96967L17.5303 11.2197C17.8232 11.5126 17.8232 11.9874 17.5303 12.2803L13.2803 16.5303C12.9874 16.8232 12.5126 16.8232 12.2197 16.5303C11.9268 16.2374 11.9268 15.7626 12.2197 15.4697L15.1893 12.5H7.75C7.33579 12.5 7 12.1642 7 11.75C7 11.3358 7.33579 11 7.75 11H15.1893L12.2197 8.03033C11.9268 7.73744 11.9268 7.26256 12.2197 6.96967Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/FileViewer/ViewerToolbar/ViewerToolbar.tsx","../src/FileViewer/ViewerToolbar/icons.tsx"],"names":["RemoveIcon","__name","props","jsx","Add2Icon","ArrowLeftLineIcon","ArrowRightLineIcon","ICON_BUTTON_CLASS","VALUE_BOX_CLASS","ToolbarIconButton","icon","label","onClick","disabled","active","className","ToolbarValueBox","children","ARROW_STYLE","PageBox","page","total","onPageChange","draft","setDraft","useState","useEffect","jsxs","e","next","ViewerToolbar","zoom","pagination","leftExtra","rightExtra","Fragment"],"mappings":"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","file":"chunk-WRBRJBUL.js","sourcesContent":["import { ReactNode, useEffect, useState } from 'react';\nimport { Add2Icon, ArrowLeftLineIcon, ArrowRightLineIcon, RemoveIcon } from './icons';\n\nexport interface ViewerToolbarZoom {\n /** Text shown in the value box, e.g. \"100%\" or \"Fit\". */\n displayText: string;\n onZoomIn: () => void;\n onZoomOut: () => void;\n /** Optional click handler on the value box (e.g. fit-to-screen / reset). */\n onReset?: () => void;\n /** Visual highlight of the value box (e.g. adaptive/fit mode active). */\n resetActive?: boolean;\n canZoomIn?: boolean;\n canZoomOut?: boolean;\n zoomOutLabel?: string;\n zoomInLabel?: string;\n resetLabel?: string;\n}\n\nexport interface ViewerToolbarPagination {\n page: number;\n total: number;\n onPrev: () => void;\n onNext: () => void;\n /** When provided the current page becomes an editable input. */\n onPageChange?: (page: number) => void;\n prevLabel?: string;\n nextLabel?: string;\n}\n\nexport interface ViewerToolbarProps {\n zoom?: ViewerToolbarZoom;\n pagination?: ViewerToolbarPagination;\n /** Extra controls rendered next to the zoom group (left side). */\n leftExtra?: ReactNode;\n /** Extra controls rendered next to the pagination group (right side). */\n rightExtra?: ReactNode;\n className?: string;\n}\n\nconst ICON_BUTTON_CLASS =\n 'inline-flex items-center justify-center w-7 h-7 rounded-[4px] border border-gray-400 dark:border-neutral-600 ' +\n 'bg-transparent text-gray-700 dark:text-neutral-200 transition-colors shrink-0 ' +\n 'enabled:hover:bg-black/5 enabled:dark:hover:bg-white/10 enabled:cursor-pointer ' +\n 'disabled:border-gray-300 dark:disabled:border-neutral-700 disabled:text-gray-300 dark:disabled:text-neutral-600 disabled:cursor-not-allowed';\n\nconst VALUE_BOX_CLASS =\n 'inline-flex items-center justify-center gap-0.5 h-7 px-2 rounded-[4px] border ' +\n 'border-gray-400 dark:border-neutral-600 bg-transparent ' +\n 'text-[14px] font-normal leading-none text-gray-900 dark:text-neutral-100 select-none shrink-0';\n\ninterface ToolbarIconButtonProps {\n icon: ReactNode;\n label: string;\n onClick?: () => void;\n disabled?: boolean;\n active?: boolean;\n className?: string;\n}\n\n/** Bordered square icon button — the single visual language for all viewer controls. */\nexport const ToolbarIconButton = ({ icon, label, onClick, disabled, active, className }: ToolbarIconButtonProps) => (\n <button\n type=\"button\"\n aria-label={label}\n onClick={onClick}\n disabled={disabled}\n className={`${ICON_BUTTON_CLASS} ${active ? 'bg-blue-50! dark:bg-neutral-700! text-blue-600! dark:text-blue-400!' : ''} ${className ?? ''}`}\n >\n {icon}\n </button>\n);\n\ninterface ToolbarValueBoxProps {\n children: ReactNode;\n onClick?: () => void;\n active?: boolean;\n label?: string;\n className?: string;\n}\n\n/** Bordered value box (zoom %, page indicator). Becomes a button when onClick is set. */\nexport const ToolbarValueBox = ({ children, onClick, active, label, className }: ToolbarValueBoxProps) => {\n if (onClick) {\n return (\n <button\n type=\"button\"\n aria-label={label ?? 'reset zoom'}\n onClick={onClick}\n className={`${VALUE_BOX_CLASS} cursor-pointer transition-colors hover:bg-blue-50 dark:hover:bg-neutral-700 ${active ? 'bg-blue-50! dark:bg-neutral-700! text-blue-600! dark:text-blue-400! border-blue-200! dark:border-neutral-500!' : ''} ${className ?? ''}`}\n >\n {children}\n </button>\n );\n }\n return <span className={`${VALUE_BOX_CLASS} ${className ?? ''}`}>{children}</span>;\n};\n\nconst ARROW_STYLE = { width: 15, height: 15 } as const;\n\nconst PageBox = ({ page, total, onPageChange }: Required<Pick<ViewerToolbarPagination, 'page' | 'total'>> & Pick<ViewerToolbarPagination, 'onPageChange'>) => {\n const [draft, setDraft] = useState(String(page));\n\n // Keep the input in sync when the page changes from scrolling / prev-next.\n useEffect(() => {\n setDraft(String(page));\n }, [page]);\n\n if (!onPageChange) {\n return (\n <ToolbarValueBox className=\"min-w-11\">\n {page}/{total}\n </ToolbarValueBox>\n );\n }\n\n return (\n <span className={`${VALUE_BOX_CLASS} min-w-11`}>\n <input\n type=\"number\"\n min={1}\n max={total}\n value={draft}\n aria-label=\"page number\"\n onChange={(e) => {\n setDraft(e.target.value);\n const next = parseInt(e.target.value, 10);\n if (!Number.isNaN(next) && next >= 1 && next <= total) onPageChange(next);\n }}\n // Valid values are already dispatched on change; on blur just snap the\n // draft back to the confirmed page (reverts an out-of-range entry).\n onBlur={() => setDraft(String(page))}\n style={{ width: `${String(total).length + 1}ch` }}\n className=\"bg-transparent text-end outline-none [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none\"\n />\n <span className=\"text-gray-400 dark:text-neutral-500\">/{total}</span>\n </span>\n );\n};\n\n/**\n * Unified bottom toolbar for all file viewer drivers.\n * Zoom controls live on the left, pagination on the right; each driver opts into\n * only the groups it supports (adaptive per capability).\n */\nexport const ViewerToolbar = ({ zoom, pagination, leftExtra, rightExtra, className }: ViewerToolbarProps) => {\n if (!zoom && !pagination && !leftExtra && !rightExtra) return null;\n\n return (\n <div\n className={`flex items-center justify-between gap-3 px-4 py-2.5 shrink-0 border-t border-[var(--section-border,#aeadac)] bg-[var(--sidebar-bg,#f7f6f5)] ${className ?? ''}`}\n >\n <div className=\"flex items-center gap-2\">\n {zoom && (\n <>\n <ToolbarIconButton\n icon={<RemoveIcon style={{ width: 15, height: 15 }} />}\n label={zoom.zoomOutLabel ?? 'zoom out'}\n onClick={zoom.onZoomOut}\n disabled={zoom.canZoomOut === false}\n />\n <ToolbarValueBox onClick={zoom.onReset} active={zoom.resetActive} label={zoom.resetLabel}>\n {zoom.displayText}\n </ToolbarValueBox>\n <ToolbarIconButton\n icon={<Add2Icon style={{ width: 15, height: 15 }} />}\n label={zoom.zoomInLabel ?? 'zoom in'}\n onClick={zoom.onZoomIn}\n disabled={zoom.canZoomIn === false}\n />\n </>\n )}\n {leftExtra}\n </div>\n\n <div className=\"flex items-center gap-2\">\n {rightExtra}\n {pagination && (\n <>\n <ToolbarIconButton\n icon={<ArrowLeftLineIcon style={ARROW_STYLE} />}\n label={pagination.prevLabel ?? 'previous page'}\n onClick={pagination.onPrev}\n disabled={pagination.page <= 1}\n />\n <PageBox page={pagination.page} total={pagination.total} onPageChange={pagination.onPageChange} />\n <ToolbarIconButton\n icon={<ArrowRightLineIcon style={ARROW_STYLE} />}\n label={pagination.nextLabel ?? 'next page'}\n onClick={pagination.onNext}\n disabled={pagination.page >= pagination.total}\n />\n </>\n )}\n </div>\n </div>\n );\n};\n","import { SVGProps } from 'react';\n\n/** Material Symbols \"remove\" (zoom-out) — extracted 1:1 from the Figma design. */\nexport const RemoveIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path d=\"M3.33301 8.66732V7.33398H12.6663V8.66732H3.33301Z\" fill=\"currentColor\" />\n </svg>\n);\n\n/** Material Symbols \"add_2\" (zoom-in) — extracted 1:1 from the Figma design. */\nexport const Add2Icon = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M7.33333 14V8.66667H2V7.33333H7.33333V2H8.66667V7.33333H14V8.66667H8.66667V14H7.33333Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\n/** Line \"arrow-left\" (previous page) — extracted 1:1 from the Figma design. */\nexport const ArrowLeftLineIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M12.7803 17.5303C12.4874 17.8232 12.0126 17.8232 11.7197 17.5303L7.46967 13.2803C7.17678 12.9874 7.17678 12.5126 7.46967 12.2197L11.7197 7.96967C12.0126 7.67678 12.4874 7.67678 12.7803 7.96967C13.0732 8.26256 13.0732 8.73744 12.7803 9.03033L9.81066 12H17.25C17.6642 12 18 12.3358 18 12.75C18 13.1642 17.6642 13.5 17.25 13.5H9.81066L12.7803 16.4697C13.0732 16.7626 13.0732 17.2374 12.7803 17.5303Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\n/** Line \"arrow-right\" (next page) — extracted 1:1 from the Figma design. */\nexport const ArrowRightLineIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M12.2197 6.96967C12.5126 6.67678 12.9874 6.67678 13.2803 6.96967L17.5303 11.2197C17.8232 11.5126 17.8232 11.9874 17.5303 12.2803L13.2803 16.5303C12.9874 16.8232 12.5126 16.8232 12.2197 16.5303C11.9268 16.2374 11.9268 15.7626 12.2197 15.4697L15.1893 12.5H7.75C7.33579 12.5 7 12.1642 7 11.75C7 11.3358 7.33579 11 7.75 11H15.1893L12.2197 8.03033C11.9268 7.73744 11.9268 7.26256 12.2197 6.96967Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n"]}
|