@underverse-ui/underverse 1.0.48 → 1.0.50
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/api-reference.json +1 -1
- package/dist/index.cjs +183 -152
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +215 -184
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/api-reference.json
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -665,18 +665,18 @@ var Card = import_react2.default.forwardRef(
|
|
|
665
665
|
)
|
|
666
666
|
}
|
|
667
667
|
),
|
|
668
|
-
(title || description) && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: cn("relative flex flex-col space-y-2 p-4 md:p-6 max-md:space-y-1.5 max-md:p-3", headerClassName), children: [
|
|
668
|
+
(title || description) && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: cn("relative flex min-w-0 flex-col space-y-2 p-4 md:p-6 max-md:space-y-1.5 max-md:p-3", headerClassName), children: [
|
|
669
669
|
title && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
670
670
|
"h3",
|
|
671
671
|
{
|
|
672
672
|
className: cn(
|
|
673
|
-
"text-base md:text-lg font-semibold leading-
|
|
673
|
+
"min-w-0 text-base md:text-lg font-semibold leading-tight tracking-tight break-words [overflow-wrap:anywhere] transition-colors duration-200 max-md:text-sm",
|
|
674
674
|
hoverable && "group-hover:text-primary"
|
|
675
675
|
),
|
|
676
676
|
children: title
|
|
677
677
|
}
|
|
678
678
|
),
|
|
679
|
-
description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm md:text-base text-muted-foreground leading-relaxed", children: description })
|
|
679
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "min-w-0 text-sm md:text-base text-muted-foreground leading-relaxed break-words [overflow-wrap:anywhere]", children: description })
|
|
680
680
|
] }),
|
|
681
681
|
children && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: cn("relative", defaultPaddingX, defaultPaddingY, contentClassName), children }),
|
|
682
682
|
footer && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: cn("relative flex items-center p-4 md:p-6 pt-0 border-t border-border mt-4 max-md:mt-3 max-md:p-3 max-md:pt-0", footerClassName), children: footer })
|
|
@@ -15016,6 +15016,7 @@ function CategoryTreeSelect(props) {
|
|
|
15016
15016
|
const describedBy = errorId || helperId;
|
|
15017
15017
|
const mergedLabels = { ...defaultLabels, ...labels };
|
|
15018
15018
|
const valueArray = singleSelect ? props.value != null ? [props.value] : [] : props.value || [];
|
|
15019
|
+
const selectedIds = (0, import_react19.useMemo)(() => new Set(valueArray), [valueArray]);
|
|
15019
15020
|
const { parentCategories, childrenMap, byId } = (0, import_react19.useMemo)(() => {
|
|
15020
15021
|
const byId2 = /* @__PURE__ */ new Map();
|
|
15021
15022
|
const childrenMap2 = /* @__PURE__ */ new Map();
|
|
@@ -15130,69 +15131,84 @@ function CategoryTreeSelect(props) {
|
|
|
15130
15131
|
}
|
|
15131
15132
|
};
|
|
15132
15133
|
const renderCategory = (category, level = 0) => {
|
|
15133
|
-
const
|
|
15134
|
-
const children = isSearchMode ? allChildren.filter((c) => visibleIds?.has(c.id)) : allChildren;
|
|
15134
|
+
const children = effectiveChildrenMap.get(category.id) || [];
|
|
15135
15135
|
const hasChildren = children.length > 0;
|
|
15136
15136
|
const isExpanded = hasChildren && (isSearchMode || expandedNodes.has(category.id));
|
|
15137
|
-
const isSelected =
|
|
15138
|
-
|
|
15139
|
-
|
|
15140
|
-
|
|
15141
|
-
"
|
|
15142
|
-
{
|
|
15143
|
-
|
|
15144
|
-
|
|
15145
|
-
"
|
|
15146
|
-
|
|
15147
|
-
|
|
15148
|
-
|
|
15149
|
-
|
|
15150
|
-
|
|
15137
|
+
const isSelected = selectedIds.has(category.id);
|
|
15138
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
15139
|
+
"div",
|
|
15140
|
+
{
|
|
15141
|
+
className: "min-w-0 animate-in fade-in-50 duration-200 [content-visibility:auto] [contain-intrinsic-size:44px]",
|
|
15142
|
+
style: { animationDelay: `${level * 30}ms` },
|
|
15143
|
+
children: [
|
|
15144
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
15145
|
+
"div",
|
|
15146
|
+
{
|
|
15147
|
+
onClick: () => !viewOnly && handleSelect(category.id, category),
|
|
15148
|
+
className: cn(
|
|
15149
|
+
"relative flex min-w-0 items-center gap-2.5 px-3 py-2.5 min-h-11 transition-all duration-200 rounded-3xl",
|
|
15150
|
+
// Không phân biệt parent/child - đồng bộ màu
|
|
15151
|
+
!viewOnly && "cursor-pointer",
|
|
15152
|
+
!viewOnly && !isSelected && "hover:bg-accent/50",
|
|
15153
|
+
// Selected state - đồng bộ cho tất cả
|
|
15154
|
+
!viewOnly && isSelected && "bg-accent/40"
|
|
15155
|
+
),
|
|
15156
|
+
style: { paddingLeft: `${level * 1.25 + 0.75}rem` },
|
|
15157
|
+
children: [
|
|
15158
|
+
hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
15159
|
+
"button",
|
|
15160
|
+
{
|
|
15161
|
+
type: "button",
|
|
15162
|
+
onClick: (e) => {
|
|
15163
|
+
e.stopPropagation();
|
|
15164
|
+
toggleExpand(category.id);
|
|
15165
|
+
},
|
|
15166
|
+
className: cn(
|
|
15167
|
+
"p-1.5 rounded-lg transition-all duration-200",
|
|
15168
|
+
"hover:scale-110 active:scale-95",
|
|
15169
|
+
"focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50",
|
|
15170
|
+
isExpanded && "text-primary",
|
|
15171
|
+
isSearchMode && "opacity-60 cursor-not-allowed hover:scale-100 active:scale-100"
|
|
15172
|
+
),
|
|
15173
|
+
disabled: isSearchMode,
|
|
15174
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: cn("transition-transform duration-200", isExpanded && "rotate-90"), children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react25.ChevronRight, { className: "w-4 h-4" }) })
|
|
15175
|
+
}
|
|
15176
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "w-7" }),
|
|
15177
|
+
viewOnly ? (
|
|
15178
|
+
// View-only mode: just display the name with folder icon
|
|
15179
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex min-w-0 items-center gap-2.5", children: [
|
|
15180
|
+
category.icon ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "h-4 w-4 shrink-0 flex items-center justify-center text-muted-foreground/60", children: category.icon }) : hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react25.FolderTree, { className: "h-4 w-4 shrink-0 text-muted-foreground/60" }) : /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "h-1.5 w-1.5 shrink-0 rounded-full bg-muted-foreground/40" }),
|
|
15181
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "min-w-0 text-sm font-medium leading-snug break-words [overflow-wrap:anywhere]", children: category.name })
|
|
15182
|
+
] })
|
|
15183
|
+
) : (
|
|
15184
|
+
// Single/Multi select mode: icon + text + badge
|
|
15185
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2.5 overflow-hidden", children: [
|
|
15186
|
+
category.icon && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "h-4 w-4 shrink-0 flex items-center justify-center text-current", children: category.icon }),
|
|
15187
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
15188
|
+
"span",
|
|
15189
|
+
{
|
|
15190
|
+
className: cn(
|
|
15191
|
+
"min-w-0 flex-1 text-sm leading-snug break-words [overflow-wrap:anywhere] transition-all duration-200",
|
|
15192
|
+
isSelected ? "font-semibold text-primary" : "text-foreground/80"
|
|
15193
|
+
),
|
|
15194
|
+
children: category.name
|
|
15195
|
+
}
|
|
15196
|
+
),
|
|
15197
|
+
hasChildren && !isSelected && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "ml-auto shrink-0 text-[10px] font-medium text-muted-foreground/50 bg-muted/50 px-1.5 py-0.5 rounded-md", children: children.length })
|
|
15198
|
+
] })
|
|
15199
|
+
)
|
|
15200
|
+
]
|
|
15201
|
+
}
|
|
15151
15202
|
),
|
|
15152
|
-
|
|
15153
|
-
|
|
15154
|
-
|
|
15155
|
-
|
|
15156
|
-
|
|
15157
|
-
type: "button",
|
|
15158
|
-
onClick: (e) => {
|
|
15159
|
-
e.stopPropagation();
|
|
15160
|
-
toggleExpand(category.id);
|
|
15161
|
-
},
|
|
15162
|
-
className: cn(
|
|
15163
|
-
"p-1.5 rounded-lg transition-all duration-200",
|
|
15164
|
-
"hover:scale-110 active:scale-95",
|
|
15165
|
-
"focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50",
|
|
15166
|
-
isExpanded && "text-primary",
|
|
15167
|
-
isSearchMode && "opacity-60 cursor-not-allowed hover:scale-100 active:scale-100"
|
|
15168
|
-
),
|
|
15169
|
-
disabled: isSearchMode,
|
|
15170
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: cn("transition-transform duration-200", isExpanded && "rotate-90"), children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react25.ChevronRight, { className: "w-4 h-4" }) })
|
|
15171
|
-
}
|
|
15172
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "w-7" }),
|
|
15173
|
-
viewOnly ? (
|
|
15174
|
-
// View-only mode: just display the name with folder icon
|
|
15175
|
-
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-2.5", children: [
|
|
15176
|
-
category.icon ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "w-4 h-4 flex items-center justify-center text-muted-foreground/60", children: category.icon }) : hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react25.FolderTree, { className: "w-4 h-4 text-muted-foreground/60" }) : /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "w-1.5 h-1.5 rounded-full bg-muted-foreground/40" }),
|
|
15177
|
-
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-sm font-medium", children: category.name })
|
|
15178
|
-
] })
|
|
15179
|
-
) : (
|
|
15180
|
-
// Single/Multi select mode: icon + text + badge
|
|
15181
|
-
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-2.5 flex-1", children: [
|
|
15182
|
-
category.icon && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "w-4 h-4 flex items-center justify-center text-current", children: category.icon }),
|
|
15183
|
-
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: cn("text-sm transition-all duration-200", isSelected ? "font-semibold text-primary" : "text-foreground/80"), children: category.name }),
|
|
15184
|
-
hasChildren && !isSelected && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "ml-auto text-[10px] font-medium text-muted-foreground/50 bg-muted/50 px-1.5 py-0.5 rounded-md", children: children.length })
|
|
15185
|
-
] })
|
|
15186
|
-
)
|
|
15187
|
-
]
|
|
15188
|
-
}
|
|
15189
|
-
),
|
|
15190
|
-
hasChildren && isExpanded && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: cn("ml-2 pl-2 border-l-2 border-dashed border-border/50", "animate-in slide-in-from-top-2 fade-in-50 duration-200"), children: children.map((child) => renderCategory(child, level + 1)) })
|
|
15191
|
-
] }, category.id);
|
|
15203
|
+
hasChildren && isExpanded && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: cn("ml-2 pl-2 border-l-2 border-dashed border-border/50", "animate-in slide-in-from-top-2 fade-in-50 duration-200"), children: children.map((child) => renderCategory(child, level + 1)) })
|
|
15204
|
+
]
|
|
15205
|
+
},
|
|
15206
|
+
category.id
|
|
15207
|
+
);
|
|
15192
15208
|
};
|
|
15193
|
-
const renderSearch = () => {
|
|
15209
|
+
const renderSearch = ({ sticky = true, className: className2 } = {}) => {
|
|
15194
15210
|
if (!isSearchEnabled) return null;
|
|
15195
|
-
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "sticky top-0 z-10 bg-popover/85 backdrop-blur-xl
|
|
15211
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: cn(sticky && "sticky top-0 z-10 bg-popover/85 pb-2 backdrop-blur-xl", className2), children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "relative", children: [
|
|
15196
15212
|
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react25.Search, { className: "absolute left-3.5 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground/60 transition-colors peer-focus:text-primary" }),
|
|
15197
15213
|
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
15198
15214
|
"input",
|
|
@@ -15234,7 +15250,18 @@ function CategoryTreeSelect(props) {
|
|
|
15234
15250
|
if (!isSearchMode) return parentCategories;
|
|
15235
15251
|
return parentCategories.filter((c) => visibleIds?.has(c.id));
|
|
15236
15252
|
}, [isSearchMode, parentCategories, visibleIds]);
|
|
15237
|
-
const
|
|
15253
|
+
const effectiveChildrenMap = (0, import_react19.useMemo)(() => {
|
|
15254
|
+
if (!isSearchMode || !visibleIds) return childrenMap;
|
|
15255
|
+
const next = /* @__PURE__ */ new Map();
|
|
15256
|
+
for (const [parentId, children] of childrenMap.entries()) {
|
|
15257
|
+
next.set(
|
|
15258
|
+
parentId,
|
|
15259
|
+
children.filter((child) => visibleIds.has(child.id))
|
|
15260
|
+
);
|
|
15261
|
+
}
|
|
15262
|
+
return next;
|
|
15263
|
+
}, [childrenMap, isSearchMode, visibleIds]);
|
|
15264
|
+
const renderTreeContent = () => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "space-y-0.5 overflow-x-hidden", children: effectiveParentCategories.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
|
|
15238
15265
|
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "w-12 h-12 rounded-2xl bg-muted/50 flex items-center justify-center mb-3", children: isSearchMode ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react25.SearchX, { className: "w-6 h-6 text-muted-foreground/50" }) : /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react25.Layers, { className: "w-6 h-6 text-muted-foreground/50" }) }),
|
|
15239
15266
|
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-sm text-muted-foreground", children: isSearchMode ? mergedLabels.noResultsText : mergedLabels.emptyText })
|
|
15240
15267
|
] }) : effectiveParentCategories.map((cat) => renderCategory(cat)) });
|
|
@@ -15357,104 +15384,108 @@ function CategoryTreeSelect(props) {
|
|
|
15357
15384
|
displayText = mergedLabels.selectedText(selectedCount);
|
|
15358
15385
|
}
|
|
15359
15386
|
}
|
|
15387
|
+
const dropdownBody = /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex max-h-80 flex-col overflow-hidden", children: [
|
|
15388
|
+
renderSearch({ sticky: false, className: "border-b border-border/30 p-2 pb-2" }),
|
|
15389
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
15390
|
+
"div",
|
|
15391
|
+
{
|
|
15392
|
+
ref: dropdownViewportRef,
|
|
15393
|
+
id: `${resolvedId}-tree`,
|
|
15394
|
+
className: cn("min-h-0 flex-1 overflow-auto overflow-x-hidden p-2 pt-2"),
|
|
15395
|
+
children: renderTreeContent()
|
|
15396
|
+
}
|
|
15397
|
+
)
|
|
15398
|
+
] });
|
|
15360
15399
|
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: cn("w-full space-y-2", className), children: [
|
|
15361
15400
|
renderLabel(),
|
|
15362
|
-
/* @__PURE__ */ (0, import_jsx_runtime46.
|
|
15363
|
-
|
|
15364
|
-
|
|
15365
|
-
|
|
15366
|
-
|
|
15367
|
-
|
|
15368
|
-
|
|
15369
|
-
|
|
15370
|
-
|
|
15371
|
-
|
|
15372
|
-
"
|
|
15373
|
-
"
|
|
15374
|
-
"
|
|
15375
|
-
|
|
15376
|
-
|
|
15377
|
-
|
|
15378
|
-
"group flex w-full items-center justify-between rounded-full transition-all duration-200",
|
|
15379
|
-
"backdrop-blur-sm",
|
|
15380
|
-
triggerSizeStyles[size].button,
|
|
15381
|
-
triggerVariantStyles[variant],
|
|
15382
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
15383
|
-
disabled && "opacity-50 cursor-not-allowed hover:transform-none hover:shadow-none",
|
|
15384
|
-
isOpen && "ring-2 ring-primary/30 border-primary/50 shadow-lg shadow-primary/10",
|
|
15385
|
-
error && "border-destructive focus-visible:ring-destructive/30"
|
|
15386
|
-
),
|
|
15387
|
-
children: [
|
|
15388
|
-
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2.5 text-left", children: [
|
|
15389
|
-
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
15390
|
-
"div",
|
|
15391
|
-
{
|
|
15392
|
-
className: cn(
|
|
15393
|
-
"shrink-0 flex items-center justify-center rounded-lg transition-all duration-300",
|
|
15394
|
-
triggerSizeStyles[size].iconWrap,
|
|
15395
|
-
isOpen ? "bg-primary/15 text-primary" : "bg-muted/50 text-muted-foreground group-hover:bg-primary/10 group-hover:text-primary"
|
|
15396
|
-
),
|
|
15397
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react25.FolderTree, { className: cn(triggerSizeStyles[size].icon, "transition-transform duration-300", isOpen && "scale-110") })
|
|
15398
|
-
}
|
|
15399
|
-
),
|
|
15400
|
-
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
15401
|
-
"span",
|
|
15402
|
-
{
|
|
15403
|
-
className: cn(
|
|
15404
|
-
"min-w-0 flex-1 truncate font-medium transition-colors duration-200",
|
|
15405
|
-
triggerSizeStyles[size].text,
|
|
15406
|
-
selectedCount === 0 ? "text-muted-foreground" : "text-foreground"
|
|
15407
|
-
),
|
|
15408
|
-
title: displayText,
|
|
15409
|
-
children: displayText
|
|
15410
|
-
}
|
|
15411
|
-
)
|
|
15412
|
-
] }),
|
|
15413
|
-
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "ml-2 flex shrink-0 items-center gap-1.5", children: [
|
|
15414
|
-
allowClear && selectedCount > 0 && !disabled && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
15415
|
-
"div",
|
|
15416
|
-
{
|
|
15417
|
-
role: "button",
|
|
15418
|
-
tabIndex: 0,
|
|
15419
|
-
"aria-label": "Clear selection",
|
|
15420
|
-
onClick: handleClear,
|
|
15421
|
-
onKeyDown: (event) => (event.key === "Enter" || event.key === " ") && handleClear(event),
|
|
15422
|
-
className: cn(
|
|
15423
|
-
"opacity-0 group-hover:opacity-100 transition-all duration-200",
|
|
15424
|
-
"p-1 rounded-lg hover:bg-destructive/10 text-muted-foreground hover:text-destructive",
|
|
15425
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30"
|
|
15426
|
-
),
|
|
15427
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react25.X, { className: triggerSizeStyles[size].clearIcon })
|
|
15428
|
-
}
|
|
15429
|
-
),
|
|
15430
|
-
selectedCount > 0 && !singleSelect && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: cn("rounded-full bg-primary/15 font-bold text-primary", triggerSizeStyles[size].badge), children: selectedCount }),
|
|
15431
|
-
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: cn("transition-all duration-300 text-muted-foreground group-hover:text-foreground", isOpen && "rotate-180 text-primary"), children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react25.ChevronDown, { className: triggerSizeStyles[size].actionIcon }) })
|
|
15432
|
-
] })
|
|
15433
|
-
]
|
|
15434
|
-
}
|
|
15435
|
-
),
|
|
15436
|
-
isOpen && !disabled && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_jsx_runtime46.Fragment, { children: [
|
|
15437
|
-
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "fixed inset-0 z-10", onClick: () => setIsOpen(false) }),
|
|
15438
|
-
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
15439
|
-
"div",
|
|
15401
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
15402
|
+
Popover,
|
|
15403
|
+
{
|
|
15404
|
+
open: isOpen,
|
|
15405
|
+
onOpenChange: setIsOpen,
|
|
15406
|
+
disabled,
|
|
15407
|
+
placement: "bottom-start",
|
|
15408
|
+
matchTriggerWidth: true,
|
|
15409
|
+
className: "z-9999",
|
|
15410
|
+
contentClassName: cn(
|
|
15411
|
+
"p-0 overflow-hidden rounded-2xl md:rounded-3xl",
|
|
15412
|
+
"border-border/40 bg-popover/95 text-popover-foreground",
|
|
15413
|
+
"shadow-2xl backdrop-blur-xl"
|
|
15414
|
+
),
|
|
15415
|
+
trigger: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
15416
|
+
"button",
|
|
15440
15417
|
{
|
|
15441
|
-
|
|
15442
|
-
|
|
15418
|
+
id: resolvedId,
|
|
15419
|
+
type: "button",
|
|
15420
|
+
disabled,
|
|
15421
|
+
role: "combobox",
|
|
15422
|
+
"aria-haspopup": "tree",
|
|
15423
|
+
"aria-controls": `${resolvedId}-tree`,
|
|
15424
|
+
"aria-labelledby": labelId,
|
|
15425
|
+
"aria-describedby": describedBy,
|
|
15426
|
+
"aria-invalid": !!error,
|
|
15443
15427
|
className: cn(
|
|
15444
|
-
"
|
|
15445
|
-
"
|
|
15446
|
-
|
|
15447
|
-
|
|
15448
|
-
"
|
|
15428
|
+
"group flex w-full items-center justify-between rounded-full transition-all duration-200",
|
|
15429
|
+
"backdrop-blur-sm",
|
|
15430
|
+
triggerSizeStyles[size].button,
|
|
15431
|
+
triggerVariantStyles[variant],
|
|
15432
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
15433
|
+
disabled && "opacity-50 cursor-not-allowed hover:transform-none hover:shadow-none",
|
|
15434
|
+
isOpen && "ring-2 ring-primary/30 border-primary/50 shadow-lg shadow-primary/10",
|
|
15435
|
+
error && "border-destructive focus-visible:ring-destructive/30"
|
|
15449
15436
|
),
|
|
15450
15437
|
children: [
|
|
15451
|
-
|
|
15452
|
-
|
|
15438
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2.5 text-left", children: [
|
|
15439
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
15440
|
+
"div",
|
|
15441
|
+
{
|
|
15442
|
+
className: cn(
|
|
15443
|
+
"shrink-0 flex items-center justify-center rounded-lg transition-all duration-300",
|
|
15444
|
+
triggerSizeStyles[size].iconWrap,
|
|
15445
|
+
isOpen ? "bg-primary/15 text-primary" : "bg-muted/50 text-muted-foreground group-hover:bg-primary/10 group-hover:text-primary"
|
|
15446
|
+
),
|
|
15447
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react25.FolderTree, { className: cn(triggerSizeStyles[size].icon, "transition-transform duration-300", isOpen && "scale-110") })
|
|
15448
|
+
}
|
|
15449
|
+
),
|
|
15450
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
15451
|
+
"span",
|
|
15452
|
+
{
|
|
15453
|
+
className: cn(
|
|
15454
|
+
"min-w-0 flex-1 truncate font-medium transition-colors duration-200",
|
|
15455
|
+
triggerSizeStyles[size].text,
|
|
15456
|
+
selectedCount === 0 ? "text-muted-foreground" : "text-foreground"
|
|
15457
|
+
),
|
|
15458
|
+
title: displayText,
|
|
15459
|
+
children: displayText
|
|
15460
|
+
}
|
|
15461
|
+
)
|
|
15462
|
+
] }),
|
|
15463
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "ml-2 flex shrink-0 items-center gap-1.5", children: [
|
|
15464
|
+
allowClear && selectedCount > 0 && !disabled && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
15465
|
+
"div",
|
|
15466
|
+
{
|
|
15467
|
+
role: "button",
|
|
15468
|
+
tabIndex: 0,
|
|
15469
|
+
"aria-label": "Clear selection",
|
|
15470
|
+
onClick: handleClear,
|
|
15471
|
+
onKeyDown: (event) => (event.key === "Enter" || event.key === " ") && handleClear(event),
|
|
15472
|
+
className: cn(
|
|
15473
|
+
"opacity-0 group-hover:opacity-100 transition-all duration-200",
|
|
15474
|
+
"p-1 rounded-lg hover:bg-destructive/10 text-muted-foreground hover:text-destructive",
|
|
15475
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30"
|
|
15476
|
+
),
|
|
15477
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react25.X, { className: triggerSizeStyles[size].clearIcon })
|
|
15478
|
+
}
|
|
15479
|
+
),
|
|
15480
|
+
selectedCount > 0 && !singleSelect && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: cn("rounded-full bg-primary/15 font-bold text-primary", triggerSizeStyles[size].badge), children: selectedCount }),
|
|
15481
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: cn("transition-all duration-300 text-muted-foreground group-hover:text-foreground", isOpen && "rotate-180 text-primary"), children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react25.ChevronDown, { className: triggerSizeStyles[size].actionIcon }) })
|
|
15482
|
+
] })
|
|
15453
15483
|
]
|
|
15454
15484
|
}
|
|
15455
|
-
)
|
|
15456
|
-
|
|
15457
|
-
|
|
15485
|
+
),
|
|
15486
|
+
children: dropdownBody
|
|
15487
|
+
}
|
|
15488
|
+
),
|
|
15458
15489
|
renderAssistiveText()
|
|
15459
15490
|
] });
|
|
15460
15491
|
}
|