@ctrl-ui/react 0.8.7 → 0.8.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (341) hide show
  1. package/dist/action-bar.d.ts +15 -7
  2. package/dist/action-bar.js +39 -19
  3. package/dist/activity.js +7 -15
  4. package/dist/audio-recorder.d.ts +14 -4
  5. package/dist/audio-recorder.js +82 -29
  6. package/dist/audio-visualizer.js +1 -1
  7. package/dist/blocks/coding-agent.js +39 -39
  8. package/dist/blocks/design-canvas.d.ts +5 -1
  9. package/dist/blocks/design-canvas.js +198 -92
  10. package/dist/blocks/discussion.d.ts +28 -0
  11. package/dist/blocks/discussion.js +67 -0
  12. package/dist/blocks/file-explorer-data.d.ts +1 -0
  13. package/dist/blocks/file-explorer-data.js +4 -1
  14. package/dist/blocks/file-explorer.d.ts +9 -1
  15. package/dist/blocks/file-explorer.js +461 -192
  16. package/dist/blocks/settings.d.ts +2 -1
  17. package/dist/blocks/settings.js +101 -79
  18. package/dist/blocks/team-chat.d.ts +12 -0
  19. package/dist/blocks/team-chat.js +26 -0
  20. package/dist/blocks/theme-toggle.js +23 -31
  21. package/dist/chat-composer-attachment.d.ts +4 -1
  22. package/dist/chat-composer-attachment.js +35 -10
  23. package/dist/chat-composer-editor/extensions/mention.d.ts +5 -1
  24. package/dist/chat-composer-editor/extensions/mention.js +59 -28
  25. package/dist/chat-composer-editor/ghost.js +2 -4
  26. package/dist/chat-composer-editor/types.d.ts +5 -0
  27. package/dist/chat-composer-editor.d.ts +1 -1
  28. package/dist/chat-composer-editor.js +57 -30
  29. package/dist/chat-composer.d.ts +13 -32
  30. package/dist/chat-composer.js +52 -12
  31. package/dist/chat-layout.d.ts +19 -0
  32. package/dist/chat-layout.js +91 -40
  33. package/dist/chat-message/social.d.ts +26 -0
  34. package/dist/chat-message/social.js +122 -0
  35. package/dist/chat-message.d.ts +28 -29
  36. package/dist/chat-message.js +106 -25
  37. package/dist/context.d.ts +2 -2
  38. package/dist/context.js +38 -23
  39. package/dist/dynamic-notification-canvas-loop.d.ts +24 -0
  40. package/dist/dynamic-notification-canvas-loop.js +113 -0
  41. package/dist/dynamic-notification-glass.js +23 -114
  42. package/dist/dynamic-notification-liquid.js +14 -118
  43. package/dist/dynamic-notification.d.ts +16 -8
  44. package/dist/dynamic-notification.js +85 -22
  45. package/dist/email/email-brand.d.ts +7 -4
  46. package/dist/email/email-brand.js +9 -6
  47. package/dist/email/email-code.d.ts +3 -2
  48. package/dist/email/email-code.js +11 -9
  49. package/dist/email/email-footer.d.ts +5 -3
  50. package/dist/email/email-footer.js +11 -5
  51. package/dist/email/email.d.ts +31 -9
  52. package/dist/email/email.js +50 -26
  53. package/dist/email/templates.d.ts +10 -9
  54. package/dist/email/templates.js +102 -38
  55. package/dist/email/theme.js +1 -1
  56. package/dist/environment-variables.d.ts +4 -2
  57. package/dist/environment-variables.js +52 -32
  58. package/dist/filter-bar/editor.js +20 -8
  59. package/dist/filter-bar/model.d.ts +1 -0
  60. package/dist/filter-bar/model.js +10 -1
  61. package/dist/filter-bar/motion.js +4 -4
  62. package/dist/filter-bar/parts.js +19 -8
  63. package/dist/filter-bar/types.d.ts +1 -0
  64. package/dist/filter-bar.js +19 -13
  65. package/dist/hooks/use-audio-recorder.js +12 -6
  66. package/dist/hooks/use-chat-composer.d.ts +19 -7
  67. package/dist/hooks/use-chat-composer.js +32 -5
  68. package/dist/hooks/use-chat-message.d.ts +28 -2
  69. package/dist/hooks/use-chat-message.js +41 -10
  70. package/dist/hooks/use-chat-thread-scroll.js +43 -7
  71. package/dist/hooks/use-color-area.d.ts +3 -3
  72. package/dist/hooks/use-color-area.js +13 -12
  73. package/dist/hooks/use-copy-to-clipboard.d.ts +2 -1
  74. package/dist/hooks/use-copy-to-clipboard.js +20 -20
  75. package/dist/hooks/use-dynamic-notification.d.ts +6 -2
  76. package/dist/hooks/use-dynamic-notification.js +26 -10
  77. package/dist/hooks/use-mobile.d.ts +3 -2
  78. package/dist/hooks/use-mobile.js +8 -4
  79. package/dist/hooks/use-textarea-trigger-menu.js +2 -1
  80. package/dist/hooks/use-trigger-menu.d.ts +54 -0
  81. package/dist/hooks/use-trigger-menu.js +102 -47
  82. package/dist/hooks/use-user-ask.d.ts +2 -0
  83. package/dist/hooks/use-user-ask.js +35 -41
  84. package/dist/inline-attachment.d.ts +6 -2
  85. package/dist/inline-attachment.js +36 -15
  86. package/dist/inline-citation.d.ts +12 -5
  87. package/dist/inline-citation.js +25 -16
  88. package/dist/knob-contracts/audio-recorder-knobs.d.ts +1 -1
  89. package/dist/knob-contracts/audio-recorder-knobs.js +2 -1
  90. package/dist/knob-contracts/audio-visualizer-knobs.d.ts +1 -1
  91. package/dist/knob-contracts/audio-visualizer-knobs.js +2 -1
  92. package/dist/knob-contracts/avatar-knobs.d.ts +1 -1
  93. package/dist/knob-contracts/avatar-knobs.js +6 -1
  94. package/dist/knob-contracts/badge-knobs.d.ts +1 -1
  95. package/dist/knob-contracts/badge-knobs.js +2 -1
  96. package/dist/knob-contracts/breadcrumb-knobs.d.ts +4 -0
  97. package/dist/knob-contracts/breadcrumb-knobs.js +8 -0
  98. package/dist/knob-contracts/button-knobs.d.ts +1 -1
  99. package/dist/knob-contracts/button-knobs.js +1 -0
  100. package/dist/knob-contracts/chat-message-knobs.d.ts +1 -1
  101. package/dist/knob-contracts/chat-message-knobs.js +8 -1
  102. package/dist/knob-contracts/code-diff-knobs.d.ts +1 -1
  103. package/dist/knob-contracts/code-diff-knobs.js +2 -0
  104. package/dist/knob-contracts/code-knobs.d.ts +1 -1
  105. package/dist/knob-contracts/code-knobs.js +2 -1
  106. package/dist/knob-contracts/dynamic-notification-knobs.d.ts +1 -1
  107. package/dist/knob-contracts/dynamic-notification-knobs.js +2 -0
  108. package/dist/knob-contracts/emoji-picker-knobs.d.ts +4 -0
  109. package/dist/knob-contracts/emoji-picker-knobs.js +10 -0
  110. package/dist/knob-contracts/field-knobs.d.ts +1 -1
  111. package/dist/knob-contracts/field-knobs.js +5 -1
  112. package/dist/knob-contracts/filter-bar-knobs.d.ts +1 -1
  113. package/dist/knob-contracts/filter-bar-knobs.js +1 -2
  114. package/dist/knob-contracts/markdown-knobs.d.ts +1 -1
  115. package/dist/knob-contracts/markdown-knobs.js +3 -1
  116. package/dist/knob-contracts/page-layout-knobs.d.ts +1 -1
  117. package/dist/knob-contracts/page-layout-knobs.js +2 -1
  118. package/dist/knob-contracts/popup-knobs.d.ts +1 -1
  119. package/dist/knob-contracts/popup-knobs.js +27 -0
  120. package/dist/knob-contracts/range-knobs.d.ts +1 -1
  121. package/dist/knob-contracts/range-knobs.js +1 -0
  122. package/dist/knob-contracts/rich-tooltip-knobs.d.ts +1 -1
  123. package/dist/knob-contracts/rich-tooltip-knobs.js +2 -1
  124. package/dist/knob-contracts/sidebar-knobs.d.ts +1 -1
  125. package/dist/knob-contracts/sidebar-knobs.js +27 -2
  126. package/dist/knob-contracts/spinner-knobs.d.ts +1 -1
  127. package/dist/knob-contracts/spinner-knobs.js +1 -1
  128. package/dist/knob-contracts/stepper-knobs.d.ts +1 -1
  129. package/dist/knob-contracts/stepper-knobs.js +4 -1
  130. package/dist/knob-contracts/switch-knobs.d.ts +1 -1
  131. package/dist/knob-contracts/switch-knobs.js +5 -0
  132. package/dist/knob-contracts/table-of-contents-knobs.d.ts +1 -1
  133. package/dist/knob-contracts/table-of-contents-knobs.js +2 -1
  134. package/dist/knob-contracts/tabs-knobs.d.ts +1 -1
  135. package/dist/knob-contracts/tabs-knobs.js +1 -0
  136. package/dist/knob-contracts/tree-knobs.d.ts +1 -1
  137. package/dist/knob-contracts/tree-knobs.js +2 -1
  138. package/dist/lib/cn.js +0 -4
  139. package/dist/lib/contrast.d.ts +1 -0
  140. package/dist/lib/contrast.js +17 -5
  141. package/dist/lib/dropzone-validation.js +41 -28
  142. package/dist/lib/env-file.d.ts +1 -1
  143. package/dist/lib/env-file.js +5 -5
  144. package/dist/lib/motion.d.ts +4 -0
  145. package/dist/lib/motion.js +15 -0
  146. package/dist/lib/trigger-detect.js +6 -8
  147. package/dist/markdown-block.js +2 -1
  148. package/dist/popup-parts.d.ts +8 -0
  149. package/dist/popup-parts.js +43 -0
  150. package/dist/source-badge.js +3 -1
  151. package/dist/styles/code.css +0 -2
  152. package/dist/styles/effects.css +6 -32
  153. package/dist/styles/index.css +10 -5
  154. package/dist/styles/recipes/accordion.css +9 -6
  155. package/dist/styles/recipes/action-bar.css +0 -15
  156. package/dist/styles/recipes/activity.css +5 -11
  157. package/dist/styles/recipes/alert.css +4 -4
  158. package/dist/styles/recipes/audio-recorder.css +15 -3
  159. package/dist/styles/recipes/audio-visualizer.css +13 -2
  160. package/dist/styles/recipes/avatar.css +78 -1
  161. package/dist/styles/recipes/badge.css +14 -4
  162. package/dist/styles/recipes/breadcrumb.css +77 -0
  163. package/dist/styles/recipes/button-group.css +5 -7
  164. package/dist/styles/recipes/button-states.css +66 -0
  165. package/dist/styles/recipes/button.css +24 -83
  166. package/dist/styles/recipes/calendar.css +17 -23
  167. package/dist/styles/recipes/card.css +2 -2
  168. package/dist/styles/recipes/chat-composer-attachment.css +9 -3
  169. package/dist/styles/recipes/chat-composer.css +7 -10
  170. package/dist/styles/recipes/chat-layout.css +35 -0
  171. package/dist/styles/recipes/chat-message-social.css +123 -0
  172. package/dist/styles/recipes/chat-message.css +157 -37
  173. package/dist/styles/recipes/choice.css +18 -21
  174. package/dist/styles/recipes/code-diff.css +46 -33
  175. package/dist/styles/recipes/code.css +36 -16
  176. package/dist/styles/recipes/collapsible.css +7 -2
  177. package/dist/styles/recipes/color-picker-details.css +3 -4
  178. package/dist/styles/recipes/color-picker-values.css +9 -8
  179. package/dist/styles/recipes/color-picker.css +11 -2
  180. package/dist/styles/recipes/context.css +3 -3
  181. package/dist/styles/recipes/dockable-panel.css +7 -4
  182. package/dist/styles/recipes/dropzone.css +7 -8
  183. package/dist/styles/recipes/dynamic-notification-input.css +8 -5
  184. package/dist/styles/recipes/dynamic-notification-motion.css +12 -21
  185. package/dist/styles/recipes/dynamic-notification.css +40 -26
  186. package/dist/styles/recipes/emoji-picker.css +132 -0
  187. package/dist/styles/recipes/empty.css +5 -4
  188. package/dist/styles/recipes/environment-variables.css +4 -15
  189. package/dist/styles/recipes/field-parts.css +30 -24
  190. package/dist/styles/recipes/field.css +61 -26
  191. package/dist/styles/recipes/filter-bar.css +18 -31
  192. package/dist/styles/recipes/gradient-editor.css +18 -7
  193. package/dist/styles/recipes/infinite-canvas.css +0 -1
  194. package/dist/styles/recipes/inline-attachment.css +3 -3
  195. package/dist/styles/recipes/inline-citation.css +10 -4
  196. package/dist/styles/recipes/item.css +23 -9
  197. package/dist/styles/recipes/markdown-block.css +5 -4
  198. package/dist/styles/recipes/markdown.css +68 -26
  199. package/dist/styles/recipes/morphing-panel.css +8 -8
  200. package/dist/styles/recipes/page-layout.css +20 -12
  201. package/dist/styles/recipes/pagination.css +4 -5
  202. package/dist/styles/recipes/phone-input.css +12 -8
  203. package/dist/styles/recipes/popup-controls.css +166 -33
  204. package/dist/styles/recipes/popup-drawer.css +3 -14
  205. package/dist/styles/recipes/popup-lists.css +128 -27
  206. package/dist/styles/recipes/popup-motion.css +4 -45
  207. package/dist/styles/recipes/popup-toast.css +55 -26
  208. package/dist/styles/recipes/popup.css +139 -141
  209. package/dist/styles/recipes/range.css +54 -18
  210. package/dist/styles/recipes/resizable.css +2 -7
  211. package/dist/styles/recipes/rich-tooltip.css +24 -34
  212. package/dist/styles/recipes/scroll-area.css +8 -1
  213. package/dist/styles/recipes/sidebar-menu.css +166 -34
  214. package/dist/styles/recipes/sidebar-parts.css +192 -0
  215. package/dist/styles/recipes/sidebar.css +188 -128
  216. package/dist/styles/recipes/source-badge.css +1 -1
  217. package/dist/styles/recipes/spinner.css +8 -1
  218. package/dist/styles/recipes/stepper.css +31 -13
  219. package/dist/styles/recipes/switch.css +68 -23
  220. package/dist/styles/recipes/table-of-contents.css +9 -1
  221. package/dist/styles/recipes/table.css +14 -10
  222. package/dist/styles/recipes/tabs.css +17 -12
  223. package/dist/styles/recipes/task-list.css +7 -14
  224. package/dist/styles/recipes/thread-rail.css +42 -19
  225. package/dist/styles/recipes/timeline.css +2 -0
  226. package/dist/styles/recipes/toolbar.css +27 -25
  227. package/dist/styles/recipes/track-highlight.css +10 -7
  228. package/dist/styles/recipes/tree.css +31 -4
  229. package/dist/styles/recipes/user-ask-details.css +0 -1
  230. package/dist/styles/recipes/user-ask.css +4 -4
  231. package/dist/styles/theme.css +37 -16
  232. package/dist/task-list.d.ts +4 -1
  233. package/dist/task-list.js +24 -8
  234. package/dist/thread-rail.d.ts +1 -1
  235. package/dist/thread-rail.js +61 -19
  236. package/dist/transcript-divider.js +2 -1
  237. package/dist/ui/alert.d.ts +3 -1
  238. package/dist/ui/alert.js +14 -8
  239. package/dist/ui/autocomplete.js +3 -1
  240. package/dist/ui/avatar.d.ts +8 -0
  241. package/dist/ui/avatar.js +23 -3
  242. package/dist/ui/badge.js +1 -1
  243. package/dist/ui/breadcrumb.d.ts +27 -0
  244. package/dist/ui/breadcrumb.js +88 -0
  245. package/dist/ui/button.d.ts +2 -1
  246. package/dist/ui/button.js +1 -1
  247. package/dist/ui/calendar.js +2 -2
  248. package/dist/ui/card.d.ts +3 -1
  249. package/dist/ui/card.js +12 -7
  250. package/dist/ui/checkbox.d.ts +2 -0
  251. package/dist/ui/code-diff.d.ts +1 -1
  252. package/dist/ui/code-diff.js +71 -27
  253. package/dist/ui/code.d.ts +5 -3
  254. package/dist/ui/code.js +26 -27
  255. package/dist/ui/color-picker.d.ts +5 -2
  256. package/dist/ui/color-picker.js +84 -36
  257. package/dist/ui/combobox-disabled-selection.d.ts +1 -2
  258. package/dist/ui/combobox-disabled-selection.js +7 -9
  259. package/dist/ui/combobox.js +13 -5
  260. package/dist/ui/command.d.ts +8 -2
  261. package/dist/ui/command.js +30 -14
  262. package/dist/ui/context-menu.js +3 -0
  263. package/dist/ui/dialog.d.ts +2 -1
  264. package/dist/ui/dialog.js +3 -22
  265. package/dist/ui/dockable-panel-geometry.d.ts +1 -0
  266. package/dist/ui/dockable-panel-geometry.js +7 -1
  267. package/dist/ui/dockable-panel.d.ts +9 -6
  268. package/dist/ui/dockable-panel.js +63 -23
  269. package/dist/ui/dropdown-menu.js +4 -3
  270. package/dist/ui/dropzone.d.ts +2 -2
  271. package/dist/ui/dropzone.js +75 -16
  272. package/dist/ui/emoji-picker.d.ts +18 -0
  273. package/dist/ui/emoji-picker.js +136 -0
  274. package/dist/ui/empty.d.ts +3 -1
  275. package/dist/ui/empty.js +12 -7
  276. package/dist/ui/gradient-editor.d.ts +1 -1
  277. package/dist/ui/gradient-editor.js +37 -21
  278. package/dist/ui/infinite-canvas.d.ts +3 -2
  279. package/dist/ui/infinite-canvas.js +63 -19
  280. package/dist/ui/input-group.d.ts +0 -3
  281. package/dist/ui/input-group.js +3 -13
  282. package/dist/ui/input-otp.d.ts +1 -1
  283. package/dist/ui/input-otp.js +32 -15
  284. package/dist/ui/input.js +4 -4
  285. package/dist/ui/item.d.ts +2 -1
  286. package/dist/ui/item.js +11 -7
  287. package/dist/ui/live-status.d.ts +7 -0
  288. package/dist/ui/live-status.js +17 -0
  289. package/dist/ui/markdown-elements.d.ts +6 -0
  290. package/dist/ui/markdown-elements.js +31 -1
  291. package/dist/ui/menubar.js +2 -2
  292. package/dist/ui/morphing-panel.js +2 -1
  293. package/dist/ui/native-select.d.ts +1 -1
  294. package/dist/ui/native-select.js +24 -11
  295. package/dist/ui/page-layout.d.ts +2 -2
  296. package/dist/ui/page-layout.js +2 -4
  297. package/dist/ui/pagination.d.ts +7 -5
  298. package/dist/ui/pagination.js +19 -13
  299. package/dist/ui/phone-input.d.ts +1 -0
  300. package/dist/ui/phone-input.js +56 -58
  301. package/dist/ui/radio-group.d.ts +2 -0
  302. package/dist/ui/resizable.d.ts +3 -2
  303. package/dist/ui/resizable.js +5 -3
  304. package/dist/ui/responsive-dialog.d.ts +1 -1
  305. package/dist/ui/responsive-dialog.js +4 -21
  306. package/dist/ui/rich-tooltip.d.ts +10 -4
  307. package/dist/ui/rich-tooltip.js +81 -33
  308. package/dist/ui/scroll-area.d.ts +1 -1
  309. package/dist/ui/scroll-area.js +43 -28
  310. package/dist/ui/sidebar-menu.d.ts +5 -1
  311. package/dist/ui/sidebar-menu.js +34 -34
  312. package/dist/ui/sidebar-provider.d.ts +10 -1
  313. package/dist/ui/sidebar-provider.js +38 -13
  314. package/dist/ui/sidebar-resize-rail.js +7 -3
  315. package/dist/ui/sidebar.d.ts +11 -6
  316. package/dist/ui/sidebar.js +48 -24
  317. package/dist/ui/slider.js +31 -22
  318. package/dist/ui/spinner.d.ts +3 -2
  319. package/dist/ui/spinner.js +3 -2
  320. package/dist/ui/stepper.d.ts +8 -1
  321. package/dist/ui/stepper.js +74 -25
  322. package/dist/ui/switch.d.ts +1 -0
  323. package/dist/ui/table-of-contents.d.ts +2 -2
  324. package/dist/ui/table-of-contents.js +20 -8
  325. package/dist/ui/table.js +4 -2
  326. package/dist/ui/textarea.d.ts +1 -1
  327. package/dist/ui/textarea.js +20 -9
  328. package/dist/ui/timeline.d.ts +3 -1
  329. package/dist/ui/timeline.js +17 -9
  330. package/dist/ui/toast.d.ts +11 -5
  331. package/dist/ui/toast.js +100 -54
  332. package/dist/ui/toolbar.d.ts +2 -1
  333. package/dist/ui/toolbar.js +3 -1
  334. package/dist/ui/tooltip.js +3 -20
  335. package/dist/ui/tree.js +120 -80
  336. package/dist/ui/trigger-menu.js +1 -0
  337. package/dist/user-ask.d.ts +10 -5
  338. package/dist/user-ask.js +31 -11
  339. package/package.json +5 -1
  340. package/dist/hooks/use-keyboard-navigation.d.ts +0 -3
  341. package/dist/hooks/use-keyboard-navigation.js +0 -22
@@ -1,6 +1,6 @@
1
1
  "use client";
2
+ import { isComposingKey, useTriggerMenu } from "./use-trigger-menu.js";
2
3
  import { caretRectInTextarea, detectTrigger } from "../lib/trigger-detect.js";
3
- import { useTriggerMenu } from "./use-trigger-menu.js";
4
4
  import { useEffect, useEffectEvent } from "react";
5
5
  //#region src/hooks/use-textarea-trigger-menu.ts
6
6
  function replaceRange(element, start, end, text) {
@@ -36,6 +36,7 @@ function useTextareaTriggerMenu(ref, options) {
36
36
  controller.report(match, match === null ? null : caretRectInTextarea(element, match.start));
37
37
  });
38
38
  const handleKeyDown = useEffectEvent((event) => {
39
+ if (isComposingKey(event)) return;
39
40
  if (controller.open && controller.handleKeyDown(event.key)) event.preventDefault();
40
41
  });
41
42
  const closeAfterBlur = useEffectEvent(() => {
@@ -27,6 +27,16 @@ export type UseTriggerMenuOptions<Item extends TriggerMenuItemData> = {
27
27
  triggers: readonly TriggerConfig<Item>[];
28
28
  onCommit: (item: Item, trigger: TriggerConfig<Item>, match: TriggerMatch) => void;
29
29
  };
30
+ /**
31
+ * Popup attributes for the element that keeps focus (textarea or editor) while the menu is up. It stays a
32
+ * multiline textbox (a <textarea> can't take role="combobox"), so open state is conveyed by `aria-controls`.
33
+ */
34
+ export type TriggerMenuInputAria = {
35
+ "aria-autocomplete": "list";
36
+ "aria-haspopup": "listbox";
37
+ "aria-controls"?: string;
38
+ "aria-activedescendant"?: string;
39
+ };
30
40
  export type TriggerMenuController<Item extends TriggerMenuItemData> = {
31
41
  open: boolean;
32
42
  items: readonly Item[];
@@ -34,6 +44,11 @@ export type TriggerMenuController<Item extends TriggerMenuItemData> = {
34
44
  anchorRect: DOMRect | null;
35
45
  activeChar: string | null;
36
46
  query: string;
47
+ /** Id for `TriggerMenuList`; the input's `aria-controls` points at it. */
48
+ listId: string;
49
+ /** Id for the option at `index`; the input's `aria-activedescendant` points at the active one. */
50
+ optionId: (index: number) => string;
51
+ inputAria: TriggerMenuInputAria;
37
52
  /** Binding → engine: publish current trigger match (or null) and caret rect to anchor to. */
38
53
  report: (match: TriggerMatch | null, anchorRect: DOMRect | null) => void;
39
54
  /** Binding → engine: route keydown while open. Returns true when engine consumed key. */
@@ -44,5 +59,44 @@ export type TriggerMenuController<Item extends TriggerMenuItemData> = {
44
59
  close: () => void;
45
60
  setOpen: (open: boolean) => void;
46
61
  };
62
+ type DismissedMatch = {
63
+ char: string;
64
+ start: number;
65
+ query: string;
66
+ };
67
+ export type TriggerMenuState = {
68
+ open: boolean;
69
+ char: string | null;
70
+ query: string;
71
+ anchorRect: DOMRect | null;
72
+ activeIndex: number;
73
+ dismissed: DismissedMatch | null;
74
+ };
75
+ export type TriggerMenuAction = {
76
+ type: "report";
77
+ match: TriggerMatch | null;
78
+ anchorRect: DOMRect | null;
79
+ } | {
80
+ type: "close";
81
+ dismissed: DismissedMatch | null;
82
+ } | {
83
+ type: "move";
84
+ delta: number;
85
+ count: number;
86
+ } | {
87
+ type: "activate";
88
+ index: number;
89
+ };
90
+ export declare const CLOSED_TRIGGER_MENU: TriggerMenuState;
91
+ /** A dismissed token stays closed until its query changes, so keyup/click re-detection after Escape can't reopen it. */
92
+ export declare function triggerMenuReducer(state: TriggerMenuState, action: TriggerMenuAction): TriggerMenuState;
93
+ /** Keys an IME is still composing must never reach the menu or the composer's submit. */
94
+ export declare function isComposingKey(event: {
95
+ isComposing: boolean;
96
+ keyCode: number;
97
+ }): boolean;
98
+ export type TriggerMenuKeyIntent = "next" | "previous" | "commit" | "dismiss" | "pass";
99
+ /** What a key means to an open menu; an empty list passes Enter/Tab through so newline, submit and Tab-out still work. */
100
+ export declare function triggerMenuKeyIntent(key: string, open: boolean, itemCount: number): TriggerMenuKeyIntent;
47
101
  export declare function useTriggerMenu<Item extends TriggerMenuItemData>({ triggers, onCommit }: UseTriggerMenuOptions<Item>): TriggerMenuController<Item>;
48
102
  //#endregion
@@ -1,12 +1,48 @@
1
- import { useRef, useState } from "react";
1
+ import { useId, useReducer, useRef } from "react";
2
2
  //#region src/hooks/use-trigger-menu.ts
3
- const CLOSED = {
3
+ const CLOSED_TRIGGER_MENU = {
4
4
  open: false,
5
5
  char: null,
6
6
  query: "",
7
7
  anchorRect: null,
8
- activeIndex: 0
8
+ activeIndex: 0,
9
+ dismissed: null
9
10
  };
11
+ /** A dismissed token stays closed until its query changes, so keyup/click re-detection after Escape can't reopen it. */
12
+ function triggerMenuReducer(state, action) {
13
+ switch (action.type) {
14
+ case "report": {
15
+ const { match, anchorRect } = action;
16
+ if (match === null) return { ...CLOSED_TRIGGER_MENU };
17
+ const { dismissed } = state;
18
+ if (dismissed !== null && dismissed.char === match.char && dismissed.start === match.start && dismissed.query === match.query) return {
19
+ ...CLOSED_TRIGGER_MENU,
20
+ dismissed
21
+ };
22
+ const activeIndex = state.open && state.char === match.char && state.query === match.query ? state.activeIndex : 0;
23
+ return {
24
+ open: true,
25
+ char: match.char,
26
+ query: match.query,
27
+ anchorRect,
28
+ activeIndex,
29
+ dismissed: null
30
+ };
31
+ }
32
+ case "close": return {
33
+ ...CLOSED_TRIGGER_MENU,
34
+ dismissed: action.dismissed
35
+ };
36
+ case "move": return {
37
+ ...state,
38
+ activeIndex: action.count === 0 ? 0 : (state.activeIndex + action.delta + action.count) % action.count
39
+ };
40
+ case "activate": return {
41
+ ...state,
42
+ activeIndex: action.index
43
+ };
44
+ }
45
+ }
10
46
  function matchesQuery(item, query) {
11
47
  if (query === "") return true;
12
48
  const needle = query.toLowerCase();
@@ -18,14 +54,45 @@ function resolveItems(trigger, query) {
18
54
  const filter = trigger.filter ?? matchesQuery;
19
55
  return trigger.items.filter((item) => filter(item, query));
20
56
  }
57
+ /** Keys an IME is still composing must never reach the menu or the composer's submit. */
58
+ function isComposingKey(event) {
59
+ return event.isComposing || event.keyCode === 229;
60
+ }
61
+ /** What a key means to an open menu; an empty list passes Enter/Tab through so newline, submit and Tab-out still work. */
62
+ function triggerMenuKeyIntent(key, open, itemCount) {
63
+ if (!open) return "pass";
64
+ if (key === "ArrowDown") return "next";
65
+ if (key === "ArrowUp") return "previous";
66
+ if (key === "Escape") return "dismiss";
67
+ if ((key === "Enter" || key === "Tab") && itemCount > 0) return "commit";
68
+ return "pass";
69
+ }
21
70
  function useTriggerMenu({ triggers, onCommit }) {
22
- const [state, setState] = useState(CLOSED);
71
+ const [state, dispatch] = useReducer(triggerMenuReducer, CLOSED_TRIGGER_MENU);
23
72
  const lastMatch = useRef(null);
73
+ const listId = useId();
24
74
  const activeTrigger = state.char === null ? null : triggers.find((trigger) => trigger.char === state.char) ?? null;
25
75
  const items = activeTrigger === null ? [] : resolveItems(activeTrigger, state.query);
76
+ const optionId = (index) => `${listId}-option-${index}`;
77
+ const hasActiveItem = state.open && state.activeIndex < items.length;
78
+ function dismiss() {
79
+ const match = lastMatch.current;
80
+ lastMatch.current = null;
81
+ dispatch({
82
+ type: "close",
83
+ dismissed: match === null ? null : {
84
+ char: match.char,
85
+ start: match.start,
86
+ query: match.query
87
+ }
88
+ });
89
+ }
26
90
  function close() {
27
91
  lastMatch.current = null;
28
- setState(CLOSED);
92
+ dispatch({
93
+ type: "close",
94
+ dismissed: null
95
+ });
29
96
  }
30
97
  function select(item) {
31
98
  const match = lastMatch.current;
@@ -33,55 +100,35 @@ function useTriggerMenu({ triggers, onCommit }) {
33
100
  close();
34
101
  }
35
102
  function report(match, anchorRect) {
36
- lastMatch.current = match;
37
- const open = match !== null && triggers.some((trigger) => trigger.char === match.char);
38
- setState((current) => {
39
- if (!open || match === null) return CLOSED;
40
- const activeIndex = current.char === match.char && current.query === match.query ? current.activeIndex : 0;
41
- return {
42
- open: true,
43
- char: match.char,
44
- query: match.query,
45
- anchorRect,
46
- activeIndex
47
- };
103
+ const known = match !== null && triggers.some((trigger) => trigger.char === match.char);
104
+ lastMatch.current = known ? match : null;
105
+ dispatch({
106
+ type: "report",
107
+ match: known ? match : null,
108
+ anchorRect
48
109
  });
49
110
  }
50
111
  function handleKeyDown(key) {
51
- if (!state.open) return false;
52
- if (key === "ArrowDown") {
53
- setState((current) => ({
54
- ...current,
55
- activeIndex: items.length === 0 ? 0 : (current.activeIndex + 1) % items.length
56
- }));
57
- return true;
58
- }
59
- if (key === "ArrowUp") {
60
- setState((current) => ({
61
- ...current,
62
- activeIndex: items.length === 0 ? 0 : (current.activeIndex - 1 + items.length) % items.length
63
- }));
64
- return true;
65
- }
66
- if (key === "Enter" || key === "Tab") {
112
+ const intent = triggerMenuKeyIntent(key, state.open, items.length);
113
+ if (intent === "next" || intent === "previous") dispatch({
114
+ type: "move",
115
+ delta: intent === "next" ? 1 : -1,
116
+ count: items.length
117
+ });
118
+ else if (intent === "commit") {
67
119
  const item = items[state.activeIndex];
68
120
  if (item && !item.disabled) select(item);
69
- return true;
70
- }
71
- if (key === "Escape") {
72
- close();
73
- return true;
74
- }
75
- return false;
121
+ } else if (intent === "dismiss") dismiss();
122
+ return intent !== "pass";
76
123
  }
77
124
  function setOpen(open) {
78
- if (!open) close();
125
+ if (!open) dismiss();
79
126
  }
80
- function setActiveIndex(activeIndex) {
81
- setState((current) => ({
82
- ...current,
83
- activeIndex
84
- }));
127
+ function setActiveIndex(index) {
128
+ dispatch({
129
+ type: "activate",
130
+ index
131
+ });
85
132
  }
86
133
  return {
87
134
  open: state.open,
@@ -90,6 +137,14 @@ function useTriggerMenu({ triggers, onCommit }) {
90
137
  anchorRect: state.anchorRect,
91
138
  activeChar: state.char,
92
139
  query: state.query,
140
+ listId,
141
+ optionId,
142
+ inputAria: {
143
+ "aria-autocomplete": "list",
144
+ "aria-haspopup": "listbox",
145
+ "aria-controls": state.open ? listId : void 0,
146
+ "aria-activedescendant": hasActiveItem ? optionId(state.activeIndex) : void 0
147
+ },
93
148
  report,
94
149
  handleKeyDown,
95
150
  setActiveIndex,
@@ -99,4 +154,4 @@ function useTriggerMenu({ triggers, onCommit }) {
99
154
  };
100
155
  }
101
156
  //#endregion
102
- export { useTriggerMenu };
157
+ export { CLOSED_TRIGGER_MENU, isComposingKey, triggerMenuKeyIntent, triggerMenuReducer, useTriggerMenu };
@@ -6,6 +6,7 @@ export type UserAskProps = Omit<ComponentProps<"section">, "style"> & {
6
6
  children?: ReactNode;
7
7
  onComplete?: (answers: UserAskAnswers) => void;
8
8
  onDismiss?: () => void;
9
+ questionStatusLabel?: (current: number, total: number, title: string) => string;
9
10
  style?: CSSProperties & UserAskKnobStyle;
10
11
  };
11
12
  export type UserAskQuestionEntry = {
@@ -36,6 +37,7 @@ export declare function useUserAsk({ onComplete, onDismiss }: Pick<UserAskProps,
36
37
  allowsMultiple: (questionId: string) => boolean;
37
38
  selectionFor: (questionId: string) => string;
38
39
  isSelected: (questionId: string, optionKey: string) => boolean;
40
+ isTabStop: (questionId: string, optionKey: string) => boolean;
39
41
  select: (questionId: string, optionKey: string) => void;
40
42
  freeformTextFor: (questionId: string) => string;
41
43
  setFreeformText: (questionId: string, text: string) => void;
@@ -8,6 +8,12 @@ function upsert(entries, entry) {
8
8
  next[index] = entry;
9
9
  return next;
10
10
  }
11
+ const arrowDeltas = {
12
+ ArrowDown: 1,
13
+ ArrowRight: 1,
14
+ ArrowUp: -1,
15
+ ArrowLeft: -1
16
+ };
11
17
  function useUserAsk({ onComplete, onDismiss }) {
12
18
  const [questions, setQuestions] = useState([]);
13
19
  const [optionsByQuestion, setOptionsByQuestion] = useState({});
@@ -114,21 +120,11 @@ function useUserAsk({ onComplete, onDismiss }) {
114
120
  function dismiss() {
115
121
  onDismiss?.();
116
122
  }
117
- function moveSelection(delta) {
118
- if (!activeQuestion) return;
119
- const options = optionsFor(activeQuestion.id);
120
- if (!options.some((option) => !option.disabled)) return;
121
- const currentKey = selectionFor(activeQuestion.id);
122
- const currentIndex = options.findIndex((option) => option.key === currentKey);
123
- let start = currentIndex;
124
- if (currentIndex === -1) start = delta > 0 ? -1 : 0;
125
- for (let step = 1; step <= options.length; step += 1) {
126
- const candidate = options[(start + delta * step + options.length * step) % options.length];
127
- if (candidate && !candidate.disabled) {
128
- select(activeQuestion.id, candidate.key);
129
- return;
130
- }
131
- }
123
+ function isTabStop(questionId, optionKey) {
124
+ if (allowsMultiple(questionId)) return true;
125
+ const selectedKey = selectionFor(questionId);
126
+ if (selectedKey !== void 0) return selectedKey === optionKey;
127
+ return optionsFor(questionId).find((option) => !option.disabled)?.key === optionKey;
132
128
  }
133
129
  function selectDigit(digit) {
134
130
  if (!activeQuestion) return;
@@ -137,39 +133,28 @@ function useUserAsk({ onComplete, onDismiss }) {
137
133
  }
138
134
  function moveActiveOption(event, delta) {
139
135
  if (!activeQuestion) return;
140
- if (!allowsMultiple(activeQuestion.id)) {
141
- moveSelection(delta);
142
- return;
143
- }
144
136
  const rows = [...event.currentTarget.querySelector("[data-slot=\"question\"][data-active]")?.querySelectorAll("[data-slot=\"option\"]:not([disabled])") ?? []];
145
137
  if (rows.length === 0) return;
146
138
  const focused = rows.findIndex((candidate) => candidate.contains(document.activeElement));
147
139
  let start = focused;
148
140
  if (focused === -1) start = delta > 0 ? -1 : 0;
149
141
  const row = rows[(start + delta + rows.length) % rows.length];
150
- (row?.matches("button, input") ? row : row?.querySelector("input, button"))?.focus();
151
- }
152
- function handleKeyDown(event) {
153
- if (event.defaultPrevented) return;
154
- if (event.key === "Escape") {
155
- event.preventDefault();
156
- dismiss();
157
- return;
158
- }
159
- if (event.key === "Enter") {
142
+ const target = row?.matches("button, input") ? row : row?.querySelector("input, button");
143
+ target?.focus();
144
+ if (!allowsMultiple(activeQuestion.id) && target?.matches("button")) target.click();
145
+ }
146
+ function handleEnter(event) {
147
+ if (event.nativeEvent.isComposing || event.keyCode === 229) return;
148
+ if (event.target instanceof Element && event.target.closest("button:not([role=\"radio\"]):not([role=\"checkbox\"]), a[href]")) return;
149
+ event.preventDefault();
150
+ advance();
151
+ }
152
+ function handleOptionKey(event) {
153
+ if (event.target instanceof Element && event.target.closest("input, textarea, [contenteditable]")) return;
154
+ const delta = arrowDeltas[event.key];
155
+ if (delta !== void 0) {
160
156
  event.preventDefault();
161
- advance();
162
- return;
163
- }
164
- if (event.target instanceof HTMLElement && event.target.closest("input, textarea, [contenteditable]")) return;
165
- if (event.key === "ArrowDown") {
166
- event.preventDefault();
167
- moveActiveOption(event, 1);
168
- return;
169
- }
170
- if (event.key === "ArrowUp") {
171
- event.preventDefault();
172
- moveActiveOption(event, -1);
157
+ moveActiveOption(event, delta);
173
158
  return;
174
159
  }
175
160
  if (/^[1-9]$/.test(event.key)) {
@@ -177,6 +162,14 @@ function useUserAsk({ onComplete, onDismiss }) {
177
162
  selectDigit(Number(event.key));
178
163
  }
179
164
  }
165
+ function handleKeyDown(event) {
166
+ if (event.defaultPrevented) return;
167
+ if (event.key === "Escape") {
168
+ event.preventDefault();
169
+ dismiss();
170
+ } else if (event.key === "Enter") handleEnter(event);
171
+ else handleOptionKey(event);
172
+ }
180
173
  return {
181
174
  questions,
182
175
  activeIndex,
@@ -191,6 +184,7 @@ function useUserAsk({ onComplete, onDismiss }) {
191
184
  allowsMultiple,
192
185
  selectionFor,
193
186
  isSelected,
187
+ isTabStop,
194
188
  select,
195
189
  freeformTextFor,
196
190
  setFreeformText,
@@ -5,13 +5,17 @@ export type InlineAttachmentState = "ready" | "pending" | "error";
5
5
  type InlineAttachmentStyleProps<Props, Style> = Omit<Props, "style"> & {
6
6
  style?: CSSProperties & Style;
7
7
  };
8
+ type AttachmentLabel = (name: string) => string;
8
9
  export type InlineAttachmentProps = InlineAttachmentStyleProps<ComponentProps<"button">, InlineAttachmentKnobStyle> & {
9
10
  name: string;
10
11
  state?: InlineAttachmentState;
11
12
  /** Width-to-height ratio of the reserved box — generated media knows its ratio before its pixels, so arrival never reflows the turn. */
12
13
  aspect?: number;
14
+ openLabel?: AttachmentLabel;
15
+ pendingLabel?: AttachmentLabel;
16
+ errorLabel?: AttachmentLabel;
13
17
  };
14
- export declare function InlineAttachment({ name, state, aspect, disabled, className, children, style, "aria-label": ariaLabel, ...props }: InlineAttachmentProps): import("react").JSX.Element;
18
+ export declare function InlineAttachment({ name, state, aspect, disabled, openLabel, pendingLabel, errorLabel, onClick, className, children, style, "aria-label": ariaLabel, ...props }: InlineAttachmentProps): import("react").JSX.Element;
15
19
  export type InlineAttachmentMediaProps = ComponentProps<"div"> & {
16
20
  src?: string;
17
21
  alt?: string;
@@ -26,7 +30,7 @@ export type InlineAttachmentTitleProps = ComponentProps<"div"> & {
26
30
  };
27
31
  export declare function InlineAttachmentTitle({ children, className, ...props }: InlineAttachmentTitleProps): import("react").JSX.Element;
28
32
  export type InlineAttachmentDescriptionProps = InlineAttachmentStyleProps<ComponentProps<"div">, InlineAttachmentKnobStyle>;
29
- export declare function InlineAttachmentDescription({ className, ...props }: InlineAttachmentDescriptionProps): import("react").JSX.Element;
33
+ export declare function InlineAttachmentDescription({ className, children, ...props }: InlineAttachmentDescriptionProps): import("react").JSX.Element;
30
34
  export type InlineAttachmentActionsProps = ComponentProps<"div"> & {
31
35
  style?: CSSProperties & InlineAttachmentKnobStyle;
32
36
  };
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { cn } from "./lib/cn.js";
3
- import { createContext, useContext } from "react";
3
+ import { createContext, useContext, useId } from "react";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region src/inline-attachment.tsx
6
6
  const InlineAttachmentContext = createContext(null);
@@ -9,32 +9,47 @@ function useInlineAttachmentContext() {
9
9
  if (!context) throw new Error("InlineAttachment compound components must be rendered inside <InlineAttachment>.");
10
10
  return context;
11
11
  }
12
- function defaultLabel(name, state) {
13
- if (state === "pending") return `Generating ${name}`;
14
- if (state === "error") return `${name} is unavailable`;
15
- return `Open attachment: ${name}`;
16
- }
17
- function InlineAttachment({ name, state = "ready", aspect = 1.26, disabled, className, children, style, "aria-label": ariaLabel, ...props }) {
12
+ const defaultOpenLabel = (name) => `Open attachment: ${name}`;
13
+ const defaultPendingLabel = (name) => `Generating ${name}`;
14
+ const defaultErrorLabel = (name) => `${name} couldn't load. Try again.`;
15
+ function InlineAttachment({ name, state = "ready", aspect = 1.26, disabled, openLabel = defaultOpenLabel, pendingLabel = defaultPendingLabel, errorLabel = defaultErrorLabel, onClick, className, children, style, "aria-label": ariaLabel, ...props }) {
18
16
  const attachmentStyle = {
19
17
  aspectRatio: aspect,
20
18
  ...style
21
19
  };
20
+ const descriptionId = useId();
21
+ const pending = state === "pending";
22
+ const defaultLabel = {
23
+ ready: openLabel,
24
+ pending: pendingLabel,
25
+ error: errorLabel
26
+ }[state](name);
22
27
  return /* @__PURE__ */ jsx(InlineAttachmentContext.Provider, {
23
28
  value: {
24
29
  name,
25
- state
30
+ state,
31
+ descriptionId
26
32
  },
27
33
  children: /* @__PURE__ */ jsx("button", {
28
34
  type: "button",
29
- "aria-label": ariaLabel ?? defaultLabel(name, state),
30
- "aria-busy": state === "pending" || void 0,
31
- disabled: disabled || state === "pending",
35
+ "aria-label": ariaLabel ?? defaultLabel,
36
+ "aria-describedby": descriptionId,
37
+ "aria-busy": pending || void 0,
38
+ "aria-disabled": pending || void 0,
39
+ disabled,
40
+ onClick: (event) => {
41
+ if (pending) {
42
+ event.preventDefault();
43
+ return;
44
+ }
45
+ onClick?.(event);
46
+ },
32
47
  "data-control-ui": "inline-attachment",
33
48
  "data-control-family": "inline-attachment",
34
49
  "data-slot": "root",
35
50
  "data-surface": "panel",
36
51
  "data-state": state,
37
- className: cn("group relative w-full max-w-72 cursor-pointer overflow-hidden disabled:cursor-default", className),
52
+ className: cn("group relative w-full max-w-72 cursor-pointer overflow-hidden disabled:cursor-default aria-disabled:cursor-default", className),
38
53
  style: attachmentStyle,
39
54
  ...props,
40
55
  children
@@ -146,22 +161,28 @@ function InlineAttachmentContent({ className, ...props }) {
146
161
  }
147
162
  function InlineAttachmentTitle({ children, className, ...props }) {
148
163
  const { name } = useInlineAttachmentContext();
164
+ const label = children ?? name;
149
165
  return /* @__PURE__ */ jsx("div", {
150
166
  "data-control-ui": "inline-attachment",
151
167
  "data-control-family": "inline-attachment",
152
168
  "data-slot": "title",
169
+ title: typeof label === "string" ? label : void 0,
153
170
  className: cn("truncate", className),
154
171
  ...props,
155
- children: children ?? name
172
+ children: label
156
173
  });
157
174
  }
158
- function InlineAttachmentDescription({ className, ...props }) {
175
+ function InlineAttachmentDescription({ className, children, ...props }) {
176
+ const { descriptionId } = useInlineAttachmentContext();
159
177
  return /* @__PURE__ */ jsx("div", {
178
+ id: descriptionId,
160
179
  "data-control-ui": "inline-attachment",
161
180
  "data-control-family": "inline-attachment",
162
181
  "data-slot": "description",
182
+ title: typeof children === "string" ? children : void 0,
163
183
  className: cn("truncate", className),
164
- ...props
184
+ ...props,
185
+ children
165
186
  });
166
187
  }
167
188
  function InlineAttachmentActions({ className, ...props }) {
@@ -13,26 +13,33 @@ export type SourceReference = {
13
13
  type InlineCitationStyleProps<Props, Style> = Omit<Props, "style"> & {
14
14
  style?: CSSProperties & Style;
15
15
  };
16
+ export type CitationLabelTemplates = {
17
+ emptyLabel?: string;
18
+ viewSourcesLabel?: (count: number) => string;
19
+ positionLabel?: (position: number, count: number) => string;
20
+ };
21
+ export declare function citationLabel(sources: readonly SourceReference[], emptyLabel?: string): string;
16
22
  type PopoverRootProps = ComponentProps<typeof Popover>;
17
23
  export type InlineCitationProps = ComponentProps<"span"> & {
18
24
  sources: readonly SourceReference[];
19
25
  open?: PopoverRootProps["open"];
20
26
  defaultOpen?: PopoverRootProps["defaultOpen"];
21
27
  onOpenChange?: PopoverRootProps["onOpenChange"];
28
+ positionLabel?: CitationLabelTemplates["positionLabel"];
22
29
  } & {
23
30
  style?: CSSProperties & InlineCitationKnobStyle;
24
31
  };
25
- export declare function InlineCitation({ sources, open, defaultOpen, onOpenChange, className, children, ...props }: InlineCitationProps): import("react").JSX.Element;
26
- export type InlineCitationTriggerProps = InlineCitationStyleProps<ComponentProps<typeof PopoverTrigger>, InlineCitationKnobStyle>;
27
- export declare function InlineCitationTrigger({ "aria-label": ariaLabel, className, children, disabled, render, ...props }: InlineCitationTriggerProps): import("react").JSX.Element;
32
+ export declare function InlineCitation({ sources, open, defaultOpen, onOpenChange, positionLabel, className, children, ...props }: InlineCitationProps): import("react").JSX.Element;
33
+ export type InlineCitationTriggerProps = InlineCitationStyleProps<ComponentProps<typeof PopoverTrigger>, InlineCitationKnobStyle> & Pick<CitationLabelTemplates, "emptyLabel" | "viewSourcesLabel">;
34
+ export declare function InlineCitationTrigger({ "aria-label": ariaLabel, emptyLabel, viewSourcesLabel, className, children, disabled, render, ...props }: InlineCitationTriggerProps): import("react").JSX.Element;
28
35
  export type InlineCitationFaviconsProps = InlineCitationStyleProps<ComponentProps<"span">, InlineCitationKnobStyle> & {
29
36
  limit?: number;
30
37
  };
31
38
  export declare function InlineCitationFavicons({ limit, className, ...props }: InlineCitationFaviconsProps): import("react").JSX.Element;
32
- export type InlineCitationLabelProps = ComponentProps<"span"> & {
39
+ export type InlineCitationLabelProps = ComponentProps<"span"> & Pick<CitationLabelTemplates, "emptyLabel"> & {
33
40
  style?: CSSProperties & InlineCitationKnobStyle;
34
41
  };
35
- export declare function InlineCitationLabel({ className, children, ...props }: InlineCitationLabelProps): import("react").JSX.Element;
42
+ export declare function InlineCitationLabel({ emptyLabel, className, children, ...props }: InlineCitationLabelProps): import("react").JSX.Element;
36
43
  export type InlineCitationContentProps = ComponentProps<typeof PopoverContent>;
37
44
  export declare function InlineCitationContent({ className, children, align, padding, ...props }: InlineCitationContentProps): import("react").JSX.Element;
38
45
  export type InlineCitationNavigationProps = InlineCitationStyleProps<ComponentProps<"div">, InlineCitationKnobStyle>;