@fdls/file-viewer 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 file-viewer contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,524 @@
1
+ [![npm version](https://img.shields.io/npm/v/file-viewer.svg)](https://www.npmjs.com/package/file-viewer)
2
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
3
+
4
+ # file-viewer
5
+
6
+ > React components for in-app file preview: a shell (`FileViewer`), PDF viewer (`react-pdf`), and image viewer with pan/zoom.
7
+
8
+ ## Prerequisites
9
+
10
+ This library targets **React 18+** and **Node.js 18+** (recommended for local development).
11
+
12
+ Peer dependencies must be installed in your app (see [Installation](#installation)).
13
+
14
+ ```sh
15
+ node -v && npm -v
16
+ ```
17
+
18
+ ## Table of contents
19
+
20
+ - [file-viewer](#file-viewer)
21
+ - [Prerequisites](#prerequisites)
22
+ - [Table of contents](#table-of-contents)
23
+ - [Getting Started](#getting-started)
24
+ - [Installation](#installation)
25
+ - [Usage](#usage)
26
+ - [Quick start](#quick-start)
27
+ - [Global defaults](#global-defaults)
28
+ - [Inline vs modal](#inline-vs-modal)
29
+ - [Styling (Tailwind & CSS)](#styling-tailwind--css)
30
+ - [PDF.js worker (required for PDF)](#pdfjs-worker-required-for-pdf)
31
+ - [React-PDF layer CSS](#react-pdf-layer-css)
32
+ - [Peer dependencies](#peer-dependencies)
33
+ - [Migration from 0.1.x](#migration-from-01x)
34
+ - [Local development (this repo)](#local-development-this-repo)
35
+ - [Serving the playground](#serving-the-playground)
36
+ - [Building the library](#building-the-library)
37
+ - [Building the playground](#building-the-playground)
38
+ - [Publishing to npm (maintainers)](#publishing-to-npm-maintainers)
39
+ - [API](#api)
40
+ - [FileViewer](#fileviewer)
41
+ - [setFileViewerDefaults](#setfileviewerdefaults)
42
+ - [PdfViewer](#pdfviewer)
43
+ - [ImageViewer](#imageviewer)
44
+ - [Translations](#translations)
45
+ - [Customization slots](#customization-slots)
46
+ - [Contributing](#contributing)
47
+ - [Built with](#built-with)
48
+ - [Versioning](#versioning)
49
+ - [License](#license)
50
+
51
+ ## Getting Started
52
+
53
+ `file-viewer` is meant to be consumed as an npm package. Clone this repository only if you want to develop or run the playground.
54
+
55
+ ```sh
56
+ git clone https://github.com/fidelesdev/file-viewer.git
57
+ cd file-viewer
58
+ npm install
59
+ npm run dev
60
+ ```
61
+
62
+ ## Installation
63
+
64
+ Your app must already use **React 18+**. Then install only the library — **npm 7+**, **Yarn 2+**, and **pnpm** install [peer dependencies](https://nodejs.org/en/blog/npm/peer-dependencies) from `file-viewer` automatically (no separate `npm install react-pdf …` in your project).
65
+
66
+ ```sh
67
+ npm install file-viewer
68
+ ```
69
+
70
+ ```sh
71
+ yarn add file-viewer
72
+ ```
73
+
74
+ ```sh
75
+ pnpm add file-viewer
76
+ ```
77
+
78
+ ### Peer dependencies (declared in `file-viewer`)
79
+
80
+ These are listed in this package’s `package.json`; the installer resolves them for you. You do not add them manually unless you use **npm 6** or disable peer auto-install.
81
+
82
+ | Package | Version | Purpose |
83
+ | ------- | ------- | ------- |
84
+ | `react`, `react-dom` | 18 or 19 | UI runtime (from your app) |
85
+ | `react-pdf` | 9.x | PDF rendering |
86
+ | `pdfjs-dist` | **~4.8.69** (same as react-pdf 9) | PDF.js engine — do not use 4.9+ / 4.10+ |
87
+ | `react-to-print` | 3.x | Print in `FileViewer` |
88
+ | `react-zoom-pan-pinch` | 4.x | Image pan/zoom |
89
+
90
+ Dialog, scroll area, tooltips, and toolbar icons are **bundled inside** `file-viewer` (no `@radix-ui/*` or `lucide-react`).
91
+
92
+ ### Migration from 0.1.x
93
+
94
+ If you installed `0.1.x`, remove these peers from your app (they are no longer required):
95
+
96
+ - `@radix-ui/react-dialog`
97
+ - `@radix-ui/react-scroll-area`
98
+ - `@radix-ui/react-tooltip`
99
+ - `lucide-react`
100
+
101
+ Then install `file-viewer@^0.2.0` only; peers are declared on the package.
102
+
103
+ ## Usage
104
+
105
+ ### Quick start
106
+
107
+ Styles load automatically when you import from `file-viewer`. **PDF preview** requires a one-time worker setup in your app entry (see [PDF.js worker](#pdfjs-worker-required-for-pdf)).
108
+
109
+ ```tsx
110
+ // main.tsx or app entry — before rendering PDFs
111
+ import {
112
+ configureFileViewerPdfWorker,
113
+ getFileViewerPdfWorkerSrc,
114
+ } from 'file-viewer'
115
+
116
+ configureFileViewerPdfWorker({
117
+ workerSrc: getFileViewerPdfWorkerSrc(),
118
+ })
119
+ ```
120
+
121
+ ```tsx
122
+ import { FileViewer } from 'file-viewer'
123
+
124
+ export function DocumentPreview() {
125
+ const [open, setOpen] = useState(true)
126
+
127
+ return (
128
+ <FileViewer
129
+ open={open}
130
+ onOpenChange={setOpen}
131
+ name="report.pdf"
132
+ extension="pdf"
133
+ url="/files/report.pdf"
134
+ />
135
+ )
136
+ }
137
+ ```
138
+
139
+ Supported preview extensions in `FileViewer`: **pdf**, **jpg**, **jpeg**, **png**. Other types show a fallback message (or `renderUnsupported`).
140
+
141
+ ### Global defaults
142
+
143
+ Configure once at app startup; each call merges incrementally.
144
+
145
+ ```ts
146
+ import { setFileViewerDefaults } from 'file-viewer'
147
+
148
+ setFileViewerDefaults({
149
+ language: 'portuguese',
150
+ fileViewer: { mode: 'inline' },
151
+ pdfViewer: { viewMode: 'continuous', zoomDebounceDelay: 500 },
152
+ })
153
+
154
+ setFileViewerDefaults({
155
+ translations: {
156
+ portuguese: { fileViewer: { downloadTooltip: 'Baixar arquivo' } },
157
+ },
158
+ })
159
+ ```
160
+
161
+
162
+ | API | Description |
163
+ | -------------------------------- | ----------------------------------- |
164
+ | `setFileViewerDefaults(partial)` | Merge into global defaults |
165
+ | `getFileViewerDefaults()` | Read current defaults (debug/tests) |
166
+ | `resetFileViewerDefaults()` | Reset to library built-ins |
167
+
168
+
169
+ **Merge priority:** instance props → `setFileViewerDefaults` → built-in defaults.
170
+
171
+ **Never global** (instance only): `open`, `url`, `name`, `extension`, and callbacks such as `onOpenChange`, `onDownload`.
172
+
173
+ ### Inline vs modal
174
+
175
+
176
+ | `mode` | Behavior |
177
+ | ------------------ | ---------------------------------------------------------- |
178
+ | `inline` (default) | Fills the parent container; close button hidden by default |
179
+ | `modal` | Full-screen dialog overlay with backdrop |
180
+
181
+
182
+ In **inline** mode, a header action can open the same file in a built-in full-screen modal (“Visualizar em tela cheia”), unless you pass `onOpenInModal` for custom behavior.
183
+
184
+ ### Styling (automatic)
185
+
186
+ The published build runs **Tailwind v4** over this library and ships the result as `dist/style.css`. Importing any export from `file-viewer` pulls that CSS in (Vite, Webpack, Next with `transpilePackages`).
187
+
188
+ **Optional manual import** (same file, if your bundler does not follow CSS from `node_modules`):
189
+
190
+ ```ts
191
+ import 'file-viewer/style.css'
192
+ ```
193
+
194
+ **Option — Your app already uses Tailwind v4:** you may scan the package instead of relying on the pre-built CSS:
195
+
196
+ ```css
197
+ @import "tailwindcss";
198
+ @source "./node_modules/file-viewer/dist";
199
+ ```
200
+
201
+ **Customization without Tailwind:** use `styles` (`React.CSSProperties`) on `FileViewer`, `PdfViewer`, `ImageViewer`, or via `setFileViewerDefaults`.
202
+
203
+ **Dynamic `classNames` from props** (e.g. `classNames={{ header: 'text-[#235685]' }}`): Tailwind only emits utilities it finds during the build scan. Classes passed as **runtime strings** are not visible to the compiler unless they also appear as **static** text in files covered by `@source` (your app source), or you add them to a **safelist** / theme. Prefer `styles` for one-off colors, or define fixed utility classes in your own CSS.
204
+
205
+ ### PDF.js worker (required for PDF)
206
+
207
+ `file-viewer` does **not** set the PDF.js worker path inside the published bundle (that would point to a non-existent file under `node_modules/file-viewer/dist/`). Call **`configureFileViewerPdfWorker`** once in your app entry, **before** any `FileViewer` / `PdfViewer` renders a PDF.
208
+
209
+ #### Recommended (matches react-pdf API version)
210
+
211
+ Uses `pdfjs.version` from react-pdf (e.g. `4.8.69`), so API and worker stay in sync:
212
+
213
+ ```ts
214
+ // src/main.tsx
215
+ import {
216
+ configureFileViewerPdfWorker,
217
+ getFileViewerPdfWorkerSrc,
218
+ } from 'file-viewer'
219
+
220
+ configureFileViewerPdfWorker({
221
+ workerSrc: getFileViewerPdfWorkerSrc(),
222
+ })
223
+
224
+ // or simply (same default):
225
+ // configureFileViewerPdfWorker()
226
+ ```
227
+
228
+ Requires network (unpkg). Fine for dev; for production you can self-host the same file or pin a local copy.
229
+
230
+ #### Version mismatch (`4.8.69` vs `4.10.x`)
231
+
232
+ If you see *The API version does not match the Worker version*, your app resolved a **newer** `pdfjs-dist` worker (often `4.10.x`) while react-pdf 9 uses **4.8.69** for the API.
233
+
234
+ Fix:
235
+
236
+ ```sh
237
+ npm install pdfjs-dist@4.8.69
238
+ ```
239
+
240
+ Or use `getFileViewerPdfWorkerSrc()` instead of `new URL('pdfjs-dist/...', import.meta.url)`.
241
+
242
+ Optional `package.json` override:
243
+
244
+ ```json
245
+ {
246
+ "overrides": {
247
+ "pdfjs-dist": "4.8.69"
248
+ }
249
+ }
250
+ ```
251
+
252
+ #### Vite — local worker (offline)
253
+
254
+ Only after pinning `pdfjs-dist@4.8.69`:
255
+
256
+ ```ts
257
+ import { configureFileViewerPdfWorker } from 'file-viewer'
258
+
259
+ configureFileViewerPdfWorker({
260
+ workerSrc: new URL(
261
+ 'pdfjs-dist/build/pdf.worker.min.mjs',
262
+ import.meta.url,
263
+ ).href,
264
+ })
265
+ ```
266
+
267
+ Or with `?url`:
268
+
269
+ ```ts
270
+ import { configureFileViewerPdfWorker } from 'file-viewer'
271
+ import pdfWorker from 'pdfjs-dist/build/pdf.worker.min.mjs?url'
272
+
273
+ configureFileViewerPdfWorker({ workerSrc: pdfWorker })
274
+ ```
275
+
276
+ #### Next.js (App Router)
277
+
278
+ In a Client Component loaded early (e.g. `providers.tsx` with `'use client'`):
279
+
280
+ ```tsx
281
+ 'use client'
282
+
283
+ import { configureFileViewerPdfWorker } from 'file-viewer'
284
+
285
+ import {
286
+ configureFileViewerPdfWorker,
287
+ getFileViewerPdfWorkerSrc,
288
+ } from 'file-viewer'
289
+
290
+ configureFileViewerPdfWorker({
291
+ workerSrc: getFileViewerPdfWorkerSrc(),
292
+ })
293
+ ```
294
+
295
+ Ensure `pdfjs-dist@4.8.69` is installed and `transpilePackages: ['file-viewer']` is set in `next.config.ts`.
296
+
297
+ #### API
298
+
299
+ | Export | Description |
300
+ | ------ | ----------- |
301
+ | `configureFileViewerPdfWorker({ workerSrc? })` | Sets `pdfjs.GlobalWorkerOptions.workerSrc` |
302
+ | `getFileViewerPdfWorkerSrc()` | CDN URL locked to `pdfjs.version` (recommended) |
303
+ | `getFileViewerPdfWorkerCdnUrl()` | Alias of `getFileViewerPdfWorkerSrc` |
304
+ | `isFileViewerPdfWorkerConfigured()` | `true` after configure was called |
305
+
306
+ See [pdf.js getting started](https://mozilla.github.io/pdf.js/getting_started/) for more context.
307
+
308
+ ### React-PDF layer CSS
309
+
310
+ Included in the bundled `style.css` (react-pdf 9 text/annotation layers). No extra imports.
311
+
312
+ ### Vite
313
+
314
+ 1. Call `configureFileViewerPdfWorker` in `main.tsx` (see [PDF.js worker](#pdfjs-worker-required-for-pdf)).
315
+ 2. Use `FileViewer` in your components:
316
+
317
+ ```tsx
318
+ import { FileViewer } from 'file-viewer'
319
+ ```
320
+
321
+ ### Next.js (App Router)
322
+
323
+ Add to `next.config.ts`:
324
+
325
+ ```ts
326
+ import type { NextConfig } from 'next'
327
+
328
+ const nextConfig: NextConfig = {
329
+ transpilePackages: ['file-viewer'],
330
+ }
331
+
332
+ export default nextConfig
333
+ ```
334
+
335
+ Call `configureFileViewerPdfWorker` in a Client Component loaded at startup, then use `FileViewer`. Shell components include `'use client'`.
336
+
337
+ ## Local development (this repo)
338
+
339
+ ### Serving the playground
340
+
341
+ ```sh
342
+ npm run dev
343
+ ```
344
+
345
+ Opens the Vite demo (`src/app/App.tsx`) with inline `FileViewer` and sample PDF/image scenarios.
346
+
347
+ ### Building the library
348
+
349
+ ```sh
350
+ npm run build:lib
351
+ ```
352
+
353
+ Outputs ESM + types to `dist/` (`index.js`, `index.d.ts`, `style.css`).
354
+
355
+ Typecheck:
356
+
357
+ ```sh
358
+ npx tsc --noEmit
359
+ ```
360
+
361
+ ### Building the playground
362
+
363
+ ```sh
364
+ npm run build
365
+ ```
366
+
367
+ Production build of the demo into `playground-dist/` (does not replace library `dist/` from `build:lib`).
368
+
369
+ Preview:
370
+
371
+ ```sh
372
+ npm run preview
373
+ ```
374
+
375
+ ## API
376
+
377
+ ### FileViewer
378
+
379
+ Shell with header (title, print, download, optional full-screen), and lazy-loaded PDF or image viewer.
380
+
381
+ ```tsx
382
+ <FileViewer
383
+ mode="inline"
384
+ open={open}
385
+ onOpenChange={setOpen}
386
+ name="document.pdf"
387
+ extension="pdf"
388
+ url="https://example.com/doc.pdf"
389
+ language="portuguese"
390
+ hideCloseButton
391
+ showOpenInModalButton
392
+ onOpenInModal={() => { /* optional custom handler */ }}
393
+ pdfViewerProps={{ viewMode: 'single' }}
394
+ classNames={{ header: 'my-header' }}
395
+ styles={{ header: { color: '#fff' } }}
396
+ dialogClassNames={{ panel: 'rounded-lg' }}
397
+ />
398
+ ```
399
+
400
+
401
+ | Prop | Type | Default | Description |
402
+ | ----------------------------------- | ------------------------------------------ | ---------------------------------- | --------------------------------------------- |
403
+ | `mode` | `'inline' | 'modal'` | `'inline'` | Layout mode |
404
+ | `open` | `boolean` | — | Controlled visibility |
405
+ | `onOpenChange` | `(open: boolean) => void` | — | Open state callback |
406
+ | `name` | `string` | — | Display name |
407
+ | `extension` | `string` | — | File extension (drives viewer choice) |
408
+ | `url` | `string` | — | File URL |
409
+ | `isLoading` | `boolean` | — | Shows loader in viewer area |
410
+ | `language` | `'english' | 'portuguese'` | `'english'` | UI strings |
411
+ | `hideCloseButton` | `boolean` | `true` in inline, `false` in modal | Hide header close control |
412
+ | `showOpenInModalButton` | `boolean` | `true` | Full-screen button (inline only) |
413
+ | `onOpenInModal` | `() => void` | — | Override built-in modal preview |
414
+ | `onDownload` | `() => void` | — | Custom download; default uses `url` |
415
+ | `pdfViewerProps` | `Omit<PdfViewerProps, 'url' | 'language'>` | — | Passed to embedded PDF viewer |
416
+ | `renderUnsupported` | `ReactNode` | — | Custom unsupported-type UI |
417
+ | `classNames` / `styles` | slot maps | — | Per-slot styling |
418
+ | `dialogClassNames` / `dialogStyles` | layer maps | — | Modal layers (`backdrop`, `content`, `panel`) |
419
+
420
+
421
+ There is **no** `hideHeader` prop yet; use `classNames.header` with `hidden` or `styles.header` as a workaround.
422
+
423
+ ### setFileViewerDefaults
424
+
425
+ ```ts
426
+ setFileViewerDefaults({
427
+ language: 'portuguese',
428
+ fileViewer: {
429
+ hideCloseButton: true,
430
+ showOpenInModalButton: true,
431
+ classNames: { header: 'app-viewer-header' },
432
+ pdfViewerProps: { viewMode: 'continuous' },
433
+ },
434
+ pdfViewer: { preloadAhead: 1, zoomDebounceDelay: 500 },
435
+ imageViewer: { classNames: { root: 'image-root' } },
436
+ toolbar: { classNames: { toolbar: 'my-toolbar' } },
437
+ tooltip: { delayDuration: 300 },
438
+ autoHide: { proximityThreshold: 160, timeout: 3000 },
439
+ translations: { /* deep partial per language */ },
440
+ })
441
+ ```
442
+
443
+ ### PdfViewer
444
+
445
+ Standalone PDF viewer (continuous scroll or single page, zoom, pagination toolbar).
446
+
447
+ ```tsx
448
+ import { PdfViewer } from 'file-viewer'
449
+
450
+ <PdfViewer
451
+ url="/doc.pdf"
452
+ viewMode="continuous"
453
+ language="english"
454
+ preloadAhead={1}
455
+ zoomDebounceDelay={500}
456
+ debounceDelay={300}
457
+ classNames={{ page: 'my-page' }}
458
+ />
459
+ ```
460
+
461
+
462
+ | Prop | Type | Default | Description |
463
+ | ----------------------------------------------------- | ------------------------- | -------------- | ------------------------------------------------ |
464
+ | `url` | `string` | — | PDF URL |
465
+ | `viewMode` | `'single' | 'continuous'` | `'continuous'` | Page layout |
466
+ | `debounceDelay` | `number` | `300` | Resize debounce (ms) |
467
+ | `zoomDebounceDelay` | `number` | `500` | Zoom canvas re-render debounce (ms) |
468
+ | `preloadAhead` | `number` | `1` | Pages mounted outside viewport (continuous) |
469
+ | `renderPagination` | `function | null` | default UI | Custom pagination; `null` hides |
470
+ | `className` / `pageClassName` / `paginationClassName` | `string` | — | Legacy aliases → `classNames` |
471
+ | `classNames` / `styles` | slot maps | — | `root`, `scrollArea`, `page`, `pagination`, etc. |
472
+
473
+
474
+ Page width in both modes is capped at **50rem** (same sizing rules).
475
+
476
+ ### ImageViewer
477
+
478
+ ```tsx
479
+ import { ImageViewer } from 'file-viewer'
480
+
481
+ <ImageViewer url="/photo.jpg" name="photo.jpg" language="portuguese" />
482
+ ```
483
+
484
+ Pan/zoom via `react-zoom-pan-pinch`, floating toolbar with auto-hide.
485
+
486
+ ### Translations
487
+
488
+ - Bundled: `english`, `portuguese`
489
+ - `getFileViewerTranslations(language)` — applies global overlay from `setFileViewerDefaults({ translations })`
490
+ - `resolveFormattedMessage` — for `FormattableMessage` entries
491
+ - Exports: `fileViewerTranslationsByLanguage`, `defaultFileViewerTranslations`
492
+
493
+ ### Customization slots
494
+
495
+ Shared types: `FileViewerClassNames`, `PdfViewerClassNames`, `ImageViewerClassNames`, `ViewerToolbarClassNames`, `FileViewerTooltipClassNames`, and matching `*Styles` (`SlotStyle` = `CSSProperties`).
496
+
497
+ See `src/features/file-viewer/customization-types.ts` for all keys.
498
+
499
+ ## Contributing
500
+
501
+ 1. Fork the repository
502
+ 2. Create a feature branch: `git checkout -b my-feature`
503
+ 3. Commit changes: `git commit -am 'Add feature'`
504
+ 4. Push: `git push origin my-feature`
505
+ 5. Open a pull request
506
+
507
+ Run `npx tsc --noEmit` and `npm run build:lib` before submitting.
508
+
509
+ ## Built with
510
+
511
+ - [React](https://react.dev/)
512
+ - [react-pdf](https://github.com/wojtekmaj/react-pdf) / [pdf.js](https://mozilla.github.io/pdf.js/)
513
+ - [react-zoom-pan-pinch](https://github.com/BetterTyped/react-zoom-pan-pinch)
514
+ - Internal UI primitives (dialog, scroll area, tooltip) and inline SVG icons — no Radix UI or Lucide at runtime
515
+ - [Tailwind CSS](https://tailwindcss.com/) v4 (utilities in components; optional pre-built `file-viewer/style.css`)
516
+ - [Vite](https://vitejs.dev/) + [tsup](https://tsup.egoist.dev/) (playground + library build)
517
+
518
+ ## Versioning
519
+
520
+ This project uses [SemVer](https://semver.org/). See `package.json` for the current version.
521
+
522
+ ## License
523
+
524
+ [MIT](LICENSE) © file-viewer contributors
package/dist/index.css ADDED
@@ -0,0 +1,30 @@
1
+ /* src/features/file-viewer/pdf-viewer.css */
2
+ .pdf-viewer .textLayer ::-moz-selection {
3
+ background: rgba(0, 0, 255, 0.25);
4
+ background: color-mix(in srgb, AccentColor, transparent 75%);
5
+ color: transparent;
6
+ }
7
+ .pdf-viewer .textLayer ::selection {
8
+ background: rgba(0, 0, 255, 0.25);
9
+ background: color-mix(in srgb, AccentColor, transparent 75%);
10
+ color: transparent;
11
+ -webkit-text-fill-color: transparent;
12
+ }
13
+ .pdf-viewer .textLayer br::-moz-selection,
14
+ .pdf-viewer .textLayer br::selection {
15
+ background: transparent;
16
+ }
17
+ .pdf-viewer [data-layout-syncing=true] .textLayer {
18
+ opacity: 0;
19
+ pointer-events: none;
20
+ }
21
+ .pdf-viewer [data-layout-syncing=true] canvas {
22
+ object-fit: contain;
23
+ }
24
+ .pdf-viewer .pdf-scroll-viewport {
25
+ scrollbar-width: none;
26
+ }
27
+ .pdf-viewer .pdf-scroll-viewport::-webkit-scrollbar {
28
+ display: none;
29
+ }
30
+ /*# sourceMappingURL=index.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/features/file-viewer/pdf-viewer.css"],"sourcesContent":["/**\n * PDF viewer overrides (selection + layout sync).\n * Requires react-pdf TextLayer.css to be loaded first.\n */\n\n/* Mozilla-style selection: highlight only, no visible glyph fill */\n.pdf-viewer .textLayer ::-moz-selection {\n background: rgba(0, 0, 255, 0.25);\n background: color-mix(in srgb, AccentColor, transparent 75%);\n color: transparent;\n}\n\n.pdf-viewer .textLayer ::selection {\n background: rgba(0, 0, 255, 0.25);\n background: color-mix(in srgb, AccentColor, transparent 75%);\n color: transparent;\n -webkit-text-fill-color: transparent;\n}\n\n.pdf-viewer .textLayer br::-moz-selection,\n.pdf-viewer .textLayer br::selection {\n background: transparent;\n}\n\n/* Hide misaligned text layer while canvas size catches up (canvas stays visible, scaled via layout) */\n.pdf-viewer [data-layout-syncing='true'] .textLayer {\n opacity: 0;\n pointer-events: none;\n}\n\n/* Keep canvas visible and proportionally scaled while layout catches up */\n.pdf-viewer [data-layout-syncing='true'] canvas {\n object-fit: contain;\n}\n\n/* Hide native scrollbars; custom ScrollAreaScrollbar is used instead */\n.pdf-viewer .pdf-scroll-viewport {\n scrollbar-width: none;\n}\n\n.pdf-viewer .pdf-scroll-viewport::-webkit-scrollbar {\n display: none;\n}\n"],"mappings":";AAMA,CAAC,WAAW,CAAC,UAAU;AACrB,cAAY,KAAK,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE;AAC5B,cAAY,UAAU,GAAG,IAAI,EAAE,WAAW,EAAE,YAAY;AACxD,SAAO;AACT;AAEA,CANC,WAMW,CANC,UAMU;AACrB,cAAY,KAAK,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE;AAC5B,cAAY,UAAU,GAAG,IAAI,EAAE,WAAW,EAAE,YAAY;AACxD,SAAO;AACP,2BAAyB;AAC3B;AAEA,CAbC,WAaW,CAbC,UAaU,EAAE;AACzB,CAdC,WAcW,CAdC,UAcU,EAAE;AACvB,cAAY;AACd;AAGA,CAnBC,WAmBW,CAAC,0BAA4B,CAnB5B;AAoBX,WAAS;AACT,kBAAgB;AAClB;AAGA,CAzBC,WAyBW,CAAC,0BAA4B;AACvC,cAAY;AACd;AAGA,CA9BC,WA8BW,CAAC;AACX,mBAAiB;AACnB;AAEA,CAlCC,WAkCW,CAJC,mBAImB;AAC9B,WAAS;AACX;","names":[]}