@underverse-ui/underverse 1.0.113 → 1.0.116
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 +327 -93
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -1
- package/dist/index.d.ts +25 -1
- package/dist/index.js +343 -109
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -17290,6 +17290,7 @@ function OverlayControls({
|
|
|
17290
17290
|
|
|
17291
17291
|
// src/components/CategoryTreeSelect.tsx
|
|
17292
17292
|
import { useEffect as useEffect25, useId as useId11, useMemo as useMemo19, useRef as useRef20, useState as useState31 } from "react";
|
|
17293
|
+
import { useVirtualizer as useVirtualizer3 } from "@tanstack/react-virtual";
|
|
17293
17294
|
import { ChevronRight as ChevronRight6, ChevronDown as ChevronDown5, FolderTree, Layers, Search as Search6, SearchX as SearchX3, X as X14 } from "lucide-react";
|
|
17294
17295
|
import { jsx as jsx49, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
17295
17296
|
var defaultLabels = {
|
|
@@ -17303,6 +17304,7 @@ var TREE_NODE_INDENT_REM = 1;
|
|
|
17303
17304
|
var TREE_BRANCH_OFFSET_CLASS = "ml-1.5 pl-1.5";
|
|
17304
17305
|
var TREE_NODE_GAP_CLASS = "gap-1.5";
|
|
17305
17306
|
var TREE_EXPANDER_PLACEHOLDER_CLASS = "w-5";
|
|
17307
|
+
var CATEGORY_TREE_DROPDOWN_MAX_HEIGHT = 320;
|
|
17306
17308
|
function getAncestorPathIds(categories, targetId) {
|
|
17307
17309
|
const byId = new Map(categories.map((category) => [category.id, category]));
|
|
17308
17310
|
const expanded = /* @__PURE__ */ new Set();
|
|
@@ -17381,6 +17383,24 @@ function pruneAncestorSelection(categories, childrenMap, selected, fromCategoryI
|
|
|
17381
17383
|
function toCategoryOrderSelection(categories, selected) {
|
|
17382
17384
|
return categories.map((category) => category.id).filter((categoryId) => selected.has(categoryId));
|
|
17383
17385
|
}
|
|
17386
|
+
function flattenVisibleCategories(roots, childrenMap, expandedNodes, expandAllVisibleBranches) {
|
|
17387
|
+
const rows = [];
|
|
17388
|
+
const stack = roots.map((category) => ({ category, level: 0, path: /* @__PURE__ */ new Set() })).reverse();
|
|
17389
|
+
while (stack.length > 0) {
|
|
17390
|
+
const { category, level, path } = stack.pop();
|
|
17391
|
+
if (path.has(category.id)) continue;
|
|
17392
|
+
rows.push({ category, level });
|
|
17393
|
+
const children = childrenMap.get(category.id) ?? [];
|
|
17394
|
+
const isExpanded = children.length > 0 && (expandAllVisibleBranches || expandedNodes.has(category.id));
|
|
17395
|
+
if (!isExpanded) continue;
|
|
17396
|
+
const nextPath = new Set(path);
|
|
17397
|
+
nextPath.add(category.id);
|
|
17398
|
+
for (let index = children.length - 1; index >= 0; index -= 1) {
|
|
17399
|
+
stack.push({ category: children[index], level: level + 1, path: nextPath });
|
|
17400
|
+
}
|
|
17401
|
+
}
|
|
17402
|
+
return rows;
|
|
17403
|
+
}
|
|
17384
17404
|
function CategoryTreeSelect(props) {
|
|
17385
17405
|
const tv = useSmartTranslations("ValidationInput");
|
|
17386
17406
|
const {
|
|
@@ -17409,6 +17429,15 @@ function CategoryTreeSelect(props) {
|
|
|
17409
17429
|
className,
|
|
17410
17430
|
useOverlayScrollbar = false,
|
|
17411
17431
|
leafOnlySelect = false,
|
|
17432
|
+
virtualized = false,
|
|
17433
|
+
estimatedItemHeight = 44,
|
|
17434
|
+
overscan = 8,
|
|
17435
|
+
maxInitialOptions,
|
|
17436
|
+
searchMode = "auto",
|
|
17437
|
+
onSearchChange,
|
|
17438
|
+
searchDebounceMs = 0,
|
|
17439
|
+
minSearchLength = 0,
|
|
17440
|
+
showSearchPromptWhenEmptyQuery = false,
|
|
17412
17441
|
singleSelect = false
|
|
17413
17442
|
} = props;
|
|
17414
17443
|
const [isOpen, setIsOpen] = useState31(false);
|
|
@@ -17416,10 +17445,13 @@ function CategoryTreeSelect(props) {
|
|
|
17416
17445
|
() => getInitialExpandedNodes(categories, { defaultExpanded, defaultExpandedIds, expandToId, viewOnly, inline })
|
|
17417
17446
|
);
|
|
17418
17447
|
const [query, setQuery] = useState31("");
|
|
17448
|
+
const [activeIndex, setActiveIndex] = useState31(null);
|
|
17419
17449
|
const [localRequiredError, setLocalRequiredError] = useState31();
|
|
17420
17450
|
const searchInputRef = useRef20(null);
|
|
17421
17451
|
const dropdownViewportRef = useRef20(null);
|
|
17422
|
-
useOverlayScrollbarTarget(dropdownViewportRef, {
|
|
17452
|
+
useOverlayScrollbarTarget(dropdownViewportRef, {
|
|
17453
|
+
enabled: isOpen && useOverlayScrollbar && !virtualized && !inline && !viewOnly
|
|
17454
|
+
});
|
|
17423
17455
|
const autoId = useId11();
|
|
17424
17456
|
const resolvedId = id ? String(id) : `category-tree-select-${autoId}`;
|
|
17425
17457
|
const labelId = label ? `${resolvedId}-label` : void 0;
|
|
@@ -17439,7 +17471,7 @@ function CategoryTreeSelect(props) {
|
|
|
17439
17471
|
const parentCategories2 = [];
|
|
17440
17472
|
for (const cat of categories) byId2.set(cat.id, cat);
|
|
17441
17473
|
for (const cat of categories) {
|
|
17442
|
-
if (cat.parent_id == null) {
|
|
17474
|
+
if (cat.parent_id == null || !byId2.has(cat.parent_id)) {
|
|
17443
17475
|
parentCategories2.push(cat);
|
|
17444
17476
|
continue;
|
|
17445
17477
|
}
|
|
@@ -17448,12 +17480,19 @@ function CategoryTreeSelect(props) {
|
|
|
17448
17480
|
}
|
|
17449
17481
|
return { parentCategories: parentCategories2, childrenMap: childrenMap2, byId: byId2 };
|
|
17450
17482
|
}, [categories]);
|
|
17451
|
-
const isSearchEnabled = useMemo19(
|
|
17452
|
-
|
|
17483
|
+
const isSearchEnabled = useMemo19(
|
|
17484
|
+
() => enableSearch ?? (categories.length > 10 || searchMode === "manual" || minSearchLength > 0 || !!onSearchChange),
|
|
17485
|
+
[categories.length, enableSearch, minSearchLength, onSearchChange, searchMode]
|
|
17486
|
+
);
|
|
17487
|
+
const trimmedQuery = useMemo19(() => query.trim(), [query]);
|
|
17488
|
+
const normalizedQuery = useMemo19(() => trimmedQuery.toLowerCase(), [trimmedQuery]);
|
|
17489
|
+
const queryMeetsMinimum = trimmedQuery.length >= minSearchLength;
|
|
17490
|
+
const shouldPromptForSearch = minSearchLength > 0 && !queryMeetsMinimum && (searchMode === "manual" || showSearchPromptWhenEmptyQuery);
|
|
17453
17491
|
const isSearchMode = isSearchEnabled && normalizedQuery.length > 0;
|
|
17492
|
+
const shouldAutoExpandSearchResults = searchMode === "auto" && isSearchMode;
|
|
17454
17493
|
const effectiveExpandedNodes = useMemo19(() => getExpandedNodesState(expandedIds, expandedNodes), [expandedIds, expandedNodes]);
|
|
17455
17494
|
const visibleIds = useMemo19(() => {
|
|
17456
|
-
if (!isSearchMode) return null;
|
|
17495
|
+
if (shouldPromptForSearch || !isSearchMode || searchMode === "manual") return null;
|
|
17457
17496
|
const matches = categories.filter((c) => c.name.toLowerCase().includes(normalizedQuery));
|
|
17458
17497
|
if (matches.length === 0) return /* @__PURE__ */ new Set();
|
|
17459
17498
|
const visible = /* @__PURE__ */ new Set();
|
|
@@ -17490,7 +17529,14 @@ function CategoryTreeSelect(props) {
|
|
|
17490
17529
|
addDescendants(m.id);
|
|
17491
17530
|
}
|
|
17492
17531
|
return visible;
|
|
17493
|
-
}, [byId, categories, childrenMap, isSearchMode, normalizedQuery]);
|
|
17532
|
+
}, [byId, categories, childrenMap, isSearchMode, normalizedQuery, searchMode, shouldPromptForSearch]);
|
|
17533
|
+
useEffect25(() => {
|
|
17534
|
+
if (!onSearchChange) return;
|
|
17535
|
+
const timeoutId = window.setTimeout(() => {
|
|
17536
|
+
onSearchChange(trimmedQuery);
|
|
17537
|
+
}, Math.max(0, searchDebounceMs));
|
|
17538
|
+
return () => window.clearTimeout(timeoutId);
|
|
17539
|
+
}, [onSearchChange, searchDebounceMs, trimmedQuery]);
|
|
17494
17540
|
useEffect25(() => {
|
|
17495
17541
|
if (!isOpen) return;
|
|
17496
17542
|
if (!isSearchEnabled) return;
|
|
@@ -17503,7 +17549,7 @@ function CategoryTreeSelect(props) {
|
|
|
17503
17549
|
}
|
|
17504
17550
|
}, [disabled, required, valueArray.length]);
|
|
17505
17551
|
const toggleExpand = (id2) => {
|
|
17506
|
-
if (
|
|
17552
|
+
if (shouldAutoExpandSearchResults) return;
|
|
17507
17553
|
const newExpanded = new Set(effectiveExpandedNodes);
|
|
17508
17554
|
if (newExpanded.has(id2)) {
|
|
17509
17555
|
newExpanded.delete(id2);
|
|
@@ -17554,27 +17600,137 @@ function CategoryTreeSelect(props) {
|
|
|
17554
17600
|
onChange(toCategoryOrderSelection(categories, newSelected));
|
|
17555
17601
|
}
|
|
17556
17602
|
};
|
|
17557
|
-
const
|
|
17603
|
+
const effectiveParentCategories = useMemo19(() => {
|
|
17604
|
+
if (shouldPromptForSearch) return [];
|
|
17605
|
+
if (!isSearchMode || searchMode === "manual") return parentCategories;
|
|
17606
|
+
return parentCategories.filter((c) => visibleIds?.has(c.id));
|
|
17607
|
+
}, [isSearchMode, parentCategories, searchMode, shouldPromptForSearch, visibleIds]);
|
|
17608
|
+
const effectiveChildrenMap = useMemo19(() => {
|
|
17609
|
+
if (shouldPromptForSearch || !isSearchMode || !visibleIds || searchMode === "manual") return childrenMap;
|
|
17610
|
+
const nextChildrenMap = /* @__PURE__ */ new Map();
|
|
17611
|
+
for (const [parentId, children] of childrenMap.entries()) {
|
|
17612
|
+
nextChildrenMap.set(
|
|
17613
|
+
parentId,
|
|
17614
|
+
children.filter((child) => visibleIds.has(child.id))
|
|
17615
|
+
);
|
|
17616
|
+
}
|
|
17617
|
+
return nextChildrenMap;
|
|
17618
|
+
}, [childrenMap, isSearchMode, searchMode, shouldPromptForSearch, visibleIds]);
|
|
17619
|
+
const flattenedRows = useMemo19(() => {
|
|
17620
|
+
if (shouldPromptForSearch) return [];
|
|
17621
|
+
const rows = flattenVisibleCategories(effectiveParentCategories, effectiveChildrenMap, effectiveExpandedNodes, shouldAutoExpandSearchResults);
|
|
17622
|
+
if (trimmedQuery || maxInitialOptions === void 0 || maxInitialOptions < 1) {
|
|
17623
|
+
return rows;
|
|
17624
|
+
}
|
|
17625
|
+
const limitedRows = rows.slice(0, maxInitialOptions);
|
|
17626
|
+
const includedIds = new Set(limitedRows.map((row) => row.category.id));
|
|
17627
|
+
const pinnedIds = /* @__PURE__ */ new Set();
|
|
17628
|
+
for (const selectedId of selectedIds) {
|
|
17629
|
+
for (const ancestorId of getAncestorPathIds(categories, selectedId)) {
|
|
17630
|
+
pinnedIds.add(ancestorId);
|
|
17631
|
+
}
|
|
17632
|
+
}
|
|
17633
|
+
if (typeof expandToId === "number") {
|
|
17634
|
+
for (const ancestorId of getAncestorPathIds(categories, expandToId)) {
|
|
17635
|
+
pinnedIds.add(ancestorId);
|
|
17636
|
+
}
|
|
17637
|
+
}
|
|
17638
|
+
for (const row of rows) {
|
|
17639
|
+
if (!pinnedIds.has(row.category.id) || includedIds.has(row.category.id)) continue;
|
|
17640
|
+
limitedRows.push(row);
|
|
17641
|
+
includedIds.add(row.category.id);
|
|
17642
|
+
}
|
|
17643
|
+
return limitedRows;
|
|
17644
|
+
}, [
|
|
17645
|
+
categories,
|
|
17646
|
+
effectiveChildrenMap,
|
|
17647
|
+
effectiveExpandedNodes,
|
|
17648
|
+
effectiveParentCategories,
|
|
17649
|
+
expandToId,
|
|
17650
|
+
maxInitialOptions,
|
|
17651
|
+
selectedIds,
|
|
17652
|
+
shouldAutoExpandSearchResults,
|
|
17653
|
+
shouldPromptForSearch,
|
|
17654
|
+
trimmedQuery
|
|
17655
|
+
]);
|
|
17656
|
+
const canVirtualize = virtualized && !inline && !viewOnly;
|
|
17657
|
+
const treeVirtualizer = useVirtualizer3({
|
|
17658
|
+
count: canVirtualize ? flattenedRows.length : 0,
|
|
17659
|
+
getScrollElement: () => dropdownViewportRef.current,
|
|
17660
|
+
estimateSize: () => estimatedItemHeight,
|
|
17661
|
+
initialRect: { width: 0, height: CATEGORY_TREE_DROPDOWN_MAX_HEIGHT },
|
|
17662
|
+
overscan,
|
|
17663
|
+
enabled: canVirtualize
|
|
17664
|
+
});
|
|
17665
|
+
const virtualRows = canVirtualize ? treeVirtualizer.getVirtualItems() : [];
|
|
17666
|
+
const scrollVirtualTreeToStart = () => {
|
|
17667
|
+
if (!canVirtualize || flattenedRows.length === 0) return;
|
|
17668
|
+
treeVirtualizer.scrollToIndex(0, { align: "start" });
|
|
17669
|
+
};
|
|
17670
|
+
const moveActiveVirtualRow = (direction) => {
|
|
17671
|
+
if (!canVirtualize || flattenedRows.length === 0) return;
|
|
17672
|
+
const nextIndex = activeIndex === null ? direction === 1 ? 0 : flattenedRows.length - 1 : (activeIndex + direction + flattenedRows.length) % flattenedRows.length;
|
|
17673
|
+
setActiveIndex(nextIndex);
|
|
17674
|
+
treeVirtualizer.scrollToIndex(nextIndex, { align: "auto" });
|
|
17675
|
+
};
|
|
17676
|
+
const handleVirtualTreeKeyDown = (event) => {
|
|
17677
|
+
if (!canVirtualize) return;
|
|
17678
|
+
if (event.key === "ArrowDown") {
|
|
17679
|
+
event.preventDefault();
|
|
17680
|
+
moveActiveVirtualRow(1);
|
|
17681
|
+
return;
|
|
17682
|
+
}
|
|
17683
|
+
if (event.key === "ArrowUp") {
|
|
17684
|
+
event.preventDefault();
|
|
17685
|
+
moveActiveVirtualRow(-1);
|
|
17686
|
+
return;
|
|
17687
|
+
}
|
|
17688
|
+
if (event.key === "Enter" && activeIndex !== null) {
|
|
17689
|
+
const row = flattenedRows[activeIndex];
|
|
17690
|
+
if (!row) return;
|
|
17691
|
+
event.preventDefault();
|
|
17692
|
+
handleSelect(row.category.id, row.category);
|
|
17693
|
+
}
|
|
17694
|
+
};
|
|
17695
|
+
useEffect25(() => {
|
|
17696
|
+
setActiveIndex(null);
|
|
17697
|
+
}, [flattenedRows]);
|
|
17698
|
+
const renderCategoryRow = (category, level = 0, virtualItem) => {
|
|
17558
17699
|
const children = effectiveChildrenMap.get(category.id) || [];
|
|
17559
17700
|
const hasChildren = children.length > 0;
|
|
17560
|
-
const isExpanded = hasChildren && (
|
|
17701
|
+
const isExpanded = hasChildren && (shouldAutoExpandSearchResults || effectiveExpandedNodes.has(category.id));
|
|
17561
17702
|
const isSelected = selectedIds.has(category.id);
|
|
17562
17703
|
const isSelectable = !viewOnly && (!leafOnlySelect || !hasChildren);
|
|
17704
|
+
const isActive = virtualItem?.index === activeIndex;
|
|
17705
|
+
const rowStyle = virtualItem ? {
|
|
17706
|
+
position: "absolute",
|
|
17707
|
+
top: 0,
|
|
17708
|
+
left: 0,
|
|
17709
|
+
width: "100%",
|
|
17710
|
+
transform: `translateY(${virtualItem.start}px)`
|
|
17711
|
+
} : void 0;
|
|
17563
17712
|
return /* @__PURE__ */ jsxs39(
|
|
17564
17713
|
"div",
|
|
17565
17714
|
{
|
|
17566
|
-
|
|
17567
|
-
|
|
17715
|
+
ref: virtualItem ? treeVirtualizer.measureElement : void 0,
|
|
17716
|
+
"data-index": virtualItem?.index,
|
|
17717
|
+
className: cn("min-w-0 [content-visibility:auto] [contain-intrinsic-size:44px]", !virtualItem && "animate-in fade-in-50 duration-200"),
|
|
17718
|
+
style: { animationDelay: virtualItem ? void 0 : `${level * 30}ms`, ...rowStyle },
|
|
17568
17719
|
children: [
|
|
17569
17720
|
/* @__PURE__ */ jsxs39(
|
|
17570
17721
|
"div",
|
|
17571
17722
|
{
|
|
17723
|
+
role: "treeitem",
|
|
17724
|
+
"aria-level": level + 1,
|
|
17725
|
+
"aria-expanded": hasChildren ? isExpanded : void 0,
|
|
17726
|
+
"aria-selected": viewOnly ? void 0 : isSelected,
|
|
17572
17727
|
onClick: () => !viewOnly && handleSelect(category.id, category),
|
|
17573
17728
|
className: cn(
|
|
17574
17729
|
"relative flex min-w-0 items-center px-3 py-2.5 min-h-11 transition-all duration-200 rounded-3xl",
|
|
17575
17730
|
TREE_NODE_GAP_CLASS,
|
|
17576
17731
|
!viewOnly && (isSelectable ? "cursor-pointer" : "cursor-default"),
|
|
17577
17732
|
isSelectable && !isSelected && "hover:bg-accent/50",
|
|
17733
|
+
canVirtualize && isActive && "bg-accent/50",
|
|
17578
17734
|
// Selected state - đồng bộ cho tất cả
|
|
17579
17735
|
!viewOnly && isSelected && "bg-accent/40"
|
|
17580
17736
|
),
|
|
@@ -17584,6 +17740,7 @@ function CategoryTreeSelect(props) {
|
|
|
17584
17740
|
"button",
|
|
17585
17741
|
{
|
|
17586
17742
|
type: "button",
|
|
17743
|
+
"aria-label": isExpanded ? `Collapse ${category.name}` : `Expand ${category.name}`,
|
|
17587
17744
|
onClick: (e) => {
|
|
17588
17745
|
e.stopPropagation();
|
|
17589
17746
|
toggleExpand(category.id);
|
|
@@ -17593,9 +17750,9 @@ function CategoryTreeSelect(props) {
|
|
|
17593
17750
|
"hover:scale-110 active:scale-95",
|
|
17594
17751
|
"focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50",
|
|
17595
17752
|
isExpanded && "text-primary",
|
|
17596
|
-
|
|
17753
|
+
shouldAutoExpandSearchResults && "opacity-60 cursor-not-allowed hover:scale-100 active:scale-100"
|
|
17597
17754
|
),
|
|
17598
|
-
disabled:
|
|
17755
|
+
disabled: shouldAutoExpandSearchResults,
|
|
17599
17756
|
children: /* @__PURE__ */ jsx49("div", { className: cn("transition-transform duration-200", isExpanded && "rotate-90"), children: /* @__PURE__ */ jsx49(ChevronRight6, { className: "w-4 h-4" }) })
|
|
17600
17757
|
}
|
|
17601
17758
|
) : /* @__PURE__ */ jsx49("span", { className: TREE_EXPANDER_PLACEHOLDER_CLASS }),
|
|
@@ -17626,15 +17783,16 @@ function CategoryTreeSelect(props) {
|
|
|
17626
17783
|
]
|
|
17627
17784
|
}
|
|
17628
17785
|
),
|
|
17629
|
-
hasChildren && isExpanded && /* @__PURE__ */ jsx49(
|
|
17786
|
+
!virtualItem && hasChildren && isExpanded && /* @__PURE__ */ jsx49(
|
|
17630
17787
|
"div",
|
|
17631
17788
|
{
|
|
17789
|
+
role: "group",
|
|
17632
17790
|
className: cn(
|
|
17633
17791
|
TREE_BRANCH_OFFSET_CLASS,
|
|
17634
17792
|
"border-l-2 border-dashed border-border/50",
|
|
17635
17793
|
"animate-in slide-in-from-top-2 fade-in-50 duration-200"
|
|
17636
17794
|
),
|
|
17637
|
-
children: children.map((child) =>
|
|
17795
|
+
children: children.map((child) => renderCategoryRow(child, level + 1))
|
|
17638
17796
|
}
|
|
17639
17797
|
)
|
|
17640
17798
|
]
|
|
@@ -17651,7 +17809,11 @@ function CategoryTreeSelect(props) {
|
|
|
17651
17809
|
{
|
|
17652
17810
|
ref: searchInputRef,
|
|
17653
17811
|
value: query,
|
|
17654
|
-
onChange: (e) =>
|
|
17812
|
+
onChange: (e) => {
|
|
17813
|
+
setQuery(e.target.value);
|
|
17814
|
+
scrollVirtualTreeToStart();
|
|
17815
|
+
},
|
|
17816
|
+
onKeyDown: handleVirtualTreeKeyDown,
|
|
17655
17817
|
placeholder: mergedLabels.searchPlaceholder,
|
|
17656
17818
|
className: cn(
|
|
17657
17819
|
"peer w-full rounded-full bg-background/90 py-2.5 pl-10 pr-10 text-sm shadow-sm",
|
|
@@ -17668,6 +17830,7 @@ function CategoryTreeSelect(props) {
|
|
|
17668
17830
|
type: "button",
|
|
17669
17831
|
onClick: () => {
|
|
17670
17832
|
setQuery("");
|
|
17833
|
+
scrollVirtualTreeToStart();
|
|
17671
17834
|
searchInputRef.current?.focus();
|
|
17672
17835
|
},
|
|
17673
17836
|
className: cn(
|
|
@@ -17682,24 +17845,40 @@ function CategoryTreeSelect(props) {
|
|
|
17682
17845
|
)
|
|
17683
17846
|
] }) });
|
|
17684
17847
|
};
|
|
17685
|
-
const
|
|
17686
|
-
|
|
17687
|
-
|
|
17688
|
-
|
|
17689
|
-
|
|
17690
|
-
|
|
17691
|
-
|
|
17692
|
-
|
|
17693
|
-
effectiveChildrenMap.set(
|
|
17694
|
-
parentId,
|
|
17695
|
-
children.filter((child) => visibleIds.has(child.id))
|
|
17696
|
-
);
|
|
17697
|
-
}
|
|
17698
|
-
}
|
|
17699
|
-
const renderTreeContent = () => /* @__PURE__ */ jsx49("div", { className: "space-y-0.5 overflow-x-hidden", children: effectiveParentCategories.length === 0 ? /* @__PURE__ */ jsxs39("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
|
|
17848
|
+
const renderTreeContent = () => /* @__PURE__ */ jsx49("div", { className: "space-y-0.5 overflow-x-hidden", children: shouldPromptForSearch ? /* @__PURE__ */ jsxs39("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
|
|
17849
|
+
/* @__PURE__ */ jsx49("div", { className: "w-12 h-12 rounded-2xl bg-muted/50 flex items-center justify-center mb-3", children: /* @__PURE__ */ jsx49(Search6, { className: "w-6 h-6 text-muted-foreground/50" }) }),
|
|
17850
|
+
/* @__PURE__ */ jsxs39("span", { className: "text-sm text-muted-foreground", children: [
|
|
17851
|
+
"Type at least ",
|
|
17852
|
+
minSearchLength,
|
|
17853
|
+
" characters to search"
|
|
17854
|
+
] })
|
|
17855
|
+
] }) : effectiveParentCategories.length === 0 ? /* @__PURE__ */ jsxs39("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
|
|
17700
17856
|
/* @__PURE__ */ jsx49("div", { className: "w-12 h-12 rounded-2xl bg-muted/50 flex items-center justify-center mb-3", children: isSearchMode ? /* @__PURE__ */ jsx49(SearchX3, { className: "w-6 h-6 text-muted-foreground/50" }) : /* @__PURE__ */ jsx49(Layers, { className: "w-6 h-6 text-muted-foreground/50" }) }),
|
|
17701
17857
|
/* @__PURE__ */ jsx49("span", { className: "text-sm text-muted-foreground", children: isSearchMode ? mergedLabels.noResultsText : mergedLabels.emptyText })
|
|
17702
|
-
] }) : effectiveParentCategories.map((cat) =>
|
|
17858
|
+
] }) : effectiveParentCategories.map((cat) => renderCategoryRow(cat)) });
|
|
17859
|
+
const renderVirtualTreeContent = () => {
|
|
17860
|
+
if (shouldPromptForSearch) {
|
|
17861
|
+
return /* @__PURE__ */ jsxs39("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
|
|
17862
|
+
/* @__PURE__ */ jsx49("div", { className: "w-12 h-12 rounded-2xl bg-muted/50 flex items-center justify-center mb-3", children: /* @__PURE__ */ jsx49(Search6, { className: "w-6 h-6 text-muted-foreground/50" }) }),
|
|
17863
|
+
/* @__PURE__ */ jsxs39("span", { className: "text-sm text-muted-foreground", children: [
|
|
17864
|
+
"Type at least ",
|
|
17865
|
+
minSearchLength,
|
|
17866
|
+
" characters to search"
|
|
17867
|
+
] })
|
|
17868
|
+
] });
|
|
17869
|
+
}
|
|
17870
|
+
if (flattenedRows.length === 0) {
|
|
17871
|
+
return /* @__PURE__ */ jsxs39("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
|
|
17872
|
+
/* @__PURE__ */ jsx49("div", { className: "w-12 h-12 rounded-2xl bg-muted/50 flex items-center justify-center mb-3", children: isSearchMode ? /* @__PURE__ */ jsx49(SearchX3, { className: "w-6 h-6 text-muted-foreground/50" }) : /* @__PURE__ */ jsx49(Layers, { className: "w-6 h-6 text-muted-foreground/50" }) }),
|
|
17873
|
+
/* @__PURE__ */ jsx49("span", { className: "text-sm text-muted-foreground", children: isSearchMode ? mergedLabels.noResultsText : mergedLabels.emptyText })
|
|
17874
|
+
] });
|
|
17875
|
+
}
|
|
17876
|
+
return /* @__PURE__ */ jsx49("div", { className: "relative overflow-x-hidden", style: { height: `${treeVirtualizer.getTotalSize()}px` }, children: virtualRows.map((virtualRow) => {
|
|
17877
|
+
const row = flattenedRows[virtualRow.index];
|
|
17878
|
+
if (!row) return null;
|
|
17879
|
+
return renderCategoryRow(row.category, row.level, virtualRow);
|
|
17880
|
+
}) });
|
|
17881
|
+
};
|
|
17703
17882
|
const renderLabel = () => label ? /* @__PURE__ */ jsx49("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxs39(
|
|
17704
17883
|
Label,
|
|
17705
17884
|
{
|
|
@@ -17742,8 +17921,10 @@ function CategoryTreeSelect(props) {
|
|
|
17742
17921
|
"div",
|
|
17743
17922
|
{
|
|
17744
17923
|
id: resolvedId,
|
|
17924
|
+
role: "tree",
|
|
17745
17925
|
"aria-labelledby": labelId,
|
|
17746
17926
|
"aria-describedby": describedBy,
|
|
17927
|
+
"aria-multiselectable": singleSelect ? void 0 : true,
|
|
17747
17928
|
className: cn("rounded-2xl border border-border/60 bg-card/50 backdrop-blur-sm p-3 shadow-sm", disabled && "opacity-50"),
|
|
17748
17929
|
children: [
|
|
17749
17930
|
renderSearch(),
|
|
@@ -17778,8 +17959,10 @@ function CategoryTreeSelect(props) {
|
|
|
17778
17959
|
"div",
|
|
17779
17960
|
{
|
|
17780
17961
|
id: resolvedId,
|
|
17962
|
+
role: "tree",
|
|
17781
17963
|
"aria-labelledby": labelId,
|
|
17782
17964
|
"aria-describedby": describedBy,
|
|
17965
|
+
"aria-multiselectable": singleSelect ? void 0 : true,
|
|
17783
17966
|
className: cn("rounded-2xl border border-border/60 bg-card/50 backdrop-blur-sm p-3 shadow-sm", disabled && "opacity-50 pointer-events-none"),
|
|
17784
17967
|
children: [
|
|
17785
17968
|
renderSearch(),
|
|
@@ -17844,6 +18027,7 @@ function CategoryTreeSelect(props) {
|
|
|
17844
18027
|
setIsOpen(nextOpen);
|
|
17845
18028
|
if (!nextOpen) {
|
|
17846
18029
|
setQuery("");
|
|
18030
|
+
scrollVirtualTreeToStart();
|
|
17847
18031
|
}
|
|
17848
18032
|
};
|
|
17849
18033
|
let displayText;
|
|
@@ -17859,15 +18043,20 @@ function CategoryTreeSelect(props) {
|
|
|
17859
18043
|
displayText = mergedLabels.selectedText(selectedCount);
|
|
17860
18044
|
}
|
|
17861
18045
|
}
|
|
17862
|
-
const dropdownBody = /* @__PURE__ */ jsxs39("div", { className: "flex
|
|
18046
|
+
const dropdownBody = /* @__PURE__ */ jsxs39("div", { className: "flex flex-col overflow-hidden", style: { maxHeight: CATEGORY_TREE_DROPDOWN_MAX_HEIGHT }, children: [
|
|
17863
18047
|
renderSearch({ sticky: false, className: "border-b border-border/30 p-2 pb-2" }),
|
|
17864
18048
|
/* @__PURE__ */ jsx49(
|
|
17865
18049
|
"div",
|
|
17866
18050
|
{
|
|
17867
18051
|
ref: dropdownViewportRef,
|
|
17868
18052
|
id: `${resolvedId}-tree`,
|
|
18053
|
+
role: "tree",
|
|
18054
|
+
"aria-multiselectable": singleSelect ? void 0 : true,
|
|
18055
|
+
"data-os-ignore": virtualized ? "" : void 0,
|
|
18056
|
+
tabIndex: canVirtualize ? 0 : void 0,
|
|
18057
|
+
onKeyDown: handleVirtualTreeKeyDown,
|
|
17869
18058
|
className: cn("min-h-0 flex-1 overflow-auto overflow-x-hidden p-2 pt-2"),
|
|
17870
|
-
children: renderTreeContent()
|
|
18059
|
+
children: canVirtualize ? renderVirtualTreeContent() : renderTreeContent()
|
|
17871
18060
|
}
|
|
17872
18061
|
)
|
|
17873
18062
|
] });
|
|
@@ -17922,6 +18111,10 @@ function CategoryTreeSelect(props) {
|
|
|
17922
18111
|
if (event.key === "Enter" || event.key === " " || event.key === "ArrowDown") {
|
|
17923
18112
|
event.preventDefault();
|
|
17924
18113
|
handleOpenChange(!isOpen);
|
|
18114
|
+
if (event.key === "ArrowDown" && canVirtualize && flattenedRows.length > 0) {
|
|
18115
|
+
setActiveIndex(0);
|
|
18116
|
+
treeVirtualizer.scrollToIndex(0, { align: "start" });
|
|
18117
|
+
}
|
|
17925
18118
|
}
|
|
17926
18119
|
},
|
|
17927
18120
|
className: cn(
|
|
@@ -21557,11 +21750,12 @@ var TableCaption = React52.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
21557
21750
|
TableCaption.displayName = "TableCaption";
|
|
21558
21751
|
|
|
21559
21752
|
// src/components/DataTable/DataTable.tsx
|
|
21753
|
+
import { useVirtualizer as useVirtualizer4 } from "@tanstack/react-virtual";
|
|
21560
21754
|
import React62 from "react";
|
|
21561
21755
|
|
|
21562
21756
|
// src/components/DataTable/components/DataTableBody.tsx
|
|
21563
21757
|
import React53 from "react";
|
|
21564
|
-
import { jsx as jsx63, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
21758
|
+
import { Fragment as Fragment22, jsx as jsx63, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
21565
21759
|
function DataTableOverflowText({
|
|
21566
21760
|
text,
|
|
21567
21761
|
align
|
|
@@ -21629,8 +21823,17 @@ function DataTableBodyRows({
|
|
|
21629
21823
|
getStickyColumnStyle,
|
|
21630
21824
|
getStickyCellClass,
|
|
21631
21825
|
t,
|
|
21632
|
-
labels
|
|
21826
|
+
labels,
|
|
21827
|
+
virtualRows,
|
|
21828
|
+
virtualPaddingTop = 0,
|
|
21829
|
+
virtualPaddingBottom = 0,
|
|
21830
|
+
measureVirtualRow
|
|
21633
21831
|
}) {
|
|
21832
|
+
const rowsToRender = virtualRows ? virtualRows.map((virtualRow) => ({
|
|
21833
|
+
row: displayedData[virtualRow.index],
|
|
21834
|
+
idx: virtualRow.index,
|
|
21835
|
+
virtualRow
|
|
21836
|
+
})).filter((item) => Boolean(item.row)) : displayedData.map((row, idx) => ({ row, idx, virtualRow: void 0 }));
|
|
21634
21837
|
return /* @__PURE__ */ jsx63(TableBody, { children: loading2 ? /* @__PURE__ */ jsx63(TableRow, { children: /* @__PURE__ */ jsx63(TableCell, { colSpan: leafColumns.length, className: "text-center py-8", children: /* @__PURE__ */ jsxs52("div", { className: "flex items-center justify-center gap-2 text-muted-foreground", children: [
|
|
21635
21838
|
/* @__PURE__ */ jsxs52("svg", { className: "animate-spin h-4 w-4", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
21636
21839
|
/* @__PURE__ */ jsx63("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
@@ -21647,48 +21850,54 @@ function DataTableBodyRows({
|
|
|
21647
21850
|
t("loading"),
|
|
21648
21851
|
"\u2026"
|
|
21649
21852
|
] })
|
|
21650
|
-
] }) }) }) : displayedData.length === 0 ? /* @__PURE__ */ jsx63(TableRow, { children: /* @__PURE__ */ jsx63(TableCell, { colSpan: leafColumns.length, className: "text-center py-6 text-muted-foreground", children: labels?.noData || t("noData") }) }) :
|
|
21651
|
-
|
|
21652
|
-
|
|
21653
|
-
|
|
21654
|
-
|
|
21655
|
-
|
|
21656
|
-
|
|
21657
|
-
|
|
21658
|
-
|
|
21853
|
+
] }) }) }) : displayedData.length === 0 ? /* @__PURE__ */ jsx63(TableRow, { children: /* @__PURE__ */ jsx63(TableCell, { colSpan: leafColumns.length, className: "text-center py-6 text-muted-foreground", children: labels?.noData || t("noData") }) }) : /* @__PURE__ */ jsxs52(Fragment22, { children: [
|
|
21854
|
+
virtualPaddingTop > 0 && /* @__PURE__ */ jsx63(TableRow, { "aria-hidden": "true", className: "border-0 hover:bg-transparent hover:shadow-none", children: /* @__PURE__ */ jsx63(TableCell, { colSpan: leafColumns.length, className: "p-0", style: { height: virtualPaddingTop } }) }),
|
|
21855
|
+
rowsToRender.map(({ row, idx, virtualRow }) => {
|
|
21856
|
+
const isStripedRow = striped && idx % 2 === 0;
|
|
21857
|
+
return /* @__PURE__ */ jsx63(
|
|
21858
|
+
TableRow,
|
|
21859
|
+
{
|
|
21860
|
+
ref: virtualRow ? measureVirtualRow : void 0,
|
|
21861
|
+
"data-index": virtualRow?.index,
|
|
21862
|
+
className: cn(densityRowClass, isStripedRow ? "bg-surface-1" : "bg-surface-0"),
|
|
21863
|
+
style: {
|
|
21864
|
+
contentVisibility: "auto",
|
|
21865
|
+
containIntrinsicSize: density === "compact" ? "0 36px" : density === "comfortable" ? "0 56px" : "0 48px"
|
|
21866
|
+
},
|
|
21867
|
+
children: leafColumns.map((col, colIdx) => {
|
|
21868
|
+
const value = col.dataIndex ? row[col.dataIndex] : void 0;
|
|
21869
|
+
const prevCol = colIdx > 0 ? leafColumns[colIdx - 1] : null;
|
|
21870
|
+
const isAfterFixedLeft = prevCol?.fixed === "left";
|
|
21871
|
+
const showBorderLeft = columnDividers && colIdx > 0 && !isAfterFixedLeft && !col.fixed;
|
|
21872
|
+
return /* @__PURE__ */ jsx63(
|
|
21873
|
+
TableCell,
|
|
21874
|
+
{
|
|
21875
|
+
"data-underverse-column-key": col.key,
|
|
21876
|
+
style: getStickyColumnStyle(col),
|
|
21877
|
+
className: cn(
|
|
21878
|
+
cellPadding,
|
|
21879
|
+
col.align === "right" && "text-right",
|
|
21880
|
+
col.align === "center" && "text-center",
|
|
21881
|
+
showBorderLeft && "border-l border-border/60",
|
|
21882
|
+
getStickyCellClass(col, isStripedRow)
|
|
21883
|
+
),
|
|
21884
|
+
children: col.render ? col.render(value, row, idx) : /* @__PURE__ */ jsx63(DataTableOverflowText, { text: String(value ?? ""), align: col.align })
|
|
21885
|
+
},
|
|
21886
|
+
col.key
|
|
21887
|
+
);
|
|
21888
|
+
})
|
|
21659
21889
|
},
|
|
21660
|
-
|
|
21661
|
-
|
|
21662
|
-
|
|
21663
|
-
|
|
21664
|
-
|
|
21665
|
-
return /* @__PURE__ */ jsx63(
|
|
21666
|
-
TableCell,
|
|
21667
|
-
{
|
|
21668
|
-
"data-underverse-column-key": col.key,
|
|
21669
|
-
style: getStickyColumnStyle(col),
|
|
21670
|
-
className: cn(
|
|
21671
|
-
cellPadding,
|
|
21672
|
-
col.align === "right" && "text-right",
|
|
21673
|
-
col.align === "center" && "text-center",
|
|
21674
|
-
showBorderLeft && "border-l border-border/60",
|
|
21675
|
-
getStickyCellClass(col, isStripedRow)
|
|
21676
|
-
),
|
|
21677
|
-
children: col.render ? col.render(value, row, idx) : /* @__PURE__ */ jsx63(DataTableOverflowText, { text: String(value ?? ""), align: col.align })
|
|
21678
|
-
},
|
|
21679
|
-
col.key
|
|
21680
|
-
);
|
|
21681
|
-
})
|
|
21682
|
-
},
|
|
21683
|
-
getRowKey(row, idx)
|
|
21684
|
-
);
|
|
21685
|
-
}) });
|
|
21890
|
+
getRowKey(row, idx)
|
|
21891
|
+
);
|
|
21892
|
+
}),
|
|
21893
|
+
virtualPaddingBottom > 0 && /* @__PURE__ */ jsx63(TableRow, { "aria-hidden": "true", className: "border-0 hover:bg-transparent hover:shadow-none", children: /* @__PURE__ */ jsx63(TableCell, { colSpan: leafColumns.length, className: "p-0", style: { height: virtualPaddingBottom } }) })
|
|
21894
|
+
] }) });
|
|
21686
21895
|
}
|
|
21687
21896
|
|
|
21688
21897
|
// src/components/DataTable/components/DataTableHeader.tsx
|
|
21689
21898
|
import React54 from "react";
|
|
21690
21899
|
import { Filter as FilterIcon } from "lucide-react";
|
|
21691
|
-
import { Fragment as
|
|
21900
|
+
import { Fragment as Fragment23, jsx as jsx64, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
21692
21901
|
function getColumnLabel(title) {
|
|
21693
21902
|
if (typeof title === "string" || typeof title === "number") {
|
|
21694
21903
|
return String(title).replace(/\s+/g, " ").trim();
|
|
@@ -21904,10 +22113,10 @@ function DataTableHeader({
|
|
|
21904
22113
|
isCenterAlign && "justify-center",
|
|
21905
22114
|
!isRightAlign && !isCenterAlign && "justify-start"
|
|
21906
22115
|
),
|
|
21907
|
-
children: isRightAlign ? /* @__PURE__ */ jsxs53(
|
|
22116
|
+
children: isRightAlign ? /* @__PURE__ */ jsxs53(Fragment23, { children: [
|
|
21908
22117
|
filterContent,
|
|
21909
22118
|
titleContent
|
|
21910
|
-
] }) : /* @__PURE__ */ jsxs53(
|
|
22119
|
+
] }) : /* @__PURE__ */ jsxs53(Fragment23, { children: [
|
|
21911
22120
|
titleContent,
|
|
21912
22121
|
filterContent
|
|
21913
22122
|
] })
|
|
@@ -21928,7 +22137,7 @@ function DataTableHeader({
|
|
|
21928
22137
|
t
|
|
21929
22138
|
]
|
|
21930
22139
|
);
|
|
21931
|
-
return /* @__PURE__ */ jsx64(
|
|
22140
|
+
return /* @__PURE__ */ jsx64(Fragment23, { children: headerRows.map((row, rowIndex) => /* @__PURE__ */ jsx64(TableRow, { children: row.map((headerCell, cellIndex) => {
|
|
21932
22141
|
const { column: col, colSpan, rowSpan, isLeaf } = headerCell;
|
|
21933
22142
|
const prevCell = cellIndex > 0 ? row[cellIndex - 1] : null;
|
|
21934
22143
|
const prevCol = prevCell?.column;
|
|
@@ -22749,6 +22958,9 @@ function DataTable({
|
|
|
22749
22958
|
horizontalMode = "auto",
|
|
22750
22959
|
overflowHidden = true,
|
|
22751
22960
|
useOverlayScrollbar = false,
|
|
22961
|
+
virtualizedRows = false,
|
|
22962
|
+
estimatedRowHeight,
|
|
22963
|
+
overscan = 8,
|
|
22752
22964
|
enableHeaderAutoFit = true,
|
|
22753
22965
|
labels
|
|
22754
22966
|
}) {
|
|
@@ -22804,6 +23016,7 @@ function DataTable({
|
|
|
22804
23016
|
console.warn("[DataTable] `rowKey` should be provided when using sort/filter/pagination to keep row identity stable.");
|
|
22805
23017
|
}, [columns, isServerMode, pageSizeOptions, rowKey]);
|
|
22806
23018
|
const densityRowClass = density === "compact" ? "h-9" : density === "comfortable" ? "h-14" : "h-12";
|
|
23019
|
+
const defaultEstimatedRowHeight = density === "compact" ? 36 : density === "comfortable" ? 56 : 48;
|
|
22807
23020
|
const cellPadding = density === "compact" ? "py-1.5 px-3" : density === "comfortable" ? "py-3 px-4" : "py-2.5 px-4";
|
|
22808
23021
|
const headerTitleClass = size === "sm" ? "text-xs" : size === "lg" ? "text-[15px]" : "text-sm";
|
|
22809
23022
|
const headerMinHeightClass = size === "sm" ? "min-h-9" : size === "lg" ? "min-h-11" : "min-h-10";
|
|
@@ -22831,8 +23044,24 @@ function DataTable({
|
|
|
22831
23044
|
};
|
|
22832
23045
|
const viewportRef = React62.useRef(null);
|
|
22833
23046
|
const tableRef = React62.useRef(null);
|
|
23047
|
+
const canVirtualizeRows = virtualizedRows && !loading2 && displayedData.length > 0;
|
|
23048
|
+
const shouldUseScrollViewport = stickyHeader || canVirtualizeRows;
|
|
23049
|
+
const rowVirtualizer = useVirtualizer4({
|
|
23050
|
+
count: canVirtualizeRows ? displayedData.length : 0,
|
|
23051
|
+
getScrollElement: () => viewportRef.current,
|
|
23052
|
+
estimateSize: () => estimatedRowHeight ?? defaultEstimatedRowHeight,
|
|
23053
|
+
initialRect: {
|
|
23054
|
+
width: 0,
|
|
23055
|
+
height: typeof maxHeight === "number" ? maxHeight : 500
|
|
23056
|
+
},
|
|
23057
|
+
overscan,
|
|
23058
|
+
enabled: canVirtualizeRows
|
|
23059
|
+
});
|
|
23060
|
+
const virtualRows = canVirtualizeRows ? rowVirtualizer.getVirtualItems() : [];
|
|
23061
|
+
const virtualPaddingTop = canVirtualizeRows && virtualRows.length > 0 ? virtualRows[0]?.start ?? 0 : 0;
|
|
23062
|
+
const virtualPaddingBottom = canVirtualizeRows && virtualRows.length > 0 ? Math.max(0, rowVirtualizer.getTotalSize() - (virtualRows[virtualRows.length - 1]?.end ?? 0)) : 0;
|
|
22834
23063
|
useOverlayScrollbarTarget(viewportRef, {
|
|
22835
|
-
enabled: useOverlayScrollbar,
|
|
23064
|
+
enabled: useOverlayScrollbar && !canVirtualizeRows,
|
|
22836
23065
|
overflowX: overlayOverflowX
|
|
22837
23066
|
});
|
|
22838
23067
|
const autoFitColumn = React62.useCallback((columnKey) => {
|
|
@@ -22896,8 +23125,9 @@ function DataTable({
|
|
|
22896
23125
|
"div",
|
|
22897
23126
|
{
|
|
22898
23127
|
ref: viewportRef,
|
|
22899
|
-
|
|
22900
|
-
|
|
23128
|
+
"data-os-ignore": canVirtualizeRows ? "" : void 0,
|
|
23129
|
+
className: cn("w-full", viewportOverflowXClass, shouldUseScrollViewport && "overflow-y-auto"),
|
|
23130
|
+
style: shouldUseScrollViewport ? { maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight } : void 0,
|
|
22901
23131
|
children: /* @__PURE__ */ jsxs56(
|
|
22902
23132
|
Table,
|
|
22903
23133
|
{
|
|
@@ -22947,7 +23177,11 @@ function DataTable({
|
|
|
22947
23177
|
getStickyColumnStyle,
|
|
22948
23178
|
getStickyCellClass,
|
|
22949
23179
|
t,
|
|
22950
|
-
labels
|
|
23180
|
+
labels,
|
|
23181
|
+
virtualRows: canVirtualizeRows ? virtualRows : void 0,
|
|
23182
|
+
virtualPaddingTop: canVirtualizeRows ? virtualPaddingTop : void 0,
|
|
23183
|
+
virtualPaddingBottom: canVirtualizeRows ? virtualPaddingBottom : void 0,
|
|
23184
|
+
measureVirtualRow: canVirtualizeRows ? rowVirtualizer.measureElement : void 0
|
|
22951
23185
|
}
|
|
22952
23186
|
)
|
|
22953
23187
|
]
|
|
@@ -23212,7 +23446,7 @@ function AccessDenied({
|
|
|
23212
23446
|
import { Moon as Moon2, Sun as Sun2, Monitor } from "lucide-react";
|
|
23213
23447
|
import { useRef as useRef25, useState as useState40 } from "react";
|
|
23214
23448
|
import { createPortal as createPortal6 } from "react-dom";
|
|
23215
|
-
import { Fragment as
|
|
23449
|
+
import { Fragment as Fragment24, jsx as jsx71, jsxs as jsxs60 } from "react/jsx-runtime";
|
|
23216
23450
|
function ThemeToggleHeadless({
|
|
23217
23451
|
theme,
|
|
23218
23452
|
onChange,
|
|
@@ -23262,7 +23496,7 @@ function ThemeToggleHeadless({
|
|
|
23262
23496
|
children: /* @__PURE__ */ jsx71(CurrentIcon, { className: "h-5 w-5" })
|
|
23263
23497
|
}
|
|
23264
23498
|
),
|
|
23265
|
-
isOpen && /* @__PURE__ */ jsxs60(
|
|
23499
|
+
isOpen && /* @__PURE__ */ jsxs60(Fragment24, { children: [
|
|
23266
23500
|
typeof window !== "undefined" && createPortal6(/* @__PURE__ */ jsx71("div", { className: "fixed inset-0 z-9998", onClick: () => setIsOpen(false) }), document.body),
|
|
23267
23501
|
typeof window !== "undefined" && dropdownPosition && createPortal6(
|
|
23268
23502
|
/* @__PURE__ */ jsx71(
|
|
@@ -23314,7 +23548,7 @@ function ThemeToggleHeadless({
|
|
|
23314
23548
|
import { useRef as useRef26, useState as useState41 } from "react";
|
|
23315
23549
|
import { createPortal as createPortal7 } from "react-dom";
|
|
23316
23550
|
import { Globe } from "lucide-react";
|
|
23317
|
-
import { Fragment as
|
|
23551
|
+
import { Fragment as Fragment25, jsx as jsx72, jsxs as jsxs61 } from "react/jsx-runtime";
|
|
23318
23552
|
function LanguageSwitcherHeadless({
|
|
23319
23553
|
locales,
|
|
23320
23554
|
currentLocale,
|
|
@@ -23359,7 +23593,7 @@ function LanguageSwitcherHeadless({
|
|
|
23359
23593
|
children: /* @__PURE__ */ jsx72(Globe, { className: "h-5 w-5" })
|
|
23360
23594
|
}
|
|
23361
23595
|
),
|
|
23362
|
-
isOpen && /* @__PURE__ */ jsxs61(
|
|
23596
|
+
isOpen && /* @__PURE__ */ jsxs61(Fragment25, { children: [
|
|
23363
23597
|
typeof window !== "undefined" && createPortal7(/* @__PURE__ */ jsx72("div", { className: "fixed inset-0 z-9998", onClick: () => setIsOpen(false) }), document.body),
|
|
23364
23598
|
typeof window !== "undefined" && dropdownPosition && createPortal7(
|
|
23365
23599
|
/* @__PURE__ */ jsx72(
|
|
@@ -25263,7 +25497,7 @@ function getDefaultLetterSpacings() {
|
|
|
25263
25497
|
}
|
|
25264
25498
|
|
|
25265
25499
|
// src/components/UEditor/toolbar.tsx
|
|
25266
|
-
import { Fragment as
|
|
25500
|
+
import { Fragment as Fragment26, jsx as jsx80, jsxs as jsxs67 } from "react/jsx-runtime";
|
|
25267
25501
|
function fileToDataUrl2(file) {
|
|
25268
25502
|
return new Promise((resolve, reject) => {
|
|
25269
25503
|
const reader = new FileReader();
|
|
@@ -25905,7 +26139,7 @@ var EditorToolbar = ({
|
|
|
25905
26139
|
},
|
|
25906
26140
|
onCancel: () => setShowImageInput(false)
|
|
25907
26141
|
}
|
|
25908
|
-
) : /* @__PURE__ */ jsxs67(
|
|
26142
|
+
) : /* @__PURE__ */ jsxs67(Fragment26, { children: [
|
|
25909
26143
|
/* @__PURE__ */ jsx80(DropdownMenuItem, { icon: LinkIcon, label: t("imageInput.addFromUrl"), onClick: () => setShowImageInput(true) }),
|
|
25910
26144
|
/* @__PURE__ */ jsx80(
|
|
25911
26145
|
DropdownMenuItem,
|
|
@@ -26950,7 +27184,7 @@ function findDiffEnd(a, b, posA, posB) {
|
|
|
26950
27184
|
posB -= size;
|
|
26951
27185
|
}
|
|
26952
27186
|
}
|
|
26953
|
-
var
|
|
27187
|
+
var Fragment27 = class _Fragment {
|
|
26954
27188
|
/**
|
|
26955
27189
|
@internal
|
|
26956
27190
|
*/
|
|
@@ -27242,7 +27476,7 @@ var Fragment26 = class _Fragment {
|
|
|
27242
27476
|
throw new RangeError("Can not convert " + nodes + " to a Fragment" + (nodes.nodesBetween ? " (looks like multiple versions of prosemirror-model were loaded)" : ""));
|
|
27243
27477
|
}
|
|
27244
27478
|
};
|
|
27245
|
-
|
|
27479
|
+
Fragment27.empty = new Fragment27([], 0);
|
|
27246
27480
|
var found = { index: 0, offset: 0 };
|
|
27247
27481
|
function retIndex(index, offset) {
|
|
27248
27482
|
found.index = index;
|
|
@@ -27467,7 +27701,7 @@ var Slice = class _Slice {
|
|
|
27467
27701
|
let openStart = json.openStart || 0, openEnd = json.openEnd || 0;
|
|
27468
27702
|
if (typeof openStart != "number" || typeof openEnd != "number")
|
|
27469
27703
|
throw new RangeError("Invalid input for Slice.fromJSON");
|
|
27470
|
-
return new _Slice(
|
|
27704
|
+
return new _Slice(Fragment27.fromJSON(schema, json.content), openStart, openEnd);
|
|
27471
27705
|
}
|
|
27472
27706
|
/**
|
|
27473
27707
|
Create a slice from a fragment by taking the maximum possible
|
|
@@ -27482,7 +27716,7 @@ var Slice = class _Slice {
|
|
|
27482
27716
|
return new _Slice(fragment, openStart, openEnd);
|
|
27483
27717
|
}
|
|
27484
27718
|
};
|
|
27485
|
-
Slice.empty = new Slice(
|
|
27719
|
+
Slice.empty = new Slice(Fragment27.empty, 0, 0);
|
|
27486
27720
|
function removeRange(content, from, to) {
|
|
27487
27721
|
let { index, offset } = content.findIndex(from), child = content.maybeChild(index);
|
|
27488
27722
|
let { index: indexTo, offset: offsetTo } = content.findIndex(to);
|
|
@@ -27580,7 +27814,7 @@ function replaceThreeWay($from, $start, $end, $to, depth) {
|
|
|
27580
27814
|
addNode(close(openEnd, replaceTwoWay($end, $to, depth + 1)), content);
|
|
27581
27815
|
}
|
|
27582
27816
|
addRange($to, null, depth, content);
|
|
27583
|
-
return new
|
|
27817
|
+
return new Fragment27(content);
|
|
27584
27818
|
}
|
|
27585
27819
|
function replaceTwoWay($from, $to, depth) {
|
|
27586
27820
|
let content = [];
|
|
@@ -27590,13 +27824,13 @@ function replaceTwoWay($from, $to, depth) {
|
|
|
27590
27824
|
addNode(close(type, replaceTwoWay($from, $to, depth + 1)), content);
|
|
27591
27825
|
}
|
|
27592
27826
|
addRange($to, null, depth, content);
|
|
27593
|
-
return new
|
|
27827
|
+
return new Fragment27(content);
|
|
27594
27828
|
}
|
|
27595
27829
|
function prepareSliceForReplace(slice, $along) {
|
|
27596
27830
|
let extra = $along.depth - slice.openStart, parent = $along.node(extra);
|
|
27597
27831
|
let node = parent.copy(slice.content);
|
|
27598
27832
|
for (let i = extra - 1; i >= 0; i--)
|
|
27599
|
-
node = $along.node(i).copy(
|
|
27833
|
+
node = $along.node(i).copy(Fragment27.from(node));
|
|
27600
27834
|
return {
|
|
27601
27835
|
start: node.resolveNoCache(slice.openStart + extra),
|
|
27602
27836
|
end: node.resolveNoCache(node.content.size - slice.openEnd - extra)
|
|
@@ -27935,7 +28169,7 @@ var Node2 = class _Node {
|
|
|
27935
28169
|
this.type = type;
|
|
27936
28170
|
this.attrs = attrs;
|
|
27937
28171
|
this.marks = marks;
|
|
27938
|
-
this.content = content ||
|
|
28172
|
+
this.content = content || Fragment27.empty;
|
|
27939
28173
|
}
|
|
27940
28174
|
/**
|
|
27941
28175
|
The array of this node's child nodes.
|
|
@@ -28240,7 +28474,7 @@ var Node2 = class _Node {
|
|
|
28240
28474
|
can optionally pass `start` and `end` indices into the
|
|
28241
28475
|
replacement fragment.
|
|
28242
28476
|
*/
|
|
28243
|
-
canReplace(from, to, replacement =
|
|
28477
|
+
canReplace(from, to, replacement = Fragment27.empty, start = 0, end = replacement.childCount) {
|
|
28244
28478
|
let one = this.contentMatchAt(from).matchFragment(replacement, start, end);
|
|
28245
28479
|
let two = one && one.matchFragment(this.content, to);
|
|
28246
28480
|
if (!two || !two.validEnd)
|
|
@@ -28322,7 +28556,7 @@ var Node2 = class _Node {
|
|
|
28322
28556
|
throw new RangeError("Invalid text node in JSON");
|
|
28323
28557
|
return schema.text(json.text, marks);
|
|
28324
28558
|
}
|
|
28325
|
-
let content =
|
|
28559
|
+
let content = Fragment27.fromJSON(schema, json.content);
|
|
28326
28560
|
let node = schema.nodeType(json.type).create(json.attrs, content, marks);
|
|
28327
28561
|
node.type.checkAttrs(node.attrs);
|
|
28328
28562
|
return node;
|
|
@@ -28418,7 +28652,7 @@ var ContentMatch = class _ContentMatch {
|
|
|
28418
28652
|
function search(match, types) {
|
|
28419
28653
|
let finished = match.matchFragment(after, startIndex);
|
|
28420
28654
|
if (finished && (!toEnd || finished.validEnd))
|
|
28421
|
-
return
|
|
28655
|
+
return Fragment27.from(types.map((tp) => tp.createAndFill()));
|
|
28422
28656
|
for (let i = 0; i < match.next.length; i++) {
|
|
28423
28657
|
let { type, next } = match.next[i];
|
|
28424
28658
|
if (!(type.isText || type.hasRequiredAttrs()) && seen.indexOf(next) == -1) {
|
|
@@ -28986,7 +29220,7 @@ function mapFragment(fragment, f, parent) {
|
|
|
28986
29220
|
child = f(child, parent, i);
|
|
28987
29221
|
mapped.push(child);
|
|
28988
29222
|
}
|
|
28989
|
-
return
|
|
29223
|
+
return Fragment27.fromArray(mapped);
|
|
28990
29224
|
}
|
|
28991
29225
|
var AddMarkStep = class _AddMarkStep extends Step {
|
|
28992
29226
|
/**
|
|
@@ -29103,7 +29337,7 @@ var AddNodeMarkStep = class _AddNodeMarkStep extends Step {
|
|
|
29103
29337
|
if (!node)
|
|
29104
29338
|
return StepResult.fail("No node at mark step's position");
|
|
29105
29339
|
let updated = node.type.create(node.attrs, null, this.mark.addToSet(node.marks));
|
|
29106
|
-
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(
|
|
29340
|
+
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment27.from(updated), 0, node.isLeaf ? 0 : 1));
|
|
29107
29341
|
}
|
|
29108
29342
|
invert(doc) {
|
|
29109
29343
|
let node = doc.nodeAt(this.pos);
|
|
@@ -29149,7 +29383,7 @@ var RemoveNodeMarkStep = class _RemoveNodeMarkStep extends Step {
|
|
|
29149
29383
|
if (!node)
|
|
29150
29384
|
return StepResult.fail("No node at mark step's position");
|
|
29151
29385
|
let updated = node.type.create(node.attrs, null, this.mark.removeFromSet(node.marks));
|
|
29152
|
-
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(
|
|
29386
|
+
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment27.from(updated), 0, node.isLeaf ? 0 : 1));
|
|
29153
29387
|
}
|
|
29154
29388
|
invert(doc) {
|
|
29155
29389
|
let node = doc.nodeAt(this.pos);
|
|
@@ -29350,7 +29584,7 @@ var AttrStep = class _AttrStep extends Step {
|
|
|
29350
29584
|
attrs[name] = node.attrs[name];
|
|
29351
29585
|
attrs[this.attr] = this.value;
|
|
29352
29586
|
let updated = node.type.create(attrs, null, node.marks);
|
|
29353
|
-
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(
|
|
29587
|
+
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment27.from(updated), 0, node.isLeaf ? 0 : 1));
|
|
29354
29588
|
}
|
|
29355
29589
|
getMap() {
|
|
29356
29590
|
return StepMap.empty;
|
|
@@ -29734,7 +29968,7 @@ var NodeSelection2 = class _NodeSelection extends Selection {
|
|
|
29734
29968
|
return new _NodeSelection($pos);
|
|
29735
29969
|
}
|
|
29736
29970
|
content() {
|
|
29737
|
-
return new Slice(
|
|
29971
|
+
return new Slice(Fragment27.from(this.node), 0, 0);
|
|
29738
29972
|
}
|
|
29739
29973
|
eq(other) {
|
|
29740
29974
|
return other instanceof _NodeSelection && other.anchor == this.anchor;
|
|
@@ -30462,10 +30696,10 @@ var CellSelection = class CellSelection2 extends Selection {
|
|
|
30462
30696
|
}
|
|
30463
30697
|
rowContent.push(cell);
|
|
30464
30698
|
}
|
|
30465
|
-
rows.push(table.child(row).copy(
|
|
30699
|
+
rows.push(table.child(row).copy(Fragment27.from(rowContent)));
|
|
30466
30700
|
}
|
|
30467
30701
|
const fragment = this.isColSelection() && this.isRowSelection() ? table : rows;
|
|
30468
|
-
return new Slice(
|
|
30702
|
+
return new Slice(Fragment27.from(fragment), 1, 1);
|
|
30469
30703
|
}
|
|
30470
30704
|
replace(tr, content = Slice.empty) {
|
|
30471
30705
|
const mapFrom = tr.steps.length, ranges = this.ranges;
|
|
@@ -30477,7 +30711,7 @@ var CellSelection = class CellSelection2 extends Selection {
|
|
|
30477
30711
|
if (sel) tr.setSelection(sel);
|
|
30478
30712
|
}
|
|
30479
30713
|
replaceWith(tr, node) {
|
|
30480
|
-
this.replace(tr, new Slice(
|
|
30714
|
+
this.replace(tr, new Slice(Fragment27.from(node), 0, 0));
|
|
30481
30715
|
}
|
|
30482
30716
|
forEachCell(f) {
|
|
30483
30717
|
const table = this.$anchorCell.node(-1);
|
|
@@ -31174,7 +31408,7 @@ function getRelativeSelectedCellsMetrics(surface) {
|
|
|
31174
31408
|
}
|
|
31175
31409
|
|
|
31176
31410
|
// src/components/UEditor/table-controls.tsx
|
|
31177
|
-
import { Fragment as
|
|
31411
|
+
import { Fragment as Fragment28, jsx as jsx82, jsxs as jsxs70 } from "react/jsx-runtime";
|
|
31178
31412
|
var FALLBACK_TABLE_ROW_HEIGHT = 44;
|
|
31179
31413
|
var FALLBACK_TABLE_COLUMN_WIDTH = 160;
|
|
31180
31414
|
var MENU_HOVER_PADDING = 18;
|
|
@@ -31811,7 +32045,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
31811
32045
|
const expandPreviewWidth = dragPreview?.kind === "add-column" ? layout.tableWidth + dragPreview.previewCols * layout.avgColumnWidth : layout.tableWidth;
|
|
31812
32046
|
const expandPreviewHeight = dragPreview?.kind === "add-row" ? layout.tableHeight + dragPreview.previewRows * layout.avgRowHeight : layout.tableHeight;
|
|
31813
32047
|
const dragStatusText = dragPreview?.kind === "row" ? `${t("tableMenu.dragRow")} ${dragPreview.originIndex + 1} -> ${dragPreview.targetIndex + 1}` : dragPreview?.kind === "column" ? `${t("tableMenu.dragColumn")} ${dragPreview.originIndex + 1} -> ${dragPreview.targetIndex + 1}` : dragPreview?.kind === "add-row" ? `+${dragPreview.previewRows}R` : dragPreview?.kind === "add-column" ? `+${dragPreview.previewCols}C` : null;
|
|
31814
|
-
return /* @__PURE__ */ jsxs70(
|
|
32048
|
+
return /* @__PURE__ */ jsxs70(Fragment28, { children: [
|
|
31815
32049
|
layout.rowHandles.map((rowHandle) => {
|
|
31816
32050
|
const menuKey = getRowMenuKey(rowHandle.index);
|
|
31817
32051
|
const visible = controlsVisible || hoverState.rowHandleIndex === rowHandle.index || openMenuKey === menuKey;
|
|
@@ -32085,7 +32319,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
32085
32319
|
)
|
|
32086
32320
|
}
|
|
32087
32321
|
),
|
|
32088
|
-
dragPreview?.kind === "row" && /* @__PURE__ */ jsxs70(
|
|
32322
|
+
dragPreview?.kind === "row" && /* @__PURE__ */ jsxs70(Fragment28, { children: [
|
|
32089
32323
|
/* @__PURE__ */ jsx82(
|
|
32090
32324
|
"div",
|
|
32091
32325
|
{
|
|
@@ -32113,7 +32347,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
32113
32347
|
}
|
|
32114
32348
|
)
|
|
32115
32349
|
] }),
|
|
32116
|
-
dragPreview?.kind === "column" && /* @__PURE__ */ jsxs70(
|
|
32350
|
+
dragPreview?.kind === "column" && /* @__PURE__ */ jsxs70(Fragment28, { children: [
|
|
32117
32351
|
/* @__PURE__ */ jsx82(
|
|
32118
32352
|
"div",
|
|
32119
32353
|
{
|
|
@@ -32141,7 +32375,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
32141
32375
|
}
|
|
32142
32376
|
)
|
|
32143
32377
|
] }),
|
|
32144
|
-
(dragPreview?.kind === "add-row" || dragPreview?.kind === "add-column") && /* @__PURE__ */ jsx82(
|
|
32378
|
+
(dragPreview?.kind === "add-row" || dragPreview?.kind === "add-column") && /* @__PURE__ */ jsx82(Fragment28, { children: /* @__PURE__ */ jsx82(
|
|
32145
32379
|
"div",
|
|
32146
32380
|
{
|
|
32147
32381
|
"aria-hidden": "true",
|