@underverse-ui/underverse 0.2.44 → 0.2.45
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/index.cjs +68 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -5
- package/dist/index.d.ts +20 -5
- package/dist/index.js +68 -29
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -8123,19 +8123,23 @@ var defaultLabels = {
|
|
|
8123
8123
|
emptyText: "No categories",
|
|
8124
8124
|
selectedText: (count) => `${count} selected`
|
|
8125
8125
|
};
|
|
8126
|
-
function CategoryTreeSelect({
|
|
8127
|
-
|
|
8128
|
-
|
|
8129
|
-
|
|
8130
|
-
|
|
8131
|
-
|
|
8132
|
-
|
|
8133
|
-
|
|
8134
|
-
|
|
8135
|
-
|
|
8126
|
+
function CategoryTreeSelect(props) {
|
|
8127
|
+
const {
|
|
8128
|
+
categories,
|
|
8129
|
+
placeholder = "Select category",
|
|
8130
|
+
disabled,
|
|
8131
|
+
viewOnly = false,
|
|
8132
|
+
defaultExpanded = false,
|
|
8133
|
+
labels,
|
|
8134
|
+
inline = false,
|
|
8135
|
+
onNodeClick,
|
|
8136
|
+
className,
|
|
8137
|
+
singleSelect = false
|
|
8138
|
+
} = props;
|
|
8136
8139
|
const [isOpen, setIsOpen] = (0, import_react18.useState)(false);
|
|
8137
8140
|
const [expandedNodes, setExpandedNodes] = (0, import_react18.useState)(/* @__PURE__ */ new Set());
|
|
8138
8141
|
const mergedLabels = { ...defaultLabels, ...labels };
|
|
8142
|
+
const valueArray = singleSelect ? props.value != null ? [props.value] : [] : props.value || [];
|
|
8139
8143
|
const parentCategories = categories.filter((c) => !c.parent_id);
|
|
8140
8144
|
const childrenMap = /* @__PURE__ */ new Map();
|
|
8141
8145
|
categories.forEach((cat) => {
|
|
@@ -8147,11 +8151,11 @@ function CategoryTreeSelect({
|
|
|
8147
8151
|
}
|
|
8148
8152
|
});
|
|
8149
8153
|
(0, import_react18.useEffect)(() => {
|
|
8150
|
-
if (viewOnly && defaultExpanded) {
|
|
8154
|
+
if ((viewOnly || inline) && defaultExpanded) {
|
|
8151
8155
|
const allParentIds = categories.filter((c) => childrenMap.has(c.id)).map((c) => c.id);
|
|
8152
8156
|
setExpandedNodes(new Set(allParentIds));
|
|
8153
8157
|
}
|
|
8154
|
-
}, [viewOnly, defaultExpanded, categories]);
|
|
8158
|
+
}, [viewOnly, inline, defaultExpanded, categories]);
|
|
8155
8159
|
const toggleExpand = (id) => {
|
|
8156
8160
|
const newExpanded = new Set(expandedNodes);
|
|
8157
8161
|
if (newExpanded.has(id)) {
|
|
@@ -8162,25 +8166,41 @@ function CategoryTreeSelect({
|
|
|
8162
8166
|
setExpandedNodes(newExpanded);
|
|
8163
8167
|
};
|
|
8164
8168
|
const handleSelect = (categoryId, category) => {
|
|
8165
|
-
if (viewOnly
|
|
8166
|
-
|
|
8167
|
-
if (
|
|
8168
|
-
|
|
8169
|
-
const
|
|
8170
|
-
|
|
8169
|
+
if (viewOnly) return;
|
|
8170
|
+
onNodeClick?.(category);
|
|
8171
|
+
if (!props.onChange) return;
|
|
8172
|
+
if (singleSelect) {
|
|
8173
|
+
const onChange = props.onChange;
|
|
8174
|
+
const currentValue = props.value;
|
|
8175
|
+
if (currentValue === categoryId) {
|
|
8176
|
+
onChange(null);
|
|
8177
|
+
} else {
|
|
8178
|
+
onChange(categoryId);
|
|
8179
|
+
}
|
|
8180
|
+
if (!inline) {
|
|
8181
|
+
setIsOpen(false);
|
|
8182
|
+
}
|
|
8171
8183
|
} else {
|
|
8172
|
-
|
|
8173
|
-
|
|
8174
|
-
|
|
8184
|
+
const onChange = props.onChange;
|
|
8185
|
+
const newSelected = new Set(valueArray);
|
|
8186
|
+
if (newSelected.has(categoryId)) {
|
|
8187
|
+
newSelected.delete(categoryId);
|
|
8188
|
+
const children = childrenMap.get(categoryId) || [];
|
|
8189
|
+
children.forEach((child) => newSelected.delete(child.id));
|
|
8190
|
+
} else {
|
|
8191
|
+
newSelected.add(categoryId);
|
|
8192
|
+
if (category.parent_id) {
|
|
8193
|
+
newSelected.add(category.parent_id);
|
|
8194
|
+
}
|
|
8175
8195
|
}
|
|
8196
|
+
onChange(Array.from(newSelected));
|
|
8176
8197
|
}
|
|
8177
|
-
onChange(Array.from(newSelected));
|
|
8178
8198
|
};
|
|
8179
8199
|
const renderCategory = (category, level = 0) => {
|
|
8180
8200
|
const children = childrenMap.get(category.id) || [];
|
|
8181
8201
|
const hasChildren = children.length > 0;
|
|
8182
8202
|
const isExpanded = expandedNodes.has(category.id);
|
|
8183
|
-
const isSelected =
|
|
8203
|
+
const isSelected = valueArray.includes(category.id);
|
|
8184
8204
|
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
|
|
8185
8205
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
8186
8206
|
"div",
|
|
@@ -8209,8 +8229,23 @@ function CategoryTreeSelect({
|
|
|
8209
8229
|
viewOnly ? (
|
|
8210
8230
|
// View-only mode: just display the name
|
|
8211
8231
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "text-sm", children: category.name })
|
|
8232
|
+
) : singleSelect ? (
|
|
8233
|
+
// Single select mode: radio-style indicator
|
|
8234
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { onClick: () => handleSelect(category.id, category), className: "flex items-center gap-2 flex-1", children: [
|
|
8235
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8236
|
+
"div",
|
|
8237
|
+
{
|
|
8238
|
+
className: cn(
|
|
8239
|
+
"w-4 h-4 border-2 rounded-full flex items-center justify-center transition-colors",
|
|
8240
|
+
isSelected ? "border-primary" : "border-muted-foreground/30"
|
|
8241
|
+
),
|
|
8242
|
+
children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "w-2 h-2 rounded-full bg-primary" })
|
|
8243
|
+
}
|
|
8244
|
+
),
|
|
8245
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: cn("text-sm", isSelected && "font-medium text-primary"), children: category.name })
|
|
8246
|
+
] })
|
|
8212
8247
|
) : (
|
|
8213
|
-
//
|
|
8248
|
+
// Multi select mode: checkbox-style indicator
|
|
8214
8249
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { onClick: () => handleSelect(category.id, category), className: "flex items-center gap-2 flex-1", children: [
|
|
8215
8250
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
8216
8251
|
"div",
|
|
@@ -8231,12 +8266,16 @@ function CategoryTreeSelect({
|
|
|
8231
8266
|
hasChildren && isExpanded && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { children: children.map((child) => renderCategory(child, level + 1)) })
|
|
8232
8267
|
] }, category.id);
|
|
8233
8268
|
};
|
|
8269
|
+
const renderTreeContent = () => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_jsx_runtime36.Fragment, { children: parentCategories.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "px-3 py-2 text-sm text-muted-foreground", children: mergedLabels.emptyText }) : parentCategories.map((cat) => renderCategory(cat)) });
|
|
8234
8270
|
if (viewOnly) {
|
|
8235
|
-
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: cn("rounded-md border bg-background p-2", disabled && "opacity-50"
|
|
8271
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: cn("rounded-md border bg-background p-2", disabled && "opacity-50", className), children: renderTreeContent() });
|
|
8272
|
+
}
|
|
8273
|
+
if (inline) {
|
|
8274
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: cn("rounded-md border bg-background p-2", disabled && "opacity-50 pointer-events-none", className), children: renderTreeContent() });
|
|
8236
8275
|
}
|
|
8237
|
-
const selectedCount =
|
|
8238
|
-
const displayText = selectedCount > 0 ? mergedLabels.selectedText(selectedCount) : placeholder;
|
|
8239
|
-
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "relative", children: [
|
|
8276
|
+
const selectedCount = valueArray.length;
|
|
8277
|
+
const displayText = singleSelect ? selectedCount > 0 ? categories.find((c) => c.id === valueArray[0])?.name || placeholder : placeholder : selectedCount > 0 ? mergedLabels.selectedText(selectedCount) : placeholder;
|
|
8278
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: cn("relative", className), children: [
|
|
8240
8279
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
8241
8280
|
"button",
|
|
8242
8281
|
{
|
|
@@ -8268,7 +8307,7 @@ function CategoryTreeSelect({
|
|
|
8268
8307
|
"rounded-md border bg-popover text-popover-foreground shadow-md",
|
|
8269
8308
|
"backdrop-blur-sm bg-popover/95 border-border/60"
|
|
8270
8309
|
),
|
|
8271
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "p-1", children:
|
|
8310
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "p-1", children: renderTreeContent() })
|
|
8272
8311
|
}
|
|
8273
8312
|
)
|
|
8274
8313
|
] })
|