@devalok/shilp-sutra 0.25.0 → 0.26.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.
Files changed (103) hide show
  1. package/dist/_chunks/framer.js +2 -2
  2. package/dist/_chunks/primitives.js +39 -39
  3. package/dist/_chunks/vendor-client.js +1 -1
  4. package/dist/_chunks/vendor-utils.js +83484 -3535
  5. package/dist/ai/index.js +1 -1
  6. package/dist/composed/bulk-action-bar.d.ts +29 -0
  7. package/dist/composed/bulk-action-bar.d.ts.map +1 -0
  8. package/dist/composed/bulk-action-bar.js +123 -0
  9. package/dist/composed/deadline-indicator.d.ts +18 -0
  10. package/dist/composed/deadline-indicator.d.ts.map +1 -0
  11. package/dist/composed/deadline-indicator.js +75 -0
  12. package/dist/composed/emoji-picker.d.ts +26 -0
  13. package/dist/composed/emoji-picker.d.ts.map +1 -0
  14. package/dist/composed/emoji-picker.js +104 -0
  15. package/dist/composed/file-preview.d.ts +22 -0
  16. package/dist/composed/file-preview.d.ts.map +1 -0
  17. package/dist/composed/file-preview.js +675 -0
  18. package/dist/composed/filter-bar.d.ts +38 -0
  19. package/dist/composed/filter-bar.d.ts.map +1 -0
  20. package/dist/composed/filter-bar.js +133 -0
  21. package/dist/composed/form-section.d.ts +12 -0
  22. package/dist/composed/form-section.d.ts.map +1 -0
  23. package/dist/composed/form-section.js +45 -0
  24. package/dist/composed/index.d.ts +22 -0
  25. package/dist/composed/index.d.ts.map +1 -1
  26. package/dist/composed/index.js +61 -36
  27. package/dist/composed/inline-edit.d.ts +16 -0
  28. package/dist/composed/inline-edit.d.ts.map +1 -0
  29. package/dist/composed/inline-edit.js +107 -0
  30. package/dist/composed/markdown-viewer.d.ts +14 -0
  31. package/dist/composed/markdown-viewer.d.ts.map +1 -0
  32. package/dist/composed/markdown-viewer.js +143 -0
  33. package/dist/composed/master-detail.d.ts +35 -0
  34. package/dist/composed/master-detail.d.ts.map +1 -0
  35. package/dist/composed/master-detail.js +124 -0
  36. package/dist/composed/member-picker.d.ts.map +1 -1
  37. package/dist/composed/member-picker.js +41 -88
  38. package/dist/composed/multi-select-popover.d.ts +44 -0
  39. package/dist/composed/multi-select-popover.d.ts.map +1 -0
  40. package/dist/composed/multi-select-popover.js +185 -0
  41. package/dist/composed/responsive-overlay.d.ts +15 -0
  42. package/dist/composed/responsive-overlay.d.ts.map +1 -0
  43. package/dist/composed/responsive-overlay.js +45 -0
  44. package/dist/ui/alert-dialog.js +10 -10
  45. package/dist/ui/avatar.js +1 -1
  46. package/dist/ui/button.d.ts +1 -1
  47. package/dist/ui/button.d.ts.map +1 -1
  48. package/dist/ui/button.js +42 -36
  49. package/dist/ui/card.d.ts +6 -48
  50. package/dist/ui/card.d.ts.map +1 -1
  51. package/dist/ui/card.js +92 -49
  52. package/dist/ui/checkbox.js +1 -1
  53. package/dist/ui/collapsible.js +1 -1
  54. package/dist/ui/color-swatch.d.ts +27 -0
  55. package/dist/ui/color-swatch.d.ts.map +1 -0
  56. package/dist/ui/color-swatch.js +91 -0
  57. package/dist/ui/data-table.d.ts +7 -1
  58. package/dist/ui/data-table.d.ts.map +1 -1
  59. package/dist/ui/data-table.js +221 -215
  60. package/dist/ui/dialog.js +4 -4
  61. package/dist/ui/dropdown-menu.js +31 -31
  62. package/dist/ui/index.d.ts +3 -0
  63. package/dist/ui/index.d.ts.map +1 -1
  64. package/dist/ui/index.js +187 -180
  65. package/dist/ui/input.d.ts +1 -1
  66. package/dist/ui/input.d.ts.map +1 -1
  67. package/dist/ui/input.js +10 -9
  68. package/dist/ui/label.js +1 -1
  69. package/dist/ui/progress-ring.d.ts +46 -0
  70. package/dist/ui/progress-ring.d.ts.map +1 -0
  71. package/dist/ui/progress-ring.js +144 -0
  72. package/dist/ui/search-input.d.ts +1 -1
  73. package/dist/ui/search-input.d.ts.map +1 -1
  74. package/dist/ui/search-input.js +9 -8
  75. package/dist/ui/select.d.ts +1 -1
  76. package/dist/ui/select.d.ts.map +1 -1
  77. package/dist/ui/select.js +28 -27
  78. package/dist/ui/sheet.js +1 -1
  79. package/dist/ui/sidebar.d.ts.map +1 -1
  80. package/dist/ui/sidebar.js +15 -15
  81. package/dist/ui/status-dot.d.ts +27 -0
  82. package/dist/ui/status-dot.d.ts.map +1 -0
  83. package/dist/ui/status-dot.js +64 -0
  84. package/dist/ui/textarea.d.ts +1 -1
  85. package/dist/ui/textarea.d.ts.map +1 -1
  86. package/dist/ui/textarea.js +13 -12
  87. package/docs/components/composed/bulk-action-bar.md +40 -0
  88. package/docs/components/composed/deadline-indicator.md +27 -0
  89. package/docs/components/composed/emoji-picker.md +43 -0
  90. package/docs/components/composed/file-preview.md +40 -0
  91. package/docs/components/composed/filter-bar.md +57 -0
  92. package/docs/components/composed/form-section.md +31 -0
  93. package/docs/components/composed/inline-edit.md +35 -0
  94. package/docs/components/composed/markdown-viewer.md +27 -0
  95. package/docs/components/composed/master-detail.md +48 -0
  96. package/docs/components/composed/multi-select-popover.md +53 -0
  97. package/docs/components/composed/responsive-overlay.md +34 -0
  98. package/docs/components/ui/color-swatch.md +25 -0
  99. package/docs/components/ui/progress-ring.md +41 -0
  100. package/docs/components/ui/status-dot.md +26 -0
  101. package/llms-full.txt +528 -1
  102. package/llms.txt +37 -9
  103. package/package.json +808 -733
@@ -0,0 +1,675 @@
1
+ "use client";
2
+ import { jsx as e, jsxs as d, Fragment as G } from "react/jsx-runtime";
3
+ import * as a from "react";
4
+ import { cn as R } from "../ui/lib/utils.js";
5
+ import { tweens as B, springs as Y } from "../ui/lib/motion.js";
6
+ import { Skeleton as V } from "../ui/skeleton.js";
7
+ import { Button as L } from "../ui/button.js";
8
+ import { Badge as J } from "../ui/badge.js";
9
+ import { IconZoomOut as Q, IconZoomIn as ee, IconZoomReset as te, IconMinimize as ne, IconMaximize as O, IconChevronLeft as ae, IconChevronRight as re, IconAlertTriangle as se, IconDownload as W, IconPlayerPlay as K, IconPlayerPause as _, IconVolumeOff as oe, IconVolume as ie } from "@tabler/icons-react";
10
+ import { m as E, A as H } from "../_chunks/framer.js";
11
+ function ce(n, o) {
12
+ var r;
13
+ if (o) {
14
+ if (o.startsWith("image/")) return "image";
15
+ if (o === "application/pdf") return "pdf";
16
+ if (o.startsWith("video/")) return "video";
17
+ if (o.startsWith("audio/")) return "audio";
18
+ }
19
+ const t = (r = n.split("?")[0].split(".").pop()) == null ? void 0 : r.toLowerCase();
20
+ return ["jpg", "jpeg", "png", "gif", "webp", "svg", "avif", "bmp"].includes(t ?? "") ? "image" : t === "pdf" ? "pdf" : ["mp4", "webm", "ogg", "mov"].includes(t ?? "") ? "video" : ["mp3", "wav", "ogg", "aac", "flac"].includes(t ?? "") ? "audio" : n.includes("figma.com") || n.includes("loom.com") || n.includes("youtube.com") || n.includes("youtu.be") || n.includes("vimeo.com") ? "embed" : "image";
21
+ }
22
+ function le(n) {
23
+ const o = n.match(/(?:youtube\.com\/watch\?v=|youtu\.be\/)([^&?]+)/);
24
+ if (o) return `https://www.youtube.com/embed/${o[1]}`;
25
+ const t = n.match(/vimeo\.com\/(\d+)/);
26
+ if (t) return `https://player.vimeo.com/video/${t[1]}`;
27
+ if (n.includes("figma.com")) return `https://www.figma.com/embed?embed_host=share&url=${encodeURIComponent(n)}`;
28
+ const r = n.match(/loom\.com\/share\/([^?]+)/);
29
+ return r ? `https://www.loom.com/embed/${r[1]}` : n;
30
+ }
31
+ function X({
32
+ volume: n,
33
+ muted: o,
34
+ onVolumeChange: t,
35
+ onMuteToggle: r,
36
+ variant: m = "light"
37
+ }) {
38
+ const h = a.useRef(null), [b, p] = a.useState(!1), v = o ? 0 : n;
39
+ function x(w) {
40
+ if (!h.current) return n;
41
+ const T = h.current.getBoundingClientRect();
42
+ return Math.max(0, Math.min(1, (w.clientX - T.left) / T.width));
43
+ }
44
+ function g(w) {
45
+ w.preventDefault(), p(!0);
46
+ const T = x(w);
47
+ t(T), w.target.setPointerCapture(w.pointerId);
48
+ }
49
+ function y(w) {
50
+ b && t(x(w));
51
+ }
52
+ function k() {
53
+ p(!1);
54
+ }
55
+ const f = m === "dark", I = f ? "bg-white/30" : "bg-surface-sunken", D = f ? "bg-white" : "bg-accent-9", P = f ? "bg-white" : "bg-accent-9";
56
+ return /* @__PURE__ */ d("div", { className: "group/vol flex items-center gap-ds-02 shrink-0", children: [
57
+ /* @__PURE__ */ e("button", { onClick: r, className: R("transition-colors", f ? "text-white hover:text-white/80" : "text-surface-fg-muted hover:text-surface-fg"), "aria-label": o ? "Unmute (M)" : "Mute (M)", children: o || n === 0 ? /* @__PURE__ */ e(oe, { className: "h-ico-sm w-ico-sm" }) : /* @__PURE__ */ e(ie, { className: "h-ico-sm w-ico-sm" }) }),
58
+ /* @__PURE__ */ e("div", { className: "w-0 overflow-hidden group-hover/vol:w-20 transition-[width] duration-200 ease-productive-standard flex items-center", children: /* @__PURE__ */ d(
59
+ "div",
60
+ {
61
+ ref: h,
62
+ className: R("relative w-full h-1 rounded-full cursor-pointer", I),
63
+ onPointerDown: g,
64
+ onPointerMove: y,
65
+ onPointerUp: k,
66
+ role: "slider",
67
+ "aria-label": "Volume",
68
+ "aria-valuenow": Math.round(v * 100),
69
+ "aria-valuemin": 0,
70
+ "aria-valuemax": 100,
71
+ tabIndex: 0,
72
+ children: [
73
+ /* @__PURE__ */ e(
74
+ "div",
75
+ {
76
+ className: R("absolute left-0 top-0 h-full rounded-full transition-[width] duration-75", D),
77
+ style: { width: `${v * 100}%` }
78
+ }
79
+ ),
80
+ /* @__PURE__ */ e(
81
+ "div",
82
+ {
83
+ className: R(
84
+ "absolute top-1/2 -translate-y-1/2 h-2.5 w-2.5 rounded-full shadow-raised transition-opacity",
85
+ P,
86
+ b ? "opacity-100 scale-110" : "opacity-0 group-hover/vol:opacity-100"
87
+ ),
88
+ style: { left: `${v * 100}%`, marginLeft: "-5px" }
89
+ }
90
+ )
91
+ ]
92
+ }
93
+ ) })
94
+ ] });
95
+ }
96
+ function j(n) {
97
+ if (!isFinite(n) || n < 0) return "0:00";
98
+ const o = Math.floor(n / 3600), t = Math.floor(n % 3600 / 60), r = Math.floor(n % 60);
99
+ return o > 0 ? `${o}:${t.toString().padStart(2, "0")}:${r.toString().padStart(2, "0")}` : `${t}:${r.toString().padStart(2, "0")}`;
100
+ }
101
+ function $({ message: n, url: o }) {
102
+ return /* @__PURE__ */ d("div", { className: "flex flex-col items-center justify-center gap-ds-04 rounded-ds-md border border-surface-border bg-surface-sunken p-ds-08 text-center", children: [
103
+ /* @__PURE__ */ e(se, { className: "h-8 w-8 text-warning-9" }),
104
+ /* @__PURE__ */ d("div", { children: [
105
+ /* @__PURE__ */ e("p", { className: "text-ds-md font-semibold text-surface-fg", children: "Preview unavailable" }),
106
+ /* @__PURE__ */ e("p", { className: "text-ds-sm text-surface-fg-muted mt-ds-01", children: n })
107
+ ] }),
108
+ /* @__PURE__ */ e(L, { variant: "outline", size: "xs", startIcon: /* @__PURE__ */ e(W, { className: "h-3.5 w-3.5" }), asChild: !0, children: /* @__PURE__ */ e("a", { href: o, download: !0, target: "_blank", rel: "noopener noreferrer", children: "Download file" }) })
109
+ ] });
110
+ }
111
+ function q({ children: n, className: o }) {
112
+ return /* @__PURE__ */ e(
113
+ E.div,
114
+ {
115
+ initial: { opacity: 0, y: 8 },
116
+ animate: { opacity: 1, y: 0 },
117
+ transition: B.fade,
118
+ className: R(
119
+ "flex items-center gap-ds-01 rounded-ds-md border border-surface-border bg-surface-overlay/95 px-ds-02 py-ds-01 shadow-floating backdrop-blur-sm",
120
+ o
121
+ ),
122
+ children: n
123
+ }
124
+ );
125
+ }
126
+ function Z() {
127
+ return /* @__PURE__ */ e("div", { className: "mx-ds-01 h-4 w-px bg-surface-border-subtle" });
128
+ }
129
+ const ue = a.lazy(
130
+ () => import("../_chunks/vendor-utils.js").then((n) => n.aC).then((n) => ({
131
+ default: function({ url: t, alt: r, onError: m }) {
132
+ const { TransformWrapper: h, TransformComponent: b } = n, [p, v] = a.useState(!1), [x, g] = a.useState(!1), [y, k] = a.useState(100), [f, I] = a.useState(!1), D = a.useRef(null), [P, C] = a.useState(!1), w = a.useRef(null);
133
+ return a.useEffect(() => {
134
+ function u(i) {
135
+ const M = D.current;
136
+ if (!M || !M.contains(document.activeElement) && !P) return;
137
+ const S = w.current;
138
+ S && (i.key === "+" || i.key === "=" ? (i.preventDefault(), S.zoomIn()) : i.key === "-" ? (i.preventDefault(), S.zoomOut()) : i.key === "0" ? (i.preventDefault(), S.resetTransform()) : i.key === "f" || i.key === "F" ? (i.preventDefault(), I((s) => !s)) : i.key === "Escape" && f && (i.preventDefault(), I(!1)));
139
+ }
140
+ return document.addEventListener("keydown", u), () => document.removeEventListener("keydown", u);
141
+ }, [P, f]), x ? /* @__PURE__ */ e($, { message: "Could not load image", url: t }) : /* @__PURE__ */ e(
142
+ "div",
143
+ {
144
+ ref: D,
145
+ className: f ? "fixed inset-0 z-50 flex flex-col items-center justify-center bg-black/90 backdrop-blur-sm" : "relative flex flex-col items-center gap-ds-03",
146
+ onMouseEnter: () => C(!0),
147
+ onMouseLeave: () => C(!1),
148
+ tabIndex: -1,
149
+ children: /* @__PURE__ */ e(
150
+ h,
151
+ {
152
+ initialScale: 1,
153
+ minScale: 0.1,
154
+ maxScale: 8,
155
+ centerOnInit: !0,
156
+ doubleClick: { mode: "toggle", step: 2 },
157
+ onTransformed: (u, i) => k(Math.round(i.scale * 100)),
158
+ children: ({ zoomIn: u, zoomOut: i, resetTransform: M, centerView: A }) => (w.current = { zoomIn: u, zoomOut: i, resetTransform: M, centerView: A }, /* @__PURE__ */ d(G, { children: [
159
+ /* @__PURE__ */ d("div", { className: R(
160
+ "overflow-hidden rounded-ds-md bg-surface-sunken",
161
+ f ? "flex-1 w-full" : "max-h-[70vh] max-w-full"
162
+ ), children: [
163
+ !p && /* @__PURE__ */ e(V, { className: "h-64 w-full rounded-ds-md" }),
164
+ /* @__PURE__ */ e(
165
+ b,
166
+ {
167
+ wrapperClass: R("!w-full", f && "!h-full"),
168
+ contentClass: "!w-full !flex !items-center !justify-center",
169
+ children: /* @__PURE__ */ e(
170
+ E.img,
171
+ {
172
+ src: t,
173
+ alt: r ?? "",
174
+ onLoad: () => v(!0),
175
+ onError: () => {
176
+ g(!0), m == null || m("Image failed to load");
177
+ },
178
+ initial: { opacity: 0 },
179
+ animate: { opacity: p ? 1 : 0 },
180
+ transition: B.fade,
181
+ className: R("max-w-full select-none", !p && "hidden", f && "max-h-[90vh] object-contain"),
182
+ draggable: !1
183
+ }
184
+ )
185
+ }
186
+ )
187
+ ] }),
188
+ p && /* @__PURE__ */ d(q, { className: f ? "absolute bottom-ds-06" : void 0, children: [
189
+ /* @__PURE__ */ e(L, { variant: "ghost", size: "icon-xs", onClick: () => i(), "aria-label": "Zoom out (-)", children: /* @__PURE__ */ e(Q, { className: "h-ico-sm w-ico-sm" }) }),
190
+ /* @__PURE__ */ d("span", { className: "text-ds-xs font-mono text-surface-fg-muted w-12 text-center tabular-nums select-none", children: [
191
+ y,
192
+ "%"
193
+ ] }),
194
+ /* @__PURE__ */ e(L, { variant: "ghost", size: "icon-xs", onClick: () => u(), "aria-label": "Zoom in (+)", children: /* @__PURE__ */ e(ee, { className: "h-ico-sm w-ico-sm" }) }),
195
+ /* @__PURE__ */ e(Z, {}),
196
+ /* @__PURE__ */ e(L, { variant: "ghost", size: "icon-xs", onClick: () => M(), "aria-label": "Reset zoom (0)", children: /* @__PURE__ */ e(te, { className: "h-ico-sm w-ico-sm" }) }),
197
+ /* @__PURE__ */ e(Z, {}),
198
+ /* @__PURE__ */ e(L, { variant: "ghost", size: "icon-xs", onClick: () => I((S) => !S), "aria-label": f ? "Exit fullscreen (Esc)" : "Fullscreen (F)", children: f ? /* @__PURE__ */ e(ne, { className: "h-ico-sm w-ico-sm" }) : /* @__PURE__ */ e(O, { className: "h-ico-sm w-ico-sm" }) })
199
+ ] })
200
+ ] }))
201
+ }
202
+ )
203
+ }
204
+ );
205
+ }
206
+ }))
207
+ ), de = a.lazy(
208
+ () => import("../_chunks/vendor-utils.js").then((n) => n.aD).then((n) => ({
209
+ default: function({ url: t, initialPage: r, onError: m }) {
210
+ const { Document: h, Page: b, pdfjs: p } = n;
211
+ a.useEffect(() => {
212
+ p.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${p.version}/build/pdf.worker.min.mjs`;
213
+ }, []);
214
+ const [v, x] = a.useState(0), [g, y] = a.useState(r), [k, f] = a.useState(String(r)), [I, D] = a.useState(!1), P = a.useRef(null), [C, w] = a.useState(!1);
215
+ a.useEffect(() => {
216
+ f(String(g));
217
+ }, [g]), a.useEffect(() => {
218
+ function u(i) {
219
+ const M = P.current;
220
+ !M || !M.contains(document.activeElement) && !C || (i.key === "ArrowRight" || i.key === "ArrowDown" ? (i.preventDefault(), y((S) => Math.min(v, S + 1))) : (i.key === "ArrowLeft" || i.key === "ArrowUp") && (i.preventDefault(), y((S) => Math.max(1, S - 1))));
221
+ }
222
+ return document.addEventListener("keydown", u), () => document.removeEventListener("keydown", u);
223
+ }, [v, C]);
224
+ function T(u) {
225
+ if (u.key === "Enter") {
226
+ const i = parseInt(k, 10);
227
+ i >= 1 && i <= v ? y(i) : f(String(g));
228
+ }
229
+ }
230
+ return I ? /* @__PURE__ */ e($, { message: "Could not load PDF", url: t }) : /* @__PURE__ */ d(
231
+ "div",
232
+ {
233
+ ref: P,
234
+ className: "flex flex-col items-center gap-ds-03",
235
+ onMouseEnter: () => w(!0),
236
+ onMouseLeave: () => w(!1),
237
+ tabIndex: -1,
238
+ children: [
239
+ /* @__PURE__ */ e("div", { className: "overflow-auto max-h-[70vh] rounded-ds-md bg-surface-sunken border border-surface-border", children: /* @__PURE__ */ e(
240
+ h,
241
+ {
242
+ file: t,
243
+ onLoadSuccess: ({ numPages: u }) => x(u),
244
+ onLoadError: () => {
245
+ D(!0), m == null || m("PDF failed to load");
246
+ },
247
+ loading: /* @__PURE__ */ e(V, { className: "h-[500px] w-[400px]" }),
248
+ error: /* @__PURE__ */ e($, { message: "Failed to load PDF", url: t }),
249
+ children: /* @__PURE__ */ e(H, { mode: "wait", children: /* @__PURE__ */ e(
250
+ E.div,
251
+ {
252
+ initial: { opacity: 0 },
253
+ animate: { opacity: 1 },
254
+ exit: { opacity: 0 },
255
+ transition: B.fade,
256
+ children: /* @__PURE__ */ e(b, { pageNumber: g, renderTextLayer: !1, renderAnnotationLayer: !1 })
257
+ },
258
+ g
259
+ ) })
260
+ }
261
+ ) }),
262
+ v > 0 && /* @__PURE__ */ d(q, { children: [
263
+ /* @__PURE__ */ e(L, { variant: "ghost", size: "icon-xs", onClick: () => y((u) => Math.max(1, u - 1)), disabled: g <= 1, "aria-label": "Previous page (←)", children: /* @__PURE__ */ e(ae, { className: "h-ico-sm w-ico-sm" }) }),
264
+ /* @__PURE__ */ d("div", { className: "flex items-center gap-ds-01 text-ds-xs text-surface-fg-muted", children: [
265
+ /* @__PURE__ */ e(
266
+ "input",
267
+ {
268
+ type: "text",
269
+ value: k,
270
+ onChange: (u) => f(u.target.value),
271
+ onKeyDown: T,
272
+ onBlur: () => f(String(g)),
273
+ className: "w-8 bg-transparent text-center font-mono text-surface-fg outline-none focus:bg-surface-raised-hover rounded-ds-sm",
274
+ "aria-label": "Page number"
275
+ }
276
+ ),
277
+ /* @__PURE__ */ d("span", { children: [
278
+ "/ ",
279
+ v
280
+ ] })
281
+ ] }),
282
+ /* @__PURE__ */ e(L, { variant: "ghost", size: "icon-xs", onClick: () => y((u) => Math.min(v, u + 1)), disabled: g >= v, "aria-label": "Next page (→)", children: /* @__PURE__ */ e(re, { className: "h-ico-sm w-ico-sm" }) })
283
+ ] })
284
+ ]
285
+ }
286
+ );
287
+ }
288
+ }))
289
+ ), U = [0.5, 0.75, 1, 1.25, 1.5, 2];
290
+ function fe({ url: n, onError: o }) {
291
+ const t = a.useRef(null), r = a.useRef(null), [m, h] = a.useState(!1), [b, p] = a.useState(0), [v, x] = a.useState(0), [g, y] = a.useState(0), [k, f] = a.useState(!1), [I, D] = a.useState(!1), [P, C] = a.useState(!0), [w, T] = a.useState(1), u = a.useRef();
292
+ a.useEffect(() => () => clearTimeout(u.current), []), a.useEffect(() => {
293
+ function s(c) {
294
+ var F;
295
+ const N = r.current;
296
+ if (!N || !N.contains(document.activeElement) && document.activeElement !== N) return;
297
+ const l = t.current;
298
+ if (l)
299
+ switch (c.key) {
300
+ case " ":
301
+ case "k":
302
+ c.preventDefault(), h((z) => (z ? l.pause() : l.play(), !z));
303
+ break;
304
+ case "ArrowRight":
305
+ c.preventDefault(), l.currentTime = Math.min(l.duration, l.currentTime + 5);
306
+ break;
307
+ case "ArrowLeft":
308
+ c.preventDefault(), l.currentTime = Math.max(0, l.currentTime - 5);
309
+ break;
310
+ case "j":
311
+ c.preventDefault(), l.currentTime = Math.max(0, l.currentTime - 10);
312
+ break;
313
+ case "l":
314
+ c.preventDefault(), l.currentTime = Math.min(l.duration, l.currentTime + 10);
315
+ break;
316
+ case "m":
317
+ c.preventDefault(), f((z) => (l.muted = !z, !z));
318
+ break;
319
+ case "f":
320
+ c.preventDefault(), (F = l.requestFullscreen) == null || F.call(l);
321
+ break;
322
+ case ">":
323
+ c.preventDefault(), i(1);
324
+ break;
325
+ case "<":
326
+ c.preventDefault(), i(-1);
327
+ break;
328
+ }
329
+ }
330
+ return document.addEventListener("keydown", s), () => document.removeEventListener("keydown", s);
331
+ }, []);
332
+ function i(s) {
333
+ const c = U.indexOf(w), N = Math.max(0, Math.min(U.length - 1, c + s)), l = U[N];
334
+ T(l), t.current && (t.current.playbackRate = l);
335
+ }
336
+ function M() {
337
+ t.current && (m ? t.current.pause() : t.current.play(), h(!m));
338
+ }
339
+ function A(s) {
340
+ if (!t.current || !v) return;
341
+ const c = s.currentTarget.getBoundingClientRect(), N = (s.clientX - c.left) / c.width;
342
+ t.current.currentTime = N * v;
343
+ }
344
+ function S() {
345
+ C(!0), clearTimeout(u.current), m && (u.current = setTimeout(() => C(!1), 3e3));
346
+ }
347
+ return I ? /* @__PURE__ */ e($, { message: "Could not load video", url: n }) : /* @__PURE__ */ d(
348
+ "div",
349
+ {
350
+ ref: r,
351
+ className: "group relative rounded-ds-md bg-black overflow-hidden",
352
+ onMouseMove: S,
353
+ onMouseLeave: () => m && C(!1),
354
+ tabIndex: -1,
355
+ children: [
356
+ /* @__PURE__ */ e(
357
+ "video",
358
+ {
359
+ ref: t,
360
+ src: n,
361
+ className: "max-h-[70vh] w-full",
362
+ onClick: M,
363
+ muted: k,
364
+ onTimeUpdate: () => {
365
+ t.current && (y(t.current.currentTime), t.current.duration && p(t.current.currentTime / t.current.duration * 100));
366
+ },
367
+ onLoadedMetadata: () => {
368
+ var s;
369
+ return x(((s = t.current) == null ? void 0 : s.duration) ?? 0);
370
+ },
371
+ onEnded: () => {
372
+ h(!1), C(!0);
373
+ },
374
+ onError: () => {
375
+ D(!0), o == null || o("Video failed to load");
376
+ },
377
+ playsInline: !0
378
+ }
379
+ ),
380
+ !m && /* @__PURE__ */ e(
381
+ E.button,
382
+ {
383
+ initial: { opacity: 0, scale: 0.8 },
384
+ animate: { opacity: 1, scale: 1 },
385
+ transition: Y.snappy,
386
+ onClick: M,
387
+ className: "absolute inset-0 flex items-center justify-center bg-black/30",
388
+ "aria-label": "Play video",
389
+ children: /* @__PURE__ */ e("div", { className: "flex h-14 w-14 items-center justify-center rounded-full bg-white/90 shadow-floating", children: /* @__PURE__ */ e(K, { className: "h-6 w-6 text-surface-fg ml-0.5" }) })
390
+ }
391
+ ),
392
+ /* @__PURE__ */ e(H, { children: P && v > 0 && /* @__PURE__ */ d(
393
+ E.div,
394
+ {
395
+ initial: { opacity: 0, y: 10 },
396
+ animate: { opacity: 1, y: 0 },
397
+ exit: { opacity: 0, y: 10 },
398
+ transition: B.fade,
399
+ className: "absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/80 to-transparent px-ds-04 pb-ds-04 pt-ds-08",
400
+ children: [
401
+ /* @__PURE__ */ d(
402
+ "div",
403
+ {
404
+ className: "relative h-1 w-full cursor-pointer rounded-full bg-white/30 mb-ds-03 group/progress",
405
+ onClick: A,
406
+ role: "slider",
407
+ "aria-label": "Video progress",
408
+ "aria-valuenow": Math.round(b),
409
+ "aria-valuemin": 0,
410
+ "aria-valuemax": 100,
411
+ tabIndex: 0,
412
+ children: [
413
+ /* @__PURE__ */ e(
414
+ "div",
415
+ {
416
+ className: "absolute left-0 top-0 h-full rounded-full bg-white transition-[width] duration-75",
417
+ style: { width: `${b}%` }
418
+ }
419
+ ),
420
+ /* @__PURE__ */ e(
421
+ "div",
422
+ {
423
+ className: "absolute top-1/2 -translate-y-1/2 h-3 w-3 rounded-full bg-white shadow-raised opacity-0 group-hover/progress:opacity-100 transition-opacity",
424
+ style: { left: `${b}%`, marginLeft: "-6px" }
425
+ }
426
+ )
427
+ ]
428
+ }
429
+ ),
430
+ /* @__PURE__ */ d("div", { className: "flex items-center gap-ds-03", children: [
431
+ /* @__PURE__ */ e("button", { onClick: M, className: "text-white hover:text-white/80", "aria-label": m ? "Pause" : "Play", children: m ? /* @__PURE__ */ e(_, { className: "h-5 w-5" }) : /* @__PURE__ */ e(K, { className: "h-5 w-5" }) }),
432
+ /* @__PURE__ */ e(
433
+ X,
434
+ {
435
+ volume: k ? 0 : 1,
436
+ muted: k,
437
+ onVolumeChange: (s) => {
438
+ t.current && (t.current.volume = s), s > 0 && k && (f(!1), t.current && (t.current.muted = !1));
439
+ },
440
+ onMuteToggle: () => {
441
+ f(!k), t.current && (t.current.muted = !k);
442
+ },
443
+ variant: "dark"
444
+ }
445
+ ),
446
+ /* @__PURE__ */ d("span", { className: "text-[11px] font-mono text-white/70 tabular-nums", children: [
447
+ j(g),
448
+ " / ",
449
+ j(v)
450
+ ] }),
451
+ /* @__PURE__ */ e("div", { className: "flex-1" }),
452
+ /* @__PURE__ */ d(
453
+ "button",
454
+ {
455
+ onClick: () => i(1),
456
+ className: "text-[11px] font-mono text-white/70 hover:text-white px-1 rounded-ds-sm hover:bg-white/10 transition-colors",
457
+ "aria-label": `Playback speed: ${w}x`,
458
+ children: [
459
+ w,
460
+ "x"
461
+ ]
462
+ }
463
+ ),
464
+ /* @__PURE__ */ e(
465
+ "button",
466
+ {
467
+ onClick: () => {
468
+ var s, c;
469
+ return (c = (s = t.current) == null ? void 0 : s.requestFullscreen) == null ? void 0 : c.call(s);
470
+ },
471
+ className: "text-white hover:text-white/80",
472
+ "aria-label": "Fullscreen (F)",
473
+ children: /* @__PURE__ */ e(O, { className: "h-4 w-4" })
474
+ }
475
+ )
476
+ ] })
477
+ ]
478
+ }
479
+ ) })
480
+ ]
481
+ }
482
+ );
483
+ }
484
+ function me({ url: n, fileName: o, onError: t }) {
485
+ const r = a.useRef(null), m = a.useRef(null), [h, b] = a.useState(!1), [p, v] = a.useState(0), [x, g] = a.useState(0), [y, k] = a.useState(0), [f, I] = a.useState(1), [D, P] = a.useState(!1), [C, w] = a.useState(!1), [T, u] = a.useState(null);
486
+ a.useEffect(() => {
487
+ function s(c) {
488
+ const N = m.current;
489
+ if (!N || !N.contains(document.activeElement) && document.activeElement !== N) return;
490
+ const l = r.current;
491
+ if (l)
492
+ switch (c.key) {
493
+ case " ":
494
+ c.preventDefault(), b((F) => (F ? l.pause() : l.play(), !F));
495
+ break;
496
+ case "ArrowRight":
497
+ c.preventDefault(), l.currentTime = Math.min(l.duration || 0, l.currentTime + 5);
498
+ break;
499
+ case "ArrowLeft":
500
+ c.preventDefault(), l.currentTime = Math.max(0, l.currentTime - 5);
501
+ break;
502
+ case "m":
503
+ c.preventDefault(), P((F) => (l.muted = !F, !F));
504
+ break;
505
+ }
506
+ }
507
+ return document.addEventListener("keydown", s), () => document.removeEventListener("keydown", s);
508
+ }, []);
509
+ function i() {
510
+ r.current && (h ? r.current.pause() : r.current.play(), b(!h));
511
+ }
512
+ function M(s) {
513
+ if (!r.current || !x) return;
514
+ const c = s.currentTarget.getBoundingClientRect(), N = Math.max(0, Math.min(1, (s.clientX - c.left) / c.width));
515
+ r.current.currentTime = N * x;
516
+ }
517
+ function A(s) {
518
+ if (!x) return;
519
+ const c = s.currentTarget.getBoundingClientRect(), N = (s.clientX - c.left) / c.width;
520
+ u(N * x);
521
+ }
522
+ function S() {
523
+ if (!r.current) return;
524
+ const s = !D;
525
+ P(s), r.current.muted = s;
526
+ }
527
+ return C ? /* @__PURE__ */ e($, { message: "Could not load audio", url: n }) : /* @__PURE__ */ d("div", { ref: m, className: "rounded-ds-lg border border-surface-border bg-surface-raised shadow-raised overflow-hidden", tabIndex: -1, children: [
528
+ /* @__PURE__ */ e(
529
+ "audio",
530
+ {
531
+ ref: r,
532
+ src: n,
533
+ onTimeUpdate: () => {
534
+ r.current && (k(r.current.currentTime), r.current.duration && v(r.current.currentTime / r.current.duration * 100));
535
+ },
536
+ onLoadedMetadata: () => {
537
+ var s;
538
+ return g(((s = r.current) == null ? void 0 : s.duration) ?? 0);
539
+ },
540
+ onEnded: () => b(!1),
541
+ onError: () => {
542
+ w(!0), t == null || t("Audio failed to load");
543
+ }
544
+ }
545
+ ),
546
+ /* @__PURE__ */ d(
547
+ "div",
548
+ {
549
+ className: "relative h-1 w-full cursor-pointer bg-surface-sunken group/bar",
550
+ onClick: M,
551
+ onMouseMove: A,
552
+ onMouseLeave: () => u(null),
553
+ role: "slider",
554
+ "aria-label": "Audio progress",
555
+ "aria-valuenow": Math.round(p),
556
+ "aria-valuemin": 0,
557
+ "aria-valuemax": 100,
558
+ tabIndex: 0,
559
+ children: [
560
+ /* @__PURE__ */ e(
561
+ "div",
562
+ {
563
+ className: "absolute left-0 top-0 h-full bg-accent-9 transition-[width] duration-75",
564
+ style: { width: `${p}%` }
565
+ }
566
+ ),
567
+ T !== null && /* @__PURE__ */ e(
568
+ "div",
569
+ {
570
+ className: "absolute -top-7 -translate-x-1/2 rounded-ds-sm bg-surface-overlay px-1.5 py-0.5 text-[10px] font-mono text-surface-fg shadow-floating pointer-events-none",
571
+ style: { left: `${T / (x || 1) * 100}%` },
572
+ children: j(T)
573
+ }
574
+ ),
575
+ /* @__PURE__ */ e(
576
+ "div",
577
+ {
578
+ className: "absolute top-1/2 -translate-y-1/2 h-2.5 w-2.5 rounded-full bg-accent-9 shadow-raised opacity-0 group-hover/bar:opacity-100 transition-opacity",
579
+ style: { left: `${p}%`, marginLeft: "-5px" }
580
+ }
581
+ )
582
+ ]
583
+ }
584
+ ),
585
+ /* @__PURE__ */ d("div", { className: "flex items-center gap-ds-04 px-ds-05 py-ds-04", children: [
586
+ /* @__PURE__ */ e(
587
+ L,
588
+ {
589
+ variant: "solid",
590
+ size: "icon-sm",
591
+ onClick: i,
592
+ "aria-label": h ? "Pause" : "Play",
593
+ className: "shrink-0",
594
+ children: h ? /* @__PURE__ */ e(_, { className: "h-ico-sm w-ico-sm" }) : /* @__PURE__ */ e(K, { className: "h-ico-sm w-ico-sm ml-0.5" })
595
+ }
596
+ ),
597
+ /* @__PURE__ */ d("div", { className: "flex-1 min-w-0", children: [
598
+ o && /* @__PURE__ */ e("p", { className: "text-ds-sm font-semibold text-surface-fg truncate", children: o }),
599
+ /* @__PURE__ */ d("p", { className: "text-ds-xs font-mono text-surface-fg-muted tabular-nums", children: [
600
+ j(y),
601
+ " / ",
602
+ j(x)
603
+ ] })
604
+ ] }),
605
+ /* @__PURE__ */ e(
606
+ X,
607
+ {
608
+ volume: f,
609
+ muted: D,
610
+ onVolumeChange: (s) => {
611
+ I(s), r.current && (r.current.volume = s), s > 0 && D && (P(!1), r.current && (r.current.muted = !1));
612
+ },
613
+ onMuteToggle: S,
614
+ variant: "light"
615
+ }
616
+ )
617
+ ] })
618
+ ] });
619
+ }
620
+ function he({ url: n, onError: o }) {
621
+ const [t, r] = a.useState(!1), [m, h] = a.useState(!1), b = le(n);
622
+ return a.useEffect(() => {
623
+ const p = setTimeout(() => {
624
+ t || (h(!0), o == null || o("Embed timed out"));
625
+ }, 15e3);
626
+ return () => clearTimeout(p);
627
+ }, [t, o]), m ? /* @__PURE__ */ e($, { message: "Could not load embed", url: n }) : /* @__PURE__ */ d("div", { className: "relative w-full rounded-ds-md overflow-hidden", style: { aspectRatio: "16 / 9" }, children: [
628
+ !t && /* @__PURE__ */ e(V, { className: "absolute inset-0" }),
629
+ /* @__PURE__ */ e(
630
+ E.iframe,
631
+ {
632
+ src: b,
633
+ title: "Embedded content",
634
+ onLoad: () => r(!0),
635
+ onError: () => {
636
+ h(!0), o == null || o("Embed failed to load");
637
+ },
638
+ initial: { opacity: 0 },
639
+ animate: { opacity: t ? 1 : 0 },
640
+ transition: B.fade,
641
+ className: "absolute inset-0 h-full w-full border-none",
642
+ allowFullScreen: !0
643
+ }
644
+ )
645
+ ] });
646
+ }
647
+ function Ne({
648
+ url: n,
649
+ type: o,
650
+ mimeType: t,
651
+ alt: r,
652
+ initialPage: m = 1,
653
+ fileName: h,
654
+ fileSize: b,
655
+ onError: p,
656
+ className: v,
657
+ ...x
658
+ }) {
659
+ const g = o ?? ce(n, t), y = /* @__PURE__ */ e(V, { className: "h-64 w-full rounded-ds-md" });
660
+ return /* @__PURE__ */ d("div", { className: R("flex flex-col gap-ds-03", v), ...x, children: [
661
+ (h || b) && /* @__PURE__ */ d("div", { className: "flex items-center gap-ds-03", children: [
662
+ h && /* @__PURE__ */ e("span", { className: "text-ds-sm font-semibold text-surface-fg truncate", children: h }),
663
+ b && /* @__PURE__ */ e(J, { variant: "subtle", size: "xs", children: b })
664
+ ] }),
665
+ g === "image" && /* @__PURE__ */ e(a.Suspense, { fallback: y, children: /* @__PURE__ */ e(ue, { url: n, alt: r, onError: p }) }),
666
+ g === "pdf" && /* @__PURE__ */ e(a.Suspense, { fallback: y, children: /* @__PURE__ */ e(de, { url: n, initialPage: m, onError: p }) }),
667
+ g === "video" && /* @__PURE__ */ e(fe, { url: n, onError: p }),
668
+ g === "audio" && /* @__PURE__ */ e(me, { url: n, fileName: h, onError: p }),
669
+ g === "embed" && /* @__PURE__ */ e(he, { url: n, onError: p }),
670
+ g !== "audio" && /* @__PURE__ */ e("div", { className: "flex justify-end", children: /* @__PURE__ */ e(L, { variant: "ghost", size: "xs", startIcon: /* @__PURE__ */ e(W, { className: "h-3.5 w-3.5" }), asChild: !0, children: /* @__PURE__ */ e("a", { href: n, download: !0, target: "_blank", rel: "noopener noreferrer", children: "Download" }) }) })
671
+ ] });
672
+ }
673
+ export {
674
+ Ne as FilePreview
675
+ };