@devalok/shilp-sutra 0.34.1 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (439) hide show
  1. package/LICENSE +21 -21
  2. package/dist/_chunks/badge-group.js +95 -95
  3. package/dist/_chunks/badge-group.js.map +1 -0
  4. package/dist/_chunks/chat.js +7 -2
  5. package/dist/_chunks/chat.js.map +1 -0
  6. package/dist/_chunks/date-picker.js.map +1 -0
  7. package/dist/_chunks/document-preview.js.map +1 -0
  8. package/dist/_chunks/file-preview.js.map +1 -0
  9. package/dist/_chunks/framer.js +62 -62
  10. package/dist/_chunks/framer.js.map +1 -0
  11. package/dist/_chunks/image-preview.js +1 -1
  12. package/dist/_chunks/image-preview.js.map +1 -0
  13. package/dist/_chunks/keybinding.js.map +1 -0
  14. package/dist/_chunks/link-context.js.map +1 -0
  15. package/dist/_chunks/mention-suggestion.js.map +1 -0
  16. package/dist/_chunks/motion-provider.js.map +1 -0
  17. package/dist/_chunks/popover.js +32 -36
  18. package/dist/_chunks/popover.js.map +1 -0
  19. package/dist/_chunks/primitives.js +686 -686
  20. package/dist/_chunks/primitives.js.map +1 -0
  21. package/dist/_chunks/rich-chat-input.js +650 -649
  22. package/dist/_chunks/rich-chat-input.js.map +1 -0
  23. package/dist/_chunks/shared.js.map +1 -0
  24. package/dist/_chunks/sonner.js.map +1 -0
  25. package/dist/_chunks/stat-row.js +158 -158
  26. package/dist/_chunks/stat-row.js.map +1 -0
  27. package/dist/_chunks/tiptap.js +11 -11
  28. package/dist/_chunks/tiptap.js.map +1 -0
  29. package/dist/_chunks/tree-view.js +1 -1
  30. package/dist/_chunks/tree-view.js.map +1 -0
  31. package/dist/_chunks/use-calendar.js.map +1 -0
  32. package/dist/_chunks/vendor-client.js +1 -1
  33. package/dist/_chunks/vendor-client.js.map +1 -0
  34. package/dist/_chunks/vendor-utils.js.map +1 -0
  35. package/dist/ai/ai-command-provider.js.map +1 -0
  36. package/dist/ai/block-renderer.js.map +1 -0
  37. package/dist/ai/blocks/loading.d.ts.map +1 -1
  38. package/dist/ai/command-bar.js.map +1 -0
  39. package/dist/ai/conversation.js +76 -76
  40. package/dist/ai/conversation.js.map +1 -0
  41. package/dist/ai/devadoot-icon.d.ts.map +1 -1
  42. package/dist/ai/index.js.map +1 -0
  43. package/dist/composed/activity-feed.js.map +1 -0
  44. package/dist/composed/avatar-group.js +1 -1
  45. package/dist/composed/avatar-group.js.map +1 -0
  46. package/dist/composed/bulk-action-bar.js +13 -21
  47. package/dist/composed/bulk-action-bar.js.map +1 -0
  48. package/dist/composed/command-palette.js.map +1 -0
  49. package/dist/composed/confirm-dialog.js.map +1 -0
  50. package/dist/composed/content-card.js.map +1 -0
  51. package/dist/composed/deadline-indicator.js.map +1 -0
  52. package/dist/composed/emoji-picker.js.map +1 -0
  53. package/dist/composed/empty-state.d.ts.map +1 -1
  54. package/dist/composed/empty-state.js +30 -30
  55. package/dist/composed/empty-state.js.map +1 -0
  56. package/dist/composed/error-boundary.js.map +1 -0
  57. package/dist/composed/filter-bar.js.map +1 -0
  58. package/dist/composed/form-section.js.map +1 -0
  59. package/dist/composed/global-loading.js.map +1 -0
  60. package/dist/composed/inline-edit.js.map +1 -0
  61. package/dist/composed/lib/string-utils.js.map +1 -0
  62. package/dist/composed/loading-skeleton.js.map +1 -0
  63. package/dist/composed/markdown-viewer.js.map +1 -0
  64. package/dist/composed/master-detail.js.map +1 -0
  65. package/dist/composed/member-picker.js.map +1 -0
  66. package/dist/composed/multi-select-popover.d.ts.map +1 -1
  67. package/dist/composed/multi-select-popover.js +4 -0
  68. package/dist/composed/multi-select-popover.js.map +1 -0
  69. package/dist/composed/page-header.js.map +1 -0
  70. package/dist/composed/page-skeletons.js.map +1 -0
  71. package/dist/composed/priority-indicator.js.map +1 -0
  72. package/dist/composed/responsive-overlay.js.map +1 -0
  73. package/dist/composed/rich-chat-input/attachment-strip.d.ts.map +1 -1
  74. package/dist/composed/rich-chat-input/reply-banner.d.ts.map +1 -1
  75. package/dist/composed/rich-chat-input/schedule-send.d.ts.map +1 -1
  76. package/dist/composed/rich-chat-input.d.ts.map +1 -1
  77. package/dist/composed/rich-text-editor.js.map +1 -0
  78. package/dist/composed/schedule-view.js.map +1 -0
  79. package/dist/composed/simple-tooltip.js.map +1 -0
  80. package/dist/composed/status-badge.d.ts.map +1 -1
  81. package/dist/composed/status-badge.js.map +1 -0
  82. package/dist/hooks/use-color-mode.js.map +1 -0
  83. package/dist/hooks/use-mobile.js.map +1 -0
  84. package/dist/hooks/use-touch-device.js.map +1 -0
  85. package/dist/hooks/use-viewport-height.js.map +1 -0
  86. package/dist/motion/check-motion-provider.d.ts +3 -0
  87. package/dist/motion/check-motion-provider.d.ts.map +1 -0
  88. package/dist/motion/index.js +14 -0
  89. package/dist/motion/index.js.map +1 -0
  90. package/dist/motion/primitives-index.js.map +1 -0
  91. package/dist/primitives/react-accordion.d.ts +114 -114
  92. package/dist/primitives/react-alert-dialog.d.ts +51 -51
  93. package/dist/primitives/react-aspect-ratio.d.ts +11 -11
  94. package/dist/primitives/react-avatar.d.ts +24 -24
  95. package/dist/primitives/react-checkbox.d.ts +50 -50
  96. package/dist/primitives/react-collapsible.d.ts +33 -33
  97. package/dist/primitives/react-context-menu.d.ts +96 -96
  98. package/dist/primitives/react-dialog.d.ts +103 -103
  99. package/dist/primitives/react-dropdown-menu.d.ts +97 -97
  100. package/dist/primitives/react-hover-card.d.ts +79 -79
  101. package/dist/primitives/react-label.d.ts +10 -10
  102. package/dist/primitives/react-menu.d.ts +169 -169
  103. package/dist/primitives/react-menubar.d.ts +115 -115
  104. package/dist/primitives/react-navigation-menu.d.ts +126 -126
  105. package/dist/primitives/react-popover.d.ts +85 -85
  106. package/dist/primitives/react-progress.d.ts +19 -19
  107. package/dist/primitives/react-radio-group.d.ts +58 -58
  108. package/dist/primitives/react-roving-focus.d.ts +49 -49
  109. package/dist/primitives/react-select.d.ts +137 -137
  110. package/dist/primitives/react-separator.d.ts +21 -21
  111. package/dist/primitives/react-slider.d.ts +75 -75
  112. package/dist/primitives/react-switch.d.ts +21 -21
  113. package/dist/primitives/react-tabs.d.ts +56 -56
  114. package/dist/primitives/react-toast.d.ts +120 -120
  115. package/dist/primitives/react-toggle-group.d.ts +75 -75
  116. package/dist/primitives/react-toggle.d.ts +24 -24
  117. package/dist/primitives/react-tooltip.d.ts +101 -101
  118. package/dist/primitives/react-visually-hidden.d.ts +22 -22
  119. package/dist/shell/app-command-palette.d.ts +2 -0
  120. package/dist/shell/app-command-palette.d.ts.map +1 -1
  121. package/dist/shell/app-command-palette.js +42 -155
  122. package/dist/shell/app-command-palette.js.map +1 -0
  123. package/dist/shell/bottom-navbar.js +1 -1
  124. package/dist/shell/bottom-navbar.js.map +1 -0
  125. package/dist/shell/command-registry.js.map +1 -0
  126. package/dist/shell/notification-center.d.ts.map +1 -1
  127. package/dist/shell/notification-center.js +194 -169
  128. package/dist/shell/notification-center.js.map +1 -0
  129. package/dist/shell/notification-preferences.js.map +1 -0
  130. package/dist/shell/sidebar.js.map +1 -0
  131. package/dist/shell/top-bar.js +1 -1
  132. package/dist/shell/top-bar.js.map +1 -0
  133. package/dist/tailwind/index.cjs +48 -1
  134. package/dist/tailwind/preset.d.ts.map +1 -1
  135. package/dist/tailwind/preset.js +48 -1
  136. package/dist/tailwind/preset.js.map +1 -0
  137. package/dist/tokens/index.css +4 -4
  138. package/dist/tokens/primitives.css +442 -442
  139. package/dist/tokens/semantic.css +742 -547
  140. package/dist/tokens/typography-semantic.css +123 -100
  141. package/dist/tokens/typography.css +422 -422
  142. package/dist/ui/accordion.js +13 -13
  143. package/dist/ui/accordion.js.map +1 -0
  144. package/dist/ui/alert-dialog.d.ts +6 -2
  145. package/dist/ui/alert-dialog.d.ts.map +1 -1
  146. package/dist/ui/alert-dialog.js +43 -42
  147. package/dist/ui/alert-dialog.js.map +1 -0
  148. package/dist/ui/alert.d.ts +3 -2
  149. package/dist/ui/alert.d.ts.map +1 -1
  150. package/dist/ui/alert.js +31 -5
  151. package/dist/ui/alert.js.map +1 -0
  152. package/dist/ui/aspect-ratio.js +1 -1
  153. package/dist/ui/aspect-ratio.js.map +1 -0
  154. package/dist/ui/autocomplete.d.ts.map +1 -1
  155. package/dist/ui/autocomplete.js +92 -67
  156. package/dist/ui/autocomplete.js.map +1 -0
  157. package/dist/ui/avatar.js +9 -9
  158. package/dist/ui/avatar.js.map +1 -0
  159. package/dist/ui/badge-indicator.js.map +1 -0
  160. package/dist/ui/banner.js.map +1 -0
  161. package/dist/ui/breadcrumb.js +1 -1
  162. package/dist/ui/breadcrumb.js.map +1 -0
  163. package/dist/ui/button-group.js.map +1 -0
  164. package/dist/ui/button-processing.d.ts.map +1 -1
  165. package/dist/ui/button-processing.js +61 -40
  166. package/dist/ui/button-processing.js.map +1 -0
  167. package/dist/ui/button.js +8 -8
  168. package/dist/ui/button.js.map +1 -0
  169. package/dist/ui/card.js.map +1 -0
  170. package/dist/ui/charts/bar-chart.d.ts.map +1 -1
  171. package/dist/ui/charts/chart-container.d.ts +2 -0
  172. package/dist/ui/charts/chart-container.d.ts.map +1 -1
  173. package/dist/ui/charts/index.js +88 -65
  174. package/dist/ui/charts/index.js.map +1 -0
  175. package/dist/ui/charts/line-chart.d.ts.map +1 -1
  176. package/dist/ui/chat/message-input.d.ts.map +1 -1
  177. package/dist/ui/chat/message-list.d.ts +1 -1
  178. package/dist/ui/chat/message-list.d.ts.map +1 -1
  179. package/dist/ui/chat/message.d.ts.map +1 -1
  180. package/dist/ui/chat/system-message.d.ts.map +1 -1
  181. package/dist/ui/checkbox.d.ts.map +1 -1
  182. package/dist/ui/checkbox.js +33 -28
  183. package/dist/ui/checkbox.js.map +1 -0
  184. package/dist/ui/code.js.map +1 -0
  185. package/dist/ui/collapsible.js +1 -1
  186. package/dist/ui/collapsible.js.map +1 -0
  187. package/dist/ui/color-input.d.ts.map +1 -1
  188. package/dist/ui/color-input.js +165 -163
  189. package/dist/ui/color-input.js.map +1 -0
  190. package/dist/ui/color-swatch.js.map +1 -0
  191. package/dist/ui/combobox.d.ts +7 -0
  192. package/dist/ui/combobox.d.ts.map +1 -1
  193. package/dist/ui/combobox.js +147 -113
  194. package/dist/ui/combobox.js.map +1 -0
  195. package/dist/ui/container.js +1 -1
  196. package/dist/ui/container.js.map +1 -0
  197. package/dist/ui/context-menu.js.map +1 -0
  198. package/dist/ui/data-table-body.js.map +1 -0
  199. package/dist/ui/data-table-bulk-actions.js +1 -1
  200. package/dist/ui/data-table-bulk-actions.js.map +1 -0
  201. package/dist/ui/data-table-card.js.map +1 -0
  202. package/dist/ui/data-table-context.js.map +1 -0
  203. package/dist/ui/data-table-header.js.map +1 -0
  204. package/dist/ui/data-table-pagination.js.map +1 -0
  205. package/dist/ui/data-table-toolbar.js.map +1 -0
  206. package/dist/ui/data-table.js +34 -31
  207. package/dist/ui/data-table.js.map +1 -0
  208. package/dist/ui/devalok-grain.js.map +1 -0
  209. package/dist/ui/dialog.js +31 -35
  210. package/dist/ui/dialog.js.map +1 -0
  211. package/dist/ui/dropdown-menu.js.map +1 -0
  212. package/dist/ui/file-upload.js +120 -120
  213. package/dist/ui/file-upload.js.map +1 -0
  214. package/dist/ui/form.d.ts +8 -0
  215. package/dist/ui/form.d.ts.map +1 -1
  216. package/dist/ui/form.js +14 -12
  217. package/dist/ui/form.js.map +1 -0
  218. package/dist/ui/hover-card.js.map +1 -0
  219. package/dist/ui/icon-button.js.map +1 -0
  220. package/dist/ui/icon-context.js.map +1 -0
  221. package/dist/ui/icon-group.js.map +1 -0
  222. package/dist/ui/icon.js.map +1 -0
  223. package/dist/ui/index.d.ts +4 -4
  224. package/dist/ui/index.d.ts.map +1 -1
  225. package/dist/ui/index.js +82 -66
  226. package/dist/ui/index.js.map +1 -0
  227. package/dist/ui/input-otp.d.ts +12 -3
  228. package/dist/ui/input-otp.d.ts.map +1 -1
  229. package/dist/ui/input-otp.js +41 -27
  230. package/dist/ui/input-otp.js.map +1 -0
  231. package/dist/ui/input.d.ts.map +1 -1
  232. package/dist/ui/input.js +16 -15
  233. package/dist/ui/input.js.map +1 -0
  234. package/dist/ui/label.d.ts.map +1 -1
  235. package/dist/ui/label.js +19 -14
  236. package/dist/ui/label.js.map +1 -0
  237. package/dist/ui/lib/check-tokens.d.ts +3 -0
  238. package/dist/ui/lib/check-tokens.d.ts.map +1 -0
  239. package/dist/ui/lib/date-utils.js.map +1 -0
  240. package/dist/ui/lib/motion.d.ts +15 -4
  241. package/dist/ui/lib/motion.d.ts.map +1 -1
  242. package/dist/ui/lib/motion.js +18 -9
  243. package/dist/ui/lib/motion.js.map +1 -0
  244. package/dist/ui/lib/utils.js.map +1 -0
  245. package/dist/ui/link.js +2 -2
  246. package/dist/ui/link.js.map +1 -0
  247. package/dist/ui/menubar.js.map +1 -0
  248. package/dist/ui/navigation-menu.js.map +1 -0
  249. package/dist/ui/number-input.d.ts +16 -1
  250. package/dist/ui/number-input.d.ts.map +1 -1
  251. package/dist/ui/number-input.js +79 -49
  252. package/dist/ui/number-input.js.map +1 -0
  253. package/dist/ui/pagination.js +1 -1
  254. package/dist/ui/pagination.js.map +1 -0
  255. package/dist/ui/progress-ring.d.ts.map +1 -1
  256. package/dist/ui/progress-ring.js.map +1 -0
  257. package/dist/ui/progress.js.map +1 -0
  258. package/dist/ui/radio.d.ts.map +1 -1
  259. package/dist/ui/radio.js +27 -20
  260. package/dist/ui/radio.js.map +1 -0
  261. package/dist/ui/search-input.js.map +1 -0
  262. package/dist/ui/segmented-control.d.ts +1 -1
  263. package/dist/ui/segmented-control.d.ts.map +1 -1
  264. package/dist/ui/segmented-control.js +2 -0
  265. package/dist/ui/segmented-control.js.map +1 -0
  266. package/dist/ui/select.d.ts.map +1 -1
  267. package/dist/ui/select.js +54 -48
  268. package/dist/ui/select.js.map +1 -0
  269. package/dist/ui/separator.d.ts.map +1 -1
  270. package/dist/ui/separator.js +10 -7
  271. package/dist/ui/separator.js.map +1 -0
  272. package/dist/ui/sheet.js +29 -29
  273. package/dist/ui/sheet.js.map +1 -0
  274. package/dist/ui/sidebar.js +7 -7
  275. package/dist/ui/sidebar.js.map +1 -0
  276. package/dist/ui/skeleton.js.map +1 -0
  277. package/dist/ui/slider.d.ts +22 -3
  278. package/dist/ui/slider.d.ts.map +1 -1
  279. package/dist/ui/slider.js +57 -19
  280. package/dist/ui/slider.js.map +1 -0
  281. package/dist/ui/spinner.js.map +1 -0
  282. package/dist/ui/split-button.d.ts.map +1 -1
  283. package/dist/ui/split-button.js +77 -76
  284. package/dist/ui/split-button.js.map +1 -0
  285. package/dist/ui/stack.js.map +1 -0
  286. package/dist/ui/stat-card.js.map +1 -0
  287. package/dist/ui/status-dot.js.map +1 -0
  288. package/dist/ui/stepper.d.ts +10 -0
  289. package/dist/ui/stepper.d.ts.map +1 -1
  290. package/dist/ui/stepper.js +80 -75
  291. package/dist/ui/stepper.js.map +1 -0
  292. package/dist/ui/switch.d.ts.map +1 -1
  293. package/dist/ui/switch.js +26 -22
  294. package/dist/ui/switch.js.map +1 -0
  295. package/dist/ui/table.js.map +1 -0
  296. package/dist/ui/tabs.d.ts +3 -1
  297. package/dist/ui/tabs.d.ts.map +1 -1
  298. package/dist/ui/tabs.js +68 -48
  299. package/dist/ui/tabs.js.map +1 -0
  300. package/dist/ui/text.d.ts +1 -1
  301. package/dist/ui/text.d.ts.map +1 -1
  302. package/dist/ui/text.js +10 -2
  303. package/dist/ui/text.js.map +1 -0
  304. package/dist/ui/textarea.js +1 -1
  305. package/dist/ui/textarea.js.map +1 -0
  306. package/dist/ui/toast-registry.d.ts +8 -0
  307. package/dist/ui/toast-registry.d.ts.map +1 -0
  308. package/dist/ui/toast-registry.js +13 -0
  309. package/dist/ui/toast-registry.js.map +1 -0
  310. package/dist/ui/toast.d.ts.map +1 -1
  311. package/dist/ui/toast.js +141 -136
  312. package/dist/ui/toast.js.map +1 -0
  313. package/dist/ui/toaster.d.ts.map +1 -1
  314. package/dist/ui/toaster.js +15 -14
  315. package/dist/ui/toaster.js.map +1 -0
  316. package/dist/ui/toggle-group.d.ts +2 -0
  317. package/dist/ui/toggle-group.d.ts.map +1 -1
  318. package/dist/ui/toggle-group.js +23 -16
  319. package/dist/ui/toggle-group.js.map +1 -0
  320. package/dist/ui/toggle.d.ts +2 -0
  321. package/dist/ui/toggle.d.ts.map +1 -1
  322. package/dist/ui/toggle.js +14 -6
  323. package/dist/ui/toggle.js.map +1 -0
  324. package/dist/ui/tooltip.js.map +1 -0
  325. package/dist/ui/visually-hidden.js.map +1 -0
  326. package/docs/components/_header.md +85 -85
  327. package/docs/components/composed/activity-feed.md +62 -62
  328. package/docs/components/composed/avatar-group.md +65 -65
  329. package/docs/components/composed/bulk-action-bar.md +40 -40
  330. package/docs/components/composed/command-palette.md +40 -40
  331. package/docs/components/composed/confirm-dialog.md +46 -46
  332. package/docs/components/composed/content-card.md +36 -36
  333. package/docs/components/composed/date-picker.md +130 -130
  334. package/docs/components/composed/deadline-indicator.md +27 -27
  335. package/docs/components/composed/emoji-picker.md +52 -52
  336. package/docs/components/composed/empty-state.md +53 -53
  337. package/docs/components/composed/error-boundary.md +29 -29
  338. package/docs/components/composed/file-preview.md +40 -40
  339. package/docs/components/composed/filter-bar.md +57 -57
  340. package/docs/components/composed/form-section.md +31 -31
  341. package/docs/components/composed/global-loading.md +27 -27
  342. package/docs/components/composed/inline-edit.md +35 -35
  343. package/docs/components/composed/loading-skeleton.md +51 -51
  344. package/docs/components/composed/markdown-viewer.md +27 -27
  345. package/docs/components/composed/master-detail.md +48 -48
  346. package/docs/components/composed/member-picker.md +35 -35
  347. package/docs/components/composed/multi-select-popover.md +62 -62
  348. package/docs/components/composed/page-header.md +41 -41
  349. package/docs/components/composed/page-skeletons.md +32 -32
  350. package/docs/components/composed/priority-indicator.md +32 -32
  351. package/docs/components/composed/responsive-overlay.md +34 -34
  352. package/docs/components/composed/rich-text-editor.md +82 -82
  353. package/docs/components/composed/schedule-view.md +39 -39
  354. package/docs/components/composed/simple-tooltip.md +33 -33
  355. package/docs/components/composed/status-badge.md +55 -55
  356. package/docs/components/shell/app-command-palette.md +44 -44
  357. package/docs/components/shell/bottom-navbar.md +52 -52
  358. package/docs/components/shell/command-registry.md +48 -48
  359. package/docs/components/shell/link-context.md +41 -41
  360. package/docs/components/shell/notification-center.md +63 -63
  361. package/docs/components/shell/notification-preferences.md +42 -42
  362. package/docs/components/shell/sidebar.md +92 -92
  363. package/docs/components/shell/top-bar.md +143 -143
  364. package/docs/components/ui/accordion.md +51 -51
  365. package/docs/components/ui/alert-dialog.md +61 -61
  366. package/docs/components/ui/alert.md +46 -46
  367. package/docs/components/ui/aspect-ratio.md +25 -25
  368. package/docs/components/ui/autocomplete.md +48 -48
  369. package/docs/components/ui/avatar.md +56 -56
  370. package/docs/components/ui/badge.md +83 -82
  371. package/docs/components/ui/banner.md +42 -42
  372. package/docs/components/ui/breadcrumb.md +37 -37
  373. package/docs/components/ui/button-group.md +41 -41
  374. package/docs/components/ui/button.md +94 -93
  375. package/docs/components/ui/card.md +52 -52
  376. package/docs/components/ui/charts.md +43 -43
  377. package/docs/components/ui/checkbox.md +36 -36
  378. package/docs/components/ui/chip.md +47 -47
  379. package/docs/components/ui/code.md +28 -28
  380. package/docs/components/ui/collapsible.md +40 -40
  381. package/docs/components/ui/color-input.md +91 -91
  382. package/docs/components/ui/color-swatch.md +25 -25
  383. package/docs/components/ui/combobox.md +54 -54
  384. package/docs/components/ui/container.md +26 -26
  385. package/docs/components/ui/context-menu.md +43 -43
  386. package/docs/components/ui/data-table-body.md +1 -1
  387. package/docs/components/ui/data-table-bulk-actions.md +1 -1
  388. package/docs/components/ui/data-table-card.md +1 -1
  389. package/docs/components/ui/data-table-context.md +1 -1
  390. package/docs/components/ui/data-table-header.md +1 -1
  391. package/docs/components/ui/data-table-pagination.md +1 -1
  392. package/docs/components/ui/data-table-toolbar.md +44 -44
  393. package/docs/components/ui/data-table.md +94 -94
  394. package/docs/components/ui/dialog.md +54 -54
  395. package/docs/components/ui/dropdown-menu.md +48 -48
  396. package/docs/components/ui/file-upload.md +41 -41
  397. package/docs/components/ui/form.md +51 -51
  398. package/docs/components/ui/hover-card.md +32 -32
  399. package/docs/components/ui/icon-button.md +40 -40
  400. package/docs/components/ui/input-otp.md +44 -44
  401. package/docs/components/ui/input.md +74 -74
  402. package/docs/components/ui/label.md +25 -25
  403. package/docs/components/ui/link.md +29 -29
  404. package/docs/components/ui/menubar.md +44 -44
  405. package/docs/components/ui/navigation-menu.md +46 -46
  406. package/docs/components/ui/number-input.md +44 -44
  407. package/docs/components/ui/pagination.md +48 -48
  408. package/docs/components/ui/popover.md +30 -30
  409. package/docs/components/ui/progress-ring.md +41 -41
  410. package/docs/components/ui/progress.md +34 -34
  411. package/docs/components/ui/radio.md +34 -34
  412. package/docs/components/ui/search-input.md +43 -43
  413. package/docs/components/ui/segmented-control.md +50 -50
  414. package/docs/components/ui/select.md +53 -53
  415. package/docs/components/ui/separator.md +32 -32
  416. package/docs/components/ui/sheet.md +47 -47
  417. package/docs/components/ui/sidebar.md +72 -72
  418. package/docs/components/ui/skeleton.md +77 -77
  419. package/docs/components/ui/slider.md +29 -29
  420. package/docs/components/ui/spinner.md +54 -54
  421. package/docs/components/ui/stack.md +39 -39
  422. package/docs/components/ui/stat-card.md +61 -61
  423. package/docs/components/ui/status-dot.md +26 -26
  424. package/docs/components/ui/stepper.md +49 -49
  425. package/docs/components/ui/switch.md +47 -47
  426. package/docs/components/ui/table.md +47 -47
  427. package/docs/components/ui/tabs.md +60 -60
  428. package/docs/components/ui/text.md +37 -37
  429. package/docs/components/ui/textarea.md +39 -39
  430. package/docs/components/ui/toast.md +65 -65
  431. package/docs/components/ui/toaster.md +47 -47
  432. package/docs/components/ui/toggle-group.md +43 -43
  433. package/docs/components/ui/toggle.md +37 -37
  434. package/docs/components/ui/tooltip.md +38 -38
  435. package/docs/components/ui/tree-view.md +65 -65
  436. package/docs/components/ui/visually-hidden.md +21 -21
  437. package/llms-full.txt +5266 -5264
  438. package/llms.txt +624 -580
  439. package/package.json +7 -8
@@ -1,84 +1,87 @@
1
1
  "use client";
2
2
  import { a as e, n as t } from "../_chunks/framer.js";
3
- import { cn as n } from "../ui/lib/utils.js";
4
- import { Spinner as r } from "../ui/spinner.js";
5
- import { Icon as i } from "../ui/icon.js";
6
- import { i as a, r as o, t as s } from "../_chunks/popover.js";
7
- import { Tooltip as c, TooltipContent as l, TooltipTrigger as u } from "../ui/tooltip.js";
8
- import { formatRelativeTime as d } from "../ui/lib/date-utils.js";
9
- import * as f from "react";
10
- import { useCallback as p, useRef as m } from "react";
11
- import { Fragment as h, jsx as g, jsxs as _ } from "react/jsx-runtime";
12
- import { IconBell as v, IconChecks as y, IconInbox as b, IconX as x } from "@tabler/icons-react";
3
+ import { durations as n } from "../ui/lib/motion.js";
4
+ import { cn as r } from "../ui/lib/utils.js";
5
+ import { Spinner as i } from "../ui/spinner.js";
6
+ import { Icon as a } from "../ui/icon.js";
7
+ import { useIsMobile as o } from "../hooks/use-mobile.js";
8
+ import { i as s, r as c, t as l } from "../_chunks/popover.js";
9
+ import { Sheet as ee, SheetContent as u, SheetTitle as d, SheetTrigger as te } from "../ui/sheet.js";
10
+ import { Tooltip as f, TooltipContent as p, TooltipTrigger as m } from "../ui/tooltip.js";
11
+ import { formatRelativeTime as h } from "../ui/lib/date-utils.js";
12
+ import * as g from "react";
13
+ import { useCallback as _, useRef as v } from "react";
14
+ import { Fragment as y, jsx as b, jsxs as x } from "react/jsx-runtime";
15
+ import { IconBell as S, IconChecks as C, IconInbox as w, IconX as T } from "@tabler/icons-react";
13
16
  //#region src/shell/notification-center.tsx
14
- function S(e, t) {
17
+ function E(e, t) {
15
18
  return e.getFullYear() === t.getFullYear() && e.getMonth() === t.getMonth() && e.getDate() === t.getDate();
16
19
  }
17
- function C(e) {
20
+ function D(e) {
18
21
  let t = new Date(e), n = /* @__PURE__ */ new Date(), r = /* @__PURE__ */ new Date();
19
- return r.setDate(n.getDate() - 1), S(t, n) ? "Today" : S(t, r) ? "Yesterday" : "Earlier";
22
+ return r.setDate(n.getDate() - 1), E(t, n) ? "Today" : E(t, r) ? "Yesterday" : "Earlier";
20
23
  }
21
- var w = {
24
+ var O = {
22
25
  INFO: "bg-info-9",
23
26
  IMPORTANT: "bg-warning-9",
24
27
  CRITICAL: "bg-error-9"
25
28
  };
26
- function T({ notification: e, onRead: t, onNavigate: r, getRoute: a, onDismiss: o }) {
27
- let s = a(e), c = () => {
28
- e.isRead || t(e.id), s && r(s);
29
+ function k({ notification: e, onRead: t, onNavigate: n, getRoute: i, onDismiss: o }) {
30
+ let s = i(e), c = () => {
31
+ e.isRead || t(e.id), s && n(s);
29
32
  };
30
- return /* @__PURE__ */ _("div", {
33
+ return /* @__PURE__ */ x("div", {
31
34
  role: "button",
32
35
  tabIndex: 0,
33
36
  onClick: c,
34
37
  onKeyDown: (e) => {
35
38
  (e.key === "Enter" || e.key === " ") && (e.preventDefault(), c());
36
39
  },
37
- className: n("group relative flex w-full cursor-pointer items-start gap-ds-04 px-ds-05 py-ds-04 text-left transition-colors duration-fast-02 ease-productive-standard", "hover:bg-surface-raised", !e.isRead && "bg-accent-1"),
40
+ className: r("group relative flex w-full cursor-pointer items-start gap-ds-04 px-ds-05 py-ds-04 text-left transition-colors duration-fast-02 ease-productive-standard", "hover:bg-surface-raised", !e.isRead && "bg-accent-1"),
38
41
  children: [
39
- /* @__PURE__ */ g("div", {
42
+ /* @__PURE__ */ b("div", {
40
43
  className: "mt-ds-02b flex shrink-0",
41
- children: /* @__PURE__ */ g("span", { className: n("h-[8px] w-[8px] rounded-ds-full transition-opacity duration-fast-02 ease-productive-standard", w[e.tier] || w.INFO, e.isRead ? "opacity-20" : "opacity-100") })
44
+ children: /* @__PURE__ */ b("span", { className: r("h-[8px] w-[8px] rounded-ds-full transition-opacity duration-fast-02 ease-productive-standard", O[e.tier] || O.INFO, e.isRead ? "opacity-20" : "opacity-100") })
42
45
  }),
43
- /* @__PURE__ */ _("div", {
46
+ /* @__PURE__ */ x("div", {
44
47
  className: "min-w-0 flex-1",
45
48
  children: [
46
- /* @__PURE__ */ g("p", {
47
- className: n("truncate text-ds-md text-surface-fg", !e.isRead && "font-semibold"),
49
+ /* @__PURE__ */ b("p", {
50
+ className: r("truncate text-ds-md text-surface-fg", !e.isRead && "font-semibold"),
48
51
  children: e.title
49
52
  }),
50
- e.body && /* @__PURE__ */ g("p", {
53
+ e.body && /* @__PURE__ */ b("p", {
51
54
  className: "mt-ds-01 line-clamp-2 text-ds-sm text-surface-fg-subtle",
52
55
  children: e.body
53
56
  }),
54
- /* @__PURE__ */ _("div", {
57
+ /* @__PURE__ */ x("div", {
55
58
  className: "mt-ds-02 flex items-center gap-ds-03",
56
- children: [/* @__PURE__ */ g("span", {
59
+ children: [/* @__PURE__ */ b("span", {
57
60
  className: "text-ds-sm text-surface-fg-subtle",
58
- children: d(e.createdAt)
59
- }), e.project && /* @__PURE__ */ _(h, { children: [/* @__PURE__ */ g("span", {
61
+ children: h(e.createdAt)
62
+ }), e.project && /* @__PURE__ */ x(y, { children: [/* @__PURE__ */ b("span", {
60
63
  className: "text-surface-fg-subtle",
61
64
  children: "·"
62
- }), /* @__PURE__ */ g("span", {
65
+ }), /* @__PURE__ */ b("span", {
63
66
  className: "truncate text-ds-sm text-surface-fg-subtle",
64
67
  children: e.project.title
65
68
  })] })]
66
69
  }),
67
- e.actions && e.actions.length > 0 && /* @__PURE__ */ g("div", {
70
+ e.actions && e.actions.length > 0 && /* @__PURE__ */ b("div", {
68
71
  className: "mt-ds-03 flex items-center gap-ds-02",
69
- children: e.actions.map((t) => /* @__PURE__ */ g("button", {
72
+ children: e.actions.map((t) => /* @__PURE__ */ b("button", {
70
73
  type: "button",
71
74
  onClick: (n) => {
72
75
  n.stopPropagation(), t.onClick(e.id);
73
76
  },
74
77
  onKeyDown: (e) => e.stopPropagation(),
75
- className: n("rounded-ds-md px-ds-03 py-ds-01 text-ds-sm font-medium transition-colors duration-fast-02 ease-productive-standard", t.variant === "primary" ? "bg-accent-9 text-accent-fg hover:bg-accent-10" : t.variant === "danger" ? "text-error-11 hover:bg-error-3" : "text-surface-fg-muted hover:bg-surface-raised-hover"),
78
+ className: r("rounded-ds-md px-ds-03 py-ds-01 text-ds-sm font-medium transition-colors duration-fast-02 ease-productive-standard", t.variant === "primary" ? "bg-accent-9 text-accent-fg hover:bg-accent-10" : t.variant === "danger" ? "text-error-11 hover:bg-error-3" : "text-surface-fg-muted hover:bg-surface-raised-hover"),
76
79
  children: t.label
77
80
  }, t.label))
78
81
  })
79
82
  ]
80
83
  }),
81
- o && /* @__PURE__ */ g("button", {
84
+ o && /* @__PURE__ */ b("button", {
82
85
  type: "button",
83
86
  "aria-label": `Dismiss notification: ${e.title}`,
84
87
  onClick: (t) => {
@@ -86,158 +89,180 @@ function T({ notification: e, onRead: t, onNavigate: r, getRoute: a, onDismiss:
86
89
  },
87
90
  onKeyDown: (e) => e.stopPropagation(),
88
91
  className: "absolute right-ds-03 top-ds-03 hidden rounded-ds-sm p-ds-01 text-surface-fg-subtle transition-[color,background-color,opacity] duration-fast-01 ease-productive-standard hover:bg-surface-raised-hover hover:text-surface-fg-muted group-hover:flex group-focus-within:flex",
89
- children: /* @__PURE__ */ g(i, {
90
- icon: x,
92
+ children: /* @__PURE__ */ b(a, {
93
+ icon: T,
91
94
  size: "sm"
92
95
  })
93
96
  })
94
97
  ]
95
98
  });
96
99
  }
97
- var E = f.forwardRef(({ notifications: d = [], unreadCount: f, open: h, onOpenChange: x, isLoading: S = !1, hasMore: w = !1, onFetchMore: E, onMarkRead: D, onMarkAllRead: O, onNavigate: k, getNotificationRoute: A, onDismiss: j, headerActions: M, emptyState: N, footerSlot: P, popoverClassName: F, className: I, ...L }, R) => {
98
- let z = m(null), B = t(), V = f ?? d.filter((e) => !e.isRead).length, H = A ?? (() => null), U = p((e) => {
99
- x?.(!1), k?.(e);
100
- }, [k, x]), W = p((e) => {
101
- D?.(e);
102
- }, [D]), G = p(() => {
103
- let e = z.current;
104
- !e || S || !w || e.scrollTop + e.clientHeight >= e.scrollHeight - 50 && E?.();
100
+ var A = g.forwardRef(({ notifications: h = [], unreadCount: g, open: T, onOpenChange: E, isLoading: O = !1, hasMore: A = !1, onFetchMore: j, onMarkRead: M, onMarkAllRead: N, onNavigate: P, getNotificationRoute: F, onDismiss: I, headerActions: L, emptyState: R, footerSlot: z, popoverClassName: B, className: V, ...H }, U) => {
101
+ let W = v(null), G = t(), K = o(), q = g ?? h.filter((e) => !e.isRead).length, J = F ?? (() => null), Y = _((e) => {
102
+ E?.(!1), P?.(e);
103
+ }, [P, E]), X = _((e) => {
104
+ M?.(e);
105
+ }, [M]), Z = _(() => {
106
+ let e = W.current;
107
+ !e || O || !A || e.scrollTop + e.clientHeight >= e.scrollHeight - 50 && j?.();
105
108
  }, [
106
- S,
107
- w,
108
- E
109
- ]), K = d.reduce((e, t) => {
110
- let n = C(t.createdAt);
109
+ O,
110
+ A,
111
+ j
112
+ ]), ne = h.reduce((e, t) => {
113
+ let n = D(t.createdAt);
111
114
  return e[n] || (e[n] = []), e[n].push(t), e;
112
- }, {}), q = [
113
- "Today",
114
- "Yesterday",
115
- "Earlier"
116
- ];
117
- return /* @__PURE__ */ _(s, {
118
- open: h,
119
- onOpenChange: x,
120
- children: [/* @__PURE__ */ _(c, { children: [/* @__PURE__ */ g(u, {
115
+ }, {}), Q = /* @__PURE__ */ x(y, { children: [
116
+ /* @__PURE__ */ x("div", {
117
+ className: "flex items-center justify-between border-b border-surface-border-strong px-ds-05 py-ds-04",
118
+ children: [/* @__PURE__ */ x("div", {
119
+ className: "flex items-center gap-ds-03",
120
+ children: [!K && /* @__PURE__ */ b("h3", {
121
+ className: "text-ds-md font-semibold text-surface-fg",
122
+ children: "Notifications"
123
+ }), q > 0 && /* @__PURE__ */ b("span", {
124
+ className: "flex h-5 min-w-5 items-center justify-center rounded-ds-full bg-accent-2 px-ds-02b text-ds-sm font-semibold text-accent-11",
125
+ children: q
126
+ })]
127
+ }), /* @__PURE__ */ x("div", {
128
+ className: "flex items-center gap-ds-03",
129
+ children: [q > 0 && N && /* @__PURE__ */ x("button", {
130
+ type: "button",
131
+ onClick: N,
132
+ className: "flex items-center gap-ds-02 text-ds-sm text-surface-fg-subtle transition-colors hover:text-accent-11",
133
+ children: [/* @__PURE__ */ b(a, {
134
+ icon: C,
135
+ size: "sm"
136
+ }), "Mark all read"]
137
+ }), L]
138
+ })]
139
+ }),
140
+ /* @__PURE__ */ x("div", {
141
+ ref: W,
142
+ onScroll: Z,
143
+ className: r("overflow-y-auto", K ? "max-h-[60vh]" : "max-h-[420px]"),
144
+ children: [h.length === 0 ? R || /* @__PURE__ */ x("div", {
145
+ className: "flex flex-col items-center justify-center px-ds-05 py-ds-09",
146
+ children: [
147
+ /* @__PURE__ */ b("div", {
148
+ className: "flex h-ds-lg w-ds-lg items-center justify-center rounded-ds-full bg-surface-raised",
149
+ children: /* @__PURE__ */ b(a, {
150
+ icon: w,
151
+ size: "lg",
152
+ className: "text-surface-fg-subtle"
153
+ })
154
+ }),
155
+ /* @__PURE__ */ b("p", {
156
+ className: "mt-ds-04 text-ds-md text-surface-fg-subtle",
157
+ children: "No notifications yet"
158
+ }),
159
+ /* @__PURE__ */ b("p", {
160
+ className: "mt-ds-02 text-ds-sm text-surface-fg-subtle",
161
+ children: "You're all caught up!"
162
+ })
163
+ ]
164
+ }) : [
165
+ "Today",
166
+ "Yesterday",
167
+ "Earlier"
168
+ ].map((t) => {
169
+ let n = ne[t];
170
+ return !n || n.length === 0 ? null : /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("div", {
171
+ className: "sticky top-0 z-raised bg-surface-overlay px-ds-05 py-ds-02b",
172
+ children: /* @__PURE__ */ b("span", {
173
+ className: "text-ds-sm font-medium text-surface-fg-subtle",
174
+ children: t
175
+ })
176
+ }), n.map((t, n) => /* @__PURE__ */ b(e.div, {
177
+ initial: G ? void 0 : { opacity: 0 },
178
+ animate: { opacity: 1 },
179
+ transition: G ? { duration: 0 } : { delay: n * .03 },
180
+ children: /* @__PURE__ */ b(k, {
181
+ notification: t,
182
+ onRead: X,
183
+ onNavigate: Y,
184
+ getRoute: J,
185
+ onDismiss: I
186
+ })
187
+ }, t.id))] }, t);
188
+ }), O && /* @__PURE__ */ b("div", {
189
+ className: "flex items-center justify-center py-ds-05",
190
+ children: /* @__PURE__ */ b(i, {})
191
+ })]
192
+ }),
193
+ z && /* @__PURE__ */ b("div", {
194
+ className: "border-t border-surface-border-strong px-ds-05 py-ds-03",
195
+ children: z
196
+ })
197
+ ] }), $ = /* @__PURE__ */ x("button", {
198
+ ...H,
199
+ ref: U,
200
+ "aria-label": q > 0 ? `Notifications, ${q} unread` : "Notifications",
201
+ className: r("relative flex h-ds-sm-plus w-ds-sm-plus items-center justify-center rounded-ds-full border border-surface-border-strong bg-surface-raised text-surface-fg-muted transition-colors ease-productive-standard hover:bg-surface-raised-hover", V),
202
+ children: [/* @__PURE__ */ b(a, {
203
+ icon: S,
204
+ size: "sm"
205
+ }), q > 0 && /* @__PURE__ */ b(e.span, {
206
+ initial: { rotate: 0 },
207
+ animate: G ? void 0 : { rotate: [
208
+ 0,
209
+ -3,
210
+ 3,
211
+ -1,
212
+ 1,
213
+ 0
214
+ ] },
215
+ transition: G ? { duration: 0 } : {
216
+ duration: n.slow01,
217
+ ease: "easeInOut"
218
+ },
219
+ className: "absolute -right-ds-01 -top-ds-01 flex h-4 min-w-4 items-center justify-center rounded-ds-full bg-accent-9 px-ds-02 text-ds-xs font-semibold text-accent-fg",
220
+ children: q > 99 ? "99+" : q
221
+ })]
222
+ });
223
+ return K ? /* @__PURE__ */ x(ee, {
224
+ open: T,
225
+ onOpenChange: E,
226
+ children: [/* @__PURE__ */ x(f, { children: [/* @__PURE__ */ b(m, {
121
227
  asChild: !0,
122
- children: /* @__PURE__ */ g(a, {
228
+ children: /* @__PURE__ */ b(te, {
123
229
  asChild: !0,
124
- children: /* @__PURE__ */ _("button", {
125
- ...L,
126
- ref: R,
127
- "aria-label": V > 0 ? `Notifications, ${V} unread` : "Notifications",
128
- className: n("relative flex h-ds-sm-plus w-ds-sm-plus items-center justify-center rounded-ds-full border border-surface-border-strong bg-surface-raised text-surface-fg-muted transition-colors ease-productive-standard hover:bg-surface-raised-hover", I),
129
- children: [/* @__PURE__ */ g(i, {
130
- icon: v,
131
- size: "sm"
132
- }), V > 0 && /* @__PURE__ */ g(e.span, {
133
- initial: { rotate: 0 },
134
- animate: B ? void 0 : { rotate: [
135
- 0,
136
- -3,
137
- 3,
138
- -1,
139
- 1,
140
- 0
141
- ] },
142
- transition: B ? { duration: 0 } : {
143
- duration: .4,
144
- ease: "easeInOut"
145
- },
146
- className: "absolute -right-ds-01 -top-ds-01 flex h-4 min-w-4 items-center justify-center rounded-ds-full bg-accent-9 px-ds-02 text-ds-xs font-semibold text-accent-fg",
147
- children: V > 99 ? "99+" : V
148
- })]
149
- })
230
+ children: $
150
231
  })
151
- }), /* @__PURE__ */ g(l, {
232
+ }), /* @__PURE__ */ b(p, {
152
233
  side: "bottom",
153
234
  align: "center",
154
235
  children: "Notifications"
155
- })] }), /* @__PURE__ */ _(o, {
156
- className: n("w-[380px] rounded-ds-xl border border-surface-border-strong bg-surface-overlay p-0 shadow-floating", F),
236
+ })] }), /* @__PURE__ */ x(u, {
237
+ side: "bottom",
238
+ className: r("p-0", B),
239
+ responsive: !1,
240
+ children: [/* @__PURE__ */ b(d, {
241
+ className: "px-ds-05 pt-ds-04 text-ds-md font-semibold text-surface-fg",
242
+ children: "Notifications"
243
+ }), Q]
244
+ })]
245
+ }) : /* @__PURE__ */ x(l, {
246
+ open: T,
247
+ onOpenChange: E,
248
+ children: [/* @__PURE__ */ x(f, { children: [/* @__PURE__ */ b(m, {
249
+ asChild: !0,
250
+ children: /* @__PURE__ */ b(s, {
251
+ asChild: !0,
252
+ children: $
253
+ })
254
+ }), /* @__PURE__ */ b(p, {
255
+ side: "bottom",
256
+ align: "center",
257
+ children: "Notifications"
258
+ })] }), /* @__PURE__ */ b(c, {
259
+ className: r("w-[380px] rounded-ds-xl border border-surface-border-strong bg-surface-overlay p-0 shadow-floating", B),
157
260
  sideOffset: 8,
158
261
  align: "end",
159
- children: [
160
- /* @__PURE__ */ _("div", {
161
- className: "flex items-center justify-between border-b border-surface-border-strong px-ds-05 py-ds-04",
162
- children: [/* @__PURE__ */ _("div", {
163
- className: "flex items-center gap-ds-03",
164
- children: [/* @__PURE__ */ g("h3", {
165
- className: "text-ds-md font-semibold text-surface-fg",
166
- children: "Notifications"
167
- }), V > 0 && /* @__PURE__ */ g("span", {
168
- className: "flex h-5 min-w-5 items-center justify-center rounded-ds-full bg-accent-2 px-ds-02b text-ds-sm font-semibold text-accent-11",
169
- children: V
170
- })]
171
- }), /* @__PURE__ */ _("div", {
172
- className: "flex items-center gap-ds-03",
173
- children: [V > 0 && O && /* @__PURE__ */ _("button", {
174
- type: "button",
175
- onClick: O,
176
- className: "flex items-center gap-ds-02 text-ds-sm text-surface-fg-subtle transition-colors hover:text-accent-11",
177
- children: [/* @__PURE__ */ g(i, {
178
- icon: y,
179
- size: "sm"
180
- }), "Mark all read"]
181
- }), M]
182
- })]
183
- }),
184
- /* @__PURE__ */ _("div", {
185
- ref: z,
186
- onScroll: G,
187
- className: "max-h-[420px] overflow-y-auto",
188
- children: [d.length === 0 ? N || /* @__PURE__ */ _("div", {
189
- className: "flex flex-col items-center justify-center px-ds-05 py-ds-09",
190
- children: [
191
- /* @__PURE__ */ g("div", {
192
- className: "flex h-ds-lg w-ds-lg items-center justify-center rounded-ds-full bg-surface-raised",
193
- children: /* @__PURE__ */ g(i, {
194
- icon: b,
195
- size: "lg",
196
- className: "text-surface-fg-subtle"
197
- })
198
- }),
199
- /* @__PURE__ */ g("p", {
200
- className: "mt-ds-04 text-ds-md text-surface-fg-subtle",
201
- children: "No notifications yet"
202
- }),
203
- /* @__PURE__ */ g("p", {
204
- className: "mt-ds-02 text-ds-sm text-surface-fg-subtle",
205
- children: "You're all caught up!"
206
- })
207
- ]
208
- }) : q.map((t) => {
209
- let n = K[t];
210
- return !n || n.length === 0 ? null : /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("div", {
211
- className: "sticky top-0 z-raised bg-surface-overlay px-ds-05 py-ds-02b",
212
- children: /* @__PURE__ */ g("span", {
213
- className: "text-ds-sm font-medium text-surface-fg-subtle",
214
- children: t
215
- })
216
- }), n.map((t, n) => /* @__PURE__ */ g(e.div, {
217
- initial: B ? void 0 : { opacity: 0 },
218
- animate: { opacity: 1 },
219
- transition: B ? { duration: 0 } : { delay: n * .03 },
220
- children: /* @__PURE__ */ g(T, {
221
- notification: t,
222
- onRead: W,
223
- onNavigate: U,
224
- getRoute: H,
225
- onDismiss: j
226
- })
227
- }, t.id))] }, t);
228
- }), S && /* @__PURE__ */ g("div", {
229
- className: "flex items-center justify-center py-ds-05",
230
- children: /* @__PURE__ */ g(r, {})
231
- })]
232
- }),
233
- P && /* @__PURE__ */ g("div", {
234
- className: "border-t border-surface-border-strong px-ds-05 py-ds-03",
235
- children: P
236
- })
237
- ]
262
+ children: Q
238
263
  })]
239
264
  });
240
265
  });
241
- E.displayName = "NotificationCenter";
266
+ A.displayName = "NotificationCenter";
242
267
  //#endregion
243
- export { E as NotificationCenter };
268
+ export { A as NotificationCenter };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification-center.js","names":[],"sources":["../../src/shell/notification-center.tsx"],"sourcesContent":["'use client'\n\n/**\n * NotificationCenter -- Popover-based notification panel.\n *\n * Props-driven: accepts notifications array and callbacks instead of\n * reading from Zustand stores or using Remix useNavigate.\n */\nimport * as React from 'react'\nimport { useRef, useCallback } from 'react'\nimport { formatRelativeTime } from '../ui/lib/date-utils'\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '../ui/popover'\nimport {\n Sheet,\n SheetContent,\n SheetTitle,\n SheetTrigger,\n} from '../ui/sheet'\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from '../ui/tooltip'\nimport { IconBell, IconChecks, IconInbox, IconX } from '@tabler/icons-react'\nimport { Icon } from '../ui/icon'\nimport { cn } from '../ui/lib/utils'\nimport { Spinner } from '../ui/spinner'\nimport { useIsMobile } from '../hooks/use-mobile'\nimport { motion, useReducedMotion } from 'framer-motion'\nimport { durations } from '../ui/lib/motion'\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\nexport interface NotificationAction {\n /** Button label */\n label: string\n /** Visual style — 'primary' is filled, 'default' is ghost, 'danger' is red ghost */\n variant?: 'primary' | 'default' | 'danger'\n /** Called when the action button is clicked. Receives the notification id. */\n onClick: (id: string) => void\n}\n\nexport interface Notification {\n id: string\n title: string\n body?: string | null\n tier: 'INFO' | 'IMPORTANT' | 'CRITICAL'\n isRead: boolean\n createdAt: string\n entityType?: string | null\n entityId?: string | null\n projectId?: string | null\n project?: { title: string } | null\n /** Inline action buttons (e.g. Approve / Deny). Max 2–3 recommended. */\n actions?: NotificationAction[]\n}\n\nexport interface NotificationCenterProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** List of notifications to display */\n notifications?: Notification[]\n /** Count of unread notifications (derived from notifications if not provided) */\n unreadCount?: number\n /** Whether the popover is open (controlled mode) */\n open?: boolean\n /** Called when the popover open state changes */\n onOpenChange?: (open: boolean) => void\n /** Whether more notifications are loading */\n isLoading?: boolean\n /** Whether there are more notifications to fetch */\n hasMore?: boolean\n /** Called when the user scrolls near the bottom to load more */\n onFetchMore?: () => void\n /** Called to mark a single notification as read */\n onMarkRead?: (id: string) => void\n /** Called to mark all notifications as read */\n onMarkAllRead?: () => void\n /** Called when the user clicks a notification (e.g., navigate to entity) */\n onNavigate?: (path: string) => void\n /** Resolve a notification to a navigation path. Return null if no navigation. */\n getNotificationRoute?: (notification: Notification) => string | null\n /** Additional actions rendered in the header (e.g., settings button) */\n headerActions?: React.ReactNode\n /** Custom empty state to display when there are no notifications */\n emptyState?: React.ReactNode\n /** Content rendered below the notification list as a footer */\n footerSlot?: React.ReactNode\n /** Called when the user dismisses a notification. Renders an X button per row when provided. */\n onDismiss?: (id: string) => void\n /** Additional className for the popover content container */\n popoverClassName?: string\n /** Additional className */\n className?: string\n}\n\n// -----------------------------------------------------------------------\n// Helpers\n// -----------------------------------------------------------------------\n\n\nfunction isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n )\n}\n\nfunction getDateGroup(dateStr: string): string {\n const date = new Date(dateStr)\n const today = new Date()\n const yesterday = new Date()\n yesterday.setDate(today.getDate() - 1)\n\n if (isSameDay(date, today)) return 'Today'\n if (isSameDay(date, yesterday)) return 'Yesterday'\n return 'Earlier'\n}\n\nconst TIER_COLORS: Record<string, string> = {\n INFO: 'bg-info-9',\n IMPORTANT: 'bg-warning-9',\n CRITICAL: 'bg-error-9',\n}\n\n// -----------------------------------------------------------------------\n// NotificationItem (internal)\n// -----------------------------------------------------------------------\n\nfunction NotificationItem({\n notification,\n onRead,\n onNavigate,\n getRoute,\n onDismiss,\n}: {\n notification: Notification\n onRead: (id: string) => void\n onNavigate: (path: string) => void\n getRoute: (notification: Notification) => string | null\n onDismiss?: (id: string) => void\n}) {\n const route = getRoute(notification)\n\n const handleClick = () => {\n if (!notification.isRead) {\n onRead(notification.id)\n }\n if (route) {\n onNavigate(route)\n }\n }\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n handleClick()\n }\n }\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n className={cn(\n 'group relative flex w-full cursor-pointer items-start gap-ds-04 px-ds-05 py-ds-04 text-left transition-colors duration-fast-02 ease-productive-standard',\n 'hover:bg-surface-raised',\n !notification.isRead && 'bg-accent-1',\n )}\n >\n {/* Tier dot — doubles as read/unread marker */}\n <div className=\"mt-ds-02b flex shrink-0\">\n <span\n className={cn(\n 'h-[8px] w-[8px] rounded-ds-full transition-opacity duration-fast-02 ease-productive-standard',\n TIER_COLORS[notification.tier] || TIER_COLORS.INFO,\n notification.isRead ? 'opacity-20' : 'opacity-100',\n )}\n />\n </div>\n\n {/* Content */}\n <div className=\"min-w-0 flex-1\">\n <p\n className={cn(\n 'truncate text-ds-md text-surface-fg',\n !notification.isRead && 'font-semibold',\n )}\n >\n {notification.title}\n </p>\n {notification.body && (\n <p className=\"mt-ds-01 line-clamp-2 text-ds-sm text-surface-fg-subtle\">\n {notification.body}\n </p>\n )}\n <div className=\"mt-ds-02 flex items-center gap-ds-03\">\n <span className=\"text-ds-sm text-surface-fg-subtle\">\n {formatRelativeTime(notification.createdAt)}\n </span>\n {notification.project && (\n <>\n <span className=\"text-surface-fg-subtle\">\n &middot;\n </span>\n <span className=\"truncate text-ds-sm text-surface-fg-subtle\">\n {notification.project.title}\n </span>\n </>\n )}\n </div>\n\n {/* Inline actions */}\n {notification.actions && notification.actions.length > 0 && (\n <div className=\"mt-ds-03 flex items-center gap-ds-02\">\n {notification.actions.map((action) => (\n <button\n key={action.label}\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n action.onClick(notification.id)\n }}\n onKeyDown={(e) => e.stopPropagation()}\n className={cn(\n 'rounded-ds-md px-ds-03 py-ds-01 text-ds-sm font-medium transition-colors duration-fast-02 ease-productive-standard',\n action.variant === 'primary'\n ? 'bg-accent-9 text-accent-fg hover:bg-accent-10'\n : action.variant === 'danger'\n ? 'text-error-11 hover:bg-error-3'\n : 'text-surface-fg-muted hover:bg-surface-raised-hover',\n )}\n >\n {action.label}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Dismiss button */}\n {onDismiss && (\n <button\n type=\"button\"\n aria-label={`Dismiss notification: ${notification.title}`}\n onClick={(e) => {\n e.stopPropagation()\n onDismiss(notification.id)\n }}\n onKeyDown={(e) => e.stopPropagation()}\n className=\"absolute right-ds-03 top-ds-03 hidden rounded-ds-sm p-ds-01 text-surface-fg-subtle transition-[color,background-color,opacity] duration-fast-01 ease-productive-standard hover:bg-surface-raised-hover hover:text-surface-fg-muted group-hover:flex group-focus-within:flex\"\n >\n <Icon icon={IconX} size=\"sm\" />\n </button>\n )}\n </div>\n )\n}\n\n// -----------------------------------------------------------------------\n// NotificationCenter\n// -----------------------------------------------------------------------\n\nconst NotificationCenter = React.forwardRef<HTMLButtonElement, NotificationCenterProps>(\n (\n {\n notifications = [],\n unreadCount: unreadCountProp,\n open,\n onOpenChange,\n isLoading = false,\n hasMore = false,\n onFetchMore,\n onMarkRead,\n onMarkAllRead,\n onNavigate,\n getNotificationRoute,\n onDismiss,\n headerActions,\n emptyState,\n footerSlot,\n popoverClassName,\n className,\n ...props\n },\n ref,\n ) => {\n const scrollRef = useRef<HTMLDivElement>(null)\n const prefersReducedMotion = useReducedMotion()\n const isMobile = useIsMobile()\n\n const unreadCount =\n unreadCountProp ?? notifications.filter((n) => !n.isRead).length\n\n const getRoute = getNotificationRoute ?? (() => null)\n\n const handleNavigate = useCallback(\n (path: string) => {\n onOpenChange?.(false)\n onNavigate?.(path)\n },\n [onNavigate, onOpenChange],\n )\n\n const handleMarkRead = useCallback(\n (id: string) => {\n onMarkRead?.(id)\n },\n [onMarkRead],\n )\n\n const handleScroll = useCallback(() => {\n const el = scrollRef.current\n if (!el || isLoading || !hasMore) return\n if (el.scrollTop + el.clientHeight >= el.scrollHeight - 50) {\n onFetchMore?.()\n }\n }, [isLoading, hasMore, onFetchMore])\n\n // Group notifications by date\n const grouped = notifications.reduce<Record<string, Notification[]>>(\n (acc, n) => {\n const group = getDateGroup(n.createdAt)\n if (!acc[group]) acc[group] = []\n acc[group].push(n)\n return acc\n },\n {},\n )\n\n const groupOrder = ['Today', 'Yesterday', 'Earlier']\n\n // -- Shared panel content (used in both Popover and Sheet) --\n const panelContent = (\n <>\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-surface-border-strong px-ds-05 py-ds-04\">\n <div className=\"flex items-center gap-ds-03\">\n {/* On mobile the SheetTitle provides the accessible heading; on desktop use h3 */}\n {!isMobile && (\n <h3 className=\"text-ds-md font-semibold text-surface-fg\">\n Notifications\n </h3>\n )}\n {unreadCount > 0 && (\n <span className=\"flex h-5 min-w-5 items-center justify-center rounded-ds-full bg-accent-2 px-ds-02b text-ds-sm font-semibold text-accent-11\">\n {unreadCount}\n </span>\n )}\n </div>\n <div className=\"flex items-center gap-ds-03\">\n {unreadCount > 0 && onMarkAllRead && (\n <button\n type=\"button\"\n onClick={onMarkAllRead}\n className=\"flex items-center gap-ds-02 text-ds-sm text-surface-fg-subtle transition-colors hover:text-accent-11\"\n >\n <Icon icon={IconChecks} size=\"sm\" />\n Mark all read\n </button>\n )}\n {headerActions}\n </div>\n </div>\n\n {/* Notification list */}\n <div\n ref={scrollRef}\n onScroll={handleScroll}\n className={cn('overflow-y-auto', isMobile ? 'max-h-[60vh]' : 'max-h-[420px]')}\n >\n {notifications.length === 0 ? (\n emptyState || (\n <div className=\"flex flex-col items-center justify-center px-ds-05 py-ds-09\">\n <div className=\"flex h-ds-lg w-ds-lg items-center justify-center rounded-ds-full bg-surface-raised\">\n <Icon icon={IconInbox} size=\"lg\" className=\"text-surface-fg-subtle\" />\n </div>\n <p className=\"mt-ds-04 text-ds-md text-surface-fg-subtle\">\n No notifications yet\n </p>\n <p className=\"mt-ds-02 text-ds-sm text-surface-fg-subtle\">\n You&apos;re all caught up!\n </p>\n </div>\n )\n ) : (\n groupOrder.map((group) => {\n const items = grouped[group]\n if (!items || items.length === 0) return null\n return (\n <div key={group}>\n <div className=\"sticky top-0 z-raised bg-surface-overlay px-ds-05 py-ds-02b\">\n <span className=\"text-ds-sm font-medium text-surface-fg-subtle\">\n {group}\n </span>\n </div>\n {items.map((notification, index) => (\n <motion.div\n key={notification.id}\n initial={prefersReducedMotion ? undefined : { opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={prefersReducedMotion ? { duration: 0 } : { delay: index * 0.03 }}\n >\n <NotificationItem\n notification={notification}\n onRead={handleMarkRead}\n onNavigate={handleNavigate}\n getRoute={getRoute}\n onDismiss={onDismiss}\n />\n </motion.div>\n ))}\n </div>\n )\n })\n )}\n\n {isLoading && (\n <div className=\"flex items-center justify-center py-ds-05\">\n <Spinner />\n </div>\n )}\n </div>\n {footerSlot && (\n <div className=\"border-t border-surface-border-strong px-ds-05 py-ds-03\">\n {footerSlot}\n </div>\n )}\n </>\n )\n\n // -- Trigger button (shared between both modes) --\n const triggerButton = (\n <button\n {...props}\n ref={ref}\n aria-label={unreadCount > 0 ? `Notifications, ${unreadCount} unread` : 'Notifications'}\n className={cn(\n 'relative flex h-ds-sm-plus w-ds-sm-plus items-center justify-center rounded-ds-full border border-surface-border-strong bg-surface-raised text-surface-fg-muted transition-colors ease-productive-standard hover:bg-surface-raised-hover',\n className,\n )}\n >\n <Icon icon={IconBell} size=\"sm\" />\n {unreadCount > 0 && (\n <motion.span\n initial={{ rotate: 0 }}\n animate={prefersReducedMotion ? undefined : { rotate: [0, -3, 3, -1, 1, 0] }}\n transition={prefersReducedMotion ? { duration: 0 } : { duration: durations.slow01, ease: 'easeInOut' }}\n className=\"absolute -right-ds-01 -top-ds-01 flex h-4 min-w-4 items-center justify-center rounded-ds-full bg-accent-9 px-ds-02 text-ds-xs font-semibold text-accent-fg\"\n >\n {unreadCount > 99 ? '99+' : unreadCount}\n </motion.span>\n )}\n </button>\n )\n\n // -- Mobile: render in a bottom Sheet --\n if (isMobile) {\n return (\n <Sheet open={open} onOpenChange={onOpenChange}>\n <Tooltip>\n <TooltipTrigger asChild>\n <SheetTrigger asChild>\n {triggerButton}\n </SheetTrigger>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" align=\"center\">\n Notifications\n </TooltipContent>\n </Tooltip>\n\n <SheetContent side=\"bottom\" className={cn('p-0', popoverClassName)} responsive={false}>\n <SheetTitle className=\"px-ds-05 pt-ds-04 text-ds-md font-semibold text-surface-fg\">\n Notifications\n </SheetTitle>\n {panelContent}\n </SheetContent>\n </Sheet>\n )\n }\n\n // -- Desktop: render in a Popover --\n return (\n <Popover open={open} onOpenChange={onOpenChange}>\n <Tooltip>\n <TooltipTrigger asChild>\n <PopoverTrigger asChild>\n {triggerButton}\n </PopoverTrigger>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" align=\"center\">\n Notifications\n </TooltipContent>\n </Tooltip>\n\n <PopoverContent\n className={cn(\n 'w-[380px] rounded-ds-xl border border-surface-border-strong bg-surface-overlay p-0 shadow-floating',\n popoverClassName,\n )}\n sideOffset={8}\n align=\"end\"\n >\n {panelContent}\n </PopoverContent>\n </Popover>\n )\n },\n)\nNotificationCenter.displayName = 'NotificationCenter'\n\nexport { NotificationCenter }\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification-preferences.js","names":[],"sources":["../../src/shell/notification-preferences.tsx"],"sourcesContent":["'use client'\n\n/**\n * NotificationPreferences -- Manage notification rules per channel/project.\n *\n * Props-driven: accepts preferences array, projects, and callbacks.\n * No internal fetching -- the consumer is responsible for data loading.\n */\nimport * as React from 'react'\nimport { useState } from 'react'\nimport { Button } from '../ui/button'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../ui/select'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '../ui/dialog'\nimport { Switch } from '../ui/switch'\nimport { Card, CardHeader, CardTitle, CardContent } from '../ui/card'\nimport { IconPlus, IconTrash, IconBell, IconMessage } from '@tabler/icons-react'\nimport { Icon } from '../ui/icon'\nimport { cn } from '../ui/lib/utils'\nimport { Spinner } from '../ui/spinner'\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\nexport interface NotificationPreference {\n id: string\n userId?: string\n projectId: string | null\n channel: string\n minTier: string\n muted: boolean\n}\n\nexport interface NotificationProject {\n id: string\n title: string\n}\n\nexport interface NotificationPreferencesProps\n extends Omit<React.ComponentPropsWithRef<'div'>, 'onSave'> {\n /** Current preference rules */\n preferences?: NotificationPreference[]\n /** Available projects for scoping rules */\n projects?: NotificationProject[]\n /** Whether data is loading */\n isLoading?: boolean\n /** Called to add or update a preference */\n onSave?: (preference: {\n projectId: string | null\n channel: string\n minTier: string\n muted: boolean\n }) => void | Promise<void>\n /** Called to toggle mute on a preference */\n onToggleMute?: (preference: NotificationPreference) => void | Promise<void>\n /** Called to update the tier on a preference */\n onUpdateTier?: (\n preference: NotificationPreference,\n newTier: string,\n ) => void | Promise<void>\n /** Called to delete a preference */\n onDelete?: (preferenceId: string) => void | Promise<void>\n /** Additional className */\n className?: string\n}\n\n// -----------------------------------------------------------------------\n// Constants\n// -----------------------------------------------------------------------\n\nconst CHANNEL_LABELS: Record<string, { label: string; icon: React.ReactNode }> = {\n IN_APP: { label: 'In-App', icon: <Icon icon={IconBell} size=\"sm\" /> },\n GOOGLE_CHAT: { label: 'Google Chat', icon: <Icon icon={IconMessage} size=\"sm\" /> },\n}\n\nconst TIER_LABELS: Record<string, string> = {\n INFO: 'All (Info+)',\n IMPORTANT: 'Important+',\n CRITICAL: 'Critical only',\n}\n\n// -----------------------------------------------------------------------\n// NotificationPreferences\n// -----------------------------------------------------------------------\n\nconst NotificationPreferences = React.forwardRef<HTMLDivElement, NotificationPreferencesProps>(\n function NotificationPreferences(\n {\n preferences = [],\n projects = [],\n isLoading = false,\n onSave,\n onToggleMute,\n onUpdateTier,\n onDelete,\n className,\n ...props\n },\n ref,\n ) {\n const [showAddDialog, setShowAddDialog] = useState(false)\n const [newProjectId, setNewProjectId] = useState<string>('global')\n const [newChannel, setNewChannel] = useState<string>('IN_APP')\n const [newMinTier, setNewMinTier] = useState<string>('INFO')\n const [newMuted, setNewMuted] = useState(false)\n const [isSaving, setIsSaving] = useState(false)\n\n const handleAdd = async () => {\n if (!onSave) return\n setIsSaving(true)\n try {\n await onSave({\n projectId: newProjectId === 'global' ? null : newProjectId,\n channel: newChannel,\n minTier: newMinTier,\n muted: newMuted,\n })\n setShowAddDialog(false)\n resetForm()\n } catch (error) {\n console.error('[Preferences] Failed to save:', error)\n } finally {\n setIsSaving(false)\n }\n }\n\n const resetForm = () => {\n setNewProjectId('global')\n setNewChannel('IN_APP')\n setNewMinTier('INFO')\n setNewMuted(false)\n }\n\n const getProjectName = (projectId: string | null) => {\n if (!projectId) return 'Global (all projects)'\n const project = projects.find((p) => p.id === projectId)\n return project?.title || 'Unknown project'\n }\n\n return (\n <>\n <Card ref={ref} className={className} {...(props as Omit<typeof props, 'color'>)}>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-ds-04\">\n <CardTitle className=\"text-ds-md font-semibold\">\n Notification Preferences\n </CardTitle>\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => setShowAddDialog(true)}\n >\n <Icon icon={IconPlus} size=\"sm\" className=\"mr-ds-02b\" />\n Add Rule\n </Button>\n </CardHeader>\n <CardContent>\n {isLoading ? (\n <div className=\"flex items-center justify-center py-ds-07\">\n <Spinner />\n </div>\n ) : preferences.length === 0 ? (\n <div className=\"py-ds-07 text-center\">\n <p className=\"text-ds-md text-surface-fg-subtle\">\n No custom preferences set. All notifications are delivered by\n default.\n </p>\n </div>\n ) : (\n <div className=\"flex flex-col\">\n {preferences.map((pref, i) => {\n const channelInfo =\n CHANNEL_LABELS[pref.channel] || CHANNEL_LABELS.IN_APP\n return (\n <div\n key={pref.id}\n className={cn(\n 'flex items-center gap-ds-05 py-ds-04',\n i < preferences.length - 1 &&\n 'border-b border-surface-border-strong',\n )}\n >\n {/* Channel icon */}\n <div className=\"flex h-ds-sm w-ds-sm shrink-0 items-center justify-center rounded-ds-lg bg-surface-raised\">\n <span className=\"[&>svg]:h-ico-sm [&>svg]:w-ico-sm text-surface-fg-muted\" aria-hidden=\"true\">{channelInfo.icon}</span>\n </div>\n\n {/* Info */}\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-ds-md font-medium text-surface-fg\">\n {channelInfo.label}\n </p>\n <p className=\"text-ds-sm text-surface-fg-subtle\">\n {getProjectName(pref.projectId)}\n </p>\n </div>\n\n {/* Min tier */}\n <Select\n value={pref.minTier}\n onValueChange={(v) => onUpdateTier?.(pref, v)}\n >\n <SelectTrigger className=\"h-ds-xs-plus w-[130px] text-ds-sm\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {Object.entries(TIER_LABELS).map(([key, label]) => (\n <SelectItem key={key} value={key}>\n {label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n\n {/* Muted toggle */}\n <div className=\"flex items-center gap-ds-02b\">\n <span className=\"text-ds-sm text-surface-fg-subtle\">\n {pref.muted ? 'Muted' : 'Active'}\n </span>\n <Switch\n checked={!pref.muted}\n onCheckedChange={() => onToggleMute?.(pref)}\n />\n </div>\n\n {/* Delete */}\n <button\n type=\"button\"\n onClick={() => onDelete?.(pref.id)}\n className=\"shrink-0 rounded p-ds-02b text-surface-fg-subtle transition-colors hover:bg-surface-raised hover:text-error-11\"\n >\n <Icon icon={IconTrash} size=\"sm\" />\n </button>\n </div>\n )\n })}\n </div>\n )}\n </CardContent>\n </Card>\n\n {/* Add Preference Dialog */}\n <Dialog open={showAddDialog} onOpenChange={setShowAddDialog}>\n <DialogContent className=\"sm:max-w-md\">\n <DialogHeader>\n <DialogTitle>Add Notification Rule</DialogTitle>\n <DialogDescription>\n Customize how you receive notifications for a specific channel\n and project.\n </DialogDescription>\n </DialogHeader>\n <div className=\"flex flex-col gap-ds-05 pt-ds-03\">\n <div className=\"flex flex-col gap-ds-02b\">\n <label htmlFor=\"pref-scope\" className=\"text-ds-sm font-medium text-surface-fg-muted\">\n Scope\n </label>\n <Select value={newProjectId} onValueChange={setNewProjectId}>\n <SelectTrigger id=\"pref-scope\">\n <SelectValue placeholder=\"Select scope\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"global\">\n Global (all projects)\n </SelectItem>\n {projects.map((p) => (\n <SelectItem key={p.id} value={p.id}>\n {p.title}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"flex flex-col gap-ds-02b\">\n <label htmlFor=\"pref-channel\" className=\"text-ds-sm font-medium text-surface-fg-muted\">\n Channel\n </label>\n <Select value={newChannel} onValueChange={setNewChannel}>\n <SelectTrigger id=\"pref-channel\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"IN_APP\">In-App</SelectItem>\n <SelectItem value=\"GOOGLE_CHAT\">Google Chat</SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"flex flex-col gap-ds-02b\">\n <label htmlFor=\"pref-min-tier\" className=\"text-ds-sm font-medium text-surface-fg-muted\">\n Minimum Tier\n </label>\n <Select value={newMinTier} onValueChange={setNewMinTier}>\n <SelectTrigger id=\"pref-min-tier\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {Object.entries(TIER_LABELS).map(([key, label]) => (\n <SelectItem key={key} value={key}>\n {label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"flex items-center justify-between\">\n <label htmlFor=\"pref-muted\" className=\"text-ds-md text-surface-fg\">\n Mute this channel\n </label>\n <Switch id=\"pref-muted\" checked={newMuted} onCheckedChange={setNewMuted} />\n </div>\n\n <div className=\"flex justify-end gap-ds-03 pt-ds-03\">\n <Button\n variant=\"ghost\"\n onClick={() => {\n setShowAddDialog(false)\n resetForm()\n }}\n >\n Cancel\n </Button>\n <Button\n onClick={handleAdd}\n disabled={isSaving}\n >\n {isSaving ? 'Saving...' : 'Save Rule'}\n </Button>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n </>\n )\n },\n)\n\nNotificationPreferences.displayName = 'NotificationPreferences'\n\nexport { NotificationPreferences }\n"],"mappings":";;;;;;;;;;;;;;AAkFA,IAAM,IAA2E;CAC/E,QAAQ;EAAE,OAAO;EAAU,MAAM,kBAAC,GAAD;GAAM,MAAM;GAAU,MAAK;GAAO,CAAA;EAAE;CACrE,aAAa;EAAE,OAAO;EAAe,MAAM,kBAAC,GAAD;GAAM,MAAM;GAAa,MAAK;GAAO,CAAA;EAAE;CACnF,EAEK,IAAsC;CAC1C,MAAM;CACN,WAAW;CACX,UAAU;CACX,EAMK,IAA0B,EAAM,WACpC,SACE,EACE,iBAAc,EAAE,EAChB,cAAW,EAAE,EACb,eAAY,IACZ,WACA,iBACA,iBACA,aACA,cACA,GAAG,KAEL,GACA;CACF,IAAM,CAAC,GAAe,KAAoB,EAAS,GAAM,EACnD,CAAC,GAAc,KAAmB,EAAiB,SAAS,EAC5D,CAAC,GAAY,KAAiB,EAAiB,SAAS,EACxD,CAAC,GAAY,KAAiB,EAAiB,OAAO,EACtD,CAAC,GAAU,KAAe,EAAS,GAAM,EACzC,CAAC,GAAU,KAAe,EAAS,GAAM,EAEzC,IAAY,YAAY;AACvB,SACL;KAAY,GAAK;AACjB,OAAI;AAQF,IAPA,MAAM,EAAO;KACX,WAAW,MAAiB,WAAW,OAAO;KAC9C,SAAS;KACT,SAAS;KACT,OAAO;KACR,CAAC,EACF,EAAiB,GAAM,EACvB,GAAW;YACJ,GAAO;AACd,YAAQ,MAAM,iCAAiC,EAAM;aAC7C;AACR,MAAY,GAAM;;;IAIhB,UAAkB;AAItB,EAHA,EAAgB,SAAS,EACzB,EAAc,SAAS,EACvB,EAAc,OAAO,EACrB,EAAY,GAAM;IAGd,KAAkB,MACjB,IACW,EAAS,MAAM,MAAM,EAAE,OAAO,EAAU,EACxC,SAAS,oBAFF;AAKzB,QACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD;EAAW;EAAgB;EAAW,GAAK;YAA3C,CACE,kBAAC,GAAD;GAAY,WAAU;aAAtB,CACE,kBAAC,GAAD;IAAW,WAAU;cAA2B;IAEpC,CAAA,EACZ,kBAAC,GAAD;IACE,MAAK;IACL,SAAQ;IACR,eAAe,EAAiB,GAAK;cAHvC,CAKE,kBAAC,GAAD;KAAM,MAAM;KAAU,MAAK;KAAK,WAAU;KAAc,CAAA,EAAA,WAEjD;MACE;MACb,kBAAC,GAAD,EAAA,UACG,IACC,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,GAAD,EAAW,CAAA;GACP,CAAA,GACJ,EAAY,WAAW,IACzB,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,KAAD;IAAG,WAAU;cAAoC;IAG7C,CAAA;GACA,CAAA,GAEN,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAY,KAAK,GAAM,MAAM;IAC5B,IAAM,IACJ,EAAe,EAAK,YAAY,EAAe;AACjD,WACE,kBAAC,OAAD;KAEE,WAAW,EACT,wCACA,IAAI,EAAY,SAAS,KACvB,wCACH;eANH;MASE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,QAAD;QAAM,WAAU;QAA0D,eAAY;kBAAQ,EAAY;QAAY,CAAA;OAClH,CAAA;MAGN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAY;QACX,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAe,EAAK,UAAU;QAC7B,CAAA,CACA;;MAGN,kBAAC,GAAD;OACE,OAAO,EAAK;OACZ,gBAAgB,MAAM,IAAe,GAAM,EAAE;iBAF/C,CAIE,kBAAC,GAAD;QAAe,WAAU;kBACvB,kBAAC,GAAD,EAAe,CAAA;QACD,CAAA,EAChB,kBAAC,GAAD,EAAA,UACG,OAAO,QAAQ,EAAY,CAAC,KAAK,CAAC,GAAK,OACtC,kBAAC,GAAD;QAAsB,OAAO;kBAC1B;QACU,EAFI,EAEJ,CACb,EACY,CAAA,CACT;;MAGT,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,QAAD;QAAM,WAAU;kBACb,EAAK,QAAQ,UAAU;QACnB,CAAA,EACP,kBAAC,GAAD;QACE,SAAS,CAAC,EAAK;QACf,uBAAuB,IAAe,EAAK;QAC3C,CAAA,CACE;;MAGN,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,IAAW,EAAK,GAAG;OAClC,WAAU;iBAEV,kBAAC,GAAD;QAAM,MAAM;QAAW,MAAK;QAAO,CAAA;OAC5B,CAAA;MACL;OA1DC,EAAK,GA0DN;KAER;GACE,CAAA,EAEI,CAAA,CACT;KAGP,kBAAC,GAAD;EAAQ,MAAM;EAAe,cAAc;YACzC,kBAAC,GAAD;GAAe,WAAU;aAAzB,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAa,yBAAmC,CAAA,EAChD,kBAAC,GAAD,EAAA,UAAmB,+EAGC,CAAA,CACP,EAAA,CAAA,EACf,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,SAAD;OAAO,SAAQ;OAAa,WAAU;iBAA+C;OAE7E,CAAA,EACR,kBAAC,GAAD;OAAQ,OAAO;OAAc,eAAe;iBAA5C,CACE,kBAAC,GAAD;QAAe,IAAG;kBAChB,kBAAC,GAAD,EAAa,aAAY,gBAAiB,CAAA;QAC5B,CAAA,EAChB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;QAAY,OAAM;kBAAS;QAEd,CAAA,EACZ,EAAS,KAAK,MACb,kBAAC,GAAD;QAAuB,OAAO,EAAE;kBAC7B,EAAE;QACQ,EAFI,EAAE,GAEN,CACb,CACY,EAAA,CAAA,CACT;SACL;;KAEN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,SAAD;OAAO,SAAQ;OAAe,WAAU;iBAA+C;OAE/E,CAAA,EACR,kBAAC,GAAD;OAAQ,OAAO;OAAY,eAAe;iBAA1C,CACE,kBAAC,GAAD;QAAe,IAAG;kBAChB,kBAAC,GAAD,EAAe,CAAA;QACD,CAAA,EAChB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;QAAY,OAAM;kBAAS;QAAmB,CAAA,EAC9C,kBAAC,GAAD;QAAY,OAAM;kBAAc;QAAwB,CAAA,CAC1C,EAAA,CAAA,CACT;SACL;;KAEN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,SAAD;OAAO,SAAQ;OAAgB,WAAU;iBAA+C;OAEhF,CAAA,EACR,kBAAC,GAAD;OAAQ,OAAO;OAAY,eAAe;iBAA1C,CACE,kBAAC,GAAD;QAAe,IAAG;kBAChB,kBAAC,GAAD,EAAe,CAAA;QACD,CAAA,EAChB,kBAAC,GAAD,EAAA,UACG,OAAO,QAAQ,EAAY,CAAC,KAAK,CAAC,GAAK,OACtC,kBAAC,GAAD;QAAsB,OAAO;kBAC1B;QACU,EAFI,EAEJ,CACb,EACY,CAAA,CACT;SACL;;KAEN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,SAAD;OAAO,SAAQ;OAAa,WAAU;iBAA6B;OAE3D,CAAA,EACR,kBAAC,GAAD;OAAQ,IAAG;OAAa,SAAS;OAAU,iBAAiB;OAAe,CAAA,CACvE;;KAEN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD;OACE,SAAQ;OACR,eAAe;AAEb,QADA,EAAiB,GAAM,EACvB,GAAW;;iBAEd;OAEQ,CAAA,EACT,kBAAC,GAAD;OACE,SAAS;OACT,UAAU;iBAET,IAAW,cAAc;OACnB,CAAA,CACL;;KACF;MACQ;;EACT,CAAA,CACR,EAAA,CAAA;EAGN;AAED,EAAwB,cAAc"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidebar.js","names":[],"sources":["../../src/shell/sidebar.tsx"],"sourcesContent":["'use client'\n\n/**\n * AppSidebar -- Application-layer sidebar built on the Sidebar primitive.\n *\n * Design-system token migration (2026-02-28):\n * All V1 colour tokens have been replaced with semantic design-system tokens.\n * Typography classes replaced with Tailwind equivalents.\n *\n * Props-driven: accepts user info, currentPath, and navItems instead of\n * reading from Remix hooks or Zustand stores.\n */\nimport * as React from 'react'\nimport { useLink } from './link-context'\nimport {\n Sidebar as ShadcnSidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarSeparator,\n} from '../ui/sidebar'\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '../ui/collapsible'\nimport { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar'\nimport { cn } from '../ui/lib/utils'\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\nexport interface NavSubItem {\n title: string\n href: string\n icon?: React.ReactNode\n exact?: boolean\n}\n\nexport interface NavItem {\n title: string\n href: string\n icon: React.ReactNode\n /** When true, the route matches only when the path is exactly equal */\n exact?: boolean\n /** Badge rendered on the right side of the nav item */\n badge?: string | number\n /** Optional child items — renders as collapsible sub-list with chevron */\n children?: NavSubItem[]\n /** Whether the collapsible is open by default. Auto-opens when a child is active. */\n defaultOpen?: boolean\n}\n\nexport interface NavGroup {\n label: string\n items: NavItem[]\n /** Action rendered next to the group label (e.g., a \"+\" button) */\n action?: React.ReactNode\n}\n\nexport interface SidebarUser {\n name: string\n email?: string\n image?: string | null\n designation?: string\n role?: string\n}\n\nexport interface SidebarPromo {\n /** Promo message text */\n text: string\n /** Optional icon rendered before the text */\n icon?: React.ReactNode\n /** Action button rendered in the promo banner */\n action?: { label: string; href?: string; onClick?: () => void }\n /** When provided, renders a dismiss (X) button that calls this handler */\n onDismiss?: () => void\n}\n\nexport interface SidebarFooterConfig {\n /** Legal/utility links rendered as a row separated by dividers */\n links?: Array<{ label: string; href: string }>\n /** Version or build info text (or link) rendered inline after links */\n version?: string | { label: string; href: string }\n /** Custom content rendered above the links row */\n slot?: React.ReactNode\n /** Promo/upsell banner rendered above the links row */\n promo?: SidebarPromo\n}\n\nexport interface AppSidebarProps\n extends React.HTMLAttributes<HTMLDivElement> {\n /** Currently active pathname -- used to highlight the active nav item */\n currentPath?: string\n /** User information displayed in the sidebar header */\n user?: SidebarUser | null\n /** Primary navigation groups rendered in the main content area */\n navGroups?: NavGroup[]\n /** Optional logo element. Falls back to a text placeholder. */\n logo?: React.ReactNode\n /** Footer links rendered at the bottom of the sidebar */\n footerLinks?: Array<{ label: string; href: string }>\n /** Structured footer config (takes precedence over footerLinks) */\n footer?: SidebarFooterConfig\n /** Content rendered between user header and navigation */\n headerSlot?: React.ReactNode\n /** Content rendered between navigation and footer */\n preFooterSlot?: React.ReactNode\n /** className applied to the wrapper div around preFooterSlot */\n preFooterClassName?: string\n /** Override rendering for specific nav items. Return null to use default rendering. */\n renderItem?: (item: NavItem, defaultRender: () => React.ReactNode) => React.ReactNode | null\n /** Additional className for the root sidebar element */\n className?: string\n}\n\n// -----------------------------------------------------------------------\n// ChevronRight (inline SVG icon for collapsible toggle)\n// -----------------------------------------------------------------------\n\nfunction ChevronRight({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n )\n}\n\nfunction CloseIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n )\n}\n\n// -----------------------------------------------------------------------\n// Shared styles\n// -----------------------------------------------------------------------\n\nconst navItemBase = 'relative gap-ds-04 rounded-ds-lg px-ds-04 py-ds-03 transition-colors duration-fast-02'\nconst navItemActive =\n \"bg-accent-2 text-accent-11 after:absolute after:right-0 after:top-0 after:h-full after:w-ds-01 after:rounded-l-ds-full after:bg-accent-9 after:content-['']\"\nconst navItemInactive = 'text-surface-fg-subtle hover:bg-surface-raised-hover hover:text-surface-fg'\n\n// -----------------------------------------------------------------------\n// NavLink (internal)\n// -----------------------------------------------------------------------\n\nfunction NavLink({\n item,\n isActive,\n isPathActive,\n}: {\n item: NavItem\n isActive: boolean\n isPathActive: (path: string, exact?: boolean) => boolean\n}) {\n const Link = useLink()\n const badgeContent =\n item.badge != null\n ? typeof item.badge === 'number' && item.badge > 99\n ? '99+'\n : String(item.badge)\n : null\n\n // S9: Collapsible children\n if (item.children && item.children.length > 0) {\n const hasActiveChild = item.children.some((child) =>\n isPathActive(child.href, child.exact),\n )\n const shouldOpen = hasActiveChild || isActive || (item.defaultOpen ?? false)\n\n return (\n <Collapsible defaultOpen={shouldOpen} className=\"group/collapsible\">\n <SidebarMenuItem>\n {/* Button row — chevron is anchored here, not on the full <li> */}\n <div className=\"relative\">\n <SidebarMenuButton\n asChild\n isActive={isActive || hasActiveChild}\n tooltip={item.title}\n className={cn(\n navItemBase,\n isActive || hasActiveChild ? navItemActive : navItemInactive,\n )}\n >\n <Link\n href={item.href}\n aria-label={item.title}\n aria-current={isActive ? 'page' : undefined}\n >\n <span className=\"[&>svg]:h-ico-md [&>svg]:w-ico-md shrink-0\" aria-hidden=\"true\">\n {item.icon}\n </span>\n <span className=\"text-ds-base\">{item.title}</span>\n </Link>\n </SidebarMenuButton>\n {badgeContent && <SidebarMenuBadge>{badgeContent}</SidebarMenuBadge>}\n <CollapsibleTrigger asChild>\n <button\n className=\"absolute right-ds-02 top-1/2 flex h-5 w-5 -translate-y-1/2 items-center justify-center rounded-ds-md text-surface-fg-subtle transition-colors hover:bg-surface-raised-hover hover:text-surface-fg group-data-[collapsible=icon]:hidden\"\n aria-label={`Toggle ${item.title}`}\n >\n <ChevronRight className=\"h-4 w-4 transition-transform duration-fast-02 ease-productive-standard group-data-[state=open]/collapsible:rotate-90\" />\n </button>\n </CollapsibleTrigger>\n </div>\n <CollapsibleContent>\n <SidebarMenuSub>\n {item.children.map((child) => {\n const childActive = isPathActive(child.href, child.exact)\n return (\n <SidebarMenuSubItem key={child.href}>\n <SidebarMenuSubButton\n asChild\n isActive={childActive}\n >\n <Link\n href={child.href}\n aria-current={childActive ? 'page' : undefined}\n >\n {child.icon && (\n <span className=\"[&>svg]:h-ico-sm [&>svg]:w-ico-sm shrink-0\" aria-hidden=\"true\">\n {child.icon}\n </span>\n )}\n <span>{child.title}</span>\n </Link>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n )\n })}\n </SidebarMenuSub>\n </CollapsibleContent>\n </SidebarMenuItem>\n </Collapsible>\n )\n }\n\n // Default: flat nav item\n return (\n <SidebarMenuItem>\n <SidebarMenuButton\n asChild\n isActive={isActive}\n tooltip={item.title}\n className={cn(\n navItemBase,\n isActive ? navItemActive : navItemInactive,\n )}\n >\n <Link\n href={item.href}\n aria-label={item.title}\n aria-current={isActive ? 'page' : undefined}\n >\n <span className=\"[&>svg]:h-ico-md [&>svg]:w-ico-md shrink-0\" aria-hidden=\"true\">{item.icon}</span>\n <span className=\"text-ds-base\">{item.title}</span>\n </Link>\n </SidebarMenuButton>\n {badgeContent && <SidebarMenuBadge>{badgeContent}</SidebarMenuBadge>}\n </SidebarMenuItem>\n )\n}\n\n// -----------------------------------------------------------------------\n// AppSidebar\n// -----------------------------------------------------------------------\n\nconst AppSidebar = React.forwardRef<HTMLDivElement, AppSidebarProps>(\n (\n {\n currentPath = '/',\n user,\n navGroups = [],\n logo,\n headerSlot,\n preFooterSlot,\n preFooterClassName,\n footerLinks = [],\n footer,\n renderItem,\n className,\n ...props\n },\n ref,\n ) => {\n const Link = useLink()\n const isActive = (path: string, exact = false) => {\n if (exact || path === '/') {\n return currentPath === path\n }\n return currentPath.startsWith(path)\n }\n\n return (\n <ShadcnSidebar\n {...props}\n ref={ref}\n aria-label=\"Main navigation\"\n className={cn(\n 'z-raised hidden h-full flex-col border-r border-surface-border-strong bg-surface-raised md:flex',\n className,\n )}\n >\n {/* Logo Header */}\n <SidebarHeader className=\"px-ds-06 py-ds-06\">\n {logo ?? (\n <span className=\"text-ds-lg font-semibold text-surface-fg\">\n Logo\n </span>\n )}\n </SidebarHeader>\n\n {/* User Info */}\n {user && (\n <div className=\"flex items-center gap-ds-04 px-ds-06 pb-ds-05\">\n <Avatar className=\"h-ds-sm-plus w-ds-sm-plus\">\n {user.image ? (\n <AvatarImage src={user.image} alt={user.name} />\n ) : null}\n <AvatarFallback className=\"bg-surface-raised-hover text-surface-fg\">\n {user.name?.charAt(0).toUpperCase()}\n </AvatarFallback>\n </Avatar>\n <div className=\"flex min-w-0 flex-col\">\n <span className=\"truncate text-ds-md text-surface-fg\">\n {user.name}\n </span>\n <span className=\"truncate text-ds-sm text-surface-fg-subtle\">\n {user.designation || user.role}\n </span>\n </div>\n </div>\n )}\n\n <SidebarSeparator />\n\n {/* Header Slot (S13) */}\n {headerSlot && (\n <>\n {headerSlot}\n <SidebarSeparator />\n </>\n )}\n\n {/* Navigation Groups */}\n <SidebarContent className=\"no-scrollbar px-ds-04\">\n {navGroups.map((group, idx) => (\n <div key={group.label}>\n {idx > 0 && <SidebarSeparator />}\n <SidebarGroup>\n <SidebarGroupLabel className=\"px-ds-04 text-ds-sm text-surface-fg-subtle\">\n {group.label}\n </SidebarGroupLabel>\n {group.action && (\n <SidebarGroupAction asChild>{group.action}</SidebarGroupAction>\n )}\n <SidebarGroupContent>\n <SidebarMenu>\n {group.items.map((item) => {\n const defaultRender = () => (\n <NavLink\n item={item}\n isActive={isActive(item.href, item.exact)}\n isPathActive={isActive}\n />\n )\n\n if (renderItem) {\n const custom = renderItem(item, defaultRender)\n if (custom !== null) {\n return <React.Fragment key={item.href}>{custom}</React.Fragment>\n }\n }\n\n return <React.Fragment key={item.href}>{defaultRender()}</React.Fragment>\n })}\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </div>\n ))}\n </SidebarContent>\n\n {/* Pre-Footer Slot (S13) */}\n {preFooterSlot && (\n <>\n <SidebarSeparator />\n <div className={preFooterClassName}>\n {preFooterSlot}\n </div>\n </>\n )}\n\n {/* Footer */}\n {footer ? (\n <SidebarFooter className=\"gap-ds-03 px-ds-06 py-ds-05\">\n {footer.slot && <div>{footer.slot}</div>}\n\n {/* Promo banner */}\n {footer.promo && (\n <div className=\"relative rounded-ds-lg border border-surface-border bg-surface-raised p-ds-04 shadow-raised\">\n {footer.promo.onDismiss && (\n <button\n onClick={footer.promo.onDismiss}\n aria-label=\"Dismiss\"\n className=\"absolute right-ds-02 top-ds-02 flex h-5 w-5 items-center justify-center rounded-ds-md text-surface-fg-subtle transition-colors hover:bg-surface-raised-hover hover:text-surface-fg\"\n >\n <CloseIcon className=\"h-3.5 w-3.5\" />\n </button>\n )}\n <div className=\"flex flex-col gap-ds-03\">\n {footer.promo.icon && (\n <span className=\"text-accent-11 [&>svg]:h-ico-md [&>svg]:w-ico-md\" aria-hidden=\"true\">\n {footer.promo.icon}\n </span>\n )}\n <div className=\"flex min-w-0 flex-col gap-ds-03\">\n <p className=\"text-ds-sm text-surface-fg\">{footer.promo.text}</p>\n {footer.promo.action && (\n footer.promo.action.href ? (\n <Link\n href={footer.promo.action.href}\n onClick={footer.promo.action.onClick}\n className=\"inline-flex self-start rounded-ds-md bg-accent-9 px-ds-04 py-ds-02 text-ds-sm font-medium text-accent-fg transition-colors hover:bg-accent-10\"\n >\n {footer.promo.action.label}\n </Link>\n ) : (\n <button\n onClick={footer.promo.action.onClick}\n className=\"inline-flex self-start rounded-ds-md bg-accent-9 px-ds-04 py-ds-02 text-ds-sm font-medium text-accent-fg transition-colors hover:bg-accent-10\"\n >\n {footer.promo.action.label}\n </button>\n )\n )}\n </div>\n </div>\n </div>\n )}\n\n {/* Links + version on same line */}\n {(footer.links?.length || footer.version) && (\n <div className=\"flex items-center gap-ds-03 text-ds-sm text-surface-fg-subtle\">\n {footer.links?.map((link, i) => (\n <React.Fragment key={link.href}>\n {i > 0 && <span>·</span>}\n <Link\n className=\"transition-colors hover:text-accent-11\"\n href={link.href}\n >\n {link.label}\n </Link>\n </React.Fragment>\n ))}\n {footer.links?.length && footer.version && <span>·</span>}\n {footer.version && (\n typeof footer.version === 'string'\n ? <span>{footer.version}</span>\n : <Link className=\"transition-colors hover:text-accent-11\" href={footer.version.href}>{footer.version.label}</Link>\n )}\n </div>\n )}\n </SidebarFooter>\n ) : footerLinks.length > 0 ? (\n <SidebarFooter className=\"px-ds-06 py-ds-05\">\n <div className=\"flex items-center gap-ds-03 text-ds-sm text-surface-fg-subtle\">\n {footerLinks.map((link, i) => (\n <React.Fragment key={link.href}>\n {i > 0 && <span>·</span>}\n <Link\n className=\"transition-colors hover:text-accent-11\"\n href={link.href}\n >\n {link.label}\n </Link>\n </React.Fragment>\n ))}\n </div>\n </SidebarFooter>\n ) : null}\n </ShadcnSidebar>\n )\n },\n)\nAppSidebar.displayName = 'AppSidebar'\n\nexport { AppSidebar }\n"],"mappings":"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"}
@@ -154,7 +154,7 @@ var A = m.forwardRef(({ user: S, onNavigate: C, onLogout: w, userMenuItems: T, c
154
154
  children: t.label
155
155
  }),
156
156
  t.badge != null && t.badge !== !1 && (typeof t.badge == "string" ? /* @__PURE__ */ g("span", {
157
- className: "ml-auto inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-ds-full bg-error-9 px-ds-02 text-[10px] font-semibold leading-none text-accent-fg",
157
+ className: "ml-auto inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-ds-full bg-error-9 px-ds-02 text-[10px] font-semibold leading-none text-error-fg",
158
158
  children: t.badge
159
159
  }) : /* @__PURE__ */ g("span", { className: "ml-auto h-[8px] w-[8px] rounded-ds-full bg-error-9" }))
160
160
  ]