@abduljebar/pdf-reader 1.0.1 → 1.0.5

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/README.md CHANGED
@@ -1,73 +1,428 @@
1
- # React + TypeScript + Vite
1
+ # React PDF Viewer Library
2
2
 
3
- This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
3
+ A modern, feature-rich PDF viewer component built with React, TypeScript, and Vite. This library provides a responsive PDF viewing experience with extensive customization options.
4
4
 
5
- Currently, two official plugins are available:
5
+ ## Features
6
6
 
7
- - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
8
- - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
7
+ ### 📱 **Responsive Design**
8
+ - Mobile-first approach with adaptive layouts
9
+ - Touch-friendly controls with gesture support
10
+ - Optimized for all screen sizes (mobile, tablet, desktop)
11
+ - Bottom-sheet navigation on mobile devices
9
12
 
10
- ## React Compiler
13
+ ### 🎨 **Customization**
14
+ - Configurable toolbar with toggle options
15
+ - Multiple view modes (vertical, horizontal, single page)
16
+ - Custom sidebar panels (thumbnails, outline, annotations)
17
+ - Theme support (light, dark, system)
18
+ - Custom CSS classes for styling
11
19
 
12
- The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
20
+ ### 🔧 **Core Features**
21
+ - High-performance PDF rendering with pdf.js
22
+ - Zoom controls (in/out, fit to width, fit to page)
23
+ - Page navigation with keyboard shortcuts
24
+ - Search functionality
25
+ - Print and download support
26
+ - File upload with drag & drop
27
+ - Smooth scrolling and transitions
13
28
 
14
- ## Expanding the ESLint configuration
29
+ ### 🎯 **UI/UX Enhancements**
30
+ - Smooth animations and transitions
31
+ - Loading states with skeleton screens
32
+ - Error handling with recovery options
33
+ - Accessible with ARIA labels
34
+ - Keyboard navigation support
35
+ - Touch gesture support
15
36
 
16
- If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
37
+ ## 📦 Installation
17
38
 
18
- ```js
19
- export default defineConfig([
20
- globalIgnores(['dist']),
21
- {
22
- files: ['**/*.{ts,tsx}'],
23
- extends: [
24
- // Other configs...
39
+ ```bash
40
+ npm install @your-library/pdf-viewer
41
+ # or
42
+ yarn add @your-library/pdf-viewer
43
+ ```
25
44
 
26
- // Remove tseslint.configs.recommended and replace with this
27
- tseslint.configs.recommendedTypeChecked,
28
- // Alternatively, use this for stricter rules
29
- tseslint.configs.strictTypeChecked,
30
- // Optionally, add this for stylistic rules
31
- tseslint.configs.stylisticTypeChecked,
45
+ ## 🚀 Quick Start
32
46
 
33
- // Other configs...
34
- ],
35
- languageOptions: {
36
- parserOptions: {
37
- project: ['./tsconfig.node.json', './tsconfig.app.json'],
38
- tsconfigRootDir: import.meta.dirname,
39
- },
40
- // other options...
41
- },
42
- },
43
- ])
44
- ```
45
-
46
- You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
47
-
48
- ```js
49
- // eslint.config.js
50
- import reactX from 'eslint-plugin-react-x'
51
- import reactDom from 'eslint-plugin-react-dom'
52
-
53
- export default defineConfig([
54
- globalIgnores(['dist']),
55
- {
56
- files: ['**/*.{ts,tsx}'],
57
- extends: [
58
- // Other configs...
59
- // Enable lint rules for React
60
- reactX.configs['recommended-typescript'],
61
- // Enable lint rules for React DOM
62
- reactDom.configs.recommended,
63
- ],
64
- languageOptions: {
65
- parserOptions: {
66
- project: ['./tsconfig.node.json', './tsconfig.app.json'],
67
- tsconfigRootDir: import.meta.dirname,
47
+ ```tsx
48
+ import { PDFViewer } from '@your-library/pdf-viewer';
49
+ import '@your-library/pdf-viewer/dist/style.css';
50
+
51
+ function App() {
52
+ return (
53
+ <div style={{ height: '100vh' }}>
54
+ <PDFViewer
55
+ pdfUrl="/document.pdf"
56
+ config={{
57
+ enableDarkMode: true,
58
+ enableZoom: true,
59
+ enablePageNavigation: true,
60
+ defaultZoom: 1,
61
+ defaultScrollMode: 'vertical',
62
+ showThumbnails: true,
63
+ showOutline: true,
64
+ }}
65
+ theme="system"
66
+ onPageChange={(page) => console.log('Page:', page)}
67
+ onZoomChange={(zoom) => console.log('Zoom:', zoom)}
68
+ />
69
+ </div>
70
+ );
71
+ }
72
+ ```
73
+
74
+ ## 📖 Documentation
75
+
76
+ ### Basic Usage
77
+
78
+ ```tsx
79
+ import { PDFViewer } from '@your-library/pdf-viewer';
80
+
81
+ function MyPDFViewer() {
82
+ return (
83
+ <PDFViewer
84
+ pdfUrl="https://example.com/document.pdf"
85
+ config={{
86
+ enableDarkMode: true,
87
+ enableZoom: true,
88
+ enablePageNavigation: true,
89
+ }}
90
+ />
91
+ );
92
+ }
93
+ ```
94
+
95
+ ### With File Upload
96
+
97
+ ```tsx
98
+ function PDFUploadViewer() {
99
+ const [file, setFile] = useState<File | null>(null);
100
+
101
+ return (
102
+ <PDFViewer
103
+ file={file}
104
+ config={{
105
+ enableFileUpload: true,
106
+ }}
107
+ onFileSelect={(selectedFile) => {
108
+ setFile(selectedFile);
109
+ console.log('File selected:', selectedFile.name);
110
+ }}
111
+ />
112
+ );
113
+ }
114
+ ```
115
+
116
+ ### Advanced Configuration
117
+
118
+ ```tsx
119
+ <PDFViewer
120
+ pdfUrl="/document.pdf"
121
+ config={{
122
+ // Feature toggles
123
+ enableDarkMode: true,
124
+ enableZoom: true,
125
+ enablePageNavigation: true,
126
+ enableViewModeToggle: true,
127
+ enableFileUpload: true,
128
+ enableSearch: true,
129
+ enablePrint: true,
130
+ enableDownload: true,
131
+
132
+ // Display options
133
+ defaultZoom: 1,
134
+ minZoom: 0.25,
135
+ maxZoom: 3,
136
+ defaultScrollMode: 'vertical',
137
+ showThumbnails: true,
138
+ showOutline: true,
139
+ showAnnotations: false,
140
+ pageGap: 40,
141
+
142
+ // UI/UX options
143
+ enableKeyboardNavigation: true,
144
+ enableSmoothScrolling: true,
145
+ showPageNumbers: true,
146
+ showDocumentTitle: true,
147
+ }}
148
+
149
+ // Layout
150
+ showSidebar={true}
151
+ sidebarWidth={280}
152
+ sidebarPosition="left"
153
+
154
+ // Theme
155
+ theme="system"
156
+
157
+ // Callbacks
158
+ onLoad={(pdfDoc) => console.log('PDF loaded:', pdfDoc)}
159
+ onError={(error) => console.error('Error:', error)}
160
+ onPageChange={(page) => console.log('Page changed:', page)}
161
+ onZoomChange={(zoom) => console.log('Zoom changed:', zoom)}
162
+
163
+ // Custom components
164
+ customToolbar={<MyCustomToolbar />}
165
+ customSidebar={<MyCustomSidebar />}
166
+ customLoadingComponent={<MyLoadingSpinner />}
167
+ />
168
+ ```
169
+
170
+ ## 🏗️ Component Architecture
171
+
172
+ ```
173
+ src/
174
+ ├── components/
175
+ │ ├── PDFViewer/
176
+ │ │ ├── PDFViewer.tsx # Main component
177
+ │ │ ├── Sidebar.tsx # Responsive sidebar
178
+ │ │ ├── PDFDocument.tsx # PDF rendering
179
+ │ │ ├── ThumbnailsPanel.tsx # Page thumbnails
180
+ │ │ ├── OutlinePanel.tsx # Document outline
181
+ │ │ └── AnnotationsPanel.tsx # Comments & highlights
182
+ │ │
183
+ │ └── Toolbar/
184
+ │ ├── Toolbar.tsx # Main toolbar
185
+ │ ├── ZoomControls.tsx # Zoom functionality
186
+ │ ├── PageControls.tsx # Page navigation
187
+ │ ├── ViewModeToggle.tsx # View mode switcher
188
+ │ ├── DarkModeToggle.tsx # Theme toggle
189
+ │ ├── FileUpload.tsx # File upload
190
+ │ └── ResponsiveDropdown.tsx # Mobile dropdown
191
+
192
+ ├── hooks/
193
+ │ └── useMediaQuery.ts # Responsive hooks
194
+
195
+ ├── types/
196
+ │ └── index.ts # TypeScript definitions
197
+
198
+ └── utils/
199
+ └── pdfWorker.ts # PDF.js setup
200
+ ```
201
+
202
+ ## 🎨 Styling
203
+
204
+ The library uses Tailwind CSS for styling. You can customize the appearance by:
205
+
206
+ 1. **Overriding CSS variables:**
207
+ ```css
208
+ :root {
209
+ --pdf-primary: #2563eb;
210
+ --pdf-secondary: #64748b;
211
+ --pdf-background: #ffffff;
212
+ --pdf-foreground: #1f2937;
213
+ }
214
+ ```
215
+
216
+ 2. **Using custom classes:**
217
+ ```tsx
218
+ <PDFViewer
219
+ className="my-custom-class"
220
+ toolbarClassName="my-toolbar-class"
221
+ sidebarClassName="my-sidebar-class"
222
+ documentClassName="my-document-class"
223
+ />
224
+ ```
225
+
226
+ 3. **Extending Tailwind config:**
227
+ ```javascript
228
+ // tailwind.config.js
229
+ module.exports = {
230
+ theme: {
231
+ extend: {
232
+ colors: {
233
+ 'pdf-primary': '#2563eb',
234
+ 'pdf-secondary': '#64748b',
68
235
  },
69
- // other options...
70
236
  },
71
237
  },
72
- ])
238
+ }
73
239
  ```
240
+
241
+ ## 📱 Responsive Breakpoints
242
+
243
+ | Device | Breakpoint | Features |
244
+ |--------|------------|----------|
245
+ | Mobile | < 768px | Bottom navigation, simplified controls, touch gestures |
246
+ | Tablet | 768px - 1024px | Condensed toolbar, medium sidebar |
247
+ | Desktop | > 1024px | Full toolbar, full sidebar, all features |
248
+
249
+ ## 🎯 Performance
250
+
251
+ - **Lazy loading**: Components load on demand
252
+ - **Virtual scrolling**: Only visible pages are rendered
253
+ - **Image optimization**: Thumbnails use appropriate resolutions
254
+ - **Memory management**: Proper cleanup of resources
255
+ - **Bundle optimization**: Code splitting for faster loads
256
+
257
+ ## 🔧 Development
258
+
259
+ ### Prerequisites
260
+ - Node.js 18+
261
+ - npm, yarn, or pnpm
262
+
263
+ ### Setup
264
+ ```bash
265
+ # Clone the repository
266
+ git clone <repository-url>
267
+ cd pdf-viewer-library
268
+
269
+ # Install dependencies
270
+ npm install
271
+
272
+ # Start development server
273
+ npm run dev
274
+
275
+ # Build for production
276
+ npm run build
277
+
278
+ # Run tests
279
+ npm test
280
+
281
+ # Lint code
282
+ npm run lint
283
+
284
+ # Type checking
285
+ npm run type-check
286
+ ```
287
+
288
+ ### Project Structure
289
+ ```
290
+ .
291
+ ├── src/ # Source code
292
+ ├── dist/ # Built files
293
+ ├── examples/ # Usage examples
294
+ ├── tests/ # Test files
295
+ ├── docs/ # Documentation
296
+ └── package.json
297
+ ```
298
+
299
+ ### Building for Distribution
300
+ ```bash
301
+ # Build library
302
+ npm run build:lib
303
+
304
+ # Build documentation
305
+ npm run build:docs
306
+
307
+ # Publish to npm
308
+ npm publish
309
+ ```
310
+
311
+ ## 🧪 Testing
312
+
313
+ ```bash
314
+ # Run all tests
315
+ npm test
316
+
317
+ # Run tests in watch mode
318
+ npm run test:watch
319
+
320
+ # Run tests with coverage
321
+ npm run test:coverage
322
+
323
+ # Run E2E tests
324
+ npm run test:e2e
325
+ ```
326
+
327
+ ## 📄 API Reference
328
+
329
+ ### PDFViewer Props
330
+
331
+ | Prop | Type | Default | Description |
332
+ |------|------|---------|-------------|
333
+ | `pdfUrl` | `string` | - | URL of the PDF to load |
334
+ | `file` | `File` | - | PDF file object |
335
+ | `config` | `PDFViewerConfig` | `{}` | Configuration object |
336
+ | `theme` | `'light' | 'dark' | 'system'` | `'system'` | Theme mode |
337
+ | `showSidebar` | `boolean` | `true` | Show/hide sidebar |
338
+ | `sidebarWidth` | `number` | `240` | Sidebar width in pixels |
339
+ | `sidebarPosition` | `'left' | 'right'` | `'left'` | Sidebar position |
340
+ | `onLoad` | `function` | - | Called when PDF loads |
341
+ | `onError` | `function` | - | Called on error |
342
+ | `onPageChange` | `function` | - | Called when page changes |
343
+ | `onZoomChange` | `function` | - | Called when zoom changes |
344
+
345
+ ### PDFViewerConfig
346
+
347
+ ```typescript
348
+ interface PDFViewerConfig {
349
+ // Feature toggles
350
+ enableDarkMode?: boolean;
351
+ enableZoom?: boolean;
352
+ enablePageNavigation?: boolean;
353
+ enableViewModeToggle?: boolean;
354
+ enableFileUpload?: boolean;
355
+ enableSearch?: boolean;
356
+ enablePrint?: boolean;
357
+ enableDownload?: boolean;
358
+
359
+ // Display options
360
+ defaultZoom?: number;
361
+ minZoom?: number;
362
+ maxZoom?: number;
363
+ defaultScrollMode?: ScrollMode;
364
+ showThumbnails?: boolean;
365
+ showOutline?: boolean;
366
+ showAnnotations?: boolean;
367
+ pageGap?: number;
368
+
369
+ // UI/UX options
370
+ enableKeyboardNavigation?: boolean;
371
+ enableSmoothScrolling?: boolean;
372
+ showPageNumbers?: boolean;
373
+ showDocumentTitle?: boolean;
374
+
375
+ // Customization
376
+ className?: string;
377
+ toolbarClassName?: string;
378
+ sidebarClassName?: string;
379
+ documentClassName?: string;
380
+ }
381
+ ```
382
+
383
+ ## 🤝 Contributing
384
+
385
+ 1. Fork the repository
386
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
387
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
388
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
389
+ 5. Open a Pull Request
390
+
391
+ ### Development Guidelines
392
+ - Follow TypeScript best practices
393
+ - Write comprehensive tests
394
+ - Document new features
395
+ - Update README when necessary
396
+ - Follow the existing code style
397
+
398
+ ## 📄 License
399
+
400
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
401
+
402
+ ## 🙏 Acknowledgments
403
+
404
+ - [PDF.js](https://mozilla.github.io/pdf.js/) - PDF rendering engine
405
+ - [Lucide React](https://lucide.dev/) - Beautiful icons
406
+ - [Tailwind CSS](https://tailwindcss.com/) - Utility-first CSS framework
407
+
408
+ ## 📞 Support
409
+
410
+ <!-- - **Documentation**: [Read the docs](https://your-library/docs) -->
411
+ - **Issues**: [GitHub Issues](https://github.com/abduljebar49/pdf-viewer/issues)
412
+ - **Discussions**: [GitHub Discussions](https://github.com/abduljebar49/pdf-viewer/discussions)
413
+ - **Email**: abduljebar49@gmail.com
414
+
415
+ ## 🚀 Roadmap
416
+
417
+ - [ ] Text selection and copying
418
+ - [ ] Annotation creation and editing
419
+ - [ ] Form filling support
420
+ - [ ] PDF/A compliance
421
+ - [ ] Multi-language support
422
+ - [ ] Plugin system
423
+ - [ ] Offline support
424
+ - [ ] Cloud storage integration
425
+
426
+ ---
427
+
428
+ Made with ❤️ by Abduljebar Sani
package/dist/index.css ADDED
@@ -0,0 +1 @@
1
+ @layer properties{@supports ((-webkit-hyphens:none) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-400:oklch(70.4% .191 22.216);--color-red-600:oklch(57.7% .245 27.325);--color-orange-500:oklch(70.5% .213 47.604);--color-yellow-300:oklch(90.5% .182 98.111);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-indigo-600:oklch(51.1% .262 276.966);--color-purple-500:oklch(62.7% .265 303.9);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--font-weight-medium:500;--font-weight-semibold:600;--radius-lg:.5rem;--radius-2xl:1rem;--animate-spin:spin 1s linear infinite;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::-moz-placeholder{opacity:1}::placeholder{opacity:1}@supports (not (-webkit-appearance:-apple-pay-button)) or (contain-intrinsic-size:1px){::-moz-placeholder{color:currentColor}::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::-moz-placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:calc(var(--spacing)*0)}.top-0{top:calc(var(--spacing)*0)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing)*2)}.top-full{top:100%}.right-0{right:calc(var(--spacing)*0)}.right-2{right:calc(var(--spacing)*2)}.right-4{right:calc(var(--spacing)*4)}.-bottom-1{bottom:calc(var(--spacing)*-1)}.bottom-0{bottom:calc(var(--spacing)*0)}.bottom-4{bottom:calc(var(--spacing)*4)}.bottom-20{bottom:calc(var(--spacing)*20)}.bottom-full{bottom:100%}.left-0{left:calc(var(--spacing)*0)}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing)*2)}.left-4{left:calc(var(--spacing)*4)}.-z-10{z-index:-10}.z-10{z-index:10}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing)*.5)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-auto{margin-top:auto}.mr-1{margin-right:calc(var(--spacing)*1)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-6{margin-left:calc(var(--spacing)*6)}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.hidden{display:none}.h-0\.5{height:calc(var(--spacing)*.5)}.h-1{height:calc(var(--spacing)*1)}.h-3{height:calc(var(--spacing)*3)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-8{height:calc(var(--spacing)*8)}.h-12{height:calc(var(--spacing)*12)}.h-32{height:calc(var(--spacing)*32)}.h-\[calc\(100vh-140px\)\]{height:calc(100vh - 140px)}.h-auto{height:auto}.h-full{height:100%}.h-screen{height:100vh}.max-h-\[60vh\]{max-height:60vh}.max-h-\[80vh\]{max-height:80vh}.w-3{width:calc(var(--spacing)*3)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-8{width:calc(var(--spacing)*8)}.w-12{width:calc(var(--spacing)*12)}.w-16{width:calc(var(--spacing)*16)}.w-48{width:calc(var(--spacing)*48)}.w-\[85vw\]{width:85vw}.w-full{width:100%}.w-screen{width:100vw}.max-w-\[200px\]{max-width:200px}.max-w-\[320px\]{max-width:320px}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-\[60px\]{min-width:60px}.min-w-\[200px\]{min-width:200px}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.scale-0{--tw-scale-x:0%;--tw-scale-y:0%;--tw-scale-z:0%;scale:var(--tw-scale-x)var(--tw-scale-y)}.scale-100{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x)var(--tw-scale-y)}.-rotate-90{rotate:-90deg}.rotate-0{rotate:none}.rotate-90{rotate:90deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing)*1)}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.scroll-smooth{scroll-behavior:smooth}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-t-2xl{border-top-left-radius:var(--radius-2xl);border-top-right-radius:var(--radius-2xl)}.rounded-l-lg{border-top-left-radius:var(--radius-lg);border-bottom-left-radius:var(--radius-lg)}.rounded-l-none{border-top-left-radius:0;border-bottom-left-radius:0}.rounded-r-lg{border-top-right-radius:var(--radius-lg);border-bottom-right-radius:var(--radius-lg)}.rounded-r-none{border-top-right-radius:0;border-bottom-right-radius:0}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-8{border-style:var(--tw-border-style);border-width:8px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-0{border-left-style:var(--tw-border-style);border-left-width:0}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-blue-500{border-color:var(--color-blue-500)}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-gray-400{border-color:var(--color-gray-400)}.border-gray-500{border-color:var(--color-gray-500)}.border-gray-600{border-color:var(--color-gray-600)}.border-gray-700{border-color:var(--color-gray-700)}.border-gray-800{border-color:var(--color-gray-800)}.border-transparent{border-color:#0000}.border-t-gray-800{border-top-color:var(--color-gray-800)}.border-t-gray-900{border-top-color:var(--color-gray-900)}.border-t-transparent{border-top-color:#0000}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black)50%,transparent)}}.bg-blue-400{background-color:var(--color-blue-400)}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-500\/20{background-color:#3080ff33}@supports (color:color-mix(in lab,red,red)){.bg-blue-500\/20{background-color:color-mix(in oklab,var(--color-blue-500)20%,transparent)}}.bg-blue-600{background-color:var(--color-blue-600)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-gray-300{background-color:var(--color-gray-300)}.bg-gray-700{background-color:var(--color-gray-700)}.bg-gray-800{background-color:var(--color-gray-800)}.bg-gray-800\/50{background-color:#1e293980}@supports (color:color-mix(in lab,red,red)){.bg-gray-800\/50{background-color:color-mix(in oklab,var(--color-gray-800)50%,transparent)}}.bg-gray-800\/80{background-color:#1e2939cc}@supports (color:color-mix(in lab,red,red)){.bg-gray-800\/80{background-color:color-mix(in oklab,var(--color-gray-800)80%,transparent)}}.bg-gray-800\/90{background-color:#1e2939e6}@supports (color:color-mix(in lab,red,red)){.bg-gray-800\/90{background-color:color-mix(in oklab,var(--color-gray-800)90%,transparent)}}.bg-gray-900{background-color:var(--color-gray-900)}.bg-red-400{background-color:var(--color-red-400)}.bg-white{background-color:var(--color-white)}.bg-white\/80{background-color:#fffc}@supports (color:color-mix(in lab,red,red)){.bg-white\/80{background-color:color-mix(in oklab,var(--color-white)80%,transparent)}}.bg-white\/90{background-color:#ffffffe6}@supports (color:color-mix(in lab,red,red)){.bg-white\/90{background-color:color-mix(in oklab,var(--color-white)90%,transparent)}}.bg-yellow-400\/50{background-color:#fac80080}@supports (color:color-mix(in lab,red,red)){.bg-yellow-400\/50{background-color:color-mix(in oklab,var(--color-yellow-400)50%,transparent)}}.bg-yellow-500\/10{background-color:#edb2001a}@supports (color:color-mix(in lab,red,red)){.bg-yellow-500\/10{background-color:color-mix(in oklab,var(--color-yellow-500)10%,transparent)}}.bg-gradient-to-br{--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-blue-400{--tw-gradient-from:var(--color-blue-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-blue-500{--tw-gradient-from:var(--color-blue-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-gray-100{--tw-gradient-from:var(--color-gray-100);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-gray-200{--tw-gradient-from:var(--color-gray-200);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-gray-700{--tw-gradient-from:var(--color-gray-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-yellow-400{--tw-gradient-from:var(--color-yellow-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-gray-200{--tw-gradient-to:var(--color-gray-200);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-gray-300{--tw-gradient-to:var(--color-gray-300);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-gray-800{--tw-gradient-to:var(--color-gray-800);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-indigo-600{--tw-gradient-to:var(--color-indigo-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-orange-500{--tw-gradient-to:var(--color-orange-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-purple-500{--tw-gradient-to:var(--color-purple-500);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.p-1{padding:calc(var(--spacing)*1)}.p-1\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-6{padding:calc(var(--spacing)*6)}.p-8{padding:calc(var(--spacing)*8)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.py-8{padding-block:calc(var(--spacing)*8)}.pr-8{padding-right:calc(var(--spacing)*8)}.text-center{text-align:center}.text-left{text-align:left}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-nowrap{white-space:nowrap}.text-blue-300{color:var(--color-blue-300)}.text-blue-400{color:var(--color-blue-400)}.text-blue-500{color:var(--color-blue-500)}.text-blue-600{color:var(--color-blue-600)}.text-gray-100{color:var(--color-gray-100)}.text-gray-200{color:var(--color-gray-200)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-800{color:var(--color-gray-800)}.text-gray-900{color:var(--color-gray-900)}.text-white{color:var(--color-white)}.text-yellow-300{color:var(--color-yellow-300)}.text-yellow-500{color:var(--color-yellow-500)}.italic{font-style:italic}.underline{text-decoration-line:underline}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-blue-300{--tw-ring-color:var(--color-blue-300)}.ring-blue-500\/50{--tw-ring-color:#3080ff80}@supports (color:color-mix(in lab,red,red)){.ring-blue-500\/50{--tw-ring-color:color-mix(in oklab,var(--color-blue-500)50%,transparent)}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur-sm{--tw-blur:blur(var(--blur-sm));filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}@media(hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.hover\:border-gray-400:hover{border-color:var(--color-gray-400)}.hover\:border-gray-600:hover{border-color:var(--color-gray-600)}.hover\:bg-blue-700:hover{background-color:var(--color-blue-700)}.hover\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-200:hover{background-color:var(--color-gray-200)}.hover\:bg-gray-300:hover{background-color:var(--color-gray-300)}.hover\:bg-gray-600:hover{background-color:var(--color-gray-600)}.hover\:bg-gray-700:hover{background-color:var(--color-gray-700)}.hover\:bg-gray-800:hover{background-color:var(--color-gray-800)}.hover\:from-gray-200:hover{--tw-gradient-from:var(--color-gray-200);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:from-gray-600:hover{--tw-gradient-from:var(--color-gray-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:to-gray-300:hover{--tw-gradient-to:var(--color-gray-300);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:to-gray-700:hover{--tw-gradient-to:var(--color-gray-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.hover\:text-gray-300:hover{color:var(--color-gray-300)}.hover\:text-gray-700:hover{color:var(--color-gray-700)}.hover\:text-red-400:hover{color:var(--color-red-400)}.hover\:text-red-600:hover{color:var(--color-red-600)}.hover\:opacity-80:hover{opacity:.8}.hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:ring-1:hover{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:ring-gray-300:hover{--tw-ring-color:var(--color-gray-300)}.hover\:ring-gray-600:hover{--tw-ring-color:var(--color-gray-600)}}.focus\:border-blue-500:focus{border-color:var(--color-blue-500)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-blue-400:focus{--tw-ring-color:var(--color-blue-400)}.focus\:ring-blue-500:focus{--tw-ring-color:var(--color-blue-500)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.active\:scale-95:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x)var(--tw-scale-y)}.disabled\:text-gray-400:disabled{color:var(--color-gray-400)}.disabled\:text-gray-500:disabled{color:var(--color-gray-500)}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}@media(min-width:40rem){.sm\:block{display:block}}@media(min-width:48rem){.md\:flex{display:flex}.md\:hidden{display:none}.md\:gap-2{gap:calc(var(--spacing)*2)}.md\:gap-3{gap:calc(var(--spacing)*3)}.md\:px-4{padding-inline:calc(var(--spacing)*4)}}@media(min-width:64rem){.lg\:block{display:block}}@media(prefers-color-scheme:dark){.dark\:border-gray-700{border-color:var(--color-gray-700)}.dark\:from-gray-700{--tw-gradient-from:var(--color-gray-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.dark\:to-gray-800{--tw-gradient-to:var(--color-gray-800);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}}}.pdf-container{scroll-snap-type:x mandatory;flex-direction:row;display:flex;overflow:auto hidden}.pdf-viewer-scrollbar{scrollbar-width:thin;scrollbar-color:#9ca3af transparent}.pdf-viewer-scrollbar::-webkit-scrollbar{width:12px;height:12px}.pdf-viewer-scrollbar::-webkit-scrollbar-track{background:0 0}.pdf-viewer-scrollbar::-webkit-scrollbar-thumb{background-color:#9ca3af;background-clip:content-box;border:3px solid #0000;border-radius:6px}.pdf-viewer-scrollbar::-webkit-scrollbar-thumb:hover{background-color:#6b7280}.dark .pdf-viewer-scrollbar::-webkit-scrollbar-thumb{background-color:#4b5563}.dark .pdf-viewer-scrollbar::-webkit-scrollbar-thumb:hover{background-color:#6b7280}.page-transition{transition:all .3s cubic-bezier(.4,0,.2,1)}@media print{.toolbar,.thumbnails,.scroll-buttons,.page-counter{display:none!important}.pdf-pages{width:100%!important;height:auto!important;padding:0!important;display:block!important}.pdf-page{-moz-column-break-inside:avoid;break-inside:avoid;page-break-inside:avoid;margin-bottom:20px}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}
package/dist/index.d.ts CHANGED
@@ -1,13 +1,93 @@
1
1
  import { FC } from 'react';
2
+ import * as pdfjsLib from 'pdfjs-dist';
2
3
 
3
4
  declare const PDFViewer: FC<PDFViewerProps>;
4
5
  export default PDFViewer;
5
6
 
6
- export declare interface PDFViewerProps {
7
- scrollMode?: ScrollMode;
7
+ declare interface PDFViewerConfig {
8
+ enableDarkMode?: boolean;
9
+ enableZoom?: boolean;
10
+ enablePageNavigation?: boolean;
11
+ enableViewModeToggle?: boolean;
12
+ enableFileUpload?: boolean;
13
+ enableSearch?: boolean;
14
+ enablePrint?: boolean;
15
+ enableDownload?: boolean;
16
+ defaultZoom?: number;
17
+ minZoom?: number;
18
+ maxZoom?: number;
19
+ defaultScrollMode?: ScrollMode;
20
+ showThumbnails?: boolean;
21
+ showOutline?: boolean;
22
+ showAnnotations?: boolean;
23
+ pageGap?: number;
24
+ enableKeyboardNavigation?: boolean;
25
+ enableSmoothScrolling?: boolean;
26
+ showPageNumbers?: boolean;
27
+ showDocumentTitle?: boolean;
28
+ className?: string;
29
+ toolbarClassName?: string;
30
+ sidebarClassName?: string;
31
+ documentClassName?: string;
32
+ }
33
+
34
+ export declare interface PDFViewerProps extends Partial<ToolbarProps> {
8
35
  pdfUrl?: string;
36
+ file?: File;
37
+ config?: PDFViewerConfig;
38
+ showSidebar?: boolean;
39
+ sidebarWidth?: number;
40
+ sidebarPosition?: 'left' | 'right';
41
+ theme?: ViewerTheme;
42
+ mobileBreakpoint?: number;
43
+ tabletBreakpoint?: number;
44
+ onLoad?: (pdfDoc: pdfjsLib.PDFDocumentProxy) => void;
45
+ onError?: (error: Error) => void;
46
+ onPageChange?: (page: number) => void;
47
+ onZoomChange?: (zoom: number) => void;
48
+ }
49
+
50
+ declare type ScrollMode = 'vertical' | 'horizontal' | 'horizontal-single';
51
+
52
+ declare interface ToolbarProps {
53
+ onFileSelected?: (file: File) => void;
54
+ filePathSpan?: string;
55
+ showFileUpload?: boolean;
56
+ onZoomIn?: () => void;
57
+ onZoomOut?: () => void;
58
+ onZoomToFit?: () => void;
59
+ onZoomToWidth?: () => void;
60
+ onZoomToPage?: () => void;
61
+ onZoomChange?: (zoom: number) => void;
62
+ currentZoom?: number;
63
+ showZoomControls?: boolean;
64
+ onPrint?: () => void;
65
+ onDownload?: () => void;
66
+ onSearch?: (query: string) => void;
67
+ showPrint?: boolean;
68
+ showDownload?: boolean;
69
+ showSearch?: boolean;
70
+ darkMode?: boolean;
71
+ onToggleDarkMode?: () => void;
72
+ showDarkModeToggle?: boolean;
73
+ totalPages?: number;
74
+ currentPage?: number;
75
+ onPageChange?: (page: number) => void;
76
+ showPageControls?: boolean;
77
+ scrollMode?: "vertical" | "horizontal" | "horizontal-single";
78
+ onToggleScrollMode?: () => void;
79
+ onPrevPage?: () => void;
80
+ onNextPage?: () => void;
81
+ showViewModeToggle?: boolean;
82
+ customButtons?: React.ReactNode[];
83
+ showSidebarToggle?: boolean;
84
+ onToggleSidebar?: () => void;
85
+ sidebarOpen?: boolean;
86
+ isLoading?: boolean;
87
+ showCloseButton?: boolean;
88
+ onClose?: () => void;
9
89
  }
10
90
 
11
- export declare type ScrollMode = "vertical" | "horizontal" | "horizontal-single";
91
+ declare type ViewerTheme = 'light' | 'dark' | 'system';
12
92
 
13
93
  export { }