@mdigital_ui/ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +296 -0
- package/dist/accordion/index.js +5 -0
- package/dist/accordion/index.js.map +1 -0
- package/dist/badge/index.js +5 -0
- package/dist/badge/index.js.map +1 -0
- package/dist/button/index.js +6 -0
- package/dist/button/index.js.map +1 -0
- package/dist/card/index.js +4 -0
- package/dist/card/index.js.map +1 -0
- package/dist/carousel/index.js +3 -0
- package/dist/carousel/index.js.map +1 -0
- package/dist/cascader/index.js +4 -0
- package/dist/cascader/index.js.map +1 -0
- package/dist/chart/index.js +4 -0
- package/dist/chart/index.js.map +1 -0
- package/dist/checkbox/index.js +5 -0
- package/dist/checkbox/index.js.map +1 -0
- package/dist/checkbox-group/index.js +4 -0
- package/dist/checkbox-group/index.js.map +1 -0
- package/dist/chunk-2JGAYDZR.js +181 -0
- package/dist/chunk-2JGAYDZR.js.map +1 -0
- package/dist/chunk-3PFA3YG6.js +228 -0
- package/dist/chunk-3PFA3YG6.js.map +1 -0
- package/dist/chunk-4OMLQCUV.js +96 -0
- package/dist/chunk-4OMLQCUV.js.map +1 -0
- package/dist/chunk-4P5EMRFI.js +298 -0
- package/dist/chunk-4P5EMRFI.js.map +1 -0
- package/dist/chunk-5UEWVFF6.js +212 -0
- package/dist/chunk-5UEWVFF6.js.map +1 -0
- package/dist/chunk-5VCGW53O.js +332 -0
- package/dist/chunk-5VCGW53O.js.map +1 -0
- package/dist/chunk-75XESYGN.js +49 -0
- package/dist/chunk-75XESYGN.js.map +1 -0
- package/dist/chunk-7AEGBABZ.js +1102 -0
- package/dist/chunk-7AEGBABZ.js.map +1 -0
- package/dist/chunk-AOITJRSV.js +134 -0
- package/dist/chunk-AOITJRSV.js.map +1 -0
- package/dist/chunk-AWPKZYHT.js +152 -0
- package/dist/chunk-AWPKZYHT.js.map +1 -0
- package/dist/chunk-BNILRB4T.js +37 -0
- package/dist/chunk-BNILRB4T.js.map +1 -0
- package/dist/chunk-BP434VYV.js +448 -0
- package/dist/chunk-BP434VYV.js.map +1 -0
- package/dist/chunk-C7SXY3ZV.js +65 -0
- package/dist/chunk-C7SXY3ZV.js.map +1 -0
- package/dist/chunk-CLLQDCDR.js +560 -0
- package/dist/chunk-CLLQDCDR.js.map +1 -0
- package/dist/chunk-CWHFK7ZC.js +128 -0
- package/dist/chunk-CWHFK7ZC.js.map +1 -0
- package/dist/chunk-D3JWPGCA.js +123 -0
- package/dist/chunk-D3JWPGCA.js.map +1 -0
- package/dist/chunk-DOKTHDG3.js +55 -0
- package/dist/chunk-DOKTHDG3.js.map +1 -0
- package/dist/chunk-DPOSWW22.js +126 -0
- package/dist/chunk-DPOSWW22.js.map +1 -0
- package/dist/chunk-E2CYDDYC.js +39 -0
- package/dist/chunk-E2CYDDYC.js.map +1 -0
- package/dist/chunk-EYTOKUBM.js +401 -0
- package/dist/chunk-EYTOKUBM.js.map +1 -0
- package/dist/chunk-FGWSUPVW.js +356 -0
- package/dist/chunk-FGWSUPVW.js.map +1 -0
- package/dist/chunk-FPOXTCYV.js +166 -0
- package/dist/chunk-FPOXTCYV.js.map +1 -0
- package/dist/chunk-FTJOSVTY.js +104 -0
- package/dist/chunk-FTJOSVTY.js.map +1 -0
- package/dist/chunk-FYHQDFKE.js +164 -0
- package/dist/chunk-FYHQDFKE.js.map +1 -0
- package/dist/chunk-H2HIBD5Y.js +158 -0
- package/dist/chunk-H2HIBD5Y.js.map +1 -0
- package/dist/chunk-J3G5WWGR.js +53 -0
- package/dist/chunk-J3G5WWGR.js.map +1 -0
- package/dist/chunk-JZCHZ4B3.js +487 -0
- package/dist/chunk-JZCHZ4B3.js.map +1 -0
- package/dist/chunk-KBCBVH7B.js +51 -0
- package/dist/chunk-KBCBVH7B.js.map +1 -0
- package/dist/chunk-KNQ7UQ2W.js +143 -0
- package/dist/chunk-KNQ7UQ2W.js.map +1 -0
- package/dist/chunk-KTBPIEP2.js +102 -0
- package/dist/chunk-KTBPIEP2.js.map +1 -0
- package/dist/chunk-L3SP7GHC.js +1023 -0
- package/dist/chunk-L3SP7GHC.js.map +1 -0
- package/dist/chunk-LBJG2UWT.js +100 -0
- package/dist/chunk-LBJG2UWT.js.map +1 -0
- package/dist/chunk-MLDX3Z67.js +470 -0
- package/dist/chunk-MLDX3Z67.js.map +1 -0
- package/dist/chunk-NNSS366W.js +331 -0
- package/dist/chunk-NNSS366W.js.map +1 -0
- package/dist/chunk-OQANRZPV.js +197 -0
- package/dist/chunk-OQANRZPV.js.map +1 -0
- package/dist/chunk-OW5A5IIF.js +175 -0
- package/dist/chunk-OW5A5IIF.js.map +1 -0
- package/dist/chunk-R225A5II.js +187 -0
- package/dist/chunk-R225A5II.js.map +1 -0
- package/dist/chunk-ROR4E6IE.js +119 -0
- package/dist/chunk-ROR4E6IE.js.map +1 -0
- package/dist/chunk-RPAQAZTI.js +54 -0
- package/dist/chunk-RPAQAZTI.js.map +1 -0
- package/dist/chunk-RQBXZKTH.js +452 -0
- package/dist/chunk-RQBXZKTH.js.map +1 -0
- package/dist/chunk-S5XJXU52.js +178 -0
- package/dist/chunk-S5XJXU52.js.map +1 -0
- package/dist/chunk-SAVE5ACL.js +324 -0
- package/dist/chunk-SAVE5ACL.js.map +1 -0
- package/dist/chunk-SERJ3TZE.js +640 -0
- package/dist/chunk-SERJ3TZE.js.map +1 -0
- package/dist/chunk-SK5ECBBK.js +175 -0
- package/dist/chunk-SK5ECBBK.js.map +1 -0
- package/dist/chunk-SOV4PE3P.js +218 -0
- package/dist/chunk-SOV4PE3P.js.map +1 -0
- package/dist/chunk-W7BQYIXF.js +687 -0
- package/dist/chunk-W7BQYIXF.js.map +1 -0
- package/dist/chunk-XMAH5PDW.js +59 -0
- package/dist/chunk-XMAH5PDW.js.map +1 -0
- package/dist/chunk-XOBGEMQY.js +94 -0
- package/dist/chunk-XOBGEMQY.js.map +1 -0
- package/dist/chunk-YNNAOXU5.js +57 -0
- package/dist/chunk-YNNAOXU5.js.map +1 -0
- package/dist/chunk-YZVSDRJD.js +253 -0
- package/dist/chunk-YZVSDRJD.js.map +1 -0
- package/dist/collapse/index.js +4 -0
- package/dist/collapse/index.js.map +1 -0
- package/dist/command/index.js +5 -0
- package/dist/command/index.js.map +1 -0
- package/dist/date-picker/index.js +5 -0
- package/dist/date-picker/index.js.map +1 -0
- package/dist/descriptions/index.js +4 -0
- package/dist/descriptions/index.js.map +1 -0
- package/dist/drawer/index.js +4 -0
- package/dist/drawer/index.js.map +1 -0
- package/dist/dropdown/index.js +5 -0
- package/dist/dropdown/index.js.map +1 -0
- package/dist/empty/index.js +4 -0
- package/dist/empty/index.js.map +1 -0
- package/dist/fetching-overlay/index.js +5 -0
- package/dist/fetching-overlay/index.js.map +1 -0
- package/dist/image/index.js +4 -0
- package/dist/image/index.js.map +1 -0
- package/dist/index.d.ts +2672 -0
- package/dist/index.js +976 -0
- package/dist/index.js.map +1 -0
- package/dist/input/index.js +5 -0
- package/dist/input/index.js.map +1 -0
- package/dist/input-group/index.js +4 -0
- package/dist/input-group/index.js.map +1 -0
- package/dist/input-otp/index.js +4 -0
- package/dist/input-otp/index.js.map +1 -0
- package/dist/input-password/index.js +6 -0
- package/dist/input-password/index.js.map +1 -0
- package/dist/kbd/index.js +4 -0
- package/dist/kbd/index.js.map +1 -0
- package/dist/modal/index.js +4 -0
- package/dist/modal/index.js.map +1 -0
- package/dist/multi-select/index.js +5 -0
- package/dist/multi-select/index.js.map +1 -0
- package/dist/notification/index.js +4 -0
- package/dist/notification/index.js.map +1 -0
- package/dist/pagination/index.js +4 -0
- package/dist/pagination/index.js.map +1 -0
- package/dist/popover/index.js +4 -0
- package/dist/popover/index.js.map +1 -0
- package/dist/progress/index.js +4 -0
- package/dist/progress/index.js.map +1 -0
- package/dist/radio/index.js +4 -0
- package/dist/radio/index.js.map +1 -0
- package/dist/radio-group/index.js +4 -0
- package/dist/radio-group/index.js.map +1 -0
- package/dist/rating/index.js +4 -0
- package/dist/rating/index.js.map +1 -0
- package/dist/ribbon/index.js +4 -0
- package/dist/ribbon/index.js.map +1 -0
- package/dist/select/index.js +6 -0
- package/dist/select/index.js.map +1 -0
- package/dist/skeleton/index.js +4 -0
- package/dist/skeleton/index.js.map +1 -0
- package/dist/slider/index.js +4 -0
- package/dist/slider/index.js.map +1 -0
- package/dist/spinner/index.js +4 -0
- package/dist/spinner/index.js.map +1 -0
- package/dist/stepper/index.js +4 -0
- package/dist/stepper/index.js.map +1 -0
- package/dist/styles/base.css +161 -0
- package/dist/styles/global.css +633 -0
- package/dist/styles/themes/dark.css +84 -0
- package/dist/styles/themes/light.css +84 -0
- package/dist/switch/index.js +4 -0
- package/dist/switch/index.js.map +1 -0
- package/dist/table/index.js +12 -0
- package/dist/table/index.js.map +1 -0
- package/dist/tabs/index.js +5 -0
- package/dist/tabs/index.js.map +1 -0
- package/dist/textarea/index.js +4 -0
- package/dist/textarea/index.js.map +1 -0
- package/dist/toggle/index.js +4 -0
- package/dist/toggle/index.js.map +1 -0
- package/dist/toggle-group/index.js +4 -0
- package/dist/toggle-group/index.js.map +1 -0
- package/dist/tooltip/index.js +4 -0
- package/dist/tooltip/index.js.map +1 -0
- package/dist/transfer/index.js +6 -0
- package/dist/transfer/index.js.map +1 -0
- package/dist/tree/index.js +4 -0
- package/dist/tree/index.js.map +1 -0
- package/dist/tree-select/index.js +6 -0
- package/dist/tree-select/index.js.map +1 -0
- package/package.json +107 -0
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
import { tree_default } from './chunk-SAVE5ACL.js';
|
|
2
|
+
import { Popover, PopoverTrigger, PopoverContent } from './chunk-3PFA3YG6.js';
|
|
3
|
+
import { getValidationStatus, cn, iconSizes, statusMessageVariants } from './chunk-YNNAOXU5.js';
|
|
4
|
+
import { cva } from 'class-variance-authority';
|
|
5
|
+
import { X, Loader2, Search, ChevronDown } from 'lucide-react';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
|
+
|
|
9
|
+
var treeSelectTriggerVariants = cva(
|
|
10
|
+
"w-full flex items-center justify-between rounded-md bg-background text-text-primary border focus:border-primary outline-none disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer transition-colors",
|
|
11
|
+
{
|
|
12
|
+
variants: {
|
|
13
|
+
status: {
|
|
14
|
+
default: "border-border hover:border-primary/50",
|
|
15
|
+
error: "border-error",
|
|
16
|
+
warning: "border-warning",
|
|
17
|
+
info: "border-info",
|
|
18
|
+
success: "border-success"
|
|
19
|
+
},
|
|
20
|
+
size: {
|
|
21
|
+
xs: "h-8 px-2 text-sm gap-2",
|
|
22
|
+
sm: "h-[var(--input-height-sm)] px-1 text-sm gap-2",
|
|
23
|
+
md: "h-[var(--input-height-md)] px-2 text-base gap-2",
|
|
24
|
+
lg: "h-[var(--input-height-lg)] px-3 text-lg gap-3"
|
|
25
|
+
},
|
|
26
|
+
fullWidth: {
|
|
27
|
+
true: "w-full",
|
|
28
|
+
false: "max-w-full"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
defaultVariants: {
|
|
32
|
+
status: "default",
|
|
33
|
+
size: "md",
|
|
34
|
+
fullWidth: true
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
var TreeSelect = React.memo(
|
|
39
|
+
({
|
|
40
|
+
size = "md",
|
|
41
|
+
label,
|
|
42
|
+
helperText,
|
|
43
|
+
error,
|
|
44
|
+
warning,
|
|
45
|
+
info,
|
|
46
|
+
success,
|
|
47
|
+
data = [],
|
|
48
|
+
placeholder = "Select an option",
|
|
49
|
+
loading = false,
|
|
50
|
+
fullWidth = true,
|
|
51
|
+
value,
|
|
52
|
+
defaultValue,
|
|
53
|
+
onChange,
|
|
54
|
+
disabled,
|
|
55
|
+
required,
|
|
56
|
+
multiple = false,
|
|
57
|
+
checkable = false,
|
|
58
|
+
searchable = true,
|
|
59
|
+
maxChipsVisible = 3,
|
|
60
|
+
maxDropdownHeight = 300,
|
|
61
|
+
defaultExpandAll = false,
|
|
62
|
+
defaultExpandedKeys = [],
|
|
63
|
+
showLine = false,
|
|
64
|
+
showIcon = true,
|
|
65
|
+
className,
|
|
66
|
+
ref,
|
|
67
|
+
...props
|
|
68
|
+
}) => {
|
|
69
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
70
|
+
const [internalValue, setInternalValue] = React.useState(
|
|
71
|
+
defaultValue || (multiple ? [] : "")
|
|
72
|
+
);
|
|
73
|
+
const [searchQuery, setSearchQuery] = React.useState("");
|
|
74
|
+
const [expandedKeys, setExpandedKeys] = React.useState(
|
|
75
|
+
defaultExpandAll ? [] : defaultExpandedKeys
|
|
76
|
+
);
|
|
77
|
+
const [visibleChipsCount, setVisibleChipsCount] = React.useState(maxChipsVisible);
|
|
78
|
+
const triggerRef = React.useRef(null);
|
|
79
|
+
const inputRef = React.useRef(null);
|
|
80
|
+
const currentValue = value !== void 0 ? value : internalValue;
|
|
81
|
+
const { status, message: helperMessage } = getValidationStatus({
|
|
82
|
+
error,
|
|
83
|
+
warning,
|
|
84
|
+
info,
|
|
85
|
+
success,
|
|
86
|
+
helperText
|
|
87
|
+
});
|
|
88
|
+
const getAllNodes = React.useCallback((nodes) => {
|
|
89
|
+
const result = [];
|
|
90
|
+
const traverse = (items) => {
|
|
91
|
+
items.forEach((item) => {
|
|
92
|
+
result.push(item);
|
|
93
|
+
if (item.children) {
|
|
94
|
+
traverse(item.children);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
traverse(nodes);
|
|
99
|
+
return result;
|
|
100
|
+
}, []);
|
|
101
|
+
const allNodes = React.useMemo(() => getAllNodes(data), [data, getAllNodes]);
|
|
102
|
+
const getNodeByKey = React.useCallback(
|
|
103
|
+
(key) => {
|
|
104
|
+
return allNodes.find((node) => node.key === key) || null;
|
|
105
|
+
},
|
|
106
|
+
[allNodes]
|
|
107
|
+
);
|
|
108
|
+
const getSelectedNodes = React.useCallback(
|
|
109
|
+
(keys) => {
|
|
110
|
+
const keyArray = Array.isArray(keys) ? keys : [keys];
|
|
111
|
+
return keyArray.map((key) => getNodeByKey(key)).filter((node) => node !== null);
|
|
112
|
+
},
|
|
113
|
+
[getNodeByKey]
|
|
114
|
+
);
|
|
115
|
+
const filteredData = React.useMemo(() => {
|
|
116
|
+
if (!searchQuery) return data;
|
|
117
|
+
const matchingKeys = /* @__PURE__ */ new Set();
|
|
118
|
+
allNodes.forEach((node) => {
|
|
119
|
+
if (node.label.toLowerCase().includes(searchQuery.toLowerCase())) {
|
|
120
|
+
let current = node;
|
|
121
|
+
while (current) {
|
|
122
|
+
matchingKeys.add(current.key);
|
|
123
|
+
const parent = allNodes.find(
|
|
124
|
+
(n) => n.children?.some((child) => child.key === current.key)
|
|
125
|
+
);
|
|
126
|
+
current = parent || null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
const filterTree = (nodes) => {
|
|
131
|
+
return nodes.filter((node) => matchingKeys.has(node.key)).map((node) => ({
|
|
132
|
+
...node,
|
|
133
|
+
children: node.children ? filterTree(node.children) : void 0
|
|
134
|
+
}));
|
|
135
|
+
};
|
|
136
|
+
return filterTree(data);
|
|
137
|
+
}, [data, searchQuery, allNodes]);
|
|
138
|
+
const selectedNodes = React.useMemo(
|
|
139
|
+
() => getSelectedNodes(currentValue),
|
|
140
|
+
[currentValue, getSelectedNodes]
|
|
141
|
+
);
|
|
142
|
+
const getDisplayValue = React.useMemo(() => {
|
|
143
|
+
if (!selectedNodes.length) return "";
|
|
144
|
+
if (selectedNodes.length === 1) return selectedNodes[0]?.label;
|
|
145
|
+
return `${selectedNodes.length} selected`;
|
|
146
|
+
}, [selectedNodes]);
|
|
147
|
+
const handleSelect = React.useCallback(
|
|
148
|
+
(_, info2) => {
|
|
149
|
+
if (disabled) return;
|
|
150
|
+
if (info2.node.children && info2.node.children.length > 0) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
let newValue;
|
|
154
|
+
if (multiple) {
|
|
155
|
+
const currentArray = Array.isArray(currentValue) ? currentValue : [];
|
|
156
|
+
if (info2.selected) {
|
|
157
|
+
newValue = [...currentArray, info2.node.key];
|
|
158
|
+
} else {
|
|
159
|
+
newValue = currentArray.filter((k) => k !== info2.node.key);
|
|
160
|
+
}
|
|
161
|
+
} else {
|
|
162
|
+
if (info2.selected) {
|
|
163
|
+
newValue = info2.node.key;
|
|
164
|
+
setIsOpen(false);
|
|
165
|
+
setSearchQuery("");
|
|
166
|
+
} else {
|
|
167
|
+
newValue = "";
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (value === void 0) {
|
|
171
|
+
setInternalValue(newValue);
|
|
172
|
+
}
|
|
173
|
+
const selectedNodesResult = getSelectedNodes(newValue);
|
|
174
|
+
onChange?.(newValue, selectedNodesResult);
|
|
175
|
+
},
|
|
176
|
+
[disabled, multiple, currentValue, value, onChange, getSelectedNodes]
|
|
177
|
+
);
|
|
178
|
+
const handleCheck = React.useCallback(
|
|
179
|
+
(keys, info2) => {
|
|
180
|
+
if (disabled) return;
|
|
181
|
+
const leafKeys = keys.filter((key) => {
|
|
182
|
+
const node = getNodeByKey(key);
|
|
183
|
+
return node && (!node.children || node.children.length === 0);
|
|
184
|
+
});
|
|
185
|
+
const leafNodes = info2.checkedNodes.filter(
|
|
186
|
+
(node) => !node.children || node.children.length === 0
|
|
187
|
+
);
|
|
188
|
+
if (value === void 0) {
|
|
189
|
+
setInternalValue(leafKeys);
|
|
190
|
+
}
|
|
191
|
+
onChange?.(leafKeys, leafNodes);
|
|
192
|
+
},
|
|
193
|
+
[disabled, value, onChange, getNodeByKey]
|
|
194
|
+
);
|
|
195
|
+
const handleInputChange = React.useCallback(
|
|
196
|
+
(e) => {
|
|
197
|
+
setSearchQuery(e.target.value);
|
|
198
|
+
if (!isOpen) setIsOpen(true);
|
|
199
|
+
},
|
|
200
|
+
[isOpen]
|
|
201
|
+
);
|
|
202
|
+
const handleInputFocus = React.useCallback(() => {
|
|
203
|
+
setIsOpen(true);
|
|
204
|
+
}, []);
|
|
205
|
+
const handleClear = React.useCallback(
|
|
206
|
+
(e) => {
|
|
207
|
+
e.stopPropagation();
|
|
208
|
+
const newValue = multiple ? [] : "";
|
|
209
|
+
if (value === void 0) {
|
|
210
|
+
setInternalValue(newValue);
|
|
211
|
+
}
|
|
212
|
+
onChange?.(newValue, []);
|
|
213
|
+
setSearchQuery("");
|
|
214
|
+
},
|
|
215
|
+
[multiple, value, onChange]
|
|
216
|
+
);
|
|
217
|
+
const handleRemoveItem = React.useCallback(
|
|
218
|
+
(e, keyToRemove) => {
|
|
219
|
+
e.stopPropagation();
|
|
220
|
+
if (!multiple || disabled) return;
|
|
221
|
+
const currentArray = Array.isArray(currentValue) ? currentValue : [];
|
|
222
|
+
const newValue = currentArray.filter((k) => k !== keyToRemove);
|
|
223
|
+
if (value === void 0) {
|
|
224
|
+
setInternalValue(newValue);
|
|
225
|
+
}
|
|
226
|
+
const selectedNodesResult = getSelectedNodes(newValue);
|
|
227
|
+
onChange?.(newValue, selectedNodesResult);
|
|
228
|
+
},
|
|
229
|
+
[multiple, disabled, currentValue, value, onChange, getSelectedNodes]
|
|
230
|
+
);
|
|
231
|
+
const handleKeyDown = React.useCallback(
|
|
232
|
+
(e) => {
|
|
233
|
+
if (!isOpen && e.key !== "Tab") {
|
|
234
|
+
if (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") {
|
|
235
|
+
e.preventDefault();
|
|
236
|
+
setIsOpen(true);
|
|
237
|
+
}
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
if (e.key === "Escape") {
|
|
241
|
+
e.preventDefault();
|
|
242
|
+
setIsOpen(false);
|
|
243
|
+
setSearchQuery("");
|
|
244
|
+
triggerRef.current?.focus();
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
[isOpen]
|
|
248
|
+
);
|
|
249
|
+
const handleInputKeyDown = React.useCallback(
|
|
250
|
+
(e) => {
|
|
251
|
+
if (e.key === "Backspace" && !searchQuery && multiple && Array.isArray(currentValue) && currentValue.length > 0) {
|
|
252
|
+
e.preventDefault();
|
|
253
|
+
const lastKey = currentValue[currentValue.length - 1];
|
|
254
|
+
handleRemoveItem(e, lastKey || "");
|
|
255
|
+
} else {
|
|
256
|
+
handleKeyDown(e);
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
[searchQuery, currentValue, multiple, handleRemoveItem, handleKeyDown]
|
|
260
|
+
);
|
|
261
|
+
React.useEffect(() => {
|
|
262
|
+
if (selectedNodes.length === 0 || !triggerRef.current) {
|
|
263
|
+
setVisibleChipsCount(maxChipsVisible);
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
const calculateVisibleChips = () => {
|
|
267
|
+
const container = triggerRef.current;
|
|
268
|
+
if (!container) return;
|
|
269
|
+
const hiddenChips = container.querySelectorAll("[data-hidden-chip]");
|
|
270
|
+
if (hiddenChips.length === 0) return;
|
|
271
|
+
const containerWidth = container.offsetWidth;
|
|
272
|
+
const padding = size === "sm" ? 12 : size === "md" ? 16 : size === "lg" ? 20 : 16;
|
|
273
|
+
const iconsWidth = 60;
|
|
274
|
+
const gap = 4;
|
|
275
|
+
const plusIndicatorWidth = 40;
|
|
276
|
+
const availableWidth = containerWidth - padding * 2 - iconsWidth;
|
|
277
|
+
let totalWidth = 0;
|
|
278
|
+
let visibleCount = 0;
|
|
279
|
+
for (let i = 0; i < hiddenChips.length; i++) {
|
|
280
|
+
const chipWidth = hiddenChips[i]?.getBoundingClientRect().width || 0;
|
|
281
|
+
const requiredSpace = totalWidth + chipWidth + (visibleCount > 0 ? gap : 0);
|
|
282
|
+
const needsPlusIndicator = i < hiddenChips.length - 1;
|
|
283
|
+
const spaceWithIndicator = requiredSpace + (needsPlusIndicator ? gap + plusIndicatorWidth : 0);
|
|
284
|
+
if (spaceWithIndicator <= availableWidth) {
|
|
285
|
+
totalWidth = requiredSpace;
|
|
286
|
+
visibleCount++;
|
|
287
|
+
} else {
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
setVisibleChipsCount(Math.max(1, visibleCount));
|
|
292
|
+
};
|
|
293
|
+
const timeoutId = setTimeout(calculateVisibleChips, 0);
|
|
294
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
295
|
+
calculateVisibleChips();
|
|
296
|
+
});
|
|
297
|
+
if (triggerRef.current) {
|
|
298
|
+
resizeObserver.observe(triggerRef.current);
|
|
299
|
+
}
|
|
300
|
+
return () => {
|
|
301
|
+
clearTimeout(timeoutId);
|
|
302
|
+
resizeObserver.disconnect();
|
|
303
|
+
};
|
|
304
|
+
}, [selectedNodes, size, maxChipsVisible]);
|
|
305
|
+
const treeSelectElement = /* @__PURE__ */ jsx(
|
|
306
|
+
"div",
|
|
307
|
+
{
|
|
308
|
+
className: cn("relative group", fullWidth ? "w-full" : "inline-block"),
|
|
309
|
+
ref,
|
|
310
|
+
...props,
|
|
311
|
+
children: /* @__PURE__ */ jsxs(
|
|
312
|
+
Popover,
|
|
313
|
+
{
|
|
314
|
+
open: isOpen,
|
|
315
|
+
onOpenChange: setIsOpen,
|
|
316
|
+
children: [
|
|
317
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
318
|
+
"button",
|
|
319
|
+
{
|
|
320
|
+
ref: triggerRef,
|
|
321
|
+
type: "button",
|
|
322
|
+
className: cn(
|
|
323
|
+
treeSelectTriggerVariants({ status, size, fullWidth }),
|
|
324
|
+
loading && "opacity-50",
|
|
325
|
+
className
|
|
326
|
+
),
|
|
327
|
+
disabled: disabled || loading,
|
|
328
|
+
"aria-haspopup": "tree",
|
|
329
|
+
"aria-expanded": isOpen,
|
|
330
|
+
"aria-labelledby": label ? "tree-select-label" : void 0,
|
|
331
|
+
children: [
|
|
332
|
+
multiple && selectedNodes.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex gap-1 flex-shrink-0", children: [
|
|
333
|
+
selectedNodes.slice(0, visibleChipsCount).map((node) => /* @__PURE__ */ jsxs(
|
|
334
|
+
"span",
|
|
335
|
+
{
|
|
336
|
+
className: "inline-flex items-center gap-1 px-2 py-0.5 bg-primary/10 text-primary rounded text-sm whitespace-nowrap",
|
|
337
|
+
children: [
|
|
338
|
+
node.label,
|
|
339
|
+
/* @__PURE__ */ jsx(
|
|
340
|
+
"button",
|
|
341
|
+
{
|
|
342
|
+
type: "button",
|
|
343
|
+
onClick: (e) => handleRemoveItem(e, node.key),
|
|
344
|
+
className: "hover:bg-primary/20 rounded-sm",
|
|
345
|
+
disabled,
|
|
346
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
|
|
347
|
+
}
|
|
348
|
+
)
|
|
349
|
+
]
|
|
350
|
+
},
|
|
351
|
+
node.key
|
|
352
|
+
)),
|
|
353
|
+
selectedNodes.length > visibleChipsCount && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center px-2 py-0.5 bg-surface text-text-muted rounded text-sm whitespace-nowrap", children: [
|
|
354
|
+
"+",
|
|
355
|
+
selectedNodes.length - visibleChipsCount
|
|
356
|
+
] })
|
|
357
|
+
] }),
|
|
358
|
+
/* @__PURE__ */ jsx(
|
|
359
|
+
"div",
|
|
360
|
+
{
|
|
361
|
+
className: "absolute opacity-0 pointer-events-none whitespace-nowrap",
|
|
362
|
+
"aria-hidden": "true",
|
|
363
|
+
children: selectedNodes.map((node) => /* @__PURE__ */ jsxs(
|
|
364
|
+
"span",
|
|
365
|
+
{
|
|
366
|
+
"data-hidden-chip": true,
|
|
367
|
+
className: "inline-flex items-center gap-1 px-2 py-0.5 bg-primary/10 text-primary rounded text-sm whitespace-nowrap",
|
|
368
|
+
children: [
|
|
369
|
+
node.label,
|
|
370
|
+
/* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
|
|
371
|
+
]
|
|
372
|
+
},
|
|
373
|
+
node.key
|
|
374
|
+
))
|
|
375
|
+
}
|
|
376
|
+
),
|
|
377
|
+
/* @__PURE__ */ jsx(
|
|
378
|
+
"input",
|
|
379
|
+
{
|
|
380
|
+
ref: inputRef,
|
|
381
|
+
type: "text",
|
|
382
|
+
className: "bg-transparent outline-none cursor-pointer placeholder:text-text-muted flex-1 min-w-0 pointer-events-none",
|
|
383
|
+
placeholder: selectedNodes.length > 0 ? "" : placeholder,
|
|
384
|
+
value: searchQuery,
|
|
385
|
+
onChange: handleInputChange,
|
|
386
|
+
onFocus: handleInputFocus,
|
|
387
|
+
onKeyDown: handleInputKeyDown,
|
|
388
|
+
disabled: disabled || loading,
|
|
389
|
+
readOnly: !isOpen || !searchable,
|
|
390
|
+
tabIndex: -1
|
|
391
|
+
}
|
|
392
|
+
),
|
|
393
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-text-muted", children: [
|
|
394
|
+
getDisplayValue && !disabled && !loading && /* @__PURE__ */ jsx(
|
|
395
|
+
"button",
|
|
396
|
+
{
|
|
397
|
+
type: "button",
|
|
398
|
+
onClick: handleClear,
|
|
399
|
+
className: "hover:text-text-primary transition-colors",
|
|
400
|
+
tabIndex: -1,
|
|
401
|
+
children: /* @__PURE__ */ jsx(X, { className: iconSizes[size] })
|
|
402
|
+
}
|
|
403
|
+
),
|
|
404
|
+
loading ? /* @__PURE__ */ jsx(Loader2, { className: cn("animate-spin", iconSizes[size]) }) : /* @__PURE__ */ jsx(Fragment, { children: isOpen && searchable ? /* @__PURE__ */ jsx(Search, { className: iconSizes[size] }) : /* @__PURE__ */ jsx(
|
|
405
|
+
ChevronDown,
|
|
406
|
+
{
|
|
407
|
+
className: cn(
|
|
408
|
+
iconSizes[size],
|
|
409
|
+
"transition-transform duration-200",
|
|
410
|
+
isOpen && "rotate-180"
|
|
411
|
+
)
|
|
412
|
+
}
|
|
413
|
+
) })
|
|
414
|
+
] })
|
|
415
|
+
]
|
|
416
|
+
}
|
|
417
|
+
) }),
|
|
418
|
+
/* @__PURE__ */ jsx(
|
|
419
|
+
PopoverContent,
|
|
420
|
+
{
|
|
421
|
+
className: "p-2 w-[var(--radix-popover-trigger-width)]",
|
|
422
|
+
align: "start",
|
|
423
|
+
onOpenAutoFocus: (e) => {
|
|
424
|
+
e.preventDefault();
|
|
425
|
+
inputRef.current?.focus();
|
|
426
|
+
},
|
|
427
|
+
children: /* @__PURE__ */ jsx(
|
|
428
|
+
"div",
|
|
429
|
+
{
|
|
430
|
+
className: "overflow-auto",
|
|
431
|
+
style: { maxHeight: maxDropdownHeight },
|
|
432
|
+
role: "tree",
|
|
433
|
+
"aria-labelledby": label ? "tree-select-label" : void 0,
|
|
434
|
+
children: filteredData.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-3 py-4 text-center text-sm text-text-muted", children: "No options found" }) : /* @__PURE__ */ jsx(
|
|
435
|
+
tree_default,
|
|
436
|
+
{
|
|
437
|
+
data: filteredData,
|
|
438
|
+
checkable,
|
|
439
|
+
checkedKeys: checkable && Array.isArray(currentValue) ? currentValue : void 0,
|
|
440
|
+
onCheck: checkable ? handleCheck : void 0,
|
|
441
|
+
selectable: !checkable,
|
|
442
|
+
selectedKeys: !checkable ? Array.isArray(currentValue) ? currentValue : currentValue ? [currentValue] : [] : void 0,
|
|
443
|
+
onSelect: !checkable ? handleSelect : void 0,
|
|
444
|
+
disabled,
|
|
445
|
+
size,
|
|
446
|
+
showLine,
|
|
447
|
+
showIcon,
|
|
448
|
+
defaultExpandAll: defaultExpandAll || !!searchQuery,
|
|
449
|
+
expandedKeys: searchQuery ? void 0 : expandedKeys,
|
|
450
|
+
onExpand: setExpandedKeys
|
|
451
|
+
}
|
|
452
|
+
)
|
|
453
|
+
}
|
|
454
|
+
)
|
|
455
|
+
}
|
|
456
|
+
)
|
|
457
|
+
]
|
|
458
|
+
}
|
|
459
|
+
)
|
|
460
|
+
}
|
|
461
|
+
);
|
|
462
|
+
if (!label && !helperMessage) return treeSelectElement;
|
|
463
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("w-full flex flex-col", !fullWidth && "inline-block"), children: [
|
|
464
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2 items-center", children: [
|
|
465
|
+
label && /* @__PURE__ */ jsx(
|
|
466
|
+
"label",
|
|
467
|
+
{
|
|
468
|
+
id: "tree-select-label",
|
|
469
|
+
className: "block mb-0.5",
|
|
470
|
+
children: /* @__PURE__ */ jsxs("span", { className: "text-sm font-medium text-text-muted", children: [
|
|
471
|
+
label,
|
|
472
|
+
required && /* @__PURE__ */ jsx("span", { className: "text-error ml-1", children: "*" })
|
|
473
|
+
] })
|
|
474
|
+
}
|
|
475
|
+
),
|
|
476
|
+
helperMessage && /* @__PURE__ */ jsx("p", { className: statusMessageVariants({ status }), children: helperMessage })
|
|
477
|
+
] }),
|
|
478
|
+
treeSelectElement
|
|
479
|
+
] });
|
|
480
|
+
}
|
|
481
|
+
);
|
|
482
|
+
TreeSelect.displayName = "TreeSelect";
|
|
483
|
+
var tree_select_default = TreeSelect;
|
|
484
|
+
|
|
485
|
+
export { tree_select_default };
|
|
486
|
+
//# sourceMappingURL=chunk-JZCHZ4B3.js.map
|
|
487
|
+
//# sourceMappingURL=chunk-JZCHZ4B3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tree-select/index.tsx"],"names":["info"],"mappings":"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","file":"chunk-JZCHZ4B3.js","sourcesContent":["import { cva } from 'class-variance-authority'\nimport { ChevronDown, Loader2, Search, X } from 'lucide-react'\nimport React from 'react'\n\nimport { Popover, PopoverContent, PopoverTrigger } from '../popover'\nimport Tree from '../tree'\nimport type { TreeNode } from '../tree/types'\nimport {\n cn,\n getValidationStatus,\n iconSizes,\n statusMessageVariants,\n} from '../utils'\nimport type { TreeSelectProps } from './types'\n\nconst treeSelectTriggerVariants = cva(\n 'w-full flex items-center justify-between rounded-md bg-background text-text-primary border focus:border-primary outline-none disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer transition-colors',\n {\n variants: {\n status: {\n default: 'border-border hover:border-primary/50',\n error: 'border-error',\n warning: 'border-warning',\n info: 'border-info',\n success: 'border-success',\n },\n size: {\n xs: 'h-8 px-2 text-sm gap-2',\n sm: 'h-[var(--input-height-sm)] px-1 text-sm gap-2',\n md: 'h-[var(--input-height-md)] px-2 text-base gap-2',\n lg: 'h-[var(--input-height-lg)] px-3 text-lg gap-3',\n },\n fullWidth: {\n true: 'w-full',\n false: 'max-w-full',\n },\n },\n defaultVariants: {\n status: 'default',\n size: 'md',\n fullWidth: true,\n },\n },\n)\n\nconst TreeSelect = React.memo<TreeSelectProps>(\n ({\n size = 'md',\n label,\n helperText,\n error,\n warning,\n info,\n success,\n data = [],\n placeholder = 'Select an option',\n loading = false,\n fullWidth = true,\n value,\n defaultValue,\n onChange,\n disabled,\n required,\n multiple = false,\n checkable = false,\n searchable = true,\n maxChipsVisible = 3,\n maxDropdownHeight = 300,\n defaultExpandAll = false,\n defaultExpandedKeys = [],\n showLine = false,\n showIcon = true,\n className,\n ref,\n ...props\n }) => {\n const [isOpen, setIsOpen] = React.useState(false)\n const [internalValue, setInternalValue] = React.useState<string | string[]>(\n defaultValue || (multiple ? [] : ''),\n )\n const [searchQuery, setSearchQuery] = React.useState('')\n const [expandedKeys, setExpandedKeys] = React.useState<string[]>(\n defaultExpandAll ? [] : defaultExpandedKeys,\n )\n const [visibleChipsCount, setVisibleChipsCount] =\n React.useState(maxChipsVisible)\n\n const triggerRef = React.useRef<HTMLButtonElement>(null)\n const inputRef = React.useRef<HTMLInputElement>(null)\n const currentValue = value !== undefined ? value : internalValue\n\n // Use shared validation status utility\n const { status, message: helperMessage } = getValidationStatus({\n error,\n warning,\n info,\n success,\n helperText,\n })\n\n // Get all nodes in a flat structure for search and lookup\n const getAllNodes = React.useCallback((nodes: TreeNode[]): TreeNode[] => {\n const result: TreeNode[] = []\n const traverse = (items: TreeNode[]) => {\n items.forEach((item) => {\n result.push(item)\n if (item.children) {\n traverse(item.children)\n }\n })\n }\n traverse(nodes)\n return result\n }, [])\n\n const allNodes = React.useMemo(() => getAllNodes(data), [data, getAllNodes])\n\n // Find node by key\n const getNodeByKey = React.useCallback(\n (key: string): TreeNode | null => {\n return allNodes.find((node) => node.key === key) || null\n },\n [allNodes],\n )\n\n // Get selected nodes\n const getSelectedNodes = React.useCallback(\n (keys: string | string[]): TreeNode[] => {\n const keyArray = Array.isArray(keys) ? keys : [keys]\n return keyArray\n .map((key) => getNodeByKey(key))\n .filter((node): node is TreeNode => node !== null)\n },\n [getNodeByKey],\n )\n\n // Filter tree data based on search query\n const filteredData = React.useMemo(() => {\n if (!searchQuery) return data\n\n const matchingKeys = new Set<string>()\n\n // Find all nodes that match the search\n allNodes.forEach((node) => {\n if (node.label.toLowerCase().includes(searchQuery.toLowerCase())) {\n // Add the node and all its ancestors\n let current: TreeNode | null = node\n while (current) {\n matchingKeys.add(current.key)\n // Find parent\n const parent = allNodes.find((n) =>\n n.children?.some((child) => child.key === current!.key),\n )\n current = parent || null\n }\n }\n })\n\n // Filter tree to only include matching nodes and their paths\n const filterTree = (nodes: TreeNode[]): TreeNode[] => {\n return nodes\n .filter((node) => matchingKeys.has(node.key))\n .map((node) => ({\n ...node,\n children: node.children ? filterTree(node.children) : undefined,\n }))\n }\n\n return filterTree(data)\n }, [data, searchQuery, allNodes])\n\n // Get display value\n const selectedNodes = React.useMemo(\n () => getSelectedNodes(currentValue),\n [currentValue, getSelectedNodes],\n )\n\n const getDisplayValue = React.useMemo(() => {\n if (!selectedNodes.length) return ''\n if (selectedNodes.length === 1) return selectedNodes[0]?.label\n return `${selectedNodes.length} selected`\n }, [selectedNodes])\n\n const handleSelect = React.useCallback(\n (_: string[], info: { selected: boolean; node: TreeNode }) => {\n if (disabled) return\n\n // Prevent selection of directory nodes (nodes with children)\n if (info.node.children && info.node.children.length > 0) {\n return\n }\n\n let newValue: string | string[]\n\n if (multiple) {\n // For multiple selection\n const currentArray = Array.isArray(currentValue) ? currentValue : []\n if (info.selected) {\n newValue = [...currentArray, info.node.key]\n } else {\n newValue = currentArray.filter((k) => k !== info.node.key)\n }\n } else {\n // For single selection\n if (info.selected) {\n newValue = info.node.key\n setIsOpen(false)\n setSearchQuery('')\n } else {\n newValue = ''\n }\n }\n\n if (value === undefined) {\n setInternalValue(newValue)\n }\n\n const selectedNodesResult = getSelectedNodes(newValue)\n onChange?.(newValue, selectedNodesResult)\n },\n [disabled, multiple, currentValue, value, onChange, getSelectedNodes],\n )\n\n const handleCheck = React.useCallback(\n (\n keys: string[],\n info: {\n checked: boolean\n node: TreeNode\n checkedNodes: TreeNode[]\n },\n ) => {\n if (disabled) return\n\n // Filter out directory nodes (nodes with children) from checked keys\n const leafKeys = keys.filter((key) => {\n const node = getNodeByKey(key)\n return node && (!node.children || node.children.length === 0)\n })\n\n const leafNodes = info.checkedNodes.filter(\n (node) => !node.children || node.children.length === 0,\n )\n\n if (value === undefined) {\n setInternalValue(leafKeys)\n }\n\n onChange?.(leafKeys, leafNodes)\n },\n [disabled, value, onChange, getNodeByKey],\n )\n\n const handleInputChange = React.useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n setSearchQuery(e.target.value)\n if (!isOpen) setIsOpen(true)\n },\n [isOpen],\n )\n\n const handleInputFocus = React.useCallback(() => {\n setIsOpen(true)\n }, [])\n\n const handleClear = React.useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation()\n const newValue = multiple ? [] : ''\n if (value === undefined) {\n setInternalValue(newValue)\n }\n onChange?.(newValue, [])\n setSearchQuery('')\n },\n [multiple, value, onChange],\n )\n\n const handleRemoveItem = React.useCallback(\n (\n e: React.MouseEvent<HTMLButtonElement, MouseEvent>,\n keyToRemove: string,\n ) => {\n e.stopPropagation()\n if (!multiple || disabled) return\n\n const currentArray = Array.isArray(currentValue) ? currentValue : []\n const newValue = currentArray.filter((k) => k !== keyToRemove)\n\n if (value === undefined) {\n setInternalValue(newValue)\n }\n\n const selectedNodesResult = getSelectedNodes(newValue)\n onChange?.(newValue, selectedNodesResult)\n },\n [multiple, disabled, currentValue, value, onChange, getSelectedNodes],\n )\n\n const handleKeyDown = React.useCallback(\n (e: React.KeyboardEvent) => {\n if (!isOpen && e.key !== 'Tab') {\n if (e.key === 'Enter' || e.key === ' ' || e.key === 'ArrowDown') {\n e.preventDefault()\n setIsOpen(true)\n }\n return\n }\n\n if (e.key === 'Escape') {\n e.preventDefault()\n setIsOpen(false)\n setSearchQuery('')\n triggerRef.current?.focus()\n }\n },\n [isOpen],\n )\n\n const handleInputKeyDown = React.useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (\n e.key === 'Backspace' &&\n !searchQuery &&\n multiple &&\n Array.isArray(currentValue) &&\n currentValue.length > 0\n ) {\n e.preventDefault()\n const lastKey = currentValue[currentValue.length - 1]\n handleRemoveItem(e as any, lastKey || '')\n } else {\n handleKeyDown(e)\n }\n },\n [searchQuery, currentValue, multiple, handleRemoveItem, handleKeyDown],\n )\n\n // Dynamic badge size calculation\n React.useEffect(() => {\n if (selectedNodes.length === 0 || !triggerRef.current) {\n setVisibleChipsCount(maxChipsVisible)\n return\n }\n\n const calculateVisibleChips = () => {\n const container = triggerRef.current\n if (!container) return\n\n const hiddenChips = container.querySelectorAll('[data-hidden-chip]')\n if (hiddenChips.length === 0) return\n\n const containerWidth = container.offsetWidth\n const padding =\n size === 'sm' ? 12 : size === 'md' ? 16 : size === 'lg' ? 20 : 16\n\n // Account for icons on the right (clear + chevron/search)\n // Use a generous estimate to avoid overflow\n const iconsWidth = 60 // Enough space for clear button + chevron + gap\n\n const gap = 4\n const plusIndicatorWidth = 40 // Width of \"+X\" badge\n\n const availableWidth = containerWidth - padding * 2 - iconsWidth\n let totalWidth = 0\n let visibleCount = 0\n\n for (let i = 0; i < hiddenChips.length; i++) {\n const chipWidth = hiddenChips[i]?.getBoundingClientRect().width || 0\n const requiredSpace =\n totalWidth + chipWidth + (visibleCount > 0 ? gap : 0)\n\n const needsPlusIndicator = i < hiddenChips.length - 1\n const spaceWithIndicator =\n requiredSpace + (needsPlusIndicator ? gap + plusIndicatorWidth : 0)\n\n if (spaceWithIndicator <= availableWidth) {\n totalWidth = requiredSpace\n visibleCount++\n } else {\n break\n }\n }\n\n setVisibleChipsCount(Math.max(1, visibleCount))\n }\n\n const timeoutId = setTimeout(calculateVisibleChips, 0)\n\n const resizeObserver = new ResizeObserver(() => {\n calculateVisibleChips()\n })\n\n if (triggerRef.current) {\n resizeObserver.observe(triggerRef.current)\n }\n\n return () => {\n clearTimeout(timeoutId)\n resizeObserver.disconnect()\n }\n }, [selectedNodes, size, maxChipsVisible])\n\n const treeSelectElement = (\n <div\n className={cn('relative group', fullWidth ? 'w-full' : 'inline-block')}\n ref={ref}\n {...props}\n >\n <Popover\n open={isOpen}\n onOpenChange={setIsOpen}\n >\n <PopoverTrigger asChild>\n <button\n ref={triggerRef}\n type=\"button\"\n className={cn(\n treeSelectTriggerVariants({ status, size, fullWidth }),\n loading && 'opacity-50',\n className,\n )}\n disabled={disabled || loading}\n aria-haspopup=\"tree\"\n aria-expanded={isOpen}\n aria-labelledby={label ? 'tree-select-label' : undefined}\n >\n {multiple && selectedNodes.length > 0 && (\n <div className=\"flex gap-1 flex-shrink-0\">\n {selectedNodes.slice(0, visibleChipsCount).map((node) => (\n <span\n key={node.key}\n className=\"inline-flex items-center gap-1 px-2 py-0.5 bg-primary/10 text-primary rounded text-sm whitespace-nowrap\"\n >\n {node.label}\n <button\n type=\"button\"\n onClick={(e) => handleRemoveItem(e, node.key)}\n className=\"hover:bg-primary/20 rounded-sm\"\n disabled={disabled}\n >\n <X className=\"h-3 w-3\" />\n </button>\n </span>\n ))}\n {selectedNodes.length > visibleChipsCount && (\n <span className=\"inline-flex items-center px-2 py-0.5 bg-surface text-text-muted rounded text-sm whitespace-nowrap\">\n +{selectedNodes.length - visibleChipsCount}\n </span>\n )}\n </div>\n )}\n <div\n className=\"absolute opacity-0 pointer-events-none whitespace-nowrap\"\n aria-hidden=\"true\"\n >\n {selectedNodes.map((node) => (\n <span\n key={node.key}\n data-hidden-chip\n className=\"inline-flex items-center gap-1 px-2 py-0.5 bg-primary/10 text-primary rounded text-sm whitespace-nowrap\"\n >\n {node.label}\n <X className=\"h-3 w-3\" />\n </span>\n ))}\n </div>\n <input\n ref={inputRef}\n type=\"text\"\n className=\"bg-transparent outline-none cursor-pointer placeholder:text-text-muted flex-1 min-w-0 pointer-events-none\"\n placeholder={selectedNodes.length > 0 ? '' : placeholder}\n value={searchQuery}\n onChange={handleInputChange}\n onFocus={handleInputFocus}\n onKeyDown={handleInputKeyDown}\n disabled={disabled || loading}\n readOnly={!isOpen || !searchable}\n tabIndex={-1}\n />\n <div className=\"flex items-center gap-1 text-text-muted\">\n {getDisplayValue && !disabled && !loading && (\n <button\n type=\"button\"\n onClick={handleClear}\n className=\"hover:text-text-primary transition-colors\"\n tabIndex={-1}\n >\n <X className={iconSizes[size]} />\n </button>\n )}\n {loading ? (\n <Loader2 className={cn('animate-spin', iconSizes[size])} />\n ) : (\n <>\n {isOpen && searchable ? (\n <Search className={iconSizes[size]} />\n ) : (\n <ChevronDown\n className={cn(\n iconSizes[size],\n 'transition-transform duration-200',\n isOpen && 'rotate-180',\n )}\n />\n )}\n </>\n )}\n </div>\n </button>\n </PopoverTrigger>\n\n <PopoverContent\n className=\"p-2 w-[var(--radix-popover-trigger-width)]\"\n align=\"start\"\n onOpenAutoFocus={(e) => {\n e.preventDefault()\n inputRef.current?.focus()\n }}\n >\n <div\n className=\"overflow-auto\"\n style={{ maxHeight: maxDropdownHeight }}\n role=\"tree\"\n aria-labelledby={label ? 'tree-select-label' : undefined}\n >\n {filteredData.length === 0 ? (\n <div className=\"px-3 py-4 text-center text-sm text-text-muted\">\n No options found\n </div>\n ) : (\n <Tree\n data={filteredData}\n checkable={checkable}\n checkedKeys={\n checkable && Array.isArray(currentValue)\n ? currentValue\n : undefined\n }\n onCheck={checkable ? handleCheck : undefined}\n selectable={!checkable}\n selectedKeys={\n !checkable\n ? Array.isArray(currentValue)\n ? currentValue\n : currentValue\n ? [currentValue]\n : []\n : undefined\n }\n onSelect={!checkable ? handleSelect : undefined}\n disabled={disabled}\n size={size}\n showLine={showLine}\n showIcon={showIcon}\n defaultExpandAll={defaultExpandAll || !!searchQuery}\n expandedKeys={searchQuery ? undefined : expandedKeys}\n onExpand={setExpandedKeys}\n />\n )}\n </div>\n </PopoverContent>\n </Popover>\n </div>\n )\n\n if (!label && !helperMessage) return treeSelectElement\n\n return (\n <div className={cn('w-full flex flex-col', !fullWidth && 'inline-block')}>\n <div className=\"flex gap-2 items-center\">\n {label && (\n <label\n id=\"tree-select-label\"\n className=\"block mb-0.5\"\n >\n <span className=\"text-sm font-medium text-text-muted\">\n {label}\n {required && <span className=\"text-error ml-1\">*</span>}\n </span>\n </label>\n )}\n {helperMessage && (\n <p className={statusMessageVariants({ status })}>{helperMessage}</p>\n )}\n </div>\n {treeSelectElement}\n </div>\n )\n },\n)\n\nTreeSelect.displayName = 'TreeSelect'\n\nexport type * from './types'\nexport default TreeSelect\n"]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { cn } from './chunk-YNNAOXU5.js';
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
var InputGroup = memo(({ children, className }) => {
|
|
6
|
+
return /* @__PURE__ */ jsx("div", { className: cn("relative flex items-center w-full", className), children });
|
|
7
|
+
});
|
|
8
|
+
InputGroup.displayName = "InputGroup";
|
|
9
|
+
var InputGroupInput = memo(
|
|
10
|
+
({ className, ...props }) => {
|
|
11
|
+
return /* @__PURE__ */ jsx(
|
|
12
|
+
"input",
|
|
13
|
+
{
|
|
14
|
+
className: cn(
|
|
15
|
+
"flex-1 w-full h-[var(--input-height-md)] px-4 text-base bg-background border border-border rounded-md outline-none text-text-primary placeholder:text-text-muted disabled:opacity-50 disabled:cursor-not-allowed read-only:bg-surface read-only:cursor-default focus:border-primary transition-colors",
|
|
16
|
+
"peer",
|
|
17
|
+
className
|
|
18
|
+
),
|
|
19
|
+
...props
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
);
|
|
24
|
+
InputGroupInput.displayName = "InputGroupInput";
|
|
25
|
+
var InputGroupAddon = memo(
|
|
26
|
+
({ children, align = "inline-end", className }) => {
|
|
27
|
+
const alignmentClasses = {
|
|
28
|
+
"inline-start": "absolute left-3 pointer-events-none",
|
|
29
|
+
"inline-end": "absolute right-3 pointer-events-none",
|
|
30
|
+
"block-start": "relative -mb-8 w-full justify-center",
|
|
31
|
+
"block-end": "relative -mt-8 w-full justify-center"
|
|
32
|
+
};
|
|
33
|
+
return /* @__PURE__ */ jsx(
|
|
34
|
+
"div",
|
|
35
|
+
{
|
|
36
|
+
className: cn(
|
|
37
|
+
"flex items-center gap-2 text-text-secondary z-10",
|
|
38
|
+
alignmentClasses[align],
|
|
39
|
+
className
|
|
40
|
+
),
|
|
41
|
+
children
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
InputGroupAddon.displayName = "InputGroupAddon";
|
|
47
|
+
var input_group_default = InputGroup;
|
|
48
|
+
|
|
49
|
+
export { InputGroupAddon, InputGroupInput, input_group_default };
|
|
50
|
+
//# sourceMappingURL=chunk-KBCBVH7B.js.map
|
|
51
|
+
//# sourceMappingURL=chunk-KBCBVH7B.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/input-group/index.tsx"],"names":[],"mappings":";;;;AASA,IAAM,aAAa,IAAA,CAAsB,CAAC,EAAE,QAAA,EAAU,WAAU,KAAM;AACpE,EAAA,2BACG,KAAA,EAAA,EAAI,SAAA,EAAW,GAAG,mCAAA,EAAqC,SAAS,GAC9D,QAAA,EACH,CAAA;AAEJ,CAAC,CAAA;AAED,UAAA,CAAW,WAAA,GAAc,YAAA;AAElB,IAAM,eAAA,GAAkB,IAAA;AAAA,EAC7B,CAAC,EAAE,SAAA,EAAW,GAAG,OAAM,KAAM;AAC3B,IAAA,uBACE,GAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAA;AAAA,UACT,uSAAA;AAAA,UACA,MAAA;AAAA,UACA;AAAA,SACF;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AAEA,eAAA,CAAgB,WAAA,GAAc,iBAAA;AAEvB,IAAM,eAAA,GAAkB,IAAA;AAAA,EAC7B,CAAC,EAAE,QAAA,EAAU,KAAA,GAAQ,YAAA,EAAc,WAAU,KAAM;AACjD,IAAA,MAAM,gBAAA,GAAmB;AAAA,MACvB,cAAA,EAAgB,qCAAA;AAAA,MAChB,YAAA,EAAc,sCAAA;AAAA,MACd,aAAA,EAAe,sCAAA;AAAA,MACf,WAAA,EAAa;AAAA,KACf;AAEA,IAAA,uBACE,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAA;AAAA,UACT,kDAAA;AAAA,UACA,iBAAiB,KAAK,CAAA;AAAA,UACtB;AAAA,SACF;AAAA,QAEC;AAAA;AAAA,KACH;AAAA,EAEJ;AACF;AAEA,eAAA,CAAgB,WAAA,GAAc,iBAAA;AAG9B,IAAO,mBAAA,GAAQ","file":"chunk-KBCBVH7B.js","sourcesContent":["import { memo } from 'react'\n\nimport { cn } from '../utils'\nimport type {\n InputGroupAddonProps,\n InputGroupInputProps,\n InputGroupProps,\n} from './types'\n\nconst InputGroup = memo<InputGroupProps>(({ children, className }) => {\n return (\n <div className={cn('relative flex items-center w-full', className)}>\n {children}\n </div>\n )\n})\n\nInputGroup.displayName = 'InputGroup'\n\nexport const InputGroupInput = memo<InputGroupInputProps>(\n ({ className, ...props }) => {\n return (\n <input\n className={cn(\n 'flex-1 w-full h-[var(--input-height-md)] px-4 text-base bg-background border border-border rounded-md outline-none text-text-primary placeholder:text-text-muted disabled:opacity-50 disabled:cursor-not-allowed read-only:bg-surface read-only:cursor-default focus:border-primary transition-colors',\n 'peer',\n className,\n )}\n {...props}\n />\n )\n },\n)\n\nInputGroupInput.displayName = 'InputGroupInput'\n\nexport const InputGroupAddon = memo<InputGroupAddonProps>(\n ({ children, align = 'inline-end', className }) => {\n const alignmentClasses = {\n 'inline-start': 'absolute left-3 pointer-events-none',\n 'inline-end': 'absolute right-3 pointer-events-none',\n 'block-start': 'relative -mb-8 w-full justify-center',\n 'block-end': 'relative -mt-8 w-full justify-center',\n }\n\n return (\n <div\n className={cn(\n 'flex items-center gap-2 text-text-secondary z-10',\n alignmentClasses[align],\n className,\n )}\n >\n {children}\n </div>\n )\n },\n)\n\nInputGroupAddon.displayName = 'InputGroupAddon'\n\nexport type * from './types'\nexport default InputGroup\n"]}
|