@marianmeres/stuic 3.132.0 → 3.134.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.
- package/dist/components/AssetsPreview/AssetsPreview.svelte +9 -0
- package/dist/components/AssetsPreview/AssetsPreview.svelte.d.ts +7 -0
- package/dist/components/AssetsPreview/AssetsPreviewInline.svelte +9 -0
- package/dist/components/AssetsPreview/AssetsPreviewInline.svelte.d.ts +7 -0
- package/dist/components/AssetsPreview/README.md +48 -7
- package/dist/components/AssetsPreview/_internal/AssetsPreviewContent.svelte +37 -4
- package/dist/components/AssetsPreview/_internal/AssetsPreviewContent.svelte.d.ts +7 -0
- package/dist/components/Avatar/Avatar.svelte +1 -4
- package/dist/components/CommentInput/CommentInput.svelte +547 -0
- package/dist/components/CommentInput/CommentInput.svelte.d.ts +113 -0
- package/dist/components/CommentInput/README.md +117 -0
- package/dist/components/CommentInput/_internal/render.d.ts +24 -0
- package/dist/components/CommentInput/_internal/render.js +47 -0
- package/dist/components/CommentInput/index.css +310 -0
- package/dist/components/CommentInput/index.d.ts +2 -0
- package/dist/components/CommentInput/index.js +1 -0
- package/dist/components/Input/FieldAssets.svelte +11 -0
- package/dist/components/Input/FieldAssets.svelte.d.ts +7 -0
- package/dist/components/Input/README.md +36 -0
- package/dist/components/Nav/README.md +1 -3
- package/dist/components/Thc/Thc.svelte +1 -6
- package/dist/index.css +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +15 -5
|
@@ -37,6 +37,13 @@
|
|
|
37
37
|
close: () => void;
|
|
38
38
|
}
|
|
39
39
|
) => void;
|
|
40
|
+
/**
|
|
41
|
+
* Optional consumer-supplied download handler. When provided, the Download button
|
|
42
|
+
* calls this instead of `forceDownload(asset.url.original)` — for auth-gated bytes
|
|
43
|
+
* or lazy fetching. Receives the current asset + its index. May be async; the
|
|
44
|
+
* button shows a busy/disabled state while the returned promise settles.
|
|
45
|
+
*/
|
|
46
|
+
onDownload?: (asset: AssetPreview, index: number) => void | Promise<void>;
|
|
40
47
|
/** optional "do not display file name" switch flag */
|
|
41
48
|
noName?: boolean;
|
|
42
49
|
/** When true (default), panning is clamped to keep image within bounds */
|
|
@@ -74,6 +81,7 @@
|
|
|
74
81
|
t = t_default,
|
|
75
82
|
classControls = "",
|
|
76
83
|
onDelete,
|
|
84
|
+
onDownload,
|
|
77
85
|
onAreaClick,
|
|
78
86
|
noName,
|
|
79
87
|
clampPan = false,
|
|
@@ -185,6 +193,7 @@
|
|
|
185
193
|
{classControls}
|
|
186
194
|
{t}
|
|
187
195
|
{onDelete}
|
|
196
|
+
{onDownload}
|
|
188
197
|
{noName}
|
|
189
198
|
{clampPan}
|
|
190
199
|
{noDownload}
|
|
@@ -16,6 +16,13 @@ export interface Props {
|
|
|
16
16
|
onDelete?: (asset: AssetPreview, index: number, controls: {
|
|
17
17
|
close: () => void;
|
|
18
18
|
}) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Optional consumer-supplied download handler. When provided, the Download button
|
|
21
|
+
* calls this instead of `forceDownload(asset.url.original)` — for auth-gated bytes
|
|
22
|
+
* or lazy fetching. Receives the current asset + its index. May be async; the
|
|
23
|
+
* button shows a busy/disabled state while the returned promise settles.
|
|
24
|
+
*/
|
|
25
|
+
onDownload?: (asset: AssetPreview, index: number) => void | Promise<void>;
|
|
19
26
|
/** optional "do not display file name" switch flag */
|
|
20
27
|
noName?: boolean;
|
|
21
28
|
/** When true (default), panning is clamped to keep image within bounds */
|
|
@@ -22,6 +22,13 @@
|
|
|
22
22
|
close: () => void;
|
|
23
23
|
}
|
|
24
24
|
) => void;
|
|
25
|
+
/**
|
|
26
|
+
* Optional consumer-supplied download handler. When provided, the Download button
|
|
27
|
+
* calls this instead of `forceDownload(asset.url.original)` — for auth-gated bytes
|
|
28
|
+
* or lazy fetching. Receives the current asset + its index. May be async; the
|
|
29
|
+
* button shows a busy/disabled state while the returned promise settles.
|
|
30
|
+
*/
|
|
31
|
+
onDownload?: (asset: AssetPreview, index: number) => void | Promise<void>;
|
|
25
32
|
/** optional "do not display file name" switch flag */
|
|
26
33
|
noName?: boolean;
|
|
27
34
|
/** When true (default), panning is clamped to keep image within bounds */
|
|
@@ -65,6 +72,7 @@
|
|
|
65
72
|
class: classProp = "",
|
|
66
73
|
classControls = "",
|
|
67
74
|
onDelete,
|
|
75
|
+
onDownload,
|
|
68
76
|
onAreaClick,
|
|
69
77
|
noName,
|
|
70
78
|
clampPan = false,
|
|
@@ -154,6 +162,7 @@
|
|
|
154
162
|
{classControls}
|
|
155
163
|
{t}
|
|
156
164
|
{onDelete}
|
|
165
|
+
{onDownload}
|
|
157
166
|
{noName}
|
|
158
167
|
{clampPan}
|
|
159
168
|
{noDownload}
|
|
@@ -12,6 +12,13 @@ export interface Props {
|
|
|
12
12
|
onDelete?: (asset: AssetPreview, index: number, controls: {
|
|
13
13
|
close: () => void;
|
|
14
14
|
}) => void;
|
|
15
|
+
/**
|
|
16
|
+
* Optional consumer-supplied download handler. When provided, the Download button
|
|
17
|
+
* calls this instead of `forceDownload(asset.url.original)` — for auth-gated bytes
|
|
18
|
+
* or lazy fetching. Receives the current asset + its index. May be async; the
|
|
19
|
+
* button shows a busy/disabled state while the returned promise settles.
|
|
20
|
+
*/
|
|
21
|
+
onDownload?: (asset: AssetPreview, index: number) => void | Promise<void>;
|
|
15
22
|
/** optional "do not display file name" switch flag */
|
|
16
23
|
noName?: boolean;
|
|
17
24
|
/** When true (default), panning is clamped to keep image within bounds */
|
|
@@ -4,13 +4,14 @@ A modal-based asset preview component for displaying images and files. Supports
|
|
|
4
4
|
|
|
5
5
|
## Props
|
|
6
6
|
|
|
7
|
-
| Prop | Type
|
|
8
|
-
| ---------------- |
|
|
9
|
-
| `assets` | `string[] \| AssetPreview[]`
|
|
10
|
-
| `classControls` | `string`
|
|
11
|
-
| `t` | `TranslateFn`
|
|
12
|
-
| `onDelete` | `(asset, index) => void`
|
|
13
|
-
| `
|
|
7
|
+
| Prop | Type | Default | Description |
|
|
8
|
+
| ---------------- | ----------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------- |
|
|
9
|
+
| `assets` | `string[] \| AssetPreview[]` | - | Array of assets to preview |
|
|
10
|
+
| `classControls` | `string` | - | CSS for control buttons |
|
|
11
|
+
| `t` | `TranslateFn` | built-in | Translation function for i18n |
|
|
12
|
+
| `onDelete` | `(asset, index) => void` | - | Optional delete handler |
|
|
13
|
+
| `onDownload` | `(asset, index) => void \| Promise<void>` | - | Optional download handler. Replaces the default `forceDownload(url.original)` — for auth-gated or lazily-fetched bytes |
|
|
14
|
+
| `prevNextBottom` | `boolean` | `false` | Render prev/next arrows at bottom |
|
|
14
15
|
|
|
15
16
|
## Types
|
|
16
17
|
|
|
@@ -140,6 +141,46 @@ interface AssetPreview {
|
|
|
140
141
|
<AssetsPreview bind:this={preview} {assets} onDelete={handleDelete} />
|
|
141
142
|
```
|
|
142
143
|
|
|
144
|
+
### With a Custom Download Handler
|
|
145
|
+
|
|
146
|
+
By default the Download button calls the built-in `forceDownload(asset.url.original)`,
|
|
147
|
+
which does a plain unauthenticated `fetch`. Supply `onDownload` to take over the action —
|
|
148
|
+
e.g. to fetch **auth-gated** bytes (a `Authorization: Bearer …` route), or to fetch
|
|
149
|
+
**lazily** only when the user actually clicks Download instead of pre-resolving an object
|
|
150
|
+
URL for every asset up front. When provided, the default path is skipped entirely.
|
|
151
|
+
|
|
152
|
+
The handler may be async; while the returned promise is pending the button shows a busy
|
|
153
|
+
spinner and is disabled (so rapid clicks can't fire duplicate fetches). Rejections are
|
|
154
|
+
caught and logged, so a failed download never breaks the preview.
|
|
155
|
+
|
|
156
|
+
```svelte
|
|
157
|
+
<script lang="ts">
|
|
158
|
+
import { AssetsPreview, type AssetPreview } from "stuic";
|
|
159
|
+
|
|
160
|
+
let preview: AssetsPreview;
|
|
161
|
+
|
|
162
|
+
async function handleDownload(asset: AssetPreview) {
|
|
163
|
+
// Fetch the bytes yourself (e.g. with an auth header), then save them.
|
|
164
|
+
const res = await fetch(String(asset.url.original), {
|
|
165
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
166
|
+
});
|
|
167
|
+
const objUrl = URL.createObjectURL(await res.blob());
|
|
168
|
+
const a = document.createElement("a");
|
|
169
|
+
a.href = objUrl;
|
|
170
|
+
a.download = asset.name || "download";
|
|
171
|
+
document.body.appendChild(a);
|
|
172
|
+
a.click();
|
|
173
|
+
a.remove();
|
|
174
|
+
setTimeout(() => URL.revokeObjectURL(objUrl), 10_000);
|
|
175
|
+
}
|
|
176
|
+
</script>
|
|
177
|
+
|
|
178
|
+
<AssetsPreview bind:this={preview} {assets} onDownload={handleDownload} />
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
> Visibility of the Download button is still controlled solely by `noDownload` —
|
|
182
|
+
> `onDownload` only changes _what_ the button does, not _whether_ it shows.
|
|
183
|
+
|
|
143
184
|
### With Custom Translations
|
|
144
185
|
|
|
145
186
|
```svelte
|
|
@@ -55,6 +55,13 @@
|
|
|
55
55
|
close: () => void;
|
|
56
56
|
}
|
|
57
57
|
) => void;
|
|
58
|
+
/**
|
|
59
|
+
* Optional consumer-supplied download handler. When provided, the Download button
|
|
60
|
+
* calls this instead of `forceDownload(asset.url.original)` — for auth-gated bytes
|
|
61
|
+
* or lazy fetching. Receives the current preview asset + its index. May be async;
|
|
62
|
+
* the button shows a busy/disabled state while the returned promise settles.
|
|
63
|
+
*/
|
|
64
|
+
onDownload?: (asset: AssetPreview, index: number) => void | Promise<void>;
|
|
58
65
|
/** Callback when a clickable area on an image is clicked */
|
|
59
66
|
onAreaClick?: (data: { area: AssetArea; asset: AssetPreviewNormalized }) => void;
|
|
60
67
|
onClose?: () => void;
|
|
@@ -81,11 +88,37 @@
|
|
|
81
88
|
classControls = "",
|
|
82
89
|
t = t_default,
|
|
83
90
|
onDelete,
|
|
91
|
+
onDownload,
|
|
84
92
|
onAreaClick,
|
|
85
93
|
onClose,
|
|
86
94
|
slideDuration = 300,
|
|
87
95
|
}: Props = $props();
|
|
88
96
|
|
|
97
|
+
// Busy state for an async `onDownload`; disables the button + shows a spinner so
|
|
98
|
+
// rapid clicks can't fire duplicate (possibly authed) fetches. Only the custom
|
|
99
|
+
// path drives this — the default `forceDownload` path is left exactly as-is.
|
|
100
|
+
let downloading = $state(false);
|
|
101
|
+
|
|
102
|
+
async function handleDownload() {
|
|
103
|
+
if (typeof onDownload === "function") {
|
|
104
|
+
try {
|
|
105
|
+
downloading = true;
|
|
106
|
+
await onDownload(previewAsset, previewIdx);
|
|
107
|
+
} catch (e) {
|
|
108
|
+
// A failed/late download must never reject up and tear down the preview.
|
|
109
|
+
clog.error("onDownload failed", e);
|
|
110
|
+
} finally {
|
|
111
|
+
downloading = false;
|
|
112
|
+
}
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
// Default (unchanged): fetch the original bytes and force a browser download.
|
|
116
|
+
forceDownload(
|
|
117
|
+
resolveUrl(String(previewAsset.url.original), baseUrl),
|
|
118
|
+
previewAsset?.name || ""
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
89
122
|
let dotTooltip: string | undefined = $state();
|
|
90
123
|
|
|
91
124
|
// Zoom state
|
|
@@ -747,12 +780,12 @@
|
|
|
747
780
|
<Button
|
|
748
781
|
class={twMerge(BUTTON_CLS, classControls)}
|
|
749
782
|
type="button"
|
|
783
|
+
disabled={downloading}
|
|
784
|
+
spinner={downloading}
|
|
785
|
+
spinnerOnly
|
|
750
786
|
onclick={(e) => {
|
|
751
787
|
e.preventDefault();
|
|
752
|
-
|
|
753
|
-
resolveUrl(String(previewAsset.url.original), baseUrl),
|
|
754
|
-
previewAsset?.name || ""
|
|
755
|
-
);
|
|
788
|
+
handleDownload();
|
|
756
789
|
}}
|
|
757
790
|
aria-label={t("download")}
|
|
758
791
|
tooltip={t("download")}
|
|
@@ -26,6 +26,13 @@ interface Props {
|
|
|
26
26
|
onDelete?: (asset: AssetPreview, index: number, controls: {
|
|
27
27
|
close: () => void;
|
|
28
28
|
}) => void;
|
|
29
|
+
/**
|
|
30
|
+
* Optional consumer-supplied download handler. When provided, the Download button
|
|
31
|
+
* calls this instead of `forceDownload(asset.url.original)` — for auth-gated bytes
|
|
32
|
+
* or lazy fetching. Receives the current preview asset + its index. May be async;
|
|
33
|
+
* the button shows a busy/disabled state while the returned promise settles.
|
|
34
|
+
*/
|
|
35
|
+
onDownload?: (asset: AssetPreview, index: number) => void | Promise<void>;
|
|
29
36
|
/** Callback when a clickable area on an image is clicked */
|
|
30
37
|
onAreaClick?: (data: {
|
|
31
38
|
area: AssetArea;
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
2
|
export type IconFn = (opts?: { size?: number; class?: string }) => string;
|
|
3
3
|
export type AvatarFallback =
|
|
4
|
-
| "icon
|
|
5
|
-
| "initials"
|
|
6
|
-
| { icon: IconFn }
|
|
7
|
-
| { initials: string };
|
|
4
|
+
"icon" | "initials" | { icon: IconFn } | { initials: string };
|
|
8
5
|
|
|
9
6
|
export interface Props {
|
|
10
7
|
/** Photo URL - when provided, renders in photo mode */
|