@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/dist/index.cjs CHANGED
@@ -17475,6 +17475,7 @@ function OverlayControls({
17475
17475
 
17476
17476
  // src/components/CategoryTreeSelect.tsx
17477
17477
  var import_react22 = require("react");
17478
+ var import_react_virtual3 = require("@tanstack/react-virtual");
17478
17479
  var import_lucide_react26 = require("lucide-react");
17479
17480
  var import_jsx_runtime49 = require("react/jsx-runtime");
17480
17481
  var defaultLabels = {
@@ -17488,6 +17489,7 @@ var TREE_NODE_INDENT_REM = 1;
17488
17489
  var TREE_BRANCH_OFFSET_CLASS = "ml-1.5 pl-1.5";
17489
17490
  var TREE_NODE_GAP_CLASS = "gap-1.5";
17490
17491
  var TREE_EXPANDER_PLACEHOLDER_CLASS = "w-5";
17492
+ var CATEGORY_TREE_DROPDOWN_MAX_HEIGHT = 320;
17491
17493
  function getAncestorPathIds(categories, targetId) {
17492
17494
  const byId = new Map(categories.map((category) => [category.id, category]));
17493
17495
  const expanded = /* @__PURE__ */ new Set();
@@ -17566,6 +17568,24 @@ function pruneAncestorSelection(categories, childrenMap, selected, fromCategoryI
17566
17568
  function toCategoryOrderSelection(categories, selected) {
17567
17569
  return categories.map((category) => category.id).filter((categoryId) => selected.has(categoryId));
17568
17570
  }
17571
+ function flattenVisibleCategories(roots, childrenMap, expandedNodes, expandAllVisibleBranches) {
17572
+ const rows = [];
17573
+ const stack = roots.map((category) => ({ category, level: 0, path: /* @__PURE__ */ new Set() })).reverse();
17574
+ while (stack.length > 0) {
17575
+ const { category, level, path } = stack.pop();
17576
+ if (path.has(category.id)) continue;
17577
+ rows.push({ category, level });
17578
+ const children = childrenMap.get(category.id) ?? [];
17579
+ const isExpanded = children.length > 0 && (expandAllVisibleBranches || expandedNodes.has(category.id));
17580
+ if (!isExpanded) continue;
17581
+ const nextPath = new Set(path);
17582
+ nextPath.add(category.id);
17583
+ for (let index = children.length - 1; index >= 0; index -= 1) {
17584
+ stack.push({ category: children[index], level: level + 1, path: nextPath });
17585
+ }
17586
+ }
17587
+ return rows;
17588
+ }
17569
17589
  function CategoryTreeSelect(props) {
17570
17590
  const tv = useSmartTranslations("ValidationInput");
17571
17591
  const {
@@ -17594,6 +17614,15 @@ function CategoryTreeSelect(props) {
17594
17614
  className,
17595
17615
  useOverlayScrollbar = false,
17596
17616
  leafOnlySelect = false,
17617
+ virtualized = false,
17618
+ estimatedItemHeight = 44,
17619
+ overscan = 8,
17620
+ maxInitialOptions,
17621
+ searchMode = "auto",
17622
+ onSearchChange,
17623
+ searchDebounceMs = 0,
17624
+ minSearchLength = 0,
17625
+ showSearchPromptWhenEmptyQuery = false,
17597
17626
  singleSelect = false
17598
17627
  } = props;
17599
17628
  const [isOpen, setIsOpen] = (0, import_react22.useState)(false);
@@ -17601,10 +17630,13 @@ function CategoryTreeSelect(props) {
17601
17630
  () => getInitialExpandedNodes(categories, { defaultExpanded, defaultExpandedIds, expandToId, viewOnly, inline })
17602
17631
  );
17603
17632
  const [query, setQuery] = (0, import_react22.useState)("");
17633
+ const [activeIndex, setActiveIndex] = (0, import_react22.useState)(null);
17604
17634
  const [localRequiredError, setLocalRequiredError] = (0, import_react22.useState)();
17605
17635
  const searchInputRef = (0, import_react22.useRef)(null);
17606
17636
  const dropdownViewportRef = (0, import_react22.useRef)(null);
17607
- useOverlayScrollbarTarget(dropdownViewportRef, { enabled: useOverlayScrollbar });
17637
+ useOverlayScrollbarTarget(dropdownViewportRef, {
17638
+ enabled: isOpen && useOverlayScrollbar && !virtualized && !inline && !viewOnly
17639
+ });
17608
17640
  const autoId = (0, import_react22.useId)();
17609
17641
  const resolvedId = id ? String(id) : `category-tree-select-${autoId}`;
17610
17642
  const labelId = label ? `${resolvedId}-label` : void 0;
@@ -17624,7 +17656,7 @@ function CategoryTreeSelect(props) {
17624
17656
  const parentCategories2 = [];
17625
17657
  for (const cat of categories) byId2.set(cat.id, cat);
17626
17658
  for (const cat of categories) {
17627
- if (cat.parent_id == null) {
17659
+ if (cat.parent_id == null || !byId2.has(cat.parent_id)) {
17628
17660
  parentCategories2.push(cat);
17629
17661
  continue;
17630
17662
  }
@@ -17633,12 +17665,19 @@ function CategoryTreeSelect(props) {
17633
17665
  }
17634
17666
  return { parentCategories: parentCategories2, childrenMap: childrenMap2, byId: byId2 };
17635
17667
  }, [categories]);
17636
- const isSearchEnabled = (0, import_react22.useMemo)(() => enableSearch ?? categories.length > 10, [enableSearch, categories.length]);
17637
- const normalizedQuery = (0, import_react22.useMemo)(() => query.trim().toLowerCase(), [query]);
17668
+ const isSearchEnabled = (0, import_react22.useMemo)(
17669
+ () => enableSearch ?? (categories.length > 10 || searchMode === "manual" || minSearchLength > 0 || !!onSearchChange),
17670
+ [categories.length, enableSearch, minSearchLength, onSearchChange, searchMode]
17671
+ );
17672
+ const trimmedQuery = (0, import_react22.useMemo)(() => query.trim(), [query]);
17673
+ const normalizedQuery = (0, import_react22.useMemo)(() => trimmedQuery.toLowerCase(), [trimmedQuery]);
17674
+ const queryMeetsMinimum = trimmedQuery.length >= minSearchLength;
17675
+ const shouldPromptForSearch = minSearchLength > 0 && !queryMeetsMinimum && (searchMode === "manual" || showSearchPromptWhenEmptyQuery);
17638
17676
  const isSearchMode = isSearchEnabled && normalizedQuery.length > 0;
17677
+ const shouldAutoExpandSearchResults = searchMode === "auto" && isSearchMode;
17639
17678
  const effectiveExpandedNodes = (0, import_react22.useMemo)(() => getExpandedNodesState(expandedIds, expandedNodes), [expandedIds, expandedNodes]);
17640
17679
  const visibleIds = (0, import_react22.useMemo)(() => {
17641
- if (!isSearchMode) return null;
17680
+ if (shouldPromptForSearch || !isSearchMode || searchMode === "manual") return null;
17642
17681
  const matches = categories.filter((c) => c.name.toLowerCase().includes(normalizedQuery));
17643
17682
  if (matches.length === 0) return /* @__PURE__ */ new Set();
17644
17683
  const visible = /* @__PURE__ */ new Set();
@@ -17675,7 +17714,14 @@ function CategoryTreeSelect(props) {
17675
17714
  addDescendants(m.id);
17676
17715
  }
17677
17716
  return visible;
17678
- }, [byId, categories, childrenMap, isSearchMode, normalizedQuery]);
17717
+ }, [byId, categories, childrenMap, isSearchMode, normalizedQuery, searchMode, shouldPromptForSearch]);
17718
+ (0, import_react22.useEffect)(() => {
17719
+ if (!onSearchChange) return;
17720
+ const timeoutId = window.setTimeout(() => {
17721
+ onSearchChange(trimmedQuery);
17722
+ }, Math.max(0, searchDebounceMs));
17723
+ return () => window.clearTimeout(timeoutId);
17724
+ }, [onSearchChange, searchDebounceMs, trimmedQuery]);
17679
17725
  (0, import_react22.useEffect)(() => {
17680
17726
  if (!isOpen) return;
17681
17727
  if (!isSearchEnabled) return;
@@ -17688,7 +17734,7 @@ function CategoryTreeSelect(props) {
17688
17734
  }
17689
17735
  }, [disabled, required, valueArray.length]);
17690
17736
  const toggleExpand = (id2) => {
17691
- if (isSearchMode) return;
17737
+ if (shouldAutoExpandSearchResults) return;
17692
17738
  const newExpanded = new Set(effectiveExpandedNodes);
17693
17739
  if (newExpanded.has(id2)) {
17694
17740
  newExpanded.delete(id2);
@@ -17739,27 +17785,137 @@ function CategoryTreeSelect(props) {
17739
17785
  onChange(toCategoryOrderSelection(categories, newSelected));
17740
17786
  }
17741
17787
  };
17742
- const renderCategory = (category, level = 0) => {
17788
+ const effectiveParentCategories = (0, import_react22.useMemo)(() => {
17789
+ if (shouldPromptForSearch) return [];
17790
+ if (!isSearchMode || searchMode === "manual") return parentCategories;
17791
+ return parentCategories.filter((c) => visibleIds?.has(c.id));
17792
+ }, [isSearchMode, parentCategories, searchMode, shouldPromptForSearch, visibleIds]);
17793
+ const effectiveChildrenMap = (0, import_react22.useMemo)(() => {
17794
+ if (shouldPromptForSearch || !isSearchMode || !visibleIds || searchMode === "manual") return childrenMap;
17795
+ const nextChildrenMap = /* @__PURE__ */ new Map();
17796
+ for (const [parentId, children] of childrenMap.entries()) {
17797
+ nextChildrenMap.set(
17798
+ parentId,
17799
+ children.filter((child) => visibleIds.has(child.id))
17800
+ );
17801
+ }
17802
+ return nextChildrenMap;
17803
+ }, [childrenMap, isSearchMode, searchMode, shouldPromptForSearch, visibleIds]);
17804
+ const flattenedRows = (0, import_react22.useMemo)(() => {
17805
+ if (shouldPromptForSearch) return [];
17806
+ const rows = flattenVisibleCategories(effectiveParentCategories, effectiveChildrenMap, effectiveExpandedNodes, shouldAutoExpandSearchResults);
17807
+ if (trimmedQuery || maxInitialOptions === void 0 || maxInitialOptions < 1) {
17808
+ return rows;
17809
+ }
17810
+ const limitedRows = rows.slice(0, maxInitialOptions);
17811
+ const includedIds = new Set(limitedRows.map((row) => row.category.id));
17812
+ const pinnedIds = /* @__PURE__ */ new Set();
17813
+ for (const selectedId of selectedIds) {
17814
+ for (const ancestorId of getAncestorPathIds(categories, selectedId)) {
17815
+ pinnedIds.add(ancestorId);
17816
+ }
17817
+ }
17818
+ if (typeof expandToId === "number") {
17819
+ for (const ancestorId of getAncestorPathIds(categories, expandToId)) {
17820
+ pinnedIds.add(ancestorId);
17821
+ }
17822
+ }
17823
+ for (const row of rows) {
17824
+ if (!pinnedIds.has(row.category.id) || includedIds.has(row.category.id)) continue;
17825
+ limitedRows.push(row);
17826
+ includedIds.add(row.category.id);
17827
+ }
17828
+ return limitedRows;
17829
+ }, [
17830
+ categories,
17831
+ effectiveChildrenMap,
17832
+ effectiveExpandedNodes,
17833
+ effectiveParentCategories,
17834
+ expandToId,
17835
+ maxInitialOptions,
17836
+ selectedIds,
17837
+ shouldAutoExpandSearchResults,
17838
+ shouldPromptForSearch,
17839
+ trimmedQuery
17840
+ ]);
17841
+ const canVirtualize = virtualized && !inline && !viewOnly;
17842
+ const treeVirtualizer = (0, import_react_virtual3.useVirtualizer)({
17843
+ count: canVirtualize ? flattenedRows.length : 0,
17844
+ getScrollElement: () => dropdownViewportRef.current,
17845
+ estimateSize: () => estimatedItemHeight,
17846
+ initialRect: { width: 0, height: CATEGORY_TREE_DROPDOWN_MAX_HEIGHT },
17847
+ overscan,
17848
+ enabled: canVirtualize
17849
+ });
17850
+ const virtualRows = canVirtualize ? treeVirtualizer.getVirtualItems() : [];
17851
+ const scrollVirtualTreeToStart = () => {
17852
+ if (!canVirtualize || flattenedRows.length === 0) return;
17853
+ treeVirtualizer.scrollToIndex(0, { align: "start" });
17854
+ };
17855
+ const moveActiveVirtualRow = (direction) => {
17856
+ if (!canVirtualize || flattenedRows.length === 0) return;
17857
+ const nextIndex = activeIndex === null ? direction === 1 ? 0 : flattenedRows.length - 1 : (activeIndex + direction + flattenedRows.length) % flattenedRows.length;
17858
+ setActiveIndex(nextIndex);
17859
+ treeVirtualizer.scrollToIndex(nextIndex, { align: "auto" });
17860
+ };
17861
+ const handleVirtualTreeKeyDown = (event) => {
17862
+ if (!canVirtualize) return;
17863
+ if (event.key === "ArrowDown") {
17864
+ event.preventDefault();
17865
+ moveActiveVirtualRow(1);
17866
+ return;
17867
+ }
17868
+ if (event.key === "ArrowUp") {
17869
+ event.preventDefault();
17870
+ moveActiveVirtualRow(-1);
17871
+ return;
17872
+ }
17873
+ if (event.key === "Enter" && activeIndex !== null) {
17874
+ const row = flattenedRows[activeIndex];
17875
+ if (!row) return;
17876
+ event.preventDefault();
17877
+ handleSelect(row.category.id, row.category);
17878
+ }
17879
+ };
17880
+ (0, import_react22.useEffect)(() => {
17881
+ setActiveIndex(null);
17882
+ }, [flattenedRows]);
17883
+ const renderCategoryRow = (category, level = 0, virtualItem) => {
17743
17884
  const children = effectiveChildrenMap.get(category.id) || [];
17744
17885
  const hasChildren = children.length > 0;
17745
- const isExpanded = hasChildren && (isSearchMode || effectiveExpandedNodes.has(category.id));
17886
+ const isExpanded = hasChildren && (shouldAutoExpandSearchResults || effectiveExpandedNodes.has(category.id));
17746
17887
  const isSelected = selectedIds.has(category.id);
17747
17888
  const isSelectable = !viewOnly && (!leafOnlySelect || !hasChildren);
17889
+ const isActive = virtualItem?.index === activeIndex;
17890
+ const rowStyle = virtualItem ? {
17891
+ position: "absolute",
17892
+ top: 0,
17893
+ left: 0,
17894
+ width: "100%",
17895
+ transform: `translateY(${virtualItem.start}px)`
17896
+ } : void 0;
17748
17897
  return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
17749
17898
  "div",
17750
17899
  {
17751
- className: "min-w-0 animate-in fade-in-50 duration-200 [content-visibility:auto] [contain-intrinsic-size:44px]",
17752
- style: { animationDelay: `${level * 30}ms` },
17900
+ ref: virtualItem ? treeVirtualizer.measureElement : void 0,
17901
+ "data-index": virtualItem?.index,
17902
+ className: cn("min-w-0 [content-visibility:auto] [contain-intrinsic-size:44px]", !virtualItem && "animate-in fade-in-50 duration-200"),
17903
+ style: { animationDelay: virtualItem ? void 0 : `${level * 30}ms`, ...rowStyle },
17753
17904
  children: [
17754
17905
  /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
17755
17906
  "div",
17756
17907
  {
17908
+ role: "treeitem",
17909
+ "aria-level": level + 1,
17910
+ "aria-expanded": hasChildren ? isExpanded : void 0,
17911
+ "aria-selected": viewOnly ? void 0 : isSelected,
17757
17912
  onClick: () => !viewOnly && handleSelect(category.id, category),
17758
17913
  className: cn(
17759
17914
  "relative flex min-w-0 items-center px-3 py-2.5 min-h-11 transition-all duration-200 rounded-3xl",
17760
17915
  TREE_NODE_GAP_CLASS,
17761
17916
  !viewOnly && (isSelectable ? "cursor-pointer" : "cursor-default"),
17762
17917
  isSelectable && !isSelected && "hover:bg-accent/50",
17918
+ canVirtualize && isActive && "bg-accent/50",
17763
17919
  // Selected state - đồng bộ cho tất cả
17764
17920
  !viewOnly && isSelected && "bg-accent/40"
17765
17921
  ),
@@ -17769,6 +17925,7 @@ function CategoryTreeSelect(props) {
17769
17925
  "button",
17770
17926
  {
17771
17927
  type: "button",
17928
+ "aria-label": isExpanded ? `Collapse ${category.name}` : `Expand ${category.name}`,
17772
17929
  onClick: (e) => {
17773
17930
  e.stopPropagation();
17774
17931
  toggleExpand(category.id);
@@ -17778,9 +17935,9 @@ function CategoryTreeSelect(props) {
17778
17935
  "hover:scale-110 active:scale-95",
17779
17936
  "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50",
17780
17937
  isExpanded && "text-primary",
17781
- isSearchMode && "opacity-60 cursor-not-allowed hover:scale-100 active:scale-100"
17938
+ shouldAutoExpandSearchResults && "opacity-60 cursor-not-allowed hover:scale-100 active:scale-100"
17782
17939
  ),
17783
- disabled: isSearchMode,
17940
+ disabled: shouldAutoExpandSearchResults,
17784
17941
  children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: cn("transition-transform duration-200", isExpanded && "rotate-90"), children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_lucide_react26.ChevronRight, { className: "w-4 h-4" }) })
17785
17942
  }
17786
17943
  ) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: TREE_EXPANDER_PLACEHOLDER_CLASS }),
@@ -17811,15 +17968,16 @@ function CategoryTreeSelect(props) {
17811
17968
  ]
17812
17969
  }
17813
17970
  ),
17814
- hasChildren && isExpanded && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
17971
+ !virtualItem && hasChildren && isExpanded && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
17815
17972
  "div",
17816
17973
  {
17974
+ role: "group",
17817
17975
  className: cn(
17818
17976
  TREE_BRANCH_OFFSET_CLASS,
17819
17977
  "border-l-2 border-dashed border-border/50",
17820
17978
  "animate-in slide-in-from-top-2 fade-in-50 duration-200"
17821
17979
  ),
17822
- children: children.map((child) => renderCategory(child, level + 1))
17980
+ children: children.map((child) => renderCategoryRow(child, level + 1))
17823
17981
  }
17824
17982
  )
17825
17983
  ]
@@ -17836,7 +17994,11 @@ function CategoryTreeSelect(props) {
17836
17994
  {
17837
17995
  ref: searchInputRef,
17838
17996
  value: query,
17839
- onChange: (e) => setQuery(e.target.value),
17997
+ onChange: (e) => {
17998
+ setQuery(e.target.value);
17999
+ scrollVirtualTreeToStart();
18000
+ },
18001
+ onKeyDown: handleVirtualTreeKeyDown,
17840
18002
  placeholder: mergedLabels.searchPlaceholder,
17841
18003
  className: cn(
17842
18004
  "peer w-full rounded-full bg-background/90 py-2.5 pl-10 pr-10 text-sm shadow-sm",
@@ -17853,6 +18015,7 @@ function CategoryTreeSelect(props) {
17853
18015
  type: "button",
17854
18016
  onClick: () => {
17855
18017
  setQuery("");
18018
+ scrollVirtualTreeToStart();
17856
18019
  searchInputRef.current?.focus();
17857
18020
  },
17858
18021
  className: cn(
@@ -17867,24 +18030,40 @@ function CategoryTreeSelect(props) {
17867
18030
  )
17868
18031
  ] }) });
17869
18032
  };
17870
- const effectiveParentCategories = (0, import_react22.useMemo)(() => {
17871
- if (!isSearchMode) return parentCategories;
17872
- return parentCategories.filter((c) => visibleIds?.has(c.id));
17873
- }, [isSearchMode, parentCategories, visibleIds]);
17874
- let effectiveChildrenMap = childrenMap;
17875
- if (isSearchMode && visibleIds) {
17876
- effectiveChildrenMap = /* @__PURE__ */ new Map();
17877
- for (const [parentId, children] of childrenMap.entries()) {
17878
- effectiveChildrenMap.set(
17879
- parentId,
17880
- children.filter((child) => visibleIds.has(child.id))
17881
- );
17882
- }
17883
- }
17884
- const renderTreeContent = () => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "space-y-0.5 overflow-x-hidden", children: effectiveParentCategories.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
18033
+ const renderTreeContent = () => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "space-y-0.5 overflow-x-hidden", children: shouldPromptForSearch ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
18034
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "w-12 h-12 rounded-2xl bg-muted/50 flex items-center justify-center mb-3", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_lucide_react26.Search, { className: "w-6 h-6 text-muted-foreground/50" }) }),
18035
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("span", { className: "text-sm text-muted-foreground", children: [
18036
+ "Type at least ",
18037
+ minSearchLength,
18038
+ " characters to search"
18039
+ ] })
18040
+ ] }) : effectiveParentCategories.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
17885
18041
  /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "w-12 h-12 rounded-2xl bg-muted/50 flex items-center justify-center mb-3", children: isSearchMode ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_lucide_react26.SearchX, { className: "w-6 h-6 text-muted-foreground/50" }) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_lucide_react26.Layers, { className: "w-6 h-6 text-muted-foreground/50" }) }),
17886
18042
  /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-sm text-muted-foreground", children: isSearchMode ? mergedLabels.noResultsText : mergedLabels.emptyText })
17887
- ] }) : effectiveParentCategories.map((cat) => renderCategory(cat)) });
18043
+ ] }) : effectiveParentCategories.map((cat) => renderCategoryRow(cat)) });
18044
+ const renderVirtualTreeContent = () => {
18045
+ if (shouldPromptForSearch) {
18046
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
18047
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "w-12 h-12 rounded-2xl bg-muted/50 flex items-center justify-center mb-3", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_lucide_react26.Search, { className: "w-6 h-6 text-muted-foreground/50" }) }),
18048
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("span", { className: "text-sm text-muted-foreground", children: [
18049
+ "Type at least ",
18050
+ minSearchLength,
18051
+ " characters to search"
18052
+ ] })
18053
+ ] });
18054
+ }
18055
+ if (flattenedRows.length === 0) {
18056
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
18057
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "w-12 h-12 rounded-2xl bg-muted/50 flex items-center justify-center mb-3", children: isSearchMode ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_lucide_react26.SearchX, { className: "w-6 h-6 text-muted-foreground/50" }) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_lucide_react26.Layers, { className: "w-6 h-6 text-muted-foreground/50" }) }),
18058
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-sm text-muted-foreground", children: isSearchMode ? mergedLabels.noResultsText : mergedLabels.emptyText })
18059
+ ] });
18060
+ }
18061
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "relative overflow-x-hidden", style: { height: `${treeVirtualizer.getTotalSize()}px` }, children: virtualRows.map((virtualRow) => {
18062
+ const row = flattenedRows[virtualRow.index];
18063
+ if (!row) return null;
18064
+ return renderCategoryRow(row.category, row.level, virtualRow);
18065
+ }) });
18066
+ };
17888
18067
  const renderLabel = () => label ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
17889
18068
  Label,
17890
18069
  {
@@ -17927,8 +18106,10 @@ function CategoryTreeSelect(props) {
17927
18106
  "div",
17928
18107
  {
17929
18108
  id: resolvedId,
18109
+ role: "tree",
17930
18110
  "aria-labelledby": labelId,
17931
18111
  "aria-describedby": describedBy,
18112
+ "aria-multiselectable": singleSelect ? void 0 : true,
17932
18113
  className: cn("rounded-2xl border border-border/60 bg-card/50 backdrop-blur-sm p-3 shadow-sm", disabled && "opacity-50"),
17933
18114
  children: [
17934
18115
  renderSearch(),
@@ -17963,8 +18144,10 @@ function CategoryTreeSelect(props) {
17963
18144
  "div",
17964
18145
  {
17965
18146
  id: resolvedId,
18147
+ role: "tree",
17966
18148
  "aria-labelledby": labelId,
17967
18149
  "aria-describedby": describedBy,
18150
+ "aria-multiselectable": singleSelect ? void 0 : true,
17968
18151
  className: cn("rounded-2xl border border-border/60 bg-card/50 backdrop-blur-sm p-3 shadow-sm", disabled && "opacity-50 pointer-events-none"),
17969
18152
  children: [
17970
18153
  renderSearch(),
@@ -18029,6 +18212,7 @@ function CategoryTreeSelect(props) {
18029
18212
  setIsOpen(nextOpen);
18030
18213
  if (!nextOpen) {
18031
18214
  setQuery("");
18215
+ scrollVirtualTreeToStart();
18032
18216
  }
18033
18217
  };
18034
18218
  let displayText;
@@ -18044,15 +18228,20 @@ function CategoryTreeSelect(props) {
18044
18228
  displayText = mergedLabels.selectedText(selectedCount);
18045
18229
  }
18046
18230
  }
18047
- const dropdownBody = /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex max-h-80 flex-col overflow-hidden", children: [
18231
+ const dropdownBody = /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex flex-col overflow-hidden", style: { maxHeight: CATEGORY_TREE_DROPDOWN_MAX_HEIGHT }, children: [
18048
18232
  renderSearch({ sticky: false, className: "border-b border-border/30 p-2 pb-2" }),
18049
18233
  /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
18050
18234
  "div",
18051
18235
  {
18052
18236
  ref: dropdownViewportRef,
18053
18237
  id: `${resolvedId}-tree`,
18238
+ role: "tree",
18239
+ "aria-multiselectable": singleSelect ? void 0 : true,
18240
+ "data-os-ignore": virtualized ? "" : void 0,
18241
+ tabIndex: canVirtualize ? 0 : void 0,
18242
+ onKeyDown: handleVirtualTreeKeyDown,
18054
18243
  className: cn("min-h-0 flex-1 overflow-auto overflow-x-hidden p-2 pt-2"),
18055
- children: renderTreeContent()
18244
+ children: canVirtualize ? renderVirtualTreeContent() : renderTreeContent()
18056
18245
  }
18057
18246
  )
18058
18247
  ] });
@@ -18107,6 +18296,10 @@ function CategoryTreeSelect(props) {
18107
18296
  if (event.key === "Enter" || event.key === " " || event.key === "ArrowDown") {
18108
18297
  event.preventDefault();
18109
18298
  handleOpenChange(!isOpen);
18299
+ if (event.key === "ArrowDown" && canVirtualize && flattenedRows.length > 0) {
18300
+ setActiveIndex(0);
18301
+ treeVirtualizer.scrollToIndex(0, { align: "start" });
18302
+ }
18110
18303
  }
18111
18304
  },
18112
18305
  className: cn(
@@ -21726,6 +21919,7 @@ var TableCaption = import_react28.default.forwardRef(({ className, ...props }, r
21726
21919
  TableCaption.displayName = "TableCaption";
21727
21920
 
21728
21921
  // src/components/DataTable/DataTable.tsx
21922
+ var import_react_virtual4 = require("@tanstack/react-virtual");
21729
21923
  var import_react38 = __toESM(require("react"), 1);
21730
21924
 
21731
21925
  // src/components/DataTable/components/DataTableBody.tsx
@@ -21798,8 +21992,17 @@ function DataTableBodyRows({
21798
21992
  getStickyColumnStyle,
21799
21993
  getStickyCellClass,
21800
21994
  t,
21801
- labels
21995
+ labels,
21996
+ virtualRows,
21997
+ virtualPaddingTop = 0,
21998
+ virtualPaddingBottom = 0,
21999
+ measureVirtualRow
21802
22000
  }) {
22001
+ const rowsToRender = virtualRows ? virtualRows.map((virtualRow) => ({
22002
+ row: displayedData[virtualRow.index],
22003
+ idx: virtualRow.index,
22004
+ virtualRow
22005
+ })).filter((item) => Boolean(item.row)) : displayedData.map((row, idx) => ({ row, idx, virtualRow: void 0 }));
21803
22006
  return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(TableBody, { children: loading2 ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(TableCell, { colSpan: leafColumns.length, className: "text-center py-8", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "flex items-center justify-center gap-2 text-muted-foreground", children: [
21804
22007
  /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("svg", { className: "animate-spin h-4 w-4", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
21805
22008
  /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
@@ -21816,42 +22019,48 @@ function DataTableBodyRows({
21816
22019
  t("loading"),
21817
22020
  "\u2026"
21818
22021
  ] })
21819
- ] }) }) }) : displayedData.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(TableCell, { colSpan: leafColumns.length, className: "text-center py-6 text-muted-foreground", children: labels?.noData || t("noData") }) }) : displayedData.map((row, idx) => {
21820
- const isStripedRow = striped && idx % 2 === 0;
21821
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
21822
- TableRow,
21823
- {
21824
- className: cn(densityRowClass, isStripedRow ? "bg-surface-1" : "bg-surface-0"),
21825
- style: {
21826
- contentVisibility: "auto",
21827
- containIntrinsicSize: density === "compact" ? "0 36px" : density === "comfortable" ? "0 56px" : "0 48px"
22022
+ ] }) }) }) : displayedData.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(TableCell, { colSpan: leafColumns.length, className: "text-center py-6 text-muted-foreground", children: labels?.noData || t("noData") }) }) : /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
22023
+ virtualPaddingTop > 0 && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(TableRow, { "aria-hidden": "true", className: "border-0 hover:bg-transparent hover:shadow-none", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(TableCell, { colSpan: leafColumns.length, className: "p-0", style: { height: virtualPaddingTop } }) }),
22024
+ rowsToRender.map(({ row, idx, virtualRow }) => {
22025
+ const isStripedRow = striped && idx % 2 === 0;
22026
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22027
+ TableRow,
22028
+ {
22029
+ ref: virtualRow ? measureVirtualRow : void 0,
22030
+ "data-index": virtualRow?.index,
22031
+ className: cn(densityRowClass, isStripedRow ? "bg-surface-1" : "bg-surface-0"),
22032
+ style: {
22033
+ contentVisibility: "auto",
22034
+ containIntrinsicSize: density === "compact" ? "0 36px" : density === "comfortable" ? "0 56px" : "0 48px"
22035
+ },
22036
+ children: leafColumns.map((col, colIdx) => {
22037
+ const value = col.dataIndex ? row[col.dataIndex] : void 0;
22038
+ const prevCol = colIdx > 0 ? leafColumns[colIdx - 1] : null;
22039
+ const isAfterFixedLeft = prevCol?.fixed === "left";
22040
+ const showBorderLeft = columnDividers && colIdx > 0 && !isAfterFixedLeft && !col.fixed;
22041
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
22042
+ TableCell,
22043
+ {
22044
+ "data-underverse-column-key": col.key,
22045
+ style: getStickyColumnStyle(col),
22046
+ className: cn(
22047
+ cellPadding,
22048
+ col.align === "right" && "text-right",
22049
+ col.align === "center" && "text-center",
22050
+ showBorderLeft && "border-l border-border/60",
22051
+ getStickyCellClass(col, isStripedRow)
22052
+ ),
22053
+ children: col.render ? col.render(value, row, idx) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(DataTableOverflowText, { text: String(value ?? ""), align: col.align })
22054
+ },
22055
+ col.key
22056
+ );
22057
+ })
21828
22058
  },
21829
- children: leafColumns.map((col, colIdx) => {
21830
- const value = col.dataIndex ? row[col.dataIndex] : void 0;
21831
- const prevCol = colIdx > 0 ? leafColumns[colIdx - 1] : null;
21832
- const isAfterFixedLeft = prevCol?.fixed === "left";
21833
- const showBorderLeft = columnDividers && colIdx > 0 && !isAfterFixedLeft && !col.fixed;
21834
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
21835
- TableCell,
21836
- {
21837
- "data-underverse-column-key": col.key,
21838
- style: getStickyColumnStyle(col),
21839
- className: cn(
21840
- cellPadding,
21841
- col.align === "right" && "text-right",
21842
- col.align === "center" && "text-center",
21843
- showBorderLeft && "border-l border-border/60",
21844
- getStickyCellClass(col, isStripedRow)
21845
- ),
21846
- children: col.render ? col.render(value, row, idx) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(DataTableOverflowText, { text: String(value ?? ""), align: col.align })
21847
- },
21848
- col.key
21849
- );
21850
- })
21851
- },
21852
- getRowKey(row, idx)
21853
- );
21854
- }) });
22059
+ getRowKey(row, idx)
22060
+ );
22061
+ }),
22062
+ virtualPaddingBottom > 0 && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(TableRow, { "aria-hidden": "true", className: "border-0 hover:bg-transparent hover:shadow-none", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(TableCell, { colSpan: leafColumns.length, className: "p-0", style: { height: virtualPaddingBottom } }) })
22063
+ ] }) });
21855
22064
  }
21856
22065
 
21857
22066
  // src/components/DataTable/components/DataTableHeader.tsx
@@ -22918,6 +23127,9 @@ function DataTable({
22918
23127
  horizontalMode = "auto",
22919
23128
  overflowHidden = true,
22920
23129
  useOverlayScrollbar = false,
23130
+ virtualizedRows = false,
23131
+ estimatedRowHeight,
23132
+ overscan = 8,
22921
23133
  enableHeaderAutoFit = true,
22922
23134
  labels
22923
23135
  }) {
@@ -22973,6 +23185,7 @@ function DataTable({
22973
23185
  console.warn("[DataTable] `rowKey` should be provided when using sort/filter/pagination to keep row identity stable.");
22974
23186
  }, [columns, isServerMode, pageSizeOptions, rowKey]);
22975
23187
  const densityRowClass = density === "compact" ? "h-9" : density === "comfortable" ? "h-14" : "h-12";
23188
+ const defaultEstimatedRowHeight = density === "compact" ? 36 : density === "comfortable" ? 56 : 48;
22976
23189
  const cellPadding = density === "compact" ? "py-1.5 px-3" : density === "comfortable" ? "py-3 px-4" : "py-2.5 px-4";
22977
23190
  const headerTitleClass = size === "sm" ? "text-xs" : size === "lg" ? "text-[15px]" : "text-sm";
22978
23191
  const headerMinHeightClass = size === "sm" ? "min-h-9" : size === "lg" ? "min-h-11" : "min-h-10";
@@ -23000,8 +23213,24 @@ function DataTable({
23000
23213
  };
23001
23214
  const viewportRef = import_react38.default.useRef(null);
23002
23215
  const tableRef = import_react38.default.useRef(null);
23216
+ const canVirtualizeRows = virtualizedRows && !loading2 && displayedData.length > 0;
23217
+ const shouldUseScrollViewport = stickyHeader || canVirtualizeRows;
23218
+ const rowVirtualizer = (0, import_react_virtual4.useVirtualizer)({
23219
+ count: canVirtualizeRows ? displayedData.length : 0,
23220
+ getScrollElement: () => viewportRef.current,
23221
+ estimateSize: () => estimatedRowHeight ?? defaultEstimatedRowHeight,
23222
+ initialRect: {
23223
+ width: 0,
23224
+ height: typeof maxHeight === "number" ? maxHeight : 500
23225
+ },
23226
+ overscan,
23227
+ enabled: canVirtualizeRows
23228
+ });
23229
+ const virtualRows = canVirtualizeRows ? rowVirtualizer.getVirtualItems() : [];
23230
+ const virtualPaddingTop = canVirtualizeRows && virtualRows.length > 0 ? virtualRows[0]?.start ?? 0 : 0;
23231
+ const virtualPaddingBottom = canVirtualizeRows && virtualRows.length > 0 ? Math.max(0, rowVirtualizer.getTotalSize() - (virtualRows[virtualRows.length - 1]?.end ?? 0)) : 0;
23003
23232
  useOverlayScrollbarTarget(viewportRef, {
23004
- enabled: useOverlayScrollbar,
23233
+ enabled: useOverlayScrollbar && !canVirtualizeRows,
23005
23234
  overflowX: overlayOverflowX
23006
23235
  });
23007
23236
  const autoFitColumn = import_react38.default.useCallback((columnKey) => {
@@ -23065,8 +23294,9 @@ function DataTable({
23065
23294
  "div",
23066
23295
  {
23067
23296
  ref: viewportRef,
23068
- className: cn("w-full", viewportOverflowXClass, stickyHeader && "overflow-y-auto"),
23069
- style: stickyHeader ? { maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight } : void 0,
23297
+ "data-os-ignore": canVirtualizeRows ? "" : void 0,
23298
+ className: cn("w-full", viewportOverflowXClass, shouldUseScrollViewport && "overflow-y-auto"),
23299
+ style: shouldUseScrollViewport ? { maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight } : void 0,
23070
23300
  children: /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(
23071
23301
  Table,
23072
23302
  {
@@ -23116,7 +23346,11 @@ function DataTable({
23116
23346
  getStickyColumnStyle,
23117
23347
  getStickyCellClass,
23118
23348
  t,
23119
- labels
23349
+ labels,
23350
+ virtualRows: canVirtualizeRows ? virtualRows : void 0,
23351
+ virtualPaddingTop: canVirtualizeRows ? virtualPaddingTop : void 0,
23352
+ virtualPaddingBottom: canVirtualizeRows ? virtualPaddingBottom : void 0,
23353
+ measureVirtualRow: canVirtualizeRows ? rowVirtualizer.measureElement : void 0
23120
23354
  }
23121
23355
  )
23122
23356
  ]
@@ -27054,7 +27288,7 @@ function findDiffEnd(a, b, posA, posB) {
27054
27288
  posB -= size;
27055
27289
  }
27056
27290
  }
27057
- var Fragment26 = class _Fragment {
27291
+ var Fragment27 = class _Fragment {
27058
27292
  /**
27059
27293
  @internal
27060
27294
  */
@@ -27346,7 +27580,7 @@ var Fragment26 = class _Fragment {
27346
27580
  throw new RangeError("Can not convert " + nodes + " to a Fragment" + (nodes.nodesBetween ? " (looks like multiple versions of prosemirror-model were loaded)" : ""));
27347
27581
  }
27348
27582
  };
27349
- Fragment26.empty = new Fragment26([], 0);
27583
+ Fragment27.empty = new Fragment27([], 0);
27350
27584
  var found = { index: 0, offset: 0 };
27351
27585
  function retIndex(index, offset) {
27352
27586
  found.index = index;
@@ -27571,7 +27805,7 @@ var Slice = class _Slice {
27571
27805
  let openStart = json.openStart || 0, openEnd = json.openEnd || 0;
27572
27806
  if (typeof openStart != "number" || typeof openEnd != "number")
27573
27807
  throw new RangeError("Invalid input for Slice.fromJSON");
27574
- return new _Slice(Fragment26.fromJSON(schema, json.content), openStart, openEnd);
27808
+ return new _Slice(Fragment27.fromJSON(schema, json.content), openStart, openEnd);
27575
27809
  }
27576
27810
  /**
27577
27811
  Create a slice from a fragment by taking the maximum possible
@@ -27586,7 +27820,7 @@ var Slice = class _Slice {
27586
27820
  return new _Slice(fragment, openStart, openEnd);
27587
27821
  }
27588
27822
  };
27589
- Slice.empty = new Slice(Fragment26.empty, 0, 0);
27823
+ Slice.empty = new Slice(Fragment27.empty, 0, 0);
27590
27824
  function removeRange(content, from, to) {
27591
27825
  let { index, offset } = content.findIndex(from), child = content.maybeChild(index);
27592
27826
  let { index: indexTo, offset: offsetTo } = content.findIndex(to);
@@ -27684,7 +27918,7 @@ function replaceThreeWay($from, $start, $end, $to, depth) {
27684
27918
  addNode(close(openEnd, replaceTwoWay($end, $to, depth + 1)), content);
27685
27919
  }
27686
27920
  addRange($to, null, depth, content);
27687
- return new Fragment26(content);
27921
+ return new Fragment27(content);
27688
27922
  }
27689
27923
  function replaceTwoWay($from, $to, depth) {
27690
27924
  let content = [];
@@ -27694,13 +27928,13 @@ function replaceTwoWay($from, $to, depth) {
27694
27928
  addNode(close(type, replaceTwoWay($from, $to, depth + 1)), content);
27695
27929
  }
27696
27930
  addRange($to, null, depth, content);
27697
- return new Fragment26(content);
27931
+ return new Fragment27(content);
27698
27932
  }
27699
27933
  function prepareSliceForReplace(slice, $along) {
27700
27934
  let extra = $along.depth - slice.openStart, parent = $along.node(extra);
27701
27935
  let node = parent.copy(slice.content);
27702
27936
  for (let i = extra - 1; i >= 0; i--)
27703
- node = $along.node(i).copy(Fragment26.from(node));
27937
+ node = $along.node(i).copy(Fragment27.from(node));
27704
27938
  return {
27705
27939
  start: node.resolveNoCache(slice.openStart + extra),
27706
27940
  end: node.resolveNoCache(node.content.size - slice.openEnd - extra)
@@ -28039,7 +28273,7 @@ var Node2 = class _Node {
28039
28273
  this.type = type;
28040
28274
  this.attrs = attrs;
28041
28275
  this.marks = marks;
28042
- this.content = content || Fragment26.empty;
28276
+ this.content = content || Fragment27.empty;
28043
28277
  }
28044
28278
  /**
28045
28279
  The array of this node's child nodes.
@@ -28344,7 +28578,7 @@ var Node2 = class _Node {
28344
28578
  can optionally pass `start` and `end` indices into the
28345
28579
  replacement fragment.
28346
28580
  */
28347
- canReplace(from, to, replacement = Fragment26.empty, start = 0, end = replacement.childCount) {
28581
+ canReplace(from, to, replacement = Fragment27.empty, start = 0, end = replacement.childCount) {
28348
28582
  let one = this.contentMatchAt(from).matchFragment(replacement, start, end);
28349
28583
  let two = one && one.matchFragment(this.content, to);
28350
28584
  if (!two || !two.validEnd)
@@ -28426,7 +28660,7 @@ var Node2 = class _Node {
28426
28660
  throw new RangeError("Invalid text node in JSON");
28427
28661
  return schema.text(json.text, marks);
28428
28662
  }
28429
- let content = Fragment26.fromJSON(schema, json.content);
28663
+ let content = Fragment27.fromJSON(schema, json.content);
28430
28664
  let node = schema.nodeType(json.type).create(json.attrs, content, marks);
28431
28665
  node.type.checkAttrs(node.attrs);
28432
28666
  return node;
@@ -28522,7 +28756,7 @@ var ContentMatch = class _ContentMatch {
28522
28756
  function search(match, types) {
28523
28757
  let finished = match.matchFragment(after, startIndex);
28524
28758
  if (finished && (!toEnd || finished.validEnd))
28525
- return Fragment26.from(types.map((tp) => tp.createAndFill()));
28759
+ return Fragment27.from(types.map((tp) => tp.createAndFill()));
28526
28760
  for (let i = 0; i < match.next.length; i++) {
28527
28761
  let { type, next } = match.next[i];
28528
28762
  if (!(type.isText || type.hasRequiredAttrs()) && seen.indexOf(next) == -1) {
@@ -29090,7 +29324,7 @@ function mapFragment(fragment, f, parent) {
29090
29324
  child = f(child, parent, i);
29091
29325
  mapped.push(child);
29092
29326
  }
29093
- return Fragment26.fromArray(mapped);
29327
+ return Fragment27.fromArray(mapped);
29094
29328
  }
29095
29329
  var AddMarkStep = class _AddMarkStep extends Step {
29096
29330
  /**
@@ -29207,7 +29441,7 @@ var AddNodeMarkStep = class _AddNodeMarkStep extends Step {
29207
29441
  if (!node)
29208
29442
  return StepResult.fail("No node at mark step's position");
29209
29443
  let updated = node.type.create(node.attrs, null, this.mark.addToSet(node.marks));
29210
- return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment26.from(updated), 0, node.isLeaf ? 0 : 1));
29444
+ return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment27.from(updated), 0, node.isLeaf ? 0 : 1));
29211
29445
  }
29212
29446
  invert(doc) {
29213
29447
  let node = doc.nodeAt(this.pos);
@@ -29253,7 +29487,7 @@ var RemoveNodeMarkStep = class _RemoveNodeMarkStep extends Step {
29253
29487
  if (!node)
29254
29488
  return StepResult.fail("No node at mark step's position");
29255
29489
  let updated = node.type.create(node.attrs, null, this.mark.removeFromSet(node.marks));
29256
- return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment26.from(updated), 0, node.isLeaf ? 0 : 1));
29490
+ return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment27.from(updated), 0, node.isLeaf ? 0 : 1));
29257
29491
  }
29258
29492
  invert(doc) {
29259
29493
  let node = doc.nodeAt(this.pos);
@@ -29454,7 +29688,7 @@ var AttrStep = class _AttrStep extends Step {
29454
29688
  attrs[name] = node.attrs[name];
29455
29689
  attrs[this.attr] = this.value;
29456
29690
  let updated = node.type.create(attrs, null, node.marks);
29457
- return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment26.from(updated), 0, node.isLeaf ? 0 : 1));
29691
+ return StepResult.fromReplace(doc, this.pos, this.pos + 1, new Slice(Fragment27.from(updated), 0, node.isLeaf ? 0 : 1));
29458
29692
  }
29459
29693
  getMap() {
29460
29694
  return StepMap.empty;
@@ -29838,7 +30072,7 @@ var NodeSelection2 = class _NodeSelection extends Selection {
29838
30072
  return new _NodeSelection($pos);
29839
30073
  }
29840
30074
  content() {
29841
- return new Slice(Fragment26.from(this.node), 0, 0);
30075
+ return new Slice(Fragment27.from(this.node), 0, 0);
29842
30076
  }
29843
30077
  eq(other) {
29844
30078
  return other instanceof _NodeSelection && other.anchor == this.anchor;
@@ -30566,10 +30800,10 @@ var CellSelection = class CellSelection2 extends Selection {
30566
30800
  }
30567
30801
  rowContent.push(cell);
30568
30802
  }
30569
- rows.push(table.child(row).copy(Fragment26.from(rowContent)));
30803
+ rows.push(table.child(row).copy(Fragment27.from(rowContent)));
30570
30804
  }
30571
30805
  const fragment = this.isColSelection() && this.isRowSelection() ? table : rows;
30572
- return new Slice(Fragment26.from(fragment), 1, 1);
30806
+ return new Slice(Fragment27.from(fragment), 1, 1);
30573
30807
  }
30574
30808
  replace(tr, content = Slice.empty) {
30575
30809
  const mapFrom = tr.steps.length, ranges = this.ranges;
@@ -30581,7 +30815,7 @@ var CellSelection = class CellSelection2 extends Selection {
30581
30815
  if (sel) tr.setSelection(sel);
30582
30816
  }
30583
30817
  replaceWith(tr, node) {
30584
- this.replace(tr, new Slice(Fragment26.from(node), 0, 0));
30818
+ this.replace(tr, new Slice(Fragment27.from(node), 0, 0));
30585
30819
  }
30586
30820
  forEachCell(f) {
30587
30821
  const table = this.$anchorCell.node(-1);