@devalok/shilp-sutra 0.38.0 → 0.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. package/AGENTS.md +151 -0
  2. package/MIGRATION.md +255 -0
  3. package/README.md +3 -0
  4. package/dist/_chunks/badge-group.js +76 -75
  5. package/dist/_chunks/badge-group.js.map +1 -1
  6. package/dist/_chunks/chart-container.js +50 -0
  7. package/dist/_chunks/chart-container.js.map +1 -0
  8. package/dist/_chunks/chat.js +236 -228
  9. package/dist/_chunks/chat.js.map +1 -1
  10. package/dist/_chunks/colors.js +30 -0
  11. package/dist/_chunks/colors.js.map +1 -0
  12. package/dist/_chunks/document-preview.js +2 -2
  13. package/dist/_chunks/document-preview.js.map +1 -1
  14. package/dist/_chunks/emoji-data.js +45 -0
  15. package/dist/_chunks/emoji-data.js.map +1 -0
  16. package/dist/_chunks/grid-lines.js +72 -0
  17. package/dist/_chunks/grid-lines.js.map +1 -0
  18. package/dist/_chunks/image-preview.js +2 -2
  19. package/dist/_chunks/image-preview.js.map +1 -1
  20. package/dist/_chunks/mention-suggestion.js +35 -263
  21. package/dist/_chunks/mention-suggestion.js.map +1 -1
  22. package/dist/_chunks/normalize-icon.js +18 -0
  23. package/dist/_chunks/normalize-icon.js.map +1 -0
  24. package/dist/_chunks/oauth-button.js +227 -0
  25. package/dist/_chunks/oauth-button.js.map +1 -0
  26. package/dist/_chunks/popover.js +3 -3
  27. package/dist/_chunks/popover.js.map +1 -1
  28. package/dist/_chunks/primitives.js +107 -107
  29. package/dist/_chunks/primitives.js.map +1 -1
  30. package/dist/_chunks/shared.js +5 -5
  31. package/dist/_chunks/shared.js.map +1 -1
  32. package/dist/_chunks/{text.js → success.js} +26 -63
  33. package/dist/_chunks/success.js.map +1 -0
  34. package/dist/_chunks/tiptap.js +1952 -1949
  35. package/dist/_chunks/tiptap.js.map +1 -1
  36. package/dist/_chunks/tooltip.js +58 -0
  37. package/dist/_chunks/tooltip.js.map +1 -0
  38. package/dist/_chunks/tree-view.js +101 -96
  39. package/dist/_chunks/tree-view.js.map +1 -1
  40. package/dist/_chunks/use-calendar.js +5 -5
  41. package/dist/_chunks/use-calendar.js.map +1 -1
  42. package/dist/ai/ai-command-provider.d.ts +3 -2
  43. package/dist/ai/ai-command-provider.d.ts.map +1 -1
  44. package/dist/ai/ai-command-provider.js.map +1 -1
  45. package/dist/ai/block-renderer.js +11 -9
  46. package/dist/ai/block-renderer.js.map +1 -1
  47. package/dist/ai/blocks/error.js +31 -0
  48. package/dist/ai/blocks/error.js.map +1 -0
  49. package/dist/ai/blocks/index.d.ts +0 -2
  50. package/dist/ai/blocks/index.d.ts.map +1 -1
  51. package/dist/ai/blocks/index.js +2 -2
  52. package/dist/ai/blocks/text.js +19 -0
  53. package/dist/ai/blocks/text.js.map +1 -0
  54. package/dist/ai/command-bar.d.ts.map +1 -1
  55. package/dist/ai/command-bar.js +198 -193
  56. package/dist/ai/command-bar.js.map +1 -1
  57. package/dist/ai/conversation.d.ts +2 -1
  58. package/dist/ai/conversation.d.ts.map +1 -1
  59. package/dist/ai/conversation.js +92 -87
  60. package/dist/ai/conversation.js.map +1 -1
  61. package/dist/ai/index.d.ts +0 -4
  62. package/dist/ai/index.d.ts.map +1 -1
  63. package/dist/ai/index.js +45 -46
  64. package/dist/ai/index.js.map +1 -1
  65. package/dist/composed/activity-feed.d.ts +2 -1
  66. package/dist/composed/activity-feed.d.ts.map +1 -1
  67. package/dist/composed/activity-feed.js +5 -5
  68. package/dist/composed/activity-feed.js.map +1 -1
  69. package/dist/composed/avatar-group.js +4 -4
  70. package/dist/composed/avatar-group.js.map +1 -1
  71. package/dist/composed/bulk-action-bar.d.ts +2 -2
  72. package/dist/composed/bulk-action-bar.d.ts.map +1 -1
  73. package/dist/composed/bulk-action-bar.js +12 -12
  74. package/dist/composed/bulk-action-bar.js.map +1 -1
  75. package/dist/composed/command-palette.d.ts +2 -1
  76. package/dist/composed/command-palette.d.ts.map +1 -1
  77. package/dist/composed/command-palette.js +106 -101
  78. package/dist/composed/command-palette.js.map +1 -1
  79. package/dist/composed/content-card.js +1 -1
  80. package/dist/composed/content-card.js.map +1 -1
  81. package/dist/composed/date-picker/index.js +747 -3
  82. package/dist/composed/date-picker/index.js.map +1 -0
  83. package/dist/composed/emoji-picker.js +4 -4
  84. package/dist/composed/emoji-picker.js.map +1 -1
  85. package/dist/composed/empty-state.d.ts +3 -3
  86. package/dist/composed/empty-state.d.ts.map +1 -1
  87. package/dist/composed/empty-state.js +40 -31
  88. package/dist/composed/empty-state.js.map +1 -1
  89. package/dist/composed/error-boundary.js +3 -3
  90. package/dist/composed/error-boundary.js.map +1 -1
  91. package/dist/composed/extensions/emoji-node.js +81 -0
  92. package/dist/composed/extensions/emoji-node.js.map +1 -0
  93. package/dist/composed/extensions/emoji-suggestion.js +117 -0
  94. package/dist/composed/extensions/emoji-suggestion.js.map +1 -0
  95. package/dist/composed/file-preview.js +498 -2
  96. package/dist/composed/file-preview.js.map +1 -0
  97. package/dist/composed/filter-bar.js +1 -1
  98. package/dist/composed/filter-bar.js.map +1 -1
  99. package/dist/composed/index.d.ts +0 -15
  100. package/dist/composed/index.d.ts.map +1 -1
  101. package/dist/composed/index.js +16 -24
  102. package/dist/composed/inline-edit.js +1 -1
  103. package/dist/composed/inline-edit.js.map +1 -1
  104. package/dist/composed/loading-skeleton.js +9 -9
  105. package/dist/composed/loading-skeleton.js.map +1 -1
  106. package/dist/composed/markdown-viewer.js +3 -3
  107. package/dist/composed/markdown-viewer.js.map +1 -1
  108. package/dist/composed/multi-select-popover.js +1 -1
  109. package/dist/composed/multi-select-popover.js.map +1 -1
  110. package/dist/composed/page-header.js +1 -1
  111. package/dist/composed/page-header.js.map +1 -1
  112. package/dist/composed/page-skeletons.js +15 -15
  113. package/dist/composed/page-skeletons.js.map +1 -1
  114. package/dist/composed/priority-indicator.js +3 -3
  115. package/dist/composed/priority-indicator.js.map +1 -1
  116. package/dist/composed/rich-chat-input.js +2073 -2
  117. package/dist/composed/rich-chat-input.js.map +1 -0
  118. package/dist/composed/rich-text-editor.js +75 -72
  119. package/dist/composed/rich-text-editor.js.map +1 -1
  120. package/dist/composed/schedule-view.js +3 -3
  121. package/dist/composed/schedule-view.js.map +1 -1
  122. package/dist/composed/status-badge.d.ts +3 -2
  123. package/dist/composed/status-badge.d.ts.map +1 -1
  124. package/dist/composed/status-badge.js +58 -53
  125. package/dist/composed/status-badge.js.map +1 -1
  126. package/dist/shell/app-command-palette.d.ts +2 -1
  127. package/dist/shell/app-command-palette.d.ts.map +1 -1
  128. package/dist/shell/app-command-palette.js.map +1 -1
  129. package/dist/shell/bottom-navbar.d.ts +3 -1
  130. package/dist/shell/bottom-navbar.d.ts.map +1 -1
  131. package/dist/shell/bottom-navbar.js +94 -86
  132. package/dist/shell/bottom-navbar.js.map +1 -1
  133. package/dist/shell/command-registry.d.ts +2 -1
  134. package/dist/shell/command-registry.d.ts.map +1 -1
  135. package/dist/shell/command-registry.js.map +1 -1
  136. package/dist/shell/notification-center.js +8 -8
  137. package/dist/shell/notification-center.js.map +1 -1
  138. package/dist/shell/notification-preferences.js +1 -1
  139. package/dist/shell/notification-preferences.js.map +1 -1
  140. package/dist/shell/sidebar.d.ts +7 -4
  141. package/dist/shell/sidebar.d.ts.map +1 -1
  142. package/dist/shell/sidebar.js +148 -134
  143. package/dist/shell/sidebar.js.map +1 -1
  144. package/dist/shell/top-bar.d.ts +4 -3
  145. package/dist/shell/top-bar.d.ts.map +1 -1
  146. package/dist/shell/top-bar.js +116 -108
  147. package/dist/shell/top-bar.js.map +1 -1
  148. package/dist/tokens/semantic.css +82 -9
  149. package/dist/ui/accordion.js +1 -1
  150. package/dist/ui/accordion.js.map +1 -1
  151. package/dist/ui/alert-dialog.js +3 -3
  152. package/dist/ui/alert-dialog.js.map +1 -1
  153. package/dist/ui/alert.js +2 -2
  154. package/dist/ui/alert.js.map +1 -1
  155. package/dist/ui/autocomplete.js +2 -2
  156. package/dist/ui/autocomplete.js.map +1 -1
  157. package/dist/ui/avatar.js +11 -11
  158. package/dist/ui/avatar.js.map +1 -1
  159. package/dist/ui/badge-indicator.js +1 -1
  160. package/dist/ui/badge-indicator.js.map +1 -1
  161. package/dist/ui/badge.d.ts +3 -2
  162. package/dist/ui/badge.d.ts.map +1 -1
  163. package/dist/ui/banner.js +1 -1
  164. package/dist/ui/banner.js.map +1 -1
  165. package/dist/ui/breadcrumb.js +1 -1
  166. package/dist/ui/breadcrumb.js.map +1 -1
  167. package/dist/ui/button.d.ts +5 -4
  168. package/dist/ui/button.d.ts.map +1 -1
  169. package/dist/ui/button.js +66 -65
  170. package/dist/ui/button.js.map +1 -1
  171. package/dist/ui/card.js +5 -5
  172. package/dist/ui/card.js.map +1 -1
  173. package/dist/ui/charts/area-chart.js +177 -0
  174. package/dist/ui/charts/area-chart.js.map +1 -0
  175. package/dist/ui/charts/bar-chart.js +127 -0
  176. package/dist/ui/charts/bar-chart.js.map +1 -0
  177. package/dist/ui/charts/chart-container.js +3 -0
  178. package/dist/ui/charts/gauge-chart.js +72 -0
  179. package/dist/ui/charts/gauge-chart.js.map +1 -0
  180. package/dist/ui/charts/index.js +10 -1035
  181. package/dist/ui/charts/line-chart.js +135 -0
  182. package/dist/ui/charts/line-chart.js.map +1 -0
  183. package/dist/ui/charts/pie-chart.js +111 -0
  184. package/dist/ui/charts/pie-chart.js.map +1 -0
  185. package/dist/ui/charts/radar-chart.js +170 -0
  186. package/dist/ui/charts/radar-chart.js.map +1 -0
  187. package/dist/ui/charts/sparkline.js +119 -0
  188. package/dist/ui/charts/sparkline.js.map +1 -0
  189. package/dist/ui/chat/message.d.ts +3 -3
  190. package/dist/ui/chat/message.d.ts.map +1 -1
  191. package/dist/ui/chat/system-message.d.ts +2 -1
  192. package/dist/ui/chat/system-message.d.ts.map +1 -1
  193. package/dist/ui/checkbox.js +1 -1
  194. package/dist/ui/checkbox.js.map +1 -1
  195. package/dist/ui/code.js +2 -2
  196. package/dist/ui/code.js.map +1 -1
  197. package/dist/ui/color-input.js +10 -10
  198. package/dist/ui/color-input.js.map +1 -1
  199. package/dist/ui/color-swatch.js +3 -3
  200. package/dist/ui/color-swatch.js.map +1 -1
  201. package/dist/ui/combobox.d.ts +2 -1
  202. package/dist/ui/combobox.d.ts.map +1 -1
  203. package/dist/ui/combobox.js +100 -95
  204. package/dist/ui/combobox.js.map +1 -1
  205. package/dist/ui/container.d.ts +6 -1
  206. package/dist/ui/container.d.ts.map +1 -1
  207. package/dist/ui/container.js +2 -1
  208. package/dist/ui/container.js.map +1 -1
  209. package/dist/ui/context-menu.js +6 -6
  210. package/dist/ui/context-menu.js.map +1 -1
  211. package/dist/ui/data-table-body.js +1 -1
  212. package/dist/ui/data-table-body.js.map +1 -1
  213. package/dist/ui/data-table-bulk-actions.js +2 -2
  214. package/dist/ui/data-table-bulk-actions.js.map +1 -1
  215. package/dist/ui/data-table-card.js +2 -2
  216. package/dist/ui/data-table-card.js.map +1 -1
  217. package/dist/ui/data-table-header.js +2 -2
  218. package/dist/ui/data-table-header.js.map +1 -1
  219. package/dist/ui/data-table-pagination.js +3 -3
  220. package/dist/ui/data-table-pagination.js.map +1 -1
  221. package/dist/ui/data-table-toolbar.js +1 -1
  222. package/dist/ui/data-table-toolbar.js.map +1 -1
  223. package/dist/ui/data-table.js +1 -1
  224. package/dist/ui/data-table.js.map +1 -1
  225. package/dist/ui/devalok-grain.d.ts +1 -1
  226. package/dist/ui/devalok-grain.js.map +1 -1
  227. package/dist/ui/dialog.js +2 -2
  228. package/dist/ui/dialog.js.map +1 -1
  229. package/dist/ui/dropdown-menu.js +6 -6
  230. package/dist/ui/dropdown-menu.js.map +1 -1
  231. package/dist/ui/file-upload.js +4 -4
  232. package/dist/ui/file-upload.js.map +1 -1
  233. package/dist/ui/hover-card.js +1 -1
  234. package/dist/ui/hover-card.js.map +1 -1
  235. package/dist/ui/icon-button.d.ts +9 -2
  236. package/dist/ui/icon-button.d.ts.map +1 -1
  237. package/dist/ui/icon-button.js +14 -13
  238. package/dist/ui/icon-button.js.map +1 -1
  239. package/dist/ui/index.d.ts +1 -3
  240. package/dist/ui/index.d.ts.map +1 -1
  241. package/dist/ui/index.js +31 -33
  242. package/dist/ui/index.js.map +1 -1
  243. package/dist/ui/input-otp.js +1 -1
  244. package/dist/ui/input-otp.js.map +1 -1
  245. package/dist/ui/input.js +2 -2
  246. package/dist/ui/input.js.map +1 -1
  247. package/dist/ui/lib/icon-input.d.ts +42 -0
  248. package/dist/ui/lib/icon-input.d.ts.map +1 -0
  249. package/dist/ui/lib/normalize-icon.d.ts +39 -0
  250. package/dist/ui/lib/normalize-icon.d.ts.map +1 -0
  251. package/dist/ui/link.js +1 -1
  252. package/dist/ui/link.js.map +1 -1
  253. package/dist/ui/menubar.js +8 -8
  254. package/dist/ui/menubar.js.map +1 -1
  255. package/dist/ui/navigation-menu.js +3 -3
  256. package/dist/ui/navigation-menu.js.map +1 -1
  257. package/dist/ui/number-input.js +3 -3
  258. package/dist/ui/number-input.js.map +1 -1
  259. package/dist/ui/oauth-button/index.d.ts +3 -0
  260. package/dist/ui/oauth-button/index.d.ts.map +1 -0
  261. package/dist/ui/oauth-button/index.js +3 -0
  262. package/dist/ui/oauth-button/oauth-button.d.ts +208 -0
  263. package/dist/ui/oauth-button/oauth-button.d.ts.map +1 -0
  264. package/dist/ui/pagination.js +1 -1
  265. package/dist/ui/pagination.js.map +1 -1
  266. package/dist/ui/progress.js +2 -2
  267. package/dist/ui/progress.js.map +1 -1
  268. package/dist/ui/radio.js +1 -1
  269. package/dist/ui/radio.js.map +1 -1
  270. package/dist/ui/segmented-control.d.ts +3 -4
  271. package/dist/ui/segmented-control.d.ts.map +1 -1
  272. package/dist/ui/segmented-control.js +53 -45
  273. package/dist/ui/segmented-control.js.map +1 -1
  274. package/dist/ui/select.js +3 -3
  275. package/dist/ui/select.js.map +1 -1
  276. package/dist/ui/sheet.js +2 -2
  277. package/dist/ui/sheet.js.map +1 -1
  278. package/dist/ui/sidebar.js +11 -11
  279. package/dist/ui/sidebar.js.map +1 -1
  280. package/dist/ui/skeleton.js +9 -9
  281. package/dist/ui/skeleton.js.map +1 -1
  282. package/dist/ui/slider.js +2 -2
  283. package/dist/ui/slider.js.map +1 -1
  284. package/dist/ui/split-button.js +7 -7
  285. package/dist/ui/split-button.js.map +1 -1
  286. package/dist/ui/stack.d.ts +6 -1
  287. package/dist/ui/stack.d.ts.map +1 -1
  288. package/dist/ui/stack.js +2 -1
  289. package/dist/ui/stack.js.map +1 -1
  290. package/dist/ui/stat-card.d.ts +2 -3
  291. package/dist/ui/stat-card.d.ts.map +1 -1
  292. package/dist/ui/stat-card.js +118 -116
  293. package/dist/ui/stat-card.js.map +1 -1
  294. package/dist/ui/status-dot.js +2 -2
  295. package/dist/ui/status-dot.js.map +1 -1
  296. package/dist/ui/stepper.d.ts +2 -1
  297. package/dist/ui/stepper.d.ts.map +1 -1
  298. package/dist/ui/stepper.js +74 -69
  299. package/dist/ui/stepper.js.map +1 -1
  300. package/dist/ui/switch.js +2 -2
  301. package/dist/ui/switch.js.map +1 -1
  302. package/dist/ui/tabs.js +3 -3
  303. package/dist/ui/tabs.js.map +1 -1
  304. package/dist/ui/text.d.ts +7 -2
  305. package/dist/ui/text.d.ts.map +1 -1
  306. package/dist/ui/text.js +2 -1
  307. package/dist/ui/text.js.map +1 -1
  308. package/dist/ui/textarea.js +1 -1
  309. package/dist/ui/textarea.js.map +1 -1
  310. package/dist/ui/toast.js +8 -8
  311. package/dist/ui/toast.js.map +1 -1
  312. package/dist/ui/toaster.d.ts +11 -2
  313. package/dist/ui/toaster.d.ts.map +1 -1
  314. package/dist/ui/toaster.js.map +1 -1
  315. package/dist/ui/toggle.js +1 -1
  316. package/dist/ui/toggle.js.map +1 -1
  317. package/dist/ui/tooltip.js +12 -12
  318. package/dist/ui/tooltip.js.map +1 -1
  319. package/dist/ui/tree-view/tree-item.d.ts +3 -2
  320. package/dist/ui/tree-view/tree-item.d.ts.map +1 -1
  321. package/dist/ui/tree-view/use-tree.d.ts +2 -1
  322. package/dist/ui/tree-view/use-tree.d.ts.map +1 -1
  323. package/docs/components/_header.md +90 -1
  324. package/docs/components/ui/oauth-button.md +86 -0
  325. package/docs/recipes/customize-brand.md +100 -4
  326. package/docs/recipes/index.md +5 -1
  327. package/docs/recipes/install-astro.md +15 -0
  328. package/docs/recipes/install-next-app-router.md +21 -5
  329. package/docs/recipes/install-next-pages.md +2 -0
  330. package/docs/recipes/install-remix.md +15 -0
  331. package/docs/recipes/install-tanstack-start.md +15 -0
  332. package/docs/recipes/install-vite.md +15 -0
  333. package/docs/recipes/troubleshoot.md +22 -0
  334. package/llms-full.txt +177 -2
  335. package/llms-quick.txt +247 -0
  336. package/llms.txt +116 -3
  337. package/package.json +80 -2
  338. package/scripts/welcome.mjs +219 -0
  339. package/skill/README.md +99 -0
  340. package/skill/SKILL.md +163 -0
  341. package/skill/install.sh +59 -0
  342. package/skill/references/components-full.md +7083 -0
  343. package/skill/references/components.md +778 -0
  344. package/skill/references/customize-brand.md +314 -0
  345. package/skill/references/server-components.md +211 -0
  346. package/skill/references/setup-astro.md +195 -0
  347. package/skill/references/setup-next-app-router.md +248 -0
  348. package/skill/references/setup-next-pages.md +127 -0
  349. package/skill/references/setup-remix.md +188 -0
  350. package/skill/references/setup-tanstack-start.md +160 -0
  351. package/skill/references/setup-vite.md +187 -0
  352. package/skill/references/troubleshoot.md +241 -0
  353. package/dist/_chunks/date-picker.js +0 -748
  354. package/dist/_chunks/date-picker.js.map +0 -1
  355. package/dist/_chunks/file-preview.js +0 -499
  356. package/dist/_chunks/file-preview.js.map +0 -1
  357. package/dist/_chunks/rich-chat-input.js +0 -2071
  358. package/dist/_chunks/rich-chat-input.js.map +0 -1
  359. package/dist/_chunks/text.js.map +0 -1
  360. package/dist/ui/charts/index.js.map +0 -1
  361. /package/{LICENSE → skill/LICENSE} +0 -0
@@ -0,0 +1,117 @@
1
+ "use client";
2
+ import { cn as e } from "../../ui/lib/utils.js";
3
+ import { g as t, p as n, y as r } from "../../_chunks/tiptap.js";
4
+ import { i, n as a, t as o } from "../../_chunks/emoji-data.js";
5
+ import * as s from "react";
6
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
7
+ import { createRoot as u } from "react-dom/client";
8
+ //#region src/composed/extensions/emoji-suggestion.tsx
9
+ function d({ emoji: e, set: t, size: n = "1.2em" }) {
10
+ return t === "native" ? /* @__PURE__ */ c("span", {
11
+ style: { fontSize: n },
12
+ children: e.native
13
+ }) : /* @__PURE__ */ c("span", {
14
+ role: "img",
15
+ "aria-label": e.native,
16
+ className: "inline-block",
17
+ style: {
18
+ width: n,
19
+ height: n,
20
+ backgroundImage: `url(${o(t)})`,
21
+ backgroundSize: "6100% 6100%",
22
+ backgroundPosition: `${100 / 60 * e.x}% ${100 / 60 * e.y}%`
23
+ }
24
+ });
25
+ }
26
+ var f = s.forwardRef(({ items: t, set: n, command: r }, i) => {
27
+ let [a, o] = s.useState(0);
28
+ return s.useEffect(() => o(0), [t]), s.useImperativeHandle(i, () => ({ onKeyDown: ({ event: e }) => e.key === "ArrowUp" ? (o((e) => (e + t.length - 1) % t.length), !0) : e.key === "ArrowDown" ? (o((e) => (e + 1) % t.length), !0) : e.key === "Enter" ? (t[a] && r(t[a]), !0) : !1 })), t.length ? /* @__PURE__ */ c("div", {
29
+ role: "listbox",
30
+ "aria-label": "Emoji suggestions",
31
+ className: "z-popover max-h-[200px] overflow-x-hidden overflow-y-auto rounded-control border border-surface-border-strong bg-surface-overlay shadow-raised-hover",
32
+ children: t.map((t, i) => /* @__PURE__ */ l("button", {
33
+ type: "button",
34
+ role: "option",
35
+ "aria-selected": i === a,
36
+ onClick: () => r(t),
37
+ className: e("flex w-full items-center gap-ds-03 px-ds-04 py-ds-02b text-left text-ds-sm", i === a ? "bg-surface-raised text-surface-fg" : "text-surface-fg-muted hover:bg-surface-raised"),
38
+ children: [/* @__PURE__ */ c(d, {
39
+ emoji: t,
40
+ set: n,
41
+ size: "1.25em"
42
+ }), /* @__PURE__ */ l("span", {
43
+ className: "truncate",
44
+ children: [
45
+ ":",
46
+ t.id,
47
+ ":"
48
+ ]
49
+ })]
50
+ }, t.id))
51
+ }) : null;
52
+ });
53
+ f.displayName = "EmojiList";
54
+ function p(e) {
55
+ return () => {
56
+ let t = null, n = null, r = null;
57
+ return {
58
+ onStart: (i) => {
59
+ n = document.createElement("div"), n.style.position = "absolute", n.style.zIndex = "1400";
60
+ let a = i.clientRect?.();
61
+ a && (n.style.left = `${a.left}px`, n.style.top = `${a.bottom + 4}px`), document.body.appendChild(n), t = u(n), t.render(/* @__PURE__ */ c(f, {
62
+ ref: (e) => {
63
+ r = e;
64
+ },
65
+ items: i.items,
66
+ set: e,
67
+ command: (e) => i.command(e)
68
+ }));
69
+ },
70
+ onUpdate: (i) => {
71
+ if (!t || !n) return;
72
+ let a = i.clientRect?.();
73
+ a && (n.style.left = `${a.left}px`, n.style.top = `${a.bottom + 4}px`), t.render(/* @__PURE__ */ c(f, {
74
+ ref: (e) => {
75
+ r = e;
76
+ },
77
+ items: i.items,
78
+ set: e,
79
+ command: (e) => i.command(e)
80
+ }));
81
+ },
82
+ onKeyDown: (e) => e.event.key === "Escape" ? (n && (t?.unmount(), n.remove(), n = null, t = null), !0) : r?.onKeyDown(e) ?? !1,
83
+ onExit: () => {
84
+ n && (t?.unmount(), n.remove(), n = null, t = null);
85
+ }
86
+ };
87
+ };
88
+ }
89
+ function m(e = "native") {
90
+ return t.create({
91
+ name: "emojiSuggestion",
92
+ addProseMirrorPlugins() {
93
+ return [n({
94
+ pluginKey: new r("emojiSuggestion"),
95
+ editor: this.editor,
96
+ char: ":",
97
+ items: async ({ query: t }) => i(await a(e), t, 8),
98
+ command: ({ editor: t, range: n, props: r }) => {
99
+ let i = r;
100
+ t.chain().focus().deleteRange(n).insertContent({
101
+ type: "emojiNode",
102
+ attrs: {
103
+ id: i.id,
104
+ native: i.native,
105
+ set: e,
106
+ x: i.x,
107
+ y: i.y
108
+ }
109
+ }).run();
110
+ },
111
+ render: p(e)
112
+ })];
113
+ }
114
+ });
115
+ }
116
+ //#endregion
117
+ export { m as createEmojiSuggestion };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emoji-suggestion.js","names":[],"sources":["../../../src/composed/extensions/emoji-suggestion.tsx"],"sourcesContent":["import { Extension } from '@tiptap/core'\nimport Suggestion, { type SuggestionKeyDownProps,type SuggestionProps } from '@tiptap/suggestion'\nimport { PluginKey } from 'prosemirror-state'\nimport * as React from 'react'\nimport { createRoot, type Root } from 'react-dom/client'\n\nimport { cn } from '../../ui/lib/utils'\nimport { loadEmojiData, type ResolvedEmoji, searchEmoji, SHEET_COLS, SHEET_ROWS,SPRITESHEET_URL } from './emoji-data'\n\n// Re-export for external consumers\nexport type { ResolvedEmoji as EmojiSuggestionItem }\n\nfunction EmojiImage({ emoji, set, size = '1.2em' }: { emoji: ResolvedEmoji; set: string; size?: string }) {\n if (set === 'native') {\n return <span style={{ fontSize: size }}>{emoji.native}</span>\n }\n return (\n <span\n role=\"img\"\n aria-label={emoji.native}\n className=\"inline-block\"\n style={{\n width: size,\n height: size,\n backgroundImage: `url(${SPRITESHEET_URL(set)})`,\n backgroundSize: `${100 * SHEET_COLS}% ${100 * SHEET_ROWS}%`,\n backgroundPosition: `${(100 / (SHEET_COLS - 1)) * emoji.x}% ${(100 / (SHEET_ROWS - 1)) * emoji.y}%`,\n }}\n />\n )\n}\n\ninterface EmojiListRef {\n onKeyDown: (props: SuggestionKeyDownProps) => boolean\n}\n\ninterface EmojiListProps {\n items: ResolvedEmoji[]\n set: string\n command: (item: ResolvedEmoji) => void\n}\n\nconst EmojiList = React.forwardRef<EmojiListRef, EmojiListProps>(\n ({ items, set, command }, ref) => {\n const [selectedIndex, setSelectedIndex] = React.useState(0)\n\n React.useEffect(() => setSelectedIndex(0), [items])\n\n React.useImperativeHandle(ref, () => ({\n onKeyDown: ({ event }: SuggestionKeyDownProps) => {\n if (event.key === 'ArrowUp') {\n setSelectedIndex((i) => (i + items.length - 1) % items.length)\n return true\n }\n if (event.key === 'ArrowDown') {\n setSelectedIndex((i) => (i + 1) % items.length)\n return true\n }\n if (event.key === 'Enter') {\n if (items[selectedIndex]) command(items[selectedIndex])\n return true\n }\n return false\n },\n }))\n\n if (!items.length) return null\n\n return (\n <div role=\"listbox\" aria-label=\"Emoji suggestions\" className=\"z-popover max-h-[200px] overflow-x-hidden overflow-y-auto rounded-control border border-surface-border-strong bg-surface-overlay shadow-raised-hover\">\n {items.map((item, index) => (\n <button\n key={item.id}\n type=\"button\"\n role=\"option\"\n aria-selected={index === selectedIndex}\n onClick={() => command(item)}\n className={cn(\n 'flex w-full items-center gap-ds-03 px-ds-04 py-ds-02b text-left text-ds-sm',\n index === selectedIndex ? 'bg-surface-raised text-surface-fg' : 'text-surface-fg-muted hover:bg-surface-raised',\n )}\n >\n <EmojiImage emoji={item} set={set} size=\"1.25em\" />\n <span className=\"truncate\">:{item.id}:</span>\n </button>\n ))}\n </div>\n )\n },\n)\nEmojiList.displayName = 'EmojiList'\n\nfunction createEmojiSuggestionRenderer(set: string) {\n return () => {\n let root: Root | null = null\n let container: HTMLDivElement | null = null\n let componentRef: EmojiListRef | null = null\n\n return {\n onStart: (props: SuggestionProps<ResolvedEmoji>) => {\n container = document.createElement('div')\n container.style.position = 'absolute'\n container.style.zIndex = '1400'\n const rect = props.clientRect?.()\n if (rect) {\n container.style.left = `${rect.left}px`\n container.style.top = `${rect.bottom + 4}px`\n }\n document.body.appendChild(container)\n root = createRoot(container)\n root.render(\n <EmojiList\n ref={(r) => { componentRef = r }}\n items={props.items as ResolvedEmoji[]}\n set={set}\n command={(item) => props.command(item)}\n />,\n )\n },\n\n onUpdate: (props: SuggestionProps<ResolvedEmoji>) => {\n if (!root || !container) return\n const rect = props.clientRect?.()\n if (rect) {\n container.style.left = `${rect.left}px`\n container.style.top = `${rect.bottom + 4}px`\n }\n root.render(\n <EmojiList\n ref={(r) => { componentRef = r }}\n items={props.items as ResolvedEmoji[]}\n set={set}\n command={(item) => props.command(item)}\n />,\n )\n },\n\n onKeyDown: (props: SuggestionKeyDownProps) => {\n if (props.event.key === 'Escape') {\n if (container) {\n root?.unmount()\n container.remove()\n container = null\n root = null\n }\n return true\n }\n return componentRef?.onKeyDown(props) ?? false\n },\n\n onExit: () => {\n if (container) {\n root?.unmount()\n container.remove()\n container = null\n root = null\n }\n },\n }\n }\n}\n\n/** Factory: call with the emoji set to get a configured extension. */\nexport function createEmojiSuggestion(set = 'native') {\n return Extension.create({\n name: 'emojiSuggestion',\n\n addProseMirrorPlugins() {\n return [\n Suggestion({\n pluginKey: new PluginKey('emojiSuggestion'),\n editor: this.editor,\n char: ':',\n items: async ({ query }) => {\n const data = await loadEmojiData(set)\n return searchEmoji(data, query, 8)\n },\n command: ({ editor, range, props: item }) => {\n const emoji = item as ResolvedEmoji\n editor\n .chain()\n .focus()\n .deleteRange(range)\n .insertContent({\n type: 'emojiNode',\n attrs: { id: emoji.id, native: emoji.native, set, x: emoji.x, y: emoji.y },\n })\n .run()\n },\n render: createEmojiSuggestionRenderer(set),\n }),\n ]\n },\n })\n}\n"],"mappings":"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"}
@@ -1,3 +1,499 @@
1
1
  "use client";
2
- import { t as e } from "../_chunks/file-preview.js";
3
- export { e as FilePreview };
2
+ import { springs as e, tweens as t } from "../ui/lib/motion.js";
3
+ import { cn as n } from "../ui/lib/utils.js";
4
+ import { Icon as r } from "../ui/icon.js";
5
+ import { n as i } from "../_chunks/badge-group.js";
6
+ import { Button as a } from "../ui/button.js";
7
+ import { Skeleton as o } from "../ui/skeleton.js";
8
+ import { a as s, i as c, t as l } from "../_chunks/shared.js";
9
+ import * as u from "react";
10
+ import { jsx as d, jsxs as f } from "react/jsx-runtime";
11
+ import { IconDownload as p, IconMaximize as m, IconPlayerPause as h, IconPlayerPlay as g } from "@tabler/icons-react";
12
+ import { AnimatePresence as _, motion as v } from "framer-motion";
13
+ //#region src/composed/file-preview/audio-preview.tsx
14
+ function y({ url: e, fileName: t, onError: n }) {
15
+ let i = u.useRef(null), o = u.useRef(null), [p, m] = u.useState(!1), [_, v] = u.useState(0), [y, b] = u.useState(0), [x, S] = u.useState(0), [C, w] = u.useState(1), [T, E] = u.useState(!1), [D, O] = u.useState(!1), [k, A] = u.useState(null);
16
+ u.useEffect(() => {
17
+ function e(e) {
18
+ let t = o.current;
19
+ if (!t || !t.contains(document.activeElement) && document.activeElement !== t) return;
20
+ let n = i.current;
21
+ if (n) switch (e.key) {
22
+ case " ":
23
+ e.preventDefault(), m((e) => (e ? n.pause() : n.play(), !e));
24
+ break;
25
+ case "ArrowRight":
26
+ e.preventDefault(), n.currentTime = Math.min(n.duration || 0, n.currentTime + 5);
27
+ break;
28
+ case "ArrowLeft":
29
+ e.preventDefault(), n.currentTime = Math.max(0, n.currentTime - 5);
30
+ break;
31
+ case "m":
32
+ e.preventDefault(), E((e) => (n.muted = !e, !e));
33
+ break;
34
+ }
35
+ }
36
+ return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e);
37
+ }, []);
38
+ function j() {
39
+ i.current && (p ? i.current.pause() : i.current.play(), m(!p));
40
+ }
41
+ function M(e) {
42
+ if (!i.current || !y) return;
43
+ let t = e.currentTarget.getBoundingClientRect(), n = Math.max(0, Math.min(1, (e.clientX - t.left) / t.width));
44
+ i.current.currentTime = n * y;
45
+ }
46
+ function N(e) {
47
+ if (!y) return;
48
+ let t = e.currentTarget.getBoundingClientRect();
49
+ A((e.clientX - t.left) / t.width * y);
50
+ }
51
+ function P() {
52
+ if (!i.current) return;
53
+ let e = !T;
54
+ E(e), i.current.muted = e;
55
+ }
56
+ return D ? /* @__PURE__ */ d(l, {
57
+ message: "Could not load audio",
58
+ url: e
59
+ }) : /* @__PURE__ */ f("div", {
60
+ ref: o,
61
+ className: "rounded-surface border border-surface-border bg-surface-raised shadow-raised overflow-hidden",
62
+ tabIndex: -1,
63
+ children: [
64
+ /* @__PURE__ */ d("audio", {
65
+ ref: i,
66
+ src: e,
67
+ onTimeUpdate: () => {
68
+ i.current && (S(i.current.currentTime), i.current.duration && v(i.current.currentTime / i.current.duration * 100));
69
+ },
70
+ onLoadedMetadata: () => b(i.current?.duration ?? 0),
71
+ onEnded: () => m(!1),
72
+ onError: () => {
73
+ O(!0), n?.("Audio failed to load");
74
+ }
75
+ }),
76
+ /* @__PURE__ */ f("div", {
77
+ className: "relative h-1 w-full cursor-pointer bg-surface-sunken group/bar",
78
+ onClick: M,
79
+ onMouseMove: N,
80
+ onMouseLeave: () => A(null),
81
+ role: "slider",
82
+ "aria-label": "Audio progress",
83
+ "aria-valuenow": Math.round(_),
84
+ "aria-valuemin": 0,
85
+ "aria-valuemax": 100,
86
+ tabIndex: 0,
87
+ children: [
88
+ /* @__PURE__ */ d("div", {
89
+ className: "absolute left-0 top-0 h-full bg-accent-9 transition-[width] duration-75",
90
+ style: { width: `${_}%` }
91
+ }),
92
+ k !== null && /* @__PURE__ */ d("div", {
93
+ className: "absolute -top-7 -translate-x-1/2 rounded-control-inner bg-surface-overlay px-1.5 py-0.5 text-[10px] font-mono text-surface-fg shadow-floating pointer-events-none",
94
+ style: { left: `${k / (y || 1) * 100}%` },
95
+ children: s(k)
96
+ }),
97
+ /* @__PURE__ */ d("div", {
98
+ className: "absolute top-1/2 -translate-y-1/2 h-2.5 w-2.5 rounded-pill bg-accent-9 shadow-raised opacity-0 group-hover/bar:opacity-100 transition-opacity",
99
+ style: {
100
+ left: `${_}%`,
101
+ marginLeft: "-5px"
102
+ }
103
+ })
104
+ ]
105
+ }),
106
+ /* @__PURE__ */ f("div", {
107
+ className: "flex items-center gap-ds-04 px-ds-05 py-ds-04",
108
+ children: [
109
+ /* @__PURE__ */ d(a, {
110
+ variant: "solid",
111
+ size: "icon-sm",
112
+ onClick: j,
113
+ "aria-label": p ? "Pause" : "Play",
114
+ title: p ? "Pause" : "Play",
115
+ className: "shrink-0",
116
+ children: p ? /* @__PURE__ */ d(r, {
117
+ icon: h,
118
+ size: "sm"
119
+ }) : /* @__PURE__ */ d(r, {
120
+ icon: g,
121
+ size: "sm",
122
+ className: "ml-0.5"
123
+ })
124
+ }),
125
+ /* @__PURE__ */ f("div", {
126
+ className: "flex-1 min-w-0",
127
+ children: [t && /* @__PURE__ */ d("p", {
128
+ className: "text-ds-sm font-semibold text-surface-fg truncate",
129
+ children: t
130
+ }), /* @__PURE__ */ f("p", {
131
+ className: "text-ds-xs font-mono text-surface-fg-muted tabular-nums",
132
+ children: [
133
+ s(x),
134
+ " / ",
135
+ s(y)
136
+ ]
137
+ })]
138
+ }),
139
+ /* @__PURE__ */ d(c, {
140
+ volume: C,
141
+ muted: T,
142
+ onVolumeChange: (e) => {
143
+ w(e), i.current && (i.current.volume = e), e > 0 && T && (E(!1), i.current && (i.current.muted = !1));
144
+ },
145
+ onMuteToggle: P,
146
+ variant: "light"
147
+ })
148
+ ]
149
+ })
150
+ ]
151
+ });
152
+ }
153
+ //#endregion
154
+ //#region src/composed/file-preview/embed-preview.tsx
155
+ function b({ url: e, embedUrl: n, onError: r }) {
156
+ let [i, a] = u.useState(!1), [s, c] = u.useState(!1);
157
+ return u.useEffect(() => {
158
+ let e = setTimeout(() => {
159
+ i || (c(!0), r?.("Embed timed out"));
160
+ }, 15e3);
161
+ return () => clearTimeout(e);
162
+ }, [i, r]), s ? /* @__PURE__ */ d(l, {
163
+ message: "Could not load embed",
164
+ url: e
165
+ }) : /* @__PURE__ */ f("div", {
166
+ className: "relative w-full rounded-control overflow-hidden",
167
+ style: { aspectRatio: "16 / 9" },
168
+ children: [!i && /* @__PURE__ */ d(o, { className: "absolute inset-0" }), /* @__PURE__ */ d(v.iframe, {
169
+ src: n,
170
+ title: "Embedded content",
171
+ onLoad: () => a(!0),
172
+ onError: () => {
173
+ c(!0), r?.("Embed failed to load");
174
+ },
175
+ initial: { opacity: 0 },
176
+ animate: { opacity: +!!i },
177
+ transition: t.fade,
178
+ className: "absolute inset-0 h-full w-full border-none",
179
+ allowFullScreen: !0
180
+ })]
181
+ });
182
+ }
183
+ //#endregion
184
+ //#region src/composed/file-preview/video-preview.tsx
185
+ var x = [
186
+ .5,
187
+ .75,
188
+ 1,
189
+ 1.25,
190
+ 1.5,
191
+ 2
192
+ ];
193
+ function S({ url: n, onError: i }) {
194
+ let a = u.useRef(null), o = u.useRef(null), [p, y] = u.useState(!1), [b, S] = u.useState(0), [C, w] = u.useState(0), [T, E] = u.useState(0), [D, O] = u.useState(!1), [k, A] = u.useState(!1), [j, M] = u.useState(!0), [N, P] = u.useState(1), F = u.useRef(void 0);
195
+ u.useEffect(() => () => clearTimeout(F.current), []), u.useEffect(() => {
196
+ function e(e) {
197
+ let t = o.current;
198
+ if (!t || !t.contains(document.activeElement) && document.activeElement !== t) return;
199
+ let n = a.current;
200
+ if (n) switch (e.key) {
201
+ case " ":
202
+ case "k":
203
+ e.preventDefault(), y((e) => (e ? n.pause() : n.play(), !e));
204
+ break;
205
+ case "ArrowRight":
206
+ e.preventDefault(), n.currentTime = Math.min(n.duration, n.currentTime + 5);
207
+ break;
208
+ case "ArrowLeft":
209
+ e.preventDefault(), n.currentTime = Math.max(0, n.currentTime - 5);
210
+ break;
211
+ case "j":
212
+ e.preventDefault(), n.currentTime = Math.max(0, n.currentTime - 10);
213
+ break;
214
+ case "l":
215
+ e.preventDefault(), n.currentTime = Math.min(n.duration, n.currentTime + 10);
216
+ break;
217
+ case "m":
218
+ e.preventDefault(), O((e) => (n.muted = !e, !e));
219
+ break;
220
+ case "f":
221
+ e.preventDefault(), n.requestFullscreen?.();
222
+ break;
223
+ case ">":
224
+ e.preventDefault(), I(1);
225
+ break;
226
+ case "<":
227
+ e.preventDefault(), I(-1);
228
+ break;
229
+ }
230
+ }
231
+ return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e);
232
+ }, []);
233
+ function I(e) {
234
+ let t = x.indexOf(N), n = x[Math.max(0, Math.min(x.length - 1, t + e))];
235
+ P(n), a.current && (a.current.playbackRate = n);
236
+ }
237
+ function L() {
238
+ a.current && (p ? a.current.pause() : a.current.play(), y(!p));
239
+ }
240
+ function R(e) {
241
+ if (!a.current || !C) return;
242
+ let t = e.currentTarget.getBoundingClientRect(), n = (e.clientX - t.left) / t.width;
243
+ a.current.currentTime = n * C;
244
+ }
245
+ function z() {
246
+ M(!0), clearTimeout(F.current), p && (F.current = setTimeout(() => M(!1), 3e3));
247
+ }
248
+ return k ? /* @__PURE__ */ d(l, {
249
+ message: "Could not load video",
250
+ url: n
251
+ }) : /* @__PURE__ */ f("div", {
252
+ ref: o,
253
+ className: "group relative rounded-control bg-black overflow-hidden",
254
+ onMouseMove: z,
255
+ onMouseLeave: () => p && M(!1),
256
+ tabIndex: -1,
257
+ children: [
258
+ /* @__PURE__ */ d("video", {
259
+ ref: a,
260
+ src: n,
261
+ className: "max-h-[70vh] w-full",
262
+ onClick: L,
263
+ muted: D,
264
+ onTimeUpdate: () => {
265
+ a.current && (E(a.current.currentTime), a.current.duration && S(a.current.currentTime / a.current.duration * 100));
266
+ },
267
+ onLoadedMetadata: () => w(a.current?.duration ?? 0),
268
+ onEnded: () => {
269
+ y(!1), M(!0);
270
+ },
271
+ onError: () => {
272
+ A(!0), i?.("Video failed to load");
273
+ },
274
+ playsInline: !0
275
+ }),
276
+ !p && /* @__PURE__ */ d(v.button, {
277
+ initial: {
278
+ opacity: 0,
279
+ scale: .8
280
+ },
281
+ animate: {
282
+ opacity: 1,
283
+ scale: 1
284
+ },
285
+ transition: e.snappy,
286
+ onClick: L,
287
+ className: "absolute inset-0 flex items-center justify-center bg-black/30",
288
+ "aria-label": "Play video",
289
+ children: /* @__PURE__ */ d("div", {
290
+ className: "flex h-14 w-14 items-center justify-center rounded-pill bg-white/90 shadow-floating",
291
+ children: /* @__PURE__ */ d(r, {
292
+ icon: g,
293
+ size: "xl",
294
+ className: "text-surface-fg ml-0.5"
295
+ })
296
+ })
297
+ }),
298
+ /* @__PURE__ */ d(_, { children: j && C > 0 && /* @__PURE__ */ f(v.div, {
299
+ initial: {
300
+ opacity: 0,
301
+ y: 10
302
+ },
303
+ animate: {
304
+ opacity: 1,
305
+ y: 0
306
+ },
307
+ exit: {
308
+ opacity: 0,
309
+ y: 10
310
+ },
311
+ transition: t.fade,
312
+ className: "absolute bottom-0 left-0 right-0 bg-linear-to-t from-black/80 to-transparent px-ds-04 pb-ds-04 pt-ds-08",
313
+ children: [/* @__PURE__ */ f("div", {
314
+ className: "relative h-1 w-full cursor-pointer rounded-pill bg-white/30 mb-ds-03 group/progress",
315
+ onClick: R,
316
+ role: "slider",
317
+ "aria-label": "Video progress",
318
+ "aria-valuenow": Math.round(b),
319
+ "aria-valuemin": 0,
320
+ "aria-valuemax": 100,
321
+ tabIndex: 0,
322
+ children: [/* @__PURE__ */ d("div", {
323
+ className: "absolute left-0 top-0 h-full rounded-pill bg-white transition-[width] duration-75",
324
+ style: { width: `${b}%` }
325
+ }), /* @__PURE__ */ d("div", {
326
+ className: "absolute top-1/2 -translate-y-1/2 h-3 w-3 rounded-pill bg-white shadow-raised opacity-0 group-hover/progress:opacity-100 transition-opacity",
327
+ style: {
328
+ left: `${b}%`,
329
+ marginLeft: "-6px"
330
+ }
331
+ })]
332
+ }), /* @__PURE__ */ f("div", {
333
+ className: "flex items-center gap-ds-03",
334
+ children: [
335
+ /* @__PURE__ */ d("button", {
336
+ onClick: L,
337
+ className: "text-white hover:text-white/80",
338
+ "aria-label": p ? "Pause" : "Play",
339
+ title: p ? "Pause" : "Play",
340
+ children: p ? /* @__PURE__ */ d(r, {
341
+ icon: h,
342
+ size: "lg"
343
+ }) : /* @__PURE__ */ d(r, {
344
+ icon: g,
345
+ size: "lg"
346
+ })
347
+ }),
348
+ /* @__PURE__ */ d(c, {
349
+ volume: +!D,
350
+ muted: D,
351
+ onVolumeChange: (e) => {
352
+ a.current && (a.current.volume = e), e > 0 && D && (O(!1), a.current && (a.current.muted = !1));
353
+ },
354
+ onMuteToggle: () => {
355
+ O(!D), a.current && (a.current.muted = !D);
356
+ },
357
+ variant: "dark"
358
+ }),
359
+ /* @__PURE__ */ f("span", {
360
+ className: "text-[11px] font-mono text-white/70 tabular-nums",
361
+ children: [
362
+ s(T),
363
+ " / ",
364
+ s(C)
365
+ ]
366
+ }),
367
+ /* @__PURE__ */ d("div", { className: "flex-1" }),
368
+ /* @__PURE__ */ f("button", {
369
+ onClick: () => I(1),
370
+ className: "text-[11px] font-mono text-white/70 hover:text-white px-1 rounded-control-inner hover:bg-white/10 transition-colors",
371
+ "aria-label": `Playback speed: ${N}x`,
372
+ children: [N, "x"]
373
+ }),
374
+ /* @__PURE__ */ d("button", {
375
+ onClick: () => a.current?.requestFullscreen?.(),
376
+ className: "text-white hover:text-white/80",
377
+ "aria-label": "Fullscreen (F)",
378
+ title: "Fullscreen",
379
+ children: /* @__PURE__ */ d(r, {
380
+ icon: m,
381
+ size: "sm"
382
+ })
383
+ })
384
+ ]
385
+ })]
386
+ }) })
387
+ ]
388
+ });
389
+ }
390
+ //#endregion
391
+ //#region src/composed/file-preview.tsx
392
+ var C = u.lazy(() => import("../_chunks/image-preview.js")), w = u.lazy(() => import("../_chunks/document-preview.js"));
393
+ function T(e, t) {
394
+ if (t) {
395
+ if (t.startsWith("image/")) return "image";
396
+ if (t === "application/pdf") return "pdf";
397
+ if (t.startsWith("video/")) return "video";
398
+ if (t.startsWith("audio/")) return "audio";
399
+ }
400
+ let n = e.split("?")[0].split(".").pop()?.toLowerCase();
401
+ return [
402
+ "jpg",
403
+ "jpeg",
404
+ "png",
405
+ "gif",
406
+ "webp",
407
+ "svg",
408
+ "avif",
409
+ "bmp"
410
+ ].includes(n ?? "") ? "image" : n === "pdf" ? "pdf" : [
411
+ "mp4",
412
+ "webm",
413
+ "ogg",
414
+ "mov"
415
+ ].includes(n ?? "") ? "video" : [
416
+ "mp3",
417
+ "wav",
418
+ "ogg",
419
+ "aac",
420
+ "flac"
421
+ ].includes(n ?? "") ? "audio" : e.includes("figma.com") || e.includes("loom.com") || e.includes("youtube.com") || e.includes("youtu.be") || e.includes("vimeo.com") ? "embed" : "image";
422
+ }
423
+ function E(e) {
424
+ let t = e.match(/(?:youtube\.com\/watch\?v=|youtu\.be\/)([^&?]+)/);
425
+ if (t) return `https://www.youtube.com/embed/${t[1]}`;
426
+ let n = e.match(/vimeo\.com\/(\d+)/);
427
+ if (n) return `https://player.vimeo.com/video/${n[1]}`;
428
+ if (e.includes("figma.com")) return `https://www.figma.com/embed?embed_host=share&url=${encodeURIComponent(e)}`;
429
+ let r = e.match(/loom\.com\/share\/([^?]+)/);
430
+ return r ? `https://www.loom.com/embed/${r[1]}` : e;
431
+ }
432
+ function D({ url: e, type: t, mimeType: s, alt: c, initialPage: l = 1, fileName: m, fileSize: h, onError: g, className: _, ...v }) {
433
+ let x = t ?? T(e, s), D = /* @__PURE__ */ d(o, { className: "h-64 w-full rounded-control" });
434
+ return /* @__PURE__ */ f("div", {
435
+ className: n("flex flex-col gap-ds-03", _),
436
+ ...v,
437
+ children: [
438
+ (m || h) && /* @__PURE__ */ f("div", {
439
+ className: "flex items-center gap-ds-03",
440
+ children: [m && /* @__PURE__ */ d("span", {
441
+ className: "text-ds-sm font-semibold text-surface-fg truncate",
442
+ children: m
443
+ }), h && /* @__PURE__ */ d(i, {
444
+ variant: "subtle",
445
+ size: "xs",
446
+ children: h
447
+ })]
448
+ }),
449
+ x === "image" && /* @__PURE__ */ d(u.Suspense, {
450
+ fallback: D,
451
+ children: /* @__PURE__ */ d(C, {
452
+ url: e,
453
+ alt: c,
454
+ onError: g
455
+ })
456
+ }),
457
+ x === "pdf" && /* @__PURE__ */ d(u.Suspense, {
458
+ fallback: D,
459
+ children: /* @__PURE__ */ d(w, {
460
+ url: e,
461
+ initialPage: l,
462
+ onError: g
463
+ })
464
+ }),
465
+ x === "video" && /* @__PURE__ */ d(S, {
466
+ url: e,
467
+ onError: g
468
+ }),
469
+ x === "audio" && /* @__PURE__ */ d(y, {
470
+ url: e,
471
+ fileName: m,
472
+ onError: g
473
+ }),
474
+ x === "embed" && /* @__PURE__ */ d(b, {
475
+ url: e,
476
+ embedUrl: E(e),
477
+ onError: g
478
+ }),
479
+ x !== "audio" && /* @__PURE__ */ d("div", {
480
+ className: "flex justify-end",
481
+ children: /* @__PURE__ */ d(a, {
482
+ variant: "ghost",
483
+ size: "xs",
484
+ startIcon: /* @__PURE__ */ d(r, { icon: p }),
485
+ asChild: !0,
486
+ children: /* @__PURE__ */ d("a", {
487
+ href: e,
488
+ download: !0,
489
+ target: "_blank",
490
+ rel: "noopener noreferrer",
491
+ children: "Download"
492
+ })
493
+ })
494
+ })
495
+ ]
496
+ });
497
+ }
498
+ //#endregion
499
+ export { D as FilePreview };