@nocoo/basalt 3.2.0 → 3.2.4

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 (225) hide show
  1. package/README.md +25 -19
  2. package/ai/COMPATIBILITY.md +41 -36
  3. package/ai/DESIGN.md +73 -56
  4. package/ai/INTEGRATION.md +819 -825
  5. package/ai/RECIPES.md +334 -135
  6. package/ai/USAGE.md +2 -2
  7. package/ai/registry.json +454 -97
  8. package/ai/sources.json +2 -2
  9. package/dist/assets/brand-mark.js +1 -2
  10. package/dist/charts/area.js +1 -2
  11. package/dist/charts/bar.js +1 -2
  12. package/dist/charts/bullet.js +1 -2
  13. package/dist/charts/chart-colors.js +1 -2
  14. package/dist/charts/charts.js +1 -2
  15. package/dist/charts/config.js +1 -2
  16. package/dist/charts/custom-chart.js +1 -2
  17. package/dist/charts/date-navigation.js +1 -2
  18. package/dist/charts/donut.js +1 -2
  19. package/dist/charts/frame.js +3 -4
  20. package/dist/charts/frame.js.map +1 -1
  21. package/dist/charts/funnel.js +1 -2
  22. package/dist/charts/gauge.js +1 -2
  23. package/dist/charts/grouped-bar.js +1 -2
  24. package/dist/charts/heatmap-calendar.js +7 -11
  25. package/dist/charts/heatmap-calendar.js.map +1 -1
  26. package/dist/charts/heatmap-matrix.js +4 -5
  27. package/dist/charts/heatmap-matrix.js.map +1 -1
  28. package/dist/charts/item-list.js +1 -2
  29. package/dist/charts/legend.js +1 -2
  30. package/dist/charts/line.js +1 -2
  31. package/dist/charts/palette.js +1 -2
  32. package/dist/charts/radar.js +1 -2
  33. package/dist/charts/sample.js +1 -2
  34. package/dist/charts/sankey.js +1 -2
  35. package/dist/charts/series.js +1 -2
  36. package/dist/charts/slot-bar.js +1 -2
  37. package/dist/charts/sparkline.js +1 -2
  38. package/dist/charts/stacked-bar.js +1 -2
  39. package/dist/charts/stat-card.js +1 -2
  40. package/dist/charts/timeline.js +1 -2
  41. package/dist/charts/timeseries.js +1 -2
  42. package/dist/charts/tooltip.js +31 -27
  43. package/dist/charts/tooltip.js.map +1 -1
  44. package/dist/components/accordion.js +1 -2
  45. package/dist/components/alert-dialog.js +1 -2
  46. package/dist/components/app-header.js +2 -3
  47. package/dist/components/app-header.js.map +1 -1
  48. package/dist/components/app-shell.js +2 -3
  49. package/dist/components/app-shell.js.map +1 -1
  50. package/dist/components/approval-card.js +1 -2
  51. package/dist/components/autocomplete.js +1 -2
  52. package/dist/components/avatar.js +1 -2
  53. package/dist/components/badge.js +1 -2
  54. package/dist/components/banner.js +1 -2
  55. package/dist/components/basalt-mark.js +1 -2
  56. package/dist/components/battery-meter.js +1 -2
  57. package/dist/components/breadcrumbs.js +1 -2
  58. package/dist/components/button.d.ts +1 -1
  59. package/dist/components/button.js +3 -3
  60. package/dist/components/button.js.map +1 -1
  61. package/dist/components/chat-bubble.js +1 -2
  62. package/dist/components/chat-composer.js +2 -3
  63. package/dist/components/chat-composer.js.map +1 -1
  64. package/dist/components/chat-header.js +1 -2
  65. package/dist/components/chat-inbox.js +1 -2
  66. package/dist/components/chat-markdown.js +1 -2
  67. package/dist/components/chat-message.js +2 -3
  68. package/dist/components/chat-message.js.map +1 -1
  69. package/dist/components/checkbox.js +1 -2
  70. package/dist/components/clipboard-text.js +1 -2
  71. package/dist/components/code.js +2 -3
  72. package/dist/components/code.js.map +1 -1
  73. package/dist/components/collapsible.js +1 -2
  74. package/dist/components/collapsible.js.map +1 -1
  75. package/dist/components/combobox.js +1 -2
  76. package/dist/components/command-palette.js +3 -4
  77. package/dist/components/command-palette.js.map +1 -1
  78. package/dist/components/confirm-dialog.js +3 -12
  79. package/dist/components/confirm-dialog.js.map +1 -1
  80. package/dist/components/context-cards.js +2 -3
  81. package/dist/components/context-cards.js.map +1 -1
  82. package/dist/components/context-menu.js +2 -3
  83. package/dist/components/context-menu.js.map +1 -1
  84. package/dist/components/data-table.js +129 -131
  85. package/dist/components/data-table.js.map +1 -1
  86. package/dist/components/date-picker.js +7 -18
  87. package/dist/components/date-picker.js.map +1 -1
  88. package/dist/components/delete-resource.js +1 -2
  89. package/dist/components/description-list.js +1 -2
  90. package/dist/components/dialog.js +1 -2
  91. package/dist/components/diff-table.js +2 -3
  92. package/dist/components/diff-table.js.map +1 -1
  93. package/dist/components/dock.js +1 -2
  94. package/dist/components/dock.js.map +1 -1
  95. package/dist/components/dropdown-menu.js +2 -3
  96. package/dist/components/dropdown-menu.js.map +1 -1
  97. package/dist/components/editable-nav-item.js +3 -4
  98. package/dist/components/editable-nav-item.js.map +1 -1
  99. package/dist/components/empty.js +1 -2
  100. package/dist/components/fab.js +1 -2
  101. package/dist/components/field.js +1 -2
  102. package/dist/components/file-dropzone.js +2 -3
  103. package/dist/components/file-dropzone.js.map +1 -1
  104. package/dist/components/filter-bar.js +2 -3
  105. package/dist/components/filter-bar.js.map +1 -1
  106. package/dist/components/flow.js +1 -2
  107. package/dist/components/grid.js +1 -2
  108. package/dist/components/hover-card.js +1 -2
  109. package/dist/components/icon-picker.js +4 -5
  110. package/dist/components/icon-picker.js.map +1 -1
  111. package/dist/components/inline-editable.js +2 -3
  112. package/dist/components/inline-editable.js.map +1 -1
  113. package/dist/components/input-area.js +1 -2
  114. package/dist/components/input-group.js +4 -5
  115. package/dist/components/input-group.js.map +1 -1
  116. package/dist/components/input.js +1 -2
  117. package/dist/components/label.js +1 -2
  118. package/dist/components/layer-card.js +3 -3
  119. package/dist/components/layer-card.js.map +1 -1
  120. package/dist/components/link.js +2 -3
  121. package/dist/components/link.js.map +1 -1
  122. package/dist/components/loader.js +1 -2
  123. package/dist/components/loading-screen.js +1 -2
  124. package/dist/components/menu-bar.js +3 -4
  125. package/dist/components/menu-bar.js.map +1 -1
  126. package/dist/components/meter.js +1 -2
  127. package/dist/components/multi-select.js +2 -3
  128. package/dist/components/multi-select.js.map +1 -1
  129. package/dist/components/navigation-menu.js +1 -2
  130. package/dist/components/overlay.d.ts +3 -6
  131. package/dist/components/overlay.js +4 -5
  132. package/dist/components/overlay.js.map +1 -1
  133. package/dist/components/page-header.js +1 -2
  134. package/dist/components/pagination.js +1 -2
  135. package/dist/components/popover.js +1 -2
  136. package/dist/components/prompt-bar.js +1 -2
  137. package/dist/components/radio.js +2 -7
  138. package/dist/components/radio.js.map +1 -1
  139. package/dist/components/recommendation-card.js +1 -2
  140. package/dist/components/resource-list.js +1 -2
  141. package/dist/components/responsive-master-detail.js +3 -4
  142. package/dist/components/responsive-master-detail.js.map +1 -1
  143. package/dist/components/scroll-area.js +2 -3
  144. package/dist/components/scroll-area.js.map +1 -1
  145. package/dist/components/section-rule.js +1 -2
  146. package/dist/components/segment-control.js +2 -3
  147. package/dist/components/segment-control.js.map +1 -1
  148. package/dist/components/select.js +2 -3
  149. package/dist/components/select.js.map +1 -1
  150. package/dist/components/sensitive-input.js +2 -3
  151. package/dist/components/sensitive-input.js.map +1 -1
  152. package/dist/components/separator.js +1 -2
  153. package/dist/components/sheet.js +1 -2
  154. package/dist/components/sidebar.d.ts +53 -19
  155. package/dist/components/sidebar.js +201 -100
  156. package/dist/components/sidebar.js.map +1 -1
  157. package/dist/components/skeleton-line.js +1 -2
  158. package/dist/components/slider.js +1 -2
  159. package/dist/components/stat-strip.js +1 -2
  160. package/dist/components/switch.js +1 -2
  161. package/dist/components/table-of-contents.js +1 -2
  162. package/dist/components/table-pager.js +1 -2
  163. package/dist/components/table.js +2 -3
  164. package/dist/components/table.js.map +1 -1
  165. package/dist/components/tabs.js +2 -3
  166. package/dist/components/tabs.js.map +1 -1
  167. package/dist/components/tag-badge.js +1 -2
  168. package/dist/components/tag-color-picker.js +3 -4
  169. package/dist/components/tag-color-picker.js.map +1 -1
  170. package/dist/components/text.js +1 -2
  171. package/dist/components/theme-toggle.js +1 -2
  172. package/dist/components/thinking.js +1 -2
  173. package/dist/components/toast.js +2 -3
  174. package/dist/components/toast.js.map +1 -1
  175. package/dist/components/toggle-group.js +1 -2
  176. package/dist/components/toggle.js +1 -2
  177. package/dist/components/tool-chips.js +1 -2
  178. package/dist/components/toolbar.js +9 -10
  179. package/dist/components/toolbar.js.map +1 -1
  180. package/dist/components/tooltip.js +1 -2
  181. package/dist/components/typeahead-field.js +6 -21
  182. package/dist/components/typeahead-field.js.map +1 -1
  183. package/dist/components/upload-queue.js +1 -2
  184. package/dist/index.d.ts +1 -1
  185. package/dist/index.js +11 -11
  186. package/dist/models/agent-feedback.js +1 -2
  187. package/dist/models/avatar.js +1 -2
  188. package/dist/models/code.js +1 -2
  189. package/dist/models/context-cards.js +1 -2
  190. package/dist/models/diff-table.js +1 -2
  191. package/dist/models/recommendation.js +1 -2
  192. package/dist/providers/accent.js +2 -7
  193. package/dist/providers/accent.js.map +1 -1
  194. package/dist/providers/link.js +1 -2
  195. package/dist/providers/theme.js +2 -7
  196. package/dist/providers/theme.js.map +1 -1
  197. package/dist/styles/base.css +71 -0
  198. package/dist/styles/standalone.css +127 -98
  199. package/dist/styles/tailwind.css +10 -2
  200. package/dist/styles/tokens.css +55 -7
  201. package/dist/utils/cn.js +1 -2
  202. package/dist/utils/control-surface.js +1 -2
  203. package/dist/utils/navigation.d.ts +2 -2
  204. package/dist/utils/navigation.js +2 -3
  205. package/dist/utils/navigation.js.map +1 -1
  206. package/dist/utils/preference-store.js +1 -2
  207. package/dist/utils/selection-indicator.js +1 -2
  208. package/dist/utils/use-checkable-group.js +1 -2
  209. package/dist/utils/use-hover-highlight.js +2 -3
  210. package/dist/utils/use-hover-highlight.js.map +1 -1
  211. package/dist/viewmodels/use-approval-card.js +11 -13
  212. package/dist/viewmodels/use-approval-card.js.map +1 -1
  213. package/dist/viewmodels/use-chat-composer.js +1 -2
  214. package/dist/viewmodels/use-chat-message.js +1 -2
  215. package/dist/viewmodels/use-code-block.js +1 -2
  216. package/dist/viewmodels/use-code-block.js.map +1 -1
  217. package/dist/viewmodels/use-context-cards.js +1 -2
  218. package/dist/viewmodels/use-diff-table.js +1 -2
  219. package/dist/viewmodels/use-diff-table.js.map +1 -1
  220. package/dist/viewmodels/use-loader.js +1 -2
  221. package/dist/viewmodels/use-recommendation-card.js +1 -2
  222. package/dist/viewmodels/use-recommendation-card.js.map +1 -1
  223. package/dist/viewmodels/use-thinking.js +1 -2
  224. package/dist/viewmodels/use-tool-chips.js +1 -2
  225. package/package.json +1 -1
@@ -5,7 +5,7 @@ import { dialogOverlayClass as n, dialogPanelClass as r } from "./dialog.js";
5
5
  import * as i from "@radix-ui/react-alert-dialog";
6
6
  import * as a from "react";
7
7
  import { jsx as o, jsxs as s } from "react/jsx-runtime";
8
- //#region src/components/alert-dialog.tsx
8
+ // src/components/alert-dialog.tsx
9
9
  var c = i.Root, l = i.Trigger, u = i.Portal, d = a.forwardRef(({ className: e, ...t }, r) => /* @__PURE__ */ o(i.Overlay, {
10
10
  ref: r,
11
11
  className: n(e),
@@ -59,7 +59,6 @@ var v = ({ className: t, ...n }) => /* @__PURE__ */ o("div", {
59
59
  ...n
60
60
  });
61
61
  v.displayName = "AlertDialogFooter";
62
- //#endregion
63
62
  export { c as AlertDialog, g as AlertDialogAction, h as AlertDialogCancel, f as AlertDialogContent, m as AlertDialogDescription, v as AlertDialogFooter, _ as AlertDialogHeader, d as AlertDialogOverlay, u as AlertDialogPortal, p as AlertDialogTitle, l as AlertDialogTrigger };
64
63
 
65
64
  //# sourceMappingURL=alert-dialog.js.map
@@ -4,13 +4,13 @@ import { BASALT_UI_CLASS as t } from "../utils/control-surface.js";
4
4
  import { Breadcrumbs as n } from "./breadcrumbs.js";
5
5
  import { ChevronRight as r } from "lucide-react";
6
6
  import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
7
- //#region src/components/app-header.tsx
7
+ // src/components/app-header.tsx
8
8
  function s({ leading: s, breadcrumbs: c, title: l, actions: u, sticky: d = !1, density: f = "comfortable", className: p, ...m }) {
9
9
  return /* @__PURE__ */ o("header", {
10
10
  "data-basalt-header": "",
11
11
  "data-sticky": d || void 0,
12
12
  "data-density": f,
13
- className: e(t, "flex shrink-0 items-center justify-between gap-basalt-space-lg px-basalt-space-lg md:px-basalt-space-lg", f === "compact" ? "h-[3.25rem]" : "h-basalt-14", p),
13
+ className: e(t, "flex shrink-0 items-center justify-between gap-basalt-space-lg px-basalt-space-lg md:px-basalt-layout-sm", f === "compact" ? "h-[3.25rem]" : "h-basalt-14", p),
14
14
  ...m,
15
15
  children: [/* @__PURE__ */ o("div", {
16
16
  className: "flex min-w-0 items-center gap-basalt-space-lg",
@@ -38,7 +38,6 @@ function s({ leading: s, breadcrumbs: c, title: l, actions: u, sticky: d = !1, d
38
38
  }) : null]
39
39
  });
40
40
  }
41
- //#endregion
42
41
  export { s as AppHeader };
43
42
 
44
43
  //# sourceMappingURL=app-header.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-header.js","names":["_Fragment","AppHeader","props","sticky","density","cn","BASALT_UI_CLASS","className","leading","breadcrumbs","Fragment","Breadcrumbs","title","ChevronRight","actions"],"sources":["../../src/components/app-header.tsx"],"sourcesContent":["import { ChevronRight } from \"lucide-react\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Breadcrumbs } from \"./breadcrumbs\";\n\nexport function AppHeader({\n\tleading,\n\tbreadcrumbs,\n\ttitle,\n\tactions,\n\tsticky = false,\n\tdensity = \"comfortable\",\n\tclassName,\n\t...props\n}: HTMLAttributes<HTMLElement> & {\n\tleading?: ReactNode;\n\tbreadcrumbs?: { href?: string; label: ReactNode }[];\n\ttitle?: ReactNode;\n\tactions?: ReactNode;\n\t/** Keep this row visible in its current scroll owner, including the shell safe area. */\n\tsticky?: boolean;\n\t/** Compact is a 52px row; comfortable is 56px. */\n\tdensity?: \"comfortable\" | \"compact\";\n}) {\n\treturn (\n\t\t<header\n\t\t\tdata-basalt-header=\"\"\n\t\t\tdata-sticky={sticky || undefined}\n\t\t\tdata-density={density}\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"flex shrink-0 items-center justify-between gap-basalt-space-lg px-basalt-space-lg md:px-basalt-space-lg\",\n\t\t\t\tdensity === \"compact\" ? \"h-[3.25rem]\" : \"h-basalt-14\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<div className=\"flex min-w-0 items-center gap-basalt-space-lg\">\n\t\t\t\t{leading ? (\n\t\t\t\t\t<div data-basalt-header-leading=\"\" className=\"flex shrink-0 items-center\">\n\t\t\t\t\t\t{leading}\n\t\t\t\t\t</div>\n\t\t\t\t) : null}\n\t\t\t\t<div className=\"flex min-w-0 items-center gap-basalt-space-sm\">\n\t\t\t\t\t{breadcrumbs && breadcrumbs.length > 0 ? (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<Breadcrumbs items={breadcrumbs} className=\"min-w-0\" />\n\t\t\t\t\t\t\t{title ? (\n\t\t\t\t\t\t\t\t<ChevronRight\n\t\t\t\t\t\t\t\t\tclassName=\"size-basalt-icon-sm shrink-0 text-basalt-muted-foreground\"\n\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{title ? (\n\t\t\t\t\t\t<h1 className=\"truncate text-basalt-base font-normal text-basalt-foreground\">\n\t\t\t\t\t\t\t{title}\n\t\t\t\t\t\t</h1>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t{actions ? (\n\t\t\t\t<div\n\t\t\t\t\tdata-basalt-header-actions=\"\"\n\t\t\t\t\tclassName=\"flex shrink-0 items-center gap-basalt-space-sm\"\n\t\t\t\t>\n\t\t\t\t\t{actions}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</header>\n\t);\n}\n"],"mappings":";;;;;;;AAMA,SAAgBC,EAAU,EACzB,YACA,gBACA,UACA,YACA,YAAS,IACT,aAAU,eACV,cACA,GAAGC,KAUD;CACF,OACC,kBAAC,UAAD;EACC,sBAAmB;EACnB,eAAaC,KAAU,KAAA;EACvB,gBAAcC;EACd,WAAWC,EACVC,GACA,2GACAF,MAAY,YAAY,gBAAgB,eACxCG,CACD;EACA,GAAIL;EAVL,UAAA,CAYC,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACEM,IACA,kBAAC,OAAD;IAAK,8BAA2B;IAAG,WAAU;IAC3C,UAAAA;GACG,CAAA,IACF,MACJ,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACEC,KAAeA,EAAY,SAAS,IACpC,kBAAAT,GAAA,EAAA,UAAA,CACC,kBAACW,GAAD;KAAa,OAAOF;KAAa,WAAU;IAAW,CAAA,GACrDG,IACA,kBAACC,GAAD;KACC,WAAU;KACV,eAAY;IACZ,CAAA,IACE,IACH,EAAA,CAAA,IACC,MACHD,IACA,kBAAC,MAAD;KAAI,WAAU;KACZ,UAAAA;IACE,CAAA,IACD,IACA;GACD,CAAA,CAAA;EACJ,CAAA,GAAAE,IACA,kBAAC,OAAD;GACC,8BAA2B;GAC3B,WAAU;GAET,UAAAA;EACG,CAAA,IACF,IACG;;AAEV"}
1
+ {"version":3,"file":"app-header.js","names":["_Fragment","AppHeader","props","sticky","density","cn","BASALT_UI_CLASS","className","leading","breadcrumbs","Fragment","Breadcrumbs","title","ChevronRight","actions"],"sources":["../../src/components/app-header.tsx"],"sourcesContent":["import { ChevronRight } from \"lucide-react\";\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Breadcrumbs } from \"./breadcrumbs\";\n\nexport function AppHeader({\n\tleading,\n\tbreadcrumbs,\n\ttitle,\n\tactions,\n\tsticky = false,\n\tdensity = \"comfortable\",\n\tclassName,\n\t...props\n}: HTMLAttributes<HTMLElement> & {\n\tleading?: ReactNode;\n\tbreadcrumbs?: { href?: string; label: ReactNode }[];\n\ttitle?: ReactNode;\n\tactions?: ReactNode;\n\t/** Keep this row visible in its current scroll owner, including the shell safe area. */\n\tsticky?: boolean;\n\t/** Compact is a 52px row; comfortable is 56px. */\n\tdensity?: \"comfortable\" | \"compact\";\n}) {\n\treturn (\n\t\t<header\n\t\t\tdata-basalt-header=\"\"\n\t\t\tdata-sticky={sticky || undefined}\n\t\t\tdata-density={density}\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"flex shrink-0 items-center justify-between gap-basalt-space-lg px-basalt-space-lg md:px-basalt-layout-sm\",\n\t\t\t\tdensity === \"compact\" ? \"h-[3.25rem]\" : \"h-basalt-14\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<div className=\"flex min-w-0 items-center gap-basalt-space-lg\">\n\t\t\t\t{leading ? (\n\t\t\t\t\t<div data-basalt-header-leading=\"\" className=\"flex shrink-0 items-center\">\n\t\t\t\t\t\t{leading}\n\t\t\t\t\t</div>\n\t\t\t\t) : null}\n\t\t\t\t<div className=\"flex min-w-0 items-center gap-basalt-space-sm\">\n\t\t\t\t\t{breadcrumbs && breadcrumbs.length > 0 ? (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<Breadcrumbs items={breadcrumbs} className=\"min-w-0\" />\n\t\t\t\t\t\t\t{title ? (\n\t\t\t\t\t\t\t\t<ChevronRight\n\t\t\t\t\t\t\t\t\tclassName=\"size-basalt-icon-sm shrink-0 text-basalt-muted-foreground\"\n\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{title ? (\n\t\t\t\t\t\t<h1 className=\"truncate text-basalt-base font-normal text-basalt-foreground\">\n\t\t\t\t\t\t\t{title}\n\t\t\t\t\t\t</h1>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t{actions ? (\n\t\t\t\t<div\n\t\t\t\t\tdata-basalt-header-actions=\"\"\n\t\t\t\t\tclassName=\"flex shrink-0 items-center gap-basalt-space-sm\"\n\t\t\t\t>\n\t\t\t\t\t{actions}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</header>\n\t);\n}\n"],"mappings":";;;;;;;AAMA,SAAgBC,EAAU,EACzB,YACA,gBACA,UACA,YACA,YAAS,IACT,aAAU,eACV,cACA,GAAGC,KAUD;CACF,OACC,kBAAC,UAAD;EACC,sBAAmB;EACnB,eAAaC,KAAU,KAAA;EACvB,gBAAcC;EACd,WAAWC,EACVC,GACA,4GACAF,MAAY,YAAY,gBAAgB,eACxCG,CACD;EACA,GAAIL;EAVL,UAAA,CAYC,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACEM,IACA,kBAAC,OAAD;IAAK,8BAA2B;IAAG,WAAU;IAC3C,UAAAA;GACG,CAAA,IACF,MACJ,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACEC,KAAeA,EAAY,SAAS,IACpC,kBAAAT,GAAA,EAAA,UAAA,CACC,kBAACW,GAAD;KAAa,OAAOF;KAAa,WAAU;IAAW,CAAA,GACrDG,IACA,kBAACC,GAAD;KACC,WAAU;KACV,eAAY;IACZ,CAAA,IACE,IACH,EAAA,CAAA,IACC,MACHD,IACA,kBAAC,MAAD;KAAI,WAAU;KACZ,UAAAA;IACE,CAAA,IACD,IACA;GACD,CAAA,CAAA;EACJ,CAAA,GAAAE,IACA,kBAAC,OAAD;GACC,8BAA2B;GAC3B,WAAU;GAET,UAAAA;EACG,CAAA,IACF,IACG;;AAEV"}
@@ -2,11 +2,11 @@
2
2
  import { cn as e } from "../utils/cn.js";
3
3
  import { BASALT_UI_CLASS as t } from "../utils/control-surface.js";
4
4
  import { jsx as n } from "react/jsx-runtime";
5
- //#region src/components/app-shell.tsx
5
+ // src/components/app-shell.tsx
6
6
  function r({ href: r = "#main-content", className: i, children: a, ...o }) {
7
7
  return /* @__PURE__ */ n("a", {
8
8
  href: r,
9
- className: e(t, "sr-only focus:not-sr-only focus:absolute focus:top-basalt-2 focus:left-basalt-2 focus:z-[100] focus:rounded-basalt-md focus:bg-basalt-primary focus:px-basalt-space-lg focus:py-basalt-space-lg focus:text-basalt-base focus:font-medium focus:text-basalt-primary-foreground", i),
9
+ className: e(t, "basalt-focus", "sr-only focus:not-sr-only focus:absolute focus:top-basalt-2 focus:left-basalt-2 focus:z-[100] focus:rounded-basalt-md focus:bg-basalt-primary focus:px-basalt-space-lg focus:py-basalt-space-lg focus:text-basalt-base focus:font-medium focus:text-basalt-primary-foreground", i),
10
10
  ...o,
11
11
  children: a
12
12
  });
@@ -27,7 +27,6 @@ function a({ className: t, ...r }) {
27
27
  ...r
28
28
  });
29
29
  }
30
- //#endregion
31
30
  export { a as AppMain, i as AppShell, r as AppSkipLink };
32
31
 
33
32
  //# sourceMappingURL=app-shell.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-shell.js","names":["AppSkipLink","props","cn","BASALT_UI_CLASS","className","AppShell","layout","AppMain"],"sources":["../../src/components/app-shell.tsx"],"sourcesContent":["import type { AnchorHTMLAttributes, HTMLAttributes } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\n\nexport function AppSkipLink({\n\thref = \"#main-content\",\n\tclassName,\n\tchildren,\n\t...props\n}: AnchorHTMLAttributes<HTMLAnchorElement>) {\n\treturn (\n\t\t<a\n\t\t\thref={href}\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"sr-only focus:not-sr-only focus:absolute focus:top-basalt-2 focus:left-basalt-2 focus:z-[100] focus:rounded-basalt-md focus:bg-basalt-primary focus:px-basalt-space-lg focus:py-basalt-space-lg focus:text-basalt-base focus:font-medium focus:text-basalt-primary-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</a>\n\t);\n}\n\nexport function AppShell({\n\tlayout = \"workspace\",\n\tclassName,\n\t...props\n}: HTMLAttributes<HTMLDivElement> & {\n\t/** Scroll owner: bounded panes, document, or document below 768px. */\n\tlayout?: \"workspace\" | \"document\" | \"responsive\";\n}) {\n\treturn (\n\t\t<div\n\t\t\tdata-basalt-shell={layout}\n\t\t\tclassName={cn(\"flex w-full bg-basalt-background\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport function AppMain({ className, ...props }: HTMLAttributes<HTMLElement>) {\n\treturn (\n\t\t<main\n\t\t\tid=\"main-content\"\n\t\t\ttabIndex={-1}\n\t\t\tdata-basalt-main=\"\"\n\t\t\tclassName={cn(\"flex min-h-0 min-w-0 flex-1 flex-col\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":";;;;;AAIA,SAAgBA,EAAY,EAC3B,UAAO,iBACP,cACA,aACA,GAAGC,KACwC;CAC3C,OACC,kBAAC,KAAD;EACO;EACN,WAAWC,EACVC,GACA,iRACAC,CACD;EACA,GAAIH;EAEH;CACC,CAAA;AAEL;AAEA,SAAgBI,EAAS,EACxB,YAAS,aACT,cACA,GAAGJ,KAID;CACF,OACC,kBAAC,OAAD;EACC,qBAAmBK;EACnB,WAAWJ,EAAG,oCAAoCE,CAAS;EAC3D,GAAIH;CACJ,CAAA;AAEH;AAEA,SAAgBM,EAAQ,EAAE,cAAW,GAAGN,KAAsC;CAC7E,OACC,kBAAC,QAAD;EACC,IAAG;EACH,UAAU;EACV,oBAAiB;EACjB,WAAWC,EAAG,wCAAwCE,CAAS;EAC/D,GAAIH;CACJ,CAAA;AAEH"}
1
+ {"version":3,"file":"app-shell.js","names":["AppSkipLink","props","cn","BASALT_UI_CLASS","className","AppShell","layout","AppMain"],"sources":["../../src/components/app-shell.tsx"],"sourcesContent":["import type { AnchorHTMLAttributes, HTMLAttributes } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\n\nexport function AppSkipLink({\n\thref = \"#main-content\",\n\tclassName,\n\tchildren,\n\t...props\n}: AnchorHTMLAttributes<HTMLAnchorElement>) {\n\treturn (\n\t\t<a\n\t\t\thref={href}\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"basalt-focus\",\n\t\t\t\t\"sr-only focus:not-sr-only focus:absolute focus:top-basalt-2 focus:left-basalt-2 focus:z-[100] focus:rounded-basalt-md focus:bg-basalt-primary focus:px-basalt-space-lg focus:py-basalt-space-lg focus:text-basalt-base focus:font-medium focus:text-basalt-primary-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</a>\n\t);\n}\n\nexport function AppShell({\n\tlayout = \"workspace\",\n\tclassName,\n\t...props\n}: HTMLAttributes<HTMLDivElement> & {\n\t/** Scroll owner: bounded panes, document, or document below 768px. */\n\tlayout?: \"workspace\" | \"document\" | \"responsive\";\n}) {\n\treturn (\n\t\t<div\n\t\t\tdata-basalt-shell={layout}\n\t\t\tclassName={cn(\"flex w-full bg-basalt-background\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport function AppMain({ className, ...props }: HTMLAttributes<HTMLElement>) {\n\treturn (\n\t\t<main\n\t\t\tid=\"main-content\"\n\t\t\ttabIndex={-1}\n\t\t\tdata-basalt-main=\"\"\n\t\t\tclassName={cn(\"flex min-h-0 min-w-0 flex-1 flex-col\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":";;;;;AAIA,SAAgBA,EAAY,EAC3B,UAAO,iBACP,cACA,aACA,GAAGC,KACwC;CAC3C,OACC,kBAAC,KAAD;EACO;EACN,WAAWC,EACVC,GACA,gBACA,iRACAC,CACD;EACA,GAAIH;EAEH;CACC,CAAA;AAEL;AAEA,SAAgBI,EAAS,EACxB,YAAS,aACT,cACA,GAAGJ,KAID;CACF,OACC,kBAAC,OAAD;EACC,qBAAmBK;EACnB,WAAWJ,EAAG,oCAAoCE,CAAS;EAC3D,GAAIH;CACJ,CAAA;AAEH;AAEA,SAAgBM,EAAQ,EAAE,cAAW,GAAGN,KAAsC;CAC7E,OACC,kBAAC,QAAD;EACC,IAAG;EACH,UAAU;EACV,oBAAiB;EACjB,WAAWC,EAAG,wCAAwCE,CAAS;EAC/D,GAAIH;CACJ,CAAA;AAEH"}
@@ -10,7 +10,7 @@ import { Radio as s } from "./radio.js";
10
10
  import { useEffect as c, useId as l, useRef as u } from "react";
11
11
  import { ChevronLeft as d, X as f } from "lucide-react";
12
12
  import { jsx as p, jsxs as m } from "react/jsx-runtime";
13
- //#region src/components/approval-card.tsx
13
+ // src/components/approval-card.tsx
14
14
  function h({ className: h, onDismiss: g, ..._ }) {
15
15
  let v = o(_), y = l(), b = u(null), x = u(null), S = u(null), C = r(b);
16
16
  c(() => {
@@ -154,7 +154,6 @@ function h({ className: h, onDismiss: g, ..._ }) {
154
154
  ]
155
155
  });
156
156
  }
157
- //#endregion
158
157
  export { h as ApprovalCard };
159
158
 
160
159
  //# sourceMappingURL=approval-card.js.map
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { TypeaheadField as e } from "./typeahead-field.js";
3
3
  import { jsx as t } from "react/jsx-runtime";
4
- //#region src/components/autocomplete.tsx
4
+ // src/components/autocomplete.tsx
5
5
  function n({ placeholder: n = "Search…", ...r }) {
6
6
  return /* @__PURE__ */ t(e, {
7
7
  placeholder: n,
@@ -9,7 +9,6 @@ function n({ placeholder: n = "Search…", ...r }) {
9
9
  ...r
10
10
  });
11
11
  }
12
- //#endregion
13
12
  export { n as Autocomplete };
14
13
 
15
14
  //# sourceMappingURL=autocomplete.js.map
@@ -5,7 +5,7 @@ import { TAG_COLORS as r } from "./tag-badge.js";
5
5
  import * as i from "react";
6
6
  import { jsx as a } from "react/jsx-runtime";
7
7
  import * as o from "@radix-ui/react-avatar";
8
- //#region src/components/avatar.tsx
8
+ // src/components/avatar.tsx
9
9
  var s = i.forwardRef(({ className: t, ...n }, r) => /* @__PURE__ */ a(o.Root, {
10
10
  ref: r,
11
11
  className: e("relative flex h-basalt-9 w-basalt-9 shrink-0 overflow-hidden rounded-basalt-full", t),
@@ -43,7 +43,6 @@ function d({ name: r, colorKey: i, initials: o, size: c = "default", className:
43
43
  })
44
44
  });
45
45
  }
46
- //#endregion
47
46
  export { s as Avatar, l as AvatarFallback, c as AvatarImage, d as AvatarInitials };
48
47
 
49
48
  //# sourceMappingURL=avatar.js.map
@@ -3,7 +3,7 @@ import { cn as e } from "../utils/cn.js";
3
3
  import { BASALT_UI_CLASS as t } from "../utils/control-surface.js";
4
4
  import { cva as n } from "class-variance-authority";
5
5
  import { jsx as r, jsxs as i } from "react/jsx-runtime";
6
- //#region src/components/badge.tsx
6
+ // src/components/badge.tsx
7
7
  var a = n("inline-flex items-center gap-basalt-space-md rounded-basalt-full border basalt-inline font-medium", {
8
8
  variants: { variant: {
9
9
  default: "border-transparent bg-basalt-primary text-basalt-primary-foreground",
@@ -32,7 +32,6 @@ function o({ className: n, variant: o, dot: s, children: c, ...l }) {
32
32
  }) : null, c]
33
33
  });
34
34
  }
35
- //#endregion
36
35
  export { o as Badge };
37
36
 
38
37
  //# sourceMappingURL=badge.js.map
@@ -5,7 +5,7 @@ import { Button as n } from "./button.js";
5
5
  import { Children as r, createContext as i, isValidElement as a, useContext as o } from "react";
6
6
  import { cva as s } from "class-variance-authority";
7
7
  import { Fragment as c, jsx as l, jsxs as u } from "react/jsx-runtime";
8
- //#region src/components/banner.tsx
8
+ // src/components/banner.tsx
9
9
  var d = s("basalt-banner flex w-full items-start gap-basalt-space-lg rounded-basalt-md", {
10
10
  variants: {
11
11
  variant: {
@@ -84,7 +84,6 @@ function h({ className: t, variant: r = "default", size: i, icon: a, children: s
84
84
  }
85
85
  h.displayName = "Banner.Action";
86
86
  var g = Object.assign(m, { Action: h });
87
- //#endregion
88
87
  export { g as Banner, h as BannerAction };
89
88
 
90
89
  //# sourceMappingURL=banner.js.map
@@ -2,7 +2,7 @@
2
2
  import { cn as e } from "../utils/cn.js";
3
3
  import { basaltMarkPng as t } from "../assets/brand-mark.js";
4
4
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
5
- //#region src/components/basalt-mark.tsx
5
+ // src/components/basalt-mark.tsx
6
6
  function i({ className: i, ...a }) {
7
7
  return /* @__PURE__ */ r("svg", {
8
8
  className: e("h-basalt-5 w-basalt-5", i),
@@ -17,7 +17,6 @@ function i({ className: i, ...a }) {
17
17
  })]
18
18
  });
19
19
  }
20
- //#endregion
21
20
  export { i as BasaltMark };
22
21
 
23
22
  //# sourceMappingURL=basalt-mark.js.map
@@ -2,7 +2,7 @@
2
2
  import { cn as e } from "../utils/cn.js";
3
3
  import { BASALT_UI_CLASS as t } from "../utils/control-surface.js";
4
4
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
5
- //#region src/components/battery-meter.tsx
5
+ // src/components/battery-meter.tsx
6
6
  function i({ value: i, label: a, status: o = "discharging", className: s, ...c }) {
7
7
  let l = o !== "offline" && Number.isFinite(i), u = l ? Math.min(100, Math.max(0, i)) : 0, d = u <= 20 ? "bg-basalt-danger" : u <= 50 ? "bg-basalt-warning" : "bg-basalt-primary";
8
8
  return /* @__PURE__ */ r("div", {
@@ -50,7 +50,6 @@ function i({ value: i, label: a, status: o = "discharging", className: s, ...c }
50
50
  ]
51
51
  });
52
52
  }
53
- //#endregion
54
53
  export { i as BatteryMeter };
55
54
 
56
55
  //# sourceMappingURL=battery-meter.js.map
@@ -4,7 +4,7 @@ import { BASALT_UI_CLASS as t } from "../utils/control-surface.js";
4
4
  import { Link as n } from "./link.js";
5
5
  import { ChevronRight as r } from "lucide-react";
6
6
  import { jsx as i, jsxs as a } from "react/jsx-runtime";
7
- //#region src/components/breadcrumbs.tsx
7
+ // src/components/breadcrumbs.tsx
8
8
  var o = "text-basalt-base font-normal";
9
9
  function s({ items: s, className: c }) {
10
10
  return /* @__PURE__ */ i("nav", {
@@ -33,7 +33,6 @@ function s({ items: s, className: c }) {
33
33
  })
34
34
  });
35
35
  }
36
- //#endregion
37
36
  export { s as Breadcrumbs };
38
37
 
39
38
  //# sourceMappingURL=breadcrumbs.js.map
@@ -2,7 +2,7 @@ import { type VariantProps } from "class-variance-authority";
2
2
  import * as React from "react";
3
3
  declare const buttonVariants: (props?: ({
4
4
  variant?: "default" | "destructive" | "ghost" | "link" | "outline" | "secondary" | null | undefined;
5
- size?: "default" | "icon" | "lg" | "sm" | null | undefined;
5
+ size?: "default" | "icon" | "icon-sm" | "lg" | "sm" | null | undefined;
6
6
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
7
  export interface ButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "type">, Omit<VariantProps<typeof buttonVariants>, "variant" | "size"> {
8
8
  /**
@@ -7,7 +7,7 @@ import { Slot as i } from "@radix-ui/react-slot";
7
7
  import { cva as a } from "class-variance-authority";
8
8
  import { Loader2 as o } from "lucide-react";
9
9
  import { jsx as s, jsxs as c } from "react/jsx-runtime";
10
- //#region src/components/button.tsx
10
+ // src/components/button.tsx
11
11
  var l = a(`${t} relative inline-flex cursor-pointer items-center justify-center gap-basalt-control-gap rounded-basalt-md font-medium wrap-anywhere transition-colors basalt-motion before:absolute before:-inset-basalt-border-width ${n} disabled:pointer-events-none disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0`, {
12
12
  variants: {
13
13
  variant: {
@@ -22,7 +22,8 @@ var l = a(`${t} relative inline-flex cursor-pointer items-center justify-center
22
22
  default: "basalt-action [&_svg]:size-basalt-icon",
23
23
  sm: "basalt-action basalt-action-sm [&_svg]:size-basalt-icon",
24
24
  lg: "basalt-action basalt-action-lg [&_svg]:size-basalt-icon-lg",
25
- icon: "basalt-action basalt-action-icon shrink-0 [&_svg]:size-basalt-icon"
25
+ icon: "basalt-action basalt-action-icon shrink-0 [&_svg]:size-basalt-icon",
26
+ "icon-sm": "basalt-action basalt-action-icon-sm shrink-0 [&_svg]:size-basalt-icon"
26
27
  }
27
28
  },
28
29
  defaultVariants: {
@@ -117,7 +118,6 @@ var d = r.forwardRef(({ className: t, variant: n, size: r, icon: i, children: a,
117
118
  children: [i, a]
118
119
  }));
119
120
  d.displayName = "LinkButton";
120
- //#endregion
121
121
  export { u as Button, d as LinkButton, l as buttonVariants };
122
122
 
123
123
  //# sourceMappingURL=button.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"button.js","names":["React","buttonVariants","cva","BASALT_UI_CLASS","FOCUS_RING","Button","props","isDisabled","disabled","loading","asChild","children","childElement","isNativeButton","blockActivationEvent","event","handleKeyEvent","blockedHandlers","sanitizedChild","slotProps","Slot","cn","className","iconNode","Loader2","icon","LinkButton"],"sources":["../../src/components/button.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { Loader2 } 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\n// Keep rounded corners inside the button's rectangular pointer target.\nconst buttonVariants = cva(\n\t`${BASALT_UI_CLASS} relative inline-flex cursor-pointer items-center justify-center gap-basalt-control-gap rounded-basalt-md font-medium wrap-anywhere transition-colors basalt-motion before:absolute before:-inset-basalt-border-width ${FOCUS_RING} disabled:pointer-events-none disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0`,\n\t{\n\t\tvariants: {\n\t\t\tvariant: {\n\t\t\t\tdefault: \"bg-basalt-primary text-basalt-primary-foreground hover:bg-basalt-primary-hover\",\n\t\t\t\tsecondary: \"basalt-choice bg-basalt-control text-basalt-foreground hover:bg-basalt-hover\",\n\t\t\t\tdestructive:\n\t\t\t\t\t\"bg-basalt-destructive text-basalt-destructive-foreground hover:bg-basalt-destructive-hover\",\n\t\t\t\toutline:\n\t\t\t\t\t\"basalt-choice border border-basalt-border bg-basalt-control hover:bg-basalt-hover hover:text-basalt-accent-foreground\",\n\t\t\t\tghost: \"basalt-choice hover:bg-basalt-hover hover:text-basalt-accent-foreground\",\n\t\t\t\tlink: \"text-basalt-primary underline-offset-4 hover:underline\",\n\t\t\t},\n\t\t\tsize: {\n\t\t\t\tdefault: \"basalt-action [&_svg]:size-basalt-icon\",\n\t\t\t\tsm: \"basalt-action basalt-action-sm [&_svg]:size-basalt-icon\",\n\t\t\t\tlg: \"basalt-action basalt-action-lg [&_svg]:size-basalt-icon-lg\",\n\t\t\t\ticon: \"basalt-action basalt-action-icon shrink-0 [&_svg]:size-basalt-icon\",\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: {\n\t\t\tvariant: \"default\",\n\t\t\tsize: \"default\",\n\t\t},\n\t},\n);\n\nexport interface ButtonProps\n\textends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"type\">,\n\t\tOmit<VariantProps<typeof buttonVariants>, \"variant\" | \"size\"> {\n\t/**\n\t * Visual style variant.\n\t * @default \"default\"\n\t */\n\tvariant?: VariantProps<typeof buttonVariants>[\"variant\"];\n\t/**\n\t * Sizing preset.\n\t * @default \"default\"\n\t */\n\tsize?: VariantProps<typeof buttonVariants>[\"size\"];\n\t/**\n\t * Pass control to child element slot.\n\t *\n\t * Note: Child element must forward props and ref in all states. When disabled or loading,\n\t * asChild suppresses click, keyboard activation (Enter/Space), and pointer handlers on both\n\t * child and parent while retaining browser default Tab navigation without trapping focus.\n\t * To preserve single DOM node layout and avoid unexpected child layout shifts, no internal\n\t * spinner is inserted in asChild loading mode; visual disabled state is expressed via aria-disabled.\n\t *\n\t * @default false\n\t */\n\tasChild?: boolean;\n\t/**\n\t * Button type attribute.\n\t * @default \"button\"\n\t */\n\ttype?: React.ButtonHTMLAttributes<HTMLButtonElement>[\"type\"];\n\t/**\n\t * Display loading spinner and disable interactions.\n\t * @default false\n\t */\n\tloading?: boolean;\n\t/**\n\t * Optional leading icon slot.\n\t */\n\ticon?: React.ReactNode;\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\tvariant,\n\t\t\tsize,\n\t\t\tasChild = false,\n\t\t\ttype = \"button\",\n\t\t\tloading = false,\n\t\t\ticon,\n\t\t\tchildren,\n\t\t\tdisabled,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst isDisabled = Boolean(disabled || loading);\n\n\t\tif (asChild) {\n\t\t\tif (isDisabled && React.isValidElement(children)) {\n\t\t\t\tconst childElement = children as React.ReactElement<Record<string, unknown>>;\n\t\t\t\tconst isNativeButton =\n\t\t\t\t\ttypeof childElement.type === \"string\" && childElement.type.toLowerCase() === \"button\";\n\n\t\t\t\tconst blockActivationEvent = (event: React.SyntheticEvent | Event) => {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\tif (\n\t\t\t\t\t\t\"stopImmediatePropagation\" in event &&\n\t\t\t\t\t\ttypeof event.stopImmediatePropagation === \"function\"\n\t\t\t\t\t) {\n\t\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tconst handleKeyEvent = (event: React.KeyboardEvent) => {\n\t\t\t\t\tif (event.key === \"Enter\" || event.key === \" \" || event.key === \"Spacebar\") {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\tif (typeof event.nativeEvent?.stopImmediatePropagation === \"function\") {\n\t\t\t\t\t\tevent.nativeEvent.stopImmediatePropagation();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tconst blockedHandlers = {\n\t\t\t\t\tonClick: blockActivationEvent,\n\t\t\t\t\tonClickCapture: blockActivationEvent,\n\t\t\t\t\tonKeyDown: handleKeyEvent,\n\t\t\t\t\tonKeyDownCapture: handleKeyEvent,\n\t\t\t\t\tonKeyUp: handleKeyEvent,\n\t\t\t\t\tonKeyUpCapture: handleKeyEvent,\n\t\t\t\t\tonKeyPress: handleKeyEvent,\n\t\t\t\t\tonKeyPressCapture: handleKeyEvent,\n\t\t\t\t\tonMouseDown: blockActivationEvent,\n\t\t\t\t\tonMouseDownCapture: blockActivationEvent,\n\t\t\t\t\tonMouseUp: blockActivationEvent,\n\t\t\t\t\tonMouseUpCapture: blockActivationEvent,\n\t\t\t\t\tonPointerDown: blockActivationEvent,\n\t\t\t\t\tonPointerDownCapture: blockActivationEvent,\n\t\t\t\t\tonPointerUp: blockActivationEvent,\n\t\t\t\t\tonPointerUpCapture: blockActivationEvent,\n\t\t\t\t\tonAuxClick: blockActivationEvent,\n\t\t\t\t\tonAuxClickCapture: blockActivationEvent,\n\t\t\t\t};\n\n\t\t\t\tconst sanitizedChild = React.cloneElement(childElement, {\n\t\t\t\t\t...blockedHandlers,\n\t\t\t\t\t...(isNativeButton ? { disabled: true } : {}),\n\t\t\t\t\t\"aria-disabled\": true,\n\t\t\t\t\t\"aria-busy\": loading ? true : undefined,\n\t\t\t\t\ttabIndex: -1,\n\t\t\t\t});\n\n\t\t\t\tconst slotProps: Record<string, unknown> = {\n\t\t\t\t\t...props,\n\t\t\t\t\t...blockedHandlers,\n\t\t\t\t\t\"aria-disabled\": true,\n\t\t\t\t\t\"aria-busy\": loading ? \"true\" : undefined,\n\t\t\t\t\ttabIndex: -1,\n\t\t\t\t};\n\t\t\t\tif (isNativeButton) {\n\t\t\t\t\tslotProps.disabled = true;\n\t\t\t\t}\n\n\t\t\t\treturn (\n\t\t\t\t\t<Slot\n\t\t\t\t\t\tclassName={cn(buttonVariants({ variant, size }), className)}\n\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\t{...slotProps}\n\t\t\t\t\t>\n\t\t\t\t\t\t{sanitizedChild}\n\t\t\t\t\t</Slot>\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn (\n\t\t\t\t<Slot className={cn(buttonVariants({ variant, size }), className)} ref={ref} {...props}>\n\t\t\t\t\t{children}\n\t\t\t\t</Slot>\n\t\t\t);\n\t\t}\n\n\t\tconst iconNode = loading ? (\n\t\t\t<Loader2 className=\"animate-basalt-spin motion-reduce:animate-none\" aria-hidden=\"true\" />\n\t\t) : (\n\t\t\ticon\n\t\t);\n\t\treturn (\n\t\t\t<button\n\t\t\t\tclassName={cn(buttonVariants({ variant, size }), className)}\n\t\t\t\tref={ref}\n\t\t\t\ttype={type}\n\t\t\t\tdisabled={isDisabled}\n\t\t\t\taria-busy={loading || undefined}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{iconNode}\n\t\t\t\t{children}\n\t\t\t</button>\n\t\t);\n\t},\n);\nButton.displayName = \"Button\";\n\nexport interface LinkButtonProps\n\textends React.AnchorHTMLAttributes<HTMLAnchorElement>,\n\t\tOmit<VariantProps<typeof buttonVariants>, \"variant\" | \"size\"> {\n\t/**\n\t * Visual style variant.\n\t * @default \"default\"\n\t */\n\tvariant?: VariantProps<typeof buttonVariants>[\"variant\"];\n\t/**\n\t * Sizing preset.\n\t * @default \"default\"\n\t */\n\tsize?: VariantProps<typeof buttonVariants>[\"size\"];\n\t/**\n\t * Optional leading icon slot.\n\t */\n\ticon?: React.ReactNode;\n}\n\nexport const LinkButton = React.forwardRef<HTMLAnchorElement, LinkButtonProps>(\n\t({ className, variant, size, icon, children, ...props }, ref) => (\n\t\t<a ref={ref} className={cn(buttonVariants({ variant, size }), className)} {...props}>\n\t\t\t{icon}\n\t\t\t{children}\n\t\t</a>\n\t),\n);\nLinkButton.displayName = \"LinkButton\";\n\nexport { buttonVariants };\n"],"mappings":"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"}
1
+ {"version":3,"file":"button.js","names":["React","buttonVariants","cva","BASALT_UI_CLASS","FOCUS_RING","Button","props","isDisabled","disabled","loading","asChild","children","childElement","isNativeButton","blockActivationEvent","event","handleKeyEvent","blockedHandlers","sanitizedChild","slotProps","Slot","cn","className","iconNode","Loader2","icon","LinkButton"],"sources":["../../src/components/button.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { Loader2 } 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\n// Keep rounded corners inside the button's rectangular pointer target.\nconst buttonVariants = cva(\n\t`${BASALT_UI_CLASS} relative inline-flex cursor-pointer items-center justify-center gap-basalt-control-gap rounded-basalt-md font-medium wrap-anywhere transition-colors basalt-motion before:absolute before:-inset-basalt-border-width ${FOCUS_RING} disabled:pointer-events-none disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0`,\n\t{\n\t\tvariants: {\n\t\t\tvariant: {\n\t\t\t\tdefault: \"bg-basalt-primary text-basalt-primary-foreground hover:bg-basalt-primary-hover\",\n\t\t\t\tsecondary: \"basalt-choice bg-basalt-control text-basalt-foreground hover:bg-basalt-hover\",\n\t\t\t\tdestructive:\n\t\t\t\t\t\"bg-basalt-destructive text-basalt-destructive-foreground hover:bg-basalt-destructive-hover\",\n\t\t\t\toutline:\n\t\t\t\t\t\"basalt-choice border border-basalt-border bg-basalt-control hover:bg-basalt-hover hover:text-basalt-accent-foreground\",\n\t\t\t\tghost: \"basalt-choice hover:bg-basalt-hover hover:text-basalt-accent-foreground\",\n\t\t\t\tlink: \"text-basalt-primary underline-offset-4 hover:underline\",\n\t\t\t},\n\t\t\tsize: {\n\t\t\t\tdefault: \"basalt-action [&_svg]:size-basalt-icon\",\n\t\t\t\tsm: \"basalt-action basalt-action-sm [&_svg]:size-basalt-icon\",\n\t\t\t\tlg: \"basalt-action basalt-action-lg [&_svg]:size-basalt-icon-lg\",\n\t\t\t\ticon: \"basalt-action basalt-action-icon shrink-0 [&_svg]:size-basalt-icon\",\n\t\t\t\t\"icon-sm\": \"basalt-action basalt-action-icon-sm shrink-0 [&_svg]:size-basalt-icon\",\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: {\n\t\t\tvariant: \"default\",\n\t\t\tsize: \"default\",\n\t\t},\n\t},\n);\n\nexport interface ButtonProps\n\textends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"type\">,\n\t\tOmit<VariantProps<typeof buttonVariants>, \"variant\" | \"size\"> {\n\t/**\n\t * Visual style variant.\n\t * @default \"default\"\n\t */\n\tvariant?: VariantProps<typeof buttonVariants>[\"variant\"];\n\t/**\n\t * Sizing preset.\n\t * @default \"default\"\n\t */\n\tsize?: VariantProps<typeof buttonVariants>[\"size\"];\n\t/**\n\t * Pass control to child element slot.\n\t *\n\t * Note: Child element must forward props and ref in all states. When disabled or loading,\n\t * asChild suppresses click, keyboard activation (Enter/Space), and pointer handlers on both\n\t * child and parent while retaining browser default Tab navigation without trapping focus.\n\t * To preserve single DOM node layout and avoid unexpected child layout shifts, no internal\n\t * spinner is inserted in asChild loading mode; visual disabled state is expressed via aria-disabled.\n\t *\n\t * @default false\n\t */\n\tasChild?: boolean;\n\t/**\n\t * Button type attribute.\n\t * @default \"button\"\n\t */\n\ttype?: React.ButtonHTMLAttributes<HTMLButtonElement>[\"type\"];\n\t/**\n\t * Display loading spinner and disable interactions.\n\t * @default false\n\t */\n\tloading?: boolean;\n\t/**\n\t * Optional leading icon slot.\n\t */\n\ticon?: React.ReactNode;\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\tvariant,\n\t\t\tsize,\n\t\t\tasChild = false,\n\t\t\ttype = \"button\",\n\t\t\tloading = false,\n\t\t\ticon,\n\t\t\tchildren,\n\t\t\tdisabled,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst isDisabled = Boolean(disabled || loading);\n\n\t\tif (asChild) {\n\t\t\tif (isDisabled && React.isValidElement(children)) {\n\t\t\t\tconst childElement = children as React.ReactElement<Record<string, unknown>>;\n\t\t\t\tconst isNativeButton =\n\t\t\t\t\ttypeof childElement.type === \"string\" && childElement.type.toLowerCase() === \"button\";\n\n\t\t\t\tconst blockActivationEvent = (event: React.SyntheticEvent | Event) => {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\tif (\n\t\t\t\t\t\t\"stopImmediatePropagation\" in event &&\n\t\t\t\t\t\ttypeof event.stopImmediatePropagation === \"function\"\n\t\t\t\t\t) {\n\t\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tconst handleKeyEvent = (event: React.KeyboardEvent) => {\n\t\t\t\t\tif (event.key === \"Enter\" || event.key === \" \" || event.key === \"Spacebar\") {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\tif (typeof event.nativeEvent?.stopImmediatePropagation === \"function\") {\n\t\t\t\t\t\tevent.nativeEvent.stopImmediatePropagation();\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tconst blockedHandlers = {\n\t\t\t\t\tonClick: blockActivationEvent,\n\t\t\t\t\tonClickCapture: blockActivationEvent,\n\t\t\t\t\tonKeyDown: handleKeyEvent,\n\t\t\t\t\tonKeyDownCapture: handleKeyEvent,\n\t\t\t\t\tonKeyUp: handleKeyEvent,\n\t\t\t\t\tonKeyUpCapture: handleKeyEvent,\n\t\t\t\t\tonKeyPress: handleKeyEvent,\n\t\t\t\t\tonKeyPressCapture: handleKeyEvent,\n\t\t\t\t\tonMouseDown: blockActivationEvent,\n\t\t\t\t\tonMouseDownCapture: blockActivationEvent,\n\t\t\t\t\tonMouseUp: blockActivationEvent,\n\t\t\t\t\tonMouseUpCapture: blockActivationEvent,\n\t\t\t\t\tonPointerDown: blockActivationEvent,\n\t\t\t\t\tonPointerDownCapture: blockActivationEvent,\n\t\t\t\t\tonPointerUp: blockActivationEvent,\n\t\t\t\t\tonPointerUpCapture: blockActivationEvent,\n\t\t\t\t\tonAuxClick: blockActivationEvent,\n\t\t\t\t\tonAuxClickCapture: blockActivationEvent,\n\t\t\t\t};\n\n\t\t\t\tconst sanitizedChild = React.cloneElement(childElement, {\n\t\t\t\t\t...blockedHandlers,\n\t\t\t\t\t...(isNativeButton ? { disabled: true } : {}),\n\t\t\t\t\t\"aria-disabled\": true,\n\t\t\t\t\t\"aria-busy\": loading ? true : undefined,\n\t\t\t\t\ttabIndex: -1,\n\t\t\t\t});\n\n\t\t\t\tconst slotProps: Record<string, unknown> = {\n\t\t\t\t\t...props,\n\t\t\t\t\t...blockedHandlers,\n\t\t\t\t\t\"aria-disabled\": true,\n\t\t\t\t\t\"aria-busy\": loading ? \"true\" : undefined,\n\t\t\t\t\ttabIndex: -1,\n\t\t\t\t};\n\t\t\t\tif (isNativeButton) {\n\t\t\t\t\tslotProps.disabled = true;\n\t\t\t\t}\n\n\t\t\t\treturn (\n\t\t\t\t\t<Slot\n\t\t\t\t\t\tclassName={cn(buttonVariants({ variant, size }), className)}\n\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\t{...slotProps}\n\t\t\t\t\t>\n\t\t\t\t\t\t{sanitizedChild}\n\t\t\t\t\t</Slot>\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn (\n\t\t\t\t<Slot className={cn(buttonVariants({ variant, size }), className)} ref={ref} {...props}>\n\t\t\t\t\t{children}\n\t\t\t\t</Slot>\n\t\t\t);\n\t\t}\n\n\t\tconst iconNode = loading ? (\n\t\t\t<Loader2 className=\"animate-basalt-spin motion-reduce:animate-none\" aria-hidden=\"true\" />\n\t\t) : (\n\t\t\ticon\n\t\t);\n\t\treturn (\n\t\t\t<button\n\t\t\t\tclassName={cn(buttonVariants({ variant, size }), className)}\n\t\t\t\tref={ref}\n\t\t\t\ttype={type}\n\t\t\t\tdisabled={isDisabled}\n\t\t\t\taria-busy={loading || undefined}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{iconNode}\n\t\t\t\t{children}\n\t\t\t</button>\n\t\t);\n\t},\n);\nButton.displayName = \"Button\";\n\nexport interface LinkButtonProps\n\textends React.AnchorHTMLAttributes<HTMLAnchorElement>,\n\t\tOmit<VariantProps<typeof buttonVariants>, \"variant\" | \"size\"> {\n\t/**\n\t * Visual style variant.\n\t * @default \"default\"\n\t */\n\tvariant?: VariantProps<typeof buttonVariants>[\"variant\"];\n\t/**\n\t * Sizing preset.\n\t * @default \"default\"\n\t */\n\tsize?: VariantProps<typeof buttonVariants>[\"size\"];\n\t/**\n\t * Optional leading icon slot.\n\t */\n\ticon?: React.ReactNode;\n}\n\nexport const LinkButton = React.forwardRef<HTMLAnchorElement, LinkButtonProps>(\n\t({ className, variant, size, icon, children, ...props }, ref) => (\n\t\t<a ref={ref} className={cn(buttonVariants({ variant, size }), className)} {...props}>\n\t\t\t{icon}\n\t\t\t{children}\n\t\t</a>\n\t),\n);\nLinkButton.displayName = \"LinkButton\";\n\nexport { buttonVariants };\n"],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  import { cn as e } from "../utils/cn.js";
3
3
  import { BASALT_UI_CLASS as t } from "../utils/control-surface.js";
4
4
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
5
- //#region src/components/chat-bubble.tsx
5
+ // src/components/chat-bubble.tsx
6
6
  function i({ variant: i = "assistant", streaming: a = !1, className: o, children: s }) {
7
7
  if (i === "system") return /* @__PURE__ */ n("p", {
8
8
  className: e(t, "px-basalt-space-sm text-center text-basalt-sm text-basalt-muted-foreground", o),
@@ -21,7 +21,6 @@ function i({ variant: i = "assistant", streaming: a = !1, className: o, children
21
21
  })
22
22
  });
23
23
  }
24
- //#endregion
25
24
  export { i as ChatBubble };
26
25
 
27
26
  //# sourceMappingURL=chat-bubble.js.map
@@ -6,7 +6,7 @@ import { InputArea as r } from "./input-area.js";
6
6
  import { useId as i, useRef as a } from "react";
7
7
  import { ArrowUp as o, Paperclip as s, Square as c, X as l } from "lucide-react";
8
8
  import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
9
- //#region src/components/chat-composer.tsx
9
+ // src/components/chat-composer.tsx
10
10
  function p({ disabled: p = !1, streaming: m = !1, label: h = "Message", placeholder: g, onSend: _, onCancel: v, sendLabel: y = "Send message", cancelLabel: b = "Stop generating", className: x, value: S, defaultValue: C, onValueChange: w, toolbar: T, attachments: E = [], onRemoveAttachment: D, onFilesSelect: O, accept: k }) {
11
11
  let A = n({
12
12
  value: S,
@@ -25,7 +25,7 @@ function p({ disabled: p = !1, streaming: m = !1, label: h = "Message", placehol
25
25
  e.preventDefault(), F();
26
26
  },
27
27
  children: [/* @__PURE__ */ f("div", {
28
- className: "rounded-basalt-lg bg-basalt-control p-basalt-space-lg ring-1 ring-basalt-border focus-within:ring-basalt-ring",
28
+ className: "basalt-focus-group rounded-basalt-lg bg-basalt-control p-basalt-space-lg ring-1 ring-basalt-border",
29
29
  children: [
30
30
  E.length > 0 && /* @__PURE__ */ d("ul", {
31
31
  "aria-label": "Attachments",
@@ -133,7 +133,6 @@ function p({ disabled: p = !1, streaming: m = !1, label: h = "Message", placehol
133
133
  })]
134
134
  });
135
135
  }
136
- //#endregion
137
136
  export { p as ChatComposer };
138
137
 
139
138
  //# sourceMappingURL=chat-composer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-composer.js","names":["_Fragment","Fragment$1","ChatComposer","vm","useChatComposer","attachments","ref","useRef","fileInput","errorId","useId","composingRef","submit","cn","className","event","Paperclip","file","onRemoveAttachment","Button","disabled","streaming","X","InputArea","label","onFilesSelect","toolbar","onCancel","cancelLabel","Square","sendLabel","ArrowUp"],"sources":["../../src/components/chat-composer.tsx"],"sourcesContent":["import { ArrowUp, Paperclip, Square, X } from \"lucide-react\";\nimport { type FormEvent, type KeyboardEvent, type ReactNode, useId, useRef } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { useChatComposer } from \"../viewmodels/use-chat-composer\";\nimport { Button } from \"./button\";\nimport { InputArea } from \"./input-area\";\n\nexport interface ChatComposerProps {\n\t/** Controlled draft; keep one draft per conversation in the application. */\n\tvalue?: string;\n\t/** Initial draft when uncontrolled. */\n\tdefaultValue?: string;\n\tonValueChange?: (value: string) => void;\n\t/** Model, tool and context controls arranged before Send. */\n\ttoolbar?: ReactNode;\n\t/** Caller-owned attachments; this component never uploads files. */\n\tattachments?: readonly ChatComposerAttachment[];\n\tonRemoveAttachment?: (id: string) => void;\n\t/** Local file selection callback. File validation/upload belong to the application. */\n\tonFilesSelect?: (files: File[]) => void;\n\taccept?: string;\n\t/**\n\t * Disable the field and send.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n\t/**\n\t * Replace send with stop. When streaming is true, the stop button renders and triggers onCancel.\n\t * @default false\n\t */\n\tstreaming?: boolean;\n\t/**\n\t * Field accessible name.\n\t * @default \"Message\"\n\t */\n\tlabel?: string;\n\t/**\n\t * Placeholder when empty.\n\t */\n\tplaceholder?: string;\n\t/**\n\t * Called with trimmed text. Async failure preserves draft and attachments for retry.\n\t */\n\tonSend: (text: string) => void | Promise<void>;\n\t/**\n\t * Called when the stop control is pressed while streaming is active.\n\t */\n\tonCancel?: () => void;\n\t/**\n\t * Send control accessible name.\n\t * @default \"Send message\"\n\t */\n\tsendLabel?: string;\n\t/**\n\t * Stop control accessible name.\n\t * @default \"Stop generating\"\n\t */\n\tcancelLabel?: string;\n\t/**\n\t * Optional class name applied to the form container.\n\t * Component manages internal draft/height state and does not forward native form rest attributes or ref.\n\t */\n\tclassName?: string;\n}\n\nexport type ChatComposerAttachment = { id: string; name: string };\n\nexport function ChatComposer({\n\tdisabled = false,\n\tstreaming = false,\n\tlabel = \"Message\",\n\tplaceholder,\n\tonSend,\n\tonCancel,\n\tsendLabel = \"Send message\",\n\tcancelLabel = \"Stop generating\",\n\tclassName,\n\tvalue,\n\tdefaultValue,\n\tonValueChange,\n\ttoolbar,\n\tattachments = [],\n\tonRemoveAttachment,\n\tonFilesSelect,\n\taccept,\n}: ChatComposerProps) {\n\tconst vm = useChatComposer({\n\t\tvalue,\n\t\tdefaultValue,\n\t\tonValueChange,\n\t\tonSend,\n\t\tdisabled,\n\t\tstreaming,\n\t\thasAttachments: attachments.length > 0,\n\t});\n\tconst ref = useRef<HTMLTextAreaElement>(null);\n\tconst fileInput = useRef<HTMLInputElement>(null);\n\tconst errorId = useId();\n\tconst composingRef = useRef(false);\n\tconst submit = async () => {\n\t\tif (await vm.send()) ref.current?.focus();\n\t};\n\n\tconst onSubmit = (event: FormEvent) => {\n\t\tevent.preventDefault();\n\t\tvoid submit();\n\t};\n\n\tconst onKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n\t\tif (composingRef.current || event.nativeEvent.isComposing || event.keyCode === 229) {\n\t\t\treturn;\n\t\t}\n\t\tif (event.key !== \"Enter\" || event.shiftKey) {\n\t\t\treturn;\n\t\t}\n\t\tevent.preventDefault();\n\t\tvoid submit();\n\t};\n\n\treturn (\n\t\t<form className={cn(\"basalt-ui shrink-0\", className)} onSubmit={onSubmit}>\n\t\t\t<div className=\"rounded-basalt-lg bg-basalt-control p-basalt-space-lg ring-1 ring-basalt-border focus-within:ring-basalt-ring\">\n\t\t\t\t{attachments.length > 0 && (\n\t\t\t\t\t<ul\n\t\t\t\t\t\taria-label=\"Attachments\"\n\t\t\t\t\t\tclassName=\"mb-basalt-space-lg flex flex-wrap gap-basalt-space-md\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{attachments.map((file) => (\n\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\tkey={file.id}\n\t\t\t\t\t\t\t\tclassName=\"flex min-w-0 max-w-full items-center gap-basalt-space-sm rounded-basalt-md bg-basalt-secondary py-basalt-space-sm pl-basalt-space-lg pr-basalt-space-sm text-basalt-sm\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Paperclip aria-hidden=\"true\" className=\"size-basalt-icon shrink-0\" />\n\t\t\t\t\t\t\t\t<span className=\"truncate\">{file.name}</span>\n\t\t\t\t\t\t\t\t{onRemoveAttachment && (\n\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\t\tdisabled={disabled || vm.pending || streaming}\n\t\t\t\t\t\t\t\t\t\tclassName=\"size-basalt-5\"\n\t\t\t\t\t\t\t\t\t\taria-label={`Remove ${file.name}`}\n\t\t\t\t\t\t\t\t\t\tonClick={() => onRemoveAttachment(file.id)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<X />\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</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t)}\n\t\t\t\t<InputArea\n\t\t\t\t\tref={ref}\n\t\t\t\t\tvalue={vm.value}\n\t\t\t\t\tonChange={(event) => vm.update(event.target.value)}\n\t\t\t\t\tonCompositionStart={() => {\n\t\t\t\t\t\tcomposingRef.current = true;\n\t\t\t\t\t}}\n\t\t\t\t\tonCompositionEnd={() => {\n\t\t\t\t\t\tcomposingRef.current = false;\n\t\t\t\t\t}}\n\t\t\t\t\tonKeyDown={onKeyDown}\n\t\t\t\t\trows={1}\n\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\tdisabled={disabled || vm.pending}\n\t\t\t\t\taria-label={label}\n\t\t\t\t\taria-describedby={vm.error ? errorId : undefined}\n\t\t\t\t\taria-description=\"Enter to send, Shift+Enter for a new line\"\n\t\t\t\t\tclassName=\"basalt-chat-input min-h-[calc(1lh+var(--basalt-space-2))] resize-none overflow-y-auto border-0 bg-transparent px-basalt-space-sm py-basalt-space-sm text-basalt-base leading-[var(--basalt-line-body)] shadow-none ring-0 outline-none\"\n\t\t\t\t/>\n\t\t\t\t<div className=\"mt-basalt-content-gap flex items-center justify-between gap-basalt-content-gap\">\n\t\t\t\t\t<div className=\"flex min-w-0 flex-1 flex-wrap items-center gap-basalt-space-sm\">\n\t\t\t\t\t\t{onFilesSelect && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\tref={fileInput}\n\t\t\t\t\t\t\t\t\ttype=\"file\"\n\t\t\t\t\t\t\t\t\tmultiple\n\t\t\t\t\t\t\t\t\taccept={accept}\n\t\t\t\t\t\t\t\t\thidden\n\t\t\t\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\t\t\t\tonFilesSelect(Array.from(event.target.files ?? []));\n\t\t\t\t\t\t\t\t\t\tevent.target.value = \"\";\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<Button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\taria-label=\"Attach files\"\n\t\t\t\t\t\t\t\t\tdisabled={disabled || vm.pending || streaming}\n\t\t\t\t\t\t\t\t\tonClick={() => fileInput.current?.click()}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Paperclip />\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<fieldset disabled={disabled || streaming || vm.pending} className=\"contents\">\n\t\t\t\t\t\t\t{toolbar}\n\t\t\t\t\t\t</fieldset>\n\t\t\t\t\t</div>\n\t\t\t\t\t{streaming ? (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\t\tonClick={onCancel}\n\t\t\t\t\t\t\tdisabled={disabled || !onCancel}\n\t\t\t\t\t\t\taria-label={cancelLabel}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Square className=\"h-basalt-3_5 w-basalt-3_5 fill-current\" strokeWidth={0} />\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\tdisabled={!vm.canSend}\n\t\t\t\t\t\t\tloading={vm.pending}\n\t\t\t\t\t\t\taria-label={sendLabel}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<ArrowUp className=\"h-basalt-4 w-basalt-4\" strokeWidth={2.25} />\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t{vm.error && (\n\t\t\t\t<p\n\t\t\t\t\tid={errorId}\n\t\t\t\t\trole=\"alert\"\n\t\t\t\t\tclassName=\"mt-basalt-content-gap text-basalt-sm text-basalt-danger\"\n\t\t\t\t>\n\t\t\t\t\t{vm.error}\n\t\t\t\t</p>\n\t\t\t)}\n\t\t</form>\n\t);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"chat-composer.js","names":["_Fragment","Fragment$1","ChatComposer","vm","useChatComposer","attachments","ref","useRef","fileInput","errorId","useId","composingRef","submit","cn","className","event","Paperclip","file","onRemoveAttachment","Button","disabled","streaming","X","InputArea","label","onFilesSelect","toolbar","onCancel","cancelLabel","Square","sendLabel","ArrowUp"],"sources":["../../src/components/chat-composer.tsx"],"sourcesContent":["import { ArrowUp, Paperclip, Square, X } from \"lucide-react\";\nimport { type FormEvent, type KeyboardEvent, type ReactNode, useId, useRef } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { useChatComposer } from \"../viewmodels/use-chat-composer\";\nimport { Button } from \"./button\";\nimport { InputArea } from \"./input-area\";\n\nexport interface ChatComposerProps {\n\t/** Controlled draft; keep one draft per conversation in the application. */\n\tvalue?: string;\n\t/** Initial draft when uncontrolled. */\n\tdefaultValue?: string;\n\tonValueChange?: (value: string) => void;\n\t/** Model, tool and context controls arranged before Send. */\n\ttoolbar?: ReactNode;\n\t/** Caller-owned attachments; this component never uploads files. */\n\tattachments?: readonly ChatComposerAttachment[];\n\tonRemoveAttachment?: (id: string) => void;\n\t/** Local file selection callback. File validation/upload belong to the application. */\n\tonFilesSelect?: (files: File[]) => void;\n\taccept?: string;\n\t/**\n\t * Disable the field and send.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n\t/**\n\t * Replace send with stop. When streaming is true, the stop button renders and triggers onCancel.\n\t * @default false\n\t */\n\tstreaming?: boolean;\n\t/**\n\t * Field accessible name.\n\t * @default \"Message\"\n\t */\n\tlabel?: string;\n\t/**\n\t * Placeholder when empty.\n\t */\n\tplaceholder?: string;\n\t/**\n\t * Called with trimmed text. Async failure preserves draft and attachments for retry.\n\t */\n\tonSend: (text: string) => void | Promise<void>;\n\t/**\n\t * Called when the stop control is pressed while streaming is active.\n\t */\n\tonCancel?: () => void;\n\t/**\n\t * Send control accessible name.\n\t * @default \"Send message\"\n\t */\n\tsendLabel?: string;\n\t/**\n\t * Stop control accessible name.\n\t * @default \"Stop generating\"\n\t */\n\tcancelLabel?: string;\n\t/**\n\t * Optional class name applied to the form container.\n\t * Component manages internal draft/height state and does not forward native form rest attributes or ref.\n\t */\n\tclassName?: string;\n}\n\nexport type ChatComposerAttachment = { id: string; name: string };\n\nexport function ChatComposer({\n\tdisabled = false,\n\tstreaming = false,\n\tlabel = \"Message\",\n\tplaceholder,\n\tonSend,\n\tonCancel,\n\tsendLabel = \"Send message\",\n\tcancelLabel = \"Stop generating\",\n\tclassName,\n\tvalue,\n\tdefaultValue,\n\tonValueChange,\n\ttoolbar,\n\tattachments = [],\n\tonRemoveAttachment,\n\tonFilesSelect,\n\taccept,\n}: ChatComposerProps) {\n\tconst vm = useChatComposer({\n\t\tvalue,\n\t\tdefaultValue,\n\t\tonValueChange,\n\t\tonSend,\n\t\tdisabled,\n\t\tstreaming,\n\t\thasAttachments: attachments.length > 0,\n\t});\n\tconst ref = useRef<HTMLTextAreaElement>(null);\n\tconst fileInput = useRef<HTMLInputElement>(null);\n\tconst errorId = useId();\n\tconst composingRef = useRef(false);\n\tconst submit = async () => {\n\t\tif (await vm.send()) ref.current?.focus();\n\t};\n\n\tconst onSubmit = (event: FormEvent) => {\n\t\tevent.preventDefault();\n\t\tvoid submit();\n\t};\n\n\tconst onKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n\t\tif (composingRef.current || event.nativeEvent.isComposing || event.keyCode === 229) {\n\t\t\treturn;\n\t\t}\n\t\tif (event.key !== \"Enter\" || event.shiftKey) {\n\t\t\treturn;\n\t\t}\n\t\tevent.preventDefault();\n\t\tvoid submit();\n\t};\n\n\treturn (\n\t\t<form className={cn(\"basalt-ui shrink-0\", className)} onSubmit={onSubmit}>\n\t\t\t<div className=\"basalt-focus-group rounded-basalt-lg bg-basalt-control p-basalt-space-lg ring-1 ring-basalt-border\">\n\t\t\t\t{attachments.length > 0 && (\n\t\t\t\t\t<ul\n\t\t\t\t\t\taria-label=\"Attachments\"\n\t\t\t\t\t\tclassName=\"mb-basalt-space-lg flex flex-wrap gap-basalt-space-md\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{attachments.map((file) => (\n\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\tkey={file.id}\n\t\t\t\t\t\t\t\tclassName=\"flex min-w-0 max-w-full items-center gap-basalt-space-sm rounded-basalt-md bg-basalt-secondary py-basalt-space-sm pl-basalt-space-lg pr-basalt-space-sm text-basalt-sm\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Paperclip aria-hidden=\"true\" className=\"size-basalt-icon shrink-0\" />\n\t\t\t\t\t\t\t\t<span className=\"truncate\">{file.name}</span>\n\t\t\t\t\t\t\t\t{onRemoveAttachment && (\n\t\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\t\tdisabled={disabled || vm.pending || streaming}\n\t\t\t\t\t\t\t\t\t\tclassName=\"size-basalt-5\"\n\t\t\t\t\t\t\t\t\t\taria-label={`Remove ${file.name}`}\n\t\t\t\t\t\t\t\t\t\tonClick={() => onRemoveAttachment(file.id)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<X />\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</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t)}\n\t\t\t\t<InputArea\n\t\t\t\t\tref={ref}\n\t\t\t\t\tvalue={vm.value}\n\t\t\t\t\tonChange={(event) => vm.update(event.target.value)}\n\t\t\t\t\tonCompositionStart={() => {\n\t\t\t\t\t\tcomposingRef.current = true;\n\t\t\t\t\t}}\n\t\t\t\t\tonCompositionEnd={() => {\n\t\t\t\t\t\tcomposingRef.current = false;\n\t\t\t\t\t}}\n\t\t\t\t\tonKeyDown={onKeyDown}\n\t\t\t\t\trows={1}\n\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\tdisabled={disabled || vm.pending}\n\t\t\t\t\taria-label={label}\n\t\t\t\t\taria-describedby={vm.error ? errorId : undefined}\n\t\t\t\t\taria-description=\"Enter to send, Shift+Enter for a new line\"\n\t\t\t\t\tclassName=\"basalt-chat-input min-h-[calc(1lh+var(--basalt-space-2))] resize-none overflow-y-auto border-0 bg-transparent px-basalt-space-sm py-basalt-space-sm text-basalt-base leading-[var(--basalt-line-body)] shadow-none ring-0 outline-none\"\n\t\t\t\t/>\n\t\t\t\t<div className=\"mt-basalt-content-gap flex items-center justify-between gap-basalt-content-gap\">\n\t\t\t\t\t<div className=\"flex min-w-0 flex-1 flex-wrap items-center gap-basalt-space-sm\">\n\t\t\t\t\t\t{onFilesSelect && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\tref={fileInput}\n\t\t\t\t\t\t\t\t\ttype=\"file\"\n\t\t\t\t\t\t\t\t\tmultiple\n\t\t\t\t\t\t\t\t\taccept={accept}\n\t\t\t\t\t\t\t\t\thidden\n\t\t\t\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\t\t\t\tonFilesSelect(Array.from(event.target.files ?? []));\n\t\t\t\t\t\t\t\t\t\tevent.target.value = \"\";\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<Button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\taria-label=\"Attach files\"\n\t\t\t\t\t\t\t\t\tdisabled={disabled || vm.pending || streaming}\n\t\t\t\t\t\t\t\t\tonClick={() => fileInput.current?.click()}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Paperclip />\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<fieldset disabled={disabled || streaming || vm.pending} className=\"contents\">\n\t\t\t\t\t\t\t{toolbar}\n\t\t\t\t\t\t</fieldset>\n\t\t\t\t\t</div>\n\t\t\t\t\t{streaming ? (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\t\tonClick={onCancel}\n\t\t\t\t\t\t\tdisabled={disabled || !onCancel}\n\t\t\t\t\t\t\taria-label={cancelLabel}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Square className=\"h-basalt-3_5 w-basalt-3_5 fill-current\" strokeWidth={0} />\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\tdisabled={!vm.canSend}\n\t\t\t\t\t\t\tloading={vm.pending}\n\t\t\t\t\t\t\taria-label={sendLabel}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<ArrowUp className=\"h-basalt-4 w-basalt-4\" strokeWidth={2.25} />\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t{vm.error && (\n\t\t\t\t<p\n\t\t\t\t\tid={errorId}\n\t\t\t\t\trole=\"alert\"\n\t\t\t\t\tclassName=\"mt-basalt-content-gap text-basalt-sm text-basalt-danger\"\n\t\t\t\t>\n\t\t\t\t\t{vm.error}\n\t\t\t\t</p>\n\t\t\t)}\n\t\t</form>\n\t);\n}\n"],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  import { cn as e } from "../utils/cn.js";
3
3
  import { BASALT_UI_CLASS as t } from "../utils/control-surface.js";
4
4
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
5
- //#region src/components/chat-header.tsx
5
+ // src/components/chat-header.tsx
6
6
  function i({ title: i, subtitle: a, leading: o, children: s, className: c, ...l }) {
7
7
  return /* @__PURE__ */ r("header", {
8
8
  className: e(t, "flex items-center justify-between gap-basalt-content-gap border-b border-basalt-border/50 px-basalt-panel-x py-basalt-panel-y leading-[var(--basalt-line-body)]", c),
@@ -28,7 +28,6 @@ function i({ title: i, subtitle: a, leading: o, children: s, className: c, ...l
28
28
  }) : null]
29
29
  });
30
30
  }
31
- //#endregion
32
31
  export { i as ChatHeader };
33
32
 
34
33
  //# sourceMappingURL=chat-header.js.map
@@ -3,7 +3,7 @@ import { cn as e } from "../utils/cn.js";
3
3
  import { useHoverHighlight as t } from "../utils/use-hover-highlight.js";
4
4
  import { NAV_ITEM_CLASS as n, NAV_LIST_CLASS as r } from "../utils/navigation.js";
5
5
  import { jsx as i, jsxs as a } from "react/jsx-runtime";
6
- //#region src/components/chat-inbox.tsx
6
+ // src/components/chat-inbox.tsx
7
7
  function o({ items: o, activeId: s, onSelect: c, className: l, ...u }) {
8
8
  let d = t();
9
9
  return /* @__PURE__ */ i("nav", {
@@ -42,7 +42,6 @@ function o({ items: o, activeId: s, onSelect: c, className: l, ...u }) {
42
42
  })
43
43
  });
44
44
  }
45
- //#endregion
46
45
  export { o as ChatInbox };
47
46
 
48
47
  //# sourceMappingURL=chat-inbox.js.map
@@ -6,7 +6,7 @@ import { Fragment as r, useMemo as i } from "react";
6
6
  import { jsx as a, jsxs as o } from "react/jsx-runtime";
7
7
  import { decodeHTML as s } from "entities";
8
8
  import { marked as c } from "marked";
9
- //#region src/components/chat-markdown.tsx
9
+ // src/components/chat-markdown.tsx
10
10
  function l(i, c = !1) {
11
11
  return i.map((i, u) => {
12
12
  let d = i, f;
@@ -116,7 +116,6 @@ function u({ content: t, streaming: n = !1, className: r }) {
116
116
  children: o
117
117
  });
118
118
  }
119
- //#endregion
120
119
  export { u as ChatMarkdown };
121
120
 
122
121
  //# sourceMappingURL=chat-markdown.js.map
@@ -6,7 +6,7 @@ import { useChatMessage as a } from "../viewmodels/use-chat-message.js";
6
6
  import { ChatMarkdown as o } from "./chat-markdown.js";
7
7
  import { Check as s, Copy as c, ExternalLink as l, FileText as u, Pencil as d, RotateCcw as f, ThumbsDown as p, ThumbsUp as m } from "lucide-react";
8
8
  import { Fragment as h, jsx as g, jsxs as _ } from "react/jsx-runtime";
9
- //#region src/components/chat-message.tsx
9
+ // src/components/chat-message.tsx
10
10
  function v({ variant: v, content: y, streaming: b, trace: x, children: S, author: C, onEdit: w, onRegenerate: T, feedback: E, onFeedback: D, className: O, sources: k = [], sourcesLabel: A = "Sources" }) {
11
11
  let j = a(y, k);
12
12
  return /* @__PURE__ */ _("article", {
@@ -111,7 +111,7 @@ function v({ variant: v, content: y, streaming: b, trace: x, children: S, author
111
111
  href: e.href,
112
112
  target: e.href ? "_blank" : void 0,
113
113
  rel: e.href ? "noopener noreferrer" : void 0,
114
- className: "flex min-w-0 items-center gap-basalt-row-gap rounded-basalt-sm px-basalt-row-x py-basalt-control-y text-basalt-sm leading-[var(--basalt-line-body)] text-basalt-muted-foreground outline-hidden hover:bg-basalt-hover focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-basalt-ring",
114
+ className: "basalt-focus basalt-focus-inset flex min-w-0 items-center gap-basalt-row-gap rounded-basalt-sm px-basalt-row-x py-basalt-control-y text-basalt-sm leading-[var(--basalt-line-body)] text-basalt-muted-foreground hover:bg-basalt-hover",
115
115
  children: [
116
116
  /* @__PURE__ */ g(u, {
117
117
  "aria-hidden": "true",
@@ -139,7 +139,6 @@ function v({ variant: v, content: y, streaming: b, trace: x, children: S, author
139
139
  })]
140
140
  });
141
141
  }
142
- //#endregion
143
142
  export { v as ChatMessage };
144
143
 
145
144
  //# sourceMappingURL=chat-message.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-message.js","names":["_Fragment","ChatMessage","vm","useChatMessage","content","sources","author","variant","cn","className","trace","ChatMarkdown","streaming","children","Collapsible","Button","text","Check","Copy","onEdit","Pencil","onRegenerate","RotateCcw","onFeedback","Fragment","feedback","ThumbsUp","ThumbsDown","CollapsibleTrigger","sourcesLabel","FileText","CollapsibleContent","Source","source","ExternalLink"],"sources":["../../src/components/chat-message.tsx"],"sourcesContent":["import {\n\tCheck,\n\tCopy,\n\tExternalLink,\n\tFileText,\n\tPencil,\n\tRotateCcw,\n\tThumbsDown,\n\tThumbsUp,\n} from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { useChatMessage } from \"../viewmodels/use-chat-message\";\nimport { Button } from \"./button\";\nimport { ChatMarkdown } from \"./chat-markdown\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"./collapsible\";\n\nexport interface ChatMessageProps {\n\tvariant: \"user\" | \"assistant\";\n\tcontent: string;\n\tstreaming?: boolean;\n\t/** Thinking, tool calls and other trace content before the response. */\n\ttrace?: ReactNode;\n\t/** Approval or result content after the response; use sources for citations. */\n\tchildren?: ReactNode;\n\tauthor?: string;\n\tonEdit?: () => void;\n\tonRegenerate?: () => void;\n\tfeedback?: \"up\" | \"down\";\n\tonFeedback?: (value: \"up\" | \"down\") => void;\n\t/** Compact source disclosure beside message actions. No card wrapper is added. */\n\tsources?: readonly { id: string; name: string; type?: string; href?: string }[];\n\t/** Source disclosure label. @default \"Sources\" */\n\tsourcesLabel?: string;\n\tclassName?: string;\n}\n\nexport function ChatMessage({\n\tvariant,\n\tcontent,\n\tstreaming,\n\ttrace,\n\tchildren,\n\tauthor,\n\tonEdit,\n\tonRegenerate,\n\tfeedback,\n\tonFeedback,\n\tclassName,\n\tsources = [],\n\tsourcesLabel = \"Sources\",\n}: ChatMessageProps) {\n\tconst vm = useChatMessage(content, sources);\n\treturn (\n\t\t<article\n\t\t\taria-label={`${author || (variant === \"user\" ? \"You\" : \"Assistant\")} message`}\n\t\t\tclassName={cn(\"basalt-ui group min-w-0 space-y-basalt-content-gap\", className)}\n\t\t>\n\t\t\t<div className={cn(\"flex\", variant === \"user\" ? \"justify-end\" : \"justify-start\")}>\n\t\t\t\t<div\n\t\t\t\t\tdata-basalt-surface={variant === \"user\" ? \"\" : undefined}\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"min-w-0 space-y-basalt-content-gap\",\n\t\t\t\t\t\tvariant === \"user\"\n\t\t\t\t\t\t\t? \"max-w-[90%] rounded-basalt-lg px-basalt-panel-x py-basalt-panel-y\"\n\t\t\t\t\t\t\t: \"w-full\",\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t{trace}\n\t\t\t\t\t{content &&\n\t\t\t\t\t\t(variant === \"user\" ? (\n\t\t\t\t\t\t\t<p className=\"whitespace-pre-wrap break-words text-basalt-base leading-[var(--basalt-line-relaxed)]\">\n\t\t\t\t\t\t\t\t{content}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<ChatMarkdown content={content} streaming={streaming} />\n\t\t\t\t\t\t))}\n\t\t\t\t\t{streaming && (\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\tclassName=\"inline-block size-basalt-2 rounded-basalt-full bg-basalt-primary animate-pulse motion-reduce:animate-none\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{children}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t{!streaming && content && (\n\t\t\t\t<Collapsible className=\"space-y-basalt-content-gap\">\n\t\t\t\t\t<div\n\t\t\t\t\t\tdata-slot=\"chat-actions\"\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\"flex flex-wrap items-center gap-basalt-space-xs text-basalt-muted-foreground\",\n\t\t\t\t\t\t\tvariant === \"user\"\n\t\t\t\t\t\t\t\t? \"justify-end -mr-[calc((var(--basalt-size-action)-var(--basalt-size-icon))/2)]\"\n\t\t\t\t\t\t\t\t: \"-ml-[calc((var(--basalt-size-action)-var(--basalt-size-icon))/2)]\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\taria-label={vm.copied ? \"Copied\" : \"Copy message\"}\n\t\t\t\t\t\t\tonClick={() => void vm.copy((text) => navigator.clipboard.writeText(text))}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{vm.copied ? <Check strokeWidth={1.5} /> : <Copy strokeWidth={1.5} />}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t{onEdit && (\n\t\t\t\t\t\t\t<Button size=\"icon\" variant=\"ghost\" aria-label=\"Edit message\" onClick={onEdit}>\n\t\t\t\t\t\t\t\t<Pencil strokeWidth={1.5} />\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{onRegenerate && (\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\taria-label=\"Regenerate response\"\n\t\t\t\t\t\t\t\tonClick={onRegenerate}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<RotateCcw strokeWidth={1.5} />\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{onFeedback && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\taria-label=\"Helpful\"\n\t\t\t\t\t\t\t\t\taria-pressed={feedback === \"up\"}\n\t\t\t\t\t\t\t\t\tonClick={() => onFeedback(\"up\")}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ThumbsUp strokeWidth={1.5} />\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\taria-label=\"Not helpful\"\n\t\t\t\t\t\t\t\t\taria-pressed={feedback === \"down\"}\n\t\t\t\t\t\t\t\t\tonClick={() => onFeedback(\"down\")}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ThumbsDown strokeWidth={1.5} />\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{vm.sources.length > 0 && (\n\t\t\t\t\t\t\t<CollapsibleTrigger\n\t\t\t\t\t\t\t\taria-label={`${sourcesLabel} ${vm.sources.length}`}\n\t\t\t\t\t\t\t\tclassName=\"ml-basalt-control-gap min-h-basalt-action gap-basalt-control-gap rounded-basalt-sm px-basalt-space-sm text-basalt-sm font-normal text-basalt-muted-foreground hover:bg-basalt-hover\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span className=\"flex items-center gap-basalt-control-gap\">\n\t\t\t\t\t\t\t\t\t<FileText aria-hidden=\"true\" className=\"size-basalt-icon\" strokeWidth={1.5} />\n\t\t\t\t\t\t\t\t\t<span>{sourcesLabel}</span>\n\t\t\t\t\t\t\t\t\t<span className=\"tabular-nums\">{vm.sources.length}</span>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</CollapsibleTrigger>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{vm.copyError && (\n\t\t\t\t\t\t\t<span role=\"alert\" className=\"text-basalt-sm text-basalt-danger\">\n\t\t\t\t\t\t\t\tCould not copy\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t\t{vm.sources.length > 0 && (\n\t\t\t\t\t\t<CollapsibleContent unstyled>\n\t\t\t\t\t\t\t<ul aria-label={sourcesLabel} className=\"space-y-basalt-space-xs\">\n\t\t\t\t\t\t\t\t{vm.sources.map((source) => {\n\t\t\t\t\t\t\t\t\tconst Source = source.href ? \"a\" : \"span\";\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<li key={source.id}>\n\t\t\t\t\t\t\t\t\t\t\t<Source\n\t\t\t\t\t\t\t\t\t\t\t\thref={source.href}\n\t\t\t\t\t\t\t\t\t\t\t\ttarget={source.href ? \"_blank\" : undefined}\n\t\t\t\t\t\t\t\t\t\t\t\trel={source.href ? \"noopener noreferrer\" : undefined}\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"flex min-w-0 items-center gap-basalt-row-gap rounded-basalt-sm px-basalt-row-x py-basalt-control-y text-basalt-sm leading-[var(--basalt-line-body)] text-basalt-muted-foreground outline-hidden hover:bg-basalt-hover focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-basalt-ring\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<FileText\n\t\t\t\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"size-basalt-icon shrink-0\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"min-w-0 flex-1 break-words\">{source.name}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t{source.type && (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"shrink-0 font-mono text-basalt-sm\">{source.type}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t{source.href && (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<ExternalLink\n\t\t\t\t\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"size-basalt-icon-sm shrink-0\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t</Source>\n\t\t\t\t\t\t\t\t\t\t</li>\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</ul>\n\t\t\t\t\t\t</CollapsibleContent>\n\t\t\t\t\t)}\n\t\t\t\t</Collapsible>\n\t\t\t)}\n\t\t</article>\n\t);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"chat-message.js","names":["_Fragment","ChatMessage","vm","useChatMessage","content","sources","author","variant","cn","className","trace","ChatMarkdown","streaming","children","Collapsible","Button","text","Check","Copy","onEdit","Pencil","onRegenerate","RotateCcw","onFeedback","Fragment","feedback","ThumbsUp","ThumbsDown","CollapsibleTrigger","sourcesLabel","FileText","CollapsibleContent","Source","source","ExternalLink"],"sources":["../../src/components/chat-message.tsx"],"sourcesContent":["import {\n\tCheck,\n\tCopy,\n\tExternalLink,\n\tFileText,\n\tPencil,\n\tRotateCcw,\n\tThumbsDown,\n\tThumbsUp,\n} from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { useChatMessage } from \"../viewmodels/use-chat-message\";\nimport { Button } from \"./button\";\nimport { ChatMarkdown } from \"./chat-markdown\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"./collapsible\";\n\nexport interface ChatMessageProps {\n\tvariant: \"user\" | \"assistant\";\n\tcontent: string;\n\tstreaming?: boolean;\n\t/** Thinking, tool calls and other trace content before the response. */\n\ttrace?: ReactNode;\n\t/** Approval or result content after the response; use sources for citations. */\n\tchildren?: ReactNode;\n\tauthor?: string;\n\tonEdit?: () => void;\n\tonRegenerate?: () => void;\n\tfeedback?: \"up\" | \"down\";\n\tonFeedback?: (value: \"up\" | \"down\") => void;\n\t/** Compact source disclosure beside message actions. No card wrapper is added. */\n\tsources?: readonly { id: string; name: string; type?: string; href?: string }[];\n\t/** Source disclosure label. @default \"Sources\" */\n\tsourcesLabel?: string;\n\tclassName?: string;\n}\n\nexport function ChatMessage({\n\tvariant,\n\tcontent,\n\tstreaming,\n\ttrace,\n\tchildren,\n\tauthor,\n\tonEdit,\n\tonRegenerate,\n\tfeedback,\n\tonFeedback,\n\tclassName,\n\tsources = [],\n\tsourcesLabel = \"Sources\",\n}: ChatMessageProps) {\n\tconst vm = useChatMessage(content, sources);\n\treturn (\n\t\t<article\n\t\t\taria-label={`${author || (variant === \"user\" ? \"You\" : \"Assistant\")} message`}\n\t\t\tclassName={cn(\"basalt-ui group min-w-0 space-y-basalt-content-gap\", className)}\n\t\t>\n\t\t\t<div className={cn(\"flex\", variant === \"user\" ? \"justify-end\" : \"justify-start\")}>\n\t\t\t\t<div\n\t\t\t\t\tdata-basalt-surface={variant === \"user\" ? \"\" : undefined}\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"min-w-0 space-y-basalt-content-gap\",\n\t\t\t\t\t\tvariant === \"user\"\n\t\t\t\t\t\t\t? \"max-w-[90%] rounded-basalt-lg px-basalt-panel-x py-basalt-panel-y\"\n\t\t\t\t\t\t\t: \"w-full\",\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t{trace}\n\t\t\t\t\t{content &&\n\t\t\t\t\t\t(variant === \"user\" ? (\n\t\t\t\t\t\t\t<p className=\"whitespace-pre-wrap break-words text-basalt-base leading-[var(--basalt-line-relaxed)]\">\n\t\t\t\t\t\t\t\t{content}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<ChatMarkdown content={content} streaming={streaming} />\n\t\t\t\t\t\t))}\n\t\t\t\t\t{streaming && (\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\tclassName=\"inline-block size-basalt-2 rounded-basalt-full bg-basalt-primary animate-pulse motion-reduce:animate-none\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t\t{children}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t{!streaming && content && (\n\t\t\t\t<Collapsible className=\"space-y-basalt-content-gap\">\n\t\t\t\t\t<div\n\t\t\t\t\t\tdata-slot=\"chat-actions\"\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\"flex flex-wrap items-center gap-basalt-space-xs text-basalt-muted-foreground\",\n\t\t\t\t\t\t\tvariant === \"user\"\n\t\t\t\t\t\t\t\t? \"justify-end -mr-[calc((var(--basalt-size-action)-var(--basalt-size-icon))/2)]\"\n\t\t\t\t\t\t\t\t: \"-ml-[calc((var(--basalt-size-action)-var(--basalt-size-icon))/2)]\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\taria-label={vm.copied ? \"Copied\" : \"Copy message\"}\n\t\t\t\t\t\t\tonClick={() => void vm.copy((text) => navigator.clipboard.writeText(text))}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{vm.copied ? <Check strokeWidth={1.5} /> : <Copy strokeWidth={1.5} />}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t{onEdit && (\n\t\t\t\t\t\t\t<Button size=\"icon\" variant=\"ghost\" aria-label=\"Edit message\" onClick={onEdit}>\n\t\t\t\t\t\t\t\t<Pencil strokeWidth={1.5} />\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{onRegenerate && (\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\taria-label=\"Regenerate response\"\n\t\t\t\t\t\t\t\tonClick={onRegenerate}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<RotateCcw strokeWidth={1.5} />\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{onFeedback && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\taria-label=\"Helpful\"\n\t\t\t\t\t\t\t\t\taria-pressed={feedback === \"up\"}\n\t\t\t\t\t\t\t\t\tonClick={() => onFeedback(\"up\")}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ThumbsUp strokeWidth={1.5} />\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\taria-label=\"Not helpful\"\n\t\t\t\t\t\t\t\t\taria-pressed={feedback === \"down\"}\n\t\t\t\t\t\t\t\t\tonClick={() => onFeedback(\"down\")}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ThumbsDown strokeWidth={1.5} />\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{vm.sources.length > 0 && (\n\t\t\t\t\t\t\t<CollapsibleTrigger\n\t\t\t\t\t\t\t\taria-label={`${sourcesLabel} ${vm.sources.length}`}\n\t\t\t\t\t\t\t\tclassName=\"ml-basalt-control-gap min-h-basalt-action gap-basalt-control-gap rounded-basalt-sm px-basalt-space-sm text-basalt-sm font-normal text-basalt-muted-foreground hover:bg-basalt-hover\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span className=\"flex items-center gap-basalt-control-gap\">\n\t\t\t\t\t\t\t\t\t<FileText aria-hidden=\"true\" className=\"size-basalt-icon\" strokeWidth={1.5} />\n\t\t\t\t\t\t\t\t\t<span>{sourcesLabel}</span>\n\t\t\t\t\t\t\t\t\t<span className=\"tabular-nums\">{vm.sources.length}</span>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</CollapsibleTrigger>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{vm.copyError && (\n\t\t\t\t\t\t\t<span role=\"alert\" className=\"text-basalt-sm text-basalt-danger\">\n\t\t\t\t\t\t\t\tCould not copy\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t\t{vm.sources.length > 0 && (\n\t\t\t\t\t\t<CollapsibleContent unstyled>\n\t\t\t\t\t\t\t<ul aria-label={sourcesLabel} className=\"space-y-basalt-space-xs\">\n\t\t\t\t\t\t\t\t{vm.sources.map((source) => {\n\t\t\t\t\t\t\t\t\tconst Source = source.href ? \"a\" : \"span\";\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<li key={source.id}>\n\t\t\t\t\t\t\t\t\t\t\t<Source\n\t\t\t\t\t\t\t\t\t\t\t\thref={source.href}\n\t\t\t\t\t\t\t\t\t\t\t\ttarget={source.href ? \"_blank\" : undefined}\n\t\t\t\t\t\t\t\t\t\t\t\trel={source.href ? \"noopener noreferrer\" : undefined}\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"basalt-focus basalt-focus-inset flex min-w-0 items-center gap-basalt-row-gap rounded-basalt-sm px-basalt-row-x py-basalt-control-y text-basalt-sm leading-[var(--basalt-line-body)] text-basalt-muted-foreground hover:bg-basalt-hover\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<FileText\n\t\t\t\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"size-basalt-icon shrink-0\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"min-w-0 flex-1 break-words\">{source.name}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t{source.type && (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"shrink-0 font-mono text-basalt-sm\">{source.type}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t{source.href && (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<ExternalLink\n\t\t\t\t\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"size-basalt-icon-sm shrink-0\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t</Source>\n\t\t\t\t\t\t\t\t\t\t</li>\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</ul>\n\t\t\t\t\t\t</CollapsibleContent>\n\t\t\t\t\t)}\n\t\t\t\t</Collapsible>\n\t\t\t)}\n\t\t</article>\n\t);\n}\n"],"mappings":"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"}
@@ -7,7 +7,7 @@ import * as i from "react";
7
7
  import { Check as a, Minus as o } from "lucide-react";
8
8
  import { jsx as s, jsxs as c } from "react/jsx-runtime";
9
9
  import * as l from "@radix-ui/react-checkbox";
10
- //#region src/components/checkbox.tsx
10
+ // src/components/checkbox.tsx
11
11
  var u = {
12
12
  sm: "h-basalt-check-sm w-basalt-check-sm",
13
13
  default: "h-basalt-check w-basalt-check"
@@ -100,7 +100,6 @@ var y = Object.assign(h, {
100
100
  Legend: _,
101
101
  Item: v
102
102
  });
103
- //#endregion
104
103
  export { y as Checkbox };
105
104
 
106
105
  //# sourceMappingURL=checkbox.js.map