@devalok/shilp-sutra 0.30.0 → 0.32.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 (266) hide show
  1. package/README.md +82 -239
  2. package/dist/_chunks/badge-group.js +123 -171
  3. package/dist/_chunks/document-preview.js +92 -0
  4. package/dist/_chunks/file-preview.js +511 -0
  5. package/dist/_chunks/image-preview.js +90 -0
  6. package/dist/_chunks/primitives.js +109 -109
  7. package/dist/_chunks/stat-row.js +144 -124
  8. package/dist/_chunks/use-calendar.js +558 -490
  9. package/dist/ai/block-renderer.d.ts +2 -1
  10. package/dist/ai/block-renderer.d.ts.map +1 -1
  11. package/dist/ai/block-renderer.js +30 -29
  12. package/dist/ai/blocks/block-table.d.ts.map +1 -1
  13. package/dist/ai/blocks/confirm.d.ts.map +1 -1
  14. package/dist/ai/blocks/divider.d.ts.map +1 -1
  15. package/dist/ai/blocks/error.d.ts.map +1 -1
  16. package/dist/ai/blocks/info.d.ts.map +1 -1
  17. package/dist/ai/blocks/loading.d.ts.map +1 -1
  18. package/dist/ai/blocks/stat-row.d.ts.map +1 -1
  19. package/dist/ai/blocks/success.d.ts.map +1 -1
  20. package/dist/ai/blocks/text.d.ts.map +1 -1
  21. package/dist/ai/command-bar.d.ts +18 -0
  22. package/dist/ai/command-bar.d.ts.map +1 -1
  23. package/dist/ai/command-bar.js +126 -125
  24. package/dist/ai/conversation.d.ts +13 -1
  25. package/dist/ai/conversation.d.ts.map +1 -1
  26. package/dist/ai/conversation.js +78 -78
  27. package/dist/ai/types.d.ts +0 -1
  28. package/dist/ai/types.d.ts.map +1 -1
  29. package/dist/ai/types.js +1 -0
  30. package/dist/composed/bulk-action-bar.d.ts +6 -4
  31. package/dist/composed/bulk-action-bar.d.ts.map +1 -1
  32. package/dist/composed/bulk-action-bar.js +102 -58
  33. package/dist/composed/command-palette.d.ts +9 -0
  34. package/dist/composed/command-palette.d.ts.map +1 -1
  35. package/dist/composed/command-palette.js +68 -68
  36. package/dist/composed/confirm-dialog.d.ts +1 -1
  37. package/dist/composed/confirm-dialog.d.ts.map +1 -1
  38. package/dist/composed/confirm-dialog.js +10 -10
  39. package/dist/composed/content-card.d.ts.map +1 -1
  40. package/dist/composed/date-picker/date-picker.d.ts +11 -1
  41. package/dist/composed/date-picker/date-picker.d.ts.map +1 -1
  42. package/dist/composed/date-picker/month-picker.d.ts.map +1 -1
  43. package/dist/composed/date-picker/year-picker.d.ts.map +1 -1
  44. package/dist/composed/deadline-indicator.d.ts +1 -1
  45. package/dist/composed/deadline-indicator.d.ts.map +1 -1
  46. package/dist/composed/deadline-indicator.js +39 -36
  47. package/dist/composed/emoji-picker.d.ts +6 -0
  48. package/dist/composed/emoji-picker.d.ts.map +1 -1
  49. package/dist/composed/emoji-picker.js +22 -20
  50. package/dist/composed/error-boundary.d.ts +21 -1
  51. package/dist/composed/error-boundary.d.ts.map +1 -1
  52. package/dist/composed/error-boundary.js +47 -32
  53. package/dist/composed/file-preview/audio-preview.d.ts +7 -0
  54. package/dist/composed/file-preview/audio-preview.d.ts.map +1 -0
  55. package/dist/composed/file-preview/document-preview.d.ts +7 -0
  56. package/dist/composed/file-preview/document-preview.d.ts.map +1 -0
  57. package/dist/composed/file-preview/embed-preview.d.ts +7 -0
  58. package/dist/composed/file-preview/embed-preview.d.ts.map +1 -0
  59. package/dist/composed/file-preview/image-preview.d.ts +7 -0
  60. package/dist/composed/file-preview/image-preview.d.ts.map +1 -0
  61. package/dist/composed/file-preview/shared.d.ts +20 -0
  62. package/dist/composed/file-preview/shared.d.ts.map +1 -0
  63. package/dist/composed/file-preview/video-preview.d.ts +6 -0
  64. package/dist/composed/file-preview/video-preview.d.ts.map +1 -0
  65. package/dist/composed/file-preview.d.ts.map +1 -1
  66. package/dist/composed/file-preview.js +10 -662
  67. package/dist/composed/filter-bar.d.ts +10 -2
  68. package/dist/composed/filter-bar.d.ts.map +1 -1
  69. package/dist/composed/filter-bar.js +42 -43
  70. package/dist/composed/form-section.d.ts +1 -1
  71. package/dist/composed/form-section.d.ts.map +1 -1
  72. package/dist/composed/form-section.js +22 -21
  73. package/dist/composed/index.d.ts +2 -2
  74. package/dist/composed/index.d.ts.map +1 -1
  75. package/dist/composed/index.js +58 -57
  76. package/dist/composed/inline-edit.d.ts +1 -1
  77. package/dist/composed/inline-edit.d.ts.map +1 -1
  78. package/dist/composed/inline-edit.js +33 -32
  79. package/dist/composed/lib/string-utils.d.ts.map +1 -1
  80. package/dist/composed/loading-skeleton.d.ts.map +1 -1
  81. package/dist/composed/markdown-viewer.d.ts +1 -1
  82. package/dist/composed/markdown-viewer.d.ts.map +1 -1
  83. package/dist/composed/markdown-viewer.js +60 -59
  84. package/dist/composed/master-detail.d.ts +11 -7
  85. package/dist/composed/master-detail.d.ts.map +1 -1
  86. package/dist/composed/master-detail.js +123 -84
  87. package/dist/composed/page-header.d.ts.map +1 -1
  88. package/dist/composed/page-skeletons.d.ts.map +1 -1
  89. package/dist/composed/priority-indicator.d.ts +1 -0
  90. package/dist/composed/priority-indicator.js +1 -0
  91. package/dist/composed/responsive-overlay.d.ts +8 -0
  92. package/dist/composed/responsive-overlay.d.ts.map +1 -1
  93. package/dist/composed/rich-text-editor.d.ts +11 -3
  94. package/dist/composed/rich-text-editor.d.ts.map +1 -1
  95. package/dist/composed/rich-text-editor.js +21 -20
  96. package/dist/composed/schedule-view.d.ts +9 -1
  97. package/dist/composed/schedule-view.d.ts.map +1 -1
  98. package/dist/hooks/index.d.ts +2 -0
  99. package/dist/hooks/index.d.ts.map +1 -1
  100. package/dist/hooks/index.js +8 -4
  101. package/dist/hooks/use-touch-device.d.ts +12 -0
  102. package/dist/hooks/use-touch-device.d.ts.map +1 -0
  103. package/dist/hooks/use-touch-device.js +13 -0
  104. package/dist/hooks/use-viewport-height.d.ts +11 -0
  105. package/dist/hooks/use-viewport-height.d.ts.map +1 -0
  106. package/dist/hooks/use-viewport-height.js +16 -0
  107. package/dist/shell/bottom-navbar.d.ts.map +1 -1
  108. package/dist/shell/bottom-navbar.js +72 -63
  109. package/dist/shell/command-registry.d.ts.map +1 -1
  110. package/dist/shell/notification-center.d.ts.map +1 -1
  111. package/dist/shell/notification-center.js +77 -77
  112. package/dist/shell/top-bar.d.ts +2 -2
  113. package/dist/shell/top-bar.d.ts.map +1 -1
  114. package/dist/shell/top-bar.js +61 -60
  115. package/dist/tailwind/index.cjs +51 -7
  116. package/dist/tailwind/preset.d.ts.map +1 -1
  117. package/dist/tailwind/preset.js +51 -7
  118. package/dist/tokens/primitives.css +3 -1
  119. package/dist/tokens/semantic.css +16 -13
  120. package/dist/tokens/typography.css +33 -4
  121. package/dist/ui/alert.d.ts +1 -0
  122. package/dist/ui/alert.d.ts.map +1 -1
  123. package/dist/ui/alert.js +42 -37
  124. package/dist/ui/autocomplete.d.ts.map +1 -1
  125. package/dist/ui/autocomplete.js +38 -39
  126. package/dist/ui/badge.d.ts +110 -2
  127. package/dist/ui/badge.d.ts.map +1 -1
  128. package/dist/ui/banner.d.ts.map +1 -1
  129. package/dist/ui/banner.js +8 -7
  130. package/dist/ui/button.d.ts +2 -2
  131. package/dist/ui/button.d.ts.map +1 -1
  132. package/dist/ui/button.js +54 -74
  133. package/dist/ui/card.d.ts +5 -1
  134. package/dist/ui/card.d.ts.map +1 -1
  135. package/dist/ui/card.js +111 -79
  136. package/dist/ui/charts/area-chart.d.ts +2 -0
  137. package/dist/ui/charts/area-chart.d.ts.map +1 -1
  138. package/dist/ui/charts/bar-chart.d.ts +2 -0
  139. package/dist/ui/charts/bar-chart.d.ts.map +1 -1
  140. package/dist/ui/charts/chart-container.d.ts +2 -0
  141. package/dist/ui/charts/chart-container.d.ts.map +1 -1
  142. package/dist/ui/charts/index.js +583 -577
  143. package/dist/ui/charts/line-chart.d.ts +2 -0
  144. package/dist/ui/charts/line-chart.d.ts.map +1 -1
  145. package/dist/ui/charts/pie-chart.d.ts +2 -0
  146. package/dist/ui/charts/pie-chart.d.ts.map +1 -1
  147. package/dist/ui/charts/radar-chart.d.ts +2 -0
  148. package/dist/ui/charts/radar-chart.d.ts.map +1 -1
  149. package/dist/ui/checkbox.d.ts +2 -0
  150. package/dist/ui/checkbox.d.ts.map +1 -1
  151. package/dist/ui/checkbox.js +36 -27
  152. package/dist/ui/code.d.ts.map +1 -1
  153. package/dist/ui/color-input.js +5 -5
  154. package/dist/ui/combobox.d.ts +6 -1
  155. package/dist/ui/combobox.d.ts.map +1 -1
  156. package/dist/ui/combobox.js +1 -1
  157. package/dist/ui/container.d.ts.map +1 -1
  158. package/dist/ui/context-menu.js +1 -1
  159. package/dist/ui/data-table-body.d.ts +12 -0
  160. package/dist/ui/data-table-body.d.ts.map +1 -0
  161. package/dist/ui/data-table-body.js +219 -0
  162. package/dist/ui/data-table-bulk-actions.d.ts +19 -0
  163. package/dist/ui/data-table-bulk-actions.d.ts.map +1 -0
  164. package/dist/ui/data-table-bulk-actions.js +61 -0
  165. package/dist/ui/data-table-card.d.ts +9 -0
  166. package/dist/ui/data-table-card.d.ts.map +1 -0
  167. package/dist/ui/data-table-card.js +73 -0
  168. package/dist/ui/data-table-context.d.ts +62 -0
  169. package/dist/ui/data-table-context.d.ts.map +1 -0
  170. package/dist/ui/data-table-context.js +48 -0
  171. package/dist/ui/data-table-header.d.ts +10 -0
  172. package/dist/ui/data-table-header.d.ts.map +1 -0
  173. package/dist/ui/data-table-header.js +141 -0
  174. package/dist/ui/data-table-pagination.d.ts +13 -0
  175. package/dist/ui/data-table-pagination.d.ts.map +1 -0
  176. package/dist/ui/data-table-pagination.js +84 -0
  177. package/dist/ui/data-table.d.ts +11 -9
  178. package/dist/ui/data-table.d.ts.map +1 -1
  179. package/dist/ui/data-table.js +258 -573
  180. package/dist/ui/dialog.d.ts +6 -2
  181. package/dist/ui/dialog.d.ts.map +1 -1
  182. package/dist/ui/dialog.js +84 -82
  183. package/dist/ui/dropdown-menu.js +1 -1
  184. package/dist/ui/hover-card.d.ts +7 -0
  185. package/dist/ui/hover-card.d.ts.map +1 -1
  186. package/dist/ui/hover-card.js +3 -3
  187. package/dist/ui/icon-group.d.ts +2 -4
  188. package/dist/ui/icon-group.d.ts.map +1 -1
  189. package/dist/ui/icon-group.js +22 -23
  190. package/dist/ui/index.d.ts +1 -2
  191. package/dist/ui/index.d.ts.map +1 -1
  192. package/dist/ui/index.js +94 -99
  193. package/dist/ui/label.js +1 -1
  194. package/dist/ui/lib/bottom-sheet.d.ts +16 -0
  195. package/dist/ui/lib/bottom-sheet.d.ts.map +1 -0
  196. package/dist/ui/lib/date-utils.d.ts.map +1 -1
  197. package/dist/ui/lib/motion.d.ts.map +1 -1
  198. package/dist/ui/lib/utils.d.ts.map +1 -1
  199. package/dist/ui/menubar.d.ts.map +1 -1
  200. package/dist/ui/menubar.js +64 -73
  201. package/dist/ui/navigation-menu.d.ts.map +1 -1
  202. package/dist/ui/navigation-menu.js +40 -44
  203. package/dist/ui/number-input.d.ts.map +1 -1
  204. package/dist/ui/number-input.js +19 -17
  205. package/dist/ui/popover.d.ts.map +1 -1
  206. package/dist/ui/popover.js +107 -32
  207. package/dist/ui/progress-ring.d.ts.map +1 -1
  208. package/dist/ui/progress-ring.js +80 -80
  209. package/dist/ui/progress.js +4 -4
  210. package/dist/ui/radio.d.ts +5 -2
  211. package/dist/ui/radio.d.ts.map +1 -1
  212. package/dist/ui/radio.js +29 -20
  213. package/dist/ui/search-input.d.ts.map +1 -1
  214. package/dist/ui/search-input.js +13 -12
  215. package/dist/ui/segmented-control.d.ts +6 -108
  216. package/dist/ui/segmented-control.d.ts.map +1 -1
  217. package/dist/ui/segmented-control.js +86 -272
  218. package/dist/ui/select.d.ts +3 -1
  219. package/dist/ui/select.d.ts.map +1 -1
  220. package/dist/ui/select.js +83 -71
  221. package/dist/ui/separator.js +5 -5
  222. package/dist/ui/sheet.d.ts +2 -0
  223. package/dist/ui/sheet.d.ts.map +1 -1
  224. package/dist/ui/sheet.js +102 -84
  225. package/dist/ui/sidebar.d.ts.map +1 -1
  226. package/dist/ui/sidebar.js +200 -175
  227. package/dist/ui/skeleton.d.ts.map +1 -1
  228. package/dist/ui/slider.js +14 -14
  229. package/dist/ui/stack.d.ts.map +1 -1
  230. package/dist/ui/status-dot.js +8 -8
  231. package/dist/ui/stepper.d.ts.map +1 -1
  232. package/dist/ui/stepper.js +33 -31
  233. package/dist/ui/switch.js +3 -3
  234. package/dist/ui/table.d.ts.map +1 -1
  235. package/dist/ui/tabs.d.ts +7 -0
  236. package/dist/ui/tabs.d.ts.map +1 -1
  237. package/dist/ui/tabs.js +102 -76
  238. package/dist/ui/text.d.ts.map +1 -1
  239. package/dist/ui/toast-types.d.ts +0 -1
  240. package/dist/ui/toast-types.d.ts.map +1 -1
  241. package/dist/ui/toast-types.js +0 -1
  242. package/dist/ui/toast.d.ts.map +1 -1
  243. package/dist/ui/toast.js +156 -150
  244. package/dist/ui/toggle-group.js +1 -1
  245. package/dist/ui/toggle.js +1 -1
  246. package/dist/ui/tooltip.js +3 -3
  247. package/dist/ui/visually-hidden.d.ts.map +1 -1
  248. package/docs/components/ui/alert.md +3 -0
  249. package/docs/components/ui/badge.md +3 -0
  250. package/docs/components/ui/card.md +4 -0
  251. package/docs/components/ui/data-table-body.md +13 -0
  252. package/docs/components/ui/data-table-bulk-actions.md +13 -0
  253. package/docs/components/ui/data-table-card.md +13 -0
  254. package/docs/components/ui/data-table-context.md +13 -0
  255. package/docs/components/ui/data-table-header.md +13 -0
  256. package/docs/components/ui/data-table-pagination.md +13 -0
  257. package/docs/components/ui/select.md +4 -0
  258. package/docs/components/ui/tabs.md +4 -0
  259. package/llms-full.txt +97 -48
  260. package/llms.txt +46 -1
  261. package/package.json +37 -7
  262. package/dist/ui/chip.d.ts +0 -19
  263. package/dist/ui/chip.d.ts.map +0 -1
  264. package/dist/ui/chip.js +0 -14
  265. package/dist/ui/lib/use-ripple.d.ts +0 -14
  266. package/dist/ui/lib/use-ripple.d.ts.map +0 -1
@@ -0,0 +1,511 @@
1
+ "use client";
2
+ import { jsxs as u, jsx as e } from "react/jsx-runtime";
3
+ import * as a from "react";
4
+ import { cn as D } from "../ui/lib/utils.js";
5
+ import { Skeleton as X } from "../ui/skeleton.js";
6
+ import { Button as V } from "../ui/button.js";
7
+ import { Icon as x } from "../ui/icon.js";
8
+ import { B as q } from "./badge-group.js";
9
+ import { IconAlertTriangle as H, IconDownload as _, IconVolumeOff as O, IconVolume as Y, IconPlayerPlay as F, IconPlayerPause as K, IconMaximize as G } from "@tabler/icons-react";
10
+ import { tweens as j, springs as J } from "../ui/lib/motion.js";
11
+ import { m as $, A as Q } from "./framer.js";
12
+ function U({ message: t, url: o }) {
13
+ return /* @__PURE__ */ u("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: [
14
+ /* @__PURE__ */ e(x, { icon: H, size: "2xl", className: "text-warning-9" }),
15
+ /* @__PURE__ */ u("div", { children: [
16
+ /* @__PURE__ */ e("p", { className: "text-ds-md font-semibold text-surface-fg", children: "Preview unavailable" }),
17
+ /* @__PURE__ */ e("p", { className: "text-ds-sm text-surface-fg-muted mt-ds-01", children: t })
18
+ ] }),
19
+ /* @__PURE__ */ e(V, { variant: "outline", size: "xs", startIcon: /* @__PURE__ */ e(x, { icon: _ }), asChild: !0, children: /* @__PURE__ */ e("a", { href: o, download: !0, target: "_blank", rel: "noopener noreferrer", children: "Download file" }) })
20
+ ] });
21
+ }
22
+ function pe({ children: t, className: o }) {
23
+ return /* @__PURE__ */ e(
24
+ $.div,
25
+ {
26
+ initial: { opacity: 0, y: 8 },
27
+ animate: { opacity: 1, y: 0 },
28
+ transition: j.fade,
29
+ className: D(
30
+ "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",
31
+ o
32
+ ),
33
+ children: t
34
+ }
35
+ );
36
+ }
37
+ function ge() {
38
+ return /* @__PURE__ */ e("div", { className: "mx-ds-01 h-4 w-px bg-surface-border-subtle" });
39
+ }
40
+ function W({
41
+ volume: t,
42
+ muted: o,
43
+ onVolumeChange: r,
44
+ onMuteToggle: n,
45
+ variant: d = "light"
46
+ }) {
47
+ const l = a.useRef(null), [f, m] = a.useState(!1), v = o ? 0 : t;
48
+ function g(p) {
49
+ if (!l.current) return t;
50
+ const M = l.current.getBoundingClientRect();
51
+ return Math.max(0, Math.min(1, (p.clientX - M.left) / M.width));
52
+ }
53
+ function b(p) {
54
+ p.preventDefault(), m(!0);
55
+ const M = g(p);
56
+ r(M), p.target.setPointerCapture(p.pointerId);
57
+ }
58
+ function N(p) {
59
+ f && r(g(p));
60
+ }
61
+ function y() {
62
+ m(!1);
63
+ }
64
+ const k = d === "dark", R = k ? "bg-white/30" : "bg-surface-sunken", T = k ? "bg-white" : "bg-accent-9", P = k ? "bg-white" : "bg-accent-9";
65
+ return /* @__PURE__ */ u("div", { className: "group/vol flex items-center gap-ds-02 shrink-0", children: [
66
+ /* @__PURE__ */ e("button", { onClick: n, className: D("transition-colors", k ? "text-white hover:text-white/80" : "text-surface-fg-muted hover:text-surface-fg"), "aria-label": o ? "Unmute (M)" : "Mute (M)", title: o ? "Unmute" : "Mute", children: o || t === 0 ? /* @__PURE__ */ e(x, { icon: O, size: "sm" }) : /* @__PURE__ */ e(x, { icon: Y, size: "sm" }) }),
67
+ /* @__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__ */ u(
68
+ "div",
69
+ {
70
+ ref: l,
71
+ className: D("relative w-full h-1 rounded-full cursor-pointer", R),
72
+ onPointerDown: b,
73
+ onPointerMove: N,
74
+ onPointerUp: y,
75
+ role: "slider",
76
+ "aria-label": "Volume",
77
+ "aria-valuenow": Math.round(v * 100),
78
+ "aria-valuemin": 0,
79
+ "aria-valuemax": 100,
80
+ tabIndex: 0,
81
+ children: [
82
+ /* @__PURE__ */ e(
83
+ "div",
84
+ {
85
+ className: D("absolute left-0 top-0 h-full rounded-full transition-[width] duration-75", T),
86
+ style: { width: `${v * 100}%` }
87
+ }
88
+ ),
89
+ /* @__PURE__ */ e(
90
+ "div",
91
+ {
92
+ className: D(
93
+ "absolute top-1/2 -translate-y-1/2 h-2.5 w-2.5 rounded-full shadow-raised transition-opacity",
94
+ P,
95
+ f ? "opacity-100 scale-110" : "opacity-0 group-hover/vol:opacity-100"
96
+ ),
97
+ style: { left: `${v * 100}%`, marginLeft: "-5px" }
98
+ }
99
+ )
100
+ ]
101
+ }
102
+ ) })
103
+ ] });
104
+ }
105
+ function L(t) {
106
+ if (!isFinite(t) || t < 0) return "0:00";
107
+ const o = Math.floor(t / 3600), r = Math.floor(t % 3600 / 60), n = Math.floor(t % 60);
108
+ return o > 0 ? `${o}:${r.toString().padStart(2, "0")}:${n.toString().padStart(2, "0")}` : `${r}:${n.toString().padStart(2, "0")}`;
109
+ }
110
+ const B = [0.5, 0.75, 1, 1.25, 1.5, 2];
111
+ function Z({ url: t, onError: o }) {
112
+ const r = a.useRef(null), n = a.useRef(null), [d, l] = a.useState(!1), [f, m] = a.useState(0), [v, g] = a.useState(0), [b, N] = a.useState(0), [y, k] = a.useState(!1), [R, T] = a.useState(!1), [P, C] = a.useState(!0), [p, M] = a.useState(1), S = a.useRef(void 0);
113
+ a.useEffect(() => () => clearTimeout(S.current), []), a.useEffect(() => {
114
+ function c(s) {
115
+ const h = n.current;
116
+ if (!h || !h.contains(document.activeElement) && document.activeElement !== h) return;
117
+ const i = r.current;
118
+ if (i)
119
+ switch (s.key) {
120
+ case " ":
121
+ case "k":
122
+ s.preventDefault(), l((w) => (w ? i.pause() : i.play(), !w));
123
+ break;
124
+ case "ArrowRight":
125
+ s.preventDefault(), i.currentTime = Math.min(i.duration, i.currentTime + 5);
126
+ break;
127
+ case "ArrowLeft":
128
+ s.preventDefault(), i.currentTime = Math.max(0, i.currentTime - 5);
129
+ break;
130
+ case "j":
131
+ s.preventDefault(), i.currentTime = Math.max(0, i.currentTime - 10);
132
+ break;
133
+ case "l":
134
+ s.preventDefault(), i.currentTime = Math.min(i.duration, i.currentTime + 10);
135
+ break;
136
+ case "m":
137
+ s.preventDefault(), k((w) => (i.muted = !w, !w));
138
+ break;
139
+ case "f":
140
+ s.preventDefault(), i.requestFullscreen?.();
141
+ break;
142
+ case ">":
143
+ s.preventDefault(), E(1);
144
+ break;
145
+ case "<":
146
+ s.preventDefault(), E(-1);
147
+ break;
148
+ }
149
+ }
150
+ return document.addEventListener("keydown", c), () => document.removeEventListener("keydown", c);
151
+ }, []);
152
+ function E(c) {
153
+ const s = B.indexOf(p), h = Math.max(0, Math.min(B.length - 1, s + c)), i = B[h];
154
+ M(i), r.current && (r.current.playbackRate = i);
155
+ }
156
+ function I() {
157
+ r.current && (d ? r.current.pause() : r.current.play(), l(!d));
158
+ }
159
+ function z(c) {
160
+ if (!r.current || !v) return;
161
+ const s = c.currentTarget.getBoundingClientRect(), h = (c.clientX - s.left) / s.width;
162
+ r.current.currentTime = h * v;
163
+ }
164
+ function A() {
165
+ C(!0), clearTimeout(S.current), d && (S.current = setTimeout(() => C(!1), 3e3));
166
+ }
167
+ return R ? /* @__PURE__ */ e(U, { message: "Could not load video", url: t }) : /* @__PURE__ */ u(
168
+ "div",
169
+ {
170
+ ref: n,
171
+ className: "group relative rounded-ds-md bg-black overflow-hidden",
172
+ onMouseMove: A,
173
+ onMouseLeave: () => d && C(!1),
174
+ tabIndex: -1,
175
+ children: [
176
+ /* @__PURE__ */ e(
177
+ "video",
178
+ {
179
+ ref: r,
180
+ src: t,
181
+ className: "max-h-[70vh] w-full",
182
+ onClick: I,
183
+ muted: y,
184
+ onTimeUpdate: () => {
185
+ r.current && (N(r.current.currentTime), r.current.duration && m(r.current.currentTime / r.current.duration * 100));
186
+ },
187
+ onLoadedMetadata: () => g(r.current?.duration ?? 0),
188
+ onEnded: () => {
189
+ l(!1), C(!0);
190
+ },
191
+ onError: () => {
192
+ T(!0), o?.("Video failed to load");
193
+ },
194
+ playsInline: !0
195
+ }
196
+ ),
197
+ !d && /* @__PURE__ */ e(
198
+ $.button,
199
+ {
200
+ initial: { opacity: 0, scale: 0.8 },
201
+ animate: { opacity: 1, scale: 1 },
202
+ transition: J.snappy,
203
+ onClick: I,
204
+ className: "absolute inset-0 flex items-center justify-center bg-black/30",
205
+ "aria-label": "Play video",
206
+ children: /* @__PURE__ */ e("div", { className: "flex h-14 w-14 items-center justify-center rounded-full bg-white/90 shadow-floating", children: /* @__PURE__ */ e(x, { icon: F, size: "xl", className: "text-surface-fg ml-0.5" }) })
207
+ }
208
+ ),
209
+ /* @__PURE__ */ e(Q, { children: P && v > 0 && /* @__PURE__ */ u(
210
+ $.div,
211
+ {
212
+ initial: { opacity: 0, y: 10 },
213
+ animate: { opacity: 1, y: 0 },
214
+ exit: { opacity: 0, y: 10 },
215
+ transition: j.fade,
216
+ 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",
217
+ children: [
218
+ /* @__PURE__ */ u(
219
+ "div",
220
+ {
221
+ className: "relative h-1 w-full cursor-pointer rounded-full bg-white/30 mb-ds-03 group/progress",
222
+ onClick: z,
223
+ role: "slider",
224
+ "aria-label": "Video progress",
225
+ "aria-valuenow": Math.round(f),
226
+ "aria-valuemin": 0,
227
+ "aria-valuemax": 100,
228
+ tabIndex: 0,
229
+ children: [
230
+ /* @__PURE__ */ e(
231
+ "div",
232
+ {
233
+ className: "absolute left-0 top-0 h-full rounded-full bg-white transition-[width] duration-75",
234
+ style: { width: `${f}%` }
235
+ }
236
+ ),
237
+ /* @__PURE__ */ e(
238
+ "div",
239
+ {
240
+ 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",
241
+ style: { left: `${f}%`, marginLeft: "-6px" }
242
+ }
243
+ )
244
+ ]
245
+ }
246
+ ),
247
+ /* @__PURE__ */ u("div", { className: "flex items-center gap-ds-03", children: [
248
+ /* @__PURE__ */ e("button", { onClick: I, className: "text-white hover:text-white/80", "aria-label": d ? "Pause" : "Play", title: d ? "Pause" : "Play", children: d ? /* @__PURE__ */ e(x, { icon: K, size: "lg" }) : /* @__PURE__ */ e(x, { icon: F, size: "lg" }) }),
249
+ /* @__PURE__ */ e(
250
+ W,
251
+ {
252
+ volume: y ? 0 : 1,
253
+ muted: y,
254
+ onVolumeChange: (c) => {
255
+ r.current && (r.current.volume = c), c > 0 && y && (k(!1), r.current && (r.current.muted = !1));
256
+ },
257
+ onMuteToggle: () => {
258
+ k(!y), r.current && (r.current.muted = !y);
259
+ },
260
+ variant: "dark"
261
+ }
262
+ ),
263
+ /* @__PURE__ */ u("span", { className: "text-[11px] font-mono text-white/70 tabular-nums", children: [
264
+ L(b),
265
+ " / ",
266
+ L(v)
267
+ ] }),
268
+ /* @__PURE__ */ e("div", { className: "flex-1" }),
269
+ /* @__PURE__ */ u(
270
+ "button",
271
+ {
272
+ onClick: () => E(1),
273
+ className: "text-[11px] font-mono text-white/70 hover:text-white px-1 rounded-ds-sm hover:bg-white/10 transition-colors",
274
+ "aria-label": `Playback speed: ${p}x`,
275
+ children: [
276
+ p,
277
+ "x"
278
+ ]
279
+ }
280
+ ),
281
+ /* @__PURE__ */ e(
282
+ "button",
283
+ {
284
+ onClick: () => r.current?.requestFullscreen?.(),
285
+ className: "text-white hover:text-white/80",
286
+ "aria-label": "Fullscreen (F)",
287
+ title: "Fullscreen",
288
+ children: /* @__PURE__ */ e(x, { icon: G, size: "sm" })
289
+ }
290
+ )
291
+ ] })
292
+ ]
293
+ }
294
+ ) })
295
+ ]
296
+ }
297
+ );
298
+ }
299
+ function ee({ url: t, fileName: o, onError: r }) {
300
+ const n = a.useRef(null), d = a.useRef(null), [l, f] = a.useState(!1), [m, v] = a.useState(0), [g, b] = a.useState(0), [N, y] = a.useState(0), [k, R] = a.useState(1), [T, P] = a.useState(!1), [C, p] = a.useState(!1), [M, S] = a.useState(null);
301
+ a.useEffect(() => {
302
+ function c(s) {
303
+ const h = d.current;
304
+ if (!h || !h.contains(document.activeElement) && document.activeElement !== h) return;
305
+ const i = n.current;
306
+ if (i)
307
+ switch (s.key) {
308
+ case " ":
309
+ s.preventDefault(), f((w) => (w ? i.pause() : i.play(), !w));
310
+ break;
311
+ case "ArrowRight":
312
+ s.preventDefault(), i.currentTime = Math.min(i.duration || 0, i.currentTime + 5);
313
+ break;
314
+ case "ArrowLeft":
315
+ s.preventDefault(), i.currentTime = Math.max(0, i.currentTime - 5);
316
+ break;
317
+ case "m":
318
+ s.preventDefault(), P((w) => (i.muted = !w, !w));
319
+ break;
320
+ }
321
+ }
322
+ return document.addEventListener("keydown", c), () => document.removeEventListener("keydown", c);
323
+ }, []);
324
+ function E() {
325
+ n.current && (l ? n.current.pause() : n.current.play(), f(!l));
326
+ }
327
+ function I(c) {
328
+ if (!n.current || !g) return;
329
+ const s = c.currentTarget.getBoundingClientRect(), h = Math.max(0, Math.min(1, (c.clientX - s.left) / s.width));
330
+ n.current.currentTime = h * g;
331
+ }
332
+ function z(c) {
333
+ if (!g) return;
334
+ const s = c.currentTarget.getBoundingClientRect(), h = (c.clientX - s.left) / s.width;
335
+ S(h * g);
336
+ }
337
+ function A() {
338
+ if (!n.current) return;
339
+ const c = !T;
340
+ P(c), n.current.muted = c;
341
+ }
342
+ return C ? /* @__PURE__ */ e(U, { message: "Could not load audio", url: t }) : /* @__PURE__ */ u("div", { ref: d, className: "rounded-ds-lg border border-surface-border bg-surface-raised shadow-raised overflow-hidden", tabIndex: -1, children: [
343
+ /* @__PURE__ */ e(
344
+ "audio",
345
+ {
346
+ ref: n,
347
+ src: t,
348
+ onTimeUpdate: () => {
349
+ n.current && (y(n.current.currentTime), n.current.duration && v(n.current.currentTime / n.current.duration * 100));
350
+ },
351
+ onLoadedMetadata: () => b(n.current?.duration ?? 0),
352
+ onEnded: () => f(!1),
353
+ onError: () => {
354
+ p(!0), r?.("Audio failed to load");
355
+ }
356
+ }
357
+ ),
358
+ /* @__PURE__ */ u(
359
+ "div",
360
+ {
361
+ className: "relative h-1 w-full cursor-pointer bg-surface-sunken group/bar",
362
+ onClick: I,
363
+ onMouseMove: z,
364
+ onMouseLeave: () => S(null),
365
+ role: "slider",
366
+ "aria-label": "Audio progress",
367
+ "aria-valuenow": Math.round(m),
368
+ "aria-valuemin": 0,
369
+ "aria-valuemax": 100,
370
+ tabIndex: 0,
371
+ children: [
372
+ /* @__PURE__ */ e(
373
+ "div",
374
+ {
375
+ className: "absolute left-0 top-0 h-full bg-accent-9 transition-[width] duration-75",
376
+ style: { width: `${m}%` }
377
+ }
378
+ ),
379
+ M !== null && /* @__PURE__ */ e(
380
+ "div",
381
+ {
382
+ 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",
383
+ style: { left: `${M / (g || 1) * 100}%` },
384
+ children: L(M)
385
+ }
386
+ ),
387
+ /* @__PURE__ */ e(
388
+ "div",
389
+ {
390
+ 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",
391
+ style: { left: `${m}%`, marginLeft: "-5px" }
392
+ }
393
+ )
394
+ ]
395
+ }
396
+ ),
397
+ /* @__PURE__ */ u("div", { className: "flex items-center gap-ds-04 px-ds-05 py-ds-04", children: [
398
+ /* @__PURE__ */ e(
399
+ V,
400
+ {
401
+ variant: "solid",
402
+ size: "icon-sm",
403
+ onClick: E,
404
+ "aria-label": l ? "Pause" : "Play",
405
+ title: l ? "Pause" : "Play",
406
+ className: "shrink-0",
407
+ children: l ? /* @__PURE__ */ e(x, { icon: K, size: "sm" }) : /* @__PURE__ */ e(x, { icon: F, size: "sm", className: "ml-0.5" })
408
+ }
409
+ ),
410
+ /* @__PURE__ */ u("div", { className: "flex-1 min-w-0", children: [
411
+ o && /* @__PURE__ */ e("p", { className: "text-ds-sm font-semibold text-surface-fg truncate", children: o }),
412
+ /* @__PURE__ */ u("p", { className: "text-ds-xs font-mono text-surface-fg-muted tabular-nums", children: [
413
+ L(N),
414
+ " / ",
415
+ L(g)
416
+ ] })
417
+ ] }),
418
+ /* @__PURE__ */ e(
419
+ W,
420
+ {
421
+ volume: k,
422
+ muted: T,
423
+ onVolumeChange: (c) => {
424
+ R(c), n.current && (n.current.volume = c), c > 0 && T && (P(!1), n.current && (n.current.muted = !1));
425
+ },
426
+ onMuteToggle: A,
427
+ variant: "light"
428
+ }
429
+ )
430
+ ] })
431
+ ] });
432
+ }
433
+ function te({ url: t, embedUrl: o, onError: r }) {
434
+ const [n, d] = a.useState(!1), [l, f] = a.useState(!1);
435
+ return a.useEffect(() => {
436
+ const m = setTimeout(() => {
437
+ n || (f(!0), r?.("Embed timed out"));
438
+ }, 15e3);
439
+ return () => clearTimeout(m);
440
+ }, [n, r]), l ? /* @__PURE__ */ e(U, { message: "Could not load embed", url: t }) : /* @__PURE__ */ u("div", { className: "relative w-full rounded-ds-md overflow-hidden", style: { aspectRatio: "16 / 9" }, children: [
441
+ !n && /* @__PURE__ */ e(X, { className: "absolute inset-0" }),
442
+ /* @__PURE__ */ e(
443
+ $.iframe,
444
+ {
445
+ src: o,
446
+ title: "Embedded content",
447
+ onLoad: () => d(!0),
448
+ onError: () => {
449
+ f(!0), r?.("Embed failed to load");
450
+ },
451
+ initial: { opacity: 0 },
452
+ animate: { opacity: n ? 1 : 0 },
453
+ transition: j.fade,
454
+ className: "absolute inset-0 h-full w-full border-none",
455
+ allowFullScreen: !0
456
+ }
457
+ )
458
+ ] });
459
+ }
460
+ const re = a.lazy(() => import("./image-preview.js")), ne = a.lazy(() => import("./document-preview.js"));
461
+ function ae(t, o) {
462
+ if (o) {
463
+ if (o.startsWith("image/")) return "image";
464
+ if (o === "application/pdf") return "pdf";
465
+ if (o.startsWith("video/")) return "video";
466
+ if (o.startsWith("audio/")) return "audio";
467
+ }
468
+ const r = t.split("?")[0].split(".").pop()?.toLowerCase();
469
+ return ["jpg", "jpeg", "png", "gif", "webp", "svg", "avif", "bmp"].includes(r ?? "") ? "image" : r === "pdf" ? "pdf" : ["mp4", "webm", "ogg", "mov"].includes(r ?? "") ? "video" : ["mp3", "wav", "ogg", "aac", "flac"].includes(r ?? "") ? "audio" : t.includes("figma.com") || t.includes("loom.com") || t.includes("youtube.com") || t.includes("youtu.be") || t.includes("vimeo.com") ? "embed" : "image";
470
+ }
471
+ function oe(t) {
472
+ const o = t.match(/(?:youtube\.com\/watch\?v=|youtu\.be\/)([^&?]+)/);
473
+ if (o) return `https://www.youtube.com/embed/${o[1]}`;
474
+ const r = t.match(/vimeo\.com\/(\d+)/);
475
+ if (r) return `https://player.vimeo.com/video/${r[1]}`;
476
+ if (t.includes("figma.com")) return `https://www.figma.com/embed?embed_host=share&url=${encodeURIComponent(t)}`;
477
+ const n = t.match(/loom\.com\/share\/([^?]+)/);
478
+ return n ? `https://www.loom.com/embed/${n[1]}` : t;
479
+ }
480
+ function ve({
481
+ url: t,
482
+ type: o,
483
+ mimeType: r,
484
+ alt: n,
485
+ initialPage: d = 1,
486
+ fileName: l,
487
+ fileSize: f,
488
+ onError: m,
489
+ className: v,
490
+ ...g
491
+ }) {
492
+ const b = o ?? ae(t, r), N = /* @__PURE__ */ e(X, { className: "h-64 w-full rounded-ds-md" });
493
+ return /* @__PURE__ */ u("div", { className: D("flex flex-col gap-ds-03", v), ...g, children: [
494
+ (l || f) && /* @__PURE__ */ u("div", { className: "flex items-center gap-ds-03", children: [
495
+ l && /* @__PURE__ */ e("span", { className: "text-ds-sm font-semibold text-surface-fg truncate", children: l }),
496
+ f && /* @__PURE__ */ e(q, { variant: "subtle", size: "xs", children: f })
497
+ ] }),
498
+ b === "image" && /* @__PURE__ */ e(a.Suspense, { fallback: N, children: /* @__PURE__ */ e(re, { url: t, alt: n, onError: m }) }),
499
+ b === "pdf" && /* @__PURE__ */ e(a.Suspense, { fallback: N, children: /* @__PURE__ */ e(ne, { url: t, initialPage: d, onError: m }) }),
500
+ b === "video" && /* @__PURE__ */ e(Z, { url: t, onError: m }),
501
+ b === "audio" && /* @__PURE__ */ e(ee, { url: t, fileName: l, onError: m }),
502
+ b === "embed" && /* @__PURE__ */ e(te, { url: t, embedUrl: oe(t), onError: m }),
503
+ b !== "audio" && /* @__PURE__ */ e("div", { className: "flex justify-end", children: /* @__PURE__ */ e(V, { variant: "ghost", size: "xs", startIcon: /* @__PURE__ */ e(x, { icon: _ }), asChild: !0, children: /* @__PURE__ */ e("a", { href: t, download: !0, target: "_blank", rel: "noopener noreferrer", children: "Download" }) }) })
504
+ ] });
505
+ }
506
+ export {
507
+ U as E,
508
+ ve as F,
509
+ pe as T,
510
+ ge as a
511
+ };
@@ -0,0 +1,90 @@
1
+ "use client";
2
+ import { jsx as t, jsxs as c, Fragment as S } from "react/jsx-runtime";
3
+ import * as n from "react";
4
+ import { cn as u } from "../ui/lib/utils.js";
5
+ import { tweens as R } from "../ui/lib/motion.js";
6
+ import { Skeleton as Z } from "../ui/skeleton.js";
7
+ import { Button as m } from "../ui/button.js";
8
+ import { Icon as l } from "../ui/icon.js";
9
+ import { IconZoomOut as D, IconZoomIn as N, IconZoomReset as T, IconMinimize as j, IconMaximize as L } from "@tabler/icons-react";
10
+ import { TransformWrapper as M, TransformComponent as O } from "react-zoom-pan-pinch";
11
+ import { E as B, T as H, a as k } from "./file-preview.js";
12
+ import { m as K } from "./framer.js";
13
+ function Y({ url: d, alt: g, onError: z }) {
14
+ const [i, w] = n.useState(!1), [y, E] = n.useState(!1), [C, I] = n.useState(100), [o, f] = n.useState(!1), p = n.useRef(null), [h, x] = n.useState(!1), v = n.useRef(null);
15
+ return n.useEffect(() => {
16
+ function s(e) {
17
+ const a = p.current;
18
+ if (!a || !a.contains(document.activeElement) && !h) return;
19
+ const r = v.current;
20
+ r && (e.key === "+" || e.key === "=" ? (e.preventDefault(), r.zoomIn()) : e.key === "-" ? (e.preventDefault(), r.zoomOut()) : e.key === "0" ? (e.preventDefault(), r.resetTransform()) : e.key === "f" || e.key === "F" ? (e.preventDefault(), f((F) => !F)) : e.key === "Escape" && o && (e.preventDefault(), f(!1)));
21
+ }
22
+ return document.addEventListener("keydown", s), () => document.removeEventListener("keydown", s);
23
+ }, [h, o]), y ? /* @__PURE__ */ t(B, { message: "Could not load image", url: d }) : /* @__PURE__ */ t(
24
+ "div",
25
+ {
26
+ ref: p,
27
+ className: o ? "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",
28
+ onMouseEnter: () => x(!0),
29
+ onMouseLeave: () => x(!1),
30
+ tabIndex: -1,
31
+ children: /* @__PURE__ */ t(
32
+ M,
33
+ {
34
+ initialScale: 1,
35
+ minScale: 0.1,
36
+ maxScale: 8,
37
+ centerOnInit: !0,
38
+ doubleClick: { mode: "toggle", step: 2 },
39
+ onTransformed: (s, e) => I(Math.round(e.scale * 100)),
40
+ children: ({ zoomIn: s, zoomOut: e, resetTransform: a, centerView: b }) => (v.current = { zoomIn: s, zoomOut: e, resetTransform: a, centerView: b }, /* @__PURE__ */ c(S, { children: [
41
+ /* @__PURE__ */ c("div", { className: u(
42
+ "overflow-hidden rounded-ds-md bg-surface-sunken",
43
+ o ? "flex-1 w-full" : "max-h-[70vh] max-w-full"
44
+ ), children: [
45
+ !i && /* @__PURE__ */ t(Z, { className: "h-64 w-full rounded-ds-md" }),
46
+ /* @__PURE__ */ t(
47
+ O,
48
+ {
49
+ wrapperClass: u("!w-full", o && "!h-full"),
50
+ contentClass: "!w-full !flex !items-center !justify-center",
51
+ children: /* @__PURE__ */ t(
52
+ K.img,
53
+ {
54
+ src: d,
55
+ alt: g ?? "",
56
+ onLoad: () => w(!0),
57
+ onError: () => {
58
+ E(!0), z?.("Image failed to load");
59
+ },
60
+ initial: { opacity: 0 },
61
+ animate: { opacity: i ? 1 : 0 },
62
+ transition: R.fade,
63
+ className: u("max-w-full select-none", !i && "hidden", o && "max-h-[90vh] object-contain"),
64
+ draggable: !1
65
+ }
66
+ )
67
+ }
68
+ )
69
+ ] }),
70
+ i && /* @__PURE__ */ c(H, { className: o ? "absolute bottom-ds-06" : void 0, children: [
71
+ /* @__PURE__ */ t(m, { variant: "ghost", size: "icon-xs", onClick: () => e(), "aria-label": "Zoom out (-)", title: "Zoom out", children: /* @__PURE__ */ t(l, { icon: D, size: "sm" }) }),
72
+ /* @__PURE__ */ c("span", { className: "text-ds-xs font-mono text-surface-fg-muted w-12 text-center tabular-nums select-none", children: [
73
+ C,
74
+ "%"
75
+ ] }),
76
+ /* @__PURE__ */ t(m, { variant: "ghost", size: "icon-xs", onClick: () => s(), "aria-label": "Zoom in (+)", title: "Zoom in", children: /* @__PURE__ */ t(l, { icon: N, size: "sm" }) }),
77
+ /* @__PURE__ */ t(k, {}),
78
+ /* @__PURE__ */ t(m, { variant: "ghost", size: "icon-xs", onClick: () => a(), "aria-label": "Reset zoom (0)", title: "Reset zoom", children: /* @__PURE__ */ t(l, { icon: T, size: "sm" }) }),
79
+ /* @__PURE__ */ t(k, {}),
80
+ /* @__PURE__ */ t(m, { variant: "ghost", size: "icon-xs", onClick: () => f((r) => !r), "aria-label": o ? "Exit fullscreen (Esc)" : "Fullscreen (F)", title: o ? "Exit fullscreen" : "Fullscreen", children: o ? /* @__PURE__ */ t(l, { icon: j, size: "sm" }) : /* @__PURE__ */ t(l, { icon: L, size: "sm" }) })
81
+ ] })
82
+ ] }))
83
+ }
84
+ )
85
+ }
86
+ );
87
+ }
88
+ export {
89
+ Y as default
90
+ };