svelte-pdf-view 0.1.9 → 0.1.11

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
@@ -112,11 +112,12 @@ The main container component that provides context for toolbar and renderer.
112
112
  </PdfViewer>
113
113
  ```
114
114
 
115
- | Prop | Type | Default | Description |
116
- | ------- | ----------- | -------- | -------------------------------------------------- |
117
- | `src` | `PdfSource` | required | PDF source (URL, ArrayBuffer, Uint8Array, or Blob) |
118
- | `scale` | `number` | `1.0` | Initial zoom scale |
119
- | `class` | `string` | `''` | CSS class for the container |
115
+ | Prop | Type | Default | Description |
116
+ | ------------------ | ----------- | -------- | ---------------------------------------------------------------------- |
117
+ | `src` | `PdfSource` | required | PDF source (URL, ArrayBuffer, Uint8Array, or Blob) |
118
+ | `scale` | `number` | `1.0` | Initial zoom scale |
119
+ | `downloadFilename` | `string` | - | Custom filename for PDF download (default: from URL or 'document.pdf') |
120
+ | `class` | `string` | `''` | CSS class for the container |
120
121
 
121
122
  ### `<PdfToolbar>`
122
123
 
@@ -166,7 +166,7 @@
166
166
  viewerState.searchTotal = 0;
167
167
  }
168
168
  },
169
- download: () => {} // Download is handled by PdfViewer, not renderer
169
+ download: async () => {} // Download is handled by PdfViewer, not renderer
170
170
  };
171
171
 
172
172
  onMount(async () => {
@@ -18,13 +18,21 @@
18
18
  src: PdfSource;
19
19
  /** Initial scale (default: 1.0) */
20
20
  scale?: number;
21
+ /** Custom filename for PDF download (default: extracted from URL or 'document.pdf') */
22
+ downloadFilename?: string;
21
23
  /** CSS class for the container */
22
24
  class?: string;
23
25
  /** Children (toolbar and renderer) */
24
26
  children?: Snippet;
25
27
  }
26
28
 
27
- let { src, scale: initialScale = 1.0, class: className = '', children }: Props = $props();
29
+ let {
30
+ src,
31
+ scale: initialScale = 1.0,
32
+ downloadFilename,
33
+ class: className = '',
34
+ children
35
+ }: Props = $props();
28
36
 
29
37
  // Reactive state that will be shared via context
30
38
  let state = $state<PdfViewerState>({
@@ -44,45 +52,44 @@
44
52
  let rendererActions: PdfViewerActions | null = null;
45
53
 
46
54
  // Download helper function
47
- function downloadPdf(filename?: string) {
55
+ async function downloadPdf(filenameOverride?: string) {
48
56
  const downloadName =
49
- filename ||
57
+ filenameOverride ||
58
+ downloadFilename ||
50
59
  (typeof src === 'string' ? src.split('/').pop() : 'document.pdf') ||
51
60
  'document.pdf';
52
61
 
62
+ let blob: Blob;
63
+
53
64
  if (typeof src === 'string') {
54
- // URL - fetch and download
55
- const link = document.createElement('a');
56
- link.href = src;
57
- link.download = downloadName;
58
- link.click();
65
+ // URL - fetch first to handle cross-origin URLs (e.g., Firebase Storage)
66
+ // The download attribute is ignored for cross-origin URLs
67
+ try {
68
+ const response = await fetch(src);
69
+ blob = await response.blob();
70
+ } catch {
71
+ // Fallback for same-origin URLs if fetch fails
72
+ const link = document.createElement('a');
73
+ link.href = src;
74
+ link.download = downloadName;
75
+ link.click();
76
+ return;
77
+ }
59
78
  } else if (src instanceof Blob) {
60
- // Blob - create object URL
61
- const url = URL.createObjectURL(src);
62
- const link = document.createElement('a');
63
- link.href = url;
64
- link.download = downloadName;
65
- link.click();
66
- URL.revokeObjectURL(url);
79
+ blob = src;
67
80
  } else if (src instanceof ArrayBuffer) {
68
- // ArrayBuffer
69
- const blob = new Blob([src], { type: 'application/pdf' });
70
- const url = URL.createObjectURL(blob);
71
- const link = document.createElement('a');
72
- link.href = url;
73
- link.download = downloadName;
74
- link.click();
75
- URL.revokeObjectURL(url);
81
+ blob = new Blob([src], { type: 'application/pdf' });
76
82
  } else {
77
- // Uint8Array - create a copy as ArrayBuffer
78
- const blob = new Blob([new Uint8Array(src)], { type: 'application/pdf' });
79
- const url = URL.createObjectURL(blob);
80
- const link = document.createElement('a');
81
- link.href = url;
82
- link.download = downloadName;
83
- link.click();
84
- URL.revokeObjectURL(url);
83
+ // Uint8Array
84
+ blob = new Blob([new Uint8Array(src)], { type: 'application/pdf' });
85
85
  }
86
+
87
+ const url = URL.createObjectURL(blob);
88
+ const link = document.createElement('a');
89
+ link.href = url;
90
+ link.download = downloadName;
91
+ link.click();
92
+ URL.revokeObjectURL(url);
86
93
  }
87
94
 
88
95
  // Actions that proxy to the renderer
@@ -7,6 +7,8 @@ interface Props {
7
7
  src: PdfSource;
8
8
  /** Initial scale (default: 1.0) */
9
9
  scale?: number;
10
+ /** Custom filename for PDF download (default: extracted from URL or 'document.pdf') */
11
+ downloadFilename?: string;
10
12
  /** CSS class for the container */
11
13
  class?: string;
12
14
  /** Children (toolbar and renderer) */
@@ -23,7 +23,7 @@ export interface PdfViewerActions {
23
23
  searchNext: () => void;
24
24
  searchPrevious: () => void;
25
25
  clearSearch: () => void;
26
- download: (filename?: string) => void;
26
+ download: (filename?: string) => Promise<void>;
27
27
  }
28
28
  export interface PdfViewerContext {
29
29
  state: PdfViewerState;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-pdf-view",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "A modern, modular PDF viewer component for Svelte 5. Built on PDF.js with TypeScript support",
5
5
  "author": "Louis Li",
6
6
  "license": "Apache-2.0",