@underverse-ui/underverse 1.0.89 → 1.0.91
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 +43 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +43 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/api-reference.json
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -16421,6 +16421,25 @@ Slider.displayName = "Slider";
|
|
|
16421
16421
|
var import_lucide_react25 = require("lucide-react");
|
|
16422
16422
|
var import_react21 = __toESM(require("react"), 1);
|
|
16423
16423
|
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
16424
|
+
function resolveKeyboardEventElement(target) {
|
|
16425
|
+
if (target instanceof Element) return target;
|
|
16426
|
+
if (target instanceof Node) return target.parentElement;
|
|
16427
|
+
return null;
|
|
16428
|
+
}
|
|
16429
|
+
function isEditableKeyboardTarget(target) {
|
|
16430
|
+
const element = resolveKeyboardEventElement(target);
|
|
16431
|
+
if (!element) return false;
|
|
16432
|
+
if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement) {
|
|
16433
|
+
return true;
|
|
16434
|
+
}
|
|
16435
|
+
if (element instanceof HTMLElement && element.isContentEditable) {
|
|
16436
|
+
return true;
|
|
16437
|
+
}
|
|
16438
|
+
if (element.closest?.('[contenteditable=""],[contenteditable="true"],[contenteditable="plaintext-only"]') || element.closest?.('[role="textbox"]')) {
|
|
16439
|
+
return true;
|
|
16440
|
+
}
|
|
16441
|
+
return false;
|
|
16442
|
+
}
|
|
16424
16443
|
function OverlayControls({
|
|
16425
16444
|
mode,
|
|
16426
16445
|
value,
|
|
@@ -16519,7 +16538,7 @@ function OverlayControls({
|
|
|
16519
16538
|
import_react21.default.useEffect(() => {
|
|
16520
16539
|
if (!enableKeyboardShortcuts) return;
|
|
16521
16540
|
const handleKeyDown2 = (e) => {
|
|
16522
|
-
if (e.target
|
|
16541
|
+
if (isEditableKeyboardTarget(e.target)) return;
|
|
16523
16542
|
switch (e.key) {
|
|
16524
16543
|
case " ":
|
|
16525
16544
|
case "k":
|
|
@@ -16863,6 +16882,11 @@ var defaultLabels = {
|
|
|
16863
16882
|
searchPlaceholder: "Search...",
|
|
16864
16883
|
noResultsText: "No results found"
|
|
16865
16884
|
};
|
|
16885
|
+
var TREE_NODE_BASE_PADDING_REM = 0.75;
|
|
16886
|
+
var TREE_NODE_INDENT_REM = 1;
|
|
16887
|
+
var TREE_BRANCH_OFFSET_CLASS = "ml-1.5 pl-1.5";
|
|
16888
|
+
var TREE_NODE_GAP_CLASS = "gap-1.5";
|
|
16889
|
+
var TREE_EXPANDER_PLACEHOLDER_CLASS = "w-5";
|
|
16866
16890
|
function getInitialExpandedNodes(categories, defaultExpanded, viewOnly, inline) {
|
|
16867
16891
|
if (!(viewOnly || inline) || !defaultExpanded) return /* @__PURE__ */ new Set();
|
|
16868
16892
|
const parentIds = /* @__PURE__ */ new Set();
|
|
@@ -17051,13 +17075,14 @@ function CategoryTreeSelect(props) {
|
|
|
17051
17075
|
{
|
|
17052
17076
|
onClick: () => !viewOnly && handleSelect(category.id, category),
|
|
17053
17077
|
className: cn(
|
|
17054
|
-
"relative flex min-w-0 items-center
|
|
17078
|
+
"relative flex min-w-0 items-center px-3 py-2.5 min-h-11 transition-all duration-200 rounded-3xl",
|
|
17079
|
+
TREE_NODE_GAP_CLASS,
|
|
17055
17080
|
!viewOnly && (isSelectable ? "cursor-pointer" : "cursor-default"),
|
|
17056
17081
|
isSelectable && !isSelected && "hover:bg-accent/50",
|
|
17057
17082
|
// Selected state - đồng bộ cho tất cả
|
|
17058
17083
|
!viewOnly && isSelected && "bg-accent/40"
|
|
17059
17084
|
),
|
|
17060
|
-
style: { paddingLeft: `${level *
|
|
17085
|
+
style: { paddingLeft: `${level * TREE_NODE_INDENT_REM + TREE_NODE_BASE_PADDING_REM}rem` },
|
|
17061
17086
|
children: [
|
|
17062
17087
|
hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
17063
17088
|
"button",
|
|
@@ -17068,7 +17093,7 @@ function CategoryTreeSelect(props) {
|
|
|
17068
17093
|
toggleExpand(category.id);
|
|
17069
17094
|
},
|
|
17070
17095
|
className: cn(
|
|
17071
|
-
"p-
|
|
17096
|
+
"p-0.5 rounded-lg transition-all duration-200",
|
|
17072
17097
|
"hover:scale-110 active:scale-95",
|
|
17073
17098
|
"focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50",
|
|
17074
17099
|
isExpanded && "text-primary",
|
|
@@ -17077,16 +17102,16 @@ function CategoryTreeSelect(props) {
|
|
|
17077
17102
|
disabled: isSearchMode,
|
|
17078
17103
|
children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: cn("transition-transform duration-200", isExpanded && "rotate-90"), children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_lucide_react26.ChevronRight, { className: "w-4 h-4" }) })
|
|
17079
17104
|
}
|
|
17080
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className:
|
|
17105
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: TREE_EXPANDER_PLACEHOLDER_CLASS }),
|
|
17081
17106
|
viewOnly ? (
|
|
17082
17107
|
// View-only mode: just display the name with folder icon
|
|
17083
|
-
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex min-w-0 items-center
|
|
17108
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: cn("flex min-w-0 items-center", TREE_NODE_GAP_CLASS), children: [
|
|
17084
17109
|
category.icon ? /* @__PURE__ */ (0, import_jsx_runtime49.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_runtime49.jsx)(import_lucide_react26.FolderTree, { className: "h-4 w-4 shrink-0 text-muted-foreground/60" }) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "h-1.5 w-1.5 shrink-0 rounded-full bg-muted-foreground/40" }),
|
|
17085
17110
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "min-w-0 text-sm font-medium leading-snug break-words [overflow-wrap:anywhere]", children: category.name })
|
|
17086
17111
|
] })
|
|
17087
17112
|
) : (
|
|
17088
17113
|
// Single/Multi select mode: icon + text + badge
|
|
17089
|
-
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex min-w-0 flex-1 items-center
|
|
17114
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: cn("flex min-w-0 flex-1 items-center overflow-hidden", TREE_NODE_GAP_CLASS), children: [
|
|
17090
17115
|
category.icon && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "h-4 w-4 shrink-0 flex items-center justify-center text-current", children: category.icon }),
|
|
17091
17116
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
17092
17117
|
"span",
|
|
@@ -17105,7 +17130,17 @@ function CategoryTreeSelect(props) {
|
|
|
17105
17130
|
]
|
|
17106
17131
|
}
|
|
17107
17132
|
),
|
|
17108
|
-
hasChildren && isExpanded && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
17133
|
+
hasChildren && isExpanded && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
17134
|
+
"div",
|
|
17135
|
+
{
|
|
17136
|
+
className: cn(
|
|
17137
|
+
TREE_BRANCH_OFFSET_CLASS,
|
|
17138
|
+
"border-l-2 border-dashed border-border/50",
|
|
17139
|
+
"animate-in slide-in-from-top-2 fade-in-50 duration-200"
|
|
17140
|
+
),
|
|
17141
|
+
children: children.map((child) => renderCategory(child, level + 1))
|
|
17142
|
+
}
|
|
17143
|
+
)
|
|
17109
17144
|
]
|
|
17110
17145
|
},
|
|
17111
17146
|
category.id
|