@ctrl-ui/react 0.8.7 → 0.8.9

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 (341) 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 +39 -39
  8. package/dist/blocks/design-canvas.d.ts +5 -1
  9. package/dist/blocks/design-canvas.js +198 -92
  10. package/dist/blocks/discussion.d.ts +28 -0
  11. package/dist/blocks/discussion.js +67 -0
  12. package/dist/blocks/file-explorer-data.d.ts +1 -0
  13. package/dist/blocks/file-explorer-data.js +4 -1
  14. package/dist/blocks/file-explorer.d.ts +9 -1
  15. package/dist/blocks/file-explorer.js +461 -192
  16. package/dist/blocks/settings.d.ts +2 -1
  17. package/dist/blocks/settings.js +101 -79
  18. package/dist/blocks/team-chat.d.ts +12 -0
  19. package/dist/blocks/team-chat.js +26 -0
  20. package/dist/blocks/theme-toggle.js +23 -31
  21. package/dist/chat-composer-attachment.d.ts +4 -1
  22. package/dist/chat-composer-attachment.js +35 -10
  23. package/dist/chat-composer-editor/extensions/mention.d.ts +5 -1
  24. package/dist/chat-composer-editor/extensions/mention.js +59 -28
  25. package/dist/chat-composer-editor/ghost.js +2 -4
  26. package/dist/chat-composer-editor/types.d.ts +5 -0
  27. package/dist/chat-composer-editor.d.ts +1 -1
  28. package/dist/chat-composer-editor.js +57 -30
  29. package/dist/chat-composer.d.ts +13 -32
  30. package/dist/chat-composer.js +52 -12
  31. package/dist/chat-layout.d.ts +19 -0
  32. package/dist/chat-layout.js +91 -40
  33. package/dist/chat-message/social.d.ts +26 -0
  34. package/dist/chat-message/social.js +122 -0
  35. package/dist/chat-message.d.ts +28 -29
  36. package/dist/chat-message.js +106 -25
  37. package/dist/context.d.ts +2 -2
  38. package/dist/context.js +38 -23
  39. package/dist/dynamic-notification-canvas-loop.d.ts +24 -0
  40. package/dist/dynamic-notification-canvas-loop.js +113 -0
  41. package/dist/dynamic-notification-glass.js +23 -114
  42. package/dist/dynamic-notification-liquid.js +14 -118
  43. package/dist/dynamic-notification.d.ts +16 -8
  44. package/dist/dynamic-notification.js +85 -22
  45. package/dist/email/email-brand.d.ts +7 -4
  46. package/dist/email/email-brand.js +9 -6
  47. package/dist/email/email-code.d.ts +3 -2
  48. package/dist/email/email-code.js +11 -9
  49. package/dist/email/email-footer.d.ts +5 -3
  50. package/dist/email/email-footer.js +11 -5
  51. package/dist/email/email.d.ts +31 -9
  52. package/dist/email/email.js +50 -26
  53. package/dist/email/templates.d.ts +10 -9
  54. package/dist/email/templates.js +102 -38
  55. package/dist/email/theme.js +1 -1
  56. package/dist/environment-variables.d.ts +4 -2
  57. package/dist/environment-variables.js +52 -32
  58. package/dist/filter-bar/editor.js +20 -8
  59. package/dist/filter-bar/model.d.ts +1 -0
  60. package/dist/filter-bar/model.js +10 -1
  61. package/dist/filter-bar/motion.js +4 -4
  62. package/dist/filter-bar/parts.js +19 -8
  63. package/dist/filter-bar/types.d.ts +1 -0
  64. package/dist/filter-bar.js +19 -13
  65. package/dist/hooks/use-audio-recorder.js +12 -6
  66. package/dist/hooks/use-chat-composer.d.ts +19 -7
  67. package/dist/hooks/use-chat-composer.js +32 -5
  68. package/dist/hooks/use-chat-message.d.ts +28 -2
  69. package/dist/hooks/use-chat-message.js +41 -10
  70. package/dist/hooks/use-chat-thread-scroll.js +43 -7
  71. package/dist/hooks/use-color-area.d.ts +3 -3
  72. package/dist/hooks/use-color-area.js +13 -12
  73. package/dist/hooks/use-copy-to-clipboard.d.ts +2 -1
  74. package/dist/hooks/use-copy-to-clipboard.js +20 -20
  75. package/dist/hooks/use-dynamic-notification.d.ts +6 -2
  76. package/dist/hooks/use-dynamic-notification.js +26 -10
  77. package/dist/hooks/use-mobile.d.ts +3 -2
  78. package/dist/hooks/use-mobile.js +8 -4
  79. package/dist/hooks/use-textarea-trigger-menu.js +2 -1
  80. package/dist/hooks/use-trigger-menu.d.ts +54 -0
  81. package/dist/hooks/use-trigger-menu.js +102 -47
  82. package/dist/hooks/use-user-ask.d.ts +2 -0
  83. package/dist/hooks/use-user-ask.js +35 -41
  84. package/dist/inline-attachment.d.ts +6 -2
  85. package/dist/inline-attachment.js +36 -15
  86. package/dist/inline-citation.d.ts +12 -5
  87. package/dist/inline-citation.js +25 -16
  88. package/dist/knob-contracts/audio-recorder-knobs.d.ts +1 -1
  89. package/dist/knob-contracts/audio-recorder-knobs.js +2 -1
  90. package/dist/knob-contracts/audio-visualizer-knobs.d.ts +1 -1
  91. package/dist/knob-contracts/audio-visualizer-knobs.js +2 -1
  92. package/dist/knob-contracts/avatar-knobs.d.ts +1 -1
  93. package/dist/knob-contracts/avatar-knobs.js +6 -1
  94. package/dist/knob-contracts/badge-knobs.d.ts +1 -1
  95. package/dist/knob-contracts/badge-knobs.js +2 -1
  96. package/dist/knob-contracts/breadcrumb-knobs.d.ts +4 -0
  97. package/dist/knob-contracts/breadcrumb-knobs.js +8 -0
  98. package/dist/knob-contracts/button-knobs.d.ts +1 -1
  99. package/dist/knob-contracts/button-knobs.js +1 -0
  100. package/dist/knob-contracts/chat-message-knobs.d.ts +1 -1
  101. package/dist/knob-contracts/chat-message-knobs.js +8 -1
  102. package/dist/knob-contracts/code-diff-knobs.d.ts +1 -1
  103. package/dist/knob-contracts/code-diff-knobs.js +2 -0
  104. package/dist/knob-contracts/code-knobs.d.ts +1 -1
  105. package/dist/knob-contracts/code-knobs.js +2 -1
  106. package/dist/knob-contracts/dynamic-notification-knobs.d.ts +1 -1
  107. package/dist/knob-contracts/dynamic-notification-knobs.js +2 -0
  108. package/dist/knob-contracts/emoji-picker-knobs.d.ts +4 -0
  109. package/dist/knob-contracts/emoji-picker-knobs.js +10 -0
  110. package/dist/knob-contracts/field-knobs.d.ts +1 -1
  111. package/dist/knob-contracts/field-knobs.js +5 -1
  112. package/dist/knob-contracts/filter-bar-knobs.d.ts +1 -1
  113. package/dist/knob-contracts/filter-bar-knobs.js +1 -2
  114. package/dist/knob-contracts/markdown-knobs.d.ts +1 -1
  115. package/dist/knob-contracts/markdown-knobs.js +3 -1
  116. package/dist/knob-contracts/page-layout-knobs.d.ts +1 -1
  117. package/dist/knob-contracts/page-layout-knobs.js +2 -1
  118. package/dist/knob-contracts/popup-knobs.d.ts +1 -1
  119. package/dist/knob-contracts/popup-knobs.js +27 -0
  120. package/dist/knob-contracts/range-knobs.d.ts +1 -1
  121. package/dist/knob-contracts/range-knobs.js +1 -0
  122. package/dist/knob-contracts/rich-tooltip-knobs.d.ts +1 -1
  123. package/dist/knob-contracts/rich-tooltip-knobs.js +2 -1
  124. package/dist/knob-contracts/sidebar-knobs.d.ts +1 -1
  125. package/dist/knob-contracts/sidebar-knobs.js +27 -2
  126. package/dist/knob-contracts/spinner-knobs.d.ts +1 -1
  127. package/dist/knob-contracts/spinner-knobs.js +1 -1
  128. package/dist/knob-contracts/stepper-knobs.d.ts +1 -1
  129. package/dist/knob-contracts/stepper-knobs.js +4 -1
  130. package/dist/knob-contracts/switch-knobs.d.ts +1 -1
  131. package/dist/knob-contracts/switch-knobs.js +5 -0
  132. package/dist/knob-contracts/table-of-contents-knobs.d.ts +1 -1
  133. package/dist/knob-contracts/table-of-contents-knobs.js +2 -1
  134. package/dist/knob-contracts/tabs-knobs.d.ts +1 -1
  135. package/dist/knob-contracts/tabs-knobs.js +1 -0
  136. package/dist/knob-contracts/tree-knobs.d.ts +1 -1
  137. package/dist/knob-contracts/tree-knobs.js +2 -1
  138. package/dist/lib/cn.js +0 -4
  139. package/dist/lib/contrast.d.ts +1 -0
  140. package/dist/lib/contrast.js +17 -5
  141. package/dist/lib/dropzone-validation.js +41 -28
  142. package/dist/lib/env-file.d.ts +1 -1
  143. package/dist/lib/env-file.js +5 -5
  144. package/dist/lib/motion.d.ts +4 -0
  145. package/dist/lib/motion.js +15 -0
  146. package/dist/lib/trigger-detect.js +6 -8
  147. package/dist/markdown-block.js +2 -1
  148. package/dist/popup-parts.d.ts +8 -0
  149. package/dist/popup-parts.js +43 -0
  150. package/dist/source-badge.js +3 -1
  151. package/dist/styles/code.css +0 -2
  152. package/dist/styles/effects.css +6 -32
  153. package/dist/styles/index.css +10 -5
  154. package/dist/styles/recipes/accordion.css +9 -6
  155. package/dist/styles/recipes/action-bar.css +0 -15
  156. package/dist/styles/recipes/activity.css +5 -11
  157. package/dist/styles/recipes/alert.css +4 -4
  158. package/dist/styles/recipes/audio-recorder.css +15 -3
  159. package/dist/styles/recipes/audio-visualizer.css +13 -2
  160. package/dist/styles/recipes/avatar.css +78 -1
  161. package/dist/styles/recipes/badge.css +14 -4
  162. package/dist/styles/recipes/breadcrumb.css +77 -0
  163. package/dist/styles/recipes/button-group.css +5 -7
  164. package/dist/styles/recipes/button-states.css +66 -0
  165. package/dist/styles/recipes/button.css +24 -83
  166. package/dist/styles/recipes/calendar.css +17 -23
  167. package/dist/styles/recipes/card.css +2 -2
  168. package/dist/styles/recipes/chat-composer-attachment.css +9 -3
  169. package/dist/styles/recipes/chat-composer.css +7 -10
  170. package/dist/styles/recipes/chat-layout.css +35 -0
  171. package/dist/styles/recipes/chat-message-social.css +123 -0
  172. package/dist/styles/recipes/chat-message.css +157 -37
  173. package/dist/styles/recipes/choice.css +18 -21
  174. package/dist/styles/recipes/code-diff.css +46 -33
  175. package/dist/styles/recipes/code.css +36 -16
  176. package/dist/styles/recipes/collapsible.css +7 -2
  177. package/dist/styles/recipes/color-picker-details.css +3 -4
  178. package/dist/styles/recipes/color-picker-values.css +9 -8
  179. package/dist/styles/recipes/color-picker.css +11 -2
  180. package/dist/styles/recipes/context.css +3 -3
  181. package/dist/styles/recipes/dockable-panel.css +7 -4
  182. package/dist/styles/recipes/dropzone.css +7 -8
  183. package/dist/styles/recipes/dynamic-notification-input.css +8 -5
  184. package/dist/styles/recipes/dynamic-notification-motion.css +12 -21
  185. package/dist/styles/recipes/dynamic-notification.css +40 -26
  186. package/dist/styles/recipes/emoji-picker.css +132 -0
  187. package/dist/styles/recipes/empty.css +5 -4
  188. package/dist/styles/recipes/environment-variables.css +4 -15
  189. package/dist/styles/recipes/field-parts.css +30 -24
  190. package/dist/styles/recipes/field.css +61 -26
  191. package/dist/styles/recipes/filter-bar.css +18 -31
  192. package/dist/styles/recipes/gradient-editor.css +18 -7
  193. package/dist/styles/recipes/infinite-canvas.css +0 -1
  194. package/dist/styles/recipes/inline-attachment.css +3 -3
  195. package/dist/styles/recipes/inline-citation.css +10 -4
  196. package/dist/styles/recipes/item.css +23 -9
  197. package/dist/styles/recipes/markdown-block.css +5 -4
  198. package/dist/styles/recipes/markdown.css +68 -26
  199. package/dist/styles/recipes/morphing-panel.css +8 -8
  200. package/dist/styles/recipes/page-layout.css +20 -12
  201. package/dist/styles/recipes/pagination.css +4 -5
  202. package/dist/styles/recipes/phone-input.css +12 -8
  203. package/dist/styles/recipes/popup-controls.css +166 -33
  204. package/dist/styles/recipes/popup-drawer.css +3 -14
  205. package/dist/styles/recipes/popup-lists.css +128 -27
  206. package/dist/styles/recipes/popup-motion.css +4 -45
  207. package/dist/styles/recipes/popup-toast.css +55 -26
  208. package/dist/styles/recipes/popup.css +139 -141
  209. package/dist/styles/recipes/range.css +54 -18
  210. package/dist/styles/recipes/resizable.css +2 -7
  211. package/dist/styles/recipes/rich-tooltip.css +24 -34
  212. package/dist/styles/recipes/scroll-area.css +8 -1
  213. package/dist/styles/recipes/sidebar-menu.css +166 -34
  214. package/dist/styles/recipes/sidebar-parts.css +192 -0
  215. package/dist/styles/recipes/sidebar.css +188 -128
  216. package/dist/styles/recipes/source-badge.css +1 -1
  217. package/dist/styles/recipes/spinner.css +8 -1
  218. package/dist/styles/recipes/stepper.css +31 -13
  219. package/dist/styles/recipes/switch.css +68 -23
  220. package/dist/styles/recipes/table-of-contents.css +9 -1
  221. package/dist/styles/recipes/table.css +14 -10
  222. package/dist/styles/recipes/tabs.css +17 -12
  223. package/dist/styles/recipes/task-list.css +7 -14
  224. package/dist/styles/recipes/thread-rail.css +42 -19
  225. package/dist/styles/recipes/timeline.css +2 -0
  226. package/dist/styles/recipes/toolbar.css +27 -25
  227. package/dist/styles/recipes/track-highlight.css +10 -7
  228. package/dist/styles/recipes/tree.css +31 -4
  229. package/dist/styles/recipes/user-ask-details.css +0 -1
  230. package/dist/styles/recipes/user-ask.css +4 -4
  231. package/dist/styles/theme.css +37 -16
  232. package/dist/task-list.d.ts +4 -1
  233. package/dist/task-list.js +24 -8
  234. package/dist/thread-rail.d.ts +1 -1
  235. package/dist/thread-rail.js +61 -19
  236. package/dist/transcript-divider.js +2 -1
  237. package/dist/ui/alert.d.ts +3 -1
  238. package/dist/ui/alert.js +14 -8
  239. package/dist/ui/autocomplete.js +3 -1
  240. package/dist/ui/avatar.d.ts +8 -0
  241. package/dist/ui/avatar.js +23 -3
  242. package/dist/ui/badge.js +1 -1
  243. package/dist/ui/breadcrumb.d.ts +27 -0
  244. package/dist/ui/breadcrumb.js +88 -0
  245. package/dist/ui/button.d.ts +2 -1
  246. package/dist/ui/button.js +1 -1
  247. package/dist/ui/calendar.js +2 -2
  248. package/dist/ui/card.d.ts +3 -1
  249. package/dist/ui/card.js +12 -7
  250. package/dist/ui/checkbox.d.ts +2 -0
  251. package/dist/ui/code-diff.d.ts +1 -1
  252. package/dist/ui/code-diff.js +71 -27
  253. package/dist/ui/code.d.ts +5 -3
  254. package/dist/ui/code.js +26 -27
  255. package/dist/ui/color-picker.d.ts +5 -2
  256. package/dist/ui/color-picker.js +84 -36
  257. package/dist/ui/combobox-disabled-selection.d.ts +1 -2
  258. package/dist/ui/combobox-disabled-selection.js +7 -9
  259. package/dist/ui/combobox.js +13 -5
  260. package/dist/ui/command.d.ts +8 -2
  261. package/dist/ui/command.js +30 -14
  262. package/dist/ui/context-menu.js +3 -0
  263. package/dist/ui/dialog.d.ts +2 -1
  264. package/dist/ui/dialog.js +3 -22
  265. package/dist/ui/dockable-panel-geometry.d.ts +1 -0
  266. package/dist/ui/dockable-panel-geometry.js +7 -1
  267. package/dist/ui/dockable-panel.d.ts +9 -6
  268. package/dist/ui/dockable-panel.js +63 -23
  269. package/dist/ui/dropdown-menu.js +4 -3
  270. package/dist/ui/dropzone.d.ts +2 -2
  271. package/dist/ui/dropzone.js +75 -16
  272. package/dist/ui/emoji-picker.d.ts +18 -0
  273. package/dist/ui/emoji-picker.js +136 -0
  274. package/dist/ui/empty.d.ts +3 -1
  275. package/dist/ui/empty.js +12 -7
  276. package/dist/ui/gradient-editor.d.ts +1 -1
  277. package/dist/ui/gradient-editor.js +37 -21
  278. package/dist/ui/infinite-canvas.d.ts +3 -2
  279. package/dist/ui/infinite-canvas.js +63 -19
  280. package/dist/ui/input-group.d.ts +0 -3
  281. package/dist/ui/input-group.js +3 -13
  282. package/dist/ui/input-otp.d.ts +1 -1
  283. package/dist/ui/input-otp.js +32 -15
  284. package/dist/ui/input.js +4 -4
  285. package/dist/ui/item.d.ts +2 -1
  286. package/dist/ui/item.js +11 -7
  287. package/dist/ui/live-status.d.ts +7 -0
  288. package/dist/ui/live-status.js +17 -0
  289. package/dist/ui/markdown-elements.d.ts +6 -0
  290. package/dist/ui/markdown-elements.js +31 -1
  291. package/dist/ui/menubar.js +2 -2
  292. package/dist/ui/morphing-panel.js +2 -1
  293. package/dist/ui/native-select.d.ts +1 -1
  294. package/dist/ui/native-select.js +24 -11
  295. package/dist/ui/page-layout.d.ts +2 -2
  296. package/dist/ui/page-layout.js +2 -4
  297. package/dist/ui/pagination.d.ts +7 -5
  298. package/dist/ui/pagination.js +19 -13
  299. package/dist/ui/phone-input.d.ts +1 -0
  300. package/dist/ui/phone-input.js +56 -58
  301. package/dist/ui/radio-group.d.ts +2 -0
  302. package/dist/ui/resizable.d.ts +3 -2
  303. package/dist/ui/resizable.js +5 -3
  304. package/dist/ui/responsive-dialog.d.ts +1 -1
  305. package/dist/ui/responsive-dialog.js +4 -21
  306. package/dist/ui/rich-tooltip.d.ts +10 -4
  307. package/dist/ui/rich-tooltip.js +81 -33
  308. package/dist/ui/scroll-area.d.ts +1 -1
  309. package/dist/ui/scroll-area.js +43 -28
  310. package/dist/ui/sidebar-menu.d.ts +5 -1
  311. package/dist/ui/sidebar-menu.js +34 -34
  312. package/dist/ui/sidebar-provider.d.ts +10 -1
  313. package/dist/ui/sidebar-provider.js +38 -13
  314. package/dist/ui/sidebar-resize-rail.js +7 -3
  315. package/dist/ui/sidebar.d.ts +11 -6
  316. package/dist/ui/sidebar.js +48 -24
  317. package/dist/ui/slider.js +31 -22
  318. package/dist/ui/spinner.d.ts +3 -2
  319. package/dist/ui/spinner.js +3 -2
  320. package/dist/ui/stepper.d.ts +8 -1
  321. package/dist/ui/stepper.js +74 -25
  322. package/dist/ui/switch.d.ts +1 -0
  323. package/dist/ui/table-of-contents.d.ts +2 -2
  324. package/dist/ui/table-of-contents.js +20 -8
  325. package/dist/ui/table.js +4 -2
  326. package/dist/ui/textarea.d.ts +1 -1
  327. package/dist/ui/textarea.js +20 -9
  328. package/dist/ui/timeline.d.ts +3 -1
  329. package/dist/ui/timeline.js +17 -9
  330. package/dist/ui/toast.d.ts +11 -5
  331. package/dist/ui/toast.js +100 -54
  332. package/dist/ui/toolbar.d.ts +2 -1
  333. package/dist/ui/toolbar.js +3 -1
  334. package/dist/ui/tooltip.js +3 -20
  335. package/dist/ui/tree.js +120 -80
  336. package/dist/ui/trigger-menu.js +1 -0
  337. package/dist/user-ask.d.ts +10 -5
  338. package/dist/user-ask.js +31 -11
  339. package/package.json +5 -1
  340. package/dist/hooks/use-keyboard-navigation.d.ts +0 -3
  341. package/dist/hooks/use-keyboard-navigation.js +0 -22
@@ -24,20 +24,28 @@ export type ActionBarProps = Omit<ComponentProps<"div">, "style"> & {
24
24
  style?: CSSProperties & ActionBarKnobStyle;
25
25
  };
26
26
  export declare function ActionBar({ label, align, className, children, context, copyValue, editValue, onCopy, onCopyError, onEdit, onEditError, ...props }: ActionBarProps): import("react").JSX.Element;
27
- export type ActionBarItemProps = ComponentProps<typeof Button> & {
27
+ type ActionBarItemBaseProps = Omit<ComponentProps<typeof Button>, "iconOnly" | "children"> & {
28
28
  icon?: ReactNode;
29
29
  };
30
- export declare function ActionBarItem({ icon, children, className, ...props }: ActionBarItemProps): import("react").JSX.Element;
31
- export type ActionBarCopyProps = Omit<ActionBarItemProps, "children"> & {
30
+ export type ActionBarItemProps = ActionBarItemBaseProps & ({
31
+ children: NonNullable<ReactNode>;
32
+ } | {
33
+ children?: null;
34
+ "aria-label": string;
35
+ });
36
+ export declare function ActionBarItem({ icon, children, active, disabled, ...props }: ActionBarItemProps): import("react").JSX.Element;
37
+ export type ActionBarCopyProps = ActionBarItemBaseProps & {
32
38
  value?: ActionBarCopyValue;
33
- children?: ReactNode;
39
+ children?: NonNullable<ReactNode>;
34
40
  copiedChildren?: ReactNode;
41
+ copiedAriaLabel?: string;
42
+ copyFailedLabel?: string;
35
43
  resetDelay?: number;
36
44
  };
37
- export declare function ActionBarCopy({ value, children, copiedChildren, resetDelay, disabled, onClick, ...props }: ActionBarCopyProps): import("react").JSX.Element;
38
- export type ActionBarEditProps = Omit<ActionBarItemProps, "children"> & {
45
+ export declare function ActionBarCopy({ value, children, copiedChildren, copiedAriaLabel, copyFailedLabel, resetDelay, disabled, onClick, ...props }: ActionBarCopyProps): import("react").JSX.Element;
46
+ export type ActionBarEditProps = ActionBarItemBaseProps & {
39
47
  value?: ActionBarCopyValue;
40
- children?: ReactNode;
48
+ children?: NonNullable<ReactNode>;
41
49
  };
42
50
  export declare function ActionBarEdit({ value, children, disabled, onClick, ...props }: ActionBarEditProps): import("react").JSX.Element;
43
51
  //#endregion
@@ -1,9 +1,11 @@
1
1
  "use client";
2
2
  import { cn } from "./lib/cn.js";
3
3
  import { Button } from "./ui/button.js";
4
+ import { LiveStatus } from "./ui/live-status.js";
4
5
  import { useCopyToClipboard } from "./hooks/use-copy-to-clipboard.js";
5
6
  import { createContext, useContext } from "react";
6
- import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
+ import { Toolbar } from "@base-ui/react/toolbar";
7
9
  //#region src/action-bar.tsx
8
10
  const ActionBarContext = createContext({});
9
11
  async function resolveCopyValue(value) {
@@ -21,30 +23,35 @@ function ActionBar({ label = "Message actions", align = "start", className, chil
21
23
  };
22
24
  return /* @__PURE__ */ jsx(ActionBarContext.Provider, {
23
25
  value: actionContext,
24
- children: /* @__PURE__ */ jsx("div", {
26
+ children: /* @__PURE__ */ jsx(Toolbar.Root, {
27
+ ...props,
25
28
  "data-control-ui": "action-bar",
26
29
  "data-control-family": "action-bar",
27
30
  "data-slot": "root",
28
- role: "toolbar",
29
31
  "aria-label": label,
30
32
  className: cn("flex items-center", align === "end" ? "justify-end" : "justify-start", className),
31
- ...props,
32
33
  children
33
34
  })
34
35
  });
35
36
  }
36
- function ActionBarItem({ icon, children, className, ...props }) {
37
- return /* @__PURE__ */ jsxs(Button, {
38
- size: "xs",
39
- className,
40
- ...props,
41
- children: [icon, children]
37
+ function ActionBarItem({ icon, children, active, disabled, ...props }) {
38
+ return /* @__PURE__ */ jsx(Toolbar.Button, {
39
+ disabled,
40
+ focusableWhenDisabled: false,
41
+ render: /* @__PURE__ */ jsxs(Button, {
42
+ size: "xs",
43
+ active,
44
+ "aria-pressed": active,
45
+ iconOnly: children == null,
46
+ ...props,
47
+ children: [icon, children]
48
+ })
42
49
  });
43
50
  }
44
- function ActionBarCopy({ value, children = "Copy", copiedChildren = "Copied", resetDelay = 1200, disabled, onClick, ...props }) {
51
+ function ActionBarCopy({ value, children = "Copy", copiedChildren = "Copied", copiedAriaLabel = "Copied to clipboard", copyFailedLabel = "Couldn't copy. Select the text and copy it manually.", resetDelay = 1200, disabled, onClick, ...props }) {
45
52
  const { copyValue: contextCopyValue, onCopy, onCopyError } = useContext(ActionBarContext);
46
53
  const copyValue = value ?? contextCopyValue;
47
- const { isCopied, copyToClipboard } = useCopyToClipboard({
54
+ const { status, copyToClipboard } = useCopyToClipboard({
48
55
  copiedDuration: resetDelay,
49
56
  onCopy,
50
57
  onCopyError
@@ -52,17 +59,30 @@ function ActionBarCopy({ value, children = "Copy", copiedChildren = "Copied", re
52
59
  async function handleClick(event) {
53
60
  onClick?.(event);
54
61
  if (event.defaultPrevented) return;
55
- const nextValue = await resolveCopyValue(copyValue);
56
- if (!nextValue) return;
57
- await copyToClipboard(nextValue);
62
+ try {
63
+ const nextValue = await resolveCopyValue(copyValue);
64
+ if (!nextValue) return;
65
+ await copyToClipboard(nextValue);
66
+ } catch (error) {
67
+ onCopyError?.(error);
68
+ }
58
69
  }
59
- return /* @__PURE__ */ jsx(ActionBarItem, {
60
- "aria-live": "polite",
70
+ let copyStatus = "";
71
+ if (status === "copied") copyStatus = copiedAriaLabel;
72
+ else if (status === "failed") copyStatus = copyFailedLabel;
73
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(ActionBarItem, {
61
74
  disabled: disabled ?? !copyValue,
62
75
  onClick: handleClick,
63
76
  ...props,
64
- children: isCopied ? copiedChildren : children
65
- });
77
+ children: status === "copied" ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
78
+ "aria-hidden": "true",
79
+ className: "contents",
80
+ children: copiedChildren
81
+ }), /* @__PURE__ */ jsx("span", {
82
+ className: "sr-only",
83
+ children
84
+ })] }) : children
85
+ }), /* @__PURE__ */ jsx(LiveStatus, { message: copyStatus })] });
66
86
  }
67
87
  function ActionBarEdit({ value, children = "Edit", disabled, onClick, ...props }) {
68
88
  const { copyValue, editValue: contextEditValue, onEdit, onEditError } = useContext(ActionBarContext);
package/dist/activity.js CHANGED
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { cn } from "./lib/cn.js";
3
+ import { LiveStatus } from "./ui/live-status.js";
3
4
  import { ScrollArea } from "./ui/scroll-area.js";
4
5
  import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "./ui/collapsible.js";
5
6
  import { createContext, useContext } from "react";
@@ -30,13 +31,13 @@ function formatActivityTitle(value) {
30
31
  }
31
32
  function Activity({ kind = "default", name, state = "pending", statusLabel, className, children, ...props }) {
32
33
  const context = {
33
- isError: state === "error",
34
34
  isRunning: state === "running",
35
35
  kind,
36
36
  name,
37
37
  state,
38
38
  statusLabel: statusLabel ?? activityStatusLabels[state]
39
39
  };
40
+ const statusText = typeof context.statusLabel === "string" ? context.statusLabel : activityStatusLabels[state];
40
41
  return /* @__PURE__ */ jsx(ActivityContext.Provider, {
41
42
  value: context,
42
43
  children: /* @__PURE__ */ jsxs(Collapsible, {
@@ -46,20 +47,9 @@ function Activity({ kind = "default", name, state = "pending", statusLabel, clas
46
47
  "data-activity-state": state,
47
48
  "data-activity-kind": kind,
48
49
  "data-activity-name": name,
49
- "aria-busy": context.isRunning || void 0,
50
50
  className: cn("group/activity min-w-0", className),
51
51
  ...props,
52
- children: [/* @__PURE__ */ jsx("span", {
53
- role: context.isError ? "alert" : "status",
54
- "aria-live": context.isError ? "assertive" : "polite",
55
- "aria-atomic": "true",
56
- "data-control-ui": "activity",
57
- "data-control-family": "activity",
58
- "data-slot": "announcement",
59
- "data-status": state,
60
- className: "sr-only",
61
- children: context.statusLabel
62
- }), children]
52
+ children: [/* @__PURE__ */ jsx(LiveStatus, { message: name ? `${formatActivityTitle(name)}: ${statusText}` : statusText }), children]
63
53
  })
64
54
  });
65
55
  }
@@ -101,18 +91,20 @@ function ActivityIcon({ className, children, ...props }) {
101
91
  "data-slot": "icon",
102
92
  ...props,
103
93
  className: cn("flex shrink-0 items-center justify-center [&_svg]:size-4", className),
104
- children: children ?? /* @__PURE__ */ jsx(Icon, {})
94
+ children: children ?? /* @__PURE__ */ jsx(Icon, { "data-motion-essential": activity.isRunning ? "" : void 0 })
105
95
  });
106
96
  }
107
97
  function ActivityTitle({ className, children, ...props }) {
108
98
  const activity = useActivityContext();
99
+ const text = children ?? (activity.name ? formatActivityTitle(activity.name) : void 0);
109
100
  return /* @__PURE__ */ jsx("span", {
110
101
  "data-control-ui": "activity",
111
102
  "data-control-family": "activity",
112
103
  "data-slot": "title",
104
+ title: typeof text === "string" ? text : void 0,
113
105
  ...props,
114
106
  className: cn("min-w-0 flex-1 truncate", className),
115
- children: children ?? (activity.name ? formatActivityTitle(activity.name) : void 0)
107
+ children: text
116
108
  });
117
109
  }
118
110
  function ActivityStatus({ className, children, ...props }) {
@@ -11,11 +11,16 @@ type AudioRecorderStyleProps<Props, Style> = Omit<Props, "style"> & {
11
11
  export declare function useAudioRecorderContext(): UseAudioRecorderResult;
12
12
  export type AudioRecorderProps = Omit<ComponentProps<"div">, "style"> & UseAudioRecorderOptions & {
13
13
  label?: string;
14
+ recordingLabel?: string;
15
+ timeLimitLabel?: string;
16
+ sendingLabel?: string;
17
+ sentLabel?: string;
18
+ canceledLabel?: string;
14
19
  style?: CSSProperties & AudioRecorderKnobStyle;
15
20
  };
16
- export declare function AudioRecorder({ onRecordingComplete, onCancel, maxDurationMs, disabled, barCount, barDurationMs, deviceId, label, className, children, ...props }: AudioRecorderProps): import("react").JSX.Element;
21
+ export declare function AudioRecorder({ onRecordingComplete, onCancel, maxDurationMs, disabled, barCount, barDurationMs, deviceId, label, recordingLabel, timeLimitLabel, sendingLabel, sentLabel, canceledLabel, className, children, ...props }: AudioRecorderProps): import("react").JSX.Element;
17
22
  export type AudioRecorderTriggerProps = AudioRecorderStyleProps<ComponentProps<typeof Button>, ButtonKnobStyle & AudioRecorderKnobStyle>;
18
- export declare function AudioRecorderTrigger({ className, children, disabled, onClick, ...props }: AudioRecorderTriggerProps): import("react").JSX.Element;
23
+ export declare function AudioRecorderTrigger({ className, children, disabled, onClick, ref, ...props }: AudioRecorderTriggerProps): import("react").JSX.Element;
19
24
  export type AudioRecorderVisualizerProps = AudioRecorderStyleProps<Omit<ComponentProps<"div">, "children">, AudioVisualizerKnobStyle & AudioRecorderKnobStyle> & {
20
25
  points?: number;
21
26
  };
@@ -23,10 +28,15 @@ export declare function AudioRecorderVisualizer({ points, className, ...props }:
23
28
  export type AudioRecorderStatusProps = AudioRecorderStyleProps<ComponentProps<"span">, AudioRecorderKnobStyle>;
24
29
  export declare function AudioRecorderStatus({ className, children, ...props }: AudioRecorderStatusProps): import("react").JSX.Element;
25
30
  export type AudioRecorderDurationProps = AudioRecorderStyleProps<ComponentProps<"span">, AudioRecorderKnobStyle>;
26
- export declare function AudioRecorderDuration({ className, children, ...props }: AudioRecorderDurationProps): import("react").JSX.Element;
31
+ export declare function AudioRecorderDuration({ className, children, durationLabel, ...props }: AudioRecorderDurationProps & {
32
+ durationLabel?: string;
33
+ }): import("react").JSX.Element;
27
34
  export type AudioRecorderCancelProps = AudioRecorderStyleProps<ComponentProps<typeof Button>, ButtonKnobStyle & AudioRecorderKnobStyle>;
28
35
  export declare function AudioRecorderCancel({ className, children, disabled, onClick, tabIndex, ...props }: AudioRecorderCancelProps): import("react").JSX.Element;
29
36
  export type AudioRecorderSubmitProps = AudioRecorderStyleProps<ComponentProps<typeof Button>, ButtonKnobStyle & AudioRecorderKnobStyle>;
30
- export declare function AudioRecorderSubmit({ className, children, disabled, onClick, tabIndex, ...props }: AudioRecorderSubmitProps): import("react").JSX.Element;
37
+ export declare function AudioRecorderSubmit({ className, children, disabled, onClick, tabIndex, label, retryLabel, ...props }: AudioRecorderSubmitProps & {
38
+ label?: string;
39
+ retryLabel?: string;
40
+ }): import("react").JSX.Element;
31
41
  //#endregion
32
42
  export type { AudioRecording };
@@ -1,20 +1,35 @@
1
1
  "use client";
2
2
  import { cn } from "./lib/cn.js";
3
3
  import { Button } from "./ui/button.js";
4
+ import { LiveStatus } from "./ui/live-status.js";
4
5
  import { AudioVisualizer } from "./audio-visualizer.js";
5
6
  import { useAudioRecorder } from "./hooks/use-audio-recorder.js";
6
7
  import { formatAudioRecorderDuration } from "./lib/format-audio-recorder-duration.js";
7
- import { createContext, use } from "react";
8
+ import { createContext, use, useRef, useState } from "react";
8
9
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
10
  import { CheckIcon, MicIcon, XIcon } from "lucide-react";
10
11
  //#region src/audio-recorder.tsx
11
12
  const AudioRecorderContext = createContext(null);
13
+ const AudioRecorderTriggerRefContext = createContext(null);
14
+ function focusAudioRecorderTrigger(triggerRef) {
15
+ triggerRef?.current?.focus();
16
+ }
12
17
  function useAudioRecorderContext() {
13
18
  const context = use(AudioRecorderContext);
14
19
  if (!context) throw new Error("AudioRecorder compound components must be rendered inside <AudioRecorder>.");
15
20
  return context;
16
21
  }
17
- function AudioRecorder({ onRecordingComplete, onCancel, maxDurationMs, disabled, barCount, barDurationMs, deviceId, label = "Voice recorder", className, children, ...props }) {
22
+ function audioRecorderAnnouncement(previous, next, maxDurationMs, labels) {
23
+ if (next.error && next.error !== previous.error) return next.error.message;
24
+ if (next.state === previous.state) return null;
25
+ if (next.state === "recording") return labels.recordingLabel;
26
+ if (next.state === "submitting") return labels.sendingLabel;
27
+ if (next.state === "recorded" && previous.state === "recording" && maxDurationMs && next.durationMs >= maxDurationMs) return labels.timeLimitLabel;
28
+ if (next.state === "idle" && previous.state === "submitting") return labels.sentLabel;
29
+ if (next.state === "idle" && (previous.state === "recording" || previous.state === "recorded")) return labels.canceledLabel;
30
+ return null;
31
+ }
32
+ function AudioRecorder({ onRecordingComplete, onCancel, maxDurationMs, disabled, barCount, barDurationMs, deviceId, label = "Voice recorder", recordingLabel = "Recording", timeLimitLabel = "Stopped at time limit", sendingLabel = "Sending voice recording", sentLabel = "Voice recording sent", canceledLabel = "Voice recording canceled", className, children, ...props }) {
18
33
  const recorder = useAudioRecorder({
19
34
  onRecordingComplete,
20
35
  onCancel,
@@ -24,21 +39,42 @@ function AudioRecorder({ onRecordingComplete, onCancel, maxDurationMs, disabled,
24
39
  barDurationMs,
25
40
  deviceId
26
41
  });
42
+ const triggerRef = useRef(null);
43
+ const [previous, setPrevious] = useState(recorder);
44
+ const [announcement, setAnnouncement] = useState("");
45
+ if (previous.state !== recorder.state || previous.error !== recorder.error) {
46
+ const next = audioRecorderAnnouncement(previous, recorder, maxDurationMs, {
47
+ recordingLabel,
48
+ timeLimitLabel,
49
+ sendingLabel,
50
+ sentLabel,
51
+ canceledLabel
52
+ });
53
+ setPrevious({
54
+ state: recorder.state,
55
+ error: recorder.error,
56
+ durationMs: recorder.durationMs
57
+ });
58
+ if (next !== null) setAnnouncement(next);
59
+ }
27
60
  return /* @__PURE__ */ jsx(AudioRecorderContext.Provider, {
28
61
  value: recorder,
29
- children: /* @__PURE__ */ jsx("div", {
30
- "data-control-ui": "audio-recorder",
31
- "data-control-family": "audio-recorder",
32
- "data-slot": "root",
33
- "data-state": recorder.state,
34
- "data-disabled": recorder.isDisabled ? "true" : void 0,
35
- "data-error": recorder.error ? "true" : void 0,
36
- role: "group",
37
- "aria-label": label,
38
- "aria-disabled": recorder.isDisabled || void 0,
39
- className: cn("flex w-full min-w-0 max-w-full items-center", className),
40
- ...props,
41
- children: children ?? /* @__PURE__ */ jsx(AudioRecorderDefaultLayout, { points: barCount })
62
+ children: /* @__PURE__ */ jsx(AudioRecorderTriggerRefContext.Provider, {
63
+ value: triggerRef,
64
+ children: /* @__PURE__ */ jsxs("div", {
65
+ "data-control-ui": "audio-recorder",
66
+ "data-control-family": "audio-recorder",
67
+ "data-slot": "root",
68
+ "data-state": recorder.state,
69
+ "data-disabled": recorder.isDisabled ? "true" : void 0,
70
+ "data-error": recorder.error ? "true" : void 0,
71
+ role: "group",
72
+ "aria-label": label,
73
+ "aria-disabled": recorder.isDisabled || void 0,
74
+ className: cn("flex w-full min-w-0 max-w-full items-center", className),
75
+ ...props,
76
+ children: [children ?? /* @__PURE__ */ jsx(AudioRecorderDefaultLayout, { points: barCount }), /* @__PURE__ */ jsx(LiveStatus, { message: announcement })]
77
+ })
42
78
  })
43
79
  });
44
80
  }
@@ -65,8 +101,14 @@ function AudioRecorderDefaultLayout({ points }) {
65
101
  })
66
102
  ] });
67
103
  }
68
- function AudioRecorderTrigger({ className, children, disabled, onClick, ...props }) {
104
+ function AudioRecorderTrigger({ className, children, disabled, onClick, ref, ...props }) {
69
105
  const recorder = useAudioRecorderContext();
106
+ const triggerRef = use(AudioRecorderTriggerRefContext);
107
+ function setRef(node) {
108
+ if (triggerRef) triggerRef.current = node;
109
+ if (typeof ref === "function") ref(node);
110
+ else if (ref) ref.current = node;
111
+ }
70
112
  const isActive = recorder.state === "requesting" || recorder.state === "recording" || recorder.state === "recorded" || recorder.state === "submitting";
71
113
  const isStatusOnly = !recorder.canStart && (recorder.state === "requesting" || recorder.state === "recording" || recorder.state === "recorded" || recorder.state === "submitting");
72
114
  const triggerVariant = audioRecorderTriggerVariant(recorder, isActive);
@@ -91,6 +133,8 @@ function AudioRecorderTrigger({ className, children, disabled, onClick, ...props
91
133
  "aria-label": ariaLabel,
92
134
  title: recorder.error?.message,
93
135
  disabled: disabled ?? (recorder.isDisabled || !recorder.canStart),
136
+ focusableWhenDisabled: true,
137
+ ref: setRef,
94
138
  className: cn("data-[status-only=true]:cursor-default", className),
95
139
  onClick: handleClick,
96
140
  ...props,
@@ -129,7 +173,6 @@ function AudioRecorderVisualizer({ points, className, ...props }) {
129
173
  active: recorder.state === "recording",
130
174
  levels: recorder.levels,
131
175
  points,
132
- "aria-hidden": !isVisible,
133
176
  className,
134
177
  ...props
135
178
  });
@@ -138,14 +181,15 @@ function AudioRecorderStatus({ className, children, ...props }) {
138
181
  const recorder = useAudioRecorderContext();
139
182
  const message = children ?? audioRecorderStatusMessage(recorder);
140
183
  const isVisible = Boolean(message);
184
+ const title = typeof message === "string" ? message : void 0;
141
185
  return /* @__PURE__ */ jsx("span", {
142
186
  "data-control-ui": "audio-recorder",
143
187
  "data-control-family": "audio-recorder",
144
188
  "data-slot": "status",
145
189
  "data-visible": isVisible ? "true" : void 0,
146
- "data-tone": recorder.state === "error" ? "error" : "neutral",
147
- "aria-hidden": !isVisible,
148
- "aria-live": "polite",
190
+ "data-tone": recorder.error ? "error" : "neutral",
191
+ "aria-hidden": "true",
192
+ title,
149
193
  className: cn("min-w-0 flex-1 truncate", className),
150
194
  ...props,
151
195
  children: message
@@ -154,29 +198,35 @@ function AudioRecorderStatus({ className, children, ...props }) {
154
198
  function audioRecorderStatusMessage(recorder) {
155
199
  if (recorder.state === "requesting") return "Allow microphone access";
156
200
  if (recorder.state === "submitting") return "Sending voice recording";
157
- if (recorder.state === "error") return recorder.error?.message;
201
+ if (recorder.error) return recorder.error.message;
158
202
  return null;
159
203
  }
160
- function AudioRecorderDuration({ className, children, ...props }) {
204
+ function AudioRecorderDuration({ className, children, durationLabel = "Recording length", ...props }) {
161
205
  const recorder = useAudioRecorderContext();
162
206
  const isVisible = recorder.state === "recording" || recorder.state === "recorded";
163
- return /* @__PURE__ */ jsx("span", {
207
+ return /* @__PURE__ */ jsxs("span", {
164
208
  "data-control-ui": "audio-recorder",
165
209
  "data-control-family": "audio-recorder",
166
210
  "data-slot": "duration",
167
211
  "data-visible": isVisible ? "true" : void 0,
168
212
  "aria-hidden": !isVisible,
169
- className: cn("shrink-0", className),
213
+ className: cn("shrink-0 tabular-nums", className),
170
214
  ...props,
171
- children: children ?? formatAudioRecorderDuration(recorder.durationMs)
215
+ children: [/* @__PURE__ */ jsxs("span", {
216
+ className: "sr-only",
217
+ children: [durationLabel, " "]
218
+ }), children ?? formatAudioRecorderDuration(recorder.durationMs)]
172
219
  });
173
220
  }
174
221
  function AudioRecorderCancel({ className, children, disabled, onClick, tabIndex, ...props }) {
175
222
  const recorder = useAudioRecorderContext();
223
+ const triggerRef = use(AudioRecorderTriggerRefContext);
176
224
  const isVisible = recorder.canCancel;
177
225
  function handleClick(event) {
178
226
  onClick?.(event);
179
- if (!event.defaultPrevented && recorder.canCancel) recorder.cancel();
227
+ if (event.defaultPrevented || !recorder.canCancel) return;
228
+ focusAudioRecorderTrigger(triggerRef);
229
+ recorder.cancel();
180
230
  }
181
231
  return /* @__PURE__ */ jsx(Button, {
182
232
  "data-control-ui": "audio-recorder",
@@ -201,12 +251,15 @@ function AudioRecorderCancel({ className, children, disabled, onClick, tabIndex,
201
251
  })
202
252
  });
203
253
  }
204
- function AudioRecorderSubmit({ className, children, disabled, onClick, tabIndex, ...props }) {
254
+ function AudioRecorderSubmit({ className, children, disabled, onClick, tabIndex, label = "Send voice recording", retryLabel = "Retry sending voice recording", ...props }) {
205
255
  const recorder = useAudioRecorderContext();
256
+ const triggerRef = use(AudioRecorderTriggerRefContext);
206
257
  const isVisible = recorder.canSubmit;
207
258
  async function handleClick(event) {
208
259
  onClick?.(event);
209
- if (!event.defaultPrevented && recorder.canSubmit) await recorder.submit();
260
+ if (event.defaultPrevented || !recorder.canSubmit) return;
261
+ focusAudioRecorderTrigger(triggerRef);
262
+ await recorder.submit();
210
263
  }
211
264
  return /* @__PURE__ */ jsx(Button, {
212
265
  "data-control-ui": "audio-recorder",
@@ -218,7 +271,7 @@ function AudioRecorderSubmit({ className, children, disabled, onClick, tabIndex,
218
271
  size: "sm",
219
272
  iconOnly: true,
220
273
  shape: "circle",
221
- "aria-label": "Send voice recording",
274
+ "aria-label": recorder.error ? retryLabel : label,
222
275
  "aria-hidden": !isVisible,
223
276
  tabIndex: isVisible ? tabIndex : -1,
224
277
  disabled: disabled ?? (recorder.state === "submitting" || !isVisible),
@@ -29,7 +29,7 @@ function AudioVisualizer({ levels, points, active = true, className, style, ...p
29
29
  "data-control-family": "audio-visualizer",
30
30
  "data-slot": "track",
31
31
  "data-active": active ? "true" : void 0,
32
- className: "flex size-full items-stretch justify-end mask-l-from-90%",
32
+ className: "flex size-full items-stretch justify-end mask-l-from-90% rtl:mask-l-from-100% rtl:mask-r-from-90%",
33
33
  children: visible.map(({ key, level }) => {
34
34
  const perceptualLevel = Math.sqrt(level);
35
35
  const visibleLevel = MIN_VISIBLE_LEVEL + perceptualLevel * .88;
@@ -10,13 +10,14 @@ import { jsx, jsxs } from "react/jsx-runtime";
10
10
  import { BotIcon, ChevronRightIcon, CircleIcon, FolderIcon, PlusIcon, SearchIcon } from "lucide-react";
11
11
  //#region src/blocks/coding-agent.tsx
12
12
  function CodingAgentBlock({ appName = "Agent", brand, sidebarTop, navigation = [], projects, activeTaskId, activeTaskTitle = "New task", onNavigationSelect, onTaskSelect, onNewTask, onSearch, headerActions, sidebarFooter, children, layout = "viewport", className, style, ...props }) {
13
- const contained = layout === "contained";
13
+ const Heading = layout === "contained" ? "h2" : "h1";
14
14
  const providerStyle = {
15
15
  "--sidebar-width": "17.5rem",
16
16
  ...style
17
17
  };
18
18
  return /* @__PURE__ */ jsxs(SidebarProvider, {
19
- className: cn("overflow-hidden bg-background text-foreground", contained ? "relative h-full min-h-0" : "h-svh min-h-svh", className),
19
+ layout,
20
+ className: cn("bg-background text-foreground", layout === "viewport" && "h-svh overflow-hidden", className),
20
21
  style: providerStyle,
21
22
  ...props,
22
23
  children: [/* @__PURE__ */ jsx(CodingAgentSidebar, {
@@ -26,7 +27,6 @@ function CodingAgentBlock({ appName = "Agent", brand, sidebarTop, navigation = [
26
27
  navigation,
27
28
  projects,
28
29
  activeTaskId,
29
- contained,
30
30
  sidebarFooter,
31
31
  onNavigationSelect,
32
32
  onTaskSelect,
@@ -39,14 +39,15 @@ function CodingAgentBlock({ appName = "Agent", brand, sidebarTop, navigation = [
39
39
  children: [
40
40
  /* @__PURE__ */ jsx(SidebarTrigger, {
41
41
  size: "xs",
42
- className: "md:hidden"
42
+ className: "lg:hidden"
43
43
  }),
44
44
  /* @__PURE__ */ jsx(FolderIcon, {
45
45
  className: "size-4 shrink-0 text-muted-foreground",
46
46
  "aria-hidden": "true"
47
47
  }),
48
- /* @__PURE__ */ jsx("h1", {
48
+ /* @__PURE__ */ jsx(Heading, {
49
49
  className: "min-w-0 flex-1 truncate text-label font-medium",
50
+ title: activeTaskTitle,
50
51
  children: activeTaskTitle
51
52
  }),
52
53
  headerActions ? /* @__PURE__ */ jsx("div", {
@@ -61,7 +62,7 @@ function CodingAgentBlock({ appName = "Agent", brand, sidebarTop, navigation = [
61
62
  })]
62
63
  });
63
64
  }
64
- function CodingAgentSidebar({ appName, brand, sidebarTop, navigation, projects, activeTaskId, contained, sidebarFooter, onNavigationSelect, onTaskSelect, onNewTask, onSearch }) {
65
+ function CodingAgentSidebar({ appName, brand, sidebarTop, navigation, projects, activeTaskId, sidebarFooter, onNavigationSelect, onTaskSelect, onNewTask, onSearch }) {
65
66
  const { setOpenMobile } = useSidebar();
66
67
  function finishMobileNavigation() {
67
68
  setOpenMobile(false);
@@ -72,7 +73,6 @@ function CodingAgentSidebar({ appName, brand, sidebarTop, navigation, projects,
72
73
  }
73
74
  return /* @__PURE__ */ jsxs(Sidebar, {
74
75
  collapsible: "offcanvas",
75
- className: contained ? "absolute! inset-y-0! h-full border-r border-sidebar-border" : void 0,
76
76
  children: [
77
77
  /* @__PURE__ */ jsxs(SidebarHeader, {
78
78
  className: "gap-1.5 border-b border-sidebar-border px-2 pb-2 pt-3",
@@ -90,16 +90,20 @@ function CodingAgentSidebar({ appName, brand, sidebarTop, navigation, projects,
90
90
  })
91
91
  }), /* @__PURE__ */ jsx("span", {
92
92
  className: "truncate text-label font-semibold",
93
+ title: appName,
93
94
  children: appName
94
95
  })]
95
- }), /* @__PURE__ */ jsx(Button, {
96
+ }), onSearch ? /* @__PURE__ */ jsx(Button, {
96
97
  variant: "ghost",
97
98
  size: "sm",
98
99
  iconOnly: true,
99
100
  "aria-label": "Search tasks",
100
101
  onClick: onSearch,
101
- children: /* @__PURE__ */ jsx(SearchIcon, { className: "size-3.5" })
102
- })]
102
+ children: /* @__PURE__ */ jsx(SearchIcon, {
103
+ className: "size-3.5",
104
+ "aria-hidden": "true"
105
+ })
106
+ }) : null]
103
107
  }),
104
108
  /* @__PURE__ */ jsx(SidebarMenu, { children: /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxs(SidebarMenuButton, {
105
109
  size: "sm",
@@ -120,7 +124,7 @@ function CodingAgentSidebar({ appName, brand, sidebarTop, navigation, projects,
120
124
  item.icon,
121
125
  /* @__PURE__ */ jsx("span", { children: item.label }),
122
126
  item.trailing ? /* @__PURE__ */ jsx("span", {
123
- className: "ml-auto shrink-0",
127
+ className: "ms-auto shrink-0",
124
128
  children: item.trailing
125
129
  }) : null
126
130
  ]
@@ -149,30 +153,26 @@ function CodingAgentSidebar({ appName, brand, sidebarTop, navigation, projects,
149
153
  children: project.name
150
154
  })
151
155
  ] }), /* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx(SidebarMenu, {
152
- className: "mt-1 pl-5",
153
- children: project.tasks.map((task) => {
154
- const isActive = task.id === activeTaskId;
155
- return /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxs(SidebarMenuButton, {
156
- size: "sm",
157
- isActive,
158
- "aria-current": isActive ? "page" : void 0,
159
- onClick: () => {
160
- onTaskSelect?.(task, project);
161
- finishMobileNavigation();
162
- },
163
- children: [
164
- /* @__PURE__ */ jsx(CircleIcon, {
165
- className: "size-1.5 fill-current opacity-35",
166
- "aria-hidden": "true"
167
- }),
168
- /* @__PURE__ */ jsx("span", { children: task.title }),
169
- task.trailing ? /* @__PURE__ */ jsx("span", {
170
- className: "ml-auto shrink-0",
171
- children: task.trailing
172
- }) : null
173
- ]
174
- }) }, task.id);
175
- })
156
+ className: "mt-1 ps-5",
157
+ children: project.tasks.map((task) => /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxs(SidebarMenuButton, {
158
+ size: "sm",
159
+ isActive: task.id === activeTaskId,
160
+ onClick: () => {
161
+ onTaskSelect?.(task, project);
162
+ finishMobileNavigation();
163
+ },
164
+ children: [
165
+ /* @__PURE__ */ jsx(CircleIcon, {
166
+ className: "size-1.5 fill-current opacity-35",
167
+ "aria-hidden": "true"
168
+ }),
169
+ /* @__PURE__ */ jsx("span", { children: task.title }),
170
+ task.trailing ? /* @__PURE__ */ jsx("span", {
171
+ className: "ms-auto shrink-0",
172
+ children: task.trailing
173
+ }) : null
174
+ ]
175
+ }) }, task.id))
176
176
  }) })]
177
177
  }, project.id))
178
178
  })]
@@ -215,11 +215,11 @@ function CodingAgentEmptyState({ title = "What should we build?", description, i
215
215
  })
216
216
  }),
217
217
  /* @__PURE__ */ jsx("h2", {
218
- className: "text-balance text-xl font-medium tracking-tight sm:text-2xl",
218
+ className: "text-balance text-heading-3 sm:text-heading-2",
219
219
  children: title
220
220
  }),
221
221
  description ? /* @__PURE__ */ jsx("p", {
222
- className: "mt-2 max-w-xl text-sm leading-6 text-muted-foreground",
222
+ className: "mt-2 max-w-xl text-pretty text-body text-muted-foreground",
223
223
  children: description
224
224
  }) : null,
225
225
  suggestions.length > 0 ? /* @__PURE__ */ jsx("div", {
@@ -227,7 +227,7 @@ function CodingAgentEmptyState({ title = "What should we build?", description, i
227
227
  children: suggestions.map((suggestion) => /* @__PURE__ */ jsx(Button, {
228
228
  variant: "surface",
229
229
  size: "lg",
230
- className: "h-auto min-h-28 w-full items-start justify-start whitespace-normal rounded-[var(--radius-panel)] px-4 py-4 text-left",
230
+ className: "h-auto min-h-28 w-full items-start justify-start whitespace-normal rounded-[var(--radius-panel)] px-4 py-4 text-start",
231
231
  onClick: () => onSuggestionSelect?.(suggestion.prompt ?? suggestion.title, suggestion),
232
232
  children: /* @__PURE__ */ jsxs("span", {
233
233
  className: "flex min-w-0 flex-col items-start gap-3",
@@ -237,7 +237,7 @@ function CodingAgentEmptyState({ title = "What should we build?", description, i
237
237
  children: suggestion.icon
238
238
  }),
239
239
  /* @__PURE__ */ jsx("span", {
240
- className: "text-sm font-medium leading-5 text-foreground",
240
+ className: "text-body font-medium text-foreground",
241
241
  children: suggestion.title
242
242
  }),
243
243
  suggestion.description ? /* @__PURE__ */ jsx("span", {
@@ -11,7 +11,11 @@ export type DesignCanvasBlockProps = Omit<ComponentProps<"div">, "children" | "d
11
11
  onSelectedLayerIdChange?: (layerId: string | null) => void;
12
12
  defaultTransform?: InfiniteCanvasTransform;
13
13
  layout?: "viewport" | "contained";
14
+ layersLabel?: string;
15
+ propertiesLabel?: string;
16
+ openLayersLabel?: string;
17
+ openPropertiesLabel?: string;
14
18
  };
15
- export declare function DesignCanvasBlock({ layers, defaultLayers, onLayersChange, selectedLayerId, defaultSelectedLayerId, onSelectedLayerIdChange, defaultTransform, layout, className, ...props }: DesignCanvasBlockProps): import("react").JSX.Element;
19
+ export declare function DesignCanvasBlock({ layers, defaultLayers, onLayersChange, selectedLayerId, defaultSelectedLayerId, onSelectedLayerIdChange, defaultTransform, layout, layersLabel, propertiesLabel, openLayersLabel, openPropertiesLabel, className, ...props }: DesignCanvasBlockProps): import("react").JSX.Element;
16
20
  //#endregion
17
21
  export type { DesignCanvasFill, DesignCanvasLayer, DesignCanvasLayerKind, DesignCanvasTool };