@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;
@@ -25,6 +25,8 @@ declare const BaseModal: $$__sveltets_2_IsomorphicComponent<{
25
25
  enableSpaceKey?: boolean;
26
26
  isSelected?: boolean;
27
27
  showScroll?: boolean;
28
+ shown?: boolean;
29
+ animateSize?: boolean;
28
30
  closeLabel?: string;
29
31
  children: any;
30
32
  }, {
@@ -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 = 'File browser';
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.20",
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": "22.22.0",
321
+ "node": "26.12.1",
319
322
  "npm": "11.1.0"
320
323
  }
321
324
  }