periplo-ui 3.15.1 → 3.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -0
- package/dist/components/InlineMultiSelect/InlineMultiSelect.d.ts +62 -0
- package/dist/components/InlineMultiSelect/InlineMultiSelect.js +173 -0
- package/dist/components/InlineMultiSelect/InlineMultiSelect.js.map +1 -0
- package/dist/components/InlineMultiSelect/index.d.ts +1 -0
- package/dist/components/InlineMultiSelect/index.js +2 -0
- package/dist/components/InlineMultiSelect/index.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -74,6 +74,37 @@
|
|
|
74
74
|
|
|
75
75
|
- Refer to documentation for individual component usage and API reference: https://periplo-ui.vercel.app/?path=/docs/getting-started--docs
|
|
76
76
|
|
|
77
|
+
## 🔧 Local Storybook Package Installation
|
|
78
|
+
|
|
79
|
+
You can test this Storybook package locally before publishing by following these steps:
|
|
80
|
+
|
|
81
|
+
### 📦 In the Storybook project:
|
|
82
|
+
|
|
83
|
+
1. **Install dependencies:**
|
|
84
|
+
```bash
|
|
85
|
+
npm install
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
2. **Build the project (if needed):**
|
|
89
|
+
```bash
|
|
90
|
+
npm run build
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
3. **Package the project:**
|
|
94
|
+
This will generate a .tgz file in the project root.
|
|
95
|
+
```bash
|
|
96
|
+
npm pack
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 📥 In the target project:
|
|
100
|
+
|
|
101
|
+
1. **Install the package locally** (replace the path with your .tgz file path):
|
|
102
|
+
```bash
|
|
103
|
+
npm install /path/to/your/file/periplo-ui-1.0.0.tgz --force
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
⚠️ Make sure to use the correct absolute or relative path to the .tgz file generated with npm pack.
|
|
107
|
+
|
|
77
108
|
## Available Commands:
|
|
78
109
|
|
|
79
110
|
| Command | Description |
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ControllerFieldState } from 'react-hook-form';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
/** Represents a selectable option in the InlineMultiSelect */
|
|
4
|
+
type Option = {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
};
|
|
8
|
+
/** Props for the InlineMultiSelect component */
|
|
9
|
+
export type InlineMultiSelectProps = {
|
|
10
|
+
/** Array of options to display in the select */
|
|
11
|
+
options: Array<Option>;
|
|
12
|
+
/** Currently selected values (controlled) */
|
|
13
|
+
value?: Array<string>;
|
|
14
|
+
/** Callback fired when selection changes */
|
|
15
|
+
onChange?: (value: string[]) => void;
|
|
16
|
+
/** Form field state from react-hook-form */
|
|
17
|
+
fieldState?: ControllerFieldState;
|
|
18
|
+
/** Default selected values (uncontrolled) */
|
|
19
|
+
defaultValue?: Array<string>;
|
|
20
|
+
/** Placeholder text when no items are selected */
|
|
21
|
+
placeholder?: string;
|
|
22
|
+
/** Text to show when no options match the search */
|
|
23
|
+
notFoundText?: string;
|
|
24
|
+
/** Placeholder for the search input */
|
|
25
|
+
commandInputPlaceholder?: string;
|
|
26
|
+
/** Maximum number of items that can be selected */
|
|
27
|
+
max?: number;
|
|
28
|
+
/** Additional CSS classes */
|
|
29
|
+
className?: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* InlineMultiSelect Component
|
|
33
|
+
*
|
|
34
|
+
* A controlled multi-select component that displays selected items inline with search functionality.
|
|
35
|
+
* Supports keyboard navigation, maximum selection limit, and custom styling.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```tsx
|
|
39
|
+
* // Controlled usage
|
|
40
|
+
* const [value, setValue] = useState<string[]>([])
|
|
41
|
+
* <InlineMultiSelect
|
|
42
|
+
* options={[{ value: '1', label: 'Option 1' }]}
|
|
43
|
+
* value={value}
|
|
44
|
+
* onChange={setValue}
|
|
45
|
+
* />
|
|
46
|
+
*
|
|
47
|
+
* // With react-hook-form
|
|
48
|
+
* const { control } = useForm()
|
|
49
|
+
* <Controller
|
|
50
|
+
* name="myField"
|
|
51
|
+
* control={control}
|
|
52
|
+
* render={({ field }) => (
|
|
53
|
+
* <InlineMultiSelect
|
|
54
|
+
* {...field}
|
|
55
|
+
* options={options}
|
|
56
|
+
* />
|
|
57
|
+
* )}
|
|
58
|
+
* />
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare const InlineMultiSelect: React.ForwardRefExoticComponent<InlineMultiSelectProps & React.RefAttributes<HTMLInputElement>>;
|
|
62
|
+
export {};
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem } from '../Command/Command.js';
|
|
5
|
+
import { X, CaretUpDown, Check } from '@phosphor-icons/react';
|
|
6
|
+
import { PopoverRoot, PopoverTrigger, PopoverContent } from '../Popover/Popover.js';
|
|
7
|
+
import { cn } from '../../lib/utils.js';
|
|
8
|
+
import { Button } from '../Button/Button.js';
|
|
9
|
+
|
|
10
|
+
const InlineMultiSelect = React.forwardRef(
|
|
11
|
+
({
|
|
12
|
+
options,
|
|
13
|
+
value,
|
|
14
|
+
onChange,
|
|
15
|
+
defaultValue,
|
|
16
|
+
placeholder,
|
|
17
|
+
notFoundText,
|
|
18
|
+
fieldState,
|
|
19
|
+
commandInputPlaceholder,
|
|
20
|
+
max,
|
|
21
|
+
className
|
|
22
|
+
}, _ref) => {
|
|
23
|
+
const inputRef = React.useRef(null);
|
|
24
|
+
const containerRef = React.useRef(null);
|
|
25
|
+
const [open, setOpen] = React.useState(false);
|
|
26
|
+
const [inputValue, setInputValue] = React.useState("");
|
|
27
|
+
const [visibleItems, setVisibleItems] = React.useState([]);
|
|
28
|
+
const [hiddenCount, setHiddenCount] = React.useState(0);
|
|
29
|
+
const [internalSelected, setInternalSelected] = React.useState(
|
|
30
|
+
options.filter((option) => defaultValue?.includes(option.value) ?? [])
|
|
31
|
+
);
|
|
32
|
+
const selected = value ? options.filter((option) => value.includes(option.value)) : internalSelected;
|
|
33
|
+
const handleSelectionChange = React.useCallback(
|
|
34
|
+
(newSelected) => {
|
|
35
|
+
if (!value) {
|
|
36
|
+
setInternalSelected(newSelected);
|
|
37
|
+
}
|
|
38
|
+
onChange?.(newSelected.map((s) => s.value));
|
|
39
|
+
},
|
|
40
|
+
[value, onChange]
|
|
41
|
+
);
|
|
42
|
+
const removeItem = React.useCallback(
|
|
43
|
+
(itemToRemove) => {
|
|
44
|
+
const newSelected = itemToRemove ? selected.filter((s) => s.value !== itemToRemove.value) : selected.slice(0, -1);
|
|
45
|
+
handleSelectionChange(newSelected);
|
|
46
|
+
},
|
|
47
|
+
[selected, handleSelectionChange]
|
|
48
|
+
);
|
|
49
|
+
const handleUnselect = React.useCallback(
|
|
50
|
+
(item, e) => {
|
|
51
|
+
e.stopPropagation();
|
|
52
|
+
e.preventDefault();
|
|
53
|
+
removeItem(item);
|
|
54
|
+
},
|
|
55
|
+
[removeItem]
|
|
56
|
+
);
|
|
57
|
+
const handleKeyDown = React.useCallback(
|
|
58
|
+
(e) => {
|
|
59
|
+
const input = inputRef.current;
|
|
60
|
+
if (input) {
|
|
61
|
+
if ((e.key === "Delete" || e.key === "Backspace") && input.value === "") {
|
|
62
|
+
removeItem();
|
|
63
|
+
}
|
|
64
|
+
if (e.key === "Escape") {
|
|
65
|
+
input.blur();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
[removeItem]
|
|
70
|
+
);
|
|
71
|
+
React.useEffect(() => {
|
|
72
|
+
const updateVisibleItems = () => {
|
|
73
|
+
if (!containerRef.current || selected.length === 0) return;
|
|
74
|
+
const maxVisibleItems = 2;
|
|
75
|
+
const visibleCount = Math.min(selected.length, maxVisibleItems);
|
|
76
|
+
setVisibleItems(selected.slice(0, visibleCount));
|
|
77
|
+
setHiddenCount(selected.length - visibleCount);
|
|
78
|
+
};
|
|
79
|
+
updateVisibleItems();
|
|
80
|
+
window.addEventListener("resize", updateVisibleItems);
|
|
81
|
+
return () => window.removeEventListener("resize", updateVisibleItems);
|
|
82
|
+
}, [selected]);
|
|
83
|
+
return /* @__PURE__ */ jsx(PopoverRoot, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxs(Command, { onKeyDown: handleKeyDown, children: [
|
|
84
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
85
|
+
Button,
|
|
86
|
+
{
|
|
87
|
+
variant: "ghost",
|
|
88
|
+
"aria-expanded": open,
|
|
89
|
+
className: cn(
|
|
90
|
+
"w-full justify-between bg-[#fff] pl-2 pr-2",
|
|
91
|
+
fieldState?.invalid ? "border-error-400 focus-within:border-error-700" : "",
|
|
92
|
+
className
|
|
93
|
+
),
|
|
94
|
+
children: [
|
|
95
|
+
/* @__PURE__ */ jsx("div", { ref: containerRef, className: "flex flex-1 flex-wrap items-center gap-1 overflow-hidden pr-2", children: /* @__PURE__ */ jsx("div", { className: "flex items-center whitespace-nowrap", children: selected.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
96
|
+
visibleItems.map((item) => /* @__PURE__ */ jsxs("div", { className: "bg-muted flex items-center gap-1 rounded px-1 py-0.5", children: [
|
|
97
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm", children: item.label }),
|
|
98
|
+
/* @__PURE__ */ jsx(
|
|
99
|
+
"span",
|
|
100
|
+
{
|
|
101
|
+
role: "button",
|
|
102
|
+
tabIndex: 0,
|
|
103
|
+
onClick: (e) => handleUnselect(item, e),
|
|
104
|
+
onKeyDown: (e) => {
|
|
105
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
106
|
+
handleUnselect(item, e);
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
"aria-label": `Eliminar ${item.label}`,
|
|
110
|
+
className: "hover:bg-muted-foreground/20 flex h-4 w-4 items-center justify-center rounded-full",
|
|
111
|
+
children: /* @__PURE__ */ jsx(X, { className: "text-muted-foreground h-3 w-3" })
|
|
112
|
+
}
|
|
113
|
+
)
|
|
114
|
+
] }, item.value)),
|
|
115
|
+
hiddenCount > 0 && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground inline-flex flex-shrink-0 items-center whitespace-nowrap text-sm", children: [
|
|
116
|
+
"+",
|
|
117
|
+
hiddenCount
|
|
118
|
+
] })
|
|
119
|
+
] }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: placeholder }) }) }),
|
|
120
|
+
/* @__PURE__ */ jsx(CaretUpDown, { className: "h-4 w-4 shrink-0 opacity-50" })
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
) }),
|
|
124
|
+
/* @__PURE__ */ jsxs(PopoverContent, { className: "px-0 py-0", children: [
|
|
125
|
+
/* @__PURE__ */ jsx(
|
|
126
|
+
CommandInput,
|
|
127
|
+
{
|
|
128
|
+
placeholder: commandInputPlaceholder ?? "Search...",
|
|
129
|
+
value: inputValue,
|
|
130
|
+
onValueChange: setInputValue,
|
|
131
|
+
children: max && /* @__PURE__ */ jsxs("div", { className: "bg-muted rounded-md px-2 py-1 text-sm", children: [
|
|
132
|
+
selected.length,
|
|
133
|
+
" / ",
|
|
134
|
+
max
|
|
135
|
+
] })
|
|
136
|
+
}
|
|
137
|
+
),
|
|
138
|
+
/* @__PURE__ */ jsxs(CommandList, { children: [
|
|
139
|
+
/* @__PURE__ */ jsx(CommandEmpty, { children: notFoundText ?? "Options not found" }),
|
|
140
|
+
open && options.length > 0 && /* @__PURE__ */ jsx(CommandGroup, { children: options.map((item) => /* @__PURE__ */ jsx(
|
|
141
|
+
CommandItem,
|
|
142
|
+
{
|
|
143
|
+
onMouseDown: (e) => {
|
|
144
|
+
e.preventDefault();
|
|
145
|
+
e.stopPropagation();
|
|
146
|
+
},
|
|
147
|
+
onSelect: () => {
|
|
148
|
+
const isSelected = selected.find((s) => s.value === item.value);
|
|
149
|
+
if (isSelected) {
|
|
150
|
+
handleSelectionChange(selected.filter((s) => s.value !== item.value));
|
|
151
|
+
} else {
|
|
152
|
+
if (max && selected.length >= max) return;
|
|
153
|
+
setInputValue("");
|
|
154
|
+
handleSelectionChange([...selected, item]);
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
className: "cursor-pointer",
|
|
158
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
159
|
+
/* @__PURE__ */ jsx("div", { className: "mr-2", children: selected.find((s) => s.value === item.value) ? /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx("div", { className: "h-4 w-4" }) }),
|
|
160
|
+
/* @__PURE__ */ jsx("div", { children: item.label })
|
|
161
|
+
] })
|
|
162
|
+
},
|
|
163
|
+
`item-${item.value}`
|
|
164
|
+
)) })
|
|
165
|
+
] })
|
|
166
|
+
] })
|
|
167
|
+
] }) });
|
|
168
|
+
}
|
|
169
|
+
);
|
|
170
|
+
InlineMultiSelect.displayName = "InlineMultiSelect";
|
|
171
|
+
|
|
172
|
+
export { InlineMultiSelect };
|
|
173
|
+
//# sourceMappingURL=InlineMultiSelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InlineMultiSelect.js","sources":["../../../src/components/InlineMultiSelect/InlineMultiSelect.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '../Command'\nimport { CaretUpDown, Check, X } from '@phosphor-icons/react'\nimport { PopoverRoot, PopoverContent, PopoverTrigger } from '../Popover'\nimport { ControllerFieldState } from 'react-hook-form'\nimport { cn } from '@/lib/utils'\nimport { Button } from '../Button'\n\n/** Represents a selectable option in the InlineMultiSelect */\ntype Option = { value: string; label: string }\n\n/** Props for the InlineMultiSelect component */\nexport type InlineMultiSelectProps = {\n /** Array of options to display in the select */\n options: Array<Option>\n /** Currently selected values (controlled) */\n value?: Array<string>\n /** Callback fired when selection changes */\n onChange?: (value: string[]) => void\n /** Form field state from react-hook-form */\n fieldState?: ControllerFieldState\n /** Default selected values (uncontrolled) */\n defaultValue?: Array<string>\n /** Placeholder text when no items are selected */\n placeholder?: string\n /** Text to show when no options match the search */\n notFoundText?: string\n /** Placeholder for the search input */\n commandInputPlaceholder?: string\n /** Maximum number of items that can be selected */\n max?: number\n /** Additional CSS classes */\n className?: string\n}\n\n/**\n * InlineMultiSelect Component\n *\n * A controlled multi-select component that displays selected items inline with search functionality.\n * Supports keyboard navigation, maximum selection limit, and custom styling.\n *\n * @example\n * ```tsx\n * // Controlled usage\n * const [value, setValue] = useState<string[]>([])\n * <InlineMultiSelect\n * options={[{ value: '1', label: 'Option 1' }]}\n * value={value}\n * onChange={setValue}\n * />\n *\n * // With react-hook-form\n * const { control } = useForm()\n * <Controller\n * name=\"myField\"\n * control={control}\n * render={({ field }) => (\n * <InlineMultiSelect\n * {...field}\n * options={options}\n * />\n * )}\n * />\n * ```\n */\nexport const InlineMultiSelect = React.forwardRef<HTMLInputElement, InlineMultiSelectProps>(\n (\n {\n options,\n value,\n onChange,\n defaultValue,\n placeholder,\n notFoundText,\n fieldState,\n commandInputPlaceholder,\n max,\n className,\n },\n _ref,\n ) => {\n const inputRef = React.useRef<HTMLInputElement>(null)\n const containerRef = React.useRef<HTMLDivElement>(null)\n const [open, setOpen] = React.useState(false)\n const [inputValue, setInputValue] = React.useState('')\n const [visibleItems, setVisibleItems] = React.useState<Option[]>([])\n const [hiddenCount, setHiddenCount] = React.useState(0)\n\n // Use controlled value if provided, otherwise use internal state\n const [internalSelected, setInternalSelected] = React.useState<InlineMultiSelectProps['options']>(\n options.filter((option) => defaultValue?.includes(option.value) ?? []),\n )\n\n const selected = value ? options.filter((option) => value.includes(option.value)) : internalSelected\n\n const handleSelectionChange = React.useCallback(\n (newSelected: Option[]) => {\n if (!value) {\n // Uncontrolled mode\n setInternalSelected(newSelected)\n }\n // Always call onChange with the new values\n onChange?.(newSelected.map((s) => s.value))\n },\n [value, onChange],\n )\n\n /**\n * Removes an item from the selection\n * @param itemToRemove - Optional item to remove. If not provided, removes the last item\n */\n const removeItem = React.useCallback(\n (itemToRemove?: Option) => {\n const newSelected = itemToRemove\n ? selected.filter((s) => s.value !== itemToRemove.value)\n : selected.slice(0, -1)\n\n handleSelectionChange(newSelected)\n },\n [selected, handleSelectionChange],\n )\n\n /**\n * Handles the unselect action when clicking the remove button\n * @param item - The item to remove\n * @param e - The event object\n */\n const handleUnselect = React.useCallback(\n (item: Option, e: React.MouseEvent | React.KeyboardEvent) => {\n e.stopPropagation()\n e.preventDefault()\n removeItem(item)\n },\n [removeItem],\n )\n\n /**\n * Handles keyboard events for the component\n * - Delete/Backspace: Removes last item when input is empty\n * - Escape: Blurs the input\n */\n const handleKeyDown = React.useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>) => {\n const input = inputRef.current\n if (input) {\n if ((e.key === 'Delete' || e.key === 'Backspace') && input.value === '') {\n removeItem()\n }\n if (e.key === 'Escape') {\n input.blur()\n }\n }\n },\n [removeItem],\n )\n\n /**\n * Effect to update visible items and handle responsive behavior\n * Shows a maximum of 2 items and displays a count for the rest\n */\n React.useEffect(() => {\n const updateVisibleItems = () => {\n if (!containerRef.current || selected.length === 0) return\n\n const maxVisibleItems = 2\n const visibleCount = Math.min(selected.length, maxVisibleItems)\n\n setVisibleItems(selected.slice(0, visibleCount))\n setHiddenCount(selected.length - visibleCount)\n }\n\n updateVisibleItems()\n window.addEventListener('resize', updateVisibleItems)\n return () => window.removeEventListener('resize', updateVisibleItems)\n }, [selected])\n\n return (\n <PopoverRoot open={open} onOpenChange={setOpen}>\n <Command onKeyDown={handleKeyDown}>\n <PopoverTrigger asChild>\n <Button\n variant=\"ghost\"\n aria-expanded={open}\n className={cn(\n 'w-full justify-between bg-[#fff] pl-2 pr-2',\n fieldState?.invalid ? 'border-error-400 focus-within:border-error-700' : '',\n className,\n )}\n >\n <div ref={containerRef} className=\"flex flex-1 flex-wrap items-center gap-1 overflow-hidden pr-2\">\n <div className=\"flex items-center whitespace-nowrap\">\n {selected.length > 0 ? (\n <>\n {visibleItems.map((item) => (\n <div key={item.value} className=\"bg-muted flex items-center gap-1 rounded px-1 py-0.5\">\n <span className=\"text-sm\">{item.label}</span>\n <span\n role=\"button\"\n tabIndex={0}\n onClick={(e) => handleUnselect(item, e)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n handleUnselect(item, e)\n }\n }}\n aria-label={`Eliminar ${item.label}`}\n className=\"hover:bg-muted-foreground/20 flex h-4 w-4 items-center justify-center rounded-full\"\n >\n <X className=\"text-muted-foreground h-3 w-3\" />\n </span>\n </div>\n ))}\n {hiddenCount > 0 && (\n <span className=\"text-muted-foreground inline-flex flex-shrink-0 items-center whitespace-nowrap text-sm\">\n +{hiddenCount}\n </span>\n )}\n </>\n ) : (\n <span className=\"text-muted-foreground\">{placeholder}</span>\n )}\n </div>\n </div>\n <CaretUpDown className=\"h-4 w-4 shrink-0 opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"px-0 py-0\">\n <CommandInput\n placeholder={commandInputPlaceholder ?? 'Search...'}\n value={inputValue}\n onValueChange={setInputValue}\n >\n {max && (\n <div className=\"bg-muted rounded-md px-2 py-1 text-sm\">\n {selected.length} / {max}\n </div>\n )}\n </CommandInput>\n <CommandList>\n <CommandEmpty>{notFoundText ?? 'Options not found'}</CommandEmpty>\n {open && options.length > 0 && (\n <CommandGroup>\n {options.map((item) => (\n <CommandItem\n key={`item-${item.value}`}\n onMouseDown={(e) => {\n e.preventDefault()\n e.stopPropagation()\n }}\n onSelect={() => {\n const isSelected = selected.find((s) => s.value === item.value)\n if (isSelected) {\n handleSelectionChange(selected.filter((s) => s.value !== item.value))\n } else {\n if (max && selected.length >= max) return\n setInputValue('')\n handleSelectionChange([...selected, item])\n }\n }}\n className=\"cursor-pointer\"\n >\n <div className=\"flex items-center\">\n <div className=\"mr-2\">\n {selected.find((s) => s.value === item.value) ? (\n <Check className=\"h-4 w-4\" />\n ) : (\n <div className=\"h-4 w-4\" />\n )}\n </div>\n <div>{item.label}</div>\n </div>\n </CommandItem>\n ))}\n </CommandGroup>\n )}\n </CommandList>\n </PopoverContent>\n </Command>\n </PopoverRoot>\n )\n },\n)\n\nInlineMultiSelect.displayName = 'InlineMultiSelect'\n"],"names":[],"mappings":";;;;;;;;;AAmEO;AAAgC;AAEnC;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIF;AACA;AACA;AACA;AACA;AACA;AAGA;AAAsD;AACiB;AAGvE;AAEA;AAAoC;AAEhC;AAEE;AAA+B;AAGjC;AAA0C;AAC5C;AACgB;AAOlB;AAAyB;AAErB;AAIA;AAAiC;AACnC;AACgC;AAQlC;AAA6B;AAEzB;AACA;AACA;AAAe;AACjB;AACW;AAQb;AAA4B;AAExB;AACA;AACE;AACE;AAAW;AAEb;AACE;AAAW;AACb;AACF;AACF;AACW;AAOb;AACE;AACE;AAEA;AACA;AAEA;AACA;AAA6C;AAG/C;AACA;AACA;AAAoE;AAGtE;AAGM;AACE;AAAC;AAAA;AACS;AACO;AACJ;AACT;AACyE;AACzE;AACF;AAEA;AAIS;AAEG;AAAsC;AACtC;AAAC;AAAA;AACM;AACK;AAC4B;AAEpC;AACE;AAAsB;AACxB;AACF;AACkC;AACxB;AAEmC;AAAA;AAC/C;AAEH;AAE0G;AAAA;AACrG;AACJ;AAOV;AACqD;AAAA;AAAA;AAEzD;AAEE;AAAA;AAAC;AAAA;AACyC;AACjC;AACQ;AAIV;AAAS;AAAO;AAAI;AACvB;AAAA;AAEJ;AAEE;AAAmD;AAI7C;AAAC;AAAA;AAGG;AACA;AAAkB;AACpB;AAEE;AACA;AACE;AAAoE;AAEpE;AACA;AACA;AAAyC;AAC3C;AACF;AACU;AAGR;AAMA;AACiB;AACnB;AAAA;AA1BuB;AA6B7B;AAEJ;AACF;AAEJ;AAGN;AAEA;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './InlineMultiSelect';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -38,4 +38,5 @@ export { SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, Sideba
|
|
|
38
38
|
export { Combobox } from './components/Combobox/Combobox.js';
|
|
39
39
|
export { DataTable } from './components/DataTable/DataTable.js';
|
|
40
40
|
export { CollapsibleContent, CollapsibleRoot, CollapsibleTrigger } from './components/Collapsible/Collapsible.js';
|
|
41
|
+
export { InlineMultiSelect } from './components/InlineMultiSelect/InlineMultiSelect.js';
|
|
41
42
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|