@nocoo/basalt 2.0.3 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +134 -15
- package/ai/COMPATIBILITY.md +180 -0
- package/ai/INTEGRATION.md +1760 -0
- package/ai/RECIPES.md +161 -0
- package/ai/USAGE.md +99 -0
- package/ai/registry.json +38099 -0
- package/ai/sources.json +10 -0
- package/dist/assets/brand-mark.d.ts +1 -0
- package/dist/assets/brand-mark.js +7 -0
- package/dist/assets/brand-mark.js.map +1 -0
- package/dist/charts/area.d.ts +58 -5
- package/dist/charts/area.js +20 -12
- package/dist/charts/area.js.map +1 -1
- package/dist/charts/bar.d.ts +54 -5
- package/dist/charts/bar.js +16 -10
- package/dist/charts/bar.js.map +1 -1
- package/dist/charts/bullet.d.ts +18 -1
- package/dist/charts/bullet.js +6 -3
- package/dist/charts/bullet.js.map +1 -1
- package/dist/charts/charts.d.ts +58 -5
- package/dist/charts/charts.js +13 -2
- package/dist/charts/charts.js.map +1 -1
- package/dist/charts/config.d.ts +7 -0
- package/dist/charts/config.js +5 -1
- package/dist/charts/config.js.map +1 -1
- package/dist/charts/custom-chart.d.ts +58 -5
- package/dist/charts/custom-chart.js +13 -2
- package/dist/charts/custom-chart.js.map +1 -1
- package/dist/charts/donut.d.ts +18 -1
- package/dist/charts/donut.js +6 -3
- package/dist/charts/donut.js.map +1 -1
- package/dist/charts/frame.d.ts +40 -3
- package/dist/charts/frame.js +55 -28
- package/dist/charts/frame.js.map +1 -1
- package/dist/charts/funnel.d.ts +18 -1
- package/dist/charts/funnel.js +5 -1
- package/dist/charts/funnel.js.map +1 -1
- package/dist/charts/gauge.d.ts +18 -1
- package/dist/charts/gauge.js +38 -20
- package/dist/charts/gauge.js.map +1 -1
- package/dist/charts/grouped-bar.d.ts +54 -5
- package/dist/charts/grouped-bar.js +16 -10
- package/dist/charts/grouped-bar.js.map +1 -1
- package/dist/charts/heatmap-calendar.d.ts +61 -0
- package/dist/charts/heatmap-calendar.js +287 -96
- package/dist/charts/heatmap-calendar.js.map +1 -1
- package/dist/charts/heatmap-matrix.d.ts +99 -0
- package/dist/charts/heatmap-matrix.js +249 -0
- package/dist/charts/heatmap-matrix.js.map +1 -0
- package/dist/charts/line.d.ts +66 -5
- package/dist/charts/line.js +37 -30
- package/dist/charts/line.js.map +1 -1
- package/dist/charts/palette.d.ts +1 -0
- package/dist/charts/palette.js +7 -1
- package/dist/charts/palette.js.map +1 -1
- package/dist/charts/radar.d.ts +18 -1
- package/dist/charts/radar.js +26 -19
- package/dist/charts/radar.js.map +1 -1
- package/dist/charts/sankey.d.ts +18 -1
- package/dist/charts/sankey.js +4 -1
- package/dist/charts/sankey.js.map +1 -1
- package/dist/charts/series.d.ts +5 -7
- package/dist/charts/series.js.map +1 -1
- package/dist/charts/slot-bar.d.ts +38 -6
- package/dist/charts/slot-bar.js +5 -2
- package/dist/charts/slot-bar.js.map +1 -1
- package/dist/charts/sparkline.d.ts +35 -5
- package/dist/charts/sparkline.js +22 -18
- package/dist/charts/sparkline.js.map +1 -1
- package/dist/charts/stacked-bar.d.ts +58 -5
- package/dist/charts/stacked-bar.js +19 -12
- package/dist/charts/stacked-bar.js.map +1 -1
- package/dist/charts/stat-card.d.ts +51 -1
- package/dist/charts/stat-card.js +66 -39
- package/dist/charts/stat-card.js.map +1 -1
- package/dist/charts/timeline.d.ts +3 -0
- package/dist/charts/timeline.js +4 -3
- package/dist/charts/timeline.js.map +1 -1
- package/dist/charts/timeseries.d.ts +58 -5
- package/dist/charts/timeseries.js +13 -2
- package/dist/charts/timeseries.js.map +1 -1
- package/dist/charts/tooltip.d.ts +57 -0
- package/dist/charts/tooltip.js +119 -2
- package/dist/charts/tooltip.js.map +1 -1
- package/dist/components/accordion.d.ts +117 -2
- package/dist/components/accordion.js +20 -13
- package/dist/components/accordion.js.map +1 -1
- package/dist/components/alert-dialog.d.ts +131 -13
- package/dist/components/alert-dialog.js +12 -9
- package/dist/components/alert-dialog.js.map +1 -1
- package/dist/components/app-header.js +18 -17
- package/dist/components/app-header.js.map +1 -1
- package/dist/components/app-shell.js +15 -14
- package/dist/components/app-shell.js.map +1 -1
- package/dist/components/autocomplete.d.ts +4 -0
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/avatar.d.ts +76 -3
- package/dist/components/avatar.js.map +1 -1
- package/dist/components/badge.d.ts +15 -1
- package/dist/components/badge.js +17 -16
- package/dist/components/badge.js.map +1 -1
- package/dist/components/banner.d.ts +88 -2
- package/dist/components/banner.js +41 -40
- package/dist/components/banner.js.map +1 -1
- package/dist/components/basalt-mark.js +14 -8
- package/dist/components/basalt-mark.js.map +1 -1
- package/dist/components/battery-meter.d.ts +10 -0
- package/dist/components/battery-meter.js +56 -0
- package/dist/components/battery-meter.js.map +1 -0
- package/dist/components/breadcrumbs.d.ts +27 -7
- package/dist/components/breadcrumbs.js +21 -20
- package/dist/components/breadcrumbs.js.map +1 -1
- package/dist/components/button.d.ts +48 -2
- package/dist/components/button.js +87 -36
- package/dist/components/button.js.map +1 -1
- package/dist/components/chat-bubble.d.ts +7 -0
- package/dist/components/chat-bubble.js +14 -13
- package/dist/components/chat-bubble.js.map +1 -1
- package/dist/components/chat-composer.d.ts +7 -3
- package/dist/components/chat-composer.js.map +1 -1
- package/dist/components/chat-header.d.ts +6 -1
- package/dist/components/chat-header.js +17 -16
- package/dist/components/chat-header.js.map +1 -1
- package/dist/components/chat-inbox.d.ts +7 -2
- package/dist/components/chat-inbox.js.map +1 -1
- package/dist/components/checkbox.js +84 -53
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/clipboard-text.d.ts +13 -2
- package/dist/components/clipboard-text.js +4 -4
- package/dist/components/clipboard-text.js.map +1 -1
- package/dist/components/collapsible.d.ts +58 -15
- package/dist/components/collapsible.js.map +1 -1
- package/dist/components/command-palette.d.ts +151 -61
- package/dist/components/command-palette.js.map +1 -1
- package/dist/components/confirm-dialog.d.ts +1 -1
- package/dist/components/confirm-dialog.js +6 -4
- package/dist/components/confirm-dialog.js.map +1 -1
- package/dist/components/context-menu.d.ts +210 -2
- package/dist/components/context-menu.js +7 -4
- package/dist/components/context-menu.js.map +1 -1
- package/dist/components/data-table.d.ts +40 -2
- package/dist/components/data-table.js +168 -120
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/date-picker.d.ts +53 -2
- package/dist/components/date-picker.js +387 -219
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/delete-resource.d.ts +7 -1
- package/dist/components/delete-resource.js +22 -18
- package/dist/components/delete-resource.js.map +1 -1
- package/dist/components/description-list.js +16 -15
- package/dist/components/description-list.js.map +1 -1
- package/dist/components/dialog.d.ts +141 -12
- package/dist/components/dialog.js +42 -38
- package/dist/components/dialog.js.map +1 -1
- package/dist/components/dock.d.ts +1 -1
- package/dist/components/dock.js +39 -58
- package/dist/components/dock.js.map +1 -1
- package/dist/components/dropdown-menu.d.ts +229 -15
- package/dist/components/dropdown-menu.js +9 -6
- package/dist/components/dropdown-menu.js.map +1 -1
- package/dist/components/editable-nav-item.d.ts +33 -0
- package/dist/components/editable-nav-item.js +90 -0
- package/dist/components/editable-nav-item.js.map +1 -0
- package/dist/components/empty.d.ts +22 -2
- package/dist/components/empty.js +22 -13
- package/dist/components/empty.js.map +1 -1
- package/dist/components/field.js +31 -30
- package/dist/components/field.js.map +1 -1
- package/dist/components/file-dropzone.d.ts +37 -0
- package/dist/components/file-dropzone.js +103 -0
- package/dist/components/file-dropzone.js.map +1 -0
- package/dist/components/filter-bar.d.ts +34 -0
- package/dist/components/filter-bar.js +52 -0
- package/dist/components/filter-bar.js.map +1 -0
- package/dist/components/flow.js +19 -18
- package/dist/components/flow.js.map +1 -1
- package/dist/components/grid.d.ts +3 -1
- package/dist/components/grid.js.map +1 -1
- package/dist/components/hover-card.d.ts +111 -1
- package/dist/components/hover-card.js +9 -6
- package/dist/components/hover-card.js.map +1 -1
- package/dist/components/icon-picker.d.ts +34 -0
- package/dist/components/icon-picker.js +77 -0
- package/dist/components/icon-picker.js.map +1 -0
- package/dist/components/inline-editable.d.ts +46 -0
- package/dist/components/inline-editable.js +124 -0
- package/dist/components/inline-editable.js.map +1 -0
- package/dist/components/input-area.js +3 -3
- package/dist/components/input-group.js +7 -7
- package/dist/components/input.js +3 -3
- package/dist/components/label.js +18 -17
- package/dist/components/label.js.map +1 -1
- package/dist/components/layer-card.d.ts +10 -2
- package/dist/components/layer-card.js +71 -68
- package/dist/components/layer-card.js.map +1 -1
- package/dist/components/loader.d.ts +10 -2
- package/dist/components/loader.js.map +1 -1
- package/dist/components/menu-bar.d.ts +174 -6
- package/dist/components/menu-bar.js +33 -29
- package/dist/components/menu-bar.js.map +1 -1
- package/dist/components/meter.d.ts +27 -2
- package/dist/components/meter.js.map +1 -1
- package/dist/components/multi-select.d.ts +64 -0
- package/dist/components/multi-select.js +218 -0
- package/dist/components/multi-select.js.map +1 -0
- package/dist/components/navigation-menu.d.ts +88 -5
- package/dist/components/navigation-menu.js.map +1 -1
- package/dist/components/overlay.js +6 -5
- package/dist/components/overlay.js.map +1 -1
- package/dist/components/page-header.js +23 -21
- package/dist/components/page-header.js.map +1 -1
- package/dist/components/pagination.js +7 -7
- package/dist/components/popover.d.ts +136 -16
- package/dist/components/popover.js +32 -28
- package/dist/components/popover.js.map +1 -1
- package/dist/components/radio.js +38 -37
- package/dist/components/radio.js.map +1 -1
- package/dist/components/resource-list.d.ts +26 -1
- package/dist/components/resource-list.js +28 -15
- package/dist/components/resource-list.js.map +1 -1
- package/dist/components/responsive-master-detail.d.ts +27 -0
- package/dist/components/responsive-master-detail.js +85 -0
- package/dist/components/responsive-master-detail.js.map +1 -0
- package/dist/components/section-rule.js +23 -22
- package/dist/components/section-rule.js.map +1 -1
- package/dist/components/select.d.ts +27 -3
- package/dist/components/select.js +11 -11
- package/dist/components/select.js.map +1 -1
- package/dist/components/sheet.d.ts +115 -11
- package/dist/components/sheet.js +37 -30
- package/dist/components/sheet.js.map +1 -1
- package/dist/components/sidebar.d.ts +109 -17
- package/dist/components/sidebar.js +109 -108
- package/dist/components/sidebar.js.map +1 -1
- package/dist/components/skeleton-line.d.ts +22 -2
- package/dist/components/skeleton-line.js.map +1 -1
- package/dist/components/slider.d.ts +61 -1
- package/dist/components/slider.js +31 -15
- package/dist/components/slider.js.map +1 -1
- package/dist/components/stat-strip.js +16 -15
- package/dist/components/stat-strip.js.map +1 -1
- package/dist/components/switch.js +78 -47
- package/dist/components/switch.js.map +1 -1
- package/dist/components/table-of-contents.js +18 -17
- package/dist/components/table-of-contents.js.map +1 -1
- package/dist/components/table-pager.js +20 -19
- package/dist/components/table-pager.js.map +1 -1
- package/dist/components/table.d.ts +9 -3
- package/dist/components/table.js +19 -18
- package/dist/components/table.js.map +1 -1
- package/dist/components/tabs.js +29 -22
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/tag-badge.d.ts +58 -0
- package/dist/components/tag-badge.js +72 -0
- package/dist/components/tag-badge.js.map +1 -0
- package/dist/components/tag-color-picker.d.ts +20 -0
- package/dist/components/tag-color-picker.js +42 -0
- package/dist/components/tag-color-picker.js.map +1 -0
- package/dist/components/text.js +17 -16
- package/dist/components/text.js.map +1 -1
- package/dist/components/toast.d.ts +173 -3
- package/dist/components/toast.js +1 -1
- package/dist/components/toast.js.map +1 -1
- package/dist/components/toggle-group.d.ts +88 -2
- package/dist/components/toggle-group.js +32 -31
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/toggle.d.ts +35 -2
- package/dist/components/toggle.js +12 -11
- package/dist/components/toggle.js.map +1 -1
- package/dist/components/tooltip.d.ts +144 -6
- package/dist/components/tooltip.js +9 -6
- package/dist/components/tooltip.js.map +1 -1
- package/dist/components/typeahead-field.js +193 -132
- package/dist/components/typeahead-field.js.map +1 -1
- package/dist/components/upload-queue.d.ts +51 -0
- package/dist/components/upload-queue.js +116 -0
- package/dist/components/upload-queue.js.map +1 -0
- package/dist/providers/accent.d.ts +46 -2
- package/dist/providers/accent.js +358 -172
- package/dist/providers/accent.js.map +1 -1
- package/dist/providers/link.d.ts +14 -4
- package/dist/providers/link.js.map +1 -1
- package/dist/providers/theme.d.ts +38 -2
- package/dist/providers/theme.js +160 -27
- package/dist/providers/theme.js.map +1 -1
- package/dist/styles/base.css +83 -0
- package/dist/styles/standalone.css +711 -120
- package/dist/styles/tailwind.css +21 -7
- package/dist/styles/tokens.css +145 -91
- package/dist/utils/control-surface.d.ts +2 -1
- package/dist/utils/control-surface.js +4 -4
- package/dist/utils/control-surface.js.map +1 -1
- package/dist/utils/selection-indicator.js +2 -2
- package/dist/utils/selection-indicator.js.map +1 -1
- package/package.json +8 -4
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../utils/cn.js";
|
|
3
|
+
import { BASALT_UI_CLASS as t } from "../utils/control-surface.js";
|
|
4
|
+
import { Button as n } from "./button.js";
|
|
5
|
+
import { X as r } from "lucide-react";
|
|
6
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
7
|
+
//#region src/components/filter-bar.tsx
|
|
8
|
+
function o({ label: r, children: o, chips: s, active: c = !1, onClear: l, clearLabel: u = "Clear filters", className: d }) {
|
|
9
|
+
return /* @__PURE__ */ a("div", {
|
|
10
|
+
role: "group",
|
|
11
|
+
"aria-label": r,
|
|
12
|
+
className: e(t, "min-w-0 space-y-3", d),
|
|
13
|
+
children: [/* @__PURE__ */ a("div", {
|
|
14
|
+
className: "flex flex-wrap items-end gap-3 [&>*]:min-w-0",
|
|
15
|
+
children: [o, c && l && /* @__PURE__ */ i(n, {
|
|
16
|
+
size: "sm",
|
|
17
|
+
variant: "ghost",
|
|
18
|
+
onClick: l,
|
|
19
|
+
children: u
|
|
20
|
+
})]
|
|
21
|
+
}), s != null && /* @__PURE__ */ i("div", {
|
|
22
|
+
className: "flex flex-wrap items-center gap-2",
|
|
23
|
+
children: s
|
|
24
|
+
})]
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function s({ label: n, value: o, onRemove: s, removeLabel: c, disabled: l = !1, className: u }) {
|
|
28
|
+
return /* @__PURE__ */ a("span", {
|
|
29
|
+
className: e(t, "inline-flex max-w-full items-center gap-1 rounded-full border border-basalt-border bg-basalt-accent py-1 pl-3 pr-1 text-xs", u),
|
|
30
|
+
children: [/* @__PURE__ */ a("span", {
|
|
31
|
+
className: "min-w-0 break-words",
|
|
32
|
+
children: [/* @__PURE__ */ a("span", {
|
|
33
|
+
className: "text-basalt-muted-foreground",
|
|
34
|
+
children: [n, ": "]
|
|
35
|
+
}), o]
|
|
36
|
+
}), /* @__PURE__ */ i("button", {
|
|
37
|
+
type: "button",
|
|
38
|
+
disabled: l,
|
|
39
|
+
"aria-label": c ?? `Remove ${n}`,
|
|
40
|
+
onClick: s,
|
|
41
|
+
className: "shrink-0 rounded-full p-1 focus-visible:outline-2 focus-visible:outline-basalt-ring disabled:opacity-50",
|
|
42
|
+
children: /* @__PURE__ */ i(r, {
|
|
43
|
+
className: "size-3",
|
|
44
|
+
"aria-hidden": "true"
|
|
45
|
+
})
|
|
46
|
+
})]
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { o as FilterBar, s as FilterChip };
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=filter-bar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter-bar.js","names":[],"sources":["../../src/components/filter-bar.tsx"],"sourcesContent":["import { X } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Button } from \"./button\";\n\nexport interface FilterBarProps {\n\t/** Accessible group name. */\n\tlabel: string;\n\t/** Application-owned search, select, and date controls. */\n\tchildren: ReactNode;\n\t/** Active chips, shown on their own wrapping row. */\n\tchips?: ReactNode;\n\t/** Whether the clear action is available. @default false */\n\tactive?: boolean;\n\t/** Requests clearing application-owned filters. */\n\tonClear?: () => void;\n\t/** Clear action text. @default \"Clear filters\" */\n\tclearLabel?: string;\n\t/** Additional root classes. */\n\tclassName?: string;\n}\n\n/** Layout only; URL serialization, query execution, and date presets belong to the caller. */\nexport function FilterBar({\n\tlabel,\n\tchildren,\n\tchips,\n\tactive = false,\n\tonClear,\n\tclearLabel = \"Clear filters\",\n\tclassName,\n}: FilterBarProps) {\n\treturn (\n\t\t<div\n\t\t\trole=\"group\"\n\t\t\taria-label={label}\n\t\t\tclassName={cn(BASALT_UI_CLASS, \"min-w-0 space-y-3\", className)}\n\t\t>\n\t\t\t<div className=\"flex flex-wrap items-end gap-3 [&>*]:min-w-0\">\n\t\t\t\t{children}\n\t\t\t\t{active && onClear && (\n\t\t\t\t\t<Button size=\"sm\" variant=\"ghost\" onClick={onClear}>\n\t\t\t\t\t\t{clearLabel}\n\t\t\t\t\t</Button>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t{chips != null && <div className=\"flex flex-wrap items-center gap-2\">{chips}</div>}\n\t\t</div>\n\t);\n}\n\nexport interface FilterChipProps {\n\t/** Filter dimension, e.g. Status. */\n\tlabel: string;\n\t/** Display value. */\n\tvalue: ReactNode;\n\t/** Requests removal from the application's filter state. */\n\tonRemove: () => void;\n\t/** Full accessible removal label; defaults to Remove plus the dimension label. */\n\tremoveLabel?: string;\n\t/** Disable removal. @default false */\n\tdisabled?: boolean;\n\t/** Additional root classes. */\n\tclassName?: string;\n}\n\nexport function FilterChip({\n\tlabel,\n\tvalue,\n\tonRemove,\n\tremoveLabel,\n\tdisabled = false,\n\tclassName,\n}: FilterChipProps) {\n\treturn (\n\t\t<span\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"inline-flex max-w-full items-center gap-1 rounded-full border border-basalt-border bg-basalt-accent py-1 pl-3 pr-1 text-xs\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t<span className=\"min-w-0 break-words\">\n\t\t\t\t<span className=\"text-basalt-muted-foreground\">{label}: </span>\n\t\t\t\t{value}\n\t\t\t</span>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tdisabled={disabled}\n\t\t\t\taria-label={removeLabel ?? `Remove ${label}`}\n\t\t\t\tonClick={onRemove}\n\t\t\t\tclassName=\"shrink-0 rounded-full p-1 focus-visible:outline-2 focus-visible:outline-basalt-ring disabled:opacity-50\"\n\t\t\t>\n\t\t\t\t<X className=\"size-3\" aria-hidden=\"true\" />\n\t\t\t</button>\n\t\t</span>\n\t);\n}\n"],"mappings":";;;;;;;AAwBA,SAAgB,EAAU,EACzB,UACA,aACA,UACA,YAAS,IACT,YACA,gBAAa,iBACb,gBACkB;CAClB,OACC,kBAAC,OAAD;EACC,MAAK;EACL,cAAY;EACZ,WAAW,EAAG,GAAiB,qBAAqB,CAAS;EAH9D,UAAA,CAKC,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,GACA,KAAU,KACV,kBAAC,GAAD;IAAQ,MAAK;IAAK,SAAQ;IAAQ,SAAS;IACzC,UAAA;GACM,CAAA,CAEL;EACJ,CAAA,GAAA,KAAS,QAAQ,kBAAC,OAAD;GAAK,WAAU;GAAqC,UAAA;EAAW,CAAA,CAC7E;;AAEP;AAiBA,SAAgB,EAAW,EAC1B,UACA,UACA,aACA,gBACA,cAAW,IACX,gBACmB;CACnB,OACC,kBAAC,QAAD;EACC,WAAW,EACV,GACA,8HACA,CACD;EALD,UAAA,CAOC,kBAAC,QAAD;GAAM,WAAU;GAAhB,UAAA,CACC,kBAAC,QAAD;IAAM,WAAU;IAAhB,UAAA,CAAgD,GAAM,IAAQ;GAC7D,CAAA,GAAA,CACI;EACN,CAAA,GAAA,kBAAC,UAAD;GACC,MAAK;GACK;GACV,cAAY,KAAe,UAAU;GACrC,SAAS;GACT,WAAU;GAEV,UAAA,kBAAC,GAAD;IAAG,WAAU;IAAS,eAAY;GAAQ,CAAA;EACnC,CAAA,CACH;;AAER"}
|
package/dist/components/flow.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn as e } from "../utils/cn.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { BASALT_UI_CLASS as t } from "../utils/control-surface.js";
|
|
4
|
+
import { Children as n, Fragment as r, useId as i } from "react";
|
|
5
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
5
6
|
//#region src/components/flow.tsx
|
|
6
|
-
function
|
|
7
|
-
let e = `flow-arrow-${
|
|
8
|
-
return /* @__PURE__ */
|
|
7
|
+
function s() {
|
|
8
|
+
let e = `flow-arrow-${i().replace(/:/g, "")}`;
|
|
9
|
+
return /* @__PURE__ */ a("li", {
|
|
9
10
|
"aria-hidden": "true",
|
|
10
11
|
className: "flex w-10 shrink-0 items-center text-basalt-muted-foreground",
|
|
11
|
-
children: /* @__PURE__ */
|
|
12
|
+
children: /* @__PURE__ */ o("svg", {
|
|
12
13
|
viewBox: "0 0 40 16",
|
|
13
14
|
className: "h-4 w-10 overflow-visible",
|
|
14
15
|
overflow: "visible",
|
|
15
16
|
"aria-hidden": "true",
|
|
16
|
-
children: [/* @__PURE__ */
|
|
17
|
+
children: [/* @__PURE__ */ a("defs", { children: /* @__PURE__ */ a("marker", {
|
|
17
18
|
id: e,
|
|
18
19
|
markerWidth: "8",
|
|
19
20
|
markerHeight: "8",
|
|
@@ -21,12 +22,12 @@ function o() {
|
|
|
21
22
|
refY: "4",
|
|
22
23
|
orient: "auto",
|
|
23
24
|
markerUnits: "userSpaceOnUse",
|
|
24
|
-
children: /* @__PURE__ */
|
|
25
|
+
children: /* @__PURE__ */ a("path", {
|
|
25
26
|
d: "M 0,1.5 Q 0,0 1.5,0 Q 3.5,1 5.8,3.2 Q 6.5,4 5.8,4.8 Q 3.5,7 1.5,8 Q 0,8 0,6.5 Z",
|
|
26
27
|
fill: "currentColor",
|
|
27
28
|
stroke: "none"
|
|
28
29
|
})
|
|
29
|
-
}) }), /* @__PURE__ */
|
|
30
|
+
}) }), /* @__PURE__ */ a("path", {
|
|
30
31
|
d: "M 0 8 L 32 8",
|
|
31
32
|
fill: "none",
|
|
32
33
|
stroke: "currentColor",
|
|
@@ -36,21 +37,21 @@ function o() {
|
|
|
36
37
|
})
|
|
37
38
|
});
|
|
38
39
|
}
|
|
39
|
-
function
|
|
40
|
-
let
|
|
41
|
-
return /* @__PURE__ */
|
|
42
|
-
"aria-label":
|
|
43
|
-
className: e("flex items-center",
|
|
44
|
-
children:
|
|
40
|
+
function c({ className: i, children: c, "aria-label": l = "Flow" }) {
|
|
41
|
+
let u = n.toArray(c);
|
|
42
|
+
return /* @__PURE__ */ a("ol", {
|
|
43
|
+
"aria-label": l,
|
|
44
|
+
className: e(t, "flex items-center", i),
|
|
45
|
+
children: u.map((e, t) => /* @__PURE__ */ o(r, { children: [e, t < u.length - 1 ? /* @__PURE__ */ a(s, {}) : null] }, t))
|
|
45
46
|
});
|
|
46
47
|
}
|
|
47
|
-
function
|
|
48
|
-
return /* @__PURE__ */
|
|
48
|
+
function l({ children: e }) {
|
|
49
|
+
return /* @__PURE__ */ a("li", {
|
|
49
50
|
className: "rounded-basalt-md border border-basalt-border bg-basalt-secondary px-3 py-2 text-sm",
|
|
50
51
|
children: e
|
|
51
52
|
});
|
|
52
53
|
}
|
|
53
54
|
//#endregion
|
|
54
|
-
export {
|
|
55
|
+
export { c as Flow, l as FlowNode };
|
|
55
56
|
|
|
56
57
|
//# sourceMappingURL=flow.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow.js","names":[],"sources":["../../src/components/flow.tsx"],"sourcesContent":["import { Children, Fragment, type ReactNode, useId } from \"react\";\nimport { cn } from \"../utils/cn\";\n\nfunction FlowArrow() {\n\tconst id = `flow-arrow-${useId().replace(/:/g, \"\")}`;\n\treturn (\n\t\t<li aria-hidden=\"true\" className=\"flex w-10 shrink-0 items-center text-basalt-muted-foreground\">\n\t\t\t<svg\n\t\t\t\tviewBox=\"0 0 40 16\"\n\t\t\t\tclassName=\"h-4 w-10 overflow-visible\"\n\t\t\t\toverflow=\"visible\"\n\t\t\t\taria-hidden=\"true\"\n\t\t\t>\n\t\t\t\t<defs>\n\t\t\t\t\t<marker\n\t\t\t\t\t\tid={id}\n\t\t\t\t\t\tmarkerWidth=\"8\"\n\t\t\t\t\t\tmarkerHeight=\"8\"\n\t\t\t\t\t\trefX=\"0\"\n\t\t\t\t\t\trefY=\"4\"\n\t\t\t\t\t\torient=\"auto\"\n\t\t\t\t\t\tmarkerUnits=\"userSpaceOnUse\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\td=\"M 0,1.5 Q 0,0 1.5,0 Q 3.5,1 5.8,3.2 Q 6.5,4 5.8,4.8 Q 3.5,7 1.5,8 Q 0,8 0,6.5 Z\"\n\t\t\t\t\t\t\tfill=\"currentColor\"\n\t\t\t\t\t\t\tstroke=\"none\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</marker>\n\t\t\t\t</defs>\n\t\t\t\t<path\n\t\t\t\t\td=\"M 0 8 L 32 8\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstrokeWidth=\"2\"\n\t\t\t\t\tmarkerEnd={`url(#${id})`}\n\t\t\t\t/>\n\t\t\t</svg>\n\t\t</li>\n\t);\n}\n\nexport type FlowProps = {\n\t/**\n\t * Accessible name for the step list.\n\t * @default \"Flow\"\n\t */\n\t\"aria-label\"?: string;\n\t/**\n\t * Additional classes for the list.\n\t */\n\tclassName?: string;\n\t/**\n\t * Step nodes.\n\t */\n\tchildren: ReactNode;\n};\n\nexport function Flow({ className, children, \"aria-label\": ariaLabel = \"Flow\" }: FlowProps) {\n\tconst nodes = Children.toArray(children);\n\treturn (\n\t\t<ol aria-label={ariaLabel} className={cn(\"flex items-center\", className)}>\n\t\t\t{nodes.map((child, index) => (\n\t\t\t\t<Fragment key={index}>\n\t\t\t\t\t{child}\n\t\t\t\t\t{index < nodes.length - 1 ? <FlowArrow /> : null}\n\t\t\t\t</Fragment>\n\t\t\t))}\n\t\t</ol>\n\t);\n}\n\nexport type FlowNodeProps = {\n\t/**\n\t * Label for the step.\n\t */\n\tchildren: ReactNode;\n};\n\nexport function FlowNode({ children }: FlowNodeProps) {\n\treturn (\n\t\t<li className=\"rounded-basalt-md border border-basalt-border bg-basalt-secondary px-3 py-2 text-sm\">\n\t\t\t{children}\n\t\t</li>\n\t);\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"flow.js","names":[],"sources":["../../src/components/flow.tsx"],"sourcesContent":["import { Children, Fragment, type ReactNode, useId } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\n\nfunction FlowArrow() {\n\tconst id = `flow-arrow-${useId().replace(/:/g, \"\")}`;\n\treturn (\n\t\t<li aria-hidden=\"true\" className=\"flex w-10 shrink-0 items-center text-basalt-muted-foreground\">\n\t\t\t<svg\n\t\t\t\tviewBox=\"0 0 40 16\"\n\t\t\t\tclassName=\"h-4 w-10 overflow-visible\"\n\t\t\t\toverflow=\"visible\"\n\t\t\t\taria-hidden=\"true\"\n\t\t\t>\n\t\t\t\t<defs>\n\t\t\t\t\t<marker\n\t\t\t\t\t\tid={id}\n\t\t\t\t\t\tmarkerWidth=\"8\"\n\t\t\t\t\t\tmarkerHeight=\"8\"\n\t\t\t\t\t\trefX=\"0\"\n\t\t\t\t\t\trefY=\"4\"\n\t\t\t\t\t\torient=\"auto\"\n\t\t\t\t\t\tmarkerUnits=\"userSpaceOnUse\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\td=\"M 0,1.5 Q 0,0 1.5,0 Q 3.5,1 5.8,3.2 Q 6.5,4 5.8,4.8 Q 3.5,7 1.5,8 Q 0,8 0,6.5 Z\"\n\t\t\t\t\t\t\tfill=\"currentColor\"\n\t\t\t\t\t\t\tstroke=\"none\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</marker>\n\t\t\t\t</defs>\n\t\t\t\t<path\n\t\t\t\t\td=\"M 0 8 L 32 8\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstrokeWidth=\"2\"\n\t\t\t\t\tmarkerEnd={`url(#${id})`}\n\t\t\t\t/>\n\t\t\t</svg>\n\t\t</li>\n\t);\n}\n\nexport type FlowProps = {\n\t/**\n\t * Accessible name for the step list.\n\t * @default \"Flow\"\n\t */\n\t\"aria-label\"?: string;\n\t/**\n\t * Additional classes for the list.\n\t */\n\tclassName?: string;\n\t/**\n\t * Step nodes.\n\t */\n\tchildren: ReactNode;\n};\n\nexport function Flow({ className, children, \"aria-label\": ariaLabel = \"Flow\" }: FlowProps) {\n\tconst nodes = Children.toArray(children);\n\treturn (\n\t\t<ol aria-label={ariaLabel} className={cn(BASALT_UI_CLASS, \"flex items-center\", className)}>\n\t\t\t{nodes.map((child, index) => (\n\t\t\t\t<Fragment key={index}>\n\t\t\t\t\t{child}\n\t\t\t\t\t{index < nodes.length - 1 ? <FlowArrow /> : null}\n\t\t\t\t</Fragment>\n\t\t\t))}\n\t\t</ol>\n\t);\n}\n\nexport type FlowNodeProps = {\n\t/**\n\t * Label for the step.\n\t */\n\tchildren: ReactNode;\n};\n\nexport function FlowNode({ children }: FlowNodeProps) {\n\treturn (\n\t\t<li className=\"rounded-basalt-md border border-basalt-border bg-basalt-secondary px-3 py-2 text-sm\">\n\t\t\t{children}\n\t\t</li>\n\t);\n}\n"],"mappings":";;;;;;AAIA,SAAS,IAAY;CACpB,IAAM,IAAK,cAAc,EAAM,CAAC,CAAC,QAAQ,MAAM,EAAE;CACjD,OACC,kBAAC,MAAD;EAAI,eAAY;EAAO,WAAU;EAChC,UAAA,kBAAC,OAAD;GACC,SAAQ;GACR,WAAU;GACV,UAAS;GACT,eAAY;GAJb,UAAA,CAMC,kBAAC,QAAD,EAAA,UACC,kBAAC,UAAD;IACK;IACJ,aAAY;IACZ,cAAa;IACb,MAAK;IACL,MAAK;IACL,QAAO;IACP,aAAY;IAEZ,UAAA,kBAAC,QAAD;KACC,GAAE;KACF,MAAK;KACL,QAAO;IACP,CAAA;GACM,CAAA,EACH,CAAA,GACN,kBAAC,QAAD;IACC,GAAE;IACF,MAAK;IACL,QAAO;IACP,aAAY;IACZ,WAAW,QAAQ,EAAG;GACtB,CAAA,CACG;;CACF,CAAA;AAEN;AAkBA,SAAgB,EAAK,EAAE,cAAW,aAAU,cAAc,IAAY,UAAqB;CAC1F,IAAM,IAAQ,EAAS,QAAQ,CAAQ;CACvC,OACC,kBAAC,MAAD;EAAI,cAAY;EAAW,WAAW,EAAG,GAAiB,qBAAqB,CAAS;EACtF,UAAA,EAAM,KAAK,GAAO,MAClB,kBAAC,GAAD,EAAA,UAAA,CACE,GACA,IAAQ,EAAM,SAAS,IAAI,kBAAC,GAAD,CAAY,CAAA,IAAI,IACnC,EAAA,GAHK,CAGL,CACV;CACE,CAAA;AAEN;AASA,SAAgB,EAAS,EAAE,eAA2B;CACrD,OACC,kBAAC,MAAD;EAAI,WAAU;EACZ;CACE,CAAA;AAEN"}
|
|
@@ -12,4 +12,6 @@ export type GridProps = {
|
|
|
12
12
|
children?: ReactNode;
|
|
13
13
|
};
|
|
14
14
|
export declare function Grid({ className, columns, style, ...props }: GridProps & HTMLAttributes<HTMLDivElement>): import("react").JSX.Element;
|
|
15
|
-
export
|
|
15
|
+
export interface GridItemProps extends HTMLAttributes<HTMLDivElement> {
|
|
16
|
+
}
|
|
17
|
+
export declare function GridItem({ className, ...props }: GridItemProps): import("react").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid.js","names":[],"sources":["../../src/components/grid.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport type GridProps = {\n\t/**\n\t * Number of equal columns.\n\t * @default 2\n\t */\n\tcolumns?: number;\n\t/**\n\t * Additional classes for the grid.\n\t */\n\tclassName?: string;\n\tchildren?: ReactNode;\n};\n\nexport function Grid({\n\tclassName,\n\tcolumns = 2,\n\tstyle,\n\t...props\n}: GridProps & HTMLAttributes<HTMLDivElement>) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\"grid gap-3\", className)}\n\t\t\t{...props}\n\t\t\tstyle={{\n\t\t\t\tgridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t/>\n\t);\n}\n\nexport function GridItem({ className, ...props }:
|
|
1
|
+
{"version":3,"file":"grid.js","names":[],"sources":["../../src/components/grid.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport type GridProps = {\n\t/**\n\t * Number of equal columns.\n\t * @default 2\n\t */\n\tcolumns?: number;\n\t/**\n\t * Additional classes for the grid.\n\t */\n\tclassName?: string;\n\tchildren?: ReactNode;\n};\n\nexport function Grid({\n\tclassName,\n\tcolumns = 2,\n\tstyle,\n\t...props\n}: GridProps & HTMLAttributes<HTMLDivElement>) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\"grid gap-3\", className)}\n\t\t\t{...props}\n\t\t\tstyle={{\n\t\t\t\tgridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t/>\n\t);\n}\n\nexport interface GridItemProps extends HTMLAttributes<HTMLDivElement> {}\n\nexport function GridItem({ className, ...props }: GridItemProps) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"flex items-center justify-center rounded-basalt-lg bg-basalt-secondary px-6 py-8 text-sm\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":";;;;AAgBA,SAAgB,EAAK,EACpB,cACA,aAAU,GACV,UACA,GAAG,KAC2C;CAC9C,OACC,kBAAC,OAAD;EACC,WAAW,EAAG,cAAc,CAAS;EACrC,GAAI;EACJ,OAAO;GACN,qBAAqB,UAAU,EAAQ;GACvC,GAAG;EACJ;CACA,CAAA;AAEH;AAIA,SAAgB,EAAS,EAAE,cAAW,GAAG,KAAwB;CAChE,OACC,kBAAC,OAAD;EACC,WAAW,EACV,4FACA,CACD;EACA,GAAI;CACJ,CAAA;AAEH"}
|
|
@@ -1,5 +1,115 @@
|
|
|
1
1
|
import * as HoverCardPrimitive from "@radix-ui/react-hover-card";
|
|
2
2
|
import * as React from "react";
|
|
3
|
+
type RadixHoverCardProps = React.ComponentPropsWithoutRef<typeof HoverCardPrimitive.Root>;
|
|
4
|
+
type RadixHoverCardTriggerProps = React.ComponentPropsWithoutRef<typeof HoverCardPrimitive.Trigger>;
|
|
5
|
+
type RadixHoverCardContentProps = React.ComponentPropsWithoutRef<typeof HoverCardPrimitive.Content>;
|
|
6
|
+
export interface HoverCardProps extends Omit<RadixHoverCardProps, "open" | "defaultOpen" | "onOpenChange" | "openDelay" | "closeDelay"> {
|
|
7
|
+
/**
|
|
8
|
+
* Controlled open state of the hover card.
|
|
9
|
+
*/
|
|
10
|
+
open?: RadixHoverCardProps["open"];
|
|
11
|
+
/**
|
|
12
|
+
* Open state of the hover card when initially rendered in uncontrolled mode.
|
|
13
|
+
* @default false
|
|
14
|
+
*/
|
|
15
|
+
defaultOpen?: RadixHoverCardProps["defaultOpen"];
|
|
16
|
+
/**
|
|
17
|
+
* Callback invoked when open state changes.
|
|
18
|
+
*/
|
|
19
|
+
onOpenChange?: RadixHoverCardProps["onOpenChange"];
|
|
20
|
+
/**
|
|
21
|
+
* Delay in milliseconds before the hover card opens after hovering trigger.
|
|
22
|
+
* @default 700
|
|
23
|
+
*/
|
|
24
|
+
openDelay?: RadixHoverCardProps["openDelay"];
|
|
25
|
+
/**
|
|
26
|
+
* Delay in milliseconds before the hover card closes after hover leaves trigger or content.
|
|
27
|
+
* @default 300
|
|
28
|
+
*/
|
|
29
|
+
closeDelay?: RadixHoverCardProps["closeDelay"];
|
|
30
|
+
}
|
|
3
31
|
export declare const HoverCard: React.FC<HoverCardPrimitive.HoverCardProps>;
|
|
32
|
+
export interface HoverCardTriggerProps extends Omit<RadixHoverCardTriggerProps, "asChild"> {
|
|
33
|
+
/**
|
|
34
|
+
* Change the default rendered anchor element to the child element, merging props and behavior.
|
|
35
|
+
* @default false
|
|
36
|
+
*/
|
|
37
|
+
asChild?: RadixHoverCardTriggerProps["asChild"];
|
|
38
|
+
}
|
|
4
39
|
export declare const HoverCardTrigger: React.ForwardRefExoticComponent<HoverCardPrimitive.HoverCardTriggerProps & React.RefAttributes<HTMLAnchorElement>>;
|
|
5
|
-
export
|
|
40
|
+
export interface HoverCardContentProps extends Omit<RadixHoverCardContentProps, "side" | "sideOffset" | "align" | "alignOffset" | "avoidCollisions" | "collisionBoundary" | "collisionPadding" | "arrowPadding" | "sticky" | "hideWhenDetached" | "forceMount" | "onEscapeKeyDown" | "onPointerDownOutside" | "onFocusOutside" | "onInteractOutside"> {
|
|
41
|
+
/**
|
|
42
|
+
* Preferred placement side relative to trigger.
|
|
43
|
+
* @default "bottom"
|
|
44
|
+
*/
|
|
45
|
+
side?: RadixHoverCardContentProps["side"];
|
|
46
|
+
/**
|
|
47
|
+
* Distance in pixels between trigger and floating content panel.
|
|
48
|
+
* @default 8
|
|
49
|
+
*/
|
|
50
|
+
sideOffset?: RadixHoverCardContentProps["sideOffset"];
|
|
51
|
+
/**
|
|
52
|
+
* Preferred alignment along the side axis.
|
|
53
|
+
* @default "center"
|
|
54
|
+
*/
|
|
55
|
+
align?: RadixHoverCardContentProps["align"];
|
|
56
|
+
/**
|
|
57
|
+
* Offset in pixels from the start or end alignment position.
|
|
58
|
+
* @default 0
|
|
59
|
+
*/
|
|
60
|
+
alignOffset?: RadixHoverCardContentProps["alignOffset"];
|
|
61
|
+
/**
|
|
62
|
+
* Whether to reposition content to avoid viewport boundary collisions.
|
|
63
|
+
* @default true
|
|
64
|
+
*/
|
|
65
|
+
avoidCollisions?: RadixHoverCardContentProps["avoidCollisions"];
|
|
66
|
+
/**
|
|
67
|
+
* Element or elements bounding boundary collision calculations.
|
|
68
|
+
* @default []
|
|
69
|
+
*/
|
|
70
|
+
collisionBoundary?: RadixHoverCardContentProps["collisionBoundary"];
|
|
71
|
+
/**
|
|
72
|
+
* Virtual padding from collision boundaries in pixels.
|
|
73
|
+
* @default 0
|
|
74
|
+
*/
|
|
75
|
+
collisionPadding?: RadixHoverCardContentProps["collisionPadding"];
|
|
76
|
+
/**
|
|
77
|
+
* Padding in pixels between popper arrow and floating panel edge.
|
|
78
|
+
* @default 0
|
|
79
|
+
*/
|
|
80
|
+
arrowPadding?: RadixHoverCardContentProps["arrowPadding"];
|
|
81
|
+
/**
|
|
82
|
+
* Sticky positioning behavior along the align axis when overflowing.
|
|
83
|
+
* @default "partial"
|
|
84
|
+
*/
|
|
85
|
+
sticky?: RadixHoverCardContentProps["sticky"];
|
|
86
|
+
/**
|
|
87
|
+
* Whether to hide content completely when trigger is fully occluded.
|
|
88
|
+
* @default false
|
|
89
|
+
*/
|
|
90
|
+
hideWhenDetached?: RadixHoverCardContentProps["hideWhenDetached"];
|
|
91
|
+
/**
|
|
92
|
+
* Force mounting content in DOM for external animation controls.
|
|
93
|
+
* When forceMount is true, the content remains mounted even when closed.
|
|
94
|
+
* The caller is responsible for visibility transitions and unmounting after animation completes.
|
|
95
|
+
*/
|
|
96
|
+
forceMount?: true;
|
|
97
|
+
/**
|
|
98
|
+
* Callback fired when the Escape key is down on the dismissable layer. Can be prevented.
|
|
99
|
+
*/
|
|
100
|
+
onEscapeKeyDown?: RadixHoverCardContentProps["onEscapeKeyDown"];
|
|
101
|
+
/**
|
|
102
|
+
* Callback fired when a pointerdown event happens outside the bounds of the dismissable layer. Can be prevented.
|
|
103
|
+
*/
|
|
104
|
+
onPointerDownOutside?: RadixHoverCardContentProps["onPointerDownOutside"];
|
|
105
|
+
/**
|
|
106
|
+
* Callback fired when focus moves outside the bounds of the dismissable layer. Can be prevented.
|
|
107
|
+
*/
|
|
108
|
+
onFocusOutside?: RadixHoverCardContentProps["onFocusOutside"];
|
|
109
|
+
/**
|
|
110
|
+
* Callback fired when an interaction (pointerdown or focus) happens outside the bounds of the dismissable layer. Can be prevented.
|
|
111
|
+
*/
|
|
112
|
+
onInteractOutside?: RadixHoverCardContentProps["onInteractOutside"];
|
|
113
|
+
}
|
|
114
|
+
export declare const HoverCardContent: React.ForwardRefExoticComponent<HoverCardContentProps & React.RefAttributes<HTMLDivElement>>;
|
|
115
|
+
export {};
|
|
@@ -5,12 +5,15 @@ import * as r from "react";
|
|
|
5
5
|
import { jsx as i } from "react/jsx-runtime";
|
|
6
6
|
import * as a from "@radix-ui/react-hover-card";
|
|
7
7
|
//#region src/components/hover-card.tsx
|
|
8
|
-
var o = a.Root, s = a.Trigger, c = r.forwardRef(({ className: r, sideOffset: o = 8, ...s }, c) => /* @__PURE__ */ i(a.Portal, {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
var o = a.Root, s = a.Trigger, c = r.forwardRef(({ className: r, sideOffset: o = 8, ...s }, c) => /* @__PURE__ */ i(a.Portal, {
|
|
9
|
+
forceMount: s.forceMount,
|
|
10
|
+
children: /* @__PURE__ */ i(a.Content, {
|
|
11
|
+
ref: c,
|
|
12
|
+
sideOffset: o,
|
|
13
|
+
className: e(t, n, "w-64 rounded-basalt-md border border-basalt-border bg-basalt-popover p-4 text-basalt-popover-foreground shadow-md", r),
|
|
14
|
+
...s
|
|
15
|
+
})
|
|
16
|
+
}));
|
|
14
17
|
c.displayName = a.Content.displayName;
|
|
15
18
|
//#endregion
|
|
16
19
|
export { o as HoverCard, c as HoverCardContent, s as HoverCardTrigger };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hover-card.js","names":[],"sources":["../../src/components/hover-card.tsx"],"sourcesContent":["import * as HoverCardPrimitive from \"@radix-ui/react-hover-card\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { MENU_GAP, OVERLAY_LAYER, OVERLAY_MOTION } from \"./overlay\";\n\nexport const HoverCard = HoverCardPrimitive.Root;\nexport const HoverCardTrigger = HoverCardPrimitive.Trigger;\n\nexport const HoverCardContent = React.forwardRef<\n\tReact.ElementRef<typeof HoverCardPrimitive.Content>,\n\
|
|
1
|
+
{"version":3,"file":"hover-card.js","names":[],"sources":["../../src/components/hover-card.tsx"],"sourcesContent":["import * as HoverCardPrimitive from \"@radix-ui/react-hover-card\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { MENU_GAP, OVERLAY_LAYER, OVERLAY_MOTION } from \"./overlay\";\n\ntype RadixHoverCardProps = React.ComponentPropsWithoutRef<typeof HoverCardPrimitive.Root>;\ntype RadixHoverCardTriggerProps = React.ComponentPropsWithoutRef<typeof HoverCardPrimitive.Trigger>;\ntype RadixHoverCardContentProps = React.ComponentPropsWithoutRef<typeof HoverCardPrimitive.Content>;\n\nexport interface HoverCardProps\n\textends Omit<\n\t\tRadixHoverCardProps,\n\t\t\"open\" | \"defaultOpen\" | \"onOpenChange\" | \"openDelay\" | \"closeDelay\"\n\t> {\n\t/**\n\t * Controlled open state of the hover card.\n\t */\n\topen?: RadixHoverCardProps[\"open\"];\n\t/**\n\t * Open state of the hover card when initially rendered in uncontrolled mode.\n\t * @default false\n\t */\n\tdefaultOpen?: RadixHoverCardProps[\"defaultOpen\"];\n\t/**\n\t * Callback invoked when open state changes.\n\t */\n\tonOpenChange?: RadixHoverCardProps[\"onOpenChange\"];\n\t/**\n\t * Delay in milliseconds before the hover card opens after hovering trigger.\n\t * @default 700\n\t */\n\topenDelay?: RadixHoverCardProps[\"openDelay\"];\n\t/**\n\t * Delay in milliseconds before the hover card closes after hover leaves trigger or content.\n\t * @default 300\n\t */\n\tcloseDelay?: RadixHoverCardProps[\"closeDelay\"];\n}\n\nexport const HoverCard = HoverCardPrimitive.Root;\n\nexport interface HoverCardTriggerProps extends Omit<RadixHoverCardTriggerProps, \"asChild\"> {\n\t/**\n\t * Change the default rendered anchor element to the child element, merging props and behavior.\n\t * @default false\n\t */\n\tasChild?: RadixHoverCardTriggerProps[\"asChild\"];\n}\n\nexport const HoverCardTrigger = HoverCardPrimitive.Trigger;\n\nexport interface HoverCardContentProps\n\textends Omit<\n\t\tRadixHoverCardContentProps,\n\t\t| \"side\"\n\t\t| \"sideOffset\"\n\t\t| \"align\"\n\t\t| \"alignOffset\"\n\t\t| \"avoidCollisions\"\n\t\t| \"collisionBoundary\"\n\t\t| \"collisionPadding\"\n\t\t| \"arrowPadding\"\n\t\t| \"sticky\"\n\t\t| \"hideWhenDetached\"\n\t\t| \"forceMount\"\n\t\t| \"onEscapeKeyDown\"\n\t\t| \"onPointerDownOutside\"\n\t\t| \"onFocusOutside\"\n\t\t| \"onInteractOutside\"\n\t> {\n\t/**\n\t * Preferred placement side relative to trigger.\n\t * @default \"bottom\"\n\t */\n\tside?: RadixHoverCardContentProps[\"side\"];\n\t/**\n\t * Distance in pixels between trigger and floating content panel.\n\t * @default 8\n\t */\n\tsideOffset?: RadixHoverCardContentProps[\"sideOffset\"];\n\t/**\n\t * Preferred alignment along the side axis.\n\t * @default \"center\"\n\t */\n\talign?: RadixHoverCardContentProps[\"align\"];\n\t/**\n\t * Offset in pixels from the start or end alignment position.\n\t * @default 0\n\t */\n\talignOffset?: RadixHoverCardContentProps[\"alignOffset\"];\n\t/**\n\t * Whether to reposition content to avoid viewport boundary collisions.\n\t * @default true\n\t */\n\tavoidCollisions?: RadixHoverCardContentProps[\"avoidCollisions\"];\n\t/**\n\t * Element or elements bounding boundary collision calculations.\n\t * @default []\n\t */\n\tcollisionBoundary?: RadixHoverCardContentProps[\"collisionBoundary\"];\n\t/**\n\t * Virtual padding from collision boundaries in pixels.\n\t * @default 0\n\t */\n\tcollisionPadding?: RadixHoverCardContentProps[\"collisionPadding\"];\n\t/**\n\t * Padding in pixels between popper arrow and floating panel edge.\n\t * @default 0\n\t */\n\tarrowPadding?: RadixHoverCardContentProps[\"arrowPadding\"];\n\t/**\n\t * Sticky positioning behavior along the align axis when overflowing.\n\t * @default \"partial\"\n\t */\n\tsticky?: RadixHoverCardContentProps[\"sticky\"];\n\t/**\n\t * Whether to hide content completely when trigger is fully occluded.\n\t * @default false\n\t */\n\thideWhenDetached?: RadixHoverCardContentProps[\"hideWhenDetached\"];\n\t/**\n\t * Force mounting content in DOM for external animation controls.\n\t * When forceMount is true, the content remains mounted even when closed.\n\t * The caller is responsible for visibility transitions and unmounting after animation completes.\n\t */\n\tforceMount?: true;\n\t/**\n\t * Callback fired when the Escape key is down on the dismissable layer. Can be prevented.\n\t */\n\tonEscapeKeyDown?: RadixHoverCardContentProps[\"onEscapeKeyDown\"];\n\t/**\n\t * Callback fired when a pointerdown event happens outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonPointerDownOutside?: RadixHoverCardContentProps[\"onPointerDownOutside\"];\n\t/**\n\t * Callback fired when focus moves outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonFocusOutside?: RadixHoverCardContentProps[\"onFocusOutside\"];\n\t/**\n\t * Callback fired when an interaction (pointerdown or focus) happens outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonInteractOutside?: RadixHoverCardContentProps[\"onInteractOutside\"];\n}\n\nexport const HoverCardContent = React.forwardRef<\n\tReact.ElementRef<typeof HoverCardPrimitive.Content>,\n\tHoverCardContentProps\n>(({ className, sideOffset = MENU_GAP, ...props }, ref) => (\n\t<HoverCardPrimitive.Portal forceMount={props.forceMount}>\n\t\t<HoverCardPrimitive.Content\n\t\t\tref={ref}\n\t\t\tsideOffset={sideOffset}\n\t\t\tclassName={cn(\n\t\t\t\tOVERLAY_LAYER,\n\t\t\t\tOVERLAY_MOTION,\n\t\t\t\t\"w-64 rounded-basalt-md border border-basalt-border bg-basalt-popover p-4 text-basalt-popover-foreground shadow-md\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t</HoverCardPrimitive.Portal>\n));\nHoverCardContent.displayName = HoverCardPrimitive.Content.displayName;\n"],"mappings":";;;;;;;AAuCA,IAAa,IAAY,EAAmB,MAU/B,IAAmB,EAAmB,SA+FtC,IAAmB,EAAM,YAGnC,EAAE,cAAW,gBAAA,GAAuB,GAAG,KAAS,MAClD,kBAAC,EAAmB,QAApB;CAA2B,YAAY,EAAM;CAC5C,UAAA,kBAAC,EAAmB,SAApB;EACM;EACO;EACZ,WAAW,EACV,GACA,GACA,qHACA,CACD;EACA,GAAI;CACJ,CAAA;AACyB,CAAA,CAC3B;AACD,EAAiB,cAAc,EAAmB,QAAQ"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export interface IconPickerOption {
|
|
3
|
+
/** Stable application-owned identifier. */
|
|
4
|
+
value: string;
|
|
5
|
+
/** Visible selection text and accessible icon name. */
|
|
6
|
+
label: string;
|
|
7
|
+
/** Caller-rendered icon, from a deliberately small subset. */
|
|
8
|
+
icon: ReactNode;
|
|
9
|
+
/** Exclude this option from selection and keyboard navigation. */
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface IconPickerProps {
|
|
13
|
+
/** Accessible picker name. */
|
|
14
|
+
label: string;
|
|
15
|
+
/** Caller-supplied icon subset; the library never imports an icon catalog. */
|
|
16
|
+
options: readonly IconPickerOption[];
|
|
17
|
+
/** Controlled icon identifier. */
|
|
18
|
+
value?: string;
|
|
19
|
+
/** Initial uncontrolled icon identifier. */
|
|
20
|
+
defaultValue?: string;
|
|
21
|
+
/** Selection request. */
|
|
22
|
+
onValueChange?: (value: string) => void;
|
|
23
|
+
/** Disable selection. @default false */
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
/** Empty selection prompt. @default "Choose icon" */
|
|
26
|
+
placeholder?: string;
|
|
27
|
+
/** Search placeholder. @default "Search icons…" */
|
|
28
|
+
searchPlaceholder?: string;
|
|
29
|
+
/** Empty-search text. @default "No icons found." */
|
|
30
|
+
emptyLabel?: string;
|
|
31
|
+
/** Additional root classes. */
|
|
32
|
+
className?: string;
|
|
33
|
+
}
|
|
34
|
+
export declare function IconPicker({ label, options, value, defaultValue, onValueChange, disabled, placeholder, searchPlaceholder, emptyLabel, className, }: IconPickerProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../utils/cn.js";
|
|
3
|
+
import { BASALT_UI_CLASS as t } from "../utils/control-surface.js";
|
|
4
|
+
import { Button as n } from "./button.js";
|
|
5
|
+
import { Input as r } from "./input.js";
|
|
6
|
+
import { Popover as i, PopoverContent as a, PopoverTrigger as o } from "./popover.js";
|
|
7
|
+
import { ToggleGroup as s, ToggleGroupItem as c } from "./toggle-group.js";
|
|
8
|
+
import { useState as l } from "react";
|
|
9
|
+
import { ChevronDown as u } from "lucide-react";
|
|
10
|
+
import { jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
11
|
+
//#region src/components/icon-picker.tsx
|
|
12
|
+
function p({ label: p, options: m, value: h, defaultValue: g = "", onValueChange: _, disabled: v = !1, placeholder: y = "Choose icon", searchPlaceholder: b = "Search icons…", emptyLabel: x = "No icons found.", className: S }) {
|
|
13
|
+
let [C, w] = l(g), [T, E] = l(!1), [D, O] = l(""), k = h ?? C, A = m.find((e) => e.value === k), j = m.filter((e) => e.label.toLocaleLowerCase().includes(D.trim().toLocaleLowerCase()));
|
|
14
|
+
return /* @__PURE__ */ f(i, {
|
|
15
|
+
open: T && !v,
|
|
16
|
+
onOpenChange: E,
|
|
17
|
+
children: [/* @__PURE__ */ d(o, {
|
|
18
|
+
asChild: !0,
|
|
19
|
+
children: /* @__PURE__ */ f(n, {
|
|
20
|
+
variant: "outline",
|
|
21
|
+
disabled: v,
|
|
22
|
+
"aria-label": p,
|
|
23
|
+
className: e(t, "max-w-full", S),
|
|
24
|
+
children: [
|
|
25
|
+
/* @__PURE__ */ d("span", {
|
|
26
|
+
"aria-hidden": "true",
|
|
27
|
+
className: "shrink-0",
|
|
28
|
+
children: A?.icon
|
|
29
|
+
}),
|
|
30
|
+
/* @__PURE__ */ d("span", {
|
|
31
|
+
className: "truncate",
|
|
32
|
+
children: A?.label ?? y
|
|
33
|
+
}),
|
|
34
|
+
/* @__PURE__ */ d(u, { className: "shrink-0" })
|
|
35
|
+
]
|
|
36
|
+
})
|
|
37
|
+
}), /* @__PURE__ */ f(a, {
|
|
38
|
+
align: "start",
|
|
39
|
+
className: "w-72 max-w-[calc(100vw-2rem)] space-y-3 p-3",
|
|
40
|
+
"aria-label": p,
|
|
41
|
+
children: [
|
|
42
|
+
/* @__PURE__ */ d(r, {
|
|
43
|
+
"aria-label": `${p}: search`,
|
|
44
|
+
value: D,
|
|
45
|
+
placeholder: b,
|
|
46
|
+
onChange: (e) => O(e.target.value)
|
|
47
|
+
}),
|
|
48
|
+
/* @__PURE__ */ d(s, {
|
|
49
|
+
type: "single",
|
|
50
|
+
"aria-label": p,
|
|
51
|
+
value: k,
|
|
52
|
+
className: "flex h-auto flex-wrap justify-start gap-1 rounded-basalt-lg p-1",
|
|
53
|
+
onValueChange: (e) => {
|
|
54
|
+
e && (h === void 0 && w(e), _?.(e), E(!1), O(""));
|
|
55
|
+
},
|
|
56
|
+
children: j.map((e) => /* @__PURE__ */ d(c, {
|
|
57
|
+
value: e.value,
|
|
58
|
+
disabled: e.disabled,
|
|
59
|
+
"aria-label": e.label,
|
|
60
|
+
title: e.label,
|
|
61
|
+
className: "size-10",
|
|
62
|
+
children: e.icon
|
|
63
|
+
}, e.value))
|
|
64
|
+
}),
|
|
65
|
+
j.length === 0 && /* @__PURE__ */ d("p", {
|
|
66
|
+
role: "status",
|
|
67
|
+
className: "text-sm text-basalt-muted-foreground",
|
|
68
|
+
children: x
|
|
69
|
+
})
|
|
70
|
+
]
|
|
71
|
+
})]
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
//#endregion
|
|
75
|
+
export { p as IconPicker };
|
|
76
|
+
|
|
77
|
+
//# sourceMappingURL=icon-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icon-picker.js","names":[],"sources":["../../src/components/icon-picker.tsx"],"sourcesContent":["import { ChevronDown } from \"lucide-react\";\nimport { type ReactNode, useState } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Button } from \"./button\";\nimport { Input } from \"./input\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\nimport { ToggleGroup, ToggleGroupItem } from \"./toggle-group\";\n\nexport interface IconPickerOption {\n\t/** Stable application-owned identifier. */\n\tvalue: string;\n\t/** Visible selection text and accessible icon name. */\n\tlabel: string;\n\t/** Caller-rendered icon, from a deliberately small subset. */\n\ticon: ReactNode;\n\t/** Exclude this option from selection and keyboard navigation. */\n\tdisabled?: boolean;\n}\nexport interface IconPickerProps {\n\t/** Accessible picker name. */\n\tlabel: string;\n\t/** Caller-supplied icon subset; the library never imports an icon catalog. */\n\toptions: readonly IconPickerOption[];\n\t/** Controlled icon identifier. */\n\tvalue?: string;\n\t/** Initial uncontrolled icon identifier. */\n\tdefaultValue?: string;\n\t/** Selection request. */\n\tonValueChange?: (value: string) => void;\n\t/** Disable selection. @default false */\n\tdisabled?: boolean;\n\t/** Empty selection prompt. @default \"Choose icon\" */\n\tplaceholder?: string;\n\t/** Search placeholder. @default \"Search icons…\" */\n\tsearchPlaceholder?: string;\n\t/** Empty-search text. @default \"No icons found.\" */\n\temptyLabel?: string;\n\t/** Additional root classes. */\n\tclassName?: string;\n}\nexport function IconPicker({\n\tlabel,\n\toptions,\n\tvalue,\n\tdefaultValue = \"\",\n\tonValueChange,\n\tdisabled = false,\n\tplaceholder = \"Choose icon\",\n\tsearchPlaceholder = \"Search icons…\",\n\temptyLabel = \"No icons found.\",\n\tclassName,\n}: IconPickerProps) {\n\tconst [localValue, setLocalValue] = useState(defaultValue);\n\tconst [open, setOpen] = useState(false);\n\tconst [query, setQuery] = useState(\"\");\n\tconst selected = value ?? localValue;\n\tconst option = options.find((option) => option.value === selected);\n\tconst matches = options.filter((option) =>\n\t\toption.label.toLocaleLowerCase().includes(query.trim().toLocaleLowerCase()),\n\t);\n\treturn (\n\t\t<Popover open={open && !disabled} onOpenChange={setOpen}>\n\t\t\t<PopoverTrigger asChild>\n\t\t\t\t<Button\n\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\taria-label={label}\n\t\t\t\t\tclassName={cn(BASALT_UI_CLASS, \"max-w-full\", className)}\n\t\t\t\t>\n\t\t\t\t\t<span aria-hidden=\"true\" className=\"shrink-0\">\n\t\t\t\t\t\t{option?.icon}\n\t\t\t\t\t</span>\n\t\t\t\t\t<span className=\"truncate\">{option?.label ?? placeholder}</span>\n\t\t\t\t\t<ChevronDown className=\"shrink-0\" />\n\t\t\t\t</Button>\n\t\t\t</PopoverTrigger>\n\t\t\t<PopoverContent\n\t\t\t\talign=\"start\"\n\t\t\t\tclassName=\"w-72 max-w-[calc(100vw-2rem)] space-y-3 p-3\"\n\t\t\t\taria-label={label}\n\t\t\t>\n\t\t\t\t<Input\n\t\t\t\t\taria-label={`${label}: search`}\n\t\t\t\t\tvalue={query}\n\t\t\t\t\tplaceholder={searchPlaceholder}\n\t\t\t\t\tonChange={(event) => setQuery(event.target.value)}\n\t\t\t\t/>\n\t\t\t\t<ToggleGroup\n\t\t\t\t\ttype=\"single\"\n\t\t\t\t\taria-label={label}\n\t\t\t\t\tvalue={selected}\n\t\t\t\t\tclassName=\"flex h-auto flex-wrap justify-start gap-1 rounded-basalt-lg p-1\"\n\t\t\t\t\tonValueChange={(next) => {\n\t\t\t\t\t\tif (!next) return;\n\t\t\t\t\t\tif (value === undefined) setLocalValue(next);\n\t\t\t\t\t\tonValueChange?.(next);\n\t\t\t\t\t\tsetOpen(false);\n\t\t\t\t\t\tsetQuery(\"\");\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{matches.map((item) => (\n\t\t\t\t\t\t<ToggleGroupItem\n\t\t\t\t\t\t\tkey={item.value}\n\t\t\t\t\t\t\tvalue={item.value}\n\t\t\t\t\t\t\tdisabled={item.disabled}\n\t\t\t\t\t\t\taria-label={item.label}\n\t\t\t\t\t\t\ttitle={item.label}\n\t\t\t\t\t\t\tclassName=\"size-10\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{item.icon}\n\t\t\t\t\t\t</ToggleGroupItem>\n\t\t\t\t\t))}\n\t\t\t\t</ToggleGroup>\n\t\t\t\t{matches.length === 0 && (\n\t\t\t\t\t<p role=\"status\" className=\"text-sm text-basalt-muted-foreground\">\n\t\t\t\t\t\t{emptyLabel}\n\t\t\t\t\t</p>\n\t\t\t\t)}\n\t\t\t</PopoverContent>\n\t\t</Popover>\n\t);\n}\n"],"mappings":";;;;;;;;;;;AAyCA,SAAgB,EAAW,EAC1B,UACA,YACA,UACA,kBAAe,IACf,kBACA,cAAW,IACX,iBAAc,eACd,uBAAoB,iBACpB,gBAAa,mBACb,gBACmB;CACnB,IAAM,CAAC,GAAY,KAAiB,EAAS,CAAY,GACnD,CAAC,GAAM,KAAW,EAAS,EAAK,GAChC,CAAC,GAAO,KAAY,EAAS,EAAE,GAC/B,IAAW,KAAS,GACpB,IAAS,EAAQ,MAAM,MAAW,EAAO,UAAU,CAAQ,GAC3D,IAAU,EAAQ,QAAQ,MAC/B,EAAO,MAAM,kBAAkB,CAAC,CAAC,SAAS,EAAM,KAAK,CAAC,CAAC,kBAAkB,CAAC,CAC3E;CACA,OACC,kBAAC,GAAD;EAAS,MAAM,KAAQ,CAAC;EAAU,cAAc;EAAhD,UAAA,CACC,kBAAC,GAAD;GAAgB,SAAA;GACf,UAAA,kBAAC,GAAD;IACC,SAAQ;IACE;IACV,cAAY;IACZ,WAAW,EAAG,GAAiB,cAAc,CAAS;IAJvD,UAAA;KAMC,kBAAC,QAAD;MAAM,eAAY;MAAO,WAAU;MACjC,UAAA,GAAQ;KACJ,CAAA;KACN,kBAAC,QAAD;MAAM,WAAU;MAAY,UAAA,GAAQ,SAAS;KAAkB,CAAA;KAC/D,kBAAC,GAAD,EAAa,WAAU,WAAY,CAAA;IAC5B;;EACO,CAAA,GAChB,kBAAC,GAAD;GACC,OAAM;GACN,WAAU;GACV,cAAY;GAHb,UAAA;IAKC,kBAAC,GAAD;KACC,cAAY,GAAG,EAAM;KACrB,OAAO;KACP,aAAa;KACb,WAAW,MAAU,EAAS,EAAM,OAAO,KAAK;IAChD,CAAA;IACD,kBAAC,GAAD;KACC,MAAK;KACL,cAAY;KACZ,OAAO;KACP,WAAU;KACV,gBAAgB,MAAS;MACnB,MACD,MAAU,KAAA,KAAW,EAAc,CAAI,GAC3C,IAAgB,CAAI,GACpB,EAAQ,EAAK,GACb,EAAS,EAAE;KACZ;KAEC,UAAA,EAAQ,KAAK,MACb,kBAAC,GAAD;MAEC,OAAO,EAAK;MACZ,UAAU,EAAK;MACf,cAAY,EAAK;MACjB,OAAO,EAAK;MACZ,WAAU;MAET,UAAA,EAAK;KACU,GARX,EAAK,KAQM,CACjB;IACW,CAAA;IACZ,EAAQ,WAAW,KACnB,kBAAC,KAAD;KAAG,MAAK;KAAS,WAAU;KACzB,UAAA;IACC,CAAA;GAEW;EACR,CAAA,CAAA;;AAEX"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export type InlineEditableChangeReason = "edit" | "save" | "blur" | "cancel";
|
|
2
|
+
export interface InlineEditableProps {
|
|
3
|
+
/** Accessible name of the edited field. */
|
|
4
|
+
label: string;
|
|
5
|
+
/** Committed value, owned by the application. */
|
|
6
|
+
value: string;
|
|
7
|
+
/** Persist the draft. Return a promise to keep the editor pending; rejection preserves the draft. */
|
|
8
|
+
onSave: (value: string) => void | Promise<void>;
|
|
9
|
+
/** Controlled edit mode. */
|
|
10
|
+
editing?: boolean;
|
|
11
|
+
/** Initial uncontrolled edit mode. @default false */
|
|
12
|
+
defaultEditing?: boolean;
|
|
13
|
+
/** Edit-mode requests with their cause, including blur that must not steal focus. */
|
|
14
|
+
onEditingChange?: (editing: boolean, reason: InlineEditableChangeReason) => void;
|
|
15
|
+
/** External pending state. @default false */
|
|
16
|
+
pending?: boolean;
|
|
17
|
+
/** Application-owned error message. */
|
|
18
|
+
error?: string;
|
|
19
|
+
/** Disable editing and saving. @default false */
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
/** Reject an empty draft. @default true */
|
|
22
|
+
required?: boolean;
|
|
23
|
+
/** Trim whitespace before validation and save. @default true */
|
|
24
|
+
trim?: boolean;
|
|
25
|
+
/** Commit when focus leaves the whole editor, including its actions. @default true */
|
|
26
|
+
saveOnBlur?: boolean;
|
|
27
|
+
/** Return a validation message to retain the draft without invoking onSave. */
|
|
28
|
+
validate?: (value: string) => string | undefined;
|
|
29
|
+
/** Empty committed-value prompt. @default "Untitled" */
|
|
30
|
+
placeholder?: string;
|
|
31
|
+
/** Edit action label prefix. @default "Edit" */
|
|
32
|
+
editLabel?: string;
|
|
33
|
+
/** Save action text. @default "Save" */
|
|
34
|
+
saveLabel?: string;
|
|
35
|
+
/** Cancel action text. @default "Cancel" */
|
|
36
|
+
cancelLabel?: string;
|
|
37
|
+
/** Pending announcement. @default "Saving…" */
|
|
38
|
+
pendingLabel?: string;
|
|
39
|
+
/** Empty-value validation message. @default "Enter a value." */
|
|
40
|
+
requiredLabel?: string;
|
|
41
|
+
/** Fallback for non-Error rejections. @default "Could not save changes." */
|
|
42
|
+
errorLabel?: string;
|
|
43
|
+
/** Additional root classes. */
|
|
44
|
+
className?: string;
|
|
45
|
+
}
|
|
46
|
+
export declare function InlineEditable({ label, value, onSave, editing, defaultEditing, onEditingChange, pending, error, disabled, required, trim, saveOnBlur, validate, placeholder, editLabel, saveLabel, cancelLabel, pendingLabel, requiredLabel, errorLabel, className, }: InlineEditableProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../utils/cn.js";
|
|
3
|
+
import { BASALT_UI_CLASS as t } from "../utils/control-surface.js";
|
|
4
|
+
import { Button as n } from "./button.js";
|
|
5
|
+
import { Input as r } from "./input.js";
|
|
6
|
+
import { useEffect as i, useId as a, useLayoutEffect as o, useRef as s, useState as c } from "react";
|
|
7
|
+
import { Pencil as l } from "lucide-react";
|
|
8
|
+
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
9
|
+
//#region src/components/inline-editable.tsx
|
|
10
|
+
function f({ label: f, value: p, onSave: m, editing: h, defaultEditing: g = !1, onEditingChange: _, pending: v = !1, error: y, disabled: b = !1, required: x = !0, trim: S = !0, saveOnBlur: C = !0, validate: w, placeholder: T = "Untitled", editLabel: E = "Edit", saveLabel: D = "Save", cancelLabel: O = "Cancel", pendingLabel: k = "Saving…", requiredLabel: A = "Enter a value.", errorLabel: j = "Could not save changes.", className: M }) {
|
|
11
|
+
let [N, P] = c(g), [F, I] = c(p), [L, R] = c(!1), [z, B] = c(), V = s(null), H = s(null), U = s(!0), W = s(0), G = s(!1), K = s(!1), q = a(), J = h ?? N, Y = v || L, X = y ?? z;
|
|
12
|
+
i(() => (U.current = !0, () => {
|
|
13
|
+
U.current = !1, W.current += 1;
|
|
14
|
+
}), []), o(() => {
|
|
15
|
+
J && !b ? (V.current?.focus(), V.current?.select()) : !J && K.current && (K.current = !1, H.current?.focus());
|
|
16
|
+
}, [J, b]), i(() => {
|
|
17
|
+
J || (W.current += 1, G.current = !1, R(!1), I(p), B(void 0));
|
|
18
|
+
}, [J, p]);
|
|
19
|
+
function Z(e, t) {
|
|
20
|
+
h === void 0 && P(e), _?.(e, t);
|
|
21
|
+
}
|
|
22
|
+
function Q(e) {
|
|
23
|
+
K.current = e !== "blur", Z(!1, e);
|
|
24
|
+
}
|
|
25
|
+
async function $(e) {
|
|
26
|
+
if (!J || b || Y || G.current) return;
|
|
27
|
+
let t = S ? F.trim() : F, n = x && !t ? A : w?.(t);
|
|
28
|
+
if (n) {
|
|
29
|
+
B(n);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (t === p) {
|
|
33
|
+
Q(e);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
G.current = !0, R(!0), B(void 0);
|
|
37
|
+
let r = ++W.current;
|
|
38
|
+
try {
|
|
39
|
+
await m(t), U.current && r === W.current && Q(e);
|
|
40
|
+
} catch (e) {
|
|
41
|
+
U.current && r === W.current && B(e instanceof Error && e.message ? e.message : j);
|
|
42
|
+
} finally {
|
|
43
|
+
U.current && r === W.current && (G.current = !1, R(!1));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return /* @__PURE__ */ d("div", {
|
|
47
|
+
role: "group",
|
|
48
|
+
"aria-label": f,
|
|
49
|
+
"aria-busy": Y,
|
|
50
|
+
className: e(t, "min-w-0 space-y-2", M),
|
|
51
|
+
onBlur: (e) => {
|
|
52
|
+
C && !e.currentTarget.contains(e.relatedTarget) && $("blur");
|
|
53
|
+
},
|
|
54
|
+
children: [
|
|
55
|
+
J ? /* @__PURE__ */ d("div", {
|
|
56
|
+
className: "flex flex-wrap items-center gap-2",
|
|
57
|
+
children: [
|
|
58
|
+
/* @__PURE__ */ u(r, {
|
|
59
|
+
ref: V,
|
|
60
|
+
"aria-label": f,
|
|
61
|
+
className: "min-w-0 flex-1 basis-32",
|
|
62
|
+
value: F,
|
|
63
|
+
disabled: b,
|
|
64
|
+
readOnly: Y,
|
|
65
|
+
"aria-invalid": !!X,
|
|
66
|
+
"aria-describedby": X ? `${q}-error` : void 0,
|
|
67
|
+
onChange: (e) => {
|
|
68
|
+
I(e.target.value), B(void 0);
|
|
69
|
+
},
|
|
70
|
+
onKeyDown: (e) => {
|
|
71
|
+
e.nativeEvent.isComposing || (e.key === "Enter" && (e.preventDefault(), $("save")), e.key === "Escape" && !Y && (e.preventDefault(), e.stopPropagation(), I(p), B(void 0), Q("cancel")));
|
|
72
|
+
}
|
|
73
|
+
}),
|
|
74
|
+
/* @__PURE__ */ u(n, {
|
|
75
|
+
size: "sm",
|
|
76
|
+
disabled: b || Y,
|
|
77
|
+
onClick: () => void $("save"),
|
|
78
|
+
children: D
|
|
79
|
+
}),
|
|
80
|
+
/* @__PURE__ */ u(n, {
|
|
81
|
+
size: "sm",
|
|
82
|
+
variant: "ghost",
|
|
83
|
+
disabled: Y,
|
|
84
|
+
onClick: () => {
|
|
85
|
+
I(p), B(void 0), Q("cancel");
|
|
86
|
+
},
|
|
87
|
+
children: O
|
|
88
|
+
})
|
|
89
|
+
]
|
|
90
|
+
}) : /* @__PURE__ */ d("button", {
|
|
91
|
+
ref: H,
|
|
92
|
+
type: "button",
|
|
93
|
+
disabled: b || v,
|
|
94
|
+
"aria-label": `${E} ${f}`,
|
|
95
|
+
className: "group flex max-w-full items-center gap-2 rounded-basalt-md px-1 py-1 text-left text-sm hover:bg-basalt-accent focus-visible:outline-2 focus-visible:outline-basalt-ring disabled:opacity-50",
|
|
96
|
+
onClick: () => {
|
|
97
|
+
I(p), B(void 0), Z(!0, "edit");
|
|
98
|
+
},
|
|
99
|
+
children: [/* @__PURE__ */ u("span", {
|
|
100
|
+
className: e("min-w-0 break-words", !p && "text-basalt-muted-foreground"),
|
|
101
|
+
children: p || T
|
|
102
|
+
}), /* @__PURE__ */ u(l, {
|
|
103
|
+
className: "size-3.5 shrink-0 text-basalt-muted-foreground",
|
|
104
|
+
"aria-hidden": "true"
|
|
105
|
+
})]
|
|
106
|
+
}),
|
|
107
|
+
Y && /* @__PURE__ */ u("p", {
|
|
108
|
+
role: "status",
|
|
109
|
+
className: "text-xs text-basalt-muted-foreground",
|
|
110
|
+
children: k
|
|
111
|
+
}),
|
|
112
|
+
X && /* @__PURE__ */ u("p", {
|
|
113
|
+
id: `${q}-error`,
|
|
114
|
+
role: "alert",
|
|
115
|
+
className: "text-xs text-basalt-destructive",
|
|
116
|
+
children: X
|
|
117
|
+
})
|
|
118
|
+
]
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
//#endregion
|
|
122
|
+
export { f as InlineEditable };
|
|
123
|
+
|
|
124
|
+
//# sourceMappingURL=inline-editable.js.map
|