@underverse-ui/underverse 0.2.43 → 0.2.44

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 CHANGED
@@ -8119,9 +8119,23 @@ function OverlayControls({
8119
8119
  var import_react18 = require("react");
8120
8120
  var import_lucide_react19 = require("lucide-react");
8121
8121
  var import_jsx_runtime36 = require("react/jsx-runtime");
8122
- function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1ECDn danh m\u1EE5c", disabled }) {
8122
+ var defaultLabels = {
8123
+ emptyText: "No categories",
8124
+ selectedText: (count) => `${count} selected`
8125
+ };
8126
+ function CategoryTreeSelect({
8127
+ categories,
8128
+ value = [],
8129
+ onChange,
8130
+ placeholder = "Select category",
8131
+ disabled,
8132
+ viewOnly = false,
8133
+ defaultExpanded = false,
8134
+ labels
8135
+ }) {
8123
8136
  const [isOpen, setIsOpen] = (0, import_react18.useState)(false);
8124
8137
  const [expandedNodes, setExpandedNodes] = (0, import_react18.useState)(/* @__PURE__ */ new Set());
8138
+ const mergedLabels = { ...defaultLabels, ...labels };
8125
8139
  const parentCategories = categories.filter((c) => !c.parent_id);
8126
8140
  const childrenMap = /* @__PURE__ */ new Map();
8127
8141
  categories.forEach((cat) => {
@@ -8132,6 +8146,12 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
8132
8146
  childrenMap.get(cat.parent_id).push(cat);
8133
8147
  }
8134
8148
  });
8149
+ (0, import_react18.useEffect)(() => {
8150
+ if (viewOnly && defaultExpanded) {
8151
+ const allParentIds = categories.filter((c) => childrenMap.has(c.id)).map((c) => c.id);
8152
+ setExpandedNodes(new Set(allParentIds));
8153
+ }
8154
+ }, [viewOnly, defaultExpanded, categories]);
8135
8155
  const toggleExpand = (id) => {
8136
8156
  const newExpanded = new Set(expandedNodes);
8137
8157
  if (newExpanded.has(id)) {
@@ -8142,6 +8162,7 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
8142
8162
  setExpandedNodes(newExpanded);
8143
8163
  };
8144
8164
  const handleSelect = (categoryId, category) => {
8165
+ if (viewOnly || !onChange) return;
8145
8166
  const newSelected = new Set(value);
8146
8167
  if (newSelected.has(categoryId)) {
8147
8168
  newSelected.delete(categoryId);
@@ -8165,20 +8186,14 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
8165
8186
  "div",
8166
8187
  {
8167
8188
  className: cn(
8168
- "relative flex items-center gap-2 px-3 py-2 cursor-pointer rounded-md transition-colors",
8169
- "hover:bg-accent",
8170
- // Selected state: subtle bg + square left indicator, avoid left rounding
8171
- isSelected && "bg-primary/10 rounded-r-md"
8189
+ "relative flex items-center gap-2 px-3 py-2 rounded-md transition-colors",
8190
+ !viewOnly && "cursor-pointer hover:bg-accent",
8191
+ // Selected state: subtle bg + square left indicator (only in select mode)
8192
+ !viewOnly && isSelected && "bg-primary/10 rounded-r-md"
8172
8193
  ),
8173
8194
  style: { paddingLeft: `${level * 1.5 + 0.75}rem` },
8174
8195
  children: [
8175
- isSelected && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8176
- "span",
8177
- {
8178
- "aria-hidden": true,
8179
- className: "absolute left-0 top-0 bottom-0 w-1 bg-primary"
8180
- }
8181
- ),
8196
+ !viewOnly && isSelected && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { "aria-hidden": true, className: "absolute left-0 top-0 bottom-0 w-1 bg-primary" }),
8182
8197
  hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8183
8198
  "button",
8184
8199
  {
@@ -8191,25 +8206,24 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
8191
8206
  children: isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react19.ChevronDown, { className: "w-4 h-4" }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react19.ChevronRight, { className: "w-4 h-4" })
8192
8207
  }
8193
8208
  ) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "w-5" }),
8194
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
8195
- "div",
8196
- {
8197
- onClick: () => handleSelect(category.id, category),
8198
- className: "flex items-center gap-2 flex-1",
8199
- children: [
8200
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8201
- "div",
8202
- {
8203
- className: cn(
8204
- "w-4 h-4 border-2 rounded flex items-center justify-center transition-colors",
8205
- isSelected ? "bg-primary border-primary" : "border-muted-foreground/30"
8206
- ),
8207
- children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react19.Check, { className: "w-3 h-3 text-primary-foreground" })
8208
- }
8209
- ),
8210
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: cn("text-sm", isSelected && "font-medium text-primary"), children: category.name })
8211
- ]
8212
- }
8209
+ viewOnly ? (
8210
+ // View-only mode: just display the name
8211
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "text-sm", children: category.name })
8212
+ ) : (
8213
+ // Select mode: clickable with checkbox
8214
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { onClick: () => handleSelect(category.id, category), className: "flex items-center gap-2 flex-1", children: [
8215
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8216
+ "div",
8217
+ {
8218
+ className: cn(
8219
+ "w-4 h-4 border-2 rounded flex items-center justify-center transition-colors",
8220
+ isSelected ? "bg-primary border-primary" : "border-muted-foreground/30"
8221
+ ),
8222
+ children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react19.Check, { className: "w-3 h-3 text-primary-foreground" })
8223
+ }
8224
+ ),
8225
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: cn("text-sm", isSelected && "font-medium text-primary"), children: category.name })
8226
+ ] })
8213
8227
  )
8214
8228
  ]
8215
8229
  }
@@ -8217,8 +8231,11 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
8217
8231
  hasChildren && isExpanded && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { children: children.map((child) => renderCategory(child, level + 1)) })
8218
8232
  ] }, category.id);
8219
8233
  };
8234
+ if (viewOnly) {
8235
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: cn("rounded-md border bg-background p-2", disabled && "opacity-50"), 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)) });
8236
+ }
8220
8237
  const selectedCount = value.length;
8221
- const displayText = selectedCount > 0 ? `\u0110\xE3 ch\u1ECDn ${selectedCount} danh m\u1EE5c` : placeholder;
8238
+ const displayText = selectedCount > 0 ? mergedLabels.selectedText(selectedCount) : placeholder;
8222
8239
  return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "relative", children: [
8223
8240
  /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
8224
8241
  "button",
@@ -8251,7 +8268,7 @@ function CategoryTreeSelect({ categories, value, onChange, placeholder = "Ch\u1E
8251
8268
  "rounded-md border bg-popover text-popover-foreground shadow-md",
8252
8269
  "backdrop-blur-sm bg-popover/95 border-border/60"
8253
8270
  ),
8254
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "p-1", children: parentCategories.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "px-3 py-2 text-sm text-muted-foreground", children: "Kh\xF4ng c\xF3 danh m\u1EE5c n\xE0o" }) : parentCategories.map((cat) => renderCategory(cat)) })
8271
+ children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "p-1", 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)) })
8255
8272
  }
8256
8273
  )
8257
8274
  ] })