art-bd-ui 1.0.1 → 1.0.3
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/dist/cjs/components/popovers/popover/popover.js +13 -2
- package/dist/cjs/components/selectors/multiselect/components/badge-list.js +47 -0
- package/dist/cjs/components/selectors/multiselect/components/options.js +14 -0
- package/dist/cjs/components/selectors/multiselect/multiselect.js +119 -0
- package/dist/cjs/components/ui/command/command.js +6 -0
- package/dist/cjs/hooks/use-debounce.js +18 -0
- package/dist/cjs/index.js +5 -0
- package/dist/esm/components/popovers/popover/popover.js +13 -2
- package/dist/esm/components/selectors/multiselect/components/badge-list.js +45 -0
- package/dist/esm/components/selectors/multiselect/components/options.js +12 -0
- package/dist/esm/components/selectors/multiselect/multiselect.js +117 -0
- package/dist/esm/components/ui/command/command.js +6 -1
- package/dist/esm/hooks/use-debounce.js +16 -0
- package/dist/esm/index.js +3 -1
- package/dist/styles.css +18 -0
- package/dist/types/index.d.ts +44 -13
- package/package.json +1 -1
|
@@ -17,7 +17,18 @@ const popoverContentVariants = classVarianceAuthority.cva([
|
|
|
17
17
|
sm: "w-56",
|
|
18
18
|
lg: "w-96",
|
|
19
19
|
},
|
|
20
|
+
matchTriggerWidth: {
|
|
21
|
+
true: null,
|
|
22
|
+
false: null,
|
|
23
|
+
},
|
|
20
24
|
},
|
|
25
|
+
compoundVariants: [
|
|
26
|
+
{
|
|
27
|
+
size: ["default", "sm", "lg"],
|
|
28
|
+
matchTriggerWidth: true,
|
|
29
|
+
class: "w-(--radix-popover-trigger-width)",
|
|
30
|
+
},
|
|
31
|
+
],
|
|
21
32
|
defaultVariants: {
|
|
22
33
|
size: "default",
|
|
23
34
|
},
|
|
@@ -37,8 +48,8 @@ const PopoverTrigger = (_a) => {
|
|
|
37
48
|
return jsxRuntime.jsx(reactPopover.Trigger, Object.assign({ "data-slot": "popover-trigger" }, props));
|
|
38
49
|
};
|
|
39
50
|
const PopoverContent = (_a) => {
|
|
40
|
-
var { className, align = "center", arrow = false, withClose = false, sideOffset = 4, size, children } = _a, props = tslib.__rest(_a, ["className", "align", "arrow", "withClose", "sideOffset", "size", "children"]);
|
|
41
|
-
return (jsxRuntime.jsx(reactPopover.Portal, { children: jsxRuntime.jsxs(reactPopover.Content, Object.assign({ "data-slot": "popover-content", align: align, sideOffset: sideOffset, className: utils.cn(popoverContentVariants({ size }), [
|
|
51
|
+
var { className, align = "center", arrow = false, withClose = false, sideOffset = 4, size, matchTriggerWidth = false, children } = _a, props = tslib.__rest(_a, ["className", "align", "arrow", "withClose", "sideOffset", "size", "matchTriggerWidth", "children"]);
|
|
52
|
+
return (jsxRuntime.jsx(reactPopover.Portal, { children: jsxRuntime.jsxs(reactPopover.Content, Object.assign({ "data-slot": "popover-content", align: align, sideOffset: sideOffset, className: utils.cn(popoverContentVariants({ size, matchTriggerWidth }), [
|
|
42
53
|
"data-[state=open]:animate-in",
|
|
43
54
|
"data-[state=open]:fade-in-0",
|
|
44
55
|
"data-[state=open]:zoom-in-95",
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
var react = require('react');
|
|
6
|
+
var badge = require('../../../ui/badge/badge.js');
|
|
7
|
+
var icon = require('../../../media/icon/icon.js');
|
|
8
|
+
var utils = require('../../../../lib/utils.js');
|
|
9
|
+
|
|
10
|
+
const BadgeList = react.memo(({ options, disabled, onRemove }) => {
|
|
11
|
+
const handleBadgeKeyDown = (e, opt) => {
|
|
12
|
+
e.stopPropagation();
|
|
13
|
+
if (disabled) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (e.key === "Enter" || e.key === " " || e.key === "Backspace" || e.key === "Delete") {
|
|
17
|
+
e.preventDefault();
|
|
18
|
+
onRemove(opt);
|
|
19
|
+
const nextBadge = e.currentTarget.nextElementSibling || e.currentTarget.previousElementSibling;
|
|
20
|
+
if (nextBadge instanceof HTMLElement) {
|
|
21
|
+
nextBadge.focus();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else if (e.key === "ArrowRight") {
|
|
25
|
+
e.preventDefault();
|
|
26
|
+
const nextBadge = e.currentTarget.nextElementSibling;
|
|
27
|
+
if (nextBadge instanceof HTMLElement) {
|
|
28
|
+
nextBadge.focus();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else if (e.key === "ArrowLeft") {
|
|
32
|
+
e.preventDefault();
|
|
33
|
+
const prevBadge = e.currentTarget.previousElementSibling;
|
|
34
|
+
if (prevBadge instanceof HTMLElement) {
|
|
35
|
+
prevBadge.focus();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: options.map((opt) => (jsxRuntime.jsxs(badge.Badge, { tabIndex: disabled ? -1 : 0, role: "button", "aria-label": `Remove ${opt.label}`, variant: "secondary", className: utils.cn("gap-1 select-none", !disabled && "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", !disabled && "cursor-pointer hover:bg-secondary/80"), onClick: () => {
|
|
40
|
+
if (!disabled) {
|
|
41
|
+
onRemove(opt);
|
|
42
|
+
}
|
|
43
|
+
}, onKeyDown: (e) => handleBadgeKeyDown(e, opt), children: [opt.label, !disabled && jsxRuntime.jsx(icon.Icon, { name: "x", className: "size-3" })] }, opt.value))) }));
|
|
44
|
+
});
|
|
45
|
+
BadgeList.displayName = "BadgeList";
|
|
46
|
+
|
|
47
|
+
exports.BadgeList = BadgeList;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
var react = require('react');
|
|
6
|
+
var command = require('../../../ui/command/command.js');
|
|
7
|
+
var checkbox = require('../../../forms/checkbox/checkbox.js');
|
|
8
|
+
|
|
9
|
+
const OptionItem = react.memo(({ option, selected, onSelect }) => (jsxRuntime.jsxs(command.CommandItem, { value: option.value, keywords: [option.label], onSelect: () => onSelect(option), className: "flex items-center gap-2", children: [jsxRuntime.jsx(checkbox.Checkbox, { tabIndex: -1, checked: selected, size: "sm" }), option.label] })));
|
|
10
|
+
OptionItem.displayName = "OptionItem";
|
|
11
|
+
const OptionsList = react.memo(({ options, selectedValues, onSelect }) => (jsxRuntime.jsx(jsxRuntime.Fragment, { children: options.map(({ value, label, children, data }) => children.length > 0 ? (jsxRuntime.jsx(command.CommandGroup, { heading: label, children: jsxRuntime.jsx(OptionsList, { options: children, selectedValues: selectedValues, onSelect: onSelect }) }, value)) : data ? (jsxRuntime.jsx(OptionItem, { option: data, selected: selectedValues.has(value), onSelect: onSelect }, value)) : null) })));
|
|
12
|
+
OptionsList.displayName = "OptionsList";
|
|
13
|
+
|
|
14
|
+
exports.OptionsList = OptionsList;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var tslib = require('tslib');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
var react = require('react');
|
|
7
|
+
var options = require('./components/options.js');
|
|
8
|
+
var badgeList = require('./components/badge-list.js');
|
|
9
|
+
var command = require('../../ui/command/command.js');
|
|
10
|
+
var popover = require('../../popovers/popover/popover.js');
|
|
11
|
+
var utils = require('../../../lib/utils.js');
|
|
12
|
+
var useDebounce = require('../../../hooks/use-debounce.js');
|
|
13
|
+
require('clsx');
|
|
14
|
+
var toggle = require('../../../utils/toggle.js');
|
|
15
|
+
var useUpdateEffect = require('../../../hooks/useUpdateEffect.js');
|
|
16
|
+
require('lodash/throttle');
|
|
17
|
+
var iconButton = require('../../buttons/icon-button/icon-button.js');
|
|
18
|
+
var flex = require('../../layout/flex/flex.js');
|
|
19
|
+
|
|
20
|
+
function isPromise(value) {
|
|
21
|
+
return value instanceof Promise;
|
|
22
|
+
}
|
|
23
|
+
function getGroupedListOptions(options, groups = []) {
|
|
24
|
+
const lookup = groups.reduce((acc, { value, label }) => {
|
|
25
|
+
acc[value] = { value, label, children: [] };
|
|
26
|
+
return acc;
|
|
27
|
+
}, {});
|
|
28
|
+
const ungrouped = [];
|
|
29
|
+
for (const opt of options) {
|
|
30
|
+
const node = {
|
|
31
|
+
value: opt.value,
|
|
32
|
+
label: opt.label,
|
|
33
|
+
children: [],
|
|
34
|
+
data: opt,
|
|
35
|
+
};
|
|
36
|
+
if (opt.group && lookup[opt.group]) {
|
|
37
|
+
lookup[opt.group].children.push(node);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
ungrouped.push(node);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const result = [];
|
|
44
|
+
for (const grp of groups) {
|
|
45
|
+
const bucket = lookup[grp.value];
|
|
46
|
+
if (bucket.children.length > 0) {
|
|
47
|
+
result.push(bucket);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return result.concat(ungrouped);
|
|
51
|
+
}
|
|
52
|
+
const defaultValue = [];
|
|
53
|
+
const defaultOptions = [];
|
|
54
|
+
const defaultGroups = [];
|
|
55
|
+
const MultiSelect = (_a) => {
|
|
56
|
+
var { value = defaultValue, onChange = () => { }, options: options$1 = defaultOptions, groups = defaultGroups, createable = false, onCreate = () => { }, onSearch, debounceDelay = 500, placeholder = "Select options...", disabled = false, clearable = false, className } = _a, props = tslib.__rest(_a, ["value", "onChange", "options", "groups", "createable", "onCreate", "onSearch", "debounceDelay", "placeholder", "disabled", "clearable", "className"]);
|
|
57
|
+
const [open, setOpen] = react.useState(false);
|
|
58
|
+
const [loading, setLoading] = react.useState(false);
|
|
59
|
+
const [searchQuery, setSearchQuery] = react.useState("");
|
|
60
|
+
const debouncedSearch = useDebounce.useDebounce(searchQuery, debounceDelay);
|
|
61
|
+
const [searchResults, setSearchResults] = react.useState(options$1);
|
|
62
|
+
useUpdateEffect.useUpdateEffect(() => {
|
|
63
|
+
if (!onSearch || !debouncedSearch) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const search = () => tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
67
|
+
try {
|
|
68
|
+
const results = onSearch(debouncedSearch);
|
|
69
|
+
if (isPromise(results)) {
|
|
70
|
+
setLoading(true);
|
|
71
|
+
const options = yield results;
|
|
72
|
+
setSearchResults(options);
|
|
73
|
+
}
|
|
74
|
+
else if (Array.isArray(results)) {
|
|
75
|
+
setSearchResults(results);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.error("Search failed:", error);
|
|
80
|
+
setSearchResults([]);
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
setLoading(false);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
void search();
|
|
87
|
+
}, [debouncedSearch, onSearch]);
|
|
88
|
+
const handleSelect = react.useCallback((opt) => {
|
|
89
|
+
onChange(toggle.toggle(value, opt, (o) => o.value));
|
|
90
|
+
}, [onChange, value]);
|
|
91
|
+
const handleRemove = react.useCallback((opt) => onChange(value.filter((v) => v.value !== opt.value)), [onChange, value]);
|
|
92
|
+
const handleClear = react.useCallback(() => onChange([]), [onChange]);
|
|
93
|
+
const optionsList = react.useMemo(() => getGroupedListOptions(searchResults, groups), [searchResults, groups]);
|
|
94
|
+
const selectedValues = react.useMemo(() => new Set(value.map((v) => v.value)), [value]);
|
|
95
|
+
const handleTriggerKeyDown = react.useCallback((e) => {
|
|
96
|
+
if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") {
|
|
97
|
+
e.preventDefault();
|
|
98
|
+
setOpen(true);
|
|
99
|
+
}
|
|
100
|
+
}, []);
|
|
101
|
+
const handleClearKeyDown = react.useCallback((e) => {
|
|
102
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
103
|
+
e.preventDefault();
|
|
104
|
+
handleClear();
|
|
105
|
+
}
|
|
106
|
+
}, [handleClear]);
|
|
107
|
+
const setPopoverVisibility = react.useCallback((open) => {
|
|
108
|
+
if (!disabled) {
|
|
109
|
+
setOpen(open);
|
|
110
|
+
}
|
|
111
|
+
}, [disabled]);
|
|
112
|
+
return (jsxRuntime.jsxs(popover.Popover, { open: open, onOpenChange: setPopoverVisibility, children: [jsxRuntime.jsx(popover.PopoverTrigger, { asChild: true, children: jsxRuntime.jsxs("div", Object.assign({}, props, { tabIndex: disabled ? -1 : 0, role: "combobox", "aria-expanded": open, "aria-haspopup": "listbox", "aria-controls": "multiselect-options", "aria-label": placeholder, "aria-disabled": disabled, onKeyDown: handleTriggerKeyDown, className: utils.cn("flex min-h-9 w-full flex-wrap items-center gap-1 rounded-md border bg-background px-3 py-1", !disabled && "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", disabled && "disabled:cursor-not-allowed disabled:opacity-50", className), children: [jsxRuntime.jsx(flex.Flex, { wrap: "wrap", gap: 1, align: "start", className: "flex-1", children: value.length > 0 ? (jsxRuntime.jsx(badgeList.BadgeList, { options: value, disabled: disabled, onRemove: handleRemove })) : (jsxRuntime.jsx("span", { className: "text-base md:text-sm text-muted-foreground", children: placeholder })) }), clearable && !disabled && value.length > 0 && (jsxRuntime.jsx(iconButton.IconButton, { icon: "circle-x", radius: "full", variant: "ghost", className: "size-5 p-0.25 self-start shrink-0", onClick: handleClear, onKeyDown: handleClearKeyDown, disabled: disabled, tooltip: "Clear All", "aria-label": "Clear all selections" }))] })) }), jsxRuntime.jsx(popover.PopoverContent, { className: "p-0", align: "start", matchTriggerWidth: true, children: jsxRuntime.jsxs(command.Command, { id: "multiselect-options", role: "listbox", shouldFilter: !onSearch, children: [jsxRuntime.jsx(command.CommandInput, { placeholder: "Search...", value: searchQuery, onValueChange: setSearchQuery, disabled: disabled }), jsxRuntime.jsxs(command.CommandList, { children: [loading ? (jsxRuntime.jsx(command.CommandLoading, { children: "Searching\u2026" })) : optionsList.length > 0 ? (jsxRuntime.jsx(options.OptionsList, { options: optionsList, selectedValues: selectedValues, onSelect: handleSelect })) : (jsxRuntime.jsx(command.CommandEmpty, { children: "No results found." })), createable && !loading && searchQuery && debouncedSearch && (jsxRuntime.jsxs(command.CommandItem, { value: searchQuery, keywords: [searchQuery], onSelect: () => {
|
|
113
|
+
onCreate(searchQuery);
|
|
114
|
+
setSearchQuery("");
|
|
115
|
+
}, children: ["Create \"", searchQuery, "\""] }))] })] }) })] }));
|
|
116
|
+
};
|
|
117
|
+
MultiSelect.displayName = "MultiSelect";
|
|
118
|
+
|
|
119
|
+
exports.MultiSelect = MultiSelect;
|
|
@@ -43,6 +43,11 @@ const CommandEmpty = (_a) => {
|
|
|
43
43
|
return jsxRuntime.jsx(cmdk.Command.Empty, Object.assign({ "data-slot": "command-empty", className: "py-6 text-center text-sm" }, props));
|
|
44
44
|
};
|
|
45
45
|
CommandEmpty.displayName = "CommandEmpty";
|
|
46
|
+
const CommandLoading = (_a) => {
|
|
47
|
+
var props = tslib.__rest(_a, []);
|
|
48
|
+
return jsxRuntime.jsx(cmdk.Command.Loading, Object.assign({ "data-slot": "command-loading", className: "py-6 text-center text-sm" }, props));
|
|
49
|
+
};
|
|
50
|
+
CommandEmpty.displayName = "CommandEmpty";
|
|
46
51
|
const CommandGroup = (_a) => {
|
|
47
52
|
var { className } = _a, props = tslib.__rest(_a, ["className"]);
|
|
48
53
|
return (jsxRuntime.jsx(cmdk.Command.Group, Object.assign({ "data-slot": "command-group", className: utils.cn("overflow-hidden p-1", "text-foreground",
|
|
@@ -79,5 +84,6 @@ exports.CommandGroup = CommandGroup;
|
|
|
79
84
|
exports.CommandInput = CommandInput;
|
|
80
85
|
exports.CommandItem = CommandItem;
|
|
81
86
|
exports.CommandList = CommandList;
|
|
87
|
+
exports.CommandLoading = CommandLoading;
|
|
82
88
|
exports.CommandSeparator = CommandSeparator;
|
|
83
89
|
exports.CommandShortcut = CommandShortcut;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
|
|
5
|
+
function useDebounce(value, delay) {
|
|
6
|
+
const [debouncedValue, setDebouncedValue] = react.useState(value);
|
|
7
|
+
react.useEffect(() => {
|
|
8
|
+
const timer = setTimeout(() => {
|
|
9
|
+
setDebouncedValue(value);
|
|
10
|
+
}, delay);
|
|
11
|
+
return () => {
|
|
12
|
+
clearTimeout(timer);
|
|
13
|
+
};
|
|
14
|
+
}, [value, delay]);
|
|
15
|
+
return debouncedValue;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
exports.useDebounce = useDebounce;
|
package/dist/cjs/index.js
CHANGED
|
@@ -14,6 +14,7 @@ var radio = require('./components/forms/radio/radio.js');
|
|
|
14
14
|
var select = require('./components/forms/select/select.js');
|
|
15
15
|
var _switch = require('./components/forms/switch/switch.js');
|
|
16
16
|
var textarea = require('./components/forms/textarea/textarea.js');
|
|
17
|
+
var multiselect = require('./components/selectors/multiselect/multiselect.js');
|
|
17
18
|
var icon = require('./components/media/icon/icon.js');
|
|
18
19
|
var avatar = require('./components/media/avatar/avatar.js');
|
|
19
20
|
var aspectRatio = require('./components/media/aspect-ratio/aspect-ratio.js');
|
|
@@ -50,6 +51,7 @@ var useControlled = require('./hooks/useControlled.js');
|
|
|
50
51
|
var usePrevious = require('./hooks/usePrevious.js');
|
|
51
52
|
var useLatest = require('./hooks/useLatest.js');
|
|
52
53
|
var useScrollState = require('./hooks/useScrollState.js');
|
|
54
|
+
var useDebounce = require('./hooks/use-debounce.js');
|
|
53
55
|
var chain = require('./utils/chain.js');
|
|
54
56
|
var mergeProps = require('./utils/mergeProps.js');
|
|
55
57
|
var mergeRefs = require('./utils/mergeRefs.js');
|
|
@@ -93,6 +95,7 @@ exports.SelectTrigger = select.SelectTrigger;
|
|
|
93
95
|
exports.SelectValue = select.SelectValue;
|
|
94
96
|
exports.Switch = _switch.Switch;
|
|
95
97
|
exports.Textarea = textarea.Textarea;
|
|
98
|
+
exports.MultiSelect = multiselect.MultiSelect;
|
|
96
99
|
exports.Icon = icon.Icon;
|
|
97
100
|
exports.Avatar = avatar.Avatar;
|
|
98
101
|
exports.AvatarFallback = avatar.AvatarFallback;
|
|
@@ -150,6 +153,7 @@ exports.CommandGroup = command.CommandGroup;
|
|
|
150
153
|
exports.CommandInput = command.CommandInput;
|
|
151
154
|
exports.CommandItem = command.CommandItem;
|
|
152
155
|
exports.CommandList = command.CommandList;
|
|
156
|
+
exports.CommandLoading = command.CommandLoading;
|
|
153
157
|
exports.CommandSeparator = command.CommandSeparator;
|
|
154
158
|
exports.CommandShortcut = command.CommandShortcut;
|
|
155
159
|
exports.DataTable = dataTable.DataTable;
|
|
@@ -220,6 +224,7 @@ exports.useControlled = useControlled.useControlled;
|
|
|
220
224
|
exports.usePrevious = usePrevious.usePrevious;
|
|
221
225
|
exports.useLatest = useLatest.useLatest;
|
|
222
226
|
exports.useScrollState = useScrollState.useScrollState;
|
|
227
|
+
exports.useDebounce = useDebounce.useDebounce;
|
|
223
228
|
exports.chain = chain.chain;
|
|
224
229
|
exports.mergeProps = mergeProps.mergeProps;
|
|
225
230
|
exports.assignRef = mergeRefs.assignRef;
|
|
@@ -15,7 +15,18 @@ const popoverContentVariants = cva([
|
|
|
15
15
|
sm: "w-56",
|
|
16
16
|
lg: "w-96",
|
|
17
17
|
},
|
|
18
|
+
matchTriggerWidth: {
|
|
19
|
+
true: null,
|
|
20
|
+
false: null,
|
|
21
|
+
},
|
|
18
22
|
},
|
|
23
|
+
compoundVariants: [
|
|
24
|
+
{
|
|
25
|
+
size: ["default", "sm", "lg"],
|
|
26
|
+
matchTriggerWidth: true,
|
|
27
|
+
class: "w-(--radix-popover-trigger-width)",
|
|
28
|
+
},
|
|
29
|
+
],
|
|
19
30
|
defaultVariants: {
|
|
20
31
|
size: "default",
|
|
21
32
|
},
|
|
@@ -35,8 +46,8 @@ const PopoverTrigger = (_a) => {
|
|
|
35
46
|
return jsx(Trigger, Object.assign({ "data-slot": "popover-trigger" }, props));
|
|
36
47
|
};
|
|
37
48
|
const PopoverContent = (_a) => {
|
|
38
|
-
var { className, align = "center", arrow = false, withClose = false, sideOffset = 4, size, children } = _a, props = __rest(_a, ["className", "align", "arrow", "withClose", "sideOffset", "size", "children"]);
|
|
39
|
-
return (jsx(Portal, { children: jsxs(Content, Object.assign({ "data-slot": "popover-content", align: align, sideOffset: sideOffset, className: cn(popoverContentVariants({ size }), [
|
|
49
|
+
var { className, align = "center", arrow = false, withClose = false, sideOffset = 4, size, matchTriggerWidth = false, children } = _a, props = __rest(_a, ["className", "align", "arrow", "withClose", "sideOffset", "size", "matchTriggerWidth", "children"]);
|
|
50
|
+
return (jsx(Portal, { children: jsxs(Content, Object.assign({ "data-slot": "popover-content", align: align, sideOffset: sideOffset, className: cn(popoverContentVariants({ size, matchTriggerWidth }), [
|
|
40
51
|
"data-[state=open]:animate-in",
|
|
41
52
|
"data-[state=open]:fade-in-0",
|
|
42
53
|
"data-[state=open]:zoom-in-95",
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
import { memo } from 'react';
|
|
4
|
+
import { Badge } from '../../../ui/badge/badge.js';
|
|
5
|
+
import { Icon } from '../../../media/icon/icon.js';
|
|
6
|
+
import { cn } from '../../../../lib/utils.js';
|
|
7
|
+
|
|
8
|
+
const BadgeList = memo(({ options, disabled, onRemove }) => {
|
|
9
|
+
const handleBadgeKeyDown = (e, opt) => {
|
|
10
|
+
e.stopPropagation();
|
|
11
|
+
if (disabled) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (e.key === "Enter" || e.key === " " || e.key === "Backspace" || e.key === "Delete") {
|
|
15
|
+
e.preventDefault();
|
|
16
|
+
onRemove(opt);
|
|
17
|
+
const nextBadge = e.currentTarget.nextElementSibling || e.currentTarget.previousElementSibling;
|
|
18
|
+
if (nextBadge instanceof HTMLElement) {
|
|
19
|
+
nextBadge.focus();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
else if (e.key === "ArrowRight") {
|
|
23
|
+
e.preventDefault();
|
|
24
|
+
const nextBadge = e.currentTarget.nextElementSibling;
|
|
25
|
+
if (nextBadge instanceof HTMLElement) {
|
|
26
|
+
nextBadge.focus();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else if (e.key === "ArrowLeft") {
|
|
30
|
+
e.preventDefault();
|
|
31
|
+
const prevBadge = e.currentTarget.previousElementSibling;
|
|
32
|
+
if (prevBadge instanceof HTMLElement) {
|
|
33
|
+
prevBadge.focus();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
return (jsx(Fragment, { children: options.map((opt) => (jsxs(Badge, { tabIndex: disabled ? -1 : 0, role: "button", "aria-label": `Remove ${opt.label}`, variant: "secondary", className: cn("gap-1 select-none", !disabled && "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", !disabled && "cursor-pointer hover:bg-secondary/80"), onClick: () => {
|
|
38
|
+
if (!disabled) {
|
|
39
|
+
onRemove(opt);
|
|
40
|
+
}
|
|
41
|
+
}, onKeyDown: (e) => handleBadgeKeyDown(e, opt), children: [opt.label, !disabled && jsx(Icon, { name: "x", className: "size-3" })] }, opt.value))) }));
|
|
42
|
+
});
|
|
43
|
+
BadgeList.displayName = "BadgeList";
|
|
44
|
+
|
|
45
|
+
export { BadgeList };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import { memo } from 'react';
|
|
4
|
+
import { CommandItem, CommandGroup } from '../../../ui/command/command.js';
|
|
5
|
+
import { Checkbox } from '../../../forms/checkbox/checkbox.js';
|
|
6
|
+
|
|
7
|
+
const OptionItem = memo(({ option, selected, onSelect }) => (jsxs(CommandItem, { value: option.value, keywords: [option.label], onSelect: () => onSelect(option), className: "flex items-center gap-2", children: [jsx(Checkbox, { tabIndex: -1, checked: selected, size: "sm" }), option.label] })));
|
|
8
|
+
OptionItem.displayName = "OptionItem";
|
|
9
|
+
const OptionsList = memo(({ options, selectedValues, onSelect }) => (jsx(Fragment, { children: options.map(({ value, label, children, data }) => children.length > 0 ? (jsx(CommandGroup, { heading: label, children: jsx(OptionsList, { options: children, selectedValues: selectedValues, onSelect: onSelect }) }, value)) : data ? (jsx(OptionItem, { option: data, selected: selectedValues.has(value), onSelect: onSelect }, value)) : null) })));
|
|
10
|
+
OptionsList.displayName = "OptionsList";
|
|
11
|
+
|
|
12
|
+
export { OptionsList };
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { __rest, __awaiter } from 'tslib';
|
|
3
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
4
|
+
import { useState, useCallback, useMemo } from 'react';
|
|
5
|
+
import { OptionsList } from './components/options.js';
|
|
6
|
+
import { BadgeList } from './components/badge-list.js';
|
|
7
|
+
import { Command, CommandInput, CommandList, CommandLoading, CommandEmpty, CommandItem } from '../../ui/command/command.js';
|
|
8
|
+
import { Popover, PopoverTrigger, PopoverContent } from '../../popovers/popover/popover.js';
|
|
9
|
+
import { cn } from '../../../lib/utils.js';
|
|
10
|
+
import { useDebounce } from '../../../hooks/use-debounce.js';
|
|
11
|
+
import 'clsx';
|
|
12
|
+
import { toggle } from '../../../utils/toggle.js';
|
|
13
|
+
import { useUpdateEffect } from '../../../hooks/useUpdateEffect.js';
|
|
14
|
+
import 'lodash/throttle';
|
|
15
|
+
import { IconButton } from '../../buttons/icon-button/icon-button.js';
|
|
16
|
+
import { Flex } from '../../layout/flex/flex.js';
|
|
17
|
+
|
|
18
|
+
function isPromise(value) {
|
|
19
|
+
return value instanceof Promise;
|
|
20
|
+
}
|
|
21
|
+
function getGroupedListOptions(options, groups = []) {
|
|
22
|
+
const lookup = groups.reduce((acc, { value, label }) => {
|
|
23
|
+
acc[value] = { value, label, children: [] };
|
|
24
|
+
return acc;
|
|
25
|
+
}, {});
|
|
26
|
+
const ungrouped = [];
|
|
27
|
+
for (const opt of options) {
|
|
28
|
+
const node = {
|
|
29
|
+
value: opt.value,
|
|
30
|
+
label: opt.label,
|
|
31
|
+
children: [],
|
|
32
|
+
data: opt,
|
|
33
|
+
};
|
|
34
|
+
if (opt.group && lookup[opt.group]) {
|
|
35
|
+
lookup[opt.group].children.push(node);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
ungrouped.push(node);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const result = [];
|
|
42
|
+
for (const grp of groups) {
|
|
43
|
+
const bucket = lookup[grp.value];
|
|
44
|
+
if (bucket.children.length > 0) {
|
|
45
|
+
result.push(bucket);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return result.concat(ungrouped);
|
|
49
|
+
}
|
|
50
|
+
const defaultValue = [];
|
|
51
|
+
const defaultOptions = [];
|
|
52
|
+
const defaultGroups = [];
|
|
53
|
+
const MultiSelect = (_a) => {
|
|
54
|
+
var { value = defaultValue, onChange = () => { }, options = defaultOptions, groups = defaultGroups, createable = false, onCreate = () => { }, onSearch, debounceDelay = 500, placeholder = "Select options...", disabled = false, clearable = false, className } = _a, props = __rest(_a, ["value", "onChange", "options", "groups", "createable", "onCreate", "onSearch", "debounceDelay", "placeholder", "disabled", "clearable", "className"]);
|
|
55
|
+
const [open, setOpen] = useState(false);
|
|
56
|
+
const [loading, setLoading] = useState(false);
|
|
57
|
+
const [searchQuery, setSearchQuery] = useState("");
|
|
58
|
+
const debouncedSearch = useDebounce(searchQuery, debounceDelay);
|
|
59
|
+
const [searchResults, setSearchResults] = useState(options);
|
|
60
|
+
useUpdateEffect(() => {
|
|
61
|
+
if (!onSearch || !debouncedSearch) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const search = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
|
+
try {
|
|
66
|
+
const results = onSearch(debouncedSearch);
|
|
67
|
+
if (isPromise(results)) {
|
|
68
|
+
setLoading(true);
|
|
69
|
+
const options = yield results;
|
|
70
|
+
setSearchResults(options);
|
|
71
|
+
}
|
|
72
|
+
else if (Array.isArray(results)) {
|
|
73
|
+
setSearchResults(results);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
console.error("Search failed:", error);
|
|
78
|
+
setSearchResults([]);
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
setLoading(false);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
void search();
|
|
85
|
+
}, [debouncedSearch, onSearch]);
|
|
86
|
+
const handleSelect = useCallback((opt) => {
|
|
87
|
+
onChange(toggle(value, opt, (o) => o.value));
|
|
88
|
+
}, [onChange, value]);
|
|
89
|
+
const handleRemove = useCallback((opt) => onChange(value.filter((v) => v.value !== opt.value)), [onChange, value]);
|
|
90
|
+
const handleClear = useCallback(() => onChange([]), [onChange]);
|
|
91
|
+
const optionsList = useMemo(() => getGroupedListOptions(searchResults, groups), [searchResults, groups]);
|
|
92
|
+
const selectedValues = useMemo(() => new Set(value.map((v) => v.value)), [value]);
|
|
93
|
+
const handleTriggerKeyDown = useCallback((e) => {
|
|
94
|
+
if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") {
|
|
95
|
+
e.preventDefault();
|
|
96
|
+
setOpen(true);
|
|
97
|
+
}
|
|
98
|
+
}, []);
|
|
99
|
+
const handleClearKeyDown = useCallback((e) => {
|
|
100
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
101
|
+
e.preventDefault();
|
|
102
|
+
handleClear();
|
|
103
|
+
}
|
|
104
|
+
}, [handleClear]);
|
|
105
|
+
const setPopoverVisibility = useCallback((open) => {
|
|
106
|
+
if (!disabled) {
|
|
107
|
+
setOpen(open);
|
|
108
|
+
}
|
|
109
|
+
}, [disabled]);
|
|
110
|
+
return (jsxs(Popover, { open: open, onOpenChange: setPopoverVisibility, children: [jsx(PopoverTrigger, { asChild: true, children: jsxs("div", Object.assign({}, props, { tabIndex: disabled ? -1 : 0, role: "combobox", "aria-expanded": open, "aria-haspopup": "listbox", "aria-controls": "multiselect-options", "aria-label": placeholder, "aria-disabled": disabled, onKeyDown: handleTriggerKeyDown, className: cn("flex min-h-9 w-full flex-wrap items-center gap-1 rounded-md border bg-background px-3 py-1", !disabled && "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", disabled && "disabled:cursor-not-allowed disabled:opacity-50", className), children: [jsx(Flex, { wrap: "wrap", gap: 1, align: "start", className: "flex-1", children: value.length > 0 ? (jsx(BadgeList, { options: value, disabled: disabled, onRemove: handleRemove })) : (jsx("span", { className: "text-base md:text-sm text-muted-foreground", children: placeholder })) }), clearable && !disabled && value.length > 0 && (jsx(IconButton, { icon: "circle-x", radius: "full", variant: "ghost", className: "size-5 p-0.25 self-start shrink-0", onClick: handleClear, onKeyDown: handleClearKeyDown, disabled: disabled, tooltip: "Clear All", "aria-label": "Clear all selections" }))] })) }), jsx(PopoverContent, { className: "p-0", align: "start", matchTriggerWidth: true, children: jsxs(Command, { id: "multiselect-options", role: "listbox", shouldFilter: !onSearch, children: [jsx(CommandInput, { placeholder: "Search...", value: searchQuery, onValueChange: setSearchQuery, disabled: disabled }), jsxs(CommandList, { children: [loading ? (jsx(CommandLoading, { children: "Searching\u2026" })) : optionsList.length > 0 ? (jsx(OptionsList, { options: optionsList, selectedValues: selectedValues, onSelect: handleSelect })) : (jsx(CommandEmpty, { children: "No results found." })), createable && !loading && searchQuery && debouncedSearch && (jsxs(CommandItem, { value: searchQuery, keywords: [searchQuery], onSelect: () => {
|
|
111
|
+
onCreate(searchQuery);
|
|
112
|
+
setSearchQuery("");
|
|
113
|
+
}, children: ["Create \"", searchQuery, "\""] }))] })] }) })] }));
|
|
114
|
+
};
|
|
115
|
+
MultiSelect.displayName = "MultiSelect";
|
|
116
|
+
|
|
117
|
+
export { MultiSelect };
|
|
@@ -41,6 +41,11 @@ const CommandEmpty = (_a) => {
|
|
|
41
41
|
return jsx(Command$1.Empty, Object.assign({ "data-slot": "command-empty", className: "py-6 text-center text-sm" }, props));
|
|
42
42
|
};
|
|
43
43
|
CommandEmpty.displayName = "CommandEmpty";
|
|
44
|
+
const CommandLoading = (_a) => {
|
|
45
|
+
var props = __rest(_a, []);
|
|
46
|
+
return jsx(Command$1.Loading, Object.assign({ "data-slot": "command-loading", className: "py-6 text-center text-sm" }, props));
|
|
47
|
+
};
|
|
48
|
+
CommandEmpty.displayName = "CommandEmpty";
|
|
44
49
|
const CommandGroup = (_a) => {
|
|
45
50
|
var { className } = _a, props = __rest(_a, ["className"]);
|
|
46
51
|
return (jsx(Command$1.Group, Object.assign({ "data-slot": "command-group", className: cn("overflow-hidden p-1", "text-foreground",
|
|
@@ -70,4 +75,4 @@ const CommandShortcut = (_a) => {
|
|
|
70
75
|
};
|
|
71
76
|
CommandShortcut.displayName = "CommandShortcut";
|
|
72
77
|
|
|
73
|
-
export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut };
|
|
78
|
+
export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandLoading, CommandSeparator, CommandShortcut };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
function useDebounce(value, delay) {
|
|
4
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
const timer = setTimeout(() => {
|
|
7
|
+
setDebouncedValue(value);
|
|
8
|
+
}, delay);
|
|
9
|
+
return () => {
|
|
10
|
+
clearTimeout(timer);
|
|
11
|
+
};
|
|
12
|
+
}, [value, delay]);
|
|
13
|
+
return debouncedValue;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { useDebounce };
|
package/dist/esm/index.js
CHANGED
|
@@ -12,6 +12,7 @@ export { RadioGroup, RadioGroupItem } from './components/forms/radio/radio.js';
|
|
|
12
12
|
export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue } from './components/forms/select/select.js';
|
|
13
13
|
export { Switch } from './components/forms/switch/switch.js';
|
|
14
14
|
export { Textarea } from './components/forms/textarea/textarea.js';
|
|
15
|
+
export { MultiSelect } from './components/selectors/multiselect/multiselect.js';
|
|
15
16
|
export { Icon } from './components/media/icon/icon.js';
|
|
16
17
|
export { Avatar, AvatarFallback, AvatarImage } from './components/media/avatar/avatar.js';
|
|
17
18
|
export { AspectRatio } from './components/media/aspect-ratio/aspect-ratio.js';
|
|
@@ -26,7 +27,7 @@ export { Text } from './components/typography/text/text.js';
|
|
|
26
27
|
export { Alert, AlertDescription, AlertTitle } from './components/ui/alert/alert.js';
|
|
27
28
|
export { Badge, badgeVariants } from './components/ui/badge/badge.js';
|
|
28
29
|
export { Calendar } from './components/ui/calendar/calendar.js';
|
|
29
|
-
export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut } from './components/ui/command/command.js';
|
|
30
|
+
export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandLoading, CommandSeparator, CommandShortcut } from './components/ui/command/command.js';
|
|
30
31
|
export { DataTable } from './components/ui/data-table/data-table.js';
|
|
31
32
|
export { DatePicker } from './components/ui/date-picker/date-picker.js';
|
|
32
33
|
export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from './components/ui/dropdown-menu/dropdown-menu.js';
|
|
@@ -48,6 +49,7 @@ export { useControlled } from './hooks/useControlled.js';
|
|
|
48
49
|
export { usePrevious } from './hooks/usePrevious.js';
|
|
49
50
|
export { useLatest } from './hooks/useLatest.js';
|
|
50
51
|
export { useScrollState } from './hooks/useScrollState.js';
|
|
52
|
+
export { useDebounce } from './hooks/use-debounce.js';
|
|
51
53
|
export { chain } from './utils/chain.js';
|
|
52
54
|
export { mergeProps } from './utils/mergeProps.js';
|
|
53
55
|
export { assignRef, mergeRefs } from './utils/mergeRefs.js';
|
package/dist/styles.css
CHANGED
|
@@ -760,6 +760,9 @@
|
|
|
760
760
|
.min-h-4 {
|
|
761
761
|
min-height: calc(var(--spacing) * 4);
|
|
762
762
|
}
|
|
763
|
+
.min-h-9 {
|
|
764
|
+
min-height: calc(var(--spacing) * 9);
|
|
765
|
+
}
|
|
763
766
|
.min-h-12 {
|
|
764
767
|
min-height: calc(var(--spacing) * 12);
|
|
765
768
|
}
|
|
@@ -778,6 +781,9 @@
|
|
|
778
781
|
.min-h-svh {
|
|
779
782
|
min-height: 100svh;
|
|
780
783
|
}
|
|
784
|
+
.w-\(--radix-popover-trigger-width\) {
|
|
785
|
+
width: var(--radix-popover-trigger-width);
|
|
786
|
+
}
|
|
781
787
|
.w-\(--sidebar-width\) {
|
|
782
788
|
width: var(--sidebar-width);
|
|
783
789
|
}
|
|
@@ -835,6 +841,9 @@
|
|
|
835
841
|
.w-\[240px\] {
|
|
836
842
|
width: 240px;
|
|
837
843
|
}
|
|
844
|
+
.w-\[300px\] {
|
|
845
|
+
width: 300px;
|
|
846
|
+
}
|
|
838
847
|
.w-auto {
|
|
839
848
|
width: auto;
|
|
840
849
|
}
|
|
@@ -1004,6 +1013,9 @@
|
|
|
1004
1013
|
.cursor-not-allowed {
|
|
1005
1014
|
cursor: not-allowed;
|
|
1006
1015
|
}
|
|
1016
|
+
.cursor-pointer {
|
|
1017
|
+
cursor: pointer;
|
|
1018
|
+
}
|
|
1007
1019
|
.resize {
|
|
1008
1020
|
resize: both;
|
|
1009
1021
|
}
|
|
@@ -1248,6 +1260,9 @@
|
|
|
1248
1260
|
.gap-y-12 {
|
|
1249
1261
|
row-gap: calc(var(--spacing) * 12);
|
|
1250
1262
|
}
|
|
1263
|
+
.self-start {
|
|
1264
|
+
align-self: flex-start;
|
|
1265
|
+
}
|
|
1251
1266
|
.truncate {
|
|
1252
1267
|
overflow: hidden;
|
|
1253
1268
|
text-overflow: ellipsis;
|
|
@@ -1402,6 +1417,9 @@
|
|
|
1402
1417
|
.p-0 {
|
|
1403
1418
|
padding: calc(var(--spacing) * 0);
|
|
1404
1419
|
}
|
|
1420
|
+
.p-0\.25 {
|
|
1421
|
+
padding: calc(var(--spacing) * 0.25);
|
|
1422
|
+
}
|
|
1405
1423
|
.p-1 {
|
|
1406
1424
|
padding: calc(var(--spacing) * 1);
|
|
1407
1425
|
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { Root as Root$1, Item } from '@radix-ui/react-toggle-group';
|
|
|
9
9
|
import { Root as Root$2 } from '@radix-ui/react-checkbox';
|
|
10
10
|
import { Root as Root$3 } from '@radix-ui/react-label';
|
|
11
11
|
import { Root as Root$4, Item as Item$1 } from '@radix-ui/react-radio-group';
|
|
12
|
-
import { Root as Root$5, Content, Group, Item as Item$2, Label as Label$1, ScrollDownButton, ScrollUpButton, Separator as Separator$1, Trigger, Value } from '@radix-ui/react-select';
|
|
12
|
+
import { Root as Root$5, Content, Group as Group$1, Item as Item$2, Label as Label$1, ScrollDownButton, ScrollUpButton, Separator as Separator$1, Trigger, Value } from '@radix-ui/react-select';
|
|
13
13
|
import { Root as Root$6 } from '@radix-ui/react-switch';
|
|
14
14
|
import { Root as Root$7, Image, Fallback } from '@radix-ui/react-avatar';
|
|
15
15
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
@@ -22,7 +22,7 @@ import { Root as Root$a } from '@radix-ui/react-toast';
|
|
|
22
22
|
import { Root as Root$b, Provider, Trigger as Trigger$3, Content as Content$3 } from '@radix-ui/react-tooltip';
|
|
23
23
|
import { DayPicker } from 'react-day-picker';
|
|
24
24
|
import { Command as Command$1 } from 'cmdk';
|
|
25
|
-
import { Root as Root$c, Portal, Trigger as Trigger$4, Content as Content$4, Group as Group$
|
|
25
|
+
import { Root as Root$c, Portal, Trigger as Trigger$4, Content as Content$4, Group as Group$2, Label as Label$2, Item as Item$3, CheckboxItem, RadioGroup as RadioGroup$1, RadioItem, Separator as Separator$2, Sub, SubTrigger, SubContent } from '@radix-ui/react-dropdown-menu';
|
|
26
26
|
import * as _radix_ui_react_slot from '@radix-ui/react-slot';
|
|
27
27
|
import { Slot } from '@radix-ui/react-slot';
|
|
28
28
|
import { Root as Root$d } from '@radix-ui/react-progress';
|
|
@@ -208,7 +208,7 @@ declare const RadioGroupItem: FC<RadioGroupItemProps>;
|
|
|
208
208
|
|
|
209
209
|
type SelectProps = ComponentProps<typeof Root$5>;
|
|
210
210
|
declare const Select: FC<SelectProps>;
|
|
211
|
-
type SelectGroupProps = ComponentProps<typeof Group>;
|
|
211
|
+
type SelectGroupProps = ComponentProps<typeof Group$1>;
|
|
212
212
|
declare const SelectGroup: FC<SelectGroupProps>;
|
|
213
213
|
type SelectValueProps = ComponentProps<typeof Value>;
|
|
214
214
|
declare const SelectValue: FC<SelectValueProps>;
|
|
@@ -245,6 +245,31 @@ declare const textareaVariants: (props?: ({
|
|
|
245
245
|
type TextareaProps = ComponentProps<"textarea"> & VariantProps<typeof textareaVariants>;
|
|
246
246
|
declare const Textarea: react.ForwardRefExoticComponent<Omit<TextareaProps, "ref"> & react.RefAttributes<HTMLTextAreaElement>>;
|
|
247
247
|
|
|
248
|
+
type Option = {
|
|
249
|
+
value: string;
|
|
250
|
+
label: string;
|
|
251
|
+
group?: string;
|
|
252
|
+
};
|
|
253
|
+
type Group = {
|
|
254
|
+
value: string;
|
|
255
|
+
label: string;
|
|
256
|
+
};
|
|
257
|
+
interface MultiSelectProps extends Omit<ComponentProps<"div">, "onChange"> {
|
|
258
|
+
value?: Option[];
|
|
259
|
+
options: Option[];
|
|
260
|
+
groups?: Group[];
|
|
261
|
+
onChange?: (value: Option[]) => void;
|
|
262
|
+
onCreate?: (query: string) => void;
|
|
263
|
+
onSearch?: (query: string) => Option[] | Promise<Option[]>;
|
|
264
|
+
debounceDelay?: number;
|
|
265
|
+
createable?: boolean;
|
|
266
|
+
clearable?: boolean;
|
|
267
|
+
disabled?: boolean;
|
|
268
|
+
placeholder?: string;
|
|
269
|
+
emptyStateText?: string;
|
|
270
|
+
}
|
|
271
|
+
declare const MultiSelect: FC<MultiSelectProps>;
|
|
272
|
+
|
|
248
273
|
type AvatarProps = ComponentProps<typeof Root$7>;
|
|
249
274
|
declare const Avatar: FC<AvatarProps>;
|
|
250
275
|
type AvatarImageProps = ComponentProps<typeof Image>;
|
|
@@ -288,6 +313,7 @@ declare const DrawerDescription: FC<DrawerDescriptionProps>;
|
|
|
288
313
|
|
|
289
314
|
declare const popoverContentVariants: (props?: ({
|
|
290
315
|
size?: "default" | "sm" | "lg" | null | undefined;
|
|
316
|
+
matchTriggerWidth?: boolean | null | undefined;
|
|
291
317
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
292
318
|
type PopoverProps = ComponentProps<typeof Root$9>;
|
|
293
319
|
declare const Popover: FC<PopoverProps>;
|
|
@@ -296,6 +322,7 @@ declare const PopoverTrigger: FC<PopoverTriggerProps>;
|
|
|
296
322
|
type PopoverContentProps = ComponentProps<typeof Content$2> & VariantProps<typeof popoverContentVariants> & {
|
|
297
323
|
arrow?: boolean;
|
|
298
324
|
withClose?: boolean;
|
|
325
|
+
matchTriggerWidth?: boolean;
|
|
299
326
|
};
|
|
300
327
|
declare const PopoverContent: FC<PopoverContentProps>;
|
|
301
328
|
type PopoverAnchorProps = ComponentProps<typeof Anchor>;
|
|
@@ -348,8 +375,8 @@ declare const Heading: react.ForwardRefExoticComponent<{
|
|
|
348
375
|
level?: HeadingLevel;
|
|
349
376
|
asChild?: boolean;
|
|
350
377
|
} & Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>, "ref"> & VariantProps<(props?: ({
|
|
351
|
-
level?:
|
|
352
|
-
weight?: "
|
|
378
|
+
level?: 2 | 1 | 3 | 4 | 5 | 6 | null | undefined;
|
|
379
|
+
weight?: "bold" | "medium" | "light" | "regular" | null | undefined;
|
|
353
380
|
align?: "center" | "right" | "left" | null | undefined;
|
|
354
381
|
color?: "default" | "destructive" | "secondary" | "muted" | "primary" | "accent" | null | undefined;
|
|
355
382
|
} & class_variance_authority_types.ClassProp) | undefined) => string> & react.RefAttributes<HTMLHeadingElement>>;
|
|
@@ -358,7 +385,7 @@ declare const Text: react.ForwardRefExoticComponent<{
|
|
|
358
385
|
asChild?: boolean;
|
|
359
386
|
} & Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & VariantProps<(props?: ({
|
|
360
387
|
type?: "body" | "small" | "tiny" | null | undefined;
|
|
361
|
-
weight?: "
|
|
388
|
+
weight?: "bold" | "medium" | "light" | "regular" | null | undefined;
|
|
362
389
|
align?: "center" | "right" | "left" | null | undefined;
|
|
363
390
|
color?: "default" | "destructive" | "secondary" | "muted" | "primary" | "accent" | null | undefined;
|
|
364
391
|
truncate?: boolean | null | undefined;
|
|
@@ -398,6 +425,8 @@ type CommandListProps = ComponentProps<typeof Command$1.List>;
|
|
|
398
425
|
declare const CommandList: FC<CommandListProps>;
|
|
399
426
|
type CommandEmptyProps = ComponentProps<typeof Command$1.Empty>;
|
|
400
427
|
declare const CommandEmpty: FC<CommandEmptyProps>;
|
|
428
|
+
type CommandLoadingProps = ComponentProps<typeof Command$1.Loading>;
|
|
429
|
+
declare const CommandLoading: FC<CommandLoadingProps>;
|
|
401
430
|
type CommandGroupProps = ComponentProps<typeof Command$1.Group>;
|
|
402
431
|
declare const CommandGroup: FC<CommandGroupProps>;
|
|
403
432
|
type CommandSeparatorProps = ComponentProps<typeof Command$1.Separator>;
|
|
@@ -525,7 +554,7 @@ type DropdownMenuContentProps = ComponentProps<typeof Content$4> & {
|
|
|
525
554
|
sideOffset?: number;
|
|
526
555
|
};
|
|
527
556
|
declare const DropdownMenuContent: FC<DropdownMenuContentProps>;
|
|
528
|
-
type DropdownMenuGroupProps = ComponentProps<typeof Group$
|
|
557
|
+
type DropdownMenuGroupProps = ComponentProps<typeof Group$2>;
|
|
529
558
|
declare const DropdownMenuGroup: FC<DropdownMenuGroupProps>;
|
|
530
559
|
type DropdownMenuItemProps = ComponentProps<typeof Item$3> & {
|
|
531
560
|
inset?: boolean;
|
|
@@ -1304,11 +1333,11 @@ declare const EmptyState: react.ForwardRefExoticComponent<Omit<{
|
|
|
1304
1333
|
inline?: boolean;
|
|
1305
1334
|
} & react.RefAttributes<HTMLDivElement>, "ref">>;
|
|
1306
1335
|
Title: FC<Omit<{
|
|
1307
|
-
level?:
|
|
1336
|
+
level?: 2 | 1 | 3 | 4 | 5 | 6;
|
|
1308
1337
|
asChild?: boolean;
|
|
1309
1338
|
} & Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>, "ref"> & class_variance_authority.VariantProps<(props?: ({
|
|
1310
|
-
level?:
|
|
1311
|
-
weight?: "
|
|
1339
|
+
level?: 2 | 1 | 3 | 4 | 5 | 6 | null | undefined;
|
|
1340
|
+
weight?: "bold" | "medium" | "light" | "regular" | null | undefined;
|
|
1312
1341
|
align?: "center" | "right" | "left" | null | undefined;
|
|
1313
1342
|
color?: "default" | "destructive" | "secondary" | "muted" | "primary" | "accent" | null | undefined;
|
|
1314
1343
|
} & class_variance_authority_types.ClassProp) | undefined) => string> & react.RefAttributes<HTMLHeadingElement>, "ref">>;
|
|
@@ -1316,7 +1345,7 @@ declare const EmptyState: react.ForwardRefExoticComponent<Omit<{
|
|
|
1316
1345
|
asChild?: boolean;
|
|
1317
1346
|
} & Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & class_variance_authority.VariantProps<(props?: ({
|
|
1318
1347
|
type?: "body" | "small" | "tiny" | null | undefined;
|
|
1319
|
-
weight?: "
|
|
1348
|
+
weight?: "bold" | "medium" | "light" | "regular" | null | undefined;
|
|
1320
1349
|
align?: "center" | "right" | "left" | null | undefined;
|
|
1321
1350
|
color?: "default" | "destructive" | "secondary" | "muted" | "primary" | "accent" | null | undefined;
|
|
1322
1351
|
truncate?: boolean | null | undefined;
|
|
@@ -1359,6 +1388,8 @@ declare const useScrollState: (containerRef: RefObject<HTMLElement | null>) => {
|
|
|
1359
1388
|
isScrolledToBottomCorner: boolean;
|
|
1360
1389
|
};
|
|
1361
1390
|
|
|
1391
|
+
declare function useDebounce<T>(value: T, delay: number): T;
|
|
1392
|
+
|
|
1362
1393
|
/**
|
|
1363
1394
|
* Creates function that execute callback functions together so that they are invoked in sequence
|
|
1364
1395
|
* with the same set of arguments.
|
|
@@ -1414,5 +1445,5 @@ interface Rect {
|
|
|
1414
1445
|
declare const DEFAULT_RECT: Rect;
|
|
1415
1446
|
declare const getBoundingRect: (node: HTMLElement) => Rect;
|
|
1416
1447
|
|
|
1417
|
-
export { Alert, AlertDescription, AlertTitle, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, Box, Button, Calendar, Checkbox, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, DEFAULT_RECT, DataTable, DatePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, Flex, Grid, Heading, Icon, IconButton, Input, Label, Link, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, StatusController, Switch, Table, TableBody, TableCaption, TableCell, TableContainer, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Text, Textarea, Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, addIf, assignRef, badgeVariants, buttonVariants, chain, getBoundingRect, mergeProps, mergeRefs, toggle, toggleVariants, useControlled, useFirstMountState, useForkRef, useLatest, usePrevious, useScrollState, useSidebar, useStateRef, useUpdateEffect };
|
|
1418
|
-
export type { BoxProps, ButtonProps, CalendarProps, CheckboxProps, Column, ColumnRenderer, DataTableProps, DialogProps, EmptyStateProps, FlexProps, GridProps, IconButtonProps, IconProps, InputProps, LabelProps, LinkProps, PopoverAnchorProps, PopoverContentProps, PopoverProps, PopoverTriggerProps, Rect, RowData, RowId, RowRenderer, StatusControllerProps, SwitchProps, TextareaProps, ToastActionElement, ToastProps, TooltipContentProps, TooltipProps, TooltipTriggerProps };
|
|
1448
|
+
export { Alert, AlertDescription, AlertTitle, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, Box, Button, Calendar, Checkbox, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandLoading, CommandSeparator, CommandShortcut, DEFAULT_RECT, DataTable, DatePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, Flex, Grid, Heading, Icon, IconButton, Input, Label, Link, MultiSelect, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, StatusController, Switch, Table, TableBody, TableCaption, TableCell, TableContainer, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Text, Textarea, Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, addIf, assignRef, badgeVariants, buttonVariants, chain, getBoundingRect, mergeProps, mergeRefs, toggle, toggleVariants, useControlled, useDebounce, useFirstMountState, useForkRef, useLatest, usePrevious, useScrollState, useSidebar, useStateRef, useUpdateEffect };
|
|
1449
|
+
export type { BoxProps, ButtonProps, CalendarProps, CheckboxProps, Column, ColumnRenderer, DataTableProps, DialogProps, EmptyStateProps, FlexProps, GridProps, Group, IconButtonProps, IconProps, InputProps, LabelProps, LinkProps, Option, PopoverAnchorProps, PopoverContentProps, PopoverProps, PopoverTriggerProps, Rect, RowData, RowId, RowRenderer, StatusControllerProps, SwitchProps, TextareaProps, ToastActionElement, ToastProps, TooltipContentProps, TooltipProps, TooltipTriggerProps };
|