@ahrowe/ui 0.4.4 → 0.5.1

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.
Files changed (33) hide show
  1. package/dist/esm/common/checkbox/checkbox.mjs +1 -1
  2. package/dist/esm/common/checkbox/checkbox.mjs.map +1 -1
  3. package/dist/esm/common/confirmModal/confirmModal.mjs +1 -1
  4. package/dist/esm/common/confirmModal/confirmModal.mjs.map +1 -1
  5. package/dist/esm/common/dropdown/dropdown.mjs +1 -1
  6. package/dist/esm/common/dropdown/dropdown.mjs.map +1 -1
  7. package/dist/esm/common/dropdown/dropdown.module.mjs.map +1 -1
  8. package/dist/esm/common/input/input.mjs +1 -1
  9. package/dist/esm/common/input/input.mjs.map +1 -1
  10. package/dist/esm/common/input/input.module.mjs +1 -1
  11. package/dist/esm/common/input/input.module.mjs.map +1 -1
  12. package/dist/esm/common/themeProvider/defaultTheme.mjs +1 -1
  13. package/dist/esm/common/themeProvider/defaultTheme.mjs.map +1 -1
  14. package/dist/esm/common/virtualList/useColumns.mjs +1 -1
  15. package/dist/esm/common/virtualList/useColumns.mjs.map +1 -1
  16. package/dist/esm/common/virtualList/virtualList.mjs +1 -1
  17. package/dist/esm/common/virtualList/virtualList.mjs.map +1 -1
  18. package/dist/esm/common/virtualList/virtualList.module.mjs.map +1 -1
  19. package/dist/esm/common/virtualList/virtualList.utils.mjs +1 -1
  20. package/dist/esm/common/virtualList/virtualList.utils.mjs.map +1 -1
  21. package/dist/index.cjs +2 -2
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/style.css +1 -1
  24. package/dist/types/package/common/configProvider/configProvider.types.d.ts +2 -0
  25. package/dist/types/package/common/confirmModal/confirmModal.d.ts +1 -1
  26. package/dist/types/package/common/confirmModal/confirmModal.types.d.ts +3 -0
  27. package/dist/types/package/common/themeProvider/theme.types.d.ts +1 -0
  28. package/dist/types/package/common/virtualList/useColumns.d.ts +0 -1
  29. package/dist/types/package/common/virtualList/virtualList.types.d.ts +21 -0
  30. package/docs/ConfigProvider.md +1 -0
  31. package/docs/ConfirmModal.md +25 -0
  32. package/docs/VirtualList.md +30 -0
  33. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- import e from"../loading/spinnerLoading/index.mjs";import t from"../checkbox/checkbox.mjs";import n from"./virtualList.module.mjs";import ee from"./virtualRow.mjs";import"./virtualList.utils.mjs";import{useVirtualWindow as r}from"./useVirtualWindow.mjs";import{useSelection as i}from"./useSelection.mjs";import{useColumns as a}from"./useColumns.mjs";import{useRowDrag as o}from"./useRowDrag.mjs";import s,{useCallback as c,useImperativeHandle as te,useMemo as l}from"react";import u from"classnames";import{FontAwesomeIcon as ne}from"@fortawesome/react-fontawesome";import{faGear as re}from"@fortawesome/free-solid-svg-icons";import{Fragment as ie,jsx as d,jsxs as f}from"react/jsx-runtime";function p({items:s,renderRow:p,columns:m,height:h=`100%`,estimatedRowHeight:g=40,overscan:_=3,rowGap:ae=0,rowPadding:v,selectedKey:y,getItemKey:b,onRowClick:oe,visibleColumnKeys:se,onVisibleColumnsChange:ce,persistColumnsKey:le,showColumnToggle:ue,onLoadMore:de,loadMoreThreshold:fe=100,isLoading:pe=!1,multiSelect:x=!1,selectedKeys:me,onSelectionChange:he,reorderable:ge=!1,onReorder:_e,longPressDelay:ve=400,treeReorder:ye=!1,getItemDepth:S,isGroup:C,onTreeDrop:w,treeIndentPx:T=24,dragHandle:E=!1,showDivider:D=!0,rowHover:O=!0,className:k,style:A,classNames:j,styles:M,...N},P){let F=c((e,t)=>b?b(e,t):t,[b]),I=l(()=>s.map((e,t)=>F(e,t)),[s,F]),be=l(()=>S?s.map((e,t)=>S(e,t)):[],[s,S]),xe=c(e=>C?C(s[e],e):!1,[C,s]),L=r({items:s,keys:I,getItemKey:b,estimatedRowHeight:g,rowGap:ae,overscan:_,onLoadMore:de,loadMoreThreshold:fe}),{rootRef:R,headerRef:Se,rowObserver:Ce,keysRef:we,offsets:Te,totalHeight:Ee,startIndex:z,endIndex:B}=L,V=i({items:s,getKey:F,multiSelect:x,selectedKeys:me,onSelectionChange:he}),{effectiveSelectedKeys:H}=V,{hasColumns:U,visibleColumns:W,columnTemplate:G,shouldShowToggle:K,effectiveVisible:De,manuallyHiddenCount:q,toggleOpen:Oe,setToggleOpen:J,toggleRef:ke,handleToggleColumn:Ae,recalculateColumns:Y}=a({columns:m,items:s,multiSelect:x,visibleColumnKeys:se,onVisibleColumnsChange:ce,persistColumnsKey:le,showColumnToggle:ue,rootRef:R,startIndex:z,endIndex:B,containerHeight:L.containerHeight,containerWidth:L.containerWidth});te(P,()=>({...L.scrollApi,recalculateColumns:Y}),[L.scrollApi,Y]);let X=o({reorderable:ge,treeReorder:ye,onReorder:_e,onTreeDrop:w,longPressDelay:ve,dragHandle:E,treeIndentPx:T,keys:I,depths:be,isGroupAt:xe,rootRef:R,keysRef:we}),je=typeof v==`number`?`${v}px`:v,Z=e=>{let r=s[e],i=F(r,e),a=y!=null&&i===y||H.has(i),o=X.getRowDragProps(e,i);return d(ee,{index:e,top:Te[e],padding:je,columnTemplate:G,isSelected:a,showDivider:D,hover:O,onClick:()=>{X.consumeSuppressedClick()||oe?.(r,e)},observer:Ce,ariaRowIndex:U?e+2:void 0,ariaPosInSet:U?void 0:e+1,ariaSetSize:U?void 0:s.length,rowRole:U?`row`:`listitem`,reserveToggleGutter:K,...o,dropIndicatorClassName:j?.dropIndicator,dropIndicatorStyle:M?.dropIndicator,rowClassName:j?.row,rowStyle:M?.row,children:U?f(ie,{children:[x&&d(`div`,{className:u(n.virtualListSelectCell,j?.selectCell),style:M?.selectCell,role:`gridcell`,onClick:e=>e.stopPropagation(),children:d(t,{selected:H.has(i),onToggle:()=>V.handleRowSelect(i),"aria-label":`Select row`})}),W.map(t=>d(`div`,{className:u(n.virtualListCell,j?.cell),style:M?.cell,role:`gridcell`,"data-fit-key":t.width.type===`fit`?t.key:void 0,children:t.renderCell(r,e)},t.key))]}):p?.(r,e)},i)},Q=[];for(let e=z;e<=B;e++)Q.push(Z(e));let $=X.draggingKey==null?-1:I.indexOf(X.draggingKey);return $>=0&&($<z||$>B)&&Q.push(Z($)),f(`div`,{...N,ref:R,className:u(n.virtualList,X.draggingKey!=null&&n.virtualListReordering,k,j?.root),style:{height:h,...A,...M?.root},onScroll:L.handleScroll,role:U?`grid`:`list`,"aria-rowcount":U?s.length+1:void 0,children:[U&&f(`div`,{ref:Se,className:u(n.virtualListHeader,j?.header),style:{gridTemplateColumns:G,...K?{paddingRight:32}:{},...M?.header},role:`row`,"aria-rowindex":1,children:[x&&d(`div`,{className:u(n.virtualListSelectCell,j?.selectCell),style:M?.selectCell,role:`columnheader`,children:d(t,{selected:V.allSelected||V.someSelected,onToggle:V.handleSelectAll,"aria-label":`Select all rows`})}),W.map(e=>d(`div`,{className:u(n.virtualListHeaderCell,j?.headerCell),style:M?.headerCell,role:`columnheader`,"data-fit-key":e.width.type===`fit`?e.key:void 0,children:e.label},e.key)),K&&f(`div`,{ref:ke,className:n.virtualListToggleWrapper,children:[d(`button`,{type:`button`,className:u(n.virtualListHeaderToggle,j?.headerToggle),style:M?.headerToggle,onClick:()=>J(e=>!e),"aria-label":`Toggle column visibility`,children:d(ne,{icon:re,style:M?.headerToggle})}),q>0&&d(`span`,{className:u(n.virtualListColumnChip,j?.columnChip),style:M?.columnChip,"data-column-hidden-count":q,"aria-label":`${q} columns hidden`,children:q}),Oe&&d(`div`,{className:u(n.virtualListTogglePopover,j?.togglePopover),style:M?.togglePopover,children:m.map(e=>d(t,{className:u(n.virtualListToggleItem,j?.toggleItem),style:M?.toggleItem,selected:De.has(e.key),onToggle:()=>Ae(e.key),cursorDefault:!1,children:e.label},e.key))})]})]}),pe?d(`div`,{className:n.virtualListLoadingFull,children:d(e,{className:n.virtualListSpinner})}):d(`div`,{className:u(n.virtualListBody,j?.body),style:{height:Ee,...M?.body},children:Q}),L.showLoadMoreSpinner&&d(`div`,{className:u(n.virtualListLoadingIndicator,j?.loadingIndicator),style:M?.loadingIndicator,children:d(e,{className:n.virtualListSpinner})})]})}var m=s.forwardRef(p);export{m as default};
1
+ import e from"../loading/spinnerLoading/index.mjs";import t from"../checkbox/checkbox.mjs";import{Align as n}from"../floatingMenu/floatingMenu.types.mjs";import r from"../floatingMenu/floatingMenu.mjs";import i from"./virtualList.module.mjs";import ee from"./virtualRow.mjs";import"./virtualList.utils.mjs";import{useVirtualWindow as a}from"./useVirtualWindow.mjs";import{useSelection as o}from"./useSelection.mjs";import{useColumns as s}from"./useColumns.mjs";import{useRowDrag as c}from"./useRowDrag.mjs";import l,{useCallback as u,useImperativeHandle as te,useMemo as d}from"react";import f from"classnames";import{FontAwesomeIcon as ne}from"@fortawesome/react-fontawesome";import{faGear as re}from"@fortawesome/free-solid-svg-icons";import{Fragment as p,jsx as m,jsxs as h}from"react/jsx-runtime";function g({items:l,renderRow:g,columns:_,height:ie=`100%`,estimatedRowHeight:ae=40,overscan:oe=3,rowGap:v=0,rowPadding:y,selectedKey:b,getItemKey:x,onRowClick:se,visibleColumnKeys:ce,onVisibleColumnsChange:le,persistColumnsKey:ue,showColumnToggle:de,onLoadMore:fe,loadMoreThreshold:pe=100,isLoading:me=!1,multiSelect:S=!1,selectedKeys:he,onSelectionChange:ge,reorderable:_e=!1,onReorder:ve,longPressDelay:ye=400,treeReorder:C=!1,getItemDepth:w,isGroup:T,onTreeDrop:E,treeIndentPx:D=24,dragHandle:O=!1,showDivider:k=!0,rowHover:A=!0,className:j,style:M,classNames:N,styles:P,...F},be){let I=u((e,t)=>x?x(e,t):t,[x]),L=d(()=>l.map((e,t)=>I(e,t)),[l,I]),xe=d(()=>w?l.map((e,t)=>w(e,t)):[],[l,w]),Se=u(e=>T?T(l[e],e):!1,[T,l]),R=a({items:l,keys:L,getItemKey:x,estimatedRowHeight:ae,rowGap:v,overscan:oe,onLoadMore:fe,loadMoreThreshold:pe}),{rootRef:z,headerRef:Ce,rowObserver:we,keysRef:Te,offsets:Ee,totalHeight:De,startIndex:B,endIndex:V}=R,H=o({items:l,getKey:I,multiSelect:S,selectedKeys:he,onSelectionChange:ge}),{effectiveSelectedKeys:U}=H,{hasColumns:W,visibleColumns:G,columnTemplate:K,shouldShowToggle:q,effectiveVisible:Oe,manuallyHiddenCount:J,toggleOpen:ke,setToggleOpen:Ae,handleToggleColumn:je,recalculateColumns:Y}=s({columns:_,items:l,multiSelect:S,visibleColumnKeys:ce,onVisibleColumnsChange:le,persistColumnsKey:ue,showColumnToggle:de,rootRef:z,startIndex:B,endIndex:V,containerHeight:R.containerHeight,containerWidth:R.containerWidth});te(be,()=>({...R.scrollApi,recalculateColumns:Y}),[R.scrollApi,Y]);let X=c({reorderable:_e,treeReorder:C,onReorder:ve,onTreeDrop:E,longPressDelay:ye,dragHandle:O,treeIndentPx:D,keys:L,depths:xe,isGroupAt:Se,rootRef:z,keysRef:Te}),Me=typeof y==`number`?`${y}px`:y,Z=e=>{let n=l[e],r=I(n,e),a=b!=null&&r===b||U.has(r),o=X.getRowDragProps(e,r);return m(ee,{index:e,top:Ee[e],padding:Me,columnTemplate:K,isSelected:a,showDivider:k,hover:A,onClick:()=>{X.consumeSuppressedClick()||se?.(n,e)},observer:we,ariaRowIndex:W?e+2:void 0,ariaPosInSet:W?void 0:e+1,ariaSetSize:W?void 0:l.length,rowRole:W?`row`:`listitem`,reserveToggleGutter:q,...o,dropIndicatorClassName:N?.dropIndicator,dropIndicatorStyle:P?.dropIndicator,rowClassName:N?.row,rowStyle:P?.row,children:W?h(p,{children:[S&&m(`div`,{className:f(i.virtualListSelectCell,N?.selectCell),style:P?.selectCell,role:`gridcell`,onClick:e=>e.stopPropagation(),children:m(t,{selected:U.has(r),onToggle:()=>H.handleRowSelect(r),"aria-label":`Select row`})}),G.map(t=>m(`div`,{className:f(i.virtualListCell,N?.cell),style:P?.cell,role:`gridcell`,"data-fit-key":t.width.type===`fit`?t.key:void 0,children:t.renderCell(n,e)},t.key))]}):g?.(n,e)},r)},Q=[];for(let e=B;e<=V;e++)Q.push(Z(e));let $=X.draggingKey==null?-1:L.indexOf(X.draggingKey);return $>=0&&($<B||$>V)&&Q.push(Z($)),h(`div`,{...F,ref:z,className:f(i.virtualList,X.draggingKey!=null&&i.virtualListReordering,j,N?.root),style:{height:ie,...M,...P?.root},onScroll:R.handleScroll,role:W?`grid`:`list`,"aria-rowcount":W?l.length+1:void 0,children:[W&&h(`div`,{ref:Ce,className:f(i.virtualListHeader,N?.header),style:{gridTemplateColumns:K,...q?{paddingRight:32}:{},...P?.header},role:`row`,"aria-rowindex":1,children:[S&&m(`div`,{className:f(i.virtualListSelectCell,N?.selectCell),style:P?.selectCell,role:`columnheader`,children:m(t,{selected:H.allSelected||H.someSelected,onToggle:H.handleSelectAll,"aria-label":`Select all rows`})}),G.map(e=>m(`div`,{className:f(i.virtualListHeaderCell,N?.headerCell),style:P?.headerCell,role:`columnheader`,"data-fit-key":e.width.type===`fit`?e.key:void 0,children:e.label},e.key)),q&&h(`div`,{className:i.virtualListToggleWrapper,children:[m(r,{isOpen:ke,onOpenChange:Ae,align:n.Right,content:m(`div`,{className:f(i.virtualListTogglePopover,N?.togglePopover),style:P?.togglePopover,children:_.filter(e=>!e.hideFromToggle).map(e=>m(t,{className:f(i.virtualListToggleItem,N?.toggleItem),style:P?.toggleItem,selected:Oe.has(e.key),onToggle:()=>je(e.key),disabled:e.lockVisible,cursorDefault:!1,children:e.toggleLabel??e.label},e.key))}),children:m(`button`,{type:`button`,className:f(i.virtualListHeaderToggle,N?.headerToggle),style:P?.headerToggle,"aria-label":`Toggle column visibility`,children:m(ne,{icon:re,style:P?.headerToggle})})}),J>0&&m(`span`,{className:f(i.virtualListColumnChip,N?.columnChip),style:P?.columnChip,"data-column-hidden-count":J,"aria-label":`${J} columns hidden`,children:J})]})]}),me?m(`div`,{className:i.virtualListLoadingFull,children:m(e,{className:i.virtualListSpinner})}):m(`div`,{className:f(i.virtualListBody,N?.body),style:{height:De,...P?.body},children:Q}),R.showLoadMoreSpinner&&m(`div`,{className:f(i.virtualListLoadingIndicator,N?.loadingIndicator),style:P?.loadingIndicator,children:m(e,{className:i.virtualListSpinner})})]})}var _=l.forwardRef(g);export{_ as default};
2
2
  //# sourceMappingURL=virtualList.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"virtualList.mjs","names":[],"sources":["../../../../package/common/virtualList/virtualList.tsx"],"sourcesContent":["import React, { useMemo, useCallback, useImperativeHandle } from 'react';\nimport cx from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faGear } from '@fortawesome/free-solid-svg-icons';\n\nimport styles from './virtualList.module.pcss';\nimport SpinnerLoading from '../loading/spinnerLoading';\nimport Checkbox from '../checkbox';\nimport VirtualRow from './virtualRow';\nimport { useVirtualWindow } from './useVirtualWindow';\nimport { useSelection } from './useSelection';\nimport { useColumns } from './useColumns';\nimport { useRowDrag } from './useRowDrag';\nimport type { VirtualListProps, VirtualListHandle } from './virtualList.types';\n\n// Pure helpers live in ./virtualList.utils; re-exported here so existing\n// imports (and unit tests) keep working against the component entry point.\nexport {\n buildOffsets,\n findStartIndex,\n getVisibleRange,\n resolveReorderTarget,\n resolveTreeDropTarget,\n lastDescendantIndex,\n buildColumnTemplate,\n} from './virtualList.utils';\n\n// ─── Orchestrator ─────────────────────────────────────────────────────────────\n// VirtualListInner wires four focused hooks together and renders. Each concern\n// lives in its own module:\n// useVirtualWindow — generic scroll / measurement / windowing (all modes)\n// useSelection — multi-row selection\n// useColumns — table mode: columns, visibility, persistence, fit widths\n// useRowDrag — reorder + tree drag-and-drop (mouse + touch)\n\nfunction VirtualListInner<T>({\n items,\n renderRow,\n columns,\n height = '100%',\n estimatedRowHeight = 40,\n overscan = 3,\n rowGap = 0,\n rowPadding,\n selectedKey,\n getItemKey,\n onRowClick,\n visibleColumnKeys,\n onVisibleColumnsChange,\n persistColumnsKey,\n showColumnToggle,\n onLoadMore,\n loadMoreThreshold = 100,\n isLoading = false,\n multiSelect = false,\n selectedKeys,\n onSelectionChange,\n reorderable = false,\n onReorder,\n longPressDelay = 400,\n treeReorder = false,\n getItemDepth,\n isGroup,\n onTreeDrop,\n treeIndentPx = 24,\n dragHandle = false,\n showDivider = true,\n rowHover = true,\n className,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n}: VirtualListProps<T>, ref: React.ForwardedRef<VirtualListHandle>) {\n const getKey = useCallback(\n (item: T, index: number): string | number => (getItemKey ? getItemKey(item, index) : index),\n [getItemKey],\n );\n const keys = useMemo(() => items.map((item, i) => getKey(item, i)), [items, getKey]);\n const depths = useMemo(\n () => (getItemDepth ? items.map((item, i) => getItemDepth(item, i)) : []),\n [items, getItemDepth],\n );\n const isGroupAt = useCallback(\n (i: number) => (isGroup ? isGroup(items[i], i) : false),\n [isGroup, items],\n );\n\n const win = useVirtualWindow<T>({\n items, keys, getItemKey, estimatedRowHeight, rowGap, overscan,\n onLoadMore, loadMoreThreshold,\n });\n const { rootRef, headerRef, rowObserver, keysRef, offsets, totalHeight, startIndex, endIndex } = win;\n\n const selection = useSelection<T>({ items, getKey, multiSelect, selectedKeys, onSelectionChange });\n const { effectiveSelectedKeys } = selection;\n\n const cols = useColumns<T>({\n columns, items, multiSelect, visibleColumnKeys, onVisibleColumnsChange, persistColumnsKey,\n showColumnToggle, rootRef, startIndex, endIndex,\n containerHeight: win.containerHeight, containerWidth: win.containerWidth,\n });\n const {\n hasColumns, visibleColumns, columnTemplate, shouldShowToggle, effectiveVisible, manuallyHiddenCount,\n toggleOpen, setToggleOpen, toggleRef, handleToggleColumn, recalculateColumns,\n } = cols;\n\n // Compose the forwarded handle from both hooks: scroll methods come from the\n // windowing engine, column controls from the column hook.\n useImperativeHandle(\n ref,\n () => ({ ...win.scrollApi, recalculateColumns }),\n [win.scrollApi, recalculateColumns],\n );\n\n const drag = useRowDrag({\n reorderable, treeReorder, onReorder, onTreeDrop, longPressDelay, dragHandle, treeIndentPx,\n keys, depths, isGroupAt, rootRef, keysRef,\n });\n\n const rowPaddingValue = typeof rowPadding === 'number' ? `${rowPadding}px` : rowPadding;\n\n const renderRowAt = (i: number) => {\n const item = items[i];\n const key = getKey(item, i);\n const isSelected = (selectedKey != null && key === selectedKey) || effectiveSelectedKeys.has(key);\n const dragProps = drag.getRowDragProps(i, key);\n\n return (\n <VirtualRow\n key={key}\n index={i}\n top={offsets[i]}\n padding={rowPaddingValue}\n columnTemplate={columnTemplate}\n isSelected={isSelected}\n showDivider={showDivider}\n hover={rowHover}\n onClick={() => {\n if (drag.consumeSuppressedClick()) return;\n onRowClick?.(item, i);\n }}\n observer={rowObserver}\n ariaRowIndex={hasColumns ? i + 2 : undefined}\n ariaPosInSet={hasColumns ? undefined : i + 1}\n ariaSetSize={hasColumns ? undefined : items.length}\n rowRole={hasColumns ? 'row' : 'listitem'}\n reserveToggleGutter={shouldShowToggle}\n {...dragProps}\n dropIndicatorClassName={classNames?.dropIndicator}\n dropIndicatorStyle={slotStyles?.dropIndicator}\n rowClassName={classNames?.row}\n rowStyle={slotStyles?.row}\n >\n {hasColumns\n ? <>\n {multiSelect && (\n <div\n className={cx(styles.virtualListSelectCell, classNames?.selectCell)}\n style={slotStyles?.selectCell}\n role=\"gridcell\"\n onClick={(e) => e.stopPropagation()}\n >\n <Checkbox\n selected={effectiveSelectedKeys.has(key)}\n onToggle={() => selection.handleRowSelect(key)}\n aria-label=\"Select row\"\n />\n </div>\n )}\n {visibleColumns.map((col) => (\n <div\n key={col.key}\n className={cx(styles.virtualListCell, classNames?.cell)}\n style={slotStyles?.cell}\n role=\"gridcell\"\n data-fit-key={col.width.type === 'fit' ? col.key : undefined}\n >\n {col.renderCell(item, i)}\n </div>\n ))}\n </>\n : renderRow?.(item, i)}\n </VirtualRow>\n );\n };\n\n const visibleRows: React.ReactNode[] = [];\n for (let i = startIndex; i <= endIndex; i++) visibleRows.push(renderRowAt(i));\n\n // Keep the row being touch-dragged mounted even if it scrolls out of the\n // window. Touch events are dispatched to the element under the finger at\n // touchstart; if that row unmounts, the browser stops delivering touchmove\n // and the drag freezes. Pinning its DOM node keeps the gesture alive.\n const draggedIndex = drag.draggingKey != null ? keys.indexOf(drag.draggingKey) : -1;\n if (draggedIndex >= 0 && (draggedIndex < startIndex || draggedIndex > endIndex)) {\n visibleRows.push(renderRowAt(draggedIndex));\n }\n\n return (\n <div\n {...rest}\n ref={rootRef}\n className={cx(styles.virtualList, drag.draggingKey != null && styles.virtualListReordering, className, classNames?.root)}\n style={{ height, ...style, ...slotStyles?.root }}\n onScroll={win.handleScroll}\n role={hasColumns ? 'grid' : 'list'}\n aria-rowcount={hasColumns ? items.length + 1 : undefined}\n >\n {hasColumns && (\n <div\n ref={headerRef}\n className={cx(styles.virtualListHeader, classNames?.header)}\n style={{ gridTemplateColumns: columnTemplate, ...(shouldShowToggle ? { paddingRight: 32 } : {}), ...slotStyles?.header }}\n role=\"row\"\n aria-rowindex={1}\n >\n {multiSelect && (\n <div\n className={cx(styles.virtualListSelectCell, classNames?.selectCell)}\n style={slotStyles?.selectCell}\n role=\"columnheader\"\n >\n <Checkbox\n selected={selection.allSelected || selection.someSelected}\n onToggle={selection.handleSelectAll}\n aria-label=\"Select all rows\"\n />\n </div>\n )}\n {visibleColumns.map((col) => (\n <div\n key={col.key}\n className={cx(styles.virtualListHeaderCell, classNames?.headerCell)}\n style={slotStyles?.headerCell}\n role=\"columnheader\"\n data-fit-key={col.width.type === 'fit' ? col.key : undefined}\n >\n {col.label}\n </div>\n ))}\n {shouldShowToggle && (\n <div ref={toggleRef} className={styles.virtualListToggleWrapper}>\n <button\n type=\"button\"\n className={cx(styles.virtualListHeaderToggle, classNames?.headerToggle)}\n style={slotStyles?.headerToggle}\n onClick={() => setToggleOpen((v) => !v)}\n aria-label=\"Toggle column visibility\"\n >\n <FontAwesomeIcon\n icon={faGear}\n style={slotStyles?.headerToggle as React.CSSProperties & Record<`--fa-font-${string}`, string>}\n />\n </button>\n {manuallyHiddenCount > 0 && (\n <span\n className={cx(styles.virtualListColumnChip, classNames?.columnChip)}\n style={slotStyles?.columnChip}\n data-column-hidden-count={manuallyHiddenCount}\n aria-label={`${manuallyHiddenCount} columns hidden`}\n >\n {manuallyHiddenCount}\n </span>\n )}\n {toggleOpen && (\n <div\n className={cx(styles.virtualListTogglePopover, classNames?.togglePopover)}\n style={slotStyles?.togglePopover}\n >\n {columns!.map((col) => (\n <Checkbox\n key={col.key}\n className={cx(styles.virtualListToggleItem, classNames?.toggleItem)}\n style={slotStyles?.toggleItem}\n selected={effectiveVisible.has(col.key)}\n onToggle={() => handleToggleColumn(col.key)}\n cursorDefault={false}\n >\n {col.label}\n </Checkbox>\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n )}\n {isLoading ? (\n <div className={styles.virtualListLoadingFull}>\n <SpinnerLoading className={styles.virtualListSpinner} />\n </div>\n ) : (\n <div\n className={cx(styles.virtualListBody, classNames?.body)}\n style={{ height: totalHeight, ...slotStyles?.body }}\n >\n {visibleRows}\n </div>\n )}\n {win.showLoadMoreSpinner && (\n <div\n className={cx(styles.virtualListLoadingIndicator, classNames?.loadingIndicator)}\n style={slotStyles?.loadingIndicator}\n >\n <SpinnerLoading className={styles.virtualListSpinner} />\n </div>\n )}\n </div>\n );\n}\n\n// forwardRef erases the generic, so cast back to a generic-preserving signature.\nconst VirtualList = React.forwardRef(VirtualListInner) as <T>(\n props: VirtualListProps<T> & { ref?: React.Ref<VirtualListHandle> },\n) => React.ReactElement | null;\n\nexport default VirtualList;\n"],"mappings":"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"}
1
+ {"version":3,"file":"virtualList.mjs","names":[],"sources":["../../../../package/common/virtualList/virtualList.tsx"],"sourcesContent":["import React, { useMemo, useCallback, useImperativeHandle } from 'react';\nimport cx from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faGear } from '@fortawesome/free-solid-svg-icons';\n\nimport styles from './virtualList.module.pcss';\nimport SpinnerLoading from '../loading/spinnerLoading';\nimport Checkbox from '../checkbox';\nimport FloatingMenu, { Align } from '../floatingMenu';\nimport VirtualRow from './virtualRow';\nimport { useVirtualWindow } from './useVirtualWindow';\nimport { useSelection } from './useSelection';\nimport { useColumns } from './useColumns';\nimport { useRowDrag } from './useRowDrag';\nimport type { VirtualListProps, VirtualListHandle } from './virtualList.types';\n\n// Pure helpers live in ./virtualList.utils; re-exported here so existing\n// imports (and unit tests) keep working against the component entry point.\nexport {\n buildOffsets,\n findStartIndex,\n getVisibleRange,\n resolveReorderTarget,\n resolveTreeDropTarget,\n lastDescendantIndex,\n buildColumnTemplate,\n} from './virtualList.utils';\n\n// ─── Orchestrator ─────────────────────────────────────────────────────────────\n// VirtualListInner wires four focused hooks together and renders. Each concern\n// lives in its own module:\n// useVirtualWindow — generic scroll / measurement / windowing (all modes)\n// useSelection — multi-row selection\n// useColumns — table mode: columns, visibility, persistence, fit widths\n// useRowDrag — reorder + tree drag-and-drop (mouse + touch)\n\nfunction VirtualListInner<T>({\n items,\n renderRow,\n columns,\n height = '100%',\n estimatedRowHeight = 40,\n overscan = 3,\n rowGap = 0,\n rowPadding,\n selectedKey,\n getItemKey,\n onRowClick,\n visibleColumnKeys,\n onVisibleColumnsChange,\n persistColumnsKey,\n showColumnToggle,\n onLoadMore,\n loadMoreThreshold = 100,\n isLoading = false,\n multiSelect = false,\n selectedKeys,\n onSelectionChange,\n reorderable = false,\n onReorder,\n longPressDelay = 400,\n treeReorder = false,\n getItemDepth,\n isGroup,\n onTreeDrop,\n treeIndentPx = 24,\n dragHandle = false,\n showDivider = true,\n rowHover = true,\n className,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n}: VirtualListProps<T>, ref: React.ForwardedRef<VirtualListHandle>) {\n const getKey = useCallback(\n (item: T, index: number): string | number => (getItemKey ? getItemKey(item, index) : index),\n [getItemKey],\n );\n const keys = useMemo(() => items.map((item, i) => getKey(item, i)), [items, getKey]);\n const depths = useMemo(\n () => (getItemDepth ? items.map((item, i) => getItemDepth(item, i)) : []),\n [items, getItemDepth],\n );\n const isGroupAt = useCallback(\n (i: number) => (isGroup ? isGroup(items[i], i) : false),\n [isGroup, items],\n );\n\n const win = useVirtualWindow<T>({\n items, keys, getItemKey, estimatedRowHeight, rowGap, overscan,\n onLoadMore, loadMoreThreshold,\n });\n const { rootRef, headerRef, rowObserver, keysRef, offsets, totalHeight, startIndex, endIndex } = win;\n\n const selection = useSelection<T>({ items, getKey, multiSelect, selectedKeys, onSelectionChange });\n const { effectiveSelectedKeys } = selection;\n\n const cols = useColumns<T>({\n columns, items, multiSelect, visibleColumnKeys, onVisibleColumnsChange, persistColumnsKey,\n showColumnToggle, rootRef, startIndex, endIndex,\n containerHeight: win.containerHeight, containerWidth: win.containerWidth,\n });\n const {\n hasColumns, visibleColumns, columnTemplate, shouldShowToggle, effectiveVisible, manuallyHiddenCount,\n toggleOpen, setToggleOpen, handleToggleColumn, recalculateColumns,\n } = cols;\n\n // Compose the forwarded handle from both hooks: scroll methods come from the\n // windowing engine, column controls from the column hook.\n useImperativeHandle(\n ref,\n () => ({ ...win.scrollApi, recalculateColumns }),\n [win.scrollApi, recalculateColumns],\n );\n\n const drag = useRowDrag({\n reorderable, treeReorder, onReorder, onTreeDrop, longPressDelay, dragHandle, treeIndentPx,\n keys, depths, isGroupAt, rootRef, keysRef,\n });\n\n const rowPaddingValue = typeof rowPadding === 'number' ? `${rowPadding}px` : rowPadding;\n\n const renderRowAt = (i: number) => {\n const item = items[i];\n const key = getKey(item, i);\n const isSelected = (selectedKey != null && key === selectedKey) || effectiveSelectedKeys.has(key);\n const dragProps = drag.getRowDragProps(i, key);\n\n return (\n <VirtualRow\n key={key}\n index={i}\n top={offsets[i]}\n padding={rowPaddingValue}\n columnTemplate={columnTemplate}\n isSelected={isSelected}\n showDivider={showDivider}\n hover={rowHover}\n onClick={() => {\n if (drag.consumeSuppressedClick()) return;\n onRowClick?.(item, i);\n }}\n observer={rowObserver}\n ariaRowIndex={hasColumns ? i + 2 : undefined}\n ariaPosInSet={hasColumns ? undefined : i + 1}\n ariaSetSize={hasColumns ? undefined : items.length}\n rowRole={hasColumns ? 'row' : 'listitem'}\n reserveToggleGutter={shouldShowToggle}\n {...dragProps}\n dropIndicatorClassName={classNames?.dropIndicator}\n dropIndicatorStyle={slotStyles?.dropIndicator}\n rowClassName={classNames?.row}\n rowStyle={slotStyles?.row}\n >\n {hasColumns\n ? <>\n {multiSelect && (\n <div\n className={cx(styles.virtualListSelectCell, classNames?.selectCell)}\n style={slotStyles?.selectCell}\n role=\"gridcell\"\n onClick={(e) => e.stopPropagation()}\n >\n <Checkbox\n selected={effectiveSelectedKeys.has(key)}\n onToggle={() => selection.handleRowSelect(key)}\n aria-label=\"Select row\"\n />\n </div>\n )}\n {visibleColumns.map((col) => (\n <div\n key={col.key}\n className={cx(styles.virtualListCell, classNames?.cell)}\n style={slotStyles?.cell}\n role=\"gridcell\"\n data-fit-key={col.width.type === 'fit' ? col.key : undefined}\n >\n {col.renderCell(item, i)}\n </div>\n ))}\n </>\n : renderRow?.(item, i)}\n </VirtualRow>\n );\n };\n\n const visibleRows: React.ReactNode[] = [];\n for (let i = startIndex; i <= endIndex; i++) visibleRows.push(renderRowAt(i));\n\n // Keep the row being touch-dragged mounted even if it scrolls out of the\n // window. Touch events are dispatched to the element under the finger at\n // touchstart; if that row unmounts, the browser stops delivering touchmove\n // and the drag freezes. Pinning its DOM node keeps the gesture alive.\n const draggedIndex = drag.draggingKey != null ? keys.indexOf(drag.draggingKey) : -1;\n if (draggedIndex >= 0 && (draggedIndex < startIndex || draggedIndex > endIndex)) {\n visibleRows.push(renderRowAt(draggedIndex));\n }\n\n return (\n <div\n {...rest}\n ref={rootRef}\n className={cx(styles.virtualList, drag.draggingKey != null && styles.virtualListReordering, className, classNames?.root)}\n style={{ height, ...style, ...slotStyles?.root }}\n onScroll={win.handleScroll}\n role={hasColumns ? 'grid' : 'list'}\n aria-rowcount={hasColumns ? items.length + 1 : undefined}\n >\n {hasColumns && (\n <div\n ref={headerRef}\n className={cx(styles.virtualListHeader, classNames?.header)}\n style={{ gridTemplateColumns: columnTemplate, ...(shouldShowToggle ? { paddingRight: 32 } : {}), ...slotStyles?.header }}\n role=\"row\"\n aria-rowindex={1}\n >\n {multiSelect && (\n <div\n className={cx(styles.virtualListSelectCell, classNames?.selectCell)}\n style={slotStyles?.selectCell}\n role=\"columnheader\"\n >\n <Checkbox\n selected={selection.allSelected || selection.someSelected}\n onToggle={selection.handleSelectAll}\n aria-label=\"Select all rows\"\n />\n </div>\n )}\n {visibleColumns.map((col) => (\n <div\n key={col.key}\n className={cx(styles.virtualListHeaderCell, classNames?.headerCell)}\n style={slotStyles?.headerCell}\n role=\"columnheader\"\n data-fit-key={col.width.type === 'fit' ? col.key : undefined}\n >\n {col.label}\n </div>\n ))}\n {shouldShowToggle && (\n <div className={styles.virtualListToggleWrapper}>\n <FloatingMenu\n isOpen={toggleOpen}\n onOpenChange={setToggleOpen}\n align={Align.Right}\n content={\n <div\n className={cx(styles.virtualListTogglePopover, classNames?.togglePopover)}\n style={slotStyles?.togglePopover}\n >\n {columns!.filter((col) => !col.hideFromToggle).map((col) => (\n <Checkbox\n key={col.key}\n className={cx(styles.virtualListToggleItem, classNames?.toggleItem)}\n style={slotStyles?.toggleItem}\n selected={effectiveVisible.has(col.key)}\n onToggle={() => handleToggleColumn(col.key)}\n disabled={col.lockVisible}\n cursorDefault={false}\n >\n {col.toggleLabel ?? col.label}\n </Checkbox>\n ))}\n </div>\n }\n >\n <button\n type=\"button\"\n className={cx(styles.virtualListHeaderToggle, classNames?.headerToggle)}\n style={slotStyles?.headerToggle}\n aria-label=\"Toggle column visibility\"\n >\n <FontAwesomeIcon\n icon={faGear}\n style={slotStyles?.headerToggle as React.CSSProperties & Record<`--fa-font-${string}`, string>}\n />\n </button>\n </FloatingMenu>\n {manuallyHiddenCount > 0 && (\n <span\n className={cx(styles.virtualListColumnChip, classNames?.columnChip)}\n style={slotStyles?.columnChip}\n data-column-hidden-count={manuallyHiddenCount}\n aria-label={`${manuallyHiddenCount} columns hidden`}\n >\n {manuallyHiddenCount}\n </span>\n )}\n </div>\n )}\n </div>\n )}\n {isLoading ? (\n <div className={styles.virtualListLoadingFull}>\n <SpinnerLoading className={styles.virtualListSpinner} />\n </div>\n ) : (\n <div\n className={cx(styles.virtualListBody, classNames?.body)}\n style={{ height: totalHeight, ...slotStyles?.body }}\n >\n {visibleRows}\n </div>\n )}\n {win.showLoadMoreSpinner && (\n <div\n className={cx(styles.virtualListLoadingIndicator, classNames?.loadingIndicator)}\n style={slotStyles?.loadingIndicator}\n >\n <SpinnerLoading className={styles.virtualListSpinner} />\n </div>\n )}\n </div>\n );\n}\n\n// forwardRef erases the generic, so cast back to a generic-preserving signature.\nconst VirtualList = React.forwardRef(VirtualListInner) as <T>(\n props: VirtualListProps<T> & { ref?: React.Ref<VirtualListHandle> },\n) => React.ReactElement | null;\n\nexport default VirtualList;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"virtualList.module.mjs","names":[],"sources":["../../../../package/common/virtualList/virtualList.module.pcss"],"sourcesContent":[".virtualList {\n overflow-y: auto;\n box-sizing: border-box;\n color: var(--text-color);\n font-family: var(--default-font);\n /* Disable the browser's own scroll anchoring — the component does its own\n scroll-position correction when row heights change, and the two fighting\n each other causes the thumb to desync while dragging. */\n overflow-anchor: none;\n /* Reserve the scrollbar gutter so rows don't re-wrap (and re-measure) when the\n vertical scrollbar appears/disappears as content grows. */\n scrollbar-gutter: stable;\n /* Establish a stacking context so every z-index inside the list (sticky\n header, toggle popover, drag clone) stays scoped to this component and\n can't paint over outside content like a modal. */\n isolation: isolate;\n\n &-drag-clone {\n box-sizing: border-box;\n contain: layout paint style;\n cursor: grabbing;\n /* It tracks the finger via transform — never animate that. */\n transition: none;\n }\n\n &-header {\n display: grid;\n position: sticky;\n top: 0;\n /* Above focused rows (z-index 1) so a focused row scrolled under the header\n never paints over it; the drag clone (z-index 3) still floats above both. */\n z-index: 2;\n background: var(--background-accent);\n border-bottom: 1px solid var(--border-color);\n box-sizing: border-box;\n\n &-cell {\n padding: 8px 12px;\n font-weight: 600;\n font-size: 13px;\n color: var(--text-dark);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n box-sizing: border-box;\n }\n\n &-toggle {\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px 8px;\n color: var(--text-dark);\n display: flex;\n align-items: center;\n border-radius: var(--default-border-radius);\n transition: background 0.15s;\n\n &:hover {\n background: var(--background-accent-light);\n color: var(--text-color);\n }\n }\n }\n\n &-toggle {\n &-wrapper {\n position: absolute;\n right: 0;\n top: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n padding: 0 4px;\n }\n\n &-popover {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n background: var(--background-accent);\n border: 1px solid var(--border-color);\n border-radius: var(--default-border-radius);\n box-shadow: var(--card-shadow);\n min-width: 160px;\n padding: 4px 0;\n }\n\n &-item {\n padding: 4px 12px;\n white-space: nowrap;\n transition: background 0.1s;\n font-size: 14px;\n\n &:hover {\n background: var(--background-accent-light);\n }\n }\n }\n\n /* Count badge on the column-toggle cog: how many columns the user has hidden.\n Positioned at the cog's upper-right corner; non-interactive. */\n &-column-chip {\n position: absolute;\n top: 0;\n right: 0;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--primary-color);\n color: var(--text-on-primary);\n font-size: 10px;\n font-weight: 600;\n line-height: 1;\n border-radius: 8px;\n pointer-events: none;\n }\n\n &-select-cell {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0 4px;\n box-sizing: border-box;\n }\n\n &-body {\n position: relative;\n box-sizing: border-box;\n }\n\n &-row {\n border-bottom: 1px solid var(--border-color);\n box-sizing: border-box;\n cursor: pointer;\n transition: background 0.1s;\n /* Isolate each row's layout/style so measuring or restyling one row can't force\n the whole list to re-layout — keeps fast scrolling smooth. */\n contain: layout style;\n\n &-no-divider {\n border-bottom: none;\n }\n\n &:hover {\n background: var(--background-accent-light);\n }\n\n /* Opt out of the hover highlight (e.g. when each row is a Card that handles\n its own hover). Declared before the `-selected` rule below, so a selected\n row's highlight still wins on hover. */\n &-no-hover:hover {\n background: transparent;\n }\n\n &-selected {\n background: var(--primary-lighter);\n\n &:hover {\n background: var(--primary-lighter);\n }\n }\n\n &-draggable {\n cursor: grab;\n /* Stop the mobile long-press from selecting text or showing the callout. */\n user-select: none;\n -webkit-touch-callout: none;\n\n &:active {\n cursor: grabbing;\n }\n }\n\n &-dragging {\n opacity: 0.4;\n }\n\n /* Tree-reorder `inside` drop: the dragged node becomes a child of this row,\n so highlight the whole row instead of drawing a between-rows line. */\n &-drop-inside {\n background: var(--primary-lighter);\n box-shadow: inset 0 0 0 2px var(--primary-color);\n }\n }\n\n /* Tree-reorder `before`/`after` drop line. Positioned inside the (relatively\n positioned absolute) row; `left` is set inline to the target's indent so it\n starts where the dropped content will. */\n &-drop-line {\n position: absolute;\n right: 0;\n height: 2px;\n background: var(--primary-color);\n pointer-events: none;\n z-index: 1;\n\n /* A small knob at the line's start, the usual tree drop-indicator look. */\n &::before {\n content: '';\n position: absolute;\n left: 0;\n top: 50%;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--primary-color);\n transform: translate(-50%, -50%);\n }\n\n &-before { top: -1px; }\n &-after { bottom: -1px; }\n }\n\n /* While a row is being dragged, suppress hover backgrounds so the pointer\n moving across rows doesn't light up the wrong one, and stop text selection.\n `touch-action: none` stops the touch drag from also scrolling the list\n (only active once the long-press has armed the drag). */\n &-reordering {\n touch-action: none;\n\n .virtualList-row {\n user-select: none;\n\n &:hover {\n background: transparent;\n }\n\n &.virtualList-row-selected:hover {\n background: var(--primary-lighter);\n }\n\n &.virtualList-row-dragging {\n background: transparent;\n }\n }\n }\n\n &-cell {\n padding: 8px 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 14px;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n min-width: 0;\n\n /* `fit` columns are content-sized — keep their cells on a single line so the\n content can't wrap, and so the width measurement reads the true intrinsic\n width. (Other cells are free to wrap for variable-height rows.) */\n &[data-fit-key] {\n white-space: nowrap;\n }\n }\n\n &-loading {\n &-full {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n }\n\n &-indicator {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 8px 0;\n }\n }\n\n &-spinner {\n width: 32px;\n height: 32px;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"virtualList.module.mjs","names":[],"sources":["../../../../package/common/virtualList/virtualList.module.pcss"],"sourcesContent":[".virtualList {\n overflow-y: auto;\n box-sizing: border-box;\n color: var(--text-color);\n font-family: var(--default-font);\n /* Disable the browser's own scroll anchoring — the component does its own\n scroll-position correction when row heights change, and the two fighting\n each other causes the thumb to desync while dragging. */\n overflow-anchor: none;\n /* Reserve the scrollbar gutter so rows don't re-wrap (and re-measure) when the\n vertical scrollbar appears/disappears as content grows. */\n scrollbar-gutter: stable;\n /* Establish a stacking context so every z-index inside the list (sticky\n header, toggle popover, drag clone) stays scoped to this component and\n can't paint over outside content like a modal. */\n isolation: isolate;\n\n &-drag-clone {\n box-sizing: border-box;\n contain: layout paint style;\n cursor: grabbing;\n /* It tracks the finger via transform — never animate that. */\n transition: none;\n }\n\n &-header {\n display: grid;\n position: sticky;\n top: 0;\n /* Above focused rows (z-index 1) so a focused row scrolled under the header\n never paints over it; the drag clone (z-index 3) still floats above both. */\n z-index: 2;\n background: var(--background-accent);\n border-bottom: 1px solid var(--border-color);\n box-sizing: border-box;\n\n &-cell {\n padding: 8px 12px;\n font-weight: 600;\n font-size: 13px;\n color: var(--text-dark);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n box-sizing: border-box;\n }\n\n &-toggle {\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px 8px;\n color: var(--text-dark);\n display: flex;\n align-items: center;\n border-radius: var(--default-border-radius);\n transition: background 0.15s;\n\n &:hover {\n background: var(--background-accent-light);\n color: var(--text-color);\n }\n }\n }\n\n &-toggle {\n &-wrapper {\n position: absolute;\n right: 0;\n top: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n padding: 0 4px;\n }\n\n /* Chrome (background, shadow, radius, positioning) is provided by the\n FloatingMenu container this renders inside — keep only sizing here. */\n &-popover {\n display: flex;\n flex-direction: column;\n min-width: 160px;\n }\n\n &-item {\n padding: 4px 12px;\n white-space: nowrap;\n transition: background 0.1s;\n font-size: 14px;\n\n &:hover {\n background: var(--background-accent-light);\n }\n }\n }\n\n /* Count badge on the column-toggle cog: how many columns the user has hidden.\n Positioned at the cog's upper-right corner; non-interactive. */\n &-column-chip {\n position: absolute;\n top: 0;\n right: 0;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--primary-color);\n color: var(--text-on-primary);\n font-size: 10px;\n font-weight: 600;\n line-height: 1;\n border-radius: 8px;\n pointer-events: none;\n }\n\n &-select-cell {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0 4px;\n box-sizing: border-box;\n }\n\n &-body {\n position: relative;\n box-sizing: border-box;\n }\n\n &-row {\n border-bottom: 1px solid var(--border-color);\n box-sizing: border-box;\n cursor: pointer;\n transition: background 0.1s;\n /* Isolate each row's layout/style so measuring or restyling one row can't force\n the whole list to re-layout — keeps fast scrolling smooth. */\n contain: layout style;\n\n &-no-divider {\n border-bottom: none;\n }\n\n &:hover {\n background: var(--background-accent-light);\n }\n\n /* Opt out of the hover highlight (e.g. when each row is a Card that handles\n its own hover). Declared before the `-selected` rule below, so a selected\n row's highlight still wins on hover. */\n &-no-hover:hover {\n background: transparent;\n }\n\n &-selected {\n background: var(--primary-lighter);\n\n &:hover {\n background: var(--primary-lighter);\n }\n }\n\n &-draggable {\n cursor: grab;\n /* Stop the mobile long-press from selecting text or showing the callout. */\n user-select: none;\n -webkit-touch-callout: none;\n\n &:active {\n cursor: grabbing;\n }\n }\n\n &-dragging {\n opacity: 0.4;\n }\n\n /* Tree-reorder `inside` drop: the dragged node becomes a child of this row,\n so highlight the whole row instead of drawing a between-rows line. */\n &-drop-inside {\n background: var(--primary-lighter);\n box-shadow: inset 0 0 0 2px var(--primary-color);\n }\n }\n\n /* Tree-reorder `before`/`after` drop line. Positioned inside the (relatively\n positioned absolute) row; `left` is set inline to the target's indent so it\n starts where the dropped content will. */\n &-drop-line {\n position: absolute;\n right: 0;\n height: 2px;\n background: var(--primary-color);\n pointer-events: none;\n z-index: 1;\n\n /* A small knob at the line's start, the usual tree drop-indicator look. */\n &::before {\n content: '';\n position: absolute;\n left: 0;\n top: 50%;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--primary-color);\n transform: translate(-50%, -50%);\n }\n\n &-before { top: -1px; }\n &-after { bottom: -1px; }\n }\n\n /* While a row is being dragged, suppress hover backgrounds so the pointer\n moving across rows doesn't light up the wrong one, and stop text selection.\n `touch-action: none` stops the touch drag from also scrolling the list\n (only active once the long-press has armed the drag). */\n &-reordering {\n touch-action: none;\n\n .virtualList-row {\n user-select: none;\n\n &:hover {\n background: transparent;\n }\n\n &.virtualList-row-selected:hover {\n background: var(--primary-lighter);\n }\n\n &.virtualList-row-dragging {\n background: transparent;\n }\n }\n }\n\n &-cell {\n padding: 8px 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 14px;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n min-width: 0;\n\n /* `fit` columns are content-sized — keep their cells on a single line so the\n content can't wrap, and so the width measurement reads the true intrinsic\n width. (Other cells are free to wrap for variable-height rows.) */\n &[data-fit-key] {\n white-space: nowrap;\n }\n }\n\n &-loading {\n &-full {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n }\n\n &-indicator {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 8px 0;\n }\n }\n\n &-spinner {\n width: 32px;\n height: 32px;\n }\n}\n"],"mappings":""}
@@ -1,2 +1,2 @@
1
- function e(e,t,n,r=0){let i=e.length,a=Array(i+1);a[0]=0;for(let o=0;o<i;o++){let s=o<i-1?r:0;a[o+1]=a[o]+(t.get(e[o])??n)+s}return{offsets:a,totalHeight:a[i]}}function t(e,t,n){if(n<=0)return 0;let r=0,i=n-1;for(;r<i;){let n=r+i>>1;e[n+1]<=t?r=n+1:i=n}return r}function n(e,n,r,i,a){if(a===0)return{startIndex:0,endIndex:-1};let o=t(e,n,a),s=o;for(;s<a&&e[s]<n+r;)s++;return{startIndex:Math.max(0,o-i),endIndex:Math.min(a-1,s+i-1)}}function r(e,t,n,r,i){if(e===-1||e===t)return null;let a=r+i/2;return(t>e?n>=a:n<=a)?t:null}function i(e,t,n,r){if(n<=0)return`before`;let i=(e-t)/n;return r?i<1/3?`before`:i>2/3?`after`:`inside`:i<.5?`before`:`after`}function a(e,t){let n=t[e],r=e+1;for(;r<t.length&&t[r]>n;)r++;return r-1}function o(e,t){return e.length===0?`1fr`:e.map(e=>{switch(e.width.type){case`fixed`:return`${e.width.px}px`;case`flex`:return`${e.width.weight??1}fr`;case`fit`:{let n=t?.[e.key];return n==null?`fit-content(100%)`:`${n}px`}}}).join(` `)}var s=`ahroweui:virtuallist:columns:`;function c(e){if(!e||typeof window>`u`)return null;try{let t=window.localStorage.getItem(s+e);if(!t)return null;let n=JSON.parse(t);if(n&&Array.isArray(n.visible)&&Array.isArray(n.known))return{visible:n.visible.filter(e=>typeof e==`string`),known:n.known.filter(e=>typeof e==`string`)}}catch{}return null}function l(e,t){return t&&t.known.includes(e.key)?t.visible.includes(e.key):!e.defaultHidden}export{s as COLUMN_STORAGE_PREFIX,o as buildColumnTemplate,e as buildOffsets,t as findStartIndex,n as getVisibleRange,l as isColumnInitiallyVisible,a as lastDescendantIndex,c as loadPersistedColumns,r as resolveReorderTarget,i as resolveTreeDropTarget};
1
+ function e(e,t,n,r=0){let i=e.length,a=Array(i+1);a[0]=0;for(let o=0;o<i;o++){let s=o<i-1?r:0;a[o+1]=a[o]+(t.get(e[o])??n)+s}return{offsets:a,totalHeight:a[i]}}function t(e,t,n){if(n<=0)return 0;let r=0,i=n-1;for(;r<i;){let n=r+i>>1;e[n+1]<=t?r=n+1:i=n}return r}function n(e,n,r,i,a){if(a===0)return{startIndex:0,endIndex:-1};let o=t(e,n,a),s=o;for(;s<a&&e[s]<n+r;)s++;return{startIndex:Math.max(0,o-i),endIndex:Math.min(a-1,s+i-1)}}function r(e,t,n,r,i){if(e===-1||e===t)return null;let a=r+i/2;return(t>e?n>=a:n<=a)?t:null}function i(e,t,n,r){if(n<=0)return`before`;let i=(e-t)/n;return r?i<1/3?`before`:i>2/3?`after`:`inside`:i<.5?`before`:`after`}function a(e,t){let n=t[e],r=e+1;for(;r<t.length&&t[r]>n;)r++;return r-1}function o(e,t){return e.length===0?`1fr`:e.map(e=>{switch(e.width.type){case`fixed`:return`${e.width.px}px`;case`flex`:return`${e.width.weight??1}fr`;case`fit`:{let n=t?.[e.key];return n==null?`fit-content(100%)`:`${n}px`}}}).join(` `)}var s=`ahroweui:virtuallist:columns:`;function c(e){if(!e||typeof window>`u`)return null;try{let t=window.localStorage.getItem(s+e);if(!t)return null;let n=JSON.parse(t);if(n&&Array.isArray(n.visible)&&Array.isArray(n.known))return{visible:n.visible.filter(e=>typeof e==`string`),known:n.known.filter(e=>typeof e==`string`)}}catch{}return null}function l(e,t){return e.lockVisible?!0:t&&t.known.includes(e.key)?t.visible.includes(e.key):!e.defaultHidden}export{s as COLUMN_STORAGE_PREFIX,o as buildColumnTemplate,e as buildOffsets,t as findStartIndex,n as getVisibleRange,l as isColumnInitiallyVisible,a as lastDescendantIndex,c as loadPersistedColumns,r as resolveReorderTarget,i as resolveTreeDropTarget};
2
2
  //# sourceMappingURL=virtualList.utils.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"virtualList.utils.mjs","names":[],"sources":["../../../../package/common/virtualList/virtualList.utils.ts"],"sourcesContent":["import type { ColumnWidthSpec, VirtualListColumn } from './virtualList.types';\n\n// ─── Layout / windowing math ──────────────────────────────────────────────────\n\nexport function buildOffsets(\n keys: (string | number)[],\n heightsMap: Map<string | number, number>,\n estimatedRowHeight: number,\n rowGap = 0,\n): { offsets: number[]; totalHeight: number } {\n const itemCount = keys.length;\n const offsets = new Array<number>(itemCount + 1);\n offsets[0] = 0;\n for (let i = 0; i < itemCount; i++) {\n const gap = i < itemCount - 1 ? rowGap : 0;\n // Heights are cached by item key, not index, so a measured row keeps its\n // height across reorders/filters instead of inheriting its neighbour's.\n offsets[i + 1] = offsets[i] + (heightsMap.get(keys[i]) ?? estimatedRowHeight) + gap;\n }\n return { offsets, totalHeight: offsets[itemCount] };\n}\n\n/** Index of the row that sits at `scrollTop` — i.e. the first row whose bottom edge is below it. */\nexport function findStartIndex(offsets: number[], scrollTop: number, itemCount: number): number {\n if (itemCount <= 0) return 0;\n let lo = 0;\n let hi = itemCount - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (offsets[mid + 1] <= scrollTop) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\nexport function getVisibleRange(\n offsets: number[],\n scrollTop: number,\n containerHeight: number,\n overscan: number,\n itemCount: number,\n): { startIndex: number; endIndex: number } {\n if (itemCount === 0) return { startIndex: 0, endIndex: -1 };\n\n const lo = findStartIndex(offsets, scrollTop, itemCount);\n\n let end = lo;\n while (end < itemCount && offsets[end] < scrollTop + containerHeight) end++;\n\n return {\n startIndex: Math.max(0, lo - overscan),\n endIndex: Math.min(itemCount - 1, end + overscan - 1),\n };\n}\n\n// ─── Reorder / tree-drop math ─────────────────────────────────────────────────\n\n/**\n * Decides where a dragged row should move to, applying midpoint hysteresis: a\n * move only happens once the pointer has crossed the centre of the row it is\n * over (downwards when moving down, upwards when moving up). Returns the target\n * index, or null if no move should occur. Pure for easy unit testing.\n */\nexport function resolveReorderTarget(\n fromIndex: number,\n overIndex: number,\n pointerY: number,\n rowTop: number,\n rowHeight: number,\n): number | null {\n if (fromIndex === -1 || fromIndex === overIndex) return null;\n const midpoint = rowTop + rowHeight / 2;\n const movingDown = overIndex > fromIndex;\n if (movingDown ? pointerY >= midpoint : pointerY <= midpoint) return overIndex;\n return null;\n}\n\n/**\n * Decides where a tree-reorder drop should land relative to the row under the\n * pointer. Group rows expose three zones (top third → `before`, middle →\n * `inside`, bottom third → `after`); leaf rows split in half (`before`/`after`)\n * since they can't receive children. Pure for easy unit testing.\n */\nexport function resolveTreeDropTarget(\n pointerY: number,\n rowTop: number,\n rowHeight: number,\n isGroup: boolean,\n): 'before' | 'inside' | 'after' {\n if (rowHeight <= 0) return 'before';\n const rel = (pointerY - rowTop) / rowHeight;\n if (isGroup) {\n if (rel < 1 / 3) return 'before';\n if (rel > 2 / 3) return 'after';\n return 'inside';\n }\n return rel < 0.5 ? 'before' : 'after';\n}\n\n/**\n * Index of the last descendant of the node at `index` in a depth-tagged flat\n * list (a contiguous run of following rows with a greater depth). Returns\n * `index` itself when the node has no children. A drop is forbidden anywhere in\n * `[index, lastDescendantIndex]` — that's the node and its own subtree.\n */\nexport function lastDescendantIndex(index: number, depths: number[]): number {\n const d = depths[index];\n let i = index + 1;\n while (i < depths.length && depths[i] > d) i++;\n return i - 1;\n}\n\n// ─── Column template ──────────────────────────────────────────────────────────\n\nexport function buildColumnTemplate(\n columns: { key: string; width: ColumnWidthSpec }[],\n fitWidths?: Record<string, number>,\n): string {\n if (columns.length === 0) return '1fr';\n return columns\n .map((col) => {\n switch (col.width.type) {\n case 'fixed': return `${col.width.px}px`;\n case 'flex': return `${col.width.weight ?? 1}fr`;\n // A `fit` track is content-sized, so it resolves independently in each\n // grid (the header and every row are separate grids) and would drift\n // out of alignment. Once we've measured the column's natural width\n // across all those grids, pin it to that exact px so every grid uses an\n // identical track. Until then, fall back to content-sizing.\n case 'fit': {\n const w = fitWidths?.[col.key];\n return w != null ? `${w}px` : 'fit-content(100%)';\n }\n }\n })\n .join(' ');\n}\n\n// ─── Column-visibility persistence ────────────────────────────────────────────\n\nexport const COLUMN_STORAGE_PREFIX = 'ahroweui:virtuallist:columns:';\n\n// We persist both the visible keys and the full set of columns that existed at\n// save time. That lets us tell \"the user hid this column\" from \"this column\n// didn't exist yet\" when columns are added later — the former stays hidden, the\n// latter falls back to its defaultHidden value.\nexport interface PersistedColumns {\n visible: string[];\n known: string[];\n}\n\nexport function loadPersistedColumns(persistKey: string | undefined): PersistedColumns | null {\n if (!persistKey || typeof window === 'undefined') return null;\n try {\n const raw = window.localStorage.getItem(COLUMN_STORAGE_PREFIX + persistKey);\n if (!raw) return null;\n const parsed = JSON.parse(raw);\n if (parsed && Array.isArray(parsed.visible) && Array.isArray(parsed.known)) {\n return {\n visible: parsed.visible.filter((k: unknown): k is string => typeof k === 'string'),\n known: parsed.known.filter((k: unknown): k is string => typeof k === 'string'),\n };\n }\n } catch {\n // Corrupt/unavailable storage — fall back to defaults.\n }\n return null;\n}\n\n/** Whether a column should start visible, honouring saved settings then `defaultHidden`. */\nexport function isColumnInitiallyVisible<T>(col: VirtualListColumn<T>, persisted: PersistedColumns | null): boolean {\n if (persisted && persisted.known.includes(col.key)) return persisted.visible.includes(col.key);\n return !col.defaultHidden;\n}\n"],"mappings":"AAIA,SAAgB,EACd,EACA,EACA,EACA,EAAS,EACmC,CAC5C,IAAM,EAAY,EAAK,OACjB,EAAc,MAAc,EAAY,CAAC,EAC/C,EAAQ,GAAK,EACb,IAAK,IAAI,EAAI,EAAG,EAAI,EAAW,IAAK,CAClC,IAAM,EAAM,EAAI,EAAY,EAAI,EAAS,EAGzC,EAAQ,EAAI,GAAK,EAAQ,IAAM,EAAW,IAAI,EAAK,EAAE,GAAK,GAAsB,CAClF,CACA,MAAO,CAAE,UAAS,YAAa,EAAQ,EAAW,CACpD,CAGA,SAAgB,EAAe,EAAmB,EAAmB,EAA2B,CAC9F,GAAI,GAAa,EAAG,MAAO,GAC3B,IAAI,EAAK,EACL,EAAK,EAAY,EACrB,KAAO,EAAK,GAAI,CACd,IAAM,EAAO,EAAK,GAAO,EACrB,EAAQ,EAAM,IAAM,EAAW,EAAK,EAAM,EACzC,EAAK,CACZ,CACA,OAAO,CACT,CAEA,SAAgB,EACd,EACA,EACA,EACA,EACA,EAC0C,CAC1C,GAAI,IAAc,EAAG,MAAO,CAAE,WAAY,EAAG,SAAU,EAAG,EAE1D,IAAM,EAAK,EAAe,EAAS,EAAW,CAAS,EAEnD,EAAM,EACV,KAAO,EAAM,GAAa,EAAQ,GAAO,EAAY,GAAiB,IAEtE,MAAO,CACL,WAAY,KAAK,IAAI,EAAG,EAAK,CAAQ,EACrC,SAAU,KAAK,IAAI,EAAY,EAAG,EAAM,EAAW,CAAC,CACtD,CACF,CAUA,SAAgB,EACd,EACA,EACA,EACA,EACA,EACe,CACf,GAAI,IAAc,IAAM,IAAc,EAAW,OAAO,KACxD,IAAM,EAAW,EAAS,EAAY,EAGtC,OAFmB,EAAY,EACd,GAAY,EAAW,GAAY,GAAiB,EAC9D,IACT,CAQA,SAAgB,EACd,EACA,EACA,EACA,EAC+B,CAC/B,GAAI,GAAa,EAAG,MAAO,SAC3B,IAAM,GAAO,EAAW,GAAU,EAMlC,OALI,EACE,EAAM,EAAI,EAAU,SACpB,EAAM,EAAI,EAAU,QACjB,SAEF,EAAM,GAAM,SAAW,OAChC,CAQA,SAAgB,EAAoB,EAAe,EAA0B,CAC3E,IAAM,EAAI,EAAO,GACb,EAAI,EAAQ,EAChB,KAAO,EAAI,EAAO,QAAU,EAAO,GAAK,GAAG,IAC3C,OAAO,EAAI,CACb,CAIA,SAAgB,EACd,EACA,EACQ,CAER,OADI,EAAQ,SAAW,EAAU,MAC1B,EACJ,IAAK,GAAQ,CACZ,OAAQ,EAAI,MAAM,KAAlB,CACE,IAAK,QAAS,MAAO,GAAG,EAAI,MAAM,GAAG,IACrC,IAAK,OAAS,MAAO,GAAG,EAAI,MAAM,QAAU,EAAE,IAM9C,IAAK,MAAS,CACZ,IAAM,EAAI,IAAY,EAAI,KAC1B,OAAO,GAAK,KAAkB,oBAAX,GAAG,EAAE,GAC1B,CACF,CACF,CAAC,EACA,KAAK,GAAG,CACb,CAIA,IAAa,EAAwB,gCAWrC,SAAgB,EAAqB,EAAyD,CAC5F,GAAI,CAAC,GAAc,OAAO,OAAW,IAAa,OAAO,KACzD,GAAI,CACF,IAAM,EAAM,OAAO,aAAa,QAAQ,EAAwB,CAAU,EAC1E,GAAI,CAAC,EAAK,OAAO,KACjB,IAAM,EAAS,KAAK,MAAM,CAAG,EAC7B,GAAI,GAAU,MAAM,QAAQ,EAAO,OAAO,GAAK,MAAM,QAAQ,EAAO,KAAK,EACvE,MAAO,CACL,QAAS,EAAO,QAAQ,OAAQ,GAA4B,OAAO,GAAM,QAAQ,EACjF,MAAO,EAAO,MAAM,OAAQ,GAA4B,OAAO,GAAM,QAAQ,CAC/E,CAEJ,MAAQ,CAER,CACA,OAAO,IACT,CAGA,SAAgB,EAA4B,EAA2B,EAA6C,CAElH,OADI,GAAa,EAAU,MAAM,SAAS,EAAI,GAAG,EAAU,EAAU,QAAQ,SAAS,EAAI,GAAG,EACtF,CAAC,EAAI,aACd"}
1
+ {"version":3,"file":"virtualList.utils.mjs","names":[],"sources":["../../../../package/common/virtualList/virtualList.utils.ts"],"sourcesContent":["import type { ColumnWidthSpec, VirtualListColumn } from './virtualList.types';\n\n// ─── Layout / windowing math ──────────────────────────────────────────────────\n\nexport function buildOffsets(\n keys: (string | number)[],\n heightsMap: Map<string | number, number>,\n estimatedRowHeight: number,\n rowGap = 0,\n): { offsets: number[]; totalHeight: number } {\n const itemCount = keys.length;\n const offsets = new Array<number>(itemCount + 1);\n offsets[0] = 0;\n for (let i = 0; i < itemCount; i++) {\n const gap = i < itemCount - 1 ? rowGap : 0;\n // Heights are cached by item key, not index, so a measured row keeps its\n // height across reorders/filters instead of inheriting its neighbour's.\n offsets[i + 1] = offsets[i] + (heightsMap.get(keys[i]) ?? estimatedRowHeight) + gap;\n }\n return { offsets, totalHeight: offsets[itemCount] };\n}\n\n/** Index of the row that sits at `scrollTop` — i.e. the first row whose bottom edge is below it. */\nexport function findStartIndex(offsets: number[], scrollTop: number, itemCount: number): number {\n if (itemCount <= 0) return 0;\n let lo = 0;\n let hi = itemCount - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (offsets[mid + 1] <= scrollTop) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\nexport function getVisibleRange(\n offsets: number[],\n scrollTop: number,\n containerHeight: number,\n overscan: number,\n itemCount: number,\n): { startIndex: number; endIndex: number } {\n if (itemCount === 0) return { startIndex: 0, endIndex: -1 };\n\n const lo = findStartIndex(offsets, scrollTop, itemCount);\n\n let end = lo;\n while (end < itemCount && offsets[end] < scrollTop + containerHeight) end++;\n\n return {\n startIndex: Math.max(0, lo - overscan),\n endIndex: Math.min(itemCount - 1, end + overscan - 1),\n };\n}\n\n// ─── Reorder / tree-drop math ─────────────────────────────────────────────────\n\n/**\n * Decides where a dragged row should move to, applying midpoint hysteresis: a\n * move only happens once the pointer has crossed the centre of the row it is\n * over (downwards when moving down, upwards when moving up). Returns the target\n * index, or null if no move should occur. Pure for easy unit testing.\n */\nexport function resolveReorderTarget(\n fromIndex: number,\n overIndex: number,\n pointerY: number,\n rowTop: number,\n rowHeight: number,\n): number | null {\n if (fromIndex === -1 || fromIndex === overIndex) return null;\n const midpoint = rowTop + rowHeight / 2;\n const movingDown = overIndex > fromIndex;\n if (movingDown ? pointerY >= midpoint : pointerY <= midpoint) return overIndex;\n return null;\n}\n\n/**\n * Decides where a tree-reorder drop should land relative to the row under the\n * pointer. Group rows expose three zones (top third → `before`, middle →\n * `inside`, bottom third → `after`); leaf rows split in half (`before`/`after`)\n * since they can't receive children. Pure for easy unit testing.\n */\nexport function resolveTreeDropTarget(\n pointerY: number,\n rowTop: number,\n rowHeight: number,\n isGroup: boolean,\n): 'before' | 'inside' | 'after' {\n if (rowHeight <= 0) return 'before';\n const rel = (pointerY - rowTop) / rowHeight;\n if (isGroup) {\n if (rel < 1 / 3) return 'before';\n if (rel > 2 / 3) return 'after';\n return 'inside';\n }\n return rel < 0.5 ? 'before' : 'after';\n}\n\n/**\n * Index of the last descendant of the node at `index` in a depth-tagged flat\n * list (a contiguous run of following rows with a greater depth). Returns\n * `index` itself when the node has no children. A drop is forbidden anywhere in\n * `[index, lastDescendantIndex]` — that's the node and its own subtree.\n */\nexport function lastDescendantIndex(index: number, depths: number[]): number {\n const d = depths[index];\n let i = index + 1;\n while (i < depths.length && depths[i] > d) i++;\n return i - 1;\n}\n\n// ─── Column template ──────────────────────────────────────────────────────────\n\nexport function buildColumnTemplate(\n columns: { key: string; width: ColumnWidthSpec }[],\n fitWidths?: Record<string, number>,\n): string {\n if (columns.length === 0) return '1fr';\n return columns\n .map((col) => {\n switch (col.width.type) {\n case 'fixed': return `${col.width.px}px`;\n case 'flex': return `${col.width.weight ?? 1}fr`;\n // A `fit` track is content-sized, so it resolves independently in each\n // grid (the header and every row are separate grids) and would drift\n // out of alignment. Once we've measured the column's natural width\n // across all those grids, pin it to that exact px so every grid uses an\n // identical track. Until then, fall back to content-sizing.\n case 'fit': {\n const w = fitWidths?.[col.key];\n return w != null ? `${w}px` : 'fit-content(100%)';\n }\n }\n })\n .join(' ');\n}\n\n// ─── Column-visibility persistence ────────────────────────────────────────────\n\nexport const COLUMN_STORAGE_PREFIX = 'ahroweui:virtuallist:columns:';\n\n// We persist both the visible keys and the full set of columns that existed at\n// save time. That lets us tell \"the user hid this column\" from \"this column\n// didn't exist yet\" when columns are added later — the former stays hidden, the\n// latter falls back to its defaultHidden value.\nexport interface PersistedColumns {\n visible: string[];\n known: string[];\n}\n\nexport function loadPersistedColumns(persistKey: string | undefined): PersistedColumns | null {\n if (!persistKey || typeof window === 'undefined') return null;\n try {\n const raw = window.localStorage.getItem(COLUMN_STORAGE_PREFIX + persistKey);\n if (!raw) return null;\n const parsed = JSON.parse(raw);\n if (parsed && Array.isArray(parsed.visible) && Array.isArray(parsed.known)) {\n return {\n visible: parsed.visible.filter((k: unknown): k is string => typeof k === 'string'),\n known: parsed.known.filter((k: unknown): k is string => typeof k === 'string'),\n };\n }\n } catch {\n // Corrupt/unavailable storage — fall back to defaults.\n }\n return null;\n}\n\n/** Whether a column should start visible, honouring saved settings then `defaultHidden`. */\nexport function isColumnInitiallyVisible<T>(col: VirtualListColumn<T>, persisted: PersistedColumns | null): boolean {\n // A locked column is always visible and can't be hidden — ignore saved state.\n if (col.lockVisible) return true;\n if (persisted && persisted.known.includes(col.key)) return persisted.visible.includes(col.key);\n return !col.defaultHidden;\n}\n"],"mappings":"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"}