@underverse-ui/underverse 1.0.97 → 1.0.98

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@underverse-ui/underverse",
3
- "version": "1.0.97",
3
+ "version": "1.0.98",
4
4
  "sourceEntry": "src/index.ts",
5
5
  "totalExports": 225,
6
6
  "exports": [
package/dist/index.cjs CHANGED
@@ -17119,15 +17119,47 @@ var TREE_NODE_INDENT_REM = 1;
17119
17119
  var TREE_BRANCH_OFFSET_CLASS = "ml-1.5 pl-1.5";
17120
17120
  var TREE_NODE_GAP_CLASS = "gap-1.5";
17121
17121
  var TREE_EXPANDER_PLACEHOLDER_CLASS = "w-5";
17122
- function getInitialExpandedNodes(categories, defaultExpanded, viewOnly, inline) {
17123
- if (!(viewOnly || inline) || !defaultExpanded) return /* @__PURE__ */ new Set();
17124
- const parentIds = /* @__PURE__ */ new Set();
17125
- for (const category of categories) {
17126
- if (typeof category.parent_id === "number") {
17127
- parentIds.add(category.parent_id);
17122
+ function getAncestorPathIds(categories, targetId) {
17123
+ const byId = new Map(categories.map((category) => [category.id, category]));
17124
+ const expanded = /* @__PURE__ */ new Set();
17125
+ let current = byId.get(targetId);
17126
+ let guard = 0;
17127
+ while (current && guard++ < categories.length) {
17128
+ expanded.add(current.id);
17129
+ if (typeof current.parent_id !== "number") break;
17130
+ current = byId.get(current.parent_id);
17131
+ }
17132
+ return expanded;
17133
+ }
17134
+ function getInitialExpandedNodes(categories, {
17135
+ defaultExpanded,
17136
+ defaultExpandedIds,
17137
+ expandToId,
17138
+ viewOnly,
17139
+ inline
17140
+ }) {
17141
+ const expanded = /* @__PURE__ */ new Set();
17142
+ if ((viewOnly || inline) && defaultExpanded) {
17143
+ for (const category of categories) {
17144
+ if (typeof category.parent_id === "number") {
17145
+ expanded.add(category.parent_id);
17146
+ }
17147
+ }
17148
+ }
17149
+ for (const id of defaultExpandedIds ?? []) {
17150
+ if (typeof id === "number") {
17151
+ expanded.add(id);
17128
17152
  }
17129
17153
  }
17130
- return parentIds;
17154
+ if (typeof expandToId === "number") {
17155
+ for (const id of getAncestorPathIds(categories, expandToId)) {
17156
+ expanded.add(id);
17157
+ }
17158
+ }
17159
+ return expanded;
17160
+ }
17161
+ function getExpandedNodesState(expandedIds, uncontrolledExpandedNodes) {
17162
+ return expandedIds !== void 0 ? new Set(expandedIds) : uncontrolledExpandedNodes;
17131
17163
  }
17132
17164
  function CategoryTreeSelect(props) {
17133
17165
  const tv = useSmartTranslations("ValidationInput");
@@ -17146,6 +17178,10 @@ function CategoryTreeSelect(props) {
17146
17178
  helperText,
17147
17179
  viewOnly = false,
17148
17180
  defaultExpanded = false,
17181
+ defaultExpandedIds,
17182
+ expandToId = null,
17183
+ expandedIds,
17184
+ onExpandedChange,
17149
17185
  enableSearch,
17150
17186
  labels,
17151
17187
  inline = false,
@@ -17156,7 +17192,9 @@ function CategoryTreeSelect(props) {
17156
17192
  singleSelect = false
17157
17193
  } = props;
17158
17194
  const [isOpen, setIsOpen] = (0, import_react22.useState)(false);
17159
- const [expandedNodes, setExpandedNodes] = (0, import_react22.useState)(() => getInitialExpandedNodes(categories, defaultExpanded, viewOnly, inline));
17195
+ const [expandedNodes, setExpandedNodes] = (0, import_react22.useState)(
17196
+ () => getInitialExpandedNodes(categories, { defaultExpanded, defaultExpandedIds, expandToId, viewOnly, inline })
17197
+ );
17160
17198
  const [query, setQuery] = (0, import_react22.useState)("");
17161
17199
  const [localRequiredError, setLocalRequiredError] = (0, import_react22.useState)();
17162
17200
  const searchInputRef = (0, import_react22.useRef)(null);
@@ -17193,6 +17231,7 @@ function CategoryTreeSelect(props) {
17193
17231
  const isSearchEnabled = (0, import_react22.useMemo)(() => enableSearch ?? categories.length > 10, [enableSearch, categories.length]);
17194
17232
  const normalizedQuery = (0, import_react22.useMemo)(() => query.trim().toLowerCase(), [query]);
17195
17233
  const isSearchMode = isSearchEnabled && normalizedQuery.length > 0;
17234
+ const effectiveExpandedNodes = (0, import_react22.useMemo)(() => getExpandedNodesState(expandedIds, expandedNodes), [expandedIds, expandedNodes]);
17196
17235
  const visibleIds = (0, import_react22.useMemo)(() => {
17197
17236
  if (!isSearchMode) return null;
17198
17237
  const matches = categories.filter((c) => c.name.toLowerCase().includes(normalizedQuery));
@@ -17245,13 +17284,16 @@ function CategoryTreeSelect(props) {
17245
17284
  }, [disabled, required, valueArray.length]);
17246
17285
  const toggleExpand = (id2) => {
17247
17286
  if (isSearchMode) return;
17248
- const newExpanded = new Set(expandedNodes);
17287
+ const newExpanded = new Set(effectiveExpandedNodes);
17249
17288
  if (newExpanded.has(id2)) {
17250
17289
  newExpanded.delete(id2);
17251
17290
  } else {
17252
17291
  newExpanded.add(id2);
17253
17292
  }
17254
- setExpandedNodes(newExpanded);
17293
+ if (expandedIds === void 0) {
17294
+ setExpandedNodes(newExpanded);
17295
+ }
17296
+ onExpandedChange?.(Array.from(newExpanded));
17255
17297
  };
17256
17298
  const handleSelect = (categoryId, category) => {
17257
17299
  if (viewOnly) return;
@@ -17293,7 +17335,7 @@ function CategoryTreeSelect(props) {
17293
17335
  const renderCategory = (category, level = 0) => {
17294
17336
  const children = effectiveChildrenMap.get(category.id) || [];
17295
17337
  const hasChildren = children.length > 0;
17296
- const isExpanded = hasChildren && (isSearchMode || expandedNodes.has(category.id));
17338
+ const isExpanded = hasChildren && (isSearchMode || effectiveExpandedNodes.has(category.id));
17297
17339
  const isSelected = selectedIds.has(category.id);
17298
17340
  const isSelectable = !viewOnly && (!leafOnlySelect || !hasChildren);
17299
17341
  return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(