@devalok/shilp-sutra 0.34.1 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (439) hide show
  1. package/LICENSE +21 -21
  2. package/dist/_chunks/badge-group.js +95 -95
  3. package/dist/_chunks/badge-group.js.map +1 -0
  4. package/dist/_chunks/chat.js +7 -2
  5. package/dist/_chunks/chat.js.map +1 -0
  6. package/dist/_chunks/date-picker.js.map +1 -0
  7. package/dist/_chunks/document-preview.js.map +1 -0
  8. package/dist/_chunks/file-preview.js.map +1 -0
  9. package/dist/_chunks/framer.js +62 -62
  10. package/dist/_chunks/framer.js.map +1 -0
  11. package/dist/_chunks/image-preview.js +1 -1
  12. package/dist/_chunks/image-preview.js.map +1 -0
  13. package/dist/_chunks/keybinding.js.map +1 -0
  14. package/dist/_chunks/link-context.js.map +1 -0
  15. package/dist/_chunks/mention-suggestion.js.map +1 -0
  16. package/dist/_chunks/motion-provider.js.map +1 -0
  17. package/dist/_chunks/popover.js +32 -36
  18. package/dist/_chunks/popover.js.map +1 -0
  19. package/dist/_chunks/primitives.js +686 -686
  20. package/dist/_chunks/primitives.js.map +1 -0
  21. package/dist/_chunks/rich-chat-input.js +650 -649
  22. package/dist/_chunks/rich-chat-input.js.map +1 -0
  23. package/dist/_chunks/shared.js.map +1 -0
  24. package/dist/_chunks/sonner.js.map +1 -0
  25. package/dist/_chunks/stat-row.js +158 -158
  26. package/dist/_chunks/stat-row.js.map +1 -0
  27. package/dist/_chunks/tiptap.js +11 -11
  28. package/dist/_chunks/tiptap.js.map +1 -0
  29. package/dist/_chunks/tree-view.js +1 -1
  30. package/dist/_chunks/tree-view.js.map +1 -0
  31. package/dist/_chunks/use-calendar.js.map +1 -0
  32. package/dist/_chunks/vendor-client.js +1 -1
  33. package/dist/_chunks/vendor-client.js.map +1 -0
  34. package/dist/_chunks/vendor-utils.js.map +1 -0
  35. package/dist/ai/ai-command-provider.js.map +1 -0
  36. package/dist/ai/block-renderer.js.map +1 -0
  37. package/dist/ai/blocks/loading.d.ts.map +1 -1
  38. package/dist/ai/command-bar.js.map +1 -0
  39. package/dist/ai/conversation.js +76 -76
  40. package/dist/ai/conversation.js.map +1 -0
  41. package/dist/ai/devadoot-icon.d.ts.map +1 -1
  42. package/dist/ai/index.js.map +1 -0
  43. package/dist/composed/activity-feed.js.map +1 -0
  44. package/dist/composed/avatar-group.js +1 -1
  45. package/dist/composed/avatar-group.js.map +1 -0
  46. package/dist/composed/bulk-action-bar.js +13 -21
  47. package/dist/composed/bulk-action-bar.js.map +1 -0
  48. package/dist/composed/command-palette.js.map +1 -0
  49. package/dist/composed/confirm-dialog.js.map +1 -0
  50. package/dist/composed/content-card.js.map +1 -0
  51. package/dist/composed/deadline-indicator.js.map +1 -0
  52. package/dist/composed/emoji-picker.js.map +1 -0
  53. package/dist/composed/empty-state.d.ts.map +1 -1
  54. package/dist/composed/empty-state.js +30 -30
  55. package/dist/composed/empty-state.js.map +1 -0
  56. package/dist/composed/error-boundary.js.map +1 -0
  57. package/dist/composed/filter-bar.js.map +1 -0
  58. package/dist/composed/form-section.js.map +1 -0
  59. package/dist/composed/global-loading.js.map +1 -0
  60. package/dist/composed/inline-edit.js.map +1 -0
  61. package/dist/composed/lib/string-utils.js.map +1 -0
  62. package/dist/composed/loading-skeleton.js.map +1 -0
  63. package/dist/composed/markdown-viewer.js.map +1 -0
  64. package/dist/composed/master-detail.js.map +1 -0
  65. package/dist/composed/member-picker.js.map +1 -0
  66. package/dist/composed/multi-select-popover.d.ts.map +1 -1
  67. package/dist/composed/multi-select-popover.js +4 -0
  68. package/dist/composed/multi-select-popover.js.map +1 -0
  69. package/dist/composed/page-header.js.map +1 -0
  70. package/dist/composed/page-skeletons.js.map +1 -0
  71. package/dist/composed/priority-indicator.js.map +1 -0
  72. package/dist/composed/responsive-overlay.js.map +1 -0
  73. package/dist/composed/rich-chat-input/attachment-strip.d.ts.map +1 -1
  74. package/dist/composed/rich-chat-input/reply-banner.d.ts.map +1 -1
  75. package/dist/composed/rich-chat-input/schedule-send.d.ts.map +1 -1
  76. package/dist/composed/rich-chat-input.d.ts.map +1 -1
  77. package/dist/composed/rich-text-editor.js.map +1 -0
  78. package/dist/composed/schedule-view.js.map +1 -0
  79. package/dist/composed/simple-tooltip.js.map +1 -0
  80. package/dist/composed/status-badge.d.ts.map +1 -1
  81. package/dist/composed/status-badge.js.map +1 -0
  82. package/dist/hooks/use-color-mode.js.map +1 -0
  83. package/dist/hooks/use-mobile.js.map +1 -0
  84. package/dist/hooks/use-touch-device.js.map +1 -0
  85. package/dist/hooks/use-viewport-height.js.map +1 -0
  86. package/dist/motion/check-motion-provider.d.ts +3 -0
  87. package/dist/motion/check-motion-provider.d.ts.map +1 -0
  88. package/dist/motion/index.js +14 -0
  89. package/dist/motion/index.js.map +1 -0
  90. package/dist/motion/primitives-index.js.map +1 -0
  91. package/dist/primitives/react-accordion.d.ts +114 -114
  92. package/dist/primitives/react-alert-dialog.d.ts +51 -51
  93. package/dist/primitives/react-aspect-ratio.d.ts +11 -11
  94. package/dist/primitives/react-avatar.d.ts +24 -24
  95. package/dist/primitives/react-checkbox.d.ts +50 -50
  96. package/dist/primitives/react-collapsible.d.ts +33 -33
  97. package/dist/primitives/react-context-menu.d.ts +96 -96
  98. package/dist/primitives/react-dialog.d.ts +103 -103
  99. package/dist/primitives/react-dropdown-menu.d.ts +97 -97
  100. package/dist/primitives/react-hover-card.d.ts +79 -79
  101. package/dist/primitives/react-label.d.ts +10 -10
  102. package/dist/primitives/react-menu.d.ts +169 -169
  103. package/dist/primitives/react-menubar.d.ts +115 -115
  104. package/dist/primitives/react-navigation-menu.d.ts +126 -126
  105. package/dist/primitives/react-popover.d.ts +85 -85
  106. package/dist/primitives/react-progress.d.ts +19 -19
  107. package/dist/primitives/react-radio-group.d.ts +58 -58
  108. package/dist/primitives/react-roving-focus.d.ts +49 -49
  109. package/dist/primitives/react-select.d.ts +137 -137
  110. package/dist/primitives/react-separator.d.ts +21 -21
  111. package/dist/primitives/react-slider.d.ts +75 -75
  112. package/dist/primitives/react-switch.d.ts +21 -21
  113. package/dist/primitives/react-tabs.d.ts +56 -56
  114. package/dist/primitives/react-toast.d.ts +120 -120
  115. package/dist/primitives/react-toggle-group.d.ts +75 -75
  116. package/dist/primitives/react-toggle.d.ts +24 -24
  117. package/dist/primitives/react-tooltip.d.ts +101 -101
  118. package/dist/primitives/react-visually-hidden.d.ts +22 -22
  119. package/dist/shell/app-command-palette.d.ts +2 -0
  120. package/dist/shell/app-command-palette.d.ts.map +1 -1
  121. package/dist/shell/app-command-palette.js +42 -155
  122. package/dist/shell/app-command-palette.js.map +1 -0
  123. package/dist/shell/bottom-navbar.js +1 -1
  124. package/dist/shell/bottom-navbar.js.map +1 -0
  125. package/dist/shell/command-registry.js.map +1 -0
  126. package/dist/shell/notification-center.d.ts.map +1 -1
  127. package/dist/shell/notification-center.js +194 -169
  128. package/dist/shell/notification-center.js.map +1 -0
  129. package/dist/shell/notification-preferences.js.map +1 -0
  130. package/dist/shell/sidebar.js.map +1 -0
  131. package/dist/shell/top-bar.js +1 -1
  132. package/dist/shell/top-bar.js.map +1 -0
  133. package/dist/tailwind/index.cjs +48 -1
  134. package/dist/tailwind/preset.d.ts.map +1 -1
  135. package/dist/tailwind/preset.js +48 -1
  136. package/dist/tailwind/preset.js.map +1 -0
  137. package/dist/tokens/index.css +4 -4
  138. package/dist/tokens/primitives.css +442 -442
  139. package/dist/tokens/semantic.css +742 -547
  140. package/dist/tokens/typography-semantic.css +123 -100
  141. package/dist/tokens/typography.css +422 -422
  142. package/dist/ui/accordion.js +13 -13
  143. package/dist/ui/accordion.js.map +1 -0
  144. package/dist/ui/alert-dialog.d.ts +6 -2
  145. package/dist/ui/alert-dialog.d.ts.map +1 -1
  146. package/dist/ui/alert-dialog.js +43 -42
  147. package/dist/ui/alert-dialog.js.map +1 -0
  148. package/dist/ui/alert.d.ts +3 -2
  149. package/dist/ui/alert.d.ts.map +1 -1
  150. package/dist/ui/alert.js +31 -5
  151. package/dist/ui/alert.js.map +1 -0
  152. package/dist/ui/aspect-ratio.js +1 -1
  153. package/dist/ui/aspect-ratio.js.map +1 -0
  154. package/dist/ui/autocomplete.d.ts.map +1 -1
  155. package/dist/ui/autocomplete.js +92 -67
  156. package/dist/ui/autocomplete.js.map +1 -0
  157. package/dist/ui/avatar.js +9 -9
  158. package/dist/ui/avatar.js.map +1 -0
  159. package/dist/ui/badge-indicator.js.map +1 -0
  160. package/dist/ui/banner.js.map +1 -0
  161. package/dist/ui/breadcrumb.js +1 -1
  162. package/dist/ui/breadcrumb.js.map +1 -0
  163. package/dist/ui/button-group.js.map +1 -0
  164. package/dist/ui/button-processing.d.ts.map +1 -1
  165. package/dist/ui/button-processing.js +61 -40
  166. package/dist/ui/button-processing.js.map +1 -0
  167. package/dist/ui/button.js +8 -8
  168. package/dist/ui/button.js.map +1 -0
  169. package/dist/ui/card.js.map +1 -0
  170. package/dist/ui/charts/bar-chart.d.ts.map +1 -1
  171. package/dist/ui/charts/chart-container.d.ts +2 -0
  172. package/dist/ui/charts/chart-container.d.ts.map +1 -1
  173. package/dist/ui/charts/index.js +88 -65
  174. package/dist/ui/charts/index.js.map +1 -0
  175. package/dist/ui/charts/line-chart.d.ts.map +1 -1
  176. package/dist/ui/chat/message-input.d.ts.map +1 -1
  177. package/dist/ui/chat/message-list.d.ts +1 -1
  178. package/dist/ui/chat/message-list.d.ts.map +1 -1
  179. package/dist/ui/chat/message.d.ts.map +1 -1
  180. package/dist/ui/chat/system-message.d.ts.map +1 -1
  181. package/dist/ui/checkbox.d.ts.map +1 -1
  182. package/dist/ui/checkbox.js +33 -28
  183. package/dist/ui/checkbox.js.map +1 -0
  184. package/dist/ui/code.js.map +1 -0
  185. package/dist/ui/collapsible.js +1 -1
  186. package/dist/ui/collapsible.js.map +1 -0
  187. package/dist/ui/color-input.d.ts.map +1 -1
  188. package/dist/ui/color-input.js +165 -163
  189. package/dist/ui/color-input.js.map +1 -0
  190. package/dist/ui/color-swatch.js.map +1 -0
  191. package/dist/ui/combobox.d.ts +7 -0
  192. package/dist/ui/combobox.d.ts.map +1 -1
  193. package/dist/ui/combobox.js +147 -113
  194. package/dist/ui/combobox.js.map +1 -0
  195. package/dist/ui/container.js +1 -1
  196. package/dist/ui/container.js.map +1 -0
  197. package/dist/ui/context-menu.js.map +1 -0
  198. package/dist/ui/data-table-body.js.map +1 -0
  199. package/dist/ui/data-table-bulk-actions.js +1 -1
  200. package/dist/ui/data-table-bulk-actions.js.map +1 -0
  201. package/dist/ui/data-table-card.js.map +1 -0
  202. package/dist/ui/data-table-context.js.map +1 -0
  203. package/dist/ui/data-table-header.js.map +1 -0
  204. package/dist/ui/data-table-pagination.js.map +1 -0
  205. package/dist/ui/data-table-toolbar.js.map +1 -0
  206. package/dist/ui/data-table.js +34 -31
  207. package/dist/ui/data-table.js.map +1 -0
  208. package/dist/ui/devalok-grain.js.map +1 -0
  209. package/dist/ui/dialog.js +31 -35
  210. package/dist/ui/dialog.js.map +1 -0
  211. package/dist/ui/dropdown-menu.js.map +1 -0
  212. package/dist/ui/file-upload.js +120 -120
  213. package/dist/ui/file-upload.js.map +1 -0
  214. package/dist/ui/form.d.ts +8 -0
  215. package/dist/ui/form.d.ts.map +1 -1
  216. package/dist/ui/form.js +14 -12
  217. package/dist/ui/form.js.map +1 -0
  218. package/dist/ui/hover-card.js.map +1 -0
  219. package/dist/ui/icon-button.js.map +1 -0
  220. package/dist/ui/icon-context.js.map +1 -0
  221. package/dist/ui/icon-group.js.map +1 -0
  222. package/dist/ui/icon.js.map +1 -0
  223. package/dist/ui/index.d.ts +4 -4
  224. package/dist/ui/index.d.ts.map +1 -1
  225. package/dist/ui/index.js +82 -66
  226. package/dist/ui/index.js.map +1 -0
  227. package/dist/ui/input-otp.d.ts +12 -3
  228. package/dist/ui/input-otp.d.ts.map +1 -1
  229. package/dist/ui/input-otp.js +41 -27
  230. package/dist/ui/input-otp.js.map +1 -0
  231. package/dist/ui/input.d.ts.map +1 -1
  232. package/dist/ui/input.js +16 -15
  233. package/dist/ui/input.js.map +1 -0
  234. package/dist/ui/label.d.ts.map +1 -1
  235. package/dist/ui/label.js +19 -14
  236. package/dist/ui/label.js.map +1 -0
  237. package/dist/ui/lib/check-tokens.d.ts +3 -0
  238. package/dist/ui/lib/check-tokens.d.ts.map +1 -0
  239. package/dist/ui/lib/date-utils.js.map +1 -0
  240. package/dist/ui/lib/motion.d.ts +15 -4
  241. package/dist/ui/lib/motion.d.ts.map +1 -1
  242. package/dist/ui/lib/motion.js +18 -9
  243. package/dist/ui/lib/motion.js.map +1 -0
  244. package/dist/ui/lib/utils.js.map +1 -0
  245. package/dist/ui/link.js +2 -2
  246. package/dist/ui/link.js.map +1 -0
  247. package/dist/ui/menubar.js.map +1 -0
  248. package/dist/ui/navigation-menu.js.map +1 -0
  249. package/dist/ui/number-input.d.ts +16 -1
  250. package/dist/ui/number-input.d.ts.map +1 -1
  251. package/dist/ui/number-input.js +79 -49
  252. package/dist/ui/number-input.js.map +1 -0
  253. package/dist/ui/pagination.js +1 -1
  254. package/dist/ui/pagination.js.map +1 -0
  255. package/dist/ui/progress-ring.d.ts.map +1 -1
  256. package/dist/ui/progress-ring.js.map +1 -0
  257. package/dist/ui/progress.js.map +1 -0
  258. package/dist/ui/radio.d.ts.map +1 -1
  259. package/dist/ui/radio.js +27 -20
  260. package/dist/ui/radio.js.map +1 -0
  261. package/dist/ui/search-input.js.map +1 -0
  262. package/dist/ui/segmented-control.d.ts +1 -1
  263. package/dist/ui/segmented-control.d.ts.map +1 -1
  264. package/dist/ui/segmented-control.js +2 -0
  265. package/dist/ui/segmented-control.js.map +1 -0
  266. package/dist/ui/select.d.ts.map +1 -1
  267. package/dist/ui/select.js +54 -48
  268. package/dist/ui/select.js.map +1 -0
  269. package/dist/ui/separator.d.ts.map +1 -1
  270. package/dist/ui/separator.js +10 -7
  271. package/dist/ui/separator.js.map +1 -0
  272. package/dist/ui/sheet.js +29 -29
  273. package/dist/ui/sheet.js.map +1 -0
  274. package/dist/ui/sidebar.js +7 -7
  275. package/dist/ui/sidebar.js.map +1 -0
  276. package/dist/ui/skeleton.js.map +1 -0
  277. package/dist/ui/slider.d.ts +22 -3
  278. package/dist/ui/slider.d.ts.map +1 -1
  279. package/dist/ui/slider.js +57 -19
  280. package/dist/ui/slider.js.map +1 -0
  281. package/dist/ui/spinner.js.map +1 -0
  282. package/dist/ui/split-button.d.ts.map +1 -1
  283. package/dist/ui/split-button.js +77 -76
  284. package/dist/ui/split-button.js.map +1 -0
  285. package/dist/ui/stack.js.map +1 -0
  286. package/dist/ui/stat-card.js.map +1 -0
  287. package/dist/ui/status-dot.js.map +1 -0
  288. package/dist/ui/stepper.d.ts +10 -0
  289. package/dist/ui/stepper.d.ts.map +1 -1
  290. package/dist/ui/stepper.js +80 -75
  291. package/dist/ui/stepper.js.map +1 -0
  292. package/dist/ui/switch.d.ts.map +1 -1
  293. package/dist/ui/switch.js +26 -22
  294. package/dist/ui/switch.js.map +1 -0
  295. package/dist/ui/table.js.map +1 -0
  296. package/dist/ui/tabs.d.ts +3 -1
  297. package/dist/ui/tabs.d.ts.map +1 -1
  298. package/dist/ui/tabs.js +68 -48
  299. package/dist/ui/tabs.js.map +1 -0
  300. package/dist/ui/text.d.ts +1 -1
  301. package/dist/ui/text.d.ts.map +1 -1
  302. package/dist/ui/text.js +10 -2
  303. package/dist/ui/text.js.map +1 -0
  304. package/dist/ui/textarea.js +1 -1
  305. package/dist/ui/textarea.js.map +1 -0
  306. package/dist/ui/toast-registry.d.ts +8 -0
  307. package/dist/ui/toast-registry.d.ts.map +1 -0
  308. package/dist/ui/toast-registry.js +13 -0
  309. package/dist/ui/toast-registry.js.map +1 -0
  310. package/dist/ui/toast.d.ts.map +1 -1
  311. package/dist/ui/toast.js +141 -136
  312. package/dist/ui/toast.js.map +1 -0
  313. package/dist/ui/toaster.d.ts.map +1 -1
  314. package/dist/ui/toaster.js +15 -14
  315. package/dist/ui/toaster.js.map +1 -0
  316. package/dist/ui/toggle-group.d.ts +2 -0
  317. package/dist/ui/toggle-group.d.ts.map +1 -1
  318. package/dist/ui/toggle-group.js +23 -16
  319. package/dist/ui/toggle-group.js.map +1 -0
  320. package/dist/ui/toggle.d.ts +2 -0
  321. package/dist/ui/toggle.d.ts.map +1 -1
  322. package/dist/ui/toggle.js +14 -6
  323. package/dist/ui/toggle.js.map +1 -0
  324. package/dist/ui/tooltip.js.map +1 -0
  325. package/dist/ui/visually-hidden.js.map +1 -0
  326. package/docs/components/_header.md +85 -85
  327. package/docs/components/composed/activity-feed.md +62 -62
  328. package/docs/components/composed/avatar-group.md +65 -65
  329. package/docs/components/composed/bulk-action-bar.md +40 -40
  330. package/docs/components/composed/command-palette.md +40 -40
  331. package/docs/components/composed/confirm-dialog.md +46 -46
  332. package/docs/components/composed/content-card.md +36 -36
  333. package/docs/components/composed/date-picker.md +130 -130
  334. package/docs/components/composed/deadline-indicator.md +27 -27
  335. package/docs/components/composed/emoji-picker.md +52 -52
  336. package/docs/components/composed/empty-state.md +53 -53
  337. package/docs/components/composed/error-boundary.md +29 -29
  338. package/docs/components/composed/file-preview.md +40 -40
  339. package/docs/components/composed/filter-bar.md +57 -57
  340. package/docs/components/composed/form-section.md +31 -31
  341. package/docs/components/composed/global-loading.md +27 -27
  342. package/docs/components/composed/inline-edit.md +35 -35
  343. package/docs/components/composed/loading-skeleton.md +51 -51
  344. package/docs/components/composed/markdown-viewer.md +27 -27
  345. package/docs/components/composed/master-detail.md +48 -48
  346. package/docs/components/composed/member-picker.md +35 -35
  347. package/docs/components/composed/multi-select-popover.md +62 -62
  348. package/docs/components/composed/page-header.md +41 -41
  349. package/docs/components/composed/page-skeletons.md +32 -32
  350. package/docs/components/composed/priority-indicator.md +32 -32
  351. package/docs/components/composed/responsive-overlay.md +34 -34
  352. package/docs/components/composed/rich-text-editor.md +82 -82
  353. package/docs/components/composed/schedule-view.md +39 -39
  354. package/docs/components/composed/simple-tooltip.md +33 -33
  355. package/docs/components/composed/status-badge.md +55 -55
  356. package/docs/components/shell/app-command-palette.md +44 -44
  357. package/docs/components/shell/bottom-navbar.md +52 -52
  358. package/docs/components/shell/command-registry.md +48 -48
  359. package/docs/components/shell/link-context.md +41 -41
  360. package/docs/components/shell/notification-center.md +63 -63
  361. package/docs/components/shell/notification-preferences.md +42 -42
  362. package/docs/components/shell/sidebar.md +92 -92
  363. package/docs/components/shell/top-bar.md +143 -143
  364. package/docs/components/ui/accordion.md +51 -51
  365. package/docs/components/ui/alert-dialog.md +61 -61
  366. package/docs/components/ui/alert.md +46 -46
  367. package/docs/components/ui/aspect-ratio.md +25 -25
  368. package/docs/components/ui/autocomplete.md +48 -48
  369. package/docs/components/ui/avatar.md +56 -56
  370. package/docs/components/ui/badge.md +83 -82
  371. package/docs/components/ui/banner.md +42 -42
  372. package/docs/components/ui/breadcrumb.md +37 -37
  373. package/docs/components/ui/button-group.md +41 -41
  374. package/docs/components/ui/button.md +94 -93
  375. package/docs/components/ui/card.md +52 -52
  376. package/docs/components/ui/charts.md +43 -43
  377. package/docs/components/ui/checkbox.md +36 -36
  378. package/docs/components/ui/chip.md +47 -47
  379. package/docs/components/ui/code.md +28 -28
  380. package/docs/components/ui/collapsible.md +40 -40
  381. package/docs/components/ui/color-input.md +91 -91
  382. package/docs/components/ui/color-swatch.md +25 -25
  383. package/docs/components/ui/combobox.md +54 -54
  384. package/docs/components/ui/container.md +26 -26
  385. package/docs/components/ui/context-menu.md +43 -43
  386. package/docs/components/ui/data-table-body.md +1 -1
  387. package/docs/components/ui/data-table-bulk-actions.md +1 -1
  388. package/docs/components/ui/data-table-card.md +1 -1
  389. package/docs/components/ui/data-table-context.md +1 -1
  390. package/docs/components/ui/data-table-header.md +1 -1
  391. package/docs/components/ui/data-table-pagination.md +1 -1
  392. package/docs/components/ui/data-table-toolbar.md +44 -44
  393. package/docs/components/ui/data-table.md +94 -94
  394. package/docs/components/ui/dialog.md +54 -54
  395. package/docs/components/ui/dropdown-menu.md +48 -48
  396. package/docs/components/ui/file-upload.md +41 -41
  397. package/docs/components/ui/form.md +51 -51
  398. package/docs/components/ui/hover-card.md +32 -32
  399. package/docs/components/ui/icon-button.md +40 -40
  400. package/docs/components/ui/input-otp.md +44 -44
  401. package/docs/components/ui/input.md +74 -74
  402. package/docs/components/ui/label.md +25 -25
  403. package/docs/components/ui/link.md +29 -29
  404. package/docs/components/ui/menubar.md +44 -44
  405. package/docs/components/ui/navigation-menu.md +46 -46
  406. package/docs/components/ui/number-input.md +44 -44
  407. package/docs/components/ui/pagination.md +48 -48
  408. package/docs/components/ui/popover.md +30 -30
  409. package/docs/components/ui/progress-ring.md +41 -41
  410. package/docs/components/ui/progress.md +34 -34
  411. package/docs/components/ui/radio.md +34 -34
  412. package/docs/components/ui/search-input.md +43 -43
  413. package/docs/components/ui/segmented-control.md +50 -50
  414. package/docs/components/ui/select.md +53 -53
  415. package/docs/components/ui/separator.md +32 -32
  416. package/docs/components/ui/sheet.md +47 -47
  417. package/docs/components/ui/sidebar.md +72 -72
  418. package/docs/components/ui/skeleton.md +77 -77
  419. package/docs/components/ui/slider.md +29 -29
  420. package/docs/components/ui/spinner.md +54 -54
  421. package/docs/components/ui/stack.md +39 -39
  422. package/docs/components/ui/stat-card.md +61 -61
  423. package/docs/components/ui/status-dot.md +26 -26
  424. package/docs/components/ui/stepper.md +49 -49
  425. package/docs/components/ui/switch.md +47 -47
  426. package/docs/components/ui/table.md +47 -47
  427. package/docs/components/ui/tabs.md +60 -60
  428. package/docs/components/ui/text.md +37 -37
  429. package/docs/components/ui/textarea.md +39 -39
  430. package/docs/components/ui/toast.md +65 -65
  431. package/docs/components/ui/toaster.md +47 -47
  432. package/docs/components/ui/toggle-group.md +43 -43
  433. package/docs/components/ui/toggle.md +37 -37
  434. package/docs/components/ui/tooltip.md +38 -38
  435. package/docs/components/ui/tree-view.md +65 -65
  436. package/docs/components/ui/visually-hidden.md +21 -21
  437. package/llms-full.txt +5266 -5264
  438. package/llms.txt +624 -580
  439. package/package.json +7 -8
@@ -10,10 +10,10 @@ import { jsx as c, jsxs as l } from "react/jsx-runtime";
10
10
  import { createPortal as u } from "react-dom";
11
11
  import { IconX as d } from "@tabler/icons-react";
12
12
  //#region src/composed/bulk-action-bar.tsx
13
- var f = s.forwardRef(function({ action: t, tabIndex: n }, r) {
14
- let [a, u] = s.useState(!1);
15
- return a ? /* @__PURE__ */ l(e.div, {
16
- ref: r,
13
+ var f = s.forwardRef(function({ action: t, tabIndex: r }, a) {
14
+ let [u, d] = s.useState(!1);
15
+ return u ? /* @__PURE__ */ l(e.div, {
16
+ ref: a,
17
17
  initial: {
18
18
  opacity: 0,
19
19
  scale: .95
@@ -26,13 +26,9 @@ var f = s.forwardRef(function({ action: t, tabIndex: n }, r) {
26
26
  opacity: 0,
27
27
  scale: .95
28
28
  },
29
- transition: {
30
- type: "spring",
31
- stiffness: 500,
32
- damping: 30
33
- },
29
+ transition: n.snappy,
34
30
  className: "flex items-center gap-ds-02",
35
- tabIndex: n,
31
+ tabIndex: r,
36
32
  children: [
37
33
  /* @__PURE__ */ c("span", {
38
34
  className: "text-ds-sm text-surface-fg-muted whitespace-nowrap",
@@ -43,19 +39,19 @@ var f = s.forwardRef(function({ action: t, tabIndex: n }, r) {
43
39
  size: "sm",
44
40
  color: "error",
45
41
  onClick: () => {
46
- u(!1), t.onClick();
42
+ d(!1), t.onClick();
47
43
  },
48
44
  children: "Confirm"
49
45
  }),
50
46
  /* @__PURE__ */ c(o, {
51
47
  variant: "ghost",
52
48
  size: "sm",
53
- onClick: () => u(!1),
49
+ onClick: () => d(!1),
54
50
  children: "Cancel"
55
51
  })
56
52
  ]
57
53
  }) : /* @__PURE__ */ c(e.div, {
58
- ref: r,
54
+ ref: a,
59
55
  initial: {
60
56
  opacity: 0,
61
57
  scale: .95
@@ -68,18 +64,14 @@ var f = s.forwardRef(function({ action: t, tabIndex: n }, r) {
68
64
  opacity: 0,
69
65
  scale: .95
70
66
  },
71
- transition: {
72
- type: "spring",
73
- stiffness: 500,
74
- damping: 30
75
- },
76
- tabIndex: n,
67
+ transition: n.snappy,
68
+ tabIndex: r,
77
69
  children: /* @__PURE__ */ c(o, {
78
70
  variant: "ghost",
79
71
  size: "sm",
80
72
  color: t.color === "error" ? "error" : "accent",
81
73
  disabled: t.disabled,
82
- onClick: t.requiresConfirmation ? () => u(!0) : t.onClick,
74
+ onClick: t.requiresConfirmation ? () => d(!0) : t.onClick,
83
75
  startIcon: t.icon ? /* @__PURE__ */ c(i, { icon: t.icon }) : void 0,
84
76
  tabIndex: -1,
85
77
  children: t.label
@@ -130,7 +122,7 @@ function p({ show: p, count: m, onClearSelection: h, actions: g, totalCount: _,
130
122
  opacity: 0
131
123
  },
132
124
  transition: n.snappy,
133
- className: r("fixed bottom-ds-06 left-1/2 z-50 -translate-x-1/2", "flex items-center gap-ds-04 rounded-ds-lg border border-surface-border bg-surface-overlay px-ds-05 py-ds-03 shadow-floating", y),
125
+ className: r("fixed bottom-ds-06 left-1/2 z-sticky -translate-x-1/2", "flex items-center gap-ds-04 rounded-ds-lg border border-surface-border bg-surface-overlay px-ds-05 py-ds-03 shadow-floating", y),
134
126
  role: "toolbar",
135
127
  "aria-label": `${m} items selected`,
136
128
  onKeyDown: T,
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bulk-action-bar.js","names":[],"sources":["../../src/composed/bulk-action-bar.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { createPortal } from 'react-dom'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport { IconX } from '@tabler/icons-react'\nimport { Icon, type IconProps } from '../ui/icon'\nimport { cn } from '../ui/lib/utils'\nimport { Button } from '../ui/button'\nimport { Badge } from '../ui/badge'\nimport { springs } from '../ui/lib/motion'\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface BulkActionBarAction {\n label: string\n icon?: IconProps['icon']\n onClick: () => void\n color?: 'accent' | 'error'\n disabled?: boolean\n /** Show inline confirmation before executing the action */\n requiresConfirmation?: boolean\n /** Custom confirmation message @default 'Are you sure?' */\n confirmMessage?: string\n}\n\nexport interface BulkActionBarProps {\n show: boolean\n count: number\n onClearSelection: () => void\n actions: BulkActionBarAction[]\n /** Total number of items available for selection */\n totalCount?: number\n /** Called when user clicks \"Select all\" */\n onSelectAll?: () => void\n className?: string\n}\n\n// ============================================================\n// ActionButton — handles inline confirmation\n// ============================================================\n\nconst ActionButton = React.forwardRef<HTMLDivElement, { action: BulkActionBarAction; tabIndex?: number }>(function ActionButton({ action, tabIndex }, ref) {\n const [confirming, setConfirming] = React.useState(false)\n\n if (confirming) {\n return (\n <motion.div\n ref={ref}\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.95 }}\n transition={springs.snappy}\n className=\"flex items-center gap-ds-02\"\n tabIndex={tabIndex}\n >\n <span className=\"text-ds-sm text-surface-fg-muted whitespace-nowrap\">\n {action.confirmMessage ?? 'Are you sure?'}\n </span>\n <Button\n variant=\"solid\"\n size=\"sm\"\n color=\"error\"\n onClick={() => {\n setConfirming(false)\n action.onClick()\n }}\n >\n Confirm\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setConfirming(false)}\n >\n Cancel\n </Button>\n </motion.div>\n )\n }\n\n return (\n <motion.div\n ref={ref}\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.95 }}\n transition={springs.snappy}\n tabIndex={tabIndex}\n >\n <Button\n variant=\"ghost\"\n size=\"sm\"\n color={action.color === 'error' ? 'error' : 'accent'}\n disabled={action.disabled}\n onClick={action.requiresConfirmation ? () => setConfirming(true) : action.onClick}\n startIcon={action.icon ? <Icon icon={action.icon} /> : undefined}\n tabIndex={-1}\n >\n {action.label}\n </Button>\n </motion.div>\n )\n})\n\n// ============================================================\n// BulkActionBar\n// ============================================================\n\nfunction BulkActionBar({\n show,\n count,\n onClearSelection,\n actions,\n totalCount,\n onSelectAll,\n className,\n}: BulkActionBarProps) {\n const [mounted, setMounted] = React.useState(false)\n const [focusedIndex, setFocusedIndex] = React.useState(0)\n const actionRefs = React.useRef<(HTMLDivElement | null)[]>([])\n\n // Reset focused index when actions change\n React.useEffect(() => {\n setFocusedIndex(0)\n }, [actions.length])\n\n React.useEffect(() => {\n setMounted(true)\n }, [])\n\n function handleKeyDown(e: React.KeyboardEvent) {\n if (e.key === 'Escape') {\n e.preventDefault()\n onClearSelection()\n return\n }\n\n const count = actions.length\n if (count === 0) return\n\n if (e.key === 'ArrowRight') {\n e.preventDefault()\n const next = (focusedIndex + 1) % count\n setFocusedIndex(next)\n actionRefs.current[next]?.focus()\n } else if (e.key === 'ArrowLeft') {\n e.preventDefault()\n const prev = (focusedIndex - 1 + count) % count\n setFocusedIndex(prev)\n actionRefs.current[prev]?.focus()\n } else if (e.key === 'Home') {\n e.preventDefault()\n setFocusedIndex(0)\n actionRefs.current[0]?.focus()\n } else if (e.key === 'End') {\n e.preventDefault()\n const last = count - 1\n setFocusedIndex(last)\n actionRefs.current[last]?.focus()\n }\n }\n\n if (!mounted) return null\n\n return createPortal(\n <AnimatePresence>\n {show && (\n <motion.div\n initial={{ y: 100, opacity: 0 }}\n animate={{ y: 0, opacity: 1 }}\n exit={{ y: 100, opacity: 0 }}\n transition={springs.snappy}\n className={cn(\n 'fixed bottom-ds-06 left-1/2 z-sticky -translate-x-1/2',\n 'flex items-center gap-ds-04 rounded-ds-lg border border-surface-border bg-surface-overlay px-ds-05 py-ds-03 shadow-floating',\n className,\n )}\n role=\"toolbar\"\n aria-label={`${count} items selected`}\n onKeyDown={handleKeyDown}\n >\n <Badge variant=\"solid\" size=\"sm\">\n {count} selected\n </Badge>\n\n {totalCount != null && totalCount > count && onSelectAll && (\n <Button variant=\"link\" size=\"xs\" onClick={onSelectAll}>\n Select all {totalCount}\n </Button>\n )}\n\n <div className=\"flex items-center gap-ds-02\">\n <AnimatePresence mode=\"popLayout\">\n {actions.map((action, i) => (\n <ActionButton\n key={action.label}\n ref={(el: HTMLDivElement | null) => { actionRefs.current[i] = el }}\n action={action}\n tabIndex={i === focusedIndex ? 0 : -1}\n />\n ))}\n </AnimatePresence>\n </div>\n\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n onClick={onClearSelection}\n aria-label=\"Clear selection\"\n >\n <Icon icon={IconX} size=\"sm\" />\n </Button>\n </motion.div>\n )}\n </AnimatePresence>,\n document.body,\n )\n}\n\nBulkActionBar.displayName = 'BulkActionBar'\n\nexport { BulkActionBar }\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-palette.js","names":[],"sources":["../../src/composed/command-palette.tsx"],"sourcesContent":["'use client'\n\n/**\n * CommandPalette -- Keyboard-driven command palette (Ctrl+K / Cmd+K).\n *\n * Adapted from Karm V2. Uses ui/Dialog as the overlay.\n * All V1 color tokens replaced with semantic design-system tokens.\n */\nimport * as React from 'react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogContentRaw,\n DialogTitle,\n DialogDescription,\n} from '../ui/dialog'\nimport { IconSearch, IconCornerDownLeft, IconArrowUp, IconArrowDown } from '@tabler/icons-react'\nimport { Icon } from '../ui/icon'\nimport { cn } from '../ui/lib/utils'\nimport { tweens, springs } from '../ui/lib/motion'\nimport { VisuallyHidden } from '../ui/visually-hidden'\nimport { useMotion } from '../motion/motion-provider'\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\nexport interface CommandItem {\n id: string\n /** Display label — string or ReactNode. When ReactNode, provide `filterValue` for search filtering. */\n label: string | React.ReactNode\n /** Optional description — string or ReactNode. */\n description?: string | React.ReactNode\n icon?: React.ReactNode\n /** Keyboard shortcut hint displayed as keycap badges (e.g., \"G D\", \"Ctrl+N\"). */\n shortcut?: string\n /** Custom render override for the label. Receives the current search query for match highlighting. */\n renderLabel?: (query: string) => React.ReactNode\n /** Plain-text value used for search filtering when `label` is a ReactNode. Falls back to `label` if string. */\n filterValue?: string\n onSelect: () => void\n}\n\nexport interface CommandGroup {\n label: string\n items: CommandItem[]\n}\n\n/** A single keyboard hint shown in the footer. */\nexport interface FooterHint {\n /** Key(s) to display — rendered as text inside `<kbd>` or as an icon. */\n keys: string\n /** Human-readable label for the hint (e.g., \"Navigate\", \"Select\"). */\n label: string\n}\n\n/**\n * A searchable command palette with keyboard navigation (Ctrl+K / Cmd+K).\n * Supports grouped items, custom keybindings, controlled/uncontrolled open state,\n * and custom empty states.\n */\nexport interface CommandPaletteProps extends React.ComponentPropsWithoutRef<'div'> {\n /** Item groups displayed in the palette. Each group has a label and an array of CommandItems. */\n groups?: CommandGroup[]\n /** Placeholder text for the search input. */\n placeholder?: string\n /** Called on every search input change with the current query string. */\n onSearch?: (query: string) => void\n /** Simple text shown when no results match. Overridden by `emptyState` if provided. */\n emptyMessage?: string\n /** Full custom empty state ReactNode — overrides `emptyMessage` when provided. */\n emptyState?: React.ReactNode\n // -- Controlled/uncontrolled open state (P1 #4) --\n /** Controlled open state. */\n open?: boolean\n /** Default open state for uncontrolled usage. */\n defaultOpen?: boolean\n /** Called when the open state changes. */\n onOpenChange?: (open: boolean) => void\n // -- Keyboard shortcut customization (P1 #6) --\n /** Keybinding(s) to toggle the palette. Pass `false` to disable.\n * String format: modifier+key, e.g., 'mod+k', 'ctrl+shift+p'.\n * 'mod' maps to Meta on macOS, Ctrl otherwise. */\n keybinding?: string | string[] | false\n // -- Configurable max-height (P2 #8) --\n /** Max height of the results container. CSS value. Default '320px'. */\n maxHeight?: string | number\n // -- Custom footer hints (P2 #11) --\n /** Custom footer keyboard hints. Pass `false` to hide the footer entirely. */\n footerHints?: FooterHint[] | false\n}\n\n// -----------------------------------------------------------------------\n// Helpers\n// -----------------------------------------------------------------------\n\nimport { getIsMac, matchesKeybinding, getModifierDisplay } from '../ui/lib/keybinding'\n\n/** Get the text-searchable value from a CommandItem. */\nfunction getFilterValue(item: CommandItem): string {\n if (item.filterValue) return item.filterValue\n if (typeof item.label === 'string') return item.label\n return ''\n}\n\n/** Get the text-searchable description from a CommandItem. */\nfunction getFilterDescription(item: CommandItem): string {\n if (typeof item.description === 'string') return item.description\n return ''\n}\n\n/** Parse a shortcut string like \"G D\" or \"Ctrl+N\" into individual keycap segments. */\nfunction parseShortcutKeys(shortcut: string): string[] {\n // If it has \"+\" separator (Ctrl+Shift+N style), split on +\n if (shortcut.includes('+')) {\n return shortcut.split('+').map(s => s.trim()).filter(Boolean)\n }\n // Otherwise split on spaces (G D style)\n return shortcut.split(/\\s+/).filter(Boolean)\n}\n\n// -----------------------------------------------------------------------\n// CommandPalette\n// -----------------------------------------------------------------------\n\nconst CommandPalette = React.forwardRef<HTMLDivElement, CommandPaletteProps>(\n function CommandPalette(\n {\n groups = [],\n placeholder = 'Search or jump to...',\n onSearch,\n emptyMessage = 'No results found.',\n emptyState,\n open: openProp,\n defaultOpen,\n onOpenChange,\n keybinding = 'mod+k',\n maxHeight = '320px',\n footerHints,\n className,\n ...props\n },\n ref,\n ) {\n // -- Controlled/uncontrolled open state --\n const isControlled = openProp !== undefined\n const [internalOpen, setInternalOpen] = React.useState(defaultOpen ?? false)\n const open = isControlled ? openProp : internalOpen\n\n // Use a ref for the current open value to avoid stale closures in setOpen\n const openRef = React.useRef(open)\n openRef.current = open\n\n const setOpen = React.useCallback(\n (nextOpen: boolean | ((prev: boolean) => boolean)) => {\n const resolved = typeof nextOpen === 'function' ? nextOpen(openRef.current) : nextOpen\n if (!isControlled) {\n setInternalOpen(resolved)\n }\n onOpenChange?.(resolved)\n },\n [isControlled, onOpenChange],\n )\n\n const [query, setQuery] = React.useState('')\n const [activeIndex, setActiveIndex] = React.useState(0)\n const inputRef = React.useRef<HTMLInputElement>(null)\n const listRef = React.useRef<HTMLDivElement>(null)\n const instanceId = React.useId()\n const listboxId = `command-palette-listbox-${instanceId}`\n\n // -- Reduced motion (P2 #12) --\n const { reducedMotion: isReduced } = useMotion()\n const noMotionTransition = { duration: 0 }\n\n // -- Platform detection (P2 #13) --\n const isMac = React.useMemo(() => getIsMac(), [])\n\n // Filter groups based on query\n const filteredGroups = React.useMemo(() => {\n if (!query.trim()) return groups\n const q = query.toLowerCase()\n return groups\n .map((group) => ({\n ...group,\n items: group.items.filter(\n (item) =>\n getFilterValue(item).toLowerCase().includes(q) ||\n getFilterDescription(item).toLowerCase().includes(q),\n ),\n }))\n .filter((group) => group.items.length > 0)\n }, [groups, query])\n\n const filteredItems = React.useMemo(\n () => filteredGroups.flatMap((g) => g.items),\n [filteredGroups],\n )\n\n // Global keyboard shortcut\n React.useEffect(() => {\n if (keybinding === false) return\n\n const bindings = Array.isArray(keybinding) ? keybinding : [keybinding]\n\n function handleKeyDown(e: KeyboardEvent) {\n for (const binding of bindings) {\n if (matchesKeybinding(e, binding)) {\n e.preventDefault()\n setOpen((prev) => !prev)\n return\n }\n }\n }\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [keybinding, setOpen])\n\n // Reset state when opening\n React.useEffect(() => {\n if (open) {\n setQuery('')\n setActiveIndex(0)\n requestAnimationFrame(() => {\n inputRef.current?.focus()\n })\n }\n }, [open])\n\n // Keyboard navigation inside the palette\n const handleKeyDown = (e: React.KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault()\n setActiveIndex((prev) =>\n prev < filteredItems.length - 1 ? prev + 1 : 0,\n )\n break\n }\n case 'ArrowUp': {\n e.preventDefault()\n setActiveIndex((prev) =>\n prev > 0 ? prev - 1 : filteredItems.length - 1,\n )\n break\n }\n case 'Enter': {\n e.preventDefault()\n const item = filteredItems[activeIndex]\n if (item) {\n item.onSelect()\n setOpen(false)\n }\n break\n }\n case 'Escape': {\n e.preventDefault()\n setOpen(false)\n break\n }\n }\n }\n\n // Scroll active item into view\n React.useEffect(() => {\n const activeEl = listRef.current?.querySelector(\n `[data-command-index=\"${activeIndex}\"]`,\n )\n activeEl?.scrollIntoView({ block: 'nearest' })\n }, [activeIndex])\n\n const handleQueryChange = (value: string) => {\n setQuery(value)\n setActiveIndex(0)\n onSearch?.(value)\n }\n\n // Build a map of item id -> flat index for keyboard navigation\n const itemIndexMap = React.useMemo(() => {\n const map = new Map<string, number>()\n let idx = 0\n for (const group of filteredGroups) {\n for (const item of group.items) {\n map.set(item.id, idx++)\n }\n }\n return map\n }, [filteredGroups])\n\n // -- Resolve motion transitions --\n const springSnappy = isReduced ? noMotionTransition : springs.snappy\n const tweenFade = isReduced ? noMotionTransition : tweens.fade\n const noInit = isReduced ? { opacity: 1, scale: 1, y: 0 } : undefined\n\n // -- Resolve max height CSS value --\n const maxHeightValue = typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight\n\n // -- Resolve footer hints --\n const resolvedFooterHints: FooterHint[] | false =\n footerHints === false\n ? false\n : footerHints ?? [\n { keys: '↑↓', label: 'Navigate' },\n { keys: '↵', label: 'Select' },\n { keys: 'Esc', label: 'Close' },\n ]\n\n // Handle dialog open change (from Dialog's own close mechanisms)\n const handleDialogOpenChange = React.useCallback(\n (nextOpen: boolean) => {\n setOpen(nextOpen)\n },\n [setOpen],\n )\n\n return (\n <Dialog open={open} onOpenChange={handleDialogOpenChange}>\n <DialogPortal>\n <DialogOverlay\n className=\"fixed inset-0 z-overlay bg-overlay data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\"\n />\n <DialogContentRaw\n ref={ref}\n {...props}\n className={cn(\n 'fixed left-1/2 top-[20%] z-modal w-full max-w-[560px] -translate-x-1/2',\n 'overflow-hidden rounded-ds-xl border border-surface-border-strong bg-surface-overlay shadow-overlay',\n 'duration-moderate-02 data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n 'data-[state=closed]:slide-out-to-left-1/2 data-[state=open]:slide-in-from-left-1/2',\n 'data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2',\n className,\n )}\n onKeyDown={handleKeyDown}\n >\n <VisuallyHidden>\n <DialogTitle>Command Palette</DialogTitle>\n <DialogDescription>\n Search or jump to pages, projects, tasks, and actions\n </DialogDescription>\n </VisuallyHidden>\n\n {/* Search input */}\n <div className=\"flex items-center gap-ds-04 border-b border-surface-border-strong px-ds-05 py-ds-04\">\n <motion.span\n initial={noInit ?? { opacity: 0, scale: 0.96 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={springSnappy}\n className=\"inline-flex shrink-0\"\n >\n <Icon icon={IconSearch} size=\"sm\" stroke=\"light\" className=\"text-surface-fg-subtle\" />\n </motion.span>\n <input\n ref={inputRef}\n value={query}\n onChange={(e) => handleQueryChange(e.target.value)}\n placeholder={placeholder}\n role=\"combobox\"\n aria-expanded={true}\n aria-controls={listboxId}\n aria-activedescendant={filteredItems[activeIndex] ? `command-item-${instanceId}-${filteredItems[activeIndex].id}` : undefined}\n aria-autocomplete=\"list\"\n className={cn(\n 'flex-1 bg-transparent text-ds-base text-surface-fg outline-hidden',\n 'placeholder:text-surface-fg-subtle',\n )}\n autoComplete=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n />\n <kbd className=\"hidden shrink-0 select-none rounded-ds-md border border-surface-border-strong bg-surface-raised px-ds-02b py-ds-01 text-ds-sm font-medium text-surface-fg-subtle shadow-kbd sm:inline-flex\">\n Esc\n </kbd>\n </div>\n\n {/* Results */}\n <div\n ref={listRef}\n id={listboxId}\n role=\"listbox\"\n aria-label=\"Command results\"\n className=\"overflow-y-auto px-ds-03 py-ds-03\"\n style={{ maxHeight: maxHeightValue }}\n >\n {filteredGroups.length === 0 && (\n <motion.div\n initial={noInit ?? { opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={tweenFade}\n className=\"flex items-center justify-center py-ds-07\"\n >\n {emptyState ?? (\n <p className=\"text-ds-md text-surface-fg-subtle\">\n {emptyMessage}\n </p>\n )}\n </motion.div>\n )}\n\n {filteredGroups.map((group, groupIdx) => (\n <motion.div\n key={group.label}\n initial={noInit ?? { opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={isReduced ? noMotionTransition : { ...tweens.fade, delay: groupIdx * 0.06 }}\n className=\"mb-ds-02\"\n >\n <div className=\"px-ds-03 pb-ds-02 pt-ds-03\">\n <span className=\"text-ds-xs font-semibold uppercase tracking-wider text-surface-fg-subtle\">\n {group.label}\n </span>\n </div>\n\n {group.items.map((item) => {\n const itemIndex = itemIndexMap.get(item.id) ?? 0\n const isActive = itemIndex === activeIndex\n return (\n <motion.button\n key={item.id}\n id={`command-item-${instanceId}-${item.id}`}\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n data-command-index={itemIndex}\n initial={noInit ?? { opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n transition={isReduced ? noMotionTransition : { ...springs.snappy, delay: itemIndex * 0.03 }}\n onClick={() => {\n item.onSelect()\n setOpen(false)\n }}\n onMouseEnter={() => setActiveIndex(itemIndex)}\n className={cn(\n 'flex w-full items-center gap-ds-04 rounded-ds-lg px-ds-03 py-ds-03 text-left transition-[color,background-color] duration-fast-02 ease-productive-standard',\n isActive\n ? 'bg-surface-raised-hover text-surface-fg'\n : 'text-surface-fg-muted hover:bg-surface-raised',\n )}\n >\n {item.icon && (\n <span\n className={cn(\n '[&>svg]:h-ico-sm [&>svg]:w-ico-sm shrink-0 transition-colors duration-fast-02 ease-productive-standard',\n isActive ? 'text-accent-11' : 'text-surface-fg-subtle',\n )}\n aria-hidden=\"true\"\n >\n {item.icon}\n </span>\n )}\n <div className=\"flex flex-1 flex-col\">\n <span className=\"text-ds-md\">\n {item.renderLabel ? item.renderLabel(query) : item.label}\n </span>\n {item.description && (\n <span className=\"text-ds-sm text-surface-fg-subtle\">\n {item.description}\n </span>\n )}\n </div>\n {item.shortcut && (\n <span className=\"flex shrink-0 items-center gap-ds-01\">\n {parseShortcutKeys(item.shortcut).map((key, i) => (\n <kbd\n key={i}\n className={cn(\n 'inline-flex min-w-[20px] items-center justify-center rounded border px-ds-02b py-ds-01 text-ds-xs font-medium shadow-kbd transition-colors duration-fast-02 ease-productive-standard',\n isActive\n ? 'bg-accent-2 text-accent-11 border-accent-6'\n : 'bg-surface-raised text-surface-fg-subtle border-surface-border-strong',\n )}\n >\n {key === 'Ctrl' || key === 'ctrl' ? getModifierDisplay(isMac) : key}\n </kbd>\n ))}\n </span>\n )}\n <AnimatePresence>\n {isActive && (\n <motion.span\n initial={isReduced ? undefined : { opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={isReduced ? undefined : { opacity: 0 }}\n transition={tweenFade}\n className=\"inline-flex shrink-0\"\n >\n <Icon icon={IconCornerDownLeft} size=\"sm\" stroke=\"light\" className=\"text-surface-fg-subtle\" />\n </motion.span>\n )}\n </AnimatePresence>\n </motion.button>\n )\n })}\n </motion.div>\n ))}\n </div>\n\n {/* Footer with keyboard hints */}\n {resolvedFooterHints !== false && (\n <motion.div\n initial={noInit ?? { opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={tweenFade}\n className=\"flex items-center gap-ds-05 border-t border-surface-border-strong px-ds-05 py-ds-03\"\n >\n {resolvedFooterHints.map((hint, i) => (\n <div key={i} className=\"flex items-center gap-ds-02b\">\n {hint.keys === '↑↓' ? (\n <div className=\"flex items-center gap-ds-01\">\n <kbd className=\"inline-flex h-ico-md w-ico-md items-center justify-center rounded border border-surface-border-strong bg-surface-raised shadow-kbd\">\n <Icon icon={IconArrowUp} size=\"xs\" className=\"text-surface-fg-subtle\" />\n </kbd>\n <kbd className=\"inline-flex h-ico-md w-ico-md items-center justify-center rounded border border-surface-border-strong bg-surface-raised shadow-kbd\">\n <Icon icon={IconArrowDown} size=\"xs\" className=\"text-surface-fg-subtle\" />\n </kbd>\n </div>\n ) : hint.keys === '↵' ? (\n <kbd className=\"inline-flex h-[20px] items-center justify-center rounded-ds-md border border-surface-border-strong bg-surface-raised px-ds-02b shadow-kbd\">\n <Icon icon={IconCornerDownLeft} size=\"xs\" className=\"text-surface-fg-subtle\" />\n </kbd>\n ) : (\n <kbd className=\"inline-flex h-[20px] items-center justify-center rounded-ds-md border border-surface-border-strong bg-surface-raised px-ds-02b text-ds-xs font-medium text-surface-fg-subtle shadow-kbd\">\n {hint.keys}\n </kbd>\n )}\n <span className=\"text-ds-xs text-surface-fg-subtle\">\n {hint.label}\n </span>\n </div>\n ))}\n </motion.div>\n )}\n </DialogContentRaw>\n </DialogPortal>\n </Dialog>\n )\n },\n)\n\nCommandPalette.displayName = 'CommandPalette'\n\nexport { CommandPalette }\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm-dialog.js","names":[],"sources":["../../src/composed/confirm-dialog.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport {\n AlertDialog,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from '../ui/alert-dialog'\nimport { Button } from '../ui/button'\nimport { cn } from '../ui/lib/utils'\n\nexport interface ConfirmDialogProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'color'> {\n /** Whether the dialog is open */\n open: boolean\n /** Called when the dialog open state changes */\n onOpenChange: (open: boolean) => void\n /** Dialog title */\n title: string\n /** Dialog description */\n description: string\n /** Confirm button text */\n confirmText?: string\n /** Cancel button text */\n cancelText?: string\n /** Color of the confirm button */\n color?: 'accent' | 'error'\n /** Whether the dialog is in a loading state */\n loading?: boolean\n /** Called when the user confirms. Dialog stays open — consumer controls closing via onOpenChange. */\n onConfirm: () => void | Promise<void>\n}\n\nconst ConfirmDialog = React.forwardRef<HTMLDivElement, ConfirmDialogProps>(\n (\n {\n open,\n onOpenChange,\n title,\n description,\n confirmText = 'Confirm',\n cancelText = 'Cancel',\n color = 'accent',\n loading = false,\n onConfirm,\n className,\n ...props\n },\n ref,\n ) => {\n return (\n <AlertDialog open={open} onOpenChange={onOpenChange}>\n <AlertDialogContent ref={ref} className={className} {...props}>\n <AlertDialogHeader>\n <AlertDialogTitle>{title}</AlertDialogTitle>\n <AlertDialogDescription>{description}</AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <Button\n variant=\"outline\"\n disabled={loading}\n onClick={() => onOpenChange(false)}\n >\n {cancelText}\n </Button>\n <Button\n variant=\"solid\"\n color={color}\n disabled={loading}\n onClick={() => onConfirm()}\n >\n {loading ? 'Processing...' : confirmText}\n </Button>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )\n },\n)\nConfirmDialog.displayName = 'ConfirmDialog'\n\nexport { ConfirmDialog }\n"],"mappings":";;;;;;AAmCA,IAAM,IAAgB,EAAM,YAExB,EACE,SACA,iBACA,UACA,gBACA,iBAAc,WACd,gBAAa,UACb,WAAQ,UACR,aAAU,IACV,cACA,cACA,GAAG,KAEL,MAGE,kBAAC,GAAD;CAAmB;CAAoB;WACrC,kBAAC,GAAD;EAAyB;EAAgB;EAAW,GAAI;YAAxD,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAmB,GAAyB,CAAA,EAC5C,kBAAC,GAAD,EAAA,UAAyB,GAAqC,CAAA,CAC5C,EAAA,CAAA,EACpB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;GACE,SAAQ;GACR,UAAU;GACV,eAAe,EAAa,GAAM;aAEjC;GACM,CAAA,EACT,kBAAC,GAAD;GACE,SAAQ;GACD;GACP,UAAU;GACV,eAAe,GAAW;aAEzB,IAAU,kBAAkB;GACtB,CAAA,CACS,EAAA,CAAA,CACD;;CACT,CAAA,CAGnB;AACD,EAAc,cAAc"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-card.js","names":[],"sources":["../../src/composed/content-card.tsx"],"sourcesContent":["// @server-safe\nimport * as React from 'react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '../ui/lib/utils'\n\nconst contentCardVariants = cva(\n 'rounded-ds-lg will-change-[box-shadow] transition-[color,background-color,border-color,box-shadow] duration-fast-02 ease-productive-standard',\n {\n variants: {\n variant: {\n default:\n 'border border-surface-border-strong bg-surface-raised shadow-raised hover:shadow-raised-hover',\n outline:\n 'border border-surface-border bg-transparent hover:border-surface-border-strong',\n ghost:\n 'border border-transparent bg-transparent hover:bg-surface-raised',\n },\n padding: {\n default: 'p-ds-05b',\n compact: 'p-ds-04',\n spacious: 'p-ds-06',\n none: 'p-0',\n },\n },\n defaultVariants: {\n variant: 'default',\n padding: 'default',\n },\n },\n)\n\nconst getPadding = (padding: string | null | undefined) => {\n switch (padding) {\n case 'compact': return 'px-ds-04 py-ds-03'\n case 'spacious': return 'px-ds-06 py-ds-05'\n default: return 'px-ds-05b py-ds-04'\n }\n}\n\nconst getContentPadding = (padding: string | null | undefined) => {\n switch (padding) {\n case 'compact': return 'p-ds-04'\n case 'spacious': return 'p-ds-06'\n default: return 'p-ds-05b'\n }\n}\n\nexport interface ContentCardProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof contentCardVariants> {\n header?: React.ReactNode\n headerTitle?: string\n headerActions?: React.ReactNode\n footer?: React.ReactNode\n}\n\nconst ContentCard = React.forwardRef<HTMLDivElement, ContentCardProps>(\n (\n {\n variant,\n padding,\n header,\n headerTitle,\n headerActions,\n footer,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const hasHeader = header || headerTitle || headerActions\n\n return (\n <div\n ref={ref}\n className={cn(\n contentCardVariants({ variant, padding: hasHeader || footer ? 'none' : padding }),\n className,\n )}\n {...props}\n >\n {hasHeader && (\n <div\n className={cn(\n 'flex items-center justify-between border-b border-surface-border-strong',\n getPadding(padding),\n )}\n >\n {header ?? (\n <>\n {headerTitle && (\n <h3 className=\"text-ds-base font-semibold text-surface-fg\">\n {headerTitle}\n </h3>\n )}\n {headerActions && (\n <div className=\"flex items-center gap-ds-03\">{headerActions}</div>\n )}\n </>\n )}\n </div>\n )}\n\n <div\n className={cn(\n (hasHeader || footer) && getContentPadding(padding),\n )}\n >\n {children}\n </div>\n\n {footer && (\n <div\n className={cn(\n 'border-t border-surface-border-strong',\n getPadding(padding),\n )}\n >\n {footer}\n </div>\n )}\n </div>\n )\n },\n)\nContentCard.displayName = 'ContentCard'\n\nexport { ContentCard, contentCardVariants }\n"],"mappings":";;;;;AAKA,IAAM,IAAsB,EAC1B,gJACA;CACE,UAAU;EACR,SAAS;GACP,SACE;GACF,SACE;GACF,OACE;GACH;EACD,SAAS;GACP,SAAS;GACT,SAAS;GACT,UAAU;GACV,MAAM;GACP;EACF;CACD,iBAAiB;EACf,SAAS;EACT,SAAS;EACV;CACF,CACF,EAEK,KAAc,MAAuC;AACzD,SAAQ,GAAR;EACE,KAAK,UAAW,QAAO;EACvB,KAAK,WAAY,QAAO;EACxB,QAAS,QAAO;;GAId,KAAqB,MAAuC;AAChE,SAAQ,GAAR;EACE,KAAK,UAAW,QAAO;EACvB,KAAK,WAAY,QAAO;EACxB,QAAS,QAAO;;GAad,IAAc,EAAM,YAEtB,EACE,YACA,YACA,WACA,gBACA,kBACA,WACA,cACA,aACA,GAAG,KAEL,MACG;CACH,IAAM,IAAY,KAAU,KAAe;AAE3C,QACE,kBAAC,OAAD;EACO;EACL,WAAW,EACT,EAAoB;GAAE;GAAS,SAAS,KAAa,IAAS,SAAS;GAAS,CAAC,EACjF,EACD;EACD,GAAI;YANN;GAQG,KACC,kBAAC,OAAD;IACE,WAAW,EACT,2EACA,EAAW,EAAQ,CACpB;cAEA,KACC,kBAAA,GAAA,EAAA,UAAA,CACG,KACC,kBAAC,MAAD;KAAI,WAAU;eACX;KACE,CAAA,EAEN,KACC,kBAAC,OAAD;KAAK,WAAU;eAA+B;KAAoB,CAAA,CAEnE,EAAA,CAAA;IAED,CAAA;GAGR,kBAAC,OAAD;IACE,WAAW,GACR,KAAa,MAAW,EAAkB,EAAQ,CACpD;IAEA;IACG,CAAA;GAEL,KACC,kBAAC,OAAD;IACE,WAAW,EACT,yCACA,EAAW,EAAQ,CACpB;cAEA;IACG,CAAA;GAEJ;;EAGX;AACD,EAAY,cAAc"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deadline-indicator.js","names":[],"sources":["../../src/composed/deadline-indicator.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { motion } from 'framer-motion'\nimport { cn } from '../ui/lib/utils'\nimport { motionProps } from '../ui/lib/motion'\nimport { IconClock } from '@tabler/icons-react'\nimport { Icon } from '../ui/icon'\nimport { SimpleTooltip } from './simple-tooltip'\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface DeadlineIndicatorProps extends React.HTMLAttributes<HTMLSpanElement> {\n deadline: Date | string\n /** Minutes before deadline to show warning color @default 1440 (24h) */\n warningThreshold?: number\n /** Minutes before deadline to show critical color @default 240 (4h) */\n criticalThreshold?: number\n /** @default 'relative' */\n format?: 'relative' | 'absolute'\n /** Show clock icon prefix */\n showIcon?: boolean\n /** Auto-refresh interval in ms to keep relative time up to date @default 60000 */\n refreshInterval?: number\n}\n\n// ============================================================\n// Helpers\n// ============================================================\n\nfunction formatRelative(minutesRemaining: number): string {\n const abs = Math.abs(minutesRemaining)\n const prefix = minutesRemaining < 0 ? 'Overdue by ' : ''\n const suffix = minutesRemaining >= 0 ? ' left' : ''\n\n if (abs < 1) return minutesRemaining < 0 ? 'Overdue' : 'Due now'\n if (abs < 60) return `${prefix}${Math.round(abs)}m${suffix}`\n if (abs < 1440) return `${prefix}${Math.round(abs / 60)}h${suffix}`\n return `${prefix}${Math.round(abs / 1440)}d${suffix}`\n}\n\nfunction formatAbsolute(date: Date): string {\n return date.toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n })\n}\n\n// ============================================================\n// DeadlineIndicator\n// ============================================================\n\nconst DeadlineIndicator = React.forwardRef<HTMLSpanElement, DeadlineIndicatorProps>(({\n deadline,\n warningThreshold = 1440,\n criticalThreshold = 240,\n format = 'relative',\n showIcon = false,\n refreshInterval = 60000,\n className,\n ...props\n}, ref) => {\n const [, forceUpdate] = React.useReducer((x: number) => x + 1, 0)\n React.useEffect(() => {\n if (!refreshInterval) return\n const id = setInterval(forceUpdate, refreshInterval)\n return () => clearInterval(id)\n }, [refreshInterval])\n\n const deadlineDate = React.useMemo(\n () => (deadline instanceof Date ? deadline : new Date(deadline)),\n [deadline],\n )\n const minutesRemaining = (deadlineDate.getTime() - Date.now()) / 60000\n\n let colorClass: string\n if (minutesRemaining <= 0) {\n colorClass = 'text-error-11 font-semibold'\n } else if (minutesRemaining <= criticalThreshold) {\n colorClass = 'text-error-11'\n } else if (minutesRemaining <= warningThreshold) {\n colorClass = 'text-warning-11'\n } else {\n colorClass = 'text-success-11'\n }\n\n const text = format === 'relative'\n ? formatRelative(minutesRemaining)\n : formatAbsolute(deadlineDate)\n\n const isOverdue = minutesRemaining <= 0\n const isCritical = minutesRemaining <= criticalThreshold && minutesRemaining > 0\n const shouldPulse = isOverdue || isCritical\n\n const showTooltip = format === 'relative'\n const tooltipContent = deadlineDate.toLocaleString()\n\n if (shouldPulse) {\n const inner = (\n <motion.span\n ref={ref}\n className={cn('inline-flex items-center gap-ds-01 font-sans text-ds-sm', colorClass, className)}\n animate={{ opacity: [1, 0.7, 1] }}\n transition={{ duration: 2, repeat: Infinity }}\n {...motionProps(props)}\n >\n {showIcon && <Icon icon={IconClock} size=\"xs\" />}\n {text}\n </motion.span>\n )\n\n return showTooltip ? <SimpleTooltip content={tooltipContent}>{inner}</SimpleTooltip> : inner\n }\n\n const inner = (\n <span\n ref={ref}\n className={cn('inline-flex items-center gap-ds-01 font-sans text-ds-sm', colorClass, className)}\n {...props}\n >\n {showIcon && <Icon icon={IconClock} size=\"xs\" />}\n {text}\n </span>\n )\n\n return showTooltip ? <SimpleTooltip content={tooltipContent}>{inner}</SimpleTooltip> : inner\n})\nDeadlineIndicator.displayName = 'DeadlineIndicator'\n\nexport { DeadlineIndicator }\n"],"mappings":";;;;;;;;;;AAgCA,SAAS,EAAe,GAAkC;CACxD,IAAM,IAAM,KAAK,IAAI,EAAiB,EAChC,IAAS,IAAmB,IAAI,gBAAgB,IAChD,IAAS,KAAoB,IAAI,UAAU;AAKjD,QAHI,IAAM,IAAU,IAAmB,IAAI,YAAY,YACnD,IAAM,KAAW,GAAG,IAAS,KAAK,MAAM,EAAI,CAAC,GAAG,MAChD,IAAM,OAAa,GAAG,IAAS,KAAK,MAAM,IAAM,GAAG,CAAC,GAAG,MACpD,GAAG,IAAS,KAAK,MAAM,IAAM,KAAK,CAAC,GAAG;;AAG/C,SAAS,EAAe,GAAoB;AAC1C,QAAO,EAAK,mBAAmB,KAAA,GAAW;EACxC,OAAO;EACP,KAAK;EACL,MAAM;EACN,QAAQ;EACT,CAAC;;AAOJ,IAAM,IAAoB,EAAM,YAAqD,EACnF,aACA,sBAAmB,MACnB,uBAAoB,KACpB,YAAS,YACT,cAAW,IACX,qBAAkB,KAClB,cACA,GAAG,KACF,MAAQ;CACT,IAAM,GAAG,KAAe,EAAM,YAAY,MAAc,IAAI,GAAG,EAAE;AACjE,GAAM,gBAAgB;AACpB,MAAI,CAAC,EAAiB;EACtB,IAAM,IAAK,YAAY,GAAa,EAAgB;AACpD,eAAa,cAAc,EAAG;IAC7B,CAAC,EAAgB,CAAC;CAErB,IAAM,IAAe,EAAM,cAClB,aAAoB,OAAO,IAAW,IAAI,KAAK,EAAS,EAC/D,CAAC,EAAS,CACX,EACK,KAAoB,EAAa,SAAS,GAAG,KAAK,KAAK,IAAI,KAE7D;AACJ,CAOE,IAPE,KAAoB,IACT,gCACJ,KAAoB,IAChB,kBACJ,KAAoB,IAChB,oBAEA;CAGf,IAAM,IAAO,MAAW,aACpB,EAAe,EAAiB,GAChC,EAAe,EAAa,EAI1B,IAFY,KAAoB,KACnB,KAAoB,KAAqB,IAAmB,GAGzE,IAAc,MAAW,YACzB,IAAiB,EAAa,gBAAgB;AAEpD,KAAI,GAAa;EACf,IAAM,IACJ,kBAAC,EAAO,MAAR;GACO;GACL,WAAW,EAAG,2DAA2D,GAAY,EAAU;GAC/F,SAAS,EAAE,SAAS;IAAC;IAAG;IAAK;IAAE,EAAE;GACjC,YAAY;IAAE,UAAU;IAAG,QAAQ;IAAU;GAC7C,GAAI,EAAY,EAAM;aALxB,CAOG,KAAY,kBAAC,GAAD;IAAM,MAAM;IAAW,MAAK;IAAO,CAAA,EAC/C,EACW;;AAGhB,SAAO,IAAc,kBAAC,GAAD;GAAe,SAAS;aAAiB;GAAsB,CAAA,GAAG;;CAGzF,IAAM,IACJ,kBAAC,QAAD;EACO;EACL,WAAW,EAAG,2DAA2D,GAAY,EAAU;EAC/F,GAAI;YAHN,CAKG,KAAY,kBAAC,GAAD;GAAM,MAAM;GAAW,MAAK;GAAO,CAAA,EAC/C,EACI;;AAGT,QAAO,IAAc,kBAAC,GAAD;EAAe,SAAS;YAAiB;EAAsB,CAAA,GAAG;EACvF;AACF,EAAkB,cAAc"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emoji-picker.js","names":[],"sources":["../../src/composed/emoji-picker.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { cn } from '../ui/lib/utils'\nimport { springs } from '../ui/lib/motion'\nimport { Skeleton } from '../ui/skeleton'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '../ui/popover'\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface EmojiData {\n id: string\n native: string\n shortcodes?: string\n}\n\nexport type EmojiSet = 'native' | 'apple' | 'google' | 'twitter' | 'facebook'\n\nexport interface EmojiPickerProps {\n onSelect: (emoji: EmojiData) => void\n /** Emoji art style. Set once — dynamic switching is not supported (emoji-mart limitation). @default 'native' */\n set?: EmojiSet\n /** @default 'auto' */\n theme?: 'auto' | 'light' | 'dark'\n /** @default 'none' */\n previewPosition?: 'top' | 'bottom' | 'none'\n /** @default 'search' */\n skinTonePosition?: 'search' | 'preview' | 'none'\n className?: string\n}\n\nexport interface EmojiPickerPopoverProps extends EmojiPickerProps {\n children: React.ReactNode\n /** @default 'start' */\n align?: 'start' | 'center' | 'end'\n}\n\n// ============================================================\n// Lazy-loaded picker\n// ============================================================\n\nconst LazyPicker = React.lazy(() =>\n import('@emoji-mart/react').then((mod) => ({\n default: mod.default,\n })),\n)\n\n// emoji-mart caches data in a module-level singleton that is set once and never\n// replaced. Each set (apple, google, etc.) needs its own data file with\n// spritesheet x/y coordinates. The `set` prop should be treated as immutable\n// configuration — dynamic switching within a single page is NOT supported.\nexport const emojiDataLoaders: Record<string, () => Promise<{ default: unknown }>> = {\n native: () => import('@emoji-mart/data'),\n apple: () => import('@emoji-mart/data/sets/15/apple.json'),\n google: () => import('@emoji-mart/data/sets/15/google.json'),\n twitter: () => import('@emoji-mart/data/sets/15/twitter.json'),\n facebook: () => import('@emoji-mart/data/sets/15/facebook.json'),\n}\n\nfunction resolveTheme(theme: 'auto' | 'light' | 'dark'): 'light' | 'dark' {\n if (theme !== 'auto') return theme\n if (typeof document === 'undefined') return 'light'\n return document.documentElement.classList.contains('dark') ? 'dark' : 'light'\n}\n\n// ============================================================\n// EmojiPicker\n// ============================================================\n\nfunction EmojiPicker({\n onSelect,\n set = 'native',\n theme = 'auto',\n previewPosition = 'none',\n skinTonePosition = 'search',\n className,\n}: EmojiPickerProps) {\n const [mounted, setMounted] = React.useState(false)\n const [data, setData] = React.useState<unknown>(null)\n\n React.useEffect(() => {\n setMounted(true)\n const loader = emojiDataLoaders[set] ?? emojiDataLoaders.native\n loader().then((mod) => setData(mod.default))\n }, [set])\n\n const isReady = mounted && !!data\n\n return (\n <AnimatePresence mode=\"wait\">\n {!isReady ? (\n <motion.div\n key=\"skeleton\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={springs.snappy}\n className={cn('rounded-ds-lg', className)}\n >\n <Skeleton className=\"h-[435px] w-[352px] rounded-ds-lg\" />\n </motion.div>\n ) : (\n <motion.div\n key=\"picker\"\n initial={{ opacity: 0, scale: 0.95 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={springs.snappy}\n className={className}\n >\n <React.Suspense\n fallback={\n <div className={cn('rounded-ds-lg', className)}>\n <Skeleton className=\"h-[435px] w-[352px] rounded-ds-lg\" />\n </div>\n }\n >\n <LazyPicker\n data={data}\n set={set}\n onEmojiSelect={onSelect}\n theme={resolveTheme(theme)}\n previewPosition={previewPosition}\n skinTonePosition={skinTonePosition}\n />\n </React.Suspense>\n </motion.div>\n )}\n </AnimatePresence>\n )\n}\n\n// ============================================================\n// EmojiPickerPopover\n// ============================================================\n\nfunction EmojiPickerPopover({\n children,\n align = 'start',\n onSelect,\n set,\n theme,\n previewPosition,\n skinTonePosition,\n className,\n}: EmojiPickerPopoverProps) {\n const [open, setOpen] = React.useState(false)\n\n const handleSelect = (emoji: EmojiData) => {\n onSelect(emoji)\n setOpen(false)\n }\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>{children}</PopoverTrigger>\n <PopoverContent\n align={align}\n className=\"w-auto border-none bg-transparent p-0 shadow-none\"\n sideOffset={8}\n >\n <EmojiPicker\n onSelect={handleSelect}\n set={set}\n theme={theme}\n previewPosition={previewPosition}\n skinTonePosition={skinTonePosition}\n className={className}\n />\n </PopoverContent>\n </Popover>\n )\n}\n\nEmojiPicker.displayName = 'EmojiPicker'\nEmojiPickerPopover.displayName = 'EmojiPickerPopover'\n\nexport { EmojiPicker, EmojiPickerPopover }\n"],"mappings":";;;;;;;;;AAgDA,IAAM,IAAa,EAAM,WACvB,OAAO,qBAAqB,MAAM,OAAS,EACzC,SAAS,EAAI,SACd,EAAE,CACJ,EAMY,IAAwE;CACnF,cAAc,OAAO;CACrB,aAAa,OAAO;CACpB,cAAc,OAAO;CACrB,eAAe,OAAO;CACtB,gBAAgB,OAAO;CACxB;AAED,SAAS,EAAa,GAAoD;AAGxE,QAFI,MAAU,SACV,OAAO,WAAa,MAAoB,UACrC,SAAS,gBAAgB,UAAU,SAAS,OAAO,GAAG,SAAS,UAFzC;;AAS/B,SAAS,EAAY,EACnB,aACA,SAAM,UACN,WAAQ,QACR,qBAAkB,QAClB,sBAAmB,UACnB,gBACmB;CACnB,IAAM,CAAC,GAAS,KAAc,EAAM,SAAS,GAAM,EAC7C,CAAC,GAAM,KAAW,EAAM,SAAkB,KAAK;AAUrD,QARA,EAAM,gBAAgB;AAGpB,EAFA,EAAW,GAAK,GACD,EAAiB,MAAQ,EAAiB,SACjD,CAAC,MAAM,MAAQ,EAAQ,EAAI,QAAQ,CAAC;IAC3C,CAAC,EAAI,CAAC,EAKP,kBAAC,GAAD;EAAiB,MAAK;YAHR,KAAa,IAgBvB,kBAAC,EAAO,KAAR;GAEE,SAAS;IAAE,SAAS;IAAG,OAAO;IAAM;GACpC,SAAS;IAAE,SAAS;IAAG,OAAO;IAAG;GACjC,YAAY,EAAQ;GACT;aAEX,kBAAC,EAAM,UAAP;IACE,UACE,kBAAC,OAAD;KAAK,WAAW,EAAG,iBAAiB,EAAU;eAC5C,kBAAC,GAAD,EAAU,WAAU,qCAAsC,CAAA;KACtD,CAAA;cAGR,kBAAC,GAAD;KACQ;KACD;KACL,eAAe;KACf,OAAO,EAAa,EAAM;KACT;KACC;KAClB,CAAA;IACa,CAAA;GACN,EAtBP,SAsBO,GAlCb,kBAAC,EAAO,KAAR;GAEE,SAAS,EAAE,SAAS,GAAG;GACvB,SAAS,EAAE,SAAS,GAAG;GACvB,MAAM,EAAE,SAAS,GAAG;GACpB,YAAY,EAAQ;GACpB,WAAW,EAAG,iBAAiB,EAAU;aAEzC,kBAAC,GAAD,EAAU,WAAU,qCAAsC,CAAA;GAC/C,EARP,WAQO;EA2BC,CAAA;;AAQtB,SAAS,EAAmB,EAC1B,aACA,WAAQ,SACR,aACA,QACA,UACA,oBACA,qBACA,gBAC0B;CAC1B,IAAM,CAAC,GAAM,KAAW,EAAM,SAAS,GAAM;AAO7C,QACE,kBAAC,GAAD;EAAe;EAAM,cAAc;YAAnC,CACE,kBAAC,GAAD;GAAgB,SAAA;GAAS;GAA0B,CAAA,EACnD,kBAAC,GAAD;GACS;GACP,WAAU;GACV,YAAY;aAEZ,kBAAC,GAAD;IACE,WAdc,MAAqB;AAEzC,KADA,EAAS,EAAM,EACf,EAAQ,GAAM;;IAaH;IACE;IACU;IACC;IACP;IACX,CAAA;GACa,CAAA,CACT;;;AAId,EAAY,cAAc,eAC1B,EAAmB,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"empty-state.d.ts","sourceRoot":"","sources":["../../src/composed/empty-state.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,MAAM,WAAW,eAAgB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC3E,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACpE,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACxB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;CAC9B;AAcD,QAAA,MAAM,UAAU,wFAuFf,CAAA;AAGD,OAAO,EAAE,UAAU,EAAE,CAAA"}
1
+ {"version":3,"file":"empty-state.d.ts","sourceRoot":"","sources":["../../src/composed/empty-state.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,MAAM,WAAW,eAAgB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC3E,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACpE,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACxB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;CAC9B;AAcD,QAAA,MAAM,UAAU,wFAwFf,CAAA;AAGD,OAAO,EAAE,UAAU,EAAE,CAAA"}
@@ -1,65 +1,65 @@
1
1
  "use client";
2
- import { a as e } from "../_chunks/framer.js";
3
- import { tweens as t } from "../ui/lib/motion.js";
4
- import { cn as n } from "../ui/lib/utils.js";
5
- import * as r from "react";
6
- import { jsx as i, jsxs as a } from "react/jsx-runtime";
2
+ import { a as e, n as t } from "../_chunks/framer.js";
3
+ import { tweens as n } from "../ui/lib/motion.js";
4
+ import { cn as r } from "../ui/lib/utils.js";
5
+ import * as i from "react";
6
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
7
7
  //#region src/composed/empty-state.tsx
8
- var o = ({ className: e }) => /* @__PURE__ */ i("svg", {
8
+ var s = ({ className: e }) => /* @__PURE__ */ a("svg", {
9
9
  xmlns: "http://www.w3.org/2000/svg",
10
10
  viewBox: "0 0 32 32",
11
11
  fill: "currentColor",
12
12
  className: e,
13
13
  "aria-hidden": "true",
14
- children: /* @__PURE__ */ i("path", { d: "M25.97,21.39c-0.9-1.85,0.08-3.95-1.72-5.39c1.76-1.44,0.8-3.55,1.69-5.39c0.05-0.12,0.04-0.25-0.02-0.35c-0.06-0.1-0.16-0.18-0.29-0.19c-2.05-0.15-3.35-2.04-5.5-1.21c-0.39-2.21-2.7-2.44-3.84-4.13c-0.08-0.1-0.19-0.16-0.31-0.16c-0.12,0-0.23,0.05-0.31,0.16c-1.14,1.69-3.43,1.92-3.82,4.13c-2.14-0.83-3.47,1.07-5.52,1.21c-0.13,0.01-0.23,0.09-0.29,0.19c-0.06,0.1-0.07,0.23-0.02,0.35c0.9,1.85-0.08,3.95,1.72,5.39c-1.76,1.44-0.8,3.55-1.69,5.39C6,21.51,6.02,21.64,6.07,21.74c0.06,0.1,0.16,0.18,0.29,0.19c2.05,0.15,3.38,2.06,5.52,1.23c0.39,2.21,2.67,2.43,3.82,4.12c0.08,0.1,0.19,0.16,0.31,0.16c0.12,0,0.23-0.05,0.31-0.16c1.14-1.69,3.42-1.92,3.81-4.13c2.14,0.83,3.48-1.07,5.53-1.22c0.13-0.01,0.23-0.09,0.29-0.19C26.01,21.64,26.02,21.51,25.97,21.39z" })
15
- }), s = r.forwardRef(({ icon: s, title: c, description: l, action: u, compact: d = !1, iconSize: f, className: p, ...m }, h) => {
16
- let g = {
14
+ children: /* @__PURE__ */ a("path", { d: "M25.97,21.39c-0.9-1.85,0.08-3.95-1.72-5.39c1.76-1.44,0.8-3.55,1.69-5.39c0.05-0.12,0.04-0.25-0.02-0.35c-0.06-0.1-0.16-0.18-0.29-0.19c-2.05-0.15-3.35-2.04-5.5-1.21c-0.39-2.21-2.7-2.44-3.84-4.13c-0.08-0.1-0.19-0.16-0.31-0.16c-0.12,0-0.23,0.05-0.31,0.16c-1.14,1.69-3.43,1.92-3.82,4.13c-2.14-0.83-3.47,1.07-5.52,1.21c-0.13,0.01-0.23,0.09-0.29,0.19c-0.06,0.1-0.07,0.23-0.02,0.35c0.9,1.85-0.08,3.95,1.72,5.39c-1.76,1.44-0.8,3.55-1.69,5.39C6,21.51,6.02,21.64,6.07,21.74c0.06,0.1,0.16,0.18,0.29,0.19c2.05,0.15,3.38,2.06,5.52,1.23c0.39,2.21,2.67,2.43,3.82,4.12c0.08,0.1,0.19,0.16,0.31,0.16c0.12,0,0.23-0.05,0.31-0.16c1.14-1.69,3.42-1.92,3.81-4.13c2.14,0.83,3.48-1.07,5.53-1.22c0.13-0.01,0.23-0.09,0.29-0.19C26.01,21.64,26.02,21.51,25.97,21.39z" })
15
+ }), c = i.forwardRef(({ icon: c, title: l, description: u, action: d, compact: f = !1, iconSize: p, className: m, ...h }, g) => {
16
+ let _ = t(), v = {
17
17
  sm: "h-ico-sm w-ico-sm",
18
18
  md: "h-ico-lg w-ico-lg",
19
19
  lg: "h-ico-xl w-ico-xl"
20
- }[f ?? (d ? "sm" : "md")], _ = s != null && !r.isValidElement(s) && (typeof s == "function" || typeof s == "object" && "$$typeof" in s), v = s ? _ ? r.createElement(s, { className: n("text-surface-fg-subtle", g) }) : s : /* @__PURE__ */ i(o, { className: n("text-surface-fg-subtle", g) });
21
- return /* @__PURE__ */ a("div", {
22
- ref: h,
23
- className: n("flex flex-col items-center justify-center text-center", d ? "gap-ds-04 py-ds-07" : "gap-ds-05 py-ds-10", p),
24
- ...m,
20
+ }[p ?? (f ? "sm" : "md")], y = c != null && !i.isValidElement(c) && (typeof c == "function" || typeof c == "object" && "$$typeof" in c), b = c ? y ? i.createElement(c, { className: r("text-surface-fg-subtle", v) }) : c : /* @__PURE__ */ a(s, { className: r("text-surface-fg-subtle", v) });
21
+ return /* @__PURE__ */ o("div", {
22
+ ref: g,
23
+ className: r("flex flex-col items-center justify-center text-center", f ? "gap-ds-04 py-ds-07" : "gap-ds-05 py-ds-10", m),
24
+ ...h,
25
25
  children: [
26
- /* @__PURE__ */ i(e.div, {
27
- className: n("flex items-center justify-center rounded-ds-xl bg-surface-raised", d ? "h-ds-md w-ds-md" : "h-ds-lg w-ds-lg", !_ && s != null && g),
28
- animate: { y: [
26
+ /* @__PURE__ */ a(e.div, {
27
+ className: r("flex items-center justify-center rounded-ds-xl bg-surface-raised", f ? "h-ds-md w-ds-md" : "h-ds-lg w-ds-lg", !y && c != null && v),
28
+ animate: _ ? {} : { y: [
29
29
  0,
30
30
  -4,
31
31
  0
32
32
  ] },
33
- transition: {
33
+ transition: _ ? {} : {
34
34
  repeat: Infinity,
35
35
  duration: 3,
36
36
  ease: "easeInOut"
37
37
  },
38
- children: v
38
+ children: b
39
39
  }),
40
- /* @__PURE__ */ a(e.div, {
40
+ /* @__PURE__ */ o(e.div, {
41
41
  className: "flex max-w-[280px] flex-col gap-ds-02",
42
42
  initial: { opacity: 0 },
43
43
  animate: { opacity: 1 },
44
44
  transition: {
45
45
  delay: .2,
46
- ...t.fade
46
+ ...n.fade
47
47
  },
48
- children: [/* @__PURE__ */ i("h3", {
49
- className: n("text-surface-fg", d ? "text-ds-md font-semibold" : "text-ds-base font-semibold"),
50
- children: c
51
- }), l && /* @__PURE__ */ i("p", {
52
- className: n("text-surface-fg-subtle", d ? "text-ds-sm" : "text-ds-md"),
48
+ children: [/* @__PURE__ */ a("h3", {
49
+ className: r("text-surface-fg", f ? "text-ds-md font-semibold" : "text-ds-base font-semibold"),
53
50
  children: l
51
+ }), u && /* @__PURE__ */ a("p", {
52
+ className: r("text-surface-fg-subtle", f ? "text-ds-sm" : "text-ds-md"),
53
+ children: u
54
54
  })]
55
55
  }),
56
- u && /* @__PURE__ */ i("div", {
56
+ d && /* @__PURE__ */ a("div", {
57
57
  className: "mt-ds-02",
58
- children: u
58
+ children: d
59
59
  })
60
60
  ]
61
61
  });
62
62
  });
63
- s.displayName = "EmptyState";
63
+ c.displayName = "EmptyState";
64
64
  //#endregion
65
- export { s as EmptyState };
65
+ export { c as EmptyState };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"empty-state.js","names":[],"sources":["../../src/composed/empty-state.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { motion, useReducedMotion } from 'framer-motion'\nimport { tweens } from '../ui/lib/motion'\nimport { cn } from '../ui/lib/utils'\n\nexport interface EmptyStateProps extends React.HTMLAttributes<HTMLDivElement> {\n icon?: React.ReactNode | React.ComponentType<{ className?: string }>\n title: string\n description?: string\n action?: React.ReactNode\n compact?: boolean\n /** Icon size. Defaults to 'sm' when compact, 'md' otherwise. */\n iconSize?: 'sm' | 'md' | 'lg'\n}\n\nconst DevalokChakraIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 32 32\"\n fill=\"currentColor\"\n className={className}\n aria-hidden=\"true\"\n >\n <path d=\"M25.97,21.39c-0.9-1.85,0.08-3.95-1.72-5.39c1.76-1.44,0.8-3.55,1.69-5.39c0.05-0.12,0.04-0.25-0.02-0.35c-0.06-0.1-0.16-0.18-0.29-0.19c-2.05-0.15-3.35-2.04-5.5-1.21c-0.39-2.21-2.7-2.44-3.84-4.13c-0.08-0.1-0.19-0.16-0.31-0.16c-0.12,0-0.23,0.05-0.31,0.16c-1.14,1.69-3.43,1.92-3.82,4.13c-2.14-0.83-3.47,1.07-5.52,1.21c-0.13,0.01-0.23,0.09-0.29,0.19c-0.06,0.1-0.07,0.23-0.02,0.35c0.9,1.85-0.08,3.95,1.72,5.39c-1.76,1.44-0.8,3.55-1.69,5.39C6,21.51,6.02,21.64,6.07,21.74c0.06,0.1,0.16,0.18,0.29,0.19c2.05,0.15,3.38,2.06,5.52,1.23c0.39,2.21,2.67,2.43,3.82,4.12c0.08,0.1,0.19,0.16,0.31,0.16c0.12,0,0.23-0.05,0.31-0.16c1.14-1.69,3.42-1.92,3.81-4.13c2.14,0.83,3.48-1.07,5.53-1.22c0.13-0.01,0.23-0.09,0.29-0.19C26.01,21.64,26.02,21.51,25.97,21.39z\" />\n </svg>\n)\n\nconst EmptyState = React.forwardRef<HTMLDivElement, EmptyStateProps>(\n (\n {\n icon,\n title,\n description,\n action,\n compact = false,\n iconSize,\n className,\n ...props\n },\n ref,\n ) => {\n const reducedMotion = useReducedMotion()\n const resolvedIconSize = iconSize ?? (compact ? 'sm' : 'md')\n const iconSizeMap = {\n sm: 'h-ico-sm w-ico-sm',\n md: 'h-ico-lg w-ico-lg',\n lg: 'h-ico-xl w-ico-xl',\n } as const\n const iconSizeClass = iconSizeMap[resolvedIconSize]\n const isComponentType =\n icon != null && !React.isValidElement(icon) && (typeof icon === 'function' || (typeof icon === 'object' && '$$typeof' in (icon as object)))\n const resolvedIcon = icon\n ? isComponentType\n ? React.createElement(icon as React.ComponentType<{ className?: string }>, {\n className: cn('text-surface-fg-subtle', iconSizeClass),\n })\n : icon\n : (\n <DevalokChakraIcon\n className={cn('text-surface-fg-subtle', iconSizeClass)}\n />\n )\n\n return (\n <div\n ref={ref}\n className={cn(\n 'flex flex-col items-center justify-center text-center',\n compact ? 'gap-ds-04 py-ds-07' : 'gap-ds-05 py-ds-10',\n className,\n )}\n {...props}\n >\n <motion.div\n className={cn(\n 'flex items-center justify-center rounded-ds-xl bg-surface-raised',\n compact ? 'h-ds-md w-ds-md' : 'h-ds-lg w-ds-lg',\n !isComponentType && icon != null && iconSizeClass,\n )}\n animate={reducedMotion ? {} : { y: [0, -4, 0] }}\n transition={reducedMotion ? {} : { repeat: Infinity, duration: 3, ease: 'easeInOut' }}\n >\n {resolvedIcon}\n </motion.div>\n\n <motion.div\n className=\"flex max-w-[280px] flex-col gap-ds-02\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={{ delay: 0.2, ...tweens.fade }}\n >\n <h3\n className={cn(\n 'text-surface-fg',\n compact ? 'text-ds-md font-semibold' : 'text-ds-base font-semibold',\n )}\n >\n {title}\n </h3>\n {description && (\n <p\n className={cn(\n 'text-surface-fg-subtle',\n compact ? 'text-ds-sm' : 'text-ds-md',\n )}\n >\n {description}\n </p>\n )}\n </motion.div>\n\n {action && <div className=\"mt-ds-02\">{action}</div>}\n </div>\n )\n },\n)\nEmptyState.displayName = 'EmptyState'\n\nexport { EmptyState }\n"],"mappings":";;;;;;;AAiBA,IAAM,KAAqB,EAAE,mBAC3B,kBAAC,OAAD;CACE,OAAM;CACN,SAAQ;CACR,MAAK;CACM;CACX,eAAY;WAEZ,kBAAC,QAAD,EAAM,GAAE,iuBAAkuB,CAAA;CACtuB,CAAA,EAGF,IAAa,EAAM,YAErB,EACE,SACA,UACA,gBACA,WACA,aAAU,IACV,aACA,cACA,GAAG,KAEL,MACG;CACH,IAAM,IAAgB,GAAkB,EAOlC,IALc;EAClB,IAAI;EACJ,IAAI;EACJ,IAAI;EACL,CALwB,MAAa,IAAU,OAAO,QAOjD,IACJ,KAAQ,QAAQ,CAAC,EAAM,eAAe,EAAK,KAAK,OAAO,KAAS,cAAe,OAAO,KAAS,YAAY,cAAe,IACtH,IAAe,IACjB,IACE,EAAM,cAAc,GAAqD,EACvE,WAAW,EAAG,0BAA0B,EAAc,EACvD,CAAC,GACF,IAEF,kBAAC,GAAD,EACE,WAAW,EAAG,0BAA0B,EAAc,EACtD,CAAA;AAGN,QACE,kBAAC,OAAD;EACO;EACL,WAAW,EACT,yDACA,IAAU,uBAAuB,sBACjC,EACD;EACD,GAAI;YAPN;GASE,kBAAC,EAAO,KAAR;IACE,WAAW,EACT,oEACA,IAAU,oBAAoB,mBAC9B,CAAC,KAAmB,KAAQ,QAAQ,EACrC;IACD,SAAS,IAAgB,EAAE,GAAG,EAAE,GAAG;KAAC;KAAG;KAAI;KAAE,EAAE;IAC/C,YAAY,IAAgB,EAAE,GAAG;KAAE,QAAQ;KAAU,UAAU;KAAG,MAAM;KAAa;cAEpF;IACU,CAAA;GAEb,kBAAC,EAAO,KAAR;IACE,WAAU;IACV,SAAS,EAAE,SAAS,GAAG;IACvB,SAAS,EAAE,SAAS,GAAG;IACvB,YAAY;KAAE,OAAO;KAAK,GAAG,EAAO;KAAM;cAJ5C,CAME,kBAAC,MAAD;KACE,WAAW,EACT,mBACA,IAAU,6BAA6B,6BACxC;eAEA;KACE,CAAA,EACJ,KACC,kBAAC,KAAD;KACE,WAAW,EACT,0BACA,IAAU,eAAe,aAC1B;eAEA;KACC,CAAA,CAEK;;GAEZ,KAAU,kBAAC,OAAD;IAAK,WAAU;cAAY;IAAa,CAAA;GAC/C;;EAGX;AACD,EAAW,cAAc"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-boundary.js","names":[],"sources":["../../src/composed/error-boundary.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { IconAlertTriangle, IconBan, IconFileUnknown, IconServerOff } from '@tabler/icons-react'\nimport { Icon } from '../ui/icon'\nimport { Button } from '../ui/button'\nimport { cn } from '../ui/lib/utils'\n\ndeclare const process: { env: { NODE_ENV?: string } } | undefined\n\nexport interface ErrorDisplayProps extends React.ComponentPropsWithoutRef<'div'> {\n error: unknown\n onReset?: () => void\n}\n\nfunction getStatusFromError(error: unknown): number | undefined {\n if (\n error &&\n typeof error === 'object' &&\n 'status' in error &&\n typeof (error as Record<string, unknown>).status === 'number'\n ) {\n return (error as Record<string, unknown>).status as number\n }\n return undefined\n}\n\nfunction getMessageFromError(error: unknown): string | undefined {\n if (error instanceof Error) {\n return error.message\n }\n if (\n error &&\n typeof error === 'object' &&\n 'data' in error\n ) {\n const data = (error as Record<string, unknown>).data\n if (typeof data === 'string') return data\n if (data && typeof data === 'object' && 'message' in data) {\n return String((data as Record<string, unknown>).message)\n }\n }\n if (typeof error === 'string') {\n return error\n }\n return undefined\n}\n\nfunction getStackFromError(error: unknown): string | undefined {\n if (error instanceof Error) {\n return error.stack\n }\n return undefined\n}\n\nfunction getErrorConfig(status?: number) {\n switch (status) {\n case 404:\n return {\n icon: IconFileUnknown,\n title: 'Page not found',\n message:\n 'The page you are looking for does not exist or has been moved.',\n bgClass: 'bg-accent-2',\n iconClass: 'text-accent-11',\n }\n case 403:\n return {\n icon: IconBan,\n title: 'Access denied',\n message:\n 'You do not have permission to view this page. Contact your administrator if you believe this is a mistake.',\n bgClass: 'bg-warning-3',\n iconClass: 'text-warning-11',\n }\n case 500:\n return {\n icon: IconServerOff,\n title: 'Server error',\n message:\n 'Something went wrong on our end. Please try again later or contact support if the issue persists.',\n bgClass: 'bg-error-3',\n iconClass: 'text-error-11',\n }\n default:\n return {\n icon: IconAlertTriangle,\n title: 'Something went wrong',\n message:\n 'An unexpected error occurred. Please try again or go back to the home page.',\n bgClass: 'bg-accent-2',\n iconClass: 'text-accent-11',\n }\n }\n}\n\nconst ErrorDisplay = React.forwardRef<HTMLDivElement, ErrorDisplayProps>(\n function ErrorDisplay({ error, onReset, className, ...props }, ref) {\n const status = getStatusFromError(error)\n const message = getMessageFromError(error)\n const stack = getStackFromError(error)\n const isDev =\n typeof process !== 'undefined' &&\n process.env &&\n process.env.NODE_ENV === 'development'\n\n const errorConfig = getErrorConfig(status)\n const ErrorIcon = errorConfig.icon\n\n return (\n <div ref={ref} {...props} className={cn(\"flex min-h-[60vh] items-center justify-center p-ds-05\", className)}>\n <div\n className=\"flex w-full max-w-lg flex-col items-center gap-ds-06 rounded-ds-xl border border-surface-border-strong bg-surface-raised p-ds-07 text-center shadow-raised\"\n >\n {/* Error Icon */}\n <div\n className={cn(\n 'flex h-ds-lg w-ds-lg items-center justify-center rounded-ds-2xl',\n errorConfig.bgClass,\n )}\n >\n <Icon\n icon={ErrorIcon}\n size=\"2xl\"\n className={errorConfig.iconClass}\n />\n </div>\n\n {/* Error IconInfoCircle */}\n <div className=\"flex flex-col gap-ds-03\">\n {status && (\n <span className=\"text-ds-sm text-surface-fg-subtle\">\n Error {status}\n </span>\n )}\n <h2 className=\"text-ds-2xl font-semibold text-surface-fg\">\n {errorConfig.title}\n </h2>\n <p className=\"text-ds-base text-surface-fg-subtle\">\n {message || errorConfig.message}\n </p>\n </div>\n\n {/* Actions */}\n {onReset && (\n <div className=\"flex items-center gap-ds-04\">\n <Button\n variant=\"outline\"\n size=\"md\"\n onClick={onReset}\n >\n Try Again\n </Button>\n </div>\n )}\n\n {/* Dev stack trace */}\n {isDev && stack && (\n <div className=\"w-full overflow-auto rounded-ds-lg border border-surface-border-strong bg-surface-raised p-ds-05 text-left\">\n <p className=\"text-ds-sm mb-ds-03 font-semibold text-surface-fg\">\n Stack Trace (development only)\n </p>\n <pre className=\"whitespace-pre-wrap text-ds-sm text-surface-fg-subtle\">\n {stack}\n </pre>\n </div>\n )}\n </div>\n </div>\n )\n},\n)\n\nErrorDisplay.displayName = 'ErrorDisplay'\n\ninterface ErrorBoundaryProps {\n children: React.ReactNode\n /** Optional callback when the user clicks \"Try Again\" */\n onReset?: () => void\n /** Optional custom fallback — receives the caught error. Defaults to ErrorDisplay. */\n fallback?: (props: { error: unknown; onReset?: () => void }) => React.ReactNode\n}\n\ninterface ErrorBoundaryState {\n error: unknown | null\n}\n\nclass ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n constructor(props: ErrorBoundaryProps) {\n super(props)\n this.state = { error: null }\n }\n\n static getDerivedStateFromError(error: unknown): ErrorBoundaryState {\n return { error }\n }\n\n private handleReset = () => {\n this.setState({ error: null })\n this.props.onReset?.()\n }\n\n render() {\n if (this.state.error !== null) {\n if (this.props.fallback) {\n return this.props.fallback({ error: this.state.error, onReset: this.handleReset })\n }\n return <ErrorDisplay error={this.state.error} onReset={this.handleReset} />\n }\n return this.props.children\n }\n}\n\nexport { ErrorDisplay, ErrorBoundary }\nexport type { ErrorBoundaryProps }\n"],"mappings":";;;;;;;;AAeA,SAAS,EAAmB,GAAoC;AAC9D,KACE,KACA,OAAO,KAAU,YACjB,YAAY,KACZ,OAAQ,EAAkC,UAAW,SAErD,QAAQ,EAAkC;;AAK9C,SAAS,EAAoB,GAAoC;AAC/D,KAAI,aAAiB,MACnB,QAAO,EAAM;AAEf,KACE,KACA,OAAO,KAAU,YACjB,UAAU,GACV;EACA,IAAM,IAAQ,EAAkC;AAChD,MAAI,OAAO,KAAS,SAAU,QAAO;AACrC,MAAI,KAAQ,OAAO,KAAS,YAAY,aAAa,EACnD,QAAO,OAAQ,EAAiC,QAAQ;;AAG5D,KAAI,OAAO,KAAU,SACnB,QAAO;;AAKX,SAAS,EAAkB,GAAoC;AAC7D,KAAI,aAAiB,MACnB,QAAO,EAAM;;AAKjB,SAAS,EAAe,GAAiB;AACvC,SAAQ,GAAR;EACE,KAAK,IACH,QAAO;GACL,MAAM;GACN,OAAO;GACP,SACE;GACF,SAAS;GACT,WAAW;GACZ;EACH,KAAK,IACH,QAAO;GACL,MAAM;GACN,OAAO;GACP,SACE;GACF,SAAS;GACT,WAAW;GACZ;EACH,KAAK,IACH,QAAO;GACL,MAAM;GACN,OAAO;GACP,SACE;GACF,SAAS;GACT,WAAW;GACZ;EACH,QACE,QAAO;GACL,MAAM;GACN,OAAO;GACP,SACE;GACF,SAAS;GACT,WAAW;GACZ;;;AAIP,IAAM,IAAe,EAAM,WACzB,SAAsB,EAAE,UAAO,YAAS,cAAW,GAAG,KAAS,GAAK;CACpE,IAAM,IAAS,EAAmB,EAAM,EAClC,IAAU,EAAoB,EAAM,EACpC,IAAQ,EAAkB,EAAM,EAChC,IACJ,OAAO,UAAY,OACnB,QAAQ,OAAA,QAAA,IAAA,aACiB,eAErB,IAAc,EAAe,EAAO,EACpC,IAAY,EAAY;AAE9B,QACE,kBAAC,OAAD;EAAU;EAAK,GAAI;EAAO,WAAW,EAAG,yDAAyD,EAAU;YACzG,kBAAC,OAAD;GACE,WAAU;aADZ;IAIE,kBAAC,OAAD;KACE,WAAW,EACT,mEACA,EAAY,QACb;eAED,kBAAC,GAAD;MACE,MAAM;MACN,MAAK;MACL,WAAW,EAAY;MACvB,CAAA;KACE,CAAA;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf;MACG,KACC,kBAAC,QAAD;OAAM,WAAU;iBAAhB,CAAoD,UAC3C,EACF;;MAET,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAY;OACV,CAAA;MACL,kBAAC,KAAD;OAAG,WAAU;iBACV,KAAW,EAAY;OACtB,CAAA;MACA;;IAGL,KACC,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,GAAD;MACE,SAAQ;MACR,MAAK;MACL,SAAS;gBACV;MAEQ,CAAA;KACL,CAAA;IAIP,KAAS,KACR,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MAAG,WAAU;gBAAoD;MAE7D,CAAA,EACJ,kBAAC,OAAD;MAAK,WAAU;gBACZ;MACG,CAAA,CACF;;IAEJ;;EACF,CAAA;EAGT;AAED,EAAa,cAAc;AAc3B,IAAM,IAAN,cAA4B,EAAM,UAAkD;CAClF,YAAY,GAA2B;AAErC,EADA,MAAM,EAAM,EACZ,KAAK,QAAQ,EAAE,OAAO,MAAM;;CAG9B,OAAO,yBAAyB,GAAoC;AAClE,SAAO,EAAE,UAAO;;CAGlB,oBAA4B;AAE1B,EADA,KAAK,SAAS,EAAE,OAAO,MAAM,CAAC,EAC9B,KAAK,MAAM,WAAW;;CAGxB,SAAS;AAOP,SANI,KAAK,MAAM,UAAU,OAMlB,KAAK,MAAM,WALZ,KAAK,MAAM,WACN,KAAK,MAAM,SAAS;GAAE,OAAO,KAAK,MAAM;GAAO,SAAS,KAAK;GAAa,CAAC,GAE7E,kBAAC,GAAD;GAAc,OAAO,KAAK,MAAM;GAAO,SAAS,KAAK;GAAe,CAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-bar.js","names":[],"sources":["../../src/composed/filter-bar.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { motion } from 'framer-motion'\nimport { IconChevronDown } from '@tabler/icons-react'\nimport { Icon } from '../ui/icon'\nimport { cn } from '../ui/lib/utils'\nimport { springs } from '../ui/lib/motion'\nimport { SearchInput } from '../ui/search-input'\nimport { Button } from '../ui/button'\nimport { Badge } from '../ui/badge'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../ui/select'\nimport { MultiSelectPopover, type MultiSelectItem } 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-ds-md 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 items-center gap-ds-02 truncate\">\n <span>{label}</span>\n {count > 0 && (\n <motion.span\n key={count}\n initial={{ scale: 0.8 }}\n animate={{ scale: 1 }}\n transition={springs.bouncy}\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, FilterSelect, FilterMultiSelect }\n"],"mappings":";;;;;;;;;;;;;;AA0BA,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,8HACA,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,EAAA,UAAO,GAAa,CAAA,EACnB,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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-section.js","names":[],"sources":["../../src/composed/form-section.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { motion } from 'framer-motion'\nimport { cn } from '../ui/lib/utils'\nimport { springs } from '../ui/lib/motion'\nimport { IconChevronDown } from '@tabler/icons-react'\nimport { Icon } from '../ui/icon'\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from '../ui/collapsible'\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":";;;;;;;;;;AA0BA,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"}
@@ -0,0 +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'\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":";;;;;;AAUA,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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline-edit.js","names":[],"sources":["../../src/composed/inline-edit.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { IconPencil } from '@tabler/icons-react'\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 ...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 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-ds-sm -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-ds-sm -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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"}
@@ -0,0 +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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loading-skeleton.js","names":[],"sources":["../../src/composed/loading-skeleton.tsx"],"sourcesContent":["// @server-safe\nimport * as React from 'react'\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-ds-lg 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-[16px] 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-[12px] w-full bg-surface-raised-hover\" />\n <Skeleton className=\"h-[12px] w-4/5 bg-surface-raised-hover\" />\n <Skeleton className=\"h-[12px] 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-ds-full bg-surface-raised-hover\" />\n <Skeleton className=\"h-[12px] w-[80px] 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-ds-lg 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-[12px] bg-surface-raised-hover',\n i === 0 ? 'w-[160px]' : '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-[12px] bg-surface-raised-hover',\n colIndex === 0 ? 'w-[160px]' : '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-[12px] w-[12px] rounded bg-surface-raised-hover\" />\n <Skeleton className=\"h-[12px] w-[80px] bg-surface-raised-hover\" />\n <Skeleton className=\"h-[16px] w-[20px] rounded-ds-full 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-ds-lg 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-[12px] w-4/5 bg-surface-raised-hover\" />\n <Skeleton className=\"h-[12px] 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-ds-full bg-surface-raised-hover\" />\n <Skeleton className=\"h-ds-03 w-[64px] bg-surface-raised-hover\" />\n </div>\n <Skeleton className=\"h-[16px] w-ds-lg rounded-ds-full 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-ds-full bg-surface-raised-hover\" />\n )}\n <div className=\"flex flex-1 flex-col gap-ds-02b\">\n <Skeleton className=\"h-[12px] 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-[20px] w-[56px] rounded-ds-full bg-surface-raised-hover\" />\n </div>\n ))}\n </div>\n )\n},\n)\n\nListSkeleton.displayName = 'ListSkeleton'\n\nexport { CardSkeleton, TableSkeleton, BoardSkeleton, ListSkeleton }\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-viewer.js","names":[],"sources":["../../src/composed/markdown-viewer.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport Markdown from 'react-markdown'\nimport remarkGfm from 'remark-gfm'\nimport { IconCopy, IconCheck } from '@tabler/icons-react'\nimport { Icon } from '../ui/icon'\nimport { cn } from '../ui/lib/utils'\nimport { Button } from '../ui/button'\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-ds-md 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-md)',\n fontSize: 'var(--font-size-sm)',\n padding: 'var(--spacing-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-ds-sm 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-ds-md 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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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"master-detail.js","names":[],"sources":["../../src/composed/master-detail.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport { IconArrowLeft } from '@tabler/icons-react'\nimport { cn } from '../ui/lib/utils'\nimport { Button } from '../ui/button'\nimport { Icon } from '../ui/icon'\nimport { springs } from '../ui/lib/motion'\n\n// ============================================================\n// Types\n// ============================================================\n\n/**\n * A responsive master-detail layout. On desktop, shows a fixed-width list panel\n * alongside a detail panel. Below the breakpoint, switches to a stacked view\n * with animated transitions and a back button.\n */\nexport interface MasterDetailProps extends React.HTMLAttributes<HTMLDivElement> {\n /** ID of currently selected item. null = no selection (show list on mobile). */\n selected?: string | null\n /** Called when mobile back button is pressed. */\n onBack?: () => void\n /** Master panel width on desktop. @default '280px' */\n masterWidth?: string\n /** Breakpoint below which stacked mode activates. @default 'md' */\n breakpoint?: 'sm' | 'md' | 'lg'\n /** Content to show in the detail pane when nothing is selected. */\n emptyState?: React.ReactNode\n /** Called when user presses ArrowUp/ArrowDown while the list has focus. */\n onNavigate?: (direction: 'up' | 'down') => void\n}\n\ninterface MasterDetailListProps extends React.HTMLAttributes<HTMLDivElement> {}\n\ninterface MasterDetailDetailProps extends React.HTMLAttributes<HTMLDivElement> {}\n\ninterface MasterDetailListItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n active?: boolean\n}\n\n// ============================================================\n// Breakpoint values\n// ============================================================\n\nconst breakpoints: Record<string, string> = {\n sm: '640px',\n md: '768px',\n lg: '1024px',\n}\n\nfunction useMediaQuery(query: string): boolean {\n const [matches, setMatches] = React.useState(false)\n\n React.useEffect(() => {\n if (typeof window === 'undefined') return\n const mql = window.matchMedia(query)\n setMatches(mql.matches)\n const handler = (e: MediaQueryListEvent) => setMatches(e.matches)\n mql.addEventListener('change', handler)\n return () => mql.removeEventListener('change', handler)\n }, [query])\n\n return matches\n}\n\n// ============================================================\n// Context\n// ============================================================\n\ninterface MasterDetailContextValue {\n selected: string | null\n isMobile: boolean\n onBack?: () => void\n emptyState?: React.ReactNode\n onNavigate?: (direction: 'up' | 'down') => void\n activeIndex: number\n setActiveIndex: (index: number) => void\n registerItemRef: (index: number, el: HTMLButtonElement | null) => void\n itemCount: number\n setItemCount: (count: number) => void\n}\n\nconst MasterDetailContext = React.createContext<MasterDetailContextValue>({\n selected: null,\n isMobile: false,\n activeIndex: 0,\n setActiveIndex: () => {},\n registerItemRef: () => {},\n itemCount: 0,\n setItemCount: () => {},\n})\n\n// ============================================================\n// Compound Components\n// ============================================================\n\nfunction MasterDetailList({ children, className, ...props }: MasterDetailListProps) {\n const { selected, isMobile, onNavigate, activeIndex, setActiveIndex, registerItemRef, setItemCount } = React.useContext(MasterDetailContext)\n const itemRefsLocal = React.useRef<(HTMLButtonElement | null)[]>([])\n\n // Count children and register with context\n const childCount = React.Children.count(children)\n React.useEffect(() => {\n setItemCount(childCount)\n }, [childCount, setItemCount])\n\n // On mobile, hide list when something is selected\n if (isMobile && selected) return null\n\n function handleKeyDown(e: React.KeyboardEvent) {\n if (e.key === 'ArrowDown') {\n e.preventDefault()\n const next = Math.min(activeIndex + 1, childCount - 1)\n setActiveIndex(next)\n itemRefsLocal.current[next]?.focus()\n onNavigate?.('down')\n } else if (e.key === 'ArrowUp') {\n e.preventDefault()\n const prev = Math.max(activeIndex - 1, 0)\n setActiveIndex(prev)\n itemRefsLocal.current[prev]?.focus()\n onNavigate?.('up')\n } else if (e.key === 'Home') {\n e.preventDefault()\n setActiveIndex(0)\n itemRefsLocal.current[0]?.focus()\n } else if (e.key === 'End') {\n e.preventDefault()\n const last = childCount - 1\n setActiveIndex(last)\n itemRefsLocal.current[last]?.focus()\n }\n }\n\n return (\n <div\n role=\"listbox\"\n tabIndex={-1}\n className={cn(\n 'overflow-y-auto focus-visible:outline-hidden',\n !isMobile && 'border-r border-surface-border',\n className,\n )}\n onKeyDown={handleKeyDown}\n {...props}\n >\n {React.Children.map(children, (child, i) => {\n if (!React.isValidElement(child)) return child\n return React.cloneElement(child as React.ReactElement<any>, {\n ref: (el: HTMLButtonElement | null) => {\n itemRefsLocal.current[i] = el\n registerItemRef(i, el)\n },\n tabIndex: i === activeIndex ? 0 : -1,\n })\n })}\n </div>\n )\n}\n\nfunction MasterDetailDetail({ children, className, ...props }: MasterDetailDetailProps) {\n const { selected, isMobile, onBack, emptyState } = React.useContext(MasterDetailContext)\n\n // On mobile, hide detail when nothing selected\n if (isMobile && !selected) return null\n\n return (\n <div className={cn('flex-1 overflow-y-auto', className)} {...props}>\n {isMobile && onBack && (\n <div className=\"border-b border-surface-border px-ds-04 py-ds-03\">\n <Button variant=\"ghost\" size=\"xs\" onClick={onBack} startIcon={<Icon icon={IconArrowLeft} />}>\n Back\n </Button>\n </div>\n )}\n <AnimatePresence mode=\"wait\">\n <motion.div\n key={selected ?? 'empty'}\n initial={isMobile ? { x: 20, opacity: 0 } : false}\n animate={{ x: 0, opacity: 1 }}\n exit={isMobile ? { x: -20, opacity: 0 } : undefined}\n transition={springs.snappy}\n >\n {selected ? children : (emptyState ?? children)}\n </motion.div>\n </AnimatePresence>\n </div>\n )\n}\n\nconst MasterDetailListItem = React.forwardRef<HTMLButtonElement, MasterDetailListItemProps>(\n function MasterDetailListItem({ active = false, children, className, onKeyDown, ...props }, ref) {\n function handleKeyDown(e: React.KeyboardEvent<HTMLButtonElement>) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n ;(e.target as HTMLButtonElement).click()\n }\n onKeyDown?.(e)\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"option\"\n aria-selected={active}\n data-active={active || undefined}\n onKeyDown={handleKeyDown}\n className={cn(\n 'flex w-full items-center px-ds-04 py-ds-03 text-left text-ds-md font-sans text-surface-fg',\n 'transition-colors duration-fast-01 ease-productive-standard',\n 'hover:bg-surface-raised-hover',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-7 focus-visible:ring-inset',\n active && 'bg-accent-2 text-accent-11 border-l-2 border-accent-9',\n className,\n )}\n {...props}\n >\n {children}\n </button>\n )\n },\n)\n\n// ============================================================\n// MasterDetail Root\n// ============================================================\n\nfunction MasterDetailRoot({\n selected = null,\n onBack,\n masterWidth = '280px',\n breakpoint = 'md',\n emptyState,\n onNavigate,\n children,\n className,\n style,\n ...props\n}: MasterDetailProps) {\n const isMobile = useMediaQuery(`(max-width: ${breakpoints[breakpoint]})`)\n const [activeIndex, setActiveIndex] = React.useState(0)\n const [itemCount, setItemCount] = React.useState(0)\n const itemRefs = React.useRef<(HTMLButtonElement | null)[]>([])\n\n const registerItemRef = React.useCallback((index: number, el: HTMLButtonElement | null) => {\n itemRefs.current[index] = el\n }, [])\n\n return (\n <MasterDetailContext.Provider value={{ selected, isMobile, onBack, emptyState, onNavigate, activeIndex, setActiveIndex, registerItemRef, itemCount, setItemCount }}>\n <div\n className={cn(\n 'flex h-full',\n !isMobile && 'grid',\n className,\n )}\n style={{\n ...style,\n ...(isMobile ? {} : { gridTemplateColumns: `${masterWidth} 1fr` }),\n }}\n {...props}\n >\n {children}\n </div>\n </MasterDetailContext.Provider>\n )\n}\n\nconst MasterDetail = Object.assign(MasterDetailRoot, {\n List: MasterDetailList,\n Detail: MasterDetailDetail,\n ListItem: MasterDetailListItem,\n})\n\nexport { MasterDetail }\nexport type { MasterDetailListItemProps }\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"member-picker.js","names":[],"sources":["../../src/composed/member-picker.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport {\n Avatar,\n AvatarImage,\n AvatarFallback,\n} from '../ui/avatar'\nimport { MultiSelectPopover, type MultiSelectItem } from './multi-select-popover'\nimport { getInitials } from './lib/string-utils'\n\n// ============================================================\n// Types — backward-compatible with original MemberPicker\n// ============================================================\n\nexport interface MemberPickerMember {\n id: string\n name: string\n avatar?: string\n}\n\nexport interface MemberPickerProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'onSelect'> {\n members: MemberPickerMember[]\n selectedIds: string[]\n onSelect: (memberId: string) => void\n multiple?: boolean\n placeholder?: string\n children: React.ReactNode\n}\n\n// ============================================================\n// MemberPicker — thin wrapper around MultiSelectPopover\n// ============================================================\n\nconst MemberPicker = React.forwardRef<HTMLDivElement, MemberPickerProps>(\n (\n {\n members,\n selectedIds,\n onSelect,\n children,\n multiple = false,\n placeholder = 'Search members...',\n ...props\n },\n ref,\n ) => {\n const items: MultiSelectItem[] = React.useMemo(\n () => members.map((m) => ({ id: m.id, label: m.name, image: m.avatar })),\n [members],\n )\n\n function handleChange(ids: string[]) {\n // Find the toggled id\n const added = ids.find((id) => !selectedIds.includes(id))\n const removed = selectedIds.find((id) => !ids.includes(id))\n const toggled = added ?? removed\n if (toggled) onSelect(toggled)\n }\n\n return (\n <MultiSelectPopover\n ref={ref}\n items={items}\n value={selectedIds}\n onValueChange={handleChange}\n searchPlaceholder={placeholder}\n maxSelections={multiple ? undefined : 1}\n renderItem={(item) => (\n <div className=\"flex items-center gap-ds-03\">\n <Avatar className=\"h-ico-md w-ico-md\">\n {item.image && <AvatarImage src={item.image} alt={item.label} />}\n <AvatarFallback className=\"bg-surface-raised-hover text-ds-xs font-semibold text-surface-fg\">\n {getInitials(item.label)}\n </AvatarFallback>\n </Avatar>\n <span className=\"flex-1 truncate text-ds-md font-body text-surface-fg\">\n {item.label}\n </span>\n </div>\n )}\n {...props}\n >\n {children}\n </MultiSelectPopover>\n )\n },\n)\n\nMemberPicker.displayName = 'MemberPicker'\n\nexport { MemberPicker }\n"],"mappings":";;;;;;;AAkCA,IAAM,IAAe,EAAM,YAEvB,EACE,YACA,gBACA,aACA,aACA,cAAW,IACX,iBAAc,qBACd,GAAG,KAEL,MACG;CACH,IAAM,IAA2B,EAAM,cAC/B,EAAQ,KAAK,OAAO;EAAE,IAAI,EAAE;EAAI,OAAO,EAAE;EAAM,OAAO,EAAE;EAAQ,EAAE,EACxE,CAAC,EAAQ,CACV;CAED,SAAS,EAAa,GAAe;EAEnC,IAAM,IAAQ,EAAI,MAAM,MAAO,CAAC,EAAY,SAAS,EAAG,CAAC,EACnD,IAAU,EAAY,MAAM,MAAO,CAAC,EAAI,SAAS,EAAG,CAAC,EACrD,IAAU,KAAS;AACzB,EAAI,KAAS,EAAS,EAAQ;;AAGhC,QACE,kBAAC,GAAD;EACO;EACE;EACP,OAAO;EACP,eAAe;EACf,mBAAmB;EACnB,eAAe,IAAW,KAAA,IAAY;EACtC,aAAa,MACX,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD;IAAQ,WAAU;cAAlB,CACG,EAAK,SAAS,kBAAC,GAAD;KAAa,KAAK,EAAK;KAAO,KAAK,EAAK;KAAS,CAAA,EAChE,kBAAC,GAAD;KAAgB,WAAU;eACvB,EAAY,EAAK,MAAM;KACT,CAAA,CACV;OACT,kBAAC,QAAD;IAAM,WAAU;cACb,EAAK;IACD,CAAA,CACH;;EAER,GAAI;EAEH;EACkB,CAAA;EAG1B;AAED,EAAa,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"multi-select-popover.d.ts","sourceRoot":"","sources":["../../src/composed/multi-select-popover.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAiB9B,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,eAAe,EAAE,CAAA;CACzB;AAED,MAAM,WAAW,uBAAwB,SAAQ,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACtG,8DAA8D;IAC9D,KAAK,CAAC,EAAE,eAAe,EAAE,CAAA;IACzB,yCAAyC;IACzC,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC3B,kCAAkC;IAClC,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,oCAAoC;IACpC,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;IACtC,2BAA2B;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,EAAE,CAAC,CAAA;IACxD,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,KAAK,KAAK,CAAC,SAAS,CAAA;IAC1E,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,mCAAmC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,yCAAyC;IACzC,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAA;IAClC,oBAAoB;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,sBAAsB;IACtB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAMD,QAAA,MAAM,kBAAkB,gGA6OvB,CAAA;AAGD,OAAO,EAAE,kBAAkB,EAAE,CAAA"}
1
+ {"version":3,"file":"multi-select-popover.d.ts","sourceRoot":"","sources":["../../src/composed/multi-select-popover.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAiB9B,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,eAAe,EAAE,CAAA;CACzB;AAED,MAAM,WAAW,uBAAwB,SAAQ,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACtG,8DAA8D;IAC9D,KAAK,CAAC,EAAE,eAAe,EAAE,CAAA;IACzB,yCAAyC;IACzC,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC3B,kCAAkC;IAClC,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,oCAAoC;IACpC,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;IACtC,2BAA2B;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,EAAE,CAAC,CAAA;IACxD,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,KAAK,KAAK,CAAC,SAAS,CAAA;IAC1E,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,mCAAmC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,yCAAyC;IACzC,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAA;IAClC,oBAAoB;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,sBAAsB;IACtB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAMD,QAAA,MAAM,kBAAkB,gGA+OvB,CAAA;AAGD,OAAO,EAAE,kBAAkB,EAAE,CAAA"}