@stackone/malachite 2.29.0 → 2.30.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"Table.js","sources":["../../../src/components/Table/Table.tsx"],"sourcesContent":["import { useVirtualizer } from '@tanstack/react-virtual';\nimport React, {\n useState,\n useMemo,\n useRef,\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n} from 'react';\nimport CaretDownIcon from '../CustomIcons/CaretDownIcon';\nimport CaretUpIcon from '../CustomIcons/CaretUpIcon';\nimport InfoIcon from '../CustomIcons/InfoIcon';\nimport WarningTriangleIcon from '../CustomIcons/WarningTriangleIcon';\nimport Tooltip from '../Tooltip';\nimport TruncatedTooltip from '../TruncatedTooltip';\nimport { FOCUS_RING_INSET } from '../focusRing';\nimport { activateOnEnterOrSpace, isFromInteractiveDescendant } from '../keyboardActivation';\nimport {\n FOREGROUND_RESET,\n SELECTED_ROW_ACCENT,\n SELECTED_ROW_BACKGROUND,\n SELECTED_ROW_FOREGROUND,\n SELECTED_TEXT_CONTEXT,\n} from '../selectedRow';\nimport TablePagination from './TablePagination';\nimport {\n TableColumnDefinition,\n TableColumns,\n TablePaginationPosition,\n TableRowActions,\n TableRowSelection,\n TableSize,\n TableType,\n TableVisibleOrderHandler,\n} from './types';\n\nexport type { TableRowActions };\n\nexport type RowVariant = 'success' | 'warning' | 'error' | 'info';\n\nexport type TableHeaderVariant = 'inline' | 'detached';\n\nexport type TableProps<T = Record<string, unknown>> = {\n columns: TableColumns<T>;\n data: T[];\n loading?: boolean;\n error?: boolean;\n errorTitle?: string;\n errorSubTitle?: string;\n emptyTitle?: string;\n emptySubTitle?: string;\n bordered?: boolean;\n showHeader?: boolean;\n rowKey?: string | ((record: T) => string);\n scrollHeight?: string | number;\n type?: TableType;\n size?: TableSize;\n /** Vertical density of body rows. 'compact' halves the cell padding so\n * rows carrying controls (buttons, dropdowns) sit close to text-row\n * height; headers keep their own padding. */\n rowDensity?: 'default' | 'compact';\n layout?: 'fixed' | 'auto';\n headerVariant?: TableHeaderVariant;\n rowClassName?: (record: T, index: number) => string;\n rowVariant?: (record: T, index: number) => RowVariant | undefined;\n onRow?: (record: T, index: number) => TableRowActions<T>;\n onClickRow?: (record: T, index: number) => void;\n /** Row the master-detail view is showing, resolved against `rowKey`. Controlled, so\n * selection can change without a row click and the highlight follows. Unlike\n * `rowSelection` it paints no control — a tint, an accent bar and `aria-current`.\n * Follows its record through a sort only with a resolvable `rowKey`. */\n selectedRowKey?: React.Key;\n /** Whether a selection change scrolls the row into view. Default true.\n *\n * Set `false` when the initial key comes from a URL: the reveal uses `scrollIntoView`,\n * which walks every scrollable ancestor, so a deep-linked row below the fold jumps the\n * page on load. Selection still highlights; only the scroll is suppressed. */\n scrollSelectedIntoView?: boolean;\n rowSelection?: TableRowSelection<T>;\n pagination?: {\n current?: number;\n pageSize?: number;\n total?: number;\n showSizeChanger?: boolean;\n showQuickJumper?: boolean;\n showTotal?: (total: number, range: [number, number]) => React.ReactNode;\n pageSizeOptions?: string[];\n position?: TablePaginationPosition[];\n onChange?: (page: number, pageSize: number) => void;\n onShowSizeChange?: (current: number, size: number) => void;\n };\n className?: string;\n style?: React.CSSProperties;\n /** When set, makes the detached-variant header sticky at this offset (px) from the\n * top of the nearest scrolling ancestor. Use this when the table sits inside a\n * page-level scroll container with other sticky elements (e.g. tabs + toolbar)\n * stacked above. */\n stickyHeaderTop?: number;\n scrollX?: boolean;\n rowSection?: (record: T) => string;\n renderSectionDivider?: (sectionKey: string, records: T[]) => React.ReactNode;\n /** Reports the rows in render order — sorted and section-grouped, so not `data` order,\n * and always all of `data`. An equal-but-new array does not re-fire, so a host cannot loop.\n * Needs a `rowKey`, or records that keep their object identity across renders. */\n onVisibleOrderChange?: TableVisibleOrderHandler<T>;\n /** Windowed rendering for large datasets (detached variant only), powered by\n * TanStack Virtual: only rows near the viewport stay mounted; spacers keep the\n * scrollbar reflecting the full list. The table body becomes the scroll\n * container, so give it a bounded height via `scrollHeight`. Row heights are\n * measured per row (non-uniform rows are fine). */\n virtual?: boolean;\n /** Estimated row height (px) used by `virtual` before rows are measured. */\n virtualRowHeightEstimate?: number;\n /** With `virtual`: virtualize against this ancestor scroll container instead of\n * the table body (e.g. a page-level scroller so content above the table can\n * scroll away). Pass the element from state (not a ref) so it arrives after\n * mount. The table body stops scrolling when this is set. */\n virtualScrollElement?: HTMLElement | null;\n};\n\nconst DEFAULT_SCROLL_COL_WIDTH = 160;\n\nconst sameRowOrder = (a: readonly string[], b: readonly string[]): boolean =>\n a.length === b.length && a.every((key, index) => key === b[index]);\n\n// Kept per object, never derived from order: any identity read off the current order is the\n// same sequence after a reorder, so the reorder would be suppressed.\nconst KEYLESS_ID_PREFIX = '\\u0000';\n\ntype KeylessIds = { ids: WeakMap<object, string>; next: number };\n\nconst keylessId = (record: unknown, registry: KeylessIds, index: number): string => {\n if (typeof record !== 'object' || record === null) {\n return `${KEYLESS_ID_PREFIX}i${index}`;\n }\n const seen = registry.ids.get(record);\n if (seen !== undefined) {\n return seen;\n }\n const id = `${KEYLESS_ID_PREFIX}${registry.next++}`;\n registry.ids.set(record, id);\n return id;\n};\n\nconst visibleRowOrder = <T,>(\n sortedData: readonly T[],\n rowKey: string | ((record: T) => string),\n registry: KeylessIds,\n): string[] => {\n if (typeof rowKey === 'function') {\n return sortedData.map((record) => rowKey(record));\n }\n return sortedData.map((record, index) => {\n const key = (record as Record<string, unknown>)[rowKey];\n return key === undefined || key === null ? keylessId(record, registry, index) : String(key);\n });\n};\n\nconst fixedPxWidth = (width: string | number | undefined): number | undefined => {\n if (typeof width === 'number') {\n return width;\n }\n if (typeof width === 'string') {\n const match = width.trim().match(/^(\\d+(?:\\.\\d+)?)px$/);\n if (match) {\n return Number(match[1]);\n }\n }\n return undefined;\n};\n\nconst computeScrollMinWidth = (columns: TableColumns<unknown>): number =>\n columns.reduce((sum, column) => {\n const fixed = fixedPxWidth(column.width);\n if (fixed !== undefined) {\n return sum + fixed;\n }\n if (typeof column.minWidth === 'number') {\n return sum + column.minWidth;\n }\n return sum + DEFAULT_SCROLL_COL_WIDTH;\n }, 0);\n\nconst isString = (value: unknown): value is string => typeof value === 'string';\n\nconst getSizeClasses = (size: TableSize): string => {\n const sizeMap: Record<TableSize, string> = {\n small: 'text-[length:var(--malachite-font-size-small)]',\n medium: 'text-[length:var(--malachite-font-size-medium)]',\n large: 'text-[length:var(--malachite-font-size-large)]',\n };\n return sizeMap[size];\n};\n\nconst ROW_BORDER_STYLE: React.CSSProperties = {\n borderBottom: '1px solid var(--malachite-card-border, #e8e8e8)',\n};\n\nconst syncScroll = (source: HTMLDivElement | null, target: HTMLDivElement | null): void => {\n if (source && target && target.scrollLeft !== source.scrollLeft) {\n target.scrollLeft = source.scrollLeft;\n }\n};\n\nconst PAGINATION_RESERVED_HEIGHT = 56;\n\nconst DEFAULT_VIRTUAL_ROW_HEIGHT = 44;\nconst VIRTUAL_OVERSCAN_ROWS = 8;\n// Bounded so a row that never mounts can't spin forever.\nconst VIRTUAL_SCROLL_CORRECTION_FRAMES = 10;\n\n// Section cards are clipped to this radius. The first and last row echo it so the selected\n// row's accent bar curves into the corner instead of being cut off by the clip.\nconst SECTION_CARD_RADIUS = 8;\n/** The detached table's outer card: `rounded-xl` + `p-[4px]` on the container below. Read from\n * the token the container itself rounds by, or overriding `radius.xl` pinches the corners. */\nconst DETACHED_CARD_RADIUS = 'var(--malachite-radius-xl, 12px)';\nconst DETACHED_CARD_PADDING = 4;\n\n/** The colour behind the table's own card, painted into the corner notches. A context channel,\n * not a theme token: no palette value, not settable through `applyTheme`, absent from\n * `getCurrentTheme`. Set it on an ancestor when a docked table does not sit on a card. */\nconst SURROUND_CHANNEL = '--malachite-ctx-table-surround';\n\n/** Cuts the docked header's top corners. A plain `border-radius` is invisible here: the\n * container behind paints the same grey, so the notch would just reveal grey. */\nconst StickyHeaderCornerCap: React.FC = () => {\n const r = DETACHED_CARD_RADIUS;\n const card = `var(${SURROUND_CHANNEL}, var(--malachite-card-background, #ffffff))`;\n\n return (\n <div\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n height: r,\n pointerEvents: 'none',\n background: [\n `radial-gradient(circle ${r} at ${r} ${r}, transparent calc(${r} - 0.5px), ${card} ${r}) top left / ${r} ${r} no-repeat`,\n `radial-gradient(circle ${r} at 0 ${r}, transparent calc(${r} - 0.5px), ${card} ${r}) top right / ${r} ${r} no-repeat`,\n ].join(', '),\n }}\n />\n );\n};\n\ntype VirtualMeasureProps = {\n measureRef: (element: HTMLDivElement | null) => void;\n index: number;\n};\n\n/** Lets the table scroll to a row a card has not mounted. The virtualizer is per-card, so\n * `startIndex`/`count` map a global index to the owning card. */\ntype VirtualCardHandle = {\n startIndex: number;\n count: number;\n scrollToIndex: (localIndex: number) => void;\n};\n\ntype VirtualSectionCardProps<T> = {\n records: T[];\n startIndex: number;\n scrollElement: HTMLElement | null;\n estimateRowHeight: number;\n style: React.CSSProperties;\n renderRow: (\n record: T,\n index: number,\n isLastInSection: boolean,\n isFirstInSection: boolean,\n virtualMeasure?: VirtualMeasureProps,\n tabStopIndex?: number,\n ) => React.ReactElement;\n /** Called with null on unmount. */\n registerHandle?: (cardKey: string, handle: VirtualCardHandle | null) => void;\n cardKey: string;\n /** The table's remembered roving-tabindex position, in global row indices. */\n rovingIndex: number;\n};\n\n/** One section card rendered as a TanStack Virtual window over its rows. */\nconst VirtualSectionCard = <T,>({\n records,\n startIndex,\n scrollElement,\n estimateRowHeight,\n style,\n renderRow,\n registerHandle,\n cardKey,\n rovingIndex,\n}: VirtualSectionCardProps<T>): React.ReactElement => {\n const cardRef = useRef<HTMLDivElement>(null);\n const [scrollMargin, setScrollMargin] = useState(0);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies(records.length): the card's offset must be re-measured when section sizes change — content above this card moves\n // biome-ignore lint/correctness/useExhaustiveDependencies(startIndex): a changed start index means the sections above grew or shrank, which moves this card\n useLayoutEffect(() => {\n const card = cardRef.current;\n if (!card || !scrollElement) {\n return;\n }\n const measure = (): void => {\n const margin =\n card.getBoundingClientRect().top -\n scrollElement.getBoundingClientRect().top +\n scrollElement.scrollTop;\n setScrollMargin((previous) => (Math.abs(previous - margin) < 1 ? previous : margin));\n };\n measure();\n if (typeof ResizeObserver === 'undefined') {\n return;\n }\n // A one-shot measure goes stale: sections above attach their virtualizers in a later\n // commit and this card does not re-render when they grow. Watch every preceding sibling\n // up to the scroll container, crossing shadow boundaries.\n const observer = new ResizeObserver(measure);\n let node: Element | null = card;\n while (node && node !== scrollElement) {\n let sibling = node.previousElementSibling;\n while (sibling) {\n observer.observe(sibling);\n sibling = sibling.previousElementSibling;\n }\n const parent: Element | null = node.parentElement;\n if (parent) {\n node = parent;\n } else {\n const root = node.getRootNode();\n node = root instanceof ShadowRoot ? root.host : null;\n }\n }\n return () => observer.disconnect();\n }, [scrollElement, records.length, startIndex]);\n\n const virtualizer = useVirtualizer({\n count: records.length,\n // State, not a ref: an ancestor's ref is not attached when this child's layout effects\n // run, so a ref would leave the virtualizer without a scroll element.\n getScrollElement: () => scrollElement,\n estimateSize: () => estimateRowHeight,\n overscan: VIRTUAL_OVERSCAN_ROWS,\n scrollMargin,\n });\n\n useEffect(() => {\n if (!registerHandle) {\n return;\n }\n registerHandle(cardKey, {\n startIndex,\n count: records.length,\n scrollToIndex: (localIndex) =>\n virtualizer.scrollToIndex(localIndex, { align: 'center' }),\n });\n return () => registerHandle(cardKey, null);\n }, [registerHandle, cardKey, startIndex, records.length, virtualizer]);\n\n const items = virtualizer.getVirtualItems();\n const totalSize = virtualizer.getTotalSize();\n\n // While the remembered row is outside the window every mounted row would be tabIndex -1 and\n // the table would leave the page tab order. Stand in with the nearest mounted row.\n const ownsRovingIndex = rovingIndex >= startIndex && rovingIndex < startIndex + records.length;\n const tabStopIndex =\n ownsRovingIndex && items.length > 0\n ? Math.min(\n Math.max(rovingIndex, startIndex + items[0].index),\n startIndex + items[items.length - 1].index,\n )\n : rovingIndex;\n const paddingTop = items.length > 0 ? items[0].start - scrollMargin : 0;\n const paddingBottom =\n items.length > 0 ? totalSize - (items[items.length - 1].end - scrollMargin) : 0;\n\n return (\n <div ref={cardRef} className=\"flex flex-col w-full\" style={style}>\n {paddingTop > 0 && (\n <div aria-hidden=\"true\" style={{ height: paddingTop, flexShrink: 0 }} />\n )}\n {items.map((item) =>\n renderRow(\n records[item.index],\n startIndex + item.index,\n item.index === records.length - 1,\n item.index === 0,\n { measureRef: virtualizer.measureElement, index: item.index },\n tabStopIndex,\n ),\n )}\n {paddingBottom > 0 && (\n <div aria-hidden=\"true\" style={{ height: paddingBottom, flexShrink: 0 }} />\n )}\n </div>\n );\n};\n\nconst computeScrollableMaxHeight = (\n scrollHeight: string | number,\n reservePagination: boolean,\n): string => {\n const reserved = reservePagination ? PAGINATION_RESERVED_HEIGHT : 0;\n if (typeof scrollHeight === 'number') {\n return `${Math.max(0, scrollHeight - reserved)}px`;\n }\n return `calc(${scrollHeight} - ${reserved}px)`;\n};\n\nconst cellWidthStyle = (column: TableColumnDefinition<unknown>): React.CSSProperties => {\n const width = column.width;\n if (width === undefined || width === null) {\n return {};\n }\n const value = typeof width === 'number' ? `${width}px` : width;\n // flexBasis keeps width columns the same size in header and body so they align.\n return { flexBasis: value, maxWidth: value };\n};\n\nconst fixedSlotStyle = (column: TableColumnDefinition<unknown>): React.CSSProperties => {\n const width = column.width;\n if (width === undefined || width === null) {\n return {};\n }\n const value = typeof width === 'number' ? `${width}px` : width;\n return { width: value, flexBasis: value };\n};\n\nconst ariaSortValue = (\n sortDirection: 'asc' | 'desc' | null | undefined,\n): 'ascending' | 'descending' | 'none' => {\n if (sortDirection === 'asc') {\n return 'ascending';\n }\n if (sortDirection === 'desc') {\n return 'descending';\n }\n return 'none';\n};\n\ntype ColumnAlign = TableColumnDefinition<unknown>['align'];\n\n/** A header's content is a flex row, so only `justify-*` moves it — `text-align` cannot. */\nconst alignJustifyClass = (align: ColumnAlign): string =>\n align === 'center' ? 'justify-center' : align === 'right' ? 'justify-end' : 'justify-start';\n\n/**\n * Detached only. Left keeps `justify-between` because that is where the detached variant already\n * draws its caret, and moving it would restyle tables that set no `align`.\n */\nconst sortableHeaderJustifyClass = (align: ColumnAlign): string =>\n align === 'center' ? 'justify-center' : align === 'right' ? 'justify-end' : 'justify-between';\n\nconst alignTextClass = (align: ColumnAlign): string =>\n align === 'center' ? 'text-center' : align === 'right' ? 'text-right' : 'text-left';\n\n/** A titleless fixed-width slot is the row-actions column, so an absent `align` stays trailing. */\nconst fixedSlotJustifyClass = (align: ColumnAlign): string =>\n align ? alignJustifyClass(align) : 'justify-end';\n\nconst HeaderInfo = ({ info }: { info: string }): React.ReactElement => (\n <Tooltip text={info} placement=\"top\">\n <InfoIcon\n size={13}\n className=\"shrink-0 text-[var(--malachite-text-secondary,#bbb)]\"\n />\n </Tooltip>\n);\n\nconst sortButtonProps = (\n title: React.ReactNode,\n onActivate?: () => void,\n): React.ButtonHTMLAttributes<HTMLButtonElement> => ({\n type: 'button',\n onClick: onActivate,\n 'aria-label': typeof title === 'string' ? `Sort by ${title}` : 'Sort column',\n});\n\ntype TableCellProps<T> = {\n column: TableColumnDefinition<T>;\n record: T;\n index: number;\n size: TableSize;\n paddingYClass: string;\n bordered: boolean;\n isFirstRow: boolean;\n isLastRow: boolean;\n isFirstColumn: boolean;\n isLastColumn: boolean;\n variantBackground: string | undefined;\n /** First column only: a box-shadow on the `<tr>` is unreliable under `border-collapse`. */\n showSelectedAccent?: boolean;\n /** Set on every cell of a selected row — in a `<table>` cells paint over the `<tr>`. */\n isSelected?: boolean;\n};\n\nconst TableCell = <T,>({\n column,\n record,\n index,\n size,\n paddingYClass,\n bordered,\n isFirstRow,\n isLastRow,\n isFirstColumn,\n isLastColumn,\n variantBackground,\n showSelectedAccent,\n isSelected,\n}: TableCellProps<T>): React.ReactElement => {\n const rawValue = (record as Record<string, unknown>)[column.dataIndex as string];\n const cellContent = column.render\n ? column.render(rawValue, record, index)\n : rawValue == null\n ? ''\n : String(rawValue);\n const titleText = column.ellipsis && isString(rawValue) ? rawValue : undefined;\n return (\n <td\n className={`\n table-cell px-4 ${paddingYClass} ${getSizeClasses(size)}\n ${column.ellipsis ? 'truncate overflow-hidden whitespace-nowrap' : ''}\n ${bordered ? 'table-cell-bordered' : ''}\n ${bordered && isFirstRow ? 'table-cell-bordered-top' : ''}\n ${bordered && isFirstColumn ? 'table-cell-bordered-left' : ''}\n ${bordered && isLastColumn ? 'table-cell-bordered-right' : ''}\n ${bordered && isFirstColumn && isFirstRow ? 'rounded-tl-lg' : ''}\n ${bordered && isLastColumn && isFirstRow ? 'rounded-tr-lg' : ''}\n ${bordered && isFirstColumn && isLastRow ? 'rounded-bl-lg' : ''}\n ${bordered && isLastColumn && isLastRow ? 'rounded-br-lg' : ''}\n ${alignTextClass(column.align)}\n `}\n style={{\n width: column.width,\n backgroundColor:\n variantBackground ??\n // Mirror the row's background, or the tint composites over the wrong opaque\n // base — they differ in dark mode.\n (isSelected\n ? bordered\n ? 'var(--malachite-table-borderedRow-background, #fff)'\n : 'var(--malachite-table-row-background, #fff)'\n : undefined),\n // Its own layer, so the tint composites over the cell instead of replacing it.\n backgroundImage: isSelected\n ? `linear-gradient(${SELECTED_ROW_BACKGROUND}, ${SELECTED_ROW_BACKGROUND})`\n : undefined,\n // Content pinning its own colour follows via the channel below.\n color: isSelected\n ? SELECTED_ROW_FOREGROUND\n : 'var(--malachite-table-row-foreground)',\n ...(isSelected ? SELECTED_TEXT_CONTEXT : {}),\n // Inset box-shadow, not `ring-*`: --tw-ring-* silently doesn't paint in a shadow root.\n boxShadow: showSelectedAccent ? `inset 2px 0 0 ${SELECTED_ROW_ACCENT}` : undefined,\n borderBottom: bordered\n ? undefined\n : isLastRow\n ? 'none'\n : '1px solid var(--malachite-table-row-border)',\n }}\n title={titleText}\n >\n {cellContent}\n </td>\n );\n};\n\ntype DetachedHeaderCellProps<T> = {\n column: TableColumnDefinition<T>;\n sortDirection: 'asc' | 'desc' | null;\n onSort?: () => void;\n};\n\nconst DetachedHeaderCell = <T,>({\n column,\n sortDirection,\n onSort,\n}: DetachedHeaderCellProps<T>): React.ReactElement => {\n const isSortable = Boolean(column.sorter);\n const titleIsEmpty = column.title === '' || column.title == null;\n const hasFixedWidth = titleIsEmpty && column.width !== undefined;\n\n if (hasFixedWidth) {\n return (\n <div\n className=\"h-full shrink-0\"\n style={fixedSlotStyle(column as TableColumnDefinition<unknown>)}\n />\n );\n }\n\n if (titleIsEmpty) {\n return (\n <div\n className=\"flex flex-[1_0_0] h-full min-w-0\"\n style={cellWidthStyle(column as TableColumnDefinition<unknown>)}\n />\n );\n }\n\n const titleNode =\n typeof column.title === 'string' ? (\n <p className=\"font-medium text-[13px] text-[#0a0a0a] tracking-[0.13px] whitespace-nowrap truncate\">\n {column.title}\n </p>\n ) : (\n column.title\n );\n\n const sortCaret = (\n <CaretDownIcon\n size={13}\n className={`shrink-0 transition-transform ${\n sortDirection ? 'text-[#0a0a0a]' : 'text-[#bbb]'\n } ${sortDirection === 'asc' ? 'rotate-180' : ''}`}\n />\n );\n\n if (!isSortable) {\n return (\n <div\n className={`flex flex-[1_0_0] items-center ${alignJustifyClass(column.align)} min-w-0 overflow-hidden px-4 py-3`}\n style={cellWidthStyle(column as TableColumnDefinition<unknown>)}\n >\n <div className=\"flex items-center gap-1 min-w-0\">\n {titleNode}\n {column.info && <HeaderInfo info={column.info} />}\n </div>\n </div>\n );\n }\n\n return (\n <div\n className=\"flex flex-[1_0_0] min-w-0 overflow-hidden\"\n style={cellWidthStyle(column as TableColumnDefinition<unknown>)}\n >\n <button\n {...sortButtonProps(column.title, onSort)}\n className={`flex flex-1 items-center ${sortableHeaderJustifyClass(column.align)} gap-1 min-w-0 px-4 py-3 cursor-pointer appearance-none bg-transparent border-0 ${alignTextClass(column.align)}`}\n >\n <div className=\"flex items-center gap-1 min-w-0\">\n {titleNode}\n {column.info && <HeaderInfo info={column.info} />}\n </div>\n {sortCaret}\n </button>\n </div>\n );\n};\n\ntype DetachedCellProps<T> = {\n column: TableColumnDefinition<T>;\n record: T;\n index: number;\n size: TableSize;\n paddingYClass: string;\n isSelected?: boolean;\n};\n\nconst DetachedCell = <T,>({\n column,\n record,\n index,\n size,\n paddingYClass,\n isSelected = false,\n}: DetachedCellProps<T>): React.ReactElement => {\n const rawValue = (record as Record<string, unknown>)[column.dataIndex as string];\n const cellContent = column.render\n ? column.render(rawValue, record, index)\n : rawValue == null\n ? ''\n : String(rawValue);\n const titleIsEmpty = column.title === '' || column.title == null;\n const hasFixedWidth = titleIsEmpty && column.width !== undefined;\n const isStringValue = isString(rawValue) && rawValue.length > 0;\n\n // Text channel — see the classic cell.\n const selectionStyle: React.CSSProperties = isSelected\n ? {\n color: SELECTED_ROW_FOREGROUND,\n ...SELECTED_TEXT_CONTEXT,\n }\n : {};\n\n if (hasFixedWidth) {\n return (\n <div\n className={`flex items-center ${fixedSlotJustifyClass(column.align)} shrink-0 overflow-hidden px-4 ${paddingYClass}`}\n style={{\n ...fixedSlotStyle(column as TableColumnDefinition<unknown>),\n ...selectionStyle,\n }}\n >\n {cellContent}\n </div>\n );\n }\n\n // Strings only: wrapping arbitrary JSX in a truncating span breaks layout.\n const cellBody =\n !column.render && isStringValue ? (\n <TruncatedTooltip text={rawValue}>{cellContent}</TruncatedTooltip>\n ) : (\n cellContent\n );\n\n return (\n <div\n className={`flex flex-[1_0_0] items-center min-w-0 overflow-hidden px-4 ${paddingYClass} ${getSizeClasses(size)} ${alignJustifyClass(column.align)}`}\n style={{\n ...cellWidthStyle(column as TableColumnDefinition<unknown>),\n ...selectionStyle,\n }}\n >\n {cellBody}\n </div>\n );\n};\n\nconst Table = <T = Record<string, unknown>>({\n columns,\n data,\n loading = false,\n error = false,\n errorTitle = 'Data unavailable',\n errorSubTitle = 'There was an issue retrieving the data. Please try again.',\n emptyTitle = 'No data',\n emptySubTitle = '',\n bordered = false,\n showHeader = true,\n rowKey = 'key',\n scrollHeight,\n size = 'small',\n rowDensity = 'default',\n layout = 'auto',\n headerVariant = 'inline',\n rowClassName,\n rowVariant,\n onRow,\n onClickRow,\n selectedRowKey,\n scrollSelectedIntoView = true,\n rowSelection,\n pagination,\n className = '',\n style,\n stickyHeaderTop,\n scrollX = false,\n rowSection,\n renderSectionDivider,\n onVisibleOrderChange,\n virtual = false,\n virtualRowHeightEstimate,\n virtualScrollElement = null,\n}: TableProps<T>) => {\n const bodyCellPaddingY = rowDensity === 'compact' ? 'py-1.5' : 'py-3';\n const [sortConfig, setSortConfig] = useState<{\n key: string;\n direction: 'asc' | 'desc';\n } | null>(null);\n\n const headerScrollRef = useRef<HTMLDivElement>(null);\n const bodyScrollRef = useRef<HTMLDivElement | null>(null);\n // Scoped lookups: querying the table's own root keeps sibling tables out.\n const containerRef = useRef<HTMLDivElement | null>(null);\n // A ref, not state: state here would re-render the whole table for no visual reason.\n const virtualCardsRef = useRef<Map<string, VirtualCardHandle>>(new Map());\n const registerVirtualCard = useCallback(\n (cardKey: string, handle: VirtualCardHandle | null): void => {\n if (handle) {\n virtualCardsRef.current.set(cardKey, handle);\n } else {\n virtualCardsRef.current.delete(cardKey);\n }\n },\n [],\n );\n\n // Roving tabindex, held in state so the position survives the virtualiser unmounting the\n // focused row.\n const tableId = useId();\n const [focusedRowIndex, setFocusedRowIndex] = useState(0);\n\n const isVirtual = virtual && headerVariant === 'detached';\n const virtualEstimate = virtualRowHeightEstimate ?? DEFAULT_VIRTUAL_ROW_HEIGHT;\n // State, so virtual cards re-render and attach their virtualizers once it exists.\n const [bodyScrollElement, setBodyScrollElement] = useState<HTMLDivElement | null>(null);\n // Stable identity so React doesn't detach/reattach every render.\n const bodyScrollRefCallback = useCallback((element: HTMLDivElement | null) => {\n bodyScrollRef.current = element;\n if (element) {\n setBodyScrollElement((previous) => (previous === element ? previous : element));\n }\n }, []);\n const virtualScroller = isVirtual ? (virtualScrollElement ?? bodyScrollElement) : null;\n // With an external scroller the body must not compete for scrolling.\n const bodyOwnsScroll = !(isVirtual && virtualScrollElement);\n\n const isStickyHeader =\n headerVariant === 'detached' &&\n stickyHeaderTop !== undefined &&\n showHeader &&\n !scrollHeight &&\n (!isVirtual || !bodyOwnsScroll);\n\n // The header height exists only to offset the selection reveal, so a table that never\n // selects must not pay for the observer or its state updates (ENG-1166, ENG-1353).\n const usesSelection = selectedRowKey !== undefined && selectedRowKey !== null;\n\n const [stickyHeaderHeight, setStickyHeaderHeight] = useState(0);\n useEffect(() => {\n const header = headerScrollRef.current;\n if (!header || !isStickyHeader || !usesSelection || typeof ResizeObserver === 'undefined') {\n setStickyHeaderHeight(0);\n return;\n }\n // Border box: the header occludes rows with its padding too. Re-reading the element\n // would force the layout this observer avoids (ENG-1166); jsdom has no `borderBoxSize`.\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0];\n const height = entry?.borderBoxSize?.[0]?.blockSize ?? entry?.contentRect.height ?? 0;\n setStickyHeaderHeight((previous) =>\n Math.abs(previous - height) < 1 ? previous : height,\n );\n });\n observer.observe(header);\n return () => observer.disconnect();\n }, [isStickyHeader, usesSelection]);\n\n // scrollIntoView ignores sticky overlays and parks rows under them; reserve the occluded\n // strip. `stickyHeaderTop` covers what the consumer stacks above, this adds the header.\n const rowScrollMarginTop = isStickyHeader\n ? (stickyHeaderTop ?? 0) + stickyHeaderHeight\n : undefined;\n\n const { sortedData, sectionDividers } = useMemo(() => {\n // dataIndex, not the render-only key.\n const sortRecords = (records: T[]): T[] => {\n if (!sortConfig) return records;\n\n const sortColumn = columns.find((col) => col.key === sortConfig.key);\n if (!sortColumn) return records;\n\n if (typeof sortColumn.sorter === 'function') {\n const sorted = [...records].sort(sortColumn.sorter);\n return sortConfig.direction === 'asc' ? sorted : sorted.reverse();\n }\n\n const field = (sortColumn.dataIndex as string) ?? sortConfig.key;\n return [...records].sort((a, b) => {\n const aComparable = (a as Record<string, unknown>)[field] as string | number;\n const bComparable = (b as Record<string, unknown>)[field] as string | number;\n\n if (aComparable < bComparable) {\n return sortConfig.direction === 'asc' ? -1 : 1;\n }\n if (aComparable > bComparable) {\n return sortConfig.direction === 'asc' ? 1 : -1;\n }\n return 0;\n });\n };\n\n if (!rowSection) {\n return {\n sortedData: sortRecords(data),\n sectionDividers: new Map<number, { key: string; records: T[] }>(),\n };\n }\n\n const groups: { key: string; records: T[] }[] = [];\n const groupIndexByKey = new Map<string, number>();\n for (const record of data) {\n const sectionKey = rowSection(record);\n let groupIndex = groupIndexByKey.get(sectionKey);\n if (groupIndex === undefined) {\n groupIndex = groups.length;\n groupIndexByKey.set(sectionKey, groupIndex);\n groups.push({ key: sectionKey, records: [] });\n }\n groups[groupIndex].records.push(record);\n }\n\n const rows: T[] = [];\n const dividers = new Map<number, { key: string; records: T[] }>();\n for (const group of groups) {\n const sectionRows = sortRecords(group.records);\n dividers.set(rows.length, { key: group.key, records: sectionRows });\n rows.push(...sectionRows);\n }\n return { sortedData: rows, sectionDividers: dividers };\n }, [data, sortConfig, columns, rowSection]);\n\n const handleSort = (key: string) => {\n setSortConfig((prev) => {\n if (prev?.key === key) {\n return prev.direction === 'asc' ? { key, direction: 'desc' } : null;\n }\n return { key, direction: 'asc' };\n });\n };\n\n // Not a useCallback reading a ref: writing the prop into a ref during render makes render\n // impure, and React may discard render work.\n const getRowKey = (record: T, index: number): string => {\n if (typeof rowKey === 'function') {\n return rowKey(record);\n }\n // ?? not ||: a falsy-but-real key (id 0, '') must keep its identity.\n return String((record as Record<string, unknown>)[rowKey] ?? index);\n };\n // Stands in for `getRowKey` below: an inline `rowKey={(r) => r.id}` changes identity every\n // render, costing a findIndex over the dataset each time. A function rowKey is taken as pure.\n const rowKeyDep = typeof rowKey === 'function' ? null : rowKey;\n\n // By key, not identity: an inline `data={rows.filter(…)}` would report every render.\n const reportedRowOrderRef = useRef<string[] | undefined>(undefined);\n const keylessIdsRef = useRef<KeylessIds | undefined>(undefined);\n // biome-ignore lint/correctness/useExhaustiveDependencies: rowKeyDep deliberately stands in for rowKey — see the note on rowKeyDep above\n useEffect(() => {\n if (!onVisibleOrderChange) {\n return;\n }\n keylessIdsRef.current ??= { ids: new WeakMap(), next: 0 };\n const rowOrder = visibleRowOrder(sortedData, rowKey, keylessIdsRef.current);\n const reported = reportedRowOrderRef.current;\n if (reported && sameRowOrder(reported, rowOrder)) {\n return;\n }\n reportedRowOrderRef.current = rowOrder;\n onVisibleOrderChange(sortedData);\n }, [sortedData, rowKeyDep, onVisibleOrderChange]);\n\n // Clamped so a shrinking dataset can't leave every row untabbable.\n const rovingIndex = Math.min(focusedRowIndex, Math.max(0, sortedData.length - 1));\n\n // Sorted-order position; with no resolvable `rowKey`, the `onClickRow` index.\n // biome-ignore lint/correctness/useExhaustiveDependencies: rowKeyDep deliberately stands in for getRowKey — see the note on rowKeyDep above\n const selectedIndex = useMemo(() => {\n if (selectedRowKey === undefined || selectedRowKey === null) {\n return -1;\n }\n const target = String(selectedRowKey);\n return sortedData.findIndex((record, index) => getRowKey(record, index) === target);\n }, [selectedRowKey, sortedData, rowKeyDep]);\n\n // Tabbing in should land on the highlighted row. No focusOriginRef, so focus is not stolen.\n useEffect(() => {\n if (selectedIndex >= 0) {\n setFocusedRowIndex(selectedIndex);\n }\n }, [selectedIndex]);\n\n // Holds what was actually revealed, not the last key seen, so every not-ready path below\n // leaves it open to retry. Keyed on index too, since a sort moves a record without its key.\n const lastScrolledRef = useRef<{ key: React.Key; index: number } | undefined>(undefined);\n useEffect(() => {\n // Clearing releases the latch: re-selecting the same record must scroll again.\n if (selectedRowKey === undefined || selectedRowKey === null) {\n lastScrolledRef.current = undefined;\n return;\n }\n if (!scrollSelectedIntoView) {\n return;\n }\n if (selectedIndex < 0) {\n return;\n }\n const last = lastScrolledRef.current;\n if (last && last.key === selectedRowKey && last.index === selectedIndex) {\n return;\n }\n if (loading || error) {\n return;\n }\n // The scroll element arrives a commit later, so the virtualizers would drop this.\n if (isVirtual && !virtualScroller) {\n return;\n }\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n // The header height lands after this flush. Reveal anyway, but hold the latch open so\n // the measured re-run can place it properly.\n const scrollMarginPending = isStickyHeader && stickyHeaderHeight === 0;\n\n // Scoped by table id: a `column.render` can nest a whole Table inside a cell.\n const rowAt = (index: number) =>\n container.querySelector<HTMLElement>(\n `[data-table-id=\"${tableId}\"][data-row-index=\"${index}\"]`,\n );\n\n // `block: 'nearest'` no-ops when already visible, so a click never moves the viewport.\n // One element per change — interaction-time, not the mount-path read ENG-1166 banned.\n const reveal = (row: HTMLElement): void => {\n // scrollIntoView resolves `inline` too, and under `scrollX` a row is wider than the\n // port, so `nearest` would scroll 1px and hide the card's border.\n const body = bodyScrollRef.current;\n const outer = virtualScrollElement;\n const bodyLeft = body?.scrollLeft;\n const outerLeft = outer?.scrollLeft;\n row.scrollIntoView({ block: 'nearest', inline: 'nearest' });\n if (body && bodyLeft !== undefined) {\n body.scrollLeft = bodyLeft;\n }\n if (outer && outerLeft !== undefined) {\n outer.scrollLeft = outerLeft;\n }\n if (!scrollMarginPending) {\n lastScrolledRef.current = { key: selectedRowKey, index: selectedIndex };\n }\n };\n\n const mounted = rowAt(selectedIndex);\n if (mounted) {\n reveal(mounted);\n return;\n }\n\n // Not mounted: under virtualisation, ask the owning card's virtualizer for it.\n if (!isVirtual) {\n return;\n }\n const card = [...virtualCardsRef.current.values()].find(\n (entry) =>\n selectedIndex >= entry.startIndex && selectedIndex < entry.startIndex + entry.count,\n );\n if (!card) {\n return;\n }\n card.scrollToIndex(selectedIndex - card.startIndex);\n\n // scrollToIndex positions from estimated heights, so correct once the real row measures.\n let frame = 0;\n let attempts = 0;\n const correct = (): void => {\n const row = rowAt(selectedIndex);\n if (row) {\n reveal(row);\n return;\n }\n if (++attempts < VIRTUAL_SCROLL_CORRECTION_FRAMES) {\n frame = requestAnimationFrame(correct);\n }\n };\n frame = requestAnimationFrame(correct);\n return () => cancelAnimationFrame(frame);\n }, [\n selectedRowKey,\n selectedIndex,\n isVirtual,\n virtualScroller,\n virtualScrollElement,\n isStickyHeader,\n stickyHeaderHeight,\n loading,\n error,\n tableId,\n scrollSelectedIntoView,\n ]);\n\n // Set only for user-driven moves, so the effect below doesn't steal focus on an\n // unrelated re-render.\n const focusOriginRef = useRef<HTMLElement | null>(null);\n\n const moveRowFocus = (from: HTMLElement, toIndex: number): void => {\n focusOriginRef.current = from;\n setFocusedRowIndex(Math.min(Math.max(0, toIndex), sortedData.length - 1));\n };\n\n // Focus after the commit, not in a rAF: the new row only becomes the tabbable one\n // once React has re-rendered. Scoped by table id so sibling tables can't steal it.\n useLayoutEffect(() => {\n const origin = focusOriginRef.current;\n if (!origin) {\n return;\n }\n focusOriginRef.current = null;\n const root = origin.getRootNode() as ParentNode;\n const rowAt = (index: number) =>\n root.querySelector<HTMLElement>(\n `[data-table-id=\"${tableId}\"][data-row-index=\"${index}\"]`,\n );\n\n const target = rowAt(rovingIndex);\n if (target) {\n target.focus();\n return;\n }\n\n // Target unmounted (virtualised, or windowed data). Land on the nearest rendered\n // row — otherwise nothing is tabbable and the table drops out of the tab order.\n const rendered = root.querySelectorAll<HTMLElement>(\n `[data-table-id=\"${tableId}\"][data-row-index]`,\n );\n const nearest = rovingIndex > 0 ? rendered[rendered.length - 1] : rendered[0];\n if (nearest) {\n setFocusedRowIndex(Number(nearest.dataset.rowIndex));\n nearest.focus();\n }\n }, [rovingIndex, tableId]);\n\n const rowKeyDown =\n (index: number, activate?: () => void) =>\n (event: React.KeyboardEvent<HTMLElement>): void => {\n const step = { ArrowDown: 1, ArrowUp: -1 }[event.key];\n if (step !== undefined) {\n event.preventDefault();\n moveRowFocus(event.currentTarget, index + step);\n return;\n }\n // Home/End only when every row is mounted; under virtualisation the target row does\n // not exist yet, so falling through lets the scroll container jump natively.\n if (!isVirtual && (event.key === 'Home' || event.key === 'End')) {\n event.preventDefault();\n moveRowFocus(event.currentTarget, event.key === 'Home' ? 0 : sortedData.length - 1);\n return;\n }\n // Enter only: neither row path claims button semantics, so Space scrolls.\n if (activate) {\n activateOnEnterOrSpace(event, activate, 'enter');\n }\n };\n\n if (headerVariant === 'detached') {\n const scrollMinWidth = scrollX\n ? computeScrollMinWidth(columns as TableColumns<unknown>)\n : 0;\n const rowMinWidthStyle: React.CSSProperties = scrollX ? { minWidth: scrollMinWidth } : {};\n\n // flexShrink 0: as a flex item of a height-bounded body, an overflow-hidden card would\n // shrink-to-fit and clip its rows instead of letting the body scroll.\n const sectionCardStyle: React.CSSProperties = {\n border: '1px solid var(--malachite-card-border, #e8e8e8)',\n borderRadius: SECTION_CARD_RADIUS,\n overflow: 'hidden',\n flexShrink: 0,\n ...rowMinWidthStyle,\n };\n\n const renderRow = (\n record: T,\n index: number,\n isLastInSection = false,\n isFirstInSection = false,\n virtualMeasure?: VirtualMeasureProps,\n // Virtual cards substitute the nearest mounted row; elsewhere all rows are mounted.\n tabStopIndex: number = rovingIndex,\n ): React.ReactElement => {\n const key = getRowKey(record, index);\n const rowActions = onRow?.(record, index) || {};\n const variant = rowVariant?.(record, index);\n const isSelected = index === selectedIndex;\n const handleClick =\n onClickRow || rowActions.onClick\n ? () => {\n onClickRow?.(record, index);\n rowActions.onClick?.(record, index);\n }\n : undefined;\n const isClickable = Boolean(handleClick);\n const rowBorder = isLastInSection ? {} : ROW_BORDER_STYLE;\n return (\n <div\n key={key}\n ref={virtualMeasure?.measureRef}\n data-index={virtualMeasure?.index}\n data-table-id={tableId}\n data-row-index={index}\n // No `role=\"button\"`: it takes presentational children, flattening the cells\n // and stripping a nested ActionMenu from the a11y tree.\n aria-current={isSelected ? 'true' : undefined}\n tabIndex={isClickable ? (index === tabStopIndex ? 0 : -1) : undefined}\n onKeyDown={isClickable ? rowKeyDown(index, handleClick) : undefined}\n className={`\n group bg-[var(--malachite-table-row-background,#fff)] flex min-h-10 items-stretch relative w-full\n ${isClickable ? `cursor-pointer hover:bg-[var(--malachite-table-row-hover-background,#fafafa)] ${FOCUS_RING_INSET}` : ''}\n ${rowClassName?.(record, index) || ''}\n `}\n style={{\n ...rowBorder,\n ...rowMinWidthStyle,\n scrollMarginTop: rowScrollMarginTop,\n // Echo the card's clip, or it cuts the accent bar's end into a stub.\n ...(isFirstInSection\n ? {\n borderTopLeftRadius: SECTION_CARD_RADIUS,\n borderTopRightRadius: SECTION_CARD_RADIUS,\n }\n : {}),\n ...(isLastInSection\n ? {\n borderBottomLeftRadius: SECTION_CARD_RADIUS,\n borderBottomRightRadius: SECTION_CARD_RADIUS,\n }\n : {}),\n // Set unconditionally it would beat `hover:bg-*` on every row.\n ...(isSelected || variant\n ? {\n backgroundColor: variant\n ? `var(--malachite-table-row-variant-${variant}-background)`\n : 'var(--malachite-table-row-background, #fff)',\n }\n : {}),\n ...(isSelected\n ? {\n // backgroundImage: as a colour the tint would composite against\n // the card behind the row.\n backgroundImage: `linear-gradient(${SELECTED_ROW_BACKGROUND}, ${SELECTED_ROW_BACKGROUND})`,\n // Inset box-shadow, not `ring-*` — see the classic cell.\n boxShadow: `inset 2px 0 0 ${SELECTED_ROW_ACCENT}`,\n }\n : {}),\n }}\n onClick={\n handleClick\n ? (event) => {\n if (!isFromInteractiveDescendant(event)) {\n handleClick();\n }\n }\n : undefined\n }\n onDoubleClick={\n rowActions.onDoubleClick\n ? () => rowActions.onDoubleClick?.(record, index)\n : undefined\n }\n onContextMenu={\n rowActions.onContextMenu\n ? () => rowActions.onContextMenu?.(record, index)\n : undefined\n }\n onMouseEnter={\n rowActions.onMouseEnter\n ? () => rowActions.onMouseEnter?.(record, index)\n : undefined\n }\n onMouseLeave={\n rowActions.onMouseLeave\n ? () => rowActions.onMouseLeave?.(record, index)\n : undefined\n }\n >\n {columns.map((column) => (\n <DetachedCell<T>\n key={column.key}\n column={column}\n record={record}\n paddingYClass={bodyCellPaddingY}\n index={index}\n size={size}\n isSelected={isSelected}\n />\n ))}\n </div>\n );\n };\n\n const renderSkeletonRow = (index: number, isLast = false): React.ReactElement => (\n <div\n key={`skeleton-${index}`}\n className=\"bg-white flex min-h-10 items-stretch w-full\"\n // Last row: no bottom border; the card border closes the section.\n style={{ ...(isLast ? {} : ROW_BORDER_STYLE), ...rowMinWidthStyle }}\n >\n {columns.map((column) => {\n // Mirror DetachedCell's widths and placement so skeleton columns don't jump\n // on load.\n const titleIsEmpty = column.title === '' || column.title == null;\n const hasFixedWidth = titleIsEmpty && column.width !== undefined;\n if (hasFixedWidth) {\n return (\n <div\n key={column.key}\n className={`flex items-center ${fixedSlotJustifyClass(column.align)} shrink-0 overflow-clip px-4 ${bodyCellPaddingY}`}\n style={fixedSlotStyle(column as TableColumnDefinition<unknown>)}\n >\n <div className=\"h-3 bg-gray-200 rounded animate-pulse w-2/5\"></div>\n </div>\n );\n }\n return (\n <div\n key={column.key}\n className={`flex flex-[1_0_0] items-center ${alignJustifyClass(column.align)} min-w-0 overflow-clip px-4 ${bodyCellPaddingY}`}\n style={cellWidthStyle(column as TableColumnDefinition<unknown>)}\n >\n <div className=\"h-3 bg-gray-200 rounded animate-pulse w-3/5\"></div>\n </div>\n );\n })}\n </div>\n );\n\n const headerRow = showHeader ? (\n <div className=\"flex min-h-10 items-stretch w-full\" style={rowMinWidthStyle}>\n {columns.map((column) => (\n <DetachedHeaderCell<T>\n key={column.key}\n column={column}\n sortDirection={sortConfig?.key === column.key ? sortConfig.direction : null}\n onSort={column.sorter ? () => handleSort(column.key) : undefined}\n />\n ))}\n </div>\n ) : null;\n\n return (\n <div\n ref={containerRef}\n className={`w-full ${className}`}\n style={{ ...FOREGROUND_RESET, ...style }}\n >\n <div\n className={`bg-[var(--malachite-table-background,#f7f7f7)] flex flex-col items-start ${isStickyHeader ? '' : 'overflow-clip'} p-[4px] relative rounded-xl w-full`}\n >\n {showHeader && (\n <div\n ref={headerScrollRef}\n onScroll={\n scrollX\n ? () =>\n syncScroll(headerScrollRef.current, bodyScrollRef.current)\n : undefined\n }\n style={{\n ...(isStickyHeader\n ? {\n position: 'sticky',\n top: stickyHeaderTop,\n zIndex: 8,\n backgroundColor:\n 'var(--malachite-table-header-background, #f7f7f7)',\n marginInline: -DETACHED_CARD_PADDING,\n width: `calc(100% + ${DETACHED_CARD_PADDING * 2}px)`,\n paddingInline: DETACHED_CARD_PADDING,\n // Vertically too, or the card's top frame sits above\n // the docked header and rows scroll through it.\n marginTop: -DETACHED_CARD_PADDING,\n paddingTop: DETACHED_CARD_PADDING,\n }\n : { width: '100%' }),\n ...(scrollX ? { overflowX: 'auto', scrollbarWidth: 'none' } : {}),\n }}\n >\n {isStickyHeader && <StickyHeaderCornerCap />}\n {headerRow}\n </div>\n )}\n\n <div\n ref={bodyScrollRefCallback}\n onScroll={\n scrollX\n ? () => syncScroll(bodyScrollRef.current, headerScrollRef.current)\n : undefined\n }\n className={`flex flex-col items-start ${scrollX ? 'overflow-x-auto' : 'overflow-x-clip'} ${bodyOwnsScroll ? 'overflow-y-auto' : 'overflow-y-visible'} w-full`}\n style={{\n // Firefox + modern Chromium only; older Webkit keeps its default.\n scrollbarWidth: 'thin',\n scrollbarColor:\n 'var(--malachite-text-placeholder, rgb(187, 187, 187)) transparent',\n // With an external virtual scroller the body is overflow-visible and\n // a bounded box would overlap content below it.\n ...(scrollHeight && bodyOwnsScroll\n ? {\n maxHeight: computeScrollableMaxHeight(\n scrollHeight,\n !!pagination,\n ),\n }\n : {}),\n }}\n >\n {error ? (\n <div className=\"flex flex-col w-full\" style={sectionCardStyle}>\n <div className=\"flex flex-col items-center justify-center bg-white w-full py-12\">\n <div className=\"text-[var(--malachite-text-secondary)] text-[14px] font-medium mb-1\">\n {errorTitle}\n </div>\n <div className=\"text-[var(--malachite-text-secondary)] text-[13px]\">\n {errorSubTitle}\n </div>\n </div>\n </div>\n ) : loading ? (\n <div className=\"flex flex-col w-full\" style={sectionCardStyle}>\n {(() => {\n const count = pagination?.pageSize\n ? Math.min(pagination.pageSize, 10)\n : 5;\n return Array.from({ length: count }).map((_, i) =>\n renderSkeletonRow(i, i === count - 1),\n );\n })()}\n </div>\n ) : sortedData.length === 0 ? (\n <div className=\"flex flex-col w-full\" style={sectionCardStyle}>\n <div className=\"flex flex-col items-center justify-center bg-white w-full py-12\">\n <div className=\"text-[var(--malachite-text-secondary)] text-[14px] font-medium\">\n {emptyTitle}\n </div>\n {emptySubTitle && (\n <div className=\"text-[var(--malachite-text-secondary)] text-[13px] mt-1\">\n {emptySubTitle}\n </div>\n )}\n </div>\n </div>\n ) : (\n (() => {\n const renderCard = (\n records: T[],\n startIndex: number,\n cardKey: string,\n ): React.ReactElement => {\n if (isVirtual) {\n return (\n <VirtualSectionCard<T>\n key={`section-card-${cardKey}`}\n cardKey={cardKey}\n records={records}\n startIndex={startIndex}\n scrollElement={virtualScroller}\n estimateRowHeight={virtualEstimate}\n style={sectionCardStyle}\n renderRow={renderRow}\n registerHandle={registerVirtualCard}\n rovingIndex={rovingIndex}\n />\n );\n }\n return (\n <div\n key={`section-card-${cardKey}`}\n className=\"flex flex-col w-full\"\n style={sectionCardStyle}\n >\n {records.map((record, i) =>\n renderRow(\n record,\n startIndex + i,\n i === records.length - 1,\n i === 0,\n ),\n )}\n </div>\n );\n };\n\n if (sectionDividers.size === 0) {\n return renderCard(sortedData, 0, 'all');\n }\n\n const starts = [...sectionDividers.keys()].sort((a, b) => a - b);\n return starts.map((start, i) => {\n const section = sectionDividers.get(start);\n if (!section) {\n return null;\n }\n const end =\n i + 1 < starts.length ? starts[i + 1] : sortedData.length;\n const records = sortedData.slice(start, end);\n const dividerContent = renderSectionDivider?.(\n section.key,\n section.records,\n );\n return (\n <React.Fragment key={`section-${section.key}`}>\n {dividerContent != null ? (\n <div\n className=\"table-section-divider\"\n style={rowMinWidthStyle}\n >\n {dividerContent}\n </div>\n ) : null}\n {renderCard(records, start, section.key)}\n </React.Fragment>\n );\n });\n })()\n )}\n </div>\n </div>\n\n {pagination && !loading && (\n <TablePagination\n current={pagination.current ?? 1}\n pageSize={pagination.pageSize ?? 10}\n total={pagination.total ?? 0}\n showSizeChanger={pagination.showSizeChanger}\n showQuickJumper={pagination.showQuickJumper}\n showTotal={pagination.showTotal}\n pageSizeOptions={pagination.pageSizeOptions}\n onChange={pagination.onChange}\n onShowSizeChange={pagination.onShowSizeChange}\n />\n )}\n </div>\n );\n }\n\n const renderHeader = (column: TableColumnDefinition<T>) => {\n const isSortable = column.sorter;\n const isActive = sortConfig?.key === column.key;\n const sortDirection = isActive ? sortConfig?.direction : null;\n\n const headerContent = (\n <div className={`flex items-center gap-2 ${alignJustifyClass(column.align)}`}>\n <span>{column.title}</span>\n {column.info && <HeaderInfo info={column.info} />}\n {isSortable && (\n <div className=\"flex flex-col\">\n <CaretUpIcon\n size={12}\n className={sortDirection === 'asc' ? 'text-blue-600' : 'text-gray-400'}\n />\n <CaretDownIcon\n size={12}\n className={`-mt-1 ${sortDirection === 'desc' ? 'text-blue-600' : 'text-gray-400'}`}\n />\n </div>\n )}\n </div>\n );\n\n return (\n <th\n key={column.key}\n className={`\n table-header table-cell px-4 py-3 font-semibold border-0 first:rounded-tl-lg last:rounded-tr-lg\n ${getSizeClasses(size)}\n ${alignTextClass(column.align)}\n `}\n style={{ width: column.width }}\n aria-sort={isSortable ? ariaSortValue(sortDirection) : undefined}\n >\n {isSortable ? (\n <button\n {...sortButtonProps(column.title, () => handleSort(column.key))}\n className={`flex w-full items-center ${alignJustifyClass(column.align)} cursor-pointer hover:opacity-80 appearance-none bg-transparent border-0 p-0 font-semibold text-inherit ${alignTextClass(column.align)}`}\n >\n {headerContent}\n </button>\n ) : (\n headerContent\n )}\n </th>\n );\n };\n\n if (error) {\n return (\n <div className=\"w-full\" style={{ ...FOREGROUND_RESET, ...style }}>\n <div\n className=\"overflow-x-auto\"\n style={{\n ...(scrollHeight ? { maxHeight: scrollHeight } : {}),\n }}\n >\n <table className=\"w-full border-collapse rounded-lg overflow-hidden\">\n {showHeader && (\n <thead>\n <tr>\n {columns.map((column) => (\n <th\n key={column.key}\n className={`\n ${bordered ? 'table-header' : 'table-header'} table-cell px-4 py-3 font-semibold border-0 first:rounded-tl-lg last:rounded-tr-lg\n ${bordered ? 'table-cell-bordered table-cell-bordered-top' : ''}\n ${bordered && column === columns[0] ? 'table-cell-bordered-left' : ''}\n ${bordered && column === columns[columns.length - 1] ? 'table-cell-bordered-right' : ''}\n ${getSizeClasses(size)}\n ${alignTextClass(column.align)}\n `}\n style={{ width: column.width }}\n >\n <div\n className={`flex items-center gap-2 ${alignJustifyClass(column.align)}`}\n >\n <span>{column.title}</span>\n {column.info && <HeaderInfo info={column.info} />}\n </div>\n </th>\n ))}\n </tr>\n </thead>\n )}\n <tbody>\n <tr>\n <td\n colSpan={columns.length + (rowSelection ? 1 : 0)}\n className=\"px-4 py-12 text-center\"\n >\n <div className=\"flex flex-col items-center justify-center\">\n <div className=\"table-error-icon w-12 h-12 rounded-full flex items-center justify-center mb-4\">\n <WarningTriangleIcon size={24} />\n </div>\n <div className=\"table-error-title text-lg font-semibold mb-2\">\n {errorTitle}\n </div>\n <div className=\"table-error-subtitle text-sm\">\n {errorSubTitle}\n </div>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n );\n }\n\n return (\n <div\n ref={containerRef}\n className={`w-full ${className}`}\n style={{ ...FOREGROUND_RESET, ...style }}\n >\n <div\n className={`overflow-hidden rounded-lg ${bordered ? 'table-bordered-container' : 'table-container-border'}`}\n data-bordered={bordered ? 'true' : 'false'}\n >\n <div\n className=\"overflow-x-auto\"\n style={{\n ...(scrollHeight ? { maxHeight: scrollHeight } : {}),\n }}\n >\n <table\n className={`w-full ${layout === 'fixed' || columns.some((col) => col.width) ? 'table-fixed' : 'table-auto'} ${bordered ? 'border-separate table-bordered' : 'border-collapse'} rounded-lg overflow-hidden`}\n style={{ borderSpacing: bordered ? '0' : '0' }}\n >\n {showHeader && (\n <thead>\n <tr>{columns.map((column) => renderHeader(column))}</tr>\n </thead>\n )}\n <tbody>\n {loading ? (\n Array.from({ length: 5 }).map((_, index) => (\n <tr\n key={index}\n className={`table-row ${bordered ? 'table-row-bordered' : ''}`}\n >\n {columns.map((column) => (\n <td\n key={column.key}\n className={`table-cell px-4 ${bodyCellPaddingY} text-left ${getSizeClasses(size)}`}\n style={{ width: column.width }}\n >\n <div className=\"h-4 bg-gray-200 rounded animate-pulse\"></div>\n </td>\n ))}\n </tr>\n ))\n ) : sortedData.length === 0 ? (\n <tr>\n <td\n colSpan={columns.length + (rowSelection ? 1 : 0)}\n className=\"px-4 py-12 text-center\"\n >\n <div className=\"flex flex-col items-center justify-center\">\n <div className=\"text-[var(--malachite-text-secondary)] text-[14px] font-medium\">\n {emptyTitle}\n </div>\n {emptySubTitle && (\n <div className=\"text-[var(--malachite-text-secondary)] text-[13px] mt-1\">\n {emptySubTitle}\n </div>\n )}\n </div>\n </td>\n </tr>\n ) : (\n sortedData.map((record, index) => {\n const key = getRowKey(record, index);\n const rowActions = onRow?.(record, index) || {};\n const variant = rowVariant?.(record, index);\n\n const isFirstRow = index === 0;\n const isLastRow = index === data.length - 1;\n\n const isSelected = index === selectedIndex;\n const variantBackground = variant\n ? `var(--malachite-table-row-variant-${variant}-background)`\n : undefined;\n\n const handleRowClick =\n onClickRow || rowActions.onClick\n ? () => {\n onClickRow?.(record, index);\n rowActions.onClick?.(record, index);\n }\n : undefined;\n\n return (\n // Keeps `row` semantics: `role=\"button\"` would strip the table\n // structure from screen readers.\n <tr\n key={key}\n data-table-id={tableId}\n data-row-index={index}\n // `aria-selected` needs a role this row lacks.\n aria-current={isSelected ? 'true' : undefined}\n tabIndex={\n handleRowClick\n ? index === rovingIndex\n ? 0\n : -1\n : undefined\n }\n onKeyDown={\n handleRowClick\n ? rowKeyDown(index, handleRowClick)\n : undefined\n }\n // Drops hover:opacity-80: opacity is not a background,\n // so the cells can't beat it and the row fades below AA.\n className={`\n ${bordered ? 'table-row-bordered' : `table-row ${isSelected ? '' : 'hover:opacity-80'}`}\n ${rowClassName?.(record, index) || ''}\n ${handleRowClick ? `cursor-pointer ${FOCUS_RING_INSET}` : ''}\n `}\n onClick={\n handleRowClick\n ? (event) => {\n if (!isFromInteractiveDescendant(event)) {\n handleRowClick();\n }\n }\n : undefined\n }\n onDoubleClick={\n rowActions.onDoubleClick\n ? () =>\n rowActions.onDoubleClick?.(record, index)\n : undefined\n }\n onContextMenu={\n rowActions.onContextMenu\n ? () =>\n rowActions.onContextMenu?.(record, index)\n : undefined\n }\n onMouseEnter={\n rowActions.onMouseEnter\n ? () => rowActions.onMouseEnter?.(record, index)\n : undefined\n }\n onMouseLeave={\n rowActions.onMouseLeave\n ? () => rowActions.onMouseLeave?.(record, index)\n : undefined\n }\n >\n {columns.map((column) => {\n const isFirstColumn = column === columns[0];\n const isLastColumn =\n column === columns[columns.length - 1];\n\n return (\n <TableCell<T>\n key={column.key}\n column={column}\n record={record}\n index={index}\n size={size}\n paddingYClass={bodyCellPaddingY}\n bordered={bordered}\n isFirstRow={isFirstRow}\n isLastRow={isLastRow}\n isFirstColumn={isFirstColumn}\n isLastColumn={isLastColumn}\n variantBackground={variantBackground}\n isSelected={isSelected}\n showSelectedAccent={\n isSelected && isFirstColumn\n }\n />\n );\n })}\n </tr>\n );\n })\n )}\n </tbody>\n </table>\n </div>\n </div>\n\n {pagination && !loading && (\n <TablePagination\n current={pagination.current ?? 1}\n pageSize={pagination.pageSize ?? 10}\n total={pagination.total ?? 0}\n showSizeChanger={pagination.showSizeChanger}\n showQuickJumper={pagination.showQuickJumper}\n showTotal={pagination.showTotal}\n pageSizeOptions={pagination.pageSizeOptions}\n onChange={pagination.onChange}\n onShowSizeChange={pagination.onShowSizeChange}\n />\n )}\n </div>\n );\n};\n\nexport default Table;\n"],"names":["DEFAULT_SCROLL_COL_WIDTH","sameRowOrder","a","b","key","index","KEYLESS_ID_PREFIX","keylessId","record","registry","seen","id","visibleRowOrder","sortedData","rowKey","fixedPxWidth","width","match","computeScrollMinWidth","columns","sum","column","fixed","isString","value","getSizeClasses","size","ROW_BORDER_STYLE","syncScroll","source","target","PAGINATION_RESERVED_HEIGHT","DEFAULT_VIRTUAL_ROW_HEIGHT","VIRTUAL_OVERSCAN_ROWS","VIRTUAL_SCROLL_CORRECTION_FRAMES","SECTION_CARD_RADIUS","DETACHED_CARD_RADIUS","DETACHED_CARD_PADDING","SURROUND_CHANNEL","StickyHeaderCornerCap","r","card","jsx","VirtualSectionCard","records","startIndex","scrollElement","estimateRowHeight","style","renderRow","registerHandle","cardKey","rovingIndex","cardRef","useRef","scrollMargin","setScrollMargin","useState","useLayoutEffect","measure","margin","previous","observer","node","sibling","parent","root","virtualizer","useVirtualizer","useEffect","localIndex","items","totalSize","tabStopIndex","paddingTop","paddingBottom","item","computeScrollableMaxHeight","scrollHeight","reservePagination","reserved","cellWidthStyle","fixedSlotStyle","ariaSortValue","sortDirection","alignJustifyClass","align","sortableHeaderJustifyClass","alignTextClass","fixedSlotJustifyClass","HeaderInfo","info","Tooltip","InfoIcon","sortButtonProps","title","onActivate","TableCell","paddingYClass","bordered","isFirstRow","isLastRow","isFirstColumn","isLastColumn","variantBackground","showSelectedAccent","isSelected","rawValue","cellContent","titleText","SELECTED_ROW_BACKGROUND","SELECTED_ROW_FOREGROUND","SELECTED_TEXT_CONTEXT","SELECTED_ROW_ACCENT","DetachedHeaderCell","onSort","isSortable","titleIsEmpty","titleNode","sortCaret","CaretDownIcon","jsxs","DetachedCell","hasFixedWidth","isStringValue","selectionStyle","cellBody","TruncatedTooltip","Table","data","loading","error","errorTitle","errorSubTitle","emptyTitle","emptySubTitle","showHeader","rowDensity","layout","headerVariant","rowClassName","rowVariant","onRow","onClickRow","selectedRowKey","scrollSelectedIntoView","rowSelection","pagination","className","stickyHeaderTop","scrollX","rowSection","renderSectionDivider","onVisibleOrderChange","virtual","virtualRowHeightEstimate","virtualScrollElement","bodyCellPaddingY","sortConfig","setSortConfig","headerScrollRef","bodyScrollRef","containerRef","virtualCardsRef","registerVirtualCard","useCallback","handle","tableId","useId","focusedRowIndex","setFocusedRowIndex","isVirtual","virtualEstimate","bodyScrollElement","setBodyScrollElement","bodyScrollRefCallback","element","virtualScroller","bodyOwnsScroll","isStickyHeader","usesSelection","stickyHeaderHeight","setStickyHeaderHeight","header","entries","entry","height","_b","_a","rowScrollMarginTop","sectionDividers","useMemo","sortRecords","sortColumn","col","sorted","field","aComparable","bComparable","groups","groupIndexByKey","sectionKey","groupIndex","rows","dividers","group","sectionRows","handleSort","prev","getRowKey","rowKeyDep","reportedRowOrderRef","keylessIdsRef","rowOrder","reported","selectedIndex","lastScrolledRef","last","container","scrollMarginPending","rowAt","reveal","row","body","outer","bodyLeft","outerLeft","mounted","frame","attempts","correct","focusOriginRef","moveRowFocus","from","toIndex","origin","rendered","nearest","rowKeyDown","activate","event","step","activateOnEnterOrSpace","scrollMinWidth","rowMinWidthStyle","sectionCardStyle","isLastInSection","isFirstInSection","virtualMeasure","rowActions","variant","handleClick","isClickable","rowBorder","FOCUS_RING_INSET","isFromInteractiveDescendant","renderSkeletonRow","isLast","headerRow","FOREGROUND_RESET","count","_","i","renderCard","starts","start","section","end","dividerContent","React","TablePagination","renderHeader","headerContent","CaretUpIcon","WarningTriangleIcon","handleRowClick"],"mappings":"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"}
1
+ {"version":3,"file":"Table.js","sources":["../../../src/components/Table/Table.tsx"],"sourcesContent":["import { useVirtualizer } from '@tanstack/react-virtual';\nimport React, {\n useState,\n useMemo,\n useRef,\n useCallback,\n useEffect,\n useId,\n useLayoutEffect,\n} from 'react';\nimport CaretDownIcon from '../CustomIcons/CaretDownIcon';\nimport CaretUpIcon from '../CustomIcons/CaretUpIcon';\nimport InfoIcon from '../CustomIcons/InfoIcon';\nimport WarningTriangleIcon from '../CustomIcons/WarningTriangleIcon';\nimport Tooltip from '../Tooltip';\nimport TruncatedTooltip from '../TruncatedTooltip';\nimport { FOCUS_RING_INSET, FOCUS_RING_INSET_OVERLAY } from '../focusRing';\nimport { activateOnEnterOrSpace, isFromInteractiveDescendant } from '../keyboardActivation';\nimport {\n FOREGROUND_RESET,\n SELECTED_ROW_ACCENT,\n SELECTED_ROW_BACKGROUND,\n SELECTED_ROW_FOREGROUND,\n SELECTED_TEXT_CONTEXT,\n} from '../selectedRow';\nimport TablePagination from './TablePagination';\nimport {\n TableColumnDefinition,\n TableColumns,\n TablePaginationPosition,\n TableRowActions,\n TableRowSelection,\n TableSize,\n TableType,\n TableVisibleOrderHandler,\n} from './types';\n\nexport type { TableRowActions };\n\nexport type RowVariant = 'success' | 'warning' | 'error' | 'info';\n\nexport type TableHeaderVariant = 'inline' | 'detached';\n\nexport type TableProps<T = Record<string, unknown>> = {\n columns: TableColumns<T>;\n data: T[];\n loading?: boolean;\n error?: boolean;\n errorTitle?: string;\n errorSubTitle?: string;\n emptyTitle?: string;\n emptySubTitle?: string;\n bordered?: boolean;\n showHeader?: boolean;\n rowKey?: string | ((record: T) => string);\n scrollHeight?: string | number;\n type?: TableType;\n size?: TableSize;\n /** Vertical density of body rows. 'compact' halves the cell padding so\n * rows carrying controls (buttons, dropdowns) sit close to text-row\n * height; headers keep their own padding. */\n rowDensity?: 'default' | 'compact';\n layout?: 'fixed' | 'auto';\n headerVariant?: TableHeaderVariant;\n rowClassName?: (record: T, index: number) => string;\n rowVariant?: (record: T, index: number) => RowVariant | undefined;\n onRow?: (record: T, index: number) => TableRowActions<T>;\n onClickRow?: (record: T, index: number) => void;\n /** Row the master-detail view is showing, resolved against `rowKey`. Controlled, so\n * selection can change without a row click and the highlight follows. Unlike\n * `rowSelection` it paints no control — a tint, an accent bar and `aria-current`.\n * Follows its record through a sort only with a resolvable `rowKey`. */\n selectedRowKey?: React.Key;\n /** Whether a selection change scrolls the row into view. Default true.\n *\n * Set `false` when the initial key comes from a URL: the reveal uses `scrollIntoView`,\n * which walks every scrollable ancestor, so a deep-linked row below the fold jumps the\n * page on load. Selection still highlights; only the scroll is suppressed. */\n scrollSelectedIntoView?: boolean;\n rowSelection?: TableRowSelection<T>;\n pagination?: {\n current?: number;\n pageSize?: number;\n total?: number;\n showSizeChanger?: boolean;\n showQuickJumper?: boolean;\n showTotal?: (total: number, range: [number, number]) => React.ReactNode;\n pageSizeOptions?: string[];\n position?: TablePaginationPosition[];\n onChange?: (page: number, pageSize: number) => void;\n onShowSizeChange?: (current: number, size: number) => void;\n };\n className?: string;\n style?: React.CSSProperties;\n /** When set, makes the detached-variant header sticky at this offset (px) from the\n * top of the nearest scrolling ancestor. Use this when the table sits inside a\n * page-level scroll container with other sticky elements (e.g. tabs + toolbar)\n * stacked above. */\n stickyHeaderTop?: number;\n scrollX?: boolean;\n rowSection?: (record: T) => string;\n renderSectionDivider?: (sectionKey: string, records: T[]) => React.ReactNode;\n /** Reports the rows in render order — sorted and section-grouped, so not `data` order,\n * and always all of `data`. An equal-but-new array does not re-fire, so a host cannot loop.\n * Needs a `rowKey`, or records that keep their object identity across renders. */\n onVisibleOrderChange?: TableVisibleOrderHandler<T>;\n /** Windowed rendering for large datasets (detached variant only), powered by\n * TanStack Virtual: only rows near the viewport stay mounted; spacers keep the\n * scrollbar reflecting the full list. The table body becomes the scroll\n * container, so give it a bounded height via `scrollHeight`. Row heights are\n * measured per row (non-uniform rows are fine). */\n virtual?: boolean;\n /** Estimated row height (px) used by `virtual` before rows are measured. */\n virtualRowHeightEstimate?: number;\n /** With `virtual`: virtualize against this ancestor scroll container instead of\n * the table body (e.g. a page-level scroller so content above the table can\n * scroll away). Pass the element from state (not a ref) so it arrives after\n * mount. The table body stops scrolling when this is set. */\n virtualScrollElement?: HTMLElement | null;\n};\n\nconst DEFAULT_SCROLL_COL_WIDTH = 160;\n\nconst sameRowOrder = (a: readonly string[], b: readonly string[]): boolean =>\n a.length === b.length && a.every((key, index) => key === b[index]);\n\n// Kept per object, never derived from order: any identity read off the current order is the\n// same sequence after a reorder, so the reorder would be suppressed.\nconst KEYLESS_ID_PREFIX = '\\u0000';\n\ntype KeylessIds = { ids: WeakMap<object, string>; next: number };\n\nconst keylessId = (record: unknown, registry: KeylessIds, index: number): string => {\n if (typeof record !== 'object' || record === null) {\n return `${KEYLESS_ID_PREFIX}i${index}`;\n }\n const seen = registry.ids.get(record);\n if (seen !== undefined) {\n return seen;\n }\n const id = `${KEYLESS_ID_PREFIX}${registry.next++}`;\n registry.ids.set(record, id);\n return id;\n};\n\nconst visibleRowOrder = <T,>(\n sortedData: readonly T[],\n rowKey: string | ((record: T) => string),\n registry: KeylessIds,\n): string[] => {\n if (typeof rowKey === 'function') {\n return sortedData.map((record) => rowKey(record));\n }\n return sortedData.map((record, index) => {\n const key = (record as Record<string, unknown>)[rowKey];\n return key === undefined || key === null ? keylessId(record, registry, index) : String(key);\n });\n};\n\nconst fixedPxWidth = (width: string | number | undefined): number | undefined => {\n if (typeof width === 'number') {\n return width;\n }\n if (typeof width === 'string') {\n const match = width.trim().match(/^(\\d+(?:\\.\\d+)?)px$/);\n if (match) {\n return Number(match[1]);\n }\n }\n return undefined;\n};\n\nconst shrinkFloor = (column: TableColumnDefinition<unknown>): number | undefined => {\n const fixed = fixedPxWidth(column.width);\n const isSlot = column.title === '' || column.title == null;\n return !isSlot &&\n fixed !== undefined &&\n typeof column.minWidth === 'number' &&\n column.minWidth < fixed\n ? column.minWidth\n : undefined;\n};\n\nconst computeScrollMinWidth = (columns: TableColumns<unknown>): number =>\n columns.reduce((sum, column) => {\n const fixed = shrinkFloor(column) ?? fixedPxWidth(column.width);\n if (fixed !== undefined) {\n return sum + fixed;\n }\n if (typeof column.minWidth === 'number') {\n return sum + column.minWidth;\n }\n return sum + DEFAULT_SCROLL_COL_WIDTH;\n }, 0);\n\nconst isRowActionSlot = (column: TableColumnDefinition<unknown>): boolean =>\n (column.title === '' || column.title == null) && fixedPxWidth(column.width) !== undefined;\n\ntype PinnedRight = { offsets: Map<string, number>; edgeKey: string | undefined };\n\nconst computePinnedRight = (columns: TableColumns<unknown>): PinnedRight => {\n const trailingSlotCount = [...columns]\n .reverse()\n .findIndex((column) => !isRowActionSlot(column));\n const firstTrailingSlot = trailingSlotCount === -1 ? 0 : columns.length - trailingSlotCount;\n const offsets = new Map<string, number>();\n const settled = columns.reduceRight<{ right: number; edge: string | undefined }>(\n (acc, column, index) => {\n const width = shrinkFloor(column) ?? fixedPxWidth(column.width);\n const pinned = column.fixed === 'right' || index >= firstTrailingSlot;\n if (!pinned || width === undefined) {\n return acc;\n }\n offsets.set(column.key, acc.right);\n return { right: acc.right + width, edge: column.key };\n },\n { right: 0, edge: undefined },\n );\n return { offsets, edgeKey: settled.edge };\n};\n\nconst HEADER_SCROLL_STYLE: React.CSSProperties = { overflowX: 'auto', scrollbarWidth: 'none' };\n\nconst DIVIDER_STICKY: React.CSSProperties = {\n position: 'sticky',\n left: 0,\n width: '100%',\n};\n\nconst NO_PINNED_COLUMNS: PinnedRight = { offsets: new Map(), edgeKey: undefined };\n\nconst PINNED_EDGE_SHADOW = '-6px 0 6px -4px var(--malachite-card-shadow, rgba(0, 0, 0, 0.1))';\n\nconst pinnedCellStyle = (\n right: number | undefined,\n isEdge: boolean,\n showEdgeShadow: boolean,\n background: 'row' | string,\n): React.CSSProperties => {\n if (right === undefined) {\n return {};\n }\n return {\n position: 'sticky',\n right,\n zIndex: 1,\n height: 'auto',\n ...(background === 'row'\n ? { backgroundColor: 'inherit', backgroundImage: 'inherit' }\n : { backgroundColor: background }),\n ...(isEdge && showEdgeShadow ? { boxShadow: PINNED_EDGE_SHADOW } : {}),\n };\n};\n\nconst solidLayer = (color: string): string => `linear-gradient(${color}, ${color})`;\n\nconst detachedRowPaint = (\n variant: RowVariant | undefined,\n isSelected: boolean,\n): React.CSSProperties => {\n if (!variant && !isSelected) {\n return {};\n }\n const layers = [\n isSelected ? solidLayer(SELECTED_ROW_BACKGROUND) : undefined,\n variant\n ? solidLayer(`var(--malachite-table-row-variant-${variant}-background)`)\n : undefined,\n ].filter(isString);\n return {\n backgroundColor: variant\n ? 'var(--malachite-table-background, #f7f7f7)'\n : 'var(--malachite-table-row-background, #fff)',\n backgroundImage: layers.join(', '),\n };\n};\n\nconst isString = (value: unknown): value is string => typeof value === 'string';\n\nconst getSizeClasses = (size: TableSize): string => {\n const sizeMap: Record<TableSize, string> = {\n small: 'text-[length:var(--malachite-font-size-small)]',\n medium: 'text-[length:var(--malachite-font-size-medium)]',\n large: 'text-[length:var(--malachite-font-size-large)]',\n };\n return sizeMap[size];\n};\n\nconst ROW_BORDER_STYLE: React.CSSProperties = {\n borderBottom: '1px solid var(--malachite-card-border, #e8e8e8)',\n};\n\nconst syncScroll = (source: HTMLDivElement | null, target: HTMLDivElement | null): void => {\n if (source && target && target.scrollLeft !== source.scrollLeft) {\n target.scrollLeft = source.scrollLeft;\n }\n};\n\nconst PAGINATION_RESERVED_HEIGHT = 56;\n\nconst DEFAULT_VIRTUAL_ROW_HEIGHT = 44;\nconst VIRTUAL_OVERSCAN_ROWS = 8;\n// Bounded so a row that never mounts can't spin forever.\nconst VIRTUAL_SCROLL_CORRECTION_FRAMES = 10;\n\n// Section cards are clipped to this radius. The first and last row echo it so the selected\n// row's accent bar curves into the corner instead of being cut off by the clip.\nconst SECTION_CARD_RADIUS = 8;\n/** The detached table's outer card: `rounded-xl` + `p-[4px]` on the container below. Read from\n * the token the container itself rounds by, or overriding `radius.xl` pinches the corners. */\nconst DETACHED_CARD_RADIUS = 'var(--malachite-radius-xl, 12px)';\nconst DETACHED_CARD_PADDING = 4;\n\n/** The colour behind the table's own card, painted into the corner notches. A context channel,\n * not a theme token: no palette value, not settable through `applyTheme`, absent from\n * `getCurrentTheme`. Set it on an ancestor when a docked table does not sit on a card. */\nconst SURROUND_CHANNEL = '--malachite-ctx-table-surround';\n\n/** Cuts the docked header's top corners. A plain `border-radius` is invisible here: the\n * container behind paints the same grey, so the notch would just reveal grey. */\nconst StickyHeaderCornerCap: React.FC = () => {\n const r = DETACHED_CARD_RADIUS;\n const card = `var(${SURROUND_CHANNEL}, var(--malachite-card-background, #ffffff))`;\n\n return (\n <div\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n height: r,\n pointerEvents: 'none',\n background: [\n `radial-gradient(circle ${r} at ${r} ${r}, transparent calc(${r} - 0.5px), ${card} ${r}) top left / ${r} ${r} no-repeat`,\n `radial-gradient(circle ${r} at 0 ${r}, transparent calc(${r} - 0.5px), ${card} ${r}) top right / ${r} ${r} no-repeat`,\n ].join(', '),\n }}\n />\n );\n};\n\ntype VirtualMeasureProps = {\n measureRef: (element: HTMLDivElement | null) => void;\n index: number;\n};\n\n/** Lets the table scroll to a row a card has not mounted. The virtualizer is per-card, so\n * `startIndex`/`count` map a global index to the owning card. */\ntype VirtualCardHandle = {\n startIndex: number;\n count: number;\n scrollToIndex: (localIndex: number) => void;\n};\n\ntype VirtualSectionCardProps<T> = {\n records: T[];\n startIndex: number;\n scrollElement: HTMLElement | null;\n estimateRowHeight: number;\n style: React.CSSProperties;\n renderRow: (\n record: T,\n index: number,\n isLastInSection: boolean,\n isFirstInSection: boolean,\n virtualMeasure?: VirtualMeasureProps,\n tabStopIndex?: number,\n ) => React.ReactElement;\n /** Called with null on unmount. */\n registerHandle?: (cardKey: string, handle: VirtualCardHandle | null) => void;\n cardKey: string;\n /** The table's remembered roving-tabindex position, in global row indices. */\n rovingIndex: number;\n};\n\n/** One section card rendered as a TanStack Virtual window over its rows. */\nconst VirtualSectionCard = <T,>({\n records,\n startIndex,\n scrollElement,\n estimateRowHeight,\n style,\n renderRow,\n registerHandle,\n cardKey,\n rovingIndex,\n}: VirtualSectionCardProps<T>): React.ReactElement => {\n const cardRef = useRef<HTMLDivElement>(null);\n const [scrollMargin, setScrollMargin] = useState(0);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies(records.length): the card's offset must be re-measured when section sizes change — content above this card moves\n // biome-ignore lint/correctness/useExhaustiveDependencies(startIndex): a changed start index means the sections above grew or shrank, which moves this card\n useLayoutEffect(() => {\n const card = cardRef.current;\n if (!card || !scrollElement) {\n return;\n }\n const measure = (): void => {\n const margin =\n card.getBoundingClientRect().top -\n scrollElement.getBoundingClientRect().top +\n scrollElement.scrollTop;\n setScrollMargin((previous) => (Math.abs(previous - margin) < 1 ? previous : margin));\n };\n measure();\n if (typeof ResizeObserver === 'undefined') {\n return;\n }\n // A one-shot measure goes stale: sections above attach their virtualizers in a later\n // commit and this card does not re-render when they grow. Watch every preceding sibling\n // up to the scroll container, crossing shadow boundaries.\n const observer = new ResizeObserver(measure);\n let node: Element | null = card;\n while (node && node !== scrollElement) {\n let sibling = node.previousElementSibling;\n while (sibling) {\n observer.observe(sibling);\n sibling = sibling.previousElementSibling;\n }\n const parent: Element | null = node.parentElement;\n if (parent) {\n node = parent;\n } else {\n const root = node.getRootNode();\n node = root instanceof ShadowRoot ? root.host : null;\n }\n }\n return () => observer.disconnect();\n }, [scrollElement, records.length, startIndex]);\n\n const virtualizer = useVirtualizer({\n count: records.length,\n // State, not a ref: an ancestor's ref is not attached when this child's layout effects\n // run, so a ref would leave the virtualizer without a scroll element.\n getScrollElement: () => scrollElement,\n estimateSize: () => estimateRowHeight,\n overscan: VIRTUAL_OVERSCAN_ROWS,\n scrollMargin,\n });\n\n useEffect(() => {\n if (!registerHandle) {\n return;\n }\n registerHandle(cardKey, {\n startIndex,\n count: records.length,\n scrollToIndex: (localIndex) =>\n virtualizer.scrollToIndex(localIndex, { align: 'center' }),\n });\n return () => registerHandle(cardKey, null);\n }, [registerHandle, cardKey, startIndex, records.length, virtualizer]);\n\n const items = virtualizer.getVirtualItems();\n const totalSize = virtualizer.getTotalSize();\n\n // While the remembered row is outside the window every mounted row would be tabIndex -1 and\n // the table would leave the page tab order. Stand in with the nearest mounted row.\n const ownsRovingIndex = rovingIndex >= startIndex && rovingIndex < startIndex + records.length;\n const tabStopIndex =\n ownsRovingIndex && items.length > 0\n ? Math.min(\n Math.max(rovingIndex, startIndex + items[0].index),\n startIndex + items[items.length - 1].index,\n )\n : rovingIndex;\n const paddingTop = items.length > 0 ? items[0].start - scrollMargin : 0;\n const paddingBottom =\n items.length > 0 ? totalSize - (items[items.length - 1].end - scrollMargin) : 0;\n\n return (\n <div ref={cardRef} className=\"flex flex-col w-full\" style={style}>\n {paddingTop > 0 && (\n <div aria-hidden=\"true\" style={{ height: paddingTop, flexShrink: 0 }} />\n )}\n {items.map((item) =>\n renderRow(\n records[item.index],\n startIndex + item.index,\n item.index === records.length - 1,\n item.index === 0,\n { measureRef: virtualizer.measureElement, index: item.index },\n tabStopIndex,\n ),\n )}\n {paddingBottom > 0 && (\n <div aria-hidden=\"true\" style={{ height: paddingBottom, flexShrink: 0 }} />\n )}\n </div>\n );\n};\n\nconst computeScrollableMaxHeight = (\n scrollHeight: string | number,\n reservePagination: boolean,\n): string => {\n const reserved = reservePagination ? PAGINATION_RESERVED_HEIGHT : 0;\n if (typeof scrollHeight === 'number') {\n return `${Math.max(0, scrollHeight - reserved)}px`;\n }\n return `calc(${scrollHeight} - ${reserved}px)`;\n};\n\nconst cellWidthStyle = (column: TableColumnDefinition<unknown>): React.CSSProperties => {\n const width = column.width;\n if (width === undefined || width === null) {\n return {};\n }\n const value = typeof width === 'number' ? `${width}px` : width;\n const floor = shrinkFloor(column);\n // flexBasis keeps width columns the same size in header and body so they align.\n return floor === undefined\n ? { flexBasis: value, maxWidth: value }\n : { flexBasis: value, maxWidth: value, minWidth: floor, flexShrink: 1 };\n};\n\nconst fixedSlotStyle = (column: TableColumnDefinition<unknown>): React.CSSProperties => {\n const width = column.width;\n if (width === undefined || width === null) {\n return {};\n }\n const value = typeof width === 'number' ? `${width}px` : width;\n return { width: value, flexBasis: value };\n};\n\nconst ariaSortValue = (\n sortDirection: 'asc' | 'desc' | null | undefined,\n): 'ascending' | 'descending' | 'none' => {\n if (sortDirection === 'asc') {\n return 'ascending';\n }\n if (sortDirection === 'desc') {\n return 'descending';\n }\n return 'none';\n};\n\ntype ColumnAlign = TableColumnDefinition<unknown>['align'];\n\n/** A header's content is a flex row, so only `justify-*` moves it — `text-align` cannot. */\nconst alignJustifyClass = (align: ColumnAlign): string =>\n align === 'center' ? 'justify-center' : align === 'right' ? 'justify-end' : 'justify-start';\n\n/**\n * Detached only. Left keeps `justify-between` because that is where the detached variant already\n * draws its caret, and moving it would restyle tables that set no `align`.\n */\nconst sortableHeaderJustifyClass = (align: ColumnAlign): string =>\n align === 'center' ? 'justify-center' : align === 'right' ? 'justify-end' : 'justify-between';\n\nconst alignTextClass = (align: ColumnAlign): string =>\n align === 'center' ? 'text-center' : align === 'right' ? 'text-right' : 'text-left';\n\n/** A titleless fixed-width slot is the row-actions column, so an absent `align` stays trailing. */\nconst fixedSlotJustifyClass = (align: ColumnAlign): string =>\n align ? alignJustifyClass(align) : 'justify-end';\n\nconst HeaderInfo = ({ info }: { info: string }): React.ReactElement => (\n <Tooltip text={info} placement=\"top\">\n <InfoIcon\n size={13}\n className=\"shrink-0 text-[var(--malachite-text-secondary,#bbb)]\"\n />\n </Tooltip>\n);\n\nconst sortButtonProps = (\n title: React.ReactNode,\n onActivate?: () => void,\n): React.ButtonHTMLAttributes<HTMLButtonElement> => ({\n type: 'button',\n onClick: onActivate,\n 'aria-label': typeof title === 'string' ? `Sort by ${title}` : 'Sort column',\n});\n\ntype TableCellProps<T> = {\n column: TableColumnDefinition<T>;\n record: T;\n index: number;\n size: TableSize;\n paddingYClass: string;\n bordered: boolean;\n isFirstRow: boolean;\n isLastRow: boolean;\n isFirstColumn: boolean;\n isLastColumn: boolean;\n variantBackground: string | undefined;\n /** First column only: a box-shadow on the `<tr>` is unreliable under `border-collapse`. */\n showSelectedAccent?: boolean;\n /** Set on every cell of a selected row — in a `<table>` cells paint over the `<tr>`. */\n isSelected?: boolean;\n};\n\nconst TableCell = <T,>({\n column,\n record,\n index,\n size,\n paddingYClass,\n bordered,\n isFirstRow,\n isLastRow,\n isFirstColumn,\n isLastColumn,\n variantBackground,\n showSelectedAccent,\n isSelected,\n}: TableCellProps<T>): React.ReactElement => {\n const rawValue = (record as Record<string, unknown>)[column.dataIndex as string];\n const cellContent = column.render\n ? column.render(rawValue, record, index)\n : rawValue == null\n ? ''\n : String(rawValue);\n const titleText = column.ellipsis && isString(rawValue) ? rawValue : undefined;\n return (\n <td\n className={`\n table-cell px-4 ${paddingYClass} ${getSizeClasses(size)}\n ${column.ellipsis ? 'truncate overflow-hidden whitespace-nowrap' : ''}\n ${bordered ? 'table-cell-bordered' : ''}\n ${bordered && isFirstRow ? 'table-cell-bordered-top' : ''}\n ${bordered && isFirstColumn ? 'table-cell-bordered-left' : ''}\n ${bordered && isLastColumn ? 'table-cell-bordered-right' : ''}\n ${bordered && isFirstColumn && isFirstRow ? 'rounded-tl-lg' : ''}\n ${bordered && isLastColumn && isFirstRow ? 'rounded-tr-lg' : ''}\n ${bordered && isFirstColumn && isLastRow ? 'rounded-bl-lg' : ''}\n ${bordered && isLastColumn && isLastRow ? 'rounded-br-lg' : ''}\n ${alignTextClass(column.align)}\n `}\n style={{\n width: column.width,\n backgroundColor:\n variantBackground ??\n // Mirror the row's background, or the tint composites over the wrong opaque\n // base — they differ in dark mode.\n (isSelected\n ? bordered\n ? 'var(--malachite-table-borderedRow-background, #fff)'\n : 'var(--malachite-table-row-background, #fff)'\n : undefined),\n // Its own layer, so the tint composites over the cell instead of replacing it.\n backgroundImage: isSelected\n ? `linear-gradient(${SELECTED_ROW_BACKGROUND}, ${SELECTED_ROW_BACKGROUND})`\n : undefined,\n // Content pinning its own colour follows via the channel below.\n color: isSelected\n ? SELECTED_ROW_FOREGROUND\n : 'var(--malachite-table-row-foreground)',\n ...(isSelected ? SELECTED_TEXT_CONTEXT : {}),\n // Inset box-shadow, not `ring-*`: --tw-ring-* silently doesn't paint in a shadow root.\n boxShadow: showSelectedAccent ? `inset 2px 0 0 ${SELECTED_ROW_ACCENT}` : undefined,\n borderBottom: bordered\n ? undefined\n : isLastRow\n ? 'none'\n : '1px solid var(--malachite-table-row-border)',\n }}\n title={titleText}\n >\n {cellContent}\n </td>\n );\n};\n\ntype DetachedHeaderCellProps<T> = {\n column: TableColumnDefinition<T>;\n sortDirection: 'asc' | 'desc' | null;\n onSort?: () => void;\n cellStyle?: React.CSSProperties;\n};\n\nconst DetachedHeaderCell = <T,>({\n column,\n sortDirection,\n onSort,\n cellStyle,\n}: DetachedHeaderCellProps<T>): React.ReactElement => {\n const isSortable = Boolean(column.sorter);\n const titleIsEmpty = column.title === '' || column.title == null;\n const hasFixedWidth = titleIsEmpty && column.width !== undefined;\n\n if (hasFixedWidth) {\n return (\n <div\n className=\"h-full shrink-0\"\n style={{\n ...fixedSlotStyle(column as TableColumnDefinition<unknown>),\n ...cellStyle,\n }}\n />\n );\n }\n\n if (titleIsEmpty) {\n return (\n <div\n className=\"flex flex-[1_0_0] h-full min-w-0\"\n style={{\n ...cellWidthStyle(column as TableColumnDefinition<unknown>),\n ...cellStyle,\n }}\n />\n );\n }\n\n const titleNode =\n typeof column.title === 'string' ? (\n <p className=\"font-medium text-[13px] text-[#0a0a0a] tracking-[0.13px] whitespace-nowrap truncate\">\n {column.title}\n </p>\n ) : (\n column.title\n );\n\n const sortCaret = (\n <CaretDownIcon\n size={13}\n className={`shrink-0 transition-transform ${\n sortDirection ? 'text-[#0a0a0a]' : 'text-[#bbb]'\n } ${sortDirection === 'asc' ? 'rotate-180' : ''}`}\n />\n );\n\n if (!isSortable) {\n return (\n <div\n className={`flex flex-[1_0_0] items-center ${alignJustifyClass(column.align)} min-w-0 overflow-hidden px-4 py-3`}\n style={{\n ...cellWidthStyle(column as TableColumnDefinition<unknown>),\n ...cellStyle,\n }}\n >\n <div className=\"flex items-center gap-1 min-w-0\">\n {titleNode}\n {column.info && <HeaderInfo info={column.info} />}\n </div>\n </div>\n );\n }\n\n return (\n <div\n className=\"flex flex-[1_0_0] min-w-0 overflow-hidden\"\n style={{ ...cellWidthStyle(column as TableColumnDefinition<unknown>), ...cellStyle }}\n >\n <button\n {...sortButtonProps(column.title, onSort)}\n className={`flex flex-1 items-center ${sortableHeaderJustifyClass(column.align)} gap-1 min-w-0 px-4 py-3 cursor-pointer appearance-none bg-transparent border-0 ${alignTextClass(column.align)}`}\n >\n <div className=\"flex items-center gap-1 min-w-0\">\n {titleNode}\n {column.info && <HeaderInfo info={column.info} />}\n </div>\n {sortCaret}\n </button>\n </div>\n );\n};\n\ntype DetachedCellProps<T> = {\n column: TableColumnDefinition<T>;\n record: T;\n index: number;\n size: TableSize;\n paddingYClass: string;\n isSelected?: boolean;\n cellStyle?: React.CSSProperties;\n};\n\nconst DetachedCell = <T,>({\n column,\n record,\n index,\n size,\n paddingYClass,\n isSelected = false,\n cellStyle,\n}: DetachedCellProps<T>): React.ReactElement => {\n const rawValue = (record as Record<string, unknown>)[column.dataIndex as string];\n const cellContent = column.render\n ? column.render(rawValue, record, index)\n : rawValue == null\n ? ''\n : String(rawValue);\n const titleIsEmpty = column.title === '' || column.title == null;\n const hasFixedWidth = titleIsEmpty && column.width !== undefined;\n const isStringValue = isString(rawValue) && rawValue.length > 0;\n\n // Text channel — see the classic cell.\n const selectionStyle: React.CSSProperties = isSelected\n ? {\n color: SELECTED_ROW_FOREGROUND,\n ...SELECTED_TEXT_CONTEXT,\n }\n : {};\n\n if (hasFixedWidth) {\n return (\n <div\n className={`flex items-center ${fixedSlotJustifyClass(column.align)} shrink-0 overflow-hidden px-4 ${paddingYClass}`}\n style={{\n ...fixedSlotStyle(column as TableColumnDefinition<unknown>),\n ...selectionStyle,\n ...cellStyle,\n }}\n >\n {cellContent}\n </div>\n );\n }\n\n // Strings only: wrapping arbitrary JSX in a truncating span breaks layout.\n const cellBody =\n !column.render && isStringValue ? (\n <TruncatedTooltip text={rawValue}>{cellContent}</TruncatedTooltip>\n ) : (\n cellContent\n );\n\n return (\n <div\n className={`flex flex-[1_0_0] items-center min-w-0 overflow-hidden px-4 ${paddingYClass} ${getSizeClasses(size)} ${alignJustifyClass(column.align)}`}\n style={{\n ...cellWidthStyle(column as TableColumnDefinition<unknown>),\n ...selectionStyle,\n ...cellStyle,\n }}\n >\n {cellBody}\n </div>\n );\n};\n\nconst Table = <T = Record<string, unknown>>({\n columns,\n data,\n loading = false,\n error = false,\n errorTitle = 'Data unavailable',\n errorSubTitle = 'There was an issue retrieving the data. Please try again.',\n emptyTitle = 'No data',\n emptySubTitle = '',\n bordered = false,\n showHeader = true,\n rowKey = 'key',\n scrollHeight,\n size = 'small',\n rowDensity = 'default',\n layout = 'auto',\n headerVariant = 'inline',\n rowClassName,\n rowVariant,\n onRow,\n onClickRow,\n selectedRowKey,\n scrollSelectedIntoView = true,\n rowSelection,\n pagination,\n className = '',\n style,\n stickyHeaderTop,\n scrollX = false,\n rowSection,\n renderSectionDivider,\n onVisibleOrderChange,\n virtual = false,\n virtualRowHeightEstimate,\n virtualScrollElement = null,\n}: TableProps<T>) => {\n const bodyCellPaddingY = rowDensity === 'compact' ? 'py-1.5' : 'py-3';\n const [sortConfig, setSortConfig] = useState<{\n key: string;\n direction: 'asc' | 'desc';\n } | null>(null);\n\n const headerRef = useRef<HTMLDivElement>(null);\n const headerScrollRef = useRef<HTMLDivElement>(null);\n const bodyScrollRef = useRef<HTMLDivElement | null>(null);\n // Scoped lookups: querying the table's own root keeps sibling tables out.\n const containerRef = useRef<HTMLDivElement | null>(null);\n // A ref, not state: state here would re-render the whole table for no visual reason.\n const virtualCardsRef = useRef<Map<string, VirtualCardHandle>>(new Map());\n const registerVirtualCard = useCallback(\n (cardKey: string, handle: VirtualCardHandle | null): void => {\n if (handle) {\n virtualCardsRef.current.set(cardKey, handle);\n } else {\n virtualCardsRef.current.delete(cardKey);\n }\n },\n [],\n );\n\n // Roving tabindex, held in state so the position survives the virtualiser unmounting the\n // focused row.\n const tableId = useId();\n const [focusedRowIndex, setFocusedRowIndex] = useState(0);\n\n const isVirtual = virtual && headerVariant === 'detached';\n const virtualEstimate = virtualRowHeightEstimate ?? DEFAULT_VIRTUAL_ROW_HEIGHT;\n // State, so virtual cards re-render and attach their virtualizers once it exists.\n const [bodyScrollElement, setBodyScrollElement] = useState<HTMLDivElement | null>(null);\n // Stable identity so React doesn't detach/reattach every render.\n const bodyScrollRefCallback = useCallback((element: HTMLDivElement | null) => {\n bodyScrollRef.current = element;\n if (element) {\n setBodyScrollElement((previous) => (previous === element ? previous : element));\n }\n }, []);\n const virtualScroller = isVirtual ? (virtualScrollElement ?? bodyScrollElement) : null;\n\n const scrollMinWidth = scrollX ? computeScrollMinWidth(columns as TableColumns<unknown>) : 0;\n const pinned: PinnedRight =\n scrollX && headerVariant === 'detached'\n ? computePinnedRight(columns as TableColumns<unknown>)\n : NO_PINNED_COLUMNS;\n const hasPinnedEdge = pinned.edgeKey !== undefined;\n const [contentHiddenRight, setContentHiddenRight] = useState(false);\n const [bodyScrollbarGutter, setBodyScrollbarGutter] = useState(0);\n const updateContentHidden = useCallback((): void => {\n const body = bodyScrollRef.current;\n setContentHiddenRight(\n body !== null && body.scrollLeft + body.clientWidth < body.scrollWidth - 1,\n );\n setBodyScrollbarGutter(body === null ? 0 : body.offsetWidth - body.clientWidth);\n }, []);\n // biome-ignore lint/correctness/useExhaustiveDependencies(scrollMinWidth): rows take it as their min width, so it moves scrollWidth without resizing the body\n useEffect(() => {\n if (!hasPinnedEdge || !bodyScrollElement) {\n setContentHiddenRight(false);\n setBodyScrollbarGutter(0);\n return;\n }\n updateContentHidden();\n if (typeof ResizeObserver === 'undefined') {\n return;\n }\n const observer = new ResizeObserver(updateContentHidden);\n observer.observe(bodyScrollElement);\n return () => observer.disconnect();\n }, [hasPinnedEdge, bodyScrollElement, scrollMinWidth, updateContentHidden]);\n // With an external scroller the body must not compete for scrolling.\n const bodyOwnsScroll = !(isVirtual && virtualScrollElement);\n\n const isStickyHeader =\n headerVariant === 'detached' &&\n stickyHeaderTop !== undefined &&\n showHeader &&\n !scrollHeight &&\n (!isVirtual || !bodyOwnsScroll);\n\n // The header height exists only to offset the selection reveal, so a table that never\n // selects must not pay for the observer or its state updates (ENG-1166, ENG-1353).\n const usesSelection = selectedRowKey !== undefined && selectedRowKey !== null;\n\n const [stickyHeaderHeight, setStickyHeaderHeight] = useState(0);\n useEffect(() => {\n const header = headerRef.current;\n if (!header || !isStickyHeader || !usesSelection || typeof ResizeObserver === 'undefined') {\n setStickyHeaderHeight(0);\n return;\n }\n // Border box: the header occludes rows with its padding too. Re-reading the element\n // would force the layout this observer avoids (ENG-1166); jsdom has no `borderBoxSize`.\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0];\n const height = entry?.borderBoxSize?.[0]?.blockSize ?? entry?.contentRect.height ?? 0;\n setStickyHeaderHeight((previous) =>\n Math.abs(previous - height) < 1 ? previous : height,\n );\n });\n observer.observe(header);\n return () => observer.disconnect();\n }, [isStickyHeader, usesSelection]);\n\n // scrollIntoView ignores sticky overlays and parks rows under them; reserve the occluded\n // strip. `stickyHeaderTop` covers what the consumer stacks above, this adds the header.\n const rowScrollMarginTop = isStickyHeader\n ? (stickyHeaderTop ?? 0) + stickyHeaderHeight\n : undefined;\n\n const { sortedData, sectionDividers } = useMemo(() => {\n // dataIndex, not the render-only key.\n const sortRecords = (records: T[]): T[] => {\n if (!sortConfig) return records;\n\n const sortColumn = columns.find((col) => col.key === sortConfig.key);\n if (!sortColumn) return records;\n\n if (typeof sortColumn.sorter === 'function') {\n const sorted = [...records].sort(sortColumn.sorter);\n return sortConfig.direction === 'asc' ? sorted : sorted.reverse();\n }\n\n const field = (sortColumn.dataIndex as string) ?? sortConfig.key;\n return [...records].sort((a, b) => {\n const aComparable = (a as Record<string, unknown>)[field] as string | number;\n const bComparable = (b as Record<string, unknown>)[field] as string | number;\n\n if (aComparable < bComparable) {\n return sortConfig.direction === 'asc' ? -1 : 1;\n }\n if (aComparable > bComparable) {\n return sortConfig.direction === 'asc' ? 1 : -1;\n }\n return 0;\n });\n };\n\n if (!rowSection) {\n return {\n sortedData: sortRecords(data),\n sectionDividers: new Map<number, { key: string; records: T[] }>(),\n };\n }\n\n const groups: { key: string; records: T[] }[] = [];\n const groupIndexByKey = new Map<string, number>();\n for (const record of data) {\n const sectionKey = rowSection(record);\n let groupIndex = groupIndexByKey.get(sectionKey);\n if (groupIndex === undefined) {\n groupIndex = groups.length;\n groupIndexByKey.set(sectionKey, groupIndex);\n groups.push({ key: sectionKey, records: [] });\n }\n groups[groupIndex].records.push(record);\n }\n\n const rows: T[] = [];\n const dividers = new Map<number, { key: string; records: T[] }>();\n for (const group of groups) {\n const sectionRows = sortRecords(group.records);\n dividers.set(rows.length, { key: group.key, records: sectionRows });\n rows.push(...sectionRows);\n }\n return { sortedData: rows, sectionDividers: dividers };\n }, [data, sortConfig, columns, rowSection]);\n\n const handleSort = (key: string) => {\n setSortConfig((prev) => {\n if (prev?.key === key) {\n return prev.direction === 'asc' ? { key, direction: 'desc' } : null;\n }\n return { key, direction: 'asc' };\n });\n };\n\n // Not a useCallback reading a ref: writing the prop into a ref during render makes render\n // impure, and React may discard render work.\n const getRowKey = (record: T, index: number): string => {\n if (typeof rowKey === 'function') {\n return rowKey(record);\n }\n // ?? not ||: a falsy-but-real key (id 0, '') must keep its identity.\n return String((record as Record<string, unknown>)[rowKey] ?? index);\n };\n // Stands in for `getRowKey` below: an inline `rowKey={(r) => r.id}` changes identity every\n // render, costing a findIndex over the dataset each time. A function rowKey is taken as pure.\n const rowKeyDep = typeof rowKey === 'function' ? null : rowKey;\n\n // By key, not identity: an inline `data={rows.filter(…)}` would report every render.\n const reportedRowOrderRef = useRef<string[] | undefined>(undefined);\n const keylessIdsRef = useRef<KeylessIds | undefined>(undefined);\n // biome-ignore lint/correctness/useExhaustiveDependencies: rowKeyDep deliberately stands in for rowKey — see the note on rowKeyDep above\n useEffect(() => {\n if (!onVisibleOrderChange) {\n return;\n }\n keylessIdsRef.current ??= { ids: new WeakMap(), next: 0 };\n const rowOrder = visibleRowOrder(sortedData, rowKey, keylessIdsRef.current);\n const reported = reportedRowOrderRef.current;\n if (reported && sameRowOrder(reported, rowOrder)) {\n return;\n }\n reportedRowOrderRef.current = rowOrder;\n onVisibleOrderChange(sortedData);\n }, [sortedData, rowKeyDep, onVisibleOrderChange]);\n\n // Clamped so a shrinking dataset can't leave every row untabbable.\n const rovingIndex = Math.min(focusedRowIndex, Math.max(0, sortedData.length - 1));\n\n // Sorted-order position; with no resolvable `rowKey`, the `onClickRow` index.\n // biome-ignore lint/correctness/useExhaustiveDependencies: rowKeyDep deliberately stands in for getRowKey — see the note on rowKeyDep above\n const selectedIndex = useMemo(() => {\n if (selectedRowKey === undefined || selectedRowKey === null) {\n return -1;\n }\n const target = String(selectedRowKey);\n return sortedData.findIndex((record, index) => getRowKey(record, index) === target);\n }, [selectedRowKey, sortedData, rowKeyDep]);\n\n // Tabbing in should land on the highlighted row. No focusOriginRef, so focus is not stolen.\n useEffect(() => {\n if (selectedIndex >= 0) {\n setFocusedRowIndex(selectedIndex);\n }\n }, [selectedIndex]);\n\n // Holds what was actually revealed, not the last key seen, so every not-ready path below\n // leaves it open to retry. Keyed on index too, since a sort moves a record without its key.\n const lastScrolledRef = useRef<{ key: React.Key; index: number } | undefined>(undefined);\n useEffect(() => {\n // Clearing releases the latch: re-selecting the same record must scroll again.\n if (selectedRowKey === undefined || selectedRowKey === null) {\n lastScrolledRef.current = undefined;\n return;\n }\n if (!scrollSelectedIntoView) {\n return;\n }\n if (selectedIndex < 0) {\n return;\n }\n const last = lastScrolledRef.current;\n if (last && last.key === selectedRowKey && last.index === selectedIndex) {\n return;\n }\n if (loading || error) {\n return;\n }\n // The scroll element arrives a commit later, so the virtualizers would drop this.\n if (isVirtual && !virtualScroller) {\n return;\n }\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n // The header height lands after this flush. Reveal anyway, but hold the latch open so\n // the measured re-run can place it properly.\n const scrollMarginPending = isStickyHeader && stickyHeaderHeight === 0;\n\n // Scoped by table id: a `column.render` can nest a whole Table inside a cell.\n const rowAt = (index: number) =>\n container.querySelector<HTMLElement>(\n `[data-table-id=\"${tableId}\"][data-row-index=\"${index}\"]`,\n );\n\n // `block: 'nearest'` no-ops when already visible, so a click never moves the viewport.\n // One element per change — interaction-time, not the mount-path read ENG-1166 banned.\n const reveal = (row: HTMLElement): void => {\n // scrollIntoView resolves `inline` too, and under `scrollX` a row is wider than the\n // port, so `nearest` would scroll 1px and hide the card's border.\n const body = bodyScrollRef.current;\n const outer = virtualScrollElement;\n const bodyLeft = body?.scrollLeft;\n const outerLeft = outer?.scrollLeft;\n row.scrollIntoView({ block: 'nearest', inline: 'nearest' });\n if (body && bodyLeft !== undefined) {\n body.scrollLeft = bodyLeft;\n }\n if (outer && outerLeft !== undefined) {\n outer.scrollLeft = outerLeft;\n }\n if (!scrollMarginPending) {\n lastScrolledRef.current = { key: selectedRowKey, index: selectedIndex };\n }\n };\n\n const mounted = rowAt(selectedIndex);\n if (mounted) {\n reveal(mounted);\n return;\n }\n\n // Not mounted: under virtualisation, ask the owning card's virtualizer for it.\n if (!isVirtual) {\n return;\n }\n const card = [...virtualCardsRef.current.values()].find(\n (entry) =>\n selectedIndex >= entry.startIndex && selectedIndex < entry.startIndex + entry.count,\n );\n if (!card) {\n return;\n }\n card.scrollToIndex(selectedIndex - card.startIndex);\n\n // scrollToIndex positions from estimated heights, so correct once the real row measures.\n let frame = 0;\n let attempts = 0;\n const correct = (): void => {\n const row = rowAt(selectedIndex);\n if (row) {\n reveal(row);\n return;\n }\n if (++attempts < VIRTUAL_SCROLL_CORRECTION_FRAMES) {\n frame = requestAnimationFrame(correct);\n }\n };\n frame = requestAnimationFrame(correct);\n return () => cancelAnimationFrame(frame);\n }, [\n selectedRowKey,\n selectedIndex,\n isVirtual,\n virtualScroller,\n virtualScrollElement,\n isStickyHeader,\n stickyHeaderHeight,\n loading,\n error,\n tableId,\n scrollSelectedIntoView,\n ]);\n\n // Set only for user-driven moves, so the effect below doesn't steal focus on an\n // unrelated re-render.\n const focusOriginRef = useRef<HTMLElement | null>(null);\n\n const moveRowFocus = (from: HTMLElement, toIndex: number): void => {\n focusOriginRef.current = from;\n setFocusedRowIndex(Math.min(Math.max(0, toIndex), sortedData.length - 1));\n };\n\n // Focus after the commit, not in a rAF: the new row only becomes the tabbable one\n // once React has re-rendered. Scoped by table id so sibling tables can't steal it.\n useLayoutEffect(() => {\n const origin = focusOriginRef.current;\n if (!origin) {\n return;\n }\n focusOriginRef.current = null;\n const root = origin.getRootNode() as ParentNode;\n const rowAt = (index: number) =>\n root.querySelector<HTMLElement>(\n `[data-table-id=\"${tableId}\"][data-row-index=\"${index}\"]`,\n );\n\n const target = rowAt(rovingIndex);\n if (target) {\n target.focus();\n return;\n }\n\n // Target unmounted (virtualised, or windowed data). Land on the nearest rendered\n // row — otherwise nothing is tabbable and the table drops out of the tab order.\n const rendered = root.querySelectorAll<HTMLElement>(\n `[data-table-id=\"${tableId}\"][data-row-index]`,\n );\n const nearest = rovingIndex > 0 ? rendered[rendered.length - 1] : rendered[0];\n if (nearest) {\n setFocusedRowIndex(Number(nearest.dataset.rowIndex));\n nearest.focus();\n }\n }, [rovingIndex, tableId]);\n\n const rowKeyDown =\n (index: number, activate?: () => void) =>\n (event: React.KeyboardEvent<HTMLElement>): void => {\n const step = { ArrowDown: 1, ArrowUp: -1 }[event.key];\n if (step !== undefined) {\n event.preventDefault();\n moveRowFocus(event.currentTarget, index + step);\n return;\n }\n // Home/End only when every row is mounted; under virtualisation the target row does\n // not exist yet, so falling through lets the scroll container jump natively.\n if (!isVirtual && (event.key === 'Home' || event.key === 'End')) {\n event.preventDefault();\n moveRowFocus(event.currentTarget, event.key === 'Home' ? 0 : sortedData.length - 1);\n return;\n }\n // Enter only: neither row path claims button semantics, so Space scrolls.\n if (activate) {\n activateOnEnterOrSpace(event, activate, 'enter');\n }\n };\n\n if (headerVariant === 'detached') {\n const rowMinWidthStyle: React.CSSProperties = scrollX ? { minWidth: scrollMinWidth } : {};\n const cellStyleFor = (\n column: TableColumnDefinition<T>,\n background: 'row' | string,\n ): React.CSSProperties => ({\n ...(scrollX && column.width === undefined\n ? { minWidth: column.minWidth ?? DEFAULT_SCROLL_COL_WIDTH }\n : {}),\n ...pinnedCellStyle(\n pinned.offsets.get(column.key),\n column.key === pinned.edgeKey,\n contentHiddenRight,\n background,\n ),\n });\n const headerPinBackground = isStickyHeader\n ? 'var(--malachite-table-header-background, #f7f7f7)'\n : 'var(--malachite-table-background, #f7f7f7)';\n\n // flexShrink 0: as a flex item of a height-bounded body, an overflow-hidden card would\n // shrink-to-fit and clip its rows instead of letting the body scroll.\n const sectionCardStyle: React.CSSProperties = {\n border: '1px solid var(--malachite-card-border, #e8e8e8)',\n borderRadius: SECTION_CARD_RADIUS,\n overflow: 'clip',\n flexShrink: 0,\n ...rowMinWidthStyle,\n };\n\n const renderRow = (\n record: T,\n index: number,\n isLastInSection = false,\n isFirstInSection = false,\n virtualMeasure?: VirtualMeasureProps,\n // Virtual cards substitute the nearest mounted row; elsewhere all rows are mounted.\n tabStopIndex: number = rovingIndex,\n ): React.ReactElement => {\n const key = getRowKey(record, index);\n const rowActions = onRow?.(record, index) || {};\n const variant = rowVariant?.(record, index);\n const isSelected = index === selectedIndex;\n const handleClick =\n onClickRow || rowActions.onClick\n ? () => {\n onClickRow?.(record, index);\n rowActions.onClick?.(record, index);\n }\n : undefined;\n const isClickable = Boolean(handleClick);\n const rowBorder = isLastInSection ? {} : ROW_BORDER_STYLE;\n return (\n <div\n key={key}\n ref={virtualMeasure?.measureRef}\n data-index={virtualMeasure?.index}\n data-table-id={tableId}\n data-row-index={index}\n // No `role=\"button\"`: it takes presentational children, flattening the cells\n // and stripping a nested ActionMenu from the a11y tree.\n aria-current={isSelected ? 'true' : undefined}\n tabIndex={isClickable ? (index === tabStopIndex ? 0 : -1) : undefined}\n onKeyDown={isClickable ? rowKeyDown(index, handleClick) : undefined}\n className={`\n group bg-[var(--malachite-table-row-background,#fff)] flex min-h-10 items-stretch relative w-full\n ${isClickable ? `cursor-pointer hover:bg-[var(--malachite-table-row-hover-background,#fafafa)] ${FOCUS_RING_INSET}` : ''}\n ${rowClassName?.(record, index) || ''}\n `}\n style={{\n ...rowBorder,\n ...rowMinWidthStyle,\n scrollMarginTop: rowScrollMarginTop,\n // Echo the card's clip, or it cuts the accent bar's end into a stub.\n ...(isFirstInSection\n ? {\n borderTopLeftRadius: SECTION_CARD_RADIUS,\n borderTopRightRadius: SECTION_CARD_RADIUS,\n }\n : {}),\n ...(isLastInSection\n ? {\n borderBottomLeftRadius: SECTION_CARD_RADIUS,\n borderBottomRightRadius: SECTION_CARD_RADIUS,\n }\n : {}),\n // Set unconditionally it would beat `hover:bg-*` on every row.\n ...detachedRowPaint(variant, isSelected),\n ...(isSelected\n ? {\n // Inset box-shadow, not `ring-*` — see the classic cell.\n boxShadow: `inset 2px 0 0 ${SELECTED_ROW_ACCENT}`,\n }\n : {}),\n }}\n onClick={\n handleClick\n ? (event) => {\n if (!isFromInteractiveDescendant(event)) {\n handleClick();\n }\n }\n : undefined\n }\n onDoubleClick={\n rowActions.onDoubleClick\n ? () => rowActions.onDoubleClick?.(record, index)\n : undefined\n }\n onContextMenu={\n rowActions.onContextMenu\n ? () => rowActions.onContextMenu?.(record, index)\n : undefined\n }\n onMouseEnter={\n rowActions.onMouseEnter\n ? () => rowActions.onMouseEnter?.(record, index)\n : undefined\n }\n onMouseLeave={\n rowActions.onMouseLeave\n ? () => rowActions.onMouseLeave?.(record, index)\n : undefined\n }\n >\n {columns.map((column) => (\n <DetachedCell<T>\n key={column.key}\n column={column}\n record={record}\n paddingYClass={bodyCellPaddingY}\n index={index}\n size={size}\n isSelected={isSelected}\n cellStyle={cellStyleFor(column, 'row')}\n />\n ))}\n {isClickable && hasPinnedEdge ? (\n <span aria-hidden=\"true\" className={FOCUS_RING_INSET_OVERLAY} />\n ) : null}\n </div>\n );\n };\n\n const renderSkeletonRow = (index: number, isLast = false): React.ReactElement => (\n <div\n key={`skeleton-${index}`}\n className=\"bg-white flex min-h-10 items-stretch w-full\"\n // Last row: no bottom border; the card border closes the section.\n style={{ ...(isLast ? {} : ROW_BORDER_STYLE), ...rowMinWidthStyle }}\n >\n {columns.map((column) => {\n // Mirror DetachedCell's widths and placement so skeleton columns don't jump\n // on load.\n const titleIsEmpty = column.title === '' || column.title == null;\n const hasFixedWidth = titleIsEmpty && column.width !== undefined;\n if (hasFixedWidth) {\n return (\n <div\n key={column.key}\n className={`flex items-center ${fixedSlotJustifyClass(column.align)} shrink-0 overflow-clip px-4 ${bodyCellPaddingY}`}\n style={{\n ...fixedSlotStyle(column as TableColumnDefinition<unknown>),\n ...cellStyleFor(column, 'row'),\n }}\n >\n <div className=\"h-3 bg-gray-200 rounded animate-pulse w-2/5\"></div>\n </div>\n );\n }\n return (\n <div\n key={column.key}\n className={`flex flex-[1_0_0] items-center ${alignJustifyClass(column.align)} min-w-0 overflow-clip px-4 ${bodyCellPaddingY}`}\n style={{\n ...cellWidthStyle(column as TableColumnDefinition<unknown>),\n ...cellStyleFor(column, 'row'),\n }}\n >\n <div className=\"h-3 bg-gray-200 rounded animate-pulse w-3/5\"></div>\n </div>\n );\n })}\n </div>\n );\n\n const headerRow = showHeader ? (\n <div className=\"flex min-h-10 items-stretch w-full\" style={rowMinWidthStyle}>\n {columns.map((column) => (\n <DetachedHeaderCell<T>\n key={column.key}\n column={column}\n sortDirection={sortConfig?.key === column.key ? sortConfig.direction : null}\n onSort={column.sorter ? () => handleSort(column.key) : undefined}\n cellStyle={cellStyleFor(column, headerPinBackground)}\n />\n ))}\n </div>\n ) : null;\n\n return (\n <div\n ref={containerRef}\n className={`w-full ${className}`}\n style={{ ...FOREGROUND_RESET, ...style }}\n >\n <div\n className={`bg-[var(--malachite-table-background,#f7f7f7)] flex flex-col items-start ${isStickyHeader ? '' : 'overflow-clip'} p-[4px] relative rounded-xl w-full`}\n >\n {showHeader && (\n <div\n ref={headerRef}\n style={{\n ...(isStickyHeader\n ? {\n position: 'sticky',\n top: stickyHeaderTop,\n zIndex: 8,\n backgroundColor:\n 'var(--malachite-table-header-background, #f7f7f7)',\n marginInline: -DETACHED_CARD_PADDING,\n width: `calc(100% + ${DETACHED_CARD_PADDING * 2}px)`,\n paddingInline: DETACHED_CARD_PADDING,\n // Vertically too, or the card's top frame sits above\n // the docked header and rows scroll through it.\n marginTop: -DETACHED_CARD_PADDING,\n paddingTop: DETACHED_CARD_PADDING,\n }\n : { width: '100%' }),\n }}\n >\n {isStickyHeader && <StickyHeaderCornerCap />}\n <div\n ref={headerScrollRef}\n onScroll={\n scrollX\n ? () =>\n syncScroll(\n headerScrollRef.current,\n bodyScrollRef.current,\n )\n : undefined\n }\n style={\n scrollX\n ? {\n ...HEADER_SCROLL_STYLE,\n paddingRight: bodyScrollbarGutter,\n }\n : undefined\n }\n >\n {headerRow}\n </div>\n </div>\n )}\n\n <div\n ref={bodyScrollRefCallback}\n onScroll={\n scrollX\n ? () => {\n syncScroll(bodyScrollRef.current, headerScrollRef.current);\n if (hasPinnedEdge) {\n updateContentHidden();\n }\n }\n : undefined\n }\n className={`flex flex-col items-start ${scrollX ? 'overflow-x-auto' : 'overflow-x-clip'} ${bodyOwnsScroll ? 'overflow-y-auto' : 'overflow-y-visible'} w-full`}\n style={{\n // Firefox + modern Chromium only; older Webkit keeps its default.\n scrollbarWidth: 'thin',\n scrollbarColor:\n 'var(--malachite-text-placeholder, rgb(187, 187, 187)) transparent',\n // With an external virtual scroller the body is overflow-visible and\n // a bounded box would overlap content below it.\n ...(scrollHeight && bodyOwnsScroll\n ? {\n maxHeight: computeScrollableMaxHeight(\n scrollHeight,\n !!pagination,\n ),\n }\n : {}),\n }}\n >\n {error ? (\n <div className=\"flex flex-col w-full\" style={sectionCardStyle}>\n <div className=\"flex flex-col items-center justify-center bg-white w-full py-12\">\n <div className=\"text-[var(--malachite-text-secondary)] text-[14px] font-medium mb-1\">\n {errorTitle}\n </div>\n <div className=\"text-[var(--malachite-text-secondary)] text-[13px]\">\n {errorSubTitle}\n </div>\n </div>\n </div>\n ) : loading ? (\n <div className=\"flex flex-col w-full\" style={sectionCardStyle}>\n {(() => {\n const count = pagination?.pageSize\n ? Math.min(pagination.pageSize, 10)\n : 5;\n return Array.from({ length: count }).map((_, i) =>\n renderSkeletonRow(i, i === count - 1),\n );\n })()}\n </div>\n ) : sortedData.length === 0 ? (\n <div className=\"flex flex-col w-full\" style={sectionCardStyle}>\n <div className=\"flex flex-col items-center justify-center bg-white w-full py-12\">\n <div className=\"text-[var(--malachite-text-secondary)] text-[14px] font-medium\">\n {emptyTitle}\n </div>\n {emptySubTitle && (\n <div className=\"text-[var(--malachite-text-secondary)] text-[13px] mt-1\">\n {emptySubTitle}\n </div>\n )}\n </div>\n </div>\n ) : (\n (() => {\n const renderCard = (\n records: T[],\n startIndex: number,\n cardKey: string,\n ): React.ReactElement => {\n if (isVirtual) {\n return (\n <VirtualSectionCard<T>\n key={`section-card-${cardKey}`}\n cardKey={cardKey}\n records={records}\n startIndex={startIndex}\n scrollElement={virtualScroller}\n estimateRowHeight={virtualEstimate}\n style={sectionCardStyle}\n renderRow={renderRow}\n registerHandle={registerVirtualCard}\n rovingIndex={rovingIndex}\n />\n );\n }\n return (\n <div\n key={`section-card-${cardKey}`}\n className=\"flex flex-col w-full\"\n style={sectionCardStyle}\n >\n {records.map((record, i) =>\n renderRow(\n record,\n startIndex + i,\n i === records.length - 1,\n i === 0,\n ),\n )}\n </div>\n );\n };\n\n if (sectionDividers.size === 0) {\n return renderCard(sortedData, 0, 'all');\n }\n\n const starts = [...sectionDividers.keys()].sort((a, b) => a - b);\n return starts.map((start, i) => {\n const section = sectionDividers.get(start);\n if (!section) {\n return null;\n }\n const end =\n i + 1 < starts.length ? starts[i + 1] : sortedData.length;\n const records = sortedData.slice(start, end);\n const dividerContent = renderSectionDivider?.(\n section.key,\n section.records,\n );\n return (\n <React.Fragment key={`section-${section.key}`}>\n {dividerContent != null ? (\n <div\n className=\"table-section-divider\"\n style={scrollX ? DIVIDER_STICKY : undefined}\n >\n {dividerContent}\n </div>\n ) : null}\n {renderCard(records, start, section.key)}\n </React.Fragment>\n );\n });\n })()\n )}\n </div>\n </div>\n\n {pagination && !loading && (\n <TablePagination\n current={pagination.current ?? 1}\n pageSize={pagination.pageSize ?? 10}\n total={pagination.total ?? 0}\n showSizeChanger={pagination.showSizeChanger}\n showQuickJumper={pagination.showQuickJumper}\n showTotal={pagination.showTotal}\n pageSizeOptions={pagination.pageSizeOptions}\n onChange={pagination.onChange}\n onShowSizeChange={pagination.onShowSizeChange}\n />\n )}\n </div>\n );\n }\n\n const renderHeader = (column: TableColumnDefinition<T>) => {\n const isSortable = column.sorter;\n const isActive = sortConfig?.key === column.key;\n const sortDirection = isActive ? sortConfig?.direction : null;\n\n const headerContent = (\n <div className={`flex items-center gap-2 ${alignJustifyClass(column.align)}`}>\n <span>{column.title}</span>\n {column.info && <HeaderInfo info={column.info} />}\n {isSortable && (\n <div className=\"flex flex-col\">\n <CaretUpIcon\n size={12}\n className={sortDirection === 'asc' ? 'text-blue-600' : 'text-gray-400'}\n />\n <CaretDownIcon\n size={12}\n className={`-mt-1 ${sortDirection === 'desc' ? 'text-blue-600' : 'text-gray-400'}`}\n />\n </div>\n )}\n </div>\n );\n\n return (\n <th\n key={column.key}\n className={`\n table-header table-cell px-4 py-3 font-semibold border-0 first:rounded-tl-lg last:rounded-tr-lg\n ${getSizeClasses(size)}\n ${alignTextClass(column.align)}\n `}\n style={{ width: column.width }}\n aria-sort={isSortable ? ariaSortValue(sortDirection) : undefined}\n >\n {isSortable ? (\n <button\n {...sortButtonProps(column.title, () => handleSort(column.key))}\n className={`flex w-full items-center ${alignJustifyClass(column.align)} cursor-pointer hover:opacity-80 appearance-none bg-transparent border-0 p-0 font-semibold text-inherit ${alignTextClass(column.align)}`}\n >\n {headerContent}\n </button>\n ) : (\n headerContent\n )}\n </th>\n );\n };\n\n if (error) {\n return (\n <div className=\"w-full\" style={{ ...FOREGROUND_RESET, ...style }}>\n <div\n className=\"overflow-x-auto\"\n style={{\n ...(scrollHeight ? { maxHeight: scrollHeight } : {}),\n }}\n >\n <table className=\"w-full border-collapse rounded-lg overflow-hidden\">\n {showHeader && (\n <thead>\n <tr>\n {columns.map((column) => (\n <th\n key={column.key}\n className={`\n ${bordered ? 'table-header' : 'table-header'} table-cell px-4 py-3 font-semibold border-0 first:rounded-tl-lg last:rounded-tr-lg\n ${bordered ? 'table-cell-bordered table-cell-bordered-top' : ''}\n ${bordered && column === columns[0] ? 'table-cell-bordered-left' : ''}\n ${bordered && column === columns[columns.length - 1] ? 'table-cell-bordered-right' : ''}\n ${getSizeClasses(size)}\n ${alignTextClass(column.align)}\n `}\n style={{ width: column.width }}\n >\n <div\n className={`flex items-center gap-2 ${alignJustifyClass(column.align)}`}\n >\n <span>{column.title}</span>\n {column.info && <HeaderInfo info={column.info} />}\n </div>\n </th>\n ))}\n </tr>\n </thead>\n )}\n <tbody>\n <tr>\n <td\n colSpan={columns.length + (rowSelection ? 1 : 0)}\n className=\"px-4 py-12 text-center\"\n >\n <div className=\"flex flex-col items-center justify-center\">\n <div className=\"table-error-icon w-12 h-12 rounded-full flex items-center justify-center mb-4\">\n <WarningTriangleIcon size={24} />\n </div>\n <div className=\"table-error-title text-lg font-semibold mb-2\">\n {errorTitle}\n </div>\n <div className=\"table-error-subtitle text-sm\">\n {errorSubTitle}\n </div>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n );\n }\n\n return (\n <div\n ref={containerRef}\n className={`w-full ${className}`}\n style={{ ...FOREGROUND_RESET, ...style }}\n >\n <div\n className={`overflow-hidden rounded-lg ${bordered ? 'table-bordered-container' : 'table-container-border'}`}\n data-bordered={bordered ? 'true' : 'false'}\n >\n <div\n className=\"overflow-x-auto\"\n style={{\n ...(scrollHeight ? { maxHeight: scrollHeight } : {}),\n }}\n >\n <table\n className={`w-full ${layout === 'fixed' || columns.some((col) => col.width) ? 'table-fixed' : 'table-auto'} ${bordered ? 'border-separate table-bordered' : 'border-collapse'} rounded-lg overflow-hidden`}\n style={{ borderSpacing: bordered ? '0' : '0' }}\n >\n {showHeader && (\n <thead>\n <tr>{columns.map((column) => renderHeader(column))}</tr>\n </thead>\n )}\n <tbody>\n {loading ? (\n Array.from({ length: 5 }).map((_, index) => (\n <tr\n key={index}\n className={`table-row ${bordered ? 'table-row-bordered' : ''}`}\n >\n {columns.map((column) => (\n <td\n key={column.key}\n className={`table-cell px-4 ${bodyCellPaddingY} text-left ${getSizeClasses(size)}`}\n style={{ width: column.width }}\n >\n <div className=\"h-4 bg-gray-200 rounded animate-pulse\"></div>\n </td>\n ))}\n </tr>\n ))\n ) : sortedData.length === 0 ? (\n <tr>\n <td\n colSpan={columns.length + (rowSelection ? 1 : 0)}\n className=\"px-4 py-12 text-center\"\n >\n <div className=\"flex flex-col items-center justify-center\">\n <div className=\"text-[var(--malachite-text-secondary)] text-[14px] font-medium\">\n {emptyTitle}\n </div>\n {emptySubTitle && (\n <div className=\"text-[var(--malachite-text-secondary)] text-[13px] mt-1\">\n {emptySubTitle}\n </div>\n )}\n </div>\n </td>\n </tr>\n ) : (\n sortedData.map((record, index) => {\n const key = getRowKey(record, index);\n const rowActions = onRow?.(record, index) || {};\n const variant = rowVariant?.(record, index);\n\n const isFirstRow = index === 0;\n const isLastRow = index === data.length - 1;\n\n const isSelected = index === selectedIndex;\n const variantBackground = variant\n ? `var(--malachite-table-row-variant-${variant}-background)`\n : undefined;\n\n const handleRowClick =\n onClickRow || rowActions.onClick\n ? () => {\n onClickRow?.(record, index);\n rowActions.onClick?.(record, index);\n }\n : undefined;\n\n return (\n // Keeps `row` semantics: `role=\"button\"` would strip the table\n // structure from screen readers.\n <tr\n key={key}\n data-table-id={tableId}\n data-row-index={index}\n // `aria-selected` needs a role this row lacks.\n aria-current={isSelected ? 'true' : undefined}\n tabIndex={\n handleRowClick\n ? index === rovingIndex\n ? 0\n : -1\n : undefined\n }\n onKeyDown={\n handleRowClick\n ? rowKeyDown(index, handleRowClick)\n : undefined\n }\n // Drops hover:opacity-80: opacity is not a background,\n // so the cells can't beat it and the row fades below AA.\n className={`\n ${bordered ? 'table-row-bordered' : `table-row ${isSelected ? '' : 'hover:opacity-80'}`}\n ${rowClassName?.(record, index) || ''}\n ${handleRowClick ? `cursor-pointer ${FOCUS_RING_INSET}` : ''}\n `}\n onClick={\n handleRowClick\n ? (event) => {\n if (!isFromInteractiveDescendant(event)) {\n handleRowClick();\n }\n }\n : undefined\n }\n onDoubleClick={\n rowActions.onDoubleClick\n ? () =>\n rowActions.onDoubleClick?.(record, index)\n : undefined\n }\n onContextMenu={\n rowActions.onContextMenu\n ? () =>\n rowActions.onContextMenu?.(record, index)\n : undefined\n }\n onMouseEnter={\n rowActions.onMouseEnter\n ? () => rowActions.onMouseEnter?.(record, index)\n : undefined\n }\n onMouseLeave={\n rowActions.onMouseLeave\n ? () => rowActions.onMouseLeave?.(record, index)\n : undefined\n }\n >\n {columns.map((column) => {\n const isFirstColumn = column === columns[0];\n const isLastColumn =\n column === columns[columns.length - 1];\n\n return (\n <TableCell<T>\n key={column.key}\n column={column}\n record={record}\n index={index}\n size={size}\n paddingYClass={bodyCellPaddingY}\n bordered={bordered}\n isFirstRow={isFirstRow}\n isLastRow={isLastRow}\n isFirstColumn={isFirstColumn}\n isLastColumn={isLastColumn}\n variantBackground={variantBackground}\n isSelected={isSelected}\n showSelectedAccent={\n isSelected && isFirstColumn\n }\n />\n );\n })}\n </tr>\n );\n })\n )}\n </tbody>\n </table>\n </div>\n </div>\n\n {pagination && !loading && (\n <TablePagination\n current={pagination.current ?? 1}\n pageSize={pagination.pageSize ?? 10}\n total={pagination.total ?? 0}\n showSizeChanger={pagination.showSizeChanger}\n showQuickJumper={pagination.showQuickJumper}\n showTotal={pagination.showTotal}\n pageSizeOptions={pagination.pageSizeOptions}\n onChange={pagination.onChange}\n onShowSizeChange={pagination.onShowSizeChange}\n />\n )}\n </div>\n );\n};\n\nexport default Table;\n"],"names":["DEFAULT_SCROLL_COL_WIDTH","sameRowOrder","a","b","key","index","KEYLESS_ID_PREFIX","keylessId","record","registry","seen","id","visibleRowOrder","sortedData","rowKey","fixedPxWidth","width","match","shrinkFloor","column","fixed","computeScrollMinWidth","columns","sum","isRowActionSlot","computePinnedRight","trailingSlotCount","firstTrailingSlot","offsets","settled","acc","HEADER_SCROLL_STYLE","DIVIDER_STICKY","NO_PINNED_COLUMNS","PINNED_EDGE_SHADOW","pinnedCellStyle","right","isEdge","showEdgeShadow","background","solidLayer","color","detachedRowPaint","variant","isSelected","layers","SELECTED_ROW_BACKGROUND","isString","value","getSizeClasses","size","ROW_BORDER_STYLE","syncScroll","source","target","PAGINATION_RESERVED_HEIGHT","DEFAULT_VIRTUAL_ROW_HEIGHT","VIRTUAL_OVERSCAN_ROWS","VIRTUAL_SCROLL_CORRECTION_FRAMES","SECTION_CARD_RADIUS","DETACHED_CARD_RADIUS","DETACHED_CARD_PADDING","SURROUND_CHANNEL","StickyHeaderCornerCap","r","card","jsx","VirtualSectionCard","records","startIndex","scrollElement","estimateRowHeight","style","renderRow","registerHandle","cardKey","rovingIndex","cardRef","useRef","scrollMargin","setScrollMargin","useState","useLayoutEffect","measure","margin","previous","observer","node","sibling","parent","root","virtualizer","useVirtualizer","useEffect","localIndex","items","totalSize","tabStopIndex","paddingTop","paddingBottom","item","computeScrollableMaxHeight","scrollHeight","reservePagination","reserved","cellWidthStyle","floor","fixedSlotStyle","ariaSortValue","sortDirection","alignJustifyClass","align","sortableHeaderJustifyClass","alignTextClass","fixedSlotJustifyClass","HeaderInfo","info","Tooltip","InfoIcon","sortButtonProps","title","onActivate","TableCell","paddingYClass","bordered","isFirstRow","isLastRow","isFirstColumn","isLastColumn","variantBackground","showSelectedAccent","rawValue","cellContent","titleText","SELECTED_ROW_FOREGROUND","SELECTED_TEXT_CONTEXT","SELECTED_ROW_ACCENT","DetachedHeaderCell","onSort","cellStyle","isSortable","titleIsEmpty","titleNode","sortCaret","CaretDownIcon","jsxs","DetachedCell","hasFixedWidth","isStringValue","selectionStyle","cellBody","TruncatedTooltip","Table","data","loading","error","errorTitle","errorSubTitle","emptyTitle","emptySubTitle","showHeader","rowDensity","layout","headerVariant","rowClassName","rowVariant","onRow","onClickRow","selectedRowKey","scrollSelectedIntoView","rowSelection","pagination","className","stickyHeaderTop","scrollX","rowSection","renderSectionDivider","onVisibleOrderChange","virtual","virtualRowHeightEstimate","virtualScrollElement","bodyCellPaddingY","sortConfig","setSortConfig","headerRef","headerScrollRef","bodyScrollRef","containerRef","virtualCardsRef","registerVirtualCard","useCallback","handle","tableId","useId","focusedRowIndex","setFocusedRowIndex","isVirtual","virtualEstimate","bodyScrollElement","setBodyScrollElement","bodyScrollRefCallback","element","virtualScroller","scrollMinWidth","pinned","hasPinnedEdge","contentHiddenRight","setContentHiddenRight","bodyScrollbarGutter","setBodyScrollbarGutter","updateContentHidden","body","bodyOwnsScroll","isStickyHeader","usesSelection","stickyHeaderHeight","setStickyHeaderHeight","header","entries","entry","height","_b","_a","rowScrollMarginTop","sectionDividers","useMemo","sortRecords","sortColumn","col","sorted","field","aComparable","bComparable","groups","groupIndexByKey","sectionKey","groupIndex","rows","dividers","group","sectionRows","handleSort","prev","getRowKey","rowKeyDep","reportedRowOrderRef","keylessIdsRef","rowOrder","reported","selectedIndex","lastScrolledRef","last","container","scrollMarginPending","rowAt","reveal","row","outer","bodyLeft","outerLeft","mounted","frame","attempts","correct","focusOriginRef","moveRowFocus","from","toIndex","origin","rendered","nearest","rowKeyDown","activate","event","step","activateOnEnterOrSpace","rowMinWidthStyle","cellStyleFor","headerPinBackground","sectionCardStyle","isLastInSection","isFirstInSection","virtualMeasure","rowActions","handleClick","isClickable","rowBorder","FOCUS_RING_INSET","isFromInteractiveDescendant","FOCUS_RING_INSET_OVERLAY","renderSkeletonRow","isLast","headerRow","FOREGROUND_RESET","count","_","i","renderCard","starts","start","section","end","dividerContent","React","TablePagination","renderHeader","headerContent","CaretUpIcon","WarningTriangleIcon","handleRowClick"],"mappings":"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"}