|
2 | 2 |
|
3 | 3 | import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react' |
4 | 4 | import { createLogger } from '@sim/logger' |
5 | | -import { ChevronLeft, ChevronRight, ZoomIn, ZoomOut } from 'lucide-react' |
6 | 5 | import { pdfjs, Document as ReactPdfDocument, Page as ReactPdfPage } from 'react-pdf' |
7 | 6 | import 'react-pdf/dist/Page/TextLayer.css' |
8 | | -import { Button, Skeleton } from '@/components/emcn' |
| 7 | +import { Skeleton } from '@/components/emcn' |
| 8 | +import { PreviewToolbar } from '@/app/workspace/[workspaceId]/files/components/file-viewer/preview-toolbar' |
9 | 9 |
|
10 | 10 | pdfjs.GlobalWorkerOptions.workerSrc = new URL( |
11 | 11 | 'pdfjs-dist/build/pdf.worker.min.mjs', |
@@ -172,81 +172,44 @@ export const PdfViewerCore = memo(function PdfViewerCore({ source, filename }: P |
172 | 172 | return ( |
173 | 173 | <div className='flex flex-1 flex-col overflow-hidden'> |
174 | 174 | {pageCount > 0 && !loadError && ( |
175 | | - <div className='flex shrink-0 items-center justify-between border-[var(--border)] border-b bg-[var(--surface-1)] px-3 py-1.5'> |
176 | | - <div className='flex items-center gap-1'> |
177 | | - <Button |
178 | | - variant='ghost' |
179 | | - size='sm' |
180 | | - onClick={() => { |
181 | | - const prev = Math.max(1, currentPage - 1) |
182 | | - setCurrentPage(prev) |
183 | | - scrollToPage(prev) |
184 | | - }} |
185 | | - disabled={currentPage <= 1} |
186 | | - className='h-6 w-6 p-0 text-[var(--text-icon)]' |
187 | | - aria-label='Previous page' |
188 | | - > |
189 | | - <ChevronLeft className='h-[14px] w-[14px]' /> |
190 | | - </Button> |
191 | | - <span className='min-w-[5rem] text-center text-[12px] text-[var(--text-secondary)]'> |
192 | | - {currentPage} / {pageCount} |
193 | | - </span> |
194 | | - <Button |
195 | | - variant='ghost' |
196 | | - size='sm' |
197 | | - onClick={() => { |
198 | | - const next = Math.min(pageCount, currentPage + 1) |
199 | | - setCurrentPage(next) |
200 | | - scrollToPage(next) |
201 | | - }} |
202 | | - disabled={currentPage >= pageCount} |
203 | | - className='h-6 w-6 p-0 text-[var(--text-icon)]' |
204 | | - aria-label='Next page' |
205 | | - > |
206 | | - <ChevronRight className='h-[14px] w-[14px]' /> |
207 | | - </Button> |
208 | | - </div> |
209 | | - |
210 | | - <div className='flex items-center gap-1'> |
211 | | - <Button |
212 | | - variant='ghost' |
213 | | - size='sm' |
214 | | - onClick={() => { |
215 | | - const c = containerRef.current |
216 | | - applyZoomAt( |
217 | | - Math.max(PDF_ZOOM_MIN, zoomRef.current / PDF_ZOOM_STEP), |
218 | | - c ? c.clientWidth / 2 : 0, |
219 | | - c ? c.clientHeight / 2 : 0 |
220 | | - ) |
221 | | - }} |
222 | | - disabled={displayZoom <= PDF_ZOOM_MIN} |
223 | | - className='h-6 w-6 p-0 text-[var(--text-icon)]' |
224 | | - aria-label='Zoom out' |
225 | | - > |
226 | | - <ZoomOut className='h-[14px] w-[14px]' /> |
227 | | - </Button> |
228 | | - <span className='min-w-[3rem] text-center text-[12px] text-[var(--text-secondary)]'> |
229 | | - {Math.round(displayZoom * 100)}% |
230 | | - </span> |
231 | | - <Button |
232 | | - variant='ghost' |
233 | | - size='sm' |
234 | | - onClick={() => { |
235 | | - const c = containerRef.current |
236 | | - applyZoomAt( |
237 | | - Math.min(PDF_ZOOM_MAX, zoomRef.current * PDF_ZOOM_STEP), |
238 | | - c ? c.clientWidth / 2 : 0, |
239 | | - c ? c.clientHeight / 2 : 0 |
240 | | - ) |
241 | | - }} |
242 | | - disabled={displayZoom >= PDF_ZOOM_MAX} |
243 | | - className='h-6 w-6 p-0 text-[var(--text-icon)]' |
244 | | - aria-label='Zoom in' |
245 | | - > |
246 | | - <ZoomIn className='h-[14px] w-[14px]' /> |
247 | | - </Button> |
248 | | - </div> |
249 | | - </div> |
| 175 | + <PreviewToolbar |
| 176 | + navigation={{ |
| 177 | + current: currentPage, |
| 178 | + total: pageCount, |
| 179 | + label: 'page', |
| 180 | + onPrevious: () => { |
| 181 | + const prev = Math.max(1, currentPage - 1) |
| 182 | + setCurrentPage(prev) |
| 183 | + scrollToPage(prev) |
| 184 | + }, |
| 185 | + onNext: () => { |
| 186 | + const next = Math.min(pageCount, currentPage + 1) |
| 187 | + setCurrentPage(next) |
| 188 | + scrollToPage(next) |
| 189 | + }, |
| 190 | + }} |
| 191 | + zoom={{ |
| 192 | + label: `${Math.round(displayZoom * 100)}%`, |
| 193 | + canZoomOut: displayZoom > PDF_ZOOM_MIN, |
| 194 | + canZoomIn: displayZoom < PDF_ZOOM_MAX, |
| 195 | + onZoomOut: () => { |
| 196 | + const c = containerRef.current |
| 197 | + applyZoomAt( |
| 198 | + Math.max(PDF_ZOOM_MIN, zoomRef.current / PDF_ZOOM_STEP), |
| 199 | + c ? c.clientWidth / 2 : 0, |
| 200 | + c ? c.clientHeight / 2 : 0 |
| 201 | + ) |
| 202 | + }, |
| 203 | + onZoomIn: () => { |
| 204 | + const c = containerRef.current |
| 205 | + applyZoomAt( |
| 206 | + Math.min(PDF_ZOOM_MAX, zoomRef.current * PDF_ZOOM_STEP), |
| 207 | + c ? c.clientWidth / 2 : 0, |
| 208 | + c ? c.clientHeight / 2 : 0 |
| 209 | + ) |
| 210 | + }, |
| 211 | + }} |
| 212 | + /> |
250 | 213 | )} |
251 | 214 |
|
252 | 215 | <div |
|
0 commit comments