@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 { Button as n } from "./button.js";
|
|
|
5
5
|
import { Input as r } from "./input.js";
|
|
6
6
|
import * as i from "react";
|
|
7
7
|
import { jsx as a } from "react/jsx-runtime";
|
|
8
|
-
|
|
8
|
+
// src/components/input-group.tsx
|
|
9
9
|
var o = i.createContext(!1), s = i.forwardRef(({ className: n, disabled: r, onClick: i, children: s, ...c }, l) => /* @__PURE__ */ a(o.Provider, {
|
|
10
10
|
value: !!r,
|
|
11
11
|
children: /* @__PURE__ */ a("div", {
|
|
@@ -14,9 +14,9 @@ var o = i.createContext(!1), s = i.forwardRef(({ className: n, disabled: r, onCl
|
|
|
14
14
|
"data-disabled": r ? "" : void 0,
|
|
15
15
|
"aria-disabled": r || void 0,
|
|
16
16
|
inert: r || void 0,
|
|
17
|
-
className: t(e("flex w-full items-center text-basalt-base shadow-xs", "[&>:first-child]:rounded-l-basalt-md [&>:last-child]:rounded-r-basalt-md", "
|
|
17
|
+
className: t(e("flex w-full items-center text-basalt-base shadow-xs", "[&>:first-child]:rounded-l-basalt-md [&>:last-child]:rounded-r-basalt-md", "basalt-focus-group has-[input[aria-invalid=true]]:border-basalt-destructive", "has-[[data-slot=input-group-addon-start]]:[&_input]:pl-basalt-space-lg", "has-[[data-slot=input-group-addon-end]]:[&_input]:pr-basalt-space-lg", "has-[[data-slot=input-group-suffix]]:[&_input]:flex-none", "has-[[data-slot=input-group-suffix]]:[&_input]:[field-sizing:content]", "has-[[data-slot=input-group-suffix]]:[&_input]:pr-0", "data-[disabled]:pointer-events-none data-[disabled]:opacity-50", n)),
|
|
18
18
|
onClick: (e) => {
|
|
19
|
-
i?.(e),
|
|
19
|
+
i?.(e), e.defaultPrevented || r || e.target.closest("input, textarea, button, a") || e.currentTarget.querySelector("input")?.focus();
|
|
20
20
|
},
|
|
21
21
|
...c,
|
|
22
22
|
children: s
|
|
@@ -28,7 +28,7 @@ var c = i.forwardRef(({ className: t, disabled: n, ...s }, c) => {
|
|
|
28
28
|
return /* @__PURE__ */ a(r, {
|
|
29
29
|
ref: c,
|
|
30
30
|
disabled: n || l,
|
|
31
|
-
className: e("min-w-0 w-auto! flex-1 rounded-none border-0 bg-transparent px-basalt-space-lg shadow-none",
|
|
31
|
+
className: e("min-w-0 w-auto! flex-1 rounded-none border-0 bg-transparent px-basalt-space-lg shadow-none", t),
|
|
32
32
|
...s
|
|
33
33
|
});
|
|
34
34
|
});
|
|
@@ -72,7 +72,6 @@ var f = Object.assign(s, {
|
|
|
72
72
|
Suffix: u,
|
|
73
73
|
Button: d
|
|
74
74
|
});
|
|
75
|
-
//#endregion
|
|
76
75
|
export { f as InputGroup };
|
|
77
76
|
|
|
78
77
|
//# sourceMappingURL=input-group.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-group.js","names":["React","InputGroupDisabled","InputGroupRoot","props","disabled","controlSurfaceClass","cn","className","onClick","event","InputGroupInput","groupDisabled","Input","InputGroupAddon","align","InputGroupSuffix","InputGroupButton","Button","InputGroup"],"sources":["../../src/components/input-group.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { controlSurfaceClass } from \"../utils/control-surface\";\nimport { Button, type ButtonProps } from \"./button\";\nimport { Input } from \"./input\";\n\nexport type InputGroupProps = React.HTMLAttributes<HTMLDivElement> & {\n\t/**\n\t * Disable the input and nested actions.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n};\n\nconst InputGroupDisabled = React.createContext(false);\n\nconst InputGroupRoot = React.forwardRef<HTMLDivElement, InputGroupProps>(\n\t({ className, disabled, onClick, children, ...props }, ref) => (\n\t\t<InputGroupDisabled.Provider value={Boolean(disabled)}>\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"input-group\"\n\t\t\t\tdata-disabled={disabled ? \"\" : undefined}\n\t\t\t\taria-disabled={disabled || undefined}\n\t\t\t\tinert={disabled || undefined}\n\t\t\t\tclassName={controlSurfaceClass(\n\t\t\t\t\tcn(\n\t\t\t\t\t\t\"flex w-full items-center text-basalt-base shadow-xs\",\n\t\t\t\t\t\t\"[&>:first-child]:rounded-l-basalt-md [&>:last-child]:rounded-r-basalt-md\",\n\t\t\t\t\t\t\"
|
|
1
|
+
{"version":3,"file":"input-group.js","names":["React","InputGroupDisabled","InputGroupRoot","props","disabled","controlSurfaceClass","cn","className","onClick","event","InputGroupInput","groupDisabled","Input","InputGroupAddon","align","InputGroupSuffix","InputGroupButton","Button","InputGroup"],"sources":["../../src/components/input-group.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { controlSurfaceClass } from \"../utils/control-surface\";\nimport { Button, type ButtonProps } from \"./button\";\nimport { Input } from \"./input\";\n\nexport type InputGroupProps = React.HTMLAttributes<HTMLDivElement> & {\n\t/**\n\t * Disable the input and nested actions.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n};\n\nconst InputGroupDisabled = React.createContext(false);\n\nconst InputGroupRoot = React.forwardRef<HTMLDivElement, InputGroupProps>(\n\t({ className, disabled, onClick, children, ...props }, ref) => (\n\t\t<InputGroupDisabled.Provider value={Boolean(disabled)}>\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"input-group\"\n\t\t\t\tdata-disabled={disabled ? \"\" : undefined}\n\t\t\t\taria-disabled={disabled || undefined}\n\t\t\t\tinert={disabled || undefined}\n\t\t\t\tclassName={controlSurfaceClass(\n\t\t\t\t\tcn(\n\t\t\t\t\t\t\"flex w-full items-center text-basalt-base shadow-xs\",\n\t\t\t\t\t\t\"[&>:first-child]:rounded-l-basalt-md [&>:last-child]:rounded-r-basalt-md\",\n\t\t\t\t\t\t\"basalt-focus-group has-[input[aria-invalid=true]]:border-basalt-destructive\",\n\t\t\t\t\t\t\"has-[[data-slot=input-group-addon-start]]:[&_input]:pl-basalt-space-lg\",\n\t\t\t\t\t\t\"has-[[data-slot=input-group-addon-end]]:[&_input]:pr-basalt-space-lg\",\n\t\t\t\t\t\t\"has-[[data-slot=input-group-suffix]]:[&_input]:flex-none\",\n\t\t\t\t\t\t\"has-[[data-slot=input-group-suffix]]:[&_input]:[field-sizing:content]\",\n\t\t\t\t\t\t\"has-[[data-slot=input-group-suffix]]:[&_input]:pr-0\",\n\t\t\t\t\t\t\"data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n\t\t\t\t\t\tclassName,\n\t\t\t\t\t),\n\t\t\t\t)}\n\t\t\t\tonClick={(event) => {\n\t\t\t\t\tonClick?.(event);\n\t\t\t\t\tif (event.defaultPrevented || disabled) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst target = event.target as HTMLElement;\n\t\t\t\t\tif (target.closest(\"input, textarea, button, a\")) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tevent.currentTarget.querySelector(\"input\")?.focus();\n\t\t\t\t}}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t</InputGroupDisabled.Provider>\n\t),\n);\nInputGroupRoot.displayName = \"InputGroup\";\n\nexport type InputGroupInputProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof Input>,\n\t\"type\" | \"size\" | \"passwordManagerIgnore\"\n> & {\n\t/**\n\t * The type of input control to render.\n\t */\n\ttype?: React.HTMLInputTypeAttribute;\n};\n\nconst InputGroupInput = React.forwardRef<HTMLInputElement, InputGroupInputProps>(\n\t({ className, disabled, ...props }, ref) => {\n\t\tconst groupDisabled = React.useContext(InputGroupDisabled);\n\t\treturn (\n\t\t\t<Input\n\t\t\t\tref={ref}\n\t\t\t\tdisabled={disabled || groupDisabled}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"min-w-0 w-auto! flex-1 rounded-none border-0 bg-transparent px-basalt-space-lg shadow-none\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nInputGroupInput.displayName = \"InputGroup.Input\";\n\nexport type InputGroupAddonProps = React.HTMLAttributes<HTMLDivElement> & {\n\t/**\n\t * Place the addon at the start or end of the group.\n\t * @default start\n\t */\n\talign?: \"start\" | \"end\";\n};\n\nfunction InputGroupAddon({ align = \"start\", className, children, ...props }: InputGroupAddonProps) {\n\treturn (\n\t\t<div\n\t\t\tdata-slot={align === \"end\" ? \"input-group-addon-end\" : \"input-group-addon-start\"}\n\t\t\tclassName={cn(\n\t\t\t\t\"pointer-events-none flex shrink-0 items-center text-basalt-muted-foreground *:pointer-events-auto [&_svg]:size-basalt-icon-lg\",\n\t\t\t\talign === \"start\" ? \"-order-1 pl-basalt-space-lg\" : \"order-1 pr-basalt-space-lg\",\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</div>\n\t);\n}\nInputGroupAddon.displayName = \"InputGroup.Addon\";\n\nexport type InputGroupSuffixProps = React.HTMLAttributes<HTMLDivElement>;\n\nfunction InputGroupSuffix({ className, children, ...props }: InputGroupSuffixProps) {\n\treturn (\n\t\t<div\n\t\t\tdata-slot=\"input-group-suffix\"\n\t\t\tclassName={cn(\n\t\t\t\t\"pointer-events-none flex min-w-0 flex-1 items-center pr-basalt-space-lg text-basalt-muted-foreground select-none\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<span className=\"truncate\">{children}</span>\n\t\t</div>\n\t);\n}\nInputGroupSuffix.displayName = \"InputGroup.Suffix\";\n\nexport interface InputGroupButtonProps\n\textends Omit<ButtonProps, \"variant\" | \"size\" | \"asChild\" | \"loading\" | \"icon\"> {\n\t/**\n\t * Visual style for the nested action.\n\t * @default ghost\n\t */\n\tvariant?: ButtonProps[\"variant\"];\n\t/**\n\t * Size for the nested action.\n\t * @default icon\n\t */\n\tsize?: ButtonProps[\"size\"];\n\t/**\n\t * Render the nested action through its child element.\n\t * @default false\n\t */\n\tasChild?: boolean;\n\t/**\n\t * Show a spinner and disable the nested action.\n\t * @default false\n\t */\n\tloading?: boolean;\n\t/**\n\t * Icon rendered before the nested action label.\n\t */\n\ticon?: React.ReactNode;\n}\n\nconst InputGroupButton = React.forwardRef<HTMLButtonElement, InputGroupButtonProps>(\n\t({ className, variant = \"ghost\", size = \"icon\", disabled, ...props }, ref) => {\n\t\tconst groupDisabled = React.useContext(InputGroupDisabled);\n\t\treturn (\n\t\t\t<Button\n\t\t\t\tref={ref}\n\t\t\t\tvariant={variant}\n\t\t\t\tsize={size}\n\t\t\t\tdisabled={disabled || groupDisabled}\n\t\t\t\tclassName={cn(\"basalt-action-inset shrink-0 rounded-basalt-sm\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nInputGroupButton.displayName = \"InputGroup.Button\";\n\nexport const InputGroup = Object.assign(InputGroupRoot, {\n\tInput: InputGroupInput,\n\tAddon: InputGroupAddon,\n\tSuffix: InputGroupSuffix,\n\tButton: InputGroupButton,\n});\n"],"mappings":";;;;;;;;AAcA,IAAMC,IAAqBD,EAAM,cAAc,EAAK,GAE9CE,IAAiBF,EAAM,YAC3B,EAAE,cAAW,aAAU,YAAS,aAAU,GAAGG,KAAS,MACtD,kBAACF,EAAmB,UAApB;CAA6B,OAAO,EAAQG;CAC3C,UAAA,kBAAC,OAAD;EACM;EACL,aAAU;EACV,iBAAeA,IAAW,KAAK,KAAA;EAC/B,iBAAeA,KAAY,KAAA;EAC3B,OAAOA,KAAY,KAAA;EACnB,WAAWC,EACVC,EACC,uDACA,4EACA,+EACA,0EACA,wEACA,4DACA,yEACA,uDACA,kEACAC,CACD,CACD;EACA,UAAU,MAAU;GAEnB,AADAC,IAAUC,CAAK,GACXA,EAAM,oBAAoBL,KAGfK,EAAM,OACV,QAAQ,4BAA4B,KAG/CA,EAAM,cAAc,cAAc,OAAO,CAAC,EAAE,MAAM;EACnD;EACA,GAAIN;EAEH;CACG,CAAA;AACuB,CAAA,CAE/B;AACA,EAAe,cAAc;AAY7B,IAAMO,IAAkBV,EAAM,YAC5B,EAAE,cAAW,aAAU,GAAGG,KAAS,MAAQ;CAC3C,IAAMQ,IAAgBX,EAAM,WAAWC,CAAkB;CACzD,OACC,kBAACW,GAAD;EACM;EACL,UAAUR,KAAYO;EACtB,WAAWL,EACV,8FACAC,CACD;EACA,GAAIJ;CACJ,CAAA;AAEH,CACD;AACA,EAAgB,cAAc;AAU9B,SAASU,EAAgB,EAAE,WAAQ,SAAS,cAAW,aAAU,GAAGV,KAA+B;CAClG,OACC,kBAAC,OAAD;EACC,aAAWW,MAAU,QAAQ,0BAA0B;EACvD,WAAWR,EACV,iIACAQ,MAAU,UAAU,gCAAgC,8BACpDP,CACD;EACA,GAAIJ;EAEH;CACG,CAAA;AAEP;AACA,EAAgB,cAAc;AAI9B,SAASY,EAAiB,EAAE,cAAW,aAAU,GAAGZ,KAAgC;CACnF,OACC,kBAAC,OAAD;EACC,aAAU;EACV,WAAWG,EACV,oHACAC,CACD;EACA,GAAIJ;EAEJ,UAAA,kBAAC,QAAD;GAAM,WAAU;GAAY;EAAe,CAAA;CACvC,CAAA;AAEP;AACA,EAAiB,cAAc;AA8B/B,IAAMa,IAAmBhB,EAAM,YAC7B,EAAE,cAAW,aAAU,SAAS,UAAO,QAAQ,aAAU,GAAGG,KAAS,MAAQ;CAC7E,IAAMQ,IAAgBX,EAAM,WAAWC,CAAkB;CACzD,OACC,kBAACgB,GAAD;EACM;EACI;EACH;EACN,UAAUb,KAAYO;EACtB,WAAWL,EAAG,kDAAkDC,CAAS;EACzE,GAAIJ;CACJ,CAAA;AAEH,CACD;AACA,EAAiB,cAAc;AAE/B,IAAae,IAAa,OAAO,OAAOhB,GAAgB;CACvD,OAAOQ;CACP,OAAOG;CACP,QAAQE;CACR,QAAQC;AACT,CAAC"}
|
package/dist/components/input.js
CHANGED
|
@@ -4,7 +4,7 @@ import { controlSurfaceClass as t } from "../utils/control-surface.js";
|
|
|
4
4
|
import { FOCUS_BORDER as n } from "./overlay.js";
|
|
5
5
|
import * as r from "react";
|
|
6
6
|
import { jsx as i } from "react/jsx-runtime";
|
|
7
|
-
|
|
7
|
+
// src/components/input.tsx
|
|
8
8
|
var a = {
|
|
9
9
|
sm: "basalt-action basalt-action-sm",
|
|
10
10
|
default: "basalt-action",
|
|
@@ -22,7 +22,6 @@ var a = {
|
|
|
22
22
|
...l ? o : {}
|
|
23
23
|
}));
|
|
24
24
|
s.displayName = "Input";
|
|
25
|
-
//#endregion
|
|
26
25
|
export { s as Input };
|
|
27
26
|
|
|
28
27
|
//# sourceMappingURL=input.js.map
|
package/dist/components/label.js
CHANGED
|
@@ -6,7 +6,7 @@ import * as o from "react";
|
|
|
6
6
|
import { Info as s } from "lucide-react";
|
|
7
7
|
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
8
8
|
import * as u from "@radix-ui/react-label";
|
|
9
|
-
|
|
9
|
+
// src/components/label.tsx
|
|
10
10
|
var d = o.forwardRef(({ className: o, children: d, showOptional: f = !1, tooltip: p, ...m }, h) => /* @__PURE__ */ l(u.Root, {
|
|
11
11
|
ref: h,
|
|
12
12
|
className: e(t, "inline-flex items-center gap-basalt-space-sm text-basalt-base font-medium leading-basalt-tight text-basalt-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-70", o),
|
|
@@ -29,7 +29,6 @@ var d = o.forwardRef(({ className: o, children: d, showOptional: f = !1, tooltip
|
|
|
29
29
|
]
|
|
30
30
|
}));
|
|
31
31
|
d.displayName = u.Root.displayName;
|
|
32
|
-
//#endregion
|
|
33
32
|
export { d as Label };
|
|
34
33
|
|
|
35
34
|
//# sourceMappingURL=label.js.map
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn as e } from "../utils/cn.js";
|
|
3
3
|
import { BASALT_UI_CLASS as t } from "../utils/control-surface.js";
|
|
4
|
+
import "./overlay.js";
|
|
4
5
|
import { Empty as n } from "./empty.js";
|
|
5
6
|
import { SkeletonLine as r } from "./skeleton-line.js";
|
|
6
7
|
import { Children as i, Fragment as a, forwardRef as o, isValidElement as s } from "react";
|
|
7
8
|
import { Slot as c } from "@radix-ui/react-slot";
|
|
8
9
|
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
9
|
-
|
|
10
|
+
// src/components/layer-card.tsx
|
|
10
11
|
var d = `${t} overflow-hidden rounded-basalt-lg ring-1 ring-basalt-border/50 text-basalt-foreground`, f = {
|
|
11
12
|
none: "",
|
|
12
13
|
sm: "p-basalt-card-sm",
|
|
@@ -35,7 +36,7 @@ h.displayName = "LayerCard";
|
|
|
35
36
|
function g({ className: t, asChild: n = !1, divided: r = !1, ...i }) {
|
|
36
37
|
return /* @__PURE__ */ l(n ? c : "div", {
|
|
37
38
|
"data-slot": "card-header",
|
|
38
|
-
className: e("flex min-w-0 justify-between gap-basalt-space-lg text-basalt-base font-medium tracking-tight text-basalt-foreground", n ? "w-full items-center px-basalt-card py-basalt-card-sm data-[state=open]:border-b data-[state=open]:border-basalt-border" : r ? "items-start p-basalt-card border-b border-basalt-border" : "items-start px-basalt-card pt-basalt-card pb-0", t),
|
|
39
|
+
className: e("flex min-w-0 justify-between gap-basalt-space-lg text-basalt-base font-medium tracking-tight text-basalt-foreground", n ? "w-full items-center rounded-none rounded-t-basalt-lg last:rounded-b-basalt-lg data-[state=closed]:rounded-b-basalt-lg px-basalt-card py-basalt-card-sm data-[state=open]:border-b data-[state=open]:border-basalt-border" : r ? "items-start p-basalt-card border-b border-basalt-border" : "items-start px-basalt-card pt-basalt-card pb-0", n && "basalt-focus basalt-focus-inset", t),
|
|
39
40
|
...i
|
|
40
41
|
});
|
|
41
42
|
}
|
|
@@ -121,7 +122,6 @@ var w = /* @__PURE__ */ new Set([
|
|
|
121
122
|
Loading: S,
|
|
122
123
|
Empty: C
|
|
123
124
|
});
|
|
124
|
-
//#endregion
|
|
125
125
|
export { T as LayerCard };
|
|
126
126
|
|
|
127
127
|
//# sourceMappingURL=layer-card.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layer-card.js","names":["ROOT_CLASSES","BASALT_UI_CLASS","PADDING_CLASSES","isElement","isValidElement","child","hasSlot","Children","children","match","Fragment","LayerCardRoot","forwardRef","props","structured","STRUCTURED_TYPES","type","cn","padding","outlined","className","LayerCardHeader","asChild","Slot","divided","LayerCardBody","LayerCardWell","LayerCardPrimary","LayerCardSecondary","LayerCardFooter","LayerCardLoading","label","SkeletonLine","LayerCardEmpty","Empty","LayerCard"],"sources":["../../src/components/layer-card.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport {\n\tChildren,\n\tFragment,\n\tforwardRef,\n\ttype HTMLAttributes,\n\tisValidElement,\n\ttype ReactElement,\n\ttype ReactNode,\n} from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Empty } from \"./empty\";\nimport { SkeletonLine } from \"./skeleton-line\";\n\nconst ROOT_CLASSES = `${BASALT_UI_CLASS} overflow-hidden rounded-basalt-lg ring-1 ring-basalt-border/50 text-basalt-foreground`;\nconst PADDING_CLASSES = {\n\tnone: \"\",\n\tsm: \"p-basalt-card-sm\",\n\tmd: \"p-basalt-card\",\n\tlg: \"p-basalt-card-lg\",\n\txl: \"p-basalt-card-xl\",\n} as const;\n\nexport type LayerCardPadding = keyof typeof PADDING_CLASSES;\n\nexport type LayerCardProps = Omit<HTMLAttributes<HTMLDivElement>, \"className\"> & {\n\t/**\n\t * Additional classes for the card root.\n\t */\n\tclassName?: string;\n\t/**\n\t * Strengthen the default perimeter hairline.\n\t * @default false\n\t */\n\toutlined?: boolean;\n\t/**\n\t * Inner spacing for unstructured card content.\n\t * @default \"md\"\n\t */\n\tpadding?: LayerCardPadding;\n};\nexport type LayerCardSectionProps = HTMLAttributes<HTMLDivElement>;\nexport type LayerCardHeaderProps = LayerCardSectionProps & {\n\t/** Apply header insets to one child, such as a CollapsibleTrigger, without another wrapper. @default false */\n\tasChild?: boolean;\n\t/** Separate the header from its body with a divider. @default false */\n\tdivided?: boolean;\n};\nexport type LayerCardWellProps = LayerCardSectionProps & {\n\t/**\n\t * Draw a hairline ring on a nested well.\n\t * @default false\n\t */\n\toutlined?: boolean;\n};\nexport type LayerCardLoadingProps = Omit<HTMLAttributes<HTMLDivElement>, \"aria-label\"> & {\n\t/**\n\t * Accessible label announced for the loading state.\n\t * @default \"Loading\"\n\t */\n\tlabel?: string;\n};\nexport type LayerCardEmptyProps = Omit<HTMLAttributes<HTMLDivElement>, \"title\" | \"children\"> & {\n\t/**\n\t * Empty-state heading.\n\t * @default \"No content\"\n\t */\n\ttitle?: string;\n\t/**\n\t * Supporting empty-state text.\n\t */\n\tdescription?: string;\n\t/**\n\t * Optional empty-state icon.\n\t */\n\ticon?: ReactNode;\n\t/**\n\t * Optional interactive action element rendered below empty content.\n\t */\n\taction?: ReactNode;\n\t/**\n\t * Custom supporting content or custom layout rendered between description and action.\n\t */\n\tchildren?: ReactNode;\n};\n\nfunction isElement(child: ReactNode): child is ReactElement<{ children?: ReactNode }> {\n\treturn isValidElement(child);\n}\n\nfunction hasSlot(children: ReactNode, match: (type: unknown) => boolean): boolean {\n\treturn Children.toArray(children).some((child) => {\n\t\tif (!isElement(child)) {\n\t\t\treturn false;\n\t\t}\n\t\tif (match(child.type)) {\n\t\t\treturn true;\n\t\t}\n\t\tif (child.type === Fragment) {\n\t\t\treturn hasSlot(child.props.children, match);\n\t\t}\n\t\treturn false;\n\t});\n}\n\nconst LayerCardRoot = forwardRef<HTMLDivElement, LayerCardProps>(\n\t({ className, children, outlined = false, padding = \"md\", ...props }, ref) => {\n\t\tconst structured = hasSlot(children, (type) => STRUCTURED_TYPES.has(type));\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\tdata-basalt-surface=\"\"\n\t\t\t\tdata-card-structured={structured || undefined}\n\t\t\t\tclassName={cn(\n\t\t\t\t\tROOT_CLASSES,\n\t\t\t\t\tstructured ? \"flex w-full flex-col\" : PADDING_CLASSES[padding],\n\t\t\t\t\toutlined && \"ring-basalt-border\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t},\n);\nLayerCardRoot.displayName = \"LayerCard\";\n\nfunction LayerCardHeader({\n\tclassName,\n\tasChild = false,\n\tdivided = false,\n\t...props\n}: LayerCardHeaderProps) {\n\tconst Component = asChild ? Slot : \"div\";\n\treturn (\n\t\t<Component\n\t\t\tdata-slot=\"card-header\"\n\t\t\tclassName={cn(\n\t\t\t\t\"flex min-w-0 justify-between gap-basalt-space-lg text-basalt-base font-medium tracking-tight text-basalt-foreground\",\n\t\t\t\tasChild\n\t\t\t\t\t? \"w-full items-center px-basalt-card py-basalt-card-sm data-[state=open]:border-b data-[state=open]:border-basalt-border\"\n\t\t\t\t\t: divided\n\t\t\t\t\t\t? \"items-start p-basalt-card border-b border-basalt-border\"\n\t\t\t\t\t\t: \"items-start px-basalt-card pt-basalt-card pb-0\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nLayerCardHeader.displayName = \"LayerCard.Header\";\n\nfunction LayerCardBody({ className, ...props }: LayerCardSectionProps) {\n\treturn (\n\t\t<div data-slot=\"card-body\" className={cn(\"min-w-0 p-basalt-card\", className)} {...props} />\n\t);\n}\nLayerCardBody.displayName = \"LayerCard.Body\";\n\nfunction LayerCardWell({ className, outlined = false, ...props }: LayerCardWellProps) {\n\treturn (\n\t\t<div\n\t\t\tdata-basalt-surface=\"\"\n\t\t\tclassName={cn(\"min-w-0 p-basalt-card\", outlined && \"ring-1 ring-basalt-border/40\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nLayerCardWell.displayName = \"LayerCard.Well\";\n\nfunction LayerCardPrimary(props: LayerCardWellProps) {\n\treturn <LayerCardWell {...props} />;\n}\nLayerCardPrimary.displayName = \"LayerCard.Primary\";\n\nfunction LayerCardSecondary(props: LayerCardHeaderProps) {\n\treturn <LayerCardHeader {...props} />;\n}\nLayerCardSecondary.displayName = \"LayerCard.Secondary\";\n\nfunction LayerCardFooter({ className, ...props }: LayerCardSectionProps) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"flex flex-wrap items-center justify-end gap-basalt-space-lg border-t border-basalt-border px-basalt-card py-basalt-card-sm\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nLayerCardFooter.displayName = \"LayerCard.Footer\";\n\nfunction LayerCardLoading({ label = \"Loading\", className, ...props }: LayerCardLoadingProps) {\n\treturn (\n\t\t<div\n\t\t\trole=\"status\"\n\t\t\taria-label={label}\n\t\t\tclassName={cn(\"space-y-basalt-space-lg p-basalt-card\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<SkeletonLine minWidth={100} maxWidth={100} />\n\t\t\t<SkeletonLine minWidth={72} maxWidth={72} />\n\t\t\t<SkeletonLine minWidth={88} maxWidth={88} />\n\t\t</div>\n\t);\n}\nLayerCardLoading.displayName = \"LayerCard.Loading\";\n\nfunction LayerCardEmpty({ title = \"No content\", className, ...props }: LayerCardEmptyProps) {\n\treturn <Empty title={title} className={cn(\"p-basalt-card\", className)} {...props} />;\n}\nLayerCardEmpty.displayName = \"LayerCard.Empty\";\n\nconst STRUCTURED_TYPES = new Set<unknown>([\n\tLayerCardHeader,\n\tLayerCardBody,\n\tLayerCardWell,\n\tLayerCardFooter,\n\tLayerCardLoading,\n\tLayerCardEmpty,\n\tLayerCardPrimary,\n\tLayerCardSecondary,\n]);\n\nexport const LayerCard = Object.assign(LayerCardRoot, {\n\tPrimary: LayerCardPrimary,\n\tSecondary: LayerCardSecondary,\n\tHeader: LayerCardHeader,\n\tBody: LayerCardBody,\n\tWell: LayerCardWell,\n\tFooter: LayerCardFooter,\n\tLoading: LayerCardLoading,\n\tEmpty: LayerCardEmpty,\n});\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"layer-card.js","names":["ROOT_CLASSES","BASALT_UI_CLASS","PADDING_CLASSES","isElement","isValidElement","child","hasSlot","Children","children","match","Fragment","LayerCardRoot","forwardRef","props","structured","STRUCTURED_TYPES","type","cn","padding","outlined","className","LayerCardHeader","asChild","Slot","divided","LayerCardBody","LayerCardWell","LayerCardPrimary","LayerCardSecondary","LayerCardFooter","LayerCardLoading","label","SkeletonLine","LayerCardEmpty","Empty","LayerCard"],"sources":["../../src/components/layer-card.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport {\n\tChildren,\n\tFragment,\n\tforwardRef,\n\ttype HTMLAttributes,\n\tisValidElement,\n\ttype ReactElement,\n\ttype ReactNode,\n} from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Empty } from \"./empty\";\nimport { FOCUS_INSET } from \"./overlay\";\nimport { SkeletonLine } from \"./skeleton-line\";\n\nconst ROOT_CLASSES = `${BASALT_UI_CLASS} overflow-hidden rounded-basalt-lg ring-1 ring-basalt-border/50 text-basalt-foreground`;\nconst PADDING_CLASSES = {\n\tnone: \"\",\n\tsm: \"p-basalt-card-sm\",\n\tmd: \"p-basalt-card\",\n\tlg: \"p-basalt-card-lg\",\n\txl: \"p-basalt-card-xl\",\n} as const;\n\nexport type LayerCardPadding = keyof typeof PADDING_CLASSES;\n\nexport type LayerCardProps = Omit<HTMLAttributes<HTMLDivElement>, \"className\"> & {\n\t/**\n\t * Additional classes for the card root.\n\t */\n\tclassName?: string;\n\t/**\n\t * Strengthen the default perimeter hairline.\n\t * @default false\n\t */\n\toutlined?: boolean;\n\t/**\n\t * Inner spacing for unstructured card content.\n\t * @default \"md\"\n\t */\n\tpadding?: LayerCardPadding;\n};\nexport type LayerCardSectionProps = HTMLAttributes<HTMLDivElement>;\nexport type LayerCardHeaderProps = LayerCardSectionProps & {\n\t/** Apply header insets to one child, such as a CollapsibleTrigger, without another wrapper. @default false */\n\tasChild?: boolean;\n\t/** Separate the header from its body with a divider. @default false */\n\tdivided?: boolean;\n};\nexport type LayerCardWellProps = LayerCardSectionProps & {\n\t/**\n\t * Draw a hairline ring on a nested well.\n\t * @default false\n\t */\n\toutlined?: boolean;\n};\nexport type LayerCardLoadingProps = Omit<HTMLAttributes<HTMLDivElement>, \"aria-label\"> & {\n\t/**\n\t * Accessible label announced for the loading state.\n\t * @default \"Loading\"\n\t */\n\tlabel?: string;\n};\nexport type LayerCardEmptyProps = Omit<HTMLAttributes<HTMLDivElement>, \"title\" | \"children\"> & {\n\t/**\n\t * Empty-state heading.\n\t * @default \"No content\"\n\t */\n\ttitle?: string;\n\t/**\n\t * Supporting empty-state text.\n\t */\n\tdescription?: string;\n\t/**\n\t * Optional empty-state icon.\n\t */\n\ticon?: ReactNode;\n\t/**\n\t * Optional interactive action element rendered below empty content.\n\t */\n\taction?: ReactNode;\n\t/**\n\t * Custom supporting content or custom layout rendered between description and action.\n\t */\n\tchildren?: ReactNode;\n};\n\nfunction isElement(child: ReactNode): child is ReactElement<{ children?: ReactNode }> {\n\treturn isValidElement(child);\n}\n\nfunction hasSlot(children: ReactNode, match: (type: unknown) => boolean): boolean {\n\treturn Children.toArray(children).some((child) => {\n\t\tif (!isElement(child)) {\n\t\t\treturn false;\n\t\t}\n\t\tif (match(child.type)) {\n\t\t\treturn true;\n\t\t}\n\t\tif (child.type === Fragment) {\n\t\t\treturn hasSlot(child.props.children, match);\n\t\t}\n\t\treturn false;\n\t});\n}\n\nconst LayerCardRoot = forwardRef<HTMLDivElement, LayerCardProps>(\n\t({ className, children, outlined = false, padding = \"md\", ...props }, ref) => {\n\t\tconst structured = hasSlot(children, (type) => STRUCTURED_TYPES.has(type));\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\tdata-basalt-surface=\"\"\n\t\t\t\tdata-card-structured={structured || undefined}\n\t\t\t\tclassName={cn(\n\t\t\t\t\tROOT_CLASSES,\n\t\t\t\t\tstructured ? \"flex w-full flex-col\" : PADDING_CLASSES[padding],\n\t\t\t\t\toutlined && \"ring-basalt-border\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t},\n);\nLayerCardRoot.displayName = \"LayerCard\";\n\nfunction LayerCardHeader({\n\tclassName,\n\tasChild = false,\n\tdivided = false,\n\t...props\n}: LayerCardHeaderProps) {\n\tconst Component = asChild ? Slot : \"div\";\n\treturn (\n\t\t<Component\n\t\t\tdata-slot=\"card-header\"\n\t\t\tclassName={cn(\n\t\t\t\t\"flex min-w-0 justify-between gap-basalt-space-lg text-basalt-base font-medium tracking-tight text-basalt-foreground\",\n\t\t\t\tasChild\n\t\t\t\t\t? \"w-full items-center rounded-none rounded-t-basalt-lg last:rounded-b-basalt-lg data-[state=closed]:rounded-b-basalt-lg px-basalt-card py-basalt-card-sm data-[state=open]:border-b data-[state=open]:border-basalt-border\"\n\t\t\t\t\t: divided\n\t\t\t\t\t\t? \"items-start p-basalt-card border-b border-basalt-border\"\n\t\t\t\t\t\t: \"items-start px-basalt-card pt-basalt-card pb-0\",\n\t\t\t\tasChild && FOCUS_INSET,\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nLayerCardHeader.displayName = \"LayerCard.Header\";\n\nfunction LayerCardBody({ className, ...props }: LayerCardSectionProps) {\n\treturn (\n\t\t<div data-slot=\"card-body\" className={cn(\"min-w-0 p-basalt-card\", className)} {...props} />\n\t);\n}\nLayerCardBody.displayName = \"LayerCard.Body\";\n\nfunction LayerCardWell({ className, outlined = false, ...props }: LayerCardWellProps) {\n\treturn (\n\t\t<div\n\t\t\tdata-basalt-surface=\"\"\n\t\t\tclassName={cn(\"min-w-0 p-basalt-card\", outlined && \"ring-1 ring-basalt-border/40\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nLayerCardWell.displayName = \"LayerCard.Well\";\n\nfunction LayerCardPrimary(props: LayerCardWellProps) {\n\treturn <LayerCardWell {...props} />;\n}\nLayerCardPrimary.displayName = \"LayerCard.Primary\";\n\nfunction LayerCardSecondary(props: LayerCardHeaderProps) {\n\treturn <LayerCardHeader {...props} />;\n}\nLayerCardSecondary.displayName = \"LayerCard.Secondary\";\n\nfunction LayerCardFooter({ className, ...props }: LayerCardSectionProps) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"flex flex-wrap items-center justify-end gap-basalt-space-lg border-t border-basalt-border px-basalt-card py-basalt-card-sm\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nLayerCardFooter.displayName = \"LayerCard.Footer\";\n\nfunction LayerCardLoading({ label = \"Loading\", className, ...props }: LayerCardLoadingProps) {\n\treturn (\n\t\t<div\n\t\t\trole=\"status\"\n\t\t\taria-label={label}\n\t\t\tclassName={cn(\"space-y-basalt-space-lg p-basalt-card\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<SkeletonLine minWidth={100} maxWidth={100} />\n\t\t\t<SkeletonLine minWidth={72} maxWidth={72} />\n\t\t\t<SkeletonLine minWidth={88} maxWidth={88} />\n\t\t</div>\n\t);\n}\nLayerCardLoading.displayName = \"LayerCard.Loading\";\n\nfunction LayerCardEmpty({ title = \"No content\", className, ...props }: LayerCardEmptyProps) {\n\treturn <Empty title={title} className={cn(\"p-basalt-card\", className)} {...props} />;\n}\nLayerCardEmpty.displayName = \"LayerCard.Empty\";\n\nconst STRUCTURED_TYPES = new Set<unknown>([\n\tLayerCardHeader,\n\tLayerCardBody,\n\tLayerCardWell,\n\tLayerCardFooter,\n\tLayerCardLoading,\n\tLayerCardEmpty,\n\tLayerCardPrimary,\n\tLayerCardSecondary,\n]);\n\nexport const LayerCard = Object.assign(LayerCardRoot, {\n\tPrimary: LayerCardPrimary,\n\tSecondary: LayerCardSecondary,\n\tHeader: LayerCardHeader,\n\tBody: LayerCardBody,\n\tWell: LayerCardWell,\n\tFooter: LayerCardFooter,\n\tLoading: LayerCardLoading,\n\tEmpty: LayerCardEmpty,\n});\n"],"mappings":"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"}
|
package/dist/components/link.js
CHANGED
|
@@ -2,17 +2,16 @@
|
|
|
2
2
|
import { cn as e } from "../utils/cn.js";
|
|
3
3
|
import { useLinkComponent as t } from "../providers/link.js";
|
|
4
4
|
import { jsx as n } from "react/jsx-runtime";
|
|
5
|
-
|
|
5
|
+
// src/components/link.tsx
|
|
6
6
|
function r({ className: r, href: i, children: a, ...o }) {
|
|
7
7
|
let s = t();
|
|
8
8
|
return /* @__PURE__ */ n(s, {
|
|
9
9
|
href: i,
|
|
10
|
-
className: e("text-basalt-primary underline-offset-4 hover:underline", r),
|
|
10
|
+
className: e("basalt-focus text-basalt-primary underline-offset-4 hover:underline", r),
|
|
11
11
|
...o,
|
|
12
12
|
children: a
|
|
13
13
|
});
|
|
14
14
|
}
|
|
15
|
-
//#endregion
|
|
16
15
|
export { r as Link };
|
|
17
16
|
|
|
18
17
|
//# sourceMappingURL=link.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link.js","names":["Link","props","Comp","useLinkComponent","cn","className"],"sources":["../../src/components/link.tsx"],"sourcesContent":["import type * as React from \"react\";\nimport { useLinkComponent } from \"../providers/link\";\nimport { cn } from \"../utils/cn\";\n\nexport type LinkProps = Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\"> &\n\tRecord<string, unknown> & {\n\t\t/**\n\t\t * The link destination.\n\t\t */\n\t\thref: string;\n\t};\n\nexport function Link({ className, href, children, ...props }: LinkProps) {\n\tconst Comp = useLinkComponent();\n\treturn (\n\t\t<Comp\n\t\t\thref={href}\n\t\t\tclassName={cn(\"text-basalt-primary underline-offset-4 hover:underline\"
|
|
1
|
+
{"version":3,"file":"link.js","names":["Link","props","Comp","useLinkComponent","cn","className"],"sources":["../../src/components/link.tsx"],"sourcesContent":["import type * as React from \"react\";\nimport { useLinkComponent } from \"../providers/link\";\nimport { cn } from \"../utils/cn\";\n\nexport type LinkProps = Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\"> &\n\tRecord<string, unknown> & {\n\t\t/**\n\t\t * The link destination.\n\t\t */\n\t\thref: string;\n\t};\n\nexport function Link({ className, href, children, ...props }: LinkProps) {\n\tconst Comp = useLinkComponent();\n\treturn (\n\t\t<Comp\n\t\t\thref={href}\n\t\t\tclassName={cn(\n\t\t\t\t\"basalt-focus text-basalt-primary underline-offset-4 hover:underline\",\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</Comp>\n\t);\n}\n"],"mappings":";;;;;AAYA,SAAgBA,EAAK,EAAE,cAAW,SAAM,aAAU,GAAGC,KAAoB;CACxE,IAAMC,IAAOC,EAAiB;CAC9B,OACC,kBAACD,GAAD;EACO;EACN,WAAWE,EACV,uEACAC,CACD;EACA,GAAIJ;EAEH;CACI,CAAA;AAER"}
|
|
@@ -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 { useLoaderViewModel as n } from "../viewmodels/use-loader.js";
|
|
5
5
|
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
6
|
-
|
|
6
|
+
// src/components/loader.tsx
|
|
7
7
|
var a = [
|
|
8
8
|
0,
|
|
9
9
|
1,
|
|
@@ -53,7 +53,6 @@ function o({ className: o, size: s = 16, label: c = "Loading", showLabel: l = !0
|
|
|
53
53
|
]
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
|
-
//#endregion
|
|
57
56
|
export { o as Loader };
|
|
58
57
|
|
|
59
58
|
//# sourceMappingURL=loader.js.map
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { cn as e } from "../utils/cn.js";
|
|
3
3
|
import { BasaltMark as t } from "./basalt-mark.js";
|
|
4
4
|
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
5
|
-
|
|
5
|
+
// src/components/loading-screen.tsx
|
|
6
6
|
function i({ label: i = "Loading", mark: a, className: o, ...s }) {
|
|
7
7
|
return /* @__PURE__ */ n("div", {
|
|
8
8
|
role: "status",
|
|
@@ -22,7 +22,6 @@ function i({ label: i = "Loading", mark: a, className: o, ...s }) {
|
|
|
22
22
|
})
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
|
-
//#endregion
|
|
26
25
|
export { i as LoadingScreen };
|
|
27
26
|
|
|
28
27
|
//# sourceMappingURL=loading-screen.js.map
|
|
@@ -6,7 +6,7 @@ import { useHoverHighlight as i } from "../utils/use-hover-highlight.js";
|
|
|
6
6
|
import * as a from "react";
|
|
7
7
|
import { jsx as o } from "react/jsx-runtime";
|
|
8
8
|
import * as s from "@radix-ui/react-menubar";
|
|
9
|
-
|
|
9
|
+
// src/components/menu-bar.tsx
|
|
10
10
|
function c(e) {
|
|
11
11
|
return /* @__PURE__ */ o(p, { ...e });
|
|
12
12
|
}
|
|
@@ -15,7 +15,7 @@ function l(e) {
|
|
|
15
15
|
}
|
|
16
16
|
var u = a.forwardRef(({ className: n, ...r }, i) => /* @__PURE__ */ o(s.Trigger, {
|
|
17
17
|
ref: i,
|
|
18
|
-
className: e(t, "inline-flex min-h-basalt-control items-center rounded-basalt-sm px-basalt-space-lg text-basalt-base font-medium
|
|
18
|
+
className: e(t, "basalt-focus basalt-focus-inset inline-flex min-h-basalt-control items-center rounded-basalt-sm px-basalt-space-lg text-basalt-base font-medium hover:bg-basalt-hover data-[state=open]:bg-basalt-selected", n),
|
|
19
19
|
...r
|
|
20
20
|
}));
|
|
21
21
|
u.displayName = s.Trigger.displayName;
|
|
@@ -35,7 +35,7 @@ d.displayName = s.Content.displayName;
|
|
|
35
35
|
var f = a.forwardRef(({ className: t, ...r }, i) => /* @__PURE__ */ o(s.Item, {
|
|
36
36
|
"data-basalt-hover-item": "",
|
|
37
37
|
ref: i,
|
|
38
|
-
className: n(e("relative
|
|
38
|
+
className: n(e("relative", t)),
|
|
39
39
|
...r
|
|
40
40
|
}));
|
|
41
41
|
f.displayName = s.Item.displayName;
|
|
@@ -45,7 +45,6 @@ function p({ className: n, ...r }) {
|
|
|
45
45
|
...r
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
|
-
//#endregion
|
|
49
48
|
export { c as MenuBar, d as MenuBarContent, f as MenuBarItem, l as MenuBarMenu, p as MenuBarRoot, u as MenuBarTrigger };
|
|
50
49
|
|
|
51
50
|
//# sourceMappingURL=menu-bar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-bar.js","names":["React","MenubarPrimitive","MenuBar","MenuBarRoot","props","MenuBarMenu","MenuBarTrigger","cn","BASALT_UI_CLASS","className","MenuBarContent","highlightRef","useHoverHighlight","ref","overlayPanelClass","MenuBarItem","overlayItemClass"],"sources":["../../src/components/menu-bar.tsx"],"sourcesContent":["import * as MenubarPrimitive from \"@radix-ui/react-menubar\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { useHoverHighlight } from \"../utils/use-hover-highlight\";\nimport { MENU_GAP, overlayItemClass, overlayPanelClass } from \"./overlay\";\n\ntype RadixMenubarProps = React.ComponentProps<typeof MenubarPrimitive.Root>;\ntype RadixMenubarMenuProps = React.ComponentProps<typeof MenubarPrimitive.Menu>;\ntype RadixMenubarTriggerProps = React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Trigger>;\ntype RadixMenubarContentProps = React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Content>;\ntype RadixMenubarItemProps = React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Item>;\n\nexport interface MenuBarProps\n\textends Omit<\n\t\tRadixMenubarProps,\n\t\t\"value\" | \"defaultValue\" | \"onValueChange\" | \"loop\" | \"dir\" | \"asChild\"\n\t> {\n\t/**\n\t * Controlled value of the currently open menu.\n\t */\n\tvalue?: RadixMenubarProps[\"value\"];\n\t/**\n\t * Uncontrolled initial value of the open menu.\n\t * @default \"\"\n\t */\n\tdefaultValue?: RadixMenubarProps[\"defaultValue\"];\n\t/**\n\t * Callback invoked when the open menu value changes.\n\t */\n\tonValueChange?: RadixMenubarProps[\"onValueChange\"];\n\t/**\n\t * Whether keyboard navigation loops around when reaching ends.\n\t * @default true\n\t */\n\tloop?: RadixMenubarProps[\"loop\"];\n\t/**\n\t * Reading direction of the menubar.\n\t * @default \"ltr\"\n\t */\n\tdir?: RadixMenubarProps[\"dir\"];\n\t/**\n\t * Change the default rendered div element to the child element, merging props and behavior.\n\t * MenuBar forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixMenubarProps[\"asChild\"];\n}\n\nexport function MenuBar(props: MenuBarProps) {\n\treturn <MenuBarRoot {...props} />;\n}\n\nexport interface MenuBarMenuProps extends Omit<RadixMenubarMenuProps, \"value\"> {\n\t/**\n\t * Unique identifier value for this menu within the menubar.\n\t */\n\tvalue?: RadixMenubarMenuProps[\"value\"];\n}\n\nexport function MenuBarMenu(props: MenuBarMenuProps) {\n\treturn <MenubarPrimitive.Menu {...props} />;\n}\n\nexport interface MenuBarTriggerProps\n\textends Omit<RadixMenubarTriggerProps, \"disabled\" | \"asChild\"> {\n\t/**\n\t * Disable the menubar trigger button.\n\t * @default false\n\t */\n\tdisabled?: RadixMenubarTriggerProps[\"disabled\"];\n\t/**\n\t * Change the default rendered button element to the child element, merging props and behavior.\n\t * Trigger forwards ref to HTMLButtonElement and inherits native button attributes.\n\t * @default false\n\t */\n\tasChild?: RadixMenubarTriggerProps[\"asChild\"];\n}\n\nexport const MenuBarTrigger = React.forwardRef<\n\tReact.ElementRef<typeof MenubarPrimitive.Trigger>,\n\tMenuBarTriggerProps\n>(({ className, ...props }, ref) => (\n\t<MenubarPrimitive.Trigger\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\tBASALT_UI_CLASS,\n\t\t\t\"inline-flex min-h-basalt-control items-center rounded-basalt-sm px-basalt-space-lg text-basalt-base font-medium outline-hidden hover:bg-basalt-hover data-[state=open]:bg-basalt-selected\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nMenuBarTrigger.displayName = MenubarPrimitive.Trigger.displayName;\n\nexport interface MenuBarContentProps\n\textends Omit<\n\t\tRadixMenubarContentProps,\n\t\t| \"loop\"\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| \"asChild\"\n\t\t| \"onCloseAutoFocus\"\n\t\t| \"onEscapeKeyDown\"\n\t\t| \"onPointerDownOutside\"\n\t\t| \"onFocusOutside\"\n\t\t| \"onInteractOutside\"\n\t> {\n\t/**\n\t * Whether keyboard navigation loops around when reaching the start or end item.\n\t * @default false\n\t */\n\tloop?: RadixMenubarContentProps[\"loop\"];\n\t/**\n\t * Preferred placement side relative to the menu trigger.\n\t * @default \"bottom\"\n\t */\n\tside?: RadixMenubarContentProps[\"side\"];\n\t/**\n\t * Distance in pixels between trigger and floating content panel.\n\t * @default 4\n\t */\n\tsideOffset?: RadixMenubarContentProps[\"sideOffset\"];\n\t/**\n\t * Preferred alignment along the side axis.\n\t * @default \"start\"\n\t */\n\talign?: RadixMenubarContentProps[\"align\"];\n\t/**\n\t * Offset in pixels from the start or end alignment position.\n\t * @default 0\n\t */\n\talignOffset?: RadixMenubarContentProps[\"alignOffset\"];\n\t/**\n\t * Whether to reposition content to avoid viewport boundary collisions.\n\t * @default true\n\t */\n\tavoidCollisions?: RadixMenubarContentProps[\"avoidCollisions\"];\n\t/**\n\t * Element or elements bounding boundary collision calculations.\n\t * @default []\n\t */\n\tcollisionBoundary?: RadixMenubarContentProps[\"collisionBoundary\"];\n\t/**\n\t * Virtual padding from collision boundaries in pixels.\n\t * @default 0\n\t */\n\tcollisionPadding?: RadixMenubarContentProps[\"collisionPadding\"];\n\t/**\n\t * Padding in pixels between popper arrow and floating panel edge.\n\t * @default 0\n\t */\n\tarrowPadding?: RadixMenubarContentProps[\"arrowPadding\"];\n\t/**\n\t * Sticky positioning behavior along the align axis when overflowing.\n\t * @default \"partial\"\n\t */\n\tsticky?: RadixMenubarContentProps[\"sticky\"];\n\t/**\n\t * Whether to hide content completely when trigger is fully occluded.\n\t * @default false\n\t */\n\thideWhenDetached?: RadixMenubarContentProps[\"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 * Change the default rendered div element to the child element, merging props and behavior.\n\t * Content forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixMenubarContentProps[\"asChild\"];\n\t/**\n\t * Callback fired when auto-focusing on close. Can be prevented.\n\t */\n\tonCloseAutoFocus?: RadixMenubarContentProps[\"onCloseAutoFocus\"];\n\t/**\n\t * Callback fired when the Escape key is down on the dismissable layer. Can be prevented.\n\t */\n\tonEscapeKeyDown?: RadixMenubarContentProps[\"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?: RadixMenubarContentProps[\"onPointerDownOutside\"];\n\t/**\n\t * Callback fired when focus moves outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonFocusOutside?: RadixMenubarContentProps[\"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?: RadixMenubarContentProps[\"onInteractOutside\"];\n}\n\nexport const MenuBarContent = React.forwardRef<\n\tReact.ElementRef<typeof MenubarPrimitive.Content>,\n\tMenuBarContentProps\n>(({ className, sideOffset = MENU_GAP, ...props }, ref) => {\n\tconst highlightRef = useHoverHighlight(ref);\n\treturn (\n\t\t<MenubarPrimitive.Portal forceMount={props.forceMount}>\n\t\t\t<MenubarPrimitive.Content\n\t\t\t\tref={highlightRef}\n\t\t\t\tsideOffset={sideOffset}\n\t\t\t\tclassName={overlayPanelClass(cn(\"basalt-hover-list min-w-basalt-40\", className))}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t</MenubarPrimitive.Portal>\n\t);\n});\nMenuBarContent.displayName = MenubarPrimitive.Content.displayName;\n\nexport interface MenuBarItemProps\n\textends Omit<RadixMenubarItemProps, \"disabled\" | \"onSelect\" | \"textValue\" | \"asChild\"> {\n\t/**\n\t * Disable the menubar item.\n\t * @default false\n\t */\n\tdisabled?: RadixMenubarItemProps[\"disabled\"];\n\t/**\n\t * Event handler called when the menubar item is selected (via click or keyboard).\n\t */\n\tonSelect?: RadixMenubarItemProps[\"onSelect\"];\n\t/**\n\t * Optional text used for typeahead navigation. By default typeahead uses item text content.\n\t */\n\ttextValue?: RadixMenubarItemProps[\"textValue\"];\n\t/**\n\t * Change the default rendered div element to the child element, merging props and behavior.\n\t * Item forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixMenubarItemProps[\"asChild\"];\n}\n\nexport const MenuBarItem = React.forwardRef<\n\tReact.ElementRef<typeof MenubarPrimitive.Item>,\n\tMenuBarItemProps\n>(({ className, ...props }, ref) => (\n\t<MenubarPrimitive.Item\n\t\tdata-basalt-hover-item=\"\"\n\t\tref={ref}\n\t\tclassName={overlayItemClass(cn(\"relative outline-hidden\", className))}\n\t\t{...props}\n\t/>\n));\nMenuBarItem.displayName = MenubarPrimitive.Item.displayName;\n\nexport interface MenuBarRootProps extends MenuBarProps {}\n\nexport function MenuBarRoot({ className, ...props }: MenuBarRootProps) {\n\treturn (\n\t\t<MenubarPrimitive.Root\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"flex min-h-basalt-control items-center gap-basalt-space-xs rounded-basalt-md border border-basalt-border bg-basalt-popover px-basalt-space-sm py-basalt-space-xs\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":";;;;;;;;;AAiDA,SAAgBE,EAAQ,GAAqB;CAC5C,OAAO,kBAACC,GAAD,EAAa,GAAIC,EAAQ,CAAA;AACjC;AASA,SAAgBC,EAAY,GAAyB;CACpD,OAAO,kBAACJ,EAAiB,MAAlB,EAAuB,GAAIG,EAAQ,CAAA;AAC3C;AAiBA,IAAaE,IAAiBN,EAAM,YAGjC,EAAE,cAAW,GAAGI,KAAS,MAC3B,kBAACH,EAAiB,SAAlB;CACM;CACL,WAAWM,EACVC,GACA,6LACAC,CACD;CACA,GAAIL;AACJ,CAAA,CACD;AACD,EAAe,cAAcH,EAAiB,QAAQ;AAiHtD,IAAaS,IAAiBV,EAAM,YAGjC,EAAE,cAAW,gBAAA,GAAuB,GAAGI,KAAS,MAAQ;CAC1D,IAAMO,IAAeC,EAAkBC,CAAG;CAC1C,OACC,kBAACZ,EAAiB,QAAlB;EAAyB,YAAYG,EAAM;EAC1C,UAAA,kBAACH,EAAiB,SAAlB;GACC,KAAKU;GACO;GACZ,WAAWG,EAAkBP,EAAG,qCAAqCE,CAAS,CAAC;GAC/E,GAAIL;EACJ,CAAA;CACuB,CAAA;AAE3B,CAAC;AACD,EAAe,cAAcH,EAAiB,QAAQ;AAyBtD,IAAac,IAAcf,EAAM,YAG9B,EAAE,cAAW,GAAGI,KAAS,MAC3B,kBAACH,EAAiB,MAAlB;CACC,0BAAuB;CAClB;CACL,WAAWe,EAAiBT,EAAG,2BAA2BE,CAAS,CAAC;CACpE,GAAIL;AACJ,CAAA,CACD;AACD,EAAY,cAAcH,EAAiB,KAAK;AAIhD,SAAgBE,EAAY,EAAE,cAAW,GAAGC,KAA2B;CACtE,OACC,kBAACH,EAAiB,MAAlB;EACC,WAAWM,EACVC,GACA,oKACAC,CACD;EACA,GAAIL;CACJ,CAAA;AAEH"}
|
|
1
|
+
{"version":3,"file":"menu-bar.js","names":["React","MenubarPrimitive","MenuBar","MenuBarRoot","props","MenuBarMenu","MenuBarTrigger","cn","BASALT_UI_CLASS","className","MenuBarContent","highlightRef","useHoverHighlight","ref","overlayPanelClass","MenuBarItem","overlayItemClass"],"sources":["../../src/components/menu-bar.tsx"],"sourcesContent":["import * as MenubarPrimitive from \"@radix-ui/react-menubar\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { useHoverHighlight } from \"../utils/use-hover-highlight\";\nimport { MENU_GAP, overlayItemClass, overlayPanelClass } from \"./overlay\";\n\ntype RadixMenubarProps = React.ComponentProps<typeof MenubarPrimitive.Root>;\ntype RadixMenubarMenuProps = React.ComponentProps<typeof MenubarPrimitive.Menu>;\ntype RadixMenubarTriggerProps = React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Trigger>;\ntype RadixMenubarContentProps = React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Content>;\ntype RadixMenubarItemProps = React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Item>;\n\nexport interface MenuBarProps\n\textends Omit<\n\t\tRadixMenubarProps,\n\t\t\"value\" | \"defaultValue\" | \"onValueChange\" | \"loop\" | \"dir\" | \"asChild\"\n\t> {\n\t/**\n\t * Controlled value of the currently open menu.\n\t */\n\tvalue?: RadixMenubarProps[\"value\"];\n\t/**\n\t * Uncontrolled initial value of the open menu.\n\t * @default \"\"\n\t */\n\tdefaultValue?: RadixMenubarProps[\"defaultValue\"];\n\t/**\n\t * Callback invoked when the open menu value changes.\n\t */\n\tonValueChange?: RadixMenubarProps[\"onValueChange\"];\n\t/**\n\t * Whether keyboard navigation loops around when reaching ends.\n\t * @default true\n\t */\n\tloop?: RadixMenubarProps[\"loop\"];\n\t/**\n\t * Reading direction of the menubar.\n\t * @default \"ltr\"\n\t */\n\tdir?: RadixMenubarProps[\"dir\"];\n\t/**\n\t * Change the default rendered div element to the child element, merging props and behavior.\n\t * MenuBar forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixMenubarProps[\"asChild\"];\n}\n\nexport function MenuBar(props: MenuBarProps) {\n\treturn <MenuBarRoot {...props} />;\n}\n\nexport interface MenuBarMenuProps extends Omit<RadixMenubarMenuProps, \"value\"> {\n\t/**\n\t * Unique identifier value for this menu within the menubar.\n\t */\n\tvalue?: RadixMenubarMenuProps[\"value\"];\n}\n\nexport function MenuBarMenu(props: MenuBarMenuProps) {\n\treturn <MenubarPrimitive.Menu {...props} />;\n}\n\nexport interface MenuBarTriggerProps\n\textends Omit<RadixMenubarTriggerProps, \"disabled\" | \"asChild\"> {\n\t/**\n\t * Disable the menubar trigger button.\n\t * @default false\n\t */\n\tdisabled?: RadixMenubarTriggerProps[\"disabled\"];\n\t/**\n\t * Change the default rendered button element to the child element, merging props and behavior.\n\t * Trigger forwards ref to HTMLButtonElement and inherits native button attributes.\n\t * @default false\n\t */\n\tasChild?: RadixMenubarTriggerProps[\"asChild\"];\n}\n\nexport const MenuBarTrigger = React.forwardRef<\n\tReact.ElementRef<typeof MenubarPrimitive.Trigger>,\n\tMenuBarTriggerProps\n>(({ className, ...props }, ref) => (\n\t<MenubarPrimitive.Trigger\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\tBASALT_UI_CLASS,\n\t\t\t\"basalt-focus basalt-focus-inset inline-flex min-h-basalt-control items-center rounded-basalt-sm px-basalt-space-lg text-basalt-base font-medium hover:bg-basalt-hover data-[state=open]:bg-basalt-selected\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nMenuBarTrigger.displayName = MenubarPrimitive.Trigger.displayName;\n\nexport interface MenuBarContentProps\n\textends Omit<\n\t\tRadixMenubarContentProps,\n\t\t| \"loop\"\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| \"asChild\"\n\t\t| \"onCloseAutoFocus\"\n\t\t| \"onEscapeKeyDown\"\n\t\t| \"onPointerDownOutside\"\n\t\t| \"onFocusOutside\"\n\t\t| \"onInteractOutside\"\n\t> {\n\t/**\n\t * Whether keyboard navigation loops around when reaching the start or end item.\n\t * @default false\n\t */\n\tloop?: RadixMenubarContentProps[\"loop\"];\n\t/**\n\t * Preferred placement side relative to the menu trigger.\n\t * @default \"bottom\"\n\t */\n\tside?: RadixMenubarContentProps[\"side\"];\n\t/**\n\t * Distance in pixels between trigger and floating content panel.\n\t * @default 4\n\t */\n\tsideOffset?: RadixMenubarContentProps[\"sideOffset\"];\n\t/**\n\t * Preferred alignment along the side axis.\n\t * @default \"start\"\n\t */\n\talign?: RadixMenubarContentProps[\"align\"];\n\t/**\n\t * Offset in pixels from the start or end alignment position.\n\t * @default 0\n\t */\n\talignOffset?: RadixMenubarContentProps[\"alignOffset\"];\n\t/**\n\t * Whether to reposition content to avoid viewport boundary collisions.\n\t * @default true\n\t */\n\tavoidCollisions?: RadixMenubarContentProps[\"avoidCollisions\"];\n\t/**\n\t * Element or elements bounding boundary collision calculations.\n\t * @default []\n\t */\n\tcollisionBoundary?: RadixMenubarContentProps[\"collisionBoundary\"];\n\t/**\n\t * Virtual padding from collision boundaries in pixels.\n\t * @default 0\n\t */\n\tcollisionPadding?: RadixMenubarContentProps[\"collisionPadding\"];\n\t/**\n\t * Padding in pixels between popper arrow and floating panel edge.\n\t * @default 0\n\t */\n\tarrowPadding?: RadixMenubarContentProps[\"arrowPadding\"];\n\t/**\n\t * Sticky positioning behavior along the align axis when overflowing.\n\t * @default \"partial\"\n\t */\n\tsticky?: RadixMenubarContentProps[\"sticky\"];\n\t/**\n\t * Whether to hide content completely when trigger is fully occluded.\n\t * @default false\n\t */\n\thideWhenDetached?: RadixMenubarContentProps[\"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 * Change the default rendered div element to the child element, merging props and behavior.\n\t * Content forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixMenubarContentProps[\"asChild\"];\n\t/**\n\t * Callback fired when auto-focusing on close. Can be prevented.\n\t */\n\tonCloseAutoFocus?: RadixMenubarContentProps[\"onCloseAutoFocus\"];\n\t/**\n\t * Callback fired when the Escape key is down on the dismissable layer. Can be prevented.\n\t */\n\tonEscapeKeyDown?: RadixMenubarContentProps[\"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?: RadixMenubarContentProps[\"onPointerDownOutside\"];\n\t/**\n\t * Callback fired when focus moves outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonFocusOutside?: RadixMenubarContentProps[\"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?: RadixMenubarContentProps[\"onInteractOutside\"];\n}\n\nexport const MenuBarContent = React.forwardRef<\n\tReact.ElementRef<typeof MenubarPrimitive.Content>,\n\tMenuBarContentProps\n>(({ className, sideOffset = MENU_GAP, ...props }, ref) => {\n\tconst highlightRef = useHoverHighlight(ref);\n\treturn (\n\t\t<MenubarPrimitive.Portal forceMount={props.forceMount}>\n\t\t\t<MenubarPrimitive.Content\n\t\t\t\tref={highlightRef}\n\t\t\t\tsideOffset={sideOffset}\n\t\t\t\tclassName={overlayPanelClass(cn(\"basalt-hover-list min-w-basalt-40\", className))}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t</MenubarPrimitive.Portal>\n\t);\n});\nMenuBarContent.displayName = MenubarPrimitive.Content.displayName;\n\nexport interface MenuBarItemProps\n\textends Omit<RadixMenubarItemProps, \"disabled\" | \"onSelect\" | \"textValue\" | \"asChild\"> {\n\t/**\n\t * Disable the menubar item.\n\t * @default false\n\t */\n\tdisabled?: RadixMenubarItemProps[\"disabled\"];\n\t/**\n\t * Event handler called when the menubar item is selected (via click or keyboard).\n\t */\n\tonSelect?: RadixMenubarItemProps[\"onSelect\"];\n\t/**\n\t * Optional text used for typeahead navigation. By default typeahead uses item text content.\n\t */\n\ttextValue?: RadixMenubarItemProps[\"textValue\"];\n\t/**\n\t * Change the default rendered div element to the child element, merging props and behavior.\n\t * Item forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixMenubarItemProps[\"asChild\"];\n}\n\nexport const MenuBarItem = React.forwardRef<\n\tReact.ElementRef<typeof MenubarPrimitive.Item>,\n\tMenuBarItemProps\n>(({ className, ...props }, ref) => (\n\t<MenubarPrimitive.Item\n\t\tdata-basalt-hover-item=\"\"\n\t\tref={ref}\n\t\tclassName={overlayItemClass(cn(\"relative\", className))}\n\t\t{...props}\n\t/>\n));\nMenuBarItem.displayName = MenubarPrimitive.Item.displayName;\n\nexport interface MenuBarRootProps extends MenuBarProps {}\n\nexport function MenuBarRoot({ className, ...props }: MenuBarRootProps) {\n\treturn (\n\t\t<MenubarPrimitive.Root\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"flex min-h-basalt-control items-center gap-basalt-space-xs rounded-basalt-md border border-basalt-border bg-basalt-popover px-basalt-space-sm py-basalt-space-xs\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":";;;;;;;;;AAiDA,SAAgBE,EAAQ,GAAqB;CAC5C,OAAO,kBAACC,GAAD,EAAa,GAAIC,EAAQ,CAAA;AACjC;AASA,SAAgBC,EAAY,GAAyB;CACpD,OAAO,kBAACJ,EAAiB,MAAlB,EAAuB,GAAIG,EAAQ,CAAA;AAC3C;AAiBA,IAAaE,IAAiBN,EAAM,YAGjC,EAAE,cAAW,GAAGI,KAAS,MAC3B,kBAACH,EAAiB,SAAlB;CACM;CACL,WAAWM,EACVC,GACA,8MACAC,CACD;CACA,GAAIL;AACJ,CAAA,CACD;AACD,EAAe,cAAcH,EAAiB,QAAQ;AAiHtD,IAAaS,IAAiBV,EAAM,YAGjC,EAAE,cAAW,gBAAA,GAAuB,GAAGI,KAAS,MAAQ;CAC1D,IAAMO,IAAeC,EAAkBC,CAAG;CAC1C,OACC,kBAACZ,EAAiB,QAAlB;EAAyB,YAAYG,EAAM;EAC1C,UAAA,kBAACH,EAAiB,SAAlB;GACC,KAAKU;GACO;GACZ,WAAWG,EAAkBP,EAAG,qCAAqCE,CAAS,CAAC;GAC/E,GAAIL;EACJ,CAAA;CACuB,CAAA;AAE3B,CAAC;AACD,EAAe,cAAcH,EAAiB,QAAQ;AAyBtD,IAAac,IAAcf,EAAM,YAG9B,EAAE,cAAW,GAAGI,KAAS,MAC3B,kBAACH,EAAiB,MAAlB;CACC,0BAAuB;CAClB;CACL,WAAWe,EAAiBT,EAAG,YAAYE,CAAS,CAAC;CACrD,GAAIL;AACJ,CAAA,CACD;AACD,EAAY,cAAcH,EAAiB,KAAK;AAIhD,SAAgBE,EAAY,EAAE,cAAW,GAAGC,KAA2B;CACtE,OACC,kBAACH,EAAiB,MAAlB;EACC,WAAWM,EACVC,GACA,oKACAC,CACD;EACA,GAAIL;CACJ,CAAA;AAEH"}
|
package/dist/components/meter.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { cn as e } from "../utils/cn.js";
|
|
3
3
|
import { jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
4
4
|
import * as r from "@radix-ui/react-progress";
|
|
5
|
-
|
|
5
|
+
// src/components/meter.tsx
|
|
6
6
|
function i({ value: i = 0, label: a, customValue: o, hideValue: s = !1, className: c, "aria-label": l }) {
|
|
7
7
|
let u = Number.isFinite(i) ? Math.min(100, Math.max(0, i)) : null, d = Math.round((u ?? 0) / 100 * 17), f = Math.floor(d / 3), p = f + Math.ceil(d / 3);
|
|
8
8
|
return /* @__PURE__ */ n("div", {
|
|
@@ -33,7 +33,6 @@ function i({ value: i = 0, label: a, customValue: o, hideValue: s = !1, classNam
|
|
|
33
33
|
})]
|
|
34
34
|
});
|
|
35
35
|
}
|
|
36
|
-
//#endregion
|
|
37
36
|
export { i as Meter };
|
|
38
37
|
|
|
39
38
|
//# sourceMappingURL=meter.js.map
|
|
@@ -8,7 +8,7 @@ import { Popover as a, PopoverContent as ee, PopoverTrigger as o } from "./popov
|
|
|
8
8
|
import { useEffect as s, useId as c, useRef as l, useState as u } from "react";
|
|
9
9
|
import { Check as te, ChevronDown as ne, X as re } from "lucide-react";
|
|
10
10
|
import { jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
11
|
-
|
|
11
|
+
// src/components/multi-select.tsx
|
|
12
12
|
function p({ label: p, options: m, value: h, defaultValue: g = [], onValueChange: ie, query: _, defaultQuery: v = "", onQueryChange: ae, open: y, defaultOpen: oe = !1, onOpenChange: se, filterOptions: ce = !0, loading: b = !1, disabled: x = !1, name: S, form: C, placeholder: le = "Select options", searchPlaceholder: ue = "Search options…", emptyLabel: w = "No options found.", loadingLabel: T = "Loading options…", removeLabel: E = "Remove", showChips: D = !0, formatSelectionCount: O, className: de }) {
|
|
13
13
|
let [fe, k] = u(g), [pe, A] = u(v), [j, M] = u(oe), [N, P] = u(null), F = l(null), I = l(null), L = l(null), R = r(L), z = l(null), B = l({
|
|
14
14
|
value: h,
|
|
@@ -75,7 +75,7 @@ function p({ label: p, options: m, value: h, defaultValue: g = [], onValueChange
|
|
|
75
75
|
type: "button",
|
|
76
76
|
disabled: x || t?.disabled,
|
|
77
77
|
"aria-label": `${E} ${n}`,
|
|
78
|
-
className: "rounded-basalt-sm p-basalt-space-sm
|
|
78
|
+
className: "basalt-focus basalt-focus-inset rounded-basalt-sm p-basalt-space-sm disabled:opacity-50",
|
|
79
79
|
onClick: () => Z(H.filter((t) => t !== e)),
|
|
80
80
|
children: /* @__PURE__ */ d(re, {
|
|
81
81
|
className: "size-basalt-icon-sm",
|
|
@@ -216,7 +216,6 @@ function p({ label: p, options: m, value: h, defaultValue: g = [], onValueChange
|
|
|
216
216
|
]
|
|
217
217
|
});
|
|
218
218
|
}
|
|
219
|
-
//#endregion
|
|
220
219
|
export { p as MultiSelect };
|
|
221
220
|
|
|
222
221
|
//# sourceMappingURL=multi-select.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-select.js","names":["MultiSelect","localValue","setLocalValue","useState","defaultValue","localQuery","setLocalQuery","defaultQuery","localOpen","setLocalOpen","defaultOpen","active","setActive","input","useRef","trigger","list","highlightRef","useHoverHighlight","pointer","resetConfig","useEffect","owner","timers","reset","timer","event","config","form","id","useId","selected","value","search","query","expanded","open","disabled","visible","options","filterOptions","option","enabled","activeValue","activeIndex","countText","formatSelectionCount","changeOpen","next","onOpenChange","changeValue","onValueChange","toggle","item","removeLast","cn","BASALT_UI_CLASS","className","showChips","label","text","removeLabel","X","name","Popover","PopoverTrigger","Button","placeholder","ChevronDown","PopoverContent","Input","loading","searchPlaceholder","onQueryChange","index","previous","Check","loadingLabel","emptyLabel"],"sources":["../../src/components/multi-select.tsx"],"sourcesContent":["import { Check, ChevronDown, X } from \"lucide-react\";\nimport { type ReactNode, useEffect, useId, useRef, useState } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { useHoverHighlight } from \"../utils/use-hover-highlight\";\nimport { Button } from \"./button\";\nimport { Input } from \"./input\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\n\nexport interface MultiSelectOption {\n\t/** Stable identifier, independent of the display label. */\n\tvalue: string;\n\t/** Searchable and accessible display name. */\n\tlabel: string;\n\t/** Optional secondary searchable text. */\n\tdescription?: string;\n\t/** Caller-provided icon or avatar. */\n\tleading?: ReactNode;\n\t/** Prevent adding or removing this option. */\n\tdisabled?: boolean;\n}\n\nexport interface MultiSelectProps {\n\t/** Accessible field and popup name. */\n\tlabel: string;\n\t/** Available options; retain selected options to preserve their display labels. */\n\toptions: readonly MultiSelectOption[];\n\t/** Controlled selected identifiers. */\n\tvalue?: readonly string[];\n\t/** Initial uncontrolled selection. @default [] */\n\tdefaultValue?: readonly string[];\n\t/** Selection requests; controlled values change only when accepted by the caller. */\n\tonValueChange?: (value: string[]) => void;\n\t/** Controlled search text; asynchronous requests belong to the caller. */\n\tquery?: string;\n\t/** Initial uncontrolled search text. @default \"\" */\n\tdefaultQuery?: string;\n\t/** Search text requests. */\n\tonQueryChange?: (query: string) => void;\n\t/** Controlled popup visibility. */\n\topen?: boolean;\n\t/** Initial uncontrolled popup visibility. @default false */\n\tdefaultOpen?: boolean;\n\t/** Popup visibility requests. */\n\tonOpenChange?: (open: boolean) => void;\n\t/** Use local label/description filtering; disable for server-filtered options. @default true */\n\tfilterOptions?: boolean;\n\t/** Loading content replaces the option list. @default false */\n\tloading?: boolean;\n\t/** Disables the trigger, chips, and native form entries. @default false */\n\tdisabled?: boolean;\n\t/** Repeated native form entry name, one entry per selected identifier. */\n\tname?: string;\n\t/** Optional external native form owner. Uncontrolled state respects uncancelled form resets. */\n\tform?: string;\n\t/** Empty selection prompt. @default \"Select options\" */\n\tplaceholder?: string;\n\t/** Search input prompt. @default \"Search options…\" */\n\tsearchPlaceholder?: string;\n\t/** Empty search result text. @default \"No options found.\" */\n\temptyLabel?: string;\n\t/** Loading announcement. @default \"Loading options…\" */\n\tloadingLabel?: string;\n\t/** Chip removal label prefix. @default \"Remove\" */\n\tremoveLabel?: string;\n\t/** Show removable selection chips; disable when a FilterBar renders its own chips. @default true */\n\tshowChips?: boolean;\n\t/** Selection count formatter, including localization. */\n\tformatSelectionCount?: (count: number) => string;\n\t/** Additional root classes. */\n\tclassName?: string;\n}\n\nexport function MultiSelect({\n\tlabel,\n\toptions,\n\tvalue,\n\tdefaultValue = [],\n\tonValueChange,\n\tquery,\n\tdefaultQuery = \"\",\n\tonQueryChange,\n\topen,\n\tdefaultOpen = false,\n\tonOpenChange,\n\tfilterOptions = true,\n\tloading = false,\n\tdisabled = false,\n\tname,\n\tform,\n\tplaceholder = \"Select options\",\n\tsearchPlaceholder = \"Search options…\",\n\temptyLabel = \"No options found.\",\n\tloadingLabel = \"Loading options…\",\n\tremoveLabel = \"Remove\",\n\tshowChips = true,\n\tformatSelectionCount,\n\tclassName,\n}: MultiSelectProps) {\n\tconst [localValue, setLocalValue] = useState(defaultValue);\n\tconst [localQuery, setLocalQuery] = useState(defaultQuery);\n\tconst [localOpen, setLocalOpen] = useState(defaultOpen);\n\tconst [active, setActive] = useState<string | null>(null);\n\tconst input = useRef<HTMLInputElement>(null);\n\tconst trigger = useRef<HTMLButtonElement>(null);\n\tconst list = useRef<HTMLDivElement>(null);\n\tconst highlightRef = useHoverHighlight(list);\n\tconst pointer = useRef<{ x: number; y: number } | null>(null);\n\tconst resetConfig = useRef({ value, defaultValue, query, defaultQuery, open });\n\tuseEffect(() => {\n\t\tresetConfig.current = { value, defaultValue, query, defaultQuery, open };\n\t});\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: form changes the native owner of the same trigger and requires rebinding its reset listener.\n\tuseEffect(() => {\n\t\tconst owner = trigger.current?.form;\n\t\tif (!owner) return;\n\t\tconst timers = new Set<ReturnType<typeof setTimeout>>();\n\t\tfunction reset(event: Event) {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\ttimers.delete(timer);\n\t\t\t\tif (event.defaultPrevented) return;\n\t\t\t\tconst config = resetConfig.current;\n\t\t\t\tif (config.value === undefined) setLocalValue(config.defaultValue);\n\t\t\t\tif (config.query === undefined) setLocalQuery(config.defaultQuery);\n\t\t\t\tif (config.open === undefined) setLocalOpen(false);\n\t\t\t\tsetActive(null);\n\t\t\t}, 0);\n\t\t\ttimers.add(timer);\n\t\t}\n\t\towner.addEventListener(\"reset\", reset);\n\t\treturn () => {\n\t\t\tfor (const timer of timers) clearTimeout(timer);\n\t\t\towner.removeEventListener(\"reset\", reset);\n\t\t};\n\t}, [form]);\n\tconst id = useId();\n\tconst selected = value ?? localValue;\n\tconst search = query ?? localQuery;\n\tconst expanded = (open ?? localOpen) && !disabled;\n\tconst visible = options.filter(\n\t\t(option) =>\n\t\t\t!filterOptions ||\n\t\t\t`${option.label} ${option.description ?? \"\"}`\n\t\t\t\t.toLocaleLowerCase()\n\t\t\t\t.includes(search.trim().toLocaleLowerCase()),\n\t);\n\tconst enabled = visible.filter((option) => !option.disabled);\n\tconst activeValue = enabled.some((option) => option.value === active)\n\t\t? active\n\t\t: enabled[0]?.value;\n\tconst activeIndex = visible.findIndex((option) => option.value === activeValue);\n\tconst countText = formatSelectionCount\n\t\t? formatSelectionCount(selected.length)\n\t\t: `${selected.length} selected`;\n\n\tfunction changeOpen(next: boolean) {\n\t\tif (disabled) return;\n\t\tif (open === undefined) setLocalOpen(next);\n\t\tonOpenChange?.(next);\n\t}\n\tfunction changeValue(next: string[]) {\n\t\tif (disabled) return;\n\t\tif (value === undefined) setLocalValue(next);\n\t\tonValueChange?.(next);\n\t}\n\tfunction toggle(option: MultiSelectOption) {\n\t\tif (option.disabled) return;\n\t\tchangeValue(\n\t\t\tselected.includes(option.value)\n\t\t\t\t? selected.filter((item) => item !== option.value)\n\t\t\t\t: [...selected, option.value],\n\t\t);\n\t}\n\tfunction removeLast() {\n\t\tif (search) return;\n\t\tconst item = [...selected]\n\t\t\t.reverse()\n\t\t\t.find((value) => !options.find((option) => option.value === value)?.disabled);\n\t\tif (item !== undefined) changeValue(selected.filter((value) => value !== item));\n\t}\n\n\treturn (\n\t\t<div className={cn(BASALT_UI_CLASS, \"min-w-0 space-y-basalt-space-lg\", className)}>\n\t\t\t{showChips && selected.length > 0 && (\n\t\t\t\t<div\n\t\t\t\t\trole=\"group\"\n\t\t\t\t\tclassName=\"flex flex-wrap gap-basalt-space-md\"\n\t\t\t\t\taria-label={`${label}: ${countText}`}\n\t\t\t\t>\n\t\t\t\t\t{selected.map((item) => {\n\t\t\t\t\t\tconst option = options.find((option) => option.value === item);\n\t\t\t\t\t\tconst text = option?.label ?? item;\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tkey={item}\n\t\t\t\t\t\t\t\tclassName=\"inline-flex max-w-full items-center gap-basalt-space-sm rounded-basalt-md border border-basalt-border bg-basalt-selected py-basalt-space-xs pl-basalt-space-lg text-basalt-sm\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span className=\"min-w-0 break-words\">{text}</span>\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\tdisabled={disabled || option?.disabled}\n\t\t\t\t\t\t\t\t\taria-label={`${removeLabel} ${text}`}\n\t\t\t\t\t\t\t\t\tclassName=\"rounded-basalt-sm p-basalt-space-sm focus-visible:outline-2 focus-visible:outline-basalt-ring disabled:opacity-50\"\n\t\t\t\t\t\t\t\t\tonClick={() => changeValue(selected.filter((value) => value !== item))}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<X className=\"size-basalt-icon-sm\" aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t{!disabled &&\n\t\t\t\tname &&\n\t\t\t\tselected.map((item) => (\n\t\t\t\t\t<input key={item} type=\"hidden\" name={name} form={form} value={item} />\n\t\t\t\t))}\n\t\t\t<Popover open={expanded} onOpenChange={changeOpen}>\n\t\t\t\t<PopoverTrigger asChild>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tref={trigger}\n\t\t\t\t\t\tform={form}\n\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\taria-label={label}\n\t\t\t\t\t\taria-describedby={`${id}-count`}\n\t\t\t\t\t\tclassName=\"w-full justify-between\"\n\t\t\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\t\t\tif (event.nativeEvent.isComposing) return;\n\t\t\t\t\t\t\tif (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tchangeOpen(true);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.key === \"Backspace\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tremoveLast();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<span className=\"truncate\">{selected.length ? countText : placeholder}</span>\n\t\t\t\t\t\t<ChevronDown aria-hidden=\"true\" />\n\t\t\t\t\t</Button>\n\t\t\t\t</PopoverTrigger>\n\t\t\t\t<PopoverContent\n\t\t\t\t\talign=\"start\"\n\t\t\t\t\tclassName=\"w-basalt-72 max-w-[calc(100vw-2rem)] p-basalt-space-lg\"\n\t\t\t\t\taria-label={label}\n\t\t\t\t\tonOpenAutoFocus={(event) => {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tinput.current?.focus();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Input\n\t\t\t\t\t\tref={input}\n\t\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\t\taria-label={`${label}: search`}\n\t\t\t\t\t\taria-expanded={expanded}\n\t\t\t\t\t\taria-autocomplete=\"list\"\n\t\t\t\t\t\taria-controls={`${id}-list`}\n\t\t\t\t\t\taria-activedescendant={\n\t\t\t\t\t\t\t!loading && activeIndex >= 0 ? `${id}-option-${activeIndex}` : undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t\tplaceholder={searchPlaceholder}\n\t\t\t\t\t\tvalue={search}\n\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\tif (query === undefined) setLocalQuery(event.target.value);\n\t\t\t\t\t\t\tonQueryChange?.(event.target.value);\n\t\t\t\t\t\t\tsetActive(null);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\t\t\tif (event.nativeEvent.isComposing) return;\n\t\t\t\t\t\t\tif (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tif (!loading && enabled.length) {\n\t\t\t\t\t\t\t\t\tconst index = enabled.findIndex((option) => option.value === activeValue);\n\t\t\t\t\t\t\t\t\tconst next =\n\t\t\t\t\t\t\t\t\t\tenabled[\n\t\t\t\t\t\t\t\t\t\t\t(index + (event.key === \"ArrowDown\" ? 1 : -1) + enabled.length) %\n\t\t\t\t\t\t\t\t\t\t\t\tenabled.length\n\t\t\t\t\t\t\t\t\t\t];\n\t\t\t\t\t\t\t\t\tsetActive(next.value);\n\t\t\t\t\t\t\t\t\tlist.current\n\t\t\t\t\t\t\t\t\t\t?.querySelector<HTMLElement>(`[data-option-index=\"${visible.indexOf(next)}\"]`)\n\t\t\t\t\t\t\t\t\t\t?.scrollIntoView({ block: \"nearest\" });\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (event.key === \"Enter\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tconst option = enabled.find((option) => option.value === activeValue);\n\t\t\t\t\t\t\t\tif (!loading && option) toggle(option);\n\t\t\t\t\t\t\t} else if (event.key === \"Backspace\" && !search) {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tremoveLast();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t\t<div\n\t\t\t\t\t\tref={highlightRef}\n\t\t\t\t\t\tid={`${id}-list`}\n\t\t\t\t\t\trole=\"listbox\"\n\t\t\t\t\t\taria-label={label}\n\t\t\t\t\t\taria-multiselectable=\"true\"\n\t\t\t\t\t\taria-busy={loading}\n\t\t\t\t\t\tclassName=\"basalt-hover-list mt-basalt-space-lg max-h-basalt-60 overflow-y-auto\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{!loading &&\n\t\t\t\t\t\t\tvisible.map((option, index) => (\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\trole=\"option\"\n\t\t\t\t\t\t\t\t\tdata-basalt-hover-item=\"\"\n\t\t\t\t\t\t\t\t\tdata-hover-active={activeValue === option.value}\n\t\t\t\t\t\t\t\t\tid={`${id}-option-${index}`}\n\t\t\t\t\t\t\t\t\tdata-option-index={index}\n\t\t\t\t\t\t\t\t\tkey={option.value}\n\t\t\t\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\t\t\t\taria-selected={selected.includes(option.value)}\n\t\t\t\t\t\t\t\t\tdata-hover-selected={selected.includes(option.value)}\n\t\t\t\t\t\t\t\t\taria-disabled={option.disabled || undefined}\n\t\t\t\t\t\t\t\t\tdisabled={option.disabled}\n\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\"flex w-full items-center gap-basalt-space-lg rounded-basalt-md px-basalt-space-lg py-basalt-space-lg text-left text-basalt-base disabled:opacity-40\",\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\tonPointerMove={(event) => {\n\t\t\t\t\t\t\t\t\t\tconst previous = pointer.current;\n\t\t\t\t\t\t\t\t\t\tif (previous?.x === event.clientX && previous.y === event.clientY) return;\n\t\t\t\t\t\t\t\t\t\tpointer.current = { x: event.clientX, y: event.clientY };\n\t\t\t\t\t\t\t\t\t\tif (!option.disabled) setActive(option.value);\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\tonMouseDown={(event) => event.preventDefault()}\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\ttoggle(option);\n\t\t\t\t\t\t\t\t\t\tinput.current?.focus();\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{option.leading}\n\t\t\t\t\t\t\t\t\t<span className=\"min-w-0 flex-1\">\n\t\t\t\t\t\t\t\t\t\t<span className=\"block break-words\">{option.label}</span>\n\t\t\t\t\t\t\t\t\t\t{option.description && (\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"block text-basalt-sm text-basalt-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t{option.description}\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t{selected.includes(option.value) && (\n\t\t\t\t\t\t\t\t\t\t<Check className=\"size-basalt-icon-lg shrink-0\" aria-hidden=\"true\" />\n\t\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))}\n\t\t\t\t\t</div>\n\t\t\t\t\t{(loading || visible.length === 0) && (\n\t\t\t\t\t\t<p\n\t\t\t\t\t\t\trole=\"status\"\n\t\t\t\t\t\t\tclassName=\"px-basalt-space-lg py-basalt-space-lg text-basalt-base text-basalt-muted-foreground\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{loading ? loadingLabel : emptyLabel}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t)}\n\t\t\t\t</PopoverContent>\n\t\t\t</Popover>\n\t\t\t<span id={`${id}-count`} className=\"sr-only\" aria-live=\"polite\">\n\t\t\t\t{countText}\n\t\t\t</span>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"multi-select.js","names":["MultiSelect","localValue","setLocalValue","useState","defaultValue","localQuery","setLocalQuery","defaultQuery","localOpen","setLocalOpen","defaultOpen","active","setActive","input","useRef","trigger","list","highlightRef","useHoverHighlight","pointer","resetConfig","useEffect","owner","timers","reset","timer","event","config","form","id","useId","selected","value","search","query","expanded","open","disabled","visible","options","filterOptions","option","enabled","activeValue","activeIndex","countText","formatSelectionCount","changeOpen","next","onOpenChange","changeValue","onValueChange","toggle","item","removeLast","cn","BASALT_UI_CLASS","className","showChips","label","text","removeLabel","X","name","Popover","PopoverTrigger","Button","placeholder","ChevronDown","PopoverContent","Input","loading","searchPlaceholder","onQueryChange","index","previous","Check","loadingLabel","emptyLabel"],"sources":["../../src/components/multi-select.tsx"],"sourcesContent":["import { Check, ChevronDown, X } from \"lucide-react\";\nimport { type ReactNode, useEffect, useId, useRef, useState } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { useHoverHighlight } from \"../utils/use-hover-highlight\";\nimport { Button } from \"./button\";\nimport { Input } from \"./input\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\n\nexport interface MultiSelectOption {\n\t/** Stable identifier, independent of the display label. */\n\tvalue: string;\n\t/** Searchable and accessible display name. */\n\tlabel: string;\n\t/** Optional secondary searchable text. */\n\tdescription?: string;\n\t/** Caller-provided icon or avatar. */\n\tleading?: ReactNode;\n\t/** Prevent adding or removing this option. */\n\tdisabled?: boolean;\n}\n\nexport interface MultiSelectProps {\n\t/** Accessible field and popup name. */\n\tlabel: string;\n\t/** Available options; retain selected options to preserve their display labels. */\n\toptions: readonly MultiSelectOption[];\n\t/** Controlled selected identifiers. */\n\tvalue?: readonly string[];\n\t/** Initial uncontrolled selection. @default [] */\n\tdefaultValue?: readonly string[];\n\t/** Selection requests; controlled values change only when accepted by the caller. */\n\tonValueChange?: (value: string[]) => void;\n\t/** Controlled search text; asynchronous requests belong to the caller. */\n\tquery?: string;\n\t/** Initial uncontrolled search text. @default \"\" */\n\tdefaultQuery?: string;\n\t/** Search text requests. */\n\tonQueryChange?: (query: string) => void;\n\t/** Controlled popup visibility. */\n\topen?: boolean;\n\t/** Initial uncontrolled popup visibility. @default false */\n\tdefaultOpen?: boolean;\n\t/** Popup visibility requests. */\n\tonOpenChange?: (open: boolean) => void;\n\t/** Use local label/description filtering; disable for server-filtered options. @default true */\n\tfilterOptions?: boolean;\n\t/** Loading content replaces the option list. @default false */\n\tloading?: boolean;\n\t/** Disables the trigger, chips, and native form entries. @default false */\n\tdisabled?: boolean;\n\t/** Repeated native form entry name, one entry per selected identifier. */\n\tname?: string;\n\t/** Optional external native form owner. Uncontrolled state respects uncancelled form resets. */\n\tform?: string;\n\t/** Empty selection prompt. @default \"Select options\" */\n\tplaceholder?: string;\n\t/** Search input prompt. @default \"Search options…\" */\n\tsearchPlaceholder?: string;\n\t/** Empty search result text. @default \"No options found.\" */\n\temptyLabel?: string;\n\t/** Loading announcement. @default \"Loading options…\" */\n\tloadingLabel?: string;\n\t/** Chip removal label prefix. @default \"Remove\" */\n\tremoveLabel?: string;\n\t/** Show removable selection chips; disable when a FilterBar renders its own chips. @default true */\n\tshowChips?: boolean;\n\t/** Selection count formatter, including localization. */\n\tformatSelectionCount?: (count: number) => string;\n\t/** Additional root classes. */\n\tclassName?: string;\n}\n\nexport function MultiSelect({\n\tlabel,\n\toptions,\n\tvalue,\n\tdefaultValue = [],\n\tonValueChange,\n\tquery,\n\tdefaultQuery = \"\",\n\tonQueryChange,\n\topen,\n\tdefaultOpen = false,\n\tonOpenChange,\n\tfilterOptions = true,\n\tloading = false,\n\tdisabled = false,\n\tname,\n\tform,\n\tplaceholder = \"Select options\",\n\tsearchPlaceholder = \"Search options…\",\n\temptyLabel = \"No options found.\",\n\tloadingLabel = \"Loading options…\",\n\tremoveLabel = \"Remove\",\n\tshowChips = true,\n\tformatSelectionCount,\n\tclassName,\n}: MultiSelectProps) {\n\tconst [localValue, setLocalValue] = useState(defaultValue);\n\tconst [localQuery, setLocalQuery] = useState(defaultQuery);\n\tconst [localOpen, setLocalOpen] = useState(defaultOpen);\n\tconst [active, setActive] = useState<string | null>(null);\n\tconst input = useRef<HTMLInputElement>(null);\n\tconst trigger = useRef<HTMLButtonElement>(null);\n\tconst list = useRef<HTMLDivElement>(null);\n\tconst highlightRef = useHoverHighlight(list);\n\tconst pointer = useRef<{ x: number; y: number } | null>(null);\n\tconst resetConfig = useRef({ value, defaultValue, query, defaultQuery, open });\n\tuseEffect(() => {\n\t\tresetConfig.current = { value, defaultValue, query, defaultQuery, open };\n\t});\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: form changes the native owner of the same trigger and requires rebinding its reset listener.\n\tuseEffect(() => {\n\t\tconst owner = trigger.current?.form;\n\t\tif (!owner) return;\n\t\tconst timers = new Set<ReturnType<typeof setTimeout>>();\n\t\tfunction reset(event: Event) {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\ttimers.delete(timer);\n\t\t\t\tif (event.defaultPrevented) return;\n\t\t\t\tconst config = resetConfig.current;\n\t\t\t\tif (config.value === undefined) setLocalValue(config.defaultValue);\n\t\t\t\tif (config.query === undefined) setLocalQuery(config.defaultQuery);\n\t\t\t\tif (config.open === undefined) setLocalOpen(false);\n\t\t\t\tsetActive(null);\n\t\t\t}, 0);\n\t\t\ttimers.add(timer);\n\t\t}\n\t\towner.addEventListener(\"reset\", reset);\n\t\treturn () => {\n\t\t\tfor (const timer of timers) clearTimeout(timer);\n\t\t\towner.removeEventListener(\"reset\", reset);\n\t\t};\n\t}, [form]);\n\tconst id = useId();\n\tconst selected = value ?? localValue;\n\tconst search = query ?? localQuery;\n\tconst expanded = (open ?? localOpen) && !disabled;\n\tconst visible = options.filter(\n\t\t(option) =>\n\t\t\t!filterOptions ||\n\t\t\t`${option.label} ${option.description ?? \"\"}`\n\t\t\t\t.toLocaleLowerCase()\n\t\t\t\t.includes(search.trim().toLocaleLowerCase()),\n\t);\n\tconst enabled = visible.filter((option) => !option.disabled);\n\tconst activeValue = enabled.some((option) => option.value === active)\n\t\t? active\n\t\t: enabled[0]?.value;\n\tconst activeIndex = visible.findIndex((option) => option.value === activeValue);\n\tconst countText = formatSelectionCount\n\t\t? formatSelectionCount(selected.length)\n\t\t: `${selected.length} selected`;\n\n\tfunction changeOpen(next: boolean) {\n\t\tif (disabled) return;\n\t\tif (open === undefined) setLocalOpen(next);\n\t\tonOpenChange?.(next);\n\t}\n\tfunction changeValue(next: string[]) {\n\t\tif (disabled) return;\n\t\tif (value === undefined) setLocalValue(next);\n\t\tonValueChange?.(next);\n\t}\n\tfunction toggle(option: MultiSelectOption) {\n\t\tif (option.disabled) return;\n\t\tchangeValue(\n\t\t\tselected.includes(option.value)\n\t\t\t\t? selected.filter((item) => item !== option.value)\n\t\t\t\t: [...selected, option.value],\n\t\t);\n\t}\n\tfunction removeLast() {\n\t\tif (search) return;\n\t\tconst item = [...selected]\n\t\t\t.reverse()\n\t\t\t.find((value) => !options.find((option) => option.value === value)?.disabled);\n\t\tif (item !== undefined) changeValue(selected.filter((value) => value !== item));\n\t}\n\n\treturn (\n\t\t<div className={cn(BASALT_UI_CLASS, \"min-w-0 space-y-basalt-space-lg\", className)}>\n\t\t\t{showChips && selected.length > 0 && (\n\t\t\t\t<div\n\t\t\t\t\trole=\"group\"\n\t\t\t\t\tclassName=\"flex flex-wrap gap-basalt-space-md\"\n\t\t\t\t\taria-label={`${label}: ${countText}`}\n\t\t\t\t>\n\t\t\t\t\t{selected.map((item) => {\n\t\t\t\t\t\tconst option = options.find((option) => option.value === item);\n\t\t\t\t\t\tconst text = option?.label ?? item;\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tkey={item}\n\t\t\t\t\t\t\t\tclassName=\"inline-flex max-w-full items-center gap-basalt-space-sm rounded-basalt-md border border-basalt-border bg-basalt-selected py-basalt-space-xs pl-basalt-space-lg text-basalt-sm\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span className=\"min-w-0 break-words\">{text}</span>\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\tdisabled={disabled || option?.disabled}\n\t\t\t\t\t\t\t\t\taria-label={`${removeLabel} ${text}`}\n\t\t\t\t\t\t\t\t\tclassName=\"basalt-focus basalt-focus-inset rounded-basalt-sm p-basalt-space-sm disabled:opacity-50\"\n\t\t\t\t\t\t\t\t\tonClick={() => changeValue(selected.filter((value) => value !== item))}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<X className=\"size-basalt-icon-sm\" aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t{!disabled &&\n\t\t\t\tname &&\n\t\t\t\tselected.map((item) => (\n\t\t\t\t\t<input key={item} type=\"hidden\" name={name} form={form} value={item} />\n\t\t\t\t))}\n\t\t\t<Popover open={expanded} onOpenChange={changeOpen}>\n\t\t\t\t<PopoverTrigger asChild>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tref={trigger}\n\t\t\t\t\t\tform={form}\n\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\taria-label={label}\n\t\t\t\t\t\taria-describedby={`${id}-count`}\n\t\t\t\t\t\tclassName=\"w-full justify-between\"\n\t\t\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\t\t\tif (event.nativeEvent.isComposing) return;\n\t\t\t\t\t\t\tif (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tchangeOpen(true);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.key === \"Backspace\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tremoveLast();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<span className=\"truncate\">{selected.length ? countText : placeholder}</span>\n\t\t\t\t\t\t<ChevronDown aria-hidden=\"true\" />\n\t\t\t\t\t</Button>\n\t\t\t\t</PopoverTrigger>\n\t\t\t\t<PopoverContent\n\t\t\t\t\talign=\"start\"\n\t\t\t\t\tclassName=\"w-basalt-72 max-w-[calc(100vw-2rem)] p-basalt-space-lg\"\n\t\t\t\t\taria-label={label}\n\t\t\t\t\tonOpenAutoFocus={(event) => {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tinput.current?.focus();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Input\n\t\t\t\t\t\tref={input}\n\t\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\t\taria-label={`${label}: search`}\n\t\t\t\t\t\taria-expanded={expanded}\n\t\t\t\t\t\taria-autocomplete=\"list\"\n\t\t\t\t\t\taria-controls={`${id}-list`}\n\t\t\t\t\t\taria-activedescendant={\n\t\t\t\t\t\t\t!loading && activeIndex >= 0 ? `${id}-option-${activeIndex}` : undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t\tplaceholder={searchPlaceholder}\n\t\t\t\t\t\tvalue={search}\n\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\tif (query === undefined) setLocalQuery(event.target.value);\n\t\t\t\t\t\t\tonQueryChange?.(event.target.value);\n\t\t\t\t\t\t\tsetActive(null);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\t\t\tif (event.nativeEvent.isComposing) return;\n\t\t\t\t\t\t\tif (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tif (!loading && enabled.length) {\n\t\t\t\t\t\t\t\t\tconst index = enabled.findIndex((option) => option.value === activeValue);\n\t\t\t\t\t\t\t\t\tconst next =\n\t\t\t\t\t\t\t\t\t\tenabled[\n\t\t\t\t\t\t\t\t\t\t\t(index + (event.key === \"ArrowDown\" ? 1 : -1) + enabled.length) %\n\t\t\t\t\t\t\t\t\t\t\t\tenabled.length\n\t\t\t\t\t\t\t\t\t\t];\n\t\t\t\t\t\t\t\t\tsetActive(next.value);\n\t\t\t\t\t\t\t\t\tlist.current\n\t\t\t\t\t\t\t\t\t\t?.querySelector<HTMLElement>(`[data-option-index=\"${visible.indexOf(next)}\"]`)\n\t\t\t\t\t\t\t\t\t\t?.scrollIntoView({ block: \"nearest\" });\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (event.key === \"Enter\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tconst option = enabled.find((option) => option.value === activeValue);\n\t\t\t\t\t\t\t\tif (!loading && option) toggle(option);\n\t\t\t\t\t\t\t} else if (event.key === \"Backspace\" && !search) {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tremoveLast();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t\t<div\n\t\t\t\t\t\tref={highlightRef}\n\t\t\t\t\t\tid={`${id}-list`}\n\t\t\t\t\t\trole=\"listbox\"\n\t\t\t\t\t\taria-label={label}\n\t\t\t\t\t\taria-multiselectable=\"true\"\n\t\t\t\t\t\taria-busy={loading}\n\t\t\t\t\t\tclassName=\"basalt-hover-list mt-basalt-space-lg max-h-basalt-60 overflow-y-auto\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{!loading &&\n\t\t\t\t\t\t\tvisible.map((option, index) => (\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\trole=\"option\"\n\t\t\t\t\t\t\t\t\tdata-basalt-hover-item=\"\"\n\t\t\t\t\t\t\t\t\tdata-hover-active={activeValue === option.value}\n\t\t\t\t\t\t\t\t\tid={`${id}-option-${index}`}\n\t\t\t\t\t\t\t\t\tdata-option-index={index}\n\t\t\t\t\t\t\t\t\tkey={option.value}\n\t\t\t\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\t\t\t\taria-selected={selected.includes(option.value)}\n\t\t\t\t\t\t\t\t\tdata-hover-selected={selected.includes(option.value)}\n\t\t\t\t\t\t\t\t\taria-disabled={option.disabled || undefined}\n\t\t\t\t\t\t\t\t\tdisabled={option.disabled}\n\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\"flex w-full items-center gap-basalt-space-lg rounded-basalt-md px-basalt-space-lg py-basalt-space-lg text-left text-basalt-base disabled:opacity-40\",\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\tonPointerMove={(event) => {\n\t\t\t\t\t\t\t\t\t\tconst previous = pointer.current;\n\t\t\t\t\t\t\t\t\t\tif (previous?.x === event.clientX && previous.y === event.clientY) return;\n\t\t\t\t\t\t\t\t\t\tpointer.current = { x: event.clientX, y: event.clientY };\n\t\t\t\t\t\t\t\t\t\tif (!option.disabled) setActive(option.value);\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\tonMouseDown={(event) => event.preventDefault()}\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\ttoggle(option);\n\t\t\t\t\t\t\t\t\t\tinput.current?.focus();\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{option.leading}\n\t\t\t\t\t\t\t\t\t<span className=\"min-w-0 flex-1\">\n\t\t\t\t\t\t\t\t\t\t<span className=\"block break-words\">{option.label}</span>\n\t\t\t\t\t\t\t\t\t\t{option.description && (\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"block text-basalt-sm text-basalt-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t{option.description}\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t{selected.includes(option.value) && (\n\t\t\t\t\t\t\t\t\t\t<Check className=\"size-basalt-icon-lg shrink-0\" aria-hidden=\"true\" />\n\t\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))}\n\t\t\t\t\t</div>\n\t\t\t\t\t{(loading || visible.length === 0) && (\n\t\t\t\t\t\t<p\n\t\t\t\t\t\t\trole=\"status\"\n\t\t\t\t\t\t\tclassName=\"px-basalt-space-lg py-basalt-space-lg text-basalt-base text-basalt-muted-foreground\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{loading ? loadingLabel : emptyLabel}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t)}\n\t\t\t\t</PopoverContent>\n\t\t\t</Popover>\n\t\t\t<span id={`${id}-count`} className=\"sr-only\" aria-live=\"polite\">\n\t\t\t\t{countText}\n\t\t\t</span>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ 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 } from "react/jsx-runtime";
|
|
6
6
|
import * as a from "@radix-ui/react-navigation-menu";
|
|
7
|
-
|
|
7
|
+
// src/components/navigation-menu.tsx
|
|
8
8
|
var o = a.Root;
|
|
9
9
|
function s({ className: n, ref: o, ...s }) {
|
|
10
10
|
let c = t(o);
|
|
@@ -24,7 +24,6 @@ function l({ className: t, active: r, ...o }) {
|
|
|
24
24
|
...o
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
|
-
//#endregion
|
|
28
27
|
export { o as NavigationMenu, c as NavigationMenuItem, l as NavigationMenuLink, s as NavigationMenuList };
|
|
29
28
|
|
|
30
29
|
//# sourceMappingURL=navigation-menu.js.map
|
|
@@ -6,11 +6,8 @@ export declare const MENU_GAP = 8;
|
|
|
6
6
|
export declare const OVERLAY_LAYER = "z-50";
|
|
7
7
|
/** Kill CSS animation and transition when the user prefers reduced motion. */
|
|
8
8
|
export declare const OVERLAY_MOTION = "motion-reduce:animate-none motion-reduce:transition-none";
|
|
9
|
-
|
|
10
|
-
export declare const FOCUS_BORDER = "
|
|
11
|
-
|
|
12
|
-
export declare const FOCUS_INSET = "outline-hidden focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-basalt-ring";
|
|
13
|
-
/** Offset ring stays visible on primary fills (ring token equals primary). */
|
|
14
|
-
export declare const FOCUS_RING = "outline-hidden focus-visible:ring-2 focus-visible:ring-basalt-ring focus-visible:ring-offset-2 focus-visible:ring-offset-basalt-background";
|
|
9
|
+
export declare const FOCUS_RING = "basalt-focus";
|
|
10
|
+
export declare const FOCUS_BORDER = "basalt-focus";
|
|
11
|
+
export declare const FOCUS_INSET = "basalt-focus basalt-focus-inset";
|
|
15
12
|
export declare function overlayPanelClass(className?: string): string;
|
|
16
13
|
export declare function overlayItemClass(className?: string): string;
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn as e } from "../utils/cn.js";
|
|
3
3
|
import { BASALT_UI_CLASS as t } from "../utils/control-surface.js";
|
|
4
|
-
|
|
5
|
-
var n = 4, r = 8, i = "z-50", a = "motion-reduce:animate-none motion-reduce:transition-none", o = "
|
|
4
|
+
// src/components/overlay.ts
|
|
5
|
+
var n = 4, r = 8, i = "z-50", a = "motion-reduce:animate-none motion-reduce:transition-none", o = "basalt-focus", s = o, c = "basalt-focus basalt-focus-inset";
|
|
6
6
|
function l(n) {
|
|
7
7
|
return e(t, i, "basalt-floating overflow-hidden rounded-basalt-md border border-basalt-border bg-basalt-popover py-basalt-menu-inset text-basalt-base text-basalt-popover-foreground shadow-md", a, n);
|
|
8
8
|
}
|
|
9
9
|
function u(t) {
|
|
10
|
-
return e("mx-basalt-menu-inset flex min-h-basalt-menu-row w-[calc(100%-var(--basalt-space-menu-inset)*2)] cursor-default items-center gap-basalt-row-gap rounded-basalt-sm px-basalt-menu-x py-basalt-menu-y text-left text-basalt-base leading-basalt-row
|
|
10
|
+
return e("mx-basalt-menu-inset flex min-h-basalt-menu-row w-[calc(100%-var(--basalt-space-menu-inset)*2)] cursor-default items-center gap-basalt-row-gap rounded-basalt-sm px-basalt-menu-x py-basalt-menu-y text-left text-basalt-base leading-basalt-row select-none", c, t);
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
export { o as FOCUS_BORDER, s as FOCUS_INSET, c as FOCUS_RING, r as MENU_GAP, n as OVERLAY_GAP, i as OVERLAY_LAYER, a as OVERLAY_MOTION, u as overlayItemClass, l as overlayPanelClass };
|
|
12
|
+
export { s as FOCUS_BORDER, c as FOCUS_INSET, o as FOCUS_RING, r as MENU_GAP, n as OVERLAY_GAP, i as OVERLAY_LAYER, a as OVERLAY_MOTION, u as overlayItemClass, l as overlayPanelClass };
|
|
14
13
|
|
|
15
14
|
//# sourceMappingURL=overlay.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlay.js","names":["OVERLAY_GAP","MENU_GAP","OVERLAY_LAYER","OVERLAY_MOTION","
|
|
1
|
+
{"version":3,"file":"overlay.js","names":["OVERLAY_GAP","MENU_GAP","OVERLAY_LAYER","OVERLAY_MOTION","FOCUS_RING","FOCUS_BORDER","FOCUS_INSET","overlayPanelClass","cn","BASALT_UI_CLASS","className","overlayItemClass"],"sources":["../../src/components/overlay.ts"],"sourcesContent":["import { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\n\n/** Gap between a field trigger and its list. Matches Kumo Select/Combobox. */\nexport const OVERLAY_GAP = 4;\n/** Gap between a menu trigger and its panel. Matches Kumo Dropdown/Popover. */\nexport const MENU_GAP = 8;\n/** Shared stacking layer for portals, menus, and chrome overlays. */\nexport const OVERLAY_LAYER = \"z-50\";\n/** Kill CSS animation and transition when the user prefers reduced motion. */\nexport const OVERLAY_MOTION = \"motion-reduce:animate-none motion-reduce:transition-none\";\n\nexport const FOCUS_RING = \"basalt-focus\";\nexport const FOCUS_BORDER = FOCUS_RING;\nexport const FOCUS_INSET = \"basalt-focus basalt-focus-inset\";\n\nexport function overlayPanelClass(className?: string) {\n\treturn cn(\n\t\tBASALT_UI_CLASS,\n\t\tOVERLAY_LAYER,\n\t\t\"basalt-floating overflow-hidden rounded-basalt-md border border-basalt-border bg-basalt-popover py-basalt-menu-inset text-basalt-base text-basalt-popover-foreground shadow-md\",\n\t\tOVERLAY_MOTION,\n\t\tclassName,\n\t);\n}\n\nexport function overlayItemClass(className?: string) {\n\treturn cn(\n\t\t\"mx-basalt-menu-inset flex min-h-basalt-menu-row w-[calc(100%-var(--basalt-space-menu-inset)*2)] cursor-default items-center gap-basalt-row-gap rounded-basalt-sm px-basalt-menu-x py-basalt-menu-y text-left text-basalt-base leading-basalt-row select-none\",\n\t\tFOCUS_INSET,\n\t\tclassName,\n\t);\n}\n"],"mappings":";;;;AAIA,IAAaA,IAAc,GAEdC,IAAW,GAEXC,IAAgB,QAEhBC,IAAiB,4DAEjBC,IAAa,gBACbC,IAAeD,GACfE,IAAc;AAE3B,SAAgBC,EAAkB,GAAoB;CACrD,OAAOC,EACNC,GACAP,GACA,kLACAC,GACAO,CACD;AACD;AAEA,SAAgBC,EAAiB,GAAoB;CACpD,OAAOH,EACN,gQACAF,GACAI,CACD;AACD"}
|