@nocoo/basalt 2.2.0 → 3.0.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 (319) hide show
  1. package/README.md +2 -0
  2. package/ai/COMPATIBILITY.md +11 -1
  3. package/ai/DESIGN.md +342 -0
  4. package/ai/INTEGRATION.md +179 -128
  5. package/ai/RECIPES.md +51 -26
  6. package/ai/USAGE.md +4 -4
  7. package/ai/registry.json +2836 -270
  8. package/dist/charts/config.d.ts +11 -11
  9. package/dist/charts/config.js +4 -4
  10. package/dist/charts/config.js.map +1 -1
  11. package/dist/charts/date-navigation.js +10 -10
  12. package/dist/charts/date-navigation.js.map +1 -1
  13. package/dist/charts/donut.js +1 -1
  14. package/dist/charts/donut.js.map +1 -1
  15. package/dist/charts/frame.d.ts +1 -1
  16. package/dist/charts/frame.js +4 -4
  17. package/dist/charts/frame.js.map +1 -1
  18. package/dist/charts/gauge.js +5 -5
  19. package/dist/charts/gauge.js.map +1 -1
  20. package/dist/charts/heatmap-calendar.js +11 -11
  21. package/dist/charts/heatmap-calendar.js.map +1 -1
  22. package/dist/charts/heatmap-matrix.js +8 -8
  23. package/dist/charts/heatmap-matrix.js.map +1 -1
  24. package/dist/charts/item-list.js +1 -1
  25. package/dist/charts/item-list.js.map +1 -1
  26. package/dist/charts/legend.js +19 -19
  27. package/dist/charts/legend.js.map +1 -1
  28. package/dist/charts/palette.js +2 -2
  29. package/dist/charts/palette.js.map +1 -1
  30. package/dist/charts/slot-bar.js +2 -2
  31. package/dist/charts/slot-bar.js.map +1 -1
  32. package/dist/charts/sparkline.js +38 -23
  33. package/dist/charts/sparkline.js.map +1 -1
  34. package/dist/charts/stat-card.d.ts +2 -2
  35. package/dist/charts/stat-card.js +61 -58
  36. package/dist/charts/stat-card.js.map +1 -1
  37. package/dist/charts/timeline.js +18 -9
  38. package/dist/charts/timeline.js.map +1 -1
  39. package/dist/charts/tooltip.js +16 -16
  40. package/dist/charts/tooltip.js.map +1 -1
  41. package/dist/components/accordion.js +1 -1
  42. package/dist/components/accordion.js.map +1 -1
  43. package/dist/components/alert-dialog.js +4 -4
  44. package/dist/components/alert-dialog.js.map +1 -1
  45. package/dist/components/app-header.js +8 -8
  46. package/dist/components/app-header.js.map +1 -1
  47. package/dist/components/app-shell.js +1 -1
  48. package/dist/components/app-shell.js.map +1 -1
  49. package/dist/components/approval-card.d.ts +13 -0
  50. package/dist/components/approval-card.js +161 -0
  51. package/dist/components/approval-card.js.map +1 -0
  52. package/dist/components/avatar.d.ts +12 -0
  53. package/dist/components/avatar.js +39 -18
  54. package/dist/components/avatar.js.map +1 -1
  55. package/dist/components/badge.js +8 -8
  56. package/dist/components/badge.js.map +1 -1
  57. package/dist/components/banner.d.ts +2 -2
  58. package/dist/components/banner.js +9 -8
  59. package/dist/components/banner.js.map +1 -1
  60. package/dist/components/basalt-mark.js +1 -1
  61. package/dist/components/basalt-mark.js.map +1 -1
  62. package/dist/components/battery-meter.js +5 -5
  63. package/dist/components/battery-meter.js.map +1 -1
  64. package/dist/components/breadcrumbs.js +6 -6
  65. package/dist/components/breadcrumbs.js.map +1 -1
  66. package/dist/components/button.js +10 -10
  67. package/dist/components/button.js.map +1 -1
  68. package/dist/components/chat-bubble.js +4 -3
  69. package/dist/components/chat-bubble.js.map +1 -1
  70. package/dist/components/chat-composer.d.ts +21 -3
  71. package/dist/components/chat-composer.js +126 -60
  72. package/dist/components/chat-composer.js.map +1 -1
  73. package/dist/components/chat-header.js +6 -6
  74. package/dist/components/chat-header.js.map +1 -1
  75. package/dist/components/chat-inbox.js +34 -30
  76. package/dist/components/chat-inbox.js.map +1 -1
  77. package/dist/components/chat-markdown.d.ts +8 -0
  78. package/dist/components/chat-markdown.js +122 -0
  79. package/dist/components/chat-markdown.js.map +1 -0
  80. package/dist/components/chat-message.d.ts +26 -0
  81. package/dist/components/chat-message.js +145 -0
  82. package/dist/components/chat-message.js.map +1 -0
  83. package/dist/components/checkbox.js +11 -11
  84. package/dist/components/checkbox.js.map +1 -1
  85. package/dist/components/clipboard-text.js +3 -3
  86. package/dist/components/clipboard-text.js.map +1 -1
  87. package/dist/components/code.d.ts +22 -20
  88. package/dist/components/code.js +94 -32
  89. package/dist/components/code.js.map +1 -1
  90. package/dist/components/collapsible.js +8 -4
  91. package/dist/components/collapsible.js.map +1 -1
  92. package/dist/components/command-palette.js +73 -47
  93. package/dist/components/command-palette.js.map +1 -1
  94. package/dist/components/context-cards.d.ts +15 -0
  95. package/dist/components/context-cards.js +148 -0
  96. package/dist/components/context-cards.js.map +1 -0
  97. package/dist/components/context-menu.d.ts +1 -1
  98. package/dist/components/context-menu.js +18 -14
  99. package/dist/components/context-menu.js.map +1 -1
  100. package/dist/components/data-table.d.ts +8 -2
  101. package/dist/components/data-table.js +161 -106
  102. package/dist/components/data-table.js.map +1 -1
  103. package/dist/components/date-picker.js +13 -13
  104. package/dist/components/date-picker.js.map +1 -1
  105. package/dist/components/delete-resource.js +1 -1
  106. package/dist/components/delete-resource.js.map +1 -1
  107. package/dist/components/description-list.js +3 -3
  108. package/dist/components/description-list.js.map +1 -1
  109. package/dist/components/dialog.d.ts +2 -2
  110. package/dist/components/dialog.js +8 -8
  111. package/dist/components/dialog.js.map +1 -1
  112. package/dist/components/diff-table.d.ts +15 -0
  113. package/dist/components/diff-table.js +146 -0
  114. package/dist/components/diff-table.js.map +1 -0
  115. package/dist/components/dock.js +2 -2
  116. package/dist/components/dock.js.map +1 -1
  117. package/dist/components/dropdown-menu.js +23 -18
  118. package/dist/components/dropdown-menu.js.map +1 -1
  119. package/dist/components/editable-nav-item.js +63 -58
  120. package/dist/components/editable-nav-item.js.map +1 -1
  121. package/dist/components/empty.js +6 -6
  122. package/dist/components/empty.js.map +1 -1
  123. package/dist/components/fab.js +1 -1
  124. package/dist/components/fab.js.map +1 -1
  125. package/dist/components/field.js +3 -3
  126. package/dist/components/field.js.map +1 -1
  127. package/dist/components/file-dropzone.js +7 -7
  128. package/dist/components/file-dropzone.js.map +1 -1
  129. package/dist/components/filter-bar.js +6 -6
  130. package/dist/components/filter-bar.js.map +1 -1
  131. package/dist/components/flow.js +4 -3
  132. package/dist/components/flow.js.map +1 -1
  133. package/dist/components/grid.d.ts +3 -1
  134. package/dist/components/grid.js +15 -8
  135. package/dist/components/grid.js.map +1 -1
  136. package/dist/components/hover-card.js +1 -1
  137. package/dist/components/hover-card.js.map +1 -1
  138. package/dist/components/icon-picker.d.ts +8 -2
  139. package/dist/components/icon-picker.js +75 -47
  140. package/dist/components/icon-picker.js.map +1 -1
  141. package/dist/components/inline-editable.js +6 -6
  142. package/dist/components/inline-editable.js.map +1 -1
  143. package/dist/components/input-area.js +3 -3
  144. package/dist/components/input-area.js.map +1 -1
  145. package/dist/components/input-group.js +5 -5
  146. package/dist/components/input-group.js.map +1 -1
  147. package/dist/components/input.js +4 -4
  148. package/dist/components/input.js.map +1 -1
  149. package/dist/components/label.js +3 -3
  150. package/dist/components/label.js.map +1 -1
  151. package/dist/components/layer-card.d.ts +9 -4
  152. package/dist/components/layer-card.js +72 -67
  153. package/dist/components/layer-card.js.map +1 -1
  154. package/dist/components/loader.d.ts +16 -10
  155. package/dist/components/loader.js +46 -53
  156. package/dist/components/loader.js.map +1 -1
  157. package/dist/components/loading-screen.js +3 -3
  158. package/dist/components/loading-screen.js.map +1 -1
  159. package/dist/components/menu-bar.js +32 -27
  160. package/dist/components/menu-bar.js.map +1 -1
  161. package/dist/components/meter.d.ts +5 -5
  162. package/dist/components/meter.js +25 -12
  163. package/dist/components/meter.js.map +1 -1
  164. package/dist/components/multi-select.js +66 -62
  165. package/dist/components/multi-select.js.map +1 -1
  166. package/dist/components/navigation-menu.d.ts +2 -2
  167. package/dist/components/navigation-menu.js +22 -8
  168. package/dist/components/navigation-menu.js.map +1 -1
  169. package/dist/components/overlay.js +2 -2
  170. package/dist/components/overlay.js.map +1 -1
  171. package/dist/components/page-header.d.ts +3 -1
  172. package/dist/components/page-header.js +12 -12
  173. package/dist/components/page-header.js.map +1 -1
  174. package/dist/components/pagination.js +3 -3
  175. package/dist/components/pagination.js.map +1 -1
  176. package/dist/components/popover.js +18 -23
  177. package/dist/components/popover.js.map +1 -1
  178. package/dist/components/prompt-bar.d.ts +16 -0
  179. package/dist/components/prompt-bar.js +49 -0
  180. package/dist/components/prompt-bar.js.map +1 -0
  181. package/dist/components/radio.js +9 -9
  182. package/dist/components/radio.js.map +1 -1
  183. package/dist/components/recommendation-card.d.ts +13 -0
  184. package/dist/components/recommendation-card.js +123 -0
  185. package/dist/components/recommendation-card.js.map +1 -0
  186. package/dist/components/resource-list.js +1 -1
  187. package/dist/components/resource-list.js.map +1 -1
  188. package/dist/components/responsive-master-detail.js +4 -4
  189. package/dist/components/responsive-master-detail.js.map +1 -1
  190. package/dist/components/scroll-area.js +3 -3
  191. package/dist/components/scroll-area.js.map +1 -1
  192. package/dist/components/section-rule.d.ts +5 -3
  193. package/dist/components/section-rule.js +12 -12
  194. package/dist/components/section-rule.js.map +1 -1
  195. package/dist/components/segment-control.js +3 -3
  196. package/dist/components/segment-control.js.map +1 -1
  197. package/dist/components/select.js +47 -32
  198. package/dist/components/select.js.map +1 -1
  199. package/dist/components/sensitive-input.js +17 -19
  200. package/dist/components/sensitive-input.js.map +1 -1
  201. package/dist/components/sheet.d.ts +4 -4
  202. package/dist/components/sheet.js +11 -10
  203. package/dist/components/sheet.js.map +1 -1
  204. package/dist/components/sidebar.js +146 -137
  205. package/dist/components/sidebar.js.map +1 -1
  206. package/dist/components/skeleton-line.d.ts +1 -1
  207. package/dist/components/skeleton-line.js +2 -2
  208. package/dist/components/skeleton-line.js.map +1 -1
  209. package/dist/components/slider.js +2 -2
  210. package/dist/components/slider.js.map +1 -1
  211. package/dist/components/stat-strip.js +5 -4
  212. package/dist/components/stat-strip.js.map +1 -1
  213. package/dist/components/switch.js +6 -6
  214. package/dist/components/switch.js.map +1 -1
  215. package/dist/components/table-of-contents.js +5 -5
  216. package/dist/components/table-of-contents.js.map +1 -1
  217. package/dist/components/table-pager.js +2 -2
  218. package/dist/components/table-pager.js.map +1 -1
  219. package/dist/components/table.js +4 -4
  220. package/dist/components/table.js.map +1 -1
  221. package/dist/components/tabs.js +7 -6
  222. package/dist/components/tabs.js.map +1 -1
  223. package/dist/components/tag-badge.d.ts +10 -10
  224. package/dist/components/tag-badge.js +11 -11
  225. package/dist/components/tag-badge.js.map +1 -1
  226. package/dist/components/tag-color-picker.d.ts +8 -1
  227. package/dist/components/tag-color-picker.js +33 -25
  228. package/dist/components/tag-color-picker.js.map +1 -1
  229. package/dist/components/text.js +5 -5
  230. package/dist/components/text.js.map +1 -1
  231. package/dist/components/theme-toggle.js +1 -1
  232. package/dist/components/theme-toggle.js.map +1 -1
  233. package/dist/components/thinking.d.ts +16 -0
  234. package/dist/components/thinking.js +85 -0
  235. package/dist/components/thinking.js.map +1 -0
  236. package/dist/components/toast.js +25 -20
  237. package/dist/components/toast.js.map +1 -1
  238. package/dist/components/toggle-group.js +6 -5
  239. package/dist/components/toggle-group.js.map +1 -1
  240. package/dist/components/toggle.js +6 -6
  241. package/dist/components/toggle.js.map +1 -1
  242. package/dist/components/tool-chips.d.ts +12 -0
  243. package/dist/components/tool-chips.js +138 -0
  244. package/dist/components/tool-chips.js.map +1 -0
  245. package/dist/components/toolbar.js +3 -3
  246. package/dist/components/toolbar.js.map +1 -1
  247. package/dist/components/tooltip.js +1 -1
  248. package/dist/components/tooltip.js.map +1 -1
  249. package/dist/components/typeahead-field.js +59 -56
  250. package/dist/components/typeahead-field.js.map +1 -1
  251. package/dist/components/upload-queue.js +15 -14
  252. package/dist/components/upload-queue.js.map +1 -1
  253. package/dist/models/agent-feedback.d.ts +44 -0
  254. package/dist/models/agent-feedback.js +28 -0
  255. package/dist/models/agent-feedback.js.map +1 -0
  256. package/dist/models/avatar.d.ts +2 -0
  257. package/dist/models/avatar.js +15 -0
  258. package/dist/models/avatar.js.map +1 -0
  259. package/dist/models/code.d.ts +6 -0
  260. package/dist/models/code.js +24 -0
  261. package/dist/models/code.js.map +1 -0
  262. package/dist/models/context-cards.d.ts +13 -0
  263. package/dist/models/context-cards.js +17 -0
  264. package/dist/models/context-cards.js.map +1 -0
  265. package/dist/models/diff-table.d.ts +12 -0
  266. package/dist/models/diff-table.js +9 -0
  267. package/dist/models/diff-table.js.map +1 -0
  268. package/dist/models/recommendation.d.ts +26 -0
  269. package/dist/models/recommendation.js +23 -0
  270. package/dist/models/recommendation.js.map +1 -0
  271. package/dist/styles/base.css +14 -2
  272. package/dist/styles/standalone.css +1865 -929
  273. package/dist/styles/tailwind.css +179 -13
  274. package/dist/styles/tokens.css +679 -20
  275. package/dist/utils/cn.js +25 -4
  276. package/dist/utils/cn.js.map +1 -1
  277. package/dist/utils/control-surface.d.ts +1 -1
  278. package/dist/utils/control-surface.js +1 -1
  279. package/dist/utils/control-surface.js.map +1 -1
  280. package/dist/utils/navigation.d.ts +3 -0
  281. package/dist/utils/navigation.js +8 -0
  282. package/dist/utils/navigation.js.map +1 -0
  283. package/dist/utils/selection-indicator.d.ts +1 -1
  284. package/dist/utils/selection-indicator.js +49 -72
  285. package/dist/utils/selection-indicator.js.map +1 -1
  286. package/dist/utils/use-hover-highlight.d.ts +4 -0
  287. package/dist/utils/use-hover-highlight.js +80 -0
  288. package/dist/utils/use-hover-highlight.js.map +1 -0
  289. package/dist/viewmodels/use-approval-card.d.ts +20 -0
  290. package/dist/viewmodels/use-approval-card.js +83 -0
  291. package/dist/viewmodels/use-approval-card.js.map +1 -0
  292. package/dist/viewmodels/use-chat-composer.d.ts +16 -0
  293. package/dist/viewmodels/use-chat-composer.js +34 -0
  294. package/dist/viewmodels/use-chat-composer.js.map +1 -0
  295. package/dist/viewmodels/use-chat-message.d.ts +16 -0
  296. package/dist/viewmodels/use-chat-message.js +26 -0
  297. package/dist/viewmodels/use-chat-message.js.map +1 -0
  298. package/dist/viewmodels/use-code-block.d.ts +8 -0
  299. package/dist/viewmodels/use-code-block.js +38 -0
  300. package/dist/viewmodels/use-code-block.js.map +1 -0
  301. package/dist/viewmodels/use-context-cards.d.ts +17 -0
  302. package/dist/viewmodels/use-context-cards.js +18 -0
  303. package/dist/viewmodels/use-context-cards.js.map +1 -0
  304. package/dist/viewmodels/use-diff-table.d.ts +16 -0
  305. package/dist/viewmodels/use-diff-table.js +42 -0
  306. package/dist/viewmodels/use-diff-table.js.map +1 -0
  307. package/dist/viewmodels/use-loader.d.ts +4 -0
  308. package/dist/viewmodels/use-loader.js +22 -0
  309. package/dist/viewmodels/use-loader.js.map +1 -0
  310. package/dist/viewmodels/use-recommendation-card.d.ts +17 -0
  311. package/dist/viewmodels/use-recommendation-card.js +41 -0
  312. package/dist/viewmodels/use-recommendation-card.js.map +1 -0
  313. package/dist/viewmodels/use-thinking.d.ts +13 -0
  314. package/dist/viewmodels/use-thinking.js +18 -0
  315. package/dist/viewmodels/use-thinking.js.map +1 -0
  316. package/dist/viewmodels/use-tool-chips.d.ts +10 -0
  317. package/dist/viewmodels/use-tool-chips.js +20 -0
  318. package/dist/viewmodels/use-tool-chips.js.map +1 -0
  319. package/package.json +3 -1
@@ -5,32 +5,32 @@ import { Breadcrumbs as n } from "./breadcrumbs.js";
5
5
  import * as r from "react";
6
6
  import { jsx as i, jsxs as a } from "react/jsx-runtime";
7
7
  //#region src/components/page-header.tsx
8
- function o({ actions: o, breadcrumbs: s, description: c, filters: l, title: u }) {
9
- let d = r.useId();
8
+ function o({ actions: o, breadcrumbs: s, description: c, filters: l, size: u = "md", title: d }) {
9
+ let f = r.useId();
10
10
  return /* @__PURE__ */ a("header", {
11
- "aria-labelledby": d,
12
- className: e(t, "space-y-4"),
11
+ "aria-labelledby": f,
12
+ className: e(t, "min-w-0 shrink-0 space-y-basalt-layout"),
13
13
  children: [
14
14
  s && s.length > 0 ? /* @__PURE__ */ i(n, { items: [...s] }) : null,
15
15
  /* @__PURE__ */ a("div", {
16
- className: "flex flex-col gap-4 md:flex-row md:items-start md:justify-between",
16
+ className: "flex flex-col gap-basalt-layout md:flex-row md:items-start md:justify-between",
17
17
  children: [/* @__PURE__ */ a("div", {
18
- className: "min-w-0 flex-1 space-y-1",
18
+ className: "min-w-0 flex-1 space-y-basalt-space-lg",
19
19
  children: [/* @__PURE__ */ i("h1", {
20
- id: d,
21
- className: "text-2xl font-semibold tracking-tight text-basalt-foreground",
22
- children: u
20
+ id: f,
21
+ className: e("font-basalt-display font-semibold tracking-tight text-basalt-foreground [overflow-wrap:anywhere]", u === "md" && "text-basalt-3xl", u === "lg" && "text-basalt-4xl", u === "xl" && "text-basalt-4xl md:text-basalt-5xl", "leading-basalt-tight"),
22
+ children: d
23
23
  }), c ? /* @__PURE__ */ i("p", {
24
- className: "text-sm text-basalt-muted-foreground",
24
+ className: e("max-w-[65ch] text-basalt-muted-foreground [overflow-wrap:anywhere]", u === "md" ? "text-basalt-base" : "text-basalt-lg leading-basalt-relaxed"),
25
25
  children: c
26
26
  }) : null]
27
27
  }), o ? /* @__PURE__ */ i("div", {
28
- className: "flex flex-wrap items-center justify-end gap-2",
28
+ className: "flex flex-wrap items-center justify-end gap-basalt-space-lg",
29
29
  children: o
30
30
  }) : null]
31
31
  }),
32
32
  l ? /* @__PURE__ */ i("div", {
33
- className: "flex flex-wrap items-center gap-2",
33
+ className: "flex flex-wrap items-center gap-basalt-space-lg",
34
34
  children: l
35
35
  }) : null
36
36
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"page-header.js","names":["React","PageHeader","titleId","cn","BASALT_UI_CLASS","breadcrumbs","Breadcrumbs","title","description","actions","filters"],"sources":["../../src/components/page-header.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Breadcrumbs } from \"./breadcrumbs\";\n\nexport interface PageHeaderBreadcrumb {\n\thref?: string;\n\tlabel: React.ReactNode;\n\ticon?: React.ReactNode;\n}\n\nexport interface PageHeaderProps {\n\t/** The page title, rendered as the only heading. */\n\ttitle: React.ReactNode;\n\t/** Supporting text below the title. */\n\tdescription?: React.ReactNode;\n\t/** Trail of parent pages. */\n\tbreadcrumbs?: readonly PageHeaderBreadcrumb[];\n\t/** Right-side title-row actions. Put the create button last. */\n\tactions?: React.ReactNode;\n\t/** Own-row filters. Keep short filters in actions. */\n\tfilters?: React.ReactNode;\n}\n\nexport function PageHeader({ actions, breadcrumbs, description, filters, title }: PageHeaderProps) {\n\tconst titleId = React.useId();\n\n\treturn (\n\t\t// biome-ignore lint/a11y/useAriaPropsSupportedByRole: the title heading names this header\n\t\t<header aria-labelledby={titleId} className={cn(BASALT_UI_CLASS, \"space-y-4\")}>\n\t\t\t{breadcrumbs && breadcrumbs.length > 0 ? <Breadcrumbs items={[...breadcrumbs]} /> : null}\n\t\t\t<div className=\"flex flex-col gap-4 md:flex-row md:items-start md:justify-between\">\n\t\t\t\t<div className=\"min-w-0 flex-1 space-y-1\">\n\t\t\t\t\t<h1 id={titleId} className=\"text-2xl font-semibold tracking-tight text-basalt-foreground\">\n\t\t\t\t\t\t{title}\n\t\t\t\t\t</h1>\n\t\t\t\t\t{description ? (\n\t\t\t\t\t\t<p className=\"text-sm text-basalt-muted-foreground\">{description}</p>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t\t{actions ? (\n\t\t\t\t\t<div className=\"flex flex-wrap items-center justify-end gap-2\">{actions}</div>\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t\t{filters ? <div className=\"flex flex-wrap items-center gap-2\">{filters}</div> : null}\n\t\t</header>\n\t);\n}\n"],"mappings":";;;;;;;AAwBA,SAAgBC,EAAW,EAAE,YAAS,gBAAa,gBAAa,YAAS,YAA0B;CAClG,IAAMC,IAAUF,EAAM,MAAM;CAE5B,OAEC,kBAAC,UAAD;EAAQ,mBAAiBE;EAAS,WAAWC,EAAGC,GAAiB,WAAW;EAA5E,UAAA;GACEC,KAAeA,EAAY,SAAS,IAAI,kBAACC,GAAD,EAAa,OAAO,CAAC,GAAGD,CAAW,EAAI,CAAA,IAAI;GACpF,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACC,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACC,kBAAC,MAAD;MAAI,IAAIH;MAAS,WAAU;MACzB,UAAAK;KACE,CAAA,GACHC,IACA,kBAAC,KAAD;MAAG,WAAU;MAAwC,UAAAA;KAAe,CAAA,IACjE,IACA;IACJ,CAAA,GAAAC,IACA,kBAAC,OAAD;KAAK,WAAU;KAAiD,UAAAA;IAAa,CAAA,IAC1E,IACA;;GACJC,IAAU,kBAAC,OAAD;IAAK,WAAU;IAAqC,UAAAA;GAAa,CAAA,IAAI;EACzE;;AAEV"}
1
+ {"version":3,"file":"page-header.js","names":["React","PageHeader","titleId","cn","BASALT_UI_CLASS","breadcrumbs","Breadcrumbs","size","title","description","actions","filters"],"sources":["../../src/components/page-header.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Breadcrumbs } from \"./breadcrumbs\";\n\nexport interface PageHeaderBreadcrumb {\n\thref?: string;\n\tlabel: React.ReactNode;\n\ticon?: React.ReactNode;\n}\n\nexport interface PageHeaderProps {\n\t/** Heading scale: workspace, dashboard, or reading-focused page. @default \"md\" */\n\tsize?: \"md\" | \"lg\" | \"xl\";\n\t/** The page title, rendered as the only heading. */\n\ttitle: React.ReactNode;\n\t/** Supporting text below the title. */\n\tdescription?: React.ReactNode;\n\t/** Trail of parent pages. */\n\tbreadcrumbs?: readonly PageHeaderBreadcrumb[];\n\t/** Right-side title-row actions. Put the create button last. */\n\tactions?: React.ReactNode;\n\t/** Own-row filters. Keep short filters in actions. */\n\tfilters?: React.ReactNode;\n}\n\nexport function PageHeader({\n\tactions,\n\tbreadcrumbs,\n\tdescription,\n\tfilters,\n\tsize = \"md\",\n\ttitle,\n}: PageHeaderProps) {\n\tconst titleId = React.useId();\n\n\treturn (\n\t\t// biome-ignore lint/a11y/useAriaPropsSupportedByRole: the title heading names this header\n\t\t<header\n\t\t\taria-labelledby={titleId}\n\t\t\tclassName={cn(BASALT_UI_CLASS, \"min-w-0 shrink-0 space-y-basalt-layout\")}\n\t\t>\n\t\t\t{breadcrumbs && breadcrumbs.length > 0 ? <Breadcrumbs items={[...breadcrumbs]} /> : null}\n\t\t\t<div className=\"flex flex-col gap-basalt-layout md:flex-row md:items-start md:justify-between\">\n\t\t\t\t<div className=\"min-w-0 flex-1 space-y-basalt-space-lg\">\n\t\t\t\t\t<h1\n\t\t\t\t\t\tid={titleId}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\"font-basalt-display font-semibold tracking-tight text-basalt-foreground [overflow-wrap:anywhere]\",\n\t\t\t\t\t\t\tsize === \"md\" && \"text-basalt-3xl\",\n\t\t\t\t\t\t\tsize === \"lg\" && \"text-basalt-4xl\",\n\t\t\t\t\t\t\tsize === \"xl\" && \"text-basalt-4xl md:text-basalt-5xl\",\n\t\t\t\t\t\t\t\"leading-basalt-tight\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{title}\n\t\t\t\t\t</h1>\n\t\t\t\t\t{description ? (\n\t\t\t\t\t\t<p\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"max-w-[65ch] text-basalt-muted-foreground [overflow-wrap:anywhere]\",\n\t\t\t\t\t\t\t\tsize === \"md\" ? \"text-basalt-base\" : \"text-basalt-lg leading-basalt-relaxed\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{description}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t\t{actions ? (\n\t\t\t\t\t<div className=\"flex flex-wrap items-center justify-end gap-basalt-space-lg\">\n\t\t\t\t\t\t{actions}\n\t\t\t\t\t</div>\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t\t{filters ? (\n\t\t\t\t<div className=\"flex flex-wrap items-center gap-basalt-space-lg\">{filters}</div>\n\t\t\t) : null}\n\t\t</header>\n\t);\n}\n"],"mappings":";;;;;;;AA0BA,SAAgBC,EAAW,EAC1B,YACA,gBACA,gBACA,YACA,UAAO,MACP,YACmB;CACnB,IAAMC,IAAUF,EAAM,MAAM;CAE5B,OAEC,kBAAC,UAAD;EACC,mBAAiBE;EACjB,WAAWC,EAAGC,GAAiB,wCAAwC;EAFxE,UAAA;GAIEC,KAAeA,EAAY,SAAS,IAAI,kBAACC,GAAD,EAAa,OAAO,CAAC,GAAGD,CAAW,EAAI,CAAA,IAAI;GACpF,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACC,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACC,kBAAC,MAAD;MACC,IAAIH;MACJ,WAAWC,EACV,oGACAI,MAAS,QAAQ,mBACjBA,MAAS,QAAQ,mBACjBA,MAAS,QAAQ,sCACjB,sBACD;MAEC,UAAAC;KACE,CAAA,GACHC,IACA,kBAAC,KAAD;MACC,WAAWN,EACV,sEACAI,MAAS,OAAO,qBAAqB,uCACtC;MAEC,UAAAE;KACC,CAAA,IACA,IACA;IACJ,CAAA,GAAAC,IACA,kBAAC,OAAD;KAAK,WAAU;KACb,UAAAA;IACG,CAAA,IACF,IACA;;GACJC,IACA,kBAAC,OAAD;IAAK,WAAU;IAAmD,UAAAA;GAAa,CAAA,IAC5E;EACG;;AAEV"}
@@ -6,7 +6,7 @@ import { useState as r } from "react";
6
6
  import { ChevronLeft as i, ChevronRight as a, ChevronsLeft as o, ChevronsRight as s } from "lucide-react";
7
7
  import { jsx as c, jsxs as l } from "react/jsx-runtime";
8
8
  //#region src/components/pagination.tsx
9
- var u = e("relative h-full w-9 shrink-0 rounded-none border-0 bg-transparent shadow-none first:rounded-l-basalt-md last:rounded-r-basalt-md", "hover:bg-basalt-accent focus-visible:bg-basalt-accent active:bg-basalt-accent", "disabled:pointer-events-none disabled:opacity-100 disabled:text-basalt-muted-foreground");
9
+ var u = e("relative basalt-action-inset w-basalt-control shrink-0 rounded-none border-0 bg-transparent shadow-none first:rounded-l-basalt-md last:rounded-r-basalt-md", "hover:bg-basalt-hover focus-visible:bg-basalt-hover active:bg-basalt-hover", "disabled:pointer-events-none disabled:opacity-100 disabled:text-basalt-muted-foreground");
10
10
  function d({ page: d, defaultPage: f = 1, pageCount: p = 10, onPageChange: m, simple: h = !1, disabled: g = !1, className: _ }) {
11
11
  let [v, y] = r(f), b = Math.max(1, p), x = Math.min(b, Math.max(1, d ?? v)), S = (e) => {
12
12
  d === void 0 && y(e), m?.(e);
@@ -15,7 +15,7 @@ function d({ page: d, defaultPage: f = 1, pageCount: p = 10, onPageChange: m, si
15
15
  "aria-label": "Pagination",
16
16
  className: _,
17
17
  children: /* @__PURE__ */ l("div", {
18
- className: t(e("inline-flex h-9 items-stretch", "[&>*:not(:first-child)]:border-l [&>*:not(:first-child)]:border-basalt-border", "[&>:first-child]:rounded-l-basalt-md [&>:last-child]:rounded-r-basalt-md")),
18
+ className: t(e("inline-flex min-h-basalt-control items-stretch", "[&>*:not(:first-child)]:border-l [&>*:not(:first-child)]:border-basalt-border", "[&>:first-child]:rounded-l-basalt-md [&>:last-child]:rounded-r-basalt-md")),
19
19
  children: [
20
20
  h ? null : /* @__PURE__ */ c(n, {
21
21
  variant: "ghost",
@@ -37,7 +37,7 @@ function d({ page: d, defaultPage: f = 1, pageCount: p = 10, onPageChange: m, si
37
37
  }),
38
38
  h ? null : /* @__PURE__ */ c("span", {
39
39
  "aria-current": "page",
40
- className: "flex h-full min-w-9 items-center justify-center px-3 text-sm font-medium tabular-nums text-basalt-foreground",
40
+ className: "basalt-choice flex min-w-basalt-control items-center justify-center px-basalt-space-lg text-basalt-base font-medium tabular-nums text-basalt-foreground",
41
41
  children: x
42
42
  }),
43
43
  /* @__PURE__ */ c(n, {
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.js","names":["itemClass","cn","Pagination","uncontrolled","setUncontrolled","useState","defaultPage","last","pageCount","current","page","go","next","onPageChange","atStart","atEnd","startDisabled","disabled","endDisabled","controlSurfaceClass","simple","Button","ChevronsLeft","ChevronLeft","ChevronRight","ChevronsRight"],"sources":["../../src/components/pagination.tsx"],"sourcesContent":["import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { controlSurfaceClass } from \"../utils/control-surface\";\nimport { Button } from \"./button\";\n\nconst itemClass = cn(\n\t\"relative h-full w-9 shrink-0 rounded-none border-0 bg-transparent shadow-none first:rounded-l-basalt-md last:rounded-r-basalt-md\",\n\t\"hover:bg-basalt-accent focus-visible:bg-basalt-accent active:bg-basalt-accent\",\n\t\"disabled:pointer-events-none disabled:opacity-100 disabled:text-basalt-muted-foreground\",\n);\n\nexport type PaginationProps = {\n\t/**\n\t * Controlled 1-based page.\n\t */\n\tpage?: number;\n\t/**\n\t * Uncontrolled initial page.\n\t * @default 1\n\t */\n\tdefaultPage?: number;\n\t/**\n\t * Last page number.\n\t * @default 10\n\t */\n\tpageCount?: number;\n\t/**\n\t * Called when the page changes.\n\t */\n\tonPageChange?: (page: number) => void;\n\t/**\n\t * Hide first, last, and page number controls.\n\t * @default false\n\t */\n\tsimple?: boolean;\n\t/**\n\t * Disable every control.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n\t/**\n\t * Additional classes for the nav.\n\t */\n\tclassName?: string;\n};\n\nexport function Pagination({\n\tpage,\n\tdefaultPage = 1,\n\tpageCount = 10,\n\tonPageChange,\n\tsimple = false,\n\tdisabled = false,\n\tclassName,\n}: PaginationProps) {\n\tconst [uncontrolled, setUncontrolled] = useState(defaultPage);\n\tconst last = Math.max(1, pageCount);\n\tconst current = Math.min(last, Math.max(1, page ?? uncontrolled));\n\tconst go = (next: number) => {\n\t\tif (page === undefined) {\n\t\t\tsetUncontrolled(next);\n\t\t}\n\t\tonPageChange?.(next);\n\t};\n\tconst atStart = current <= 1;\n\tconst atEnd = current >= last;\n\tconst startDisabled = disabled || atStart;\n\tconst endDisabled = disabled || atEnd;\n\n\treturn (\n\t\t<nav aria-label=\"Pagination\" className={className}>\n\t\t\t<div\n\t\t\t\tclassName={controlSurfaceClass(\n\t\t\t\t\tcn(\n\t\t\t\t\t\t\"inline-flex h-9 items-stretch\",\n\t\t\t\t\t\t\"[&>*:not(:first-child)]:border-l [&>*:not(:first-child)]:border-basalt-border\",\n\t\t\t\t\t\t\"[&>:first-child]:rounded-l-basalt-md [&>:last-child]:rounded-r-basalt-md\",\n\t\t\t\t\t),\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t{simple ? null : (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\ticon={<ChevronsLeft />}\n\t\t\t\t\t\tclassName={itemClass}\n\t\t\t\t\t\taria-label=\"First page\"\n\t\t\t\t\t\tdisabled={startDisabled}\n\t\t\t\t\t\tonClick={() => go(1)}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t<Button\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\ticon={<ChevronLeft />}\n\t\t\t\t\tclassName={itemClass}\n\t\t\t\t\taria-label=\"Previous page\"\n\t\t\t\t\tdisabled={startDisabled}\n\t\t\t\t\tonClick={() => go(Math.max(1, current - 1))}\n\t\t\t\t/>\n\t\t\t\t{simple ? null : (\n\t\t\t\t\t<span\n\t\t\t\t\t\taria-current=\"page\"\n\t\t\t\t\t\tclassName=\"flex h-full min-w-9 items-center justify-center px-3 text-sm font-medium tabular-nums text-basalt-foreground\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{current}\n\t\t\t\t\t</span>\n\t\t\t\t)}\n\t\t\t\t<Button\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\ticon={<ChevronRight />}\n\t\t\t\t\tclassName={itemClass}\n\t\t\t\t\taria-label=\"Next page\"\n\t\t\t\t\tdisabled={endDisabled}\n\t\t\t\t\tonClick={() => go(Math.min(last, current + 1))}\n\t\t\t\t/>\n\t\t\t\t{simple ? null : (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\ticon={<ChevronsRight />}\n\t\t\t\t\t\tclassName={itemClass}\n\t\t\t\t\t\taria-label=\"Last page\"\n\t\t\t\t\t\tdisabled={endDisabled}\n\t\t\t\t\t\tonClick={() => go(last)}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</nav>\n\t);\n}\n"],"mappings":";;;;;;;;AAMA,IAAMA,IAAYC,EACjB,oIACA,iFACA,yFACD;AAqCA,SAAgBC,EAAW,EAC1B,SACA,iBAAc,GACd,eAAY,IACZ,iBACA,YAAS,IACT,cAAW,IACX,gBACmB;CACnB,IAAM,CAACC,GAAcC,KAAmBC,EAASC,CAAW,GACtDC,IAAO,KAAK,IAAI,GAAGC,CAAS,GAC5BC,IAAU,KAAK,IAAIF,GAAM,KAAK,IAAI,GAAGG,KAAQP,CAAY,CAAC,GAC1DQ,KAAM,MAAiB;EAI5B,AAHID,MAAS,KAAA,KACZN,EAAgBQ,CAAI,GAErBC,IAAeD,CAAI;CACpB,GACME,IAAUL,KAAW,GACrBM,IAAQN,KAAWF,GACnBS,IAAgBC,KAAYH,GAC5BI,IAAcD,KAAYF;CAEhC,OACC,kBAAC,OAAD;EAAK,cAAW;EAAwB;EACvC,UAAA,kBAAC,OAAD;GACC,WAAWI,EACVlB,EACC,iCACA,iFACA,0EACD,CACD;GAPD,UAAA;IASEmB,IAAS,OACT,kBAACC,GAAD;KACC,SAAQ;KACR,MAAK;KACL,MAAM,kBAACC,GAAD,CAAe,CAAA;KACrB,WAAWtB;KACX,cAAW;KACX,UAAUgB;KACV,eAAeL,EAAG,CAAC;IACnB,CAAA;IAEF,kBAACU,GAAD;KACC,SAAQ;KACR,MAAK;KACL,MAAM,kBAACE,GAAD,CAAc,CAAA;KACpB,WAAWvB;KACX,cAAW;KACX,UAAUgB;KACV,eAAeL,EAAG,KAAK,IAAI,GAAGF,IAAU,CAAC,CAAC;IAC1C,CAAA;IACAW,IAAS,OACT,kBAAC,QAAD;KACC,gBAAa;KACb,WAAU;KAET,UAAAX;IACI,CAAA;IAEP,kBAACY,GAAD;KACC,SAAQ;KACR,MAAK;KACL,MAAM,kBAACG,GAAD,CAAe,CAAA;KACrB,WAAWxB;KACX,cAAW;KACX,UAAUkB;KACV,eAAeP,EAAG,KAAK,IAAIJ,GAAME,IAAU,CAAC,CAAC;IAC7C,CAAA;IACAW,IAAS,OACT,kBAACC,GAAD;KACC,SAAQ;KACR,MAAK;KACL,MAAM,kBAACI,GAAD,CAAgB,CAAA;KACtB,WAAWzB;KACX,cAAW;KACX,UAAUkB;KACV,eAAeP,EAAGJ,CAAI;IACtB,CAAA;GAEE;;CACD,CAAA;AAEP"}
1
+ {"version":3,"file":"pagination.js","names":["itemClass","cn","Pagination","uncontrolled","setUncontrolled","useState","defaultPage","last","pageCount","current","page","go","next","onPageChange","atStart","atEnd","startDisabled","disabled","endDisabled","controlSurfaceClass","simple","Button","ChevronsLeft","ChevronLeft","ChevronRight","ChevronsRight"],"sources":["../../src/components/pagination.tsx"],"sourcesContent":["import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { controlSurfaceClass } from \"../utils/control-surface\";\nimport { Button } from \"./button\";\n\nconst itemClass = cn(\n\t\"relative basalt-action-inset w-basalt-control shrink-0 rounded-none border-0 bg-transparent shadow-none first:rounded-l-basalt-md last:rounded-r-basalt-md\",\n\t\"hover:bg-basalt-hover focus-visible:bg-basalt-hover active:bg-basalt-hover\",\n\t\"disabled:pointer-events-none disabled:opacity-100 disabled:text-basalt-muted-foreground\",\n);\n\nexport type PaginationProps = {\n\t/**\n\t * Controlled 1-based page.\n\t */\n\tpage?: number;\n\t/**\n\t * Uncontrolled initial page.\n\t * @default 1\n\t */\n\tdefaultPage?: number;\n\t/**\n\t * Last page number.\n\t * @default 10\n\t */\n\tpageCount?: number;\n\t/**\n\t * Called when the page changes.\n\t */\n\tonPageChange?: (page: number) => void;\n\t/**\n\t * Hide first, last, and page number controls.\n\t * @default false\n\t */\n\tsimple?: boolean;\n\t/**\n\t * Disable every control.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n\t/**\n\t * Additional classes for the nav.\n\t */\n\tclassName?: string;\n};\n\nexport function Pagination({\n\tpage,\n\tdefaultPage = 1,\n\tpageCount = 10,\n\tonPageChange,\n\tsimple = false,\n\tdisabled = false,\n\tclassName,\n}: PaginationProps) {\n\tconst [uncontrolled, setUncontrolled] = useState(defaultPage);\n\tconst last = Math.max(1, pageCount);\n\tconst current = Math.min(last, Math.max(1, page ?? uncontrolled));\n\tconst go = (next: number) => {\n\t\tif (page === undefined) {\n\t\t\tsetUncontrolled(next);\n\t\t}\n\t\tonPageChange?.(next);\n\t};\n\tconst atStart = current <= 1;\n\tconst atEnd = current >= last;\n\tconst startDisabled = disabled || atStart;\n\tconst endDisabled = disabled || atEnd;\n\n\treturn (\n\t\t<nav aria-label=\"Pagination\" className={className}>\n\t\t\t<div\n\t\t\t\tclassName={controlSurfaceClass(\n\t\t\t\t\tcn(\n\t\t\t\t\t\t\"inline-flex min-h-basalt-control items-stretch\",\n\t\t\t\t\t\t\"[&>*:not(:first-child)]:border-l [&>*:not(:first-child)]:border-basalt-border\",\n\t\t\t\t\t\t\"[&>:first-child]:rounded-l-basalt-md [&>:last-child]:rounded-r-basalt-md\",\n\t\t\t\t\t),\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t{simple ? null : (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\ticon={<ChevronsLeft />}\n\t\t\t\t\t\tclassName={itemClass}\n\t\t\t\t\t\taria-label=\"First page\"\n\t\t\t\t\t\tdisabled={startDisabled}\n\t\t\t\t\t\tonClick={() => go(1)}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t<Button\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\ticon={<ChevronLeft />}\n\t\t\t\t\tclassName={itemClass}\n\t\t\t\t\taria-label=\"Previous page\"\n\t\t\t\t\tdisabled={startDisabled}\n\t\t\t\t\tonClick={() => go(Math.max(1, current - 1))}\n\t\t\t\t/>\n\t\t\t\t{simple ? null : (\n\t\t\t\t\t<span\n\t\t\t\t\t\taria-current=\"page\"\n\t\t\t\t\t\tclassName=\"basalt-choice flex min-w-basalt-control items-center justify-center px-basalt-space-lg text-basalt-base font-medium tabular-nums text-basalt-foreground\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{current}\n\t\t\t\t\t</span>\n\t\t\t\t)}\n\t\t\t\t<Button\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\ticon={<ChevronRight />}\n\t\t\t\t\tclassName={itemClass}\n\t\t\t\t\taria-label=\"Next page\"\n\t\t\t\t\tdisabled={endDisabled}\n\t\t\t\t\tonClick={() => go(Math.min(last, current + 1))}\n\t\t\t\t/>\n\t\t\t\t{simple ? null : (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\ticon={<ChevronsRight />}\n\t\t\t\t\t\tclassName={itemClass}\n\t\t\t\t\t\taria-label=\"Last page\"\n\t\t\t\t\t\tdisabled={endDisabled}\n\t\t\t\t\t\tonClick={() => go(last)}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</nav>\n\t);\n}\n"],"mappings":";;;;;;;;AAMA,IAAMA,IAAYC,EACjB,8JACA,8EACA,yFACD;AAqCA,SAAgBC,EAAW,EAC1B,SACA,iBAAc,GACd,eAAY,IACZ,iBACA,YAAS,IACT,cAAW,IACX,gBACmB;CACnB,IAAM,CAACC,GAAcC,KAAmBC,EAASC,CAAW,GACtDC,IAAO,KAAK,IAAI,GAAGC,CAAS,GAC5BC,IAAU,KAAK,IAAIF,GAAM,KAAK,IAAI,GAAGG,KAAQP,CAAY,CAAC,GAC1DQ,KAAM,MAAiB;EAI5B,AAHID,MAAS,KAAA,KACZN,EAAgBQ,CAAI,GAErBC,IAAeD,CAAI;CACpB,GACME,IAAUL,KAAW,GACrBM,IAAQN,KAAWF,GACnBS,IAAgBC,KAAYH,GAC5BI,IAAcD,KAAYF;CAEhC,OACC,kBAAC,OAAD;EAAK,cAAW;EAAwB;EACvC,UAAA,kBAAC,OAAD;GACC,WAAWI,EACVlB,EACC,kDACA,iFACA,0EACD,CACD;GAPD,UAAA;IASEmB,IAAS,OACT,kBAACC,GAAD;KACC,SAAQ;KACR,MAAK;KACL,MAAM,kBAACC,GAAD,CAAe,CAAA;KACrB,WAAWtB;KACX,cAAW;KACX,UAAUgB;KACV,eAAeL,EAAG,CAAC;IACnB,CAAA;IAEF,kBAACU,GAAD;KACC,SAAQ;KACR,MAAK;KACL,MAAM,kBAACE,GAAD,CAAc,CAAA;KACpB,WAAWvB;KACX,cAAW;KACX,UAAUgB;KACV,eAAeL,EAAG,KAAK,IAAI,GAAGF,IAAU,CAAC,CAAC;IAC1C,CAAA;IACAW,IAAS,OACT,kBAAC,QAAD;KACC,gBAAa;KACb,WAAU;KAET,UAAAX;IACI,CAAA;IAEP,kBAACY,GAAD;KACC,SAAQ;KACR,MAAK;KACL,MAAM,kBAACG,GAAD,CAAe,CAAA;KACrB,WAAWxB;KACX,cAAW;KACX,UAAUkB;KACV,eAAeP,EAAG,KAAK,IAAIJ,GAAME,IAAU,CAAC,CAAC;IAC7C,CAAA;IACAW,IAAS,OACT,kBAACC,GAAD;KACC,SAAQ;KACR,MAAK;KACL,MAAM,kBAACI,GAAD,CAAgB,CAAA;KACtB,WAAWzB;KACX,cAAW;KACX,UAAUkB;KACV,eAAeP,EAAGJ,CAAI;IACtB,CAAA;GAEE;;CACD,CAAA;AAEP"}
@@ -18,12 +18,12 @@ var c = [
18
18
  align: c,
19
19
  side: l,
20
20
  sideOffset: u,
21
- className: e(t, n, "rounded-basalt-md border border-basalt-border bg-basalt-popover px-4 py-3 text-sm text-basalt-popover-foreground shadow-md outline-hidden", r),
21
+ className: e(t, n, "basalt-floating rounded-basalt-md border border-basalt-border bg-basalt-popover p-basalt-card text-basalt-base leading-[var(--basalt-line-body)] text-basalt-popover-foreground shadow-md outline-hidden", r),
22
22
  ...p,
23
23
  children: [/* @__PURE__ */ a(i, { children: f }), d ? /* @__PURE__ */ a(s.Arrow, {
24
24
  asChild: !0,
25
- width: 20,
26
- height: 10,
25
+ width: 12,
26
+ height: 6,
27
27
  children: /* @__PURE__ */ a(h, {})
28
28
  }) : null]
29
29
  })
@@ -31,36 +31,31 @@ var c = [
31
31
  f.displayName = s.Content.displayName;
32
32
  var p = r.forwardRef(({ className: t, ...n }, r) => /* @__PURE__ */ a("h2", {
33
33
  ref: r,
34
- className: e("m-0 text-base font-medium leading-6 text-basalt-foreground", t),
34
+ className: e("m-0 mb-basalt-space-sm text-basalt-base font-medium leading-[var(--basalt-line-body)] text-basalt-popover-foreground", t),
35
35
  ...n
36
36
  }));
37
37
  p.displayName = "PopoverTitle";
38
38
  var m = r.forwardRef(({ className: t, ...n }, r) => /* @__PURE__ */ a("p", {
39
39
  ref: r,
40
- className: e("m-0 text-base leading-6 text-basalt-muted-foreground", t),
40
+ className: e("m-0 text-basalt-base leading-[var(--basalt-line-body)] text-basalt-muted-foreground", t),
41
41
  ...n
42
42
  }));
43
43
  m.displayName = "PopoverDescription";
44
44
  function h(e) {
45
- return /* @__PURE__ */ a("svg", {
46
- width: 20,
47
- height: 10,
48
- "aria-hidden": !0,
45
+ return /* @__PURE__ */ o("svg", {
49
46
  ...e,
50
- children: /* @__PURE__ */ o("svg", {
51
- width: "100%",
52
- height: "100%",
53
- viewBox: "0 0 20 10",
54
- preserveAspectRatio: "none",
55
- "aria-hidden": !0,
56
- children: [/* @__PURE__ */ a("path", {
57
- d: "M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z",
58
- className: "fill-basalt-popover"
59
- }), /* @__PURE__ */ a("path", {
60
- d: "M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z",
61
- className: "fill-basalt-border"
62
- })]
63
- })
47
+ width: 12,
48
+ height: 6,
49
+ viewBox: "0 0 12 6",
50
+ "aria-hidden": !0,
51
+ children: [/* @__PURE__ */ a("path", {
52
+ d: "M0 0H12L6 6Z",
53
+ className: "fill-basalt-popover"
54
+ }), /* @__PURE__ */ a("path", {
55
+ d: "M0 0L6 6L12 0",
56
+ fill: "none",
57
+ className: "stroke-basalt-border"
58
+ })]
64
59
  });
65
60
  }
66
61
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"popover.js","names":["React","PopoverPrimitive","POPOVER_SIDES","Popover","PopoverTrigger","PopoverClose","PopoverContent","props","cn","OVERLAY_LAYER","OVERLAY_MOTION","className","Slottable","arrow","ArrowSvg","PopoverTitle","PopoverDescription"],"sources":["../../src/components/popover.tsx"],"sourcesContent":["import * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport { Slottable } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { MENU_GAP, OVERLAY_LAYER, OVERLAY_MOTION } from \"./overlay\";\n\nexport const POPOVER_SIDES = [\"top\", \"bottom\", \"left\", \"right\"] as const;\nexport type PopoverSide = (typeof POPOVER_SIDES)[number];\n\ntype RadixPopoverProps = React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Root>;\ntype RadixPopoverTriggerProps = React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Trigger>;\ntype RadixPopoverCloseProps = React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Close>;\ntype RadixPopoverContentProps = React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>;\n\nexport interface PopoverProps\n\textends Omit<RadixPopoverProps, \"children\" | \"open\" | \"defaultOpen\" | \"onOpenChange\" | \"modal\"> {\n\t/**\n\t * Popover structure elements, typically PopoverTrigger and PopoverContent.\n\t */\n\tchildren?: React.ReactNode;\n\t/**\n\t * Controlled open state of the popover.\n\t */\n\topen?: RadixPopoverProps[\"open\"];\n\t/**\n\t * Uncontrolled initial open state of the popover.\n\t * @default false\n\t */\n\tdefaultOpen?: RadixPopoverProps[\"defaultOpen\"];\n\t/**\n\t * Callback called when the open state changes.\n\t */\n\tonOpenChange?: RadixPopoverProps[\"onOpenChange\"];\n\t/**\n\t * Whether the popover renders modally, preventing outside interaction and hiding background content from screen readers.\n\t * @default false\n\t */\n\tmodal?: RadixPopoverProps[\"modal\"];\n}\n\nexport const Popover: React.FC<PopoverProps> = PopoverPrimitive.Root;\n\nexport interface PopoverTriggerProps extends Omit<RadixPopoverTriggerProps, \"asChild\"> {\n\t/**\n\t * Change the default rendered button element to the child element, merging props and behavior.\n\t * PopoverTrigger forwards ref to HTMLButtonElement and inherits native button attributes.\n\t * @default false\n\t */\n\tasChild?: RadixPopoverTriggerProps[\"asChild\"];\n}\n\nexport const PopoverTrigger = PopoverPrimitive.Trigger;\n\nexport interface PopoverCloseProps extends Omit<RadixPopoverCloseProps, \"asChild\"> {\n\t/**\n\t * Change the default rendered button element to the child element, merging props and behavior.\n\t * PopoverClose forwards ref to HTMLButtonElement and inherits native button attributes.\n\t * @default false\n\t */\n\tasChild?: RadixPopoverCloseProps[\"asChild\"];\n}\n\nexport const PopoverClose = PopoverPrimitive.Close;\n\nexport interface PopoverContentProps\n\textends Omit<\n\t\tRadixPopoverContentProps,\n\t\t| \"side\"\n\t\t| \"sideOffset\"\n\t\t| \"align\"\n\t\t| \"alignOffset\"\n\t\t| \"avoidCollisions\"\n\t\t| \"collisionBoundary\"\n\t\t| \"collisionPadding\"\n\t\t| \"arrowPadding\"\n\t\t| \"sticky\"\n\t\t| \"hideWhenDetached\"\n\t\t| \"updatePositionStrategy\"\n\t\t| \"forceMount\"\n\t\t| \"asChild\"\n\t\t| \"onOpenAutoFocus\"\n\t\t| \"onCloseAutoFocus\"\n\t\t| \"onEscapeKeyDown\"\n\t\t| \"onPointerDownOutside\"\n\t\t| \"onFocusOutside\"\n\t\t| \"onInteractOutside\"\n\t> {\n\t/**\n\t * Preferred placement side relative to trigger.\n\t * @default \"bottom\"\n\t */\n\tside?: RadixPopoverContentProps[\"side\"];\n\t/**\n\t * Distance in pixels between trigger and floating content panel.\n\t * @default 8\n\t */\n\tsideOffset?: RadixPopoverContentProps[\"sideOffset\"];\n\t/**\n\t * Preferred alignment along the side axis.\n\t * @default \"center\"\n\t */\n\talign?: RadixPopoverContentProps[\"align\"];\n\t/**\n\t * Offset in pixels from the start or end alignment position.\n\t * @default 0\n\t */\n\talignOffset?: RadixPopoverContentProps[\"alignOffset\"];\n\t/**\n\t * Whether to reposition content to avoid viewport boundary collisions.\n\t * @default true\n\t */\n\tavoidCollisions?: RadixPopoverContentProps[\"avoidCollisions\"];\n\t/**\n\t * Element or elements bounding boundary collision calculations.\n\t * @default []\n\t */\n\tcollisionBoundary?: RadixPopoverContentProps[\"collisionBoundary\"];\n\t/**\n\t * Virtual padding from collision boundaries in pixels.\n\t * @default 0\n\t */\n\tcollisionPadding?: RadixPopoverContentProps[\"collisionPadding\"];\n\t/**\n\t * Padding in pixels between popper arrow and floating panel edge.\n\t * @default 0\n\t */\n\tarrowPadding?: RadixPopoverContentProps[\"arrowPadding\"];\n\t/**\n\t * Sticky positioning behavior along the align axis when overflowing.\n\t * @default \"partial\"\n\t */\n\tsticky?: RadixPopoverContentProps[\"sticky\"];\n\t/**\n\t * Whether to hide content completely when trigger is fully occluded.\n\t * @default false\n\t */\n\thideWhenDetached?: RadixPopoverContentProps[\"hideWhenDetached\"];\n\t/**\n\t * Strategy used to calculate and update popper position.\n\t * @default \"optimized\"\n\t */\n\tupdatePositionStrategy?: RadixPopoverContentProps[\"updatePositionStrategy\"];\n\t/**\n\t * Force mounting content in DOM for external animation controls.\n\t * When forceMount is true, the content remains mounted even when closed.\n\t * The caller is responsible for visibility transitions and unmounting after animation completes.\n\t * Note: Keeping modal content forceMounted may isolate background interactions until unmounted.\n\t */\n\tforceMount?: true;\n\t/**\n\t * Change the default rendered div element to the child element, merging props and behavior.\n\t * PopoverContent forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixPopoverContentProps[\"asChild\"];\n\t/**\n\t * Callback fired when auto-focusing on open. Can be prevented.\n\t */\n\tonOpenAutoFocus?: RadixPopoverContentProps[\"onOpenAutoFocus\"];\n\t/**\n\t * Callback fired when auto-focusing on close. Can be prevented.\n\t */\n\tonCloseAutoFocus?: RadixPopoverContentProps[\"onCloseAutoFocus\"];\n\t/**\n\t * Callback fired when the Escape key is down on the dismissable layer. Can be prevented.\n\t */\n\tonEscapeKeyDown?: RadixPopoverContentProps[\"onEscapeKeyDown\"];\n\t/**\n\t * Callback fired when a pointerdown event happens outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonPointerDownOutside?: RadixPopoverContentProps[\"onPointerDownOutside\"];\n\t/**\n\t * Callback fired when focus moves outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonFocusOutside?: RadixPopoverContentProps[\"onFocusOutside\"];\n\t/**\n\t * Callback fired when an interaction (pointerdown or focus) happens outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonInteractOutside?: RadixPopoverContentProps[\"onInteractOutside\"];\n\t/**\n\t * Show the pointing arrow.\n\t * @default true\n\t */\n\tarrow?: boolean;\n}\n\nexport const PopoverContent = React.forwardRef<\n\tReact.ElementRef<typeof PopoverPrimitive.Content>,\n\tPopoverContentProps\n>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\talign = \"center\",\n\t\t\tside = \"bottom\",\n\t\t\tsideOffset = MENU_GAP,\n\t\t\tarrow = true,\n\t\t\tchildren,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => (\n\t\t<PopoverPrimitive.Portal forceMount={props.forceMount}>\n\t\t\t<PopoverPrimitive.Content\n\t\t\t\tref={ref}\n\t\t\t\talign={align}\n\t\t\t\tside={side}\n\t\t\t\tsideOffset={sideOffset}\n\t\t\t\tclassName={cn(\n\t\t\t\t\tOVERLAY_LAYER,\n\t\t\t\t\tOVERLAY_MOTION,\n\t\t\t\t\t\"rounded-basalt-md border border-basalt-border bg-basalt-popover px-4 py-3 text-sm text-basalt-popover-foreground shadow-md outline-hidden\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<Slottable>{children}</Slottable>\n\t\t\t\t{arrow ? (\n\t\t\t\t\t<PopoverPrimitive.Arrow asChild width={20} height={10}>\n\t\t\t\t\t\t<ArrowSvg />\n\t\t\t\t\t</PopoverPrimitive.Arrow>\n\t\t\t\t) : null}\n\t\t\t</PopoverPrimitive.Content>\n\t\t</PopoverPrimitive.Portal>\n\t),\n);\nPopoverContent.displayName = PopoverPrimitive.Content.displayName;\n\nexport interface PopoverTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {}\n\nexport const PopoverTitle = React.forwardRef<HTMLHeadingElement, PopoverTitleProps>(\n\t({ className, ...props }, ref) => (\n\t\t<h2\n\t\t\tref={ref}\n\t\t\tclassName={cn(\"m-0 text-base font-medium leading-6 text-basalt-foreground\", className)}\n\t\t\t{...props}\n\t\t/>\n\t),\n);\nPopoverTitle.displayName = \"PopoverTitle\";\n\nexport interface PopoverDescriptionProps extends React.HTMLAttributes<HTMLParagraphElement> {}\n\nexport const PopoverDescription = React.forwardRef<HTMLParagraphElement, PopoverDescriptionProps>(\n\t({ className, ...props }, ref) => (\n\t\t<p\n\t\t\tref={ref}\n\t\t\tclassName={cn(\"m-0 text-base leading-6 text-basalt-muted-foreground\", className)}\n\t\t\t{...props}\n\t\t/>\n\t),\n);\nPopoverDescription.displayName = \"PopoverDescription\";\n\nfunction ArrowSvg(props: React.ComponentProps<\"svg\">) {\n\treturn (\n\t\t<svg width={20} height={10} aria-hidden {...props}>\n\t\t\t<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 20 10\" preserveAspectRatio=\"none\" aria-hidden>\n\t\t\t\t<path\n\t\t\t\t\td=\"M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z\"\n\t\t\t\t\tclassName=\"fill-basalt-popover\"\n\t\t\t\t/>\n\t\t\t\t<path\n\t\t\t\t\td=\"M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z\"\n\t\t\t\t\tclassName=\"fill-basalt-border\"\n\t\t\t\t/>\n\t\t\t</svg>\n\t\t</svg>\n\t);\n}\n"],"mappings":";;;;;;;;AAMA,IAAaE,IAAgB;CAAC;CAAO;CAAU;CAAQ;AAAO,GAkCjDC,IAAkCF,EAAiB,MAWnDG,IAAiBH,EAAiB,SAWlCI,IAAeJ,EAAiB,OA4HhCK,IAAiBN,EAAM,YAKlC,EACC,cACA,WAAQ,UACR,UAAO,UACP,gBAAA,GACA,WAAQ,IACR,aACA,GAAGO,KAEJ,MAEA,kBAACN,EAAiB,QAAlB;CAAyB,YAAYM,EAAM;CAC1C,UAAA,kBAACN,EAAiB,SAAlB;EACM;EACE;EACD;EACM;EACZ,WAAWO,EACVC,GACAC,GACA,6IACAC,CACD;EACA,GAAIJ;EAXL,UAAA,CAaC,kBAACK,GAAD,EAAY,YAAoB,CAAA,GAC/BC,IACA,kBAACZ,EAAiB,OAAlB;GAAwB,SAAA;GAAQ,OAAO;GAAI,QAAQ;GAClD,UAAA,kBAACa,GAAD,CAAW,CAAA;EACY,CAAA,IACrB,IACqB;;AACF,CAAA,CAE3B;AACA,EAAe,cAAcb,EAAiB,QAAQ;AAItD,IAAac,IAAef,EAAM,YAChC,EAAE,cAAW,GAAGO,KAAS,MACzB,kBAAC,MAAD;CACM;CACL,WAAWC,EAAG,8DAA8DG,CAAS;CACrF,GAAIJ;AACJ,CAAA,CAEH;AACA,EAAa,cAAc;AAI3B,IAAaS,IAAqBhB,EAAM,YACtC,EAAE,cAAW,GAAGO,KAAS,MACzB,kBAAC,KAAD;CACM;CACL,WAAWC,EAAG,wDAAwDG,CAAS;CAC/E,GAAIJ;AACJ,CAAA,CAEH;AACA,EAAmB,cAAc;AAEjC,SAASO,EAAS,GAAoC;CACrD,OACC,kBAAC,OAAD;EAAK,OAAO;EAAI,QAAQ;EAAI,eAAA;EAAY,GAAIP;EAC3C,UAAA,kBAAC,OAAD;GAAK,OAAM;GAAO,QAAO;GAAO,SAAQ;GAAY,qBAAoB;GAAO,eAAA;GAA/E,UAAA,CACC,kBAAC,QAAD;IACC,GAAE;IACF,WAAU;GACV,CAAA,GACD,kBAAC,QAAD;IACC,GAAE;IACF,WAAU;GACV,CAAA,CACG;;CACD,CAAA;AAEP"}
1
+ {"version":3,"file":"popover.js","names":["React","PopoverPrimitive","POPOVER_SIDES","Popover","PopoverTrigger","PopoverClose","PopoverContent","props","cn","OVERLAY_LAYER","OVERLAY_MOTION","className","Slottable","arrow","ArrowSvg","PopoverTitle","PopoverDescription"],"sources":["../../src/components/popover.tsx"],"sourcesContent":["import * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport { Slottable } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { MENU_GAP, OVERLAY_LAYER, OVERLAY_MOTION } from \"./overlay\";\n\nexport const POPOVER_SIDES = [\"top\", \"bottom\", \"left\", \"right\"] as const;\nexport type PopoverSide = (typeof POPOVER_SIDES)[number];\n\ntype RadixPopoverProps = React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Root>;\ntype RadixPopoverTriggerProps = React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Trigger>;\ntype RadixPopoverCloseProps = React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Close>;\ntype RadixPopoverContentProps = React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>;\n\nexport interface PopoverProps\n\textends Omit<RadixPopoverProps, \"children\" | \"open\" | \"defaultOpen\" | \"onOpenChange\" | \"modal\"> {\n\t/**\n\t * Popover structure elements, typically PopoverTrigger and PopoverContent.\n\t */\n\tchildren?: React.ReactNode;\n\t/**\n\t * Controlled open state of the popover.\n\t */\n\topen?: RadixPopoverProps[\"open\"];\n\t/**\n\t * Uncontrolled initial open state of the popover.\n\t * @default false\n\t */\n\tdefaultOpen?: RadixPopoverProps[\"defaultOpen\"];\n\t/**\n\t * Callback called when the open state changes.\n\t */\n\tonOpenChange?: RadixPopoverProps[\"onOpenChange\"];\n\t/**\n\t * Whether the popover renders modally, preventing outside interaction and hiding background content from screen readers.\n\t * @default false\n\t */\n\tmodal?: RadixPopoverProps[\"modal\"];\n}\n\nexport const Popover: React.FC<PopoverProps> = PopoverPrimitive.Root;\n\nexport interface PopoverTriggerProps extends Omit<RadixPopoverTriggerProps, \"asChild\"> {\n\t/**\n\t * Change the default rendered button element to the child element, merging props and behavior.\n\t * PopoverTrigger forwards ref to HTMLButtonElement and inherits native button attributes.\n\t * @default false\n\t */\n\tasChild?: RadixPopoverTriggerProps[\"asChild\"];\n}\n\nexport const PopoverTrigger = PopoverPrimitive.Trigger;\n\nexport interface PopoverCloseProps extends Omit<RadixPopoverCloseProps, \"asChild\"> {\n\t/**\n\t * Change the default rendered button element to the child element, merging props and behavior.\n\t * PopoverClose forwards ref to HTMLButtonElement and inherits native button attributes.\n\t * @default false\n\t */\n\tasChild?: RadixPopoverCloseProps[\"asChild\"];\n}\n\nexport const PopoverClose = PopoverPrimitive.Close;\n\nexport interface PopoverContentProps\n\textends Omit<\n\t\tRadixPopoverContentProps,\n\t\t| \"side\"\n\t\t| \"sideOffset\"\n\t\t| \"align\"\n\t\t| \"alignOffset\"\n\t\t| \"avoidCollisions\"\n\t\t| \"collisionBoundary\"\n\t\t| \"collisionPadding\"\n\t\t| \"arrowPadding\"\n\t\t| \"sticky\"\n\t\t| \"hideWhenDetached\"\n\t\t| \"updatePositionStrategy\"\n\t\t| \"forceMount\"\n\t\t| \"asChild\"\n\t\t| \"onOpenAutoFocus\"\n\t\t| \"onCloseAutoFocus\"\n\t\t| \"onEscapeKeyDown\"\n\t\t| \"onPointerDownOutside\"\n\t\t| \"onFocusOutside\"\n\t\t| \"onInteractOutside\"\n\t> {\n\t/**\n\t * Preferred placement side relative to trigger.\n\t * @default \"bottom\"\n\t */\n\tside?: RadixPopoverContentProps[\"side\"];\n\t/**\n\t * Distance in pixels between trigger and floating content panel.\n\t * @default 8\n\t */\n\tsideOffset?: RadixPopoverContentProps[\"sideOffset\"];\n\t/**\n\t * Preferred alignment along the side axis.\n\t * @default \"center\"\n\t */\n\talign?: RadixPopoverContentProps[\"align\"];\n\t/**\n\t * Offset in pixels from the start or end alignment position.\n\t * @default 0\n\t */\n\talignOffset?: RadixPopoverContentProps[\"alignOffset\"];\n\t/**\n\t * Whether to reposition content to avoid viewport boundary collisions.\n\t * @default true\n\t */\n\tavoidCollisions?: RadixPopoverContentProps[\"avoidCollisions\"];\n\t/**\n\t * Element or elements bounding boundary collision calculations.\n\t * @default []\n\t */\n\tcollisionBoundary?: RadixPopoverContentProps[\"collisionBoundary\"];\n\t/**\n\t * Virtual padding from collision boundaries in pixels.\n\t * @default 0\n\t */\n\tcollisionPadding?: RadixPopoverContentProps[\"collisionPadding\"];\n\t/**\n\t * Padding in pixels between popper arrow and floating panel edge.\n\t * @default 0\n\t */\n\tarrowPadding?: RadixPopoverContentProps[\"arrowPadding\"];\n\t/**\n\t * Sticky positioning behavior along the align axis when overflowing.\n\t * @default \"partial\"\n\t */\n\tsticky?: RadixPopoverContentProps[\"sticky\"];\n\t/**\n\t * Whether to hide content completely when trigger is fully occluded.\n\t * @default false\n\t */\n\thideWhenDetached?: RadixPopoverContentProps[\"hideWhenDetached\"];\n\t/**\n\t * Strategy used to calculate and update popper position.\n\t * @default \"optimized\"\n\t */\n\tupdatePositionStrategy?: RadixPopoverContentProps[\"updatePositionStrategy\"];\n\t/**\n\t * Force mounting content in DOM for external animation controls.\n\t * When forceMount is true, the content remains mounted even when closed.\n\t * The caller is responsible for visibility transitions and unmounting after animation completes.\n\t * Note: Keeping modal content forceMounted may isolate background interactions until unmounted.\n\t */\n\tforceMount?: true;\n\t/**\n\t * Change the default rendered div element to the child element, merging props and behavior.\n\t * PopoverContent forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixPopoverContentProps[\"asChild\"];\n\t/**\n\t * Callback fired when auto-focusing on open. Can be prevented.\n\t */\n\tonOpenAutoFocus?: RadixPopoverContentProps[\"onOpenAutoFocus\"];\n\t/**\n\t * Callback fired when auto-focusing on close. Can be prevented.\n\t */\n\tonCloseAutoFocus?: RadixPopoverContentProps[\"onCloseAutoFocus\"];\n\t/**\n\t * Callback fired when the Escape key is down on the dismissable layer. Can be prevented.\n\t */\n\tonEscapeKeyDown?: RadixPopoverContentProps[\"onEscapeKeyDown\"];\n\t/**\n\t * Callback fired when a pointerdown event happens outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonPointerDownOutside?: RadixPopoverContentProps[\"onPointerDownOutside\"];\n\t/**\n\t * Callback fired when focus moves outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonFocusOutside?: RadixPopoverContentProps[\"onFocusOutside\"];\n\t/**\n\t * Callback fired when an interaction (pointerdown or focus) happens outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonInteractOutside?: RadixPopoverContentProps[\"onInteractOutside\"];\n\t/**\n\t * Show the pointing arrow.\n\t * @default true\n\t */\n\tarrow?: boolean;\n}\n\nexport const PopoverContent = React.forwardRef<\n\tReact.ElementRef<typeof PopoverPrimitive.Content>,\n\tPopoverContentProps\n>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\talign = \"center\",\n\t\t\tside = \"bottom\",\n\t\t\tsideOffset = MENU_GAP,\n\t\t\tarrow = true,\n\t\t\tchildren,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => (\n\t\t<PopoverPrimitive.Portal forceMount={props.forceMount}>\n\t\t\t<PopoverPrimitive.Content\n\t\t\t\tref={ref}\n\t\t\t\talign={align}\n\t\t\t\tside={side}\n\t\t\t\tsideOffset={sideOffset}\n\t\t\t\tclassName={cn(\n\t\t\t\t\tOVERLAY_LAYER,\n\t\t\t\t\tOVERLAY_MOTION,\n\t\t\t\t\t\"basalt-floating rounded-basalt-md border border-basalt-border bg-basalt-popover p-basalt-card text-basalt-base leading-[var(--basalt-line-body)] text-basalt-popover-foreground shadow-md outline-hidden\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<Slottable>{children}</Slottable>\n\t\t\t\t{arrow ? (\n\t\t\t\t\t<PopoverPrimitive.Arrow asChild width={12} height={6}>\n\t\t\t\t\t\t<ArrowSvg />\n\t\t\t\t\t</PopoverPrimitive.Arrow>\n\t\t\t\t) : null}\n\t\t\t</PopoverPrimitive.Content>\n\t\t</PopoverPrimitive.Portal>\n\t),\n);\nPopoverContent.displayName = PopoverPrimitive.Content.displayName;\n\nexport interface PopoverTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {}\n\nexport const PopoverTitle = React.forwardRef<HTMLHeadingElement, PopoverTitleProps>(\n\t({ className, ...props }, ref) => (\n\t\t<h2\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\t\"m-0 mb-basalt-space-sm text-basalt-base font-medium leading-[var(--basalt-line-body)] text-basalt-popover-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t),\n);\nPopoverTitle.displayName = \"PopoverTitle\";\n\nexport interface PopoverDescriptionProps extends React.HTMLAttributes<HTMLParagraphElement> {}\n\nexport const PopoverDescription = React.forwardRef<HTMLParagraphElement, PopoverDescriptionProps>(\n\t({ className, ...props }, ref) => (\n\t\t<p\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\t\"m-0 text-basalt-base leading-[var(--basalt-line-body)] text-basalt-muted-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t),\n);\nPopoverDescription.displayName = \"PopoverDescription\";\n\nfunction ArrowSvg(props: React.ComponentProps<\"svg\">) {\n\treturn (\n\t\t<svg {...props} width={12} height={6} viewBox=\"0 0 12 6\" aria-hidden>\n\t\t\t<path d=\"M0 0H12L6 6Z\" className=\"fill-basalt-popover\" />\n\t\t\t<path d=\"M0 0L6 6L12 0\" fill=\"none\" className=\"stroke-basalt-border\" />\n\t\t</svg>\n\t);\n}\n"],"mappings":";;;;;;;;AAMA,IAAaE,IAAgB;CAAC;CAAO;CAAU;CAAQ;AAAO,GAkCjDC,IAAkCF,EAAiB,MAWnDG,IAAiBH,EAAiB,SAWlCI,IAAeJ,EAAiB,OA4HhCK,IAAiBN,EAAM,YAKlC,EACC,cACA,WAAQ,UACR,UAAO,UACP,gBAAA,GACA,WAAQ,IACR,aACA,GAAGO,KAEJ,MAEA,kBAACN,EAAiB,QAAlB;CAAyB,YAAYM,EAAM;CAC1C,UAAA,kBAACN,EAAiB,SAAlB;EACM;EACE;EACD;EACM;EACZ,WAAWO,EACVC,GACAC,GACA,4MACAC,CACD;EACA,GAAIJ;EAXL,UAAA,CAaC,kBAACK,GAAD,EAAY,YAAoB,CAAA,GAC/BC,IACA,kBAACZ,EAAiB,OAAlB;GAAwB,SAAA;GAAQ,OAAO;GAAI,QAAQ;GAClD,UAAA,kBAACa,GAAD,CAAW,CAAA;EACY,CAAA,IACrB,IACqB;;AACF,CAAA,CAE3B;AACA,EAAe,cAAcb,EAAiB,QAAQ;AAItD,IAAac,IAAef,EAAM,YAChC,EAAE,cAAW,GAAGO,KAAS,MACzB,kBAAC,MAAD;CACM;CACL,WAAWC,EACV,wHACAG,CACD;CACA,GAAIJ;AACJ,CAAA,CAEH;AACA,EAAa,cAAc;AAI3B,IAAaS,IAAqBhB,EAAM,YACtC,EAAE,cAAW,GAAGO,KAAS,MACzB,kBAAC,KAAD;CACM;CACL,WAAWC,EACV,uFACAG,CACD;CACA,GAAIJ;AACJ,CAAA,CAEH;AACA,EAAmB,cAAc;AAEjC,SAASO,EAAS,GAAoC;CACrD,OACC,kBAAC,OAAD;EAAK,GAAIP;EAAO,OAAO;EAAI,QAAQ;EAAG,SAAQ;EAAW,eAAA;EAAzD,UAAA,CACC,kBAAC,QAAD;GAAM,GAAE;GAAe,WAAU;EAAuB,CAAA,GACxD,kBAAC,QAAD;GAAM,GAAE;GAAgB,MAAK;GAAO,WAAU;EAAwB,CAAA,CAClE;;AAEP"}
@@ -0,0 +1,16 @@
1
+ import { type ChatComposerProps } from "./chat-composer.js";
2
+ export type PromptModel = {
3
+ id: string;
4
+ label: string;
5
+ disabled?: boolean;
6
+ };
7
+ export interface PromptBarProps extends Omit<ChatComposerProps, "toolbar"> {
8
+ models: readonly PromptModel[];
9
+ model: string;
10
+ onModelChange: (model: string) => void;
11
+ reasoning?: boolean;
12
+ onReasoningChange?: (value: boolean) => void;
13
+ webSearch?: boolean;
14
+ onWebSearchChange?: (value: boolean) => void;
15
+ }
16
+ export declare function PromptBar({ models, model, onModelChange, reasoning, onReasoningChange, webSearch, onWebSearchChange, ...props }: PromptBarProps): import("react").JSX.Element;
@@ -0,0 +1,49 @@
1
+ "use client";
2
+ import { ChatComposer as e } from "./chat-composer.js";
3
+ import { Select as t, SelectContent as n, SelectItem as r, SelectTrigger as i, SelectValue as a } from "./select.js";
4
+ import { Toggle as o } from "./toggle.js";
5
+ import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
6
+ //#region src/components/prompt-bar.tsx
7
+ function u({ models: u, model: d, onModelChange: f, reasoning: p, onReasoningChange: m, webSearch: h, onWebSearchChange: g, ..._ }) {
8
+ let v = _.disabled || _.streaming;
9
+ return /* @__PURE__ */ c(e, {
10
+ ..._,
11
+ toolbar: /* @__PURE__ */ l(s, { children: [
12
+ /* @__PURE__ */ l(t, {
13
+ value: d,
14
+ onValueChange: f,
15
+ disabled: v,
16
+ children: [/* @__PURE__ */ c(i, {
17
+ size: "sm",
18
+ "aria-label": "Model",
19
+ className: "w-auto min-w-0 max-w-full border-0 bg-transparent shadow-none",
20
+ children: /* @__PURE__ */ c(a, {})
21
+ }), /* @__PURE__ */ c(n, { children: u.map((e) => /* @__PURE__ */ c(r, {
22
+ value: e.id,
23
+ disabled: e.disabled,
24
+ children: e.label
25
+ }, e.id)) })]
26
+ }),
27
+ m && /* @__PURE__ */ c(o, {
28
+ size: "sm",
29
+ pressed: p,
30
+ onPressedChange: m,
31
+ disabled: v,
32
+ "aria-label": "Reasoning",
33
+ children: "Think"
34
+ }),
35
+ g && /* @__PURE__ */ c(o, {
36
+ size: "sm",
37
+ pressed: h,
38
+ onPressedChange: g,
39
+ disabled: v,
40
+ "aria-label": "Web search",
41
+ children: "Search"
42
+ })
43
+ ] })
44
+ });
45
+ }
46
+ //#endregion
47
+ export { u as PromptBar };
48
+
49
+ //# sourceMappingURL=prompt-bar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-bar.js","names":["_Fragment","PromptBar","props","disabled","ChatComposer","Fragment","Select","model","onModelChange","SelectTrigger","SelectValue","SelectContent","models","SelectItem","item","onReasoningChange","Toggle","reasoning","onWebSearchChange","webSearch"],"sources":["../../src/components/prompt-bar.tsx"],"sourcesContent":["import { ChatComposer, type ChatComposerProps } from \"./chat-composer\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"./select\";\nimport { Toggle } from \"./toggle\";\n\nexport type PromptModel = { id: string; label: string; disabled?: boolean };\nexport interface PromptBarProps extends Omit<ChatComposerProps, \"toolbar\"> {\n\tmodels: readonly PromptModel[];\n\tmodel: string;\n\tonModelChange: (model: string) => void;\n\treasoning?: boolean;\n\tonReasoningChange?: (value: boolean) => void;\n\twebSearch?: boolean;\n\tonWebSearchChange?: (value: boolean) => void;\n}\n\nexport function PromptBar({\n\tmodels,\n\tmodel,\n\tonModelChange,\n\treasoning,\n\tonReasoningChange,\n\twebSearch,\n\tonWebSearchChange,\n\t...props\n}: PromptBarProps) {\n\tconst disabled = props.disabled || props.streaming;\n\treturn (\n\t\t<ChatComposer\n\t\t\t{...props}\n\t\t\ttoolbar={\n\t\t\t\t<>\n\t\t\t\t\t<Select value={model} onValueChange={onModelChange} disabled={disabled}>\n\t\t\t\t\t\t<SelectTrigger\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\taria-label=\"Model\"\n\t\t\t\t\t\t\tclassName=\"w-auto min-w-0 max-w-full border-0 bg-transparent shadow-none\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<SelectValue />\n\t\t\t\t\t\t</SelectTrigger>\n\t\t\t\t\t\t<SelectContent>\n\t\t\t\t\t\t\t{models.map((item) => (\n\t\t\t\t\t\t\t\t<SelectItem key={item.id} value={item.id} disabled={item.disabled}>\n\t\t\t\t\t\t\t\t\t{item.label}\n\t\t\t\t\t\t\t\t</SelectItem>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</SelectContent>\n\t\t\t\t\t</Select>\n\t\t\t\t\t{onReasoningChange && (\n\t\t\t\t\t\t<Toggle\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tpressed={reasoning}\n\t\t\t\t\t\t\tonPressedChange={onReasoningChange}\n\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\taria-label=\"Reasoning\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tThink\n\t\t\t\t\t\t</Toggle>\n\t\t\t\t\t)}\n\t\t\t\t\t{onWebSearchChange && (\n\t\t\t\t\t\t<Toggle\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tpressed={webSearch}\n\t\t\t\t\t\t\tonPressedChange={onWebSearchChange}\n\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\taria-label=\"Web search\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tSearch\n\t\t\t\t\t\t</Toggle>\n\t\t\t\t\t)}\n\t\t\t\t</>\n\t\t\t}\n\t\t/>\n\t);\n}\n"],"mappings":";;;;;;AAeA,SAAgBC,EAAU,EACzB,WACA,UACA,kBACA,cACA,sBACA,cACA,sBACA,GAAGC,KACe;CAClB,IAAMC,IAAWD,EAAM,YAAYA,EAAM;CACzC,OACC,kBAACE,GAAD;EACC,GAAIF;EACJ,SACC,kBAAAF,GAAA,EAAA,UAAA;GACC,kBAACM,GAAD;IAAQ,OAAOC;IAAO,eAAeC;IAAyB;IAA9D,UAAA,CACC,kBAACC,GAAD;KACC,MAAK;KACL,cAAW;KACX,WAAU;KAEV,UAAA,kBAACC,GAAD,CAAc,CAAA;IACA,CAAA,GACf,kBAACC,GAAD,EAAA,UACEC,EAAO,KAAK,MACZ,kBAACC,GAAD;KAA0B,OAAOC,EAAK;KAAI,UAAUA,EAAK;KACvD,UAAAA,EAAK;IACK,GAFKA,EAAK,EAEV,CACZ,EACa,CAAA,CACR;;GACPC,KACA,kBAACC,GAAD;IACC,MAAK;IACL,SAASC;IACT,iBAAiBF;IACP;IACV,cAAW;IACX,UAAA;GAEO,CAAA;GAERG,KACA,kBAACF,GAAD;IACC,MAAK;IACL,SAASG;IACT,iBAAiBD;IACP;IACV,cAAW;IACX,UAAA;GAEO,CAAA;EAER,EAAA,CAAA;CAEH,CAAA;AAEH"}
@@ -8,14 +8,14 @@ import { jsx as a, jsxs as o } from "react/jsx-runtime";
8
8
  import * as s from "@radix-ui/react-radio-group";
9
9
  //#region src/components/radio.tsx
10
10
  var c = {
11
- sm: "h-3 w-3",
12
- default: "h-4 w-4"
11
+ sm: "h-basalt-check-sm w-basalt-check-sm",
12
+ default: "h-basalt-check w-basalt-check"
13
13
  }, l = {
14
- sm: "h-1.5 w-1.5 fill-current text-current",
15
- default: "h-2.5 w-2.5 fill-current text-current"
14
+ sm: "h-basalt-1_5 w-basalt-1_5 fill-current text-current",
15
+ default: "h-basalt-2_5 w-basalt-2_5 fill-current text-current"
16
16
  }, u = r.forwardRef(({ className: t, ...n }, r) => /* @__PURE__ */ a("legend", {
17
17
  ref: r,
18
- className: e("text-sm font-medium text-basalt-foreground", t),
18
+ className: e("mb-basalt-field-gap text-basalt-base font-medium leading-[var(--basalt-line-body)] text-basalt-foreground", t),
19
19
  ...n
20
20
  }));
21
21
  u.displayName = "Radio.Legend";
@@ -37,13 +37,13 @@ var d = r.forwardRef(({ className: t, error: n, disabled: i = !1, children: c, "
37
37
  }), S = [x.map((e) => e.props.id).filter(Boolean).join(" "), f].filter(Boolean).join(" ") || void 0, C = [g ? _ : null, l].filter(Boolean).join(" ") || void 0;
38
38
  return /* @__PURE__ */ o("fieldset", {
39
39
  disabled: i,
40
- className: "flex flex-col gap-2",
40
+ className: "basalt-ui flex flex-col gap-basalt-field-gap",
41
41
  children: [
42
42
  x,
43
43
  /* @__PURE__ */ a(s.Root, {
44
44
  ref: m,
45
45
  disabled: i,
46
- className: e("grid gap-2", t),
46
+ className: e("grid gap-basalt-space-lg", t),
47
47
  ...p,
48
48
  "aria-labelledby": S,
49
49
  "aria-describedby": C,
@@ -52,7 +52,7 @@ var d = r.forwardRef(({ className: t, error: n, disabled: i = !1, children: c, "
52
52
  }),
53
53
  g ? /* @__PURE__ */ a("p", {
54
54
  id: _,
55
- className: "text-xs text-basalt-destructive",
55
+ className: "text-basalt-sm text-basalt-destructive",
56
56
  role: "alert",
57
57
  children: n
58
58
  }) : null
@@ -62,7 +62,7 @@ var d = r.forwardRef(({ className: t, error: n, disabled: i = !1, children: c, "
62
62
  d.displayName = "Radio.Group";
63
63
  var f = r.forwardRef(({ className: r, size: o = "default", ...u }, d) => /* @__PURE__ */ a(s.Item, {
64
64
  ref: d,
65
- className: e(t, "aspect-square shrink-0 rounded-full border border-basalt-primary text-basalt-primary disabled:cursor-not-allowed disabled:opacity-50", c[o], n, r),
65
+ className: e(t, "aspect-square shrink-0 rounded-basalt-full border border-basalt-primary text-basalt-primary disabled:cursor-not-allowed disabled:opacity-50", c[o], n, r),
66
66
  ...u,
67
67
  children: /* @__PURE__ */ a(s.Indicator, {
68
68
  className: "flex items-center justify-center",
@@ -1 +1 @@
1
- {"version":3,"file":"radio.js","names":["React","RadioGroupPrimitive","RADIO_SIZE_CLASS","RADIO_INDICATOR_CLASS","RadioLegend","props","cn","className","RadioGroup","describedBy","ariaInvalid","labelledBy","generatedId","invalid","error","errorId","defaultLegendId","legends","items","children","child","labeledLegends","legendId","legend","index","mergedLabelledBy","mergedDescribedBy","RadioRoot","BASALT_UI_CLASS","size","FOCUS_RING","Circle","Radio"],"sources":["../../src/components/radio.tsx"],"sourcesContent":["import * as RadioGroupPrimitive from \"@radix-ui/react-radio-group\";\nimport { Circle } from \"lucide-react\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { FOCUS_RING } from \"./overlay\";\n\nexport type RadioSize = \"sm\" | \"default\";\n\nconst RADIO_SIZE_CLASS: Record<RadioSize, string> = {\n\tsm: \"h-3 w-3\",\n\tdefault: \"h-4 w-4\",\n};\n\nconst RADIO_INDICATOR_CLASS: Record<RadioSize, string> = {\n\tsm: \"h-1.5 w-1.5 fill-current text-current\",\n\tdefault: \"h-2.5 w-2.5 fill-current text-current\",\n};\n\nexport type RadioGroupProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>,\n\t\"disabled\" | \"value\" | \"defaultValue\" | \"onValueChange\"\n> & {\n\t/**\n\t * The controlled selected value.\n\t */\n\tvalue?: string;\n\t/**\n\t * The initially selected value.\n\t */\n\tdefaultValue?: string;\n\t/**\n\t * Called when the selected value changes.\n\t */\n\tonValueChange?: (value: string) => void;\n\t/**\n\t * Marks the group invalid and shows alert copy.\n\t */\n\terror?: React.ReactNode;\n\t/**\n\t * Disable every item in the group.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n};\n\nexport type RadioLegendProps = React.ComponentPropsWithoutRef<\"legend\">;\n\nexport type RadioProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>,\n\t\"value\"\n> & {\n\t/**\n\t * The value associated with the radio item.\n\t */\n\tvalue: string;\n\t/**\n\t * The visual size of the radio.\n\t * @default default\n\t */\n\tsize?: RadioSize;\n};\n\nconst RadioLegend = React.forwardRef<HTMLLegendElement, RadioLegendProps>(\n\t({ className, ...props }, ref) => (\n\t\t<legend\n\t\t\tref={ref}\n\t\t\tclassName={cn(\"text-sm font-medium text-basalt-foreground\", className)}\n\t\t\t{...props}\n\t\t/>\n\t),\n);\nRadioLegend.displayName = \"Radio.Legend\";\n\nexport const RadioGroup = React.forwardRef<\n\tReact.ElementRef<typeof RadioGroupPrimitive.Root>,\n\tRadioGroupProps\n>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\terror,\n\t\t\tdisabled = false,\n\t\t\tchildren,\n\t\t\t\"aria-describedby\": describedBy,\n\t\t\t\"aria-invalid\": ariaInvalid,\n\t\t\t\"aria-labelledby\": labelledBy,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst generatedId = React.useId();\n\t\tconst invalid = Boolean(error);\n\t\tconst errorId = `${generatedId}-error`;\n\t\tconst defaultLegendId = `${generatedId}-legend`;\n\t\tconst legends: React.ReactElement<RadioLegendProps>[] = [];\n\t\tconst items: React.ReactNode[] = [];\n\t\tReact.Children.forEach(children, (child) => {\n\t\t\tif (React.isValidElement(child) && child.type === RadioLegend) {\n\t\t\t\tlegends.push(child as React.ReactElement<RadioLegendProps>);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\titems.push(child);\n\t\t});\n\t\tconst labeledLegends = legends.map((legend, index) => {\n\t\t\tconst legendId =\n\t\t\t\tlegend.props.id ?? (index === 0 ? defaultLegendId : `${defaultLegendId}-${index}`);\n\t\t\treturn React.cloneElement(legend, { key: legendId, id: legendId });\n\t\t});\n\t\tconst legendIds = labeledLegends\n\t\t\t.map((legend) => legend.props.id)\n\t\t\t.filter(Boolean)\n\t\t\t.join(\" \");\n\t\tconst mergedLabelledBy = [legendIds, labelledBy].filter(Boolean).join(\" \") || undefined;\n\t\tconst mergedDescribedBy =\n\t\t\t[invalid ? errorId : null, describedBy].filter(Boolean).join(\" \") || undefined;\n\t\treturn (\n\t\t\t<fieldset disabled={disabled} className=\"flex flex-col gap-2\">\n\t\t\t\t{labeledLegends}\n\t\t\t\t<RadioGroupPrimitive.Root\n\t\t\t\t\tref={ref}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tclassName={cn(\"grid gap-2\", className)}\n\t\t\t\t\t{...props}\n\t\t\t\t\taria-labelledby={mergedLabelledBy}\n\t\t\t\t\taria-describedby={mergedDescribedBy}\n\t\t\t\t\taria-invalid={invalid ? true : ariaInvalid}\n\t\t\t\t>\n\t\t\t\t\t{items}\n\t\t\t\t</RadioGroupPrimitive.Root>\n\t\t\t\t{invalid ? (\n\t\t\t\t\t<p id={errorId} className=\"text-xs text-basalt-destructive\" role=\"alert\">\n\t\t\t\t\t\t{error}\n\t\t\t\t\t</p>\n\t\t\t\t) : null}\n\t\t\t</fieldset>\n\t\t);\n\t},\n);\nRadioGroup.displayName = \"Radio.Group\";\n\nconst RadioRoot = React.forwardRef<React.ElementRef<typeof RadioGroupPrimitive.Item>, RadioProps>(\n\t({ className, size = \"default\", ...props }, ref) => (\n\t\t<RadioGroupPrimitive.Item\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"aspect-square shrink-0 rounded-full border border-basalt-primary text-basalt-primary disabled:cursor-not-allowed disabled:opacity-50\",\n\t\t\t\tRADIO_SIZE_CLASS[size],\n\t\t\t\tFOCUS_RING,\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<RadioGroupPrimitive.Indicator className=\"flex items-center justify-center\">\n\t\t\t\t<Circle className={RADIO_INDICATOR_CLASS[size]} />\n\t\t\t</RadioGroupPrimitive.Indicator>\n\t\t</RadioGroupPrimitive.Item>\n\t),\n);\nRadioRoot.displayName = RadioGroupPrimitive.Item.displayName;\n\nexport const Radio = Object.assign(RadioRoot, {\n\tGroup: RadioGroup,\n\tLegend: RadioLegend,\n\tItem: RadioRoot,\n});\n"],"mappings":";;;;;;;;;AASA,IAAME,IAA8C;CACnD,IAAI;CACJ,SAAS;AACV,GAEMC,IAAmD;CACxD,IAAI;CACJ,SAAS;AACV,GA8CMC,IAAcJ,EAAM,YACxB,EAAE,cAAW,GAAGK,KAAS,MACzB,kBAAC,UAAD;CACM;CACL,WAAWC,EAAG,8CAA8CC,CAAS;CACrE,GAAIF;AACJ,CAAA,CAEH;AACA,EAAY,cAAc;AAE1B,IAAaG,IAAaR,EAAM,YAK9B,EACC,cACA,UACA,cAAW,IACX,aACA,oBAAoBS,GACpB,gBAAgBC,GAChB,mBAAmBC,GACnB,GAAGN,KAEJ,MACI;CACJ,IAAMO,IAAcZ,EAAM,MAAM,GAC1Ba,IAAU,EAAQC,GAClBC,IAAU,GAAGH,EAAY,SACzBI,IAAkB,GAAGJ,EAAY,UACjCK,IAAkD,CAAC,GACnDC,IAA2B,CAAC;CAClC,EAAM,SAAS,QAAQC,IAAW,MAAU;EAC3C,IAAInB,EAAM,eAAeoB,CAAK,KAAKA,EAAM,SAAShB,GAAa;GAC9D,EAAQ,KAAKgB,CAA6C;GAC1D;EACD;EACA,EAAM,KAAKA,CAAK;CACjB,CAAC;CACD,IAAMC,IAAiBJ,EAAQ,KAAK,GAAQ,MAAU;EACrD,IAAMK,IACLC,EAAO,MAAM,OAAOC,MAAU,IAAIR,IAAkB,GAAGA,EAAgB,GAAGQ;EAC3E,OAAOxB,EAAM,aAAauB,GAAQ;GAAE,KAAKD;GAAU,IAAIA;EAAS,CAAC;CAClE,CAAC,GAKKG,IAAmB,CAJPJ,EAChB,KAAK,MAAWE,EAAO,MAAM,EAAE,CAAC,CAChC,OAAO,OAAO,CAAC,CACf,KAAK,GACmB,GAAWZ,CAAU,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,KAAK,KAAA,GACxEe,IACL,CAACb,IAAUE,IAAU,MAAMN,CAAW,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,KAAK,KAAA;CACtE,OACC,kBAAC,YAAD;EAAoB;EAAU,WAAU;EAAxC,UAAA;GACEY;GACD,kBAACpB,EAAoB,MAArB;IACM;IACK;IACV,WAAWK,EAAG,cAAcC,CAAS;IACrC,GAAIF;IACJ,mBAAiBoB;IACjB,oBAAkBC;IAClB,gBAAcb,IAAU,KAAOH;IAE9B,UAAAQ;GACwB,CAAA;GACzBL,IACA,kBAAC,KAAD;IAAG,IAAIE;IAAS,WAAU;IAAkC,MAAK;IAC/D,UAAAD;GACC,CAAA,IACA;EACK;;AAEZ,CACD;AACA,EAAW,cAAc;AAEzB,IAAMa,IAAY3B,EAAM,YACtB,EAAE,cAAW,UAAO,WAAW,GAAGK,KAAS,MAC3C,kBAACJ,EAAoB,MAArB;CACM;CACL,WAAWK,EACVsB,GACA,wIACA1B,EAAiB2B,IACjBC,GACAvB,CACD;CACA,GAAIF;CAEJ,UAAA,kBAACJ,EAAoB,WAArB;EAA+B,WAAU;EACxC,UAAA,kBAAC8B,GAAD,EAAQ,WAAW5B,EAAsB0B,GAAQ,CAAA;CACnB,CAAA;AACN,CAAA,CAE5B;AACA,EAAU,cAAc5B,EAAoB,KAAK;AAEjD,IAAa+B,IAAQ,OAAO,OAAOL,GAAW;CAC7C,OAAOnB;CACP,QAAQJ;CACR,MAAMuB;AACP,CAAC"}
1
+ {"version":3,"file":"radio.js","names":["React","RadioGroupPrimitive","RADIO_SIZE_CLASS","RADIO_INDICATOR_CLASS","RadioLegend","props","cn","className","RadioGroup","describedBy","ariaInvalid","labelledBy","generatedId","invalid","error","errorId","defaultLegendId","legends","items","children","child","labeledLegends","legendId","legend","index","mergedLabelledBy","mergedDescribedBy","RadioRoot","BASALT_UI_CLASS","size","FOCUS_RING","Circle","Radio"],"sources":["../../src/components/radio.tsx"],"sourcesContent":["import * as RadioGroupPrimitive from \"@radix-ui/react-radio-group\";\nimport { Circle } from \"lucide-react\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { FOCUS_RING } from \"./overlay\";\n\nexport type RadioSize = \"sm\" | \"default\";\n\nconst RADIO_SIZE_CLASS: Record<RadioSize, string> = {\n\tsm: \"h-basalt-check-sm w-basalt-check-sm\",\n\tdefault: \"h-basalt-check w-basalt-check\",\n};\n\nconst RADIO_INDICATOR_CLASS: Record<RadioSize, string> = {\n\tsm: \"h-basalt-1_5 w-basalt-1_5 fill-current text-current\",\n\tdefault: \"h-basalt-2_5 w-basalt-2_5 fill-current text-current\",\n};\n\nexport type RadioGroupProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>,\n\t\"disabled\" | \"value\" | \"defaultValue\" | \"onValueChange\"\n> & {\n\t/**\n\t * The controlled selected value.\n\t */\n\tvalue?: string;\n\t/**\n\t * The initially selected value.\n\t */\n\tdefaultValue?: string;\n\t/**\n\t * Called when the selected value changes.\n\t */\n\tonValueChange?: (value: string) => void;\n\t/**\n\t * Marks the group invalid and shows alert copy.\n\t */\n\terror?: React.ReactNode;\n\t/**\n\t * Disable every item in the group.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n};\n\nexport type RadioLegendProps = React.ComponentPropsWithoutRef<\"legend\">;\n\nexport type RadioProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>,\n\t\"value\"\n> & {\n\t/**\n\t * The value associated with the radio item.\n\t */\n\tvalue: string;\n\t/**\n\t * The visual size of the radio.\n\t * @default default\n\t */\n\tsize?: RadioSize;\n};\n\nconst RadioLegend = React.forwardRef<HTMLLegendElement, RadioLegendProps>(\n\t({ className, ...props }, ref) => (\n\t\t<legend\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\t\"mb-basalt-field-gap text-basalt-base font-medium leading-[var(--basalt-line-body)] text-basalt-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t),\n);\nRadioLegend.displayName = \"Radio.Legend\";\n\nexport const RadioGroup = React.forwardRef<\n\tReact.ElementRef<typeof RadioGroupPrimitive.Root>,\n\tRadioGroupProps\n>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\terror,\n\t\t\tdisabled = false,\n\t\t\tchildren,\n\t\t\t\"aria-describedby\": describedBy,\n\t\t\t\"aria-invalid\": ariaInvalid,\n\t\t\t\"aria-labelledby\": labelledBy,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst generatedId = React.useId();\n\t\tconst invalid = Boolean(error);\n\t\tconst errorId = `${generatedId}-error`;\n\t\tconst defaultLegendId = `${generatedId}-legend`;\n\t\tconst legends: React.ReactElement<RadioLegendProps>[] = [];\n\t\tconst items: React.ReactNode[] = [];\n\t\tReact.Children.forEach(children, (child) => {\n\t\t\tif (React.isValidElement(child) && child.type === RadioLegend) {\n\t\t\t\tlegends.push(child as React.ReactElement<RadioLegendProps>);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\titems.push(child);\n\t\t});\n\t\tconst labeledLegends = legends.map((legend, index) => {\n\t\t\tconst legendId =\n\t\t\t\tlegend.props.id ?? (index === 0 ? defaultLegendId : `${defaultLegendId}-${index}`);\n\t\t\treturn React.cloneElement(legend, { key: legendId, id: legendId });\n\t\t});\n\t\tconst legendIds = labeledLegends\n\t\t\t.map((legend) => legend.props.id)\n\t\t\t.filter(Boolean)\n\t\t\t.join(\" \");\n\t\tconst mergedLabelledBy = [legendIds, labelledBy].filter(Boolean).join(\" \") || undefined;\n\t\tconst mergedDescribedBy =\n\t\t\t[invalid ? errorId : null, describedBy].filter(Boolean).join(\" \") || undefined;\n\t\treturn (\n\t\t\t<fieldset disabled={disabled} className=\"basalt-ui flex flex-col gap-basalt-field-gap\">\n\t\t\t\t{labeledLegends}\n\t\t\t\t<RadioGroupPrimitive.Root\n\t\t\t\t\tref={ref}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tclassName={cn(\"grid gap-basalt-space-lg\", className)}\n\t\t\t\t\t{...props}\n\t\t\t\t\taria-labelledby={mergedLabelledBy}\n\t\t\t\t\taria-describedby={mergedDescribedBy}\n\t\t\t\t\taria-invalid={invalid ? true : ariaInvalid}\n\t\t\t\t>\n\t\t\t\t\t{items}\n\t\t\t\t</RadioGroupPrimitive.Root>\n\t\t\t\t{invalid ? (\n\t\t\t\t\t<p id={errorId} className=\"text-basalt-sm text-basalt-destructive\" role=\"alert\">\n\t\t\t\t\t\t{error}\n\t\t\t\t\t</p>\n\t\t\t\t) : null}\n\t\t\t</fieldset>\n\t\t);\n\t},\n);\nRadioGroup.displayName = \"Radio.Group\";\n\nconst RadioRoot = React.forwardRef<React.ElementRef<typeof RadioGroupPrimitive.Item>, RadioProps>(\n\t({ className, size = \"default\", ...props }, ref) => (\n\t\t<RadioGroupPrimitive.Item\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"aspect-square shrink-0 rounded-basalt-full border border-basalt-primary text-basalt-primary disabled:cursor-not-allowed disabled:opacity-50\",\n\t\t\t\tRADIO_SIZE_CLASS[size],\n\t\t\t\tFOCUS_RING,\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<RadioGroupPrimitive.Indicator className=\"flex items-center justify-center\">\n\t\t\t\t<Circle className={RADIO_INDICATOR_CLASS[size]} />\n\t\t\t</RadioGroupPrimitive.Indicator>\n\t\t</RadioGroupPrimitive.Item>\n\t),\n);\nRadioRoot.displayName = RadioGroupPrimitive.Item.displayName;\n\nexport const Radio = Object.assign(RadioRoot, {\n\tGroup: RadioGroup,\n\tLegend: RadioLegend,\n\tItem: RadioRoot,\n});\n"],"mappings":";;;;;;;;;AASA,IAAME,IAA8C;CACnD,IAAI;CACJ,SAAS;AACV,GAEMC,IAAmD;CACxD,IAAI;CACJ,SAAS;AACV,GA8CMC,IAAcJ,EAAM,YACxB,EAAE,cAAW,GAAGK,KAAS,MACzB,kBAAC,UAAD;CACM;CACL,WAAWC,EACV,6GACAC,CACD;CACA,GAAIF;AACJ,CAAA,CAEH;AACA,EAAY,cAAc;AAE1B,IAAaG,IAAaR,EAAM,YAK9B,EACC,cACA,UACA,cAAW,IACX,aACA,oBAAoBS,GACpB,gBAAgBC,GAChB,mBAAmBC,GACnB,GAAGN,KAEJ,MACI;CACJ,IAAMO,IAAcZ,EAAM,MAAM,GAC1Ba,IAAU,EAAQC,GAClBC,IAAU,GAAGH,EAAY,SACzBI,IAAkB,GAAGJ,EAAY,UACjCK,IAAkD,CAAC,GACnDC,IAA2B,CAAC;CAClC,EAAM,SAAS,QAAQC,IAAW,MAAU;EAC3C,IAAInB,EAAM,eAAeoB,CAAK,KAAKA,EAAM,SAAShB,GAAa;GAC9D,EAAQ,KAAKgB,CAA6C;GAC1D;EACD;EACA,EAAM,KAAKA,CAAK;CACjB,CAAC;CACD,IAAMC,IAAiBJ,EAAQ,KAAK,GAAQ,MAAU;EACrD,IAAMK,IACLC,EAAO,MAAM,OAAOC,MAAU,IAAIR,IAAkB,GAAGA,EAAgB,GAAGQ;EAC3E,OAAOxB,EAAM,aAAauB,GAAQ;GAAE,KAAKD;GAAU,IAAIA;EAAS,CAAC;CAClE,CAAC,GAKKG,IAAmB,CAJPJ,EAChB,KAAK,MAAWE,EAAO,MAAM,EAAE,CAAC,CAChC,OAAO,OAAO,CAAC,CACf,KAAK,GACmB,GAAWZ,CAAU,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,KAAK,KAAA,GACxEe,IACL,CAACb,IAAUE,IAAU,MAAMN,CAAW,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,KAAK,KAAA;CACtE,OACC,kBAAC,YAAD;EAAoB;EAAU,WAAU;EAAxC,UAAA;GACEY;GACD,kBAACpB,EAAoB,MAArB;IACM;IACK;IACV,WAAWK,EAAG,4BAA4BC,CAAS;IACnD,GAAIF;IACJ,mBAAiBoB;IACjB,oBAAkBC;IAClB,gBAAcb,IAAU,KAAOH;IAE9B,UAAAQ;GACwB,CAAA;GACzBL,IACA,kBAAC,KAAD;IAAG,IAAIE;IAAS,WAAU;IAAyC,MAAK;IACtE,UAAAD;GACC,CAAA,IACA;EACK;;AAEZ,CACD;AACA,EAAW,cAAc;AAEzB,IAAMa,IAAY3B,EAAM,YACtB,EAAE,cAAW,UAAO,WAAW,GAAGK,KAAS,MAC3C,kBAACJ,EAAoB,MAArB;CACM;CACL,WAAWK,EACVsB,GACA,+IACA1B,EAAiB2B,IACjBC,GACAvB,CACD;CACA,GAAIF;CAEJ,UAAA,kBAACJ,EAAoB,WAArB;EAA+B,WAAU;EACxC,UAAA,kBAAC8B,GAAD,EAAQ,WAAW5B,EAAsB0B,GAAQ,CAAA;CACnB,CAAA;AACN,CAAA,CAE5B;AACA,EAAU,cAAc5B,EAAoB,KAAK;AAEjD,IAAa+B,IAAQ,OAAO,OAAOL,GAAW;CAC7C,OAAOnB;CACP,QAAQJ;CACR,MAAMuB;AACP,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { type RecommendationOption } from "../models/recommendation.js";
2
+ export type { RecommendationConfidence, RecommendationOption } from "../models/recommendation.js";
3
+ export interface RecommendationCardProps {
4
+ /** Caller-owned options with stable IDs. Remount with a new key for a new request. */
5
+ options: readonly RecommendationOption[];
6
+ /** Card heading. @default "Recommended action" */
7
+ title?: string;
8
+ /** Explicit acceptance; rejected promises keep the choice and allow retry. */
9
+ onAccept: (option: RecommendationOption) => void | Promise<void>;
10
+ disabled?: boolean;
11
+ className?: string;
12
+ }
13
+ export declare function RecommendationCard({ title, className, ...props }: RecommendationCardProps): import("react").JSX.Element;
@@ -0,0 +1,123 @@
1
+ "use client";
2
+ import { cn as e } from "../utils/cn.js";
3
+ import { Button as t } from "./button.js";
4
+ import { Collapsible as n, CollapsibleContent as r, CollapsibleTrigger as i } from "./collapsible.js";
5
+ import { useHoverHighlight as a } from "../utils/use-hover-highlight.js";
6
+ import { LayerCard as o } from "./layer-card.js";
7
+ import { useRecommendationCardViewModel as s } from "../viewmodels/use-recommendation-card.js";
8
+ import { RECOMMENDATION_CONFIDENCE as c } from "../models/recommendation.js";
9
+ import { useId as l, useRef as u } from "react";
10
+ import { Check as d, ChevronDown as f } from "lucide-react";
11
+ import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
12
+ //#region src/components/recommendation-card.tsx
13
+ function g({ value: t }) {
14
+ let n = c[t];
15
+ return /* @__PURE__ */ h("span", {
16
+ className: e("inline-flex min-w-0 items-center gap-basalt-space-md text-basalt-sm", n.className),
17
+ children: [/* @__PURE__ */ m("span", {
18
+ "aria-hidden": "true",
19
+ className: "inline-flex items-center gap-basalt-space-xs",
20
+ children: [
21
+ 0,
22
+ 1,
23
+ 2
24
+ ].map((t) => /* @__PURE__ */ m("span", { className: e("h-basalt-2_5 w-basalt-1 rounded-basalt-full", t < n.bars ? "bg-current" : "bg-basalt-border") }, t))
25
+ }), n.label]
26
+ });
27
+ }
28
+ function _({ title: c = "Recommended action", className: _, ...v }) {
29
+ let y = s(v), b = l(), x = a(), S = u(null);
30
+ return /* @__PURE__ */ h(o, {
31
+ padding: "none",
32
+ "aria-labelledby": b,
33
+ className: e("w-full min-w-0 overflow-hidden leading-[var(--basalt-line-body)]", _),
34
+ children: [/* @__PURE__ */ h("div", {
35
+ className: "space-y-basalt-space-md px-basalt-panel-x py-basalt-panel-y",
36
+ children: [/* @__PURE__ */ m("h3", {
37
+ id: b,
38
+ className: "break-words text-basalt-base font-medium",
39
+ children: c
40
+ }), y.active ? /* @__PURE__ */ m("p", {
41
+ className: "basalt-agent-reveal whitespace-pre-wrap break-words text-basalt-code leading-[var(--basalt-line-body)] text-basalt-muted-foreground",
42
+ children: y.active.description
43
+ }, y.active.id) : /* @__PURE__ */ m("p", {
44
+ className: "text-basalt-base text-basalt-muted-foreground",
45
+ role: "status",
46
+ children: "No recommendations yet"
47
+ })]
48
+ }), y.active && /* @__PURE__ */ h(n, {
49
+ open: y.open,
50
+ onOpenChange: y.setOpen,
51
+ children: [
52
+ /* @__PURE__ */ m(r, {
53
+ unstyled: !0,
54
+ children: /* @__PURE__ */ h("div", {
55
+ className: "border-t border-basalt-border px-[calc(var(--basalt-space-panel-x)-var(--basalt-space-row-x))] py-basalt-panel-y",
56
+ children: [/* @__PURE__ */ m("p", {
57
+ className: "px-basalt-row-x py-basalt-space-sm text-basalt-sm text-basalt-muted-foreground",
58
+ children: "Other options"
59
+ }), /* @__PURE__ */ m("div", {
60
+ ref: x,
61
+ className: "basalt-hover-list",
62
+ role: "group",
63
+ "aria-label": "Alternative recommendations",
64
+ children: y.others.map((e) => /* @__PURE__ */ h(t, {
65
+ variant: "ghost",
66
+ disabled: y.blocked || e.disabled,
67
+ "data-basalt-hover-item": "",
68
+ "data-disabled": y.blocked || e.disabled ? "" : void 0,
69
+ onClick: () => {
70
+ y.select(e.id), S.current?.focus();
71
+ },
72
+ className: "h-auto min-h-basalt-menu-row w-full justify-start whitespace-normal px-basalt-row-x py-basalt-row-y text-left hover:bg-transparent",
73
+ children: [/* @__PURE__ */ m("span", {
74
+ className: "min-w-0 flex-1 break-words text-basalt-code",
75
+ children: e.label
76
+ }), /* @__PURE__ */ m(g, { value: e.confidence })]
77
+ }, e.id))
78
+ })]
79
+ })
80
+ }),
81
+ y.error && /* @__PURE__ */ m("p", {
82
+ role: "alert",
83
+ className: "px-basalt-panel-x pb-basalt-space-lg text-basalt-sm text-basalt-danger",
84
+ children: y.error
85
+ }),
86
+ /* @__PURE__ */ h("div", {
87
+ className: "flex min-w-0 flex-wrap items-center justify-between gap-basalt-content-gap border-t border-basalt-border px-basalt-panel-x py-basalt-panel-y",
88
+ children: [/* @__PURE__ */ m(g, { value: y.active.confidence }), /* @__PURE__ */ h("div", {
89
+ className: "flex min-w-0 max-w-full flex-wrap items-center justify-end gap-basalt-content-gap",
90
+ children: [y.others.length > 0 && /* @__PURE__ */ m(i, {
91
+ asChild: !0,
92
+ children: /* @__PURE__ */ h(t, {
93
+ ref: S,
94
+ size: "sm",
95
+ variant: "secondary",
96
+ disabled: y.blocked,
97
+ children: ["Alternatives", /* @__PURE__ */ m(f, {
98
+ "aria-hidden": "true",
99
+ className: e("transition-transform basalt-motion motion-reduce:transition-none", y.open && "rotate-180")
100
+ })]
101
+ })
102
+ }), /* @__PURE__ */ m(t, {
103
+ size: "sm",
104
+ disabled: y.blocked || y.active.disabled || y.accepted,
105
+ loading: y.pending,
106
+ onClick: () => void y.accept(),
107
+ children: y.accepted ? /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m(d, { "aria-hidden": "true" }), "Accepted"] }) : y.active.actionLabel ?? "Accept"
108
+ })]
109
+ })]
110
+ }),
111
+ /* @__PURE__ */ m("span", {
112
+ role: "status",
113
+ className: "sr-only",
114
+ children: y.accepted ? "Recommendation accepted" : y.pending ? "Accepting recommendation" : ""
115
+ })
116
+ ]
117
+ })]
118
+ });
119
+ }
120
+ //#endregion
121
+ export { _ as RecommendationCard };
122
+
123
+ //# sourceMappingURL=recommendation-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommendation-card.js","names":["_Fragment","Fragment$1","Confidence","confidence","RECOMMENDATION_CONFIDENCE","value","cn","bar","RecommendationCard","props","vm","useRecommendationCardViewModel","id","useId","highlightRef","useHoverHighlight","alternativesRef","useRef","LayerCard","className","title","Collapsible","CollapsibleContent","Button","option","CollapsibleTrigger","ChevronDown","Check"],"sources":["../../src/components/recommendation-card.tsx"],"sourcesContent":["import { Check, ChevronDown } from \"lucide-react\";\nimport { useId, useRef } from \"react\";\nimport {\n\tRECOMMENDATION_CONFIDENCE,\n\ttype RecommendationConfidence,\n\ttype RecommendationOption,\n} from \"../models/recommendation\";\nimport { cn } from \"../utils/cn\";\nimport { useHoverHighlight } from \"../utils/use-hover-highlight\";\nimport { useRecommendationCardViewModel } from \"../viewmodels/use-recommendation-card\";\nimport { Button } from \"./button\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"./collapsible\";\nimport { LayerCard } from \"./layer-card\";\n\nexport type { RecommendationConfidence, RecommendationOption } from \"../models/recommendation\";\n\nexport interface RecommendationCardProps {\n\t/** Caller-owned options with stable IDs. Remount with a new key for a new request. */\n\toptions: readonly RecommendationOption[];\n\t/** Card heading. @default \"Recommended action\" */\n\ttitle?: string;\n\t/** Explicit acceptance; rejected promises keep the choice and allow retry. */\n\tonAccept: (option: RecommendationOption) => void | Promise<void>;\n\tdisabled?: boolean;\n\tclassName?: string;\n}\n\nfunction Confidence({ value }: { value: RecommendationConfidence }) {\n\tconst confidence = RECOMMENDATION_CONFIDENCE[value];\n\treturn (\n\t\t<span\n\t\t\tclassName={cn(\n\t\t\t\t\"inline-flex min-w-0 items-center gap-basalt-space-md text-basalt-sm\",\n\t\t\t\tconfidence.className,\n\t\t\t)}\n\t\t>\n\t\t\t<span aria-hidden=\"true\" className=\"inline-flex items-center gap-basalt-space-xs\">\n\t\t\t\t{[0, 1, 2].map((bar) => (\n\t\t\t\t\t<span\n\t\t\t\t\t\tkey={bar}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\"h-basalt-2_5 w-basalt-1 rounded-basalt-full\",\n\t\t\t\t\t\t\tbar < confidence.bars ? \"bg-current\" : \"bg-basalt-border\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</span>\n\t\t\t{confidence.label}\n\t\t</span>\n\t);\n}\n\nexport function RecommendationCard({\n\ttitle = \"Recommended action\",\n\tclassName,\n\t...props\n}: RecommendationCardProps) {\n\tconst vm = useRecommendationCardViewModel(props);\n\tconst id = useId();\n\tconst highlightRef = useHoverHighlight();\n\tconst alternativesRef = useRef<HTMLButtonElement>(null);\n\treturn (\n\t\t<LayerCard\n\t\t\tpadding=\"none\"\n\t\t\taria-labelledby={id}\n\t\t\tclassName={cn(\"w-full min-w-0 overflow-hidden leading-[var(--basalt-line-body)]\", className)}\n\t\t>\n\t\t\t<div className=\"space-y-basalt-space-md px-basalt-panel-x py-basalt-panel-y\">\n\t\t\t\t<h3 id={id} className=\"break-words text-basalt-base font-medium\">\n\t\t\t\t\t{title}\n\t\t\t\t</h3>\n\t\t\t\t{vm.active ? (\n\t\t\t\t\t<p\n\t\t\t\t\t\tkey={vm.active.id}\n\t\t\t\t\t\tclassName=\"basalt-agent-reveal whitespace-pre-wrap break-words text-basalt-code leading-[var(--basalt-line-body)] text-basalt-muted-foreground\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{vm.active.description}\n\t\t\t\t\t</p>\n\t\t\t\t) : (\n\t\t\t\t\t<p className=\"text-basalt-base text-basalt-muted-foreground\" role=\"status\">\n\t\t\t\t\t\tNo recommendations yet\n\t\t\t\t\t</p>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t{vm.active && (\n\t\t\t\t<Collapsible open={vm.open} onOpenChange={vm.setOpen}>\n\t\t\t\t\t<CollapsibleContent unstyled>\n\t\t\t\t\t\t<div className=\"border-t border-basalt-border px-[calc(var(--basalt-space-panel-x)-var(--basalt-space-row-x))] py-basalt-panel-y\">\n\t\t\t\t\t\t\t<p className=\"px-basalt-row-x py-basalt-space-sm text-basalt-sm text-basalt-muted-foreground\">\n\t\t\t\t\t\t\t\tOther options\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tref={highlightRef}\n\t\t\t\t\t\t\t\tclassName=\"basalt-hover-list\"\n\t\t\t\t\t\t\t\trole=\"group\"\n\t\t\t\t\t\t\t\taria-label=\"Alternative recommendations\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{vm.others.map((option) => (\n\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\tkey={option.id}\n\t\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\t\tdisabled={vm.blocked || option.disabled}\n\t\t\t\t\t\t\t\t\t\tdata-basalt-hover-item=\"\"\n\t\t\t\t\t\t\t\t\t\tdata-disabled={vm.blocked || option.disabled ? \"\" : undefined}\n\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\tvm.select(option.id);\n\t\t\t\t\t\t\t\t\t\t\talternativesRef.current?.focus();\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\tclassName=\"h-auto min-h-basalt-menu-row w-full justify-start whitespace-normal px-basalt-row-x py-basalt-row-y text-left hover:bg-transparent\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<span className=\"min-w-0 flex-1 break-words text-basalt-code\">\n\t\t\t\t\t\t\t\t\t\t\t{option.label}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t<Confidence value={option.confidence} />\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</CollapsibleContent>\n\t\t\t\t\t{vm.error && (\n\t\t\t\t\t\t<p\n\t\t\t\t\t\t\trole=\"alert\"\n\t\t\t\t\t\t\tclassName=\"px-basalt-panel-x pb-basalt-space-lg text-basalt-sm text-basalt-danger\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{vm.error}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t)}\n\t\t\t\t\t<div className=\"flex min-w-0 flex-wrap items-center justify-between gap-basalt-content-gap border-t border-basalt-border px-basalt-panel-x py-basalt-panel-y\">\n\t\t\t\t\t\t<Confidence value={vm.active.confidence} />\n\t\t\t\t\t\t<div className=\"flex min-w-0 max-w-full flex-wrap items-center justify-end gap-basalt-content-gap\">\n\t\t\t\t\t\t\t{vm.others.length > 0 && (\n\t\t\t\t\t\t\t\t<CollapsibleTrigger asChild>\n\t\t\t\t\t\t\t\t\t<Button ref={alternativesRef} size=\"sm\" variant=\"secondary\" disabled={vm.blocked}>\n\t\t\t\t\t\t\t\t\t\tAlternatives\n\t\t\t\t\t\t\t\t\t\t<ChevronDown\n\t\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\t\"transition-transform basalt-motion motion-reduce:transition-none\",\n\t\t\t\t\t\t\t\t\t\t\t\tvm.open && \"rotate-180\",\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t</CollapsibleTrigger>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\tdisabled={vm.blocked || vm.active.disabled || vm.accepted}\n\t\t\t\t\t\t\t\tloading={vm.pending}\n\t\t\t\t\t\t\t\tonClick={() => void vm.accept()}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{vm.accepted ? (\n\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t<Check aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t\t\tAccepted\n\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t(vm.active.actionLabel ?? \"Accept\")\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<span role=\"status\" className=\"sr-only\">\n\t\t\t\t\t\t{vm.accepted ? \"Recommendation accepted\" : vm.pending ? \"Accepting recommendation\" : \"\"}\n\t\t\t\t\t</span>\n\t\t\t\t</Collapsible>\n\t\t\t)}\n\t\t</LayerCard>\n\t);\n}\n"],"mappings":";;;;;;;;;;;;AA2BA,SAASE,EAAW,EAAE,YAA8C;CACnE,IAAMC,IAAaC,EAA0BC;CAC7C,OACC,kBAAC,QAAD;EACC,WAAWC,EACV,uEACAH,EAAW,SACZ;EAJD,UAAA,CAMC,kBAAC,QAAD;GAAM,eAAY;GAAO,WAAU;GACjC,UAAA;IAAC;IAAG;IAAG;GAAC,CAAC,CAAC,KAAK,MACf,kBAAC,QAAD,EAEC,WAAWG,EACV,+CACAC,IAAMJ,EAAW,OAAO,eAAe,kBACxC,EACA,GALKI,CAKL,CACD;EACI,CAAA,GACLJ,EAAW,KACP;;AAER;AAEA,SAAgBK,EAAmB,EAClC,WAAQ,sBACR,cACA,GAAGC,KACwB;CAC3B,IAAMC,IAAKC,EAA+BF,CAAK,GACzCG,IAAKC,EAAM,GACXC,IAAeC,EAAkB,GACjCC,IAAkBC,EAA0B,IAAI;CACtD,OACC,kBAACC,GAAD;EACC,SAAQ;EACR,mBAAiBN;EACjB,WAAWN,EAAG,oEAAoEa,CAAS;EAH5F,UAAA,CAKC,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACC,kBAAC,MAAD;IAAQ;IAAI,WAAU;IACpB,UAAAC;GACE,CAAA,GACHV,EAAG,SACH,kBAAC,KAAD;IAEC,WAAU;IAET,UAAAA,EAAG,OAAO;GACT,GAJGA,EAAG,OAAO,EAIb,IAEH,kBAAC,KAAD;IAAG,WAAU;IAAgD,MAAK;IAAS,UAAA;GAExE,CAAA,CAEA;EACJ,CAAA,GAAAA,EAAG,UACH,kBAACW,GAAD;GAAa,MAAMX,EAAG;GAAM,cAAcA,EAAG;GAA7C,UAAA;IACC,kBAACY,GAAD;KAAoB,UAAA;KACnB,UAAA,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACC,kBAAC,KAAD;OAAG,WAAU;OAAiF,UAAA;MAE3F,CAAA,GACH,kBAAC,OAAD;OACC,KAAKR;OACL,WAAU;OACV,MAAK;OACL,cAAW;OAEV,UAAAJ,EAAG,OAAO,KAAK,MACf,kBAACa,GAAD;QAEC,SAAQ;QACR,UAAUb,EAAG,WAAWc,EAAO;QAC/B,0BAAuB;QACvB,iBAAed,EAAG,WAAWc,EAAO,WAAW,KAAK,KAAA;QACpD,eAAe;SAEd,AADAd,EAAG,OAAOc,EAAO,EAAE,GACnBR,EAAgB,SAAS,MAAM;QAChC;QACA,WAAU;QAVX,UAAA,CAYC,kBAAC,QAAD;SAAM,WAAU;SACd,UAAAQ,EAAO;QACH,CAAA,GACN,kBAACtB,GAAD,EAAY,OAAOsB,EAAO,WAAa,CAAA,CAChC;OAfF,GAAAA,EAAO,EAeL,CACR;MACG,CAAA,CACD;;IACc,CAAA;IACnBd,EAAG,SACH,kBAAC,KAAD;KACC,MAAK;KACL,WAAU;KAET,UAAAA,EAAG;IACF,CAAA;IAEJ,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACC,kBAACR,GAAD,EAAY,OAAOQ,EAAG,OAAO,WAAa,CAAA,GAC1C,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACEA,EAAG,OAAO,SAAS,KACnB,kBAACe,GAAD;OAAoB,SAAA;OACnB,UAAA,kBAACF,GAAD;QAAQ,KAAKP;QAAiB,MAAK;QAAK,SAAQ;QAAY,UAAUN,EAAG;QAAzE,UAAA,CAAkF,gBAEjF,kBAACgB,GAAD;SACC,eAAY;SACZ,WAAWpB,EACV,oEACAI,EAAG,QAAQ,YACZ;QACA,CAAA,CACM;;MACW,CAAA,GAErB,kBAACa,GAAD;OACC,MAAK;OACL,UAAUb,EAAG,WAAWA,EAAG,OAAO,YAAYA,EAAG;OACjD,SAASA,EAAG;OACZ,eAAe,KAAKA,EAAG,OAAO;OAE7B,UAAAA,EAAG,WACH,kBAAAV,GAAA,EAAA,UAAA,CACC,kBAAC2B,GAAD,EAAO,eAAY,OAAQ,CAAA,GAAC,UAE3B,EAAA,CAAA,IAEDjB,EAAG,OAAO,eAAe;MAEpB,CAAA,CACJ;KACD,CAAA,CAAA;;IACL,kBAAC,QAAD;KAAM,MAAK;KAAS,WAAU;KAC5B,UAAAA,EAAG,WAAW,4BAA4BA,EAAG,UAAU,6BAA6B;IAChF,CAAA;GACM;EAEJ,CAAA,CAAA;;AAEb"}
@@ -15,7 +15,7 @@ var a = [{
15
15
  }];
16
16
  function o({ title: o, description: s, data: c, header: l, toolbar: u, filters: d, bulkActions: f, state: p, children: m, footer: h, className: g, loading: _, empty: v, error: y, onRetry: b }) {
17
17
  return /* @__PURE__ */ i("div", {
18
- className: e("min-w-0 space-y-4", g),
18
+ className: e("min-w-0 space-y-basalt-layout-lg", g),
19
19
  children: [
20
20
  l ?? /* @__PURE__ */ r(n, {
21
21
  title: o,