@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,5 +1,6 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
+ import { useColorArea } from "../hooks/use-color-area.js";
3
4
  import { formatGradient } from "../lib/color.js";
4
5
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./select.js";
5
6
  import { ColorPicker, ColorPickerAlpha, ColorPickerArea, ColorPickerContent, ColorPickerFormatSelect, ColorPickerHue, ColorPickerInput, ColorPickerTrigger } from "./color-picker.js";
@@ -30,6 +31,7 @@ function GradientEditor({ defaultStops = DEFAULT_STOPS, defaultType = "linear",
30
31
  const [selectedId, setSelectedId] = useState(defaultStops[0]?.id ?? "stop-1");
31
32
  const idCounter = useRef(defaultStops.length);
32
33
  const trackRef = useRef(null);
34
+ const [stopNodes] = useState(() => /* @__PURE__ */ new Map());
33
35
  const gradient = formatGradient(stops, type, angle);
34
36
  function updateStops(nextStops) {
35
37
  setStops(nextStops);
@@ -58,7 +60,7 @@ function GradientEditor({ defaultStops = DEFAULT_STOPS, defaultType = "linear",
58
60
  if (stops.length <= 2) return;
59
61
  const nextStops = stops.filter((stop) => stop.id !== id);
60
62
  updateStops(nextStops);
61
- if (selectedId === id) setSelectedId(nextStops[0]?.id ?? selectedId);
63
+ setSelectedId((current) => current === id ? nextStops[0]?.id ?? current : current);
62
64
  };
63
65
  const setType = (nextType) => {
64
66
  setTypeState(nextType);
@@ -71,6 +73,7 @@ function GradientEditor({ defaultStops = DEFAULT_STOPS, defaultType = "linear",
71
73
  selectedId,
72
74
  gradient,
73
75
  trackRef,
76
+ stopNodes,
74
77
  select: setSelectedId,
75
78
  setStopColor,
76
79
  setStopPosition,
@@ -130,30 +133,35 @@ function GradientEditorTrack({ className, children, style, "aria-label": ariaLab
130
133
  children: children ?? stops.map((stop) => /* @__PURE__ */ jsx(GradientEditorStop, { stop }, stop.id))
131
134
  });
132
135
  }
133
- function GradientEditorStop({ stop, className, style, onPointerDown, onKeyDown, onFocus, onDoubleClick, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...props }) {
134
- const { stops, selectedId, select, setStopPosition, removeStop, trackRef } = useGradientEditor();
136
+ function GradientEditorStop({ stop, className, style, onPointerDown, onKeyDown, onFocus, onDoubleClick, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ref, ...props }) {
137
+ const { stops, selectedId, select, setStopPosition, removeStop, trackRef, stopNodes } = useGradientEditor();
135
138
  const selected = stop.id === selectedId;
136
139
  const canRemove = stops.length > 2;
140
+ const { onPointerDown: startDrag } = useColorArea((offset, rect) => setStopPosition(stop.id, offset.x / rect.width), trackRef);
137
141
  function handlePointerDown(event) {
138
142
  onPointerDown?.(event);
139
143
  if (event.defaultPrevented) return;
140
144
  select(stop.id);
141
145
  event.currentTarget.focus();
142
- event.preventDefault();
143
- const track = trackRef.current;
144
- if (!track) return;
145
- const move = (moveEvent) => {
146
- const rect = track.getBoundingClientRect();
147
- setStopPosition(stop.id, (moveEvent.clientX - rect.left) / rect.width);
148
- };
149
- const up = () => {
150
- window.removeEventListener("pointermove", move);
151
- window.removeEventListener("pointerup", up);
152
- document.body.style.userSelect = "";
146
+ startDrag(event);
147
+ }
148
+ function registerStop(node) {
149
+ stopNodes.set(stop.id, node);
150
+ const cleanup = typeof ref === "function" ? ref(node) : void 0;
151
+ if (ref && typeof ref === "object") ref.current = node;
152
+ return () => {
153
+ stopNodes.delete(stop.id);
154
+ if (typeof cleanup === "function") cleanup();
155
+ else if (typeof ref === "function") ref(null);
156
+ else if (ref) ref.current = null;
153
157
  };
154
- document.body.style.userSelect = "none";
155
- window.addEventListener("pointermove", move);
156
- window.addEventListener("pointerup", up);
158
+ }
159
+ function remove() {
160
+ if (!canRemove) return;
161
+ const index = stops.findIndex((candidate) => candidate.id === stop.id);
162
+ const neighbour = stops[index + 1] ?? stops[index - 1];
163
+ if (neighbour) stopNodes.get(neighbour.id)?.focus();
164
+ removeStop(stop.id);
157
165
  }
158
166
  function handleFocus(event) {
159
167
  onFocus?.(event);
@@ -194,27 +202,35 @@ function GradientEditorStop({ stop, className, style, onPointerDown, onKeyDown,
194
202
  case "Delete":
195
203
  if (!canRemove) return;
196
204
  event.preventDefault();
197
- removeStop(stop.id);
205
+ remove();
198
206
  }
199
207
  }
200
208
  function handleDoubleClick(event) {
201
209
  onDoubleClick?.(event);
202
- if (!event.defaultPrevented) removeStop(stop.id);
210
+ if (!event.defaultPrevented) remove();
203
211
  }
204
- const defaultLabel = `Gradient stop at ${Math.round(stop.position * 100)}%. Use arrow keys to move${canRemove ? ", Delete to remove" : ""}.`;
212
+ const percent = Math.round(stop.position * 100);
213
+ const defaultLabel = `Gradient stop ${stops.indexOf(stop) + 1}`;
205
214
  return /* @__PURE__ */ jsx("button", {
215
+ ref: registerStop,
206
216
  type: "button",
217
+ role: "slider",
207
218
  "data-control-ui": "gradient-editor",
208
219
  "data-control-family": "gradient-editor",
209
220
  "data-slot": "stop",
210
221
  "data-selected": selected ? "true" : void 0,
211
222
  "aria-label": ariaLabelledBy === void 0 ? ariaLabel ?? defaultLabel : ariaLabel,
212
223
  "aria-labelledby": ariaLabelledBy,
224
+ "aria-orientation": "horizontal",
225
+ "aria-valuemin": 0,
226
+ "aria-valuemax": 100,
227
+ "aria-valuenow": percent,
228
+ "aria-valuetext": `${percent}%, ${stop.color}`,
213
229
  onPointerDown: handlePointerDown,
214
230
  onFocus: handleFocus,
215
231
  onKeyDown: handleKeyDown,
216
232
  onDoubleClick: handleDoubleClick,
217
- className: cn("-translate-x-1/2 absolute top-1/2 -translate-y-1/2 cursor-grab touch-pan-y overflow-hidden active:cursor-grabbing", className),
233
+ className: cn("-translate-x-1/2 absolute top-1/2 -translate-y-1/2 cursor-grab touch-pan-y active:cursor-grabbing", className),
218
234
  style: {
219
235
  ...style,
220
236
  left: `${stop.position * 100}%`,
@@ -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 { jsx } from "react/jsx-runtime";
6
6
  import { PreviewCard } from "@base-ui/react/preview-card";
@@ -30,6 +30,7 @@ export type InfiniteCanvasItemProps = Omit<ComponentProps<"div">, "style"> & {
30
30
  x: number;
31
31
  y: number;
32
32
  onPositionChange?: (position: InfiniteCanvasPoint) => void;
33
+ movableItemLabel?: string;
33
34
  style?: CSSProperties & InfiniteCanvasKnobStyle;
34
35
  };
35
36
  export type InfiniteCanvasControlsProps = Omit<ComponentProps<"div">, "children" | "style"> & {
@@ -43,8 +44,8 @@ type InfiniteCanvasContextValue = {
43
44
  zoomBy: (factor: number, reason: InfiniteCanvasMoveReason) => void;
44
45
  };
45
46
  export declare function useInfiniteCanvas(): InfiniteCanvasContextValue;
46
- export declare function InfiniteCanvas({ transform: controlledTransform, defaultTransform, onTransformChange, minScale: minScaleProp, maxScale: maxScaleProp, className, children, style, onPointerDown, onPointerMove, onPointerUp, onPointerCancel, onWheel, onKeyDown, "aria-label": ariaLabel, ...props }: InfiniteCanvasProps): import("react").JSX.Element;
47
+ export declare function InfiniteCanvas({ transform: controlledTransform, defaultTransform, onTransformChange, minScale: minScaleProp, maxScale: maxScaleProp, className, children, style, onPointerDown, onPointerMove, onPointerUp, onPointerCancel, onWheel, onKeyDown, "aria-label": ariaLabel, "aria-keyshortcuts": ariaKeyShortcuts, ...props }: InfiniteCanvasProps): import("react").JSX.Element;
47
48
  export declare function InfiniteCanvasContent({ className, style, ...props }: InfiniteCanvasContentProps): import("react").JSX.Element;
48
- export declare function InfiniteCanvasItem({ x, y, onPositionChange, className, style, onPointerDown, onPointerMove, onPointerUp, onPointerCancel, ...props }: InfiniteCanvasItemProps): import("react").JSX.Element;
49
+ export declare function InfiniteCanvasItem({ x, y, onPositionChange, movableItemLabel, className, style, onPointerDown, onPointerMove, onPointerUp, onPointerCancel, onKeyDown, ...props }: InfiniteCanvasItemProps): import("react").JSX.Element;
49
50
  export declare function InfiniteCanvasControls({ className, ...props }: InfiniteCanvasControlsProps): import("react").JSX.Element;
50
51
  //#endregion
@@ -16,6 +16,7 @@ const KEYBOARD_PAN_STEP = 32;
16
16
  const GRID_SIZE = 24;
17
17
  const WHEEL_ZOOM_SPEED = .004;
18
18
  const MAX_WHEEL_ZOOM_DELTA = 50;
19
+ const CANVAS_KEY_SHORTCUTS = "ArrowLeft ArrowRight ArrowUp ArrowDown + - 0";
19
20
  const NOTCHED_WHEEL_DELTA = 40;
20
21
  const KEYBOARD_PAN_DIRECTIONS = {
21
22
  ArrowLeft: {
@@ -35,6 +36,14 @@ const KEYBOARD_PAN_DIRECTIONS = {
35
36
  y: 1
36
37
  }
37
38
  };
39
+ const KEYBOARD_ZOOM_FACTORS = {
40
+ "+": 1.15,
41
+ "=": 1.15,
42
+ "-": 1 / 1.15
43
+ };
44
+ function keyboardPanStep(shiftKey) {
45
+ return shiftKey ? 96 : KEYBOARD_PAN_STEP;
46
+ }
38
47
  const InfiniteCanvasContext = createContext(null);
39
48
  function clampScale(scale, minScale, maxScale) {
40
49
  return Math.min(Math.max(scale, minScale), maxScale);
@@ -68,7 +77,7 @@ function useInfiniteCanvas() {
68
77
  if (!context) throw new Error("useInfiniteCanvas must be used within InfiniteCanvas");
69
78
  return context;
70
79
  }
71
- function InfiniteCanvas({ transform: controlledTransform, defaultTransform = DEFAULT_TRANSFORM, onTransformChange, minScale: minScaleProp = DEFAULT_MIN_SCALE, maxScale: maxScaleProp = DEFAULT_MAX_SCALE, className, children, style, onPointerDown, onPointerMove, onPointerUp, onPointerCancel, onWheel, onKeyDown, "aria-label": ariaLabel = "Infinite canvas", ...props }) {
80
+ function InfiniteCanvas({ transform: controlledTransform, defaultTransform = DEFAULT_TRANSFORM, onTransformChange, minScale: minScaleProp = DEFAULT_MIN_SCALE, maxScale: maxScaleProp = DEFAULT_MAX_SCALE, className, children, style, onPointerDown, onPointerMove, onPointerUp, onPointerCancel, onWheel, onKeyDown, "aria-label": ariaLabel = "Infinite canvas", "aria-keyshortcuts": ariaKeyShortcuts, ...props }) {
72
81
  const minScale = Math.max(.1, minScaleProp);
73
82
  const maxScale = Math.max(minScale, maxScaleProp);
74
83
  const [uncontrolledTransform, setUncontrolledTransform] = useState(defaultTransform);
@@ -176,23 +185,32 @@ function InfiniteCanvas({ transform: controlledTransform, defaultTransform = DEF
176
185
  root.addEventListener("wheel", listener, { passive: false });
177
186
  return () => root.removeEventListener("wheel", listener);
178
187
  }, []);
179
- function moveWithKeyboard(event) {
180
- onKeyDown?.(event);
181
- if (event.defaultPrevented) return;
182
- const currentTransform = transformRef.current;
183
- const direction = KEYBOARD_PAN_DIRECTIONS[event.key];
188
+ function applyKeyboardCommand(key, shiftKey) {
189
+ const direction = KEYBOARD_PAN_DIRECTIONS[key];
184
190
  if (direction) {
185
- const panStep = event.shiftKey ? 96 : KEYBOARD_PAN_STEP;
191
+ const currentTransform = transformRef.current;
192
+ const panStep = keyboardPanStep(shiftKey);
186
193
  commitTransform({
187
194
  ...currentTransform,
188
195
  x: currentTransform.x + direction.x * panStep,
189
196
  y: currentTransform.y + direction.y * panStep
190
197
  }, "keyboard");
191
- } else if (event.key === "+" || event.key === "=") zoomBy(1.15, "keyboard");
192
- else if (event.key === "-") zoomBy(1 / 1.15, "keyboard");
193
- else if (event.key === "0") reset("keyboard");
194
- else return;
195
- event.preventDefault();
198
+ return true;
199
+ }
200
+ const zoomFactor = KEYBOARD_ZOOM_FACTORS[key];
201
+ if (zoomFactor) {
202
+ zoomBy(zoomFactor, "keyboard");
203
+ return true;
204
+ }
205
+ if (key !== "0") return false;
206
+ reset("keyboard");
207
+ return true;
208
+ }
209
+ function moveWithKeyboard(event) {
210
+ onKeyDown?.(event);
211
+ if (event.defaultPrevented || event.target !== event.currentTarget) return;
212
+ if (event.ctrlKey || event.metaKey || event.altKey) return;
213
+ if (applyKeyboardCommand(event.key, event.shiftKey)) event.preventDefault();
196
214
  }
197
215
  const context = {
198
216
  transform,
@@ -218,7 +236,7 @@ function InfiniteCanvas({ transform: controlledTransform, defaultTransform = DEF
218
236
  "data-easing": easing || void 0,
219
237
  "aria-label": ariaLabel,
220
238
  role: "application",
221
- "aria-keyshortcuts": "ArrowLeft ArrowRight ArrowUp ArrowDown + - 0",
239
+ "aria-keyshortcuts": ariaKeyShortcuts ? `${CANVAS_KEY_SHORTCUTS} ${ariaKeyShortcuts}` : CANVAS_KEY_SHORTCUTS,
222
240
  tabIndex: 0,
223
241
  className: cn("relative isolate overflow-hidden overscroll-contain touch-none select-none data-panning:cursor-grabbing", className),
224
242
  style: canvasStyle,
@@ -246,7 +264,7 @@ function InfiniteCanvasContent({ className, style, ...props }) {
246
264
  }
247
265
  });
248
266
  }
249
- function InfiniteCanvasItem({ x, y, onPositionChange, className, style, onPointerDown, onPointerMove, onPointerUp, onPointerCancel, ...props }) {
267
+ function InfiniteCanvasItem({ x, y, onPositionChange, movableItemLabel = "Movable item", className, style, onPointerDown, onPointerMove, onPointerUp, onPointerCancel, onKeyDown, ...props }) {
250
268
  const { transform } = useInfiniteCanvas();
251
269
  const dragRef = useRef(null);
252
270
  const [dragging, setDragging] = useState(false);
@@ -290,7 +308,37 @@ function InfiniteCanvasItem({ x, y, onPositionChange, className, style, onPointe
290
308
  onPointerCancel?.(event);
291
309
  finishDrag(event);
292
310
  }
311
+ function moveWithKeyboard(event) {
312
+ onKeyDown?.(event);
313
+ if (event.defaultPrevented || !onPositionChange || event.target !== event.currentTarget) return;
314
+ if (event.ctrlKey || event.metaKey || event.altKey) return;
315
+ const direction = KEYBOARD_PAN_DIRECTIONS[event.key];
316
+ if (!direction) return;
317
+ event.preventDefault();
318
+ const step = keyboardPanStep(event.shiftKey) / transform.scale;
319
+ onPositionChange({
320
+ x: x + direction.x * step,
321
+ y: y + direction.y * step
322
+ });
323
+ }
293
324
  return /* @__PURE__ */ jsx("div", {
325
+ ...onPositionChange ? {
326
+ role: "group",
327
+ "aria-roledescription": movableItemLabel,
328
+ "aria-keyshortcuts": "ArrowLeft ArrowRight ArrowUp ArrowDown",
329
+ tabIndex: 0,
330
+ onPointerDown: beginDrag,
331
+ onPointerMove: updateDrag,
332
+ onPointerUp: endDrag,
333
+ onPointerCancel: cancelDrag,
334
+ onKeyDown: moveWithKeyboard
335
+ } : {
336
+ onPointerDown,
337
+ onPointerMove,
338
+ onPointerUp,
339
+ onPointerCancel,
340
+ onKeyDown
341
+ },
294
342
  ...props,
295
343
  "data-control-ui": "infinite-canvas",
296
344
  "data-control-family": "infinite-canvas",
@@ -301,11 +349,7 @@ function InfiniteCanvasItem({ x, y, onPositionChange, className, style, onPointe
301
349
  ...style,
302
350
  left: x,
303
351
  top: y
304
- },
305
- onPointerDown: beginDrag,
306
- onPointerMove: updateDrag,
307
- onPointerUp: endDrag,
308
- onPointerCancel: cancelDrag
352
+ }
309
353
  });
310
354
  }
311
355
  function InfiniteCanvasControls({ className, ...props }) {
@@ -15,7 +15,4 @@ export type InputGroupAddonProps = ComponentProps<"span"> & {
15
15
  export declare function useIsInsideInputGroup(): boolean;
16
16
  export declare function InputGroup({ size, className, render, children, ...props }: InputGroupProps): import("react").JSX.Element;
17
17
  export declare function InputGroupAddon({ className, ...props }: InputGroupAddonProps): import("react").JSX.Element;
18
- export declare function InputGroupInput({ className, ...props }: ComponentProps<"input"> & {
19
- style?: CSSProperties & FieldKnobStyle;
20
- }): import("react").JSX.Element;
21
18
  //#endregion
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
3
  import { createContext, use } from "react";
4
- import { jsx } from "react/jsx-runtime";
5
4
  import { useRender } from "@base-ui/react/use-render";
5
+ import { jsx } from "react/jsx-runtime";
6
6
  //#region src/ui/input-group.tsx
7
7
  const InputGroupSurfaceContext = createContext(false);
8
8
  function useIsInsideInputGroup() {
@@ -31,23 +31,13 @@ function InputGroup({ size = "md", className, render, children, ...props }) {
31
31
  }
32
32
  function InputGroupAddon({ className, ...props }) {
33
33
  return /* @__PURE__ */ jsx("span", {
34
+ ...props,
34
35
  "data-control-ui": "input-group",
35
36
  "data-control-family": "field",
36
37
  "data-field-kind": "input-group",
37
38
  "data-slot": "addon",
38
- className: cn("inline-flex shrink-0 items-center", className),
39
- ...props
40
- });
41
- }
42
- function InputGroupInput({ className, ...props }) {
43
- return /* @__PURE__ */ jsx("input", {
44
- "data-control-ui": "input-group",
45
- "data-control-family": "field",
46
- "data-field-kind": "input-group",
47
- "data-slot": "input",
48
- className: cn("h-full min-w-0 flex-1", className),
49
- ...props
39
+ className: cn("inline-flex shrink-0 items-center", className)
50
40
  });
51
41
  }
52
42
  //#endregion
53
- export { InputGroup, InputGroupAddon, InputGroupInput, useIsInsideInputGroup };
43
+ export { InputGroup, InputGroupAddon, useIsInsideInputGroup };
@@ -33,5 +33,5 @@ export type InputOTPSeparatorProps = ComponentProps<"div"> & {
33
33
  };
34
34
  export declare function InputOTPSlot({ index, length, className, ...props }: InputOTPSlotProps): import("react").JSX.Element;
35
35
  export declare function InputOTPSeparator({ className, ...props }: InputOTPSeparatorProps): import("react").JSX.Element;
36
- export declare function InputOTP({ length, separator, className, children, ...props }: InputOTPProps): import("react").JSX.Element;
36
+ export declare function InputOTP({ length, separator, className, children, "aria-label": ariaLabel, ...props }: InputOTPProps): import("react").JSX.Element;
37
37
  //#endregion
@@ -1,17 +1,24 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
- import { Fragment } from "react";
3
+ import { Fragment, createContext, useContext, useId } from "react";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  import { OTPField } from "@base-ui/react/otp-field";
6
6
  //#region src/ui/input-otp.tsx
7
+ const InputOTPLabelContext = createContext(void 0);
8
+ function slotAriaLabel(index, length) {
9
+ if (index === 0) return void 0;
10
+ return length ? `Character ${index + 1} of ${length}` : `Character ${index + 1}`;
11
+ }
7
12
  function InputOTPSlot({ index, length, className, ...props }) {
13
+ const labelId = useContext(InputOTPLabelContext);
8
14
  return /* @__PURE__ */ jsx(OTPField.Input, {
9
15
  "data-control-ui": "input-otp",
10
16
  "data-field-kind": "input-otp",
11
17
  "data-slot": "slot",
12
18
  "data-control-family": "field",
13
19
  "data-control": "true",
14
- "aria-label": length ? `Character ${index + 1} of ${length}` : `Character ${index + 1}`,
20
+ "aria-label": slotAriaLabel(index, length),
21
+ "aria-labelledby": index === 0 ? labelId : void 0,
15
22
  className: cn("relative flex size-[var(--control-h-md)] items-center justify-center", className),
16
23
  ...props
17
24
  });
@@ -26,19 +33,29 @@ function InputOTPSeparator({ className, ...props }) {
26
33
  ...props
27
34
  });
28
35
  }
29
- function InputOTP({ length = 6, separator = false, className, children, ...props }) {
30
- return /* @__PURE__ */ jsx(OTPField.Root, {
31
- "data-control-ui": "input-otp",
32
- "data-control-family": "field",
33
- "data-field-kind": "input-otp",
34
- "data-slot": "root",
35
- length,
36
- className: cn("flex items-center", className),
37
- ...props,
38
- children: children ?? Array.from({ length }, (_, index) => `input-otp-slot-${index}`).map((slotKey, index) => /* @__PURE__ */ jsxs(Fragment, { children: [separator && index === Math.ceil(length / 2) ? /* @__PURE__ */ jsx(InputOTPSeparator, {}) : null, /* @__PURE__ */ jsx(InputOTPSlot, {
39
- index,
40
- length
41
- })] }, slotKey))
36
+ function InputOTP({ length = 6, separator = false, className, children, "aria-label": ariaLabel, ...props }) {
37
+ const labelId = useId();
38
+ const labelledBy = ariaLabel ? labelId : void 0;
39
+ return /* @__PURE__ */ jsxs(InputOTPLabelContext.Provider, {
40
+ value: labelledBy,
41
+ children: [ariaLabel ? /* @__PURE__ */ jsx("span", {
42
+ id: labelId,
43
+ hidden: true,
44
+ children: ariaLabel
45
+ }) : null, /* @__PURE__ */ jsx(OTPField.Root, {
46
+ "data-control-ui": "input-otp",
47
+ "data-control-family": "field",
48
+ "data-field-kind": "input-otp",
49
+ "data-slot": "root",
50
+ length,
51
+ "aria-labelledby": labelledBy,
52
+ className: cn("flex items-center", className),
53
+ ...props,
54
+ children: children ?? Array.from({ length }, (_, index) => `input-otp-slot-${index}`).map((slotKey, index) => /* @__PURE__ */ jsxs(Fragment, { children: [separator && index === Math.ceil(length / 2) ? /* @__PURE__ */ jsx(InputOTPSeparator, {}) : null, /* @__PURE__ */ jsx(InputOTPSlot, {
55
+ index,
56
+ length
57
+ })] }, slotKey))
58
+ })]
42
59
  });
43
60
  }
44
61
  //#endregion
package/dist/ui/input.js CHANGED
@@ -6,21 +6,21 @@ import { Input as Input$1 } from "@base-ui/react/input";
6
6
  //#region src/ui/input.tsx
7
7
  function Input({ size = "md", className, ...props }) {
8
8
  if (useIsInsideInputGroup()) return /* @__PURE__ */ jsx(Input$1, {
9
+ ...props,
9
10
  "data-control-ui": "input-group",
10
11
  "data-control-family": "field",
11
12
  "data-field-kind": "input-group",
12
13
  "data-slot": "input",
13
- className: cn("h-full min-w-0 flex-1", className),
14
- ...props
14
+ className: cn("h-full min-w-0 flex-1", className)
15
15
  });
16
16
  return /* @__PURE__ */ jsx(Input$1, {
17
+ ...props,
17
18
  "data-control-ui": "input",
18
19
  "data-slot": "root",
19
20
  "data-control-family": "field",
20
21
  "data-control": "true",
21
22
  "data-size": size,
22
- className: cn("w-full min-w-0", className),
23
- ...props
23
+ className: cn("w-full min-w-0", className)
24
24
  });
25
25
  }
26
26
  //#endregion
package/dist/ui/item.d.ts CHANGED
@@ -20,6 +20,7 @@ export type ItemMediaProps = Omit<ComponentProps<"div">, "style"> & {
20
20
  style?: CSSProperties & ItemKnobStyle;
21
21
  };
22
22
  export type ItemTitleProps = Omit<ComponentProps<"div">, "style"> & {
23
+ render?: RenderProp<ComponentProps<"div">>;
23
24
  style?: CSSProperties & ItemKnobStyle;
24
25
  };
25
26
  export type ItemGroupProps = ComponentProps<"div"> & {
@@ -33,7 +34,7 @@ export declare function ItemMedia({ className, ...props }: ItemMediaProps): impo
33
34
  export declare function ItemContent({ className, ...props }: ComponentProps<"div"> & {
34
35
  style?: CSSProperties & ItemKnobStyle;
35
36
  }): import("react").JSX.Element;
36
- export declare function ItemTitle({ className, ...props }: ItemTitleProps): import("react").JSX.Element;
37
+ export declare function ItemTitle({ render, className, ...props }: ItemTitleProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
37
38
  export declare function ItemDescription({ className, ...props }: ItemDescriptionProps): import("react").JSX.Element;
38
39
  export declare function ItemActions({ className, ...props }: ComponentProps<"div"> & {
39
40
  style?: CSSProperties & ItemKnobStyle;
package/dist/ui/item.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
3
  import { Separator } from "./separator.js";
4
- import { jsx } from "react/jsx-runtime";
5
4
  import { useRender } from "@base-ui/react/use-render";
5
+ import { jsx } from "react/jsx-runtime";
6
6
  //#region src/ui/item.tsx
7
7
  const itemVariants = [
8
8
  "default",
@@ -61,13 +61,17 @@ function ItemContent({ className, ...props }) {
61
61
  ...props
62
62
  });
63
63
  }
64
- function ItemTitle({ className, ...props }) {
65
- return /* @__PURE__ */ jsx("div", {
66
- "data-control-ui": "item",
67
- "data-control-family": "item",
68
- "data-slot": "title",
69
- className: cn("flex w-fit items-center", className),
70
- ...props
64
+ function ItemTitle({ render, className, ...props }) {
65
+ return useRender({
66
+ defaultTagName: "div",
67
+ render,
68
+ props: {
69
+ ...props,
70
+ "data-control-ui": "item",
71
+ "data-control-family": "item",
72
+ "data-slot": "title",
73
+ className: cn("flex w-fit items-center", className)
74
+ }
71
75
  });
72
76
  }
73
77
  function ItemDescription({ className, ...props }) {
@@ -0,0 +1,7 @@
1
+ import { ComponentProps } from "react";
2
+ //#region src/ui/live-status.d.ts
3
+ export type LiveStatusProps = Omit<ComponentProps<"span">, "role" | "children"> & {
4
+ message: string;
5
+ };
6
+ export declare function LiveStatus({ message, className, ...props }: LiveStatusProps): import("react").JSX.Element;
7
+ //#endregion
@@ -0,0 +1,17 @@
1
+ import { cn } from "../lib/cn.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/ui/live-status.tsx
4
+ function LiveStatus({ message, className, ...props }) {
5
+ return /* @__PURE__ */ jsx("span", {
6
+ ...props,
7
+ role: "status",
8
+ "aria-live": "polite",
9
+ "aria-atomic": "true",
10
+ "data-control-ui": "live-status",
11
+ "data-slot": "root",
12
+ className: cn("sr-only", className),
13
+ children: message
14
+ });
15
+ }
16
+ //#endregion
17
+ export { LiveStatus };
@@ -17,6 +17,9 @@ export declare function MarkdownCode({ className, children, node: _node, ...prop
17
17
  export declare function MarkdownH1({ className, node: _node, ...props }: MarkdownElementProps<"h1">): JSX.Element;
18
18
  export declare function MarkdownH2({ className, node: _node, ...props }: MarkdownElementProps<"h2">): JSX.Element;
19
19
  export declare function MarkdownH3({ className, node: _node, ...props }: MarkdownElementProps<"h3">): JSX.Element;
20
+ export declare function MarkdownH4({ className, node: _node, ...props }: MarkdownElementProps<"h4">): JSX.Element;
21
+ export declare function MarkdownH5({ className, node: _node, ...props }: MarkdownElementProps<"h5">): JSX.Element;
22
+ export declare function MarkdownH6({ className, node: _node, ...props }: MarkdownElementProps<"h6">): JSX.Element;
20
23
  export declare function MarkdownP({ className, node: _node, ...props }: MarkdownElementProps<"p">): JSX.Element;
21
24
  export declare function MarkdownUl({ className, node: _node, ...props }: MarkdownElementProps<"ul">): JSX.Element;
22
25
  export declare function MarkdownOl({ className, node: _node, ...props }: MarkdownElementProps<"ol">): JSX.Element;
@@ -35,6 +38,9 @@ export declare const markdownComponents: {
35
38
  h1: typeof MarkdownH1;
36
39
  h2: typeof MarkdownH2;
37
40
  h3: typeof MarkdownH3;
41
+ h4: typeof MarkdownH4;
42
+ h5: typeof MarkdownH5;
43
+ h6: typeof MarkdownH6;
38
44
  p: typeof MarkdownP;
39
45
  ul: typeof MarkdownUl;
40
46
  ol: typeof MarkdownOl;
@@ -74,6 +74,33 @@ function MarkdownH3({ className, node: _node, ...props }) {
74
74
  ...props
75
75
  });
76
76
  }
77
+ function MarkdownH4({ className, node: _node, ...props }) {
78
+ return /* @__PURE__ */ jsx("h4", {
79
+ "data-control-ui": "markdown",
80
+ "data-control-family": "markdown",
81
+ "data-slot": "h4",
82
+ className,
83
+ ...props
84
+ });
85
+ }
86
+ function MarkdownH5({ className, node: _node, ...props }) {
87
+ return /* @__PURE__ */ jsx("h5", {
88
+ "data-control-ui": "markdown",
89
+ "data-control-family": "markdown",
90
+ "data-slot": "h5",
91
+ className,
92
+ ...props
93
+ });
94
+ }
95
+ function MarkdownH6({ className, node: _node, ...props }) {
96
+ return /* @__PURE__ */ jsx("h6", {
97
+ "data-control-ui": "markdown",
98
+ "data-control-family": "markdown",
99
+ "data-slot": "h6",
100
+ className,
101
+ ...props
102
+ });
103
+ }
77
104
  function MarkdownP({ className, node: _node, ...props }) {
78
105
  return /* @__PURE__ */ jsx("p", {
79
106
  "data-control-ui": "markdown",
@@ -197,6 +224,9 @@ const markdownComponents = {
197
224
  h1: MarkdownH1,
198
225
  h2: MarkdownH2,
199
226
  h3: MarkdownH3,
227
+ h4: MarkdownH4,
228
+ h5: MarkdownH5,
229
+ h6: MarkdownH6,
200
230
  p: MarkdownP,
201
231
  ul: MarkdownUl,
202
232
  ol: MarkdownOl,
@@ -211,4 +241,4 @@ const markdownComponents = {
211
241
  td: MarkdownTd
212
242
  };
213
243
  //#endregion
214
- export { MarkdownA, MarkdownBlockquote, MarkdownCode, MarkdownEm, MarkdownH1, MarkdownH2, MarkdownH3, MarkdownHr, MarkdownInlineCode, MarkdownLi, MarkdownOl, MarkdownP, MarkdownPre, MarkdownStrong, MarkdownTable, MarkdownTd, MarkdownTh, MarkdownUl, markdownComponents };
244
+ export { MarkdownA, MarkdownBlockquote, MarkdownCode, MarkdownEm, MarkdownH1, MarkdownH2, MarkdownH3, MarkdownH4, MarkdownH5, MarkdownH6, MarkdownHr, MarkdownInlineCode, MarkdownLi, MarkdownOl, MarkdownP, MarkdownPre, MarkdownStrong, MarkdownTable, MarkdownTd, MarkdownTh, MarkdownUl, markdownComponents };
@@ -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 { popupItemStructureClasses } from "../surface-variants.js";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -43,7 +43,6 @@ function MenubarContent({ className, children, ...props }) {
43
43
  return /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, {
44
44
  "data-skin": skin.id,
45
45
  "data-effects": controlEffectsAttribute(skin.effects),
46
- side: "bottom",
47
46
  align: "start",
48
47
  sideOffset: 6,
49
48
  className: "z-(--z-popup)",
@@ -111,6 +110,7 @@ function MenubarShortcut({ className, ...props }) {
111
110
  "data-slot": "shortcut",
112
111
  "data-control-family": "popup",
113
112
  "data-popup-part": "shortcut",
113
+ "aria-hidden": "true",
114
114
  className: cn(className),
115
115
  ...props
116
116
  });
@@ -133,6 +133,7 @@ function MenubarSubTrigger({ className, inset = false, children, ...props }) {
133
133
  "data-popup-kind": "menubar",
134
134
  "data-control-family": "popup",
135
135
  "data-slot": "sub-trigger-indicator",
136
+ "data-icon-dir": "inline",
136
137
  "aria-hidden": "true",
137
138
  children: "›"
138
139
  })]
@@ -143,7 +144,6 @@ function MenubarSubContent({ className, children, ...props }) {
143
144
  return /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, {
144
145
  "data-skin": skin.id,
145
146
  "data-effects": controlEffectsAttribute(skin.effects),
146
- side: "right",
147
147
  align: "start",
148
148
  sideOffset: -4,
149
149
  alignOffset: -5,