laif-ds 0.2.71 → 0.2.73

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.
@@ -0,0 +1,460 @@
1
+ "use client";
2
+ import { jsx as r, jsxs as m, Fragment as T } from "react/jsx-runtime";
3
+ import { getNameOrUrl as z, getExt as F, getMimeFromFile as $, imageExts as K, isFile as D, getFileMetadata as B, getFormatIcon as W, formatMetadata as q } from "../../../lib/file-preview.js";
4
+ import { cva as v } from "../../../node_modules/class-variance-authority/dist/index.js";
5
+ import { motion as G } from "framer-motion";
6
+ import f, { useEffect as U, Fragment as X } from "react";
7
+ import { Button as H } from "../button.js";
8
+ import { DropdownMenu as J, DropdownMenuTrigger as Q, DropdownMenuContent as Y, DropdownMenuSeparator as Z, DropdownMenuItem as ee } from "../dropdown-menu.js";
9
+ import { Icon as P } from "../icon.js";
10
+ import { Spinner as te } from "../spinner.js";
11
+ import { cn as x } from "../../../lib/utils.js";
12
+ const re = {
13
+ layout: !0,
14
+ initial: { opacity: 0, y: "100%" },
15
+ animate: { opacity: 1, y: 0 },
16
+ exit: { opacity: 0, y: "100%" }
17
+ }, ae = v(
18
+ "group/file ring-d-ring focus-visible:ring-d-accent relative flex items-center gap-1.5 overflow-hidden rounded-md transition-colors focus-within:ring focus-visible:ring focus-visible:outline-none",
19
+ {
20
+ variants: {
21
+ variant: {
22
+ default: "bg-d-card border-d-muted border",
23
+ outline: "border-d-border bg-transparent border hover:bg-d-accent/50 hover:border-d-foreground/70",
24
+ ghost: "bg-transparent hover:bg-d-accent/50"
25
+ },
26
+ size: {
27
+ default: "max-w-48 p-0.5 text-sm",
28
+ sm: "max-w-36 p-0.5 text-xs"
29
+ }
30
+ },
31
+ defaultVariants: {
32
+ variant: "default",
33
+ size: "default"
34
+ }
35
+ }
36
+ ), V = v(
37
+ "aspect-square h-full shrink-0 rounded-sm",
38
+ {
39
+ variants: {
40
+ size: {
41
+ default: "min-h-10 max-w-10 bg-d-secondary",
42
+ sm: "min-h-8 max-w-8"
43
+ }
44
+ },
45
+ defaultVariants: {
46
+ size: "default"
47
+ }
48
+ }
49
+ ), ne = v("", {
50
+ variants: {
51
+ size: {
52
+ default: "h-5 w-5",
53
+ sm: "h-4 w-4"
54
+ }
55
+ },
56
+ defaultVariants: {
57
+ size: "default"
58
+ }
59
+ }), ie = v(
60
+ "flex max-w-full overflow-hidden whitespace-nowrap",
61
+ {
62
+ variants: {
63
+ size: {
64
+ default: "text-sm",
65
+ sm: "text-xs"
66
+ }
67
+ },
68
+ defaultVariants: {
69
+ size: "default"
70
+ }
71
+ }
72
+ ), oe = v("text-d-muted-foreground", {
73
+ variants: {
74
+ size: {
75
+ default: "text-sm",
76
+ sm: "text-xs"
77
+ }
78
+ },
79
+ defaultVariants: {
80
+ size: "default"
81
+ }
82
+ }), se = v(
83
+ "hover:bg-d-accent hover:text-d-accent-foreground data-[state=open]:bg-d-accent data-[state=open]:text-d-accent-foreground cursor-pointer focus-visible:bg-d-accent rounded-r-sm focus-visible:outline-none",
84
+ {
85
+ variants: {
86
+ size: {
87
+ default: "h-full min-h-10 px-0.5",
88
+ sm: "h-full min-h-8 px-0.5"
89
+ }
90
+ },
91
+ defaultVariants: {
92
+ size: "default"
93
+ }
94
+ }
95
+ ), le = v(
96
+ "absolute flex self-start overflow-visible rounded-sm p-0.5 text-xs opacity-0 group-hover/file:opacity-100 before:absolute before:top-0 before:right-1/2 before:-z-10 before:h-[400%] before:w-[300%] before:translate-x-1/2 before:-translate-y-1/2 before:rounded-full before:bg-radial before:from-50% before:to-transparent before:to-80% before:blur-xs before:content-[''] focus-visible:opacity-100",
97
+ {
98
+ variants: {
99
+ variant: {
100
+ default: "bg-d-card hover:bg-d-card before:from-d-card",
101
+ outline: "bg-d-background hover:bg-d-background before:from-d-background",
102
+ ghost: "before:from-d-background"
103
+ },
104
+ size: {
105
+ default: "top-1 right-1 !size-4.5",
106
+ sm: "top-1 right-1 !size-4"
107
+ }
108
+ },
109
+ defaultVariants: {
110
+ variant: "default",
111
+ size: "default"
112
+ }
113
+ }
114
+ ), j = f.createContext({ variant: "default", size: "default" }), N = () => f.useContext(j), I = ({
115
+ sizeLabel: e,
116
+ formatLabel: a
117
+ }) => {
118
+ const { size: o } = N(), t = q(e, a);
119
+ return t ? /* @__PURE__ */ r(
120
+ "div",
121
+ {
122
+ className: oe({ size: o }),
123
+ "aria-label": `${e ? `Size: ${e}` : ""}${e && a ? ", " : ""}${a ? `Format: ${a}` : ""}`,
124
+ children: t
125
+ }
126
+ ) : null;
127
+ }, ce = ({
128
+ fileUrl: e,
129
+ fileName: a
130
+ }) => {
131
+ const { size: o } = N(), [t, n] = f.useState(e), s = F(a);
132
+ f.useEffect(() => {
133
+ n(e);
134
+ }, [e]);
135
+ const c = () => {
136
+ n(void 0);
137
+ };
138
+ return t ? /* @__PURE__ */ r(
139
+ "img",
140
+ {
141
+ alt: a,
142
+ className: x(V({ size: o }), "object-cover"),
143
+ width: 40,
144
+ height: 40,
145
+ loading: "lazy",
146
+ onError: c,
147
+ decoding: "async",
148
+ src: t
149
+ }
150
+ ) : /* @__PURE__ */ r(k, { ext: s, mimeType: "image/*" });
151
+ }, k = ({
152
+ className: e,
153
+ ext: a,
154
+ mimeType: o
155
+ }) => {
156
+ const { size: t } = N(), { iconName: n, colorClass: s } = W(a ?? "", o);
157
+ return /* @__PURE__ */ r(
158
+ "div",
159
+ {
160
+ className: x(
161
+ V({ size: t }),
162
+ "flex items-center justify-center",
163
+ e
164
+ ),
165
+ "aria-hidden": "true",
166
+ children: /* @__PURE__ */ r(
167
+ P,
168
+ {
169
+ name: n,
170
+ className: x(ne({ size: t }), s),
171
+ "aria-hidden": "true"
172
+ }
173
+ )
174
+ }
175
+ );
176
+ }, de = ({
177
+ url: e,
178
+ onPreview: a,
179
+ onDownload: o,
180
+ onRemove: t,
181
+ disabled: n = !1
182
+ }) => {
183
+ const { size: s } = N(), [c, h] = f.useState(!1), [b, g] = f.useState(
184
+ null
185
+ ), u = [
186
+ {
187
+ key: "preview",
188
+ cond: !!a,
189
+ icon: "Presentation",
190
+ label: "Anteprima",
191
+ onSelect: a
192
+ },
193
+ {
194
+ key: "download",
195
+ cond: !!o,
196
+ icon: "Download",
197
+ label: "Download",
198
+ onSelect: o
199
+ },
200
+ {
201
+ key: "remove",
202
+ cond: !!t,
203
+ icon: "Trash",
204
+ label: "Elimina",
205
+ onSelect: t,
206
+ danger: !0
207
+ }
208
+ ], w = async (i) => {
209
+ if (i.onSelect && !b)
210
+ try {
211
+ const d = i.onSelect(e);
212
+ typeof d?.then == "function" && (g(i.key), await d);
213
+ } catch (d) {
214
+ console.error(d);
215
+ } finally {
216
+ g(null), h(!1);
217
+ }
218
+ };
219
+ return /* @__PURE__ */ m(J, { onOpenChange: (i) => h(i), open: c, children: [
220
+ /* @__PURE__ */ r(
221
+ Q,
222
+ {
223
+ disabled: n || !e,
224
+ className: se({ size: s }),
225
+ "aria-label": "File actions",
226
+ onClick: (i) => i.stopPropagation(),
227
+ onKeyDown: (i) => i.stopPropagation(),
228
+ children: /* @__PURE__ */ r(
229
+ P,
230
+ {
231
+ name: "ChevronDown",
232
+ className: x(s === "sm" ? "size-3" : "size-4"),
233
+ "aria-hidden": "true"
234
+ }
235
+ )
236
+ }
237
+ ),
238
+ /* @__PURE__ */ r(
239
+ Y,
240
+ {
241
+ align: "end",
242
+ onClick: (i) => i.stopPropagation(),
243
+ onPointerDown: (i) => i.stopPropagation(),
244
+ children: u.filter((i) => i.cond).map((i, d, y) => /* @__PURE__ */ m(X, { children: [
245
+ i.danger && y.length > 1 && /* @__PURE__ */ r(Z, {}),
246
+ /* @__PURE__ */ m(
247
+ ee,
248
+ {
249
+ onSelect: (S) => {
250
+ S.preventDefault(), w(i);
251
+ },
252
+ variant: i.danger ? "destructive" : "default",
253
+ disabled: !!b,
254
+ children: [
255
+ b === i.key ? /* @__PURE__ */ r(te, { size: "sm" }) : /* @__PURE__ */ r(P, { name: i.icon, size: "sm" }),
256
+ /* @__PURE__ */ r("span", { children: i.label })
257
+ ]
258
+ }
259
+ )
260
+ ] }, i.key))
261
+ }
262
+ )
263
+ ] });
264
+ }, O = ({
265
+ name: e,
266
+ className: a
267
+ }) => {
268
+ const { size: o } = N(), t = e.lastIndexOf("."), n = t > 0 && t < e.length - 1, s = n ? e.slice(0, t) : e, c = n ? e.slice(t + 1) : "";
269
+ return /* @__PURE__ */ m(
270
+ "span",
271
+ {
272
+ className: x(ie({ size: o }), a),
273
+ title: e,
274
+ children: [
275
+ /* @__PURE__ */ r("span", { className: "shrink-1 truncate", children: s }),
276
+ c && /* @__PURE__ */ r("span", { className: "w-fit", children: `.${c}` })
277
+ ]
278
+ }
279
+ );
280
+ }, Pe = f.forwardRef(
281
+ (e, a) => {
282
+ const o = z(e.file), t = F(o), n = $(e.file), s = t === "csv" || n === "text/csv";
283
+ return n && n.startsWith("image/") || t && K.has(t) ? /* @__PURE__ */ r(fe, { ...e, ref: a }) : !s && (t === "txt" || t === "md" || n && n.startsWith("text/")) ? /* @__PURE__ */ r(ue, { ...e, ref: a }) : /* @__PURE__ */ r(me, { ...e, ref: a });
284
+ }
285
+ ), L = f.forwardRef(
286
+ ({
287
+ file: e,
288
+ clickable: a = !0,
289
+ onRemove: o,
290
+ onPreview: t,
291
+ onDownload: n,
292
+ showActionMenu: s = !1,
293
+ className: c,
294
+ defaultClassName: h,
295
+ children: b,
296
+ onClick: g,
297
+ variant: u = "default",
298
+ size: w = "default"
299
+ }, i) => {
300
+ const [d, y] = f.useState(
301
+ () => D(e) ? "" : e.url
302
+ );
303
+ U(() => {
304
+ if (D(e)) {
305
+ const l = URL.createObjectURL(e);
306
+ return y(l), () => {
307
+ URL.revokeObjectURL(l);
308
+ };
309
+ } else
310
+ y(e.url);
311
+ }, [e]);
312
+ const S = B(e), R = z(e), M = !s && !!g, p = a && (!!t || M), E = async (l) => {
313
+ if (M) {
314
+ try {
315
+ await g(l);
316
+ } catch (C) {
317
+ console.error(C);
318
+ }
319
+ return;
320
+ }
321
+ if (t) {
322
+ try {
323
+ await t(d);
324
+ } catch (C) {
325
+ console.error(C);
326
+ }
327
+ return;
328
+ }
329
+ }, A = (l) => {
330
+ p && (l.stopPropagation(), E(l));
331
+ }, _ = (l) => {
332
+ p && (l.stopPropagation(), (l.key === "Enter" || l.key === " ") && (l.preventDefault(), E(l)));
333
+ };
334
+ return /* @__PURE__ */ r(
335
+ G.div,
336
+ {
337
+ ref: i,
338
+ role: p ? "button" : "group",
339
+ tabIndex: p ? 0 : -1,
340
+ "aria-label": `File: ${R}`,
341
+ className: x(
342
+ ae({ variant: u, size: w }),
343
+ p && "cursor-pointer",
344
+ h,
345
+ c
346
+ ),
347
+ onClick: p ? A : void 0,
348
+ onKeyDown: p ? _ : void 0,
349
+ ...re,
350
+ children: /* @__PURE__ */ m(j.Provider, { value: { variant: u, size: w }, children: [
351
+ /* @__PURE__ */ m("div", { className: "flex h-full w-full min-w-0 items-center gap-1", children: [
352
+ b(d, S),
353
+ s && /* @__PURE__ */ r(
354
+ de,
355
+ {
356
+ url: d,
357
+ onPreview: t,
358
+ onDownload: n,
359
+ onRemove: o,
360
+ disabled: !d
361
+ }
362
+ )
363
+ ] }),
364
+ !s && o ? /* @__PURE__ */ r(
365
+ H,
366
+ {
367
+ className: le({ variant: u, size: w }),
368
+ variant: "ghost",
369
+ size: "icon",
370
+ "aria-label": `Remove ${R}`,
371
+ disabled: !d,
372
+ onClick: (l) => {
373
+ l.stopPropagation(), d && o(d);
374
+ },
375
+ children: /* @__PURE__ */ r(P, { name: "X", className: "size-full", "aria-hidden": "true" })
376
+ }
377
+ ) : null
378
+ ] })
379
+ }
380
+ );
381
+ }
382
+ ), fe = f.forwardRef(({ showThumbnail: e = !0, ...a }, o) => {
383
+ const t = z(a.file);
384
+ return /* @__PURE__ */ r(L, { ...a, ref: o, children: (n, s) => /* @__PURE__ */ m(T, { children: [
385
+ e ? /* @__PURE__ */ r(ce, { fileUrl: n, fileName: t }) : /* @__PURE__ */ r(k, { ext: F(t), mimeType: "image/*" }),
386
+ /* @__PURE__ */ m("div", { className: "mr-1 flex min-w-0 flex-1 flex-col gap-0.5", children: [
387
+ /* @__PURE__ */ r(O, { name: t, className: "inline-flex min-w-0 flex-1" }),
388
+ /* @__PURE__ */ r(
389
+ I,
390
+ {
391
+ sizeLabel: s.sizeLabel,
392
+ formatLabel: s.formatLabel
393
+ }
394
+ )
395
+ ] })
396
+ ] }) });
397
+ }), ue = f.forwardRef(({ file: e, showThumbnail: a = !0, ...o }, t) => {
398
+ const [n, s] = f.useState(null), c = z(e), h = o.size ?? "default";
399
+ U(() => {
400
+ if (D(e)) {
401
+ const g = new FileReader();
402
+ return g.onload = (u) => {
403
+ u.target?.result && s(
404
+ typeof u.target.result == "string" ? u.target.result.slice(0, 100) : ""
405
+ );
406
+ }, g.readAsText(e), () => {
407
+ g.abort();
408
+ };
409
+ } else
410
+ s(null);
411
+ }, [e]);
412
+ const b = "text/plain";
413
+ return /* @__PURE__ */ r(L, { ...o, ref: t, file: e, children: (g, u) => /* @__PURE__ */ m(T, { children: [
414
+ n && a ? /* @__PURE__ */ r(
415
+ "div",
416
+ {
417
+ className: x(
418
+ V({ size: h }),
419
+ "flex items-start justify-start overflow-hidden p-0.5 leading-tight",
420
+ h === "sm" ? "text-[7px]" : "text-[8px]"
421
+ ),
422
+ title: n,
423
+ "aria-label": "Text preview",
424
+ role: "img",
425
+ children: n
426
+ }
427
+ ) : /* @__PURE__ */ r(k, { mimeType: b }),
428
+ /* @__PURE__ */ m("div", { className: "mr-1 min-w-0 flex-1", children: [
429
+ /* @__PURE__ */ r(O, { name: c, className: "inline-flex min-w-0 flex-1" }),
430
+ /* @__PURE__ */ r(
431
+ I,
432
+ {
433
+ sizeLabel: u.sizeLabel,
434
+ formatLabel: u.formatLabel
435
+ }
436
+ )
437
+ ] })
438
+ ] }) });
439
+ }), me = f.forwardRef((e, a) => {
440
+ const o = z(e.file), t = F(o), n = $(e.file);
441
+ return /* @__PURE__ */ r(L, { ...e, ref: a, children: (s, c) => /* @__PURE__ */ m(T, { children: [
442
+ /* @__PURE__ */ r(k, { ext: t, mimeType: n }),
443
+ /* @__PURE__ */ m("div", { className: "mr-1 flex min-w-0 flex-1 flex-col gap-0.5", children: [
444
+ /* @__PURE__ */ r(O, { name: o, className: "inline-flex min-w-0 flex-1" }),
445
+ /* @__PURE__ */ r(
446
+ I,
447
+ {
448
+ sizeLabel: c.sizeLabel,
449
+ formatLabel: c.formatLabel
450
+ }
451
+ )
452
+ ] })
453
+ ] }) });
454
+ });
455
+ export {
456
+ Pe as FilePreview,
457
+ me as GenericFilePreview,
458
+ fe as ImageFilePreview,
459
+ ue as TextFilePreview
460
+ };
@@ -3,7 +3,7 @@ import { jsxs as v, jsx as r, Fragment as B } from "react/jsx-runtime";
3
3
  import l from "react";
4
4
  import { Button as S } from "./button.js";
5
5
  import { Card as P, CardHeader as _, CardTitle as W, CardContent as H } from "./card.js";
6
- import { FilePreview as k } from "./file-preview.js";
6
+ import { FilePreview as k } from "./file-preview/index.js";
7
7
  import { Icon as K } from "./icon.js";
8
8
  import { Input as O } from "./input.js";
9
9
  const U = {
@@ -5,7 +5,7 @@ import { useState as y, useEffect as S, useRef as Q } from "react";
5
5
  import { omit as T } from "../../node_modules/remeda/dist/omit-HZOiLuMO.js";
6
6
  import { AudioVisualizer as X } from "./audio-visualizer.js";
7
7
  import { Button as g } from "./button.js";
8
- import { FilePreview as Y } from "./file-preview.js";
8
+ import { FilePreview as Y } from "./file-preview/index.js";
9
9
  import { InterruptPrompt as Z } from "./interrupt-prompt.js";
10
10
  import { useAudioRecording as _ } from "../../hooks/use-audio-recording.js";
11
11
  import { useAutosizeTextArea as $ } from "../../hooks/use-autosize-textarea.js";
package/dist/index.d.ts CHANGED
@@ -265,6 +265,14 @@ export declare type AppKanbanColumn = {
265
265
  id: string;
266
266
  label: string;
267
267
  disabled?: boolean;
268
+ /**
269
+ * Prevent dropping cards into this column.
270
+ */
271
+ disableOnDragIn?: boolean;
272
+ /**
273
+ * Prevent dragging cards out of this column.
274
+ */
275
+ disableOnDragOut?: boolean;
268
276
  };
269
277
 
270
278
  export declare type AppKanbanConfig<T = any> = {
@@ -418,6 +426,10 @@ export declare interface AppTimePickerProps {
418
426
  useUtc?: boolean;
419
427
  /** Show seconds column in the time picker. @default false */
420
428
  withSeconds?: boolean;
429
+ /** Step interval for minute options. Must be between 1 and 59. @default 1 */
430
+ minuteStep?: number;
431
+ /** Step interval for second options. Must be between 1 and 59. @default 1 */
432
+ secondStep?: number;
421
433
  /** HTML `id` for the trigger element. */
422
434
  id?: string;
423
435
  /** `data-testid` attribute for E2E testing (e.g. Playwright). */
@@ -567,7 +579,7 @@ export declare interface BadgeProps extends React_2.ComponentPropsWithoutRef<"sp
567
579
  }
568
580
 
569
581
  export declare const badgeVariants: (props?: ({
570
- variant?: "link" | "default" | "destructive" | "warning" | "success" | "outline" | "outline-primary" | "outline-destructive" | "outline-warning" | "outline-success" | "secondary" | "ghost" | "ghost-destructive" | "ghost-accent" | "ghost-warning" | "ghost-success" | null | undefined;
582
+ variant?: "link" | "default" | "outline" | "ghost" | "destructive" | "warning" | "success" | "outline-primary" | "outline-destructive" | "outline-warning" | "outline-success" | "secondary" | "ghost-destructive" | "ghost-accent" | "ghost-warning" | "ghost-success" | null | undefined;
571
583
  } & ClassProp) | undefined) => string;
572
584
 
573
585
  declare type BarItemDataType = RepeatDataType | NoRepeatDataType;
@@ -639,7 +651,7 @@ export declare type ButtonSize = "default" | "sm" | "lg" | "icon";
639
651
  export declare type ButtonVariant = "default" | "destructive" | "outline" | "outline-primary" | "outline-destructive" | "secondary" | "ghost" | "ghost-destructive" | "ghost-accent" | "link";
640
652
 
641
653
  export declare const buttonVariants: (props?: ({
642
- variant?: "link" | "default" | "destructive" | "outline" | "outline-primary" | "outline-destructive" | "secondary" | "ghost" | "ghost-destructive" | "ghost-accent" | null | undefined;
654
+ variant?: "link" | "default" | "outline" | "ghost" | "destructive" | "outline-primary" | "outline-destructive" | "secondary" | "ghost-destructive" | "ghost-accent" | null | undefined;
643
655
  size?: "default" | "sm" | "lg" | "icon" | null | undefined;
644
656
  } & ClassProp) | undefined) => string;
645
657
 
@@ -1676,6 +1688,10 @@ declare interface DatePickerSingleProps extends DatePickerBaseProps {
1676
1688
  showTime?: boolean;
1677
1689
  /** Show seconds column in the time picker (requires `showTime`). @default false */
1678
1690
  withSeconds?: boolean;
1691
+ /** Step interval for minute options in time picker. Must be between 1 and 59. @default 1 */
1692
+ minuteStep?: number;
1693
+ /** Step interval for second options in time picker. Must be between 1 and 59. @default 1 */
1694
+ secondStep?: number;
1679
1695
  }
1680
1696
 
1681
1697
  /**
@@ -1745,6 +1761,7 @@ export declare const DropdownMenuGroup: React_2.ForwardRefExoticComponent<Dropdo
1745
1761
 
1746
1762
  export declare const DropdownMenuItem: React_2.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuItemProps & React_2.RefAttributes<HTMLDivElement>, "ref"> & {
1747
1763
  inset?: boolean;
1764
+ variant?: "default" | "destructive";
1748
1765
  } & React_2.RefAttributes<HTMLDivElement>>;
1749
1766
 
1750
1767
  export declare const DropdownMenuLabel: React_2.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuLabelProps & React_2.RefAttributes<HTMLDivElement>, "ref"> & {
@@ -1781,16 +1798,89 @@ export declare enum ELogicalFilterOperator {
1781
1798
 
1782
1799
  export declare const FilePreview: default_2.ForwardRefExoticComponent<FilePreviewProps & default_2.RefAttributes<HTMLDivElement>>;
1783
1800
 
1784
- export declare const FilePreviewer: () => JSX.Element;
1785
-
1786
- declare interface FilePreviewProps {
1801
+ /**
1802
+ * Props for the `FilePreview` component.
1803
+ *
1804
+ * The component renders different previews depending on file type (image, text, generic).
1805
+ * If you pass a native `File`, an object URL is created and revoked automatically.
1806
+ */
1807
+ declare type FilePreviewBaseProps = {
1808
+ /**
1809
+ * The file to render.
1810
+ *
1811
+ * - If a native `File` is provided, the component will create a temporary object URL.
1812
+ * - If an object is provided, `url` is used directly.
1813
+ */
1787
1814
  file: IFilePreviewCallbackReturn;
1788
- onRemove?: (url: string) => void;
1789
- onPreview?: (url: string) => void;
1790
- onDownload?: (url: string) => void;
1815
+ /**
1816
+ * Optional container click handler.
1817
+ *
1818
+ * If provided, it takes precedence over `onPreview` when the container is activated.
1819
+ *
1820
+ * Returning `false` currently has no special meaning in the component implementation
1821
+ * (it is allowed for convenience/consistency with other APIs).
1822
+ */
1823
+ onClick?: (event: default_2.MouseEvent | default_2.KeyboardEvent) => void | Promise<void> | false;
1824
+ /**
1825
+ * Called when the user requests to remove the file.
1826
+ * Receives the resolved file URL (object URL for `File`, otherwise `file.url`).
1827
+ */
1828
+ onRemove?: (url: string) => void | Promise<void>;
1829
+ /**
1830
+ * Called when the user requests to preview/open the file.
1831
+ * Receives the resolved file URL (object URL for `File`, otherwise `file.url`).
1832
+ */
1833
+ onPreview?: (url: string) => void | Promise<void>;
1834
+ /**
1835
+ * Called when the user requests to download the file.
1836
+ * Receives the resolved file URL (object URL for `File`, otherwise `file.url`).
1837
+ */
1838
+ onDownload?: (url: string) => void | Promise<void>;
1839
+ /**
1840
+ * Shows a dropdown menu with the available actions (Preview/Download/Remove)
1841
+ * depending on which callbacks are provided.
1842
+ *
1843
+ * @default false
1844
+ */
1791
1845
  showActionMenu?: boolean;
1846
+ /**
1847
+ * Controls whether a thumbnail/preview is rendered when available.
1848
+ *
1849
+ * - **Images**: when `true`, renders the image thumbnail; when `false`, renders the format icon instead.
1850
+ * - **Text files**: when `true` and a preview can be extracted (only for native `File`), renders the first characters of the file;
1851
+ * otherwise falls back to the format icon.
1852
+ * - **Other file types**: this prop has no effect.
1853
+ *
1854
+ * @default true
1855
+ */
1856
+ showThumbnail?: boolean;
1857
+ /** Optional additional className applied to the root container. */
1792
1858
  className?: string;
1793
- }
1859
+ variant?: FilePreviewVariant;
1860
+ size?: FilePreviewSize;
1861
+ };
1862
+
1863
+ export declare const FilePreviewer: () => JSX.Element;
1864
+
1865
+ declare type FilePreviewProps = (FilePreviewBaseProps & {
1866
+ /**
1867
+ * Enables click/keyboard interaction on the container.
1868
+ *
1869
+ * Note: the container is effectively clickable only if `onPreview` or `onClick` is provided.
1870
+ *
1871
+ * @default true
1872
+ */
1873
+ clickable?: boolean;
1874
+ showActionMenu?: false | undefined;
1875
+ }) | (FilePreviewBaseProps & {
1876
+ showActionMenu: true;
1877
+ clickable?: never;
1878
+ onClick?: never;
1879
+ });
1880
+
1881
+ declare type FilePreviewSize = "default" | "sm";
1882
+
1883
+ declare type FilePreviewVariant = "default" | "outline" | "ghost";
1794
1884
 
1795
1885
  export declare const FileUploader: default_2.FC<FileUploaderProps>;
1796
1886
 
@@ -2873,7 +2963,7 @@ export declare function TooltipProvider({ delayDuration, ...props }: React_2.Com
2873
2963
  export declare function TooltipTrigger({ ...props }: React_2.ComponentProps<typeof TooltipPrimitive.Trigger>): JSX.Element;
2874
2964
 
2875
2965
  declare const tooltipTriggerVariants: (props?: ({
2876
- variant?: "default" | "secondary" | "ghost" | "primary" | "muted" | "accent" | null | undefined;
2966
+ variant?: "default" | "ghost" | "secondary" | "primary" | "muted" | "accent" | null | undefined;
2877
2967
  size?: "default" | "sm" | "lg" | null | undefined;
2878
2968
  } & ClassProp) | undefined) => string;
2879
2969
 
package/dist/index.js CHANGED
@@ -54,7 +54,7 @@ import { CircularProgress as Mt } from "./components/ui/charts/circular.js";
54
54
  import { DropdownMenu as Dt, DropdownMenuCheckboxItem as At, DropdownMenuContent as Ft, DropdownMenuGroup as It, DropdownMenuItem as wt, DropdownMenuLabel as Pt, DropdownMenuPortal as ht, DropdownMenuRadioGroup as vt, DropdownMenuRadioItem as Gt, DropdownMenuSeparator as Bt, DropdownMenuShortcut as Lt, DropdownMenuSub as Rt, DropdownMenuSubContent as kt, DropdownMenuSubTrigger as Ht, DropdownMenuTrigger as yt } from "./components/ui/dropdown-menu.js";
55
55
  import { Slider as Ot } from "./components/ui/slider.js";
56
56
  import { ThemeSwitcher as zt } from "./components/ui/theme-switcher.js";
57
- import { FilePreview as jt } from "./components/ui/file-preview.js";
57
+ import { FilePreview as jt } from "./components/ui/file-preview/index.js";
58
58
  import { FileUploader as Ut } from "./components/ui/file-uploader.js";
59
59
  import { AudioVisualizer as qt } from "./components/ui/audio-visualizer.js";
60
60
  import { Carousel as Qt, CarouselContent as Xt, CarouselItem as Yt, CarouselNext as Zt, CarouselPrevious as _t } from "./components/ui/carousel.js";