@ctrl-ui/react 0.8.6 → 0.8.8

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 (376) hide show
  1. package/dist/action-bar.d.ts +15 -7
  2. package/dist/action-bar.js +39 -19
  3. package/dist/activity.js +7 -15
  4. package/dist/audio-recorder.d.ts +14 -4
  5. package/dist/audio-recorder.js +82 -29
  6. package/dist/audio-visualizer.js +1 -1
  7. package/dist/blocks/coding-agent.js +54 -57
  8. package/dist/blocks/design-canvas-data.d.ts +32 -0
  9. package/dist/blocks/design-canvas-data.js +100 -0
  10. package/dist/blocks/design-canvas-inspector.d.ts +8 -0
  11. package/dist/blocks/design-canvas-inspector.js +238 -0
  12. package/dist/blocks/design-canvas.d.ts +21 -0
  13. package/dist/blocks/design-canvas.js +452 -0
  14. package/dist/blocks/discussion.d.ts +28 -0
  15. package/dist/blocks/discussion.js +67 -0
  16. package/dist/blocks/file-explorer-data.d.ts +1 -0
  17. package/dist/blocks/file-explorer-data.js +4 -1
  18. package/dist/blocks/file-explorer.d.ts +9 -1
  19. package/dist/blocks/file-explorer.js +461 -192
  20. package/dist/blocks/settings.d.ts +2 -1
  21. package/dist/blocks/settings.js +101 -79
  22. package/dist/blocks/team-chat.d.ts +12 -0
  23. package/dist/blocks/team-chat.js +26 -0
  24. package/dist/blocks/theme-toggle.js +23 -31
  25. package/dist/chat-composer-attachment.d.ts +12 -3
  26. package/dist/chat-composer-attachment.js +61 -19
  27. package/dist/chat-composer-editor/extensions/mention.d.ts +5 -1
  28. package/dist/chat-composer-editor/extensions/mention.js +58 -27
  29. package/dist/chat-composer-editor/ghost.js +2 -4
  30. package/dist/chat-composer-editor/types.d.ts +5 -0
  31. package/dist/chat-composer-editor.d.ts +1 -1
  32. package/dist/chat-composer-editor.js +71 -28
  33. package/dist/chat-composer.d.ts +13 -32
  34. package/dist/chat-composer.js +54 -13
  35. package/dist/chat-layout.d.ts +19 -0
  36. package/dist/chat-layout.js +96 -32
  37. package/dist/chat-message/social.d.ts +26 -0
  38. package/dist/chat-message/social.js +122 -0
  39. package/dist/chat-message.d.ts +28 -29
  40. package/dist/chat-message.js +106 -25
  41. package/dist/context.d.ts +2 -2
  42. package/dist/context.js +38 -23
  43. package/dist/dynamic-notification-canvas-loop.d.ts +24 -0
  44. package/dist/dynamic-notification-canvas-loop.js +113 -0
  45. package/dist/dynamic-notification-glass.js +23 -114
  46. package/dist/dynamic-notification-liquid.js +14 -118
  47. package/dist/dynamic-notification.d.ts +16 -8
  48. package/dist/dynamic-notification.js +85 -22
  49. package/dist/email/email-brand.d.ts +7 -4
  50. package/dist/email/email-brand.js +9 -6
  51. package/dist/email/email-code.d.ts +3 -2
  52. package/dist/email/email-code.js +11 -9
  53. package/dist/email/email-footer.d.ts +5 -3
  54. package/dist/email/email-footer.js +11 -5
  55. package/dist/email/email.d.ts +31 -9
  56. package/dist/email/email.js +50 -26
  57. package/dist/email/templates.d.ts +10 -9
  58. package/dist/email/templates.js +102 -38
  59. package/dist/email/theme.js +1 -1
  60. package/dist/environment-variables.d.ts +4 -2
  61. package/dist/environment-variables.js +52 -32
  62. package/dist/filter-bar/context.d.ts +32 -0
  63. package/dist/filter-bar/context.js +11 -0
  64. package/dist/filter-bar/editor.d.ts +14 -0
  65. package/dist/filter-bar/editor.js +216 -0
  66. package/dist/filter-bar/model.d.ts +10 -0
  67. package/dist/filter-bar/model.js +57 -0
  68. package/dist/filter-bar/motion.d.ts +10 -0
  69. package/dist/filter-bar/motion.js +84 -0
  70. package/dist/filter-bar/parts.d.ts +19 -0
  71. package/dist/filter-bar/parts.js +244 -0
  72. package/dist/filter-bar/types.d.ts +54 -0
  73. package/dist/filter-bar/types.js +0 -0
  74. package/dist/filter-bar.d.ts +27 -0
  75. package/dist/filter-bar.js +310 -0
  76. package/dist/hooks/use-audio-recorder.js +12 -6
  77. package/dist/hooks/use-chat-composer.d.ts +21 -7
  78. package/dist/hooks/use-chat-composer.js +32 -5
  79. package/dist/hooks/use-chat-message.d.ts +28 -2
  80. package/dist/hooks/use-chat-message.js +41 -10
  81. package/dist/hooks/use-chat-thread-scroll.js +43 -7
  82. package/dist/hooks/use-color-area.d.ts +3 -3
  83. package/dist/hooks/use-color-area.js +13 -12
  84. package/dist/hooks/use-copy-to-clipboard.d.ts +2 -1
  85. package/dist/hooks/use-copy-to-clipboard.js +20 -20
  86. package/dist/hooks/use-dropzone.d.ts +7 -4
  87. package/dist/hooks/use-dropzone.js +34 -3
  88. package/dist/hooks/use-dynamic-notification.d.ts +6 -2
  89. package/dist/hooks/use-dynamic-notification.js +26 -10
  90. package/dist/hooks/use-mobile.d.ts +3 -2
  91. package/dist/hooks/use-mobile.js +8 -4
  92. package/dist/hooks/use-textarea-trigger-menu.js +2 -1
  93. package/dist/hooks/use-trigger-menu.d.ts +54 -0
  94. package/dist/hooks/use-trigger-menu.js +102 -47
  95. package/dist/hooks/use-user-ask.d.ts +2 -0
  96. package/dist/hooks/use-user-ask.js +35 -41
  97. package/dist/inline-attachment.d.ts +6 -2
  98. package/dist/inline-attachment.js +44 -29
  99. package/dist/inline-citation.d.ts +12 -5
  100. package/dist/inline-citation.js +25 -16
  101. package/dist/knob-contracts/audio-recorder-knobs.d.ts +1 -1
  102. package/dist/knob-contracts/audio-recorder-knobs.js +2 -1
  103. package/dist/knob-contracts/audio-visualizer-knobs.d.ts +1 -1
  104. package/dist/knob-contracts/audio-visualizer-knobs.js +2 -1
  105. package/dist/knob-contracts/avatar-knobs.d.ts +1 -1
  106. package/dist/knob-contracts/avatar-knobs.js +6 -1
  107. package/dist/knob-contracts/badge-knobs.d.ts +1 -1
  108. package/dist/knob-contracts/badge-knobs.js +2 -1
  109. package/dist/knob-contracts/breadcrumb-knobs.d.ts +4 -0
  110. package/dist/knob-contracts/breadcrumb-knobs.js +8 -0
  111. package/dist/knob-contracts/button-knobs.d.ts +1 -1
  112. package/dist/knob-contracts/button-knobs.js +1 -0
  113. package/dist/knob-contracts/chat-layout-knobs.d.ts +1 -1
  114. package/dist/knob-contracts/chat-layout-knobs.js +2 -1
  115. package/dist/knob-contracts/chat-message-knobs.d.ts +1 -1
  116. package/dist/knob-contracts/chat-message-knobs.js +8 -1
  117. package/dist/knob-contracts/choice-knobs.d.ts +1 -1
  118. package/dist/knob-contracts/choice-knobs.js +1 -0
  119. package/dist/knob-contracts/code-diff-knobs.d.ts +1 -1
  120. package/dist/knob-contracts/code-diff-knobs.js +2 -0
  121. package/dist/knob-contracts/code-knobs.d.ts +1 -1
  122. package/dist/knob-contracts/code-knobs.js +2 -1
  123. package/dist/knob-contracts/collapsible-knobs.d.ts +1 -1
  124. package/dist/knob-contracts/collapsible-knobs.js +1 -1
  125. package/dist/knob-contracts/dynamic-notification-knobs.d.ts +1 -1
  126. package/dist/knob-contracts/dynamic-notification-knobs.js +2 -0
  127. package/dist/knob-contracts/emoji-picker-knobs.d.ts +4 -0
  128. package/dist/knob-contracts/emoji-picker-knobs.js +10 -0
  129. package/dist/knob-contracts/field-knobs.d.ts +1 -1
  130. package/dist/knob-contracts/field-knobs.js +5 -1
  131. package/dist/knob-contracts/filter-bar-knobs.d.ts +4 -0
  132. package/dist/knob-contracts/filter-bar-knobs.js +15 -0
  133. package/dist/knob-contracts/infinite-canvas-knobs.d.ts +1 -1
  134. package/dist/knob-contracts/infinite-canvas-knobs.js +3 -0
  135. package/dist/knob-contracts/markdown-knobs.d.ts +1 -1
  136. package/dist/knob-contracts/markdown-knobs.js +3 -1
  137. package/dist/knob-contracts/page-layout-knobs.d.ts +1 -1
  138. package/dist/knob-contracts/page-layout-knobs.js +4 -1
  139. package/dist/knob-contracts/popup-knobs.d.ts +1 -1
  140. package/dist/knob-contracts/popup-knobs.js +28 -0
  141. package/dist/knob-contracts/range-knobs.d.ts +1 -1
  142. package/dist/knob-contracts/range-knobs.js +1 -0
  143. package/dist/knob-contracts/rich-tooltip-knobs.d.ts +1 -1
  144. package/dist/knob-contracts/rich-tooltip-knobs.js +2 -1
  145. package/dist/knob-contracts/sidebar-knobs.d.ts +1 -1
  146. package/dist/knob-contracts/sidebar-knobs.js +27 -2
  147. package/dist/knob-contracts/spinner-knobs.d.ts +1 -1
  148. package/dist/knob-contracts/spinner-knobs.js +1 -1
  149. package/dist/knob-contracts/stepper-knobs.d.ts +1 -1
  150. package/dist/knob-contracts/stepper-knobs.js +4 -1
  151. package/dist/knob-contracts/switch-knobs.d.ts +1 -1
  152. package/dist/knob-contracts/switch-knobs.js +5 -0
  153. package/dist/knob-contracts/table-of-contents-knobs.d.ts +1 -1
  154. package/dist/knob-contracts/table-of-contents-knobs.js +4 -5
  155. package/dist/knob-contracts/tabs-knobs.d.ts +1 -1
  156. package/dist/knob-contracts/tabs-knobs.js +1 -0
  157. package/dist/knob-contracts/tree-knobs.d.ts +1 -1
  158. package/dist/knob-contracts/tree-knobs.js +2 -1
  159. package/dist/lib/cn.js +0 -4
  160. package/dist/lib/contrast.d.ts +1 -0
  161. package/dist/lib/contrast.js +17 -5
  162. package/dist/lib/dropzone-validation.js +41 -28
  163. package/dist/lib/env-file.d.ts +1 -1
  164. package/dist/lib/env-file.js +5 -5
  165. package/dist/lib/motion.d.ts +4 -0
  166. package/dist/lib/motion.js +15 -0
  167. package/dist/lib/trigger-detect.js +6 -8
  168. package/dist/markdown-block.js +13 -8
  169. package/dist/popup-parts.d.ts +8 -0
  170. package/dist/popup-parts.js +43 -0
  171. package/dist/scripts/contrast-eval.js +5 -4
  172. package/dist/source-badge.js +3 -1
  173. package/dist/styles/code.css +0 -2
  174. package/dist/styles/effects.css +6 -32
  175. package/dist/styles/index.css +14 -8
  176. package/dist/styles/recipes/accordion.css +9 -6
  177. package/dist/styles/recipes/action-bar.css +0 -15
  178. package/dist/styles/recipes/activity.css +5 -11
  179. package/dist/styles/recipes/alert.css +4 -4
  180. package/dist/styles/recipes/audio-recorder.css +15 -3
  181. package/dist/styles/recipes/audio-visualizer.css +13 -2
  182. package/dist/styles/recipes/avatar.css +78 -1
  183. package/dist/styles/recipes/badge.css +14 -4
  184. package/dist/styles/recipes/breadcrumb.css +77 -0
  185. package/dist/styles/recipes/button-group.css +6 -8
  186. package/dist/styles/recipes/button-states.css +66 -0
  187. package/dist/styles/recipes/button.css +26 -85
  188. package/dist/styles/recipes/calendar.css +17 -23
  189. package/dist/styles/recipes/card.css +2 -2
  190. package/dist/styles/recipes/chat-composer-attachment.css +9 -3
  191. package/dist/styles/recipes/chat-composer.css +21 -16
  192. package/dist/styles/recipes/chat-layout.css +64 -2
  193. package/dist/styles/recipes/chat-message-social.css +123 -0
  194. package/dist/styles/recipes/chat-message.css +157 -37
  195. package/dist/styles/recipes/choice.css +25 -21
  196. package/dist/styles/recipes/code-diff.css +51 -26
  197. package/dist/styles/recipes/code.css +44 -18
  198. package/dist/styles/recipes/collapsible.css +43 -1
  199. package/dist/styles/recipes/color-picker-details.css +3 -4
  200. package/dist/styles/recipes/color-picker-values.css +9 -8
  201. package/dist/styles/recipes/color-picker.css +23 -4
  202. package/dist/styles/recipes/context.css +3 -3
  203. package/dist/styles/recipes/dockable-panel.css +18 -7
  204. package/dist/styles/recipes/dropzone.css +7 -8
  205. package/dist/styles/recipes/dynamic-notification-input.css +8 -5
  206. package/dist/styles/recipes/dynamic-notification-motion.css +12 -21
  207. package/dist/styles/recipes/dynamic-notification.css +40 -26
  208. package/dist/styles/recipes/emoji-picker.css +132 -0
  209. package/dist/styles/recipes/empty.css +5 -4
  210. package/dist/styles/recipes/environment-variables.css +4 -15
  211. package/dist/styles/recipes/field-parts.css +89 -21
  212. package/dist/styles/recipes/field.css +83 -26
  213. package/dist/styles/recipes/filter-bar.css +161 -0
  214. package/dist/styles/recipes/gradient-editor.css +18 -7
  215. package/dist/styles/recipes/infinite-canvas.css +51 -4
  216. package/dist/styles/recipes/inline-attachment.css +9 -4
  217. package/dist/styles/recipes/inline-citation.css +10 -4
  218. package/dist/styles/recipes/item.css +23 -9
  219. package/dist/styles/recipes/markdown-block.css +5 -4
  220. package/dist/styles/recipes/markdown.css +68 -26
  221. package/dist/styles/recipes/morphing-panel.css +8 -8
  222. package/dist/styles/recipes/page-layout.css +36 -10
  223. package/dist/styles/recipes/pagination.css +5 -6
  224. package/dist/styles/recipes/phone-input.css +12 -8
  225. package/dist/styles/recipes/popup-controls.css +175 -26
  226. package/dist/styles/recipes/popup-drawer.css +35 -44
  227. package/dist/styles/recipes/popup-lists.css +139 -29
  228. package/dist/styles/recipes/popup-motion.css +4 -45
  229. package/dist/styles/recipes/popup-toast.css +55 -26
  230. package/dist/styles/recipes/popup.css +149 -153
  231. package/dist/styles/recipes/range.css +55 -19
  232. package/dist/styles/recipes/resizable.css +36 -7
  233. package/dist/styles/recipes/rich-tooltip.css +24 -34
  234. package/dist/styles/recipes/scroll-area.css +8 -1
  235. package/dist/styles/recipes/sidebar-menu.css +149 -34
  236. package/dist/styles/recipes/sidebar-parts.css +154 -0
  237. package/dist/styles/recipes/sidebar.css +187 -128
  238. package/dist/styles/recipes/source-badge.css +1 -1
  239. package/dist/styles/recipes/spinner.css +12 -1
  240. package/dist/styles/recipes/stepper.css +31 -13
  241. package/dist/styles/recipes/switch.css +68 -23
  242. package/dist/styles/recipes/table-of-contents.css +49 -41
  243. package/dist/styles/recipes/table.css +14 -10
  244. package/dist/styles/recipes/tabs.css +38 -12
  245. package/dist/styles/recipes/task-list.css +7 -14
  246. package/dist/styles/recipes/thread-rail.css +42 -19
  247. package/dist/styles/recipes/timeline.css +2 -0
  248. package/dist/styles/recipes/toolbar.css +27 -25
  249. package/dist/styles/recipes/track-highlight.css +12 -8
  250. package/dist/styles/recipes/transcript-divider.css +2 -2
  251. package/dist/styles/recipes/tree.css +31 -4
  252. package/dist/styles/recipes/user-ask-details.css +0 -1
  253. package/dist/styles/recipes/user-ask.css +4 -4
  254. package/dist/styles/theme.css +287 -107
  255. package/dist/task-list.d.ts +4 -1
  256. package/dist/task-list.js +24 -8
  257. package/dist/thread-rail.d.ts +1 -1
  258. package/dist/thread-rail.js +61 -19
  259. package/dist/transcript-divider.js +2 -1
  260. package/dist/ui/alert.d.ts +3 -1
  261. package/dist/ui/alert.js +14 -8
  262. package/dist/ui/autocomplete.js +7 -1
  263. package/dist/ui/avatar.d.ts +8 -0
  264. package/dist/ui/avatar.js +23 -3
  265. package/dist/ui/badge.js +1 -1
  266. package/dist/ui/breadcrumb.d.ts +27 -0
  267. package/dist/ui/breadcrumb.js +88 -0
  268. package/dist/ui/button.d.ts +2 -1
  269. package/dist/ui/button.js +1 -1
  270. package/dist/ui/calendar.js +2 -2
  271. package/dist/ui/card.d.ts +3 -1
  272. package/dist/ui/card.js +12 -7
  273. package/dist/ui/checkbox-group.js +1 -1
  274. package/dist/ui/checkbox.d.ts +2 -0
  275. package/dist/ui/code-diff.d.ts +1 -1
  276. package/dist/ui/code-diff.js +71 -27
  277. package/dist/ui/code.d.ts +5 -3
  278. package/dist/ui/code.js +27 -28
  279. package/dist/ui/color-picker.d.ts +5 -2
  280. package/dist/ui/color-picker.js +84 -36
  281. package/dist/ui/combobox-disabled-selection.d.ts +1 -2
  282. package/dist/ui/combobox-disabled-selection.js +7 -8
  283. package/dist/ui/combobox.d.ts +5 -23
  284. package/dist/ui/combobox.js +36 -16
  285. package/dist/ui/command.d.ts +8 -2
  286. package/dist/ui/command.js +39 -15
  287. package/dist/ui/context-menu.js +3 -0
  288. package/dist/ui/dialog.d.ts +2 -1
  289. package/dist/ui/dialog.js +3 -22
  290. package/dist/ui/dockable-panel-geometry.d.ts +1 -0
  291. package/dist/ui/dockable-panel-geometry.js +7 -1
  292. package/dist/ui/dockable-panel.d.ts +9 -6
  293. package/dist/ui/dockable-panel.js +81 -33
  294. package/dist/ui/drawer.d.ts +7 -4
  295. package/dist/ui/drawer.js +35 -22
  296. package/dist/ui/dropdown-menu.js +4 -3
  297. package/dist/ui/dropzone.d.ts +5 -3
  298. package/dist/ui/dropzone.js +78 -17
  299. package/dist/ui/emoji-picker.d.ts +18 -0
  300. package/dist/ui/emoji-picker.js +136 -0
  301. package/dist/ui/empty.d.ts +3 -1
  302. package/dist/ui/empty.js +12 -7
  303. package/dist/ui/field.js +1 -1
  304. package/dist/ui/gradient-editor.d.ts +1 -1
  305. package/dist/ui/gradient-editor.js +37 -21
  306. package/dist/ui/infinite-canvas.d.ts +13 -1
  307. package/dist/ui/infinite-canvas.js +139 -20
  308. package/dist/ui/input-group.d.ts +2 -4
  309. package/dist/ui/input-group.js +13 -14
  310. package/dist/ui/input-otp.d.ts +1 -1
  311. package/dist/ui/input-otp.js +32 -15
  312. package/dist/ui/input.js +11 -2
  313. package/dist/ui/item.d.ts +2 -1
  314. package/dist/ui/item.js +11 -7
  315. package/dist/ui/live-status.d.ts +7 -0
  316. package/dist/ui/live-status.js +17 -0
  317. package/dist/ui/markdown-elements.d.ts +6 -0
  318. package/dist/ui/markdown-elements.js +42 -9
  319. package/dist/ui/menubar.js +2 -2
  320. package/dist/ui/morphing-panel.js +2 -1
  321. package/dist/ui/native-select.d.ts +1 -1
  322. package/dist/ui/native-select.js +24 -11
  323. package/dist/ui/number-field.d.ts +1 -1
  324. package/dist/ui/number-field.js +13 -2
  325. package/dist/ui/page-layout.d.ts +2 -2
  326. package/dist/ui/page-layout.js +2 -4
  327. package/dist/ui/pagination.d.ts +7 -5
  328. package/dist/ui/pagination.js +19 -13
  329. package/dist/ui/phone-input.d.ts +1 -0
  330. package/dist/ui/phone-input.js +56 -58
  331. package/dist/ui/radio-group.d.ts +3 -0
  332. package/dist/ui/radio-group.js +11 -1
  333. package/dist/ui/resizable.d.ts +20 -2
  334. package/dist/ui/resizable.js +130 -8
  335. package/dist/ui/responsive-dialog.d.ts +1 -1
  336. package/dist/ui/responsive-dialog.js +9 -23
  337. package/dist/ui/rich-tooltip.d.ts +10 -4
  338. package/dist/ui/rich-tooltip.js +81 -33
  339. package/dist/ui/scroll-area.d.ts +4 -1
  340. package/dist/ui/scroll-area.js +44 -28
  341. package/dist/ui/select.d.ts +2 -1
  342. package/dist/ui/select.js +57 -32
  343. package/dist/ui/sidebar-menu.d.ts +5 -1
  344. package/dist/ui/sidebar-menu.js +31 -33
  345. package/dist/ui/sidebar-provider.d.ts +10 -1
  346. package/dist/ui/sidebar-provider.js +38 -13
  347. package/dist/ui/sidebar-resize-rail.js +7 -3
  348. package/dist/ui/sidebar.d.ts +11 -6
  349. package/dist/ui/sidebar.js +46 -23
  350. package/dist/ui/slider.js +31 -22
  351. package/dist/ui/spinner.d.ts +3 -2
  352. package/dist/ui/spinner.js +3 -2
  353. package/dist/ui/stepper.d.ts +8 -1
  354. package/dist/ui/stepper.js +74 -25
  355. package/dist/ui/switch.d.ts +1 -0
  356. package/dist/ui/table-of-contents.d.ts +5 -4
  357. package/dist/ui/table-of-contents.js +143 -52
  358. package/dist/ui/table.js +15 -9
  359. package/dist/ui/textarea.d.ts +1 -1
  360. package/dist/ui/textarea.js +20 -9
  361. package/dist/ui/timeline.d.ts +3 -1
  362. package/dist/ui/timeline.js +17 -9
  363. package/dist/ui/toast.d.ts +11 -5
  364. package/dist/ui/toast.js +100 -54
  365. package/dist/ui/toggle.d.ts +1 -1
  366. package/dist/ui/toggle.js +2 -1
  367. package/dist/ui/toolbar.d.ts +3 -2
  368. package/dist/ui/toolbar.js +4 -2
  369. package/dist/ui/tooltip.js +3 -20
  370. package/dist/ui/tree.js +120 -80
  371. package/dist/ui/trigger-menu.js +7 -2
  372. package/dist/user-ask.d.ts +10 -5
  373. package/dist/user-ask.js +31 -11
  374. package/package.json +5 -1
  375. package/dist/hooks/use-keyboard-navigation.d.ts +0 -3
  376. package/dist/hooks/use-keyboard-navigation.js +0 -22
@@ -0,0 +1,452 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { Button } from "../ui/button.js";
4
+ import { ScrollArea } from "../ui/scroll-area.js";
5
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../ui/tooltip.js";
6
+ import { createDesignCanvasLayer, designCanvasFillColor, drawnDesignCanvasBounds } from "./design-canvas-data.js";
7
+ import { DesignCanvasInspector } from "./design-canvas-inspector.js";
8
+ import { Drawer, DrawerContent, DrawerTitle } from "../ui/drawer.js";
9
+ import { InfiniteCanvas, InfiniteCanvasContent, InfiniteCanvasControls, InfiniteCanvasItem } from "../ui/infinite-canvas.js";
10
+ import { ResizableFloatingPanel } from "../ui/resizable.js";
11
+ import { Toolbar, ToolbarButton, ToolbarGroup, ToolbarSeparator } from "../ui/toolbar.js";
12
+ import { useRef, useState } from "react";
13
+ import { jsx, jsxs } from "react/jsx-runtime";
14
+ import { CircleIcon, FrameIcon, LayersIcon, MousePointer2Icon, SlidersHorizontalIcon, SquareIcon, TypeIcon } from "lucide-react";
15
+ //#region src/blocks/design-canvas.tsx
16
+ const TOOLS = [
17
+ {
18
+ tool: "move",
19
+ label: "Move",
20
+ shortcut: "V",
21
+ icon: /* @__PURE__ */ jsx(MousePointer2Icon, {})
22
+ },
23
+ {
24
+ tool: "frame",
25
+ label: "Frame",
26
+ shortcut: "F",
27
+ icon: /* @__PURE__ */ jsx(FrameIcon, {})
28
+ },
29
+ {
30
+ tool: "rectangle",
31
+ label: "Rectangle",
32
+ shortcut: "R",
33
+ icon: /* @__PURE__ */ jsx(SquareIcon, {})
34
+ },
35
+ {
36
+ tool: "ellipse",
37
+ label: "Ellipse",
38
+ shortcut: "O",
39
+ icon: /* @__PURE__ */ jsx(CircleIcon, {})
40
+ },
41
+ {
42
+ tool: "text",
43
+ label: "Text",
44
+ shortcut: "T",
45
+ icon: /* @__PURE__ */ jsx(TypeIcon, {})
46
+ }
47
+ ];
48
+ const LAYER_ICONS = {
49
+ frame: /* @__PURE__ */ jsx(FrameIcon, {}),
50
+ rectangle: /* @__PURE__ */ jsx(SquareIcon, {}),
51
+ ellipse: /* @__PURE__ */ jsx(CircleIcon, {}),
52
+ text: /* @__PURE__ */ jsx(TypeIcon, {})
53
+ };
54
+ const NUDGE_DIRECTIONS = {
55
+ ArrowLeft: {
56
+ x: -1,
57
+ y: 0
58
+ },
59
+ ArrowRight: {
60
+ x: 1,
61
+ y: 0
62
+ },
63
+ ArrowUp: {
64
+ x: 0,
65
+ y: -1
66
+ },
67
+ ArrowDown: {
68
+ x: 0,
69
+ y: 1
70
+ }
71
+ };
72
+ const DEFAULT_TRANSFORM = {
73
+ x: 0,
74
+ y: 0,
75
+ scale: 1
76
+ };
77
+ const CLICK_TOLERANCE_PX = 4;
78
+ const DELETE_KEYS = /* @__PURE__ */ new Set(["Delete", "Backspace"]);
79
+ const CANVAS_KEY_SHORTCUTS = `${TOOLS.map((entry) => entry.shortcut).join(" ")} Enter Delete Backspace Escape`;
80
+ const LAYER_KEY_SHORTCUTS = "Enter Space ArrowLeft ArrowRight ArrowUp ArrowDown Delete Backspace";
81
+ function newLayerId(kind) {
82
+ return `${kind}-${Math.random().toString(36).slice(2, 8)}`;
83
+ }
84
+ function toolForShortcut(key) {
85
+ return TOOLS.find((entry) => entry.shortcut === key.toUpperCase())?.tool;
86
+ }
87
+ function layerFromDraft(draft, id) {
88
+ return createDesignCanvasLayer(draft.kind, drawnDesignCanvasBounds(draft.kind, draft.start, draft.end, draft.clickTolerance), id);
89
+ }
90
+ function DesignCanvasBlock({ layers, defaultLayers = [], onLayersChange, selectedLayerId, defaultSelectedLayerId = null, onSelectedLayerIdChange, defaultTransform = DEFAULT_TRANSFORM, layout = "viewport", layersLabel = "Layers", propertiesLabel = "Properties", openLayersLabel = "Show layers", openPropertiesLabel = "Show properties", className, ...props }) {
91
+ const [internalLayers, setInternalLayers] = useState(defaultLayers);
92
+ const [internalSelectedLayerId, setInternalSelectedLayerId] = useState(defaultSelectedLayerId);
93
+ const transformRef = useRef(defaultTransform);
94
+ const [tool, setTool] = useState("move");
95
+ const [draft, setDraft] = useState(null);
96
+ const [layersOpen, setLayersOpen] = useState(false);
97
+ const [propertiesOpen, setPropertiesOpen] = useState(false);
98
+ const currentLayers = layers ?? internalLayers;
99
+ const currentSelectedLayerId = selectedLayerId === void 0 ? internalSelectedLayerId : selectedLayerId;
100
+ const selectedLayer = currentLayers.find((layer) => layer.id === currentSelectedLayerId);
101
+ function changeLayers(next) {
102
+ if (layers === void 0) setInternalLayers(next);
103
+ onLayersChange?.(next);
104
+ }
105
+ function selectLayer(layerId) {
106
+ if (selectedLayerId === void 0) setInternalSelectedLayerId(layerId);
107
+ onSelectedLayerIdChange?.(layerId);
108
+ }
109
+ function replaceLayer(next) {
110
+ changeLayers(currentLayers.map((layer) => layer.id === next.id ? next : layer));
111
+ }
112
+ function addLayer(layer) {
113
+ changeLayers([...currentLayers, layer]);
114
+ selectLayer(layer.id);
115
+ setTool("move");
116
+ }
117
+ function toWorldPoint(local) {
118
+ const { x, y, scale } = transformRef.current;
119
+ return {
120
+ x: (local.x - x) / scale,
121
+ y: (local.y - y) / scale
122
+ };
123
+ }
124
+ function worldPointAt(event) {
125
+ const bounds = event.currentTarget.getBoundingClientRect();
126
+ return toWorldPoint({
127
+ x: event.clientX - bounds.left,
128
+ y: event.clientY - bounds.top
129
+ });
130
+ }
131
+ function addLayerAtViewportCenter(kind, canvas) {
132
+ const center = toWorldPoint({
133
+ x: canvas.clientWidth / 2,
134
+ y: canvas.clientHeight / 2
135
+ });
136
+ const bounds = drawnDesignCanvasBounds(kind, center, center, CLICK_TOLERANCE_PX / transformRef.current.scale);
137
+ addLayer(createDesignCanvasLayer(kind, bounds, newLayerId(kind)));
138
+ }
139
+ function beginDrawOrDeselect(event) {
140
+ if (event.defaultPrevented || event.target !== event.currentTarget) return;
141
+ if (tool === "move") {
142
+ selectLayer(null);
143
+ return;
144
+ }
145
+ if (!event.isPrimary || event.button !== 0) return;
146
+ event.preventDefault();
147
+ event.currentTarget.setPointerCapture(event.pointerId);
148
+ const point = worldPointAt(event);
149
+ setDraft({
150
+ kind: tool,
151
+ pointerId: event.pointerId,
152
+ start: point,
153
+ end: point,
154
+ clickTolerance: CLICK_TOLERANCE_PX / transformRef.current.scale
155
+ });
156
+ }
157
+ function resizeDraft(event) {
158
+ if (draft?.pointerId !== event.pointerId) return;
159
+ setDraft({
160
+ ...draft,
161
+ end: worldPointAt(event)
162
+ });
163
+ }
164
+ function commitDraft(event) {
165
+ if (draft?.pointerId !== event.pointerId) return;
166
+ setDraft(null);
167
+ addLayer(layerFromDraft(draft, newLayerId(draft.kind)));
168
+ }
169
+ function cancelDraft(event) {
170
+ if (draft?.pointerId === event.pointerId) setDraft(null);
171
+ }
172
+ function editLayerWithKey(layer, event) {
173
+ const nudge = NUDGE_DIRECTIONS[event.key];
174
+ if (DELETE_KEYS.has(event.key)) {
175
+ changeLayers(currentLayers.filter((entry) => entry.id !== layer.id));
176
+ if (layer.id === currentSelectedLayerId) selectLayer(null);
177
+ } else if (nudge) {
178
+ const distance = event.shiftKey ? 10 : 1;
179
+ replaceLayer({
180
+ ...layer,
181
+ x: layer.x + nudge.x * distance,
182
+ y: layer.y + nudge.y * distance
183
+ });
184
+ } else return false;
185
+ return true;
186
+ }
187
+ function handleLayerKey(layer, event) {
188
+ if (event.metaKey || event.ctrlKey || event.altKey) return;
189
+ if (event.key === "Enter" || event.key === " ") selectLayer(layer.id);
190
+ else if (!editLayerWithKey(layer, event)) return;
191
+ event.preventDefault();
192
+ if (DELETE_KEYS.has(event.key)) event.currentTarget.closest("[data-control-family=\"infinite-canvas\"][data-slot=\"root\"]")?.focus();
193
+ }
194
+ function handleShortcut(event) {
195
+ if (event.defaultPrevented || event.metaKey || event.ctrlKey || event.altKey) return;
196
+ const shortcutTool = toolForShortcut(event.key);
197
+ if (shortcutTool) setTool(shortcutTool);
198
+ else if (event.key === "Escape") {
199
+ setDraft(null);
200
+ setTool("move");
201
+ selectLayer(null);
202
+ } else if (event.key === "Enter" && tool !== "move" && event.target === event.currentTarget) addLayerAtViewportCenter(tool, event.currentTarget);
203
+ else if (!selectedLayer || !editLayerWithKey(selectedLayer, event)) return;
204
+ event.preventDefault();
205
+ }
206
+ const layerList = /* @__PURE__ */ jsx(DesignCanvasLayerList, {
207
+ layers: currentLayers,
208
+ selectedLayerId: currentSelectedLayerId,
209
+ onSelect: selectLayer
210
+ });
211
+ const inspector = /* @__PURE__ */ jsx(DesignCanvasInspector, {
212
+ layer: selectedLayer,
213
+ onLayerChange: replaceLayer
214
+ });
215
+ const propertiesTitle = selectedLayer?.name ?? "Design";
216
+ return /* @__PURE__ */ jsxs("div", {
217
+ className: cn("@container/design-canvas relative isolate overflow-hidden bg-background text-foreground", layout === "contained" ? "h-full min-h-0" : "h-svh", className),
218
+ ...props,
219
+ children: [
220
+ /* @__PURE__ */ jsxs(InfiniteCanvas, {
221
+ "aria-label": "Design canvas",
222
+ "aria-keyshortcuts": CANVAS_KEY_SHORTCUTS,
223
+ defaultTransform,
224
+ onTransformChange: (next) => {
225
+ transformRef.current = next;
226
+ },
227
+ "data-tool": tool,
228
+ className: cn("size-full", tool !== "move" && "cursor-crosshair"),
229
+ style: {
230
+ "--cui-infinite-canvas-radius": "0px",
231
+ "--cui-infinite-canvas-border-color": "transparent",
232
+ "--cui-infinite-canvas-background": "var(--muted)"
233
+ },
234
+ onPointerDown: beginDrawOrDeselect,
235
+ onPointerMove: resizeDraft,
236
+ onPointerUp: commitDraft,
237
+ onPointerCancel: cancelDraft,
238
+ onKeyDown: handleShortcut,
239
+ children: [/* @__PURE__ */ jsxs(InfiniteCanvasContent, {
240
+ className: cn(tool !== "move" && "[&>*]:pointer-events-none"),
241
+ children: [currentLayers.map((layer) => /* @__PURE__ */ jsx(DesignCanvasLayerNode, {
242
+ layer,
243
+ selected: layer.id === currentSelectedLayerId,
244
+ onSelect: () => selectLayer(layer.id),
245
+ onKeyDown: (event) => handleLayerKey(layer, event),
246
+ onLayerChange: replaceLayer
247
+ }, layer.id)), draft ? /* @__PURE__ */ jsx(DesignCanvasLayerNode, {
248
+ layer: layerFromDraft(draft, "draft"),
249
+ selected: true
250
+ }) : null]
251
+ }), /* @__PURE__ */ jsx(InfiniteCanvasControls, { className: "start-3 end-auto top-3 bottom-auto w-max @4xl/design-canvas:inset-x-0 @4xl/design-canvas:mx-auto" })]
252
+ }),
253
+ /* @__PURE__ */ jsx(ResizableFloatingPanel, {
254
+ side: "left",
255
+ defaultSize: 224,
256
+ minSize: 180,
257
+ maxSize: 360,
258
+ className: "hidden @4xl/design-canvas:flex",
259
+ children: /* @__PURE__ */ jsx(DesignCanvasPanel, {
260
+ label: layersLabel,
261
+ title: layersLabel,
262
+ children: layerList
263
+ })
264
+ }),
265
+ /* @__PURE__ */ jsx(ResizableFloatingPanel, {
266
+ defaultSize: 280,
267
+ minSize: 256,
268
+ maxSize: 440,
269
+ className: "hidden @xl/design-canvas:flex",
270
+ children: /* @__PURE__ */ jsx(DesignCanvasPanel, {
271
+ label: propertiesLabel,
272
+ title: propertiesTitle,
273
+ children: inspector
274
+ })
275
+ }),
276
+ /* @__PURE__ */ jsx(Drawer, {
277
+ side: "left",
278
+ open: layersOpen,
279
+ onOpenChange: setLayersOpen,
280
+ children: /* @__PURE__ */ jsx(DrawerContent, {
281
+ side: "left",
282
+ className: "gap-0 p-0",
283
+ children: /* @__PURE__ */ jsx(DesignCanvasPanel, {
284
+ label: layersLabel,
285
+ title: layersLabel,
286
+ inDrawer: true,
287
+ children: layerList
288
+ })
289
+ })
290
+ }),
291
+ /* @__PURE__ */ jsx(Drawer, {
292
+ side: "right",
293
+ open: propertiesOpen,
294
+ onOpenChange: setPropertiesOpen,
295
+ children: /* @__PURE__ */ jsx(DrawerContent, {
296
+ side: "right",
297
+ className: "gap-0 p-0",
298
+ children: /* @__PURE__ */ jsx(DesignCanvasPanel, {
299
+ label: propertiesLabel,
300
+ title: propertiesTitle,
301
+ inDrawer: true,
302
+ children: inspector
303
+ })
304
+ })
305
+ }),
306
+ /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Toolbar, {
307
+ variant: "floating",
308
+ "aria-label": "Design tools",
309
+ className: "absolute start-4 bottom-4 w-max @4xl/design-canvas:inset-x-0 @4xl/design-canvas:mx-auto",
310
+ children: [
311
+ /* @__PURE__ */ jsx(ToolbarGroup, {
312
+ "aria-label": "Tools",
313
+ children: TOOLS.map((entry) => /* @__PURE__ */ jsx(DesignCanvasToolbarButton, {
314
+ label: entry.label,
315
+ hint: `${entry.label} · ${entry.shortcut}`,
316
+ pressed: tool === entry.tool,
317
+ onClick: () => setTool(entry.tool),
318
+ children: entry.icon
319
+ }, entry.tool))
320
+ }),
321
+ /* @__PURE__ */ jsx(ToolbarSeparator, { className: "@4xl/design-canvas:hidden" }),
322
+ /* @__PURE__ */ jsxs(ToolbarGroup, {
323
+ className: "@4xl/design-canvas:hidden",
324
+ children: [/* @__PURE__ */ jsx(DesignCanvasToolbarButton, {
325
+ label: openLayersLabel,
326
+ hint: openLayersLabel,
327
+ "aria-haspopup": "dialog",
328
+ "aria-expanded": layersOpen,
329
+ onClick: () => setLayersOpen(true),
330
+ children: /* @__PURE__ */ jsx(LayersIcon, {})
331
+ }), /* @__PURE__ */ jsx(DesignCanvasToolbarButton, {
332
+ label: openPropertiesLabel,
333
+ hint: openPropertiesLabel,
334
+ "aria-haspopup": "dialog",
335
+ "aria-expanded": propertiesOpen,
336
+ className: "@xl/design-canvas:hidden",
337
+ onClick: () => setPropertiesOpen(true),
338
+ children: /* @__PURE__ */ jsx(SlidersHorizontalIcon, {})
339
+ })]
340
+ })
341
+ ]
342
+ }) })
343
+ ]
344
+ });
345
+ }
346
+ function DesignCanvasPanel({ label, title, inDrawer = false, children }) {
347
+ const titleClassName = "flex h-11 shrink-0 items-center border-b px-3 text-caption font-medium";
348
+ const titleText = /* @__PURE__ */ jsx("span", {
349
+ className: "truncate",
350
+ title,
351
+ children: title
352
+ });
353
+ return /* @__PURE__ */ jsxs("aside", {
354
+ "aria-label": label,
355
+ className: "flex min-h-0 flex-1 flex-col",
356
+ children: [inDrawer ? /* @__PURE__ */ jsx(DrawerTitle, {
357
+ className: titleClassName,
358
+ children: titleText
359
+ }) : /* @__PURE__ */ jsx("h2", {
360
+ className: titleClassName,
361
+ children: titleText
362
+ }), /* @__PURE__ */ jsx(ScrollArea, {
363
+ className: "min-h-0 flex-1",
364
+ children
365
+ })]
366
+ });
367
+ }
368
+ function DesignCanvasLayerList({ layers, selectedLayerId, onSelect }) {
369
+ return /* @__PURE__ */ jsx("ul", {
370
+ className: "flex flex-col gap-0.5 p-2",
371
+ children: layers.toReversed().map((layer) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(Button, {
372
+ variant: "ghost",
373
+ size: "sm",
374
+ active: layer.id === selectedLayerId,
375
+ "aria-pressed": layer.id === selectedLayerId,
376
+ className: "w-full justify-start [&_svg]:size-3.5 [&_svg]:text-muted-foreground",
377
+ onClick: () => onSelect(layer.id),
378
+ children: [LAYER_ICONS[layer.kind], /* @__PURE__ */ jsx("span", {
379
+ className: "truncate",
380
+ title: layer.name,
381
+ children: layer.name
382
+ })]
383
+ }) }, layer.id))
384
+ });
385
+ }
386
+ function DesignCanvasLayerNode({ layer, selected, onSelect, onKeyDown, onLayerChange }) {
387
+ const fillColor = designCanvasFillColor(layer.fill);
388
+ const interactive = onSelect !== void 0;
389
+ return /* @__PURE__ */ jsxs(InfiniteCanvasItem, {
390
+ x: layer.x,
391
+ y: layer.y,
392
+ "aria-label": layer.name,
393
+ role: interactive ? "button" : void 0,
394
+ tabIndex: interactive ? 0 : void 0,
395
+ "aria-pressed": interactive ? selected : void 0,
396
+ "aria-keyshortcuts": interactive ? LAYER_KEY_SHORTCUTS : void 0,
397
+ "data-selected": selected || void 0,
398
+ className: "outline-primary data-selected:outline-2",
399
+ style: {
400
+ width: layer.width,
401
+ height: layer.height,
402
+ rotate: `${layer.rotation}deg`,
403
+ opacity: layer.opacity / 100
404
+ },
405
+ onPointerDown: onSelect,
406
+ onKeyDown,
407
+ onPositionChange: onLayerChange && ((position) => onLayerChange({
408
+ ...layer,
409
+ x: Math.round(position.x),
410
+ y: Math.round(position.y)
411
+ })),
412
+ children: [
413
+ layer.kind === "frame" ? /* @__PURE__ */ jsx("span", {
414
+ className: "absolute start-0 bottom-full mb-1 whitespace-nowrap text-caption text-muted-foreground",
415
+ children: layer.name
416
+ }) : null,
417
+ layer.kind === "text" ? /* @__PURE__ */ jsx("p", {
418
+ className: "size-full overflow-hidden text-2xl leading-8 whitespace-nowrap",
419
+ style: { color: fillColor },
420
+ children: layer.text
421
+ }) : /* @__PURE__ */ jsx("div", {
422
+ className: "size-full",
423
+ style: {
424
+ background: fillColor,
425
+ borderRadius: layer.kind === "ellipse" ? "50%" : layer.cornerRadius
426
+ }
427
+ }),
428
+ selected ? /* @__PURE__ */ jsxs("span", {
429
+ className: "absolute inset-x-0 top-full mx-auto mt-1.5 w-max rounded-sm bg-primary px-1 text-micro whitespace-nowrap text-primary-foreground tabular-nums",
430
+ children: [
431
+ layer.width,
432
+ " × ",
433
+ layer.height
434
+ ]
435
+ }) : null
436
+ ]
437
+ });
438
+ }
439
+ function DesignCanvasToolbarButton({ label, hint, pressed, children, ...props }) {
440
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
441
+ render: /* @__PURE__ */ jsx(ToolbarButton, {
442
+ ...props,
443
+ "aria-label": label,
444
+ iconOnly: true,
445
+ "aria-pressed": pressed,
446
+ "data-pressed": pressed ? "" : void 0
447
+ }),
448
+ children
449
+ }), /* @__PURE__ */ jsx(TooltipContent, { children: hint })] });
450
+ }
451
+ //#endregion
452
+ export { DesignCanvasBlock };
@@ -0,0 +1,28 @@
1
+ import { ChatComposer } from "../chat-composer.js";
2
+ import { ChatMessage } from "../chat-message.js";
3
+ import { ComponentProps, ReactNode } from "react";
4
+ //#region src/blocks/discussion.d.ts
5
+ export type DiscussionComposerProps = Omit<ComponentProps<typeof ChatComposer>, "submitKey" | "children"> & {
6
+ label: string;
7
+ placeholder?: string;
8
+ submitLabel?: ReactNode;
9
+ secondaryAction?: ReactNode;
10
+ hint?: ReactNode;
11
+ autoFocus?: boolean;
12
+ };
13
+ export declare function DiscussionComposer({ label, placeholder, submitLabel, secondaryAction, hint, autoFocus, ...props }: DiscussionComposerProps): import("react").JSX.Element;
14
+ export type DiscussionCommentProps = Omit<ComponentProps<typeof ChatMessage>, "from" | "layout" | "authorLabel" | "children"> & {
15
+ author: string;
16
+ avatar?: ReactNode;
17
+ sentAt: string;
18
+ timeLabel: ReactNode;
19
+ edited?: boolean;
20
+ children: ReactNode;
21
+ actions?: ReactNode;
22
+ onReply?: () => void;
23
+ replyLabel?: ReactNode;
24
+ replies?: ReactNode;
25
+ replyComposer?: ReactNode;
26
+ };
27
+ export declare function DiscussionComment({ author, avatar, sentAt, timeLabel, edited, children, actions, onReply, replyLabel, replies, replyComposer, ...props }: DiscussionCommentProps): import("react").JSX.Element;
28
+ //#endregion
@@ -0,0 +1,67 @@
1
+ "use client";
2
+ import { Button } from "../ui/button.js";
3
+ import { ChatComposer, ChatComposerShell, ChatComposerSubmit, ChatComposerTextarea, ChatComposerToolbar } from "../chat-composer.js";
4
+ import { ChatMessageReplies } from "../chat-message/social.js";
5
+ import { ChatMessage, ChatMessageActions, ChatMessageAuthor, ChatMessageAvatar, ChatMessageBody, ChatMessageContent, ChatMessageFooter, ChatMessageHeader, ChatMessageRow, ChatMessageTime } from "../chat-message.js";
6
+ import { Kbd, KbdGroup } from "../ui/kbd.js";
7
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
+ import { CornerDownRightIcon } from "lucide-react";
9
+ //#region src/blocks/discussion.tsx
10
+ function DiscussionComposer({ label, placeholder, submitLabel = "Post", secondaryAction, hint = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(KbdGroup, { children: [/* @__PURE__ */ jsx(Kbd, { children: "⌘" }), /* @__PURE__ */ jsx(Kbd, { children: "Enter" })] }), /* @__PURE__ */ jsx("span", { children: "to post" })] }), autoFocus, ...props }) {
11
+ return /* @__PURE__ */ jsx(ChatComposer, {
12
+ submitKey: "mod-enter",
13
+ ...props,
14
+ children: /* @__PURE__ */ jsxs(ChatComposerShell, { children: [/* @__PURE__ */ jsx(ChatComposerTextarea, {
15
+ "aria-label": label,
16
+ placeholder,
17
+ autoFocus,
18
+ "aria-keyshortcuts": "Meta+Enter Control+Enter"
19
+ }), /* @__PURE__ */ jsxs(ChatComposerToolbar, { children: [/* @__PURE__ */ jsx("span", {
20
+ className: "flex min-w-0 items-center gap-1.5 text-caption text-muted-foreground",
21
+ children: hint
22
+ }), /* @__PURE__ */ jsxs("span", {
23
+ className: "flex items-center gap-2",
24
+ children: [secondaryAction, /* @__PURE__ */ jsx(ChatComposerSubmit, { children: submitLabel })]
25
+ })] })] })
26
+ });
27
+ }
28
+ function initials(name) {
29
+ return name.split(/\s+/).slice(0, 2).map((word) => word.charAt(0).toUpperCase()).join("");
30
+ }
31
+ function DiscussionComment({ author, avatar, sentAt, timeLabel, edited = false, children, actions, onReply, replyLabel = "Reply", replies, replyComposer, ...props }) {
32
+ const hasReplies = Boolean(replies) || Boolean(replyComposer);
33
+ return /* @__PURE__ */ jsx(ChatMessage, {
34
+ from: "participant",
35
+ layout: "flat",
36
+ authorLabel: author,
37
+ ...props,
38
+ children: /* @__PURE__ */ jsxs(ChatMessageRow, { children: [
39
+ /* @__PURE__ */ jsx(ChatMessageAvatar, { children: avatar ?? /* @__PURE__ */ jsx("span", {
40
+ "aria-hidden": "true",
41
+ children: initials(author)
42
+ }) }),
43
+ /* @__PURE__ */ jsxs(ChatMessageBody, { children: [
44
+ /* @__PURE__ */ jsxs(ChatMessageHeader, { children: [
45
+ /* @__PURE__ */ jsx(ChatMessageAuthor, { children: author }),
46
+ /* @__PURE__ */ jsx(ChatMessageTime, {
47
+ dateTime: sentAt,
48
+ children: timeLabel
49
+ }),
50
+ edited ? /* @__PURE__ */ jsx("span", { children: "(edited)" }) : null
51
+ ] }),
52
+ /* @__PURE__ */ jsx(ChatMessageContent, { children }),
53
+ onReply ? /* @__PURE__ */ jsx(ChatMessageFooter, { children: /* @__PURE__ */ jsxs(Button, {
54
+ variant: "ghost",
55
+ size: "xs",
56
+ onClick: onReply,
57
+ className: "-ms-2",
58
+ children: [/* @__PURE__ */ jsx(CornerDownRightIcon, { "aria-hidden": "true" }), replyLabel]
59
+ }) }) : null,
60
+ hasReplies ? /* @__PURE__ */ jsxs(ChatMessageReplies, { children: [replies, replyComposer] }) : null
61
+ ] }),
62
+ actions ? /* @__PURE__ */ jsx(ChatMessageActions, { children: actions }) : null
63
+ ] })
64
+ });
65
+ }
66
+ //#endregion
67
+ export { DiscussionComment, DiscussionComposer };
@@ -52,5 +52,6 @@ export declare function groupFileExplorerItems<T extends {
52
52
  label: string;
53
53
  items: T[];
54
54
  }[];
55
+ export declare function orderFileExplorerEntries(entries: readonly FileExplorerEntry[]): FileExplorerEntry[];
55
56
  export declare function searchFileExplorer(location: FileExplorerLocation, query: string): readonly FileExplorerSearchResult[];
56
57
  //#endregion
@@ -52,6 +52,9 @@ function groupFileExplorerItems(items) {
52
52
  items: groupedItems
53
53
  }));
54
54
  }
55
+ function orderFileExplorerEntries(entries) {
56
+ return groupFileExplorerItems(entries).flatMap((group) => group.items);
57
+ }
55
58
  function searchFileExplorer(location, query) {
56
59
  const normalizedQuery = query.trim().toLocaleLowerCase();
57
60
  if (!normalizedQuery) return [];
@@ -71,4 +74,4 @@ function searchFileExplorer(location, query) {
71
74
  return results;
72
75
  }
73
76
  //#endregion
74
- export { groupFileExplorerItems, resolveFileExplorer, searchFileExplorer };
77
+ export { groupFileExplorerItems, orderFileExplorerEntries, resolveFileExplorer, searchFileExplorer };
@@ -16,9 +16,17 @@ export type FileExplorerBlockProps = Omit<ComponentProps<"div">, "children" | "d
16
16
  sidebarTop?: ReactNode;
17
17
  sidebarFooter?: ReactNode;
18
18
  headerActions?: ReactNode;
19
+ headerMenuItems?: ReactNode;
19
20
  searchPlaceholder?: string | false;
21
+ searchLabel?: string;
22
+ clearSearchLabel?: string;
23
+ searchResultsLabel?: string;
24
+ searchStatusLabel?: (count: number, query: string) => string;
25
+ backLabel?: string;
26
+ moreActionsLabel?: string;
27
+ detailsLabel?: string;
20
28
  layout?: "viewport" | "contained";
21
29
  };
22
- export declare function FileExplorerBlock({ locations, activeLocationId, defaultActiveLocationId, selectedPath, defaultSelectedPath, searchValue, defaultSearchValue, onActiveLocationChange, onSelectedPathChange, onSearchValueChange, onOpenEntry, sidebarTop, sidebarFooter, headerActions, searchPlaceholder, layout, className, style, ...props }: FileExplorerBlockProps): import("react").JSX.Element;
30
+ export declare function FileExplorerBlock({ locations, activeLocationId, defaultActiveLocationId, selectedPath, defaultSelectedPath, searchValue, defaultSearchValue, onActiveLocationChange, onSelectedPathChange, onSearchValueChange, onOpenEntry, sidebarTop, sidebarFooter, headerActions, headerMenuItems, searchPlaceholder, searchLabel, clearSearchLabel, searchResultsLabel, searchStatusLabel, backLabel, moreActionsLabel, detailsLabel, layout, className, style, ...props }: FileExplorerBlockProps): import("react").JSX.Element;
23
31
  //#endregion
24
32
  export type { FileExplorerBreadcrumb, FileExplorerColumn, FileExplorerEntry, FileExplorerEntryDetail, FileExplorerLocation, FileExplorerResolution, FileExplorerSearchResult };