@marianmeres/stuic 3.39.0 → 3.40.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.
@@ -57,6 +57,8 @@
57
57
  prevNextBottom?: boolean;
58
58
  /** Callback when a clickable area on an image is clicked */
59
59
  onAreaClick?: (data: { area: AssetArea; asset: AssetPreviewNormalized }) => void;
60
+ /** Max number of images to preload in each direction from current (0 = all). Default 3. */
61
+ preloadWindow?: number;
60
62
  }
61
63
  </script>
62
64
 
@@ -82,6 +84,7 @@
82
84
  noDots = false,
83
85
  noCurrentOfTotal = false,
84
86
  prevNextBottom = false,
87
+ preloadWindow = 3,
85
88
  }: Props = $props();
86
89
 
87
90
  let assets: AssetPreviewNormalized[] = $derived(
@@ -96,17 +99,26 @@
96
99
  const visible = modal?.visibility().visible;
97
100
  if (visible) {
98
101
  // Use the index from open(index) if provided, otherwise reset to 0
99
- previewIdx = _openIdx ?? 0;
102
+ const idx = _openIdx ?? 0;
103
+ previewIdx = idx;
100
104
  _openIdx = undefined;
101
105
 
102
- // perhaps we should have some upper limit here...
103
- const toPreload: PreloadImgOptions[] = (assets ?? [])
104
- .filter((asset) => asset.isImage)
105
- .map((asset) => ({
106
- src: resolveUrl(String(asset.url.full), baseUrl),
107
- srcset: resolveSrcset(asset.srcset ?? "", baseUrl) || undefined,
108
- sizes: asset.sizes,
109
- }));
106
+ const toPreload: PreloadImgOptions[] = [];
107
+ const len = assets.length;
108
+ const pw = preloadWindow > 0 ? preloadWindow : len;
109
+
110
+ for (let offset = -pw; offset <= pw; offset++) {
111
+ const i = idx + offset;
112
+ if (i < 0 || i >= len) continue;
113
+ const asset = assets[i];
114
+ if (asset?.isImage) {
115
+ toPreload.push({
116
+ src: resolveUrl(String(asset.url.full), baseUrl),
117
+ srcset: resolveSrcset(asset.srcset ?? "", baseUrl) || undefined,
118
+ sizes: asset.sizes,
119
+ });
120
+ }
121
+ }
110
122
 
111
123
  clog.debug("going to (maybe) preload", toPreload);
112
124
  if (toPreload.length) preloadImgs(toPreload);
@@ -156,6 +168,7 @@
156
168
  {#if assets.length}
157
169
  <ModalDialog
158
170
  bind:this={modal}
171
+ noAutoFocus
159
172
  classDialog={modalClassDialog}
160
173
  class={twMerge(
161
174
  "max-w-full max-h-full h-full rounded-lg",
@@ -39,6 +39,8 @@ export interface Props {
39
39
  area: AssetArea;
40
40
  asset: AssetPreviewNormalized;
41
41
  }) => void;
42
+ /** Max number of images to preload in each direction from current (0 = all). Default 3. */
43
+ preloadWindow?: number;
42
44
  }
43
45
  declare const AssetsPreview: import("svelte").Component<Props, {
44
46
  open: (index?: number) => void;
@@ -19,6 +19,8 @@
19
19
  ariaDescribedby?: string;
20
20
  /** Disable body scroll lock when dialog is open */
21
21
  noScrollLock?: boolean;
22
+ /** Do not auto-focus the first focusable element when dialog opens */
23
+ noAutoFocus?: boolean;
22
24
  }
23
25
  </script>
24
26
 
@@ -46,6 +48,7 @@
46
48
  ariaLabelledby,
47
49
  ariaDescribedby,
48
50
  noScrollLock,
51
+ noAutoFocus,
49
52
  }: Props = $props();
50
53
 
51
54
  // important to start as undefined (because of scroll save/restore)
@@ -155,7 +158,7 @@
155
158
  {#if visible}
156
159
  <dialog
157
160
  bind:this={dialog}
158
- use:focusTrap
161
+ use:focusTrap={{ autoFocusFirst: !noAutoFocus }}
159
162
  data-type={type}
160
163
  aria-labelledby={ariaLabelledby}
161
164
  aria-describedby={ariaDescribedby}
@@ -17,6 +17,8 @@ export interface Props {
17
17
  ariaDescribedby?: string;
18
18
  /** Disable body scroll lock when dialog is open */
19
19
  noScrollLock?: boolean;
20
+ /** Do not auto-focus the first focusable element when dialog opens */
21
+ noAutoFocus?: boolean;
20
22
  }
21
23
  declare const ModalDialog: import("svelte").Component<Props, {
22
24
  open: (openerOrEvent?: null | HTMLElement | MouseEvent) => void;
@@ -16,7 +16,7 @@
16
16
  // const auto = $derived(dp.isCoarse ? 3 : 2);
17
17
 
18
18
  // if sw not provided use thicker on mobile
19
- const _strokeWidth = $derived(strokeWidth ?? 2);
19
+ const _strokeWidth = $derived(strokeWidth ?? 1.5);
20
20
 
21
21
  const _strokeLinecap = $derived(linecapRound ? "round" : "square");
22
22
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marianmeres/stuic",
3
- "version": "3.39.0",
3
+ "version": "3.40.0",
4
4
  "files": [
5
5
  "dist",
6
6
  "!dist/**/*.test.*",
@@ -39,43 +39,43 @@
39
39
  "svelte": "^5.0.0"
40
40
  },
41
41
  "devDependencies": {
42
- "@eslint/js": "^9.39.2",
43
- "@marianmeres/icons-fns": "^5.0.0",
42
+ "@eslint/js": "^9.39.3",
44
43
  "@marianmeres/random-human-readable": "^1.6.1",
45
44
  "@sveltejs/adapter-auto": "^4.0.0",
46
- "@sveltejs/kit": "^2.52.0",
45
+ "@sveltejs/kit": "^2.53.1",
47
46
  "@sveltejs/package": "^2.5.7",
48
47
  "@sveltejs/vite-plugin-svelte": "^6.2.4",
49
- "@tailwindcss/cli": "^4.1.18",
48
+ "@tailwindcss/cli": "^4.2.1",
50
49
  "@tailwindcss/forms": "^0.5.11",
51
50
  "@tailwindcss/typography": "^0.5.19",
52
- "@tailwindcss/vite": "^4.1.18",
53
- "@types/node": "^25.2.3",
51
+ "@tailwindcss/vite": "^4.2.1",
52
+ "@types/node": "^25.3.0",
54
53
  "dotenv": "^16.6.1",
55
- "eslint": "^9.39.2",
54
+ "eslint": "^9.39.3",
56
55
  "globals": "^16.5.0",
57
56
  "prettier": "^3.8.1",
58
- "prettier-plugin-svelte": "^3.4.1",
57
+ "prettier-plugin-svelte": "^3.5.0",
59
58
  "publint": "^0.3.17",
60
- "svelte": "^5.51.2",
61
- "svelte-check": "^4.4.0",
62
- "tailwindcss": "^4.1.18",
59
+ "svelte": "^5.53.3",
60
+ "svelte-check": "^4.4.3",
61
+ "tailwindcss": "^4.2.1",
63
62
  "tsx": "^4.21.0",
64
63
  "typescript": "^5.9.3",
65
- "typescript-eslint": "^8.55.0",
64
+ "typescript-eslint": "^8.56.1",
66
65
  "vite": "^7.3.1",
67
66
  "vitest": "^3.2.4"
68
67
  },
69
68
  "dependencies": {
70
69
  "@marianmeres/clog": "^3.15.2",
70
+ "@marianmeres/icons-fns": "^5.0.0",
71
71
  "@marianmeres/item-collection": "^1.3.5",
72
72
  "@marianmeres/paging-store": "^2.0.2",
73
73
  "@marianmeres/parse-boolean": "^2.0.5",
74
74
  "@marianmeres/ticker": "^1.16.5",
75
75
  "esm-env": "^1.2.2",
76
- "libphonenumber-js": "^1.12.36",
76
+ "libphonenumber-js": "^1.12.37",
77
77
  "runed": "^0.23.4",
78
- "tailwind-merge": "^3.4.1"
78
+ "tailwind-merge": "^3.5.0"
79
79
  },
80
80
  "scripts": {
81
81
  "dev": "vite dev",