@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,15 +1,15 @@
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 { Button } from "./button.js";
6
6
  import { Input } from "./input.js";
7
7
  import { useColorArea } from "../hooks/use-color-area.js";
8
8
  import { formatColor, getChannels, hsvaToRgba, parseColor, pointToHueSat, pointToSaturationValue, setChannel } from "../lib/color.js";
9
- import { TARGET_RATIO, contrastOf, fixColorForContrast, nextFixLevel, wcagLevels } from "../lib/contrast.js";
9
+ import { TARGET_RATIO, contrastOf, fixColorForContrast, formatContrastRatio, nextFixLevel, wcagLevels } from "../lib/contrast.js";
10
10
  import { NumberField, NumberFieldGroup, NumberFieldInput } from "./number-field.js";
11
11
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./select.js";
12
- import { createContext, useContext, useEffect, useRef, useState, useSyncExternalStore } from "react";
12
+ import { createContext, useContext, useEffect, useId, useRef, useState, useSyncExternalStore } from "react";
13
13
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
14
14
  import { Popover } from "@base-ui/react/popover";
15
15
  import { Slider } from "@base-ui/react/slider";
@@ -111,8 +111,9 @@ function useColorState(props) {
111
111
  const setChannelValue = (id, next) => commit(setChannel(hsvaRef.current, id, next));
112
112
  const setFromString = (raw) => {
113
113
  const parsed = parseColor(raw);
114
- if (!parsed) return;
114
+ if (!parsed) return false;
115
115
  commit(reconcileAchromatic(hsvaRef.current, parsed));
116
+ return true;
116
117
  };
117
118
  const setFormat = (next) => {
118
119
  if (formatProp === void 0) setFormatState(next);
@@ -241,6 +242,7 @@ function ColorPickerArea({ className, style, ...props }) {
241
242
  setHsva(axis === "s" ? { s: next } : { v: next });
242
243
  }
243
244
  return /* @__PURE__ */ jsxs("div", {
245
+ "data-focus-ring": "within",
244
246
  ref: areaRef,
245
247
  "data-control-ui": "color-picker",
246
248
  "data-control-family": "color-picker",
@@ -318,6 +320,10 @@ function ColorPickerHue({ className, "aria-label": ariaLabel, "aria-labelledby":
318
320
  "data-control-ui": "color-picker",
319
321
  "data-control-family": "color-picker",
320
322
  "data-slot": "hue",
323
+ format: {
324
+ style: "unit",
325
+ unit: "degree"
326
+ },
321
327
  "aria-label": ariaLabelledBy === void 0 ? ariaLabel ?? "Hue" : ariaLabel,
322
328
  "aria-labelledby": ariaLabelledBy,
323
329
  value: hsva.h,
@@ -340,6 +346,7 @@ function ColorPickerHue({ className, "aria-label": ariaLabel, "aria-labelledby":
340
346
  "data-control-ui": "color-picker",
341
347
  "data-control-family": "color-picker",
342
348
  "data-slot": "hue-thumb",
349
+ "data-focus-ring": "within",
343
350
  className: RING_THUMB
344
351
  })
345
352
  })
@@ -360,6 +367,7 @@ function ColorPickerAlpha({ className, "aria-label": ariaLabel, "aria-labelledby
360
367
  "aria-label": ariaLabelledBy === void 0 ? ariaLabel ?? "Opacity" : ariaLabel,
361
368
  "aria-labelledby": ariaLabelledBy,
362
369
  value: hsva.a,
370
+ format: { style: "percent" },
363
371
  min: 0,
364
372
  max: 1,
365
373
  step: .01,
@@ -382,6 +390,7 @@ function ColorPickerAlpha({ className, "aria-label": ariaLabel, "aria-labelledby
382
390
  "data-control-ui": "color-picker",
383
391
  "data-control-family": "color-picker",
384
392
  "data-slot": "alpha-thumb",
393
+ "data-focus-ring": "within",
385
394
  className: RING_THUMB
386
395
  })
387
396
  })
@@ -404,6 +413,7 @@ function ColorPickerWheel({ className, style, ...props }) {
404
413
  const left = 50 + radius * Math.cos(rad);
405
414
  const top = 50 + radius * Math.sin(rad);
406
415
  return /* @__PURE__ */ jsxs("div", {
416
+ "data-focus-ring": "within",
407
417
  ref: areaRef,
408
418
  "data-control-ui": "color-picker",
409
419
  "data-control-family": "color-picker",
@@ -456,38 +466,62 @@ function ColorPickerWheel({ className, style, ...props }) {
456
466
  ]
457
467
  });
458
468
  }
459
- function ColorPickerInput({ size = "sm", className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...props }) {
469
+ function ColorPickerInput({ size = "sm", className, invalidLabel = "Enter a hex, rgb(), hsl() or oklch() color.", "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, onFocus, onBlur, onKeyDown, ...props }) {
460
470
  const { valueString, setFromString, disabled } = useColorPicker();
471
+ const invalidMessageId = useId();
461
472
  const [draft, setDraft] = useState(valueString);
462
473
  const [editing, setEditing] = useState(false);
474
+ const [invalid, setInvalid] = useState(false);
475
+ const describedBy = [ariaDescribedBy, invalid ? invalidMessageId : void 0].filter(Boolean).join(" ") || void 0;
463
476
  const shown = editing ? draft : valueString;
464
477
  const commit = () => {
465
- setFromString(draft);
478
+ const accepted = setFromString(draft);
479
+ setInvalid(!accepted);
480
+ if (accepted) setEditing(false);
481
+ };
482
+ const revert = () => {
483
+ setInvalid(false);
466
484
  setEditing(false);
467
485
  };
468
- return /* @__PURE__ */ jsx(Input, {
469
- size,
470
- value: shown,
471
- disabled,
486
+ return /* @__PURE__ */ jsxs("span", {
472
487
  "data-control-ui": "color-picker",
473
488
  "data-control-family": "color-picker",
474
489
  "data-slot": "input",
475
- spellCheck: false,
476
- autoComplete: "off",
477
- "aria-label": ariaLabelledBy === void 0 ? ariaLabel ?? "Color value" : ariaLabel,
478
- "aria-labelledby": ariaLabelledBy,
479
- className,
480
- onFocus: () => {
481
- setDraft(valueString);
482
- setEditing(true);
483
- },
484
- onChange: (event) => setDraft(event.target.value),
485
- onBlur: commit,
486
- onKeyDown: (event) => {
487
- if (event.key === "Enter") commit();
488
- else if (event.key === "Escape") setEditing(false);
489
- },
490
- ...props
490
+ className: "contents",
491
+ children: [/* @__PURE__ */ jsx(Input, {
492
+ ...props,
493
+ size,
494
+ value: shown,
495
+ disabled,
496
+ spellCheck: false,
497
+ autoComplete: "off",
498
+ "aria-label": ariaLabelledBy === void 0 ? ariaLabel ?? "Color value" : ariaLabel,
499
+ "aria-labelledby": ariaLabelledBy,
500
+ "aria-invalid": invalid || void 0,
501
+ "aria-describedby": describedBy,
502
+ className,
503
+ onFocus: (event) => {
504
+ onFocus?.(event);
505
+ if (editing) return;
506
+ setDraft(valueString);
507
+ setEditing(true);
508
+ },
509
+ onChange: (event) => setDraft(event.target.value),
510
+ onBlur: (event) => {
511
+ onBlur?.(event);
512
+ commit();
513
+ },
514
+ onKeyDown: (event) => {
515
+ onKeyDown?.(event);
516
+ if (event.defaultPrevented) return;
517
+ if (event.key === "Enter") commit();
518
+ else if (event.key === "Escape") revert();
519
+ }
520
+ }), invalid ? /* @__PURE__ */ jsx("span", {
521
+ id: invalidMessageId,
522
+ className: "sr-only",
523
+ children: invalidLabel
524
+ }) : null]
491
525
  });
492
526
  }
493
527
  function ColorPickerFormatSelect({ formats = [
@@ -617,7 +651,7 @@ function ColorPickerSwatches({ colors, label, className, children, ...props }) {
617
651
  });
618
652
  }
619
653
  function ColorPickerSwatch({ color, className, "aria-label": ariaLabel, ...props }) {
620
- const { setFromString, valueString } = useColorPicker();
654
+ const { setFromString, valueString, disabled } = useColorPicker();
621
655
  const selected = sameColor(valueString, color);
622
656
  return /* @__PURE__ */ jsxs("button", {
623
657
  type: "button",
@@ -628,8 +662,9 @@ function ColorPickerSwatch({ color, className, "aria-label": ariaLabel, ...props
628
662
  "aria-pressed": selected,
629
663
  "aria-label": ariaLabel ?? `Set color ${color}`,
630
664
  title: color,
665
+ disabled,
631
666
  onClick: () => setFromString(color),
632
- className: cn("relative shrink-0 cursor-pointer overflow-hidden", className),
667
+ className: cn("relative shrink-0 cursor-pointer overflow-hidden disabled:cursor-not-allowed", className),
633
668
  ...props,
634
669
  children: [/* @__PURE__ */ jsx("span", {
635
670
  "data-control-ui": "color-picker",
@@ -652,21 +687,22 @@ function ColorPickerSwatch({ color, className, "aria-label": ariaLabel, ...props
652
687
  });
653
688
  }
654
689
  function ColorPickerSwatchAdd({ onAdd, className, children, ...props }) {
655
- const { valueString } = useColorPicker();
690
+ const { valueString, disabled } = useColorPicker();
656
691
  return /* @__PURE__ */ jsx("button", {
657
692
  type: "button",
658
693
  "data-control-ui": "color-picker",
659
694
  "data-control-family": "color-picker",
660
695
  "data-slot": "swatch-add",
661
696
  "aria-label": "Add current color",
697
+ disabled,
662
698
  onClick: () => onAdd?.(valueString),
663
- className: cn("flex shrink-0 cursor-pointer items-center justify-center", className),
699
+ className: cn("relative flex shrink-0 cursor-pointer items-center justify-center disabled:cursor-not-allowed", className),
664
700
  ...props,
665
701
  children: children ?? /* @__PURE__ */ jsx(PlusIcon, {})
666
702
  });
667
703
  }
668
- function ColorPickerContrast({ background = "#ffffff", className, ...props }) {
669
- const { hsva, setFromString } = useColorPicker();
704
+ function ColorPickerContrast({ background = "#ffffff", passLabel = "Passes", failLabel = "Fails", className, ...props }) {
705
+ const { hsva, setFromString, disabled } = useColorPicker();
670
706
  const bg = parseColor(background);
671
707
  if (!bg) return null;
672
708
  const bgRgba = hsvaToRgba(bg);
@@ -689,14 +725,18 @@ function ColorPickerContrast({ background = "#ffffff", className, ...props }) {
689
725
  "data-control-ui": "color-picker",
690
726
  "data-control-family": "color-picker",
691
727
  "data-slot": "contrast-ratio",
692
- children: [ratio.toFixed(2), ":1"]
728
+ children: [formatContrastRatio(ratio), ":1"]
693
729
  }),
694
730
  /* @__PURE__ */ jsx(WcagPill, {
695
731
  ok: levels.AA,
732
+ passLabel,
733
+ failLabel,
696
734
  children: "AA"
697
735
  }),
698
736
  /* @__PURE__ */ jsx(WcagPill, {
699
737
  ok: levels.AAA,
738
+ passLabel,
739
+ failLabel,
700
740
  children: "AAA"
701
741
  }),
702
742
  target ? /* @__PURE__ */ jsxs("button", {
@@ -704,14 +744,15 @@ function ColorPickerContrast({ background = "#ffffff", className, ...props }) {
704
744
  "data-control-ui": "color-picker",
705
745
  "data-control-family": "color-picker",
706
746
  "data-slot": "contrast-fix",
747
+ disabled,
707
748
  onClick: applyFix,
708
- className: "ml-auto cursor-pointer",
709
- children: ["Fix → ", target]
749
+ className: "ms-auto cursor-pointer disabled:cursor-not-allowed",
750
+ children: ["Fix for ", target]
710
751
  }) : null
711
752
  ]
712
753
  });
713
754
  }
714
- function WcagPill({ ok, children }) {
755
+ function WcagPill({ ok, passLabel, failLabel, children }) {
715
756
  return /* @__PURE__ */ jsxs("span", {
716
757
  "data-control-ui": "color-picker",
717
758
  "data-control-family": "color-picker",
@@ -719,7 +760,14 @@ function WcagPill({ ok, children }) {
719
760
  "data-passing": ok ? "true" : void 0,
720
761
  className: "inline-flex items-center",
721
762
  children: [
722
- ok ? "✓" : "✕",
763
+ /* @__PURE__ */ jsx("span", {
764
+ "aria-hidden": "true",
765
+ children: ok ? "✓" : "✕"
766
+ }),
767
+ /* @__PURE__ */ jsx("span", {
768
+ className: "sr-only",
769
+ children: ok ? passLabel : failLabel
770
+ }),
723
771
  " ",
724
772
  children
725
773
  ]
@@ -1,4 +1,3 @@
1
1
  //#region src/ui/combobox-disabled-selection.d.ts
2
- export declare function shouldAcceptComboboxValueChange<Value>(value: Value | null, disabledValues: ReadonlySet<unknown>, multiple?: boolean): boolean;
3
- export declare function emitComboboxValueChange<Value>(value: Value | null, disabledValues: ReadonlySet<unknown>, onValueChange: (value: Value | null) => void): boolean;
2
+ export declare function shouldAcceptComboboxValueChange(next: unknown, previous: unknown, disabledValues: ReadonlySet<unknown>): boolean;
4
3
  //#endregion
@@ -1,12 +1,10 @@
1
1
  //#region src/ui/combobox-disabled-selection.ts
2
- function shouldAcceptComboboxValueChange(value, disabledValues, multiple = false) {
3
- if (multiple && Array.isArray(value)) return value.every((item) => !disabledValues.has(item));
4
- return value === null || !disabledValues.has(value);
5
- }
6
- function emitComboboxValueChange(value, disabledValues, onValueChange) {
7
- if (!shouldAcceptComboboxValueChange(value, disabledValues)) return false;
8
- onValueChange(value);
9
- return true;
2
+ function shouldAcceptComboboxValueChange(next, previous, disabledValues) {
3
+ if (Array.isArray(next)) {
4
+ const kept = new Set(Array.isArray(previous) ? previous : []);
5
+ return next.every((item) => kept.has(item) || !disabledValues.has(item));
6
+ }
7
+ return next === null || next === previous || !disabledValues.has(next);
10
8
  }
11
9
  //#endregion
12
- export { emitComboboxValueChange, shouldAcceptComboboxValueChange };
10
+ export { shouldAcceptComboboxValueChange };
@@ -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";
@@ -12,6 +12,7 @@ import { Combobox as Combobox$1 } from "@base-ui/react/combobox";
12
12
  const ComboboxDisabledValueContext = createContext(null);
13
13
  function Combobox({ children, onValueChange, autoHighlight = true, ...props }) {
14
14
  const [disabledValues] = useState(() => /* @__PURE__ */ new Set());
15
+ const [committedValue, setCommittedValue] = useState(() => props.value ?? props.defaultValue ?? null);
15
16
  const [disabledValueRegistry] = useState(() => ({ register(value, disabled) {
16
17
  if (!disabled || value === void 0) return () => {};
17
18
  disabledValues.add(value);
@@ -22,9 +23,15 @@ function Combobox({ children, onValueChange, autoHighlight = true, ...props }) {
22
23
  children: /* @__PURE__ */ jsx(Combobox$1.Root, {
23
24
  autoHighlight,
24
25
  ...props,
25
- onValueChange: onValueChange ? (value, eventDetails) => {
26
- if (shouldAcceptComboboxValueChange(value, disabledValues, props.multiple)) onValueChange(value, eventDetails);
27
- } : void 0,
26
+ onValueChange: (value, eventDetails) => {
27
+ const previousValue = props.value === void 0 ? committedValue : props.value;
28
+ if (!shouldAcceptComboboxValueChange(value, previousValue, disabledValues)) {
29
+ eventDetails.cancel();
30
+ return;
31
+ }
32
+ setCommittedValue(value);
33
+ onValueChange?.(value, eventDetails);
34
+ },
28
35
  children
29
36
  })
30
37
  });
@@ -62,8 +69,9 @@ function ComboboxTrigger({ className, children, ...props }) {
62
69
  function ComboboxInput({ size = "md", className, ...props }) {
63
70
  return /* @__PURE__ */ jsxs(Combobox$1.InputGroup, {
64
71
  "data-control-ui": "combobox",
72
+ "data-control-family": "field",
65
73
  "data-field-kind": "combobox",
66
- "data-slot": "root",
74
+ "data-slot": "input-group",
67
75
  className: "relative flex w-full items-center",
68
76
  children: [/* @__PURE__ */ jsx(Combobox$1.Input, {
69
77
  "data-control-ui": "combobox",
@@ -74,7 +82,7 @@ function ComboboxInput({ size = "md", className, ...props }) {
74
82
  "data-size": size,
75
83
  className: cn("w-full min-w-0 disabled:cursor-not-allowed", className),
76
84
  ...props
77
- }), /* @__PURE__ */ jsx(ComboboxTrigger, { className: "absolute right-1.5 top-1/2 -translate-y-1/2" })]
85
+ }), /* @__PURE__ */ jsx(ComboboxTrigger, { className: "absolute end-1.5 top-1/2 -translate-y-1/2" })]
78
86
  });
79
87
  }
80
88
  function ComboboxContent({ className, children, sideOffset = 6, anchor, ...props }) {
@@ -19,15 +19,21 @@ export type CommandInputProps = Omit<ComponentProps<typeof Command$1.Input>, "st
19
19
  style?: CSSProperties & PopupKnobStyle;
20
20
  };
21
21
  export declare function CommandInput({ className, ...props }: CommandInputProps): import("react").JSX.Element;
22
- export declare function CommandList({ className, children, ...props }: ComponentProps<typeof Command$1.List> & {
22
+ export type CommandListProps = Omit<ComponentProps<typeof Command$1.List>, "style"> & {
23
23
  style?: CSSProperties & PopupKnobStyle;
24
- }): import("react").JSX.Element;
24
+ getResultsLabel?: (count: number) => string;
25
+ };
26
+ export declare function CommandList({ className, children, getResultsLabel, ...props }: CommandListProps): import("react").JSX.Element;
25
27
  export type CommandEmptyProps = Omit<ComponentProps<typeof Command$1.Empty>, "style" | "title"> & {
26
28
  style?: CSSProperties & PopupKnobStyle;
27
29
  title?: ReactNode;
28
30
  description?: ReactNode;
29
31
  };
30
32
  export declare function CommandEmpty({ className, children, title, description, ...props }: CommandEmptyProps): import("react").JSX.Element;
33
+ export type CommandLoadingProps = Omit<ComponentProps<typeof Command$1.Loading>, "style"> & {
34
+ style?: CSSProperties & PopupKnobStyle;
35
+ };
36
+ export declare function CommandLoading({ label, className, ...props }: CommandLoadingProps): import("react").JSX.Element;
31
37
  export type CommandGroupProps = Omit<ComponentProps<typeof Command$1.Group>, "style"> & {
32
38
  style?: CSSProperties & PopupKnobStyle;
33
39
  };
@@ -1,11 +1,12 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
+ import { LiveStatus } from "./live-status.js";
3
4
  import { ScrollArea } from "./scroll-area.js";
4
5
  import { popupItemStructureClasses } from "../surface-variants.js";
5
6
  import { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "./empty.js";
6
7
  import { Dialog, DialogContent, DialogDescription, DialogTitle } from "./dialog.js";
7
8
  import { useEffect, useRef } from "react";
8
- import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
10
  import { Command as Command$1, useCommandState } from "cmdk";
10
11
  //#region src/ui/command.tsx
11
12
  function Command({ chrome = "standalone", className, ...props }) {
@@ -39,6 +40,7 @@ function CommandDialog({ title = "Command palette", description = "Search for a
39
40
  }),
40
41
  /* @__PURE__ */ jsx(Command, {
41
42
  chrome: "embedded",
43
+ label: title,
42
44
  ...commandProps,
43
45
  "data-control-ui": "command",
44
46
  "data-popup-kind": "command",
@@ -103,15 +105,20 @@ function CommandListSurface({ hasResults, ...props }) {
103
105
  role: hasResults ? "listbox" : "group"
104
106
  });
105
107
  }
106
- function CommandList({ className, children, ...props }) {
107
- const hasResults = useCommandState((state) => state.filtered.count > 0);
108
+ function defaultResultsLabel(count) {
109
+ if (count === 0) return "No results found";
110
+ return count === 1 ? "1 result" : `${count} results`;
111
+ }
112
+ function CommandList({ className, children, getResultsLabel = defaultResultsLabel, ...props }) {
113
+ const count = useCommandState((state) => state.filtered.count);
108
114
  const search = useCommandState((state) => state.search);
115
+ const hasResults = count > 0;
109
116
  const viewportRef = useRef(null);
110
117
  useEffect(() => {
111
118
  const frame = requestAnimationFrame(() => viewportRef.current?.scrollTo({ top: 0 }));
112
119
  return () => cancelAnimationFrame(frame);
113
120
  }, [search]);
114
- return /* @__PURE__ */ jsx(ScrollArea, {
121
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(ScrollArea, {
115
122
  viewportRef,
116
123
  maxHeight: "min(360px, var(--available-height, 360px))",
117
124
  className: "min-h-0 w-full",
@@ -128,7 +135,7 @@ function CommandList({ className, children, ...props }) {
128
135
  children
129
136
  })
130
137
  })
131
- });
138
+ }), /* @__PURE__ */ jsx(LiveStatus, { message: search ? getResultsLabel(count) : "" })] });
132
139
  }
133
140
  function CommandEmpty({ className, children, title = "No results found", description = "Try a different search term.", ...props }) {
134
141
  return /* @__PURE__ */ jsx(Command$1.Empty, {
@@ -139,14 +146,22 @@ function CommandEmpty({ className, children, title = "No results found", descrip
139
146
  "data-slot": "empty",
140
147
  className,
141
148
  ...props,
142
- children: /* @__PURE__ */ jsx("div", {
143
- role: "status",
144
- children: children ?? /* @__PURE__ */ jsx(Empty, { children: /* @__PURE__ */ jsxs(EmptyHeader, { children: [
145
- /* @__PURE__ */ jsx(EmptyMedia, { children: /* @__PURE__ */ jsx(CommandEmptyIcon, {}) }),
146
- /* @__PURE__ */ jsx(EmptyTitle, { children: title }),
147
- description ? /* @__PURE__ */ jsx(EmptyDescription, { children: description }) : null
148
- ] }) })
149
- })
149
+ children: /* @__PURE__ */ jsx("div", { children: children ?? /* @__PURE__ */ jsx(Empty, { children: /* @__PURE__ */ jsxs(EmptyHeader, { children: [
150
+ /* @__PURE__ */ jsx(EmptyMedia, { children: /* @__PURE__ */ jsx(CommandEmptyIcon, {}) }),
151
+ /* @__PURE__ */ jsx(EmptyTitle, { children: title }),
152
+ description ? /* @__PURE__ */ jsx(EmptyDescription, { children: description }) : null
153
+ ] }) }) })
154
+ });
155
+ }
156
+ function CommandLoading({ label = "Loading results", className, ...props }) {
157
+ return /* @__PURE__ */ jsx(Command$1.Loading, {
158
+ "data-control-ui": "command",
159
+ "data-control-family": "popup",
160
+ "data-popup-kind": "command",
161
+ "data-slot": "loading",
162
+ label,
163
+ className,
164
+ ...props
150
165
  });
151
166
  }
152
167
  function CommandEmptyIcon() {
@@ -216,9 +231,10 @@ function CommandShortcut({ className, ...props }) {
216
231
  "data-control-family": "popup",
217
232
  "data-popup-part": "shortcut",
218
233
  "data-slot": "shortcut",
234
+ "aria-hidden": "true",
219
235
  className: cn(className),
220
236
  ...props
221
237
  });
222
238
  }
223
239
  //#endregion
224
- export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut };
240
+ export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandLoading, CommandSeparator, CommandShortcut };
@@ -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";
@@ -17,6 +17,7 @@ function ContextMenuTrigger({ className, ...props }) {
17
17
  "data-control-family": "popup",
18
18
  "data-popup-kind": "context-menu",
19
19
  "data-slot": "trigger",
20
+ tabIndex: 0,
20
21
  className,
21
22
  ...props
22
23
  });
@@ -153,6 +154,7 @@ function ContextMenuShortcut({ className, ...props }) {
153
154
  "data-slot": "shortcut",
154
155
  "data-control-family": "popup",
155
156
  "data-popup-part": "shortcut",
157
+ "aria-hidden": "true",
156
158
  className: cn(className),
157
159
  ...props
158
160
  });
@@ -175,6 +177,7 @@ function ContextMenuSubTrigger({ className, inset = false, children, ...props })
175
177
  "data-popup-kind": "context-menu",
176
178
  "data-control-family": "popup",
177
179
  "data-slot": "sub-trigger-indicator",
180
+ "data-icon-dir": "inline",
178
181
  "aria-hidden": "true",
179
182
  children: "›"
180
183
  })]
@@ -15,6 +15,7 @@ export type DialogContentProps = Omit<ComponentProps<"div">, "style"> & {
15
15
  style?: CSSProperties & PopupKnobStyle;
16
16
  } & {
17
17
  showCloseButton?: boolean;
18
+ closeLabel?: string;
18
19
  };
19
20
  export declare function Dialog(props: DialogProps): import("react").JSX.Element;
20
21
  export declare function DialogTrigger({ className, ...props }: ComponentProps<typeof Dialog$1.Trigger> & {
@@ -22,7 +23,7 @@ export declare function DialogTrigger({ className, ...props }: ComponentProps<ty
22
23
  }): import("react").JSX.Element;
23
24
  export type DialogCloseProps = Omit<ComponentProps<typeof Dialog$1.Close>, "render"> & Pick<ButtonProps, "variant" | "size" | "tone" | "iconOnly">;
24
25
  export declare function DialogClose({ className, children, variant, size, tone, iconOnly, ...props }: DialogCloseProps): import("react").JSX.Element;
25
- export declare function DialogContent({ className, children, showCloseButton, ...props }: DialogContentProps): import("react").JSX.Element;
26
+ export declare function DialogContent({ className, children, showCloseButton, closeLabel, ...props }: DialogContentProps): import("react").JSX.Element;
26
27
  export declare function DialogHeader({ className, ...props }: ComponentProps<"div"> & {
27
28
  style?: CSSProperties & PopupKnobStyle;
28
29
  }): import("react").JSX.Element;
package/dist/ui/dialog.js CHANGED
@@ -1,8 +1,9 @@
1
1
  "use client";
2
- import { controlEffectsAttribute, skinAdornment } from "../skin.js";
3
2
  import { cn } from "../lib/cn.js";
3
+ import { controlEffectsAttribute, skinAdornment } from "../skin.js";
4
4
  import { useSkin } from "../skin-provider.js";
5
5
  import { Button } from "./button.js";
6
+ import { PopupCloseButton } from "../popup-parts.js";
6
7
  import { jsx, jsxs } from "react/jsx-runtime";
7
8
  import { Dialog as Dialog$1 } from "@base-ui/react/dialog";
8
9
  //#region src/ui/dialog.tsx
@@ -33,7 +34,7 @@ function DialogClose({ className, children, variant = "surface", size = "sm", to
33
34
  })
34
35
  });
35
36
  }
36
- function DialogContent({ className, children, showCloseButton = true, ...props }) {
37
+ function DialogContent({ className, children, showCloseButton = true, closeLabel = "Close", ...props }) {
37
38
  const skin = useSkin();
38
39
  return /* @__PURE__ */ jsxs(Dialog$1.Portal, { children: [/* @__PURE__ */ jsx(Dialog$1.Backdrop, {
39
40
  "data-control-ui": "dialog",
@@ -58,27 +59,7 @@ function DialogContent({ className, children, showCloseButton = true, ...props }
58
59
  children: [
59
60
  skinAdornment(skin, "dialog", "titlebar", {}),
60
61
  children,
61
- showCloseButton ? /* @__PURE__ */ jsxs(DialogClose, {
62
- variant: "ghost",
63
- size: "xs",
64
- iconOnly: true,
65
- className: "absolute",
66
- children: [/* @__PURE__ */ jsx("svg", {
67
- viewBox: "0 0 16 16",
68
- className: "size-4",
69
- "aria-hidden": "true",
70
- fill: "none",
71
- children: /* @__PURE__ */ jsx("path", {
72
- d: "M4 4 12 12M12 4 4 12",
73
- stroke: "currentColor",
74
- strokeWidth: "1.4",
75
- strokeLinecap: "round"
76
- })
77
- }), /* @__PURE__ */ jsx("span", {
78
- className: "sr-only",
79
- children: "Close"
80
- })]
81
- }) : null
62
+ showCloseButton ? /* @__PURE__ */ jsx(Dialog$1.Close, { render: /* @__PURE__ */ jsx(PopupCloseButton, { label: closeLabel }) }) : null
82
63
  ]
83
64
  })] });
84
65
  }
@@ -14,4 +14,5 @@ export type DockablePanelPosition = {
14
14
  export declare function clampDockablePanelPosition(position: DockablePanelPosition, bounds: DockablePanelBounds, panel: DockablePanelSize, inset?: number): DockablePanelPosition;
15
15
  export declare function dockablePanelSideAt(pointerX: number, width: number): "left" | "right";
16
16
  export declare function oppositeDockablePanelSide(placement: "left" | "right"): "left" | "right";
17
+ export declare function dockablePanelSideForKey(key: string, placement: "left" | "right"): "left" | "right" | null;
17
18
  //#endregion
@@ -13,5 +13,11 @@ function dockablePanelSideAt(pointerX, width) {
13
13
  function oppositeDockablePanelSide(placement) {
14
14
  return placement === "left" ? "right" : "left";
15
15
  }
16
+ function dockablePanelSideForKey(key, placement) {
17
+ if (key === "ArrowLeft") return "left";
18
+ if (key === "ArrowRight") return "right";
19
+ if (key === "Enter" || key === " ") return oppositeDockablePanelSide(placement);
20
+ return null;
21
+ }
16
22
  //#endregion
17
- export { clampDockablePanelPosition, dockablePanelSideAt, oppositeDockablePanelSide };
23
+ export { clampDockablePanelPosition, dockablePanelSideAt, dockablePanelSideForKey, oppositeDockablePanelSide };
@@ -1,6 +1,6 @@
1
1
  import { ButtonKnobStyle } from "../knob-contracts/button-knobs.js";
2
2
  import { DockablePanelKnobStyle } from "../knob-contracts/dockable-panel-knobs.js";
3
- import { CSSProperties, ComponentProps, ReactNode } from "react";
3
+ import { CSSProperties, ComponentProps, ReactNode, RefObject } from "react";
4
4
  //#region src/ui/dockable-panel.d.ts
5
5
  export type DockablePanelPlacement = "left" | "right";
6
6
  export type DockablePanelProps = Omit<ComponentProps<"aside">, "onChange" | "ref" | "style"> & {
@@ -10,15 +10,18 @@ export type DockablePanelProps = Omit<ComponentProps<"aside">, "onChange" | "ref
10
10
  placement?: DockablePanelPlacement;
11
11
  defaultPlacement?: DockablePanelPlacement;
12
12
  onPlacementChange?: (placement: DockablePanelPlacement) => void;
13
+ finalFocus?: RefObject<HTMLElement | null>;
13
14
  style?: CSSProperties & DockablePanelKnobStyle;
14
15
  };
15
16
  export type DockablePanelHeaderProps = Omit<ComponentProps<"div">, "style"> & {
16
17
  style?: CSSProperties & DockablePanelKnobStyle;
17
18
  };
18
- export type DockablePanelDragHandleProps = Omit<ComponentProps<"button">, "style"> & {
19
+ export type DockablePanelDragHandleProps = Omit<ComponentProps<"div">, "style"> & {
20
+ dragLabel?: string;
21
+ dockHintLabel?: string;
19
22
  style?: CSSProperties & DockablePanelKnobStyle;
20
23
  };
21
- export type DockablePanelTitleProps = Omit<ComponentProps<"h2">, "style"> & {
24
+ export type DockablePanelTitleProps = Omit<ComponentProps<"h2">, "style" | "id"> & {
22
25
  style?: CSSProperties & DockablePanelKnobStyle;
23
26
  };
24
27
  export type DockablePanelActionsProps = ComponentProps<"div"> & {
@@ -45,10 +48,10 @@ export type DockablePanelContentProps = ComponentProps<"div"> & {
45
48
  padding?: DockablePanelContentPadding;
46
49
  style?: CSSProperties & DockablePanelKnobStyle;
47
50
  };
48
- export declare function DockablePanel({ open: openProp, defaultOpen, onOpenChange, placement: placementProp, defaultPlacement, onPlacementChange, className, style, children, "aria-label": ariaLabel, ...props }: DockablePanelProps): import("react").JSX.Element | null;
51
+ export declare function DockablePanel({ open: openProp, defaultOpen, onOpenChange, placement: placementProp, defaultPlacement, onPlacementChange, finalFocus, className, style, children, "aria-label": ariaLabel, ...props }: DockablePanelProps): import("react").JSX.Element | null;
49
52
  export declare function DockablePanelHeader({ className, ...props }: DockablePanelHeaderProps): import("react").JSX.Element;
50
- export declare function DockablePanelDragHandle({ className, onPointerDown, onPointerMove, onPointerUp, onPointerCancel, children, ...props }: DockablePanelDragHandleProps): import("react").JSX.Element;
51
- export declare function DockablePanelTitle({ className, ...props }: DockablePanelTitleProps): import("react").JSX.Element;
53
+ export declare function DockablePanelDragHandle({ className, onPointerDown, onPointerMove, onPointerUp, onPointerCancel, children, dragLabel, dockHintLabel, ...props }: DockablePanelDragHandleProps): import("react").JSX.Element;
54
+ export declare function DockablePanelTitle({ className, children, ...props }: DockablePanelTitleProps): import("react").JSX.Element;
52
55
  export declare function DockablePanelActions({ className, ...props }: DockablePanelActionsProps): import("react").JSX.Element;
53
56
  export declare function DockablePanelToggle({ className, children, "aria-label": ariaLabel, onClick, ...props }: DockablePanelToggleProps): import("react").JSX.Element | null;
54
57
  export declare function DockablePanelDock({ placement: nextPlacement, className, children, "aria-label": ariaLabel, onClick, ...props }: DockablePanelDockProps): import("react").JSX.Element | null;