@devalok/shilp-sutra 0.56.0 → 0.59.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 (374) hide show
  1. package/MIGRATION.md +198 -0
  2. package/dist/_chunks/badge-group.js +75 -174
  3. package/dist/_chunks/badge-group.js.map +1 -1
  4. package/dist/_chunks/chat.js +270 -253
  5. package/dist/_chunks/chat.js.map +1 -1
  6. package/dist/_chunks/document-preview.js +1 -1
  7. package/dist/_chunks/document-preview.js.map +1 -1
  8. package/dist/_chunks/emoji-suggestion.js +1 -1
  9. package/dist/_chunks/emoji-suggestion.js.map +1 -1
  10. package/dist/_chunks/image-preview.js +71 -70
  11. package/dist/_chunks/image-preview.js.map +1 -1
  12. package/dist/_chunks/mention-suggestion.js +2 -2
  13. package/dist/_chunks/mention-suggestion.js.map +1 -1
  14. package/dist/_chunks/motion-preference.js +15 -0
  15. package/dist/_chunks/motion-preference.js.map +1 -0
  16. package/dist/_chunks/motion-provider.js +1 -1
  17. package/dist/_chunks/motion-provider.js.map +1 -1
  18. package/dist/_chunks/oauth-button.js +1 -1
  19. package/dist/_chunks/oauth-button.js.map +1 -1
  20. package/dist/_chunks/popover.js +50 -49
  21. package/dist/_chunks/popover.js.map +1 -1
  22. package/dist/_chunks/primitives-internal.js +29 -29
  23. package/dist/_chunks/primitives-internal.js.map +1 -1
  24. package/dist/_chunks/shared.js +48 -47
  25. package/dist/_chunks/shared.js.map +1 -1
  26. package/dist/_chunks/success.js +36 -36
  27. package/dist/_chunks/success.js.map +1 -1
  28. package/dist/_chunks/tree-view.js +1 -1
  29. package/dist/_chunks/tree-view.js.map +1 -1
  30. package/dist/_chunks/use-calendar.js +4 -4
  31. package/dist/_chunks/use-calendar.js.map +1 -1
  32. package/dist/ai/block-renderer.js +8 -8
  33. package/dist/ai/blocks/text.js +1 -1
  34. package/dist/ai/blocks/text.js.map +1 -1
  35. package/dist/ai/command-bar.js +67 -67
  36. package/dist/ai/command-bar.js.map +1 -1
  37. package/dist/ai/conversation.js +35 -35
  38. package/dist/ai/conversation.js.map +1 -1
  39. package/dist/ai/index.js +4 -4
  40. package/dist/composed/activity-feed.d.ts.map +1 -1
  41. package/dist/composed/activity-feed.js +109 -108
  42. package/dist/composed/activity-feed.js.map +1 -1
  43. package/dist/composed/avatar-group.d.ts +7 -2
  44. package/dist/composed/avatar-group.d.ts.map +1 -1
  45. package/dist/composed/avatar-group.js +3 -3
  46. package/dist/composed/avatar-group.js.map +1 -1
  47. package/dist/composed/command-palette.js +137 -137
  48. package/dist/composed/command-palette.js.map +1 -1
  49. package/dist/composed/content-card.js +2 -2
  50. package/dist/composed/content-card.js.map +1 -1
  51. package/dist/composed/date-picker/index.js +9 -9
  52. package/dist/composed/date-picker/index.js.map +1 -1
  53. package/dist/composed/diff.d.ts +23 -2
  54. package/dist/composed/diff.d.ts.map +1 -1
  55. package/dist/composed/diff.js +341 -260
  56. package/dist/composed/diff.js.map +1 -1
  57. package/dist/composed/emoji-picker.js +3 -3
  58. package/dist/composed/emoji-picker.js.map +1 -1
  59. package/dist/composed/empty-state.js +4 -4
  60. package/dist/composed/error-boundary.js +2 -2
  61. package/dist/composed/error-boundary.js.map +1 -1
  62. package/dist/composed/file-preview/image-preview.d.ts.map +1 -1
  63. package/dist/composed/file-preview/shared.d.ts.map +1 -1
  64. package/dist/composed/file-preview/video-preview.d.ts.map +1 -1
  65. package/dist/composed/file-preview.js +152 -151
  66. package/dist/composed/file-preview.js.map +1 -1
  67. package/dist/composed/filter-bar.d.ts.map +1 -1
  68. package/dist/composed/filter-bar.js +53 -52
  69. package/dist/composed/filter-bar.js.map +1 -1
  70. package/dist/composed/form-section.d.ts.map +1 -1
  71. package/dist/composed/form-section.js +38 -37
  72. package/dist/composed/form-section.js.map +1 -1
  73. package/dist/composed/inline-edit.js +1 -1
  74. package/dist/composed/inline-edit.js.map +1 -1
  75. package/dist/composed/loading-skeleton.js +3 -3
  76. package/dist/composed/loading-skeleton.js.map +1 -1
  77. package/dist/composed/master-detail.d.ts.map +1 -1
  78. package/dist/composed/master-detail.js +1 -1
  79. package/dist/composed/master-detail.js.map +1 -1
  80. package/dist/composed/member-picker.js +1 -1
  81. package/dist/composed/member-picker.js.map +1 -1
  82. package/dist/composed/multi-select-popover.d.ts.map +1 -1
  83. package/dist/composed/multi-select-popover.js +109 -108
  84. package/dist/composed/multi-select-popover.js.map +1 -1
  85. package/dist/composed/page-skeletons.js +4 -4
  86. package/dist/composed/page-skeletons.js.map +1 -1
  87. package/dist/composed/responsive-modal.js +1 -1
  88. package/dist/composed/responsive-modal.js.map +1 -1
  89. package/dist/composed/rich-chat-input/attachment-strip.d.ts.map +1 -1
  90. package/dist/composed/rich-chat-input/reply-banner.d.ts.map +1 -1
  91. package/dist/composed/rich-chat-input/schedule-send.d.ts.map +1 -1
  92. package/dist/composed/rich-chat-input.d.ts.map +1 -1
  93. package/dist/composed/rich-chat-input.js +473 -472
  94. package/dist/composed/rich-chat-input.js.map +1 -1
  95. package/dist/composed/rich-text-editor.js +6 -6
  96. package/dist/composed/rich-text-editor.js.map +1 -1
  97. package/dist/composed/schedule-view.js +5 -5
  98. package/dist/composed/schedule-view.js.map +1 -1
  99. package/dist/composed/status-badge.d.ts.map +1 -1
  100. package/dist/composed/status-badge.js +29 -28
  101. package/dist/composed/status-badge.js.map +1 -1
  102. package/dist/hooks/index.d.ts +1 -0
  103. package/dist/hooks/index.d.ts.map +1 -1
  104. package/dist/hooks/index.js +4 -3
  105. package/dist/hooks/use-container-size.d.ts +18 -0
  106. package/dist/hooks/use-container-size.d.ts.map +1 -0
  107. package/dist/hooks/use-container-size.js +28 -0
  108. package/dist/hooks/use-container-size.js.map +1 -0
  109. package/dist/motion/index.d.ts +1 -0
  110. package/dist/motion/index.d.ts.map +1 -1
  111. package/dist/motion/index.js +2 -15
  112. package/dist/motion/motion-preference.d.ts +36 -0
  113. package/dist/motion/motion-preference.d.ts.map +1 -0
  114. package/dist/motion/motion-provider.d.ts +2 -1
  115. package/dist/motion/motion-provider.d.ts.map +1 -1
  116. package/dist/motion/primitives-index.js +103 -102
  117. package/dist/motion/primitives-index.js.map +1 -1
  118. package/dist/motion/primitives.d.ts.map +1 -1
  119. package/dist/shell/app-shell.d.ts +101 -0
  120. package/dist/shell/app-shell.d.ts.map +1 -0
  121. package/dist/shell/app-shell.js +76 -0
  122. package/dist/shell/app-shell.js.map +1 -0
  123. package/dist/shell/bottom-navbar.js +21 -21
  124. package/dist/shell/bottom-navbar.js.map +1 -1
  125. package/dist/shell/index.d.ts +2 -1
  126. package/dist/shell/index.d.ts.map +1 -1
  127. package/dist/shell/index.js +6 -5
  128. package/dist/shell/notification-center.d.ts +17 -0
  129. package/dist/shell/notification-center.d.ts.map +1 -1
  130. package/dist/shell/notification-center.js +110 -105
  131. package/dist/shell/notification-center.js.map +1 -1
  132. package/dist/shell/notification-preferences.js +1 -1
  133. package/dist/shell/notification-preferences.js.map +1 -1
  134. package/dist/shell/top-bar.js +7 -7
  135. package/dist/shell/top-bar.js.map +1 -1
  136. package/dist/tokens/generate-scale.d.ts +49 -0
  137. package/dist/tokens/generate-scale.d.ts.map +1 -1
  138. package/dist/tokens/index.css +1 -0
  139. package/dist/tokens/palettes.css +292 -0
  140. package/dist/tokens/primitives.css +29 -26
  141. package/dist/tokens/semantic.css +170 -47
  142. package/dist/tokens/shilp-sutra.css +1 -0
  143. package/dist/tokens/utilities.css +10 -7
  144. package/dist/tokens/variants.css +1 -1
  145. package/dist/ui/accordion.d.ts.map +1 -1
  146. package/dist/ui/accordion.js +27 -26
  147. package/dist/ui/accordion.js.map +1 -1
  148. package/dist/ui/alert-dialog.d.ts.map +1 -1
  149. package/dist/ui/alert-dialog.js +60 -59
  150. package/dist/ui/alert-dialog.js.map +1 -1
  151. package/dist/ui/alert.d.ts.map +1 -1
  152. package/dist/ui/alert.js +55 -113
  153. package/dist/ui/alert.js.map +1 -1
  154. package/dist/ui/autocomplete.js +80 -80
  155. package/dist/ui/autocomplete.js.map +1 -1
  156. package/dist/ui/avatar.d.ts.map +1 -1
  157. package/dist/ui/avatar.js +71 -70
  158. package/dist/ui/avatar.js.map +1 -1
  159. package/dist/ui/badge-indicator.d.ts +4 -8
  160. package/dist/ui/badge-indicator.d.ts.map +1 -1
  161. package/dist/ui/badge-indicator.js +3 -8
  162. package/dist/ui/badge-indicator.js.map +1 -1
  163. package/dist/ui/badge.d.ts +55 -34
  164. package/dist/ui/badge.d.ts.map +1 -1
  165. package/dist/ui/banner.d.ts.map +1 -1
  166. package/dist/ui/banner.js +43 -41
  167. package/dist/ui/banner.js.map +1 -1
  168. package/dist/ui/button-group.d.ts.map +1 -1
  169. package/dist/ui/button-group.js +3 -23
  170. package/dist/ui/button-group.js.map +1 -1
  171. package/dist/ui/button.d.ts +10 -1
  172. package/dist/ui/button.d.ts.map +1 -1
  173. package/dist/ui/button.js +79 -212
  174. package/dist/ui/button.js.map +1 -1
  175. package/dist/ui/card.d.ts.map +1 -1
  176. package/dist/ui/card.js +78 -75
  177. package/dist/ui/card.js.map +1 -1
  178. package/dist/ui/charts/radar-chart.d.ts.map +1 -1
  179. package/dist/ui/charts/radar-chart.js +1 -1
  180. package/dist/ui/charts/radar-chart.js.map +1 -1
  181. package/dist/ui/chat/date-separator.d.ts +8 -1
  182. package/dist/ui/chat/date-separator.d.ts.map +1 -1
  183. package/dist/ui/chat/message-list.d.ts.map +1 -1
  184. package/dist/ui/chat/message.d.ts.map +1 -1
  185. package/dist/ui/chat/typing-indicator.d.ts.map +1 -1
  186. package/dist/ui/checkbox.js +1 -1
  187. package/dist/ui/checkbox.js.map +1 -1
  188. package/dist/ui/code.js +2 -2
  189. package/dist/ui/code.js.map +1 -1
  190. package/dist/ui/color-input.d.ts.map +1 -1
  191. package/dist/ui/color-input.js +151 -150
  192. package/dist/ui/color-input.js.map +1 -1
  193. package/dist/ui/combobox.d.ts +14 -0
  194. package/dist/ui/combobox.d.ts.map +1 -1
  195. package/dist/ui/combobox.js +156 -152
  196. package/dist/ui/combobox.js.map +1 -1
  197. package/dist/ui/context-menu.d.ts.map +1 -1
  198. package/dist/ui/context-menu.js +70 -69
  199. package/dist/ui/context-menu.js.map +1 -1
  200. package/dist/ui/data-table-body.d.ts +3 -1
  201. package/dist/ui/data-table-body.d.ts.map +1 -1
  202. package/dist/ui/data-table-body.js +93 -92
  203. package/dist/ui/data-table-body.js.map +1 -1
  204. package/dist/ui/data-table-bulk-actions.d.ts +7 -1
  205. package/dist/ui/data-table-bulk-actions.d.ts.map +1 -1
  206. package/dist/ui/data-table-bulk-actions.js +14 -8
  207. package/dist/ui/data-table-bulk-actions.js.map +1 -1
  208. package/dist/ui/data-table-card.d.ts.map +1 -1
  209. package/dist/ui/data-table-card.js +66 -47
  210. package/dist/ui/data-table-card.js.map +1 -1
  211. package/dist/ui/data-table-context.d.ts +4 -0
  212. package/dist/ui/data-table-context.d.ts.map +1 -1
  213. package/dist/ui/data-table-context.js +2 -2
  214. package/dist/ui/data-table-context.js.map +1 -1
  215. package/dist/ui/data-table-header.d.ts.map +1 -1
  216. package/dist/ui/data-table-header.js +50 -46
  217. package/dist/ui/data-table-header.js.map +1 -1
  218. package/dist/ui/data-table-pagination.js +3 -3
  219. package/dist/ui/data-table-pagination.js.map +1 -1
  220. package/dist/ui/data-table-toolbar.d.ts +11 -1
  221. package/dist/ui/data-table-toolbar.d.ts.map +1 -1
  222. package/dist/ui/data-table-toolbar.js +7 -7
  223. package/dist/ui/data-table-toolbar.js.map +1 -1
  224. package/dist/ui/data-table.d.ts +52 -5
  225. package/dist/ui/data-table.d.ts.map +1 -1
  226. package/dist/ui/data-table.js +181 -169
  227. package/dist/ui/data-table.js.map +1 -1
  228. package/dist/ui/dialog.d.ts.map +1 -1
  229. package/dist/ui/dialog.js +62 -61
  230. package/dist/ui/dialog.js.map +1 -1
  231. package/dist/ui/dot.d.ts.map +1 -1
  232. package/dist/ui/dot.js +10 -41
  233. package/dist/ui/dot.js.map +1 -1
  234. package/dist/ui/dropdown-menu.d.ts.map +1 -1
  235. package/dist/ui/dropdown-menu.js +79 -78
  236. package/dist/ui/dropdown-menu.js.map +1 -1
  237. package/dist/ui/file-upload.d.ts.map +1 -1
  238. package/dist/ui/file-upload.js +117 -116
  239. package/dist/ui/file-upload.js.map +1 -1
  240. package/dist/ui/form.d.ts.map +1 -1
  241. package/dist/ui/form.js +27 -26
  242. package/dist/ui/form.js.map +1 -1
  243. package/dist/ui/hover-card.d.ts.map +1 -1
  244. package/dist/ui/hover-card.js +26 -25
  245. package/dist/ui/hover-card.js.map +1 -1
  246. package/dist/ui/icon.js +7 -7
  247. package/dist/ui/index.d.ts +2 -2
  248. package/dist/ui/index.d.ts.map +1 -1
  249. package/dist/ui/index.js +3 -3
  250. package/dist/ui/index.js.map +1 -1
  251. package/dist/ui/input-otp.js +1 -1
  252. package/dist/ui/input-otp.js.map +1 -1
  253. package/dist/ui/input.js +8 -8
  254. package/dist/ui/input.js.map +1 -1
  255. package/dist/ui/menubar.d.ts.map +1 -1
  256. package/dist/ui/menubar.js +73 -72
  257. package/dist/ui/menubar.js.map +1 -1
  258. package/dist/ui/navigation-menu.d.ts.map +1 -1
  259. package/dist/ui/navigation-menu.js +80 -79
  260. package/dist/ui/navigation-menu.js.map +1 -1
  261. package/dist/ui/number-input.js +3 -3
  262. package/dist/ui/number-input.js.map +1 -1
  263. package/dist/ui/pagination.js +1 -1
  264. package/dist/ui/pagination.js.map +1 -1
  265. package/dist/ui/popover.d.ts.map +1 -1
  266. package/dist/ui/progress-ring.js +2 -2
  267. package/dist/ui/progress-ring.js.map +1 -1
  268. package/dist/ui/progress.d.ts.map +1 -1
  269. package/dist/ui/progress.js +82 -74
  270. package/dist/ui/progress.js.map +1 -1
  271. package/dist/ui/radio.d.ts.map +1 -1
  272. package/dist/ui/radio.js +32 -31
  273. package/dist/ui/radio.js.map +1 -1
  274. package/dist/ui/search-input.d.ts.map +1 -1
  275. package/dist/ui/search-input.js +28 -27
  276. package/dist/ui/search-input.js.map +1 -1
  277. package/dist/ui/select.d.ts.map +1 -1
  278. package/dist/ui/select.js +67 -66
  279. package/dist/ui/select.js.map +1 -1
  280. package/dist/ui/sheet.js +1 -1
  281. package/dist/ui/sheet.js.map +1 -1
  282. package/dist/ui/sidebar.d.ts.map +1 -1
  283. package/dist/ui/sidebar.js +14 -14
  284. package/dist/ui/sidebar.js.map +1 -1
  285. package/dist/ui/slider.d.ts +63 -9
  286. package/dist/ui/slider.d.ts.map +1 -1
  287. package/dist/ui/slider.js +75 -33
  288. package/dist/ui/slider.js.map +1 -1
  289. package/dist/ui/split-button.d.ts +8 -2
  290. package/dist/ui/split-button.d.ts.map +1 -1
  291. package/dist/ui/split-button.js +49 -95
  292. package/dist/ui/split-button.js.map +1 -1
  293. package/dist/ui/stat-card.d.ts.map +1 -1
  294. package/dist/ui/stat-card.js +89 -88
  295. package/dist/ui/stat-card.js.map +1 -1
  296. package/dist/ui/stat-flash.js +16 -16
  297. package/dist/ui/stepper.d.ts.map +1 -1
  298. package/dist/ui/stepper.js +63 -62
  299. package/dist/ui/stepper.js.map +1 -1
  300. package/dist/ui/surface.d.ts.map +1 -1
  301. package/dist/ui/surface.js +2 -2
  302. package/dist/ui/surface.js.map +1 -1
  303. package/dist/ui/switch.js +1 -1
  304. package/dist/ui/switch.js.map +1 -1
  305. package/dist/ui/table.js +3 -3
  306. package/dist/ui/table.js.map +1 -1
  307. package/dist/ui/tabs.d.ts.map +1 -1
  308. package/dist/ui/tabs.js +68 -67
  309. package/dist/ui/tabs.js.map +1 -1
  310. package/dist/ui/textarea.js +5 -5
  311. package/dist/ui/textarea.js.map +1 -1
  312. package/dist/ui/toast.d.ts.map +1 -1
  313. package/dist/ui/toast.js +196 -195
  314. package/dist/ui/toast.js.map +1 -1
  315. package/dist/ui/toggle.d.ts.map +1 -1
  316. package/dist/ui/toggle.js +26 -24
  317. package/dist/ui/toggle.js.map +1 -1
  318. package/dist/ui/tooltip.d.ts.map +1 -1
  319. package/dist/ui/tooltip.js +37 -36
  320. package/dist/ui/tooltip.js.map +1 -1
  321. package/dist/ui/tree-view/tree-item.d.ts.map +1 -1
  322. package/docs/components/composed/avatar-group.md +4 -4
  323. package/docs/components/composed/diff.md +10 -2
  324. package/docs/components/composed/schedule-view.md +1 -1
  325. package/docs/components/shell/app-shell.md +132 -0
  326. package/docs/components/ui/avatar.md +1 -1
  327. package/docs/components/ui/button.md +1 -1
  328. package/docs/components/ui/chat.md +7 -1
  329. package/docs/components/ui/color-swatch.md +1 -1
  330. package/docs/components/ui/data-table-toolbar.md +6 -2
  331. package/docs/components/ui/data-table.md +41 -7
  332. package/docs/components/ui/dot.md +1 -1
  333. package/docs/components/ui/progress.md +1 -0
  334. package/docs/components/ui/surface.md +3 -3
  335. package/docs/components/ui/table.md +2 -2
  336. package/docs/recipes/customize-brand.md +58 -0
  337. package/docs/recipes/install-astro.md +1 -0
  338. package/docs/recipes/install-next-app-router.md +1 -0
  339. package/docs/recipes/install-next-pages.md +22 -1
  340. package/docs/recipes/install-remix.md +1 -0
  341. package/docs/recipes/install-tanstack-start.md +1 -0
  342. package/docs/recipes/install-vite.md +2 -0
  343. package/docs/recipes/server-components.md +7 -4
  344. package/docs/recipes/troubleshoot.md +1 -0
  345. package/llms.txt +2 -1
  346. package/make-kit/Guidelines.md +2 -2
  347. package/make-kit/components/button.md +1 -1
  348. package/make-kit/components/card.md +6 -6
  349. package/make-kit/components/surface.md +4 -4
  350. package/make-kit/foundations/color.md +4 -4
  351. package/make-kit/foundations/dark-mode.md +1 -1
  352. package/make-kit/foundations/radius.md +1 -1
  353. package/make-kit/foundations/surfaces.md +9 -9
  354. package/mcp-manifest.json +358 -35
  355. package/package.json +8 -4
  356. package/skill/SKILL.md +12 -6
  357. package/skill/references/components.md +2 -1
  358. package/skill/references/customize-brand.md +58 -0
  359. package/skill/references/server-components.md +7 -4
  360. package/skill/references/setup-astro.md +1 -0
  361. package/skill/references/setup-next-app-router.md +1 -0
  362. package/skill/references/setup-next-pages.md +22 -1
  363. package/skill/references/setup-remix.md +1 -0
  364. package/skill/references/setup-tanstack-start.md +1 -0
  365. package/skill/references/setup-vite.md +2 -0
  366. package/skill/references/troubleshoot.md +1 -0
  367. package/dist/motion/check-motion-provider.d.ts +0 -2
  368. package/dist/motion/check-motion-provider.d.ts.map +0 -1
  369. package/dist/motion/index.js.map +0 -1
  370. package/dist/primitives/react-toast.d.ts +0 -120
  371. package/dist/ui/charts/_internal/scales.d.ts +0 -5
  372. package/dist/ui/charts/_internal/scales.d.ts.map +0 -1
  373. package/dist/ui/lib/slot.d.ts +0 -8
  374. package/dist/ui/lib/slot.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"loading-skeleton.js","names":[],"sources":["../../src/composed/loading-skeleton.tsx"],"sourcesContent":["// @server-safe\nimport * as React from 'react'\n\nimport { cn } from '../ui/lib/utils'\nimport { Skeleton } from '../ui/skeleton'\n\n// Non-negative integer count (guards Array.from against NaN / negatives → RangeError).\nconst clamp = (n: number | undefined, fallback: number) =>\n Math.max(0, Math.floor(typeof n === 'number' && !Number.isNaN(n) ? n : fallback))\n\n// role=status + aria-busy so AT announces the loading region (child Skeletons are\n// aria-hidden). sr-only label gives the announcement text.\nfunction statusProps(label?: string) {\n return { role: 'status' as const, 'aria-busy': true, 'aria-label': label ?? 'Loading' }\n}\nfunction SrLabel({ label }: { label?: string }) {\n return <span className=\"sr-only\">{label ?? 'Loading'}…</span>\n}\n\nexport interface CardSkeletonProps extends React.ComponentPropsWithoutRef<'div'> {\n className?: string\n /** Accessible label for the loading region. @default 'Loading' */\n label?: string\n}\n\nconst CardSkeleton = React.forwardRef<HTMLDivElement, CardSkeletonProps>(\n function CardSkeleton({ className, label, ...props }, ref) {\n return (\n <div\n ref={ref}\n {...statusProps(label)}\n {...props}\n className={cn('rounded-surface border border-card bg-surface-raised p-ds-05b', className)}\n >\n <SrLabel label={label} />\n <div className=\"flex items-center justify-between pb-ds-05\">\n <Skeleton className=\"h-ds-05 w-ds-13\" />\n <Skeleton className=\"h-ico-sm w-ico-sm rounded\" />\n </div>\n <div className=\"space-y-ds-04\">\n <Skeleton className=\"h-ds-04 w-full\" />\n <Skeleton className=\"h-ds-04 w-4/5\" />\n <Skeleton className=\"h-ds-04 w-3/5\" />\n </div>\n <div className=\"flex items-center gap-ds-03 pt-ds-05\">\n <Skeleton className=\"h-ds-xs w-ds-xs rounded-pill\" />\n <Skeleton className=\"h-ds-04 w-ds-11\" />\n </div>\n </div>\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({ rows = 5, columns = 4, className, label, ...props }, ref) {\n const r = clamp(rows, 5)\n const c = Math.max(1, clamp(columns, 4))\n return (\n <div\n ref={ref}\n {...statusProps(label)}\n {...props}\n className={cn('overflow-hidden rounded-surface border border-card', className)}\n >\n <SrLabel label={label} />\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: c }).map((_, i) => (\n <Skeleton key={`head-${i}`} className={cn('h-ds-04', i === 0 ? 'w-ds-13' : 'flex-1')} />\n ))}\n </div>\n {/* Rows */}\n {Array.from({ length: r }).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 < r - 1 && 'border-b border-surface-border-strong',\n )}\n >\n {Array.from({ length: c }).map((_, colIndex) => (\n <Skeleton\n key={`cell-${rowIndex}-${colIndex}`}\n className={cn('h-ds-04', colIndex === 0 ? 'w-ds-13' : 'flex-1')}\n />\n ))}\n </div>\n ))}\n </div>\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({ columns = 4, cardsPerColumn = 3, className, label, ...props }, ref) {\n const c = clamp(columns, 4)\n const cards = clamp(cardsPerColumn, 3)\n return (\n <div ref={ref} {...statusProps(label)} {...props} className={cn('flex gap-ds-05 overflow-x-auto', className)}>\n <SrLabel label={label} />\n {Array.from({ length: c }).map((_, colIndex) => (\n <div key={`col-${colIndex}`} className=\"flex w-[272px] shrink-0 flex-col gap-ds-03\">\n {/* Column header */}\n <div className=\"flex items-center justify-between px-ds-02 py-ds-03\">\n <div className=\"flex items-center gap-ds-03\">\n <Skeleton className=\"h-ds-04 w-ds-04 rounded\" />\n <Skeleton className=\"h-ds-04 w-ds-11\" />\n <Skeleton className=\"h-ds-05 w-ds-05b rounded-pill\" />\n </div>\n <Skeleton className=\"h-ico-sm w-ico-sm rounded\" />\n </div>\n {/* Column cards */}\n {Array.from({ length: cards }).map((_, cardIndex) => (\n <div\n key={`card-${colIndex}-${cardIndex}`}\n className=\"rounded-surface border border-card bg-surface-raised p-ds-04\"\n >\n <div className=\"space-y-ds-03\">\n <Skeleton className=\"h-ds-04 w-4/5\" />\n <Skeleton className=\"h-ds-04 w-3/5\" />\n </div>\n <div className=\"flex items-center justify-between pt-ds-04\">\n <div className=\"flex items-center gap-ds-02b\">\n <Skeleton className=\"h-ico-md w-ico-md rounded-pill\" />\n <Skeleton className=\"h-ds-03 w-ds-10\" />\n </div>\n <Skeleton className=\"h-ds-05 w-ds-lg rounded-pill\" />\n </div>\n </div>\n ))}\n </div>\n ))}\n </div>\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({ rows = 6, showAvatar = true, className, label, ...props }, ref) {\n const r = clamp(rows, 6)\n return (\n <div ref={ref} {...statusProps(label)} {...props} className={cn('flex flex-col', className)}>\n <SrLabel label={label} />\n {Array.from({ length: r }).map((_, i) => (\n <div\n key={`list-${i}`}\n className={cn(\n 'flex items-center gap-ds-04 py-ds-04',\n i < r - 1 && 'border-b border-surface-border-strong',\n )}\n >\n {showAvatar && <Skeleton className=\"h-ds-sm w-ds-sm shrink-0 rounded-pill\" />}\n <div className=\"flex flex-1 flex-col gap-ds-02b\">\n <Skeleton className=\"h-ds-04 w-2/5\" />\n <Skeleton className=\"h-ds-03 w-3/5\" />\n </div>\n <Skeleton className=\"h-ds-05b w-ds-09 rounded-pill\" />\n </div>\n ))}\n </div>\n )\n },\n)\nListSkeleton.displayName = 'ListSkeleton'\n\nexport { BoardSkeleton, CardSkeleton, ListSkeleton, TableSkeleton }\n"],"mappings":"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"}
1
+ {"version":3,"file":"loading-skeleton.js","names":[],"sources":["../../src/composed/loading-skeleton.tsx"],"sourcesContent":["// @server-safe\nimport * as React from 'react'\n\nimport { cn } from '../ui/lib/utils'\nimport { Skeleton } from '../ui/skeleton'\n\n// Non-negative integer count (guards Array.from against NaN / negatives → RangeError).\nconst clamp = (n: number | undefined, fallback: number) =>\n Math.max(0, Math.floor(typeof n === 'number' && !Number.isNaN(n) ? n : fallback))\n\n// role=status + aria-busy so AT announces the loading region (child Skeletons are\n// aria-hidden). sr-only label gives the announcement text.\nfunction statusProps(label?: string) {\n return { role: 'status' as const, 'aria-busy': true, 'aria-label': label ?? 'Loading' }\n}\nfunction SrLabel({ label }: { label?: string }) {\n return <span className=\"sr-only\">{label ?? 'Loading'}…</span>\n}\n\nexport interface CardSkeletonProps extends React.ComponentPropsWithoutRef<'div'> {\n className?: string\n /** Accessible label for the loading region. @default 'Loading' */\n label?: string\n}\n\nconst CardSkeleton = React.forwardRef<HTMLDivElement, CardSkeletonProps>(\n function CardSkeleton({ className, label, ...props }, ref) {\n return (\n <div\n ref={ref}\n {...statusProps(label)}\n {...props}\n className={cn('rounded-surface border border-card bg-surface-panel p-ds-05b', className)}\n >\n <SrLabel label={label} />\n <div className=\"flex items-center justify-between pb-ds-05\">\n <Skeleton className=\"h-ds-05 w-ds-13\" />\n <Skeleton className=\"h-ico-sm w-ico-sm rounded\" />\n </div>\n <div className=\"space-y-ds-04\">\n <Skeleton className=\"h-ds-04 w-full\" />\n <Skeleton className=\"h-ds-04 w-4/5\" />\n <Skeleton className=\"h-ds-04 w-3/5\" />\n </div>\n <div className=\"flex items-center gap-ds-03 pt-ds-05\">\n <Skeleton className=\"h-ds-xs w-ds-xs rounded-pill\" />\n <Skeleton className=\"h-ds-04 w-ds-11\" />\n </div>\n </div>\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({ rows = 5, columns = 4, className, label, ...props }, ref) {\n const r = clamp(rows, 5)\n const c = Math.max(1, clamp(columns, 4))\n return (\n <div\n ref={ref}\n {...statusProps(label)}\n {...props}\n className={cn('overflow-hidden rounded-surface border border-card', className)}\n >\n <SrLabel label={label} />\n {/* Header */}\n <div className=\"flex items-center gap-ds-05 border-b border-surface-border-strong bg-surface-panel px-ds-05 py-ds-04\">\n {Array.from({ length: c }).map((_, i) => (\n <Skeleton key={`head-${i}`} className={cn('h-ds-04', i === 0 ? 'w-ds-13' : 'flex-1')} />\n ))}\n </div>\n {/* Rows */}\n {Array.from({ length: r }).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 < r - 1 && 'border-b border-surface-border-strong',\n )}\n >\n {Array.from({ length: c }).map((_, colIndex) => (\n <Skeleton\n key={`cell-${rowIndex}-${colIndex}`}\n className={cn('h-ds-04', colIndex === 0 ? 'w-ds-13' : 'flex-1')}\n />\n ))}\n </div>\n ))}\n </div>\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({ columns = 4, cardsPerColumn = 3, className, label, ...props }, ref) {\n const c = clamp(columns, 4)\n const cards = clamp(cardsPerColumn, 3)\n return (\n <div ref={ref} {...statusProps(label)} {...props} className={cn('flex gap-ds-05 overflow-x-auto', className)}>\n <SrLabel label={label} />\n {Array.from({ length: c }).map((_, colIndex) => (\n <div key={`col-${colIndex}`} className=\"flex w-[272px] shrink-0 flex-col gap-ds-03\">\n {/* Column header */}\n <div className=\"flex items-center justify-between px-ds-02 py-ds-03\">\n <div className=\"flex items-center gap-ds-03\">\n <Skeleton className=\"h-ds-04 w-ds-04 rounded\" />\n <Skeleton className=\"h-ds-04 w-ds-11\" />\n <Skeleton className=\"h-ds-05 w-ds-05b rounded-pill\" />\n </div>\n <Skeleton className=\"h-ico-sm w-ico-sm rounded\" />\n </div>\n {/* Column cards */}\n {Array.from({ length: cards }).map((_, cardIndex) => (\n <div\n key={`card-${colIndex}-${cardIndex}`}\n className=\"rounded-surface border border-card bg-surface-panel p-ds-04\"\n >\n <div className=\"space-y-ds-03\">\n <Skeleton className=\"h-ds-04 w-4/5\" />\n <Skeleton className=\"h-ds-04 w-3/5\" />\n </div>\n <div className=\"flex items-center justify-between pt-ds-04\">\n <div className=\"flex items-center gap-ds-02b\">\n <Skeleton className=\"h-ico-md w-ico-md rounded-pill\" />\n <Skeleton className=\"h-ds-03 w-ds-10\" />\n </div>\n <Skeleton className=\"h-ds-05 w-ds-lg rounded-pill\" />\n </div>\n </div>\n ))}\n </div>\n ))}\n </div>\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({ rows = 6, showAvatar = true, className, label, ...props }, ref) {\n const r = clamp(rows, 6)\n return (\n <div ref={ref} {...statusProps(label)} {...props} className={cn('flex flex-col', className)}>\n <SrLabel label={label} />\n {Array.from({ length: r }).map((_, i) => (\n <div\n key={`list-${i}`}\n className={cn(\n 'flex items-center gap-ds-04 py-ds-04',\n i < r - 1 && 'border-b border-surface-border-strong',\n )}\n >\n {showAvatar && <Skeleton className=\"h-ds-sm w-ds-sm shrink-0 rounded-pill\" />}\n <div className=\"flex flex-1 flex-col gap-ds-02b\">\n <Skeleton className=\"h-ds-04 w-2/5\" />\n <Skeleton className=\"h-ds-03 w-3/5\" />\n </div>\n <Skeleton className=\"h-ds-05b w-ds-09 rounded-pill\" />\n </div>\n ))}\n </div>\n )\n },\n)\nListSkeleton.displayName = 'ListSkeleton'\n\nexport { BoardSkeleton, CardSkeleton, ListSkeleton, TableSkeleton }\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"master-detail.d.ts","sourceRoot":"","sources":["../../src/composed/master-detail.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAO9B;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAEf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAC9D,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,sCAAsC;IACtC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mEAAmE;IACnE,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IAC/B,mEAAmE;IACnE,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC5B,+EAA+E;IAC/E,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,CAAA;CAChD;AAED,UAAU,qBAAsB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;CAAG;AAC/E,UAAU,uBAAwB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;CAAG;AACjF,UAAU,yBAA0B,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IACvF,8EAA8E;IAC9E,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AA6CD,iBAAS,gBAAgB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,qBAAqB,4BA2D1G;AAED,iBAAS,kBAAkB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,uBAAuB,4BA4BrF;AA4CD,iBAAS,gBAAgB,CAAC,EACxB,QAAQ,EACR,eAAsB,EACtB,QAAQ,EACR,KAAe,EACf,MAAM,EACN,WAAqB,EACrB,UAAiB,EACjB,UAAU,EACV,UAAU,EACV,QAAQ,EACR,SAAS,EACT,KAAK,EACL,GAAG,KAAK,EACT,EAAE,iBAAiB,qBAmCnB;AAED,QAAA,MAAM,YAAY;;;;CAIhB,CAAA;AAEF,OAAO,EAAE,YAAY,EAAE,CAAA;AACvB,YAAY,EAAE,yBAAyB,EAAE,CAAA"}
1
+ {"version":3,"file":"master-detail.d.ts","sourceRoot":"","sources":["../../src/composed/master-detail.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAO9B;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAEf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAC9D,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,sCAAsC;IACtC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mEAAmE;IACnE,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IAC/B,mEAAmE;IACnE,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC5B,+EAA+E;IAC/E,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,CAAA;CAChD;AAED,UAAU,qBAAsB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;CAAG;AAC/E,UAAU,uBAAwB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;CAAG;AACjF,UAAU,yBAA0B,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IACvF,8EAA8E;IAC9E,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AA6CD,iBAAS,gBAAgB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,qBAAqB,4BA2D1G;AAED,iBAAS,kBAAkB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,uBAAuB,4BA4BrF;AAgDD,iBAAS,gBAAgB,CAAC,EACxB,QAAQ,EACR,eAAsB,EACtB,QAAQ,EACR,KAAe,EACf,MAAM,EACN,WAAqB,EACrB,UAAiB,EACjB,UAAU,EACV,UAAU,EACV,QAAQ,EACR,SAAS,EACT,KAAK,EACL,GAAG,KAAK,EACT,EAAE,iBAAiB,qBAmCnB;AAED,QAAA,MAAM,YAAY;;;;CAIhB,CAAA;AAEF,OAAO,EAAE,YAAY,EAAE,CAAA;AACvB,YAAY,EAAE,yBAAyB,EAAE,CAAA"}
@@ -134,7 +134,7 @@ var _ = i.forwardRef(function({ active: e, value: n, children: r, className: o,
134
134
  "data-active": m || void 0,
135
135
  onKeyDown: h,
136
136
  onClick: g,
137
- className: t("flex w-full items-center px-ds-04 py-ds-03 text-left text-body-md font-sans text-surface-fg", "transition-colors duration-fast-01 ease-productive-standard", "hover:bg-surface-raised-hover", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-7 focus-visible:ring-inset", m && "bg-accent-2 text-accent-11 font-medium", o),
137
+ className: t("flex w-full items-center px-ds-04 py-ds-03 text-left text-body-md font-sans text-surface-fg", "transition-colors duration-fast-01 ease-productive-standard", "hover:bg-surface-panel-hover", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-7 focus-visible:ring-inset", m && "bg-accent-4 text-accent-11 font-medium", o),
138
138
  ...l,
139
139
  children: r
140
140
  });
@@ -1 +1 @@
1
- {"version":3,"file":"master-detail.js","names":[],"sources":["../../src/composed/master-detail.tsx"],"sourcesContent":["'use client'\n\nimport { IconArrowLeft } from '@tabler/icons-react'\nimport { AnimatePresence, motion, useReducedMotion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { Button } from '../ui/button'\nimport { Icon } from '../ui/icon'\nimport { springs } from '../ui/lib/motion'\nimport { cn } from '../ui/lib/utils'\n\n/**\n * A responsive master-detail layout. Desktop: fixed-width list panel + detail\n * panel. Below the breakpoint: stacked view with a back button. The list is an\n * ARIA `listbox` with roving keyboard nav (Arrow/Home/End + Enter/Space).\n *\n * Selection can be **controlled** (`selected`) or **owned** by the component\n * (`defaultSelected` + `onSelect`, deriving each row's active state from its\n * `value` — no hand-wiring `active` + `onClick` per row).\n */\nexport interface MasterDetailProps\n // Replaces the rarely-used native text-selection `onSelect` with our row-select callback.\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'> {\n /** Controlled selected item id. `null` = no selection. Omit for uncontrolled. */\n selected?: string | null\n /** Uncontrolled initial selection. */\n defaultSelected?: string | null\n /** Called with a row's `value` when it's chosen (click or Enter/Space). */\n onSelect?: (value: string) => void\n /** Accessible name for the list (the `listbox`). @default 'Items' */\n label?: string\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 the user presses ArrowUp/ArrowDown while the list has focus. */\n onNavigate?: (direction: 'up' | 'down') => void\n}\n\ninterface MasterDetailListProps extends React.HTMLAttributes<HTMLDivElement> {}\ninterface MasterDetailDetailProps extends React.HTMLAttributes<HTMLDivElement> {}\ninterface MasterDetailListItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Explicit active state. Omit to derive from `value` === the selected id. */\n active?: boolean\n /** Row id — enables derived selection + auto-fires `onSelect` on activate. */\n value?: string\n}\n\nconst breakpoints: Record<string, string> = { sm: '640px', md: '768px', lg: '1024px' }\n\nfunction useMediaQuery(query: string): boolean {\n const [matches, setMatches] = React.useState(false)\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 return matches\n}\n\ninterface MasterDetailContextValue {\n selected: string | null\n onSelect?: (value: string) => void\n label: string\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}\n\nconst MasterDetailContext = React.createContext<MasterDetailContextValue>({\n selected: null,\n label: 'Items',\n isMobile: false,\n activeIndex: 0,\n setActiveIndex: () => {},\n registerItemRef: () => {},\n})\n\nfunction itemIsActive(child: React.ReactNode, selected: string | null): boolean {\n if (!React.isValidElement(child)) return false\n const p = child.props as { active?: boolean; value?: string }\n return p.active ?? (p.value != null && p.value === selected)\n}\n\nfunction MasterDetailList({ children, className, 'aria-label': ariaLabel, ...props }: MasterDetailListProps) {\n const { selected, label, isMobile, onNavigate, activeIndex, setActiveIndex, registerItemRef } =\n React.useContext(MasterDetailContext)\n const itemRefsLocal = React.useRef<(HTMLButtonElement | null)[]>([])\n const childCount = React.Children.count(children)\n\n // Roving focus starts on the active/selected row (derived from `active` or `value`).\n const activeChildIndex = React.useMemo(() => {\n let idx = -1\n React.Children.forEach(children, (child, i) => {\n if (itemIsActive(child, selected)) idx = i\n })\n return idx\n }, [children, selected])\n React.useEffect(() => {\n if (activeChildIndex >= 0) setActiveIndex(activeChildIndex)\n }, [activeChildIndex, setActiveIndex])\n\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); itemRefsLocal.current[next]?.focus(); onNavigate?.('down')\n } else if (e.key === 'ArrowUp') {\n e.preventDefault()\n const prev = Math.max(activeIndex - 1, 0)\n setActiveIndex(prev); itemRefsLocal.current[prev]?.focus(); onNavigate?.('up')\n } else if (e.key === 'Home') {\n e.preventDefault(); setActiveIndex(0); itemRefsLocal.current[0]?.focus()\n } else if (e.key === 'End') {\n e.preventDefault()\n const last = childCount - 1\n setActiveIndex(last); itemRefsLocal.current[last]?.focus()\n }\n }\n\n return (\n <div\n role=\"listbox\"\n aria-label={ariaLabel ?? label}\n tabIndex={-1}\n className={cn('overflow-y-auto focus-visible:outline-hidden', !isMobile && 'border-e border-surface-border', className)}\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 const reduced = useReducedMotion()\n if (isMobile && !selected) return null\n\n return (\n // aria-live so AT users are told the detail changed when the selection swaps.\n <div role=\"region\" aria-label=\"Detail\" aria-live=\"polite\" 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} className=\"rtl:-scale-x-100\" />}>\n Back\n </Button>\n </div>\n )}\n <AnimatePresence mode=\"wait\">\n <motion.div\n key={selected ?? 'empty'}\n initial={isMobile && !reduced ? { x: 20, opacity: 0 } : false}\n animate={{ x: 0, opacity: 1 }}\n exit={isMobile && !reduced ? { x: -20, opacity: 0 } : undefined}\n transition={reduced ? { duration: 0 } : 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, value, children, className, onKeyDown, onClick, ...props }, ref) {\n const { selected, onSelect } = React.useContext(MasterDetailContext)\n const isActive = active ?? (value != null && value === selected)\n\n function handleKeyDown(e: React.KeyboardEvent<HTMLButtonElement>) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n ;(e.currentTarget as HTMLButtonElement).click()\n }\n onKeyDown?.(e)\n }\n function handleClick(e: React.MouseEvent<HTMLButtonElement>) {\n if (value != null) onSelect?.(value)\n onClick?.(e)\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n data-active={isActive || undefined}\n onKeyDown={handleKeyDown}\n onClick={handleClick}\n className={cn(\n 'flex w-full items-center px-ds-04 py-ds-03 text-left text-body-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 isActive && 'bg-accent-2 text-accent-11 font-medium',\n className,\n )}\n {...props}\n >\n {children}\n </button>\n )\n },\n)\n\nfunction MasterDetailRoot({\n selected,\n defaultSelected = null,\n onSelect,\n label = 'Items',\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 itemRefs = React.useRef<(HTMLButtonElement | null)[]>([])\n\n // Controlled when `selected` is provided; otherwise own the selection.\n const isControlled = selected !== undefined\n const [internalSelected, setInternalSelected] = React.useState<string | null>(defaultSelected)\n const resolvedSelected = isControlled ? selected ?? null : internalSelected\n\n const handleSelect = React.useCallback(\n (value: string) => {\n if (!isControlled) setInternalSelected(value)\n onSelect?.(value)\n },\n [isControlled, onSelect],\n )\n\n const registerItemRef = React.useCallback((index: number, el: HTMLButtonElement | null) => {\n itemRefs.current[index] = el\n }, [])\n\n return (\n <MasterDetailContext.Provider\n value={{ selected: resolvedSelected, onSelect: handleSelect, label, isMobile, onBack, emptyState, onNavigate, activeIndex, setActiveIndex, registerItemRef }}\n >\n <div\n className={cn('flex h-full', !isMobile && 'grid', className)}\n style={{ ...style, ...(isMobile ? {} : { gridTemplateColumns: `${masterWidth} 1fr` }) }}\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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"}
1
+ {"version":3,"file":"master-detail.js","names":[],"sources":["../../src/composed/master-detail.tsx"],"sourcesContent":["'use client'\n\nimport { IconArrowLeft } from '@tabler/icons-react'\nimport { AnimatePresence, motion, useReducedMotion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { Button } from '../ui/button'\nimport { Icon } from '../ui/icon'\nimport { springs } from '../ui/lib/motion'\nimport { cn } from '../ui/lib/utils'\n\n/**\n * A responsive master-detail layout. Desktop: fixed-width list panel + detail\n * panel. Below the breakpoint: stacked view with a back button. The list is an\n * ARIA `listbox` with roving keyboard nav (Arrow/Home/End + Enter/Space).\n *\n * Selection can be **controlled** (`selected`) or **owned** by the component\n * (`defaultSelected` + `onSelect`, deriving each row's active state from its\n * `value` — no hand-wiring `active` + `onClick` per row).\n */\nexport interface MasterDetailProps\n // Replaces the rarely-used native text-selection `onSelect` with our row-select callback.\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'> {\n /** Controlled selected item id. `null` = no selection. Omit for uncontrolled. */\n selected?: string | null\n /** Uncontrolled initial selection. */\n defaultSelected?: string | null\n /** Called with a row's `value` when it's chosen (click or Enter/Space). */\n onSelect?: (value: string) => void\n /** Accessible name for the list (the `listbox`). @default 'Items' */\n label?: string\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 the user presses ArrowUp/ArrowDown while the list has focus. */\n onNavigate?: (direction: 'up' | 'down') => void\n}\n\ninterface MasterDetailListProps extends React.HTMLAttributes<HTMLDivElement> {}\ninterface MasterDetailDetailProps extends React.HTMLAttributes<HTMLDivElement> {}\ninterface MasterDetailListItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Explicit active state. Omit to derive from `value` === the selected id. */\n active?: boolean\n /** Row id — enables derived selection + auto-fires `onSelect` on activate. */\n value?: string\n}\n\nconst breakpoints: Record<string, string> = { sm: '640px', md: '768px', lg: '1024px' }\n\nfunction useMediaQuery(query: string): boolean {\n const [matches, setMatches] = React.useState(false)\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 return matches\n}\n\ninterface MasterDetailContextValue {\n selected: string | null\n onSelect?: (value: string) => void\n label: string\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}\n\nconst MasterDetailContext = React.createContext<MasterDetailContextValue>({\n selected: null,\n label: 'Items',\n isMobile: false,\n activeIndex: 0,\n setActiveIndex: () => {},\n registerItemRef: () => {},\n})\n\nfunction itemIsActive(child: React.ReactNode, selected: string | null): boolean {\n if (!React.isValidElement(child)) return false\n const p = child.props as { active?: boolean; value?: string }\n return p.active ?? (p.value != null && p.value === selected)\n}\n\nfunction MasterDetailList({ children, className, 'aria-label': ariaLabel, ...props }: MasterDetailListProps) {\n const { selected, label, isMobile, onNavigate, activeIndex, setActiveIndex, registerItemRef } =\n React.useContext(MasterDetailContext)\n const itemRefsLocal = React.useRef<(HTMLButtonElement | null)[]>([])\n const childCount = React.Children.count(children)\n\n // Roving focus starts on the active/selected row (derived from `active` or `value`).\n const activeChildIndex = React.useMemo(() => {\n let idx = -1\n React.Children.forEach(children, (child, i) => {\n if (itemIsActive(child, selected)) idx = i\n })\n return idx\n }, [children, selected])\n React.useEffect(() => {\n if (activeChildIndex >= 0) setActiveIndex(activeChildIndex)\n }, [activeChildIndex, setActiveIndex])\n\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); itemRefsLocal.current[next]?.focus(); onNavigate?.('down')\n } else if (e.key === 'ArrowUp') {\n e.preventDefault()\n const prev = Math.max(activeIndex - 1, 0)\n setActiveIndex(prev); itemRefsLocal.current[prev]?.focus(); onNavigate?.('up')\n } else if (e.key === 'Home') {\n e.preventDefault(); setActiveIndex(0); itemRefsLocal.current[0]?.focus()\n } else if (e.key === 'End') {\n e.preventDefault()\n const last = childCount - 1\n setActiveIndex(last); itemRefsLocal.current[last]?.focus()\n }\n }\n\n return (\n <div\n role=\"listbox\"\n aria-label={ariaLabel ?? label}\n tabIndex={-1}\n className={cn('overflow-y-auto focus-visible:outline-hidden', !isMobile && 'border-e border-surface-border', className)}\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 const reduced = useReducedMotion()\n if (isMobile && !selected) return null\n\n return (\n // aria-live so AT users are told the detail changed when the selection swaps.\n <div role=\"region\" aria-label=\"Detail\" aria-live=\"polite\" 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} className=\"rtl:-scale-x-100\" />}>\n Back\n </Button>\n </div>\n )}\n <AnimatePresence mode=\"wait\">\n <motion.div\n key={selected ?? 'empty'}\n initial={isMobile && !reduced ? { x: 20, opacity: 0 } : false}\n animate={{ x: 0, opacity: 1 }}\n exit={isMobile && !reduced ? { x: -20, opacity: 0 } : undefined}\n transition={reduced ? { duration: 0 } : 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, value, children, className, onKeyDown, onClick, ...props }, ref) {\n const { selected, onSelect } = React.useContext(MasterDetailContext)\n const isActive = active ?? (value != null && value === selected)\n\n function handleKeyDown(e: React.KeyboardEvent<HTMLButtonElement>) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n ;(e.currentTarget as HTMLButtonElement).click()\n }\n onKeyDown?.(e)\n }\n function handleClick(e: React.MouseEvent<HTMLButtonElement>) {\n if (value != null) onSelect?.(value)\n onClick?.(e)\n }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n data-active={isActive || undefined}\n onKeyDown={handleKeyDown}\n onClick={handleClick}\n className={cn(\n 'flex w-full items-center px-ds-04 py-ds-03 text-left text-body-md font-sans text-surface-fg',\n 'transition-colors duration-fast-01 ease-productive-standard',\n 'hover:bg-surface-panel-hover',\n 'focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-7 focus-visible:ring-inset',\n // accent-4, not accent-2: in dark the pale steps sit BELOW the panel\n // while the grey hover sits above it, so a merely hovered row read\n // stronger than the selected one (1.03:1 vs 1.30:1) and in the\n // opposite direction.\n isActive && 'bg-accent-4 text-accent-11 font-medium',\n className,\n )}\n {...props}\n >\n {children}\n </button>\n )\n },\n)\n\nfunction MasterDetailRoot({\n selected,\n defaultSelected = null,\n onSelect,\n label = 'Items',\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 itemRefs = React.useRef<(HTMLButtonElement | null)[]>([])\n\n // Controlled when `selected` is provided; otherwise own the selection.\n const isControlled = selected !== undefined\n const [internalSelected, setInternalSelected] = React.useState<string | null>(defaultSelected)\n const resolvedSelected = isControlled ? selected ?? null : internalSelected\n\n const handleSelect = React.useCallback(\n (value: string) => {\n if (!isControlled) setInternalSelected(value)\n onSelect?.(value)\n },\n [isControlled, onSelect],\n )\n\n const registerItemRef = React.useCallback((index: number, el: HTMLButtonElement | null) => {\n itemRefs.current[index] = el\n }, [])\n\n return (\n <MasterDetailContext.Provider\n value={{ selected: resolvedSelected, onSelect: handleSelect, label, isMobile, onBack, emptyState, onNavigate, activeIndex, setActiveIndex, registerItemRef }}\n >\n <div\n className={cn('flex h-full', !isMobile && 'grid', className)}\n style={{ ...style, ...(isMobile ? {} : { gridTemplateColumns: `${masterWidth} 1fr` }) }}\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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"}
@@ -30,7 +30,7 @@ var c = a.forwardRef(({ members: c, selectedIds: l, onSelect: u, children: d, mu
30
30
  src: i.image,
31
31
  alt: i.label
32
32
  }), /* @__PURE__ */ o(t, {
33
- className: "bg-surface-raised-hover text-body-xs font-semibold text-surface-fg",
33
+ className: "bg-surface-panel-hover text-body-xs font-semibold text-surface-fg",
34
34
  children: r(i.label)
35
35
  })]
36
36
  }), /* @__PURE__ */ o("span", {
@@ -1 +1 @@
1
- {"version":3,"file":"member-picker.js","names":[],"sources":["../../src/composed/member-picker.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\n\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '../ui/avatar'\nimport { getInitials } from './lib/string-utils'\nimport { type MultiSelectItem,MultiSelectPopover } from './multi-select-popover'\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-body-xs font-semibold text-surface-fg\">\n {getInitials(item.label)}\n </AvatarFallback>\n </Avatar>\n <span className=\"flex-1 truncate text-body-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":";;;;;;;AAmCA,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;CAAO,EAAE,GACvE,CAAC,CAAO,CACV;CAEA,SAAS,EAAa,GAAe;EAEnC,IAAM,IAAQ,EAAI,MAAM,MAAO,CAAC,EAAY,SAAS,CAAE,CAAC,GAClD,IAAU,EAAY,MAAM,MAAO,CAAC,EAAI,SAAS,CAAE,CAAC,GACpD,IAAU,KAAS;EACzB,AAAI,KAAS,EAAS,CAAO;CAC/B;CAEA,OACE,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;IAAQ,CAAA,GAC/D,kBAAC,GAAD;KAAgB,WAAU;eACvB,EAAY,EAAK,KAAK;IACT,CAAA,CACV;OACR,kBAAC,QAAD;IAAM,WAAU;cACb,EAAK;GACF,CAAA,CACH;;EAEP,GAAI;EAEH;CACiB,CAAA;AAExB,CACF;AAEA,EAAa,cAAc"}
1
+ {"version":3,"file":"member-picker.js","names":[],"sources":["../../src/composed/member-picker.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\n\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '../ui/avatar'\nimport { getInitials } from './lib/string-utils'\nimport { type MultiSelectItem,MultiSelectPopover } from './multi-select-popover'\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-panel-hover text-body-xs font-semibold text-surface-fg\">\n {getInitials(item.label)}\n </AvatarFallback>\n </Avatar>\n <span className=\"flex-1 truncate text-body-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":";;;;;;;AAmCA,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;CAAO,EAAE,GACvE,CAAC,CAAO,CACV;CAEA,SAAS,EAAa,GAAe;EAEnC,IAAM,IAAQ,EAAI,MAAM,MAAO,CAAC,EAAY,SAAS,CAAE,CAAC,GAClD,IAAU,EAAY,MAAM,MAAO,CAAC,EAAI,SAAS,CAAE,CAAC,GACpD,IAAU,KAAS;EACzB,AAAI,KAAS,EAAS,CAAO;CAC/B;CAEA,OACE,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;IAAQ,CAAA,GAC/D,kBAAC,GAAD;KAAgB,WAAU;eACvB,EAAY,EAAK,KAAK;IACT,CAAA,CACV;OACR,kBAAC,QAAD;IAAM,WAAU;cACb,EAAK;GACF,CAAA,CACH;;EAEP,GAAI;EAEH;CACiB,CAAA;AAExB,CACF;AAEA,EAAa,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"multi-select-popover.d.ts","sourceRoot":"","sources":["../../src/composed/multi-select-popover.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAgB9B,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"}
1
+ {"version":3,"file":"multi-select-popover.d.ts","sourceRoot":"","sources":["../../src/composed/multi-select-popover.tsx"],"names":[],"mappings":"AAIA,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,gGAmPvB,CAAA;AAGD,OAAO,EAAE,kBAAkB,EAAE,CAAA"}
@@ -1,92 +1,93 @@
1
1
  "use client";
2
2
  import { springs as e } from "../ui/lib/motion.js";
3
- import { cn as t } from "../ui/lib/utils.js";
4
- import { Spinner as n } from "../ui/spinner.js";
5
- import { Icon as r } from "../ui/icon.js";
6
- import { Popover as i, PopoverContent as a, PopoverTrigger as o } from "../_chunks/popover.js";
7
- import * as s from "react";
8
- import { Fragment as c, jsx as l, jsxs as u } from "react/jsx-runtime";
9
- import { IconCheck as d, IconSearch as f } from "@tabler/icons-react";
10
- import { motion as p } from "framer-motion";
3
+ import { MotionPreference as t } from "../_chunks/motion-preference.js";
4
+ import { cn as n } from "../ui/lib/utils.js";
5
+ import { Spinner as r } from "../ui/spinner.js";
6
+ import { Icon as i } from "../ui/icon.js";
7
+ import { Popover as a, PopoverContent as o, PopoverTrigger as s } from "../_chunks/popover.js";
8
+ import * as c from "react";
9
+ import { Fragment as l, jsx as u, jsxs as d } from "react/jsx-runtime";
10
+ import { IconCheck as f, IconSearch as p } from "@tabler/icons-react";
11
+ import { motion as m } from "framer-motion";
11
12
  //#region src/composed/multi-select-popover.tsx
12
- var m = s.forwardRef(({ items: m, groups: h, value: g, onValueChange: _, searchPlaceholder: v = "Search...", onSearch: y, searchDebounce: b = 300, renderItem: x, emptyMessage: S = "No results found", maxSelections: C, align: w = "start", width: T, children: E, className: D, ...O }, k) => {
13
- let [A, j] = s.useState(!1), [M, N] = s.useState(""), [P, F] = s.useState(null), [I, L] = s.useState(!1), [R, z] = s.useState(-1), B = s.useRef(void 0), V = s.useRef(null);
14
- s.useEffect(() => {
15
- A || (N(""), F(null), z(-1));
16
- }, [A]), s.useEffect(() => {
17
- if (!(!y || !A)) {
18
- if (!M.trim()) {
19
- F(null), L(!1);
13
+ var h = c.forwardRef(({ items: h, groups: g, value: _, onValueChange: v, searchPlaceholder: y = "Search...", onSearch: b, searchDebounce: x = 300, renderItem: S, emptyMessage: C = "No results found", maxSelections: w, align: T = "start", width: E, children: D, className: O, ...k }, A) => {
14
+ let [j, M] = c.useState(!1), [N, P] = c.useState(""), [F, I] = c.useState(null), [L, R] = c.useState(!1), [z, B] = c.useState(-1), V = c.useRef(void 0), H = c.useRef(null);
15
+ c.useEffect(() => {
16
+ j || (P(""), I(null), B(-1));
17
+ }, [j]), c.useEffect(() => {
18
+ if (!(!b || !j)) {
19
+ if (!N.trim()) {
20
+ I(null), R(!1);
20
21
  return;
21
22
  }
22
- return L(!0), clearTimeout(B.current), B.current = setTimeout(() => {
23
- y(M).then((e) => F(e)).catch(() => F([])).finally(() => L(!1));
24
- }, b), () => clearTimeout(B.current);
23
+ return R(!0), clearTimeout(V.current), V.current = setTimeout(() => {
24
+ b(N).then((e) => I(e)).catch(() => I([])).finally(() => R(!1));
25
+ }, x), () => clearTimeout(V.current);
25
26
  }
26
27
  }, [
27
- M,
28
- y,
28
+ N,
29
29
  b,
30
- A
30
+ x,
31
+ j
31
32
  ]);
32
- let H = s.useMemo(() => P || (h ? h.flatMap((e) => e.items) : m ?? []), [
33
- m,
33
+ let U = c.useMemo(() => F || (g ? g.flatMap((e) => e.items) : h ?? []), [
34
34
  h,
35
- P
36
- ]), U = s.useMemo(() => {
37
- if (y) return H;
38
- let e = M.toLowerCase();
39
- return e ? H.filter((t) => t.label.toLowerCase().includes(e)) : H;
35
+ g,
36
+ F
37
+ ]), W = c.useMemo(() => {
38
+ if (b) return U;
39
+ let e = N.toLowerCase();
40
+ return e ? U.filter((t) => t.label.toLowerCase().includes(e)) : U;
40
41
  }, [
41
- H,
42
- M,
43
- y
44
- ]), W = s.useMemo(() => {
45
- if (!h || y || P) return null;
46
- let e = M.toLowerCase();
47
- return h.map((t) => ({
42
+ U,
43
+ N,
44
+ b
45
+ ]), G = c.useMemo(() => {
46
+ if (!g || b || F) return null;
47
+ let e = N.toLowerCase();
48
+ return g.map((t) => ({
48
49
  ...t,
49
50
  items: e ? t.items.filter((t) => t.label.toLowerCase().includes(e)) : t.items
50
51
  })).filter((e) => e.items.length > 0);
51
52
  }, [
52
- h,
53
- M,
54
- y,
55
- P
53
+ g,
54
+ N,
55
+ b,
56
+ F
56
57
  ]);
57
- function G(e) {
58
- g.includes(e) ? _(g.filter((t) => t !== e)) : C && g.length >= C ? _([...g.slice(1), e]) : _([...g, e]);
59
- }
60
- s.useEffect(() => {
61
- z(-1);
62
- }, [M]), s.useEffect(() => {
63
- if (R < 0) return;
64
- let e = V.current;
65
- e && e.querySelectorAll("[data-multiselect-item]")[R]?.scrollIntoView({ block: "nearest" });
66
- }, [R]);
67
58
  function K(e) {
68
- let t = U.length;
59
+ _.includes(e) ? v(_.filter((t) => t !== e)) : w && _.length >= w ? v([..._.slice(1), e]) : v([..._, e]);
60
+ }
61
+ c.useEffect(() => {
62
+ B(-1);
63
+ }, [N]), c.useEffect(() => {
64
+ if (z < 0) return;
65
+ let e = H.current;
66
+ e && e.querySelectorAll("[data-multiselect-item]")[z]?.scrollIntoView({ block: "nearest" });
67
+ }, [z]);
68
+ function q(e) {
69
+ let t = W.length;
69
70
  if (t !== 0) {
70
- if (e.key === "ArrowDown") e.preventDefault(), z((e) => e < t - 1 ? e + 1 : 0);
71
- else if (e.key === "ArrowUp") e.preventDefault(), z((e) => e <= 0 ? t - 1 : e - 1);
72
- else if (e.key === "Enter" && R >= 0) {
71
+ if (e.key === "ArrowDown") e.preventDefault(), B((e) => e < t - 1 ? e + 1 : 0);
72
+ else if (e.key === "ArrowUp") e.preventDefault(), B((e) => e <= 0 ? t - 1 : e - 1);
73
+ else if (e.key === "Enter" && z >= 0) {
73
74
  e.preventDefault();
74
- let t = U[R];
75
- t && !t.disabled && G(t.id);
75
+ let t = W[z];
76
+ t && !t.disabled && K(t.id);
76
77
  }
77
78
  }
78
79
  }
79
- let q = 0;
80
- function J(n) {
81
- let i = g.includes(n.id), a = q++, o = a === R;
82
- return /* @__PURE__ */ u(p.button, {
83
- id: `msp-item-${a}`,
80
+ let J = 0;
81
+ function Y(r) {
82
+ let a = _.includes(r.id), o = J++, s = o === z;
83
+ return /* @__PURE__ */ u(t, { children: /* @__PURE__ */ d(m.button, {
84
+ id: `msp-item-${o}`,
84
85
  type: "button",
85
86
  role: "option",
86
- "aria-selected": i,
87
- disabled: n.disabled,
87
+ "aria-selected": a,
88
+ disabled: r.disabled,
88
89
  "data-multiselect-item": "",
89
- "data-focused": o ? "" : void 0,
90
+ "data-focused": s ? "" : void 0,
90
91
  initial: {
91
92
  opacity: 0,
92
93
  x: -8
@@ -97,90 +98,90 @@ var m = s.forwardRef(({ items: m, groups: h, value: g, onValueChange: _, searchP
97
98
  },
98
99
  transition: {
99
100
  ...e.snappy,
100
- delay: a * .02
101
+ delay: o * .02
101
102
  },
102
- onClick: () => G(n.id),
103
- className: t("flex w-full items-center gap-ds-03 px-ds-04 py-ds-02b text-left transition-colors duration-fast-01 ease-productive-standard", "hover:bg-surface-raised-hover", "disabled:opacity-action-disabled disabled:cursor-not-allowed", i && "bg-accent-2 text-accent-11", o && "bg-surface-raised-hover"),
104
- children: [x ? /* @__PURE__ */ l("span", {
103
+ onClick: () => K(r.id),
104
+ className: n("flex w-full items-center gap-ds-03 px-ds-04 py-ds-02b text-left transition-colors duration-fast-01 ease-productive-standard", "hover:bg-surface-panel-hover", "disabled:opacity-action-disabled disabled:cursor-not-allowed", a && "bg-accent-4 text-accent-11", s && "bg-surface-panel-hover"),
105
+ children: [S ? /* @__PURE__ */ u("span", {
105
106
  className: "flex-1 min-w-0",
106
- children: x(n, i)
107
- }) : /* @__PURE__ */ u(c, { children: [n.image && /* @__PURE__ */ l("img", {
108
- src: n.image,
107
+ children: S(r, a)
108
+ }) : /* @__PURE__ */ d(l, { children: [r.image && /* @__PURE__ */ u("img", {
109
+ src: r.image,
109
110
  alt: "",
110
111
  className: "h-ico-md w-ico-md rounded-pill object-cover shrink-0"
111
- }), /* @__PURE__ */ u("span", {
112
+ }), /* @__PURE__ */ d("span", {
112
113
  className: "flex-1 min-w-0",
113
- children: [/* @__PURE__ */ l("span", {
114
+ children: [/* @__PURE__ */ u("span", {
114
115
  className: "block truncate text-body-md font-body text-surface-fg",
115
- children: n.label
116
- }), n.description && /* @__PURE__ */ l("span", {
116
+ children: r.label
117
+ }), r.description && /* @__PURE__ */ u("span", {
117
118
  className: "block truncate text-caption text-surface-fg-subtle",
118
- children: n.description
119
+ children: r.description
119
120
  })]
120
- })] }), i && /* @__PURE__ */ l(p.span, {
121
+ })] }), a && /* @__PURE__ */ u(m.span, {
121
122
  initial: { scale: 0 },
122
123
  animate: { scale: 1 },
123
124
  transition: e.snappy,
124
125
  className: "inline-flex shrink-0",
125
- children: /* @__PURE__ */ l(r, {
126
- icon: d,
126
+ children: /* @__PURE__ */ u(i, {
127
+ icon: f,
127
128
  size: "sm",
128
129
  className: "text-accent-11"
129
130
  })
130
131
  })]
131
- }, n.id);
132
+ }, r.id) });
132
133
  }
133
- return /* @__PURE__ */ u(i, {
134
- open: A,
135
- onOpenChange: j,
134
+ return /* @__PURE__ */ d(a, {
135
+ open: j,
136
+ onOpenChange: M,
136
137
  modal: !1,
137
- children: [/* @__PURE__ */ l(o, {
138
+ children: [/* @__PURE__ */ u(s, {
138
139
  asChild: !0,
139
- children: E
140
- }), /* @__PURE__ */ u(a, {
141
- ref: k,
142
- ...O,
143
- className: t("border-surface-border-strong bg-surface-overlay p-0", D),
144
- style: { width: T ?? 240 },
145
- align: w,
140
+ children: D
141
+ }), /* @__PURE__ */ d(o, {
142
+ ref: A,
143
+ ...k,
144
+ className: n("border-surface-border-strong bg-surface-overlay p-0", O),
145
+ style: { width: E ?? 240 },
146
+ align: T,
146
147
  sideOffset: 4,
147
- children: [/* @__PURE__ */ u("div", {
148
+ children: [/* @__PURE__ */ d("div", {
148
149
  className: "flex items-center gap-ds-03 border-b border-surface-border-strong px-ds-04 py-ds-03",
149
150
  children: [
150
- /* @__PURE__ */ l(r, {
151
- icon: f,
151
+ /* @__PURE__ */ u(i, {
152
+ icon: p,
152
153
  size: "sm",
153
154
  stroke: "light",
154
155
  className: "shrink-0 text-surface-fg-subtle"
155
156
  }),
156
- /* @__PURE__ */ l("input", {
157
+ /* @__PURE__ */ u("input", {
157
158
  type: "text",
158
- placeholder: v,
159
- value: M,
160
- onChange: (e) => N(e.target.value),
161
- onKeyDown: K,
159
+ placeholder: y,
160
+ value: N,
161
+ onChange: (e) => P(e.target.value),
162
+ onKeyDown: q,
162
163
  "aria-label": "Search",
163
- "aria-activedescendant": R >= 0 ? `msp-item-${R}` : void 0,
164
+ "aria-activedescendant": z >= 0 ? `msp-item-${z}` : void 0,
164
165
  className: "w-full bg-transparent text-body-md font-body text-surface-fg placeholder:text-surface-fg-subtle outline-hidden"
165
166
  }),
166
- I && /* @__PURE__ */ l(n, { size: "sm" })
167
+ L && /* @__PURE__ */ u(r, { size: "sm" })
167
168
  ]
168
- }), /* @__PURE__ */ u("div", {
169
- ref: V,
169
+ }), /* @__PURE__ */ d("div", {
170
+ ref: H,
170
171
  role: "listbox",
171
172
  "aria-multiselectable": "true",
172
173
  className: "max-h-[240px] overflow-y-auto py-ds-02",
173
- children: [W ? W.map((e) => /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("div", {
174
+ children: [G ? G.map((e) => /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("div", {
174
175
  className: "px-ds-04 py-ds-02 text-label-xs font-semibold uppercase tracking-wider text-surface-fg-subtle",
175
176
  children: e.label
176
- }), e.items.map(J)] }, e.label)) : U.map(J), !I && U.length === 0 && /* @__PURE__ */ l("p", {
177
+ }), e.items.map(Y)] }, e.label)) : W.map(Y), !L && W.length === 0 && /* @__PURE__ */ u("p", {
177
178
  className: "px-ds-04 py-ds-05 text-center text-body-sm font-body text-surface-fg-subtle",
178
- children: S
179
+ children: C
179
180
  })]
180
181
  })]
181
182
  })]
182
183
  });
183
184
  });
184
- m.displayName = "MultiSelectPopover";
185
+ h.displayName = "MultiSelectPopover";
185
186
  //#endregion
186
- export { m as MultiSelectPopover };
187
+ export { h as MultiSelectPopover };
@@ -1 +1 @@
1
- {"version":3,"file":"multi-select-popover.js","names":[],"sources":["../../src/composed/multi-select-popover.tsx"],"sourcesContent":["'use client'\n\nimport { IconCheck, IconSearch } from '@tabler/icons-react'\nimport { motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { Icon } from '../ui/icon'\nimport { springs } from '../ui/lib/motion'\nimport { cn } from '../ui/lib/utils'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '../ui/popover'\nimport { Spinner } from '../ui/spinner'\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface MultiSelectItem {\n id: string\n label: string\n image?: string\n description?: string\n disabled?: boolean\n}\n\nexport interface MultiSelectGroup {\n label: string\n items: MultiSelectItem[]\n}\n\nexport interface MultiSelectPopoverProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'onSelect'> {\n /** Flat list of items (use `groups` for grouped rendering) */\n items?: MultiSelectItem[]\n /** Grouped items with section headers */\n groups?: MultiSelectGroup[]\n /** Currently selected item IDs */\n value: string[]\n /** Called when selection changes */\n onValueChange: (ids: string[]) => void\n /** @default 'Search...' */\n searchPlaceholder?: string\n /** Async search — replaces local filter with server results */\n onSearch?: (query: string) => Promise<MultiSelectItem[]>\n /** Debounce for async search in ms @default 300 */\n searchDebounce?: number\n /** Custom item renderer */\n renderItem?: (item: MultiSelectItem, selected: boolean) => React.ReactNode\n /** Message when no items match filter @default 'No results found' */\n emptyMessage?: string\n /** Maximum number of selections */\n maxSelections?: number\n /** Popover alignment @default 'start' */\n align?: 'start' | 'center' | 'end'\n /** Popover width */\n width?: string | number\n /** Trigger element */\n children: React.ReactNode\n}\n\n// ============================================================\n// MultiSelectPopover\n// ============================================================\n\nconst MultiSelectPopover = React.forwardRef<HTMLDivElement, MultiSelectPopoverProps>(\n (\n {\n items,\n groups,\n value,\n onValueChange,\n searchPlaceholder = 'Search...',\n onSearch,\n searchDebounce = 300,\n renderItem,\n emptyMessage = 'No results found',\n maxSelections,\n align = 'start',\n width,\n children,\n className,\n ...props\n },\n ref,\n ) => {\n const [open, setOpen] = React.useState(false)\n const [search, setSearch] = React.useState('')\n const [asyncItems, setAsyncItems] = React.useState<MultiSelectItem[] | null>(null)\n const [loading, setLoading] = React.useState(false)\n const [focusedIndex, setFocusedIndex] = React.useState(-1)\n const debounceRef = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n const listRef = React.useRef<HTMLDivElement>(null)\n\n // Reset search and focus when popover closes\n React.useEffect(() => {\n if (!open) {\n setSearch('')\n setAsyncItems(null)\n setFocusedIndex(-1)\n }\n }, [open])\n\n // Async search\n React.useEffect(() => {\n if (!onSearch || !open) return\n if (!search.trim()) {\n setAsyncItems(null)\n setLoading(false)\n return\n }\n setLoading(true)\n clearTimeout(debounceRef.current)\n debounceRef.current = setTimeout(() => {\n onSearch(search)\n .then((results) => setAsyncItems(results))\n .catch(() => setAsyncItems([]))\n .finally(() => setLoading(false))\n }, searchDebounce)\n return () => clearTimeout(debounceRef.current)\n }, [search, onSearch, searchDebounce, open])\n\n // Resolve visible items\n const allItems = React.useMemo(() => {\n if (asyncItems) return asyncItems\n if (groups) return groups.flatMap((g) => g.items)\n return items ?? []\n }, [items, groups, asyncItems])\n\n const filteredItems = React.useMemo(() => {\n if (onSearch) return allItems // async search handles its own filtering\n const q = search.toLowerCase()\n if (!q) return allItems\n return allItems.filter((item) => item.label.toLowerCase().includes(q))\n }, [allItems, search, onSearch])\n\n const filteredGroups = React.useMemo(() => {\n if (!groups || onSearch || asyncItems) return null\n const q = search.toLowerCase()\n return groups\n .map((g) => ({\n ...g,\n items: q ? g.items.filter((item) => item.label.toLowerCase().includes(q)) : g.items,\n }))\n .filter((g) => g.items.length > 0)\n }, [groups, search, onSearch, asyncItems])\n\n function toggle(id: string) {\n const isSelected = value.includes(id)\n if (isSelected) {\n onValueChange(value.filter((v) => v !== id))\n } else {\n if (maxSelections && value.length >= maxSelections) {\n // Replace: drop the first selected item to make room for the new one\n onValueChange([...value.slice(1), id])\n } else {\n onValueChange([...value, id])\n }\n }\n }\n\n // Reset focused index when search text changes\n \n React.useEffect(() => { setFocusedIndex(-1) }, [search])\n\n // Scroll focused item into view\n React.useEffect(() => {\n if (focusedIndex < 0) return\n const list = listRef.current\n if (!list) return\n const items = list.querySelectorAll('[data-multiselect-item]')\n items[focusedIndex]?.scrollIntoView({ block: 'nearest' })\n }, [focusedIndex])\n\n function handleSearchKeyDown(e: React.KeyboardEvent) {\n const count = filteredItems.length\n if (count === 0) return\n\n if (e.key === 'ArrowDown') {\n e.preventDefault()\n setFocusedIndex((prev) => (prev < count - 1 ? prev + 1 : 0))\n } else if (e.key === 'ArrowUp') {\n e.preventDefault()\n setFocusedIndex((prev) => (prev <= 0 ? count - 1 : prev - 1))\n } else if (e.key === 'Enter' && focusedIndex >= 0) {\n e.preventDefault()\n const item = filteredItems[focusedIndex]\n if (item && !item.disabled) toggle(item.id)\n }\n }\n\n let itemCounter = 0\n\n function renderItemRow(item: MultiSelectItem) {\n const isSelected = value.includes(item.id)\n const index = itemCounter++\n const isFocused = index === focusedIndex\n return (\n <motion.button\n key={item.id}\n id={`msp-item-${index}`}\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n disabled={item.disabled}\n data-multiselect-item=\"\"\n data-focused={isFocused ? '' : undefined}\n initial={{ opacity: 0, x: -8 }}\n animate={{ opacity: 1, x: 0 }}\n transition={{ ...springs.snappy, delay: index * 0.02 }}\n onClick={() => toggle(item.id)}\n className={cn(\n 'flex w-full items-center gap-ds-03 px-ds-04 py-ds-02b text-left transition-colors duration-fast-01 ease-productive-standard',\n 'hover:bg-surface-raised-hover',\n 'disabled:opacity-action-disabled disabled:cursor-not-allowed',\n isSelected && 'bg-accent-2 text-accent-11',\n isFocused && 'bg-surface-raised-hover',\n )}\n >\n {renderItem ? (\n <span className=\"flex-1 min-w-0\">{renderItem(item, isSelected)}</span>\n ) : (\n <>\n {item.image && (\n <img\n src={item.image}\n alt=\"\"\n className=\"h-ico-md w-ico-md rounded-pill object-cover shrink-0\"\n />\n )}\n <span className=\"flex-1 min-w-0\">\n <span className=\"block truncate text-body-md font-body text-surface-fg\">{item.label}</span>\n {item.description && (\n <span className=\"block truncate text-caption text-surface-fg-subtle\">{item.description}</span>\n )}\n </span>\n </>\n )}\n {isSelected && (\n <motion.span\n initial={{ scale: 0 }}\n animate={{ scale: 1 }}\n transition={springs.snappy}\n className=\"inline-flex shrink-0\"\n >\n <Icon icon={IconCheck} size=\"sm\" className=\"text-accent-11\" />\n </motion.span>\n )}\n </motion.button>\n )\n }\n\n return (\n <Popover open={open} onOpenChange={setOpen} modal={false}>\n <PopoverTrigger asChild>{children}</PopoverTrigger>\n <PopoverContent\n ref={ref}\n {...props}\n className={cn(\n 'border-surface-border-strong bg-surface-overlay p-0',\n className,\n )}\n style={{ width: width ?? 240 }}\n align={align}\n sideOffset={4}\n >\n {/* Search */}\n <div className=\"flex items-center gap-ds-03 border-b border-surface-border-strong px-ds-04 py-ds-03\">\n <Icon icon={IconSearch} size=\"sm\" stroke=\"light\" className=\"shrink-0 text-surface-fg-subtle\" />\n <input\n type=\"text\"\n placeholder={searchPlaceholder}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n onKeyDown={handleSearchKeyDown}\n aria-label=\"Search\"\n aria-activedescendant={focusedIndex >= 0 ? `msp-item-${focusedIndex}` : undefined}\n className=\"w-full bg-transparent text-body-md font-body text-surface-fg placeholder:text-surface-fg-subtle outline-hidden\"\n />\n {loading && <Spinner size=\"sm\" />}\n </div>\n\n {/* Items */}\n <div ref={listRef} role=\"listbox\" aria-multiselectable=\"true\" className=\"max-h-[240px] overflow-y-auto py-ds-02\">\n {filteredGroups\n ? filteredGroups.map((group) => (\n <div key={group.label}>\n <div className=\"px-ds-04 py-ds-02 text-label-xs font-semibold uppercase tracking-wider text-surface-fg-subtle\">\n {group.label}\n </div>\n {group.items.map(renderItemRow)}\n </div>\n ))\n : filteredItems.map(renderItemRow)}\n {!loading && filteredItems.length === 0 && (\n <p className=\"px-ds-04 py-ds-05 text-center text-body-sm font-body text-surface-fg-subtle\">\n {emptyMessage}\n </p>\n )}\n </div>\n </PopoverContent>\n </Popover>\n )\n },\n)\nMultiSelectPopover.displayName = 'MultiSelectPopover'\n\nexport { MultiSelectPopover }\n"],"mappings":"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"}
1
+ {"version":3,"file":"multi-select-popover.js","names":[],"sources":["../../src/composed/multi-select-popover.tsx"],"sourcesContent":["'use client'\n\nimport { IconCheck, IconSearch } from '@tabler/icons-react'\nimport { motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { MotionPreference } from '../motion/motion-preference'\nimport { Icon } from '../ui/icon'\nimport { springs } from '../ui/lib/motion'\nimport { cn } from '../ui/lib/utils'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '../ui/popover'\nimport { Spinner } from '../ui/spinner'\n\n// ============================================================\n// Types\n// ============================================================\n\nexport interface MultiSelectItem {\n id: string\n label: string\n image?: string\n description?: string\n disabled?: boolean\n}\n\nexport interface MultiSelectGroup {\n label: string\n items: MultiSelectItem[]\n}\n\nexport interface MultiSelectPopoverProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'onSelect'> {\n /** Flat list of items (use `groups` for grouped rendering) */\n items?: MultiSelectItem[]\n /** Grouped items with section headers */\n groups?: MultiSelectGroup[]\n /** Currently selected item IDs */\n value: string[]\n /** Called when selection changes */\n onValueChange: (ids: string[]) => void\n /** @default 'Search...' */\n searchPlaceholder?: string\n /** Async search — replaces local filter with server results */\n onSearch?: (query: string) => Promise<MultiSelectItem[]>\n /** Debounce for async search in ms @default 300 */\n searchDebounce?: number\n /** Custom item renderer */\n renderItem?: (item: MultiSelectItem, selected: boolean) => React.ReactNode\n /** Message when no items match filter @default 'No results found' */\n emptyMessage?: string\n /** Maximum number of selections */\n maxSelections?: number\n /** Popover alignment @default 'start' */\n align?: 'start' | 'center' | 'end'\n /** Popover width */\n width?: string | number\n /** Trigger element */\n children: React.ReactNode\n}\n\n// ============================================================\n// MultiSelectPopover\n// ============================================================\n\nconst MultiSelectPopover = React.forwardRef<HTMLDivElement, MultiSelectPopoverProps>(\n (\n {\n items,\n groups,\n value,\n onValueChange,\n searchPlaceholder = 'Search...',\n onSearch,\n searchDebounce = 300,\n renderItem,\n emptyMessage = 'No results found',\n maxSelections,\n align = 'start',\n width,\n children,\n className,\n ...props\n },\n ref,\n ) => {\n const [open, setOpen] = React.useState(false)\n const [search, setSearch] = React.useState('')\n const [asyncItems, setAsyncItems] = React.useState<MultiSelectItem[] | null>(null)\n const [loading, setLoading] = React.useState(false)\n const [focusedIndex, setFocusedIndex] = React.useState(-1)\n const debounceRef = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n const listRef = React.useRef<HTMLDivElement>(null)\n\n // Reset search and focus when popover closes\n React.useEffect(() => {\n if (!open) {\n setSearch('')\n setAsyncItems(null)\n setFocusedIndex(-1)\n }\n }, [open])\n\n // Async search\n React.useEffect(() => {\n if (!onSearch || !open) return\n if (!search.trim()) {\n setAsyncItems(null)\n setLoading(false)\n return\n }\n setLoading(true)\n clearTimeout(debounceRef.current)\n debounceRef.current = setTimeout(() => {\n onSearch(search)\n .then((results) => setAsyncItems(results))\n .catch(() => setAsyncItems([]))\n .finally(() => setLoading(false))\n }, searchDebounce)\n return () => clearTimeout(debounceRef.current)\n }, [search, onSearch, searchDebounce, open])\n\n // Resolve visible items\n const allItems = React.useMemo(() => {\n if (asyncItems) return asyncItems\n if (groups) return groups.flatMap((g) => g.items)\n return items ?? []\n }, [items, groups, asyncItems])\n\n const filteredItems = React.useMemo(() => {\n if (onSearch) return allItems // async search handles its own filtering\n const q = search.toLowerCase()\n if (!q) return allItems\n return allItems.filter((item) => item.label.toLowerCase().includes(q))\n }, [allItems, search, onSearch])\n\n const filteredGroups = React.useMemo(() => {\n if (!groups || onSearch || asyncItems) return null\n const q = search.toLowerCase()\n return groups\n .map((g) => ({\n ...g,\n items: q ? g.items.filter((item) => item.label.toLowerCase().includes(q)) : g.items,\n }))\n .filter((g) => g.items.length > 0)\n }, [groups, search, onSearch, asyncItems])\n\n function toggle(id: string) {\n const isSelected = value.includes(id)\n if (isSelected) {\n onValueChange(value.filter((v) => v !== id))\n } else {\n if (maxSelections && value.length >= maxSelections) {\n // Replace: drop the first selected item to make room for the new one\n onValueChange([...value.slice(1), id])\n } else {\n onValueChange([...value, id])\n }\n }\n }\n\n // Reset focused index when search text changes\n \n React.useEffect(() => { setFocusedIndex(-1) }, [search])\n\n // Scroll focused item into view\n React.useEffect(() => {\n if (focusedIndex < 0) return\n const list = listRef.current\n if (!list) return\n const items = list.querySelectorAll('[data-multiselect-item]')\n items[focusedIndex]?.scrollIntoView({ block: 'nearest' })\n }, [focusedIndex])\n\n function handleSearchKeyDown(e: React.KeyboardEvent) {\n const count = filteredItems.length\n if (count === 0) return\n\n if (e.key === 'ArrowDown') {\n e.preventDefault()\n setFocusedIndex((prev) => (prev < count - 1 ? prev + 1 : 0))\n } else if (e.key === 'ArrowUp') {\n e.preventDefault()\n setFocusedIndex((prev) => (prev <= 0 ? count - 1 : prev - 1))\n } else if (e.key === 'Enter' && focusedIndex >= 0) {\n e.preventDefault()\n const item = filteredItems[focusedIndex]\n if (item && !item.disabled) toggle(item.id)\n }\n }\n\n let itemCounter = 0\n\n function renderItemRow(item: MultiSelectItem) {\n const isSelected = value.includes(item.id)\n const index = itemCounter++\n const isFocused = index === focusedIndex\n return (\n <MotionPreference>\n <motion.button\n key={item.id}\n id={`msp-item-${index}`}\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n disabled={item.disabled}\n data-multiselect-item=\"\"\n data-focused={isFocused ? '' : undefined}\n initial={{ opacity: 0, x: -8 }}\n animate={{ opacity: 1, x: 0 }}\n transition={{ ...springs.snappy, delay: index * 0.02 }}\n onClick={() => toggle(item.id)}\n className={cn(\n 'flex w-full items-center gap-ds-03 px-ds-04 py-ds-02b text-left transition-colors duration-fast-01 ease-productive-standard',\n 'hover:bg-surface-panel-hover',\n 'disabled:opacity-action-disabled disabled:cursor-not-allowed',\n // accent-4 so the selection stays above the focus ring's\n // panel-hover fill in dark; accent-2 sat below the panel.\n isSelected && 'bg-accent-4 text-accent-11',\n isFocused && 'bg-surface-panel-hover',\n )}\n >\n {renderItem ? (\n <span className=\"flex-1 min-w-0\">{renderItem(item, isSelected)}</span>\n ) : (\n <>\n {item.image && (\n <img\n src={item.image}\n alt=\"\"\n className=\"h-ico-md w-ico-md rounded-pill object-cover shrink-0\"\n />\n )}\n <span className=\"flex-1 min-w-0\">\n <span className=\"block truncate text-body-md font-body text-surface-fg\">{item.label}</span>\n {item.description && (\n <span className=\"block truncate text-caption text-surface-fg-subtle\">{item.description}</span>\n )}\n </span>\n </>\n )}\n {isSelected && (\n <motion.span\n initial={{ scale: 0 }}\n animate={{ scale: 1 }}\n transition={springs.snappy}\n className=\"inline-flex shrink-0\"\n >\n <Icon icon={IconCheck} size=\"sm\" className=\"text-accent-11\" />\n </motion.span>\n )}\n </motion.button>\n </MotionPreference>\n )\n }\n\n return (\n <Popover open={open} onOpenChange={setOpen} modal={false}>\n <PopoverTrigger asChild>{children}</PopoverTrigger>\n <PopoverContent\n ref={ref}\n {...props}\n className={cn(\n 'border-surface-border-strong bg-surface-overlay p-0',\n className,\n )}\n style={{ width: width ?? 240 }}\n align={align}\n sideOffset={4}\n >\n {/* Search */}\n <div className=\"flex items-center gap-ds-03 border-b border-surface-border-strong px-ds-04 py-ds-03\">\n <Icon icon={IconSearch} size=\"sm\" stroke=\"light\" className=\"shrink-0 text-surface-fg-subtle\" />\n <input\n type=\"text\"\n placeholder={searchPlaceholder}\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n onKeyDown={handleSearchKeyDown}\n aria-label=\"Search\"\n aria-activedescendant={focusedIndex >= 0 ? `msp-item-${focusedIndex}` : undefined}\n className=\"w-full bg-transparent text-body-md font-body text-surface-fg placeholder:text-surface-fg-subtle outline-hidden\"\n />\n {loading && <Spinner size=\"sm\" />}\n </div>\n\n {/* Items */}\n <div ref={listRef} role=\"listbox\" aria-multiselectable=\"true\" className=\"max-h-[240px] overflow-y-auto py-ds-02\">\n {filteredGroups\n ? filteredGroups.map((group) => (\n <div key={group.label}>\n <div className=\"px-ds-04 py-ds-02 text-label-xs font-semibold uppercase tracking-wider text-surface-fg-subtle\">\n {group.label}\n </div>\n {group.items.map(renderItemRow)}\n </div>\n ))\n : filteredItems.map(renderItemRow)}\n {!loading && filteredItems.length === 0 && (\n <p className=\"px-ds-04 py-ds-05 text-center text-body-sm font-body text-surface-fg-subtle\">\n {emptyMessage}\n </p>\n )}\n </div>\n </PopoverContent>\n </Popover>\n )\n },\n)\nMultiSelectPopover.displayName = 'MultiSelectPopover'\n\nexport { MultiSelectPopover }\n"],"mappings":"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"}
@@ -27,7 +27,7 @@ var s = n.forwardRef(function({ className: n, label: s, ...c }, l) {
27
27
  /* @__PURE__ */ r("div", {
28
28
  className: "grid grid-cols-1 gap-ds-05 sm:grid-cols-2 lg:grid-cols-4",
29
29
  children: Array.from({ length: 4 }).map((e, n) => /* @__PURE__ */ i("div", {
30
- className: "flex flex-col gap-ds-04 rounded-surface border border-card bg-surface-raised p-ds-05b",
30
+ className: "flex flex-col gap-ds-04 rounded-surface border border-card bg-surface-panel p-ds-05b",
31
31
  children: [
32
32
  /* @__PURE__ */ i("div", {
33
33
  className: "flex items-center justify-between",
@@ -39,7 +39,7 @@ var s = n.forwardRef(function({ className: n, label: s, ...c }, l) {
39
39
  }, `stat-${n}`))
40
40
  }),
41
41
  /* @__PURE__ */ i("div", {
42
- className: "rounded-surface border border-card bg-surface-raised p-ds-06",
42
+ className: "rounded-surface border border-card bg-surface-panel p-ds-06",
43
43
  children: [
44
44
  /* @__PURE__ */ i("div", {
45
45
  className: "mb-ds-06 flex items-center justify-between",
@@ -91,7 +91,7 @@ var c = n.forwardRef(function({ className: n, label: s, ...c }, l) {
91
91
  /* @__PURE__ */ r("div", {
92
92
  className: "grid grid-cols-1 gap-ds-05 sm:grid-cols-2 lg:grid-cols-3",
93
93
  children: Array.from({ length: 6 }).map((e, n) => /* @__PURE__ */ i("div", {
94
- className: "flex flex-col gap-ds-05 rounded-surface border border-card bg-surface-raised p-ds-05b",
94
+ className: "flex flex-col gap-ds-05 rounded-surface border border-card bg-surface-panel p-ds-05b",
95
95
  children: [
96
96
  /* @__PURE__ */ i("div", {
97
97
  className: "flex items-center justify-between",
@@ -124,7 +124,7 @@ var l = n.forwardRef(function({ className: n, label: s, ...c }, l) {
124
124
  ref: l,
125
125
  ...a(s),
126
126
  ...c,
127
- className: e("flex h-full flex-col gap-0 rounded-surface border border-card bg-surface-raised", n),
127
+ className: e("flex h-full flex-col gap-0 rounded-surface border border-card bg-surface-panel", n),
128
128
  children: [
129
129
  /* @__PURE__ */ r(o, { label: s }),
130
130
  /* @__PURE__ */ i("div", {