@inui/design-system 0.0.0-stage → 1.22.0

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 (312) hide show
  1. package/README.md +360 -2
  2. package/dist/components/ui/accordion.d.ts +44 -0
  3. package/dist/components/ui/accordion.d.ts.map +1 -0
  4. package/dist/components/ui/accordion.js +86 -0
  5. package/dist/components/ui/accordion.js.map +1 -0
  6. package/dist/components/ui/ai-avatar.d.ts +46 -0
  7. package/dist/components/ui/ai-avatar.d.ts.map +1 -0
  8. package/dist/components/ui/ai-avatar.js +43 -0
  9. package/dist/components/ui/ai-avatar.js.map +1 -0
  10. package/dist/components/ui/ai-label.d.ts +118 -0
  11. package/dist/components/ui/ai-label.d.ts.map +1 -0
  12. package/dist/components/ui/ai-label.js +184 -0
  13. package/dist/components/ui/ai-label.js.map +1 -0
  14. package/dist/components/ui/ai-sparkle.d.ts +91 -0
  15. package/dist/components/ui/ai-sparkle.d.ts.map +1 -0
  16. package/dist/components/ui/ai-sparkle.js +200 -0
  17. package/dist/components/ui/ai-sparkle.js.map +1 -0
  18. package/dist/components/ui/alert-dialog.d.ts +79 -0
  19. package/dist/components/ui/alert-dialog.d.ts.map +1 -0
  20. package/dist/components/ui/alert-dialog.js +147 -0
  21. package/dist/components/ui/alert-dialog.js.map +1 -0
  22. package/dist/components/ui/alert.d.ts +71 -0
  23. package/dist/components/ui/alert.d.ts.map +1 -0
  24. package/dist/components/ui/alert.js +108 -0
  25. package/dist/components/ui/alert.js.map +1 -0
  26. package/dist/components/ui/aspect-ratio.d.ts +30 -0
  27. package/dist/components/ui/aspect-ratio.d.ts.map +1 -0
  28. package/dist/components/ui/aspect-ratio.js +40 -0
  29. package/dist/components/ui/aspect-ratio.js.map +1 -0
  30. package/dist/components/ui/attachment.d.ts +74 -0
  31. package/dist/components/ui/attachment.d.ts.map +1 -0
  32. package/dist/components/ui/attachment.js +142 -0
  33. package/dist/components/ui/attachment.js.map +1 -0
  34. package/dist/components/ui/avatar.d.ts +82 -0
  35. package/dist/components/ui/avatar.d.ts.map +1 -0
  36. package/dist/components/ui/avatar.js +123 -0
  37. package/dist/components/ui/avatar.js.map +1 -0
  38. package/dist/components/ui/badge.d.ts +130 -0
  39. package/dist/components/ui/badge.d.ts.map +1 -0
  40. package/dist/components/ui/badge.js +226 -0
  41. package/dist/components/ui/badge.js.map +1 -0
  42. package/dist/components/ui/breadcrumb.d.ts +43 -0
  43. package/dist/components/ui/breadcrumb.d.ts.map +1 -0
  44. package/dist/components/ui/breadcrumb.js +98 -0
  45. package/dist/components/ui/breadcrumb.js.map +1 -0
  46. package/dist/components/ui/browser-tabs.d.ts +218 -0
  47. package/dist/components/ui/browser-tabs.d.ts.map +1 -0
  48. package/dist/components/ui/browser-tabs.js +528 -0
  49. package/dist/components/ui/browser-tabs.js.map +1 -0
  50. package/dist/components/ui/bubble.d.ts +80 -0
  51. package/dist/components/ui/bubble.d.ts.map +1 -0
  52. package/dist/components/ui/bubble.js +235 -0
  53. package/dist/components/ui/bubble.js.map +1 -0
  54. package/dist/components/ui/button-group.d.ts +60 -0
  55. package/dist/components/ui/button-group.d.ts.map +1 -0
  56. package/dist/components/ui/button-group.js +89 -0
  57. package/dist/components/ui/button-group.js.map +1 -0
  58. package/dist/components/ui/button.d.ts +157 -0
  59. package/dist/components/ui/button.d.ts.map +1 -0
  60. package/dist/components/ui/button.js +144 -0
  61. package/dist/components/ui/button.js.map +1 -0
  62. package/dist/components/ui/calendar.d.ts +57 -0
  63. package/dist/components/ui/calendar.d.ts.map +1 -0
  64. package/dist/components/ui/calendar.js +163 -0
  65. package/dist/components/ui/calendar.js.map +1 -0
  66. package/dist/components/ui/card.d.ts +96 -0
  67. package/dist/components/ui/card.d.ts.map +1 -0
  68. package/dist/components/ui/card.js +131 -0
  69. package/dist/components/ui/card.js.map +1 -0
  70. package/dist/components/ui/carousel.d.ts +86 -0
  71. package/dist/components/ui/carousel.d.ts.map +1 -0
  72. package/dist/components/ui/carousel.js +207 -0
  73. package/dist/components/ui/carousel.js.map +1 -0
  74. package/dist/components/ui/checkbox.d.ts +54 -0
  75. package/dist/components/ui/checkbox.d.ts.map +1 -0
  76. package/dist/components/ui/checkbox.js +78 -0
  77. package/dist/components/ui/checkbox.js.map +1 -0
  78. package/dist/components/ui/collapsible.d.ts +45 -0
  79. package/dist/components/ui/collapsible.d.ts.map +1 -0
  80. package/dist/components/ui/collapsible.js +65 -0
  81. package/dist/components/ui/collapsible.js.map +1 -0
  82. package/dist/components/ui/combobox.d.ts +111 -0
  83. package/dist/components/ui/combobox.d.ts.map +1 -0
  84. package/dist/components/ui/combobox.js +264 -0
  85. package/dist/components/ui/combobox.js.map +1 -0
  86. package/dist/components/ui/command.d.ts +71 -0
  87. package/dist/components/ui/command.d.ts.map +1 -0
  88. package/dist/components/ui/command.js +133 -0
  89. package/dist/components/ui/command.js.map +1 -0
  90. package/dist/components/ui/context-menu.d.ts +70 -0
  91. package/dist/components/ui/context-menu.d.ts.map +1 -0
  92. package/dist/components/ui/context-menu.js +163 -0
  93. package/dist/components/ui/context-menu.js.map +1 -0
  94. package/dist/components/ui/count-badge.d.ts +40 -0
  95. package/dist/components/ui/count-badge.d.ts.map +1 -0
  96. package/dist/components/ui/count-badge.js +43 -0
  97. package/dist/components/ui/count-badge.js.map +1 -0
  98. package/dist/components/ui/data-table.d.ts +1026 -0
  99. package/dist/components/ui/data-table.d.ts.map +1 -0
  100. package/dist/components/ui/data-table.js +3423 -0
  101. package/dist/components/ui/data-table.js.map +1 -0
  102. package/dist/components/ui/dialog.d.ts +73 -0
  103. package/dist/components/ui/dialog.d.ts.map +1 -0
  104. package/dist/components/ui/dialog.js +145 -0
  105. package/dist/components/ui/dialog.js.map +1 -0
  106. package/dist/components/ui/direction.d.ts +35 -0
  107. package/dist/components/ui/direction.d.ts.map +1 -0
  108. package/dist/components/ui/direction.js +35 -0
  109. package/dist/components/ui/direction.js.map +1 -0
  110. package/dist/components/ui/drawer.d.ts +53 -0
  111. package/dist/components/ui/drawer.d.ts.map +1 -0
  112. package/dist/components/ui/drawer.js +115 -0
  113. package/dist/components/ui/drawer.js.map +1 -0
  114. package/dist/components/ui/dropdown-menu.d.ts +75 -0
  115. package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
  116. package/dist/components/ui/dropdown-menu.js +173 -0
  117. package/dist/components/ui/dropdown-menu.js.map +1 -0
  118. package/dist/components/ui/dropzone.d.ts +141 -0
  119. package/dist/components/ui/dropzone.d.ts.map +1 -0
  120. package/dist/components/ui/dropzone.js +257 -0
  121. package/dist/components/ui/dropzone.js.map +1 -0
  122. package/dist/components/ui/empty.d.ts +94 -0
  123. package/dist/components/ui/empty.d.ts.map +1 -0
  124. package/dist/components/ui/empty.js +149 -0
  125. package/dist/components/ui/empty.js.map +1 -0
  126. package/dist/components/ui/field.d.ts +122 -0
  127. package/dist/components/ui/field.d.ts.map +1 -0
  128. package/dist/components/ui/field.js +254 -0
  129. package/dist/components/ui/field.js.map +1 -0
  130. package/dist/components/ui/hover-card.d.ts +51 -0
  131. package/dist/components/ui/hover-card.d.ts.map +1 -0
  132. package/dist/components/ui/hover-card.js +101 -0
  133. package/dist/components/ui/hover-card.js.map +1 -0
  134. package/dist/components/ui/input-group.d.ts +62 -0
  135. package/dist/components/ui/input-group.d.ts.map +1 -0
  136. package/dist/components/ui/input-group.js +115 -0
  137. package/dist/components/ui/input-group.js.map +1 -0
  138. package/dist/components/ui/input-otp.d.ts +52 -0
  139. package/dist/components/ui/input-otp.d.ts.map +1 -0
  140. package/dist/components/ui/input-otp.js +89 -0
  141. package/dist/components/ui/input-otp.js.map +1 -0
  142. package/dist/components/ui/input.d.ts +47 -0
  143. package/dist/components/ui/input.d.ts.map +1 -0
  144. package/dist/components/ui/input.js +47 -0
  145. package/dist/components/ui/input.js.map +1 -0
  146. package/dist/components/ui/item.d.ts +74 -0
  147. package/dist/components/ui/item.d.ts.map +1 -0
  148. package/dist/components/ui/item.js +176 -0
  149. package/dist/components/ui/item.js.map +1 -0
  150. package/dist/components/ui/kbd.d.ts +41 -0
  151. package/dist/components/ui/kbd.d.ts.map +1 -0
  152. package/dist/components/ui/kbd.js +58 -0
  153. package/dist/components/ui/kbd.js.map +1 -0
  154. package/dist/components/ui/key-value-pair.d.ts +56 -0
  155. package/dist/components/ui/key-value-pair.d.ts.map +1 -0
  156. package/dist/components/ui/key-value-pair.js +110 -0
  157. package/dist/components/ui/key-value-pair.js.map +1 -0
  158. package/dist/components/ui/label.d.ts +83 -0
  159. package/dist/components/ui/label.d.ts.map +1 -0
  160. package/dist/components/ui/label.js +85 -0
  161. package/dist/components/ui/label.js.map +1 -0
  162. package/dist/components/ui/marker.d.ts +54 -0
  163. package/dist/components/ui/marker.d.ts.map +1 -0
  164. package/dist/components/ui/marker.js +79 -0
  165. package/dist/components/ui/marker.js.map +1 -0
  166. package/dist/components/ui/menubar.d.ts +72 -0
  167. package/dist/components/ui/menubar.d.ts.map +1 -0
  168. package/dist/components/ui/menubar.js +174 -0
  169. package/dist/components/ui/menubar.js.map +1 -0
  170. package/dist/components/ui/message-scroller.d.ts +53 -0
  171. package/dist/components/ui/message-scroller.d.ts.map +1 -0
  172. package/dist/components/ui/message-scroller.js +95 -0
  173. package/dist/components/ui/message-scroller.js.map +1 -0
  174. package/dist/components/ui/message.d.ts +63 -0
  175. package/dist/components/ui/message.d.ts.map +1 -0
  176. package/dist/components/ui/message.js +92 -0
  177. package/dist/components/ui/message.js.map +1 -0
  178. package/dist/components/ui/meta-list.d.ts +55 -0
  179. package/dist/components/ui/meta-list.d.ts.map +1 -0
  180. package/dist/components/ui/meta-list.js +75 -0
  181. package/dist/components/ui/meta-list.js.map +1 -0
  182. package/dist/components/ui/native-select.d.ts +51 -0
  183. package/dist/components/ui/native-select.d.ts.map +1 -0
  184. package/dist/components/ui/native-select.js +75 -0
  185. package/dist/components/ui/native-select.js.map +1 -0
  186. package/dist/components/ui/navigation-menu.d.ts +56 -0
  187. package/dist/components/ui/navigation-menu.d.ts.map +1 -0
  188. package/dist/components/ui/navigation-menu.js +116 -0
  189. package/dist/components/ui/navigation-menu.js.map +1 -0
  190. package/dist/components/ui/page-header.d.ts +223 -0
  191. package/dist/components/ui/page-header.d.ts.map +1 -0
  192. package/dist/components/ui/page-header.js +233 -0
  193. package/dist/components/ui/page-header.js.map +1 -0
  194. package/dist/components/ui/pagination.d.ts +68 -0
  195. package/dist/components/ui/pagination.d.ts.map +1 -0
  196. package/dist/components/ui/pagination.js +145 -0
  197. package/dist/components/ui/pagination.js.map +1 -0
  198. package/dist/components/ui/popover.d.ts +61 -0
  199. package/dist/components/ui/popover.d.ts.map +1 -0
  200. package/dist/components/ui/popover.js +144 -0
  201. package/dist/components/ui/popover.js.map +1 -0
  202. package/dist/components/ui/progress.d.ts +35 -0
  203. package/dist/components/ui/progress.d.ts.map +1 -0
  204. package/dist/components/ui/progress.js +46 -0
  205. package/dist/components/ui/progress.js.map +1 -0
  206. package/dist/components/ui/questionnaire.d.ts +92 -0
  207. package/dist/components/ui/questionnaire.d.ts.map +1 -0
  208. package/dist/components/ui/questionnaire.js +277 -0
  209. package/dist/components/ui/questionnaire.js.map +1 -0
  210. package/dist/components/ui/radio-group.d.ts +50 -0
  211. package/dist/components/ui/radio-group.d.ts.map +1 -0
  212. package/dist/components/ui/radio-group.js +65 -0
  213. package/dist/components/ui/radio-group.js.map +1 -0
  214. package/dist/components/ui/resizable.d.ts +44 -0
  215. package/dist/components/ui/resizable.d.ts.map +1 -0
  216. package/dist/components/ui/resizable.js +73 -0
  217. package/dist/components/ui/resizable.js.map +1 -0
  218. package/dist/components/ui/scroll-area.d.ts +55 -0
  219. package/dist/components/ui/scroll-area.d.ts.map +1 -0
  220. package/dist/components/ui/scroll-area.js +72 -0
  221. package/dist/components/ui/scroll-area.js.map +1 -0
  222. package/dist/components/ui/select.d.ts +274 -0
  223. package/dist/components/ui/select.d.ts.map +1 -0
  224. package/dist/components/ui/select.js +609 -0
  225. package/dist/components/ui/select.js.map +1 -0
  226. package/dist/components/ui/separator.d.ts +31 -0
  227. package/dist/components/ui/separator.d.ts.map +1 -0
  228. package/dist/components/ui/separator.js +38 -0
  229. package/dist/components/ui/separator.js.map +1 -0
  230. package/dist/components/ui/sheet.d.ts +59 -0
  231. package/dist/components/ui/sheet.d.ts.map +1 -0
  232. package/dist/components/ui/sheet.js +128 -0
  233. package/dist/components/ui/sheet.js.map +1 -0
  234. package/dist/components/ui/sidebar.d.ts +166 -0
  235. package/dist/components/ui/sidebar.d.ts.map +1 -0
  236. package/dist/components/ui/sidebar.js +512 -0
  237. package/dist/components/ui/sidebar.js.map +1 -0
  238. package/dist/components/ui/skeleton.d.ts +35 -0
  239. package/dist/components/ui/skeleton.d.ts.map +1 -0
  240. package/dist/components/ui/skeleton.js +46 -0
  241. package/dist/components/ui/skeleton.js.map +1 -0
  242. package/dist/components/ui/slider.d.ts +39 -0
  243. package/dist/components/ui/slider.d.ts.map +1 -0
  244. package/dist/components/ui/slider.js +75 -0
  245. package/dist/components/ui/slider.js.map +1 -0
  246. package/dist/components/ui/sonner.d.ts +56 -0
  247. package/dist/components/ui/sonner.d.ts.map +1 -0
  248. package/dist/components/ui/sonner.js +96 -0
  249. package/dist/components/ui/sonner.js.map +1 -0
  250. package/dist/components/ui/spinner.d.ts +37 -0
  251. package/dist/components/ui/spinner.d.ts.map +1 -0
  252. package/dist/components/ui/spinner.js +51 -0
  253. package/dist/components/ui/spinner.js.map +1 -0
  254. package/dist/components/ui/stepper.d.ts +84 -0
  255. package/dist/components/ui/stepper.d.ts.map +1 -0
  256. package/dist/components/ui/stepper.js +145 -0
  257. package/dist/components/ui/stepper.js.map +1 -0
  258. package/dist/components/ui/switch.d.ts +36 -0
  259. package/dist/components/ui/switch.d.ts.map +1 -0
  260. package/dist/components/ui/switch.js +44 -0
  261. package/dist/components/ui/switch.js.map +1 -0
  262. package/dist/components/ui/table.d.ts +80 -0
  263. package/dist/components/ui/table.d.ts.map +1 -0
  264. package/dist/components/ui/table.js +130 -0
  265. package/dist/components/ui/table.js.map +1 -0
  266. package/dist/components/ui/tabs.d.ts +87 -0
  267. package/dist/components/ui/tabs.d.ts.map +1 -0
  268. package/dist/components/ui/tabs.js +128 -0
  269. package/dist/components/ui/tabs.js.map +1 -0
  270. package/dist/components/ui/textarea.d.ts +35 -0
  271. package/dist/components/ui/textarea.d.ts.map +1 -0
  272. package/dist/components/ui/textarea.js +38 -0
  273. package/dist/components/ui/textarea.js.map +1 -0
  274. package/dist/components/ui/time-picker.d.ts +58 -0
  275. package/dist/components/ui/time-picker.d.ts.map +1 -0
  276. package/dist/components/ui/time-picker.js +188 -0
  277. package/dist/components/ui/time-picker.js.map +1 -0
  278. package/dist/components/ui/toggle-group.d.ts +52 -0
  279. package/dist/components/ui/toggle-group.d.ts.map +1 -0
  280. package/dist/components/ui/toggle-group.js +94 -0
  281. package/dist/components/ui/toggle-group.js.map +1 -0
  282. package/dist/components/ui/toggle.d.ts +50 -0
  283. package/dist/components/ui/toggle.d.ts.map +1 -0
  284. package/dist/components/ui/toggle.js +70 -0
  285. package/dist/components/ui/toggle.js.map +1 -0
  286. package/dist/components/ui/tooltip.d.ts +51 -0
  287. package/dist/components/ui/tooltip.d.ts.map +1 -0
  288. package/dist/components/ui/tooltip.js +78 -0
  289. package/dist/components/ui/tooltip.js.map +1 -0
  290. package/dist/hooks/use-dark-mode.d.ts +2 -0
  291. package/dist/hooks/use-dark-mode.d.ts.map +1 -0
  292. package/dist/hooks/use-dark-mode.js +36 -0
  293. package/dist/hooks/use-dark-mode.js.map +1 -0
  294. package/dist/hooks/use-mobile.d.ts +2 -0
  295. package/dist/hooks/use-mobile.d.ts.map +1 -0
  296. package/dist/hooks/use-mobile.js +20 -0
  297. package/dist/hooks/use-mobile.js.map +1 -0
  298. package/dist/index.d.ts +88 -0
  299. package/dist/index.d.ts.map +1 -0
  300. package/dist/index.js +77 -0
  301. package/dist/lib/scope.d.ts +64 -0
  302. package/dist/lib/scope.d.ts.map +1 -0
  303. package/dist/lib/scope.js +74 -0
  304. package/dist/lib/scope.js.map +1 -0
  305. package/dist/lib/utils.d.ts +3 -0
  306. package/dist/lib/utils.d.ts.map +1 -0
  307. package/dist/lib/utils.js +11 -0
  308. package/dist/lib/utils.js.map +1 -0
  309. package/dist/styles.css +2 -0
  310. package/dist/theme-tokens.css +537 -0
  311. package/dist/theme.css +417 -0
  312. package/package.json +103 -3
@@ -0,0 +1,85 @@
1
+ import { cn } from "../../lib/utils.js";
2
+ import "react";
3
+ import { Label as Label$1 } from "radix-ui";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { cva } from "class-variance-authority";
6
+ //#region src/components/ui/label.tsx
7
+ var labelVariants = cva("flex items-center gap-2 leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:text-disabled-foreground peer-disabled:cursor-not-allowed peer-disabled:text-disabled-foreground has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:text-disabled-foreground", {
8
+ variants: { size: {
9
+ default: "text-sm",
10
+ sm: "text-xs"
11
+ } },
12
+ defaultVariants: { size: "default" }
13
+ });
14
+ function Label({ className, size = "default", required = false, optional = false, children, ...props }) {
15
+ return /* @__PURE__ */ jsxs(Label$1.Root, {
16
+ "data-slot": "label",
17
+ "data-size": size,
18
+ "data-required": required || void 0,
19
+ "data-optional": optional && !required || void 0,
20
+ className: cn(labelVariants({ size }), className),
21
+ ...props,
22
+ children: [children, required ? /* @__PURE__ */ jsx(RequiredDot, {}) : optional ? /* @__PURE__ */ jsx(OptionalHint, {}) : null]
23
+ });
24
+ }
25
+ /** The required mark — a 6px destructive dot. Decorative: the control's own `required`/`aria-required` is what assistive tech reads. */
26
+ function RequiredDot({ className }) {
27
+ return /* @__PURE__ */ jsx("span", {
28
+ "aria-hidden": "true",
29
+ "data-slot": "required-dot",
30
+ className: cn("-ml-1 inline-block size-1.5 shrink-0 self-start rounded-full bg-destructive", className)
31
+ });
32
+ }
33
+ /** The optional mark — a muted "(optional)" after the label text. */
34
+ function OptionalHint({ className }) {
35
+ return /* @__PURE__ */ jsx("span", {
36
+ "data-slot": "optional-hint",
37
+ className: cn("-ml-1 font-normal text-muted-foreground", className),
38
+ children: "(optional)"
39
+ });
40
+ }
41
+ /**
42
+ * WHEN TO USE
43
+ * - Labelling any form control (Input, Checkbox, RadioGroupItem, Switch, ...)
44
+ * - Pair via `htmlFor`/`id`, or wrap the control so the whole row becomes a click target
45
+ * (dims automatically either way when the control is disabled)
46
+ *
47
+ * NOT WHEN
48
+ * - The field also needs description or error text — use Field instead, which renders its own label internally
49
+ *
50
+ * KEY RULES
51
+ * - `select-none` — label text is not selectable, matching native label behavior
52
+ * - Dims when: its own peer control is disabled (`peer-disabled:*`, sibling usage), it wraps a disabled
53
+ * control (`has-disabled:*`, wrapping usage), or a parent group is disabled (`group-data-[disabled=true]:*`)
54
+ * - `size`: "default" (text-sm) | "sm" (text-xs) — match it to the control it
55
+ * labels, e.g. "sm" next to a `size="sm"` Select in a dense form row.
56
+ * - Three states, all marked on the Label itself (never on the control or elsewhere): plain
57
+ * `<Label>` for an ordinary field; `<Label optional>` adds a muted "(optional)" hint, for forms
58
+ * where most fields are required and the exceptions need calling out; `<Label required>` adds a
59
+ * small red dot, for a mandatory field. Pick one convention per form — mark the required ones OR
60
+ * the optional ones, not both. Both marks are decorative: the control must still carry
61
+ * `required`/`aria-required`, which is what assistive tech announces.
62
+ *
63
+ * USAGE
64
+ * <Label htmlFor="email">Email</Label>
65
+ * <Input id="email" />
66
+ *
67
+ * <Label className="flex items-center gap-2">
68
+ * <Checkbox /> Accept terms
69
+ * </Label>
70
+ *
71
+ * <Label size="sm" htmlFor="team">Team</Label>
72
+ * <Select size="sm">...</Select>
73
+ *
74
+ * // Mandatory field: red dot on the label, `required` on the control
75
+ * <Label htmlFor="email" required>Email</Label>
76
+ * <Input id="email" required />
77
+ *
78
+ * // Optional field called out explicitly
79
+ * <Label htmlFor="nickname" optional>Nickname</Label>
80
+ * <Input id="nickname" />
81
+ */
82
+ //#endregion
83
+ export { Label, OptionalHint, RequiredDot };
84
+
85
+ //# sourceMappingURL=label.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"label.js","names":[],"sources":["../../../src/components/ui/label.tsx"],"sourcesContent":["/**\n * Label — accessible form control label.\n *\n * Dims via `group-data-[disabled=true]` when a parent group (not just its\n * own peer control) is disabled, and via `has-disabled` when WRAPPING a\n * disabled control —\n * `peer-disabled` only ever matches a disabled control that's a following\n * sibling, never one nested inside the label, which is the more common of\n * the two documented usages below.\n *\n * Dims to `text-disabled-foreground`, not `opacity-50` — an opacity\n * approach blends the label's dark text down to ~3.3:1 against a\n * light background, failing WCAG 1.4.3's 4.5:1 text minimum (a disabled\n * *control* is exempt from contrast rules, but this label is a separate\n * element describing it, not the control itself, so it still needs to pass).\n * Not `text-muted-foreground` either — that step alone doesn't read as\n * clearly faded next to normal (near-black) label text; disabled-foreground\n * is a dedicated, deliberately lighter token for exactly this case (see\n * theme-tokens.css).\n */\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Label as LabelPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst labelVariants = cva(\n \"flex items-center gap-2 leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:text-disabled-foreground peer-disabled:cursor-not-allowed peer-disabled:text-disabled-foreground has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:text-disabled-foreground\",\n {\n variants: {\n size: {\n default: \"text-sm\",\n sm: \"text-xs\",\n },\n },\n defaultVariants: {\n size: \"default\",\n },\n }\n)\n\n// Three states a label can be in, and the label is the only place they're\n// marked: plain (nothing shown), optional (a muted \"(optional)\" hint), and\n// required (a 6px destructive dot). Both marks are decorative — the control\n// itself must still carry `required`/`aria-required`, which is what\n// assistive tech announces. Shared with FieldLegend via the two helpers.\nfunction Label({\n className,\n size = \"default\",\n required = false,\n optional = false,\n children,\n ...props\n}: React.ComponentProps<typeof LabelPrimitive.Root> &\n VariantProps<typeof labelVariants> & {\n /** Marks the field as mandatory with a red dot after the text. Visual only — also put `required`/`aria-required` on the control. */\n required?: boolean\n /** Shows a muted \"(optional)\" hint after the text, for forms where most fields are required and the exceptions need calling out. Mutually exclusive with `required`. */\n optional?: boolean\n }) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n data-size={size}\n data-required={required || undefined}\n data-optional={(optional && !required) || undefined}\n className={cn(labelVariants({ size }), className)}\n {...props}\n >\n {children}\n {required ? <RequiredDot /> : optional ? <OptionalHint /> : null}\n </LabelPrimitive.Root>\n )\n}\n\n/** The required mark — a 6px destructive dot. Decorative: the control's own `required`/`aria-required` is what assistive tech reads. */\nfunction RequiredDot({ className }: { className?: string }) {\n return (\n <span\n aria-hidden=\"true\"\n data-slot=\"required-dot\"\n // `self-start`: sits at the top of the label text like a superscript\n // marker, not centred on the line.\n className={cn(\n \"-ml-1 inline-block size-1.5 shrink-0 self-start rounded-full bg-destructive\",\n className\n )}\n />\n )\n}\n\n/** The optional mark — a muted \"(optional)\" after the label text. */\nfunction OptionalHint({ className }: { className?: string }) {\n return (\n <span\n data-slot=\"optional-hint\"\n className={cn(\"-ml-1 font-normal text-muted-foreground\", className)}\n >\n (optional)\n </span>\n )\n}\n\nexport { Label, RequiredDot, OptionalHint }\n\n/**\n * WHEN TO USE\n * - Labelling any form control (Input, Checkbox, RadioGroupItem, Switch, ...)\n * - Pair via `htmlFor`/`id`, or wrap the control so the whole row becomes a click target\n * (dims automatically either way when the control is disabled)\n *\n * NOT WHEN\n * - The field also needs description or error text — use Field instead, which renders its own label internally\n *\n * KEY RULES\n * - `select-none` — label text is not selectable, matching native label behavior\n * - Dims when: its own peer control is disabled (`peer-disabled:*`, sibling usage), it wraps a disabled\n * control (`has-disabled:*`, wrapping usage), or a parent group is disabled (`group-data-[disabled=true]:*`)\n * - `size`: \"default\" (text-sm) | \"sm\" (text-xs) — match it to the control it\n * labels, e.g. \"sm\" next to a `size=\"sm\"` Select in a dense form row.\n * - Three states, all marked on the Label itself (never on the control or elsewhere): plain\n * `<Label>` for an ordinary field; `<Label optional>` adds a muted \"(optional)\" hint, for forms\n * where most fields are required and the exceptions need calling out; `<Label required>` adds a\n * small red dot, for a mandatory field. Pick one convention per form — mark the required ones OR\n * the optional ones, not both. Both marks are decorative: the control must still carry\n * `required`/`aria-required`, which is what assistive tech announces.\n *\n * USAGE\n * <Label htmlFor=\"email\">Email</Label>\n * <Input id=\"email\" />\n *\n * <Label className=\"flex items-center gap-2\">\n * <Checkbox /> Accept terms\n * </Label>\n *\n * <Label size=\"sm\" htmlFor=\"team\">Team</Label>\n * <Select size=\"sm\">...</Select>\n *\n * // Mandatory field: red dot on the label, `required` on the control\n * <Label htmlFor=\"email\" required>Email</Label>\n * <Input id=\"email\" required />\n *\n * // Optional field called out explicitly\n * <Label htmlFor=\"nickname\" optional>Nickname</Label>\n * <Input id=\"nickname\" />\n */\n"],"mappings":";;;;;;AA2BA,IAAM,gBAAgB,IACpB,kVACA;CACE,UAAU,EACR,MAAM;EACJ,SAAS;EACT,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,UACR;AACF,CACF;AAOA,SAAS,MAAM,EACb,WACA,OAAO,WACP,WAAW,OACX,WAAW,OACX,UACA,GAAG,SAOA;CACH,OACE,qBAAC,QAAe,MAAhB;EACE,aAAU;EACV,aAAW;EACX,iBAAe,YAAY,KAAA;EAC3B,iBAAgB,YAAY,CAAC,YAAa,KAAA;EAC1C,WAAW,GAAG,cAAc,EAAE,KAAK,CAAC,GAAG,SAAS;EAChD,GAAI;EANN,UAAA,CAQG,UACA,WAAW,oBAAC,aAAD,CAAc,CAAA,IAAI,WAAW,oBAAC,cAAD,CAAe,CAAA,IAAI,IACzC;;AAEzB;;AAGA,SAAS,YAAY,EAAE,aAAqC;CAC1D,OACE,oBAAC,QAAD;EACE,eAAY;EACZ,aAAU;EAGV,WAAW,GACT,+EACA,SACF;CACD,CAAA;AAEL;;AAGA,SAAS,aAAa,EAAE,aAAqC;CAC3D,OACE,oBAAC,QAAD;EACE,aAAU;EACV,WAAW,GAAG,2CAA2C,SAAS;EACnE,UAAA;CAEK,CAAA;AAEV"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Marker — small annotation with an optional leading icon.
3
+ *
4
+ * cva-driven `div` (or `Slot` via `asChild`), no external primitive.
5
+ */
6
+ import * as React from "react";
7
+ import { type VariantProps } from "class-variance-authority";
8
+ declare const markerVariants: (props?: ({
9
+ variant?: "separator" | "default" | "border" | null | undefined;
10
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
11
+ declare function Marker({ className, variant, asChild, ...props }: React.ComponentProps<"div"> & VariantProps<typeof markerVariants> & {
12
+ asChild?: boolean;
13
+ }): React.JSX.Element;
14
+ declare function MarkerIcon({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
15
+ declare function MarkerContent({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
16
+ export { Marker, MarkerIcon, MarkerContent, markerVariants };
17
+ /**
18
+ * WHEN TO USE
19
+ * - Timeline entries, activity-log rows, or an inline annotation between
20
+ * blocks of content — e.g. "Deployed 2 minutes ago", "Build started".
21
+ * - `MarkerIcon` for a small leading glyph (e.g. a status dot) before the
22
+ * text — it's `aria-hidden`, so pair it with real text in
23
+ * `MarkerContent`, not an icon alone.
24
+ *
25
+ * NOT WHEN
26
+ * - A categorical tag, or an operational-status label — use Badge (with a
27
+ * colored icon for status; see Badge's docs for the convention).
28
+ * - A section heading.
29
+ * - A list row with media and actions — use Item.
30
+ *
31
+ * KEY RULES
32
+ * - Three variants: `default` (plain), `separator` (draws a horizontal
33
+ * rule on both sides of the content — a standalone divider-style
34
+ * annotation), `border` (a bottom border under the whole marker — for
35
+ * stacking timeline entries). Omit `variant` for `default`.
36
+ * - `asChild` renders Marker as its child (e.g. an `<a>`) instead of a
37
+ * `div`.
38
+ * - Links inside MarkerContent get underlined automatically.
39
+ *
40
+ * USAGE
41
+ * <Marker>
42
+ * <MarkerContent>Deployed 2 minutes ago</MarkerContent>
43
+ * </Marker>
44
+ *
45
+ * <Marker>
46
+ * <MarkerIcon><CircleDotIcon /></MarkerIcon>
47
+ * <MarkerContent>Build started</MarkerContent>
48
+ * </Marker>
49
+ *
50
+ * <Marker variant="separator">
51
+ * <MarkerContent>Today</MarkerContent>
52
+ * </Marker>
53
+ */
54
+ //# sourceMappingURL=marker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marker.d.ts","sourceRoot":"","sources":["../../../src/components/ui/marker.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAKjE,QAAA,MAAM,cAAc;;8EAYnB,CAAA;AAED,iBAAS,MAAM,CAAC,EACd,SAAS,EACT,OAAmB,EACnB,OAAe,EACf,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAC5B,YAAY,CAAC,OAAO,cAAc,CAAC,GAAG;IACpC,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,qBAWF;AAED,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,qBAYxE;AAED,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,qBAW3E;AAED,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,CAAA;AAE5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG"}
@@ -0,0 +1,79 @@
1
+ import { cn } from "../../lib/utils.js";
2
+ import "react";
3
+ import { Slot } from "radix-ui";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { cva } from "class-variance-authority";
6
+ //#region src/components/ui/marker.tsx
7
+ var markerVariants = cva("group/marker relative flex min-h-4 w-full items-center gap-2 text-left text-sm text-muted-foreground [&_svg:not([class*='size-'])]:size-4 [a]:underline [a]:underline-offset-3 [a]:hover:text-foreground", { variants: { variant: {
8
+ default: "",
9
+ separator: "before:mr-1 before:h-px before:min-w-0 before:flex-1 before:bg-border after:ml-1 after:h-px after:min-w-0 after:flex-1 after:bg-border",
10
+ border: "border-b border-border pb-2"
11
+ } } });
12
+ function Marker({ className, variant = "default", asChild = false, ...props }) {
13
+ const Comp = asChild ? Slot.Root : "div";
14
+ return /* @__PURE__ */ jsx(Comp, {
15
+ "data-slot": "marker",
16
+ "data-variant": variant,
17
+ className: cn(markerVariants({
18
+ variant,
19
+ className
20
+ })),
21
+ ...props
22
+ });
23
+ }
24
+ function MarkerIcon({ className, ...props }) {
25
+ return /* @__PURE__ */ jsx("span", {
26
+ "data-slot": "marker-icon",
27
+ "aria-hidden": "true",
28
+ className: cn("size-4 shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
29
+ ...props
30
+ });
31
+ }
32
+ function MarkerContent({ className, ...props }) {
33
+ return /* @__PURE__ */ jsx("span", {
34
+ "data-slot": "marker-content",
35
+ className: cn("min-w-0 wrap-break-word group-data-[variant=separator]/marker:flex-none group-data-[variant=separator]/marker:text-center *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground", className),
36
+ ...props
37
+ });
38
+ }
39
+ /**
40
+ * WHEN TO USE
41
+ * - Timeline entries, activity-log rows, or an inline annotation between
42
+ * blocks of content — e.g. "Deployed 2 minutes ago", "Build started".
43
+ * - `MarkerIcon` for a small leading glyph (e.g. a status dot) before the
44
+ * text — it's `aria-hidden`, so pair it with real text in
45
+ * `MarkerContent`, not an icon alone.
46
+ *
47
+ * NOT WHEN
48
+ * - A categorical tag, or an operational-status label — use Badge (with a
49
+ * colored icon for status; see Badge's docs for the convention).
50
+ * - A section heading.
51
+ * - A list row with media and actions — use Item.
52
+ *
53
+ * KEY RULES
54
+ * - Three variants: `default` (plain), `separator` (draws a horizontal
55
+ * rule on both sides of the content — a standalone divider-style
56
+ * annotation), `border` (a bottom border under the whole marker — for
57
+ * stacking timeline entries). Omit `variant` for `default`.
58
+ * - `asChild` renders Marker as its child (e.g. an `<a>`) instead of a
59
+ * `div`.
60
+ * - Links inside MarkerContent get underlined automatically.
61
+ *
62
+ * USAGE
63
+ * <Marker>
64
+ * <MarkerContent>Deployed 2 minutes ago</MarkerContent>
65
+ * </Marker>
66
+ *
67
+ * <Marker>
68
+ * <MarkerIcon><CircleDotIcon /></MarkerIcon>
69
+ * <MarkerContent>Build started</MarkerContent>
70
+ * </Marker>
71
+ *
72
+ * <Marker variant="separator">
73
+ * <MarkerContent>Today</MarkerContent>
74
+ * </Marker>
75
+ */
76
+ //#endregion
77
+ export { Marker, MarkerContent, MarkerIcon, markerVariants };
78
+
79
+ //# sourceMappingURL=marker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marker.js","names":[],"sources":["../../../src/components/ui/marker.tsx"],"sourcesContent":["/**\n * Marker — small annotation with an optional leading icon.\n *\n * cva-driven `div` (or `Slot` via `asChild`), no external primitive.\n */\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst markerVariants = cva(\n \"group/marker relative flex min-h-4 w-full items-center gap-2 text-left text-sm text-muted-foreground [&_svg:not([class*='size-'])]:size-4 [a]:underline [a]:underline-offset-3 [a]:hover:text-foreground\",\n {\n variants: {\n variant: {\n default: \"\",\n separator:\n \"before:mr-1 before:h-px before:min-w-0 before:flex-1 before:bg-border after:ml-1 after:h-px after:min-w-0 after:flex-1 after:bg-border\",\n border: \"border-b border-border pb-2\",\n },\n },\n }\n)\n\nfunction Marker({\n className,\n variant = \"default\",\n asChild = false,\n ...props\n}: React.ComponentProps<\"div\"> &\n VariantProps<typeof markerVariants> & {\n asChild?: boolean\n }) {\n const Comp = asChild ? Slot.Root : \"div\"\n\n return (\n <Comp\n data-slot=\"marker\"\n data-variant={variant}\n className={cn(markerVariants({ variant, className }))}\n {...props}\n />\n )\n}\n\nfunction MarkerIcon({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"marker-icon\"\n aria-hidden=\"true\"\n className={cn(\n \"size-4 shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction MarkerContent({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"marker-content\"\n className={cn(\n \"min-w-0 wrap-break-word group-data-[variant=separator]/marker:flex-none group-data-[variant=separator]/marker:text-center *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Marker, MarkerIcon, MarkerContent, markerVariants }\n\n/**\n * WHEN TO USE\n * - Timeline entries, activity-log rows, or an inline annotation between\n * blocks of content — e.g. \"Deployed 2 minutes ago\", \"Build started\".\n * - `MarkerIcon` for a small leading glyph (e.g. a status dot) before the\n * text — it's `aria-hidden`, so pair it with real text in\n * `MarkerContent`, not an icon alone.\n *\n * NOT WHEN\n * - A categorical tag, or an operational-status label — use Badge (with a\n * colored icon for status; see Badge's docs for the convention).\n * - A section heading.\n * - A list row with media and actions — use Item.\n *\n * KEY RULES\n * - Three variants: `default` (plain), `separator` (draws a horizontal\n * rule on both sides of the content — a standalone divider-style\n * annotation), `border` (a bottom border under the whole marker — for\n * stacking timeline entries). Omit `variant` for `default`.\n * - `asChild` renders Marker as its child (e.g. an `<a>`) instead of a\n * `div`.\n * - Links inside MarkerContent get underlined automatically.\n *\n * USAGE\n * <Marker>\n * <MarkerContent>Deployed 2 minutes ago</MarkerContent>\n * </Marker>\n *\n * <Marker>\n * <MarkerIcon><CircleDotIcon /></MarkerIcon>\n * <MarkerContent>Build started</MarkerContent>\n * </Marker>\n *\n * <Marker variant=\"separator\">\n * <MarkerContent>Today</MarkerContent>\n * </Marker>\n */\n"],"mappings":";;;;;;AAYA,IAAM,iBAAiB,IACrB,4MACA,EACE,UAAU,EACR,SAAS;CACP,SAAS;CACT,WACE;CACF,QAAQ;AACV,EACF,EACF,CACF;AAEA,SAAS,OAAO,EACd,WACA,UAAU,WACV,UAAU,OACV,GAAG,SAIA;CACH,MAAM,OAAO,UAAU,KAAK,OAAO;CAEnC,OACE,oBAAC,MAAD;EACE,aAAU;EACV,gBAAc;EACd,WAAW,GAAG,eAAe;GAAE;GAAS;EAAU,CAAC,CAAC;EACpD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAuC;CACzE,OACE,oBAAC,QAAD;EACE,aAAU;EACV,eAAY;EACZ,WAAW,GACT,wDACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,cAAc,EAAE,WAAW,GAAG,SAAuC;CAC5E,OACE,oBAAC,QAAD;EACE,aAAU;EACV,WAAW,GACT,kMACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Menubar — persistent desktop-style app menu bar (File / Edit / View).
3
+ *
4
+ * Built on the Radix Menubar primitive: supports submenus, checkbox items,
5
+ * radio groups, and shortcut hints.
6
+ */
7
+ import * as React from "react";
8
+ import { Menubar as MenubarPrimitive } from "radix-ui";
9
+ declare function Menubar({ className, ...props }: React.ComponentProps<typeof MenubarPrimitive.Root>): React.JSX.Element;
10
+ declare function MenubarMenu({ ...props }: React.ComponentProps<typeof MenubarPrimitive.Menu>): React.JSX.Element;
11
+ declare function MenubarGroup({ ...props }: React.ComponentProps<typeof MenubarPrimitive.Group>): React.JSX.Element;
12
+ declare function MenubarPortal({ ...props }: React.ComponentProps<typeof MenubarPrimitive.Portal>): React.JSX.Element;
13
+ declare function MenubarRadioGroup({ ...props }: React.ComponentProps<typeof MenubarPrimitive.RadioGroup>): React.JSX.Element;
14
+ declare function MenubarTrigger({ className, ...props }: React.ComponentProps<typeof MenubarPrimitive.Trigger>): React.JSX.Element;
15
+ declare function MenubarContent({ className, align, alignOffset, sideOffset, ...props }: React.ComponentProps<typeof MenubarPrimitive.Content>): React.JSX.Element;
16
+ declare function MenubarItem({ className, inset, variant, ...props }: React.ComponentProps<typeof MenubarPrimitive.Item> & {
17
+ inset?: boolean;
18
+ variant?: "default" | "destructive";
19
+ }): React.JSX.Element;
20
+ declare function MenubarCheckboxItem({ className, children, checked, inset, ...props }: React.ComponentProps<typeof MenubarPrimitive.CheckboxItem> & {
21
+ inset?: boolean;
22
+ }): React.JSX.Element;
23
+ declare function MenubarRadioItem({ className, children, inset, ...props }: React.ComponentProps<typeof MenubarPrimitive.RadioItem> & {
24
+ inset?: boolean;
25
+ }): React.JSX.Element;
26
+ declare function MenubarLabel({ className, inset, ...props }: React.ComponentProps<typeof MenubarPrimitive.Label> & {
27
+ inset?: boolean;
28
+ }): React.JSX.Element;
29
+ declare function MenubarSeparator({ className, ...props }: React.ComponentProps<typeof MenubarPrimitive.Separator>): React.JSX.Element;
30
+ declare function MenubarShortcut({ className, ...props }: React.ComponentProps<"span">): React.JSX.Element;
31
+ declare function MenubarSub({ ...props }: React.ComponentProps<typeof MenubarPrimitive.Sub>): React.JSX.Element;
32
+ declare function MenubarSubTrigger({ className, inset, children, ...props }: React.ComponentProps<typeof MenubarPrimitive.SubTrigger> & {
33
+ inset?: boolean;
34
+ }): React.JSX.Element;
35
+ declare function MenubarSubContent({ className, ...props }: React.ComponentProps<typeof MenubarPrimitive.SubContent>): React.JSX.Element;
36
+ export { Menubar, MenubarPortal, MenubarMenu, MenubarTrigger, MenubarContent, MenubarGroup, MenubarSeparator, MenubarLabel, MenubarItem, MenubarShortcut, MenubarCheckboxItem, MenubarRadioGroup, MenubarRadioItem, MenubarSub, MenubarSubTrigger, MenubarSubContent, };
37
+ /**
38
+ * WHEN TO USE
39
+ * - Desktop-style app chrome with several always-visible menus that share
40
+ * hover-to-open behavior (opening one, then hovering the next, switches
41
+ * without a click)
42
+ *
43
+ * NOT WHEN
44
+ * - A single action menu on one trigger — use DropdownMenu
45
+ * - A right-click context menu — use ContextMenu
46
+ * - Site/section navigation — use NavigationMenu
47
+ *
48
+ * KEY RULES
49
+ * - MenubarItem variant="destructive" tints text/focus red for delete-style actions
50
+ * - MenubarCheckboxItem and MenubarRadioItem behave like their DropdownMenu
51
+ * counterparts — checked state is controlled by the caller
52
+ * - MenubarShortcut is a plain right-aligned hint, not a working keybinding —
53
+ * wire the actual shortcut yourself
54
+ *
55
+ * USAGE
56
+ * <Menubar>
57
+ * <MenubarMenu>
58
+ * <MenubarTrigger>File</MenubarTrigger>
59
+ * <MenubarContent>
60
+ * <MenubarItem>New tab <MenubarShortcut>⌘T</MenubarShortcut></MenubarItem>
61
+ * <MenubarSeparator />
62
+ * <MenubarSub>
63
+ * <MenubarSubTrigger>Share</MenubarSubTrigger>
64
+ * <MenubarSubContent>
65
+ * <MenubarItem>Copy link</MenubarItem>
66
+ * </MenubarSubContent>
67
+ * </MenubarSub>
68
+ * </MenubarContent>
69
+ * </MenubarMenu>
70
+ * </Menubar>
71
+ */
72
+ //# sourceMappingURL=menubar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menubar.d.ts","sourceRoot":"","sources":["../../../src/components/ui/menubar.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,174 @@
1
+ "use client";
2
+ import { cn } from "../../lib/utils.js";
3
+ import { getPortalContainer } from "../../lib/scope.js";
4
+ import "react";
5
+ import { Menubar as Menubar$1 } from "radix-ui";
6
+ import { CheckIcon, ChevronRightIcon } from "lucide-react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ //#region src/components/ui/menubar.tsx
9
+ function Menubar({ className, ...props }) {
10
+ return /* @__PURE__ */ jsx(Menubar$1.Root, {
11
+ "data-slot": "menubar",
12
+ className: cn("flex h-8 items-center gap-0.5 rounded-lg border p-[3px]", className),
13
+ ...props
14
+ });
15
+ }
16
+ function MenubarMenu({ ...props }) {
17
+ return /* @__PURE__ */ jsx(Menubar$1.Menu, {
18
+ "data-slot": "menubar-menu",
19
+ ...props
20
+ });
21
+ }
22
+ function MenubarGroup({ ...props }) {
23
+ return /* @__PURE__ */ jsx(Menubar$1.Group, {
24
+ "data-slot": "menubar-group",
25
+ ...props
26
+ });
27
+ }
28
+ function MenubarPortal({ ...props }) {
29
+ return /* @__PURE__ */ jsx(Menubar$1.Portal, {
30
+ "data-slot": "menubar-portal",
31
+ container: getPortalContainer(),
32
+ ...props
33
+ });
34
+ }
35
+ function MenubarRadioGroup({ ...props }) {
36
+ return /* @__PURE__ */ jsx(Menubar$1.RadioGroup, {
37
+ "data-slot": "menubar-radio-group",
38
+ ...props
39
+ });
40
+ }
41
+ function MenubarTrigger({ className, ...props }) {
42
+ return /* @__PURE__ */ jsx(Menubar$1.Trigger, {
43
+ "data-slot": "menubar-trigger",
44
+ className: cn("flex items-center rounded-sm px-1.5 py-[2px] text-sm font-medium outline-hidden select-none hover:bg-muted focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:outline-1 aria-expanded:bg-muted", className),
45
+ ...props
46
+ });
47
+ }
48
+ function MenubarContent({ className, align = "start", alignOffset = -4, sideOffset = 8, ...props }) {
49
+ return /* @__PURE__ */ jsx(MenubarPortal, { children: /* @__PURE__ */ jsx(Menubar$1.Content, {
50
+ "data-slot": "menubar-content",
51
+ align,
52
+ alignOffset,
53
+ sideOffset,
54
+ className: cn("z-50 min-w-36 origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-lg bg-popover p-1 text-popover-foreground shadow-popover ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95", className),
55
+ ...props
56
+ }) });
57
+ }
58
+ function MenubarItem({ className, inset, variant = "default", ...props }) {
59
+ return /* @__PURE__ */ jsx(Menubar$1.Item, {
60
+ "data-slot": "menubar-item",
61
+ "data-inset": inset,
62
+ "data-variant": variant,
63
+ className: cn("group/menubar-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive!", className),
64
+ ...props
65
+ });
66
+ }
67
+ function MenubarCheckboxItem({ className, children, checked, inset, ...props }) {
68
+ return /* @__PURE__ */ jsxs(Menubar$1.CheckboxItem, {
69
+ "data-slot": "menubar-checkbox-item",
70
+ "data-inset": inset,
71
+ className: cn("relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-1.5 pl-7 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0", className),
72
+ checked,
73
+ ...props,
74
+ children: [/* @__PURE__ */ jsx("span", {
75
+ className: "pointer-events-none absolute left-1.5 flex size-4 items-center justify-center [&_svg:not([class*='size-'])]:size-4",
76
+ children: /* @__PURE__ */ jsx(Menubar$1.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, {}) })
77
+ }), children]
78
+ });
79
+ }
80
+ function MenubarRadioItem({ className, children, inset, ...props }) {
81
+ return /* @__PURE__ */ jsxs(Menubar$1.RadioItem, {
82
+ "data-slot": "menubar-radio-item",
83
+ "data-inset": inset,
84
+ className: cn("relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-1.5 pl-7 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
85
+ ...props,
86
+ children: [/* @__PURE__ */ jsx("span", {
87
+ className: "pointer-events-none absolute left-1.5 flex size-4 items-center justify-center [&_svg:not([class*='size-'])]:size-4",
88
+ children: /* @__PURE__ */ jsx(Menubar$1.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, {}) })
89
+ }), children]
90
+ });
91
+ }
92
+ function MenubarLabel({ className, inset, ...props }) {
93
+ return /* @__PURE__ */ jsx(Menubar$1.Label, {
94
+ "data-slot": "menubar-label",
95
+ "data-inset": inset,
96
+ className: cn("px-1.5 py-1 text-sm font-medium data-inset:pl-7", className),
97
+ ...props
98
+ });
99
+ }
100
+ function MenubarSeparator({ className, ...props }) {
101
+ return /* @__PURE__ */ jsx(Menubar$1.Separator, {
102
+ "data-slot": "menubar-separator",
103
+ className: cn("-mx-1 my-1 h-px bg-border", className),
104
+ ...props
105
+ });
106
+ }
107
+ function MenubarShortcut({ className, ...props }) {
108
+ return /* @__PURE__ */ jsx("span", {
109
+ "data-slot": "menubar-shortcut",
110
+ className: cn("ml-auto text-xs tracking-widest text-muted-foreground group-focus/menubar-item:text-accent-foreground", className),
111
+ ...props
112
+ });
113
+ }
114
+ function MenubarSub({ ...props }) {
115
+ return /* @__PURE__ */ jsx(Menubar$1.Sub, {
116
+ "data-slot": "menubar-sub",
117
+ ...props
118
+ });
119
+ }
120
+ function MenubarSubTrigger({ className, inset, children, ...props }) {
121
+ return /* @__PURE__ */ jsxs(Menubar$1.SubTrigger, {
122
+ "data-slot": "menubar-sub-trigger",
123
+ "data-inset": inset,
124
+ className: cn("flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-none select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-7 data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='size-'])]:size-4", className),
125
+ ...props,
126
+ children: [children, /* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-auto size-4" })]
127
+ });
128
+ }
129
+ function MenubarSubContent({ className, ...props }) {
130
+ return /* @__PURE__ */ jsx(Menubar$1.SubContent, {
131
+ "data-slot": "menubar-sub-content",
132
+ className: cn("z-50 min-w-32 origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-lg bg-popover p-1 text-popover-foreground shadow-popover ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95", className),
133
+ ...props
134
+ });
135
+ }
136
+ /**
137
+ * WHEN TO USE
138
+ * - Desktop-style app chrome with several always-visible menus that share
139
+ * hover-to-open behavior (opening one, then hovering the next, switches
140
+ * without a click)
141
+ *
142
+ * NOT WHEN
143
+ * - A single action menu on one trigger — use DropdownMenu
144
+ * - A right-click context menu — use ContextMenu
145
+ * - Site/section navigation — use NavigationMenu
146
+ *
147
+ * KEY RULES
148
+ * - MenubarItem variant="destructive" tints text/focus red for delete-style actions
149
+ * - MenubarCheckboxItem and MenubarRadioItem behave like their DropdownMenu
150
+ * counterparts — checked state is controlled by the caller
151
+ * - MenubarShortcut is a plain right-aligned hint, not a working keybinding —
152
+ * wire the actual shortcut yourself
153
+ *
154
+ * USAGE
155
+ * <Menubar>
156
+ * <MenubarMenu>
157
+ * <MenubarTrigger>File</MenubarTrigger>
158
+ * <MenubarContent>
159
+ * <MenubarItem>New tab <MenubarShortcut>⌘T</MenubarShortcut></MenubarItem>
160
+ * <MenubarSeparator />
161
+ * <MenubarSub>
162
+ * <MenubarSubTrigger>Share</MenubarSubTrigger>
163
+ * <MenubarSubContent>
164
+ * <MenubarItem>Copy link</MenubarItem>
165
+ * </MenubarSubContent>
166
+ * </MenubarSub>
167
+ * </MenubarContent>
168
+ * </MenubarMenu>
169
+ * </Menubar>
170
+ */
171
+ //#endregion
172
+ export { Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger };
173
+
174
+ //# sourceMappingURL=menubar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menubar.js","names":[],"sources":["../../../src/components/ui/menubar.tsx"],"sourcesContent":["\"use client\"\n\n/**\n * Menubar — persistent desktop-style app menu bar (File / Edit / View).\n *\n * Built on the Radix Menubar primitive: supports submenus, checkbox items,\n * radio groups, and shortcut hints.\n */\n\nimport * as React from \"react\"\nimport { Menubar as MenubarPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/lib/utils\"\nimport { getPortalContainer } from \"@/lib/scope\"\nimport { CheckIcon, ChevronRightIcon } from \"lucide-react\"\n\nfunction Menubar({\n className,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Root>) {\n return (\n <MenubarPrimitive.Root\n data-slot=\"menubar\"\n className={cn(\n \"flex h-8 items-center gap-0.5 rounded-lg border p-[3px]\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction MenubarMenu({\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Menu>) {\n return <MenubarPrimitive.Menu data-slot=\"menubar-menu\" {...props} />\n}\n\nfunction MenubarGroup({\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Group>) {\n return <MenubarPrimitive.Group data-slot=\"menubar-group\" {...props} />\n}\n\nfunction MenubarPortal({\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Portal>) {\n return (\n <MenubarPrimitive.Portal\n data-slot=\"menubar-portal\"\n container={getPortalContainer()}\n {...props}\n />\n )\n}\n\nfunction MenubarRadioGroup({\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.RadioGroup>) {\n return (\n <MenubarPrimitive.RadioGroup data-slot=\"menubar-radio-group\" {...props} />\n )\n}\n\nfunction MenubarTrigger({\n className,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Trigger>) {\n return (\n <MenubarPrimitive.Trigger\n data-slot=\"menubar-trigger\"\n className={cn(\n \"flex items-center rounded-sm px-1.5 py-[2px] text-sm font-medium outline-hidden select-none hover:bg-muted focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:outline-1 aria-expanded:bg-muted\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction MenubarContent({\n className,\n align = \"start\",\n alignOffset = -4,\n sideOffset = 8,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Content>) {\n return (\n <MenubarPortal>\n <MenubarPrimitive.Content\n data-slot=\"menubar-content\"\n align={align}\n alignOffset={alignOffset}\n sideOffset={sideOffset}\n className={cn(\n // Exit triplet added alongside the entrance fix below — every\n // sibling menu (DropdownMenu/ContextMenu SubContent) animates both\n // ways; this one only ever had the entrance rule, dead or not.\n \"z-50 min-w-36 origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-lg bg-popover p-1 text-popover-foreground shadow-popover ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95\",\n className\n )}\n {...props}\n />\n </MenubarPortal>\n )\n}\n\nfunction MenubarItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Item> & {\n inset?: boolean\n variant?: \"default\" | \"destructive\"\n}) {\n return (\n <MenubarPrimitive.Item\n data-slot=\"menubar-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"group/menubar-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive!\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction MenubarCheckboxItem({\n className,\n children,\n checked,\n inset,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.CheckboxItem> & {\n inset?: boolean\n}) {\n return (\n <MenubarPrimitive.CheckboxItem\n data-slot=\"menubar-checkbox-item\"\n data-inset={inset}\n className={cn(\n \"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-1.5 pl-7 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-1.5 flex size-4 items-center justify-center [&_svg:not([class*='size-'])]:size-4\">\n <MenubarPrimitive.ItemIndicator>\n <CheckIcon />\n </MenubarPrimitive.ItemIndicator>\n </span>\n {children}\n </MenubarPrimitive.CheckboxItem>\n )\n}\n\nfunction MenubarRadioItem({\n className,\n children,\n inset,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.RadioItem> & {\n inset?: boolean\n}) {\n return (\n <MenubarPrimitive.RadioItem\n data-slot=\"menubar-radio-item\"\n data-inset={inset}\n className={cn(\n \"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-1.5 pl-7 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-1.5 flex size-4 items-center justify-center [&_svg:not([class*='size-'])]:size-4\">\n <MenubarPrimitive.ItemIndicator>\n <CheckIcon />\n </MenubarPrimitive.ItemIndicator>\n </span>\n {children}\n </MenubarPrimitive.RadioItem>\n )\n}\n\nfunction MenubarLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Label> & {\n inset?: boolean\n}) {\n return (\n <MenubarPrimitive.Label\n data-slot=\"menubar-label\"\n data-inset={inset}\n className={cn(\n \"px-1.5 py-1 text-sm font-medium data-inset:pl-7\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction MenubarSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Separator>) {\n return (\n <MenubarPrimitive.Separator\n data-slot=\"menubar-separator\"\n className={cn(\"-mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n )\n}\n\nfunction MenubarShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"menubar-shortcut\"\n className={cn(\n \"ml-auto text-xs tracking-widest text-muted-foreground group-focus/menubar-item:text-accent-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction MenubarSub({\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Sub>) {\n return <MenubarPrimitive.Sub data-slot=\"menubar-sub\" {...props} />\n}\n\nfunction MenubarSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.SubTrigger> & {\n inset?: boolean\n}) {\n return (\n <MenubarPrimitive.SubTrigger\n data-slot=\"menubar-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-none select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-7 data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto size-4\" />\n </MenubarPrimitive.SubTrigger>\n )\n}\n\nfunction MenubarSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof MenubarPrimitive.SubContent>) {\n return (\n <MenubarPrimitive.SubContent\n data-slot=\"menubar-sub-content\"\n className={cn(\n \"z-50 min-w-32 origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-lg bg-popover p-1 text-popover-foreground shadow-popover ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Menubar,\n MenubarPortal,\n MenubarMenu,\n MenubarTrigger,\n MenubarContent,\n MenubarGroup,\n MenubarSeparator,\n MenubarLabel,\n MenubarItem,\n MenubarShortcut,\n MenubarCheckboxItem,\n MenubarRadioGroup,\n MenubarRadioItem,\n MenubarSub,\n MenubarSubTrigger,\n MenubarSubContent,\n}\n\n/**\n * WHEN TO USE\n * - Desktop-style app chrome with several always-visible menus that share\n * hover-to-open behavior (opening one, then hovering the next, switches\n * without a click)\n *\n * NOT WHEN\n * - A single action menu on one trigger — use DropdownMenu\n * - A right-click context menu — use ContextMenu\n * - Site/section navigation — use NavigationMenu\n *\n * KEY RULES\n * - MenubarItem variant=\"destructive\" tints text/focus red for delete-style actions\n * - MenubarCheckboxItem and MenubarRadioItem behave like their DropdownMenu\n * counterparts — checked state is controlled by the caller\n * - MenubarShortcut is a plain right-aligned hint, not a working keybinding —\n * wire the actual shortcut yourself\n *\n * USAGE\n * <Menubar>\n * <MenubarMenu>\n * <MenubarTrigger>File</MenubarTrigger>\n * <MenubarContent>\n * <MenubarItem>New tab <MenubarShortcut>⌘T</MenubarShortcut></MenubarItem>\n * <MenubarSeparator />\n * <MenubarSub>\n * <MenubarSubTrigger>Share</MenubarSubTrigger>\n * <MenubarSubContent>\n * <MenubarItem>Copy link</MenubarItem>\n * </MenubarSubContent>\n * </MenubarSub>\n * </MenubarContent>\n * </MenubarMenu>\n * </Menubar>\n */\n"],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * MessageScroller — auto-sticking scroll container for chat transcripts and log streams.
3
+ *
4
+ * Pins to the newest item by default and reveals a jump-to-latest
5
+ * MessageScrollerButton once the user scrolls away from it. Wraps the
6
+ * `@shadcn/react` message-scroller primitive. Render Message or Bubble
7
+ * items inside MessageScrollerItem; mark the item the viewport should pin
8
+ * to with `scrollAnchor` (typically the last item).
9
+ */
10
+ import * as React from "react";
11
+ import { MessageScroller as MessageScrollerPrimitive, useMessageScroller, useMessageScrollerScrollable, useMessageScrollerVisibility } from "@shadcn/react/message-scroller";
12
+ import { Button, type TextButtonSize } from "../../components/ui/button";
13
+ declare function MessageScrollerProvider(props: React.ComponentProps<typeof MessageScrollerPrimitive.Provider>): React.JSX.Element;
14
+ declare function MessageScroller({ className, ...props }: React.ComponentProps<typeof MessageScrollerPrimitive.Root>): React.JSX.Element;
15
+ declare function MessageScrollerViewport({ className, ...props }: React.ComponentProps<typeof MessageScrollerPrimitive.Viewport>): React.JSX.Element;
16
+ declare function MessageScrollerContent({ className, ...props }: React.ComponentProps<typeof MessageScrollerPrimitive.Content>): React.JSX.Element;
17
+ declare function MessageScrollerItem({ className, scrollAnchor, ...props }: React.ComponentProps<typeof MessageScrollerPrimitive.Item>): React.JSX.Element;
18
+ declare function MessageScrollerButton({ direction, className, children, render, variant, size, ...props }: React.ComponentProps<typeof MessageScrollerPrimitive.Button> & Pick<React.ComponentProps<typeof Button>, "variant"> & {
19
+ size?: TextButtonSize;
20
+ }): React.JSX.Element;
21
+ export { MessageScrollerProvider, MessageScroller, MessageScrollerViewport, MessageScrollerContent, MessageScrollerItem, MessageScrollerButton, useMessageScroller, useMessageScrollerScrollable, useMessageScrollerVisibility, };
22
+ /**
23
+ * WHEN TO USE
24
+ * - Chat transcripts, live logs, or any list where new content should keep the newest item in view
25
+ * - Streaming or incrementally-appended content
26
+ *
27
+ * NOT WHEN
28
+ * - Static, non-growing lists — use ScrollArea
29
+ * - Feeds anchored to the top (e.g. paginated results) — this only pins to one end anchor
30
+ *
31
+ * KEY RULES
32
+ * - Requires MessageScrollerProvider as an ancestor — MessageScroller does nothing useful without it
33
+ * - Exactly one MessageScrollerItem should carry `scrollAnchor` (usually the last rendered item) — that's what the viewport pins to and what the jump button targets
34
+ * - MessageScrollerButton `direction`: "end" (default, jump to newest) or "start"
35
+ * - useMessageScroller / useMessageScrollerScrollable / useMessageScrollerVisibility expose scroll state for custom UI — reach for these before wiring a manual scroll listener
36
+ *
37
+ * USAGE
38
+ * <MessageScrollerProvider>
39
+ * <MessageScroller className="h-80 rounded-xl border">
40
+ * <MessageScrollerViewport>
41
+ * <MessageScrollerContent>
42
+ * {messages.map((m, i) => (
43
+ * <MessageScrollerItem key={m.id} scrollAnchor={i === messages.length - 1}>
44
+ * <Message align={m.align}>{m.body}</Message>
45
+ * </MessageScrollerItem>
46
+ * ))}
47
+ * </MessageScrollerContent>
48
+ * </MessageScrollerViewport>
49
+ * <MessageScrollerButton direction="end" />
50
+ * </MessageScroller>
51
+ * </MessageScrollerProvider>
52
+ */
53
+ //# sourceMappingURL=message-scroller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-scroller.d.ts","sourceRoot":"","sources":["../../../src/components/ui/message-scroller.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EACL,eAAe,IAAI,wBAAwB,EAC3C,kBAAkB,EAClB,4BAA4B,EAC5B,4BAA4B,EAC7B,MAAM,gCAAgC,CAAA;AAGvC,OAAO,EAAE,MAAM,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAGpE,iBAAS,uBAAuB,CAC9B,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,QAAQ,CAAC,qBAGtE;AAED,iBAAS,eAAe,CAAC,EACvB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,IAAI,CAAC,qBAW5D;AAED,iBAAS,uBAAuB,CAAC,EAC/B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,QAAQ,CAAC,qBAWhE;AAED,iBAAS,sBAAsB,CAAC,EAC9B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,OAAO,CAAC,qBAQ/D;AAED,iBAAS,mBAAmB,CAAC,EAC3B,SAAS,EACT,YAAoB,EACpB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,IAAI,CAAC,qBAY5D;AAED,iBAAS,qBAAqB,CAAC,EAC7B,SAAiB,EACjB,SAAS,EACT,QAAQ,EACR,MAAM,EACN,OAAqB,EACrB,IAAW,EACX,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,wBAAwB,CAAC,MAAM,CAAC,GAC7D,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,SAAS,CAAC,GAAG;IACrD,IAAI,CAAC,EAAE,cAAc,CAAA;CACtB,qBAoCF;AAED,OAAO,EACL,uBAAuB,EACvB,eAAe,EACf,uBAAuB,EACvB,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAClB,4BAA4B,EAC5B,4BAA4B,GAC7B,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG"}