@underverse-ui/underverse 1.0.113 → 1.0.115
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 +324 -91
- 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 +340 -107
- 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,23 @@ 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 rowVirtualizer = useVirtualizer4({
|
|
23049
|
+
count: canVirtualizeRows ? displayedData.length : 0,
|
|
23050
|
+
getScrollElement: () => viewportRef.current,
|
|
23051
|
+
estimateSize: () => estimatedRowHeight ?? defaultEstimatedRowHeight,
|
|
23052
|
+
initialRect: {
|
|
23053
|
+
width: 0,
|
|
23054
|
+
height: typeof maxHeight === "number" ? maxHeight : 500
|
|
23055
|
+
},
|
|
23056
|
+
overscan,
|
|
23057
|
+
enabled: canVirtualizeRows
|
|
23058
|
+
});
|
|
23059
|
+
const virtualRows = canVirtualizeRows ? rowVirtualizer.getVirtualItems() : [];
|
|
23060
|
+
const virtualPaddingTop = canVirtualizeRows && virtualRows.length > 0 ? virtualRows[0]?.start ?? 0 : 0;
|
|
23061
|
+
const virtualPaddingBottom = canVirtualizeRows && virtualRows.length > 0 ? Math.max(0, rowVirtualizer.getTotalSize() - (virtualRows[virtualRows.length - 1]?.end ?? 0)) : 0;
|
|
22834
23062
|
useOverlayScrollbarTarget(viewportRef, {
|
|
22835
|
-
enabled: useOverlayScrollbar,
|
|
23063
|
+
enabled: useOverlayScrollbar && !canVirtualizeRows,
|
|
22836
23064
|
overflowX: overlayOverflowX
|
|
22837
23065
|
});
|
|
22838
23066
|
const autoFitColumn = React62.useCallback((columnKey) => {
|
|
@@ -22896,6 +23124,7 @@ function DataTable({
|
|
|
22896
23124
|
"div",
|
|
22897
23125
|
{
|
|
22898
23126
|
ref: viewportRef,
|
|
23127
|
+
"data-os-ignore": canVirtualizeRows ? "" : void 0,
|
|
22899
23128
|
className: cn("w-full", viewportOverflowXClass, stickyHeader && "overflow-y-auto"),
|
|
22900
23129
|
style: stickyHeader ? { maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight } : void 0,
|
|
22901
23130
|
children: /* @__PURE__ */ jsxs56(
|
|
@@ -22947,7 +23176,11 @@ function DataTable({
|
|
|
22947
23176
|
getStickyColumnStyle,
|
|
22948
23177
|
getStickyCellClass,
|
|
22949
23178
|
t,
|
|
22950
|
-
labels
|
|
23179
|
+
labels,
|
|
23180
|
+
virtualRows: canVirtualizeRows ? virtualRows : void 0,
|
|
23181
|
+
virtualPaddingTop: canVirtualizeRows ? virtualPaddingTop : void 0,
|
|
23182
|
+
virtualPaddingBottom: canVirtualizeRows ? virtualPaddingBottom : void 0,
|
|
23183
|
+
measureVirtualRow: canVirtualizeRows ? rowVirtualizer.measureElement : void 0
|
|
22951
23184
|
}
|
|
22952
23185
|
)
|
|
22953
23186
|
]
|
|
@@ -23212,7 +23445,7 @@ function AccessDenied({
|
|
|
23212
23445
|
import { Moon as Moon2, Sun as Sun2, Monitor } from "lucide-react";
|
|
23213
23446
|
import { useRef as useRef25, useState as useState40 } from "react";
|
|
23214
23447
|
import { createPortal as createPortal6 } from "react-dom";
|
|
23215
|
-
import { Fragment as
|
|
23448
|
+
import { Fragment as Fragment24, jsx as jsx71, jsxs as jsxs60 } from "react/jsx-runtime";
|
|
23216
23449
|
function ThemeToggleHeadless({
|
|
23217
23450
|
theme,
|
|
23218
23451
|
onChange,
|
|
@@ -23262,7 +23495,7 @@ function ThemeToggleHeadless({
|
|
|
23262
23495
|
children: /* @__PURE__ */ jsx71(CurrentIcon, { className: "h-5 w-5" })
|
|
23263
23496
|
}
|
|
23264
23497
|
),
|
|
23265
|
-
isOpen && /* @__PURE__ */ jsxs60(
|
|
23498
|
+
isOpen && /* @__PURE__ */ jsxs60(Fragment24, { children: [
|
|
23266
23499
|
typeof window !== "undefined" && createPortal6(/* @__PURE__ */ jsx71("div", { className: "fixed inset-0 z-9998", onClick: () => setIsOpen(false) }), document.body),
|
|
23267
23500
|
typeof window !== "undefined" && dropdownPosition && createPortal6(
|
|
23268
23501
|
/* @__PURE__ */ jsx71(
|
|
@@ -23314,7 +23547,7 @@ function ThemeToggleHeadless({
|
|
|
23314
23547
|
import { useRef as useRef26, useState as useState41 } from "react";
|
|
23315
23548
|
import { createPortal as createPortal7 } from "react-dom";
|
|
23316
23549
|
import { Globe } from "lucide-react";
|
|
23317
|
-
import { Fragment as
|
|
23550
|
+
import { Fragment as Fragment25, jsx as jsx72, jsxs as jsxs61 } from "react/jsx-runtime";
|
|
23318
23551
|
function LanguageSwitcherHeadless({
|
|
23319
23552
|
locales,
|
|
23320
23553
|
currentLocale,
|
|
@@ -23359,7 +23592,7 @@ function LanguageSwitcherHeadless({
|
|
|
23359
23592
|
children: /* @__PURE__ */ jsx72(Globe, { className: "h-5 w-5" })
|
|
23360
23593
|
}
|
|
23361
23594
|
),
|
|
23362
|
-
isOpen && /* @__PURE__ */ jsxs61(
|
|
23595
|
+
isOpen && /* @__PURE__ */ jsxs61(Fragment25, { children: [
|
|
23363
23596
|
typeof window !== "undefined" && createPortal7(/* @__PURE__ */ jsx72("div", { className: "fixed inset-0 z-9998", onClick: () => setIsOpen(false) }), document.body),
|
|
23364
23597
|
typeof window !== "undefined" && dropdownPosition && createPortal7(
|
|
23365
23598
|
/* @__PURE__ */ jsx72(
|
|
@@ -25263,7 +25496,7 @@ function getDefaultLetterSpacings() {
|
|
|
25263
25496
|
}
|
|
25264
25497
|
|
|
25265
25498
|
// src/components/UEditor/toolbar.tsx
|
|
25266
|
-
import { Fragment as
|
|
25499
|
+
import { Fragment as Fragment26, jsx as jsx80, jsxs as jsxs67 } from "react/jsx-runtime";
|
|
25267
25500
|
function fileToDataUrl2(file) {
|
|
25268
25501
|
return new Promise((resolve, reject) => {
|
|
25269
25502
|
const reader = new FileReader();
|
|
@@ -25905,7 +26138,7 @@ var EditorToolbar = ({
|
|
|
25905
26138
|
},
|
|
25906
26139
|
onCancel: () => setShowImageInput(false)
|
|
25907
26140
|
}
|
|
25908
|
-
) : /* @__PURE__ */ jsxs67(
|
|
26141
|
+
) : /* @__PURE__ */ jsxs67(Fragment26, { children: [
|
|
25909
26142
|
/* @__PURE__ */ jsx80(DropdownMenuItem, { icon: LinkIcon, label: t("imageInput.addFromUrl"), onClick: () => setShowImageInput(true) }),
|
|
25910
26143
|
/* @__PURE__ */ jsx80(
|
|
25911
26144
|
DropdownMenuItem,
|
|
@@ -26950,7 +27183,7 @@ function findDiffEnd(a, b, posA, posB) {
|
|
|
26950
27183
|
posB -= size;
|
|
26951
27184
|
}
|
|
26952
27185
|
}
|
|
26953
|
-
var
|
|
27186
|
+
var Fragment27 = class _Fragment {
|
|
26954
27187
|
/**
|
|
26955
27188
|
@internal
|
|
26956
27189
|
*/
|
|
@@ -27242,7 +27475,7 @@ var Fragment26 = class _Fragment {
|
|
|
27242
27475
|
throw new RangeError("Can not convert " + nodes + " to a Fragment" + (nodes.nodesBetween ? " (looks like multiple versions of prosemirror-model were loaded)" : ""));
|
|
27243
27476
|
}
|
|
27244
27477
|
};
|
|
27245
|
-
|
|
27478
|
+
Fragment27.empty = new Fragment27([], 0);
|
|
27246
27479
|
var found = { index: 0, offset: 0 };
|
|
27247
27480
|
function retIndex(index, offset) {
|
|
27248
27481
|
found.index = index;
|
|
@@ -27467,7 +27700,7 @@ var Slice = class _Slice {
|
|
|
27467
27700
|
let openStart = json.openStart || 0, openEnd = json.openEnd || 0;
|
|
27468
27701
|
if (typeof openStart != "number" || typeof openEnd != "number")
|
|
27469
27702
|
throw new RangeError("Invalid input for Slice.fromJSON");
|
|
27470
|
-
return new _Slice(
|
|
27703
|
+
return new _Slice(Fragment27.fromJSON(schema, json.content), openStart, openEnd);
|
|
27471
27704
|
}
|
|
27472
27705
|
/**
|
|
27473
27706
|
Create a slice from a fragment by taking the maximum possible
|
|
@@ -27482,7 +27715,7 @@ var Slice = class _Slice {
|
|
|
27482
27715
|
return new _Slice(fragment, openStart, openEnd);
|
|
27483
27716
|
}
|
|
27484
27717
|
};
|
|
27485
|
-
Slice.empty = new Slice(
|
|
27718
|
+
Slice.empty = new Slice(Fragment27.empty, 0, 0);
|
|
27486
27719
|
function removeRange(content, from, to) {
|
|
27487
27720
|
let { index, offset } = content.findIndex(from), child = content.maybeChild(index);
|
|
27488
27721
|
let { index: indexTo, offset: offsetTo } = content.findIndex(to);
|
|
@@ -27580,7 +27813,7 @@ function replaceThreeWay($from, $start, $end, $to, depth) {
|
|
|
27580
27813
|
addNode(close(openEnd, replaceTwoWay($end, $to, depth + 1)), content);
|
|
27581
27814
|
}
|
|
27582
27815
|
addRange($to, null, depth, content);
|
|
27583
|
-
return new
|
|
27816
|
+
return new Fragment27(content);
|
|
27584
27817
|
}
|
|
27585
27818
|
function replaceTwoWay($from, $to, depth) {
|
|
27586
27819
|
let content = [];
|
|
@@ -27590,13 +27823,13 @@ function replaceTwoWay($from, $to, depth) {
|
|
|
27590
27823
|
addNode(close(type, replaceTwoWay($from, $to, depth + 1)), content);
|
|
27591
27824
|
}
|
|
27592
27825
|
addRange($to, null, depth, content);
|
|
27593
|
-
return new
|
|
27826
|
+
return new Fragment27(content);
|
|
27594
27827
|
}
|
|
27595
27828
|
function prepareSliceForReplace(slice, $along) {
|
|
27596
27829
|
let extra = $along.depth - slice.openStart, parent = $along.node(extra);
|
|
27597
27830
|
let node = parent.copy(slice.content);
|
|
27598
27831
|
for (let i = extra - 1; i >= 0; i--)
|
|
27599
|
-
node = $along.node(i).copy(
|
|
27832
|
+
node = $along.node(i).copy(Fragment27.from(node));
|
|
27600
27833
|
return {
|
|
27601
27834
|
start: node.resolveNoCache(slice.openStart + extra),
|
|
27602
27835
|
end: node.resolveNoCache(node.content.size - slice.openEnd - extra)
|
|
@@ -27935,7 +28168,7 @@ var Node2 = class _Node {
|
|
|
27935
28168
|
this.type = type;
|
|
27936
28169
|
this.attrs = attrs;
|
|
27937
28170
|
this.marks = marks;
|
|
27938
|
-
this.content = content ||
|
|
28171
|
+
this.content = content || Fragment27.empty;
|
|
27939
28172
|
}
|
|
27940
28173
|
/**
|
|
27941
28174
|
The array of this node's child nodes.
|
|
@@ -28240,7 +28473,7 @@ var Node2 = class _Node {
|
|
|
28240
28473
|
can optionally pass `start` and `end` indices into the
|
|
28241
28474
|
replacement fragment.
|
|
28242
28475
|
*/
|
|
28243
|
-
canReplace(from, to, replacement =
|
|
28476
|
+
canReplace(from, to, replacement = Fragment27.empty, start = 0, end = replacement.childCount) {
|
|
28244
28477
|
let one = this.contentMatchAt(from).matchFragment(replacement, start, end);
|
|
28245
28478
|
let two = one && one.matchFragment(this.content, to);
|
|
28246
28479
|
if (!two || !two.validEnd)
|
|
@@ -28322,7 +28555,7 @@ var Node2 = class _Node {
|
|
|
28322
28555
|
throw new RangeError("Invalid text node in JSON");
|
|
28323
28556
|
return schema.text(json.text, marks);
|
|
28324
28557
|
}
|
|
28325
|
-
let content =
|
|
28558
|
+
let content = Fragment27.fromJSON(schema, json.content);
|
|
28326
28559
|
let node = schema.nodeType(json.type).create(json.attrs, content, marks);
|
|
28327
28560
|
node.type.checkAttrs(node.attrs);
|
|
28328
28561
|
return node;
|
|
@@ -28418,7 +28651,7 @@ var ContentMatch = class _ContentMatch {
|
|
|
28418
28651
|
function search(match, types) {
|
|
28419
28652
|
let finished = match.matchFragment(after, startIndex);
|
|
28420
28653
|
if (finished && (!toEnd || finished.validEnd))
|
|
28421
|
-
return
|
|
28654
|
+
return Fragment27.from(types.map((tp) => tp.createAndFill()));
|
|
28422
28655
|
for (let i = 0; i < match.next.length; i++) {
|
|
28423
28656
|
let { type, next } = match.next[i];
|
|
28424
28657
|
if (!(type.isText || type.hasRequiredAttrs()) && seen.indexOf(next) == -1) {
|
|
@@ -28986,7 +29219,7 @@ function mapFragment(fragment, f, parent) {
|
|
|
28986
29219
|
child = f(child, parent, i);
|
|
28987
29220
|
mapped.push(child);
|
|
28988
29221
|
}
|
|
28989
|
-
return
|
|
29222
|
+
return Fragment27.fromArray(mapped);
|
|
28990
29223
|
}
|
|
28991
29224
|
var AddMarkStep = class _AddMarkStep extends Step {
|
|
28992
29225
|
/**
|
|
@@ -29103,7 +29336,7 @@ var AddNodeMarkStep = class _AddNodeMarkStep extends Step {
|
|
|
29103
29336
|
if (!node)
|
|
29104
29337
|
return StepResult.fail("No node at mark step's position");
|
|
29105
29338
|
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(
|
|
29339
|
+
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment27.from(updated), 0, node.isLeaf ? 0 : 1));
|
|
29107
29340
|
}
|
|
29108
29341
|
invert(doc) {
|
|
29109
29342
|
let node = doc.nodeAt(this.pos);
|
|
@@ -29149,7 +29382,7 @@ var RemoveNodeMarkStep = class _RemoveNodeMarkStep extends Step {
|
|
|
29149
29382
|
if (!node)
|
|
29150
29383
|
return StepResult.fail("No node at mark step's position");
|
|
29151
29384
|
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(
|
|
29385
|
+
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment27.from(updated), 0, node.isLeaf ? 0 : 1));
|
|
29153
29386
|
}
|
|
29154
29387
|
invert(doc) {
|
|
29155
29388
|
let node = doc.nodeAt(this.pos);
|
|
@@ -29350,7 +29583,7 @@ var AttrStep = class _AttrStep extends Step {
|
|
|
29350
29583
|
attrs[name] = node.attrs[name];
|
|
29351
29584
|
attrs[this.attr] = this.value;
|
|
29352
29585
|
let updated = node.type.create(attrs, null, node.marks);
|
|
29353
|
-
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(
|
|
29586
|
+
return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment27.from(updated), 0, node.isLeaf ? 0 : 1));
|
|
29354
29587
|
}
|
|
29355
29588
|
getMap() {
|
|
29356
29589
|
return StepMap.empty;
|
|
@@ -29734,7 +29967,7 @@ var NodeSelection2 = class _NodeSelection extends Selection {
|
|
|
29734
29967
|
return new _NodeSelection($pos);
|
|
29735
29968
|
}
|
|
29736
29969
|
content() {
|
|
29737
|
-
return new Slice(
|
|
29970
|
+
return new Slice(Fragment27.from(this.node), 0, 0);
|
|
29738
29971
|
}
|
|
29739
29972
|
eq(other) {
|
|
29740
29973
|
return other instanceof _NodeSelection && other.anchor == this.anchor;
|
|
@@ -30462,10 +30695,10 @@ var CellSelection = class CellSelection2 extends Selection {
|
|
|
30462
30695
|
}
|
|
30463
30696
|
rowContent.push(cell);
|
|
30464
30697
|
}
|
|
30465
|
-
rows.push(table.child(row).copy(
|
|
30698
|
+
rows.push(table.child(row).copy(Fragment27.from(rowContent)));
|
|
30466
30699
|
}
|
|
30467
30700
|
const fragment = this.isColSelection() && this.isRowSelection() ? table : rows;
|
|
30468
|
-
return new Slice(
|
|
30701
|
+
return new Slice(Fragment27.from(fragment), 1, 1);
|
|
30469
30702
|
}
|
|
30470
30703
|
replace(tr, content = Slice.empty) {
|
|
30471
30704
|
const mapFrom = tr.steps.length, ranges = this.ranges;
|
|
@@ -30477,7 +30710,7 @@ var CellSelection = class CellSelection2 extends Selection {
|
|
|
30477
30710
|
if (sel) tr.setSelection(sel);
|
|
30478
30711
|
}
|
|
30479
30712
|
replaceWith(tr, node) {
|
|
30480
|
-
this.replace(tr, new Slice(
|
|
30713
|
+
this.replace(tr, new Slice(Fragment27.from(node), 0, 0));
|
|
30481
30714
|
}
|
|
30482
30715
|
forEachCell(f) {
|
|
30483
30716
|
const table = this.$anchorCell.node(-1);
|
|
@@ -31174,7 +31407,7 @@ function getRelativeSelectedCellsMetrics(surface) {
|
|
|
31174
31407
|
}
|
|
31175
31408
|
|
|
31176
31409
|
// src/components/UEditor/table-controls.tsx
|
|
31177
|
-
import { Fragment as
|
|
31410
|
+
import { Fragment as Fragment28, jsx as jsx82, jsxs as jsxs70 } from "react/jsx-runtime";
|
|
31178
31411
|
var FALLBACK_TABLE_ROW_HEIGHT = 44;
|
|
31179
31412
|
var FALLBACK_TABLE_COLUMN_WIDTH = 160;
|
|
31180
31413
|
var MENU_HOVER_PADDING = 18;
|
|
@@ -31811,7 +32044,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
31811
32044
|
const expandPreviewWidth = dragPreview?.kind === "add-column" ? layout.tableWidth + dragPreview.previewCols * layout.avgColumnWidth : layout.tableWidth;
|
|
31812
32045
|
const expandPreviewHeight = dragPreview?.kind === "add-row" ? layout.tableHeight + dragPreview.previewRows * layout.avgRowHeight : layout.tableHeight;
|
|
31813
32046
|
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(
|
|
32047
|
+
return /* @__PURE__ */ jsxs70(Fragment28, { children: [
|
|
31815
32048
|
layout.rowHandles.map((rowHandle) => {
|
|
31816
32049
|
const menuKey = getRowMenuKey(rowHandle.index);
|
|
31817
32050
|
const visible = controlsVisible || hoverState.rowHandleIndex === rowHandle.index || openMenuKey === menuKey;
|
|
@@ -32085,7 +32318,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
32085
32318
|
)
|
|
32086
32319
|
}
|
|
32087
32320
|
),
|
|
32088
|
-
dragPreview?.kind === "row" && /* @__PURE__ */ jsxs70(
|
|
32321
|
+
dragPreview?.kind === "row" && /* @__PURE__ */ jsxs70(Fragment28, { children: [
|
|
32089
32322
|
/* @__PURE__ */ jsx82(
|
|
32090
32323
|
"div",
|
|
32091
32324
|
{
|
|
@@ -32113,7 +32346,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
32113
32346
|
}
|
|
32114
32347
|
)
|
|
32115
32348
|
] }),
|
|
32116
|
-
dragPreview?.kind === "column" && /* @__PURE__ */ jsxs70(
|
|
32349
|
+
dragPreview?.kind === "column" && /* @__PURE__ */ jsxs70(Fragment28, { children: [
|
|
32117
32350
|
/* @__PURE__ */ jsx82(
|
|
32118
32351
|
"div",
|
|
32119
32352
|
{
|
|
@@ -32141,7 +32374,7 @@ function TableControls({ editor, containerRef }) {
|
|
|
32141
32374
|
}
|
|
32142
32375
|
)
|
|
32143
32376
|
] }),
|
|
32144
|
-
(dragPreview?.kind === "add-row" || dragPreview?.kind === "add-column") && /* @__PURE__ */ jsx82(
|
|
32377
|
+
(dragPreview?.kind === "add-row" || dragPreview?.kind === "add-column") && /* @__PURE__ */ jsx82(Fragment28, { children: /* @__PURE__ */ jsx82(
|
|
32145
32378
|
"div",
|
|
32146
32379
|
{
|
|
32147
32380
|
"aria-hidden": "true",
|