@underverse-ui/underverse 1.0.96 → 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.
package/dist/index.js CHANGED
@@ -6608,9 +6608,15 @@ var variantStyles5 = {
6608
6608
  inactiveTab: "text-muted-foreground hover:text-foreground"
6609
6609
  }
6610
6610
  };
6611
- function getTabsBaseId(tabs) {
6611
+ function normalizeTabsId(value) {
6612
+ const normalized = value.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
6613
+ return normalized || "default";
6614
+ }
6615
+ function getTabsBaseId(tabs, id, fallbackId) {
6616
+ if (id) return `tabs-${normalizeTabsId(id)}`;
6617
+ if (fallbackId) return `tabs-${normalizeTabsId(fallbackId)}`;
6612
6618
  const key = tabs.map((t) => t.value).join("-");
6613
- return `tabs-${key || "default"}`;
6619
+ return `tabs-${normalizeTabsId(key || "default")}`;
6614
6620
  }
6615
6621
  function getTabTriggerId(baseId, index) {
6616
6622
  return `${baseId}-tab-${index}`;
@@ -6635,6 +6641,7 @@ function shouldHandleTabClickLocally(event, target) {
6635
6641
  return !(event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || target === "_blank");
6636
6642
  }
6637
6643
  var Tabs = ({
6644
+ id,
6638
6645
  tabs,
6639
6646
  defaultValue,
6640
6647
  className,
@@ -6651,7 +6658,8 @@ var Tabs = ({
6651
6658
  const [active, setActive] = React22.useState(defaultValue || tabs[0]?.value);
6652
6659
  const [underlineStyle, setUnderlineStyle] = React22.useState({});
6653
6660
  const tabRefs = React22.useRef([]);
6654
- const baseId = React22.useMemo(() => getTabsBaseId(tabs), [tabs]);
6661
+ const autoId = React22.useId();
6662
+ const baseId = React22.useMemo(() => getTabsBaseId(tabs, id, autoId), [autoId, id, tabs]);
6655
6663
  const handleTabChange = (value) => {
6656
6664
  setActive(value);
6657
6665
  onTabChange?.(value);
@@ -7048,7 +7056,7 @@ import { ChevronLeft, ChevronRight as ChevronRight2, ChevronsLeft, ChevronsRight
7048
7056
 
7049
7057
  // src/components/Combobox.tsx
7050
7058
  import * as React24 from "react";
7051
- import { useId as useId5 } from "react";
7059
+ import { useId as useId6 } from "react";
7052
7060
  import { ChevronDown, Search as Search4, SearchX, Check as Check3, X as X9 } from "lucide-react";
7053
7061
  import { Fragment as Fragment5, jsx as jsx29, jsxs as jsxs22 } from "react/jsx-runtime";
7054
7062
  var getOptionLabel = (option) => {
@@ -7107,7 +7115,7 @@ var Combobox = ({
7107
7115
  const inputRef = React24.useRef(null);
7108
7116
  const optionsViewportRef = React24.useRef(null);
7109
7117
  useOverlayScrollbarTarget(optionsViewportRef, { enabled: useOverlayScrollbar });
7110
- const autoId = useId5();
7118
+ const autoId = useId6();
7111
7119
  const resolvedId = id ? String(id) : `combobox-${autoId}`;
7112
7120
  const labelId = label ? `${resolvedId}-label` : void 0;
7113
7121
  const enableSearch = options.length > 10;
@@ -8169,7 +8177,7 @@ function formatDateSmart(date, locale = "en") {
8169
8177
  // src/components/DatePicker.tsx
8170
8178
  import { Calendar, ChevronLeft as ChevronLeft2, ChevronRight as ChevronRight3, Sparkles as Sparkles2, X as XIcon } from "lucide-react";
8171
8179
  import * as React28 from "react";
8172
- import { useId as useId6 } from "react";
8180
+ import { useId as useId7 } from "react";
8173
8181
  import { Fragment as Fragment6, jsx as jsx34, jsxs as jsxs24 } from "react/jsx-runtime";
8174
8182
  var DatePicker = ({
8175
8183
  id,
@@ -8576,7 +8584,7 @@ var DatePicker = ({
8576
8584
  )
8577
8585
  ] })
8578
8586
  ] });
8579
- const autoId = useId6();
8587
+ const autoId = useId7();
8580
8588
  const resolvedId = id ? String(id) : `datepicker-${autoId}`;
8581
8589
  const labelId = label ? `${resolvedId}-label` : void 0;
8582
8590
  const labelSize = sizeStyles8[size].label;
@@ -9155,7 +9163,7 @@ var DateRangePicker = ({
9155
9163
  const displayFormat = (date) => formatDateShort(date);
9156
9164
  const displayLabel = tempStart && tempEnd ? `${displayFormat(tempStart)} - ${displayFormat(tempEnd)}` : tempStart ? `${displayFormat(tempStart)} - ...` : placeholder;
9157
9165
  const effectiveError = localRequiredError;
9158
- const autoId = useId6();
9166
+ const autoId = useId7();
9159
9167
  const resolvedId = id ? String(id) : `daterangepicker-${autoId}`;
9160
9168
  const labelId = label ? `${resolvedId}-label` : void 0;
9161
9169
  return /* @__PURE__ */ jsxs24("div", { className: cn("space-y-1.5", className), children: [
@@ -15270,7 +15278,7 @@ function CalendarTimeline({
15270
15278
 
15271
15279
  // src/components/MultiCombobox.tsx
15272
15280
  import * as React39 from "react";
15273
- import { useId as useId8 } from "react";
15281
+ import { useId as useId9 } from "react";
15274
15282
  import { ChevronDown as ChevronDown4, Search as Search5, Check as Check6, SearchX as SearchX2, Loader2 as Loader24, X as X13, Sparkles as Sparkles3 } from "lucide-react";
15275
15283
  import { Fragment as Fragment13, jsx as jsx45, jsxs as jsxs35 } from "react/jsx-runtime";
15276
15284
  var MultiCombobox = ({
@@ -15408,7 +15416,7 @@ var MultiCombobox = ({
15408
15416
  outline: "border-2 border-input bg-transparent hover:border-primary",
15409
15417
  ghost: "border border-transparent bg-muted/50 hover:bg-muted"
15410
15418
  };
15411
- const autoId = useId8();
15419
+ const autoId = useId9();
15412
15420
  const resolvedId = id ? String(id) : `multicombobox-${autoId}`;
15413
15421
  const labelId = label ? `${resolvedId}-label` : void 0;
15414
15422
  const labelSize = size === "sm" ? "text-xs" : size === "lg" ? "text-base" : "text-sm";
@@ -16912,7 +16920,7 @@ function OverlayControls({
16912
16920
  }
16913
16921
 
16914
16922
  // src/components/CategoryTreeSelect.tsx
16915
- import { useEffect as useEffect25, useId as useId10, useMemo as useMemo19, useRef as useRef19, useState as useState31 } from "react";
16923
+ import { useEffect as useEffect25, useId as useId11, useMemo as useMemo19, useRef as useRef19, useState as useState31 } from "react";
16916
16924
  import { ChevronRight as ChevronRight6, ChevronDown as ChevronDown5, FolderTree, Layers, Search as Search6, SearchX as SearchX3, X as X14 } from "lucide-react";
16917
16925
  import { jsx as jsx49, jsxs as jsxs39 } from "react/jsx-runtime";
16918
16926
  var defaultLabels = {
@@ -16926,15 +16934,47 @@ var TREE_NODE_INDENT_REM = 1;
16926
16934
  var TREE_BRANCH_OFFSET_CLASS = "ml-1.5 pl-1.5";
16927
16935
  var TREE_NODE_GAP_CLASS = "gap-1.5";
16928
16936
  var TREE_EXPANDER_PLACEHOLDER_CLASS = "w-5";
16929
- function getInitialExpandedNodes(categories, defaultExpanded, viewOnly, inline) {
16930
- if (!(viewOnly || inline) || !defaultExpanded) return /* @__PURE__ */ new Set();
16931
- const parentIds = /* @__PURE__ */ new Set();
16932
- for (const category of categories) {
16933
- if (typeof category.parent_id === "number") {
16934
- parentIds.add(category.parent_id);
16937
+ function getAncestorPathIds(categories, targetId) {
16938
+ const byId = new Map(categories.map((category) => [category.id, category]));
16939
+ const expanded = /* @__PURE__ */ new Set();
16940
+ let current = byId.get(targetId);
16941
+ let guard = 0;
16942
+ while (current && guard++ < categories.length) {
16943
+ expanded.add(current.id);
16944
+ if (typeof current.parent_id !== "number") break;
16945
+ current = byId.get(current.parent_id);
16946
+ }
16947
+ return expanded;
16948
+ }
16949
+ function getInitialExpandedNodes(categories, {
16950
+ defaultExpanded,
16951
+ defaultExpandedIds,
16952
+ expandToId,
16953
+ viewOnly,
16954
+ inline
16955
+ }) {
16956
+ const expanded = /* @__PURE__ */ new Set();
16957
+ if ((viewOnly || inline) && defaultExpanded) {
16958
+ for (const category of categories) {
16959
+ if (typeof category.parent_id === "number") {
16960
+ expanded.add(category.parent_id);
16961
+ }
16962
+ }
16963
+ }
16964
+ for (const id of defaultExpandedIds ?? []) {
16965
+ if (typeof id === "number") {
16966
+ expanded.add(id);
16967
+ }
16968
+ }
16969
+ if (typeof expandToId === "number") {
16970
+ for (const id of getAncestorPathIds(categories, expandToId)) {
16971
+ expanded.add(id);
16935
16972
  }
16936
16973
  }
16937
- return parentIds;
16974
+ return expanded;
16975
+ }
16976
+ function getExpandedNodesState(expandedIds, uncontrolledExpandedNodes) {
16977
+ return expandedIds !== void 0 ? new Set(expandedIds) : uncontrolledExpandedNodes;
16938
16978
  }
16939
16979
  function CategoryTreeSelect(props) {
16940
16980
  const tv = useSmartTranslations("ValidationInput");
@@ -16953,6 +16993,10 @@ function CategoryTreeSelect(props) {
16953
16993
  helperText,
16954
16994
  viewOnly = false,
16955
16995
  defaultExpanded = false,
16996
+ defaultExpandedIds,
16997
+ expandToId = null,
16998
+ expandedIds,
16999
+ onExpandedChange,
16956
17000
  enableSearch,
16957
17001
  labels,
16958
17002
  inline = false,
@@ -16963,13 +17007,15 @@ function CategoryTreeSelect(props) {
16963
17007
  singleSelect = false
16964
17008
  } = props;
16965
17009
  const [isOpen, setIsOpen] = useState31(false);
16966
- const [expandedNodes, setExpandedNodes] = useState31(() => getInitialExpandedNodes(categories, defaultExpanded, viewOnly, inline));
17010
+ const [expandedNodes, setExpandedNodes] = useState31(
17011
+ () => getInitialExpandedNodes(categories, { defaultExpanded, defaultExpandedIds, expandToId, viewOnly, inline })
17012
+ );
16967
17013
  const [query, setQuery] = useState31("");
16968
17014
  const [localRequiredError, setLocalRequiredError] = useState31();
16969
17015
  const searchInputRef = useRef19(null);
16970
17016
  const dropdownViewportRef = useRef19(null);
16971
17017
  useOverlayScrollbarTarget(dropdownViewportRef, { enabled: useOverlayScrollbar });
16972
- const autoId = useId10();
17018
+ const autoId = useId11();
16973
17019
  const resolvedId = id ? String(id) : `category-tree-select-${autoId}`;
16974
17020
  const labelId = label ? `${resolvedId}-label` : void 0;
16975
17021
  const effectiveError = error ?? localRequiredError;
@@ -17000,6 +17046,7 @@ function CategoryTreeSelect(props) {
17000
17046
  const isSearchEnabled = useMemo19(() => enableSearch ?? categories.length > 10, [enableSearch, categories.length]);
17001
17047
  const normalizedQuery = useMemo19(() => query.trim().toLowerCase(), [query]);
17002
17048
  const isSearchMode = isSearchEnabled && normalizedQuery.length > 0;
17049
+ const effectiveExpandedNodes = useMemo19(() => getExpandedNodesState(expandedIds, expandedNodes), [expandedIds, expandedNodes]);
17003
17050
  const visibleIds = useMemo19(() => {
17004
17051
  if (!isSearchMode) return null;
17005
17052
  const matches = categories.filter((c) => c.name.toLowerCase().includes(normalizedQuery));
@@ -17052,13 +17099,16 @@ function CategoryTreeSelect(props) {
17052
17099
  }, [disabled, required, valueArray.length]);
17053
17100
  const toggleExpand = (id2) => {
17054
17101
  if (isSearchMode) return;
17055
- const newExpanded = new Set(expandedNodes);
17102
+ const newExpanded = new Set(effectiveExpandedNodes);
17056
17103
  if (newExpanded.has(id2)) {
17057
17104
  newExpanded.delete(id2);
17058
17105
  } else {
17059
17106
  newExpanded.add(id2);
17060
17107
  }
17061
- setExpandedNodes(newExpanded);
17108
+ if (expandedIds === void 0) {
17109
+ setExpandedNodes(newExpanded);
17110
+ }
17111
+ onExpandedChange?.(Array.from(newExpanded));
17062
17112
  };
17063
17113
  const handleSelect = (categoryId, category) => {
17064
17114
  if (viewOnly) return;
@@ -17100,7 +17150,7 @@ function CategoryTreeSelect(props) {
17100
17150
  const renderCategory = (category, level = 0) => {
17101
17151
  const children = effectiveChildrenMap.get(category.id) || [];
17102
17152
  const hasChildren = children.length > 0;
17103
- const isExpanded = hasChildren && (isSearchMode || expandedNodes.has(category.id));
17153
+ const isExpanded = hasChildren && (isSearchMode || effectiveExpandedNodes.has(category.id));
17104
17154
  const isSelected = selectedIds.has(category.id);
17105
17155
  const isSelectable = !viewOnly && (!leafOnlySelect || !hasChildren);
17106
17156
  return /* @__PURE__ */ jsxs39(
@@ -20731,7 +20781,7 @@ var MusicPlayer = ({
20731
20781
  var MusicPlayer_default = MusicPlayer;
20732
20782
 
20733
20783
  // src/components/Grid.tsx
20734
- import React51, { useId as useId11 } from "react";
20784
+ import React51, { useId as useId12 } from "react";
20735
20785
  import { Fragment as Fragment20, jsx as jsx59, jsxs as jsxs49 } from "react/jsx-runtime";
20736
20786
  var BP_MIN = {
20737
20787
  sm: 640,
@@ -20796,7 +20846,7 @@ var GridRoot = React51.forwardRef(
20796
20846
  children,
20797
20847
  ...rest
20798
20848
  }, ref) => {
20799
- const id = useId11().replace(/[:]/g, "");
20849
+ const id = useId12().replace(/[:]/g, "");
20800
20850
  const baseClass = `uv-grid-${id}`;
20801
20851
  const baseCols = toTemplateCols(columns, minColumnWidth);
20802
20852
  const baseRows = toTemplateRows(rows);