@ctrl-ui/react 0.8.7 → 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 (351) hide show
  1. package/dist/action-bar.d.ts +15 -7
  2. package/dist/action-bar.js +40 -20
  3. package/dist/activity.js +8 -16
  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-inspector.js +2 -2
  9. package/dist/blocks/design-canvas.d.ts +5 -1
  10. package/dist/blocks/design-canvas.js +200 -94
  11. package/dist/blocks/discussion.d.ts +28 -0
  12. package/dist/blocks/discussion.js +67 -0
  13. package/dist/blocks/file-explorer-data.d.ts +1 -0
  14. package/dist/blocks/file-explorer-data.js +4 -1
  15. package/dist/blocks/file-explorer.d.ts +9 -1
  16. package/dist/blocks/file-explorer.js +461 -192
  17. package/dist/blocks/settings.d.ts +2 -1
  18. package/dist/blocks/settings.js +102 -80
  19. package/dist/blocks/team-chat.d.ts +12 -0
  20. package/dist/blocks/team-chat.js +26 -0
  21. package/dist/blocks/theme-toggle.js +23 -31
  22. package/dist/chat-composer-attachment.d.ts +4 -1
  23. package/dist/chat-composer-attachment.js +35 -10
  24. package/dist/chat-composer-editor/extensions/mention.d.ts +5 -1
  25. package/dist/chat-composer-editor/extensions/mention.js +58 -27
  26. package/dist/chat-composer-editor/ghost.js +2 -4
  27. package/dist/chat-composer-editor/types.d.ts +5 -0
  28. package/dist/chat-composer-editor.d.ts +1 -1
  29. package/dist/chat-composer-editor.js +57 -30
  30. package/dist/chat-composer.d.ts +13 -32
  31. package/dist/chat-composer.js +53 -13
  32. package/dist/chat-layout.d.ts +19 -0
  33. package/dist/chat-layout.js +91 -40
  34. package/dist/chat-message/social.d.ts +26 -0
  35. package/dist/chat-message/social.js +122 -0
  36. package/dist/chat-message.d.ts +28 -29
  37. package/dist/chat-message.js +106 -25
  38. package/dist/context.d.ts +2 -2
  39. package/dist/context.js +39 -24
  40. package/dist/dynamic-notification-canvas-loop.d.ts +24 -0
  41. package/dist/dynamic-notification-canvas-loop.js +113 -0
  42. package/dist/dynamic-notification-glass.js +23 -114
  43. package/dist/dynamic-notification-liquid.js +14 -118
  44. package/dist/dynamic-notification.d.ts +16 -8
  45. package/dist/dynamic-notification.js +86 -23
  46. package/dist/email/email-brand.d.ts +7 -4
  47. package/dist/email/email-brand.js +9 -6
  48. package/dist/email/email-code.d.ts +3 -2
  49. package/dist/email/email-code.js +11 -9
  50. package/dist/email/email-footer.d.ts +5 -3
  51. package/dist/email/email-footer.js +11 -5
  52. package/dist/email/email.d.ts +31 -9
  53. package/dist/email/email.js +50 -26
  54. package/dist/email/templates.d.ts +10 -9
  55. package/dist/email/templates.js +102 -38
  56. package/dist/email/theme.js +1 -1
  57. package/dist/environment-variables.d.ts +4 -2
  58. package/dist/environment-variables.js +52 -32
  59. package/dist/filter-bar/editor.js +20 -8
  60. package/dist/filter-bar/model.d.ts +1 -0
  61. package/dist/filter-bar/model.js +10 -1
  62. package/dist/filter-bar/motion.js +4 -4
  63. package/dist/filter-bar/parts.js +20 -9
  64. package/dist/filter-bar/types.d.ts +1 -0
  65. package/dist/filter-bar.js +20 -14
  66. package/dist/hooks/use-audio-recorder.js +12 -6
  67. package/dist/hooks/use-chat-composer.d.ts +19 -7
  68. package/dist/hooks/use-chat-composer.js +32 -5
  69. package/dist/hooks/use-chat-message.d.ts +28 -2
  70. package/dist/hooks/use-chat-message.js +41 -10
  71. package/dist/hooks/use-chat-thread-scroll.js +43 -7
  72. package/dist/hooks/use-color-area.d.ts +3 -3
  73. package/dist/hooks/use-color-area.js +13 -12
  74. package/dist/hooks/use-copy-to-clipboard.d.ts +2 -1
  75. package/dist/hooks/use-copy-to-clipboard.js +20 -20
  76. package/dist/hooks/use-dynamic-notification.d.ts +6 -2
  77. package/dist/hooks/use-dynamic-notification.js +26 -10
  78. package/dist/hooks/use-mobile.d.ts +3 -2
  79. package/dist/hooks/use-mobile.js +8 -4
  80. package/dist/hooks/use-textarea-trigger-menu.js +2 -1
  81. package/dist/hooks/use-trigger-menu.d.ts +54 -0
  82. package/dist/hooks/use-trigger-menu.js +102 -47
  83. package/dist/hooks/use-user-ask.d.ts +2 -0
  84. package/dist/hooks/use-user-ask.js +35 -41
  85. package/dist/inline-attachment.d.ts +6 -2
  86. package/dist/inline-attachment.js +36 -15
  87. package/dist/inline-citation.d.ts +12 -5
  88. package/dist/inline-citation.js +26 -17
  89. package/dist/knob-contracts/audio-recorder-knobs.d.ts +1 -1
  90. package/dist/knob-contracts/audio-recorder-knobs.js +2 -1
  91. package/dist/knob-contracts/audio-visualizer-knobs.d.ts +1 -1
  92. package/dist/knob-contracts/audio-visualizer-knobs.js +2 -1
  93. package/dist/knob-contracts/avatar-knobs.d.ts +1 -1
  94. package/dist/knob-contracts/avatar-knobs.js +6 -1
  95. package/dist/knob-contracts/badge-knobs.d.ts +1 -1
  96. package/dist/knob-contracts/badge-knobs.js +2 -1
  97. package/dist/knob-contracts/breadcrumb-knobs.d.ts +4 -0
  98. package/dist/knob-contracts/breadcrumb-knobs.js +8 -0
  99. package/dist/knob-contracts/button-knobs.d.ts +1 -1
  100. package/dist/knob-contracts/button-knobs.js +1 -0
  101. package/dist/knob-contracts/chat-message-knobs.d.ts +1 -1
  102. package/dist/knob-contracts/chat-message-knobs.js +8 -1
  103. package/dist/knob-contracts/code-diff-knobs.d.ts +1 -1
  104. package/dist/knob-contracts/code-diff-knobs.js +2 -0
  105. package/dist/knob-contracts/code-knobs.d.ts +1 -1
  106. package/dist/knob-contracts/code-knobs.js +2 -1
  107. package/dist/knob-contracts/dynamic-notification-knobs.d.ts +1 -1
  108. package/dist/knob-contracts/dynamic-notification-knobs.js +2 -0
  109. package/dist/knob-contracts/emoji-picker-knobs.d.ts +4 -0
  110. package/dist/knob-contracts/emoji-picker-knobs.js +10 -0
  111. package/dist/knob-contracts/field-knobs.d.ts +1 -1
  112. package/dist/knob-contracts/field-knobs.js +5 -1
  113. package/dist/knob-contracts/filter-bar-knobs.d.ts +1 -1
  114. package/dist/knob-contracts/filter-bar-knobs.js +1 -2
  115. package/dist/knob-contracts/markdown-knobs.d.ts +1 -1
  116. package/dist/knob-contracts/markdown-knobs.js +3 -1
  117. package/dist/knob-contracts/page-layout-knobs.d.ts +1 -1
  118. package/dist/knob-contracts/page-layout-knobs.js +2 -1
  119. package/dist/knob-contracts/popup-knobs.d.ts +1 -1
  120. package/dist/knob-contracts/popup-knobs.js +27 -0
  121. package/dist/knob-contracts/range-knobs.d.ts +1 -1
  122. package/dist/knob-contracts/range-knobs.js +1 -0
  123. package/dist/knob-contracts/rich-tooltip-knobs.d.ts +1 -1
  124. package/dist/knob-contracts/rich-tooltip-knobs.js +2 -1
  125. package/dist/knob-contracts/sidebar-knobs.d.ts +1 -1
  126. package/dist/knob-contracts/sidebar-knobs.js +27 -2
  127. package/dist/knob-contracts/spinner-knobs.d.ts +1 -1
  128. package/dist/knob-contracts/spinner-knobs.js +1 -1
  129. package/dist/knob-contracts/stepper-knobs.d.ts +1 -1
  130. package/dist/knob-contracts/stepper-knobs.js +4 -1
  131. package/dist/knob-contracts/switch-knobs.d.ts +1 -1
  132. package/dist/knob-contracts/switch-knobs.js +5 -0
  133. package/dist/knob-contracts/table-of-contents-knobs.d.ts +1 -1
  134. package/dist/knob-contracts/table-of-contents-knobs.js +2 -1
  135. package/dist/knob-contracts/tabs-knobs.d.ts +1 -1
  136. package/dist/knob-contracts/tabs-knobs.js +1 -0
  137. package/dist/knob-contracts/tree-knobs.d.ts +1 -1
  138. package/dist/knob-contracts/tree-knobs.js +2 -1
  139. package/dist/lib/cn.js +0 -4
  140. package/dist/lib/contrast.d.ts +1 -0
  141. package/dist/lib/contrast.js +17 -5
  142. package/dist/lib/dropzone-validation.js +41 -28
  143. package/dist/lib/env-file.d.ts +1 -1
  144. package/dist/lib/env-file.js +5 -5
  145. package/dist/lib/motion.d.ts +4 -0
  146. package/dist/lib/motion.js +15 -0
  147. package/dist/lib/phone-input-format.js +1 -1
  148. package/dist/lib/trigger-detect.js +6 -8
  149. package/dist/markdown-block.js +2 -1
  150. package/dist/popup-parts.d.ts +8 -0
  151. package/dist/popup-parts.js +43 -0
  152. package/dist/source-badge.js +3 -1
  153. package/dist/styles/code.css +0 -2
  154. package/dist/styles/effects.css +6 -32
  155. package/dist/styles/index.css +10 -5
  156. package/dist/styles/recipes/accordion.css +9 -6
  157. package/dist/styles/recipes/action-bar.css +0 -15
  158. package/dist/styles/recipes/activity.css +5 -11
  159. package/dist/styles/recipes/alert.css +4 -4
  160. package/dist/styles/recipes/audio-recorder.css +15 -3
  161. package/dist/styles/recipes/audio-visualizer.css +13 -2
  162. package/dist/styles/recipes/avatar.css +78 -1
  163. package/dist/styles/recipes/badge.css +14 -4
  164. package/dist/styles/recipes/breadcrumb.css +77 -0
  165. package/dist/styles/recipes/button-group.css +5 -7
  166. package/dist/styles/recipes/button-states.css +66 -0
  167. package/dist/styles/recipes/button.css +24 -83
  168. package/dist/styles/recipes/calendar.css +17 -23
  169. package/dist/styles/recipes/card.css +2 -2
  170. package/dist/styles/recipes/chat-composer-attachment.css +9 -3
  171. package/dist/styles/recipes/chat-composer.css +7 -10
  172. package/dist/styles/recipes/chat-layout.css +35 -0
  173. package/dist/styles/recipes/chat-message-social.css +123 -0
  174. package/dist/styles/recipes/chat-message.css +157 -37
  175. package/dist/styles/recipes/choice.css +18 -21
  176. package/dist/styles/recipes/code-diff.css +46 -33
  177. package/dist/styles/recipes/code.css +36 -16
  178. package/dist/styles/recipes/collapsible.css +7 -2
  179. package/dist/styles/recipes/color-picker-details.css +3 -4
  180. package/dist/styles/recipes/color-picker-values.css +9 -8
  181. package/dist/styles/recipes/color-picker.css +11 -2
  182. package/dist/styles/recipes/context.css +3 -3
  183. package/dist/styles/recipes/dockable-panel.css +7 -4
  184. package/dist/styles/recipes/dropzone.css +7 -8
  185. package/dist/styles/recipes/dynamic-notification-input.css +8 -5
  186. package/dist/styles/recipes/dynamic-notification-motion.css +12 -21
  187. package/dist/styles/recipes/dynamic-notification.css +40 -26
  188. package/dist/styles/recipes/emoji-picker.css +132 -0
  189. package/dist/styles/recipes/empty.css +5 -4
  190. package/dist/styles/recipes/environment-variables.css +4 -15
  191. package/dist/styles/recipes/field-parts.css +30 -24
  192. package/dist/styles/recipes/field.css +61 -26
  193. package/dist/styles/recipes/filter-bar.css +18 -31
  194. package/dist/styles/recipes/gradient-editor.css +18 -7
  195. package/dist/styles/recipes/infinite-canvas.css +0 -1
  196. package/dist/styles/recipes/inline-attachment.css +3 -3
  197. package/dist/styles/recipes/inline-citation.css +10 -4
  198. package/dist/styles/recipes/item.css +23 -9
  199. package/dist/styles/recipes/markdown-block.css +5 -4
  200. package/dist/styles/recipes/markdown.css +68 -26
  201. package/dist/styles/recipes/morphing-panel.css +8 -8
  202. package/dist/styles/recipes/page-layout.css +20 -12
  203. package/dist/styles/recipes/pagination.css +4 -5
  204. package/dist/styles/recipes/phone-input.css +12 -8
  205. package/dist/styles/recipes/popup-controls.css +166 -33
  206. package/dist/styles/recipes/popup-drawer.css +3 -14
  207. package/dist/styles/recipes/popup-lists.css +128 -27
  208. package/dist/styles/recipes/popup-motion.css +4 -45
  209. package/dist/styles/recipes/popup-toast.css +55 -26
  210. package/dist/styles/recipes/popup.css +139 -141
  211. package/dist/styles/recipes/range.css +54 -18
  212. package/dist/styles/recipes/resizable.css +2 -7
  213. package/dist/styles/recipes/rich-tooltip.css +24 -34
  214. package/dist/styles/recipes/scroll-area.css +8 -1
  215. package/dist/styles/recipes/sidebar-menu.css +149 -34
  216. package/dist/styles/recipes/sidebar-parts.css +154 -0
  217. package/dist/styles/recipes/sidebar.css +187 -128
  218. package/dist/styles/recipes/source-badge.css +1 -1
  219. package/dist/styles/recipes/spinner.css +8 -1
  220. package/dist/styles/recipes/stepper.css +31 -13
  221. package/dist/styles/recipes/switch.css +68 -23
  222. package/dist/styles/recipes/table-of-contents.css +9 -1
  223. package/dist/styles/recipes/table.css +14 -10
  224. package/dist/styles/recipes/tabs.css +17 -12
  225. package/dist/styles/recipes/task-list.css +7 -14
  226. package/dist/styles/recipes/thread-rail.css +42 -19
  227. package/dist/styles/recipes/timeline.css +2 -0
  228. package/dist/styles/recipes/toolbar.css +27 -25
  229. package/dist/styles/recipes/track-highlight.css +10 -7
  230. package/dist/styles/recipes/tree.css +31 -4
  231. package/dist/styles/recipes/user-ask-details.css +0 -1
  232. package/dist/styles/recipes/user-ask.css +4 -4
  233. package/dist/styles/theme.css +37 -16
  234. package/dist/task-list.d.ts +4 -1
  235. package/dist/task-list.js +24 -8
  236. package/dist/thread-rail.d.ts +1 -1
  237. package/dist/thread-rail.js +61 -19
  238. package/dist/transcript-divider.js +2 -1
  239. package/dist/ui/alert-dialog.js +1 -1
  240. package/dist/ui/alert.d.ts +3 -1
  241. package/dist/ui/alert.js +14 -8
  242. package/dist/ui/autocomplete.js +4 -2
  243. package/dist/ui/avatar.d.ts +8 -0
  244. package/dist/ui/avatar.js +23 -3
  245. package/dist/ui/badge.js +1 -1
  246. package/dist/ui/breadcrumb.d.ts +27 -0
  247. package/dist/ui/breadcrumb.js +88 -0
  248. package/dist/ui/button.d.ts +2 -1
  249. package/dist/ui/button.js +3 -3
  250. package/dist/ui/calendar.js +2 -2
  251. package/dist/ui/card.d.ts +3 -1
  252. package/dist/ui/card.js +12 -7
  253. package/dist/ui/checkbox.d.ts +2 -0
  254. package/dist/ui/code-diff.d.ts +1 -1
  255. package/dist/ui/code-diff.js +72 -28
  256. package/dist/ui/code.d.ts +5 -3
  257. package/dist/ui/code.js +28 -29
  258. package/dist/ui/collapsible.js +1 -1
  259. package/dist/ui/color-picker.d.ts +5 -2
  260. package/dist/ui/color-picker.js +85 -37
  261. package/dist/ui/combobox-disabled-selection.d.ts +1 -2
  262. package/dist/ui/combobox-disabled-selection.js +7 -9
  263. package/dist/ui/combobox.js +14 -6
  264. package/dist/ui/command.d.ts +8 -2
  265. package/dist/ui/command.js +30 -14
  266. package/dist/ui/context-menu.js +4 -1
  267. package/dist/ui/dialog.d.ts +2 -1
  268. package/dist/ui/dialog.js +4 -23
  269. package/dist/ui/dockable-panel-geometry.d.ts +1 -0
  270. package/dist/ui/dockable-panel-geometry.js +7 -1
  271. package/dist/ui/dockable-panel.d.ts +9 -6
  272. package/dist/ui/dockable-panel.js +63 -23
  273. package/dist/ui/drawer.js +1 -1
  274. package/dist/ui/dropdown-menu.js +5 -4
  275. package/dist/ui/dropzone.d.ts +2 -2
  276. package/dist/ui/dropzone.js +75 -16
  277. package/dist/ui/emoji-picker.d.ts +18 -0
  278. package/dist/ui/emoji-picker.js +136 -0
  279. package/dist/ui/empty.d.ts +3 -1
  280. package/dist/ui/empty.js +12 -7
  281. package/dist/ui/gradient-editor.d.ts +1 -1
  282. package/dist/ui/gradient-editor.js +37 -21
  283. package/dist/ui/hover-card.js +1 -1
  284. package/dist/ui/infinite-canvas.d.ts +3 -2
  285. package/dist/ui/infinite-canvas.js +63 -19
  286. package/dist/ui/input-group.d.ts +0 -3
  287. package/dist/ui/input-group.js +4 -14
  288. package/dist/ui/input-otp.d.ts +1 -1
  289. package/dist/ui/input-otp.js +32 -15
  290. package/dist/ui/input.js +4 -4
  291. package/dist/ui/item.d.ts +2 -1
  292. package/dist/ui/item.js +12 -8
  293. package/dist/ui/live-status.d.ts +7 -0
  294. package/dist/ui/live-status.js +17 -0
  295. package/dist/ui/markdown-elements.d.ts +6 -0
  296. package/dist/ui/markdown-elements.js +31 -1
  297. package/dist/ui/menubar.js +3 -3
  298. package/dist/ui/morphing-panel.js +3 -2
  299. package/dist/ui/native-select.d.ts +1 -1
  300. package/dist/ui/native-select.js +24 -11
  301. package/dist/ui/navigation-menu.js +1 -1
  302. package/dist/ui/page-layout.d.ts +2 -2
  303. package/dist/ui/page-layout.js +2 -4
  304. package/dist/ui/pagination.d.ts +7 -5
  305. package/dist/ui/pagination.js +19 -13
  306. package/dist/ui/phone-input.d.ts +1 -0
  307. package/dist/ui/phone-input.js +58 -60
  308. package/dist/ui/popover.js +1 -1
  309. package/dist/ui/radio-group.d.ts +2 -0
  310. package/dist/ui/resizable.d.ts +3 -2
  311. package/dist/ui/resizable.js +5 -3
  312. package/dist/ui/responsive-dialog.d.ts +1 -1
  313. package/dist/ui/responsive-dialog.js +4 -21
  314. package/dist/ui/rich-tooltip.d.ts +10 -4
  315. package/dist/ui/rich-tooltip.js +82 -34
  316. package/dist/ui/scroll-area.d.ts +1 -1
  317. package/dist/ui/scroll-area.js +43 -28
  318. package/dist/ui/select.js +1 -1
  319. package/dist/ui/sheet.js +1 -1
  320. package/dist/ui/sidebar-menu.d.ts +5 -1
  321. package/dist/ui/sidebar-menu.js +32 -34
  322. package/dist/ui/sidebar-provider.d.ts +10 -1
  323. package/dist/ui/sidebar-provider.js +39 -14
  324. package/dist/ui/sidebar-resize-rail.js +8 -4
  325. package/dist/ui/sidebar.d.ts +11 -6
  326. package/dist/ui/sidebar.js +47 -24
  327. package/dist/ui/slider.js +31 -22
  328. package/dist/ui/spinner.d.ts +3 -2
  329. package/dist/ui/spinner.js +3 -2
  330. package/dist/ui/stepper.d.ts +8 -1
  331. package/dist/ui/stepper.js +74 -25
  332. package/dist/ui/switch.d.ts +1 -0
  333. package/dist/ui/table-of-contents.d.ts +2 -2
  334. package/dist/ui/table-of-contents.js +20 -8
  335. package/dist/ui/table.js +4 -2
  336. package/dist/ui/textarea.d.ts +1 -1
  337. package/dist/ui/textarea.js +20 -9
  338. package/dist/ui/timeline.d.ts +3 -1
  339. package/dist/ui/timeline.js +17 -9
  340. package/dist/ui/toast.d.ts +11 -5
  341. package/dist/ui/toast.js +101 -55
  342. package/dist/ui/toolbar.d.ts +3 -2
  343. package/dist/ui/toolbar.js +4 -2
  344. package/dist/ui/tooltip.js +4 -21
  345. package/dist/ui/tree.js +121 -81
  346. package/dist/ui/trigger-menu.js +2 -1
  347. package/dist/user-ask.d.ts +10 -5
  348. package/dist/user-ask.js +32 -12
  349. package/package.json +5 -1
  350. package/dist/hooks/use-keyboard-navigation.d.ts +0 -3
  351. package/dist/hooks/use-keyboard-navigation.js +0 -22
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { controlEffectsAttribute } from "../skin.js";
3
2
  import { cn } from "../lib/cn.js";
3
+ import { controlEffectsAttribute } from "../skin.js";
4
4
  import { useSkin } from "../skin-provider.js";
5
5
  import { ScrollArea } from "./scroll-area.js";
6
6
  import { popupItemStructureClasses } from "../surface-variants.js";
@@ -103,6 +103,7 @@ function TriggerMenuGroup({ className, ...props }) {
103
103
  "data-control-family": "popup",
104
104
  "data-popup-kind": "trigger-menu",
105
105
  "data-slot": "group",
106
+ role: "group",
106
107
  className: cn("flex flex-col", className),
107
108
  ...props
108
109
  });
@@ -6,7 +6,7 @@ import { CSSProperties, ComponentProps } from "react";
6
6
  type UserAskStyleProps<Props, Style> = Omit<Props, "style"> & {
7
7
  style?: CSSProperties & Style;
8
8
  };
9
- export declare function UserAsk({ onComplete, onDismiss, autoFocus, className, children, ...props }: UserAskProps): import("react").JSX.Element;
9
+ export declare function UserAsk({ onComplete, onDismiss, autoFocus, questionStatusLabel, className, children, ...props }: UserAskProps): import("react").JSX.Element;
10
10
  export type UserAskHeaderProps = ComponentProps<"header"> & {
11
11
  style?: CSSProperties & UserAskKnobStyle;
12
12
  };
@@ -44,8 +44,13 @@ export type UserAskFooterProps = ComponentProps<"footer"> & {
44
44
  style?: CSSProperties & UserAskKnobStyle;
45
45
  };
46
46
  export declare function UserAskFooter({ className, ...props }: UserAskFooterProps): import("react").JSX.Element;
47
- export type UserAskDismissProps = ComponentProps<typeof Button>;
48
- export declare function UserAskDismiss({ className, children, onClick, ...props }: UserAskDismissProps): import("react").JSX.Element;
49
- export type UserAskSubmitProps = ComponentProps<typeof Button>;
50
- export declare function UserAskSubmit({ className, children, disabled, onClick, ...props }: UserAskSubmitProps): import("react").JSX.Element;
47
+ export type UserAskDismissProps = ComponentProps<typeof Button> & {
48
+ label?: string;
49
+ };
50
+ export declare function UserAskDismiss({ label, className, children, onClick, ...props }: UserAskDismissProps): import("react").JSX.Element;
51
+ export type UserAskSubmitProps = ComponentProps<typeof Button> & {
52
+ continueLabel?: string;
53
+ submitLabel?: string;
54
+ };
55
+ export declare function UserAskSubmit({ continueLabel, submitLabel, className, children, disabled, onClick, ...props }: UserAskSubmitProps): import("react").JSX.Element;
51
56
  //#endregion
package/dist/user-ask.js CHANGED
@@ -1,9 +1,10 @@
1
1
  "use client";
2
2
  import { cn } from "./lib/cn.js";
3
- import { useUserAsk } from "./hooks/use-user-ask.js";
4
3
  import { Button } from "./ui/button.js";
4
+ import { LiveStatus } from "./ui/live-status.js";
5
+ import { useUserAsk } from "./hooks/use-user-ask.js";
5
6
  import { Kbd } from "./ui/kbd.js";
6
- import { createContext, useContext, useEffect, useId, useRef } from "react";
7
+ import { createContext, useContext, useEffect, useId, useRef, useState } from "react";
7
8
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
9
  import { Check, ChevronLeft, ChevronRight, PencilLine } from "lucide-react";
9
10
  //#region src/user-ask.tsx
@@ -19,13 +20,18 @@ function useUserAskQuestionContext() {
19
20
  if (!context) throw new Error("UserAsk options must be rendered inside <UserAskQuestion>.");
20
21
  return context;
21
22
  }
22
- function UserAsk({ onComplete, onDismiss, autoFocus = false, className, children, ...props }) {
23
+ function defaultQuestionStatusLabel(current, total, title) {
24
+ return `Question ${current} of ${total}: ${title}`;
25
+ }
26
+ function UserAsk({ onComplete, onDismiss, autoFocus = false, questionStatusLabel = defaultQuestionStatusLabel, className, children, ...props }) {
23
27
  const ask = useUserAsk({
24
28
  onComplete,
25
29
  onDismiss
26
30
  });
27
31
  const titleId = useId();
28
32
  const panelRef = useRef(null);
33
+ const [hasNavigated, setHasNavigated] = useState(false);
34
+ const questionStatus = hasNavigated && ask.activeQuestion ? questionStatusLabel(ask.activeIndex + 1, ask.questions.length, ask.activeQuestion.title) : "";
29
35
  useEffect(() => {
30
36
  if (autoFocus) panelRef.current?.focus();
31
37
  }, [autoFocus]);
@@ -33,6 +39,7 @@ function UserAsk({ onComplete, onDismiss, autoFocus = false, className, children
33
39
  useEffect(() => {
34
40
  if (lastActiveIndex.current === ask.activeIndex) return;
35
41
  lastActiveIndex.current = ask.activeIndex;
42
+ setHasNavigated(true);
36
43
  const panel = panelRef.current;
37
44
  const active = document.activeElement;
38
45
  const activeIsUsable = active instanceof HTMLElement && panel?.contains(active) && active.checkVisibility();
@@ -43,7 +50,7 @@ function UserAsk({ onComplete, onDismiss, autoFocus = false, className, children
43
50
  ...ask,
44
51
  titleId
45
52
  },
46
- children: /* @__PURE__ */ jsx("section", {
53
+ children: /* @__PURE__ */ jsxs("section", {
47
54
  ref: panelRef,
48
55
  "data-control-ui": "user-ask",
49
56
  "data-control-family": "user-ask",
@@ -54,7 +61,7 @@ function UserAsk({ onComplete, onDismiss, autoFocus = false, className, children
54
61
  onKeyDown: ask.handleKeyDown,
55
62
  className: cn("relative w-full", className),
56
63
  ...props,
57
- children
64
+ children: [children, /* @__PURE__ */ jsx(LiveStatus, { message: questionStatus })]
58
65
  })
59
66
  });
60
67
  }
@@ -212,6 +219,7 @@ function UserAskOption({ value, recommended = false, disabled = false, className
212
219
  role: question.multiple ? "checkbox" : "radio",
213
220
  "aria-checked": selected,
214
221
  disabled,
222
+ tabIndex: ask.isTabStop(question.id, key) ? 0 : -1,
215
223
  "data-control-ui": "user-ask",
216
224
  "data-control-family": "user-ask",
217
225
  "data-slot": "option",
@@ -297,6 +305,7 @@ function UserAskOptionInput({ label = "Other", placeholder = "Type your own answ
297
305
  role: question.multiple ? "checkbox" : "radio",
298
306
  "aria-checked": false,
299
307
  disabled,
308
+ tabIndex: ask.isTabStop(question.id, key) ? 0 : -1,
300
309
  "data-control-ui": "user-ask",
301
310
  "data-control-family": "user-ask",
302
311
  "data-slot": "option",
@@ -334,7 +343,7 @@ function UserAskOptionInput({ label = "Other", placeholder = "Type your own answ
334
343
  type: "button",
335
344
  role: "checkbox",
336
345
  "aria-checked": true,
337
- "aria-label": `Clear ${label}`,
346
+ "aria-label": label,
338
347
  "data-control-ui": "user-ask",
339
348
  "data-control-family": "user-ask",
340
349
  "data-slot": "option-indicator",
@@ -343,12 +352,17 @@ function UserAskOptionInput({ label = "Other", placeholder = "Type your own answ
343
352
  onClick: () => ask.select(question.id, key),
344
353
  className: "inline-flex shrink-0 items-center justify-center",
345
354
  children: /* @__PURE__ */ jsx(Check, { className: "size-3" })
346
- }) : /* @__PURE__ */ jsx("span", {
347
- "aria-hidden": "true",
355
+ }) : /* @__PURE__ */ jsx("button", {
356
+ type: "button",
357
+ role: "radio",
358
+ "aria-checked": true,
359
+ "aria-label": label,
360
+ tabIndex: -1,
348
361
  "data-control-ui": "user-ask",
349
362
  "data-control-family": "user-ask",
350
363
  "data-slot": "option-indicator",
351
364
  "data-selected": "",
365
+ onClick: () => inputRef.current?.focus(),
352
366
  className: "inline-flex shrink-0 items-center justify-center",
353
367
  children: /* @__PURE__ */ jsx(PencilLine, { className: "size-3" })
354
368
  }), /* @__PURE__ */ jsx("input", {
@@ -376,7 +390,7 @@ function UserAskFooter({ className, ...props }) {
376
390
  ...props
377
391
  });
378
392
  }
379
- function UserAskDismiss({ className, children, onClick, ...props }) {
393
+ function UserAskDismiss({ label = "Dismiss", className, children, onClick, ...props }) {
380
394
  const ask = useUserAskContext();
381
395
  function handleClick(event) {
382
396
  onClick?.(event);
@@ -389,13 +403,17 @@ function UserAskDismiss({ className, children, onClick, ...props }) {
389
403
  type: "button",
390
404
  variant: "quiet",
391
405
  size: "xs",
406
+ "aria-keyshortcuts": "Escape",
392
407
  onClick: handleClick,
393
408
  className: cn(className),
394
409
  ...props,
395
- children: children ?? /* @__PURE__ */ jsxs(Fragment$1, { children: ["Dismiss", /* @__PURE__ */ jsx(Kbd, { children: "esc" })] })
410
+ children: children ?? /* @__PURE__ */ jsxs(Fragment$1, { children: [label, /* @__PURE__ */ jsx(Kbd, {
411
+ "aria-hidden": "true",
412
+ children: "Esc"
413
+ })] })
396
414
  });
397
415
  }
398
- function UserAskSubmit({ className, children, disabled, onClick, ...props }) {
416
+ function UserAskSubmit({ continueLabel = "Continue", submitLabel = "Submit answers", className, children, disabled, onClick, ...props }) {
399
417
  const ask = useUserAskContext();
400
418
  function handleClick(event) {
401
419
  onClick?.(event);
@@ -410,10 +428,12 @@ function UserAskSubmit({ className, children, disabled, onClick, ...props }) {
410
428
  tone: "primary",
411
429
  size: "xs",
412
430
  disabled: disabled ?? !ask.canContinue,
431
+ "aria-keyshortcuts": "Enter",
413
432
  onClick: handleClick,
414
433
  className,
415
434
  ...props,
416
- children: children ?? /* @__PURE__ */ jsxs(Fragment$1, { children: ["Continue", /* @__PURE__ */ jsx(Kbd, {
435
+ children: children ?? /* @__PURE__ */ jsxs(Fragment$1, { children: [ask.isLastQuestion ? submitLabel : continueLabel, /* @__PURE__ */ jsx(Kbd, {
436
+ "aria-hidden": "true",
417
437
  "data-user-ask-submit-kbd": "true",
418
438
  children: "⏎"
419
439
  })] })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ctrl-ui/react",
3
- "version": "0.8.7",
3
+ "version": "0.8.8",
4
4
  "description": "Control UI components, blocks, and primitives with neutral defaults and consumer-owned themes.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -40,6 +40,7 @@
40
40
  "clsx": "^2.1.1",
41
41
  "cmdk": "^1.1.1",
42
42
  "diff": "^9.0.0",
43
+ "frimousse": "^0.4.0",
43
44
  "libphonenumber-js": "^1.13.13",
44
45
  "lucide-react": "^1.47.0",
45
46
  "prosemirror-commands": "^1.7.2",
@@ -69,6 +70,9 @@
69
70
  "diff": {
70
71
  "optional": true
71
72
  },
73
+ "frimousse": {
74
+ "optional": true
75
+ },
72
76
  "libphonenumber-js": {
73
77
  "optional": true
74
78
  },
@@ -1,3 +0,0 @@
1
- //#region src/hooks/use-keyboard-navigation.d.ts
2
- export declare function useKeyboardNavigation(): boolean;
3
- //#endregion
@@ -1,22 +0,0 @@
1
- import { useEffect, useState } from "react";
2
- //#region src/hooks/use-keyboard-navigation.ts
3
- function useKeyboardNavigation() {
4
- const [keyboardNavigation, setKeyboardNavigation] = useState(false);
5
- useEffect(() => {
6
- function markKeyboardNavigation(event) {
7
- if (event.key === "Tab") setKeyboardNavigation(true);
8
- }
9
- function clearKeyboardNavigation() {
10
- setKeyboardNavigation(false);
11
- }
12
- document.addEventListener("keydown", markKeyboardNavigation, true);
13
- document.addEventListener("pointerdown", clearKeyboardNavigation, true);
14
- return () => {
15
- document.removeEventListener("keydown", markKeyboardNavigation, true);
16
- document.removeEventListener("pointerdown", clearKeyboardNavigation, true);
17
- };
18
- }, []);
19
- return keyboardNavigation;
20
- }
21
- //#endregion
22
- export { useKeyboardNavigation };