@devalok/shilp-sutra 0.49.3 → 0.49.4

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 (313) hide show
  1. package/dist/_chunks/badge-group.js.map +1 -1
  2. package/dist/_chunks/block-shell.js.map +1 -1
  3. package/dist/_chunks/chart-container.js.map +1 -1
  4. package/dist/_chunks/chat.js.map +1 -1
  5. package/dist/_chunks/colors.js.map +1 -1
  6. package/dist/_chunks/document-preview.js.map +1 -1
  7. package/dist/_chunks/emoji-suggestion.js.map +1 -1
  8. package/dist/_chunks/emoji.js +2 -2
  9. package/dist/_chunks/emoji.js.map +1 -1
  10. package/dist/_chunks/field-state.js.map +1 -1
  11. package/dist/_chunks/grid-lines.js.map +1 -1
  12. package/dist/_chunks/image-preview.js.map +1 -1
  13. package/dist/_chunks/keybinding.js.map +1 -1
  14. package/dist/_chunks/link-context.js.map +1 -1
  15. package/dist/_chunks/mention-suggestion.js.map +1 -1
  16. package/dist/_chunks/motion-provider.js.map +1 -1
  17. package/dist/_chunks/normalize-icon.js.map +1 -1
  18. package/dist/_chunks/oauth-button.js.map +1 -1
  19. package/dist/_chunks/popover.js.map +1 -1
  20. package/dist/_chunks/primitives.js +1123 -1153
  21. package/dist/_chunks/primitives.js.map +1 -1
  22. package/dist/_chunks/shared.js.map +1 -1
  23. package/dist/_chunks/success.js.map +1 -1
  24. package/dist/_chunks/tiptap.js +4283 -3460
  25. package/dist/_chunks/tiptap.js.map +1 -1
  26. package/dist/_chunks/tooltip.js.map +1 -1
  27. package/dist/_chunks/tree-view.js +1 -1
  28. package/dist/_chunks/tree-view.js.map +1 -1
  29. package/dist/_chunks/use-calendar.js.map +1 -1
  30. package/dist/_chunks/use-controllable-open.js.map +1 -1
  31. package/dist/_chunks/vendor-client.js +86 -59
  32. package/dist/_chunks/vendor-client.js.map +1 -1
  33. package/dist/_chunks/vendor-utils.js +555 -513
  34. package/dist/_chunks/vendor-utils.js.map +1 -1
  35. package/dist/ai/ai-command-provider.d.ts +1 -1
  36. package/dist/ai/ai-command-provider.d.ts.map +1 -1
  37. package/dist/ai/ai-command-provider.js.map +1 -1
  38. package/dist/ai/block-renderer.js.map +1 -1
  39. package/dist/ai/blocks/block-shell.d.ts +1 -1
  40. package/dist/ai/blocks/block-shell.d.ts.map +1 -1
  41. package/dist/ai/blocks/block-table.d.ts +1 -1
  42. package/dist/ai/blocks/block-table.d.ts.map +1 -1
  43. package/dist/ai/blocks/confirm.d.ts +1 -1
  44. package/dist/ai/blocks/confirm.d.ts.map +1 -1
  45. package/dist/ai/blocks/divider.d.ts +1 -1
  46. package/dist/ai/blocks/divider.d.ts.map +1 -1
  47. package/dist/ai/blocks/error.d.ts +1 -1
  48. package/dist/ai/blocks/error.d.ts.map +1 -1
  49. package/dist/ai/blocks/error.js.map +1 -1
  50. package/dist/ai/blocks/info.d.ts +1 -1
  51. package/dist/ai/blocks/info.d.ts.map +1 -1
  52. package/dist/ai/blocks/loading.d.ts +1 -1
  53. package/dist/ai/blocks/loading.d.ts.map +1 -1
  54. package/dist/ai/blocks/stat-row.d.ts +1 -1
  55. package/dist/ai/blocks/stat-row.d.ts.map +1 -1
  56. package/dist/ai/blocks/success.d.ts +1 -1
  57. package/dist/ai/blocks/success.d.ts.map +1 -1
  58. package/dist/ai/blocks/text.d.ts +1 -1
  59. package/dist/ai/blocks/text.d.ts.map +1 -1
  60. package/dist/ai/blocks/text.js.map +1 -1
  61. package/dist/ai/command-bar.js.map +1 -1
  62. package/dist/ai/conversation.js.map +1 -1
  63. package/dist/ai/devadoot-icon.d.ts +1 -1
  64. package/dist/ai/devadoot-icon.d.ts.map +1 -1
  65. package/dist/ai/index.js.map +1 -1
  66. package/dist/composed/activity-feed.js.map +1 -1
  67. package/dist/composed/avatar-group.js.map +1 -1
  68. package/dist/composed/bulk-action-bar.js.map +1 -1
  69. package/dist/composed/command-palette.js.map +1 -1
  70. package/dist/composed/confirm-dialog.js.map +1 -1
  71. package/dist/composed/content-card.js.map +1 -1
  72. package/dist/composed/date-picker/index.js.map +1 -1
  73. package/dist/composed/deadline-indicator.js.map +1 -1
  74. package/dist/composed/emoji-picker.d.ts +2 -2
  75. package/dist/composed/emoji-picker.d.ts.map +1 -1
  76. package/dist/composed/emoji-picker.js.map +1 -1
  77. package/dist/composed/empty-state.js.map +1 -1
  78. package/dist/composed/error-boundary.d.ts +1 -1
  79. package/dist/composed/error-boundary.js.map +1 -1
  80. package/dist/composed/extensions/emoji-node.js.map +1 -1
  81. package/dist/composed/file-preview/audio-preview.d.ts +2 -1
  82. package/dist/composed/file-preview/audio-preview.d.ts.map +1 -1
  83. package/dist/composed/file-preview/document-preview.d.ts +2 -1
  84. package/dist/composed/file-preview/document-preview.d.ts.map +1 -1
  85. package/dist/composed/file-preview/embed-preview.d.ts +2 -1
  86. package/dist/composed/file-preview/embed-preview.d.ts.map +1 -1
  87. package/dist/composed/file-preview/image-preview.d.ts +2 -1
  88. package/dist/composed/file-preview/image-preview.d.ts.map +1 -1
  89. package/dist/composed/file-preview/shared.d.ts +5 -5
  90. package/dist/composed/file-preview/shared.d.ts.map +1 -1
  91. package/dist/composed/file-preview/video-preview.d.ts +2 -1
  92. package/dist/composed/file-preview/video-preview.d.ts.map +1 -1
  93. package/dist/composed/file-preview.d.ts +1 -1
  94. package/dist/composed/file-preview.d.ts.map +1 -1
  95. package/dist/composed/file-preview.js.map +1 -1
  96. package/dist/composed/filter-bar.d.ts +2 -2
  97. package/dist/composed/filter-bar.d.ts.map +1 -1
  98. package/dist/composed/filter-bar.js.map +1 -1
  99. package/dist/composed/form-section.js.map +1 -1
  100. package/dist/composed/global-loading.js.map +1 -1
  101. package/dist/composed/inline-edit.js.map +1 -1
  102. package/dist/composed/lib/string-utils.js.map +1 -1
  103. package/dist/composed/loading-skeleton.js.map +1 -1
  104. package/dist/composed/markdown-viewer.js.map +1 -1
  105. package/dist/composed/master-detail.d.ts +3 -3
  106. package/dist/composed/master-detail.d.ts.map +1 -1
  107. package/dist/composed/master-detail.js.map +1 -1
  108. package/dist/composed/member-picker.js.map +1 -1
  109. package/dist/composed/multi-select-popover.js.map +1 -1
  110. package/dist/composed/page-header.js.map +1 -1
  111. package/dist/composed/page-skeletons.js.map +1 -1
  112. package/dist/composed/priority-indicator.js.map +1 -1
  113. package/dist/composed/responsive-modal.js +8 -4
  114. package/dist/composed/responsive-modal.js.map +1 -1
  115. package/dist/composed/rich-chat-input/attachment-strip.d.ts +2 -1
  116. package/dist/composed/rich-chat-input/attachment-strip.d.ts.map +1 -1
  117. package/dist/composed/rich-chat-input/chat-toolbar.d.ts +17 -17
  118. package/dist/composed/rich-chat-input/chat-toolbar.d.ts.map +1 -1
  119. package/dist/composed/rich-chat-input/recording-overlay.d.ts +2 -1
  120. package/dist/composed/rich-chat-input/recording-overlay.d.ts.map +1 -1
  121. package/dist/composed/rich-chat-input/reply-banner.d.ts +2 -1
  122. package/dist/composed/rich-chat-input/reply-banner.d.ts.map +1 -1
  123. package/dist/composed/rich-chat-input/schedule-send.d.ts +4 -3
  124. package/dist/composed/rich-chat-input/schedule-send.d.ts.map +1 -1
  125. package/dist/composed/rich-chat-input.js +2 -1
  126. package/dist/composed/rich-chat-input.js.map +1 -1
  127. package/dist/composed/rich-text-editor.js +2 -1
  128. package/dist/composed/rich-text-editor.js.map +1 -1
  129. package/dist/composed/schedule-view.js.map +1 -1
  130. package/dist/composed/simple-tooltip.js.map +1 -1
  131. package/dist/composed/status-badge.js.map +1 -1
  132. package/dist/hooks/use-color-mode.js +2 -1
  133. package/dist/hooks/use-color-mode.js.map +1 -1
  134. package/dist/hooks/use-mobile.js.map +1 -1
  135. package/dist/hooks/use-touch-device.js.map +1 -1
  136. package/dist/hooks/use-viewport-height.js.map +1 -1
  137. package/dist/motion/index.js.map +1 -1
  138. package/dist/motion/motion-provider.d.ts +1 -1
  139. package/dist/motion/motion-provider.d.ts.map +1 -1
  140. package/dist/motion/primitives-index.js.map +1 -1
  141. package/dist/shell/app-command-palette.js.map +1 -1
  142. package/dist/shell/bottom-navbar.js.map +1 -1
  143. package/dist/shell/command-registry.d.ts +1 -1
  144. package/dist/shell/command-registry.d.ts.map +1 -1
  145. package/dist/shell/command-registry.js.map +1 -1
  146. package/dist/shell/notification-center.js.map +1 -1
  147. package/dist/shell/notification-preferences.js.map +1 -1
  148. package/dist/shell/sidebar.js.map +1 -1
  149. package/dist/shell/top-bar.js.map +1 -1
  150. package/dist/ui/accordion.js.map +1 -1
  151. package/dist/ui/alert-dialog.js.map +1 -1
  152. package/dist/ui/alert.js.map +1 -1
  153. package/dist/ui/aspect-ratio.js.map +1 -1
  154. package/dist/ui/autocomplete.js.map +1 -1
  155. package/dist/ui/avatar.d.ts +1 -1
  156. package/dist/ui/avatar.js.map +1 -1
  157. package/dist/ui/badge-group.d.ts +1 -1
  158. package/dist/ui/badge-group.d.ts.map +1 -1
  159. package/dist/ui/badge-indicator.d.ts +1 -1
  160. package/dist/ui/badge-indicator.d.ts.map +1 -1
  161. package/dist/ui/badge-indicator.js.map +1 -1
  162. package/dist/ui/banner.js.map +1 -1
  163. package/dist/ui/breadcrumb.d.ts +2 -2
  164. package/dist/ui/breadcrumb.js.map +1 -1
  165. package/dist/ui/button-group.js.map +1 -1
  166. package/dist/ui/button-processing.d.ts +2 -1
  167. package/dist/ui/button-processing.d.ts.map +1 -1
  168. package/dist/ui/button-processing.js.map +1 -1
  169. package/dist/ui/button.js.map +1 -1
  170. package/dist/ui/card.js +1 -1
  171. package/dist/ui/card.js.map +1 -1
  172. package/dist/ui/charts/_internal/axes.d.ts +2 -1
  173. package/dist/ui/charts/_internal/axes.d.ts.map +1 -1
  174. package/dist/ui/charts/_internal/grid-lines.d.ts +2 -1
  175. package/dist/ui/charts/_internal/grid-lines.d.ts.map +1 -1
  176. package/dist/ui/charts/_internal/legend.d.ts +2 -1
  177. package/dist/ui/charts/_internal/legend.d.ts.map +1 -1
  178. package/dist/ui/charts/_internal/tooltip.d.ts +1 -1
  179. package/dist/ui/charts/_internal/tooltip.d.ts.map +1 -1
  180. package/dist/ui/charts/area-chart.js.map +1 -1
  181. package/dist/ui/charts/bar-chart.js.map +1 -1
  182. package/dist/ui/charts/gauge-chart.js.map +1 -1
  183. package/dist/ui/charts/line-chart.js.map +1 -1
  184. package/dist/ui/charts/pie-chart.js.map +1 -1
  185. package/dist/ui/charts/radar-chart.js.map +1 -1
  186. package/dist/ui/charts/sparkline.js +2 -2
  187. package/dist/ui/charts/sparkline.js.map +1 -1
  188. package/dist/ui/chat/date-separator.d.ts +2 -1
  189. package/dist/ui/chat/date-separator.d.ts.map +1 -1
  190. package/dist/ui/chat/message.d.ts +8 -8
  191. package/dist/ui/chat/message.d.ts.map +1 -1
  192. package/dist/ui/chat/typing-indicator.d.ts +2 -1
  193. package/dist/ui/chat/typing-indicator.d.ts.map +1 -1
  194. package/dist/ui/chat/unread-separator.d.ts +2 -1
  195. package/dist/ui/chat/unread-separator.d.ts.map +1 -1
  196. package/dist/ui/checkbox.js.map +1 -1
  197. package/dist/ui/code.js.map +1 -1
  198. package/dist/ui/collapsible.js.map +1 -1
  199. package/dist/ui/color-input.js.map +1 -1
  200. package/dist/ui/color-swatch.js.map +1 -1
  201. package/dist/ui/combobox.js +15 -6
  202. package/dist/ui/combobox.js.map +1 -1
  203. package/dist/ui/container.js.map +1 -1
  204. package/dist/ui/context-menu.d.ts +2 -2
  205. package/dist/ui/context-menu.js.map +1 -1
  206. package/dist/ui/data-table-body.d.ts +1 -1
  207. package/dist/ui/data-table-body.d.ts.map +1 -1
  208. package/dist/ui/data-table-body.js +1 -1
  209. package/dist/ui/data-table-body.js.map +1 -1
  210. package/dist/ui/data-table-bulk-actions.d.ts +2 -1
  211. package/dist/ui/data-table-bulk-actions.d.ts.map +1 -1
  212. package/dist/ui/data-table-bulk-actions.js.map +1 -1
  213. package/dist/ui/data-table-card.d.ts +1 -1
  214. package/dist/ui/data-table-card.d.ts.map +1 -1
  215. package/dist/ui/data-table-card.js.map +1 -1
  216. package/dist/ui/data-table-context.d.ts +1 -1
  217. package/dist/ui/data-table-context.d.ts.map +1 -1
  218. package/dist/ui/data-table-context.js.map +1 -1
  219. package/dist/ui/data-table-header.d.ts +2 -1
  220. package/dist/ui/data-table-header.d.ts.map +1 -1
  221. package/dist/ui/data-table-header.js.map +1 -1
  222. package/dist/ui/data-table-pagination.d.ts +2 -1
  223. package/dist/ui/data-table-pagination.d.ts.map +1 -1
  224. package/dist/ui/data-table-pagination.js.map +1 -1
  225. package/dist/ui/data-table-toolbar.d.ts +1 -1
  226. package/dist/ui/data-table-toolbar.d.ts.map +1 -1
  227. package/dist/ui/data-table-toolbar.js.map +1 -1
  228. package/dist/ui/data-table.d.ts +1 -1
  229. package/dist/ui/data-table.d.ts.map +1 -1
  230. package/dist/ui/data-table.js.map +1 -1
  231. package/dist/ui/devalok-grain.d.ts +2 -1
  232. package/dist/ui/devalok-grain.d.ts.map +1 -1
  233. package/dist/ui/devalok-grain.js.map +1 -1
  234. package/dist/ui/dialog.js.map +1 -1
  235. package/dist/ui/dot.js +1 -1
  236. package/dist/ui/dot.js.map +1 -1
  237. package/dist/ui/dropdown-menu.d.ts +1 -1
  238. package/dist/ui/dropdown-menu.js.map +1 -1
  239. package/dist/ui/file-upload.js.map +1 -1
  240. package/dist/ui/form.js.map +1 -1
  241. package/dist/ui/hover-card.js.map +1 -1
  242. package/dist/ui/icon-button.js.map +1 -1
  243. package/dist/ui/icon-context.d.ts +1 -1
  244. package/dist/ui/icon-context.d.ts.map +1 -1
  245. package/dist/ui/icon-context.js.map +1 -1
  246. package/dist/ui/icon-group.js.map +1 -1
  247. package/dist/ui/icon.js.map +1 -1
  248. package/dist/ui/index.js.map +1 -1
  249. package/dist/ui/input-otp.js.map +1 -1
  250. package/dist/ui/input.js.map +1 -1
  251. package/dist/ui/label.js.map +1 -1
  252. package/dist/ui/lib/bottom-sheet.d.ts +1 -1
  253. package/dist/ui/lib/bottom-sheet.d.ts.map +1 -1
  254. package/dist/ui/lib/date-utils.js.map +1 -1
  255. package/dist/ui/lib/link-context.d.ts +1 -1
  256. package/dist/ui/lib/link-context.d.ts.map +1 -1
  257. package/dist/ui/lib/motion.js.map +1 -1
  258. package/dist/ui/lib/utils.js.map +1 -1
  259. package/dist/ui/link.js.map +1 -1
  260. package/dist/ui/menubar.d.ts +1 -1
  261. package/dist/ui/menubar.js.map +1 -1
  262. package/dist/ui/navigation-menu.js +14 -9
  263. package/dist/ui/navigation-menu.js.map +1 -1
  264. package/dist/ui/number-input.js.map +1 -1
  265. package/dist/ui/pagination.js.map +1 -1
  266. package/dist/ui/progress-ring.js.map +1 -1
  267. package/dist/ui/progress.js.map +1 -1
  268. package/dist/ui/radio.js.map +1 -1
  269. package/dist/ui/search-input.js.map +1 -1
  270. package/dist/ui/segmented-control.js.map +1 -1
  271. package/dist/ui/select.js.map +1 -1
  272. package/dist/ui/separator.js.map +1 -1
  273. package/dist/ui/sheet.js.map +1 -1
  274. package/dist/ui/sidebar.js +1 -1
  275. package/dist/ui/sidebar.js.map +1 -1
  276. package/dist/ui/skeleton.js.map +1 -1
  277. package/dist/ui/slider.js.map +1 -1
  278. package/dist/ui/spinner.js.map +1 -1
  279. package/dist/ui/split-button.js.map +1 -1
  280. package/dist/ui/stack.js.map +1 -1
  281. package/dist/ui/stat-card.js.map +1 -1
  282. package/dist/ui/stat-flash.d.ts +2 -1
  283. package/dist/ui/stat-flash.d.ts.map +1 -1
  284. package/dist/ui/stat-flash.js +1 -1
  285. package/dist/ui/stat-flash.js.map +1 -1
  286. package/dist/ui/stepper.d.ts +1 -1
  287. package/dist/ui/stepper.d.ts.map +1 -1
  288. package/dist/ui/stepper.js +1 -1
  289. package/dist/ui/stepper.js.map +1 -1
  290. package/dist/ui/surface.js.map +1 -1
  291. package/dist/ui/switch.d.ts +1 -1
  292. package/dist/ui/switch.js.map +1 -1
  293. package/dist/ui/table-row-link.js.map +1 -1
  294. package/dist/ui/table.js.map +1 -1
  295. package/dist/ui/tabs.js.map +1 -1
  296. package/dist/ui/text.js.map +1 -1
  297. package/dist/ui/textarea.js.map +1 -1
  298. package/dist/ui/toast-registry.js.map +1 -1
  299. package/dist/ui/toast.d.ts +4 -4
  300. package/dist/ui/toast.d.ts.map +1 -1
  301. package/dist/ui/toast.js +5 -3
  302. package/dist/ui/toast.js.map +1 -1
  303. package/dist/ui/toaster.js.map +1 -1
  304. package/dist/ui/toggle-group.js.map +1 -1
  305. package/dist/ui/toggle.js.map +1 -1
  306. package/dist/ui/tooltip.js.map +1 -1
  307. package/dist/ui/truncated-text.js.map +1 -1
  308. package/dist/ui/visually-hidden.js.map +1 -1
  309. package/llms.txt +1 -1
  310. package/mcp-manifest.json +1 -1
  311. package/package.json +21 -21
  312. package/skill/SKILL.md +1 -1
  313. package/skill/references/components.md +1 -1
@@ -1,7 +1,8 @@
1
1
  "use client";
2
+ import * as React from 'react';
2
3
  export default function ImagePreview({ url, alt, onError }: {
3
4
  url: string;
4
5
  alt?: string;
5
6
  onError?: (msg: string) => void;
6
- }): import("react/jsx-runtime").JSX.Element;
7
+ }): React.JSX.Element;
7
8
  //# sourceMappingURL=image-preview.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"image-preview.d.ts","sourceRoot":"","sources":["../../../src/composed/file-preview/image-preview.tsx"],"names":[],"mappings":"AAwBA,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,2CA6GzH"}
1
+ {"version":3,"file":"image-preview.d.ts","sourceRoot":"","sources":["../../../src/composed/file-preview/image-preview.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAc9B,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,qBA6GzH"}
@@ -3,12 +3,12 @@ import * as React from 'react';
3
3
  export declare function ErrorFallback({ message, url }: {
4
4
  message: string;
5
5
  url: string;
6
- }): import("react/jsx-runtime").JSX.Element;
6
+ }): React.JSX.Element;
7
7
  export declare function Toolbar({ children, className }: {
8
8
  children: React.ReactNode;
9
9
  className?: string;
10
- }): import("react/jsx-runtime").JSX.Element;
11
- export declare function ToolbarDivider(): import("react/jsx-runtime").JSX.Element;
10
+ }): React.JSX.Element;
11
+ export declare function ToolbarDivider(): React.JSX.Element;
12
12
  export declare function MediaSlider({ value, max, step, onValueChange, tone, ariaLabel, disabled, className, }: {
13
13
  value: number;
14
14
  max?: number;
@@ -18,13 +18,13 @@ export declare function MediaSlider({ value, max, step, onValueChange, tone, ari
18
18
  ariaLabel: string;
19
19
  disabled?: boolean;
20
20
  className?: string;
21
- }): import("react/jsx-runtime").JSX.Element;
21
+ }): React.JSX.Element;
22
22
  export declare function VolumeControl({ volume, muted, onVolumeChange, onMuteToggle, variant, }: {
23
23
  volume: number;
24
24
  muted: boolean;
25
25
  onVolumeChange: (v: number) => void;
26
26
  onMuteToggle: () => void;
27
27
  variant?: 'light' | 'dark';
28
- }): import("react/jsx-runtime").JSX.Element;
28
+ }): React.JSX.Element;
29
29
  export declare function formatTime(s: number): string;
30
30
  //# sourceMappingURL=shared.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/composed/file-preview/shared.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAW9B,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,2CAa/E;AAMD,wBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,2CAcjG;AAED,wBAAgB,cAAc,4CAE7B;AAWD,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,GAAS,EACT,IAAQ,EACR,aAAa,EACb,IAAc,EACd,SAAS,EACT,QAAQ,EACR,SAAS,GACV,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,2CAoCA;AAMD,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,KAAK,EACL,cAAc,EACd,YAAY,EACZ,OAAiB,GAClB,EAAE;IACD,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,OAAO,CAAA;IACd,cAAc,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC,YAAY,EAAE,MAAM,IAAI,CAAA;IACxB,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAC3B,2CAsBA;AAMD,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAO5C"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/composed/file-preview/shared.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAW9B,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,qBAa/E;AAMD,wBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,qBAcjG;AAED,wBAAgB,cAAc,sBAE7B;AAWD,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,GAAS,EACT,IAAQ,EACR,aAAa,EACb,IAAc,EACd,SAAS,EACT,QAAQ,EACR,SAAS,GACV,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,qBAoCA;AAMD,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,KAAK,EACL,cAAc,EACd,YAAY,EACZ,OAAiB,GAClB,EAAE;IACD,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,OAAO,CAAA;IACd,cAAc,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC,YAAY,EAAE,MAAM,IAAI,CAAA;IACxB,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAC3B,qBAsBA;AAMD,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAO5C"}
@@ -1,6 +1,7 @@
1
1
  "use client";
2
+ import * as React from 'react';
2
3
  export default function VideoPreview({ url, onError }: {
3
4
  url: string;
4
5
  onError?: (msg: string) => void;
5
- }): import("react/jsx-runtime").JSX.Element;
6
+ }): React.JSX.Element;
6
7
  //# sourceMappingURL=video-preview.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"video-preview.d.ts","sourceRoot":"","sources":["../../../src/composed/file-preview/video-preview.tsx"],"names":[],"mappings":"AAoBA,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,2CAoNtG"}
1
+ {"version":3,"file":"video-preview.d.ts","sourceRoot":"","sources":["../../../src/composed/file-preview/video-preview.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAY9B,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,qBAoNtG"}
@@ -16,7 +16,7 @@ export interface FilePreviewProps extends Omit<React.HTMLAttributes<HTMLDivEleme
16
16
  /** Called on errors (broken URL, CORS, timeout) */
17
17
  onError?: (error: string) => void;
18
18
  }
19
- declare function FilePreview({ url, type: typeProp, mimeType, alt, initialPage, fileName, fileSize, onError, className, ...props }: FilePreviewProps): import("react/jsx-runtime").JSX.Element;
19
+ declare function FilePreview({ url, type: typeProp, mimeType, alt, initialPage, fileName, fileSize, onError, className, ...props }: FilePreviewProps): React.JSX.Element;
20
20
  export { FilePreview };
21
21
  export type { FileType };
22
22
  //# sourceMappingURL=file-preview.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-preview.d.ts","sourceRoot":"","sources":["../../src/composed/file-preview.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAsB9B,KAAK,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAA;AAE7D,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,SAAS,CAAC;IAC7F,GAAG,EAAE,MAAM,CAAA;IACX,iDAAiD;IACjD,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,mCAAmC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,mDAAmD;IACnD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CAClC;AA8CD,iBAAS,WAAW,CAAC,EACnB,GAAG,EACH,IAAI,EAAE,QAAQ,EACd,QAAQ,EACR,GAAG,EACH,WAAe,EACf,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,SAAS,EACT,GAAG,KAAK,EACT,EAAE,gBAAgB,2CA2ClB;AAED,OAAO,EAAE,WAAW,EAAE,CAAA;AACtB,YAAY,EAAE,QAAQ,EAAE,CAAA"}
1
+ {"version":3,"file":"file-preview.d.ts","sourceRoot":"","sources":["../../src/composed/file-preview.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAsB9B,KAAK,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAA;AAE7D,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,SAAS,CAAC;IAC7F,GAAG,EAAE,MAAM,CAAA;IACX,iDAAiD;IACjD,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,mCAAmC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,mDAAmD;IACnD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CAClC;AA8CD,iBAAS,WAAW,CAAC,EACnB,GAAG,EACH,IAAI,EAAE,QAAQ,EACd,QAAQ,EACR,GAAG,EACH,WAAe,EACf,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,SAAS,EACT,GAAG,KAAK,EACT,EAAE,gBAAgB,qBA2ClB;AAED,OAAO,EAAE,WAAW,EAAE,CAAA;AACtB,YAAY,EAAE,QAAQ,EAAE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"file-preview.js","names":[],"sources":["../../src/composed/file-preview/audio-preview.tsx","../../src/composed/file-preview/embed-preview.tsx","../../src/composed/file-preview/video-preview.tsx","../../src/composed/file-preview.tsx"],"sourcesContent":["'use client'\n\nimport { IconPlayerPause,IconPlayerPlay } from '@tabler/icons-react'\nimport * as React from 'react'\n\nimport { Button } from '../../ui/button'\nimport { Icon } from '../../ui/icon'\nimport { TruncatedText } from '../../ui/truncated-text'\nimport { ErrorFallback, formatTime,MediaSlider,VolumeControl } from './shared'\n\n// ============================================================\n// Audio Preview — Branded mini-player (Spotify/SoundCloud style)\n// ============================================================\n\nexport default function AudioPreview({ url, fileName, onError }: { url: string; fileName?: string; onError?: (msg: string) => void }) {\n const audioRef = React.useRef<HTMLAudioElement>(null)\n const containerRef = React.useRef<HTMLDivElement>(null)\n const [playing, setPlaying] = React.useState(false)\n const [progress, setProgress] = React.useState(0)\n const [duration, setDuration] = React.useState(0)\n const [currentTime, setCurrentTime] = React.useState(0)\n const [volume, setVolume] = React.useState(1)\n const [muted, setMuted] = React.useState(false)\n const [error, setError] = React.useState(false)\n\n // Keyboard shortcuts\n React.useEffect(() => {\n function handleKeyDown(e: KeyboardEvent) {\n const el = containerRef.current\n if (!el || !el.contains(document.activeElement) && document.activeElement !== el) return\n const a = audioRef.current\n if (!a) return\n\n switch (e.key) {\n case ' ':\n e.preventDefault()\n setPlaying(prev => {\n if (prev) a.pause(); else a.play()\n return !prev\n })\n break\n case 'ArrowRight':\n e.preventDefault()\n a.currentTime = Math.min(a.duration || 0, a.currentTime + 5)\n break\n case 'ArrowLeft':\n e.preventDefault()\n a.currentTime = Math.max(0, a.currentTime - 5)\n break\n case 'm':\n e.preventDefault()\n setMuted(prev => {\n a.muted = !prev\n return !prev\n })\n break\n }\n }\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n \n }, [])\n\n function togglePlay() {\n if (!audioRef.current) return\n if (playing) audioRef.current.pause()\n else audioRef.current.play()\n setPlaying(!playing)\n }\n\n function handleSeek(nextProgress: number) {\n if (!audioRef.current || !duration) return\n audioRef.current.currentTime = (nextProgress / 100) * duration\n }\n\n function toggleMute() {\n if (!audioRef.current) return\n const next = !muted\n setMuted(next)\n audioRef.current.muted = next\n }\n\n if (error) return <ErrorFallback message=\"Could not load audio\" url={url} />\n\n return (\n <div ref={containerRef} className=\"rounded-surface bg-surface-raised shadow-raised overflow-hidden\" tabIndex={-1}>\n {/* eslint-disable-next-line jsx-a11y/media-has-caption */}\n <audio\n ref={audioRef}\n src={url}\n onTimeUpdate={() => {\n if (!audioRef.current) return\n setCurrentTime(audioRef.current.currentTime)\n if (audioRef.current.duration) setProgress((audioRef.current.currentTime / audioRef.current.duration) * 100)\n }}\n onLoadedMetadata={() => setDuration(audioRef.current?.duration ?? 0)}\n onEnded={() => setPlaying(false)}\n onError={() => { setError(true); onError?.('Audio failed to load') }}\n />\n\n {/* Progress bar — full width at top (Spotify style) */}\n <div className=\"px-ds-03 pt-ds-02\">\n <MediaSlider\n value={progress}\n max={100}\n step={0.1}\n onValueChange={handleSeek}\n tone=\"light\"\n ariaLabel=\"Audio progress\"\n />\n </div>\n\n {/* Controls */}\n <div className=\"flex items-center gap-ds-04 px-ds-05 py-ds-04\">\n <Button\n variant=\"solid\"\n size=\"icon-sm\"\n onClick={togglePlay}\n aria-label={playing ? 'Pause' : 'Play'}\n title={playing ? 'Pause' : 'Play'}\n className=\"shrink-0\"\n >\n {playing ? (\n <Icon icon={IconPlayerPause} size=\"sm\" />\n ) : (\n <Icon icon={IconPlayerPlay} size=\"sm\" className=\"ml-0.5\" />\n )}\n </Button>\n\n {/* File name + time */}\n <div className=\"flex-1 min-w-0\">\n {fileName && (\n <TruncatedText as=\"p\" mode=\"middle\" className=\"text-ds-sm font-semibold text-surface-fg\">\n {fileName}\n </TruncatedText>\n )}\n <p className=\"text-ds-xs font-mono text-surface-fg-muted tabular-nums\">\n {formatTime(currentTime)} / {formatTime(duration)}\n </p>\n </div>\n\n {/* Volume */}\n <VolumeControl\n volume={volume}\n muted={muted}\n onVolumeChange={(v) => {\n setVolume(v)\n if (audioRef.current) audioRef.current.volume = v\n if (v > 0 && muted) {\n setMuted(false)\n if (audioRef.current) audioRef.current.muted = false\n }\n }}\n onMuteToggle={toggleMute}\n variant=\"light\"\n />\n </div>\n </div>\n )\n}\n","'use client'\n\nimport { motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { tweens } from '../../ui/lib/motion'\nimport { Skeleton } from '../../ui/skeleton'\nimport { ErrorFallback } from './shared'\n\n// ============================================================\n// Embed Preview — 16:9 with error timeout\n// ============================================================\n\nexport default function EmbedPreview({ url, embedUrl, onError }: { url: string; embedUrl: string; onError?: (msg: string) => void }) {\n const [loaded, setLoaded] = React.useState(false)\n const [error, setError] = React.useState(false)\n\n // Timeout — if iframe doesn't load in 15s, show error\n React.useEffect(() => {\n const timer = setTimeout(() => {\n if (!loaded) { setError(true); onError?.('Embed timed out') }\n }, 15000)\n return () => clearTimeout(timer)\n }, [loaded, onError])\n\n if (error) return <ErrorFallback message=\"Could not load embed\" url={url} />\n\n return (\n <div className=\"relative w-full rounded-control overflow-hidden\" style={{ aspectRatio: '16 / 9' }}>\n {!loaded && <Skeleton className=\"absolute inset-0\" />}\n <motion.iframe\n src={embedUrl}\n title=\"Embedded content\"\n onLoad={() => setLoaded(true)}\n onError={() => { setError(true); onError?.('Embed failed to load') }}\n initial={{ opacity: 0 }}\n animate={{ opacity: loaded ? 1 : 0 }}\n transition={tweens.fade}\n className=\"absolute inset-0 h-full w-full border-none\"\n allowFullScreen\n />\n </div>\n )\n}\n","'use client'\n\nimport {\n IconMaximize,\n IconPlayerPause,\n IconPlayerPlay,\n} from '@tabler/icons-react'\nimport { AnimatePresence,motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { Icon } from '../../ui/icon'\nimport { springs, tweens } from '../../ui/lib/motion'\nimport { ErrorFallback, formatTime,MediaSlider,VolumeControl } from './shared'\n\n// ============================================================\n// Video Preview — Custom player with DS styling\n// ============================================================\n\nconst PLAYBACK_RATES = [0.5, 0.75, 1, 1.25, 1.5, 2] as const\n\nexport default function VideoPreview({ url, onError }: { url: string; onError?: (msg: string) => void }) {\n const videoRef = React.useRef<HTMLVideoElement>(null)\n const containerRef = React.useRef<HTMLDivElement>(null)\n const [playing, setPlaying] = React.useState(false)\n const [progress, setProgress] = React.useState(0)\n const [duration, setDuration] = React.useState(0)\n const [currentTime, setCurrentTime] = React.useState(0)\n const [muted, setMuted] = React.useState(false)\n const [error, setError] = React.useState(false)\n const [showControls, setShowControls] = React.useState(true)\n const [playbackRate, setPlaybackRate] = React.useState(1)\n // Kept current every render so the mount-time keydown handler (empty deps)\n // reads the live rate instead of the stale initial 1x. See #91.\n const playbackRateRef = React.useRef(playbackRate)\n playbackRateRef.current = playbackRate\n const hideTimer = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n\n React.useEffect(() => {\n return () => clearTimeout(hideTimer.current)\n }, [])\n\n // Keyboard shortcuts — YouTube style\n React.useEffect(() => {\n function handleKeyDown(e: KeyboardEvent) {\n const el = containerRef.current\n if (!el || !el.contains(document.activeElement) && document.activeElement !== el) return\n const v = videoRef.current\n if (!v) return\n\n switch (e.key) {\n case ' ':\n case 'k':\n e.preventDefault()\n setPlaying(prev => {\n if (prev) v.pause(); else v.play()\n return !prev\n })\n break\n case 'ArrowRight':\n e.preventDefault()\n v.currentTime = Math.min(v.duration, v.currentTime + 5)\n break\n case 'ArrowLeft':\n e.preventDefault()\n v.currentTime = Math.max(0, v.currentTime - 5)\n break\n case 'j':\n e.preventDefault()\n v.currentTime = Math.max(0, v.currentTime - 10)\n break\n case 'l':\n e.preventDefault()\n v.currentTime = Math.min(v.duration, v.currentTime + 10)\n break\n case 'm':\n e.preventDefault()\n setMuted(prev => {\n v.muted = !prev\n return !prev\n })\n break\n case 'f':\n e.preventDefault()\n v.requestFullscreen?.()\n break\n case '>':\n e.preventDefault()\n cyclePlaybackRate(1)\n break\n case '<':\n e.preventDefault()\n cyclePlaybackRate(-1)\n break\n }\n }\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [])\n\n function cyclePlaybackRate(direction: 1 | -1) {\n const idx = PLAYBACK_RATES.indexOf(playbackRateRef.current as typeof PLAYBACK_RATES[number])\n const nextIdx = Math.max(0, Math.min(PLAYBACK_RATES.length - 1, idx + direction))\n const next = PLAYBACK_RATES[nextIdx]\n setPlaybackRate(next)\n if (videoRef.current) videoRef.current.playbackRate = next\n }\n\n function togglePlay() {\n if (!videoRef.current) return\n if (playing) videoRef.current.pause()\n else videoRef.current.play()\n setPlaying(!playing)\n }\n\n function handleSeek(nextProgress: number) {\n if (!videoRef.current || !duration) return\n videoRef.current.currentTime = (nextProgress / 100) * duration\n }\n\n function handleMouseMove() {\n setShowControls(true)\n clearTimeout(hideTimer.current)\n if (playing) {\n hideTimer.current = setTimeout(() => setShowControls(false), 3000)\n }\n }\n\n if (error) return <ErrorFallback message=\"Could not load video\" url={url} />\n\n return (\n <div\n ref={containerRef}\n className=\"group relative rounded-control bg-black overflow-hidden\"\n onMouseMove={handleMouseMove}\n onMouseLeave={() => playing && setShowControls(false)}\n tabIndex={-1}\n >\n {/* eslint-disable-next-line jsx-a11y/media-has-caption */}\n <video\n ref={videoRef}\n src={url}\n className=\"max-h-[70vh] w-full\"\n onClick={togglePlay}\n muted={muted}\n onTimeUpdate={() => {\n if (!videoRef.current) return\n setCurrentTime(videoRef.current.currentTime)\n if (videoRef.current.duration) setProgress((videoRef.current.currentTime / videoRef.current.duration) * 100)\n }}\n onLoadedMetadata={() => setDuration(videoRef.current?.duration ?? 0)}\n onEnded={() => { setPlaying(false); setShowControls(true) }}\n onError={() => { setError(true); onError?.('Video failed to load') }}\n playsInline\n />\n\n {/* Play button overlay — shown when paused */}\n {!playing && (\n <motion.button\n initial={{ opacity: 0, scale: 0.8 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={springs.snappy}\n onClick={togglePlay}\n className=\"absolute inset-0 flex items-center justify-center bg-black/30\"\n aria-label=\"Play video\"\n >\n <div className=\"flex h-14 w-14 items-center justify-center rounded-pill bg-white/90 shadow-floating\">\n <Icon icon={IconPlayerPlay} size=\"xl\" className=\"text-surface-fg ml-0.5\" />\n </div>\n </motion.button>\n )}\n\n {/* Bottom controls — auto-hide after 3s during playback */}\n <AnimatePresence>\n {showControls && duration > 0 && (\n <motion.div\n initial={{ opacity: 0, y: 10 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 10 }}\n transition={tweens.fade}\n 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\"\n >\n {/* Progress bar */}\n <MediaSlider\n className=\"mb-ds-03\"\n value={progress}\n max={100}\n step={0.1}\n onValueChange={handleSeek}\n tone=\"dark\"\n ariaLabel=\"Video progress\"\n />\n\n {/* Controls row */}\n <div className=\"flex items-center gap-ds-03\">\n <button onClick={togglePlay} className=\"text-white hover:text-white/80\" aria-label={playing ? 'Pause' : 'Play'} title={playing ? 'Pause' : 'Play'}>\n {playing ? <Icon icon={IconPlayerPause} size=\"lg\" /> : <Icon icon={IconPlayerPlay} size=\"lg\" />}\n </button>\n <VolumeControl\n volume={muted ? 0 : 1}\n muted={muted}\n onVolumeChange={(v) => {\n if (videoRef.current) videoRef.current.volume = v\n if (v > 0 && muted) { setMuted(false); if (videoRef.current) videoRef.current.muted = false }\n }}\n onMuteToggle={() => { setMuted(!muted); if (videoRef.current) videoRef.current.muted = !muted }}\n variant=\"dark\"\n />\n <span className=\"text-ds-sm font-mono text-white/70 tabular-nums\">\n {formatTime(currentTime)} / {formatTime(duration)}\n </span>\n <div className=\"flex-1\" />\n <button\n onClick={() => cyclePlaybackRate(1)}\n className=\"text-ds-sm font-mono text-white/70 hover:text-white px-1 rounded-control-inner hover:bg-white/10 transition-colors\"\n aria-label={`Playback speed: ${playbackRate}x`}\n >\n {playbackRate}x\n </button>\n <button\n onClick={() => videoRef.current?.requestFullscreen?.()}\n className=\"text-white hover:text-white/80\"\n aria-label=\"Fullscreen (F)\"\n title=\"Fullscreen\"\n >\n <Icon icon={IconMaximize} size=\"sm\" />\n </button>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n )\n}\n","'use client'\n\nimport { IconDownload } from '@tabler/icons-react'\nimport * as React from 'react'\n\nimport { Badge } from '../ui/badge'\nimport { Button } from '../ui/button'\nimport { Icon } from '../ui/icon'\nimport { cn } from '../ui/lib/utils'\nimport { Skeleton } from '../ui/skeleton'\nimport { TruncatedText } from '../ui/truncated-text'\n\n// Sub-components: direct imports for non-peer-dep renderers,\n// React.lazy for renderers that pull in optional peer deps\n// (react-zoom-pan-pinch, react-pdf) to preserve code-splitting.\nconst LazyImagePreview = React.lazy(() => import('./file-preview/image-preview'))\nconst LazyDocumentPreview = React.lazy(() => import('./file-preview/document-preview'))\nimport AudioPreview from './file-preview/audio-preview'\nimport EmbedPreview from './file-preview/embed-preview'\nimport VideoPreview from './file-preview/video-preview'\n\n// ============================================================\n// Types\n// ============================================================\n\ntype FileType = 'image' | 'pdf' | 'video' | 'audio' | 'embed'\n\nexport interface FilePreviewProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onError'> {\n url: string\n /** Auto-detected from URL/mimeType if omitted */\n type?: FileType\n mimeType?: string\n alt?: string\n /** PDF starting page @default 1 */\n initialPage?: number\n /** File name for display */\n fileName?: string\n /** File size for display (e.g. '2.4 MB') */\n fileSize?: string\n /** Called on errors (broken URL, CORS, timeout) */\n onError?: (error: string) => void\n}\n\n// ============================================================\n// Type Detection\n// ============================================================\n\nfunction detectType(url: string, mimeType?: string): FileType {\n if (mimeType) {\n if (mimeType.startsWith('image/')) return 'image'\n if (mimeType === 'application/pdf') return 'pdf'\n if (mimeType.startsWith('video/')) return 'video'\n if (mimeType.startsWith('audio/')) return 'audio'\n }\n\n const ext = url.split('?')[0].split('.').pop()?.toLowerCase()\n if (['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'avif', 'bmp'].includes(ext ?? '')) return 'image'\n if (ext === 'pdf') return 'pdf'\n if (['mp4', 'webm', 'ogg', 'mov'].includes(ext ?? '')) return 'video'\n if (['mp3', 'wav', 'ogg', 'aac', 'flac'].includes(ext ?? '')) return 'audio'\n\n if (url.includes('figma.com') || url.includes('loom.com') || url.includes('youtube.com') || url.includes('youtu.be') || url.includes('vimeo.com')) {\n return 'embed'\n }\n\n return 'image'\n}\n\nfunction getEmbedUrl(url: string): string {\n const ytMatch = url.match(/(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/)([^&?]+)/)\n if (ytMatch) return `https://www.youtube.com/embed/${ytMatch[1]}`\n\n const vimeoMatch = url.match(/vimeo\\.com\\/(\\d+)/)\n if (vimeoMatch) return `https://player.vimeo.com/video/${vimeoMatch[1]}`\n\n if (url.includes('figma.com')) return `https://www.figma.com/embed?embed_host=share&url=${encodeURIComponent(url)}`\n\n const loomMatch = url.match(/loom\\.com\\/share\\/([^?]+)/)\n if (loomMatch) return `https://www.loom.com/embed/${loomMatch[1]}`\n\n return url\n}\n\n// ============================================================\n// FilePreview — Main component (router)\n// ============================================================\n\nfunction FilePreview({\n url,\n type: typeProp,\n mimeType,\n alt,\n initialPage = 1,\n fileName,\n fileSize,\n onError,\n className,\n ...props\n}: FilePreviewProps) {\n const type = typeProp ?? detectType(url, mimeType)\n const fallback = <Skeleton className=\"h-64 w-full rounded-control\" />\n\n return (\n <div className={cn('flex flex-col gap-ds-03', className)} {...props}>\n {/* File info bar */}\n {(fileName || fileSize) && (\n <div className=\"flex items-center gap-ds-03\">\n {fileName && (\n <TruncatedText mode=\"middle\" className=\"min-w-0 text-ds-sm font-semibold text-surface-fg\">\n {fileName}\n </TruncatedText>\n )}\n {fileSize && <Badge variant=\"subtle\" size=\"xs\">{fileSize}</Badge>}\n </div>\n )}\n\n {/* Preview */}\n {type === 'image' && (\n <React.Suspense fallback={fallback}>\n <LazyImagePreview url={url} alt={alt} onError={onError} />\n </React.Suspense>\n )}\n {type === 'pdf' && (\n <React.Suspense fallback={fallback}>\n <LazyDocumentPreview url={url} initialPage={initialPage} onError={onError} />\n </React.Suspense>\n )}\n {type === 'video' && <VideoPreview url={url} onError={onError} />}\n {type === 'audio' && <AudioPreview url={url} fileName={fileName} onError={onError} />}\n {type === 'embed' && <EmbedPreview url={url} embedUrl={getEmbedUrl(url)} onError={onError} />}\n\n {/* Download — not shown for audio (it has its own layout) */}\n {type !== 'audio' && (\n <div className=\"flex justify-end\">\n <Button variant=\"ghost\" size=\"xs\" startIcon={<Icon icon={IconDownload} />} asChild>\n <a href={url} download target=\"_blank\" rel=\"noopener noreferrer\">Download</a>\n </Button>\n </div>\n )}\n </div>\n )\n}\n\nexport { FilePreview }\nexport type { FileType }\n"],"mappings":"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"}
1
+ {"version":3,"file":"file-preview.js","names":[],"sources":["../../src/composed/file-preview/audio-preview.tsx","../../src/composed/file-preview/embed-preview.tsx","../../src/composed/file-preview/video-preview.tsx","../../src/composed/file-preview.tsx"],"sourcesContent":["'use client'\n\nimport { IconPlayerPause,IconPlayerPlay } from '@tabler/icons-react'\nimport * as React from 'react'\n\nimport { Button } from '../../ui/button'\nimport { Icon } from '../../ui/icon'\nimport { TruncatedText } from '../../ui/truncated-text'\nimport { ErrorFallback, formatTime,MediaSlider,VolumeControl } from './shared'\n\n// ============================================================\n// Audio Preview — Branded mini-player (Spotify/SoundCloud style)\n// ============================================================\n\nexport default function AudioPreview({ url, fileName, onError }: { url: string; fileName?: string; onError?: (msg: string) => void }) {\n const audioRef = React.useRef<HTMLAudioElement>(null)\n const containerRef = React.useRef<HTMLDivElement>(null)\n const [playing, setPlaying] = React.useState(false)\n const [progress, setProgress] = React.useState(0)\n const [duration, setDuration] = React.useState(0)\n const [currentTime, setCurrentTime] = React.useState(0)\n const [volume, setVolume] = React.useState(1)\n const [muted, setMuted] = React.useState(false)\n const [error, setError] = React.useState(false)\n\n // Keyboard shortcuts\n React.useEffect(() => {\n function handleKeyDown(e: KeyboardEvent) {\n const el = containerRef.current\n if (!el || !el.contains(document.activeElement) && document.activeElement !== el) return\n const a = audioRef.current\n if (!a) return\n\n switch (e.key) {\n case ' ':\n e.preventDefault()\n setPlaying(prev => {\n if (prev) a.pause(); else a.play()\n return !prev\n })\n break\n case 'ArrowRight':\n e.preventDefault()\n a.currentTime = Math.min(a.duration || 0, a.currentTime + 5)\n break\n case 'ArrowLeft':\n e.preventDefault()\n a.currentTime = Math.max(0, a.currentTime - 5)\n break\n case 'm':\n e.preventDefault()\n setMuted(prev => {\n a.muted = !prev\n return !prev\n })\n break\n }\n }\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n \n }, [])\n\n function togglePlay() {\n if (!audioRef.current) return\n if (playing) audioRef.current.pause()\n else audioRef.current.play()\n setPlaying(!playing)\n }\n\n function handleSeek(nextProgress: number) {\n if (!audioRef.current || !duration) return\n audioRef.current.currentTime = (nextProgress / 100) * duration\n }\n\n function toggleMute() {\n if (!audioRef.current) return\n const next = !muted\n setMuted(next)\n audioRef.current.muted = next\n }\n\n if (error) return <ErrorFallback message=\"Could not load audio\" url={url} />\n\n return (\n <div ref={containerRef} className=\"rounded-surface bg-surface-raised shadow-raised overflow-hidden\" tabIndex={-1}>\n {/* eslint-disable-next-line jsx-a11y/media-has-caption */}\n <audio\n ref={audioRef}\n src={url}\n onTimeUpdate={() => {\n if (!audioRef.current) return\n setCurrentTime(audioRef.current.currentTime)\n if (audioRef.current.duration) setProgress((audioRef.current.currentTime / audioRef.current.duration) * 100)\n }}\n onLoadedMetadata={() => setDuration(audioRef.current?.duration ?? 0)}\n onEnded={() => setPlaying(false)}\n onError={() => { setError(true); onError?.('Audio failed to load') }}\n />\n\n {/* Progress bar — full width at top (Spotify style) */}\n <div className=\"px-ds-03 pt-ds-02\">\n <MediaSlider\n value={progress}\n max={100}\n step={0.1}\n onValueChange={handleSeek}\n tone=\"light\"\n ariaLabel=\"Audio progress\"\n />\n </div>\n\n {/* Controls */}\n <div className=\"flex items-center gap-ds-04 px-ds-05 py-ds-04\">\n <Button\n variant=\"solid\"\n size=\"icon-sm\"\n onClick={togglePlay}\n aria-label={playing ? 'Pause' : 'Play'}\n title={playing ? 'Pause' : 'Play'}\n className=\"shrink-0\"\n >\n {playing ? (\n <Icon icon={IconPlayerPause} size=\"sm\" />\n ) : (\n <Icon icon={IconPlayerPlay} size=\"sm\" className=\"ml-0.5\" />\n )}\n </Button>\n\n {/* File name + time */}\n <div className=\"flex-1 min-w-0\">\n {fileName && (\n <TruncatedText as=\"p\" mode=\"middle\" className=\"text-ds-sm font-semibold text-surface-fg\">\n {fileName}\n </TruncatedText>\n )}\n <p className=\"text-ds-xs font-mono text-surface-fg-muted tabular-nums\">\n {formatTime(currentTime)} / {formatTime(duration)}\n </p>\n </div>\n\n {/* Volume */}\n <VolumeControl\n volume={volume}\n muted={muted}\n onVolumeChange={(v) => {\n setVolume(v)\n if (audioRef.current) audioRef.current.volume = v\n if (v > 0 && muted) {\n setMuted(false)\n if (audioRef.current) audioRef.current.muted = false\n }\n }}\n onMuteToggle={toggleMute}\n variant=\"light\"\n />\n </div>\n </div>\n )\n}\n","'use client'\n\nimport { motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { tweens } from '../../ui/lib/motion'\nimport { Skeleton } from '../../ui/skeleton'\nimport { ErrorFallback } from './shared'\n\n// ============================================================\n// Embed Preview — 16:9 with error timeout\n// ============================================================\n\nexport default function EmbedPreview({ url, embedUrl, onError }: { url: string; embedUrl: string; onError?: (msg: string) => void }) {\n const [loaded, setLoaded] = React.useState(false)\n const [error, setError] = React.useState(false)\n\n // Timeout — if iframe doesn't load in 15s, show error\n React.useEffect(() => {\n const timer = setTimeout(() => {\n if (!loaded) { setError(true); onError?.('Embed timed out') }\n }, 15000)\n return () => clearTimeout(timer)\n }, [loaded, onError])\n\n if (error) return <ErrorFallback message=\"Could not load embed\" url={url} />\n\n return (\n <div className=\"relative w-full rounded-control overflow-hidden\" style={{ aspectRatio: '16 / 9' }}>\n {!loaded && <Skeleton className=\"absolute inset-0\" />}\n <motion.iframe\n src={embedUrl}\n title=\"Embedded content\"\n onLoad={() => setLoaded(true)}\n onError={() => { setError(true); onError?.('Embed failed to load') }}\n initial={{ opacity: 0 }}\n animate={{ opacity: loaded ? 1 : 0 }}\n transition={tweens.fade}\n className=\"absolute inset-0 h-full w-full border-none\"\n allowFullScreen\n />\n </div>\n )\n}\n","'use client'\n\nimport {\n IconMaximize,\n IconPlayerPause,\n IconPlayerPlay,\n} from '@tabler/icons-react'\nimport { AnimatePresence,motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { Icon } from '../../ui/icon'\nimport { springs, tweens } from '../../ui/lib/motion'\nimport { ErrorFallback, formatTime,MediaSlider,VolumeControl } from './shared'\n\n// ============================================================\n// Video Preview — Custom player with DS styling\n// ============================================================\n\nconst PLAYBACK_RATES = [0.5, 0.75, 1, 1.25, 1.5, 2] as const\n\nexport default function VideoPreview({ url, onError }: { url: string; onError?: (msg: string) => void }) {\n const videoRef = React.useRef<HTMLVideoElement>(null)\n const containerRef = React.useRef<HTMLDivElement>(null)\n const [playing, setPlaying] = React.useState(false)\n const [progress, setProgress] = React.useState(0)\n const [duration, setDuration] = React.useState(0)\n const [currentTime, setCurrentTime] = React.useState(0)\n const [muted, setMuted] = React.useState(false)\n const [error, setError] = React.useState(false)\n const [showControls, setShowControls] = React.useState(true)\n const [playbackRate, setPlaybackRate] = React.useState(1)\n // Kept current every render so the mount-time keydown handler (empty deps)\n // reads the live rate instead of the stale initial 1x. See #91.\n const playbackRateRef = React.useRef(playbackRate)\n playbackRateRef.current = playbackRate\n const hideTimer = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n\n React.useEffect(() => {\n return () => clearTimeout(hideTimer.current)\n }, [])\n\n // Keyboard shortcuts — YouTube style\n React.useEffect(() => {\n function handleKeyDown(e: KeyboardEvent) {\n const el = containerRef.current\n if (!el || !el.contains(document.activeElement) && document.activeElement !== el) return\n const v = videoRef.current\n if (!v) return\n\n switch (e.key) {\n case ' ':\n case 'k':\n e.preventDefault()\n setPlaying(prev => {\n if (prev) v.pause(); else v.play()\n return !prev\n })\n break\n case 'ArrowRight':\n e.preventDefault()\n v.currentTime = Math.min(v.duration, v.currentTime + 5)\n break\n case 'ArrowLeft':\n e.preventDefault()\n v.currentTime = Math.max(0, v.currentTime - 5)\n break\n case 'j':\n e.preventDefault()\n v.currentTime = Math.max(0, v.currentTime - 10)\n break\n case 'l':\n e.preventDefault()\n v.currentTime = Math.min(v.duration, v.currentTime + 10)\n break\n case 'm':\n e.preventDefault()\n setMuted(prev => {\n v.muted = !prev\n return !prev\n })\n break\n case 'f':\n e.preventDefault()\n v.requestFullscreen?.()\n break\n case '>':\n e.preventDefault()\n cyclePlaybackRate(1)\n break\n case '<':\n e.preventDefault()\n cyclePlaybackRate(-1)\n break\n }\n }\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [])\n\n function cyclePlaybackRate(direction: 1 | -1) {\n const idx = PLAYBACK_RATES.indexOf(playbackRateRef.current as typeof PLAYBACK_RATES[number])\n const nextIdx = Math.max(0, Math.min(PLAYBACK_RATES.length - 1, idx + direction))\n const next = PLAYBACK_RATES[nextIdx]\n setPlaybackRate(next)\n if (videoRef.current) videoRef.current.playbackRate = next\n }\n\n function togglePlay() {\n if (!videoRef.current) return\n if (playing) videoRef.current.pause()\n else videoRef.current.play()\n setPlaying(!playing)\n }\n\n function handleSeek(nextProgress: number) {\n if (!videoRef.current || !duration) return\n videoRef.current.currentTime = (nextProgress / 100) * duration\n }\n\n function handleMouseMove() {\n setShowControls(true)\n clearTimeout(hideTimer.current)\n if (playing) {\n hideTimer.current = setTimeout(() => setShowControls(false), 3000)\n }\n }\n\n if (error) return <ErrorFallback message=\"Could not load video\" url={url} />\n\n return (\n <div\n ref={containerRef}\n className=\"group relative rounded-control bg-black overflow-hidden\"\n onMouseMove={handleMouseMove}\n onMouseLeave={() => playing && setShowControls(false)}\n tabIndex={-1}\n >\n {/* eslint-disable-next-line jsx-a11y/media-has-caption */}\n <video\n ref={videoRef}\n src={url}\n className=\"max-h-[70vh] w-full\"\n onClick={togglePlay}\n muted={muted}\n onTimeUpdate={() => {\n if (!videoRef.current) return\n setCurrentTime(videoRef.current.currentTime)\n if (videoRef.current.duration) setProgress((videoRef.current.currentTime / videoRef.current.duration) * 100)\n }}\n onLoadedMetadata={() => setDuration(videoRef.current?.duration ?? 0)}\n onEnded={() => { setPlaying(false); setShowControls(true) }}\n onError={() => { setError(true); onError?.('Video failed to load') }}\n playsInline\n />\n\n {/* Play button overlay — shown when paused */}\n {!playing && (\n <motion.button\n initial={{ opacity: 0, scale: 0.8 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={springs.snappy}\n onClick={togglePlay}\n className=\"absolute inset-0 flex items-center justify-center bg-black/30\"\n aria-label=\"Play video\"\n >\n <div className=\"flex h-14 w-14 items-center justify-center rounded-pill bg-white/90 shadow-floating\">\n <Icon icon={IconPlayerPlay} size=\"xl\" className=\"text-surface-fg ml-0.5\" />\n </div>\n </motion.button>\n )}\n\n {/* Bottom controls — auto-hide after 3s during playback */}\n <AnimatePresence>\n {showControls && duration > 0 && (\n <motion.div\n initial={{ opacity: 0, y: 10 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 10 }}\n transition={tweens.fade}\n 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\"\n >\n {/* Progress bar */}\n <MediaSlider\n className=\"mb-ds-03\"\n value={progress}\n max={100}\n step={0.1}\n onValueChange={handleSeek}\n tone=\"dark\"\n ariaLabel=\"Video progress\"\n />\n\n {/* Controls row */}\n <div className=\"flex items-center gap-ds-03\">\n <button onClick={togglePlay} className=\"text-white hover:text-white/80\" aria-label={playing ? 'Pause' : 'Play'} title={playing ? 'Pause' : 'Play'}>\n {playing ? <Icon icon={IconPlayerPause} size=\"lg\" /> : <Icon icon={IconPlayerPlay} size=\"lg\" />}\n </button>\n <VolumeControl\n volume={muted ? 0 : 1}\n muted={muted}\n onVolumeChange={(v) => {\n if (videoRef.current) videoRef.current.volume = v\n if (v > 0 && muted) { setMuted(false); if (videoRef.current) videoRef.current.muted = false }\n }}\n onMuteToggle={() => { setMuted(!muted); if (videoRef.current) videoRef.current.muted = !muted }}\n variant=\"dark\"\n />\n <span className=\"text-ds-sm font-mono text-white/70 tabular-nums\">\n {formatTime(currentTime)} / {formatTime(duration)}\n </span>\n <div className=\"flex-1\" />\n <button\n onClick={() => cyclePlaybackRate(1)}\n className=\"text-ds-sm font-mono text-white/70 hover:text-white px-1 rounded-control-inner hover:bg-white/10 transition-colors\"\n aria-label={`Playback speed: ${playbackRate}x`}\n >\n {playbackRate}x\n </button>\n <button\n onClick={() => videoRef.current?.requestFullscreen?.()}\n className=\"text-white hover:text-white/80\"\n aria-label=\"Fullscreen (F)\"\n title=\"Fullscreen\"\n >\n <Icon icon={IconMaximize} size=\"sm\" />\n </button>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n )\n}\n","'use client'\n\nimport { IconDownload } from '@tabler/icons-react'\nimport * as React from 'react'\n\nimport { Badge } from '../ui/badge'\nimport { Button } from '../ui/button'\nimport { Icon } from '../ui/icon'\nimport { cn } from '../ui/lib/utils'\nimport { Skeleton } from '../ui/skeleton'\nimport { TruncatedText } from '../ui/truncated-text'\n\n// Sub-components: direct imports for non-peer-dep renderers,\n// React.lazy for renderers that pull in optional peer deps\n// (react-zoom-pan-pinch, react-pdf) to preserve code-splitting.\nconst LazyImagePreview = React.lazy(() => import('./file-preview/image-preview'))\nconst LazyDocumentPreview = React.lazy(() => import('./file-preview/document-preview'))\nimport AudioPreview from './file-preview/audio-preview'\nimport EmbedPreview from './file-preview/embed-preview'\nimport VideoPreview from './file-preview/video-preview'\n\n// ============================================================\n// Types\n// ============================================================\n\ntype FileType = 'image' | 'pdf' | 'video' | 'audio' | 'embed'\n\nexport interface FilePreviewProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onError'> {\n url: string\n /** Auto-detected from URL/mimeType if omitted */\n type?: FileType\n mimeType?: string\n alt?: string\n /** PDF starting page @default 1 */\n initialPage?: number\n /** File name for display */\n fileName?: string\n /** File size for display (e.g. '2.4 MB') */\n fileSize?: string\n /** Called on errors (broken URL, CORS, timeout) */\n onError?: (error: string) => void\n}\n\n// ============================================================\n// Type Detection\n// ============================================================\n\nfunction detectType(url: string, mimeType?: string): FileType {\n if (mimeType) {\n if (mimeType.startsWith('image/')) return 'image'\n if (mimeType === 'application/pdf') return 'pdf'\n if (mimeType.startsWith('video/')) return 'video'\n if (mimeType.startsWith('audio/')) return 'audio'\n }\n\n const ext = url.split('?')[0].split('.').pop()?.toLowerCase()\n if (['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'avif', 'bmp'].includes(ext ?? '')) return 'image'\n if (ext === 'pdf') return 'pdf'\n if (['mp4', 'webm', 'ogg', 'mov'].includes(ext ?? '')) return 'video'\n if (['mp3', 'wav', 'ogg', 'aac', 'flac'].includes(ext ?? '')) return 'audio'\n\n if (url.includes('figma.com') || url.includes('loom.com') || url.includes('youtube.com') || url.includes('youtu.be') || url.includes('vimeo.com')) {\n return 'embed'\n }\n\n return 'image'\n}\n\nfunction getEmbedUrl(url: string): string {\n const ytMatch = url.match(/(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/)([^&?]+)/)\n if (ytMatch) return `https://www.youtube.com/embed/${ytMatch[1]}`\n\n const vimeoMatch = url.match(/vimeo\\.com\\/(\\d+)/)\n if (vimeoMatch) return `https://player.vimeo.com/video/${vimeoMatch[1]}`\n\n if (url.includes('figma.com')) return `https://www.figma.com/embed?embed_host=share&url=${encodeURIComponent(url)}`\n\n const loomMatch = url.match(/loom\\.com\\/share\\/([^?]+)/)\n if (loomMatch) return `https://www.loom.com/embed/${loomMatch[1]}`\n\n return url\n}\n\n// ============================================================\n// FilePreview — Main component (router)\n// ============================================================\n\nfunction FilePreview({\n url,\n type: typeProp,\n mimeType,\n alt,\n initialPage = 1,\n fileName,\n fileSize,\n onError,\n className,\n ...props\n}: FilePreviewProps) {\n const type = typeProp ?? detectType(url, mimeType)\n const fallback = <Skeleton className=\"h-64 w-full rounded-control\" />\n\n return (\n <div className={cn('flex flex-col gap-ds-03', className)} {...props}>\n {/* File info bar */}\n {(fileName || fileSize) && (\n <div className=\"flex items-center gap-ds-03\">\n {fileName && (\n <TruncatedText mode=\"middle\" className=\"min-w-0 text-ds-sm font-semibold text-surface-fg\">\n {fileName}\n </TruncatedText>\n )}\n {fileSize && <Badge variant=\"subtle\" size=\"xs\">{fileSize}</Badge>}\n </div>\n )}\n\n {/* Preview */}\n {type === 'image' && (\n <React.Suspense fallback={fallback}>\n <LazyImagePreview url={url} alt={alt} onError={onError} />\n </React.Suspense>\n )}\n {type === 'pdf' && (\n <React.Suspense fallback={fallback}>\n <LazyDocumentPreview url={url} initialPage={initialPage} onError={onError} />\n </React.Suspense>\n )}\n {type === 'video' && <VideoPreview url={url} onError={onError} />}\n {type === 'audio' && <AudioPreview url={url} fileName={fileName} onError={onError} />}\n {type === 'embed' && <EmbedPreview url={url} embedUrl={getEmbedUrl(url)} onError={onError} />}\n\n {/* Download — not shown for audio (it has its own layout) */}\n {type !== 'audio' && (\n <div className=\"flex justify-end\">\n <Button variant=\"ghost\" size=\"xs\" startIcon={<Icon icon={IconDownload} />} asChild>\n <a href={url} download target=\"_blank\" rel=\"noopener noreferrer\">Download</a>\n </Button>\n </div>\n )}\n </div>\n )\n}\n\nexport { FilePreview }\nexport type { FileType }\n"],"mappings":"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"}
@@ -30,7 +30,7 @@ export interface FilterSelectProps {
30
30
  allLabel?: string;
31
31
  className?: string;
32
32
  }
33
- declare function FilterSelect({ label, value, onValueChange, options, allLabel, className, }: FilterSelectProps): import("react/jsx-runtime").JSX.Element;
33
+ declare function FilterSelect({ label, value, onValueChange, options, allLabel, className, }: FilterSelectProps): React.JSX.Element;
34
34
  export interface FilterMultiSelectProps {
35
35
  label: string;
36
36
  value: string[];
@@ -41,6 +41,6 @@ export interface FilterMultiSelectProps {
41
41
  }[];
42
42
  className?: string;
43
43
  }
44
- declare function FilterMultiSelect({ label, value, onValueChange, options, className, }: FilterMultiSelectProps): import("react/jsx-runtime").JSX.Element;
44
+ declare function FilterMultiSelect({ label, value, onValueChange, options, className, }: FilterMultiSelectProps): React.JSX.Element;
45
45
  export { FilterBar, FilterMultiSelect, FilterSelect };
46
46
  //# sourceMappingURL=filter-bar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"filter-bar.d.ts","sourceRoot":"","sources":["../../src/composed/filter-bar.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAqB9B,KAAK,aAAa,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAQvC;;;;GAIG;AACH,MAAM,WAAW,cAAe,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC1E,8FAA8F;IAC9F,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,yFAAyF;IACzF,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACxC,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;IACvB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,aAAa,CAAA;CACrB;AAED,QAAA,MAAM,SAAS,uFAsCb,CAAA;AAOF,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC3C,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,iBAAS,YAAY,CAAC,EACpB,KAAK,EACL,KAAK,EACL,aAAa,EACb,OAAO,EACP,QAAgB,EAChB,SAAS,GACV,EAAE,iBAAiB,2CAsBnB;AAMD,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;IACzC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,iBAAS,iBAAiB,CAAC,EACzB,KAAK,EACL,KAAK,EACL,aAAa,EACb,OAAO,EACP,SAAS,GACV,EAAE,sBAAsB,2CAsDxB;AAED,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAC,YAAY,EAAE,CAAA"}
1
+ {"version":3,"file":"filter-bar.d.ts","sourceRoot":"","sources":["../../src/composed/filter-bar.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAqB9B,KAAK,aAAa,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAQvC;;;;GAIG;AACH,MAAM,WAAW,cAAe,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC1E,8FAA8F;IAC9F,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,yFAAyF;IACzF,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACxC,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;IACvB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,aAAa,CAAA;CACrB;AAED,QAAA,MAAM,SAAS,uFAsCb,CAAA;AAOF,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC3C,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,iBAAS,YAAY,CAAC,EACpB,KAAK,EACL,KAAK,EACL,aAAa,EACb,OAAO,EACP,QAAgB,EAChB,SAAS,GACV,EAAE,iBAAiB,qBAsBnB;AAMD,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;IACzC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,iBAAS,iBAAiB,CAAC,EACzB,KAAK,EACL,KAAK,EACL,aAAa,EACb,OAAO,EACP,SAAS,GACV,EAAE,sBAAsB,qBAsDxB;AAED,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAC,YAAY,EAAE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"filter-bar.js","names":[],"sources":["../../src/composed/filter-bar.tsx"],"sourcesContent":["'use client'\n\nimport { IconChevronDown } from '@tabler/icons-react'\nimport { motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { Badge } from '../ui/badge'\nimport { Button } from '../ui/button'\nimport { Icon } from '../ui/icon'\nimport { springs } from '../ui/lib/motion'\nimport { cn } from '../ui/lib/utils'\nimport { SearchInput } from '../ui/search-input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../ui/select'\nimport { type MultiSelectItem,MultiSelectPopover } from './multi-select-popover'\n\n// ============================================================\n// Context\n// ============================================================\n\ntype FilterBarSize = 'xs' | 'sm' | 'md'\n\nconst FilterBarContext = React.createContext<{ size: FilterBarSize }>({ size: 'sm' })\n\n// ============================================================\n// FilterBar\n// ============================================================\n\n/**\n * A toolbar for filtering lists/tables. Composes a search input, slot-based\n * filter controls (Select, MultiSelect), and an optional \"Clear all\" button.\n * Size is propagated to all child controls via context.\n */\nexport interface FilterBarProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Controlled search input value. Omit `onSearchChange` to hide the search input entirely. */\n searchValue?: string\n /** Called when the search input changes. If not provided, the search input is hidden. */\n onSearchChange?: (value: string) => void\n searchPlaceholder?: string\n /** When provided, a \"Clear all\" button appears that calls this handler. */\n onClearAll?: () => void\n /** Size propagated to all child controls. @default 'sm' */\n size?: FilterBarSize\n}\n\nconst FilterBar = React.forwardRef<HTMLDivElement, FilterBarProps>(({\n searchValue,\n onSearchChange,\n searchPlaceholder = 'Search...',\n onClearAll,\n size = 'sm',\n children,\n className,\n ...props\n}, ref) => {\n return (\n <FilterBarContext.Provider value={{ size }}>\n <div\n ref={ref}\n className={cn('flex flex-wrap items-center gap-ds-03', className)}\n role=\"toolbar\"\n aria-label=\"Filters\"\n {...props}\n >\n {onSearchChange && (\n <SearchInput\n size={size}\n value={searchValue}\n onChange={(e) => onSearchChange(e.target.value)}\n onClear={searchValue ? () => onSearchChange('') : undefined}\n placeholder={searchPlaceholder}\n className=\"w-48\"\n />\n )}\n {children}\n {onClearAll && (\n <Button variant=\"ghost\" size={size} onClick={onClearAll}>\n Clear all\n </Button>\n )}\n </div>\n </FilterBarContext.Provider>\n )\n})\nFilterBar.displayName = 'FilterBar'\n\n// ============================================================\n// FilterSelect\n// ============================================================\n\nexport interface FilterSelectProps {\n label: string\n value: string\n onValueChange: (value: string) => void\n options: { value: string; label: string }[]\n /** Label for the \"all\" option @default 'All' */\n allLabel?: string\n className?: string\n}\n\nfunction FilterSelect({\n label,\n value,\n onValueChange,\n options,\n allLabel = 'All',\n className,\n}: FilterSelectProps) {\n const { size } = React.useContext(FilterBarContext)\n const isFiltered = value !== '' && value !== 'all'\n\n return (\n <Select value={value} onValueChange={onValueChange}>\n <SelectTrigger\n size={size}\n className={cn('w-40', isFiltered && 'border-accent-7', className)}\n >\n <SelectValue placeholder={label} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">{allLabel}</SelectItem>\n {options.map((o) => (\n <SelectItem key={o.value} value={o.value}>\n {o.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )\n}\n\n// ============================================================\n// FilterMultiSelect\n// ============================================================\n\nexport interface FilterMultiSelectProps {\n label: string\n value: string[]\n onValueChange: (values: string[]) => void\n options: { value: string; label: string }[]\n className?: string\n}\n\nfunction FilterMultiSelect({\n label,\n value,\n onValueChange,\n options,\n className,\n}: FilterMultiSelectProps) {\n const { size } = React.useContext(FilterBarContext)\n const count = value.length\n\n const items: MultiSelectItem[] = React.useMemo(\n () => options.map((o) => ({ id: o.value, label: o.label })),\n [options],\n )\n\n // Trigger button sized by FilterBar context\n const triggerSizeClasses: Record<string, string> = {\n xs: 'h-ds-xs-plus text-ds-sm px-ds-02',\n sm: 'h-ds-sm text-ds-sm px-ds-03',\n md: 'h-ds-md text-ds-md px-ds-04',\n }\n\n return (\n <MultiSelectPopover\n items={items}\n value={value}\n onValueChange={onValueChange}\n searchPlaceholder={`Search ${label.toLowerCase()}...`}\n >\n <button\n type=\"button\"\n className={cn(\n 'flex items-center justify-between gap-ds-02 whitespace-nowrap rounded-control border bg-surface-raised-hover text-surface-fg',\n 'hover:bg-surface-raised-active transition-colors duration-fast-01 ease-productive-standard',\n triggerSizeClasses[size],\n count > 0 ? 'border-accent-7' : 'border-surface-border-strong',\n 'w-40',\n className,\n )}\n >\n <span className=\"flex min-w-0 items-center gap-ds-02\">\n <span className=\"truncate\">{label}</span>\n {count > 0 && (\n <motion.span\n key={count}\n initial={{ scale: 0.8 }}\n animate={{ scale: 1 }}\n transition={springs.snappy}\n className=\"inline-flex\"\n >\n <Badge size=\"xs\" variant=\"solid\" className=\"ml-ds-01\">\n {count}\n </Badge>\n </motion.span>\n )}\n </span>\n <Icon icon={IconChevronDown} size=\"xs\" className=\"opacity-50 shrink-0\" />\n </button>\n </MultiSelectPopover>\n )\n}\n\nexport { FilterBar, FilterMultiSelect,FilterSelect }\n"],"mappings":";;;;;;;;;;;;;;AA2BA,IAAM,IAAmB,EAAM,cAAuC,EAAE,MAAM,MAAM,CAAC,EAuB/E,IAAY,EAAM,YAA4C,EAClE,gBACA,mBACA,uBAAoB,aACpB,eACA,UAAO,MACP,aACA,cACA,GAAG,KACF,MAEC,kBAAC,EAAiB,UAAlB;CAA2B,OAAO,EAAE,SAAM;WACxC,kBAAC,OAAD;EACO;EACL,WAAW,EAAG,yCAAyC,EAAU;EACjE,MAAK;EACL,cAAW;EACX,GAAI;YALN;GAOG,KACC,kBAAC,GAAD;IACQ;IACN,OAAO;IACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAM;IAC/C,SAAS,UAAoB,EAAe,GAAG,GAAG,KAAA;IAClD,aAAa;IACb,WAAU;IACV,CAAA;GAEH;GACA,KACC,kBAAC,GAAD;IAAQ,SAAQ;IAAc;IAAM,SAAS;cAAY;IAEhD,CAAA;GAEP;;CACoB,CAAA,CAE9B;AACF,EAAU,cAAc;AAgBxB,SAAS,EAAa,EACpB,UACA,UACA,kBACA,YACA,cAAW,OACX,gBACoB;CACpB,IAAM,EAAE,YAAS,EAAM,WAAW,EAAiB;AAGnD,QACE,kBAAC,GAAD;EAAe;EAAsB;YAArC,CACE,kBAAC,GAAD;GACQ;GACN,WAAW,EAAG,QAND,MAAU,MAAM,MAAU,SAMH,mBAAmB,EAAU;aAEjE,kBAAC,GAAD,EAAa,aAAa,GAAS,CAAA;GACrB,CAAA,EAChB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;GAAY,OAAM;aAAO;GAAsB,CAAA,EAC9C,EAAQ,KAAK,MACZ,kBAAC,GAAD;GAA0B,OAAO,EAAE;aAChC,EAAE;GACQ,EAFI,EAAE,MAEN,CACb,CACY,EAAA,CAAA,CACT;;;AAgBb,SAAS,EAAkB,EACzB,UACA,UACA,kBACA,YACA,gBACyB;CACzB,IAAM,EAAE,YAAS,EAAM,WAAW,EAAiB,EAC7C,IAAQ,EAAM;AAcpB,QACE,kBAAC,GAAD;EACS,OAdsB,EAAM,cAC/B,EAAQ,KAAK,OAAO;GAAE,IAAI,EAAE;GAAO,OAAO,EAAE;GAAO,EAAE,EAC3D,CAAC,EAAQ,CACV;EAYU;EACQ;EACf,mBAAmB,UAAU,EAAM,aAAa,CAAC;YAEjD,kBAAC,UAAD;GACE,MAAK;GACL,WAAW,EACT,gIACA,8FAjB2C;IACjD,IAAI;IACJ,IAAI;IACJ,IAAI;IACL,CAc0B,IACnB,IAAQ,IAAI,oBAAoB,gCAChC,QACA,EACD;aATH,CAWE,kBAAC,QAAD;IAAM,WAAU;cAAhB,CACE,kBAAC,QAAD;KAAM,WAAU;eAAY;KAAa,CAAA,EACxC,IAAQ,KACP,kBAAC,EAAO,MAAR;KAEE,SAAS,EAAE,OAAO,IAAK;KACvB,SAAS,EAAE,OAAO,GAAG;KACrB,YAAY,EAAQ;KACpB,WAAU;eAEV,kBAAC,GAAD;MAAO,MAAK;MAAK,SAAQ;MAAQ,WAAU;gBACxC;MACK,CAAA;KACI,EATP,EASO,CAEX;OACP,kBAAC,GAAD;IAAM,MAAM;IAAiB,MAAK;IAAK,WAAU;IAAwB,CAAA,CAClE;;EACU,CAAA"}
1
+ {"version":3,"file":"filter-bar.js","names":[],"sources":["../../src/composed/filter-bar.tsx"],"sourcesContent":["'use client'\n\nimport { IconChevronDown } from '@tabler/icons-react'\nimport { motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { Badge } from '../ui/badge'\nimport { Button } from '../ui/button'\nimport { Icon } from '../ui/icon'\nimport { springs } from '../ui/lib/motion'\nimport { cn } from '../ui/lib/utils'\nimport { SearchInput } from '../ui/search-input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../ui/select'\nimport { type MultiSelectItem,MultiSelectPopover } from './multi-select-popover'\n\n// ============================================================\n// Context\n// ============================================================\n\ntype FilterBarSize = 'xs' | 'sm' | 'md'\n\nconst FilterBarContext = React.createContext<{ size: FilterBarSize }>({ size: 'sm' })\n\n// ============================================================\n// FilterBar\n// ============================================================\n\n/**\n * A toolbar for filtering lists/tables. Composes a search input, slot-based\n * filter controls (Select, MultiSelect), and an optional \"Clear all\" button.\n * Size is propagated to all child controls via context.\n */\nexport interface FilterBarProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Controlled search input value. Omit `onSearchChange` to hide the search input entirely. */\n searchValue?: string\n /** Called when the search input changes. If not provided, the search input is hidden. */\n onSearchChange?: (value: string) => void\n searchPlaceholder?: string\n /** When provided, a \"Clear all\" button appears that calls this handler. */\n onClearAll?: () => void\n /** Size propagated to all child controls. @default 'sm' */\n size?: FilterBarSize\n}\n\nconst FilterBar = React.forwardRef<HTMLDivElement, FilterBarProps>(({\n searchValue,\n onSearchChange,\n searchPlaceholder = 'Search...',\n onClearAll,\n size = 'sm',\n children,\n className,\n ...props\n}, ref) => {\n return (\n <FilterBarContext.Provider value={{ size }}>\n <div\n ref={ref}\n className={cn('flex flex-wrap items-center gap-ds-03', className)}\n role=\"toolbar\"\n aria-label=\"Filters\"\n {...props}\n >\n {onSearchChange && (\n <SearchInput\n size={size}\n value={searchValue}\n onChange={(e) => onSearchChange(e.target.value)}\n onClear={searchValue ? () => onSearchChange('') : undefined}\n placeholder={searchPlaceholder}\n className=\"w-48\"\n />\n )}\n {children}\n {onClearAll && (\n <Button variant=\"ghost\" size={size} onClick={onClearAll}>\n Clear all\n </Button>\n )}\n </div>\n </FilterBarContext.Provider>\n )\n})\nFilterBar.displayName = 'FilterBar'\n\n// ============================================================\n// FilterSelect\n// ============================================================\n\nexport interface FilterSelectProps {\n label: string\n value: string\n onValueChange: (value: string) => void\n options: { value: string; label: string }[]\n /** Label for the \"all\" option @default 'All' */\n allLabel?: string\n className?: string\n}\n\nfunction FilterSelect({\n label,\n value,\n onValueChange,\n options,\n allLabel = 'All',\n className,\n}: FilterSelectProps) {\n const { size } = React.useContext(FilterBarContext)\n const isFiltered = value !== '' && value !== 'all'\n\n return (\n <Select value={value} onValueChange={onValueChange}>\n <SelectTrigger\n size={size}\n className={cn('w-40', isFiltered && 'border-accent-7', className)}\n >\n <SelectValue placeholder={label} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">{allLabel}</SelectItem>\n {options.map((o) => (\n <SelectItem key={o.value} value={o.value}>\n {o.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )\n}\n\n// ============================================================\n// FilterMultiSelect\n// ============================================================\n\nexport interface FilterMultiSelectProps {\n label: string\n value: string[]\n onValueChange: (values: string[]) => void\n options: { value: string; label: string }[]\n className?: string\n}\n\nfunction FilterMultiSelect({\n label,\n value,\n onValueChange,\n options,\n className,\n}: FilterMultiSelectProps) {\n const { size } = React.useContext(FilterBarContext)\n const count = value.length\n\n const items: MultiSelectItem[] = React.useMemo(\n () => options.map((o) => ({ id: o.value, label: o.label })),\n [options],\n )\n\n // Trigger button sized by FilterBar context\n const triggerSizeClasses: Record<string, string> = {\n xs: 'h-ds-xs-plus text-ds-sm px-ds-02',\n sm: 'h-ds-sm text-ds-sm px-ds-03',\n md: 'h-ds-md text-ds-md px-ds-04',\n }\n\n return (\n <MultiSelectPopover\n items={items}\n value={value}\n onValueChange={onValueChange}\n searchPlaceholder={`Search ${label.toLowerCase()}...`}\n >\n <button\n type=\"button\"\n className={cn(\n 'flex items-center justify-between gap-ds-02 whitespace-nowrap rounded-control border bg-surface-raised-hover text-surface-fg',\n 'hover:bg-surface-raised-active transition-colors duration-fast-01 ease-productive-standard',\n triggerSizeClasses[size],\n count > 0 ? 'border-accent-7' : 'border-surface-border-strong',\n 'w-40',\n className,\n )}\n >\n <span className=\"flex min-w-0 items-center gap-ds-02\">\n <span className=\"truncate\">{label}</span>\n {count > 0 && (\n <motion.span\n key={count}\n initial={{ scale: 0.8 }}\n animate={{ scale: 1 }}\n transition={springs.snappy}\n className=\"inline-flex\"\n >\n <Badge size=\"xs\" variant=\"solid\" className=\"ml-ds-01\">\n {count}\n </Badge>\n </motion.span>\n )}\n </span>\n <Icon icon={IconChevronDown} size=\"xs\" className=\"opacity-50 shrink-0\" />\n </button>\n </MultiSelectPopover>\n )\n}\n\nexport { FilterBar, FilterMultiSelect,FilterSelect }\n"],"mappings":";;;;;;;;;;;;;;AA2BA,IAAM,IAAmB,EAAM,cAAuC,EAAE,MAAM,KAAK,CAAC,GAuB9E,IAAY,EAAM,YAA4C,EAClE,gBACA,mBACA,uBAAoB,aACpB,eACA,UAAO,MACP,aACA,cACA,GAAG,KACF,MAEC,kBAAC,EAAiB,UAAlB;CAA2B,OAAO,EAAE,QAAK;WACvC,kBAAC,OAAD;EACO;EACL,WAAW,EAAG,yCAAyC,CAAS;EAChE,MAAK;EACL,cAAW;EACX,GAAI;YALN;GAOG,KACC,kBAAC,GAAD;IACQ;IACN,OAAO;IACP,WAAW,MAAM,EAAe,EAAE,OAAO,KAAK;IAC9C,SAAS,UAAoB,EAAe,EAAE,IAAI,KAAA;IAClD,aAAa;IACb,WAAU;GACX,CAAA;GAEF;GACA,KACC,kBAAC,GAAD;IAAQ,SAAQ;IAAc;IAAM,SAAS;cAAY;GAEjD,CAAA;EAEP;;AACoB,CAAA,CAE9B;AACD,EAAU,cAAc;AAgBxB,SAAS,EAAa,EACpB,UACA,UACA,kBACA,YACA,cAAW,OACX,gBACoB;CACpB,IAAM,EAAE,YAAS,EAAM,WAAW,CAAgB;CAGlD,OACE,kBAAC,GAAD;EAAe;EAAsB;YAArC,CACE,kBAAC,GAAD;GACQ;GACN,WAAW,EAAG,QAND,MAAU,MAAM,MAAU,SAMH,mBAAmB,CAAS;aAEhE,kBAAC,GAAD,EAAa,aAAa,EAAQ,CAAA;EACrB,CAAA,GACf,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;GAAY,OAAM;aAAO;EAAqB,CAAA,GAC7C,EAAQ,KAAK,MACZ,kBAAC,GAAD;GAA0B,OAAO,EAAE;aAChC,EAAE;EACO,GAFK,EAAE,KAEP,CACb,CACY,EAAA,CAAA,CACT;;AAEZ;AAcA,SAAS,EAAkB,EACzB,UACA,UACA,kBACA,YACA,gBACyB;CACzB,IAAM,EAAE,YAAS,EAAM,WAAW,CAAgB,GAC5C,IAAQ,EAAM;CAcpB,OACE,kBAAC,GAAD;EACS,OAdsB,EAAM,cAC/B,EAAQ,KAAK,OAAO;GAAE,IAAI,EAAE;GAAO,OAAO,EAAE;EAAM,EAAE,GAC1D,CAAC,CAAO,CAYC;EACA;EACQ;EACf,mBAAmB,UAAU,EAAM,YAAY,EAAE;YAEjD,kBAAC,UAAD;GACE,MAAK;GACL,WAAW,EACT,gIACA,8FACA;IAjBN,IAAI;IACJ,IAAI;IACJ,IAAI;GAeE,EAAmB,IACnB,IAAQ,IAAI,oBAAoB,gCAChC,QACA,CACF;aATF,CAWE,kBAAC,QAAD;IAAM,WAAU;cAAhB,CACE,kBAAC,QAAD;KAAM,WAAU;eAAY;IAAY,CAAA,GACvC,IAAQ,KACP,kBAAC,EAAO,MAAR;KAEE,SAAS,EAAE,OAAO,GAAI;KACtB,SAAS,EAAE,OAAO,EAAE;KACpB,YAAY,EAAQ;KACpB,WAAU;eAEV,kBAAC,GAAD;MAAO,MAAK;MAAK,SAAQ;MAAQ,WAAU;gBACxC;KACI,CAAA;IACI,GATN,CASM,CAEX;OACN,kBAAC,GAAD;IAAM,MAAM;IAAiB,MAAK;IAAK,WAAU;GAAuB,CAAA,CAClE;;CACU,CAAA;AAExB"}
@@ -1 +1 @@
1
- {"version":3,"file":"form-section.js","names":[],"sources":["../../src/composed/form-section.tsx"],"sourcesContent":["'use client'\n\nimport { IconChevronDown } from '@tabler/icons-react'\nimport { motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from '../ui/collapsible'\nimport { Icon } from '../ui/icon'\nimport { springs } from '../ui/lib/motion'\nimport { cn } from '../ui/lib/utils'\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface FormSectionProps extends React.HTMLAttributes<HTMLDivElement> {\n title: string\n description?: string\n collapsible?: boolean\n /** @default true */\n defaultOpen?: boolean\n}\n\n// ============================================================\n// FormSection\n// ============================================================\n\nconst FormSection = React.forwardRef<HTMLDivElement, FormSectionProps>(({\n title,\n description,\n collapsible = false,\n defaultOpen = true,\n children,\n className,\n ...props\n}, ref) => {\n const header = (\n <div className=\"flex flex-col gap-ds-01\">\n <span className=\"text-ds-md font-semibold text-surface-fg font-sans\">\n {title}\n </span>\n {description && (\n <span className=\"text-ds-sm text-surface-fg-muted font-sans\">\n {description}\n </span>\n )}\n </div>\n )\n\n const [isOpen, setIsOpen] = React.useState(defaultOpen)\n\n if (collapsible) {\n return (\n <Collapsible defaultOpen={defaultOpen} onOpenChange={setIsOpen} className={cn('space-y-ds-04', className)} {...props}>\n <CollapsibleTrigger className=\"flex w-full items-center justify-between py-ds-02 group\">\n {header}\n <motion.span\n animate={{ rotate: isOpen ? 180 : 0 }}\n transition={springs.snappy}\n className=\"inline-flex\"\n >\n <Icon icon={IconChevronDown} size=\"sm\" className=\"text-surface-fg-muted\" />\n </motion.span>\n </CollapsibleTrigger>\n <div className=\"border-b border-surface-border-subtle\" />\n <CollapsibleContent>\n <div className=\"space-y-ds-04 pt-ds-02\">\n {children}\n </div>\n </CollapsibleContent>\n </Collapsible>\n )\n }\n\n return (\n <div ref={ref} className={cn('space-y-ds-04', className)} {...props}>\n {header}\n <div className=\"border-b border-surface-border-subtle\" />\n <div className=\"space-y-ds-04\">\n {children}\n </div>\n </div>\n )\n})\nFormSection.displayName = 'FormSection'\n\nexport { FormSection }\n"],"mappings":";;;;;;;;;;AA2BA,IAAM,IAAc,EAAM,YAA8C,EACtE,UACA,gBACA,iBAAc,IACd,iBAAc,IACd,aACA,cACA,GAAG,KACF,MAAQ;CACT,IAAM,IACJ,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,QAAD;GAAM,WAAU;aACb;GACI,CAAA,EACN,KACC,kBAAC,QAAD;GAAM,WAAU;aACb;GACI,CAAA,CAEL;KAGF,CAAC,GAAQ,KAAa,EAAM,SAAS,EAAY;AAyBvD,QAvBI,IAEA,kBAAC,GAAD;EAA0B;EAAa,cAAc;EAAW,WAAW,EAAG,iBAAiB,EAAU;EAAE,GAAI;YAA/G;GACE,kBAAC,GAAD;IAAoB,WAAU;cAA9B,CACG,GACD,kBAAC,EAAO,MAAR;KACE,SAAS,EAAE,QAAQ,IAAS,MAAM,GAAG;KACrC,YAAY,EAAQ;KACpB,WAAU;eAEV,kBAAC,GAAD;MAAM,MAAM;MAAiB,MAAK;MAAK,WAAU;MAA0B,CAAA;KAC/D,CAAA,CACK;;GACrB,kBAAC,OAAD,EAAK,WAAU,yCAA0C,CAAA;GACzD,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;IAAK,WAAU;IACZ;IACG,CAAA,EACa,CAAA;GACT;MAKhB,kBAAC,OAAD;EAAU;EAAK,WAAW,EAAG,iBAAiB,EAAU;EAAE,GAAI;YAA9D;GACG;GACD,kBAAC,OAAD,EAAK,WAAU,yCAA0C,CAAA;GACzD,kBAAC,OAAD;IAAK,WAAU;IACZ;IACG,CAAA;GACF;;EAER;AACF,EAAY,cAAc"}
1
+ {"version":3,"file":"form-section.js","names":[],"sources":["../../src/composed/form-section.tsx"],"sourcesContent":["'use client'\n\nimport { IconChevronDown } from '@tabler/icons-react'\nimport { motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from '../ui/collapsible'\nimport { Icon } from '../ui/icon'\nimport { springs } from '../ui/lib/motion'\nimport { cn } from '../ui/lib/utils'\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface FormSectionProps extends React.HTMLAttributes<HTMLDivElement> {\n title: string\n description?: string\n collapsible?: boolean\n /** @default true */\n defaultOpen?: boolean\n}\n\n// ============================================================\n// FormSection\n// ============================================================\n\nconst FormSection = React.forwardRef<HTMLDivElement, FormSectionProps>(({\n title,\n description,\n collapsible = false,\n defaultOpen = true,\n children,\n className,\n ...props\n}, ref) => {\n const header = (\n <div className=\"flex flex-col gap-ds-01\">\n <span className=\"text-ds-md font-semibold text-surface-fg font-sans\">\n {title}\n </span>\n {description && (\n <span className=\"text-ds-sm text-surface-fg-muted font-sans\">\n {description}\n </span>\n )}\n </div>\n )\n\n const [isOpen, setIsOpen] = React.useState(defaultOpen)\n\n if (collapsible) {\n return (\n <Collapsible defaultOpen={defaultOpen} onOpenChange={setIsOpen} className={cn('space-y-ds-04', className)} {...props}>\n <CollapsibleTrigger className=\"flex w-full items-center justify-between py-ds-02 group\">\n {header}\n <motion.span\n animate={{ rotate: isOpen ? 180 : 0 }}\n transition={springs.snappy}\n className=\"inline-flex\"\n >\n <Icon icon={IconChevronDown} size=\"sm\" className=\"text-surface-fg-muted\" />\n </motion.span>\n </CollapsibleTrigger>\n <div className=\"border-b border-surface-border-subtle\" />\n <CollapsibleContent>\n <div className=\"space-y-ds-04 pt-ds-02\">\n {children}\n </div>\n </CollapsibleContent>\n </Collapsible>\n )\n }\n\n return (\n <div ref={ref} className={cn('space-y-ds-04', className)} {...props}>\n {header}\n <div className=\"border-b border-surface-border-subtle\" />\n <div className=\"space-y-ds-04\">\n {children}\n </div>\n </div>\n )\n})\nFormSection.displayName = 'FormSection'\n\nexport { FormSection }\n"],"mappings":";;;;;;;;;;AA2BA,IAAM,IAAc,EAAM,YAA8C,EACtE,UACA,gBACA,iBAAc,IACd,iBAAc,IACd,aACA,cACA,GAAG,KACF,MAAQ;CACT,IAAM,IACJ,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,QAAD;GAAM,WAAU;aACb;EACG,CAAA,GACL,KACC,kBAAC,QAAD;GAAM,WAAU;aACb;EACG,CAAA,CAEL;KAGD,CAAC,GAAQ,KAAa,EAAM,SAAS,CAAW;CAyBtD,OAvBI,IAEA,kBAAC,GAAD;EAA0B;EAAa,cAAc;EAAW,WAAW,EAAG,iBAAiB,CAAS;EAAG,GAAI;YAA/G;GACE,kBAAC,GAAD;IAAoB,WAAU;cAA9B,CACG,GACD,kBAAC,EAAO,MAAR;KACE,SAAS,EAAE,QAAQ,IAAS,MAAM,EAAE;KACpC,YAAY,EAAQ;KACpB,WAAU;eAEV,kBAAC,GAAD;MAAM,MAAM;MAAiB,MAAK;MAAK,WAAU;KAAyB,CAAA;IAC/D,CAAA,CACK;;GACpB,kBAAC,OAAD,EAAK,WAAU,wCAAyC,CAAA;GACxD,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;IAAK,WAAU;IACZ;GACE,CAAA,EACa,CAAA;EACT;MAKf,kBAAC,OAAD;EAAU;EAAK,WAAW,EAAG,iBAAiB,CAAS;EAAG,GAAI;YAA9D;GACG;GACD,kBAAC,OAAD,EAAK,WAAU,wCAAyC,CAAA;GACxD,kBAAC,OAAD;IAAK,WAAU;IACZ;GACE,CAAA;EACF;;AAET,CAAC;AACD,EAAY,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"global-loading.js","names":[],"sources":["../../src/composed/global-loading.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { useEffect, useRef, useState } from 'react'\n\nimport { cn } from '../ui/lib/utils'\n\nexport interface GlobalLoadingProps extends React.ComponentPropsWithoutRef<'div'> {\n isLoading: boolean\n}\n\nconst GlobalLoading = React.forwardRef<HTMLDivElement, GlobalLoadingProps>(\n function GlobalLoading({ isLoading, className, ...props }, forwardedRef) {\n const ref = useRef<HTMLDivElement>(null)\n const [animationComplete, setAnimationComplete] = useState(true)\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n\n useEffect(() => {\n return () => { clearTimeout(timeoutRef.current) }\n }, [])\n\n useEffect(() => {\n if (!ref.current) return\n\n if (isLoading) {\n setAnimationComplete(false)\n }\n }, [isLoading])\n\n return (\n <div\n ref={forwardedRef}\n role=\"progressbar\"\n aria-label=\"Page loading\"\n aria-hidden={!isLoading}\n aria-valuetext={isLoading ? 'Loading' : undefined}\n {...props}\n className={cn(\"pointer-events-none fixed inset-x-0 top-0 z-toast h-1\", className)}\n >\n <div\n ref={ref}\n className={cn(\n 'h-full bg-accent-9 transition-[width,opacity] duration-slow-01 ease-productive-standard',\n isLoading && 'w-4/5 opacity-100',\n !isLoading && animationComplete && 'w-0 opacity-0',\n !isLoading && !animationComplete && 'w-full opacity-100',\n )}\n style={\n !isLoading && !animationComplete\n ? { boxShadow: '0 0 8px var(--color-accent-9)' }\n : undefined\n }\n onTransitionEnd={() => {\n if (!isLoading) {\n // After the \"complete\" animation finishes, hide the bar\n timeoutRef.current = setTimeout(() => {\n setAnimationComplete(true)\n }, 200)\n }\n }}\n />\n </div>\n )\n},\n)\n\nGlobalLoading.displayName = 'GlobalLoading'\n\nexport { GlobalLoading }\n"],"mappings":";;;;;;AAWA,IAAM,IAAgB,EAAM,WAC1B,SAAuB,EAAE,cAAW,cAAW,GAAG,KAAS,GAAc;CACzE,IAAM,IAAM,EAAuB,KAAK,EAClC,CAAC,GAAmB,KAAwB,EAAS,GAAK,EAC1D,IAAa,EAAkD,KAAA,EAAU;AAc/E,QAZA,cACe;AAAE,eAAa,EAAW,QAAQ;IAC9C,EAAE,CAAC,EAEN,QAAgB;AACT,IAAI,WAEL,KACF,EAAqB,GAAM;IAE5B,CAAC,EAAU,CAAC,EAGb,kBAAC,OAAD;EACE,KAAK;EACL,MAAK;EACL,cAAW;EACX,eAAa,CAAC;EACd,kBAAgB,IAAY,YAAY,KAAA;EACxC,GAAI;EACJ,WAAW,EAAG,yDAAyD,EAAU;YAEjF,kBAAC,OAAD;GACO;GACL,WAAW,EACT,2FACA,KAAa,qBACb,CAAC,KAAa,KAAqB,iBACnC,CAAC,KAAa,CAAC,KAAqB,qBACrC;GACD,OACE,CAAC,KAAa,CAAC,IACX,EAAE,WAAW,iCAAiC,GAC9C,KAAA;GAEN,uBAAuB;AACrB,IAAK,MAEH,EAAW,UAAU,iBAAiB;AACpC,OAAqB,GAAK;OACzB,IAAI;;GAGX,CAAA;EACE,CAAA;EAGT;AAED,EAAc,cAAc"}
1
+ {"version":3,"file":"global-loading.js","names":[],"sources":["../../src/composed/global-loading.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { useEffect, useRef, useState } from 'react'\n\nimport { cn } from '../ui/lib/utils'\n\nexport interface GlobalLoadingProps extends React.ComponentPropsWithoutRef<'div'> {\n isLoading: boolean\n}\n\nconst GlobalLoading = React.forwardRef<HTMLDivElement, GlobalLoadingProps>(\n function GlobalLoading({ isLoading, className, ...props }, forwardedRef) {\n const ref = useRef<HTMLDivElement>(null)\n const [animationComplete, setAnimationComplete] = useState(true)\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n\n useEffect(() => {\n return () => { clearTimeout(timeoutRef.current) }\n }, [])\n\n useEffect(() => {\n if (!ref.current) return\n\n if (isLoading) {\n setAnimationComplete(false)\n }\n }, [isLoading])\n\n return (\n <div\n ref={forwardedRef}\n role=\"progressbar\"\n aria-label=\"Page loading\"\n aria-hidden={!isLoading}\n aria-valuetext={isLoading ? 'Loading' : undefined}\n {...props}\n className={cn(\"pointer-events-none fixed inset-x-0 top-0 z-toast h-1\", className)}\n >\n <div\n ref={ref}\n className={cn(\n 'h-full bg-accent-9 transition-[width,opacity] duration-slow-01 ease-productive-standard',\n isLoading && 'w-4/5 opacity-100',\n !isLoading && animationComplete && 'w-0 opacity-0',\n !isLoading && !animationComplete && 'w-full opacity-100',\n )}\n style={\n !isLoading && !animationComplete\n ? { boxShadow: '0 0 8px var(--color-accent-9)' }\n : undefined\n }\n onTransitionEnd={() => {\n if (!isLoading) {\n // After the \"complete\" animation finishes, hide the bar\n timeoutRef.current = setTimeout(() => {\n setAnimationComplete(true)\n }, 200)\n }\n }}\n />\n </div>\n )\n},\n)\n\nGlobalLoading.displayName = 'GlobalLoading'\n\nexport { GlobalLoading }\n"],"mappings":";;;;;;AAWA,IAAM,IAAgB,EAAM,WAC1B,SAAuB,EAAE,cAAW,cAAW,GAAG,KAAS,GAAc;CACzE,IAAM,IAAM,EAAuB,IAAI,GACjC,CAAC,GAAmB,KAAwB,EAAS,EAAI,GACzD,IAAa,EAAkD,KAAA,CAAS;CAc9E,OAZA,cACe;EAAE,aAAa,EAAW,OAAO;CAAE,GAC/C,CAAC,CAAC,GAEL,QAAgB;EACT,EAAI,WAEL,KACF,EAAqB,EAAK;CAE9B,GAAG,CAAC,CAAS,CAAC,GAGZ,kBAAC,OAAD;EACE,KAAK;EACL,MAAK;EACL,cAAW;EACX,eAAa,CAAC;EACd,kBAAgB,IAAY,YAAY,KAAA;EACxC,GAAI;EACJ,WAAW,EAAG,yDAAyD,CAAS;YAEhF,kBAAC,OAAD;GACO;GACL,WAAW,EACT,2FACA,KAAa,qBACb,CAAC,KAAa,KAAqB,iBACnC,CAAC,KAAa,CAAC,KAAqB,oBACtC;GACA,OACE,CAAC,KAAa,CAAC,IACX,EAAE,WAAW,gCAAgC,IAC7C,KAAA;GAEN,uBAAuB;IACrB,AAAK,MAEH,EAAW,UAAU,iBAAiB;KACpC,EAAqB,EAAI;IAC3B,GAAG,GAAG;GAEV;EACD,CAAA;CACE,CAAA;AAET,CACA;AAEA,EAAc,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"inline-edit.js","names":[],"sources":["../../src/composed/inline-edit.tsx"],"sourcesContent":["'use client'\n\nimport { IconPencil } from '@tabler/icons-react'\nimport * as React from 'react'\n\nimport { Icon } from '../ui/icon'\nimport { cn } from '../ui/lib/utils'\nimport { Spinner } from '../ui/spinner'\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface InlineEditProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSave'> {\n value: string\n onSave: (newValue: string) => void | Promise<void>\n placeholder?: string\n /** CSS class applied to the editable text (e.g. 'text-ds-lg font-semibold') */\n textClassName?: string\n readOnly?: boolean\n maxLength?: number\n /** External saving state — shows spinner */\n saving?: boolean\n}\n\n// ============================================================\n// InlineEdit — contentEditable approach\n//\n// No mode switch. No input field. The text IS the editor.\n// Click → cursor appears in the text. Type. Enter saves. Escape reverts.\n// Like Notion, Linear, Figma layer names.\n// ============================================================\n\nconst InlineEdit = React.forwardRef<HTMLDivElement, InlineEditProps>(({\n value,\n onSave,\n placeholder = 'Click to edit',\n textClassName,\n readOnly = false,\n maxLength,\n saving: savingProp = false,\n className,\n // aria-label / aria-labelledby apply to the editable textbox (the inner\n // span), not the outer wrapper div. Intercept them from ...props so they\n // land on the role=\"textbox\" element that actually needs the name.\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n ...props\n}, ref) => {\n const [saving, setSaving] = React.useState(false)\n const [focused, setFocused] = React.useState(false)\n const editRef = React.useRef<HTMLSpanElement>(null)\n const snapshotRef = React.useRef(value)\n\n const isSaving = savingProp || saving\n const isEmpty = !value\n\n // Sync DOM text when value changes externally (and not focused)\n React.useEffect(() => {\n if (!focused && editRef.current) {\n editRef.current.textContent = value\n }\n }, [value, focused])\n\n function handleFocus() {\n if (readOnly || isSaving) return\n setFocused(true)\n snapshotRef.current = value\n\n // Select all text on focus (like clicking a file name in Finder)\n requestAnimationFrame(() => {\n if (!editRef.current) return\n const range = document.createRange()\n range.selectNodeContents(editRef.current)\n const sel = window.getSelection()\n sel?.removeAllRanges()\n sel?.addRange(range)\n })\n }\n\n async function commit() {\n if (!editRef.current) return\n setFocused(false)\n const raw = editRef.current.textContent ?? ''\n const trimmed = raw.trim()\n\n // Enforce maxLength\n const final = maxLength ? trimmed.slice(0, maxLength) : trimmed\n\n // Reset DOM to clean value\n editRef.current.textContent = final || value\n\n if (final === value) return\n const result = onSave(final)\n if (result instanceof Promise) {\n setSaving(true)\n try {\n await result\n } catch {\n // Revert on error\n if (editRef.current) editRef.current.textContent = value\n } finally {\n setSaving(false)\n }\n }\n }\n\n function cancel() {\n if (!editRef.current) return\n editRef.current.textContent = snapshotRef.current\n setFocused(false)\n editRef.current.blur()\n }\n\n function handleKeyDown(e: React.KeyboardEvent) {\n if (e.key === 'Escape') {\n e.preventDefault()\n cancel()\n } else if (e.key === 'Enter') {\n e.preventDefault()\n commit()\n }\n }\n\n function handleInput() {\n if (!editRef.current || !maxLength) return\n const text = editRef.current.textContent ?? ''\n if (text.length > maxLength) {\n editRef.current.textContent = text.slice(0, maxLength)\n // Move cursor to end\n const range = document.createRange()\n range.selectNodeContents(editRef.current)\n range.collapse(false)\n const sel = window.getSelection()\n sel?.removeAllRanges()\n sel?.addRange(range)\n }\n }\n\n // Prevent paste from inserting rich content\n function handlePaste(e: React.ClipboardEvent) {\n e.preventDefault()\n const text = e.clipboardData.getData('text/plain')\n document.execCommand('insertText', false, text)\n }\n\n return (\n <div ref={ref} className={cn('group inline-flex items-center gap-ds-02', className)} {...props}>\n <span\n ref={editRef}\n role={readOnly ? undefined : 'textbox'}\n contentEditable={!readOnly && !isSaving}\n suppressContentEditableWarning\n tabIndex={readOnly ? undefined : 0}\n // Fall back to the placeholder when no explicit label is supplied —\n // screen readers need _something_ on role=\"textbox\".\n aria-label={readOnly ? undefined : (ariaLabel ?? (ariaLabelledBy ? undefined : placeholder))}\n aria-labelledby={readOnly ? undefined : ariaLabelledBy}\n onFocus={handleFocus}\n onBlur={commit}\n onKeyDown={handleKeyDown}\n onInput={handleInput}\n onPaste={handlePaste}\n spellCheck={focused}\n className={cn(\n 'font-sans text-surface-fg outline-hidden',\n textClassName,\n // Idle: subtle hover hint\n !readOnly && !focused && 'cursor-text rounded-control-inner -mx-ds-01 px-ds-01 hover:bg-surface-raised-hover transition-colors duration-fast-01',\n // Focused: subtle underline to indicate editing\n focused && 'rounded-control-inner -mx-ds-01 px-ds-01 bg-surface-raised-hover ring-1 ring-accent-7',\n // Empty: show placeholder styling\n isEmpty && !focused && 'text-surface-fg-subtle italic',\n // Read-only\n readOnly && 'cursor-default',\n )}\n data-placeholder={placeholder}\n >\n {value || (focused ? '' : placeholder)}\n </span>\n {!readOnly && !focused && !isSaving && (\n <Icon icon={IconPencil} size=\"xs\" className=\"text-surface-fg-subtle opacity-0 group-hover:opacity-100 transition-opacity duration-fast-01 shrink-0\" />\n )}\n {isSaving && <Spinner size=\"sm\" />}\n </div>\n )\n})\nInlineEdit.displayName = 'InlineEdit'\n\nexport { InlineEdit }\n"],"mappings":"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"}
1
+ {"version":3,"file":"inline-edit.js","names":[],"sources":["../../src/composed/inline-edit.tsx"],"sourcesContent":["'use client'\n\nimport { IconPencil } from '@tabler/icons-react'\nimport * as React from 'react'\n\nimport { Icon } from '../ui/icon'\nimport { cn } from '../ui/lib/utils'\nimport { Spinner } from '../ui/spinner'\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface InlineEditProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSave'> {\n value: string\n onSave: (newValue: string) => void | Promise<void>\n placeholder?: string\n /** CSS class applied to the editable text (e.g. 'text-ds-lg font-semibold') */\n textClassName?: string\n readOnly?: boolean\n maxLength?: number\n /** External saving state — shows spinner */\n saving?: boolean\n}\n\n// ============================================================\n// InlineEdit — contentEditable approach\n//\n// No mode switch. No input field. The text IS the editor.\n// Click → cursor appears in the text. Type. Enter saves. Escape reverts.\n// Like Notion, Linear, Figma layer names.\n// ============================================================\n\nconst InlineEdit = React.forwardRef<HTMLDivElement, InlineEditProps>(({\n value,\n onSave,\n placeholder = 'Click to edit',\n textClassName,\n readOnly = false,\n maxLength,\n saving: savingProp = false,\n className,\n // aria-label / aria-labelledby apply to the editable textbox (the inner\n // span), not the outer wrapper div. Intercept them from ...props so they\n // land on the role=\"textbox\" element that actually needs the name.\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n ...props\n}, ref) => {\n const [saving, setSaving] = React.useState(false)\n const [focused, setFocused] = React.useState(false)\n const editRef = React.useRef<HTMLSpanElement>(null)\n const snapshotRef = React.useRef(value)\n\n const isSaving = savingProp || saving\n const isEmpty = !value\n\n // Sync DOM text when value changes externally (and not focused)\n React.useEffect(() => {\n if (!focused && editRef.current) {\n editRef.current.textContent = value\n }\n }, [value, focused])\n\n function handleFocus() {\n if (readOnly || isSaving) return\n setFocused(true)\n snapshotRef.current = value\n\n // Select all text on focus (like clicking a file name in Finder)\n requestAnimationFrame(() => {\n if (!editRef.current) return\n const range = document.createRange()\n range.selectNodeContents(editRef.current)\n const sel = window.getSelection()\n sel?.removeAllRanges()\n sel?.addRange(range)\n })\n }\n\n async function commit() {\n if (!editRef.current) return\n setFocused(false)\n const raw = editRef.current.textContent ?? ''\n const trimmed = raw.trim()\n\n // Enforce maxLength\n const final = maxLength ? trimmed.slice(0, maxLength) : trimmed\n\n // Reset DOM to clean value\n editRef.current.textContent = final || value\n\n if (final === value) return\n const result = onSave(final)\n if (result instanceof Promise) {\n setSaving(true)\n try {\n await result\n } catch {\n // Revert on error\n if (editRef.current) editRef.current.textContent = value\n } finally {\n setSaving(false)\n }\n }\n }\n\n function cancel() {\n if (!editRef.current) return\n editRef.current.textContent = snapshotRef.current\n setFocused(false)\n editRef.current.blur()\n }\n\n function handleKeyDown(e: React.KeyboardEvent) {\n if (e.key === 'Escape') {\n e.preventDefault()\n cancel()\n } else if (e.key === 'Enter') {\n e.preventDefault()\n commit()\n }\n }\n\n function handleInput() {\n if (!editRef.current || !maxLength) return\n const text = editRef.current.textContent ?? ''\n if (text.length > maxLength) {\n editRef.current.textContent = text.slice(0, maxLength)\n // Move cursor to end\n const range = document.createRange()\n range.selectNodeContents(editRef.current)\n range.collapse(false)\n const sel = window.getSelection()\n sel?.removeAllRanges()\n sel?.addRange(range)\n }\n }\n\n // Prevent paste from inserting rich content\n function handlePaste(e: React.ClipboardEvent) {\n e.preventDefault()\n const text = e.clipboardData.getData('text/plain')\n document.execCommand('insertText', false, text)\n }\n\n return (\n <div ref={ref} className={cn('group inline-flex items-center gap-ds-02', className)} {...props}>\n <span\n ref={editRef}\n role={readOnly ? undefined : 'textbox'}\n contentEditable={!readOnly && !isSaving}\n suppressContentEditableWarning\n tabIndex={readOnly ? undefined : 0}\n // Fall back to the placeholder when no explicit label is supplied —\n // screen readers need _something_ on role=\"textbox\".\n aria-label={readOnly ? undefined : (ariaLabel ?? (ariaLabelledBy ? undefined : placeholder))}\n aria-labelledby={readOnly ? undefined : ariaLabelledBy}\n onFocus={handleFocus}\n onBlur={commit}\n onKeyDown={handleKeyDown}\n onInput={handleInput}\n onPaste={handlePaste}\n spellCheck={focused}\n className={cn(\n 'font-sans text-surface-fg outline-hidden',\n textClassName,\n // Idle: subtle hover hint\n !readOnly && !focused && 'cursor-text rounded-control-inner -mx-ds-01 px-ds-01 hover:bg-surface-raised-hover transition-colors duration-fast-01',\n // Focused: subtle underline to indicate editing\n focused && 'rounded-control-inner -mx-ds-01 px-ds-01 bg-surface-raised-hover ring-1 ring-accent-7',\n // Empty: show placeholder styling\n isEmpty && !focused && 'text-surface-fg-subtle italic',\n // Read-only\n readOnly && 'cursor-default',\n )}\n data-placeholder={placeholder}\n >\n {value || (focused ? '' : placeholder)}\n </span>\n {!readOnly && !focused && !isSaving && (\n <Icon icon={IconPencil} size=\"xs\" className=\"text-surface-fg-subtle opacity-0 group-hover:opacity-100 transition-opacity duration-fast-01 shrink-0\" />\n )}\n {isSaving && <Spinner size=\"sm\" />}\n </div>\n )\n})\nInlineEdit.displayName = 'InlineEdit'\n\nexport { InlineEdit }\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"string-utils.js","names":[],"sources":["../../../src/composed/lib/string-utils.ts"],"sourcesContent":["// @server-safe\n/**\n * Extract initials from a person's name.\n * \"John Doe\" -> \"JD\", \"Alice\" -> \"AL\"\n */\nexport function getInitials(name: string): string {\n const trimmed = name.trim()\n if (!trimmed) return ''\n const parts = trimmed.split(/\\s+/)\n if (parts.length >= 2) return (parts[0][0] + parts[1][0]).toUpperCase()\n return trimmed.slice(0, 2).toUpperCase()\n}\n"],"mappings":";AAKA,SAAgB,EAAY,GAAsB;CAChD,IAAM,IAAU,EAAK,MAAM;AAC3B,KAAI,CAAC,EAAS,QAAO;CACrB,IAAM,IAAQ,EAAQ,MAAM,MAAM;AAElC,QADI,EAAM,UAAU,KAAW,EAAM,GAAG,KAAK,EAAM,GAAG,IAAI,aAAa,GAChE,EAAQ,MAAM,GAAG,EAAE,CAAC,aAAa"}
1
+ {"version":3,"file":"string-utils.js","names":[],"sources":["../../../src/composed/lib/string-utils.ts"],"sourcesContent":["// @server-safe\n/**\n * Extract initials from a person's name.\n * \"John Doe\" -> \"JD\", \"Alice\" -> \"AL\"\n */\nexport function getInitials(name: string): string {\n const trimmed = name.trim()\n if (!trimmed) return ''\n const parts = trimmed.split(/\\s+/)\n if (parts.length >= 2) return (parts[0][0] + parts[1][0]).toUpperCase()\n return trimmed.slice(0, 2).toUpperCase()\n}\n"],"mappings":";AAKA,SAAgB,EAAY,GAAsB;CAChD,IAAM,IAAU,EAAK,KAAK;CAC1B,IAAI,CAAC,GAAS,OAAO;CACrB,IAAM,IAAQ,EAAQ,MAAM,KAAK;CAEjC,OADI,EAAM,UAAU,KAAW,EAAM,EAAE,CAAC,KAAK,EAAM,EAAE,CAAC,GAAA,CAAI,YAAY,IAC/D,EAAQ,MAAM,GAAG,CAAC,CAAC,CAAC,YAAY;AACzC"}
@@ -1 +1 @@
1
- {"version":3,"file":"loading-skeleton.js","names":[],"sources":["../../src/composed/loading-skeleton.tsx"],"sourcesContent":["// @server-safe\nimport * as React from 'react'\n\nimport { cn } from '../ui/lib/utils'\nimport { Skeleton } from '../ui/skeleton'\n\nexport interface CardSkeletonProps extends React.ComponentPropsWithoutRef<'div'> {\n className?: string\n}\n\nconst CardSkeleton = React.forwardRef<HTMLDivElement, CardSkeletonProps>(\n function CardSkeleton({ className, ...props }, ref) {\n return (\n <div\n ref={ref}\n {...props}\n className={cn(\n 'rounded-surface border border-surface-border-strong bg-surface-raised p-ds-05b',\n className,\n )}\n >\n <div className=\"flex items-center justify-between pb-ds-05\">\n <Skeleton className=\"h-ds-05 w-[128px] bg-surface-raised-hover\" />\n <Skeleton className=\"h-ico-sm w-ico-sm rounded bg-surface-raised-hover\" />\n </div>\n <div className=\"space-y-ds-04\">\n <Skeleton className=\"h-ds-04 w-full bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-04 w-4/5 bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-04 w-3/5 bg-surface-raised-hover\" />\n </div>\n <div className=\"flex items-center gap-ds-03 pt-ds-05\">\n <Skeleton className=\"h-ds-xs w-ds-xs rounded-pill bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-04 w-ds-11 bg-surface-raised-hover\" />\n </div>\n </div>\n )\n},\n)\n\nCardSkeleton.displayName = 'CardSkeleton'\n\nexport interface TableSkeletonProps extends CardSkeletonProps {\n rows?: number\n columns?: number\n}\n\nconst TableSkeleton = React.forwardRef<HTMLDivElement, TableSkeletonProps>(\n function TableSkeleton({\n rows = 5,\n columns = 4,\n className,\n ...props\n}, ref) {\n return (\n <div\n ref={ref}\n {...props}\n className={cn(\n 'overflow-hidden rounded-surface border border-surface-border-strong',\n className,\n )}\n >\n {/* Header */}\n <div className=\"flex items-center gap-ds-05 border-b border-surface-border-strong bg-surface-raised px-ds-05 py-ds-04\">\n {Array.from({ length: columns }).map((_, i) => (\n <Skeleton\n key={`head-${i}`}\n className={cn(\n 'h-ds-04 bg-surface-raised-hover',\n i === 0 ? 'w-ds-13' : 'flex-1',\n )}\n />\n ))}\n </div>\n\n {/* Rows */}\n {Array.from({ length: rows }).map((_, rowIndex) => (\n <div\n key={`row-${rowIndex}`}\n className={cn(\n 'flex items-center gap-ds-05 px-ds-05 py-ds-04',\n rowIndex < rows - 1 && 'border-b border-surface-border-strong',\n )}\n style={{ animationDelay: `${rowIndex * 50}ms` }}\n >\n {Array.from({ length: columns }).map((_, colIndex) => (\n <Skeleton\n key={`cell-${rowIndex}-${colIndex}`}\n className={cn(\n 'h-ds-04 bg-surface-raised-hover',\n colIndex === 0 ? 'w-ds-13' : 'flex-1',\n )}\n />\n ))}\n </div>\n ))}\n </div>\n )\n},\n)\n\nTableSkeleton.displayName = 'TableSkeleton'\n\nexport interface BoardSkeletonProps extends CardSkeletonProps {\n columns?: number\n cardsPerColumn?: number\n}\n\nconst BoardSkeleton = React.forwardRef<HTMLDivElement, BoardSkeletonProps>(\n function BoardSkeleton({\n columns = 4,\n cardsPerColumn = 3,\n className,\n ...props\n}, ref) {\n return (\n <div ref={ref} {...props} className={cn('flex gap-ds-05 overflow-x-auto', className)}>\n {Array.from({ length: columns }).map((_, colIndex) => (\n <div\n key={`col-${colIndex}`}\n className=\"flex w-[272px] shrink-0 flex-col gap-ds-03\"\n >\n {/* Column header */}\n <div className=\"flex items-center justify-between px-ds-02 py-ds-03\">\n <div className=\"flex items-center gap-ds-03\">\n <Skeleton className=\"h-ds-04 w-ds-04 rounded bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-04 w-ds-11 bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-05 w-ds-05b rounded-pill bg-surface-raised-hover\" />\n </div>\n <Skeleton className=\"h-ico-sm w-ico-sm rounded bg-surface-raised-hover\" />\n </div>\n\n {/* Column cards */}\n {Array.from({ length: cardsPerColumn }).map((_, cardIndex) => (\n <div\n key={`card-${colIndex}-${cardIndex}`}\n className=\"rounded-surface border border-surface-border-strong bg-surface-raised p-ds-04\"\n style={{ animationDelay: `${(colIndex * cardsPerColumn + cardIndex) * 50}ms` }}\n >\n <div className=\"space-y-ds-03\">\n <Skeleton className=\"h-ds-04 w-4/5 bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-04 w-3/5 bg-surface-raised-hover\" />\n </div>\n <div className=\"flex items-center justify-between pt-ds-04\">\n <div className=\"flex items-center gap-ds-02b\">\n <Skeleton className=\"h-ico-md w-ico-md rounded-pill bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-03 w-ds-10 bg-surface-raised-hover\" />\n </div>\n <Skeleton className=\"h-ds-05 w-ds-lg rounded-pill bg-surface-raised-hover\" />\n </div>\n </div>\n ))}\n </div>\n ))}\n </div>\n )\n},\n)\n\nBoardSkeleton.displayName = 'BoardSkeleton'\n\nexport interface ListSkeletonProps extends CardSkeletonProps {\n rows?: number\n showAvatar?: boolean\n}\n\nconst ListSkeleton = React.forwardRef<HTMLDivElement, ListSkeletonProps>(\n function ListSkeleton({\n rows = 6,\n showAvatar = true,\n className,\n ...props\n}, ref) {\n return (\n <div ref={ref} {...props} className={cn('flex flex-col', className)}>\n {Array.from({ length: rows }).map((_, i) => (\n <div\n key={`list-${i}`}\n className={cn(\n 'flex items-center gap-ds-04 py-ds-04',\n i < rows - 1 && 'border-b border-surface-border-strong',\n )}\n style={{ animationDelay: `${i * 50}ms` }}\n >\n {showAvatar && (\n <Skeleton className=\"h-ds-sm w-ds-sm shrink-0 rounded-pill bg-surface-raised-hover\" />\n )}\n <div className=\"flex flex-1 flex-col gap-ds-02b\">\n <Skeleton className=\"h-ds-04 w-2/5 bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-03 w-3/5 bg-surface-raised-hover\" />\n </div>\n <Skeleton className=\"h-ds-05b w-[56px] rounded-pill bg-surface-raised-hover\" />\n </div>\n ))}\n </div>\n )\n},\n)\n\nListSkeleton.displayName = 'ListSkeleton'\n\nexport { BoardSkeleton, CardSkeleton, ListSkeleton,TableSkeleton }\n"],"mappings":";;;;;AAUA,IAAM,IAAe,EAAM,WACzB,SAAsB,EAAE,cAAW,GAAG,KAAS,GAAK;AACpD,QACE,kBAAC,OAAD;EACO;EACL,GAAI;EACJ,WAAW,EACT,kFACA,EACD;YANH;GAQE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD,EAAU,WAAU,6CAA8C,CAAA,EAClE,kBAAC,GAAD,EAAU,WAAU,qDAAsD,CAAA,CACtE;;GACN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD,EAAU,WAAU,0CAA2C,CAAA;KAC/D,kBAAC,GAAD,EAAU,WAAU,yCAA0C,CAAA;KAC9D,kBAAC,GAAD,EAAU,WAAU,yCAA0C,CAAA;KAC1D;;GACN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD,EAAU,WAAU,wDAAyD,CAAA,EAC7E,kBAAC,GAAD,EAAU,WAAU,2CAA4C,CAAA,CAC5D;;GACF;;EAGT;AAED,EAAa,cAAc;AAO3B,IAAM,IAAgB,EAAM,WAC1B,SAAuB,EACvB,UAAO,GACP,aAAU,GACV,cACA,GAAG,KACF,GAAK;AACN,QACE,kBAAC,OAAD;EACO;EACL,GAAI;EACJ,WAAW,EACT,uEACA,EACD;YANH,CASE,kBAAC,OAAD;GAAK,WAAU;aACZ,MAAM,KAAK,EAAE,QAAQ,GAAS,CAAC,CAAC,KAAK,GAAG,MACvC,kBAAC,GAAD,EAEE,WAAW,EACT,mCACA,MAAM,IAAI,YAAY,SACvB,EACD,EALK,QAAQ,IAKb,CACF;GACE,CAAA,EAGL,MAAM,KAAK,EAAE,QAAQ,GAAM,CAAC,CAAC,KAAK,GAAG,MACpC,kBAAC,OAAD;GAEE,WAAW,EACT,iDACA,IAAW,IAAO,KAAK,wCACxB;GACD,OAAO,EAAE,gBAAgB,GAAG,IAAW,GAAG,KAAK;aAE9C,MAAM,KAAK,EAAE,QAAQ,GAAS,CAAC,CAAC,KAAK,GAAG,MACvC,kBAAC,GAAD,EAEE,WAAW,EACT,mCACA,MAAa,IAAI,YAAY,SAC9B,EACD,EALK,QAAQ,EAAS,GAAG,IAKzB,CACF;GACE,EAhBC,OAAO,IAgBR,CACN,CACE;;EAGT;AAED,EAAc,cAAc;AAO5B,IAAM,IAAgB,EAAM,WAC1B,SAAuB,EACvB,aAAU,GACV,oBAAiB,GACjB,cACA,GAAG,KACF,GAAK;AACN,QACE,kBAAC,OAAD;EAAU;EAAK,GAAI;EAAO,WAAW,EAAG,kCAAkC,EAAU;YACjF,MAAM,KAAK,EAAE,QAAQ,GAAS,CAAC,CAAC,KAAK,GAAG,MACvC,kBAAC,OAAD;GAEE,WAAU;aAFZ,CAKE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,GAAD,EAAU,WAAU,mDAAoD,CAAA;MACxE,kBAAC,GAAD,EAAU,WAAU,2CAA4C,CAAA;MAChE,kBAAC,GAAD,EAAU,WAAU,yDAA0D,CAAA;MAC1E;QACN,kBAAC,GAAD,EAAU,WAAU,qDAAsD,CAAA,CACtE;OAGL,MAAM,KAAK,EAAE,QAAQ,GAAgB,CAAC,CAAC,KAAK,GAAG,MAC9C,kBAAC,OAAD;IAEE,WAAU;IACV,OAAO,EAAE,gBAAgB,IAAI,IAAW,IAAiB,KAAa,GAAG,KAAK;cAHhF,CAKE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAU,WAAU,yCAA0C,CAAA,EAC9D,kBAAC,GAAD,EAAU,WAAU,yCAA0C,CAAA,CAC1D;QACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAU,WAAU,0DAA2D,CAAA,EAC/E,kBAAC,GAAD,EAAU,WAAU,2CAA4C,CAAA,CAC5D;SACN,kBAAC,GAAD,EAAU,WAAU,wDAAyD,CAAA,CACzE;OACF;MAfC,QAAQ,EAAS,GAAG,IAerB,CACN,CACE;KAjCC,OAAO,IAiCR,CACN;EACE,CAAA;EAGT;AAED,EAAc,cAAc;AAO5B,IAAM,IAAe,EAAM,WACzB,SAAsB,EACtB,UAAO,GACP,gBAAa,IACb,cACA,GAAG,KACF,GAAK;AACN,QACE,kBAAC,OAAD;EAAU;EAAK,GAAI;EAAO,WAAW,EAAG,iBAAiB,EAAU;YAChE,MAAM,KAAK,EAAE,QAAQ,GAAM,CAAC,CAAC,KAAK,GAAG,MACpC,kBAAC,OAAD;GAEE,WAAW,EACT,wCACA,IAAI,IAAO,KAAK,wCACjB;GACD,OAAO,EAAE,gBAAgB,GAAG,IAAI,GAAG,KAAK;aAN1C;IAQG,KACC,kBAAC,GAAD,EAAU,WAAU,iEAAkE,CAAA;IAExF,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAU,WAAU,yCAA0C,CAAA,EAC9D,kBAAC,GAAD,EAAU,WAAU,yCAA0C,CAAA,CAC1D;;IACN,kBAAC,GAAD,EAAU,WAAU,0DAA2D,CAAA;IAC3E;KAfC,QAAQ,IAeT,CACN;EACE,CAAA;EAGT;AAED,EAAa,cAAc"}
1
+ {"version":3,"file":"loading-skeleton.js","names":[],"sources":["../../src/composed/loading-skeleton.tsx"],"sourcesContent":["// @server-safe\nimport * as React from 'react'\n\nimport { cn } from '../ui/lib/utils'\nimport { Skeleton } from '../ui/skeleton'\n\nexport interface CardSkeletonProps extends React.ComponentPropsWithoutRef<'div'> {\n className?: string\n}\n\nconst CardSkeleton = React.forwardRef<HTMLDivElement, CardSkeletonProps>(\n function CardSkeleton({ className, ...props }, ref) {\n return (\n <div\n ref={ref}\n {...props}\n className={cn(\n 'rounded-surface border border-surface-border-strong bg-surface-raised p-ds-05b',\n className,\n )}\n >\n <div className=\"flex items-center justify-between pb-ds-05\">\n <Skeleton className=\"h-ds-05 w-[128px] bg-surface-raised-hover\" />\n <Skeleton className=\"h-ico-sm w-ico-sm rounded bg-surface-raised-hover\" />\n </div>\n <div className=\"space-y-ds-04\">\n <Skeleton className=\"h-ds-04 w-full bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-04 w-4/5 bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-04 w-3/5 bg-surface-raised-hover\" />\n </div>\n <div className=\"flex items-center gap-ds-03 pt-ds-05\">\n <Skeleton className=\"h-ds-xs w-ds-xs rounded-pill bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-04 w-ds-11 bg-surface-raised-hover\" />\n </div>\n </div>\n )\n},\n)\n\nCardSkeleton.displayName = 'CardSkeleton'\n\nexport interface TableSkeletonProps extends CardSkeletonProps {\n rows?: number\n columns?: number\n}\n\nconst TableSkeleton = React.forwardRef<HTMLDivElement, TableSkeletonProps>(\n function TableSkeleton({\n rows = 5,\n columns = 4,\n className,\n ...props\n}, ref) {\n return (\n <div\n ref={ref}\n {...props}\n className={cn(\n 'overflow-hidden rounded-surface border border-surface-border-strong',\n className,\n )}\n >\n {/* Header */}\n <div className=\"flex items-center gap-ds-05 border-b border-surface-border-strong bg-surface-raised px-ds-05 py-ds-04\">\n {Array.from({ length: columns }).map((_, i) => (\n <Skeleton\n key={`head-${i}`}\n className={cn(\n 'h-ds-04 bg-surface-raised-hover',\n i === 0 ? 'w-ds-13' : 'flex-1',\n )}\n />\n ))}\n </div>\n\n {/* Rows */}\n {Array.from({ length: rows }).map((_, rowIndex) => (\n <div\n key={`row-${rowIndex}`}\n className={cn(\n 'flex items-center gap-ds-05 px-ds-05 py-ds-04',\n rowIndex < rows - 1 && 'border-b border-surface-border-strong',\n )}\n style={{ animationDelay: `${rowIndex * 50}ms` }}\n >\n {Array.from({ length: columns }).map((_, colIndex) => (\n <Skeleton\n key={`cell-${rowIndex}-${colIndex}`}\n className={cn(\n 'h-ds-04 bg-surface-raised-hover',\n colIndex === 0 ? 'w-ds-13' : 'flex-1',\n )}\n />\n ))}\n </div>\n ))}\n </div>\n )\n},\n)\n\nTableSkeleton.displayName = 'TableSkeleton'\n\nexport interface BoardSkeletonProps extends CardSkeletonProps {\n columns?: number\n cardsPerColumn?: number\n}\n\nconst BoardSkeleton = React.forwardRef<HTMLDivElement, BoardSkeletonProps>(\n function BoardSkeleton({\n columns = 4,\n cardsPerColumn = 3,\n className,\n ...props\n}, ref) {\n return (\n <div ref={ref} {...props} className={cn('flex gap-ds-05 overflow-x-auto', className)}>\n {Array.from({ length: columns }).map((_, colIndex) => (\n <div\n key={`col-${colIndex}`}\n className=\"flex w-[272px] shrink-0 flex-col gap-ds-03\"\n >\n {/* Column header */}\n <div className=\"flex items-center justify-between px-ds-02 py-ds-03\">\n <div className=\"flex items-center gap-ds-03\">\n <Skeleton className=\"h-ds-04 w-ds-04 rounded bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-04 w-ds-11 bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-05 w-ds-05b rounded-pill bg-surface-raised-hover\" />\n </div>\n <Skeleton className=\"h-ico-sm w-ico-sm rounded bg-surface-raised-hover\" />\n </div>\n\n {/* Column cards */}\n {Array.from({ length: cardsPerColumn }).map((_, cardIndex) => (\n <div\n key={`card-${colIndex}-${cardIndex}`}\n className=\"rounded-surface border border-surface-border-strong bg-surface-raised p-ds-04\"\n style={{ animationDelay: `${(colIndex * cardsPerColumn + cardIndex) * 50}ms` }}\n >\n <div className=\"space-y-ds-03\">\n <Skeleton className=\"h-ds-04 w-4/5 bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-04 w-3/5 bg-surface-raised-hover\" />\n </div>\n <div className=\"flex items-center justify-between pt-ds-04\">\n <div className=\"flex items-center gap-ds-02b\">\n <Skeleton className=\"h-ico-md w-ico-md rounded-pill bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-03 w-ds-10 bg-surface-raised-hover\" />\n </div>\n <Skeleton className=\"h-ds-05 w-ds-lg rounded-pill bg-surface-raised-hover\" />\n </div>\n </div>\n ))}\n </div>\n ))}\n </div>\n )\n},\n)\n\nBoardSkeleton.displayName = 'BoardSkeleton'\n\nexport interface ListSkeletonProps extends CardSkeletonProps {\n rows?: number\n showAvatar?: boolean\n}\n\nconst ListSkeleton = React.forwardRef<HTMLDivElement, ListSkeletonProps>(\n function ListSkeleton({\n rows = 6,\n showAvatar = true,\n className,\n ...props\n}, ref) {\n return (\n <div ref={ref} {...props} className={cn('flex flex-col', className)}>\n {Array.from({ length: rows }).map((_, i) => (\n <div\n key={`list-${i}`}\n className={cn(\n 'flex items-center gap-ds-04 py-ds-04',\n i < rows - 1 && 'border-b border-surface-border-strong',\n )}\n style={{ animationDelay: `${i * 50}ms` }}\n >\n {showAvatar && (\n <Skeleton className=\"h-ds-sm w-ds-sm shrink-0 rounded-pill bg-surface-raised-hover\" />\n )}\n <div className=\"flex flex-1 flex-col gap-ds-02b\">\n <Skeleton className=\"h-ds-04 w-2/5 bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-03 w-3/5 bg-surface-raised-hover\" />\n </div>\n <Skeleton className=\"h-ds-05b w-[56px] rounded-pill bg-surface-raised-hover\" />\n </div>\n ))}\n </div>\n )\n},\n)\n\nListSkeleton.displayName = 'ListSkeleton'\n\nexport { BoardSkeleton, CardSkeleton, ListSkeleton,TableSkeleton }\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"markdown-viewer.js","names":[],"sources":["../../src/composed/markdown-viewer.tsx"],"sourcesContent":["'use client'\n\nimport { IconCheck,IconCopy } from '@tabler/icons-react'\nimport * as React from 'react'\nimport Markdown from 'react-markdown'\nimport remarkGfm from 'remark-gfm'\n\nimport { Button } from '../ui/button'\nimport { Icon } from '../ui/icon'\nimport { cn } from '../ui/lib/utils'\n\n// react-syntax-highlighter is lazy-loaded in CodeBlock component below\n\n// ============================================================\n// Heading helpers\n// ============================================================\n\nfunction slugify(text: string): string {\n return text.toLowerCase().replace(/[^\\w]+/g, '-').replace(/(^-|-$)/g, '')\n}\n\n/** Recursively extract text content from React children */\nfunction extractText(node: React.ReactNode): string {\n if (typeof node === 'string') return node\n if (typeof node === 'number') return String(node)\n if (!node) return ''\n if (Array.isArray(node)) return node.map(extractText).join('')\n if (typeof node === 'object' && 'props' in node) {\n return extractText((node as React.ReactElement<{ children?: React.ReactNode }>).props.children)\n }\n return ''\n}\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface MarkdownViewerProps extends React.HTMLAttributes<HTMLDivElement> {\n content: string\n /** Tighter spacing for inline use */\n compact?: boolean\n /** Allow raw HTML in markdown @default false */\n allowHtml?: boolean\n /** Link target @default '_blank' */\n linkTarget?: string\n}\n\n// ============================================================\n// MarkdownViewer\n// ============================================================\n\n// Small copy-to-clipboard button for code blocks\nfunction CopyButton({ code }: { code: string }) {\n const [copied, setCopied] = React.useState(false)\n const timerRef = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n React.useEffect(() => () => clearTimeout(timerRef.current), [])\n\n function handleCopy() {\n navigator.clipboard.writeText(code).then(() => {\n setCopied(true)\n timerRef.current = setTimeout(() => setCopied(false), 2000)\n })\n }\n\n return (\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n className=\"absolute top-ds-02 right-ds-02 opacity-0 group-hover:opacity-100 transition-opacity\"\n onClick={handleCopy}\n aria-label={copied ? 'Copied' : 'Copy code'}\n >\n {copied ? <Icon icon={IconCheck} size=\"xs\" /> : <Icon icon={IconCopy} size=\"xs\" />}\n </Button>\n )\n}\n\n// Syntax-highlighted code block with lazy-loaded highlighter\nfunction CodeBlock({ language, code, mb }: { language: string; code: string; mb: string }) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const [modules, setModules] = React.useState<{ Highlighter: any; style: any } | null>(null)\n\n React.useEffect(() => {\n let cancelled = false\n Promise.all([\n import('react-syntax-highlighter'),\n import('react-syntax-highlighter/dist/esm/styles/prism/one-dark'),\n ]).then(([hlMod, styleMod]) => {\n if (!cancelled) {\n setModules({ Highlighter: hlMod.Prism ?? hlMod.default, style: styleMod.default })\n }\n }).catch(() => { /* fallback to plain pre */ })\n return () => { cancelled = true }\n }, [])\n\n if (!modules) {\n return (\n <div className={cn('group relative', mb)}>\n <pre className=\"bg-surface-sunken rounded-control p-ds-04 overflow-x-auto text-ds-sm font-mono\">\n <code>{code}</code>\n </pre>\n <CopyButton code={code} />\n </div>\n )\n }\n\n const { Highlighter, style } = modules\n return (\n <div className={cn('group relative', mb)}>\n <Highlighter\n language={language}\n style={style}\n customStyle={{\n margin: 0,\n borderRadius: 'var(--radius-ds-md)',\n fontSize: 'var(--text-ds-sm)',\n padding: 'var(--spacing-ds-04)',\n }}\n >\n {code}\n </Highlighter>\n <CopyButton code={code} />\n </div>\n )\n}\n\nconst MarkdownViewer = React.forwardRef<HTMLDivElement, MarkdownViewerProps>(({\n content,\n compact = false,\n allowHtml = false,\n linkTarget = '_blank',\n className,\n ...props\n}, ref) => {\n const mb = compact ? 'mb-ds-02' : 'mb-ds-03'\n const mt = compact ? 'mt-ds-03' : 'mt-ds-05'\n\n return (\n <div ref={ref} className={cn('font-sans text-surface-fg', className)} {...props}>\n <Markdown\n remarkPlugins={[remarkGfm]}\n skipHtml={!allowHtml}\n components={{\n h1: ({ children }) => {\n const slug = slugify(extractText(children))\n return (\n <h1 id={slug} className={cn('group', compact ? 'text-ds-md' : 'text-ds-lg', 'font-semibold text-surface-fg', mt, mb)}>\n <a href={`#${slug}`} className=\"opacity-0 group-hover:opacity-100 text-surface-fg-subtle mr-ds-02 no-underline\" aria-hidden=\"true\">\n #\n </a>\n {children}\n </h1>\n )\n },\n h2: ({ children }) => {\n const slug = slugify(extractText(children))\n return (\n <h2 id={slug} className={cn('group', 'text-ds-md font-semibold text-surface-fg', compact ? 'mt-ds-03' : 'mt-ds-04', mb)}>\n <a href={`#${slug}`} className=\"opacity-0 group-hover:opacity-100 text-surface-fg-subtle mr-ds-02 no-underline\" aria-hidden=\"true\">\n #\n </a>\n {children}\n </h2>\n )\n },\n h3: ({ children }) => {\n const slug = slugify(extractText(children))\n return (\n <h3 id={slug} className={cn('group', 'text-ds-md font-semibold text-surface-fg', 'mt-ds-03', mb)}>\n <a href={`#${slug}`} className=\"opacity-0 group-hover:opacity-100 text-surface-fg-subtle mr-ds-02 no-underline\" aria-hidden=\"true\">\n #\n </a>\n {children}\n </h3>\n )\n },\n p: ({ children }) => (\n <p className={cn('text-ds-md text-surface-fg leading-ds-relaxed', mb)}>\n {children}\n </p>\n ),\n a: ({ href, children }) => (\n <a\n href={href}\n target={linkTarget}\n rel={linkTarget === '_blank' ? 'noopener noreferrer' : undefined}\n className=\"text-accent-11 hover:underline\"\n >\n {children}\n </a>\n ),\n code: ({ className: codeClassName, children, ...codeProps }) => {\n const langMatch = codeClassName ? /language-(\\w+)/.exec(codeClassName) : null\n if (langMatch) {\n const lang = langMatch[1]\n const codeString = String(children).replace(/\\n$/, '')\n return <CodeBlock language={lang} code={codeString} mb={mb} />\n }\n return (\n <code className=\"bg-surface-sunken rounded-control-inner px-1.5 py-0.5 text-ds-sm font-mono text-surface-fg\" {...codeProps}>\n {children}\n </code>\n )\n },\n pre: ({ children }) => (\n <>{children}</>\n ),\n blockquote: ({ children }) => (\n <blockquote className={cn('border-l-2 border-surface-border-subtle pl-ds-04 text-surface-fg-muted italic', mb)}>\n {children}\n </blockquote>\n ),\n ul: ({ children }) => (\n <ul className={cn('list-disc pl-ds-06 text-ds-md text-surface-fg space-y-ds-01', mb)}>\n {children}\n </ul>\n ),\n ol: ({ children }) => (\n <ol className={cn('list-decimal pl-ds-06 text-ds-md text-surface-fg space-y-ds-01', mb)}>\n {children}\n </ol>\n ),\n table: ({ children }) => (\n <div className={cn('overflow-x-auto', mb)}>\n <table className=\"w-full border-collapse\">\n {children}\n </table>\n </div>\n ),\n th: ({ children }) => (\n <th className=\"border border-surface-border-subtle px-ds-03 py-ds-02 text-left text-ds-sm font-semibold bg-surface-sunken\">\n {children}\n </th>\n ),\n td: ({ children }) => (\n <td className=\"border border-surface-border-subtle px-ds-03 py-ds-02 text-ds-sm\">\n {children}\n </td>\n ),\n hr: () => <hr className={cn('border-surface-border-subtle', compact ? 'my-ds-03' : 'my-ds-04')} />,\n img: ({ src, alt }) => (\n <img src={src} alt={alt ?? ''} className=\"rounded-control max-w-full\" loading=\"lazy\" />\n ),\n }}\n >\n {content}\n </Markdown>\n </div>\n )\n})\nMarkdownViewer.displayName = 'MarkdownViewer'\n\nexport { MarkdownViewer }\n"],"mappings":"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"}
1
+ {"version":3,"file":"markdown-viewer.js","names":[],"sources":["../../src/composed/markdown-viewer.tsx"],"sourcesContent":["'use client'\n\nimport { IconCheck,IconCopy } from '@tabler/icons-react'\nimport * as React from 'react'\nimport Markdown from 'react-markdown'\nimport remarkGfm from 'remark-gfm'\n\nimport { Button } from '../ui/button'\nimport { Icon } from '../ui/icon'\nimport { cn } from '../ui/lib/utils'\n\n// react-syntax-highlighter is lazy-loaded in CodeBlock component below\n\n// ============================================================\n// Heading helpers\n// ============================================================\n\nfunction slugify(text: string): string {\n return text.toLowerCase().replace(/[^\\w]+/g, '-').replace(/(^-|-$)/g, '')\n}\n\n/** Recursively extract text content from React children */\nfunction extractText(node: React.ReactNode): string {\n if (typeof node === 'string') return node\n if (typeof node === 'number') return String(node)\n if (!node) return ''\n if (Array.isArray(node)) return node.map(extractText).join('')\n if (typeof node === 'object' && 'props' in node) {\n return extractText((node as React.ReactElement<{ children?: React.ReactNode }>).props.children)\n }\n return ''\n}\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface MarkdownViewerProps extends React.HTMLAttributes<HTMLDivElement> {\n content: string\n /** Tighter spacing for inline use */\n compact?: boolean\n /** Allow raw HTML in markdown @default false */\n allowHtml?: boolean\n /** Link target @default '_blank' */\n linkTarget?: string\n}\n\n// ============================================================\n// MarkdownViewer\n// ============================================================\n\n// Small copy-to-clipboard button for code blocks\nfunction CopyButton({ code }: { code: string }) {\n const [copied, setCopied] = React.useState(false)\n const timerRef = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n React.useEffect(() => () => clearTimeout(timerRef.current), [])\n\n function handleCopy() {\n navigator.clipboard.writeText(code).then(() => {\n setCopied(true)\n timerRef.current = setTimeout(() => setCopied(false), 2000)\n })\n }\n\n return (\n <Button\n variant=\"ghost\"\n size=\"icon-xs\"\n className=\"absolute top-ds-02 right-ds-02 opacity-0 group-hover:opacity-100 transition-opacity\"\n onClick={handleCopy}\n aria-label={copied ? 'Copied' : 'Copy code'}\n >\n {copied ? <Icon icon={IconCheck} size=\"xs\" /> : <Icon icon={IconCopy} size=\"xs\" />}\n </Button>\n )\n}\n\n// Syntax-highlighted code block with lazy-loaded highlighter\nfunction CodeBlock({ language, code, mb }: { language: string; code: string; mb: string }) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const [modules, setModules] = React.useState<{ Highlighter: any; style: any } | null>(null)\n\n React.useEffect(() => {\n let cancelled = false\n Promise.all([\n import('react-syntax-highlighter'),\n import('react-syntax-highlighter/dist/esm/styles/prism/one-dark'),\n ]).then(([hlMod, styleMod]) => {\n if (!cancelled) {\n setModules({ Highlighter: hlMod.Prism ?? hlMod.default, style: styleMod.default })\n }\n }).catch(() => { /* fallback to plain pre */ })\n return () => { cancelled = true }\n }, [])\n\n if (!modules) {\n return (\n <div className={cn('group relative', mb)}>\n <pre className=\"bg-surface-sunken rounded-control p-ds-04 overflow-x-auto text-ds-sm font-mono\">\n <code>{code}</code>\n </pre>\n <CopyButton code={code} />\n </div>\n )\n }\n\n const { Highlighter, style } = modules\n return (\n <div className={cn('group relative', mb)}>\n <Highlighter\n language={language}\n style={style}\n customStyle={{\n margin: 0,\n borderRadius: 'var(--radius-ds-md)',\n fontSize: 'var(--text-ds-sm)',\n padding: 'var(--spacing-ds-04)',\n }}\n >\n {code}\n </Highlighter>\n <CopyButton code={code} />\n </div>\n )\n}\n\nconst MarkdownViewer = React.forwardRef<HTMLDivElement, MarkdownViewerProps>(({\n content,\n compact = false,\n allowHtml = false,\n linkTarget = '_blank',\n className,\n ...props\n}, ref) => {\n const mb = compact ? 'mb-ds-02' : 'mb-ds-03'\n const mt = compact ? 'mt-ds-03' : 'mt-ds-05'\n\n return (\n <div ref={ref} className={cn('font-sans text-surface-fg', className)} {...props}>\n <Markdown\n remarkPlugins={[remarkGfm]}\n skipHtml={!allowHtml}\n components={{\n h1: ({ children }) => {\n const slug = slugify(extractText(children))\n return (\n <h1 id={slug} className={cn('group', compact ? 'text-ds-md' : 'text-ds-lg', 'font-semibold text-surface-fg', mt, mb)}>\n <a href={`#${slug}`} className=\"opacity-0 group-hover:opacity-100 text-surface-fg-subtle mr-ds-02 no-underline\" aria-hidden=\"true\">\n #\n </a>\n {children}\n </h1>\n )\n },\n h2: ({ children }) => {\n const slug = slugify(extractText(children))\n return (\n <h2 id={slug} className={cn('group', 'text-ds-md font-semibold text-surface-fg', compact ? 'mt-ds-03' : 'mt-ds-04', mb)}>\n <a href={`#${slug}`} className=\"opacity-0 group-hover:opacity-100 text-surface-fg-subtle mr-ds-02 no-underline\" aria-hidden=\"true\">\n #\n </a>\n {children}\n </h2>\n )\n },\n h3: ({ children }) => {\n const slug = slugify(extractText(children))\n return (\n <h3 id={slug} className={cn('group', 'text-ds-md font-semibold text-surface-fg', 'mt-ds-03', mb)}>\n <a href={`#${slug}`} className=\"opacity-0 group-hover:opacity-100 text-surface-fg-subtle mr-ds-02 no-underline\" aria-hidden=\"true\">\n #\n </a>\n {children}\n </h3>\n )\n },\n p: ({ children }) => (\n <p className={cn('text-ds-md text-surface-fg leading-ds-relaxed', mb)}>\n {children}\n </p>\n ),\n a: ({ href, children }) => (\n <a\n href={href}\n target={linkTarget}\n rel={linkTarget === '_blank' ? 'noopener noreferrer' : undefined}\n className=\"text-accent-11 hover:underline\"\n >\n {children}\n </a>\n ),\n code: ({ className: codeClassName, children, ...codeProps }) => {\n const langMatch = codeClassName ? /language-(\\w+)/.exec(codeClassName) : null\n if (langMatch) {\n const lang = langMatch[1]\n const codeString = String(children).replace(/\\n$/, '')\n return <CodeBlock language={lang} code={codeString} mb={mb} />\n }\n return (\n <code className=\"bg-surface-sunken rounded-control-inner px-1.5 py-0.5 text-ds-sm font-mono text-surface-fg\" {...codeProps}>\n {children}\n </code>\n )\n },\n pre: ({ children }) => (\n <>{children}</>\n ),\n blockquote: ({ children }) => (\n <blockquote className={cn('border-l-2 border-surface-border-subtle pl-ds-04 text-surface-fg-muted italic', mb)}>\n {children}\n </blockquote>\n ),\n ul: ({ children }) => (\n <ul className={cn('list-disc pl-ds-06 text-ds-md text-surface-fg space-y-ds-01', mb)}>\n {children}\n </ul>\n ),\n ol: ({ children }) => (\n <ol className={cn('list-decimal pl-ds-06 text-ds-md text-surface-fg space-y-ds-01', mb)}>\n {children}\n </ol>\n ),\n table: ({ children }) => (\n <div className={cn('overflow-x-auto', mb)}>\n <table className=\"w-full border-collapse\">\n {children}\n </table>\n </div>\n ),\n th: ({ children }) => (\n <th className=\"border border-surface-border-subtle px-ds-03 py-ds-02 text-left text-ds-sm font-semibold bg-surface-sunken\">\n {children}\n </th>\n ),\n td: ({ children }) => (\n <td className=\"border border-surface-border-subtle px-ds-03 py-ds-02 text-ds-sm\">\n {children}\n </td>\n ),\n hr: () => <hr className={cn('border-surface-border-subtle', compact ? 'my-ds-03' : 'my-ds-04')} />,\n img: ({ src, alt }) => (\n <img src={src} alt={alt ?? ''} className=\"rounded-control max-w-full\" loading=\"lazy\" />\n ),\n }}\n >\n {content}\n </Markdown>\n </div>\n )\n})\nMarkdownViewer.displayName = 'MarkdownViewer'\n\nexport { MarkdownViewer }\n"],"mappings":"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"}
@@ -26,9 +26,9 @@ interface MasterDetailDetailProps extends React.HTMLAttributes<HTMLDivElement> {
26
26
  interface MasterDetailListItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
27
27
  active?: boolean;
28
28
  }
29
- declare function MasterDetailList({ children, className, ...props }: MasterDetailListProps): import("react/jsx-runtime").JSX.Element | null;
30
- declare function MasterDetailDetail({ children, className, ...props }: MasterDetailDetailProps): import("react/jsx-runtime").JSX.Element | null;
31
- declare function MasterDetailRoot({ selected, onBack, masterWidth, breakpoint, emptyState, onNavigate, children, className, style, ...props }: MasterDetailProps): import("react/jsx-runtime").JSX.Element;
29
+ declare function MasterDetailList({ children, className, ...props }: MasterDetailListProps): React.JSX.Element | null;
30
+ declare function MasterDetailDetail({ children, className, ...props }: MasterDetailDetailProps): React.JSX.Element | null;
31
+ declare function MasterDetailRoot({ selected, onBack, masterWidth, breakpoint, emptyState, onNavigate, children, className, style, ...props }: MasterDetailProps): React.JSX.Element;
32
32
  declare const MasterDetail: typeof MasterDetailRoot & {
33
33
  List: typeof MasterDetailList;
34
34
  Detail: typeof MasterDetailDetail;