@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.
- package/README.md +25 -19
- package/ai/COMPATIBILITY.md +41 -36
- package/ai/DESIGN.md +73 -56
- package/ai/INTEGRATION.md +819 -825
- package/ai/RECIPES.md +334 -135
- package/ai/USAGE.md +2 -2
- package/ai/registry.json +454 -97
- package/ai/sources.json +2 -2
- package/dist/assets/brand-mark.js +1 -2
- package/dist/charts/area.js +1 -2
- package/dist/charts/bar.js +1 -2
- package/dist/charts/bullet.js +1 -2
- package/dist/charts/chart-colors.js +1 -2
- package/dist/charts/charts.js +1 -2
- package/dist/charts/config.js +1 -2
- package/dist/charts/custom-chart.js +1 -2
- package/dist/charts/date-navigation.js +1 -2
- package/dist/charts/donut.js +1 -2
- package/dist/charts/frame.js +3 -4
- package/dist/charts/frame.js.map +1 -1
- package/dist/charts/funnel.js +1 -2
- package/dist/charts/gauge.js +1 -2
- package/dist/charts/grouped-bar.js +1 -2
- package/dist/charts/heatmap-calendar.js +7 -11
- package/dist/charts/heatmap-calendar.js.map +1 -1
- package/dist/charts/heatmap-matrix.js +4 -5
- package/dist/charts/heatmap-matrix.js.map +1 -1
- package/dist/charts/item-list.js +1 -2
- package/dist/charts/legend.js +1 -2
- package/dist/charts/line.js +1 -2
- package/dist/charts/palette.js +1 -2
- package/dist/charts/radar.js +1 -2
- package/dist/charts/sample.js +1 -2
- package/dist/charts/sankey.js +1 -2
- package/dist/charts/series.js +1 -2
- package/dist/charts/slot-bar.js +1 -2
- package/dist/charts/sparkline.js +1 -2
- package/dist/charts/stacked-bar.js +1 -2
- package/dist/charts/stat-card.js +1 -2
- package/dist/charts/timeline.js +1 -2
- package/dist/charts/timeseries.js +1 -2
- package/dist/charts/tooltip.js +31 -27
- package/dist/charts/tooltip.js.map +1 -1
- package/dist/components/accordion.js +1 -2
- package/dist/components/alert-dialog.js +1 -2
- package/dist/components/app-header.js +2 -3
- package/dist/components/app-header.js.map +1 -1
- package/dist/components/app-shell.js +2 -3
- package/dist/components/app-shell.js.map +1 -1
- package/dist/components/approval-card.js +1 -2
- package/dist/components/autocomplete.js +1 -2
- package/dist/components/avatar.js +1 -2
- package/dist/components/badge.js +1 -2
- package/dist/components/banner.js +1 -2
- package/dist/components/basalt-mark.js +1 -2
- package/dist/components/battery-meter.js +1 -2
- package/dist/components/breadcrumbs.js +1 -2
- package/dist/components/button.d.ts +1 -1
- package/dist/components/button.js +3 -3
- package/dist/components/button.js.map +1 -1
- package/dist/components/chat-bubble.js +1 -2
- package/dist/components/chat-composer.js +2 -3
- package/dist/components/chat-composer.js.map +1 -1
- package/dist/components/chat-header.js +1 -2
- package/dist/components/chat-inbox.js +1 -2
- package/dist/components/chat-markdown.js +1 -2
- package/dist/components/chat-message.js +2 -3
- package/dist/components/chat-message.js.map +1 -1
- package/dist/components/checkbox.js +1 -2
- package/dist/components/clipboard-text.js +1 -2
- package/dist/components/code.js +2 -3
- package/dist/components/code.js.map +1 -1
- package/dist/components/collapsible.js +1 -2
- package/dist/components/collapsible.js.map +1 -1
- package/dist/components/combobox.js +1 -2
- package/dist/components/command-palette.js +3 -4
- package/dist/components/command-palette.js.map +1 -1
- package/dist/components/confirm-dialog.js +3 -12
- package/dist/components/confirm-dialog.js.map +1 -1
- package/dist/components/context-cards.js +2 -3
- package/dist/components/context-cards.js.map +1 -1
- package/dist/components/context-menu.js +2 -3
- package/dist/components/context-menu.js.map +1 -1
- package/dist/components/data-table.js +129 -131
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/date-picker.js +7 -18
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/delete-resource.js +1 -2
- package/dist/components/description-list.js +1 -2
- package/dist/components/dialog.js +1 -2
- package/dist/components/diff-table.js +2 -3
- package/dist/components/diff-table.js.map +1 -1
- package/dist/components/dock.js +1 -2
- package/dist/components/dock.js.map +1 -1
- package/dist/components/dropdown-menu.js +2 -3
- package/dist/components/dropdown-menu.js.map +1 -1
- package/dist/components/editable-nav-item.js +3 -4
- package/dist/components/editable-nav-item.js.map +1 -1
- package/dist/components/empty.js +1 -2
- package/dist/components/fab.js +1 -2
- package/dist/components/field.js +1 -2
- package/dist/components/file-dropzone.js +2 -3
- package/dist/components/file-dropzone.js.map +1 -1
- package/dist/components/filter-bar.js +2 -3
- package/dist/components/filter-bar.js.map +1 -1
- package/dist/components/flow.js +1 -2
- package/dist/components/grid.js +1 -2
- package/dist/components/hover-card.js +1 -2
- package/dist/components/icon-picker.js +4 -5
- package/dist/components/icon-picker.js.map +1 -1
- package/dist/components/inline-editable.js +2 -3
- package/dist/components/inline-editable.js.map +1 -1
- package/dist/components/input-area.js +1 -2
- package/dist/components/input-group.js +4 -5
- package/dist/components/input-group.js.map +1 -1
- package/dist/components/input.js +1 -2
- package/dist/components/label.js +1 -2
- package/dist/components/layer-card.js +3 -3
- package/dist/components/layer-card.js.map +1 -1
- package/dist/components/link.js +2 -3
- package/dist/components/link.js.map +1 -1
- package/dist/components/loader.js +1 -2
- package/dist/components/loading-screen.js +1 -2
- package/dist/components/menu-bar.js +3 -4
- package/dist/components/menu-bar.js.map +1 -1
- package/dist/components/meter.js +1 -2
- package/dist/components/multi-select.js +2 -3
- package/dist/components/multi-select.js.map +1 -1
- package/dist/components/navigation-menu.js +1 -2
- package/dist/components/overlay.d.ts +3 -6
- package/dist/components/overlay.js +4 -5
- package/dist/components/overlay.js.map +1 -1
- package/dist/components/page-header.js +1 -2
- package/dist/components/pagination.js +1 -2
- package/dist/components/popover.js +1 -2
- package/dist/components/prompt-bar.js +1 -2
- package/dist/components/radio.js +2 -7
- package/dist/components/radio.js.map +1 -1
- package/dist/components/recommendation-card.js +1 -2
- package/dist/components/resource-list.js +1 -2
- package/dist/components/responsive-master-detail.js +3 -4
- package/dist/components/responsive-master-detail.js.map +1 -1
- package/dist/components/scroll-area.js +2 -3
- package/dist/components/scroll-area.js.map +1 -1
- package/dist/components/section-rule.js +1 -2
- package/dist/components/segment-control.js +2 -3
- package/dist/components/segment-control.js.map +1 -1
- package/dist/components/select.js +2 -3
- package/dist/components/select.js.map +1 -1
- package/dist/components/sensitive-input.js +2 -3
- package/dist/components/sensitive-input.js.map +1 -1
- package/dist/components/separator.js +1 -2
- package/dist/components/sheet.js +1 -2
- package/dist/components/sidebar.d.ts +53 -19
- package/dist/components/sidebar.js +201 -100
- package/dist/components/sidebar.js.map +1 -1
- package/dist/components/skeleton-line.js +1 -2
- package/dist/components/slider.js +1 -2
- package/dist/components/stat-strip.js +1 -2
- package/dist/components/switch.js +1 -2
- package/dist/components/table-of-contents.js +1 -2
- package/dist/components/table-pager.js +1 -2
- package/dist/components/table.js +2 -3
- package/dist/components/table.js.map +1 -1
- package/dist/components/tabs.js +2 -3
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/tag-badge.js +1 -2
- package/dist/components/tag-color-picker.js +3 -4
- package/dist/components/tag-color-picker.js.map +1 -1
- package/dist/components/text.js +1 -2
- package/dist/components/theme-toggle.js +1 -2
- package/dist/components/thinking.js +1 -2
- package/dist/components/toast.js +2 -3
- package/dist/components/toast.js.map +1 -1
- package/dist/components/toggle-group.js +1 -2
- package/dist/components/toggle.js +1 -2
- package/dist/components/tool-chips.js +1 -2
- package/dist/components/toolbar.js +9 -10
- package/dist/components/toolbar.js.map +1 -1
- package/dist/components/tooltip.js +1 -2
- package/dist/components/typeahead-field.js +6 -21
- package/dist/components/typeahead-field.js.map +1 -1
- package/dist/components/upload-queue.js +1 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +11 -11
- package/dist/models/agent-feedback.js +1 -2
- package/dist/models/avatar.js +1 -2
- package/dist/models/code.js +1 -2
- package/dist/models/context-cards.js +1 -2
- package/dist/models/diff-table.js +1 -2
- package/dist/models/recommendation.js +1 -2
- package/dist/providers/accent.js +2 -7
- package/dist/providers/accent.js.map +1 -1
- package/dist/providers/link.js +1 -2
- package/dist/providers/theme.js +2 -7
- package/dist/providers/theme.js.map +1 -1
- package/dist/styles/base.css +71 -0
- package/dist/styles/standalone.css +127 -98
- package/dist/styles/tailwind.css +10 -2
- package/dist/styles/tokens.css +55 -7
- package/dist/utils/cn.js +1 -2
- package/dist/utils/control-surface.js +1 -2
- package/dist/utils/navigation.d.ts +2 -2
- package/dist/utils/navigation.js +2 -3
- package/dist/utils/navigation.js.map +1 -1
- package/dist/utils/preference-store.js +1 -2
- package/dist/utils/selection-indicator.js +1 -2
- package/dist/utils/use-checkable-group.js +1 -2
- package/dist/utils/use-hover-highlight.js +2 -3
- package/dist/utils/use-hover-highlight.js.map +1 -1
- package/dist/viewmodels/use-approval-card.js +11 -13
- package/dist/viewmodels/use-approval-card.js.map +1 -1
- package/dist/viewmodels/use-chat-composer.js +1 -2
- package/dist/viewmodels/use-chat-message.js +1 -2
- package/dist/viewmodels/use-code-block.js +1 -2
- package/dist/viewmodels/use-code-block.js.map +1 -1
- package/dist/viewmodels/use-context-cards.js +1 -2
- package/dist/viewmodels/use-diff-table.js +1 -2
- package/dist/viewmodels/use-diff-table.js.map +1 -1
- package/dist/viewmodels/use-loader.js +1 -2
- package/dist/viewmodels/use-recommendation-card.js +1 -2
- package/dist/viewmodels/use-recommendation-card.js.map +1 -1
- package/dist/viewmodels/use-thinking.js +1 -2
- package/dist/viewmodels/use-tool-chips.js +1 -2
- 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
|
-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
package/dist/components/badge.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|