@widgetic/design-system 0.5.20 → 0.5.22
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.
|
@@ -33,6 +33,10 @@
|
|
|
33
33
|
export let enableSpaceKey = false;
|
|
34
34
|
export let isSelected = false;
|
|
35
35
|
export let showScroll = false;
|
|
36
|
+
// An image preview stays hidden until its real size is known, so the card does not open large and then shrink.
|
|
37
|
+
export let shown = true;
|
|
38
|
+
// Width and height ease to the content, instead of jumping.
|
|
39
|
+
export let animateSize = false;
|
|
36
40
|
// The words a screen reader says for the close button. A page that shows the modal in another language passes its own.
|
|
37
41
|
export let closeLabel: string = 'Close modal';
|
|
38
42
|
|
|
@@ -319,6 +323,8 @@
|
|
|
319
323
|
min-height: {2 * contentPadding + 50}px;
|
|
320
324
|
max-width: {modalStyle.maxWidth};
|
|
321
325
|
max-height: {modalStyle.maxHeight};
|
|
326
|
+
visibility: {viewportWidth === 0 || !shown ? 'hidden' : 'visible'};
|
|
327
|
+
transition: {animateSize ? 'width 200ms ease, height 200ms ease' : 'none'};
|
|
322
328
|
padding: {contentPadding}px 0;
|
|
323
329
|
user-select: text;
|
|
324
330
|
-webkit-user-select: text;
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
// words (tooltips and screen readers): a page that shows this in another language passes its own
|
|
41
41
|
export let backLabel: string = 'Back';
|
|
42
42
|
export let forwardLabel: string = 'Forward';
|
|
43
|
-
export let rootLabel: string = '
|
|
43
|
+
export let rootLabel: string = 'Files';
|
|
44
44
|
export let breadcrumbLabel: string = 'breadcrumb';
|
|
45
45
|
// event handlers
|
|
46
46
|
export let onNavigate: BreadcrumbsProps['onNavigate'] = () => {};
|
|
@@ -76,6 +76,16 @@
|
|
|
76
76
|
let scale = 1.5;
|
|
77
77
|
let loading = true;
|
|
78
78
|
let error: string | null = null;
|
|
79
|
+
// pdf.js reads the file with fetch. The upload host sends no CORS header, so that read fails.
|
|
80
|
+
// The browser's own viewer loads the same address as a frame, which does not need that header.
|
|
81
|
+
let browserFrameUrl = '';
|
|
82
|
+
let frameHeight = 640;
|
|
83
|
+
|
|
84
|
+
function sizeBrowserFrame() {
|
|
85
|
+
const host = containerDiv?.closest('.file-browser-module') || containerDiv?.closest('.portal-contents');
|
|
86
|
+
const available = host instanceof HTMLElement ? host.clientHeight : 0;
|
|
87
|
+
frameHeight = Math.max(360, (available || 720) - 140);
|
|
88
|
+
}
|
|
79
89
|
let mounted = false;
|
|
80
90
|
let currentUrl = '';
|
|
81
91
|
let canvasWidth = initialContainerWidth; // Start with initial size
|
|
@@ -194,6 +204,26 @@
|
|
|
194
204
|
renderPDF();
|
|
195
205
|
}
|
|
196
206
|
|
|
207
|
+
function prefersBrowserFrame(absoluteUrl: string): boolean {
|
|
208
|
+
try {
|
|
209
|
+
const parsed = new URL(absoluteUrl, window.location.href);
|
|
210
|
+
const isHttp = parsed.protocol === 'http:' || parsed.protocol === 'https:';
|
|
211
|
+
return isHttp && parsed.origin !== window.location.origin;
|
|
212
|
+
} catch {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function showBrowserFrame(absoluteUrl: string) {
|
|
218
|
+
currentUrl = url;
|
|
219
|
+
browserFrameUrl = absoluteUrl;
|
|
220
|
+
sizeBrowserFrame();
|
|
221
|
+
error = null;
|
|
222
|
+
isCanvasReady = true;
|
|
223
|
+
pdfDoc = null;
|
|
224
|
+
renderingPhase = 'ready';
|
|
225
|
+
}
|
|
226
|
+
|
|
197
227
|
async function loadPDF() {
|
|
198
228
|
if (!url || !browser) {
|
|
199
229
|
console.error('Cannot load PDF: missing URL or not in browser');
|
|
@@ -211,12 +241,20 @@
|
|
|
211
241
|
// Reset state
|
|
212
242
|
loading = true;
|
|
213
243
|
error = null;
|
|
244
|
+
browserFrameUrl = '';
|
|
214
245
|
isCanvasReady = false;
|
|
215
246
|
showPdfContent = false;
|
|
216
247
|
loadedFromCache = false;
|
|
217
248
|
|
|
218
249
|
// Get absolute URL for cache key
|
|
219
250
|
const absoluteUrl = getAbsoluteUrl(url);
|
|
251
|
+
|
|
252
|
+
// A file on another host (the upload CDN) has no CORS header. pdf.js would fetch it and the
|
|
253
|
+
// browser would log that failure. The browser's own viewer loads it as a frame instead.
|
|
254
|
+
if (prefersBrowserFrame(absoluteUrl)) {
|
|
255
|
+
showBrowserFrame(absoluteUrl);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
220
258
|
|
|
221
259
|
// Check if the PDF is in the cache
|
|
222
260
|
const cachedEntry = pdfCache.get(absoluteUrl);
|
|
@@ -337,6 +375,17 @@
|
|
|
337
375
|
} catch (err) {
|
|
338
376
|
if(showLogs) console.error('Error loading PDF:', err);
|
|
339
377
|
const errorMessage = err instanceof Error ? err.message : 'Failed to load PDF';
|
|
378
|
+
const fetchBlocked = /failed to fetch|networkerror|load failed/i.test(errorMessage);
|
|
379
|
+
const frameUrl = getAbsoluteUrl(url);
|
|
380
|
+
if (fetchBlocked && /^https?:/i.test(frameUrl)) {
|
|
381
|
+
browserFrameUrl = frameUrl;
|
|
382
|
+
sizeBrowserFrame();
|
|
383
|
+
error = null;
|
|
384
|
+
isCanvasReady = true;
|
|
385
|
+
pdfDoc = null;
|
|
386
|
+
renderingPhase = 'ready';
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
340
389
|
error = errorMessage;
|
|
341
390
|
dispatch('error', { message: errorMessage });
|
|
342
391
|
pdfDoc = null;
|
|
@@ -537,6 +586,9 @@
|
|
|
537
586
|
<!-- PDF Viewer HTML template -->
|
|
538
587
|
|
|
539
588
|
<div class="{className ? className + ' ' : ''}pdf-viewer-container w-full h-full px-4 widgetic-colors relative" bind:this={containerDiv} style={style}>
|
|
589
|
+
{#if browserFrameUrl}
|
|
590
|
+
<iframe class="pdf-browser-frame w-full border-0 bg-white" style="height: {frameHeight}px" src={browserFrameUrl} title={failedLabel}></iframe>
|
|
591
|
+
{:else}
|
|
540
592
|
<!-- Always render loading or error state on top of content -->
|
|
541
593
|
{#if !mounted || loading || (!isCanvasReady && !error)}
|
|
542
594
|
<div class="text-[hsl(var(--grey5))] p-6 absolute z-10 widgetic-colors flex items-center justify-center inset-0">
|
|
@@ -582,6 +634,7 @@
|
|
|
582
634
|
</div>
|
|
583
635
|
</WScrollArea>
|
|
584
636
|
</div>
|
|
637
|
+
{/if}
|
|
585
638
|
</div>
|
|
586
639
|
|
|
587
640
|
<style>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@widgetic/design-system",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.22",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"svelte": "./dist/index.js",
|
|
@@ -314,8 +314,11 @@
|
|
|
314
314
|
"overrides": {
|
|
315
315
|
"shell-quote": "^1.12.0"
|
|
316
316
|
},
|
|
317
|
+
"engines": {
|
|
318
|
+
"node": ">=26.12.1"
|
|
319
|
+
},
|
|
317
320
|
"volta": {
|
|
318
|
-
"node": "
|
|
321
|
+
"node": "26.12.1",
|
|
319
322
|
"npm": "11.1.0"
|
|
320
323
|
}
|
|
321
324
|
}
|